Include Tight decoding optimizations from TurboVNC

- As with the encoder, the decoder now uses the TurboJPEG wrapper, which
  allows it to decode JPEG images directly into the framebuffer.  This
  eliminates a buffer copy (CopyRectangle()) as well as the expensive
  RGB pixel conversion in DecompressJpegRectBPP().  The TurboJPEG
  wrapper performs RGB pixel conversion more optimally, and only when
  necessary (it uses the libjpeg-turbo colorspace extensions when
  available, in order to avoid RGB conversion.)
- The other Tight subencoding types are also now decoded directly into
  the framebuffer, which eliminates buffer copies.
- The Tight decoder now supports the rfbTightNoZlib extension, which
  allows the server to bypass zlib compression when Compression Level 0
  is selected.  The encoder already supports this extension.  Passing
  the data stream through zlib when Compression Level 0 is selected
  needlessly wastes CPU time, since all zlib is doing is copying the
  data internally into its own structures.
pull/3/head
DRC 6 years ago
parent 6814e946e0
commit d7b14624cb

@ -317,6 +317,13 @@ set(LIBVNCCLIENT_SOURCES
${COMMON_DIR}/minilzo.c ${COMMON_DIR}/minilzo.c
) )
if(JPEG_FOUND)
set(LIBVNCCLIENT_SOURCES
${LIBVNCCLIENT_SOURCES}
${COMMON_DIR}/turbojpeg.c
)
endif()
if(GNUTLS_FOUND) if(GNUTLS_FOUND)
set(LIBVNCCLIENT_SOURCES set(LIBVNCCLIENT_SOURCES
${LIBVNCCLIENT_SOURCES} ${LIBVNCCLIENT_SOURCES}

@ -47,12 +47,6 @@
#define Z_NULL NULL #define Z_NULL NULL
#endif #endif
#endif #endif
#ifdef LIBVNCSERVER_HAVE_LIBJPEG
#ifdef _RPCNDR_H /* This Windows header typedefs 'boolean', jpeglib has to know */
#define HAVE_BOOLEAN
#endif
#include <jpeglib.h>
#endif
#ifndef _MSC_VER #ifndef _MSC_VER
/* Strings.h is not available in MSVC */ /* Strings.h is not available in MSVC */
@ -171,13 +165,6 @@ static rfbBool HandleTight16(rfbClient* client, int rx, int ry, int rw, int rh);
static rfbBool HandleTight32(rfbClient* client, int rx, int ry, int rw, int rh); static rfbBool HandleTight32(rfbClient* client, int rx, int ry, int rw, int rh);
static long ReadCompactLen (rfbClient* client); static long ReadCompactLen (rfbClient* client);
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 JpegSetSrcManager(j_decompress_ptr cinfo, uint8_t *compressedData,
int compressedLen);
#endif #endif
static rfbBool HandleZRLE8(rfbClient* client, int rx, int ry, int rw, int rh); static rfbBool HandleZRLE8(rfbClient* client, int rx, int ry, int rw, int rh);
static rfbBool HandleZRLE15(rfbClient* client, int rx, int ry, int rw, int rh); static rfbBool HandleZRLE15(rfbClient* client, int rx, int ry, int rw, int rh);

@ -1,4 +1,7 @@
/* /*
* Copyright (C) 2017 D. R. Commander. All Rights Reserved.
* Copyright (C) 2004-2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright (C) 2004 Landmark Graphics Corporation. All Rights Reserved.
* Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved. * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved.
* *
* This is free software; you can redistribute it and/or modify * This is free software; you can redistribute it and/or modify
@ -71,16 +74,16 @@
/* Type declarations */ /* Type declarations */
typedef void (*filterPtrBPP)(rfbClient* client, int, CARDBPP *); typedef void (*filterPtrBPP)(rfbClient* client, int, int, int);
/* Prototypes */ /* Prototypes */
static int InitFilterCopyBPP (rfbClient* client, int rw, int rh); static int InitFilterCopyBPP (rfbClient* client, int rw, int rh);
static int InitFilterPaletteBPP (rfbClient* client, int rw, int rh); static int InitFilterPaletteBPP (rfbClient* client, int rw, int rh);
static int InitFilterGradientBPP (rfbClient* client, int rw, int rh); static int InitFilterGradientBPP (rfbClient* client, int rw, int rh);
static void FilterCopyBPP (rfbClient* client, int numRows, CARDBPP *destBuffer); static void FilterCopyBPP (rfbClient* client, int srcx, int srcy, int numRows);
static void FilterPaletteBPP (rfbClient* client, int numRows, CARDBPP *destBuffer); static void FilterPaletteBPP (rfbClient* client, int srcx, int srcy, int numRows);
static void FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *destBuffer); static void FilterGradientBPP (rfbClient* client, int srcx, int srcy, int numRows);
#if BPP != 8 #if BPP != 8
static rfbBool DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h); static rfbBool DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h);
@ -96,9 +99,17 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh)
uint8_t filter_id; uint8_t filter_id;
filterPtrBPP filterFn; filterPtrBPP filterFn;
z_streamp zs; z_streamp zs;
char *buffer2;
int err, stream_id, compressedLen, bitsPixel; int err, stream_id, compressedLen, bitsPixel;
int bufferSize, rowSize, numRows, portionLen, rowsProcessed, extraBytes; int bufferSize, rowSize, numRows, portionLen, rowsProcessed, extraBytes;
rfbBool readUncompressed = FALSE;
if (client->frameBuffer == NULL)
return FALSE;
if (rx + rw > client->width || ry + rh > client->height) {
rfbClientLog("Rect out of bounds: %dx%d at (%d, %d)\n", rx, ry, rw, rh);
return FALSE;
}
if (!ReadFromRFBServer(client, (char *)&comp_ctl, 1)) if (!ReadFromRFBServer(client, (char *)&comp_ctl, 1))
return FALSE; return FALSE;
@ -114,6 +125,11 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh)
comp_ctl >>= 1; comp_ctl >>= 1;
} }
if ((comp_ctl & rfbTightNoZlib) == rfbTightNoZlib) {
comp_ctl &= ~(rfbTightNoZlib);
readUncompressed = TRUE;
}
/* Handle solid rectangles. */ /* Handle solid rectangles. */
if (comp_ctl == rfbTightFill) { if (comp_ctl == rfbTightFill) {
#if BPP == 32 #if BPP == 32
@ -195,10 +211,7 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh)
if (!ReadFromRFBServer(client, (char*)client->buffer, rh * rowSize)) if (!ReadFromRFBServer(client, (char*)client->buffer, rh * rowSize))
return FALSE; return FALSE;
buffer2 = &client->buffer[TIGHT_MIN_TO_COMPRESS * 4]; filterFn(client, rx, ry, rh);
filterFn(client, rh, (CARDBPP *)buffer2);
client->GotBitmap(client, (uint8_t *)buffer2, rx, ry, rw, rh);
return TRUE; return TRUE;
} }
@ -209,6 +222,14 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh)
rfbClientLog("Incorrect data received from the server.\n"); rfbClientLog("Incorrect data received from the server.\n");
return FALSE; return FALSE;
} }
if (readUncompressed) {
if (!ReadFromRFBServer(client, (char*)client->buffer, compressedLen))
return FALSE;
filterFn(client, rx, ry, rh);
return TRUE;
}
/* 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;
@ -229,7 +250,6 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh)
/* Read, decode and draw actual pixel data in a loop. */ /* Read, decode and draw actual pixel data in a loop. */
bufferSize = RFB_BUFFER_SIZE * bitsPixel / (bitsPixel + BPP) & 0xFFFFFFFC; bufferSize = RFB_BUFFER_SIZE * bitsPixel / (bitsPixel + BPP) & 0xFFFFFFFC;
buffer2 = &client->buffer[bufferSize];
if (rowSize > bufferSize) { if (rowSize > bufferSize) {
/* Should be impossible when RFB_BUFFER_SIZE >= 16384 */ /* Should be impossible when RFB_BUFFER_SIZE >= 16384 */
rfbClientLog("Internal error: incorrect buffer size.\n"); rfbClientLog("Internal error: incorrect buffer size.\n");
@ -271,14 +291,12 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh)
numRows = (bufferSize - zs->avail_out) / rowSize; numRows = (bufferSize - zs->avail_out) / rowSize;
filterFn(client, numRows, (CARDBPP *)buffer2); filterFn(client, rx, ry+rowsProcessed, numRows);
extraBytes = bufferSize - zs->avail_out - numRows * rowSize; extraBytes = bufferSize - zs->avail_out - numRows * rowSize;
if (extraBytes > 0) if (extraBytes > 0)
memcpy(client->buffer, &client->buffer[numRows * rowSize], extraBytes); memcpy(client->buffer, &client->buffer[numRows * rowSize], extraBytes);
client->GotBitmap(client, (uint8_t *)buffer2, rx, ry+rowsProcessed, rw, numRows);
rowsProcessed += numRows; rowsProcessed += numRows;
} }
while (zs->avail_out == 0); while (zs->avail_out == 0);
@ -317,16 +335,19 @@ InitFilterCopyBPP (rfbClient* client, int rw, int rh)
} }
static void static void
FilterCopyBPP (rfbClient* client, int numRows, CARDBPP *dst) FilterCopyBPP (rfbClient* client, int srcx, int srcy, int numRows)
{ {
CARDBPP *dst =
(CARDBPP *)&client->frameBuffer[(srcy * client->width + srcx) * BPP / 8];
int y;
#if BPP == 32 #if BPP == 32
int x, y; int x;
if (client->cutZeros) { if (client->cutZeros) {
for (y = 0; y < numRows; y++) { for (y = 0; y < numRows; y++) {
for (x = 0; x < client->rectWidth; x++) { for (x = 0; x < client->rectWidth; x++) {
dst[y*client->rectWidth+x] = dst[y*client->width+x] =
RGB24_TO_PIXEL32(client->buffer[(y*client->rectWidth+x)*3], 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+1],
client->buffer[(y*client->rectWidth+x)*3+2]); client->buffer[(y*client->rectWidth+x)*3+2]);
@ -336,7 +357,9 @@ FilterCopyBPP (rfbClient* client, int numRows, CARDBPP *dst)
} }
#endif #endif
memcpy (dst, client->buffer, numRows * client->rectWidth * (BPP / 8)); for (y = 0; y < numRows; y++)
memcpy (&dst[y*client->width], &client->buffer[y*client->rectWidth],
client->rectWidth * (BPP / 8));
} }
static int static int
@ -356,8 +379,10 @@ InitFilterGradientBPP (rfbClient* client, int rw, int rh)
#if BPP == 32 #if BPP == 32
static void static void
FilterGradient24 (rfbClient* client, int numRows, uint32_t *dst) FilterGradient24 (rfbClient* client, int srcx, int srcy, int numRows)
{ {
CARDBPP *dst =
(CARDBPP *)&client->frameBuffer[(srcy * client->width + srcx) * BPP / 8];
int x, y, c; int x, y, c;
uint8_t thisRow[2048*3]; uint8_t thisRow[2048*3];
uint8_t pix[3]; uint8_t pix[3];
@ -370,7 +395,7 @@ FilterGradient24 (rfbClient* client, int numRows, uint32_t *dst)
pix[c] = client->tightPrevRow[c] + client->buffer[y*client->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*client->rectWidth] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]); dst[y*client->width] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]);
/* Remaining pixels of a row */ /* Remaining pixels of a row */
for (x = 1; x < client->rectWidth; x++) { for (x = 1; x < client->rectWidth; x++) {
@ -385,7 +410,7 @@ FilterGradient24 (rfbClient* client, int numRows, uint32_t *dst)
pix[c] = (uint8_t)est[c] + client->buffer[(y*client->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*client->rectWidth+x] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]); dst[y*client->width+x] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]);
} }
memcpy(client->tightPrevRow, thisRow, client->rectWidth * 3); memcpy(client->tightPrevRow, thisRow, client->rectWidth * 3);
@ -395,8 +420,10 @@ FilterGradient24 (rfbClient* client, int numRows, uint32_t *dst)
#endif #endif
static void static void
FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *dst) FilterGradientBPP (rfbClient* client, int srcx, int srcy, int numRows)
{ {
CARDBPP *dst =
(CARDBPP *)&client->frameBuffer[(srcy * client->width + srcx) * BPP / 8];
int x, y, c; int x, y, c;
CARDBPP *src = (CARDBPP *)client->buffer; CARDBPP *src = (CARDBPP *)client->buffer;
uint16_t *thatRow = (uint16_t *)client->tightPrevRow; uint16_t *thatRow = (uint16_t *)client->tightPrevRow;
@ -408,7 +435,7 @@ FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *dst)
#if BPP == 32 #if BPP == 32
if (client->cutZeros) { if (client->cutZeros) {
FilterGradient24(client, numRows, dst); FilterGradient24(client, srcx, srcy, numRows);
return; return;
} }
#endif #endif
@ -428,7 +455,7 @@ FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *dst)
pix[c] = (uint16_t)(((src[y*client->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*client->rectWidth] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]); dst[y*client->width] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]);
/* Remaining pixels of a row */ /* Remaining pixels of a row */
for (x = 1; x < client->rectWidth; x++) { for (x = 1; x < client->rectWidth; x++) {
@ -442,7 +469,7 @@ FilterGradientBPP (rfbClient* client, int numRows, CARDBPP *dst)
pix[c] = (uint16_t)(((src[y*client->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*client->rectWidth+x] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]); dst[y*client->width+x] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]);
} }
memcpy(thatRow, thisRow, client->rectWidth * 3 * sizeof(uint16_t)); memcpy(thatRow, thisRow, client->rectWidth * 3 * sizeof(uint16_t));
} }
@ -487,9 +514,11 @@ InitFilterPaletteBPP (rfbClient* client, int rw, int rh)
} }
static void static void
FilterPaletteBPP (rfbClient* client, int numRows, CARDBPP *dst) FilterPaletteBPP (rfbClient* client, int srcx, int srcy, int numRows)
{ {
int x, y, b, w; int x, y, b, w;
CARDBPP *dst =
(CARDBPP *)&client->frameBuffer[(srcy * client->width + srcx) * BPP / 8];
uint8_t *src = (uint8_t *)client->buffer; uint8_t *src = (uint8_t *)client->buffer;
CARDBPP *palette = (CARDBPP *)client->tightPalette; CARDBPP *palette = (CARDBPP *)client->tightPalette;
@ -498,16 +527,16 @@ FilterPaletteBPP (rfbClient* client, int numRows, CARDBPP *dst)
for (y = 0; y < numRows; y++) { for (y = 0; y < numRows; y++) {
for (x = 0; x < client->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*client->rectWidth+x*8+7-b] = palette[src[y*w+x] >> b & 1]; dst[y*client->width+x*8+7-b] = palette[src[y*w+x] >> b & 1];
} }
for (b = 7; b >= 8 - client->rectWidth % 8; b--) { for (b = 7; b >= 8 - client->rectWidth % 8; b--) {
dst[y*client->rectWidth+x*8+7-b] = palette[src[y*w+x] >> b & 1]; dst[y*client->width+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 < client->rectWidth; x++) for (x = 0; x < client->rectWidth; x++)
dst[y*client->rectWidth+x] = palette[(int)src[y*client->rectWidth+x]]; dst[y*client->width+x] = palette[(int)src[y*client->rectWidth+x]];
} }
} }
@ -522,13 +551,9 @@ FilterPaletteBPP (rfbClient* client, int numRows, CARDBPP *dst)
static rfbBool static rfbBool
DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h) DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h)
{ {
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
int compressedLen; int compressedLen;
uint8_t *compressedData; uint8_t *compressedData, *dst;
CARDBPP *pixelPtr; int pixelSize, pitch, flags = 0;
JSAMPROW rowPointer[1];
int dx, dy;
compressedLen = (int)ReadCompactLen(client); compressedLen = (int)ReadCompactLen(client);
if (compressedLen <= 0) { if (compressedLen <= 0) {
@ -550,47 +575,57 @@ DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h)
if(client->GotJpeg != NULL) if(client->GotJpeg != NULL)
return client->GotJpeg(client, compressedData, compressedLen, x, y, w, h); return client->GotJpeg(client, compressedData, compressedLen, x, y, w, h);
cinfo.err = jpeg_std_error(&jerr); if (!client->tjhnd) {
cinfo.client_data = client; if ((client->tjhnd = tjInitDecompress()) == NULL) {
jpeg_create_decompress(&cinfo); rfbClientLog("TurboJPEG error: %s\n", tjGetErrorStr());
free(compressedData);
JpegSetSrcManager(&cinfo, compressedData, compressedLen); return FALSE;
}
}
jpeg_read_header(&cinfo, TRUE); #if BPP == 16
cinfo.out_color_space = JCS_RGB; flags = 0;
pixelSize = 3;
pitch = w * pixelSize;
dst = (uint8_t *)client->buffer;
#else
if (client->format.bigEndian) flags |= TJ_ALPHAFIRST;
if (client->format.redShift == 16 && client->format.blueShift == 0)
flags |= TJ_BGR;
if (client->format.bigEndian) flags ^= TJ_BGR;
pixelSize = BPP / 8;
pitch = client->width * pixelSize;
dst = &client->frameBuffer[y * pitch + x * pixelSize];
#endif
jpeg_start_decompress(&cinfo); if (tjDecompress(client->tjhnd, compressedData, (unsigned long)compressedLen,
if (cinfo.output_width != w || cinfo.output_height != h || dst, w, pitch, h, pixelSize, flags)==-1) {
cinfo.output_components != 3) { rfbClientLog("TurboJPEG error: %s\n", tjGetErrorStr());
rfbClientLog("Tight Encoding: Wrong JPEG data received.\n");
jpeg_destroy_decompress(&cinfo);
free(compressedData); free(compressedData);
return FALSE; return FALSE;
} }
rowPointer[0] = (JSAMPROW)client->buffer; free(compressedData);
dy = 0;
while (cinfo.output_scanline < cinfo.output_height) { #if BPP == 16
jpeg_read_scanlines(&cinfo, rowPointer, 1); pixelSize = BPP / 8;
if (client->jpegError) { pitch = client->width * pixelSize;
break; dst = &client->frameBuffer[y * pitch + x * pixelSize];
} {
pixelPtr = (CARDBPP *)&client->buffer[RFB_BUFFER_SIZE / 2]; CARDBPP *dst16=(CARDBPP *)dst, *dst2;
for (dx = 0; dx < w; dx++) { char *src = client->buffer;
*pixelPtr++ = int i, j;
RGB24_TO_PIXEL(BPP, client->buffer[dx*3], client->buffer[dx*3+1], client->buffer[dx*3+2]);
for (j = 0; j < h; j++) {
for (i = 0, dst2 = dst16; i < w; i++, dst2++, src += 3) {
*dst2 = RGB24_TO_PIXEL(BPP, src[0], src[1], src[2]);
}
dst16 += client->width;
} }
client->GotBitmap(client, (uint8_t *)&client->buffer[RFB_BUFFER_SIZE / 2], x, y + dy, w, 1);
dy++;
} }
#endif
if (!client->jpegError) return TRUE;
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
free(compressedData);
return !client->jpegError;
} }
#else #else
@ -617,70 +652,6 @@ ReadCompactLen (rfbClient* client)
return len; 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;
}
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;
if(client->jpegSrcManager == NULL)
client->jpegSrcManager = malloc(sizeof(struct jpeg_source_mgr));
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
#undef CARDBPP #undef CARDBPP

