Commit 669b4c86 authored by dscho's avatar dscho

make zlib and tight handling thread safe (static -> rfbClient)

parent dc1094f0
...@@ -166,48 +166,6 @@ static void JpegSetSrcManager(j_decompress_ptr cinfo, uint8_t *compressedData, ...@@ -166,48 +166,6 @@ static void JpegSetSrcManager(j_decompress_ptr cinfo, uint8_t *compressedData,
#endif #endif
#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. * ConnectToRFBServer.
*/ */
...@@ -1060,93 +1018,6 @@ PrintPixelFormat(rfbPixelFormat *format) ...@@ -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 */ /* avoid name clashes with LibVNCServer */
#define rfbEncryptBytes rfbClientEncryptBytes #define rfbEncryptBytes rfbClientEncryptBytes
......
...@@ -104,11 +104,11 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) ...@@ -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. */ /* Flush zlib streams if we are told by the server to do so. */
for (stream_id = 0; stream_id < 4; stream_id++) { for (stream_id = 0; stream_id < 4; stream_id++) {
if ((comp_ctl & 1) && zlibStreamActive[stream_id]) { if ((comp_ctl & 1) && client->zlibStreamActive[stream_id]) {
if (inflateEnd (&zlibStream[stream_id]) != Z_OK && if (inflateEnd (&client->zlibStream[stream_id]) != Z_OK &&
zlibStream[stream_id].msg != NULL) client->zlibStream[stream_id].msg != NULL)
rfbClientLog("inflateEnd: %s\n", zlibStream[stream_id].msg); rfbClientLog("inflateEnd: %s\n", client->zlibStream[stream_id].msg);
zlibStreamActive[stream_id] = FALSE; client->zlibStreamActive[stream_id] = FALSE;
} }
comp_ctl >>= 1; comp_ctl >>= 1;
} }
...@@ -211,8 +211,8 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) ...@@ -211,8 +211,8 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh)
/* Now let's initialize compression stream if needed. */ /* Now let's initialize compression stream if needed. */
stream_id = comp_ctl & 0x03; stream_id = comp_ctl & 0x03;
zs = &zlibStream[stream_id]; zs = &client->zlibStream[stream_id];
if (!zlibStreamActive[stream_id]) { if (!client->zlibStreamActive[stream_id]) {
zs->zalloc = Z_NULL; zs->zalloc = Z_NULL;
zs->zfree = Z_NULL; zs->zfree = Z_NULL;
zs->opaque = Z_NULL; zs->opaque = Z_NULL;
...@@ -222,7 +222,7 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) ...@@ -222,7 +222,7 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh)
rfbClientLog("InflateInit error: %s.\n", zs->msg); rfbClientLog("InflateInit error: %s.\n", zs->msg);
return FALSE; return FALSE;
} }
zlibStreamActive[stream_id] = TRUE; client->zlibStreamActive[stream_id] = TRUE;
} }
/* Read, decode and draw actual pixel data in a loop. */ /* 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) ...@@ -244,12 +244,12 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh)
else else
portionLen = compressedLen; portionLen = compressedLen;
if (!ReadFromRFBServer(client, (char*)zlib_buffer, portionLen)) if (!ReadFromRFBServer(client, (char*)client->zlib_buffer, portionLen))
return FALSE; return FALSE;
compressedLen -= portionLen; compressedLen -= portionLen;
zs->next_in = (Bytef *)zlib_buffer; zs->next_in = (Bytef *)client->zlib_buffer;
zs->avail_in = portionLen; zs->avail_in = portionLen;
do { do {
...@@ -308,15 +308,15 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) ...@@ -308,15 +308,15 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh)
static int static int
InitFilterCopyBPP (rfbClient* client, int rw, int rh) InitFilterCopyBPP (rfbClient* client, int rw, int rh)
{ {
rectWidth = rw; client->rectWidth = rw;
#if BPP == 32 #if BPP == 32
if (client->format.depth == 24 && client->format.redMax == 0xFF && if (client->format.depth == 24 && client->format.redMax == 0xFF &&
client->format.greenMax == 0xFF && client->format.blueMax == 0xFF) { client->format.greenMax == 0xFF && client->format.blueMax == 0xFF) {
cutZeros = TRUE; client->cutZeros = TRUE;
return 24; return 24;
} else { } else {
cutZeros = FALSE; client->cutZeros = FALSE;
} }
#endif #endif
...@@ -330,20 +330,20 @@ FilterCopyBPP (rfbClient* client, int numRows, CARDBPP *dst) ...@@ -330,20 +330,20 @@ FilterCopyBPP (rfbClient* client, int numRows, CARDBPP *dst)
#if BPP == 32 #if BPP == 32
int x, y; int x, y;
if (cutZeros) { if (client->cutZeros) {
for (y = 0; y < numRows; y++) { for (y = 0; y < numRows; y++) {
for (x = 0; x < rectWidth; x++) { for (x = 0; x < client->rectWidth; x++) {
dst[y*rectWidth+x] = dst[y*client->rectWidth+x] =
RGB24_TO_PIXEL32(client->buffer[(y*rectWidth+x)*3], RGB24_TO_PIXEL32(client->buffer[(y*client->rectWidth+x)*3],
client->buffer[(y*rectWidth+x)*3+1], client->buffer[(y*client->rectWidth+x)*3+1],
client->buffer[(y*rectWidth+x)*3+2]); client->buffer[(y*client->rectWidth+x)*3+2]);
} }
} }
return; return;
} }
#endif #endif
memcpy (dst, client->buffer, numRows * rectWidth * (BPP / 8)); memcpy (dst, client->buffer, numRows * client->rectWidth * (BPP / 8));
} }
static int static int
...@@ -352,10 +352,10 @@ InitFilterGradientBPP (rfbClient* client, int rw, int rh) ...@@ -352,10 +352,10 @@ InitFilterGradientBPP (rfbClient* client, int rw, int rh)
int bits; int bits;
bits = InitFilterCopyBPP(client, rw, rh); bits = InitFilterCopyBPP(client, rw, rh);
if (cutZeros) if (client->cutZeros)
memset(tightPrevRow, 0, rw * 3); memset(client->tightPrevRow, 0, rw * 3);
else else
memset(tightPrevRow, 0, rw * 3 * sizeof(uint16_t)); memset(client->tightPrevRow, 0, rw * 3 * sizeof(uint16_t));
return bits; return bits;
} }
...@@ -374,28 +374,28 @@ FilterGradient24 (rfbClient* client, int numRows, uint32_t *dst) ...@@ -374,28 +374,28 @@ FilterGradient24 (rfbClient* client, int numRows, uint32_t *dst)
/* First pixel in a row */ /* First pixel in a row */
for (c = 0; c < 3; c++) { 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]; 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 */ /* Remaining pixels of a row */
for (x = 1; x < rectWidth; x++) { for (x = 1; x < client->rectWidth; x++) {
for (c = 0; c < 3; c++) { for (c = 0; c < 3; c++) {
est[c] = (int)tightPrevRow[x*3+c] + (int)pix[c] - est[c] = (int)client->tightPrevRow[x*3+c] + (int)pix[c] -
(int)tightPrevRow[(x-1)*3+c]; (int)client->tightPrevRow[(x-1)*3+c];
if (est[c] > 0xFF) { if (est[c] > 0xFF) {
est[c] = 0xFF; est[c] = 0xFF;
} else if (est[c] < 0x00) { } else if (est[c] < 0x00) {
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]; 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) ...@@ -406,7 +406,7 @@ FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *dst)
{ {
int x, y, c; int x, y, c;
CARDBPP *src = (CARDBPP *)client->buffer; 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 thisRow[2048*3];
uint16_t pix[3]; uint16_t pix[3];
uint16_t max[3]; uint16_t max[3];
...@@ -414,7 +414,7 @@ FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *dst) ...@@ -414,7 +414,7 @@ FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *dst)
int est[3]; int est[3];
#if BPP == 32 #if BPP == 32
if (cutZeros) { if (client->cutZeros) {
FilterGradient24(client, numRows, dst); FilterGradient24(client, numRows, dst);
return; return;
} }
...@@ -432,13 +432,13 @@ FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *dst) ...@@ -432,13 +432,13 @@ FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *dst)
/* First pixel in a row */ /* First pixel in a row */
for (c = 0; c < 3; c++) { 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]; 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 */ /* Remaining pixels of a row */
for (x = 1; x < rectWidth; x++) { for (x = 1; x < client->rectWidth; x++) {
for (c = 0; c < 3; c++) { for (c = 0; c < 3; c++) {
est[c] = (int)thatRow[x*3+c] + (int)pix[c] - (int)thatRow[(x-1)*3+c]; est[c] = (int)thatRow[x*3+c] + (int)pix[c] - (int)thatRow[(x-1)*3+c];
if (est[c] > (int)max[c]) { if (est[c] > (int)max[c]) {
...@@ -446,12 +446,12 @@ FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *dst) ...@@ -446,12 +446,12 @@ FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *dst)
} else if (est[c] < 0) { } else if (est[c] < 0) {
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]; 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) ...@@ -461,36 +461,36 @@ InitFilterPaletteBPP (rfbClient* client, int rw, int rh)
uint8_t numColors; uint8_t numColors;
#if BPP == 32 #if BPP == 32
int i; int i;
CARDBPP *palette = (CARDBPP *)tightPalette; CARDBPP *palette = (CARDBPP *)client->tightPalette;
#endif #endif
rectWidth = rw; client->rectWidth = rw;
if (!ReadFromRFBServer(client, (char*)&numColors, 1)) if (!ReadFromRFBServer(client, (char*)&numColors, 1))
return 0; return 0;
rectColors = (int)numColors; client->rectColors = (int)numColors;
if (++rectColors < 2) if (++client->rectColors < 2)
return 0; return 0;
#if BPP == 32 #if BPP == 32
if (client->format.depth == 24 && client->format.redMax == 0xFF && if (client->format.depth == 24 && client->format.redMax == 0xFF &&
client->format.greenMax == 0xFF && client->format.blueMax == 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; return 0;
for (i = rectColors - 1; i >= 0; i--) { for (i = client->rectColors - 1; i >= 0; i--) {
palette[i] = RGB24_TO_PIXEL32(tightPalette[i*3], palette[i] = RGB24_TO_PIXEL32(client->tightPalette[i*3],
tightPalette[i*3+1], client->tightPalette[i*3+1],
tightPalette[i*3+2]); client->tightPalette[i*3+2]);
} }
return (rectColors == 2) ? 1 : 8; return (client->rectColors == 2) ? 1 : 8;
} }
#endif #endif
if (!ReadFromRFBServer(client, (char*)&tightPalette, rectColors * (BPP / 8))) if (!ReadFromRFBServer(client, (char*)&client->tightPalette, client->rectColors * (BPP / 8)))
return 0; return 0;
return (rectColors == 2) ? 1 : 8; return (client->rectColors == 2) ? 1 : 8;
} }
static void static void
...@@ -498,23 +498,23 @@ FilterPaletteBPP (rfbClient* client, int numRows, CARDBPP *dst) ...@@ -498,23 +498,23 @@ FilterPaletteBPP (rfbClient* client, int numRows, CARDBPP *dst)
{ {
int x, y, b, w; int x, y, b, w;
uint8_t *src = (uint8_t *)client->buffer; uint8_t *src = (uint8_t *)client->buffer;
CARDBPP *palette = (CARDBPP *)tightPalette; CARDBPP *palette = (CARDBPP *)client->tightPalette;
if (rectColors == 2) { if (client->rectColors == 2) {
w = (rectWidth + 7) / 8; w = (client->rectWidth + 7) / 8;
for (y = 0; y < numRows; y++) { 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--) 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--) { for (b = 7; b >= 8 - client->rectWidth % 8; 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];
} }
} }
} else { } else {
for (y = 0; y < numRows; y++) for (y = 0; y < numRows; y++)
for (x = 0; x < rectWidth; x++) for (x = 0; x < client->rectWidth; x++)
dst[y*rectWidth+x] = palette[(int)src[y*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) ...@@ -563,6 +563,7 @@ DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h)
} }
cinfo.err = jpeg_std_error(&jerr); cinfo.err = jpeg_std_error(&jerr);
cinfo.client_data = client;
jpeg_create_decompress(&cinfo); jpeg_create_decompress(&cinfo);
JpegSetSrcManager(&cinfo, compressedData, compressedLen); JpegSetSrcManager(&cinfo, compressedData, compressedLen);
...@@ -583,7 +584,7 @@ DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h) ...@@ -583,7 +584,7 @@ DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h)
dy = 0; dy = 0;
while (cinfo.output_scanline < cinfo.output_height) { while (cinfo.output_scanline < cinfo.output_height) {
jpeg_read_scanlines(&cinfo, rowPointer, 1); jpeg_read_scanlines(&cinfo, rowPointer, 1);
if (jpegError) { if (client->jpegError) {
break; break;
} }
pixelPtr = (CARDBPP *)&client->buffer[RFB_BUFFER_SIZE / 2]; pixelPtr = (CARDBPP *)&client->buffer[RFB_BUFFER_SIZE / 2];
...@@ -595,13 +596,100 @@ DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h) ...@@ -595,13 +596,100 @@ DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h)
dy++; dy++;
} }
if (!jpegError) if (!client->jpegError)
jpeg_finish_decompress(&cinfo); jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo); jpeg_destroy_decompress(&cinfo);
free(compressedData); 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 #endif
......
...@@ -154,6 +154,15 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel, ...@@ -154,6 +154,15 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel,
client->bufoutptr=client->buf; client->bufoutptr=client->buf;
client->buffered=0; 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->HandleCursorPos = DummyPoint;
client->SoftCursorLockArea = DummyRect; client->SoftCursorLockArea = DummyRect;
client->SoftCursorUnlockScreen = Dummy; client->SoftCursorUnlockScreen = Dummy;
......
...@@ -46,16 +46,16 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh) ...@@ -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 * buffer, this buffer allocation should only happen once, on the
* first update. * 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 )); client->raw_buffer_size = (( rw * rh ) * ( BPP / 8 ));
raw_buffer = (char*) malloc( raw_buffer_size ); client->raw_buffer = (char*) malloc( client->raw_buffer_size );
} }
...@@ -65,26 +65,26 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh) ...@@ -65,26 +65,26 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh)
remaining = rfbClientSwap32IfLE(hdr.nBytes); remaining = rfbClientSwap32IfLE(hdr.nBytes);
/* Need to initialize the decompressor state. */ /* Need to initialize the decompressor state. */
decompStream.next_in = ( Bytef * )client->buffer; client->decompStream.next_in = ( Bytef * )client->buffer;
decompStream.avail_in = 0; client->decompStream.avail_in = 0;
decompStream.next_out = ( Bytef * )raw_buffer; client->decompStream.next_out = ( Bytef * )client->raw_buffer;
decompStream.avail_out = raw_buffer_size; client->decompStream.avail_out = client->raw_buffer_size;
decompStream.data_type = Z_BINARY; client->decompStream.data_type = Z_BINARY;
/* Initialize the decompression stream structures on the first invocation. */ /* 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 ) { if ( inflateResult != Z_OK ) {
rfbClientLog( rfbClientLog(
"inflateInit returned error: %d, msg: %s\n", "inflateInit returned error: %d, msg: %s\n",
inflateResult, inflateResult,
decompStream.msg); client->decompStream.msg);
return FALSE; return FALSE;
} }
decompStreamInited = TRUE; client->decompStreamInited = TRUE;
} }
...@@ -107,11 +107,11 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh) ...@@ -107,11 +107,11 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh)
if (!ReadFromRFBServer(client, client->buffer,toRead)) if (!ReadFromRFBServer(client, client->buffer,toRead))
return FALSE; return FALSE;
decompStream.next_in = ( Bytef * )client->buffer; client->decompStream.next_in = ( Bytef * )client->buffer;
decompStream.avail_in = toRead; client->decompStream.avail_in = toRead;
/* Need to uncompress buffer full. */ /* 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. */ /* We never supply a dictionary for compression. */
if ( inflateResult == Z_NEED_DICT ) { if ( inflateResult == Z_NEED_DICT ) {
...@@ -122,15 +122,15 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh) ...@@ -122,15 +122,15 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh)
rfbClientLog( rfbClientLog(
"zlib inflate returned error: %d, msg: %s\n", "zlib inflate returned error: %d, msg: %s\n",
inflateResult, inflateResult,
decompStream.msg); client->decompStream.msg);
return FALSE; return FALSE;
} }
/* Result buffer allocated to be at least large enough. We should /* Result buffer allocated to be at least large enough. We should
* never run out of space! * never run out of space!
*/ */
if (( decompStream.avail_in > 0 ) && if (( client->decompStream.avail_in > 0 ) &&
( decompStream.avail_out <= 0 )) { ( client->decompStream.avail_out <= 0 )) {
rfbClientLog("zlib inflate ran out of space!\n"); rfbClientLog("zlib inflate ran out of space!\n");
return FALSE; return FALSE;
} }
...@@ -142,14 +142,14 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh) ...@@ -142,14 +142,14 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh)
if ( inflateResult == Z_OK ) { if ( inflateResult == Z_OK ) {
/* Put the uncompressed contents of the update on the screen. */ /* 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 { else {
rfbClientLog( rfbClientLog(
"zlib inflate returned error: %d, msg: %s\n", "zlib inflate returned error: %d, msg: %s\n",
inflateResult, inflateResult,
decompStream.msg); client->decompStream.msg);
return FALSE; return FALSE;
} }
......
...@@ -132,6 +132,50 @@ typedef struct _rfbClient { ...@@ -132,6 +132,50 @@ typedef struct _rfbClient {
char *bufoutptr; char *bufoutptr;
int buffered; 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 */ /* cursor.c */
uint8_t *rcSource, *rcMask; uint8_t *rcSource, *rcMask;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment