diff options
author | Peter Åstrand <astrand@cendio.se> | 2004-12-09 20:01:00 +0000 |
---|---|---|
committer | Peter Åstrand <astrand@cendio.se> | 2004-12-09 20:01:00 +0000 |
commit | 0af24d4282f7afb0cf97f89b93107ede4b60468d (patch) | |
tree | 4952dc308a5b91030b4b62ae5ae88819fa60be19 | |
parent | 5bbd61b0a2180b73bfb32dc1b1981ea04e70c471 (diff) | |
download | tigervnc-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.cxx | 7 | ||||
-rw-r--r-- | rfb/tightDecode.h | 72 |
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 |