📄 vncencodezlib.cpp
字号:
{
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 + -