]> source.dussan.org Git - tigervnc.git/commitdiff
If the client and server are using identical pixel formats, then perform Tight decodi...
authorDRC <dcommander@users.sourceforge.net>
Thu, 3 Nov 2011 18:49:21 +0000 (18:49 +0000)
committerDRC <dcommander@users.sourceforge.net>
Thu, 3 Nov 2011 18:49:21 +0000 (18:49 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4757 3789f03b-4d11-0410-bbf8-ca57d06f2519

common/rfb/CMakeLists.txt
common/rfb/CMsgHandler.h
common/rfb/PixelFormat.cxx
common/rfb/PixelFormat.h
common/rfb/TightDecoder.cxx
common/rfb/TightDecoder.h
common/rfb/tightDecode.h
vncviewer/CConn.cxx
vncviewer/CConn.h
vncviewer/DesktopWindow.h
vncviewer/Viewport.h

index be03c646f4d6c2d5b08c5d5b4457fe8795250b48..27e3caa5ef728eb32abbe8e8c3d56676878a3682 100644 (file)
@@ -23,6 +23,7 @@ set(RFB_SOURCES
   HextileDecoder.cxx
   HextileEncoder.cxx
   JpegCompressor.cxx
+  JpegDecompressor.cxx
   KeyRemapper.cxx
   LogWriter.cxx
   Logger.cxx
index d8b949b3b6f6e737d33d66a340665d06dbaf7b34..c81d55ef32f926029f71a4741ca6e2e3f22d7ee2 100644 (file)
@@ -1,5 +1,6 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
  * Copyright 2009 Pierre Ossman for Cendio AB
+ * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -68,6 +69,11 @@ namespace rfb {
     virtual void imageRect(const Rect& r, void* pixels) = 0;
     virtual void copyRect(const Rect& r, int srcX, int srcY) = 0;
 
+    virtual rdr::U8* getRawPixelsRW(const Rect& r, int* stride) = 0;
+    virtual void releaseRawPixels(const Rect& r) = 0;
+
+    virtual const PixelFormat &getPreferredPF(void) = 0;
+
     ConnParams cp;
   };
 }
index c5bec82532fa5101c51cf93f02cc4f1af0eb19e7..f7073224e05dc2a63b18847c1f701f1f511df808 100644 (file)
@@ -225,6 +225,61 @@ void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src,
 }
 
 
+void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src,
+                                int w, int pitch, int h, ColourMap* cm) const
+{
+  if (is888()) {
+    // Optimised common case
+    int rindex, gindex, bindex;
+
+    if (bigEndian) {
+      rindex = (24 - redShift)/8;
+      gindex = (24 - greenShift)/8;
+      bindex = (24 - blueShift)/8;
+    } else {
+      rindex = redShift/8;
+      gindex = greenShift/8;
+      bindex = blueShift/8;
+    }
+
+    int dstPad = pitch - w * 4;
+    while (h > 0) {
+      rdr::U8 *dstEndOfRow = (rdr::U8 *)dst + w * 4;
+      while (dst < dstEndOfRow) {
+        dst[rindex] = *(src++);
+        dst[gindex] = *(src++);
+        dst[bindex] = *(src++);
+        dst += 4;
+      }
+      dst += dstPad;
+      h--;
+    }
+  } else {
+    // Generic code
+    Pixel p;
+    rdr::U8 r, g, b;
+    int pixelSize = bpp/8;
+
+    int dstPad = pitch - w * pixelSize;
+    while (h > 0) {
+      rdr::U8 *dstEndOfRow = (rdr::U8 *)dst + w * pixelSize;
+      while (dst < dstEndOfRow) {
+        r = *(src++);
+        g = *(src++);
+        b = *(src++);
+
+        p = pixelFromRGB(r, g, b, cm);
+
+        bufferFromPixel(dst, p);
+        dst += pixelSize;
+      }
+      dst += dstPad;
+      h--;
+    }
+  }
+}
+
+
 void PixelFormat::rgbFromPixel(Pixel p, ColourMap* cm, Colour* rgb) const
 {
   rdr::U16 r, g, b;
index 6566e38b4b9b3a8d3e7587fbe52924c2f7f654cf..88e80f4c3669053fd9489ed5b9001ddcd8443468 100644 (file)
@@ -53,6 +53,8 @@ namespace rfb {
     Pixel pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue, ColourMap* cm=0) const;
 
     void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int pixels, ColourMap* cm=0) const;
