diff options
Diffstat (limited to 'libvncserver/tabletrans24template.c')
-rwxr-xr-x | libvncserver/tabletrans24template.c | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/libvncserver/tabletrans24template.c b/libvncserver/tabletrans24template.c new file mode 100755 index 0000000..4b3a0a0 --- /dev/null +++ b/libvncserver/tabletrans24template.c @@ -0,0 +1,281 @@ +/* + * tabletranstemplate.c - template for translation using lookup tables. + * + * This file shouldn't be compiled. It is included multiple times by + * translate.c, each time with different definitions of the macros IN and OUT. + * + * For each pair of values IN and OUT, this file defines two functions for + * translating a given rectangle of pixel data. One uses a single lookup + * table, and the other uses three separate lookup tables for the red, green + * and blue values. + * + * I know this code isn't nice to read because of all the macros, but + * efficiency is important here. + */ + +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>. + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * 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. + */ + +#if !defined(BPP) +#error "This file shouldn't be compiled." +#error "It is included as part of translate.c" +#endif + +#if BPP == 24 + +/* + * rfbTranslateWithSingleTableINtoOUT translates a rectangle of pixel data + * using a single lookup table. + */ + +static void +rfbTranslateWithSingleTable24to24 (char *table, rfbPixelFormat *in, + rfbPixelFormat *out, + char *iptr, char *optr, + int bytesBetweenInputLines, + int width, int height) +{ + uint8_t *ip = (uint8_t *)iptr; + uint8_t *op = (uint8_t *)optr; + int ipextra = bytesBetweenInputLines - width * 3; + uint8_t *opLineEnd; + uint8_t *t = (uint8_t *)table; + int shift = rfbEndianTest?0:8; + uint8_t c; + + while (height > 0) { + opLineEnd = op + width*3; + + while (op < opLineEnd) { + *(uint32_t*)op = t[((*(uint32_t *)ip)>>shift)&0x00ffffff]; + if(!rfbEndianTest) + memmove(op,op+1,3); + if (out->bigEndian != in->bigEndian) { + c = op[0]; op[0] = op[2]; op[2] = c; + } + op += 3; + ip += 3; + } + + ip += ipextra; + height--; + } +} + +/* + * rfbTranslateWithRGBTablesINtoOUT translates a rectangle of pixel data + * using three separate lookup tables for the red, green and blue values. + */ + +static void +rfbTranslateWithRGBTables24to24 (char *table, rfbPixelFormat *in, + rfbPixelFormat *out, + char *iptr, char *optr, + int bytesBetweenInputLines, + int width, int height) +{ + uint8_t *ip = (uint8_t *)iptr; + uint8_t *op = (uint8_t *)optr; + int ipextra = bytesBetweenInputLines - width*3; + uint8_t *opLineEnd; + uint8_t *redTable = (uint8_t *)table; + uint8_t *greenTable = redTable + 3*(in->redMax + 1); + uint8_t *blueTable = greenTable + 3*(in->greenMax + 1); + uint32_t outValue,inValue; + int shift = rfbEndianTest?0:8; + + while (height > 0) { + opLineEnd = op+3*width; + + while (op < opLineEnd) { + inValue = ((*(uint32_t *)ip)>>shift)&0x00ffffff; + outValue = (redTable[(inValue >> in->redShift) & in->redMax] | + greenTable[(inValue >> in->greenShift) & in->greenMax] | + blueTable[(inValue >> in->blueShift) & in->blueMax]); + memcpy(op,&outValue,3); + op += 3; + ip+=3; + } + ip += ipextra; + height--; + } +} + +#else + +#define IN_T CONCAT3E(uint,BPP,_t) +#define OUT_T CONCAT3E(uint,BPP,_t) +#define rfbTranslateWithSingleTable24toOUT \ + CONCAT4E(rfbTranslateWithSingleTable,24,to,BPP) +#define rfbTranslateWithSingleTableINto24 \ + CONCAT4E(rfbTranslateWithSingleTable,BPP,to,24) +#define rfbTranslateWithRGBTables24toOUT \ + CONCAT4E(rfbTranslateWithRGBTables,24,to,BPP) +#define rfbTranslateWithRGBTablesINto24 \ + CONCAT4E(rfbTranslateWithRGBTables,BPP,to,24) + +/* + * rfbTranslateWithSingleTableINtoOUT translates a rectangle of pixel data + * using a single lookup table. + */ + +static void +rfbTranslateWithSingleTable24toOUT (char *table, rfbPixelFormat *in, + rfbPixelFormat *out, + char *iptr, char *optr, + int bytesBetweenInputLines, + int width, int height) +{ + uint8_t *ip = (uint8_t *)iptr; + OUT_T *op = (OUT_T *)optr; + int ipextra = bytesBetweenInputLines - width*3; + OUT_T *opLineEnd; + OUT_T *t = (OUT_T *)table; + int shift = rfbEndianTest?0:8; + + while (height > 0) { + opLineEnd = op + width; + + while (op < opLineEnd) { + *(op++) = t[((*(uint32_t *)ip)>>shift)&0x00ffffff]; + ip+=3; + } + + ip += ipextra; + height--; + } +} + + +/* + * rfbTranslateWithRGBTablesINtoOUT translates a rectangle of pixel data + * using three separate lookup tables for the red, green and blue values. + */ + +static void +rfbTranslateWithRGBTables24toOUT (char *table, rfbPixelFormat *in, + rfbPixelFormat *out, + char *iptr, char *optr, + int bytesBetweenInputLines, + int width, int height) +{ + uint8_t *ip = (uint8_t *)iptr; + OUT_T *op = (OUT_T *)optr; + int ipextra = bytesBetweenInputLines - width*3; + OUT_T *opLineEnd; + OUT_T *redTable = (OUT_T *)table; + OUT_T *greenTable = redTable + in->redMax + 1; + OUT_T *blueTable = greenTable + in->greenMax + 1; + uint32_t inValue; + int shift = rfbEndianTest?0:8; + + while (height > 0) { + opLineEnd = &op[width]; + + while (op < opLineEnd) { + inValue = ((*(uint32_t *)ip)>>shift)&0x00ffffff; + *(op++) = (redTable[(inValue >> in->redShift) & in->redMax] | + greenTable[(inValue >> in->greenShift) & in->greenMax] | + blueTable[(inValue >> in->blueShift) & in->blueMax]); + ip+=3; + } + ip += ipextra; + height--; + } +} + +/* + * rfbTranslateWithSingleTableINto24 translates a rectangle of pixel data + * using a single lookup table. + */ + +static void +rfbTranslateWithSingleTableINto24 (char *table, rfbPixelFormat *in, + rfbPixelFormat *out, + char *iptr, char *optr, + int bytesBetweenInputLines, + int width, int height) +{ + IN_T *ip = (IN_T *)iptr; + uint8_t *op = (uint8_t *)optr; + int ipextra = bytesBetweenInputLines / sizeof(IN_T) - width; + uint8_t *opLineEnd; + uint8_t *t = (uint8_t *)table; + + while (height > 0) { + opLineEnd = op + width * 3; + + while (op < opLineEnd) { + memcpy(op,&t[3*(*(ip++))],3); + op += 3; + } + + ip += ipextra; + height--; + } +} + + +/* + * rfbTranslateWithRGBTablesINto24 translates a rectangle of pixel data + * using three separate lookup tables for the red, green and blue values. + */ + +static void +rfbTranslateWithRGBTablesINto24 (char *table, rfbPixelFormat *in, + rfbPixelFormat *out, + char *iptr, char *optr, + int bytesBetweenInputLines, + int width, int height) +{ + IN_T *ip = (IN_T *)iptr; + uint8_t *op = (uint8_t *)optr; + int ipextra = bytesBetweenInputLines / sizeof(IN_T) - width; + uint8_t *opLineEnd; + uint8_t *redTable = (uint8_t *)table; + uint8_t *greenTable = redTable + 3*(in->redMax + 1); + uint8_t *blueTable = greenTable + 3*(in->greenMax + 1); + uint32_t outValue; + + while (height > 0) { + opLineEnd = op+3*width; + + while (op < opLineEnd) { + outValue = (redTable[(*ip >> in->redShift) & in->redMax] | + greenTable[(*ip >> in->greenShift) & in->greenMax] | + blueTable[(*ip >> in->blueShift) & in->blueMax]); + memcpy(op,&outValue,3); + op += 3; + ip++; + } + ip += ipextra; + height--; + } +} + +#undef IN_T +#undef OUT_T +#undef rfbTranslateWithSingleTable24toOUT +#undef rfbTranslateWithRGBTables24toOUT +#undef rfbTranslateWithSingleTableINto24 +#undef rfbTranslateWithRGBTablesINto24 + +#endif |