Decouple decoders from CConnection
diff --git a/common/rfb/CopyRectDecoder.cxx b/common/rfb/CopyRectDecoder.cxx
index 4b10418..4690b5e 100644
--- a/common/rfb/CopyRectDecoder.cxx
+++ b/common/rfb/CopyRectDecoder.cxx
@@ -16,13 +16,12 @@
  * USA.
  */
 #include <rdr/InStream.h>
-#include <rfb/CConnection.h>
 #include <rfb/PixelBuffer.h>
 #include <rfb/CopyRectDecoder.h>
 
 using namespace rfb;
 
-CopyRectDecoder::CopyRectDecoder(CConnection* conn) : Decoder(conn)
+CopyRectDecoder::CopyRectDecoder()
 {
 }
 
@@ -30,9 +29,11 @@
 {
 }
 
-void CopyRectDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb)
+void CopyRectDecoder::readRect(const Rect& r, rdr::InStream* is,
+                               const ConnParams& cp,
+                               ModifiablePixelBuffer* pb)
 {
-  int srcX = conn->getInStream()->readU16();
-  int srcY = conn->getInStream()->readU16();
+  int srcX = is->readU16();
+  int srcY = is->readU16();
   pb->copyRect(r, Point(r.tl.x-srcX, r.tl.y-srcY));
 }
diff --git a/common/rfb/CopyRectDecoder.h b/common/rfb/CopyRectDecoder.h
index d14bf92..a7195ce 100644
--- a/common/rfb/CopyRectDecoder.h
+++ b/common/rfb/CopyRectDecoder.h
@@ -24,9 +24,10 @@
 
   class CopyRectDecoder : public Decoder {
   public:
-    CopyRectDecoder(CConnection* conn);
+    CopyRectDecoder();
     virtual ~CopyRectDecoder();
-    virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb);
+    virtual void readRect(const Rect& r, rdr::InStream* is,
+                          const ConnParams& cp, ModifiablePixelBuffer* pb);
   };
 }
 #endif
diff --git a/common/rfb/DecodeManager.cxx b/common/rfb/DecodeManager.cxx
index f6ffa4b..b82d31d 100644
--- a/common/rfb/DecodeManager.cxx
+++ b/common/rfb/DecodeManager.cxx
@@ -19,6 +19,7 @@
 #include <assert.h>
 #include <string.h>
 
+#include <rfb/CConnection.h>
 #include <rfb/DecodeManager.h>
 #include <rfb/Decoder.h>
 
@@ -53,11 +54,11 @@
   }
 
   if (!decoders[encoding]) {
-    decoders[encoding] = Decoder::createDecoder(encoding, conn);
+    decoders[encoding] = Decoder::createDecoder(encoding);
     if (!decoders[encoding]) {
       vlog.error("Unknown encoding %d", encoding);
       throw rdr::Exception("Unknown encoding");
     }
   }
-  decoders[encoding]->readRect(r, pb);
+  decoders[encoding]->readRect(r, conn->getInStream(), conn->cp, pb);
 }
diff --git a/common/rfb/Decoder.cxx b/common/rfb/Decoder.cxx
index 3faa975..a1f4438 100644
--- a/common/rfb/Decoder.cxx
+++ b/common/rfb/Decoder.cxx
@@ -28,7 +28,7 @@
 
 using namespace rfb;
 
-Decoder::Decoder(CConnection* conn_) : conn(conn_)
+Decoder::Decoder()
 {
 }
 
@@ -51,21 +51,21 @@
   }
 }
 
-Decoder* Decoder::createDecoder(int encoding, CConnection* conn)
+Decoder* Decoder::createDecoder(int encoding)
 {
   switch (encoding) {
   case encodingRaw:
-    return new RawDecoder(conn);
+    return new RawDecoder();
   case encodingCopyRect:
-    return new CopyRectDecoder(conn);
+    return new CopyRectDecoder();
   case encodingRRE:
-    return new RREDecoder(conn);
+    return new RREDecoder();
   case encodingHextile:
-    return new HextileDecoder(conn);
+    return new HextileDecoder();
   case encodingZRLE:
-    return new ZRLEDecoder(conn);
+    return new ZRLEDecoder();
   case encodingTight:
-    return new TightDecoder(conn);
+    return new TightDecoder();
   default:
     return NULL;
   }
diff --git a/common/rfb/Decoder.h b/common/rfb/Decoder.h
index ff67f57..9d929ea 100644
--- a/common/rfb/Decoder.h
+++ b/common/rfb/Decoder.h
@@ -19,28 +19,27 @@
 #ifndef __RFB_DECODER_H__
 #define __RFB_DECODER_H__
 
-#include <rfb/Rect.h>
+namespace rdr { class InStream; }
 
 namespace rfb {
-  class CConnection;
+  class ConnParams;
   class ModifiablePixelBuffer;
+  class Rect;
 
   class Decoder {
   public:
-    Decoder(CConnection* conn);
+    Decoder();
     virtual ~Decoder();
 
     // readRect() is the main interface that decodes the given rectangle
-    // with data from the CConnection, given at decoder creation, onto
-    // the ModifiablePixelBuffer. The PixelFormat of the PixelBuffer might
-    // not match the ConnParams and it is up to the decoder to do
-    // any necessary conversion.
-    virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb)=0;
+    // with data from the given InStream, onto the ModifiablePixelBuffer.
+    // The PixelFormat of the PixelBuffer might not match the ConnParams
+    // and it is up to the decoder to do any necessary conversion.
+    virtual void readRect(const Rect& r, rdr::InStream* is,
+                          const ConnParams& cp, ModifiablePixelBuffer* pb)=0;
 
     static bool supported(int encoding);
-    static Decoder* createDecoder(int encoding, CConnection* conn);
-  protected:
-    CConnection* conn;
+    static Decoder* createDecoder(int encoding);
   };
 }
 