+    void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int w, int pitch,
+                       int h, ColourMap* cm=0) const;
 
     void rgbFromPixel(Pixel pix, ColourMap* cm, Colour* rgb) const;
     inline void rgbFromPixel(Pixel pix, ColourMap* cm, rdr::U16 *r, rdr::U16 *g, rdr::U16 *b) const;
index daca00aa75bb6e243b2b13005a134708602d033a..670e480a439dbc3ae7f0b927e4e3b74e700e9924 100644 (file)
@@ -1,5 +1,6 @@
 /* Copyright (C) 2000-2003 Constantin Kaplinsky.  All Rights Reserved.
  * Copyright 2004-2005 Cendio AB.
+ * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
  *    
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include <rfb/CMsgReader.h>
 #include <rfb/CMsgHandler.h>
 #include <rfb/TightDecoder.h>
-#include <stdio.h> /* jpeglib.h needs FILE */
-extern "C" {
-#include <jpeglib.h>
-}
 
 using namespace rfb;
 
 #define TIGHT_MAX_WIDTH 2048
 
-static void JpegSetSrcManager(j_decompress_ptr cinfo, char *compressedData,
-                             int compressedLen);
-static bool jpegError;
-
 #define EXTRA_ARGS CMsgHandler* handler
 #define FILL_RECT(r, p) handler->fillRect(r, p)
 #define IMAGE_RECT(r, p) handler->imageRect(r, p)
