如何为VNC服务器实现ZLIB编码? [英] How to implement ZLIB encoding for VNC server?

查看:100
本文介绍了如何为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