⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vncencodezlib.cpp

📁 teamviewer source code vc++
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				{
					AddToQueu(dest,sz_rfbFramebufferUpdateRectHeader +newsize,outConn,1);
					return 0;
				}
				///vnclog.Print(LL_INTINFO, VNCLOG("XOR "));
				break;
			}

		case PURE_ZLIB:
			{
				if (rawDataSize<1000 && m_queueEnable)
				{
				surh->encoding = Swap32IfLE(rfbEncodingRaw);
				memcpy(dest+sz_rfbFramebufferUpdateRectHeader,m_buffer,rawDataSize);
				AddToQueu(dest,sz_rfbFramebufferUpdateRectHeader +rawDataSize,outConn,1);
				return 0;
				}

				surh->encoding = Swap32IfLE(rfbEncodingZlib);
				///vnclog.Print(LL_INTINFO, VNCLOG("Pure "));
				break;
			}
	}
		// Initialize input/output buffer assignment for compressor state.
		compStream.next_in = m_buffer;
		compStream.avail_out = maxCompSize;
		compStream.next_out = (dest+sz_rfbFramebufferUpdateRectHeader+sz_rfbZlibHeader);
		compStream.data_type = Z_BINARY;
	
		// If necessary, the first time, initialize the compressor state.
		if ( compStreamInited == false )
		{
	
			compStream.total_in = 0;
			compStream.total_out = 0;
			compStream.zalloc = Z_NULL;
			compStream.zfree = Z_NULL;
			compStream.opaque = Z_NULL;
	
			//vnclog.Print(LL_INTINFO, VNCLOG("calling deflateInit2 with zlib level:%d"), m_compresslevel);
	
			deflateResult = deflateInit2( &compStream,
										m_compresslevel,
										Z_DEFLATED,
										MAX_WBITS,
										MAX_MEM_LEVEL,
										Z_DEFAULT_STRATEGY );
			if ( deflateResult != Z_OK )
			{
				vnclog.Print(LL_INTINFO, VNCLOG("deflateInit2 returned error:%d:%s"), deflateResult, compStream.msg);
				return vncEncoder::EncodeRect(source, dest, rect);
			}
			compStreamInited = true;
		}

		// Record previous total output size.
		previousTotalOut = compStream.total_out;

		// Compress the raw data into the result buffer.
		deflateResult = deflate( &compStream, Z_SYNC_FLUSH );

		if ( deflateResult != Z_OK )
		{
			vnclog.Print(LL_INTINFO, VNCLOG("deflate returned error:%d:%s"), deflateResult, compStream.msg);
			return vncEncoder::EncodeRect(source, dest, rect);
		}
	
		// Calculate size of compressed data.
		totalCompDataLen = compStream.total_out - previousTotalOut;
	
		// Format the ZlibHeader
		rfbZlibHeader *zlibh=(rfbZlibHeader *)(dest+sz_rfbFramebufferUpdateRectHeader);
		zlibh->nBytes = Swap32IfLE(totalCompDataLen);
	
		// Update statistics
		encodedSize += sz_rfbZlibHeader + totalCompDataLen;
		rectangleOverhead += sz_rfbFramebufferUpdateRectHeader;

		// Return the amount of data sent	
		return sz_rfbFramebufferUpdateRectHeader +
			sz_rfbZlibHeader +
			totalCompDataLen;

}

