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-ca57d06f2519tags/v1.1.90
@@ -30,6 +30,7 @@ set(RFB_SOURCES | |||
Password.cxx | |||
PixelBuffer.cxx | |||
PixelFormat.cxx | |||
PixelTransformer.cxx | |||
RREEncoder.cxx | |||
RREDecoder.cxx | |||
RawDecoder.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()); | |||
} |
@@ -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 |
@@ -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); | |||
} | |||
@@ -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. | |||
@@ -91,10 +80,15 @@ namespace rfb { | |||
// the rectangle given to getImage(). | |||
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; |
@@ -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()); |
@@ -165,7 +165,7 @@ void TXImage::setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs) | |||
void TXImage::updateColourMap() | |||
{ | |||
if (tig != 0) | |||
tig->setColourMapEntries(0, 0, 0); | |||
tig->setColourMapEntries(0, 0); | |||
} | |||
void TXImage::lookup(int index, int* r, int* g, int* b) |