summaryrefslogtreecommitdiffstats
path: root/rfb/transInitTempl.h
diff options
context:
space:
mode:
Diffstat (limited to 'rfb/transInitTempl.h')
-rw-r--r--rfb/transInitTempl.h254
1 files changed, 254 insertions, 0 deletions
diff --git a/rfb/transInitTempl.h b/rfb/transInitTempl.h
new file mode 100644
index 00000000..2658f9f0
--- /dev/null
+++ b/rfb/transInitTempl.h
@@ -0,0 +1,254 @@
+/* Copyright (C) 2002-2003 RealVNC Ltd. 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
+ * 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.
+ */
+//
+// transInitTempl.h - templates for functions to initialise lookup tables for
+// the translation functions.
+//
+// This file is #included after having set the following macros:
+// BPPOUT - 8, 16 or 32
+
+#if !defined(BPPOUT)
+#error "transInitTempl.h: BPPOUT not defined"
+#endif
+
+namespace rfb {
+
+// CONCAT2E concatenates its arguments, expanding them if they are macros
+
+#ifndef CONCAT2E
+#define CONCAT2(a,b) a##b
+#define CONCAT2E(a,b) CONCAT2(a,b)
+#endif
+
+#ifndef SWAP16
+#define SWAP16(n) ((((n) & 0xff) << 8) | (((n) >> 8) & 0xff))
+#endif
+
+#ifndef SWAP32
+#define SWAP32(n) (((n) >> 24) | (((n) & 0x00ff0000) >> 8) | \
+ (((n) & 0x0000ff00) << 8) | ((n) << 24))
+#endif
+
+#define OUTPIXEL rdr::CONCAT2E(U,BPPOUT)
+#define SWAPOUT CONCAT2E(SWAP,BPPOUT)
+#define initSimpleCMtoTCOUT CONCAT2E(initSimpleCMtoTC,BPPOUT)
+#define initSimpleTCtoTCOUT CONCAT2E(initSimpleTCtoTC,BPPOUT)
+#define initSimpleCMtoCubeOUT CONCAT2E(initSimpleCMtoCube,BPPOUT)
+#define initSimpleTCtoCubeOUT CONCAT2E(initSimpleTCtoCube,BPPOUT)
+#define initRGBTCtoTCOUT CONCAT2E(initRGBTCtoTC,BPPOUT)
+#define initRGBTCtoCubeOUT CONCAT2E(initRGBTCtoCube,BPPOUT)
+#define initOneRGBTableOUT CONCAT2E(initOneRGBTable,BPPOUT)
+#define initOneRGBCubeTableOUT CONCAT2E(initOneRGBCubeTable,BPPOUT)
+
+#ifndef TRANS_INIT_TEMPL_ENDIAN_TEST
+#define TRANS_INIT_TEMPL_ENDIAN_TEST
+ static rdr::U32 endianTest = 1;
+ static bool nativeBigEndian = *(rdr::U8*)(&endianTest) != 1;
+#endif
+
+void initSimpleCMtoTCOUT (rdr::U8** tablep, const PixelFormat& inPF,
+ ColourMap* cm, const PixelFormat& outPF)
+{
+ if (inPF.bpp != 8 && inPF.bigEndian != nativeBigEndian)
+ throw Exception("Internal error: inPF is not native endian");
+
+ int size = 1 << inPF.bpp;
+
+ delete [] *tablep;
+ *tablep = new rdr::U8[size * sizeof(OUTPIXEL)];
+ OUTPIXEL* table = (OUTPIXEL*)*tablep;
+
+ for (int i = 0; i < size; i++) {
+ int r,g,b;
+ cm->lookup(i,&r,&g,&b);
+
+ table[i] = ((((r * outPF.redMax + 32767) / 65535) << outPF.redShift) |
+ (((g * outPF.greenMax + 32767) / 65535) << outPF.greenShift) |
+ (((b * outPF.blueMax + 32767) / 65535) << outPF.blueShift));
+#if (BPPOUT != 8)
+ if (outPF.bigEndian != nativeBigEndian)
+ table[i] = SWAPOUT (table[i]);
+#endif
+ }
+}
+
+void initSimpleTCtoTCOUT (rdr::U8** tablep, const PixelFormat& inPF,
+ const PixelFormat& outPF)
+{
+ if (inPF.bpp != 8 && inPF.bigEndian != nativeBigEndian)
+ throw Exception("Internal error: inPF is not native endian");
+
+ int size = 1 << inPF.bpp;
+
+ delete [] *tablep;
+ *tablep = new rdr::U8[size * sizeof(OUTPIXEL)];
+ OUTPIXEL* table = (OUTPIXEL*)*tablep;
+
+ for (int i = 0; i < size; i++) {
+ int r = (i >> inPF.redShift) & inPF.redMax;
+ int g = (i >> inPF.greenShift) & inPF.greenMax;
+ int b = (i >> inPF.blueShift) & inPF.blueMax;
+
+ r = (r * outPF.redMax + inPF.redMax/2) / inPF.redMax;
+ g = (g * outPF.greenMax + inPF.greenMax/2) / inPF.greenMax;
+ b = (b * outPF.blueMax + inPF.blueMax/2) / inPF.blueMax;
+
+ table[i] = ((r << outPF.redShift) |
+ (g << outPF.greenShift) |
+ (b << outPF.blueShift));
+#if (BPPOUT != 8)
+ if (outPF.bigEndian != nativeBigEndian)
+ table[i] = SWAPOUT (table[i]);
+#endif
+ }
+}
+
+void initSimpleCMtoCubeOUT (rdr::U8** tablep, const PixelFormat& inPF,
+ ColourMap* cm, ColourCube* cube)
+{
+ if (inPF.bpp != 8 && inPF.bigEndian != nativeBigEndian)
+ throw Exception("Internal error: inPF is not native endian");
+
+ int size = 1 << inPF.bpp;
+
+ delete [] *tablep;
+ *tablep = new rdr::U8[size * sizeof(OUTPIXEL)];
+ OUTPIXEL* table = (OUTPIXEL*)*tablep;
+
+ for (int i = 0; i < size; i++) {
+ int r,g,b;
+ cm->lookup(i,&r,&g,&b);
+ r = (r * (cube->nRed-1) + 32767) / 65535;
+ g = (g * (cube->nGreen-1) + 32767) / 65535;
+ b = (b * (cube->nBlue-1) + 32767) / 65535;
+ table[i] = cube->lookup(r, g, b);
+ }
+}
+
+void initSimpleTCtoCubeOUT (rdr::U8** tablep, const PixelFormat& inPF,
+ ColourCube* cube)
+{
+ if (inPF.bpp != 8 && inPF.bigEndian != nativeBigEndian)
+ throw Exception("Internal error: inPF is not native endian");
+
+ int size = 1 << inPF.bpp;
+
+ delete [] *tablep;
+ *tablep = new rdr::U8[size * sizeof(OUTPIXEL)];
+ OUTPIXEL* table = (OUTPIXEL*)*tablep;
+
+ for (int i = 0; i < size; i++) {
+ int r = (i >> inPF.redShift) & inPF.redMax;
+ int g = (i >> inPF.greenShift) & inPF.greenMax;
+ int b = (i >> inPF.blueShift) & inPF.blueMax;
+
+ r = (r * (cube->nRed-1) + inPF.redMax/2) / inPF.redMax;
+ g = (g * (cube->nGreen-1) + inPF.greenMax/2) / inPF.greenMax;
+ b = (b * (cube->nBlue-1) + inPF.blueMax/2) / inPF.blueMax;
+
+ table[i] = cube->lookup(r, g, b);
+ }
+}
+
+void initOneRGBTableOUT (OUTPIXEL* table, int inMax, int outMax,
+ int outShift, bool swap)
+{
+ int size = inMax + 1;
+
+ for (int i = 0; i < size; i++) {
+ table[i] = ((i * outMax + inMax / 2) / inMax) << outShift;
+#if (BPPOUT != 8)
+ if (swap)
+ table[i] = SWAPOUT (table[i]);
+#endif
+ }
+}
+
+void initRGBTCtoTCOUT (rdr::U8** tablep, const PixelFormat& inPF,
+ const PixelFormat& outPF)
+{
+ if (inPF.bpp != 8 && inPF.bigEndian != nativeBigEndian)
+ throw Exception("Internal error: inPF is not native endian");
+
+ int size = inPF.redMax + inPF.greenMax + inPF.blueMax + 3;
+
+ delete [] *tablep;
+ *tablep = new rdr::U8[size * sizeof(OUTPIXEL)];
+
+ OUTPIXEL* redTable = (OUTPIXEL*)*tablep;
+ OUTPIXEL* greenTable = redTable + inPF.redMax + 1;
+ OUTPIXEL* blueTable = greenTable + inPF.greenMax + 1;
+
+ bool swap = (outPF.bigEndian != nativeBigEndian);
+
+ initOneRGBTableOUT (redTable, inPF.redMax, outPF.redMax,
+ outPF.redShift, swap);
+ initOneRGBTableOUT (greenTable, inPF.greenMax, outPF.greenMax,
+ outPF.greenShift, swap);
+ initOneRGBTableOUT (blueTable, inPF.blueMax, outPF.blueMax,
+ outPF.blueShift, swap);
+}
+
+
+void initOneRGBCubeTableOUT (OUTPIXEL* table, int inMax, int outMax,
+ int outMult)
+{
+ int size = inMax + 1;
+
+ for (int i = 0; i < size; i++) {
+ table[i] = ((i * outMax + inMax / 2) / inMax) * outMult;
+ }
+}
+
+void initRGBTCtoCubeOUT (rdr::U8** tablep, const PixelFormat& inPF,
+ ColourCube* cube)
+{
+ if (inPF.bpp != 8 && inPF.bigEndian != nativeBigEndian)
+ throw Exception("Internal error: inPF is not native endian");
+
+ int size = inPF.redMax + inPF.greenMax + inPF.blueMax + 3 + cube->size();
+
+ delete [] *tablep;
+ *tablep = new rdr::U8[size * sizeof(OUTPIXEL)];
+
+ OUTPIXEL* redTable = (OUTPIXEL*)*tablep;
+ OUTPIXEL* greenTable = redTable + inPF.redMax + 1;
+ OUTPIXEL* blueTable = greenTable + inPF.greenMax + 1;
+ OUTPIXEL* cubeTable = blueTable + inPF.blueMax + 1;
+
+ initOneRGBCubeTableOUT (redTable, inPF.redMax, cube->nRed-1,
+ cube->redMult());
+ initOneRGBCubeTableOUT (greenTable, inPF.greenMax, cube->nGreen-1,
+ cube->greenMult());
+ initOneRGBCubeTableOUT (blueTable, inPF.blueMax, cube->nBlue-1,
+ cube->blueMult());
+ for (int i = 0; i < cube->size(); i++) {
+ cubeTable[i] = cube->table[i];
+ }
+}
+
+#undef OUTPIXEL
+#undef initSimpleCMtoTCOUT
+#undef initSimpleTCtoTCOUT
+#undef initSimpleCMtoCubeOUT
+#undef initSimpleTCtoCubeOUT
+#undef initRGBTCtoTCOUT
+#undef initRGBTCtoCubeOUT
+#undef initOneRGBTableOUT
+#undef initOneRGBCubeTableOUT
+}