inline UINT
vncEncodeZlib::PrepareXOR(BYTE * m_buffer,BYTE * m_buffer2,RECT rect)
{
	
	DWORD c1;
	DWORD c2;
	unsigned char *c1ptr;
	unsigned char *c2ptr;

	unsigned char *sourceptr = m_buffer;
	unsigned char *source2ptr = m_buffer2;
	unsigned char *sourceposptr = m_buffer2;

	const int rectW = rect.right - rect.left;
	const int rectH = rect.bottom - rect.top;
	const int BytePerPixel=m_remoteformat.bitsPerPixel/8;
	const int rawDataSize = (rectW*rectH*BytePerPixel);
	const int maskDataSize = (((rectW*rectH)+7)/8);
	
	if (m_MaskbufferSize < maskDataSize)
	{
		if (m_Maskbuffer != NULL)
		{
			delete [] m_Maskbuffer;
			m_Maskbuffer = NULL;
		}
		m_Maskbuffer = new mybool [maskDataSize+1];
	}
	
	c1ptr=(unsigned char *)&c1;
	c2ptr=(unsigned char *)&c2;

	totalraw+=rawDataSize; //stats

	memcpy(c1ptr,sourceptr,BytePerPixel);
	// detect mono and solid parts
	int j=0;
	int nr_colors=1;
	bool temparray[8];
	int byte_nr=0;
	for (int i=0; i<rawDataSize;i=i+BytePerPixel)
	{
		if (memcmp(sourceptr,c1ptr,BytePerPixel)!= 0)
		{
			if (nr_colors==1)
				{
					memcpy(c2ptr,sourceptr,BytePerPixel);
					nr_colors++;
					SoMoMu=MONO_COLOR;
				}
			else if (memcmp(sourceptr,c2ptr,BytePerPixel)!= 0)
				{
						SoMoMu=MULTI_COLOR;
						nr_colors++;
						break;//stop checking we have more then 2 colors
				}
			temparray[j]=true;
		}
		else
		{
			temparray[j]=false;
		}
		if (j==7) //0-7 byte
		{
			m_Maskbuffer[byte_nr].b0=temparray[0];
			m_Maskbuffer[byte_nr].b1=temparray[1];
			m_Maskbuffer[byte_nr].b2=temparray[2];
			m_Maskbuffer[byte_nr].b3=temparray[3];
			m_Maskbuffer[byte_nr].b4=temparray[4];
			m_Maskbuffer[byte_nr].b5=temparray[5];
			m_Maskbuffer[byte_nr].b6=temparray[6];
			m_Maskbuffer[byte_nr].b7=temparray[7];
			byte_nr++;
			j=0;
		}
		else j++;
		sourceptr+=BytePerPixel;
		source2ptr+=BytePerPixel;
	}
	// add the last partial byte
	if (j!=0)
	{
		m_Maskbuffer[byte_nr].b0=temparray[0];
		m_Maskbuffer[byte_nr].b1=temparray[1];
		m_Maskbuffer[byte_nr].b2=temparray[2];
		m_Maskbuffer[byte_nr].b3=temparray[3];
		m_Maskbuffer[byte_nr].b4=temparray[4];
		m_Maskbuffer[byte_nr].b5=temparray[5];
		m_Maskbuffer[byte_nr].b6=temparray[6];
		m_Maskbuffer[byte_nr].b7=temparray[7];
	}

//SOLID COLOR
	if (nr_colors==1)
	{
	//full solid rectangle
		unsigned char *sourceptr = m_buffer;
		memcpy(sourceptr,c1ptr,BytePerPixel);
		SoMoMu=SOLID_COLOR;
		return BytePerPixel;
		}
//MONO COLOR
	if (nr_colors==2)
	{

		unsigned char *sourceptr = m_buffer;
		memcpy(sourceptr,m_Maskbuffer,maskDataSize);
		sourceptr+=maskDataSize;
		memcpy(sourceptr,c1ptr,BytePerPixel);
		sourceptr+=BytePerPixel;
		memcpy(sourceptr,c2ptr,BytePerPixel);
		SoMoMu=MONO_COLOR;
		return maskDataSize+(2)*BytePerPixel;
	}

//USE XOR AGAINST PREVIOUS IMAGE
	{
		int j=0;
		int k=0;
		SoMoMu=XOR_SEQUENCE;
		bool temparray[8];
		int byte_nr=0;
		sourceptr = m_buffer;
		source2ptr = m_buffer2;
		for (int i=0; i<rawDataSize;i=i+BytePerPixel)
		{
			if (memcmp(sourceptr,source2ptr,BytePerPixel)!= 0)
			{
				memcpy(sourceposptr,sourceptr,BytePerPixel);
				temparray[j]=true;
				sourceposptr+=BytePerPixel;
				k++;
			}
			else
			{
				temparray[j]=false;
			}
			if (j==7) //0-7 byte
			{
				m_Maskbuffer[byte_nr].b0=temparray[0];
				m_Maskbuffer[byte_nr].b1=temparray[1];
				m_Maskbuffer[byte_nr].b2=temparray[2];
				m_Maskbuffer[byte_nr].b3=temparray[3];
				m_Maskbuffer[byte_nr].b4=temparray[4];
				m_Maskbuffer[byte_nr].b5=temparray[5];
				m_Maskbuffer[byte_nr].b6=temparray[6];
				m_Maskbuffer[byte_nr].b7=temparray[7];
				byte_nr++;
				j=0;
			}
			else j++;
			sourceptr+=BytePerPixel;
			source2ptr+=BytePerPixel;
		}
		//add last byte, perhaps j==0
		if (j!=0)
		{
			m_Maskbuffer[byte_nr].b0=temparray[0];
			m_Maskbuffer[byte_nr].b1=temparray[1];
			m_Maskbuffer[byte_nr].b2=temparray[2];
			m_Maskbuffer[byte_nr].b3=temparray[3];
			m_Maskbuffer[byte_nr].b4=temparray[4];
			m_Maskbuffer[byte_nr].b5=temparray[5];
			m_Maskbuffer[byte_nr].b6=temparray[6];
			m_Maskbuffer[byte_nr].b7=temparray[7];
		}
	
		//check if new size is better then old
		if ((maskDataSize+(k)*BytePerPixel)<rawDataSize)
		{
			unsigned char *sourceptr = m_buffer;
			memcpy(sourceptr,m_Maskbuffer,maskDataSize);
			sourceptr+=maskDataSize;
			memcpy(sourceptr,m_buffer2,k*BytePerPixel);
			return maskDataSize+(k)*BytePerPixel;
		}
	}
	SoMoMu=PURE_ZLIB;
	return 0;
}