diff --git a/common/rfb/HextileDecoder.cxx b/common/rfb/HextileDecoder.cxx
index 8b18b7b..705ccf5 100644
--- a/common/rfb/HextileDecoder.cxx
+++ b/common/rfb/HextileDecoder.cxx
@@ -15,8 +15,8 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
  * USA.
  */
-#include <rfb/CMsgReader.h>
-#include <rfb/CConnection.h>
+#include <rdr/InStream.h>
+#include <rfb/ConnParams.h>
 #include <rfb/PixelBuffer.h>
 #include <rfb/HextileDecoder.h>
 
@@ -32,7 +32,7 @@
 #include <rfb/hextileDecode.h>
 #undef BPP
 
-HextileDecoder::HextileDecoder(CConnection* conn) : Decoder(conn)
+HextileDecoder::HextileDecoder()
 {
 }
 
@@ -40,11 +40,11 @@
 {
 }
 
-void HextileDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb)
+void HextileDecoder::readRect(const Rect& r, rdr::InStream* is,
+                              const ConnParams& cp, ModifiablePixelBuffer* pb)
 {
-  rdr::InStream* is = conn->getInStream();
-  rdr::U8* buf = conn->reader()->getImageBuf(16 * 16 * 4);
-  const PixelFormat& pf = conn->cp.pf();
+  const PixelFormat& pf = cp.pf();
+  rdr::U8 buf[16 * 16 * 4 * pf.bpp/8];
   switch (pf.bpp) {
   case 8:  hextileDecode8 (r, is, (rdr::U8*) buf, pf, pb); break;
   case 16: hextileDecode16(r, is, (rdr::U16*)buf, pf, pb); break;
diff --git a/common/rfb/HextileDecoder.h b/common/rfb/HextileDecoder.h
index ffc495e..22eefba 100644
--- a/common/rfb/HextileDecoder.h
+++ b/common/rfb/HextileDecoder.h
@@ -24,9 +24,10 @@
 
   class HextileDecoder : public Decoder {
   public:
-    HextileDecoder(CConnection* conn);
+    HextileDecoder();
     virtual ~HextileDecoder();
-    virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb);
+    virtual void readRect(const Rect& r, rdr::InStream* is,
+                          const ConnParams& cp, ModifiablePixelBuffer* pb);
   };
 }
 #endif
diff --git a/common/rfb/RREDecoder.cxx b/common/rfb/RREDecoder.cxx
index 8dc391a..b802644 100644
--- a/common/rfb/RREDecoder.cxx
+++ b/common/rfb/RREDecoder.cxx
@@ -15,8 +15,8 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
  * USA.
  */
-#include <rfb/CMsgReader.h>
-#include <rfb/CConnection.h>
+#include <rdr/InStream.h>
+#include <rfb/ConnParams.h>
 #include <rfb/PixelBuffer.h>
 #include <rfb/RREDecoder.h>
 
@@ -32,7 +32,7 @@
 #include <rfb/rreDecode.h>
 #undef BPP
 
-RREDecoder::RREDecoder(CConnection* conn) : Decoder(conn)
+RREDecoder::RREDecoder()
 {
 }
 
@@ -40,10 +40,10 @@
 {
 }
 
