summaryrefslogtreecommitdiffstats
path: root/common/rfb
diff options
context:
space:
mode:
authorDRC <dcommander@users.sourceforge.net>2009-04-06 07:20:34 +0000
committerDRC <dcommander@users.sourceforge.net>2009-04-06 07:20:34 +0000
commite420dcb3b0d3f0725094f221936e0c600a2aa0d8 (patch)
tree62fd9183f96e70c4ed9283be67841c3b61beda15 /common/rfb
parent4492baa70a901b787d75429a0029a76f2186c4e7 (diff)
downloadtigervnc-e420dcb3b0d3f0725094f221936e0c600a2aa0d8.tar.gz
tigervnc-e420dcb3b0d3f0725094f221936e0c600a2aa0d8.zip
Take advantage of libjpeg colorspace extensions, if available
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3759 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'common/rfb')
-rw-r--r--common/rfb/tightDecode.h63
1 files changed, 54 insertions, 9 deletions
diff --git a/common/rfb/tightDecode.h b/common/rfb/tightDecode.h
index 9679dd78..394f044d 100644
--- a/common/rfb/tightDecode.h
+++ b/common/rfb/tightDecode.h
@@ -228,9 +228,12 @@ DecompressJpegRect(const Rect& r, rdr::InStream* is,
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
- PIXEL_T *pixelPtr = buf;
- static rdr::U8 scanline_buffer[TIGHT_MAX_WIDTH*3];
- JSAMPROW scanline = scanline_buffer;
+ int w = r.width();
+ int h = r.height();
+ int pixelsize = 3;
+ rdr::U8 *dstBuf = NULL;
+ bool dstBufIsTemp = false;
+ const rfb::PixelFormat& pf = handler->cp.pf();
// Read length
int compressedLen = is->readCompactLength();
@@ -250,11 +253,51 @@ DecompressJpegRect(const Rect& r, rdr::InStream* is,
jpeg_create_decompress(&cinfo);
JpegSetSrcManager(&cinfo, (char*)netbuf, compressedLen);
jpeg_read_header(&cinfo, TRUE);
- cinfo.out_color_space = JCS_RGB;
+
+ #ifdef JCS_EXTENSIONS
+ pixelsize = pf.bpp / 8;
+ if(pf.redMax == 255 && pf.greenMax == 255 && pf.blueMax == 255) {
+ int redShift, greenShift, blueShift;
+ if(pf.bigEndian) {
+ redShift = 24 - pf.redShift;
+ greenShift = 24 - pf.greenShift;
+ blueShift = 24 - pf.blueShift;
+ }
+ else {
+ redShift = pf.redShift;
+ greenShift = pf.greenShift;
+ blueShift = pf.blueShift;
+ }
+ if(redShift == 0 && greenShift == 8 && blueShift == 16 && pixelsize == 3)
+ cinfo.out_color_space = JCS_EXT_RGB;
+ if(redShift == 0 && greenShift == 8 && blueShift == 16 && pixelsize == 4)
+ cinfo.out_color_space = JCS_EXT_RGBX;
+ if(redShift == 16 && greenShift == 8 && blueShift == 0 && pixelsize == 3)
+ cinfo.out_color_space = JCS_EXT_BGR;
+ if(redShift == 16 && greenShift == 8 && blueShift == 0 && pixelsize == 4)
+ cinfo.out_color_space = JCS_EXT_BGRX;
+ if(redShift == 24 && greenShift == 16 && blueShift == 8 && pixelsize == 4)
+ cinfo.out_color_space = JCS_EXT_XBGR;
+ if(redShift == 8 && greenShift == 16 && blueShift == 24 && pixelsize == 4)
+ cinfo.out_color_space = JCS_EXT_XRGB;
+ if(cinfo.out_color_space != JCS_RGB)
+ dstBuf = (rdr::U8 *)buf;
+ }
+ else
+ #endif
+ {
+ dstBuf = new rdr::U8[w * h * pixelsize];
+ dstBufIsTemp = true;
+ cinfo.out_color_space = JCS_RGB;
+ }
+
+ JSAMPROW *rowPointer = new JSAMPROW[h];
+ for (int dy = 0; dy < h; dy++)
+ rowPointer[dy] = (JSAMPROW)(&dstBuf[dy * w * pixelsize]);
jpeg_start_decompress(&cinfo);
if (cinfo.output_width != (unsigned)r.width() || cinfo.output_height != (unsigned)r.height() ||
- cinfo.output_components != 3) {
+ cinfo.output_components != pixelsize) {
jpeg_destroy_decompress(&cinfo);
throw Exception("Tight Encoding: Wrong JPEG data received.\n");
}
@@ -262,15 +305,16 @@ DecompressJpegRect(const Rect& r, rdr::InStream* is,
// Decompress
const rfb::PixelFormat& myFormat = handler->cp.pf();
while (cinfo.output_scanline < cinfo.output_height) {
- jpeg_read_scanlines(&cinfo, &scanline, 1);
+ jpeg_read_scanlines(&cinfo, &rowPointer[cinfo.output_scanline],
+ cinfo.output_height - cinfo.output_scanline);
if (jpegError) {
break;
}
-
- myFormat.bufferFromRGB((rdr::U8*)pixelPtr, (const rdr::U8*)scanline, r.width());
- pixelPtr += r.width();
}
+ if (cinfo.out_color_space == JCS_RGB)
+ myFormat.bufferFromRGB((rdr::U8*)buf, dstBuf, w * h);
+
IMAGE_RECT(r, buf);
if (!jpegError) {
@@ -279,6 +323,7 @@ DecompressJpegRect(const Rect& r, rdr::InStream* is,
jpeg_destroy_decompress(&cinfo);
+ if (dstBufIsTemp) delete [] dstBuf;
delete [] netbuf;
return !jpegError;