diff options
Diffstat (limited to 'rfb/transInitTempl.h')
-rw-r--r-- | rfb/transInitTempl.h | 254 |
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 +} |