123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- /* 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.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <rfb/PixelFormat.h>
- #include <rfb/Exception.h>
- #include <rfb/ConnParams.h>
- #include <rfb/SMsgWriter.h>
- #include <rfb/ColourMap.h>
- #include <rfb/TrueColourMap.h>
- #include <rfb/PixelBuffer.h>
- #include <rfb/ColourCube.h>
- #include <rfb/TransImageGetter.h>
-
- using namespace rfb;
-
- const PixelFormat bgr233PF(8, 8, false, true, 7, 7, 3, 0, 3, 6);
-
- 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)
- {
- }
-
- TransImageGetter::~TransImageGetter()
- {
- delete [] table;
- }
-
- void TransImageGetter::init(PixelBuffer* pb_, const PixelFormat& out,
- 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");
-
- 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);
- }
- }
-
- void TransImageGetter::setColourMapEntries(int firstCol, int nCols,
- SMsgWriter* writer)
- {
- 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());
- }
- }
-
- 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());
- }
-
- void TransImageGetter::translatePixels(void* inPtr, void* outPtr,
- int nPixels) const
- {
- (*transFn)(table, pb->getPF(), inPtr, nPixels,
- outPF, outPtr, nPixels, nPixels, 1);
- }
|