@@ -60,82 +53,25 @@ TightDecoder::~TightDecoder()
 
 void TightDecoder::readRect(const Rect& r, CMsgHandler* handler)
 {
-  rdr::InStream* is = reader->getInStream();
-  /* Uncompressed RGB24 JPEG data, before translated, can be up to 3
-     times larger, if VNC bpp is 8. */
-  rdr::U8* buf = reader->getImageBuf(r.area()*3);
-  switch (reader->bpp()) {
+  is = reader->getInStream();
+  this->handler = handler;
+  clientpf = handler->getPreferredPF();
+  serverpf = handler->cp.pf();
+
+  if (clientpf.equal(serverpf)) {
+    /* Decode directly into the framebuffer (fast path) */
+    directDecode = true;
+  } else {
+    /* Decode into an intermediate buffer and use pixel translation */
+    directDecode = false;
+  }
+
+  switch (serverpf.bpp) {
   case 8:
-    tightDecode8 (r, is, zis, (rdr::U8*) buf, handler); break;
+    tightDecode8 (r); break;
   case 16:
-    tightDecode16(r, is, zis, (rdr::U16*)buf, handler); break;
+    tightDecode16(r); break;
   case 32:
-    tightDecode32(r, is, zis, (rdr::U32*)buf, handler); break;
+    tightDecode32(r); break;
   }
 }
-
-
-//
-// A "Source manager" for the JPEG library.
-//
-
-static struct jpeg_source_mgr jpegSrcManager;
-static JOCTET *jpegBufferPtr;
-static size_t jpegBufferLen;
-
-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
-JpegInitSource(j_decompress_ptr cinfo)
-{
-  jpegError = false;
-}
-
-static boolean
-JpegFillInputBuffer(j_decompress_ptr cinfo)
-{
-  jpegError = true;
-  jpegSrcManager.bytes_in_buffer = jpegBufferLen;
-  jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr;
-
-  return TRUE;
-}
-
-static void
-JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes)
-{
-  if (num_bytes < 0 || (size_t)num_bytes > jpegSrcManager.bytes_in_buffer) {
-    jpegError = true;
-    jpegSrcManager.bytes_in_buffer = jpegBufferLen;
-    jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr;
-  } else {
-    jpegSrcManager.next_input_byte += (size_t) num_bytes;
-    jpegSrcManager.bytes_in_buffer -= (size_t) num_bytes;
-  }
-}
-
-static void
-JpegTermSource(j_decompress_ptr cinfo)
-{
-  /* No work necessary here. */
-}
-
-static void
-JpegSetSrcManager(j_decompress_ptr cinfo, char *compressedData, int compressedLen)
-{
-  jpegBufferPtr = (JOCTET *)compressedData;
-  jpegBufferLen = (size_t)compressedLen;
-
-  jpegSrcManager.init_source = JpegInitSource;
-  jpegSrcManager.fill_input_buffer = JpegFillInputBuffer;
-  jpegSrcManager.skip_input_data = JpegSkipInputData;
-  jpegSrcManager.resync_to_restart = jpeg_resync_to_restart;
-  jpegSrcManager.term_source = JpegTermSource;
-  jpegSrcManager.next_input_byte = jpegBufferPtr;
-  jpegSrcManager.bytes_in_buffer = jpegBufferLen;
-
-  cinfo->src = &jpegSrcManager;
-}
index 1047b374a3013a70439d487ea416cd7bb38cf294..9a28fb9b966f21d5e916a13cac72e1242608ef64 100644 (file)
@@ -1,4 +1,5 @@
 /* Copyright (C) 2000-2003 Constantin Kaplinsky.  All Rights Reserved.
+ * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
  *    
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 
 #include <rdr/ZlibInStream.h>
 #include <rfb/Decoder.h>
+#include <rfb/JpegDecompressor.h>
 
 namespace rfb {
 
   class TightDecoder : public Decoder {
+
   public:
     static Decoder* create(CMsgReader* reader);
     virtual void readRect(const Rect& r, CMsgHandler* handler);
     virtual ~TightDecoder();
+
   private:
+    void tightDecode8(const Rect& r);
+    void tightDecode16(const Rect& r);
+    void tightDecode32(const Rect& r);
+
+    void DecompressJpegRect8(const Rect& r);
+    void DecompressJpegRect16(const Rect& r);
+    void DecompressJpegRect32(const Rect& r);
+
+    void FilterGradient8(rdr::InStream* is, rdr::U8* buf, int stride, 
+                         const Rect& r, int dataSize);
+    void FilterGradient16(rdr::InStream* is, rdr::U16* buf, int stride, 
+                          const Rect& r, int dataSize);
+    void FilterGradient24(rdr::InStream* is, rdr::U32* buf, int stride, 
+                          const Rect& r, int dataSize);
+    void FilterGradient32(rdr::InStream* is, rdr::U32* buf, int stride, 
+                          const Rect& r, int dataSize);
+
+    void directFillRect8(const Rect& r, Pixel pix);
+    void directFillRect16(const Rect& r, Pixel pix);
+    void directFillRect32(const Rect& r, Pixel pix);
+
     TightDecoder(CMsgReader* reader);
+
     CMsgReader* reader;
+    CMsgHandler* handler;
+    rdr::InStream* is;
     rdr::ZlibInStream zis[4];
+    JpegDecompressor jd;
+    PixelFormat clientpf;
+    PixelFormat serverpf;
+    bool directDecode;
   };
 
   // Compression control 
index 96042cb87b6f92271e0ab7de0eae4ea1ff393292..4ea18a972c027dc9b95e57df1ecc2822e2bbb51c 100644 (file)
@@ -1,5 +1,6 @@
 /* Copyright (C) 2000-2003 Constantin Kaplinsky.  All Rights Reserved.
  * Copyright 2004-2005 Cendio AB.
+ * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
  *    
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -42,32 +43,20 @@ namespace rfb {
 
 #define PIXEL_T rdr::CONCAT2E(U,BPP)
 #define READ_PIXEL CONCAT2E(readOpaque,BPP)
-#define TIGHT_DECODE CONCAT2E(tightDecode,BPP)
+#define TIGHT_DECODE TightDecoder::CONCAT2E(tightDecode,BPP)
+#define DECOMPRESS_JPEG_RECT TightDecoder::CONCAT2E(DecompressJpegRect,BPP)
+#define FILTER_GRADIENT TightDecoder::CONCAT2E(FilterGradient,BPP)
+#define DIRECT_FILL_RECT TightDecoder::CONCAT2E(directFillRect,BPP)
 
 #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);
-#if BPP == 32
-static void FilterGradient24(const Rect& r, rdr::InStream* is, int dataSize,
-                            PIXEL_T* buf, CMsgHandler* handler);
-#endif
 
 // Main function implementing Tight decoder
 
-void TIGHT_DECODE (const Rect& r, rdr::InStream* is,
-                   rdr::ZlibInStream zis[], PIXEL_T* buf
-#ifdef EXTRA_ARGS
-                      , EXTRA_ARGS
-#endif
-                      )
+void TIGHT_DECODE (const Rect& r)
 {
-  rdr::U8 *bytebuf = (rdr::U8*) buf;
   bool cutZeros = false;
-  const rfb::PixelFormat& myFormat = handler->cp.pf();
 #if BPP == 32
-  if (myFormat.is888()) {
+  if (serverpf.is888()) {
     cutZeros = true;
   } 
 #endif
@@ -86,18 +75,20 @@ void TIGHT_DECODE (const Rect& r, rdr::InStream* is,
   if (comp_ctl == rfbTightFill) {
     PIXEL_T pix;
     if (cutZeros) {
+      rdr::U8 bytebuf[3];
       is->readBytes(bytebuf, 3);
-      myFormat.bufferFromRGB((rdr::U8*)&pix, bytebuf, 1, NULL);
+      serverpf.bufferFromRGB((rdr::U8*)&pix, bytebuf, 1, NULL);
     } else {
       pix = is->READ_PIXEL();
     }
-    FILL_RECT(r, pix);
+    if (directDecode) DIRECT_FILL_RECT(r, pix);
+    else FILL_RECT(r, pix);
     return;
   }
 
   // "JPEG" compression type.
   if (comp_ctl == rfbTightJpeg) {
-    DecompressJpegRect(r, is, buf, handler);
+    DECOMPRESS_JPEG_RECT(r);
     return;
   }
 
@@ -122,11 +113,11 @@ void TIGHT_DECODE (const Rect& r, rdr::InStream* is,
         rdr::U8 elem[3];
         for (int i = 0;i < palSize;i++) {
           is->readBytes(elem, 3);
-          myFormat.bufferFromRGB((rdr::U8*)&palette[i], elem, 1, NULL);
+          serverpf.bufferFromRGB((rdr::U8*)&palette[i], elem, 1, NULL);
         }
       } else {
-       for (int i = 0; i < palSize; i++)
-         palette[i] = is->READ_PIXEL();
+        for (int i = 0; i < palSize; i++)
+          palette[i] = is->READ_PIXEL();
       }
       break;
     case rfbTightFilterGradient: 
@@ -161,78 +152,93 @@ void TIGHT_DECODE (const Rect& r, rdr::InStream* is,
     input = &zis[streamId];
   }
 
+  PIXEL_T *buf;
+  int stride = r.width();
+  if (directDecode) buf = (PIXEL_T *)handler->getRawPixelsRW(r, &stride);
+  else buf = (PIXEL_T *)reader->getImageBuf(r.area());
+
   if (palSize == 0) {
     // Truecolor data
     if (useGradient) {
 #if BPP == 32
       if (cutZeros) {
-       FilterGradient24(r, input, dataSize, buf, handler);
+        FilterGradient24(input, buf, stride, r, dataSize);
       } else 
 #endif
-       {
-         FilterGradient(r, input, dataSize, buf, handler);
-       }
+      {
+        FILTER_GRADIENT(input, buf, stride, r, dataSize);
+      }
     } else {
+      // Copy
+      int h = r.height();
+      PIXEL_T *ptr = buf;
       if (cutZeros) {
+        int w = r.width(), pad = stride - w;
         rdr::U8 elem[3];
-        for (int i = 0;i < r.area();i++) {
-          input->readBytes(elem, 3);
-          myFormat.bufferFromRGB((rdr::U8*)&buf[i], elem, 1, NULL);
+        while (h > 0) {
+          PIXEL_T *endOfRow = ptr + w;
+          while (ptr < endOfRow) {
+            input->readBytes(elem, 3);
+            serverpf.bufferFromRGB((rdr::U8*)ptr++, elem, 1, NULL);
+          }
+          ptr += pad;
+          h--;
         }
       } else {
-        input->readBytes(buf, dataSize); 
+        while (h > 0) {
+          input->readBytes(ptr, rowSize);
+          ptr += stride;
+          h--;
+        }
       }
     }
   } else {
-    int x, y, b;
+    // Indexed color
+    int x, h = r.height(), w = r.width(), b, pad = stride - w;
     PIXEL_T *ptr = buf;
     rdr::U8 bits;
     if (palSize <= 2) {
       // 2-color palette
-      for (y = 0; y < r.height(); y++) {
-        for (x = 0; x < r.width() / 8; x++) {
+      while (h > 0) {
+        for (x = 0; x < w / 8; x++) {
           bits = input->readU8();
           for (b = 7; b >= 0; b--) {
             *ptr++ = palette[bits >> b & 1];
-         }
+          }
         }
-        if (r.width() % 8 != 0) {
+        if (w % 8 != 0) {
           bits = input->readU8();
-          for (b = 7; b >= 8 - r.width() % 8; b--) {
+          for (b = 7; b >= 8 - w % 8; b--) {
             *ptr++ = palette[bits >> b & 1];
           }
         }
+        ptr += pad;
+        h--;
       }
     } else {
       // 256-color palette
-      for (y = 0; y < r.height(); y++) {
-        for (x = 0; x < r.width(); x++) {
+      while (h > 0) {
+        PIXEL_T *endOfRow = ptr + w;
+        while (ptr < endOfRow) {
           *ptr++ = palette[input->readU8()];
-       }
+        }
+        ptr += pad;
+        h--;
       }
     }
   }
 
-  IMAGE_RECT(r, buf);
+  if (directDecode) handler->releaseRawPixels(r);
+  else IMAGE_RECT(r, buf);
 
   if (streamId != -1) {
     zis[streamId].reset();
   }
 }
 
-static bool
-DecompressJpegRect(const Rect& r, rdr::InStream* is,
-                  PIXEL_T* buf, CMsgHandler* handler)
+void
+DECOMPRESS_JPEG_RECT(const Rect& r)
 {
-  struct jpeg_decompress_struct cinfo;
-  struct jpeg_error_mgr jerr;
-  int w = r.width();
-  int h = r.height();
-  int pixelsize;
-  rdr::U8 *dstBuf = NULL;
-  bool dstBufIsTemp = false;
-  const rfb::PixelFormat& pf = handler->cp.pf();
-
   // Read length
   int compressedLen = is->readCompactLength();
   if (compressedLen <= 0) {
@@ -246,97 +252,21 @@ DecompressJpegRect(const Rect& r, rdr::InStream* is,
   }
   is->readBytes(netbuf, compressedLen);
 
-  // Set up JPEG decompression
-  cinfo.err = jpeg_std_error(&jerr);
-  jpeg_create_decompress(&cinfo);
-  JpegSetSrcManager(&cinfo, (char*)netbuf, compressedLen);
-  jpeg_read_header(&cinfo, TRUE);
+  // We always use direct decoding with JPEG images
+  int stride;
+  rdr::U8 *buf = handler->getRawPixelsRW(r, &stride);
+  jd.decompress(netbuf, compressedLen, buf, stride * clientpf.bpp / 8, r,
+                clientpf);
+  handler->releaseRawPixels(r);
 
-  cinfo.out_color_space = JCS_RGB;
-  pixelsize = 3;
-
-#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)
-      cinfo.out_color_space = JCS_EXT_RGBX;
-    if(redShift == 16 && greenShift == 8 && blueShift == 0)
-      cinfo.out_color_space = JCS_EXT_BGRX;
-    if(redShift == 24 && greenShift == 16 && blueShift == 8)
-      cinfo.out_color_space = JCS_EXT_XBGR;
-    if(redShift == 8 && greenShift == 16 && blueShift == 24)
-      cinfo.out_color_space = JCS_EXT_XRGB;
-
-    if (cinfo.out_color_space != JCS_RGB) {
-      dstBuf = (rdr::U8 *)buf;
-      pixelsize = 4;
-    }
-  }
-#endif
-
-  if (cinfo.out_color_space == JCS_RGB) {
-    dstBuf = new rdr::U8[w * h * pixelsize];
-    dstBufIsTemp = true;
-  }
-
-  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 != pixelsize) {
-      jpeg_destroy_decompress(&cinfo);
-      throw Exception("Tight Encoding: Wrong JPEG data received.\n");
-  }
-
-  // Decompress
-  const rfb::PixelFormat& myFormat = handler->cp.pf();
-  while (cinfo.output_scanline < cinfo.output_height) {
-    jpeg_read_scanlines(&cinfo, &rowPointer[cinfo.output_scanline],
-                       cinfo.output_height - cinfo.output_scanline);
-    if (jpegError) {
-      break;
-    }
-  }
-
-  delete [] rowPointer;
-
-  if (cinfo.out_color_space == JCS_RGB)
-    myFormat.bufferFromRGB((rdr::U8*)buf, dstBuf, w * h);
-
-  IMAGE_RECT(r, buf);
-
-  if (!jpegError) {
-    jpeg_finish_decompress(&cinfo);
-  }
-
-  jpeg_destroy_decompress(&cinfo);
-
-  if (dstBufIsTemp) delete [] dstBuf;
   delete [] netbuf;
-
-  return !jpegError;
 }
 
 #if BPP == 32
 
-static void
-FilterGradient24(const Rect& r, rdr::InStream* is, int dataSize,
-                PIXEL_T* buf, CMsgHandler* handler)
+void
+TightDecoder::FilterGradient24(rdr::InStream* is, PIXEL_T* buf, int stride,
+                               const Rect& r, int dataSize)
 {
   int x, y, c;
   static rdr::U8 prevRow[TIGHT_MAX_WIDTH*3];
@@ -354,7 +284,6 @@ FilterGradient24(const Rect& r, rdr::InStream* is, int dataSize,
   is->readBytes(netbuf, dataSize);
 
   // Set up shortcut variables
-  const rfb::PixelFormat& myFormat = handler->cp.pf();
   int rectHeight = r.height();
   int rectWidth = r.width();
 
@@ -364,21 +293,21 @@ FilterGradient24(const Rect& r, rdr::InStream* is, int dataSize,
       pix[c] = netbuf[y*rectWidth*3+c] + prevRow[c];
       thisRow[c] = pix[c];
     }
-    myFormat.bufferFromRGB((rdr::U8*)&buf[y*rectWidth], pix, 1, NULL);
+    serverpf.bufferFromRGB((rdr::U8*)&buf[y*stride], pix, 1, NULL);
 
     /* 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] > 0xff) {
-         est[c] = 0xff;
-       } else if (est[c] < 0) {
-         est[c] = 0;
-       }
-       pix[c] = netbuf[(y*rectWidth+x)*3+c] + est[c];
-       thisRow[x*3+c] = pix[c];
+        est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c];
+        if (est[c] > 0xff) {
+          est[c] = 0xff;
+        } else if (est[c] < 0) {
+          est[c] = 0;
+        }
+        pix[c] = netbuf[(y*rectWidth+x)*3+c] + est[c];
+        thisRow[x*3+c] = pix[c];
       }
-      myFormat.bufferFromRGB((rdr::U8*)&buf[y*rectWidth+x], pix, 1, NULL);
+      serverpf.bufferFromRGB((rdr::U8*)&buf[y*stride+x], pix, 1, NULL);
     }
 
     memcpy(prevRow, thisRow, sizeof(prevRow));
@@ -389,9 +318,9 @@ FilterGradient24(const Rect& r, rdr::InStream* is, int dataSize,
 
 #endif
 
-static void
-FilterGradient(const Rect& r, rdr::InStream* is, int dataSize,
-              PIXEL_T* buf, CMsgHandler* handler)
+void
+FILTER_GRADIENT(rdr::InStream* is, PIXEL_T* buf, int stride, const Rect& r,
+                int dataSize)
 {
   int x, y, c;
   static rdr::U8 prevRow[TIGHT_MAX_WIDTH*sizeof(PIXEL_T)];
@@ -409,19 +338,18 @@ FilterGradient(const Rect& r, rdr::InStream* is, int dataSize,
   is->readBytes(netbuf, dataSize);
 
   // Set up shortcut variables
-  const rfb::PixelFormat& myFormat = handler->cp.pf();
   int rectHeight = r.height();
   int rectWidth = r.width();
 
   for (y = 0; y < rectHeight; y++) {
     /* First pixel in a row */