-void RREDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb)
+void RREDecoder::readRect(const Rect& r, rdr::InStream* is,
+                          const ConnParams& cp, ModifiablePixelBuffer* pb)
 {
-  rdr::InStream* is = conn->getInStream();
-  const PixelFormat& pf = conn->cp.pf();
+  const PixelFormat& pf = cp.pf();
   switch (pf.bpp) {
   case 8:  rreDecode8 (r, is, pf, pb); break;
   case 16: rreDecode16(r, is, pf, pb); break;
diff --git a/common/rfb/RREDecoder.h b/common/rfb/RREDecoder.h
index b33bc55..3bed62b 100644
--- a/common/rfb/RREDecoder.h
+++ b/common/rfb/RREDecoder.h
@@ -24,9 +24,10 @@
 
   class RREDecoder : public Decoder {
   public:
-    RREDecoder(CConnection* conn);
+    RREDecoder();
     virtual ~RREDecoder();
-    virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb);
+    virtual void readRect(const Rect& r, rdr::InStream* is,
+                          const ConnParams& cp, ModifiablePixelBuffer* pb);
   };
 }
 #endif
diff --git a/common/rfb/RawDecoder.cxx b/common/rfb/RawDecoder.cxx
index d2b3d06..292c343 100644
--- a/common/rfb/RawDecoder.cxx
+++ b/common/rfb/RawDecoder.cxx
@@ -16,14 +16,13 @@
  * USA.
  */
 #include <rdr/InStream.h>
-#include <rfb/CMsgReader.h>
-#include <rfb/CConnection.h>
+#include <rfb/ConnParams.h>
 #include <rfb/PixelBuffer.h>
 #include <rfb/RawDecoder.h>
 
 using namespace rfb;
 
-RawDecoder::RawDecoder(CConnection* conn) : Decoder(conn)
+RawDecoder::RawDecoder()
 {
 }
 
@@ -31,22 +30,37 @@
 {
 }
 
-void RawDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb)
+void RawDecoder::readRect(const Rect& r, rdr::InStream* is,
+                          const ConnParams& cp, ModifiablePixelBuffer* pb)
 {
+  const PixelFormat& pf = cp.pf();
+
+  rdr::U8 imageBuf[16384];
+  const int maxPixels = sizeof(imageBuf) / (pf.bpp/8);
+
   int x = r.tl.x;
   int y = r.tl.y;
   int w = r.width();
   int h = r.height();
-  int nPixels;
-  rdr::U8* imageBuf = conn->reader()->getImageBuf(w, w*h, &nPixels);
-  const PixelFormat& pf = conn->cp.pf();
-  int bytesPerRow = w * (pf.bpp / 8);
+
   while (h > 0) {
-    int nRows = nPixels / w;
-    if (nRows > h) nRows = h;
-    conn->getInStream()->readBytes(imageBuf, nRows * bytesPerRow);
-    pb->imageRect(pf, Rect(x, y, x+w, y+nRows), imageBuf);
-    h -= nRows;
-    y += nRows;
+    int dx;
+
+    dx = 0;
+    while (dx < w) {
+      int dw;
+
+      dw = maxPixels;
+      if (dx + dw > w)
+        dw = w - dx;
+
+      is->readBytes(imageBuf, dw * pf.bpp/8);
+      pb->imageRect(pf, Rect(x+dx, y, x+dx+dw, y+1), imageBuf);
+
+      dx += dw;
+    }
+
+    y++;
+    h--;
   }
 }
diff --git a/common/rfb/RawDecoder.h b/common/rfb/RawDecoder.h
index 7a784c6..4caf175 100644
--- a/common/rfb/RawDecoder.h
+++ b/common/rfb/RawDecoder.h
@@ -21,12 +21,12 @@
 #include <rfb/Decoder.h>
 
 namespace rfb {
-
   class RawDecoder : public Decoder {
   public:
-    RawDecoder(CConnection* conn);
+    RawDecoder();
     virtual ~RawDecoder();
-    virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb);
+    virtual void readRect(const Rect& r, rdr::InStream* is,
+                          const ConnParams& cp, ModifiablePixelBuffer* pb);
   };
 }
 #endif
diff --git a/common/rfb/TightDecoder.cxx b/common/rfb/TightDecoder.cxx
index 5f4142b..96749a9 100644
--- a/common/rfb/TightDecoder.cxx
+++ b/common/rfb/TightDecoder.cxx
@@ -17,8 +17,8 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
  * USA.
  */
-#include <rfb/CMsgReader.h>
-#include <rfb/CConnection.h>
+#include <rdr/InStream.h>
+#include <rfb/ConnParams.h>
 #include <rfb/PixelBuffer.h>
 #include <rfb/TightDecoder.h>
 
@@ -36,7 +36,7 @@
 #include <rfb/tightDecode.h>
 #undef BPP
 
-TightDecoder::TightDecoder(CConnection* conn) : Decoder(conn)
+TightDecoder::TightDecoder()
 {
 }
 
@@ -44,12 +44,13 @@
 {
 }
 
