UINT vncEncodeTight::EncodeSubrect(BYTE *source, VSocket *outConn, BYTE *dest, int x, int y, int w, int h) { SendTightHeader(x, y, w, h); RECT r; r.left = x; r.top = y; r.right = x + w; r.bottom = y + h; Translate(source, m_buffer, r); m_paletteMaxColors = w * h / m_conf[m_compresslevel].idxMaxColorsDivisor; if ( m_paletteMaxColors < 2 && w * h >= m_conf[m_compresslevel].monoMinRectSize ) { m_paletteMaxColors = 2; } switch (m_remoteformat.bitsPerPixel) { case 8: FillPalette8(w * h); break; case 16: FillPalette16(w * h); break; default: FillPalette32(w * h); } int encDataSize; switch (m_paletteNumColors) { case 0: // Truecolor image if (DetectSmoothImage(w, h)) { if (m_qualitylevel != -1) { encDataSize = SendJpegRect(dest, w, h, m_conf[m_qualitylevel].jpegQuality); } else { encDataSize = SendGradientRect(dest, w, h); } } else { encDataSize = SendFullColorRect(dest, w, h); } break; case 1: // Solid rectangle encDataSize = SendSolidRect(dest); break; case 2: // Two-color rectangle encDataSize = SendMonoRect(dest, w, h); break; default: // Up to 256 different colors if ( m_paletteNumColors > 96 && m_qualitylevel != -1 && m_qualitylevel <= 3 && DetectSmoothImage(w, h) ) { encDataSize = SendJpegRect(dest, w, h, m_conf[m_qualitylevel].jpegQuality); } else { encDataSize = SendIndexedRect(dest, w, h); } } if (encDataSize < 0) return vncEncoder::EncodeRect(source, dest, r, 0, 0); outConn->SendQueued((char *)m_hdrBuffer, m_hdrBufferBytes); encodedSize += m_hdrBufferBytes - sz_rfbFramebufferUpdateRectHeader + encDataSize; transmittedSize += m_hdrBufferBytes + encDataSize; return encDataSize; }
// Encode the rectangle using Ultra compression // Encode the rectangle using Ultra compression inline UINT vncEncodeUltra2::EncodeRect(BYTE *source, VSocket *outConn, BYTE *dest, const rfb::Rect &rect2) { int Size = 0; rfb::Rect rect; rect.br.x=rect2.br.x; rect.br.y=rect2.br.y; rect.tl.x=rect2.tl.x; rect.tl.y=rect2.tl.y; /*while(((rect.br.x-rect.tl.x))/8*8!=(rect.br.x-rect.tl.x)) { if (rect.br.x+1<=framebufferWidth) rect.br.x+=1; else if (rect.tl.x-1>=0) rect.tl.x-=1; } while(((rect.br.y-rect.tl.y))/8*8!=(rect.br.y-rect.tl.y)) { if (rect.br.y+1<=framebufferHeight) rect.br.y+=1; else if (rect.tl.y-1>=0) rect.tl.y-=1; }*/ const int rectW = rect.br.x - rect.tl.x; const int rectH = rect.br.y - rect.tl.y; const int rawDataSize = (rectW*rectH*m_remoteformat.bitsPerPixel / 8); if (rectW==0) return 0; if (rectH==0) return 0; rfbFramebufferUpdateRectHeader *surh=(rfbFramebufferUpdateRectHeader *)dest; // Modif rdv@2002 - v1.1.x - Application Resize surh->r.x = (CARD16) rect.tl.x-m_SWOffsetx; surh->r.y = (CARD16) rect.tl.y-m_SWOffsety; surh->r.w = (CARD16) (rectW); surh->r.h = (CARD16) (rectH); surh->r.x = Swap16IfLE(surh->r.x); surh->r.y = Swap16IfLE(surh->r.y); surh->r.w = Swap16IfLE(surh->r.w); surh->r.h = Swap16IfLE(surh->r.h); surh->encoding = Swap32IfLE(rfbEncodingUltra2); // create a space big enough for the Zlib encoded pixels if (m_bufflen < rawDataSize) { if (m_buffer != NULL) { delete [] m_buffer; m_buffer = NULL; } m_buffer = new BYTE [rawDataSize+1000]; if (m_buffer == NULL) return vncEncoder::EncodeRect(source, dest, rect); m_bufflen = rawDataSize+999; } // Translate the data into our new buffer Translate(source, m_buffer, rect); rfbZlibHeader *zlibh=(rfbZlibHeader *)(dest+sz_rfbFramebufferUpdateRectHeader); if ((rectW*rectH)<1024) { if (rawDataSize < 64) { return vncEncoder::EncodeRect(source, dest, rect); } if (lzo==false) { if (lzo_init() == LZO_E_OK) lzo=true; } lzo1x_1_compress(m_buffer,rawDataSize,dest+sz_rfbFramebufferUpdateRectHeader+sz_rfbZlibHeader,&out_len,wrkmem); if (out_len > (lzo_uint)rawDataSize) { return vncEncoder::EncodeRect(source, dest, rect); } surh->encoding = Swap32IfLE(rfbEncodingUltra); zlibh->nBytes = Swap32IfLE(out_len); Size=out_len; } else { Size=SendJpegRect(m_buffer,dest+sz_rfbFramebufferUpdateRectHeader+sz_rfbZlibHeader, rawDataSize, rectW , rectH , m_qualitylevel*10,m_remoteformat); zlibh->nBytes = Swap32IfLE(Size); } transmittedSize += sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader+ Size; return sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader+ Size; }