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/TightEncoderBPP.cxx b/common/rfb/TightEncoderBPP.cxx
new file mode 100644
index 0000000..8874662
--- /dev/null
+++ b/common/rfb/TightEncoderBPP.cxx
@@ -0,0 +1,165 @@
+/* Copyright (C) 2000-2003 Constantin Kaplinsky.  All Rights Reserved.
+ * Copyright (C) 2011 D. R. Commander.  All Rights Reserved.
+ * Copyright 2014 Pierre Ossman for Cendio AB
+ * 
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+
+#define CONCAT2(a,b) a##b
+#define CONCAT2E(a,b) CONCAT2(a,b)
+
+#define UBPP CONCAT2E(U,BPP)
+
+void TightEncoder::writeMonoRect(int width, int height,
+                                 const rdr::UBPP* buffer, int stride,
+                                 const PixelFormat& pf,
+                                 const Palette& palette)
+{
+  rdr::OutStream* os;
+
+  const int streamId = 1;
+  rdr::UBPP pal[2];
+
+  int length;
+  rdr::OutStream* zos;
+
+  assert(palette.size() == 2);
+
+  os = conn->getOutStream();
+
+  os->writeU8((streamId | tightExplicitFilter) << 4);
+  os->writeU8(tightFilterPalette);
+
+  // Write the palette
+  pal[0] = (rdr::UBPP)palette.getColour(0);
+  pal[1] = (rdr::UBPP)palette.getColour(1);
+
+  os->writeU8(1);
+  writePixels((rdr::U8*)pal, pf, 2, os);
+
+  // Set up compression
+  length = (width + 7)/8 * height;
+  zos = getZlibOutStream(streamId, monoZlibLevel, length);
+
+  // Encode the data
+  rdr::UBPP bg;
+  unsigned int value, mask;
+  int pad, aligned_width;
+  int x, y, bg_bits;
+
+  bg = pal[0];
+  aligned_width = width - width % 8;
+  pad = stride - width;
+
+  for (y = 0; y < height; y++) {
+    for (x = 0; x < aligned_width; x += 8) {
+      for (bg_bits = 0; bg_bits < 8; bg_bits++) {
+        if (*buffer++ != bg)
+          break;
+      }
+      if (bg_bits == 8) {
+        zos->writeU8(0);
+        continue;
+      }
+      mask = 0x80 >> bg_bits;
+      value = mask;
+      for (bg_bits++; bg_bits < 8; bg_bits++) {
+        mask >>= 1;
+        if (*buffer++ != bg) {
+          value |= mask;
+        }
+      }
+      zos->writeU8(value);
+    }
+
+    if (x < width) {
+      mask = 0x80;
+      value = 0;
+
+      for (; x < width; x++) {
+        if (*buffer++ != bg) {
+          value |= mask;
+        }
+        mask >>= 1;
+      }
+      zos->writeU8(value);
+    }
+
+    buffer += pad;
+  }
+
+  // Finish the zlib stream
+  flushZlibOutStream(zos);
+}
+
+#if (BPP != 8)
+void TightEncoder::writeIndexedRect(int width, int height,
+                                    const rdr::UBPP* buffer, int stride,
+                                    const PixelFormat& pf,
+                                    const Palette& palette)
+{
+  rdr::OutStream* os;
+
+  const int streamId = 2;
+  rdr::UBPP pal[256];
+
+  rdr::OutStream* zos;
+
+  int pad;
+  rdr::UBPP prevColour;
+  unsigned char idx;
+
+  assert(palette.size() > 0);
+  assert(palette.size() <= 256);
+
+  os = conn->getOutStream();
+
+  os->writeU8((streamId | tightExplicitFilter) << 4);
+  os->writeU8(tightFilterPalette);
+
+  // Write the palette
+  for (int i = 0; i < palette.size(); i++)
+    pal[i] = (rdr::UBPP)palette.getColour(i);
+
+  os->writeU8(palette.size() - 1);
+  writePixels((rdr::U8*)pal, pf, palette.size(), os);
+
+  // Set up compression
+  zos = getZlibOutStream(streamId, idxZlibLevel, width * height);
+
+  // Encode the data
+  pad = stride - width;
+
+  prevColour = *buffer;
+  idx = palette.lookup(*buffer);
+
+  while (height--) {
+    int w = width;
+    while (w--) {
+      if (*buffer != prevColour) {
+        prevColour = *buffer;
+        idx = palette.lookup(*buffer);
+      }
+      zos->writeU8(idx);
+      buffer++;
+    }
+    buffer += pad;
+  }
+
+  // Finish the zlib stream
+  flushZlibOutStream(zos);
+}
+#endif  // #if (BPP != 8)