Move image encoding logic into a central EncodeManager class

This allows us to apply a lot more server logic
independently of which encoder is in use.

Most of this class are things moved over from the
Tight encoder.
diff --git a/common/rfb/Encoder.h b/common/rfb/Encoder.h
index aeeb5c3..62cb6eb 100644
--- a/common/rfb/Encoder.h
+++ b/common/rfb/Encoder.h
@@ -20,31 +20,75 @@
 #ifndef __RFB_ENCODER_H__
 #define __RFB_ENCODER_H__
 
+#include <rdr/types.h>
 #include <rfb/Rect.h>
 
 namespace rfb {
   class SConnection;
   class PixelBuffer;
+  class Palette;
+  class PixelFormat;
+
+  enum EncoderFlags {
+    // A constant for encoders that don't need anything special
+    EncoderPlain = 0,
+    // Give us the raw frame buffer, and not something converted to
+    // the what the client is asking for.
+    EncoderUseNativePF = 1 << 0,
+  };
 
   class Encoder {
   public:
-    Encoder(SConnection* conn);
+    Encoder(SConnection* conn, int encoding,
+            enum EncoderFlags flags, unsigned int maxPaletteSize);
     virtual ~Encoder();
 
+    // isSupported() should return a boolean indiciating if this encoder
+    // is okay to use with the current connection. This usually involves
+    // checking the list of encodings in the connection parameters.
+    virtual bool isSupported()=0;
+
     virtual void setCompressLevel(int level) {};
     virtual void setQualityLevel(int level) {};
     virtual void setFineQualityLevel(int quality, int subsampling) {};
-    virtual int getNumRects(const Rect &r) { return 1; }
 
     // writeRect() is the main interface that encodes the given rectangle
     // with data from the PixelBuffer onto the SConnection given at
-    // encoder creation. The PixelFormat of the PixelBuffer might not
-    // match the ConnParams and it is up ot the encoder to do
-    // any necessary conversion.
-    virtual void writeRect(const Rect& r, PixelBuffer* pb)=0;
+    // encoder creation.
+    //
+    // The PixelBuffer will be in the PixelFormat specified in ConnParams
+    // unless the flag UseNativePF is specified. In that case the
+    // PixelBuffer will remain in its native format and encoder will have
+    // to handle any conversion itself.
+    //
+    // The Palette will always be in the PixelFormat specified in
+    // ConnParams. An empty palette indicates a large number of colours,
+    // but could still be less than maxPaletteSize.
+    virtual void writeRect(const PixelBuffer* pb, const Palette& palette)=0;
 
-    static bool supported(int encoding);
-    static Encoder* createEncoder(int encoding, SConnection* conn);
+    // writeSolidRect() is a short cut in order to encode single colour
+    // rectangles efficiently without having to create a fake single
+    // colour PixelBuffer. The colour argument follows the same semantics
+    // as the PixelBuffer for writeRect().
+    //
+    // Note that there is a default implementation that can be called
+    // using Encoder::writeSolidRect() in the event that there is no
+    // efficient short cut.
+    virtual void writeSolidRect(int width, int height,
+                                const PixelFormat& pf,
+                                const rdr::U8* colour)=0;
+
+  protected:
+    // Helper method for redirecting a single colour palette to the
+    // short cut method.
+    void writeSolidRect(const PixelBuffer* pb, const Palette& palette);
+
+  public:
+    const int encoding;
+    const enum EncoderFlags flags;
+
+    // Maximum size of the palette per rect
+    const unsigned int maxPaletteSize;
 
   protected:
     SConnection* conn;