summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2011-03-08 16:53:07 +0000
committerPierre Ossman <ossman@cendio.se>2011-03-08 16:53:07 +0000
commita273934db1bf1a599fb45f7e5e74436cdac99748 (patch)
treef840f0110aa4e8a137b5296d08470d01b951519b /common
parent90a57dad03ba2192ce9bef8feb66504dc7be0a05 (diff)
downloadtigervnc-a273934db1bf1a599fb45f7e5e74436cdac99748.tar.gz
tigervnc-a273934db1bf1a599fb45f7e5e74436cdac99748.zip
Split out the pixel format conversion magic to its own class and make
TransImageGetter be just an ImageGetter interface to that functionality. This allows more flexible use of the pixel conversion routines. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4338 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'common')
-rw-r--r--common/rfb/CMakeLists.txt1
-rw-r--r--common/rfb/PixelTransformer.cxx302
-rw-r--r--common/rfb/PixelTransformer.h95
-rw-r--r--common/rfb/TransImageGetter.cxx236
-rw-r--r--common/rfb/TransImageGetter.h24
-rw-r--r--common/rfb/VNCSConnectionST.cxx2
6 files changed, 427 insertions, 233 deletions
diff --git a/common/rfb/CMakeLists.txt b/common/rfb/CMakeLists.txt
index d9ccf2f4..70d52c03 100644
--- a/common/rfb/CMakeLists.txt
+++ b/common/rfb/CMakeLists.txt
@@ -30,6 +30,7 @@ set(RFB_SOURCES
Password.cxx
PixelBuffer.cxx
PixelFormat.cxx
+ PixelTransformer.cxx
RREEncoder.cxx
RREDecoder.cxx
RawDecoder.cxx
diff --git a/common/rfb/PixelTransformer.cxx b/common/rfb/PixelTransformer.cxx
new file mode 100644
index 00000000..4c57d1b0
--- /dev/null
+++ b/common/rfb/PixelTransformer.cxx
@@ -0,0 +1,302 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2011 Pierre Ossman <ossman@cendio.se> 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.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rfb/PixelFormat.h>
+#include <rfb/Exception.h>
+#include <rfb/ColourMap.h>
+#include <rfb/TrueColourMap.h>
+#include <rfb/PixelBuffer.h>
+#include <rfb/ColourCube.h>
+#include <rfb/PixelTransformer.h>
+
+using namespace rfb;
+
+static void noTransFn(void* table_,
+ const PixelFormat& inPF, void* inPtr, int inStride,
+ const PixelFormat& outPF, void* outPtr, int outStride,
+ int width, int height)
+{
+ rdr::U8* ip = (rdr::U8*)inPtr;
+ rdr::U8* op = (rdr::U8*)outPtr;
+ int inStrideBytes = inStride * (inPF.bpp/8);
+ int outStrideBytes = outStride * (outPF.bpp/8);
+ int widthBytes = width * (outPF.bpp/8);
+
+ while (height > 0) {
+ memcpy(op, ip, widthBytes);
+ ip += inStrideBytes;
+ op += outStrideBytes;
+ height--;
+ }
+}
+
+#define BPPOUT 8
+#include "transInitTempl.h"
+#define BPPIN 8
+#include "transTempl.h"
+#undef BPPIN
+#define BPPIN 16
+#include "transTempl.h"
+#undef BPPIN
+#define BPPIN 32
+#include "transTempl.h"
+#undef BPPIN
+#undef BPPOUT
+
+#define BPPOUT 16
+#include "transInitTempl.h"
+#define BPPIN 8
+#include "transTempl.h"
+#undef BPPIN
+#define BPPIN 16
+#include "transTempl.h"
+#undef BPPIN
+#define BPPIN 32
+#include "transTempl.h"
+#undef BPPIN
+#undef BPPOUT
+
+#define BPPOUT 32
+#include "transInitTempl.h"
+#define BPPIN 8
+#include "transTempl.h"
+#undef BPPIN
+#define BPPIN 16
+#include "transTempl.h"
+#undef BPPIN
+#define BPPIN 32
+#include "transTempl.h"
+#undef BPPIN
+#undef BPPOUT
+
+
+// Translation functions. Note that transSimple* is only used for 8/16bpp and
+// transRGB* is used for 16/32bpp
+
+static transFnType transSimpleFns[][3] = {
+ { transSimple8to8, transSimple8to16, transSimple8to32 },
+ { transSimple16to8, transSimple16to16, transSimple16to32 },
+};
+static transFnType transRGBFns[][3] = {
+ { transRGB16to8, transRGB16to16, transRGB16to32 },
+ { transRGB32to8, transRGB32to16, transRGB32to32 }
+};
+static transFnType transRGBCubeFns[][3] = {
+ { transRGBCube16to8, transRGBCube16to16, transRGBCube16to32 },
+ { transRGBCube32to8, transRGBCube32to16, transRGBCube32to32 }
+};
+
+// Table initialisation functions.
+
+typedef void (*initCMtoTCFnType)(rdr::U8** tablep, const PixelFormat& inPF,
+ ColourMap* cm, const PixelFormat& outPF);
+typedef void (*initTCtoTCFnType)(rdr::U8** tablep, const PixelFormat& inPF,
+ const PixelFormat& outPF);
+typedef void (*initCMtoCubeFnType)(rdr::U8** tablep, const PixelFormat& inPF,
+ ColourMap* cm, ColourCube* cube);
+typedef void (*initTCtoCubeFnType)(rdr::U8** tablep, const PixelFormat& inPF,
+ ColourCube* cube);
+
+
+static initCMtoTCFnType initSimpleCMtoTCFns[] = {
+ initSimpleCMtoTC8, initSimpleCMtoTC16, initSimpleCMtoTC32
+};
+
+static initTCtoTCFnType initSimpleTCtoTCFns[] = {
+ initSimpleTCtoTC8, initSimpleTCtoTC16, initSimpleTCtoTC32
+};
+
+static initCMtoCubeFnType initSimpleCMtoCubeFns[] = {
+ initSimpleCMtoCube8, initSimpleCMtoCube16, initSimpleCMtoCube32
+};
+
+static initTCtoCubeFnType initSimpleTCtoCubeFns[] = {
+ initSimpleTCtoCube8, initSimpleTCtoCube16, initSimpleTCtoCube32
+};
+
+static initTCtoTCFnType initRGBTCtoTCFns[] = {
+ initRGBTCtoTC8, initRGBTCtoTC16, initRGBTCtoTC32
+};
+
+static initTCtoCubeFnType initRGBTCtoCubeFns[] = {
+ initRGBTCtoCube8, initRGBTCtoCube16, initRGBTCtoCube32
+};
+
+
+PixelTransformer::PixelTransformer(bool econ)
+ : economic(econ), cmCallback(0), table(0), transFn(0), cube(0)
+{
+}
+
+PixelTransformer::~PixelTransformer()
+{
+ delete [] table;
+}
+
+void PixelTransformer::init(const PixelFormat& inPF_, ColourMap* inCM_,
+ const PixelFormat& outPF_, ColourCube* cube_,
+ setCMFnType cmCallback_, void *cbData_)
+{
+ inPF = inPF_;
+ inCM = inCM_;
+
+ outPF = outPF_;
+ cube = cube_;
+ cmCallback = cmCallback_;
+ cbData = cbData_;
+
+ if (table)
+ delete [] table;
+ table = NULL;
+ transFn = NULL;
+
+ if ((inPF.bpp != 8) && (inPF.bpp != 16) && (inPF.bpp != 32))
+ throw Exception("PixelTransformer: bpp in not 8, 16 or 32");
+
+ if ((outPF.bpp != 8) && (outPF.bpp != 16) && (outPF.bpp != 32))
+ throw Exception("PixelTransformer: bpp out not 8, 16 or 32");
+
+ if (!outPF.trueColour) {
+ if (outPF.bpp != 8)
+ throw Exception("PixelTransformer: outPF has color map but not 8bpp");
+
+ if (!inPF.trueColour) {
+ if (inPF.bpp != 8)
+ throw Exception("PixelTransformer: inPF has colorMap but not 8bpp");
+ if (!inCM)
+ throw Exception("PixelTransformer: inPF has colorMap but no colour map specified");
+
+ // CM to CM/Cube
+
+ if (cube) {
+ transFn = transSimpleFns[0][0];
+ (*initSimpleCMtoCubeFns[0]) (&table, inPF, inCM, cube);
+ } else {
+ transFn = noTransFn;
+ setColourMapEntries(0, 256);
+ }
+ return;
+ }
+
+ // TC to CM/Cube
+
+ ColourCube defaultCube(6,6,6);
+ if (!cube) cube = &defaultCube;
+
+ if ((inPF.bpp > 16) || (economic && (inPF.bpp == 16))) {
+ transFn = transRGBCubeFns[inPF.bpp/32][0];
+ (*initRGBTCtoCubeFns[0]) (&table, inPF, cube);
+ } else {
+ transFn = transSimpleFns[inPF.bpp/16][0];
+ (*initSimpleTCtoCubeFns[0]) (&table, inPF, cube);
+ }
+
+ if (cube != &defaultCube)
+ return;
+
+ if (!cmCallback)
+ throw Exception("PixelTransformer: Neither colour map callback nor colour cube provided");
+
+ cmCallback(0, 216, cube, cbData);
+ cube = 0;
+ return;
+ }
+
+ if (inPF.equal(outPF)) {
+ transFn = noTransFn;
+ return;
+ }
+
+ if (!inPF.trueColour) {
+
+ // CM to TC
+
+ if (inPF.bpp != 8)
+ throw Exception("PixelTransformer: inPF has colorMap but not 8bpp");
+ if (!inCM)
+ throw Exception("PixelTransformer: inPF has colorMap but no colour map specified");
+
+ transFn = transSimpleFns[0][outPF.bpp/16];
+ (*initSimpleCMtoTCFns[outPF.bpp/16]) (&table, inPF, inCM, outPF);
+ return;
+ }
+
+ // TC to TC
+
+ if ((inPF.bpp > 16) || (economic && (inPF.bpp == 16))) {
+ transFn = transRGBFns[inPF.bpp/32][outPF.bpp/16];
+ (*initRGBTCtoTCFns[outPF.bpp/16]) (&table, inPF, outPF);
+ } else {
+ transFn = transSimpleFns[inPF.bpp/16][outPF.bpp/16];
+ (*initSimpleTCtoTCFns[outPF.bpp/16]) (&table, inPF, outPF);
+ }
+}
+
+void PixelTransformer::setColourMapEntries(int firstCol, int nCols)
+{
+ if (nCols == 0)
+ nCols = (1 << inPF.depth) - firstCol;
+
+ if (inPF.trueColour) return; // shouldn't be called in this case
+
+ if (outPF.trueColour) {
+ (*initSimpleCMtoTCFns[outPF.bpp/16]) (&table, inPF, inCM, outPF);
+ } else if (cube) {
+ (*initSimpleCMtoCubeFns[outPF.bpp/16]) (&table, inPF, inCM, cube);
+ } else {
+ if (!cmCallback)
+ throw Exception("PixelTransformer: Neither colour map callback nor colour cube provided");
+ cmCallback(firstCol, nCols, inCM, cbData);
+ }
+}
+
+void PixelTransformer::translatePixels(void* inPtr, void* outPtr,
+ int nPixels) const
+{
+ if (!transFn)
+ throw Exception("PixelTransformer: not initialised yet");
+
+ (*transFn)(table, inPF, inPtr, nPixels,
+ outPF, outPtr, nPixels, nPixels, 1);
+}
+
+void PixelTransformer::translateRect(void* inPtr, int inStride,
+ Rect inRect,
+ void* outPtr, int outStride,
+ Point outCoord) const
+{
+ char *in, *out;
+
+ if (!transFn)
+ throw Exception("PixelTransformer: not initialised yet");
+
+ in = (char*)inPtr;
+ in += inPF.bpp/8 * inRect.tl.x;
+ in += (inStride * inPF.bpp/8) * inRect.tl.y;
+
+ out = (char*)outPtr;
+ out += outPF.bpp/8 * outCoord.x;
+ out += (outStride * outPF.bpp/8) * outCoord.y;
+
+ (*transFn)(table, inPF, in, inStride,
+ outPF, out, outStride,
+ inRect.width(), inRect.height());
+}
diff --git a/common/rfb/PixelTransformer.h b/common/rfb/PixelTransformer.h
new file mode 100644
index 00000000..b5ba8c0c
--- /dev/null
+++ b/common/rfb/PixelTransformer.h
@@ -0,0 +1,95 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2011 Pierre Ossman <ossman@cendio.se> 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.
+ */
+
+#ifndef __RFB_PIXELTRANSFORMER_H__
+#define __RFB_PIXELTRANSFORMER_H__
+
+#include <rfb/Rect.h>
+#include <rfb/PixelFormat.h>
+
+namespace rfb {
+ typedef void (*transFnType)(void* table_,
+ const PixelFormat& inPF, void* inPtr,
+ int inStride,
+ const PixelFormat& outPF, void* outPtr,
+ int outStride, int width, int height);
+
+ class SMsgWriter;
+ class ColourMap;
+ class PixelBuffer;
+ class ColourCube;
+
+ typedef void (*setCMFnType)(int firstColour, int nColours, ColourMap* cm, void* data);
+
+ class PixelTransformer {
+ public:
+
+ PixelTransformer(bool econ=false);
+ virtual ~PixelTransformer();
+
+ // init() is called to initialise the translation tables. The inPF and
+ // inCM arguments give the source format details, outPF gives the
+ // target pixel format. If the target has a colour map, then the you
+ // must specify either a colour map callback or a colour cube to indicate
+ // how the target colour map should be handled. If both are specified
+ // then the cube will be used.
+
+ void init(const PixelFormat& inPF, ColourMap* inCM,
+ const PixelFormat& outPF, ColourCube* cube = NULL,
+ setCMFnType cmCallback = NULL, void *cbData = NULL);
+
+ // setColourMapEntries() is called when the colour map specified to init()
+ // has changed. firstColour and nColours specify which part of the
+ // colour map has changed. If nColours is 0, this means the rest of the
+ // colour map. If the target also has a colour map, then the callback or
+ // cube specified to init() will be used. If the target is true colour
+ // then instead we update the internal translation table - in this case
+ // the caller should also make sure that the target surface receives an
+ // update of the relevant parts (the simplest thing to do is just update
+ // the whole framebuffer, though it is possible to be smarter than this).
+
+ void setColourMapEntries(int firstColour, int nColours);
+
+ // translatePixels() translates the given number of pixels from inPtr,
+ // putting it into the buffer pointed to by outPtr. The pixels at inPtr
+ // should be in the format given by inPF to init(), and the translated
+ // pixels will be in the format given by the outPF argument to init().
+ void translatePixels(void* inPtr, void* outPtr, int nPixels) const;
+
+ // Similar to translatePixels() but handles an arbitrary region of
+ // two pixel buffers.
+ void translateRect(void* inPtr, int inStride, Rect inRect,
+ void* outPtr, int outStride, Point outCoord) const;
+
+ private:
+ bool economic;
+
+ PixelFormat inPF;
+ ColourMap* inCM;
+
+ PixelFormat outPF;
+ setCMFnType cmCallback;
+ void *cbData;
+ ColourCube* cube;
+
+ rdr::U8* table;
+ transFnType transFn;
+ };
+}
+#endif
diff --git a/common/rfb/TransImageGetter.cxx b/common/rfb/TransImageGetter.cxx
index f5435f73..e2939c7b 100644
--- a/common/rfb/TransImageGetter.cxx
+++ b/common/rfb/TransImageGetter.cxx
@@ -15,6 +15,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -30,248 +31,49 @@
using namespace rfb;
-static void noTransFn(void* table_,
- const PixelFormat& inPF, void* inPtr, int inStride,
- const PixelFormat& outPF, void* outPtr, int outStride,
- int width, int height)
-{
- rdr::U8* ip = (rdr::U8*)inPtr;
- rdr::U8* op = (rdr::U8*)outPtr;
- int inStrideBytes = inStride * (inPF.bpp/8);
- int outStrideBytes = outStride * (outPF.bpp/8);
- int widthBytes = width * (outPF.bpp/8);
-
- while (height > 0) {
- memcpy(op, ip, widthBytes);
- ip += inStrideBytes;
- op += outStrideBytes;
- height--;
- }
-}
-
-#define BPPOUT 8
-#include "transInitTempl.h"
-#define BPPIN 8
-#include "transTempl.h"
-#undef BPPIN
-#define BPPIN 16
-#include "transTempl.h"
-#undef BPPIN
-#define BPPIN 32
-#include "transTempl.h"
-#undef BPPIN
-#undef BPPOUT
-
-#define BPPOUT 16
-#include "transInitTempl.h"
-#define BPPIN 8
-#include "transTempl.h"
-#undef BPPIN
-#define BPPIN 16
-#include "transTempl.h"
-#undef BPPIN
-#define BPPIN 32
-#include "transTempl.h"
-#undef BPPIN
-#undef BPPOUT
-
-#define BPPOUT 32
-#include "transInitTempl.h"
-#define BPPIN 8
-#include "transTempl.h"
-#undef BPPIN
-#define BPPIN 16
-#include "transTempl.h"
-#undef BPPIN
-#define BPPIN 32
-#include "transTempl.h"
-#undef BPPIN
-#undef BPPOUT
-
-
-// Translation functions. Note that transSimple* is only used for 8/16bpp and
-// transRGB* is used for 16/32bpp
-
-static transFnType transSimpleFns[][3] = {
- { transSimple8to8, transSimple8to16, transSimple8to32 },
- { transSimple16to8, transSimple16to16, transSimple16to32 },
-};
-static transFnType transRGBFns[][3] = {
- { transRGB16to8, transRGB16to16, transRGB16to32 },
- { transRGB32to8, transRGB32to16, transRGB32to32 }
-};
-static transFnType transRGBCubeFns[][3] = {
- { transRGBCube16to8, transRGBCube16to16, transRGBCube16to32 },
- { transRGBCube32to8, transRGBCube32to16, transRGBCube32to32 }
-};
-
-// Table initialisation functions.
-
-typedef void (*initCMtoTCFnType)(rdr::U8** tablep, const PixelFormat& inPF,
- ColourMap* cm, const PixelFormat& outPF);
-typedef void (*initTCtoTCFnType)(rdr::U8** tablep, const PixelFormat& inPF,
- const PixelFormat& outPF);
-typedef void (*initCMtoCubeFnType)(rdr::U8** tablep, const PixelFormat& inPF,
- ColourMap* cm, ColourCube* cube);
-typedef void (*initTCtoCubeFnType)(rdr::U8** tablep, const PixelFormat& inPF,
- ColourCube* cube);
-
-
-static initCMtoTCFnType initSimpleCMtoTCFns[] = {
- initSimpleCMtoTC8, initSimpleCMtoTC16, initSimpleCMtoTC32
-};
-
-static initTCtoTCFnType initSimpleTCtoTCFns[] = {
- initSimpleTCtoTC8, initSimpleTCtoTC16, initSimpleTCtoTC32
-};
-
-static initCMtoCubeFnType initSimpleCMtoCubeFns[] = {
- initSimpleCMtoCube8, initSimpleCMtoCube16, initSimpleCMtoCube32
-};
-
-static initTCtoCubeFnType initSimpleTCtoCubeFns[] = {
- initSimpleTCtoCube8, initSimpleTCtoCube16, initSimpleTCtoCube32
-};
-
-static initTCtoTCFnType initRGBTCtoTCFns[] = {
- initRGBTCtoTC8, initRGBTCtoTC16, initRGBTCtoTC32
-};
-
-static initTCtoCubeFnType initRGBTCtoCubeFns[] = {
- initRGBTCtoCube8, initRGBTCtoCube16, initRGBTCtoCube32
-};
-
-
TransImageGetter::TransImageGetter(bool econ)
- : economic(econ), pb(0), table(0), transFn(0), cube(0)
+ : PixelTransformer(econ), pb(0)
{
}
TransImageGetter::~TransImageGetter()
{
- delete [] table;
}
void TransImageGetter::init(PixelBuffer* pb_, const PixelFormat& out,
- SMsgWriter* writer, ColourCube* cube_)
+ SMsgWriter* writer_, ColourCube* cube_)
{
pb = pb_;
- outPF = out;
- transFn = 0;
- cube = cube_;
- const PixelFormat& inPF = pb->getPF();
-
- if ((inPF.bpp != 8) && (inPF.bpp != 16) && (inPF.bpp != 32))
- throw Exception("TransImageGetter: bpp in not 8, 16 or 32");
+ writer = writer_;
- if ((outPF.bpp != 8) && (outPF.bpp != 16) && (outPF.bpp != 32))
- throw Exception("TransImageGetter: bpp out not 8, 16 or 32");
-
- if (!outPF.trueColour) {
- if (outPF.bpp != 8)
- throw Exception("TransImageGetter: outPF has color map but not 8bpp");
-
- if (!inPF.trueColour) {
- if (inPF.bpp != 8)
- throw Exception("TransImageGetter: inPF has colorMap but not 8bpp");
-
- // CM to CM/Cube
-
- if (cube) {
- transFn = transSimpleFns[inPF.bpp/16][outPF.bpp/16];
- (*initSimpleCMtoCubeFns[outPF.bpp/16]) (&table, inPF,
- pb->getColourMap(), cube);
- } else {
- transFn = noTransFn;
- setColourMapEntries(0, 256, writer);
- }
- return;
- }
-
- // TC to CM/Cube
-
- ColourCube defaultCube(6,6,6);
- if (!cube) cube = &defaultCube;
-
- if ((inPF.bpp > 16) || (economic && (inPF.bpp == 16))) {
- transFn = transRGBCubeFns[inPF.bpp/32][outPF.bpp/16];
- (*initRGBTCtoCubeFns[outPF.bpp/16]) (&table, inPF, cube);
- } else {
- transFn = transSimpleFns[inPF.bpp/16][outPF.bpp/16];
- (*initSimpleTCtoCubeFns[outPF.bpp/16]) (&table, inPF, cube);
- }
-
- if (cube != &defaultCube)
- return;
-
- if (writer) writer->writeSetColourMapEntries(0, 216, cube);
- cube = 0;
- return;
- }
-
- if (inPF.equal(outPF)) {
- transFn = noTransFn;
- return;
- }
-
- if (!inPF.trueColour) {
-
- // CM to TC
-
- if (inPF.bpp != 8)
- throw Exception("TransImageGetter: inPF has colorMap but not 8bpp");
- transFn = transSimpleFns[inPF.bpp/16][outPF.bpp/16];
- (*initSimpleCMtoTCFns[outPF.bpp/16]) (&table, inPF, pb->getColourMap(),
- outPF);
- return;
- }
-
- // TC to TC
-
- if ((inPF.bpp > 16) || (economic && (inPF.bpp == 16))) {
- transFn = transRGBFns[inPF.bpp/32][outPF.bpp/16];
- (*initRGBTCtoTCFns[outPF.bpp/16]) (&table, inPF, outPF);
- } else {
- transFn = transSimpleFns[inPF.bpp/16][outPF.bpp/16];
- (*initSimpleTCtoTCFns[outPF.bpp/16]) (&table, inPF, outPF);
- }
+ PixelTransformer::init(pb->getPF(), pb->getColourMap(), out, cube_,
+ cmCallback, this);
}
-void TransImageGetter::setColourMapEntries(int firstCol, int nCols,
- SMsgWriter* writer)
+void TransImageGetter::setColourMapEntries(int firstCol, int nCols)
{
- if (nCols == 0)
- nCols = (1 << pb->getPF().depth) - firstCol;
- if (pb->getPF().trueColour) return; // shouldn't be called in this case
-
- if (outPF.trueColour) {
- (*initSimpleCMtoTCFns[outPF.bpp/16]) (&table, pb->getPF(),
- pb->getColourMap(), outPF);
- } else if (cube) {
- (*initSimpleCMtoCubeFns[outPF.bpp/16]) (&table, pb->getPF(),
- pb->getColourMap(), cube);
- } else if (writer && pb->getColourMap()) {
- writer->writeSetColourMapEntries(firstCol, nCols, pb->getColourMap());
- }
+ PixelTransformer::setColourMapEntries(firstCol, nCols);
}
void TransImageGetter::getImage(void* outPtr, const Rect& r, int outStride)
{
- if (!transFn)
- throw Exception("TransImageGetter: not initialised yet");
-
int inStride;
const rdr::U8* inPtr = pb->getPixelsR(r.translate(offset.negate()), &inStride);
if (!outStride) outStride = r.width();
- (*transFn)(table, pb->getPF(), (void*)inPtr, inStride,
- outPF, outPtr, outStride, r.width(), r.height());
+ translateRect((void*)inPtr, inStride, r, outPtr, outStride, r.tl);
}
-void TransImageGetter::translatePixels(void* inPtr, void* outPtr,
- int nPixels) const
+void TransImageGetter::cmCallback(int firstColour, int nColours,
+ ColourMap* cm, void* data)
{
- (*transFn)(table, pb->getPF(), inPtr, nPixels,
- outPF, outPtr, nPixels, nPixels, 1);
+ TransImageGetter *self;
+
+ assert(data);
+ self = (TransImageGetter*)data;
+
+ if (self->writer)
+ self->writer->writeSetColourMapEntries(firstColour, nColours, cm);
}
+
diff --git a/common/rfb/TransImageGetter.h b/common/rfb/TransImageGetter.h
index 5328e6d0..7942247a 100644
--- a/common/rfb/TransImageGetter.h
+++ b/common/rfb/TransImageGetter.h
@@ -25,21 +25,18 @@
#include <rfb/Rect.h>
#include <rfb/PixelFormat.h>
+#include <rfb/PixelTransformer.h>
#include <rfb/ImageGetter.h>
namespace rfb {
- typedef void (*transFnType)(void* table_,
- const PixelFormat& inPF, void* inPtr,
- int inStride,
- const PixelFormat& outPF, void* outPtr,
- int outStride, int width, int height);
class SMsgWriter;
class ColourMap;
class PixelBuffer;
class ColourCube;
- class TransImageGetter : public ImageGetter {
+ class TransImageGetter : public ImageGetter,
+ public PixelTransformer {
public:
TransImageGetter(bool econ=false);
@@ -65,8 +62,7 @@ namespace rfb {
// framebuffer (the simplest thing to do is just update the whole
// framebuffer, though it is possible to be smarter than this).
- void setColourMapEntries(int firstColour, int nColours,
- SMsgWriter* writer=0);
+ void setColourMapEntries(int firstColour, int nColours);
// getImage() gets the given rectangle of data from the PixelBuffer,
// translates it into the client's pixel format and puts it in the buffer
@@ -75,13 +71,6 @@ namespace rfb {
// padding will be outStride-r.width() pixels).
void getImage(void* outPtr, const Rect& r, int outStride=0);
- // translatePixels() translates the given number of pixels from inPtr,
- // putting it into the buffer pointed to by outPtr. The pixels at inPtr
- // should be in the same format as the PixelBuffer, and the translated
- // pixels will be in the format previously given by the outPF argument to
- // init(). Note that this call does not use the PixelBuffer's pixel data.
- void translatePixels(void* inPtr, void* outPtr, int nPixels) const;
-
// setPixelBuffer() changes the pixel buffer to be used. The new pixel
// buffer MUST have the same pixel format as the old one - if not you
// should call init() instead.
@@ -92,9 +81,14 @@ namespace rfb {
void setOffset(const Point& offset_) { offset = offset_; }
private:
+ static void cmCallback(int firstColour, int nColours,
+ ColourMap* cm, void* data);
+
+ private:
bool economic;
PixelBuffer* pb;
PixelFormat outPF;
+ SMsgWriter* writer;
rdr::U8* table;
transFnType transFn;
ColourCube* cube;
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index e1c8cf86..5add7eae 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -760,7 +760,7 @@ void VNCSConnectionST::setColourMapEntries(int firstColour, int nColours)
if (!readyForSetColourMapEntries) return;
if (server->pb->getPF().trueColour) return;
- image_getter.setColourMapEntries(firstColour, nColours, writer());
+ image_getter.setColourMapEntries(firstColour, nColours);
if (cp.pf().trueColour) {
updates.add_changed(server->pb->getRect());