@ -319,7 +319,6 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel,
#ifdef LIBVNCSERVER_HAVE_LIBJPEG #ifdef LIBVNCSERVER_HAVE_LIBJPEG
memset(client->zlibStreamActive,0,sizeof(rfbBool)*4); memset(client->zlibStreamActive,0,sizeof(rfbBool)*4);
client->jpegSrcManager = NULL;
#endif #endif
#endif #endif
@ -517,9 +516,6 @@ void rfbClientCleanup(rfbClient* client) {
client->decompStream.msg != NULL) client->decompStream.msg != NULL)
rfbClientLog("inflateEnd: %s\n", client->decompStream.msg ); rfbClientLog("inflateEnd: %s\n", client->decompStream.msg );
} }
if (client->jpegSrcManager)
free(client->jpegSrcManager);
#endif #endif
#endif #endif

@ -7,6 +7,7 @@
*/ */
/* /*
* Copyright (C) 2017 D. R. Commander. All Rights Reserved.
* Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved. * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved.
* Copyright (C) 2000 Tridia Corporation. All Rights Reserved. * Copyright (C) 2000 Tridia Corporation. All Rights Reserved.
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
@ -51,6 +52,7 @@
#endif #endif
#include <rfb/rfbproto.h> #include <rfb/rfbproto.h>
#include <rfb/keysym.h> #include <rfb/keysym.h>
#include "turbojpeg.h"
#ifdef LIBVNCSERVER_HAVE_SASL #ifdef LIBVNCSERVER_HAVE_SASL
#include <sasl/sasl.h> #include <sasl/sasl.h>
@ -295,7 +297,7 @@ typedef struct _rfbClient {
uint8_t tightPrevRow[2048*3*sizeof(uint16_t)]; uint8_t tightPrevRow[2048*3*sizeof(uint16_t)];
#ifdef LIBVNCSERVER_HAVE_LIBJPEG #ifdef LIBVNCSERVER_HAVE_LIBJPEG
/** JPEG decoder state. */ /** JPEG decoder state (obsolete-- do not use). */
rfbBool jpegError; rfbBool jpegError;
struct jpeg_source_mgr* jpegSrcManager; struct jpeg_source_mgr* jpegSrcManager;
@ -422,6 +424,14 @@ typedef struct _rfbClient {
GetUserProc GetUser; GetUserProc GetUser;
#endif /* LIBVNCSERVER_HAVE_SASL */ #endif /* LIBVNCSERVER_HAVE_SASL */
#ifdef LIBVNCSERVER_HAVE_LIBZ
#ifdef LIBVNCSERVER_HAVE_LIBJPEG
/** JPEG decoder state. */
tjhandle tjhnd;
#endif
#endif
} rfbClient; } rfbClient;
/* cursor.c */ /* cursor.c */

Loading…
Cancel
Save