summaryrefslogtreecommitdiffstats
path: root/common/rfb/JpegDecompressor.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'common/rfb/JpegDecompressor.cxx')
-rw-r--r--common/rfb/JpegDecompressor.cxx65
1 files changed, 30 insertions, 35 deletions
diff --git a/common/rfb/JpegDecompressor.cxx b/common/rfb/JpegDecompressor.cxx
index 503c030f..ca1ad226 100644
--- a/common/rfb/JpegDecompressor.cxx
+++ b/common/rfb/JpegDecompressor.cxx
@@ -1,6 +1,7 @@
/* Copyright (C) 2000-2003 Constantin Kaplinsky. All Rights Reserved.
* Copyright (C) 2004-2005 Cendio AB. All rights reserved.
* Copyright (C) 2011 D. R. Commander. All Rights Reserved.
+ * Copyright 2014 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,7 +23,6 @@
#include <rdr/Exception.h>
#include <rfb/Rect.h>
#include <rfb/PixelFormat.h>
-#include <os/print.h>
#include <stdio.h>
extern "C" {
@@ -33,6 +33,14 @@ extern "C" {
using namespace rfb;
+//
+// Special formats that libjpeg can have optimised code paths for
+//
+
+static const PixelFormat pfRGBX(32, 24, false, true, 255, 255, 255, 0, 8, 16);
+static const PixelFormat pfBGRX(32, 24, false, true, 255, 255, 255, 16, 8, 0);
+static const PixelFormat pfXRGB(32, 24, false, true, 255, 255, 255, 8, 16, 24);
+static const PixelFormat pfXBGR(32, 24, false, true, 255, 255, 255, 24, 16, 8);
//
// Error manager implmentation for the JPEG library
@@ -139,12 +147,12 @@ JpegDecompressor::~JpegDecompressor(void)
}
void JpegDecompressor::decompress(const rdr::U8 *jpegBuf, int jpegBufLen,
- rdr::U8 *buf, int pitch, const Rect& r, const PixelFormat& pf)
+ rdr::U8 *buf, int stride, const Rect& r, const PixelFormat& pf)
{
int w = r.width();
int h = r.height();
int pixelsize;
- int dstBufPitch;
+ int dstBufStride;
rdr::U8 *dstBuf = NULL;
bool dstBufIsTemp = false;
JSAMPROW *rowPointer = NULL;
@@ -163,50 +171,37 @@ void JpegDecompressor::decompress(const rdr::U8 *jpegBuf, int jpegBufLen,
jpeg_read_header(dinfo, TRUE);
dinfo->out_color_space = JCS_RGB;
pixelsize = 3;
- if (pitch == 0) pitch = w * pf.bpp / 8;
- dstBufPitch = pitch;
+ if (stride == 0)
+ stride = w;
+ dstBufStride = stride;
#ifdef JCS_EXTENSIONS
// Try to have libjpeg output directly to our native format
- if (pf.is888()) {
- 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;
- }
-
- // libjpeg can only handle some "standard" formats
- if(redShift == 0 && greenShift == 8 && blueShift == 16)
- dinfo->out_color_space = JCS_EXT_RGBX;
- if(redShift == 16 && greenShift == 8 && blueShift == 0)
- dinfo->out_color_space = JCS_EXT_BGRX;
- if(redShift == 24 && greenShift == 16 && blueShift == 8)
- dinfo->out_color_space = JCS_EXT_XBGR;
- if(redShift == 8 && greenShift == 16 && blueShift == 24)
- dinfo->out_color_space = JCS_EXT_XRGB;
-
- if (dinfo->out_color_space != JCS_RGB) {
- dstBuf = (rdr::U8 *)buf;
- pixelsize = 4;
- }
+ // libjpeg can only handle some "standard" formats
+ if (pfRGBX.equal(pf))
+ dinfo->out_color_space = JCS_EXT_RGBX;
+ else if (pfBGRX.equal(pf))
+ dinfo->out_color_space = JCS_EXT_BGRX;
+ else if (pfXRGB.equal(pf))
+ dinfo->out_color_space = JCS_EXT_XRGB;
+ else if (pfXBGR.equal(pf))
+ dinfo->out_color_space = JCS_EXT_XBGR;
+
+ if (dinfo->out_color_space != JCS_RGB) {
+ dstBuf = (rdr::U8 *)buf;
+ pixelsize = 4;
}
#endif
if (dinfo->out_color_space == JCS_RGB) {
dstBuf = new rdr::U8[w * h * pixelsize];
dstBufIsTemp = true;
- dstBufPitch = w * pixelsize;
+ dstBufStride = w;
}
rowPointer = new JSAMPROW[h];
for (int dy = 0; dy < h; dy++)
- rowPointer[dy] = (JSAMPROW)(&dstBuf[dy * dstBufPitch]);
+ rowPointer[dy] = (JSAMPROW)(&dstBuf[dy * dstBufStride * pixelsize]);
jpeg_start_decompress(dinfo);
@@ -225,7 +220,7 @@ void JpegDecompressor::decompress(const rdr::U8 *jpegBuf, int jpegBufLen,
}
if (dinfo->out_color_space == JCS_RGB)
- pf.bufferFromRGB((rdr::U8*)buf, dstBuf, w, pitch, h);
+ pf.bufferFromRGB((rdr::U8*)buf, dstBuf, w, stride, h);
jpeg_finish_decompress(dinfo);