-    myFormat.rgbFromBuffer(pix, (rdr::U8*)&netbuf[y*rectWidth], 1, NULL);
+    serverpf.rgbFromBuffer(pix, (rdr::U8*)&netbuf[y*rectWidth], 1, NULL);
     for (c = 0; c < 3; c++)
       pix[c] += prevRow[c];
 
     memcpy(thisRow, pix, sizeof(pix));
 
-    myFormat.bufferFromRGB((rdr::U8*)&buf[y*rectWidth], pix, 1, NULL);
+    serverpf.bufferFromRGB((rdr::U8*)&buf[y*stride], pix, 1, NULL);
 
     /* Remaining pixels of a row */
     for (x = 1; x < rectWidth; x++) {
@@ -434,13 +362,13 @@ FilterGradient(const Rect& r, rdr::InStream* is, int dataSize,
         }
       }
 
-      myFormat.rgbFromBuffer(pix, (rdr::U8*)&netbuf[y*rectWidth+x], 1, NULL);
+      serverpf.rgbFromBuffer(pix, (rdr::U8*)&netbuf[y*rectWidth+x], 1, NULL);
       for (c = 0; c < 3; c++)
         pix[c] += est[c];
 
       memcpy(&thisRow[x*3], pix, sizeof(pix));
 
-      myFormat.bufferFromRGB((rdr::U8*)&buf[y*rectWidth+x], pix, 1, NULL);
+      serverpf.bufferFromRGB((rdr::U8*)&buf[y*stride+x], pix, 1, NULL);
     }
 
     memcpy(prevRow, thisRow, sizeof(prevRow));
@@ -449,7 +377,39 @@ FilterGradient(const Rect& r, rdr::InStream* is, int dataSize,
   delete [] netbuf;
 }
 
+void
+DIRECT_FILL_RECT(const Rect& r, Pixel pix) {
+
+  int stride;
+  PIXEL_T *buf = (PIXEL_T *)handler->getRawPixelsRW(r, &stride);
+
+  int w = r.width(), h = r.height();
+  PIXEL_T *ptr = buf;
+#if BPP != 8
+  int pad = stride - w;
+#endif
+
+  while (h > 0) {
+#if BPP == 8
+    memset(ptr, pix, w);
+    ptr += stride;
+#else
+    PIXEL_T *endOfRow = ptr + w;
+    while (ptr < endOfRow) {
+      *ptr++ = pix;
+    }
+    ptr += pad;
+#endif
+    h--;
+  }
+
+  handler->releaseRawPixels(r);
+}
+
 #undef TIGHT_MIN_TO_COMPRESS
