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,
#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
......
This diff is collapsed.
......@@ -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;
......
......@@ -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;
}
......
......@@ -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;
......
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