From 669b4c86855cc11a8904f4acb4039a14b91cbf6d Mon Sep 17 00:00:00 2001 From: dscho Date: Mon, 23 May 2005 19:26:12 +0000 Subject: [PATCH] make zlib and tight handling thread safe (static -> rfbClient) --- libvncclient/rfbproto.c | 129 ----------------------- libvncclient/tight.c | 214 +++++++++++++++++++++++++++------------ libvncclient/vncviewer.c | 9 ++ libvncclient/zlib.c | 44 ++++---- rfb/rfbclient.h | 44 ++++++++ 5 files changed, 226 insertions(+), 214 deletions(-) diff --git a/libvncclient/rfbproto.c b/libvncclient/rfbproto.c index 211a478..dd5d961 100644 --- a/libvncclient/rfbproto.c +++ b/libvncclient/rfbproto.c @@ -166,48 +166,6 @@ static void JpegSetSrcManager(j_decompress_ptr cinfo, uint8_t *compressedData, #endif #endif -/* The zlib encoding requires expansion/decompression/deflation of the - compressed data in the "buffer" above into another, result buffer. - However, the size of the result buffer can be determined precisely - based on the bitsPerPixel, height and width of the rectangle. We - allocate this buffer one time to be the full size of the buffer. */ - -#ifdef LIBVNCSERVER_HAVE_LIBZ -static int raw_buffer_size = -1; -static char *raw_buffer; - -static z_stream decompStream; -static rfbBool decompStreamInited = FALSE; - -#endif - - -#ifdef LIBVNCSERVER_HAVE_LIBJPEG -/* - * Variables for the ``tight'' encoding implementation. - */ - -/* Separate buffer for compressed data. */ -/* TODO: threading issues */ -#define ZLIB_BUFFER_SIZE 30000 -static char zlib_buffer[ZLIB_BUFFER_SIZE]; - -/* Four independent compression streams for zlib library. */ -static z_stream zlibStream[4]; -static rfbBool zlibStreamActive[4] = { - FALSE, FALSE, FALSE, FALSE -}; - -/* Filter stuff. Should be initialized by filter initialization code. */ -static rfbBool cutZeros; -static int rectWidth, rectColors; -static char tightPalette[256*4]; -static uint8_t tightPrevRow[2048*3*sizeof(uint16_t)]; - -/* JPEG decoder state. */ -static rfbBool jpegError; -#endif - /* * ConnectToRFBServer. */ @@ -1060,93 +1018,6 @@ PrintPixelFormat(rfbPixelFormat *format) } } -#ifdef LIBVNCSERVER_HAVE_LIBJPEG - -static long -ReadCompactLen (rfbClient* client) -{ - long len; - uint8_t b; - - if (!ReadFromRFBServer(client, (char *)&b, 1)) - return -1; - len = (int)b & 0x7F; - if (b & 0x80) { - if (!ReadFromRFBServer(client, (char *)&b, 1)) - return -1; - len |= ((int)b & 0x7F) << 7; - if (b & 0x80) { - if (!ReadFromRFBServer(client, (char *)&b, 1)) - return -1; - len |= ((int)b & 0xFF) << 14; - } - } - return len; -} - -/* - * JPEG source manager functions for JPEG decompression in Tight decoder. - */ - -static struct jpeg_source_mgr jpegSrcManager; -static JOCTET *jpegBufferPtr; -static size_t jpegBufferLen; - -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 || 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, uint8_t *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; -} - -#endif - /* avoid name clashes with LibVNCServer */ #define rfbEncryptBytes rfbClientEncryptBytes diff --git a/libvncclient/tight.c b/libvncclient/tight.c index 6bcb905..4819b5b 100644 --- a/libvncclient/tight.c +++ b/libvncclient/tight.c @@ -104,11 +104,11 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) /* Flush zlib streams if we are told by the server to do so. */ for (stream_id = 0; stream_id < 4; stream_id++) { - if ((comp_ctl & 1) && zlibStreamActive[stream_id]) { - if (inflateEnd (&zlibStream[stream_id]) != Z_OK && - zlibStream[stream_id].msg != NULL) - rfbClientLog("inflateEnd: %s\n", zlibStream[stream_id].msg); - zlibStreamActive[stream_id] = FALSE; + if ((comp_ctl & 1) && client->zlibStreamActive[stream_id]) { + if (inflateEnd (&client->zlibStream[stream_id]) != Z_OK && + client->zlibStream[stream_id].msg != NULL) + rfbClientLog("inflateEnd: %s\n", client->zlibStream[stream_id].msg); + client->zlibStreamActive[stream_id] = FALSE; } comp_ctl >>= 1; } @@ -211,8 +211,8 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) /* Now let's initialize compression stream if needed. */ stream_id = comp_ctl & 0x03; - zs = &zlibStream[stream_id]; - if (!zlibStreamActive[stream_id]) { + zs = &client->zlibStream[stream_id]; + if (!client->zlibStreamActive[stream_id]) { zs->zalloc = Z_NULL; zs->zfree = Z_NULL; zs->opaque = Z_NULL; @@ -222,7 +222,7 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) rfbClientLog("InflateInit error: %s.\n", zs->msg); return FALSE; } - zlibStreamActive[stream_id] = TRUE; + client->zlibStreamActive[stream_id] = TRUE; } /* Read, decode and draw actual pixel data in a loop. */ @@ -244,12 +244,12 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) else portionLen = compressedLen; - if (!ReadFromRFBServer(client, (char*)zlib_buffer, portionLen)) + if (!ReadFromRFBServer(client, (char*)client->zlib_buffer, portionLen)) return FALSE; compressedLen -= portionLen; - zs->next_in = (Bytef *)zlib_buffer; + zs->next_in = (Bytef *)client->zlib_buffer; zs->avail_in = portionLen; do { @@ -308,15 +308,15 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) static int InitFilterCopyBPP (rfbClient* client, int rw, int rh) { - rectWidth = rw; + client->rectWidth = rw; #if BPP == 32 if (client->format.depth == 24 && client->format.redMax == 0xFF && client->format.greenMax == 0xFF && client->format.blueMax == 0xFF) { - cutZeros = TRUE; + client->cutZeros = TRUE; return 24; } else { - cutZeros = FALSE; + client->cutZeros = FALSE; } #endif @@ -330,20 +330,20 @@ FilterCopyBPP (rfbClient* client, int numRows, CARDBPP *dst) #if BPP == 32 int x, y; - if (cutZeros) { + if (client->cutZeros) { for (y = 0; y < numRows; y++) { - for (x = 0; x < rectWidth; x++) { - dst[y*rectWidth+x] = - RGB24_TO_PIXEL32(client->buffer[(y*rectWidth+x)*3], - client->buffer[(y*rectWidth+x)*3+1], - client->buffer[(y*rectWidth+x)*3+2]); + for (x = 0; x < client->rectWidth; x++) { + dst[y*client->rectWidth+x] = + RGB24_TO_PIXEL32(client->buffer[(y*client->rectWidth+x)*3], + client->buffer[(y*client->rectWidth+x)*3+1], + client->buffer[(y*client->rectWidth+x)*3+2]); } } return; } #endif - memcpy (dst, client->buffer, numRows * rectWidth * (BPP / 8)); + memcpy (dst, client->buffer, numRows * client->rectWidth * (BPP / 8)); } static int @@ -352,10 +352,10 @@ InitFilterGradientBPP (rfbClient* client, int rw, int rh) int bits; bits = InitFilterCopyBPP(client, rw, rh); - if (cutZeros) - memset(tightPrevRow, 0, rw * 3); + if (client->cutZeros) + memset(client->tightPrevRow, 0, rw * 3); else - memset(tightPrevRow, 0, rw * 3 * sizeof(uint16_t)); + memset(client->tightPrevRow, 0, rw * 3 * sizeof(uint16_t)); return bits; } @@ -374,28 +374,28 @@ FilterGradient24 (rfbClient* client, int numRows, uint32_t *dst) /* First pixel in a row */ for (c = 0; c < 3; c++) { - pix[c] = tightPrevRow[c] + client->buffer[y*rectWidth*3+c]; + pix[c] = client->tightPrevRow[c] + client->buffer[y*client->rectWidth*3+c]; thisRow[c] = pix[c]; } - dst[y*rectWidth] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]); + dst[y*client->rectWidth] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]); /* Remaining pixels of a row */ - for (x = 1; x < rectWidth; x++) { + for (x = 1; x < client->rectWidth; x++) { for (c = 0; c < 3; c++) { - est[c] = (int)tightPrevRow[x*3+c] + (int)pix[c] - - (int)tightPrevRow[(x-1)*3+c]; + est[c] = (int)client->tightPrevRow[x*3+c] + (int)pix[c] - + (int)client->tightPrevRow[(x-1)*3+c]; if (est[c] > 0xFF) { est[c] = 0xFF; } else if (est[c] < 0x00) { est[c] = 0x00; } - pix[c] = (uint8_t)est[c] + client->buffer[(y*rectWidth+x)*3+c]; + pix[c] = (uint8_t)est[c] + client->buffer[(y*client->rectWidth+x)*3+c]; thisRow[x*3+c] = pix[c]; } - dst[y*rectWidth+x] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]); + dst[y*client->rectWidth+x] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]); } - memcpy(tightPrevRow, thisRow, rectWidth * 3); + memcpy(client->tightPrevRow, thisRow, client->rectWidth * 3); } } @@ -406,7 +406,7 @@ FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *dst) { int x, y, c; CARDBPP *src = (CARDBPP *)client->buffer; - uint16_t *thatRow = (uint16_t *)tightPrevRow; + uint16_t *thatRow = (uint16_t *)client->tightPrevRow; uint16_t thisRow[2048*3]; uint16_t pix[3]; uint16_t max[3]; @@ -414,7 +414,7 @@ FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *dst) int est[3]; #if BPP == 32 - if (cutZeros) { + if (client->cutZeros) { FilterGradient24(client, numRows, dst); return; } @@ -432,13 +432,13 @@ FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *dst) /* First pixel in a row */ for (c = 0; c < 3; c++) { - pix[c] = (uint16_t)(((src[y*rectWidth] >> shift[c]) + thatRow[c]) & max[c]); + pix[c] = (uint16_t)(((src[y*client->rectWidth] >> shift[c]) + thatRow[c]) & max[c]); thisRow[c] = pix[c]; } - dst[y*rectWidth] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]); + dst[y*client->rectWidth] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]); /* Remaining pixels of a row */ - for (x = 1; x < rectWidth; x++) { + for (x = 1; x < client->rectWidth; 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]) { @@ -446,12 +446,12 @@ FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *dst) } else if (est[c] < 0) { est[c] = 0; } - pix[c] = (uint16_t)(((src[y*rectWidth+x] >> shift[c]) + est[c]) & max[c]); + pix[c] = (uint16_t)(((src[y*client->rectWidth+x] >> shift[c]) + est[c]) & max[c]); thisRow[x*3+c] = pix[c]; } - dst[y*rectWidth+x] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]); + dst[y*client->rectWidth+x] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]); } - memcpy(thatRow, thisRow, rectWidth * 3 * sizeof(uint16_t)); + memcpy(thatRow, thisRow, client->rectWidth * 3 * sizeof(uint16_t)); } } @@ -461,36 +461,36 @@ InitFilterPaletteBPP (rfbClient* client, int rw, int rh) uint8_t numColors; #if BPP == 32 int i; - CARDBPP *palette = (CARDBPP *)tightPalette; + CARDBPP *palette = (CARDBPP *)client->tightPalette; #endif - rectWidth = rw; + client->rectWidth = rw; if (!ReadFromRFBServer(client, (char*)&numColors, 1)) return 0; - rectColors = (int)numColors; - if (++rectColors < 2) + client->rectColors = (int)numColors; + if (++client->rectColors < 2) return 0; #if BPP == 32 if (client->format.depth == 24 && client->format.redMax == 0xFF && client->format.greenMax == 0xFF && client->format.blueMax == 0xFF) { - if (!ReadFromRFBServer(client, (char*)&tightPalette, rectColors * 3)) + if (!ReadFromRFBServer(client, (char*)&client->tightPalette, client->rectColors * 3)) return 0; - for (i = rectColors - 1; i >= 0; i--) { - palette[i] = RGB24_TO_PIXEL32(tightPalette[i*3], - tightPalette[i*3+1], - tightPalette[i*3+2]); + for (i = client->rectColors - 1; i >= 0; i--) { + palette[i] = RGB24_TO_PIXEL32(client->tightPalette[i*3], + client->tightPalette[i*3+1], + client->tightPalette[i*3+2]); } - return (rectColors == 2) ? 1 : 8; + return (client->rectColors == 2) ? 1 : 8; } #endif - if (!ReadFromRFBServer(client, (char*)&tightPalette, rectColors * (BPP / 8))) + if (!ReadFromRFBServer(client, (char*)&client->tightPalette, client->rectColors * (BPP / 8))) return 0; - return (rectColors == 2) ? 1 : 8; + return (client->rectColors == 2) ? 1 : 8; } static void @@ -498,23 +498,23 @@ FilterPaletteBPP (rfbClient* client, int numRows, CARDBPP *dst) { int x, y, b, w; uint8_t *src = (uint8_t *)client->buffer; - CARDBPP *palette = (CARDBPP *)tightPalette; + CARDBPP *palette = (CARDBPP *)client->tightPalette; - if (rectColors == 2) { - w = (rectWidth + 7) / 8; + if (client->rectColors == 2) { + w = (client->rectWidth + 7) / 8; for (y = 0; y < numRows; y++) { - for (x = 0; x < rectWidth / 8; x++) { + for (x = 0; x < client->rectWidth / 8; x++) { for (b = 7; b >= 0; b--) - dst[y*rectWidth+x*8+7-b] = palette[src[y*w+x] >> b & 1]; + dst[y*client->rectWidth+x*8+7-b] = palette[src[y*w+x] >> b & 1]; } - for (b = 7; b >= 8 - rectWidth % 8; b--) { - dst[y*rectWidth+x*8+7-b] = palette[src[y*w+x] >> b & 1]; + for (b = 7; b >= 8 - client->rectWidth % 8; b--) { + dst[y*client->rectWidth+x*8+7-b] = palette[src[y*w+x] >> b & 1]; } } } else { for (y = 0; y < numRows; y++) - for (x = 0; x < rectWidth; x++) - dst[y*rectWidth+x] = palette[(int)src[y*rectWidth+x]]; + for (x = 0; x < client->rectWidth; x++) + dst[y*client->rectWidth+x] = palette[(int)src[y*client->rectWidth+x]]; } } @@ -563,6 +563,7 @@ DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h) } cinfo.err = jpeg_std_error(&jerr); + cinfo.client_data = client; jpeg_create_decompress(&cinfo); JpegSetSrcManager(&cinfo, compressedData, compressedLen); @@ -583,7 +584,7 @@ DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h) dy = 0; while (cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo, rowPointer, 1); - if (jpegError) { + if (client->jpegError) { break; } pixelPtr = (CARDBPP *)&client->buffer[RFB_BUFFER_SIZE / 2]; @@ -595,13 +596,100 @@ DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h) dy++; } - if (!jpegError) + if (!client->jpegError) jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); free(compressedData); - return !jpegError; + return !client->jpegError; +} + +#else + +static long +ReadCompactLen (rfbClient* client) +{ + long len; + uint8_t b; + + if (!ReadFromRFBServer(client, (char *)&b, 1)) + return -1; + len = (int)b & 0x7F; + if (b & 0x80) { + if (!ReadFromRFBServer(client, (char *)&b, 1)) + return -1; + len |= ((int)b & 0x7F) << 7; + if (b & 0x80) { + if (!ReadFromRFBServer(client, (char *)&b, 1)) + return -1; + len |= ((int)b & 0xFF) << 14; + } + } + return len; +} + +/* + * JPEG source manager functions for JPEG decompression in Tight decoder. + */ + +static void +JpegInitSource(j_decompress_ptr cinfo) +{ + rfbClient* client=(rfbClient*)cinfo->client_data; + client->jpegError = FALSE; + client->jpegSrcManager = malloc(sizeof(struct jpeg_source_mgr)); +} + +static boolean +JpegFillInputBuffer(j_decompress_ptr cinfo) +{ + rfbClient* client=(rfbClient*)cinfo->client_data; + client->jpegError = TRUE; + client->jpegSrcManager->bytes_in_buffer = client->jpegBufferLen; + client->jpegSrcManager->next_input_byte = (JOCTET *)client->jpegBufferPtr; + + return TRUE; +} + +static void +JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes) +{ + rfbClient* client=(rfbClient*)cinfo->client_data; + if (num_bytes < 0 || num_bytes > client->jpegSrcManager->bytes_in_buffer) { + client->jpegError = TRUE; + client->jpegSrcManager->bytes_in_buffer = client->jpegBufferLen; + client->jpegSrcManager->next_input_byte = (JOCTET *)client->jpegBufferPtr; + } else { + client->jpegSrcManager->next_input_byte += (size_t) num_bytes; + client->jpegSrcManager->bytes_in_buffer -= (size_t) num_bytes; + } +} + +static void +JpegTermSource(j_decompress_ptr cinfo) +{ + /* nothing to do here. */ +} + +static void +JpegSetSrcManager(j_decompress_ptr cinfo, + uint8_t *compressedData, + int compressedLen) +{ + rfbClient* client=(rfbClient*)cinfo->client_data; + client->jpegBufferPtr = compressedData; + client->jpegBufferLen = (size_t)compressedLen; + + client->jpegSrcManager->init_source = JpegInitSource; + client->jpegSrcManager->fill_input_buffer = JpegFillInputBuffer; + client->jpegSrcManager->skip_input_data = JpegSkipInputData; + client->jpegSrcManager->resync_to_restart = jpeg_resync_to_restart; + client->jpegSrcManager->term_source = JpegTermSource; + client->jpegSrcManager->next_input_byte = (JOCTET*)client->jpegBufferPtr; + client->jpegSrcManager->bytes_in_buffer = client->jpegBufferLen; + + cinfo->src = client->jpegSrcManager; } #endif diff --git a/libvncclient/vncviewer.c b/libvncclient/vncviewer.c index 87c708d..2927b74 100644 --- a/libvncclient/vncviewer.c +++ b/libvncclient/vncviewer.c @@ -154,6 +154,15 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel, client->bufoutptr=client->buf; client->buffered=0; +#ifdef LIBVNCSERVER_HAVE_LIBZ + client->raw_buffer_size = -1; + client->decompStreamInited = FALSE; +#endif + +#ifdef LIBVNCSERVER_HAVE_LIBJPEG + memset(client->zlibStreamActive,0,sizeof(rfbBool)*4); +#endif + client->HandleCursorPos = DummyPoint; client->SoftCursorLockArea = DummyRect; client->SoftCursorUnlockScreen = Dummy; diff --git a/libvncclient/zlib.c b/libvncclient/zlib.c index ec371be..2a32d1c 100644 --- a/libvncclient/zlib.c +++ b/libvncclient/zlib.c @@ -46,16 +46,16 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh) * buffer, this buffer allocation should only happen once, on the * first update. */ - if ( raw_buffer_size < (( rw * rh ) * ( BPP / 8 ))) { + if ( client->raw_buffer_size < (( rw * rh ) * ( BPP / 8 ))) { - if ( raw_buffer != NULL ) { + if ( client->raw_buffer != NULL ) { - free( raw_buffer ); + free( client->raw_buffer ); } - raw_buffer_size = (( rw * rh ) * ( BPP / 8 )); - raw_buffer = (char*) malloc( raw_buffer_size ); + client->raw_buffer_size = (( rw * rh ) * ( BPP / 8 )); + client->raw_buffer = (char*) malloc( client->raw_buffer_size ); } @@ -65,26 +65,26 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh) remaining = rfbClientSwap32IfLE(hdr.nBytes); /* Need to initialize the decompressor state. */ - decompStream.next_in = ( Bytef * )client->buffer; - decompStream.avail_in = 0; - decompStream.next_out = ( Bytef * )raw_buffer; - decompStream.avail_out = raw_buffer_size; - decompStream.data_type = Z_BINARY; + client->decompStream.next_in = ( Bytef * )client->buffer; + client->decompStream.avail_in = 0; + client->decompStream.next_out = ( Bytef * )client->raw_buffer; + client->decompStream.avail_out = client->raw_buffer_size; + client->decompStream.data_type = Z_BINARY; /* Initialize the decompression stream structures on the first invocation. */ - if ( decompStreamInited == FALSE ) { + if ( client->decompStreamInited == FALSE ) { - inflateResult = inflateInit( &decompStream ); + inflateResult = inflateInit( &client->decompStream ); if ( inflateResult != Z_OK ) { rfbClientLog( "inflateInit returned error: %d, msg: %s\n", inflateResult, - decompStream.msg); + client->decompStream.msg); return FALSE; } - decompStreamInited = TRUE; + client->decompStreamInited = TRUE; } @@ -107,11 +107,11 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh) if (!ReadFromRFBServer(client, client->buffer,toRead)) return FALSE; - decompStream.next_in = ( Bytef * )client->buffer; - decompStream.avail_in = toRead; + client->decompStream.next_in = ( Bytef * )client->buffer; + client->decompStream.avail_in = toRead; /* Need to uncompress buffer full. */ - inflateResult = inflate( &decompStream, Z_SYNC_FLUSH ); + inflateResult = inflate( &client->decompStream, Z_SYNC_FLUSH ); /* We never supply a dictionary for compression. */ if ( inflateResult == Z_NEED_DICT ) { @@ -122,15 +122,15 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh) rfbClientLog( "zlib inflate returned error: %d, msg: %s\n", inflateResult, - decompStream.msg); + client->decompStream.msg); return FALSE; } /* Result buffer allocated to be at least large enough. We should * never run out of space! */ - if (( decompStream.avail_in > 0 ) && - ( decompStream.avail_out <= 0 )) { + if (( client->decompStream.avail_in > 0 ) && + ( client->decompStream.avail_out <= 0 )) { rfbClientLog("zlib inflate ran out of space!\n"); return FALSE; } @@ -142,14 +142,14 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh) if ( inflateResult == Z_OK ) { /* Put the uncompressed contents of the update on the screen. */ - CopyRectangle(client, raw_buffer, rx, ry, rw, rh); + CopyRectangle(client, client->raw_buffer, rx, ry, rw, rh); } else { rfbClientLog( "zlib inflate returned error: %d, msg: %s\n", inflateResult, - decompStream.msg); + client->decompStream.msg); return FALSE; } diff --git a/rfb/rfbclient.h b/rfb/rfbclient.h index b094ce2..5d34526 100644 --- a/rfb/rfbclient.h +++ b/rfb/rfbclient.h @@ -132,6 +132,50 @@ typedef struct _rfbClient { char *bufoutptr; int buffered; + /* The zlib encoding requires expansion/decompression/deflation of the + compressed data in the "buffer" above into another, result buffer. + However, the size of the result buffer can be determined precisely + based on the bitsPerPixel, height and width of the rectangle. We + allocate this buffer one time to be the full size of the buffer. */ + +#ifdef LIBVNCSERVER_HAVE_LIBZ + int raw_buffer_size; + char *raw_buffer; + + z_stream decompStream; + rfbBool decompStreamInited; + +#endif + + +#ifdef LIBVNCSERVER_HAVE_LIBJPEG + /* + * Variables for the ``tight'' encoding implementation. + */ + + /* Separate buffer for compressed data. */ +#define ZLIB_BUFFER_SIZE 30000 + char zlib_buffer[ZLIB_BUFFER_SIZE]; + + /* Four independent compression streams for zlib library. */ + z_stream zlibStream[4]; + rfbBool zlibStreamActive[4]; + + /* Filter stuff. Should be initialized by filter initialization code. */ + rfbBool cutZeros; + int rectWidth, rectColors; + char tightPalette[256*4]; + uint8_t tightPrevRow[2048*3*sizeof(uint16_t)]; + + /* JPEG decoder state. */ + rfbBool jpegError; + + struct jpeg_source_mgr* jpegSrcManager; + void* jpegBufferPtr; + size_t jpegBufferLen; + +#endif + /* cursor.c */ uint8_t *rcSource, *rcMask;