+#undef DIRECT_FILL_RECT
+#undef FILTER_GRADIENT
+#undef DECOMPRESS_JPEG_RECT
 #undef TIGHT_DECODE
 #undef READ_PIXEL
 #undef PIXEL_T
index 4e741276602d6058d5eeb43c3172594b68c3d5ba..3d3d582df84802912d7f38027f32f9b17e3ef010 100644 (file)
@@ -1,5 +1,6 @@
 /* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
  * Copyright 2009-2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -411,6 +412,14 @@ void CConn::setCursor(int width, int height, const Point& hotspot,
   desktop->setCursor(width, height, hotspot, data, mask);
 }
 
+rdr::U8* CConn::getRawPixelsRW(const rfb::Rect& r, int* stride) {
+  return desktop->getPixelsRW(r, stride);
+}
+void CConn::releaseRawPixels(const rfb::Rect& r) {
+  desktop->damageRect(r);
+}
+
+
 ////////////////////// Internal methods //////////////////////
 
 void CConn::resizeFramebuffer()
index 3cde6d5f5133f77d37426324b6afa980739012c5..d6177fcd7529c706660c5f5ba5ad9ff3b5bc97e0 100644 (file)
@@ -67,6 +67,11 @@ public:
   void imageRect(const rfb::Rect& r, void* p);
   void copyRect(const rfb::Rect& r, int sx, int sy);
 
+  rdr::U8* getRawPixelsRW(const rfb::Rect& r, int* stride);
+  void releaseRawPixels(const rfb::Rect& r);
+
+  const rfb::PixelFormat &getPreferredPF() { return fullColourPF; }
+
   void setCursor(int width, int height, const rfb::Point& hotspot,
                  void* data, void* mask);
 
index a190b7006e27fe0c3f6b2dbb3a18665cead8a6c8..fbb5f954b0182823d26cfd69be08b44024bdaca5 100644 (file)
@@ -61,6 +61,13 @@ public:
     viewport->copyRect(r, srcX, srcY);
   }
 
+  rdr::U8* getPixelsRW(const rfb::Rect& r, int* stride) {
+    return viewport->getPixelsRW(r, stride);
+  }
+  void damageRect(const rfb::Rect& r) {
+    viewport->damageRect(r);
+  }
+
   void resizeFramebuffer(int new_w, int new_h);
 
   void setCursor(int width, int height, const rfb::Point& hotspot,
index 144ad420b2326fdb38847a3758f9b941091d28af..c66c19a0f4567c0ae64b529a50cbd891f43689d4 100644 (file)
@@ -97,6 +97,16 @@ public:
     damageRect(r);
   }
 
+  rdr::U8* getPixelsRW(const rfb::Rect& r, int* stride) {
+    return frameBuffer->getPixelsRW(r, stride);
+  }
+
+  void damageRect(const rfb::Rect& r) {
+    damage.assign_union(rfb::Region(r));
+    if (!Fl::has_timeout(handleUpdateTimeout, this))
+      Fl::add_timeout(0.500, handleUpdateTimeout, this);
+  };
+
   void setCursor(int width, int height, const rfb::Point& hotspot,
                  void* data, void* mask);
 
@@ -110,12 +120,6 @@ public:
 
 private:
 
-  void damageRect(const rfb::Rect& r) {
-    damage.assign_union(rfb::Region(r));
-    if (!Fl::has_timeout(handleUpdateTimeout, this))
-      Fl::add_timeout(0.500, handleUpdateTimeout, this);
-  };
-
   static void handleUpdateTimeout(void *data);
 
   void commitColourMap();