summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Åstrand <astrand@cendio.se>2004-12-09 20:01:00 +0000
committerPeter Åstrand <astrand@cendio.se>2004-12-09 20:01:00 +0000
commit0af24d4282f7afb0cf97f89b93107ede4b60468d (patch)
tree4952dc308a5b91030b4b62ae5ae88819fa60be19
parent5bbd61b0a2180b73bfb32dc1b1981ea04e70c471 (diff)
downloadtigervnc-0af24d4282f7afb0cf97f89b93107ede4b60468d.tar.gz
tigervnc-0af24d4282f7afb0cf97f89b93107ede4b60468d.zip
Implemented client side gradient filter. Only tested with 16 bpp, though.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@35 3789f03b-4d11-0410-bbf8-ca57d06f2519
-rw-r--r--rfb/TightDecoder.cxx7
-rw-r--r--rfb/tightDecode.h72
2 files changed, 74 insertions, 5 deletions
diff --git a/rfb/TightDecoder.cxx b/rfb/TightDecoder.cxx
index d634acb1..e51558fe 100644
--- a/rfb/TightDecoder.cxx
+++ b/rfb/TightDecoder.cxx
@@ -26,7 +26,12 @@ extern "C" {
using namespace rfb;
-#define RGB24_TO_PIXEL(bpp,r,g,b) \
+#define RGB_TO_PIXEL(r,g,b) \
+ (((PIXEL_T)(r) & myFormat.redMax) << myFormat.redShift | \
+ ((PIXEL_T)(g) & myFormat.greenMax) << myFormat.greenShift | \
+ ((PIXEL_T)(b) & myFormat.blueMax) << myFormat.blueShift)
+
+#define RGB24_TO_PIXEL(r,g,b) \
((((PIXEL_T)(r) & 0xFF) * myFormat.redMax + 127) / 255 \
<< myFormat.redShift | \
(((PIXEL_T)(g) & 0xFF) * myFormat.greenMax + 127) / 255 \
diff --git a/rfb/tightDecode.h b/rfb/tightDecode.h
index d066a558..a6b36f86 100644
--- a/rfb/tightDecode.h
+++ b/rfb/tightDecode.h
@@ -47,6 +47,8 @@ namespace rfb {
#define TIGHT_MIN_TO_COMPRESS 12
static bool DecompressJpegRect(const Rect& r, rdr::InStream* is,
PIXEL_T* buf, CMsgHandler* handler);
+static void FilterGradient(const Rect& r, rdr::InStream* is, int dataSize,
+ PIXEL_T* buf, CMsgHandler* handler);
// Main function implementing Tight decoder
@@ -88,7 +90,7 @@ void TIGHT_DECODE (const Rect& r, rdr::InStream* is,
// "Basic" compression type.
int palSize = 0;
- PIXEL_T palette[256];
+ static PIXEL_T palette[256];
bool useGradient = false;
if ((comp_ctl & rfbTightExplicitFilter) != 0) {
@@ -133,9 +135,10 @@ void TIGHT_DECODE (const Rect& r, rdr::InStream* is,
if (palSize == 0) {
// Truecolor data
- input->readBytes(buf, dataSize);
if (useGradient) {
- // FIXME: Implement the "gradient" filter.
+ FilterGradient(r, input, dataSize, buf, handler);
+ } else {
+ input->readBytes(buf, dataSize);
}
} else {
int x, y, b, w;
@@ -216,7 +219,7 @@ DecompressJpegRect(const Rect& r, rdr::InStream* is,
pixelPtr = (PIXEL_T*)(scanline);
for (int dx = 0; dx < r.width(); dx++) {
*pixelPtr++ =
- RGB24_TO_PIXEL(BPP, scanline[dx*3], scanline[dx*3+1], scanline[dx*3+2]);
+ RGB24_TO_PIXEL(scanline[dx*3], scanline[dx*3+1], scanline[dx*3+2]);
}
scanline += bytesPerRow;
}
@@ -234,6 +237,67 @@ DecompressJpegRect(const Rect& r, rdr::InStream* is,
}
+static void
+FilterGradient(const Rect& r, rdr::InStream* is, int dataSize,
+ PIXEL_T* buf, CMsgHandler* handler)
+{
+ int x, y, c;
+ static PIXEL_T prevRow[TIGHT_MAX_WIDTH*sizeof(PIXEL_T)];
+ static PIXEL_T thisRow[TIGHT_MAX_WIDTH*sizeof(PIXEL_T)];
+ int pix[3];
+ int max[3];
+ int shift[3];
+ int est[3];
+
+ memset(prevRow, 0, sizeof(prevRow));
+
+ // Allocate netbuf and read in data
+ PIXEL_T *netbuf = (PIXEL_T*)new rdr::U8[dataSize];
+ if (!netbuf)
+ throw Exception("rfb::tightDecode unable to allocate buffer");
+ is->readBytes(netbuf, dataSize);
+
+ // Set up shortcut variables
+ const rfb::PixelFormat& myFormat = handler->cp.pf();
+ max[0] = myFormat.redMax;
+ max[1] = myFormat.greenMax;
+ max[2] = myFormat.blueMax;
+ shift[0] = myFormat.redShift;
+ shift[1] = myFormat.greenShift;
+ shift[2] = myFormat.blueShift;
+ int rectHeight = r.height();
+ int rectWidth = r.width();
+
+ for (y = 0; y < rectHeight; y++) {
+ /* First pixel in a row */
+ for (c = 0; c < 3; c++) {
+ pix[c] = (netbuf[y*rectWidth] >> shift[c]) + prevRow[c] & max[c];
+ thisRow[c] = pix[c];
+ }
+ buf[y*rectWidth] = RGB_TO_PIXEL(pix[0], pix[1], pix[2]);
+
+ /* Remaining pixels of a row */
+ for (x = 1; x < rectWidth; x++) {
+ for (c = 0; c < 3; c++) {
+ est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c];
+ if (est[c] > max[c]) {
+ est[c] = max[c];
+ } else if (est[c] < 0) {
+ est[c] = 0;
+ }
+ pix[c] = (netbuf[y*rectWidth+x] >> shift[c]) + est[c] & max[c];
+ thisRow[x*3+c] = pix[c];
+ }
+ buf[y*rectWidth+x] = RGB_TO_PIXEL(pix[0], pix[1], pix[2]);
+ }
+
+ memcpy(prevRow, thisRow, sizeof(prevRow));
+ }
+
+ delete [] netbuf;
+}
+
+#undef TIGHT_MIN_TO_COMPRESS
#undef TIGHT_DECODE
#undef READ_PIXEL
#undef PIXEL_T