-void TightDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb)
+void TightDecoder::readRect(const Rect& r, rdr::InStream* is,
+                            const ConnParams& cp, ModifiablePixelBuffer* pb)
 {
-  is = conn->getInStream();
+  this->is = is;
   this->pb = pb;
   clientpf = pb->getPF();
-  serverpf = conn->cp.pf();
+  serverpf = cp.pf();
 
   if (clientpf.equal(serverpf)) {
     /* Decode directly into the framebuffer (fast path) */
diff --git a/common/rfb/TightDecoder.h b/common/rfb/TightDecoder.h
index a44f7d8..028514a 100644
--- a/common/rfb/TightDecoder.h
+++ b/common/rfb/TightDecoder.h
@@ -28,9 +28,10 @@
   class TightDecoder : public Decoder {
 
   public:
-    TightDecoder(CConnection* conn);
+    TightDecoder();
     virtual ~TightDecoder();
-    virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb);
+    virtual void readRect(const Rect& r, rdr::InStream* is,
+                          const ConnParams& cp, ModifiablePixelBuffer* pb);
 
   private:
     rdr::U32 readCompact(rdr::InStream* is);
diff --git a/common/rfb/ZRLEDecoder.cxx b/common/rfb/ZRLEDecoder.cxx
index 60e5dd1..1328012 100644
--- a/common/rfb/ZRLEDecoder.cxx
+++ b/common/rfb/ZRLEDecoder.cxx
@@ -15,8 +15,8 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
  * USA.
  */
-#include <rfb/CMsgReader.h>
-#include <rfb/CConnection.h>
+#include <rdr/InStream.h>
+#include <rfb/ConnParams.h>
 #include <rfb/PixelBuffer.h>
 #include <rfb/ZRLEDecoder.h>
 
@@ -58,7 +58,7 @@
 #undef CPIXEL
 #undef BPP
 
-ZRLEDecoder::ZRLEDecoder(CConnection* conn) : Decoder(conn)
+ZRLEDecoder::ZRLEDecoder()
 {
 }
 
@@ -66,11 +66,11 @@
 {
 }
 
-void ZRLEDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb)
+void ZRLEDecoder::readRect(const Rect& r, rdr::InStream* is,
+                           const ConnParams& cp, ModifiablePixelBuffer* pb)
 {
-  rdr::InStream* is = conn->getInStream();
-  rdr::U8* buf = conn->reader()->getImageBuf(64 * 64 * 4);
-  const rfb::PixelFormat& pf = conn->cp.pf();
+  const rfb::PixelFormat& pf = cp.pf();
+  rdr::U8* buf[64 * 64 * 4 * pf.bpp/8];
   switch (pf.bpp) {
   case 8:  zrleDecode8 (r, is, &zis, (rdr::U8*) buf, pf, pb); break;
   case 16: zrleDecode16(r, is, &zis, (rdr::U16*)buf, pf, pb); break;
diff --git a/common/rfb/ZRLEDecoder.h b/common/rfb/ZRLEDecoder.h
index 492597e..5ab80b4 100644
--- a/common/rfb/ZRLEDecoder.h
+++ b/common/rfb/ZRLEDecoder.h
@@ -25,9 +25,10 @@
 
   class ZRLEDecoder : public Decoder {
   public:
-    ZRLEDecoder(CConnection* conn);
+    ZRLEDecoder();
     virtual ~ZRLEDecoder();
-    virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb);
+    virtual void readRect(const Rect& r, rdr::InStream* is,
+                          const ConnParams& cp, ModifiablePixelBuffer* pb);
   private:
     rdr::ZlibInStream zis;
   };
diff --git a/common/rfb/tightDecode.h b/common/rfb/tightDecode.h
index 7a1a9a2..88fda73 100644
--- a/common/rfb/tightDecode.h
+++ b/common/rfb/tightDecode.h
@@ -153,8 +153,10 @@
 
   PIXEL_T *buf;
   int stride = r.width();
-  if (directDecode) buf = (PIXEL_T *)pb->getBufferRW(r, &stride);
-  else buf = (PIXEL_T *)conn->reader()->getImageBuf(r.area());
+  if (directDecode)
+    buf = (PIXEL_T *)pb->getBufferRW(r, &stride);
+  else
+    buf = new PIXEL_T[r.area()];
 
   if (palSize == 0) {
     // Truecolor data
@@ -225,8 +227,12 @@
     }
   }
 
-  if (directDecode) pb->commitBufferRW(r);
-  else pb->imageRect(serverpf, r, buf);
+  if (directDecode)
+    pb->commitBufferRW(r);
+  else {
+    pb->imageRect(serverpf, r, buf);
+    delete [] buf;
+  }
 
   delete [] netbuf;