void
vncEncodeZlib::AddToQueu(BYTE *source,int sizerect,VSocket *outConn,int updatetype)
{
	if (m_Queuelen+sizerect>(MaxQueuebufflen)) SendZlibrects(outConn);
	memcpy(m_Queuebuffer+m_Queuelen,source,sizerect);
	m_Queuelen+=sizerect;
	m_nNbRects++;
	if (updatetype==1) must_be_zipped=true;
	if (m_nNbRects>50) SendZlibrects(outConn);
}

void
vncEncodeZlib::SendZlibrects(VSocket *outConn)
{
	int NRects=m_nNbRects;
	const int rawDataSize = (m_Queuelen);
	const int maxCompSize = (m_Queuelen + (m_Queuelen/100) + 8);

	if (NRects==0) return; // NO update
	if (m_nNbRects<3 && !must_be_zipped) 
	{
		outConn->SendExactQueue( (char *)m_Queuebuffer, m_Queuelen); // 1 Small update
		m_nNbRects=0;
		m_Queuelen=0;
		encodedSize += m_Queuelen-sz_rfbFramebufferUpdateRectHeader;
		rectangleOverhead += sz_rfbFramebufferUpdateRectHeader;
		return;
	}
	m_nNbRects=0;
	m_Queuelen=0;
	must_be_zipped=false;


	int nRet = compress((unsigned char*)(m_QueueCompressedbuffer),
						(unsigned long*)&maxCompSize,
						(unsigned char*)m_Queuebuffer,
						rawDataSize
						);

	if (nRet != 0)
	{
		vnclog.Print(LL_INTINFO, VNCLOG("compression error"));
		return ;
	}
	int rawDataSize1=rawDataSize/65535;
	int rawDataSize2=rawDataSize%65535;

	rfbFramebufferUpdateRectHeader CacheRectsHeader;
	CacheRectsHeader.r.x = (CARD16)(NRects);
	CacheRectsHeader.r.y = (CARD16)(rawDataSize2);
	CacheRectsHeader.r.w = (CARD16)(rawDataSize1);
	CacheRectsHeader.r.x = Swap16IfLE(CacheRectsHeader.r.x);
	CacheRectsHeader.r.y = Swap16IfLE(CacheRectsHeader.r.y);
	CacheRectsHeader.r.w = Swap16IfLE(CacheRectsHeader.r.w);
 	CacheRectsHeader.r.h = 0;
	CacheRectsHeader.encoding = Swap32IfLE(rfbEncodingSolMonoZip);

	// Format the ZlibHeader
	rfbZlibHeader CacheZipHeader;
	CacheZipHeader.nBytes = Swap32IfLE(maxCompSize);

	vnclog.Print(LL_INTINFO, VNCLOG("********QUEUEQUEUE********** %d %d %d\r"),maxCompSize,rawDataSize,NRects);
	outConn->SendExactQueue((char *)&CacheRectsHeader, sizeof(CacheRectsHeader));
	outConn->SendExactQueue((char *)&CacheZipHeader, sizeof(CacheZipHeader));
	outConn->SendExactQueue((char *)m_QueueCompressedbuffer, maxCompSize);
	// Update statistics
	encodedSize += sz_rfbZlibHeader + maxCompSize;
	rectangleOverhead += sz_rfbFramebufferUpdateRectHeader;
	transmittedSize += maxCompSize+sz_rfbFramebufferUpdateRectHeader+sz_rfbZlibHeader;
}

void
vncEncodeZlib::LastRect(VSocket *outConn)
{
	SendZlibrects(outConn);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -