如何为VNC服务器实现ZLIB编码? [英] How to implement ZLIB encoding for VNC server?
本文介绍了如何为VNC服务器实现ZLIB编码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
为我的VNC服务器添加ZLIB编码时遇到了问题。问题是,客户端(查看器)只接受第一个帧缓冲区,后续帧缓冲区被绘制为空白屏幕。在某个地方,我看到我们必须使用单个ZLIB流进行VNC会话,但我不知道如何实现它。下面是我的代码片段,在我的VNC服务器中发送矩形像素数据。
Hi,
While adding ZLIB encoding for my VNC server and I came across a problem. The issue is, only the very first framebuffer is accepted by the client (viewer) and subsequent framebuffers are plotted as blank screens. Somewhere I saw that we have to make use of a single ZLIB stream for a VNC session but I don't know how to implement it. Below is my code snippet sending a rectangle of pixel data in my VNC server.
//==============================================================================
//Note: Rectangle header containing x, y, height, width and encoding is sent
//prior to this code.
//
//reduce the BMP header size from total length
uLongf sourceLen = DATA_SIZE-0x436;
//add sufficient length for encoding algorithm
uLongf destLen = (sourceLen*1.001)+12;
unsigned char* compressedBuffer = (unsigned char*)malloc(destLen);
zlibstream.next_in = (Bytef*)pixelDataBuffer;
zlibstream.avail_in = (uInt)sourceLen;
zlibstream.next_out = compressedBuffer;
zlibstream.avail_out = (uInt)destLen;
if ((uLong)zlibstream.avail_out != destLen) return 1;//Z_BUF_ERROR;
zlibstream.zalloc = (alloc_func)0;
zlibstream.zfree = (free_func)0;
zlibstream.opaque = (voidpf)0;
if(!bFirstUpdateSent)
{
//Initialize the ZLIB ONLY for the first time
printf("before deflateInit \r\n");
zliberr = deflateInit(&zlibstream, Z_DEFAULT_COMPRESSION);
if (zliberr != Z_OK)
{
printf("deflateInit failed \r\n");
}
}
bFirstUpdateSent = TRUE;
printf("before deflate \r\n");
//Apply ZLIB encoding to the pixel buffer
zliberr = deflate(&zlibstream, Z_FINISH);
if (zliberr != Z_STREAM_END) {
return zliberr == Z_OK ? 0 : 1;
}
destLen = zlibstream.total_out;
printf("zlib data length = %d \r\n", zlibPixelBufferLength-4);
unsigned char zlibHeader[4];
UINT32 zlibLength = destLen;
zlibHeader[0] = zlibLength>>24;
zlibHeader[1] = zlibLength>>16;
zlibHeader[2] = zlibLength>>8;
zlibHeader[3] = zlibLength;
//Send length of the zlib buffer
iSendResult = send( ClientSocket, (const char*)zlibHeader, 4, 0 );
if(iSendResult==SOCKET_ERROR){return 1;}
//send zlib encoded pixel data
iSendResult = send( ClientSocket, (const char*)compressedBuffer, destLen, 0 );
//==============================================================================
请帮忙。
问候,
-KK-
Please help.
Regards,
-KK-
推荐答案
我可以自己解决这个问题。我想在调用init函数之前初始化zalloc,zfree和opaque,并在每次放气周期后重置流。以下是更新的代码。
I could resolve the issue by myself. I suppose to initialize zalloc, zfree and opaque before calling the init function and reset the stream after each deflate cycle. Following is the updated code.
//==============================================================================
//Note: Rectangle header containing x, y, height, width and encoding is sent
//prior to this code.
//
//reduce the BMP header size from total length
uLongf sourceLen = DATA_SIZE-0x436;
//add sufficient length for encoding algorithm
uLongf destLen = (sourceLen*1.001)+12;
unsigned char* compressedBuffer = (unsigned char*)malloc(destLen);
zlibstream.next_in = (Bytef*)pixelDataBuffer;
zlibstream.avail_in = (uInt)sourceLen;
zlibstream.next_out = compressedBuffer;
zlibstream.avail_out = (uInt)destLen;
if ((uLong)zlibstream.avail_out != destLen) return 1;//Z_BUF_ERROR;
if(!bFirstUpdateSent)
{
//must initialize zalloc, zfree and opaque before calling the init function
zlibstream.zalloc = (alloc_func)0;
zlibstream.zfree = (free_func)0;
zlibstream.opaque = (voidpf)0;
//Initialize the ZLIB for the first time
printf("before deflateInit \r\n");
zliberr = deflateInit(&zlibstream, Z_DEFAULT_COMPRESSION);
if (zliberr != Z_OK)
{
printf("deflateInit failed \r\n");
}
}
bFirstUpdateSent = TRUE;
printf("before deflate \r\n");
//Apply ZLIB encoding to the pixel buffer
zliberr = deflate(&zlibstream, Z_FINISH);
if (zliberr != Z_STREAM_END) {
return zliberr == Z_OK ? 0 : 1;
}
destLen = zlibstream.total_out;
unsigned char zlibHeader[4];
UINT32 zlibLength = destLen;
zlibHeader[0] = zlibLength>>24; zlibHeader[1] = zlibLength>>16; zlibHeader[2] = zlibLength>>8; zlibHeader[3] = zlibLength;
//Send length of the zlib buffer
iSendResult = send( ClientSocket, (const char*)zlibHeader, 4, 0 );
if(iSendResult==SOCKET_ERROR){return 1;}
//send zlib encoded pixel data
iSendResult = send( ClientSocket, (const char*)compressedBuffer, destLen, 0 );
//Reset the stream for next cycle
zliberr = deflateReset(&zlibstream);
//==============================================================================
问候,
-KK -
Regards,
-KK-
最后问题得到解决,如果有人有兴趣,这里是更新后的代码。
Finally the issue is resolved and here is the updated code if someone is interested in.
//==============================================================================
if(!bFirstUpdateSent)
{
zlibstream.zalloc = (alloc_func)0;
zlibstream.zfree = (free_func)0;
zlibstream.opaque = (voidpf)0;
//Initialize the ZLIB for the first time
printf("before deflateInit \r\n");
zliberr = deflateInit(&zlibstream, Z_DEFAULT_COMPRESSION);
if (zliberr != Z_OK)
{
printf("deflateInit failed \r\n");
}
}
bFirstUpdateSent = TRUE;
//reduce the BMP header size from total length
uLongf sourceLen = DATA_SIZE-0x436;
//add sufficient length for encoding algorithm
uLongf destLen = (sourceLen*1.001)+12;
unsigned char* compressedBuffer = (unsigned char*)malloc(destLen);
zlibstream.next_in = (Bytef*)pixelDataBuffer;
zlibstream.avail_in = (uInt)sourceLen;
zlibstream.next_out = compressedBuffer;
zlibstream.avail_out = (uInt)destLen;
previous_out = zlibstream.total_out;
printf("before deflate \r\n");
//Apply ZLIB encoding to the pixel buffer
zliberr = deflate(&zlibstream, Z_SYNC_FLUSH);
destLen = zlibstream.total_out - previous_out;
printf("zlib data length = %d \r\n", destLen);
unsigned char zlibHeader[4];
UINT32 zlibLength = destLen;
zlibHeader[0] = zlibLength>>24; zlibHeader[1] = zlibLength>>16; zlibHeader[2] = zlibLength>>8; zlibHeader[3] = zlibLength;
//Send length of the zlib buffer
iSendResult = send( ClientSocket, (const char*)zlibHeader, 4, 0 );
if(iSendResult==SOCKET_ERROR){return 1;}
//send zlib encoded pixel data
iSendResult = send( ClientSocket, (const char*)compressedBuffer, destLen, 0 );
//Free the buffer
free(compressedBuffer);
//==============================================================================
问候,
-KK -
Regards,
-KK-
这篇关于如何为VNC服务器实现ZLIB编码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文