inline UINT vncEncoder::EncodeRect(BYTE *source,VSocket *outConn, BYTE *dest, const rfb::Rect &rect) { return EncodeRect(source, dest, rect); }
inline UINT vncEncoder::EncodeRect(BYTE *source, boost::shared_ptr<CAbstractStream> outstream /*VSocket *outConn*/, BYTE *dest, const rfb::Rect &rect) { return EncodeRect(source, dest, rect); }
// Tight inline UINT vncEncoder::EncodeRect(BYTE *source, VSocket *outConn, BYTE *dest, const RECT &rect) { rfb::Rect TRect; TRect.br.x = rect.right; TRect.tl.x = rect.left; TRect.tl.y = rect.top; TRect.br.y = rect.bottom; return EncodeRect(source, dest, TRect); }
// Tight inline UINT vncEncoder::EncodeRect(BYTE *source, boost::shared_ptr<CAbstractStream> outstream /*VSocket *outConn*/, BYTE *dest, const RECT &rect) { rfb::Rect TRect; TRect.br.x = rect.right; TRect.tl.x = rect.left; TRect.tl.y = rect.top; TRect.br.y = rect.bottom; return EncodeRect(source, dest, TRect); }
UINT vncEncodeTight::EncodeRect(BYTE *source, VSocket *outConn, BYTE *dest, const RECT &rect, int offx, int offy) { int x = rect.left, y = rect.top; int w = rect.right - x, h = rect.bottom - y; offsetx = offx; offsety = offy; const int maxRectSize = m_conf[m_compresslevel].maxRectSize; const int rawDataSize = maxRectSize * (m_remoteformat.bitsPerPixel / 8); if (m_bufflen < rawDataSize) { if (m_buffer != NULL) delete [] m_buffer; m_buffer = new BYTE [rawDataSize+1]; if (m_buffer == NULL) return vncEncoder::EncodeRect(source, dest, rect, offsetx, offsety); m_bufflen = rawDataSize; } if ( m_remoteformat.depth == 24 && m_remoteformat.redMax == 0xFF && m_remoteformat.greenMax == 0xFF && m_remoteformat.blueMax == 0xFF ) { m_usePixelFormat24 = true; } else { m_usePixelFormat24 = false; } if (!m_use_lastrect || w * h < MIN_SPLIT_RECT_SIZE) return EncodeRectSimple(source, outConn, dest, rect); // Calculate maximum number of rows in one non-solid rectangle. int nMaxRows; { int maxRectSize = m_conf[m_compresslevel].maxRectSize; int maxRectWidth = m_conf[m_compresslevel].maxRectWidth; int nMaxWidth = (w > maxRectWidth) ? maxRectWidth : w; nMaxRows = maxRectSize / nMaxWidth; } // Try to find large solid-color areas and send them separately. CARD32 colorValue; int x_best, y_best, w_best, h_best; int dx, dy, dw, dh; for (dy = y; dy < y + h; dy += MAX_SPLIT_TILE_SIZE) { // If a rectangle becomes too large, send its upper part now. if (dy - y >= nMaxRows) { RECT upperRect; SetRect(&upperRect, x, y, x + w, y + nMaxRows); int size = EncodeRectSimple(source, outConn, dest, upperRect); outConn->SendQueued((char *)dest, size); y += nMaxRows; h -= nMaxRows; } dh = (dy + MAX_SPLIT_TILE_SIZE <= y + h) ? MAX_SPLIT_TILE_SIZE : (y + h - dy); for (dx = x; dx < x + w; dx += MAX_SPLIT_TILE_SIZE) { dw = (dx + MAX_SPLIT_TILE_SIZE <= x + w) ? MAX_SPLIT_TILE_SIZE : (x + w - dx); if (CheckSolidTile(source, dx, dy, dw, dh, &colorValue, FALSE)) { // Get dimensions of solid-color area. FindBestSolidArea(source, dx, dy, w - (dx - x), h - (dy - y), colorValue, &w_best, &h_best); // Make sure a solid rectangle is large enough // (or the whole rectangle is of the same color). if ( w_best * h_best != w * h && w_best * h_best < MIN_SOLID_SUBRECT_SIZE ) continue; // Try to extend solid rectangle to maximum size. x_best = dx; y_best = dy; ExtendSolidArea(source, x, y, w, h, colorValue, &x_best, &y_best, &w_best, &h_best); // Compute dimensions of surrounding rectangles. RECT rects[4]; SetRect(&rects[0], x, y, x + w, y_best); SetRect(&rects[1], x, y_best, x_best, y_best + h_best); SetRect(&rects[2], x_best + w_best, y_best, x + w, y_best + h_best); SetRect(&rects[3], x, y_best + h_best, x + w, y + h); // Send solid-color area and surrounding rectangles. for (int i = 0; i < 4; i++) { if (i == 2) { RECT onePixel; SetRect(&onePixel, x_best, y_best, x_best + 1, y_best + 1); Translate(source, m_buffer, onePixel); SendTightHeader(x_best, y_best, w_best, h_best); int size = SendSolidRect(dest); outConn->SendQueued((char *)m_hdrBuffer, m_hdrBufferBytes); outConn->SendQueued((char *)dest, size); encodedSize += (m_hdrBufferBytes + size - sz_rfbFramebufferUpdateRectHeader); transmittedSize += (m_hdrBufferBytes + size); } if ( rects[i].left == rects[i].right || rects[i].top == rects[i].bottom ) { continue; } int size = EncodeRect(source, outConn, dest, rects[i], offsetx, offsety); outConn->SendQueued((char *)dest, size); } // Return after all recursive calls done (0 == data sent). return 0; } } } // No suitable solid-color rectangles found. return EncodeRectSimple(source, outConn, dest, rect); }
// Encode a rectangle directly to the output stream. // This implementation may not be the best, but it will work with all // of the existing EncodeRect(BYTE *, BYTE *, const RECT &) implementations. // Note, that the returned value is that of any data in the dest buffer that // was not yet transmitted on the outConn. // The primary justification for adding this method is to allow encodings to // transmit partial data during the encoding process. This can improve // performance considerably for slower (more complex) encoding algorithms. inline UINT vncEncoder::EncodeRect(BYTE *source, VSocket *outConn, BYTE *dest, const RECT &rect, int offsetx, int offsety) { return EncodeRect(source, dest, rect, offsetx, offsety); }