📄 clientconnectiontight.cpp
字号:
int ClientConnection::InitFilterPalette (int rw, int rh)
{
m_tightCurrentFilter = &ClientConnection::FilterPalette;
m_tightRectWidth = rw;
CARD8 numColors;
ReadExact((char *)&numColors, 1);
m_tightRectColors = (int)numColors;
if (++m_tightRectColors < 2)
return 0;
if (m_myFormat.depth == 24 && m_myFormat.redMax == 0xFF &&
m_myFormat.greenMax == 0xFF && m_myFormat.blueMax == 0xFF) {
CheckBufferSize(m_tightRectColors * 3);
ReadExact(m_netbuf, m_tightRectColors * 3);
for (int i = 0; i < m_tightRectColors; i++)
m_tightPalette[i] = COLOR_FROM_PIXEL24_ADDRESS(&m_netbuf[i*3]);
} else {
CheckBufferSize(m_tightRectColors * (m_myFormat.bitsPerPixel / 8));
ReadExact(m_netbuf, m_tightRectColors * (m_myFormat.bitsPerPixel / 8));
SETUP_COLOR_SHORTCUTS;
int i;
switch (m_myFormat.bitsPerPixel) {
case 8:
for (i = 0; i < m_tightRectColors; i++)
m_tightPalette[i] = COLOR_FROM_PIXEL8_ADDRESS(&m_netbuf[i]);
break;
case 16:
for (i = 0; i < m_tightRectColors; i++)
m_tightPalette[i] = COLOR_FROM_PIXEL16_ADDRESS(&m_netbuf[i*2]);
break;
default:
for (i = 0; i < m_tightRectColors; i++)
m_tightPalette[i] = COLOR_FROM_PIXEL32_ADDRESS(&m_netbuf[i*4]);
}
}
return (m_tightRectColors == 2) ? 1 : 8;
}
//
// Actual filtering code follows.
//
#define DEFINE_TIGHT_FILTER_COPY(bpp) \
\
void ClientConnection::FilterCopy##bpp (int numRows) \
{ \
COLORREF *dst = (COLORREF *)m_zlibbuf; \
\
SETUP_COLOR_SHORTCUTS; \
\
int x; \
for (int y = 0; y < numRows; y++) { \
for (x = 0; x < m_tightRectWidth; x++) { \
dst[y*m_tightRectWidth+x] = \
COLOR_FROM_PIXEL##bpp##_ADDRESS(m_netbuf + \
(y*m_tightRectWidth+x)*(bpp/8)); \
} \
} \
}
DEFINE_TIGHT_FILTER_COPY(8)
DEFINE_TIGHT_FILTER_COPY(16)
DEFINE_TIGHT_FILTER_COPY(24)
DEFINE_TIGHT_FILTER_COPY(32)
#define DEFINE_TIGHT_FILTER_GRADIENT(bpp) \
\
void ClientConnection::FilterGradient##bpp (int numRows) \
{ \
int x, y, c; \
CARD##bpp *src = (CARD##bpp *)m_netbuf; \
COLORREF *dst = (COLORREF *)m_zlibbuf; \
CARD16 *thatRow = (CARD16 *)m_tightPrevRow; \
CARD16 thisRow[2048*3]; \
CARD16 pix[3]; \
CARD16 max[3]; \
int shift[3]; \
int est[3]; \
\
max[0] = m_myFormat.redMax; \
max[1] = m_myFormat.greenMax; \
max[2] = m_myFormat.blueMax; \
\
shift[0] = m_myFormat.redShift; \
shift[1] = m_myFormat.greenShift; \
shift[2] = m_myFormat.blueShift; \
\
for (y = 0; y < numRows; y++) { \
\
/* First pixel in a row */ \
for (c = 0; c < 3; c++) { \
pix[c] = (CARD16)((src[y*m_tightRectWidth] >> shift[c]) + \
thatRow[c] & max[c]); \
thisRow[c] = pix[c]; \
} \
dst[y*m_tightRectWidth] = PALETTERGB((CARD32)pix[0] * 255 / max[0], \
(CARD32)pix[1] * 255 / max[1], \
(CARD32)pix[2] * 255 / max[2]); \
\
/* Remaining pixels of a row */ \
for (x = 1; x < m_tightRectWidth; x++) { \
for (c = 0; c < 3; c++) { \
est[c] = (int)thatRow[x*3+c] + (int)pix[c]-(int)thatRow[(x-1)*3 + c]; \
if (est[c] > (int)max[c]) { \
est[c] = (int)max[c]; \
} else if (est[c] < 0) { \
est[c] = 0; \
} \
pix[c] = (CARD16)((src[y*m_tightRectWidth+x] >> shift[c]) + \
est[c] & max[c]); \
thisRow[x*3+c] = pix[c]; \
} \
dst[y*m_tightRectWidth+x] = PALETTERGB((CARD32)pix[0] * 255 / max[0], \
(CARD32)pix[1] * 255 / max[1], \
(CARD32)pix[2] * 255 / max[2]); \
} \
memcpy(thatRow, thisRow, m_tightRectWidth * 3 * sizeof(CARD16)); \
} \
}
DEFINE_TIGHT_FILTER_GRADIENT(8)
DEFINE_TIGHT_FILTER_GRADIENT(16)
DEFINE_TIGHT_FILTER_GRADIENT(32)
void ClientConnection::FilterGradient24 (int numRows)
{
CARD8 thisRow[2048*3];
CARD8 pix[3];
int est[3];
COLORREF *dst = (COLORREF *)m_zlibbuf;
for (int y = 0; y < numRows; y++) {
// First pixel in a row
for (int c = 0; c < 3; c++) {
pix[c] = m_tightPrevRow[c] + m_netbuf[y*m_tightRectWidth*3+c];
thisRow[c] = pix[c];
}
dst[y*m_tightRectWidth] = COLOR_FROM_PIXEL24_ADDRESS(pix);
// Remaining pixels of a row
for (int x = 1; x < m_tightRectWidth; x++) {
for (int c = 0; c < 3; c++) {
est[c] = (int)m_tightPrevRow[x*3+c] + (int)pix[c] -
(int)m_tightPrevRow[(x-1)*3+c];
if (est[c] > 0xFF) {
est[c] = 0xFF;
} else if (est[c] < 0x00) {
est[c] = 0x00;
}
pix[c] = (CARD8)est[c] + m_netbuf[(y*m_tightRectWidth+x)*3+c];
thisRow[x*3+c] = pix[c];
}
dst[y*m_tightRectWidth+x] = COLOR_FROM_PIXEL24_ADDRESS(pix);
}
memcpy(m_tightPrevRow, thisRow, m_tightRectWidth * 3);
}
}
void ClientConnection::FilterPalette (int numRows)
{
int x, y, b, w;
CARD8 *src = (CARD8 *)m_netbuf;
COLORREF *dst = (COLORREF *)m_zlibbuf;
if (m_tightRectColors == 2) {
w = (m_tightRectWidth + 7) / 8;
for (y = 0; y < numRows; y++) {
for (x = 0; x < m_tightRectWidth / 8; x++) {
for (b = 7; b >= 0; b--)
dst[y*m_tightRectWidth+x*8+7-b] = m_tightPalette[src[y*w+x] >> b & 1];
}
for (b = 7; b >= 8 - m_tightRectWidth % 8; b--) {
dst[y*m_tightRectWidth+x*8+7-b] = m_tightPalette[src[y*w+x] >> b & 1];
}
}
} else {
for (y = 0; y < numRows; y++)
for (x = 0; x < m_tightRectWidth; x++)
dst[y*m_tightRectWidth+x] = m_tightPalette[(int)src[y*m_tightRectWidth+x]];
}
}
//
// JPEG decompression code.
//
static bool jpegError;
static void JpegSetSrcManager(j_decompress_ptr cinfo, char *compressedData,
int compressedLen);
void ClientConnection::DecompressJpegRect(int x, int y, int w, int h)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
int compressedLen = (int)ReadCompactLen();
if (compressedLen <= 0) {
vnclog.Print(0, VNCLOG(_T("Incorrect data received from the server.")));
return;
}
CheckBufferSize(compressedLen);
ReadExact(m_netbuf, compressedLen);
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
JpegSetSrcManager(&cinfo, m_netbuf, compressedLen);
jpeg_read_header(&cinfo, TRUE);
cinfo.out_color_space = JCS_RGB;
jpeg_start_decompress(&cinfo);
if ((int)cinfo.output_width != w || (int)cinfo.output_height != h ||
cinfo.output_components != 3) {
vnclog.Print(0, VNCLOG(_T("Tight Encoding: Wrong JPEG data received.")));
jpeg_destroy_decompress(&cinfo);
return;
}
omni_mutex_lock l(m_bitmapdcMutex);
ObjectSelector b(m_hBitmapDC, m_hBitmap);
PaletteSelector p(m_hBitmapDC, m_hPalette);
// Two scanlines: for 24bit and COLORREF samples
CheckZlibBufferSize(2*2048*4);
JSAMPROW rowPointer[1];
rowPointer[0] = (JSAMPROW)m_zlibbuf;
COLORREF *pixelPtr;
for (int dy = 0; cinfo.output_scanline < cinfo.output_height; dy++) {
jpeg_read_scanlines(&cinfo, rowPointer, 1);
if (jpegError) {
break;
}
pixelPtr = (COLORREF *)&m_zlibbuf[2048*4];
for (int dx = 0; dx < w; dx++) {
*pixelPtr++ = COLOR_FROM_PIXEL24_ADDRESS(&m_zlibbuf[dx*3]);
}
SETPIXELS_NOCONV(&m_zlibbuf[2048*4], x, y + dy, w, 1);
}
if (!jpegError)
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
}
//
// A "Source manager" for the JPEG library.
//
static struct jpeg_source_mgr jpegSrcManager;
static JOCTET *jpegBufferPtr;
static size_t jpegBufferLen;
static void JpegInitSource(j_decompress_ptr cinfo);
static boolean JpegFillInputBuffer(j_decompress_ptr cinfo);
static void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes);
static void JpegTermSource(j_decompress_ptr cinfo);
static void
JpegInitSource(j_decompress_ptr cinfo)
{
jpegError = false;
}
static boolean
JpegFillInputBuffer(j_decompress_ptr cinfo)
{
jpegError = true;
jpegSrcManager.bytes_in_buffer = jpegBufferLen;
jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr;
return TRUE;
}
static void
JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes)
{
if (num_bytes < 0 || (size_t)num_bytes > jpegSrcManager.bytes_in_buffer) {
jpegError = true;
jpegSrcManager.bytes_in_buffer = jpegBufferLen;
jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr;
} else {
jpegSrcManager.next_input_byte += (size_t) num_bytes;
jpegSrcManager.bytes_in_buffer -= (size_t) num_bytes;
}
}
static void
JpegTermSource(j_decompress_ptr cinfo)
{
/* No work necessary here. */
}
static void
JpegSetSrcManager(j_decompress_ptr cinfo, char *compressedData, int compressedLen)
{
jpegBufferPtr = (JOCTET *)compressedData;
jpegBufferLen = (size_t)compressedLen;
jpegSrcManager.init_source = JpegInitSource;
jpegSrcManager.fill_input_buffer = JpegFillInputBuffer;
jpegSrcManager.skip_input_data = JpegSkipInputData;
jpegSrcManager.resync_to_restart = jpeg_resync_to_restart;
jpegSrcManager.term_source = JpegTermSource;
jpegSrcManager.next_input_byte = jpegBufferPtr;
jpegSrcManager.bytes_in_buffer = jpegBufferLen;
cinfo->src = &jpegSrcManager;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -