Home | History | Annotate | Download | only in libvncserver
      1 /*
      2  * tabletranstemplate.c - template for translation using lookup tables.
      3  *
      4  * This file shouldn't be compiled.  It is included multiple times by
      5  * translate.c, each time with different definitions of the macros IN and OUT.
      6  *
      7  * For each pair of values IN and OUT, this file defines two functions for
      8  * translating a given rectangle of pixel data.  One uses a single lookup
      9  * table, and the other uses three separate lookup tables for the red, green
     10  * and blue values.
     11  *
     12  * I know this code isn't nice to read because of all the macros, but
     13  * efficiency is important here.
     14  */
     15 
     16 /*
     17  *  OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk (at) incompleteness.net>.
     18  *  Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
     19  *  All Rights Reserved.
     20  *
     21  *  This is free software; you can redistribute it and/or modify
     22  *  it under the terms of the GNU General Public License as published by
     23  *  the Free Software Foundation; either version 2 of the License, or
     24  *  (at your option) any later version.
     25  *
     26  *  This software is distributed in the hope that it will be useful,
     27  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     28  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     29  *  GNU General Public License for more details.
     30  *
     31  *  You should have received a copy of the GNU General Public License
     32  *  along with this software; if not, write to the Free Software
     33  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
     34  *  USA.
     35  */
     36 
     37 #if !defined(BPP)
     38 #error "This file shouldn't be compiled."
     39 #error "It is included as part of translate.c"
     40 #endif
     41 
     42 #if BPP == 24
     43 
     44 /*
     45  * rfbTranslateWithSingleTableINtoOUT translates a rectangle of pixel data
     46  * using a single lookup table.
     47  */
     48 
     49 static void
     50 rfbTranslateWithSingleTable24to24 (char *table, rfbPixelFormat *in,
     51                                     rfbPixelFormat *out,
     52                                     char *iptr, char *optr,
     53                                     int bytesBetweenInputLines,
     54                                     int width, int height)
     55 {
     56     uint8_t *ip = (uint8_t *)iptr;
     57     uint8_t *op = (uint8_t *)optr;
     58     int ipextra = bytesBetweenInputLines - width * 3;
     59     uint8_t *opLineEnd;
     60     uint8_t *t = (uint8_t *)table;
     61     int shift = rfbEndianTest?0:8;
     62     uint8_t c;
     63 
     64     while (height > 0) {
     65         opLineEnd = op + width*3;
     66 
     67         while (op < opLineEnd) {
     68 	    *(uint32_t*)op = t[((*(uint32_t *)ip)>>shift)&0x00ffffff];
     69 	    if(!rfbEndianTest)
     70 	      memmove(op,op+1,3);
     71 	    if (out->bigEndian != in->bigEndian) {
     72 	      c = op[0]; op[0] = op[2]; op[2] = c;
     73 	    }
     74 	    op += 3;
     75 	    ip += 3;
     76         }
     77 
     78         ip += ipextra;
     79         height--;
     80     }
     81 }
     82 
     83 /*
     84  * rfbTranslateWithRGBTablesINtoOUT translates a rectangle of pixel data
     85  * using three separate lookup tables for the red, green and blue values.
     86  */
     87 
     88 static void
     89 rfbTranslateWithRGBTables24to24 (char *table, rfbPixelFormat *in,
     90                                   rfbPixelFormat *out,
     91                                   char *iptr, char *optr,
     92                                   int bytesBetweenInputLines,
     93                                   int width, int height)
     94 {
     95     uint8_t *ip = (uint8_t *)iptr;
     96     uint8_t *op = (uint8_t *)optr;
     97     int ipextra = bytesBetweenInputLines - width*3;
     98     uint8_t *opLineEnd;
     99     uint8_t *redTable = (uint8_t *)table;
    100     uint8_t *greenTable = redTable + 3*(in->redMax + 1);
    101     uint8_t *blueTable = greenTable + 3*(in->greenMax + 1);
    102     uint32_t outValue,inValue;
    103     int shift = rfbEndianTest?0:8;
    104 
    105     while (height > 0) {
    106         opLineEnd = op+3*width;
    107 
    108         while (op < opLineEnd) {
    109 	    inValue = ((*(uint32_t *)ip)>>shift)&0x00ffffff;
    110             outValue = (redTable[(inValue >> in->redShift) & in->redMax] |
    111                        greenTable[(inValue >> in->greenShift) & in->greenMax] |
    112                        blueTable[(inValue >> in->blueShift) & in->blueMax]);
    113 	    memcpy(op,&outValue,3);
    114 	    op += 3;
    115             ip+=3;
    116         }
    117         ip += ipextra;
    118         height--;
    119     }
    120 }
    121 
    122 #else
    123 
    124 #define IN_T CONCAT3E(uint,BPP,_t)
    125 #define OUT_T CONCAT3E(uint,BPP,_t)
    126 #define rfbTranslateWithSingleTable24toOUT \
    127                                 CONCAT4E(rfbTranslateWithSingleTable,24,to,BPP)
    128 #define rfbTranslateWithSingleTableINto24 \
    129                                 CONCAT4E(rfbTranslateWithSingleTable,BPP,to,24)
    130 #define rfbTranslateWithRGBTables24toOUT \
    131                                 CONCAT4E(rfbTranslateWithRGBTables,24,to,BPP)
    132 #define rfbTranslateWithRGBTablesINto24 \
    133                                 CONCAT4E(rfbTranslateWithRGBTables,BPP,to,24)
    134 
    135 /*
    136  * rfbTranslateWithSingleTableINtoOUT translates a rectangle of pixel data
    137  * using a single lookup table.
    138  */
    139 
    140 static void
    141 rfbTranslateWithSingleTable24toOUT (char *table, rfbPixelFormat *in,
    142                                     rfbPixelFormat *out,
    143                                     char *iptr, char *optr,
    144                                     int bytesBetweenInputLines,
    145                                     int width, int height)
    146 {
    147     uint8_t *ip = (uint8_t *)iptr;
    148     OUT_T *op = (OUT_T *)optr;
    149     int ipextra = bytesBetweenInputLines - width*3;
    150     OUT_T *opLineEnd;
    151     OUT_T *t = (OUT_T *)table;
    152     int shift = rfbEndianTest?0:8;
    153 
    154     while (height > 0) {
    155         opLineEnd = op + width;
    156 
    157         while (op < opLineEnd) {
    158             *(op++) = t[((*(uint32_t *)ip)>>shift)&0x00ffffff];
    159 	    ip+=3;
    160         }
    161 
    162         ip += ipextra;
    163         height--;
    164     }
    165 }
    166 
    167 
    168 /*
    169  * rfbTranslateWithRGBTablesINtoOUT translates a rectangle of pixel data
    170  * using three separate lookup tables for the red, green and blue values.
    171  */
    172 
    173 static void
    174 rfbTranslateWithRGBTables24toOUT (char *table, rfbPixelFormat *in,
    175                                   rfbPixelFormat *out,
    176                                   char *iptr, char *optr,
    177                                   int bytesBetweenInputLines,
    178                                   int width, int height)
    179 {
    180     uint8_t *ip = (uint8_t *)iptr;
    181     OUT_T *op = (OUT_T *)optr;
    182     int ipextra = bytesBetweenInputLines - width*3;
    183     OUT_T *opLineEnd;
    184     OUT_T *redTable = (OUT_T *)table;
    185     OUT_T *greenTable = redTable + in->redMax + 1;
    186     OUT_T *blueTable = greenTable + in->greenMax + 1;
    187     uint32_t inValue;
    188     int shift = rfbEndianTest?0:8;
    189 
    190     while (height > 0) {
    191         opLineEnd = &op[width];
    192 
    193         while (op < opLineEnd) {
    194 	    inValue = ((*(uint32_t *)ip)>>shift)&0x00ffffff;
    195             *(op++) = (redTable[(inValue >> in->redShift) & in->redMax] |
    196                        greenTable[(inValue >> in->greenShift) & in->greenMax] |
    197                        blueTable[(inValue >> in->blueShift) & in->blueMax]);
    198             ip+=3;
    199         }
    200         ip += ipextra;
    201         height--;
    202     }
    203 }
    204 
    205 /*
    206  * rfbTranslateWithSingleTableINto24 translates a rectangle of pixel data
    207  * using a single lookup table.
    208  */
    209 
    210 static void
    211 rfbTranslateWithSingleTableINto24 (char *table, rfbPixelFormat *in,
    212                                     rfbPixelFormat *out,
    213                                     char *iptr, char *optr,
    214                                     int bytesBetweenInputLines,
    215                                     int width, int height)
    216 {
    217     IN_T *ip = (IN_T *)iptr;
    218     uint8_t *op = (uint8_t *)optr;
    219     int ipextra = bytesBetweenInputLines / sizeof(IN_T) - width;
    220     uint8_t *opLineEnd;
    221     uint8_t *t = (uint8_t *)table;
    222 
    223     while (height > 0) {
    224         opLineEnd = op + width * 3;
    225 
    226         while (op < opLineEnd) {
    227 	    memcpy(op,&t[3*(*(ip++))],3);
    228 	    op += 3;
    229         }
    230 
    231         ip += ipextra;
    232         height--;
    233     }
    234 }
    235 
    236 
    237 /*
    238  * rfbTranslateWithRGBTablesINto24 translates a rectangle of pixel data
    239  * using three separate lookup tables for the red, green and blue values.
    240  */
    241 
    242 static void
    243 rfbTranslateWithRGBTablesINto24 (char *table, rfbPixelFormat *in,
    244                                   rfbPixelFormat *out,
    245                                   char *iptr, char *optr,
    246                                   int bytesBetweenInputLines,
    247                                   int width, int height)
    248 {
    249     IN_T *ip = (IN_T *)iptr;
    250     uint8_t *op = (uint8_t *)optr;
    251     int ipextra = bytesBetweenInputLines / sizeof(IN_T) - width;
    252     uint8_t *opLineEnd;
    253     uint8_t *redTable = (uint8_t *)table;
    254     uint8_t *greenTable = redTable + 3*(in->redMax + 1);
    255     uint8_t *blueTable = greenTable + 3*(in->greenMax + 1);
    256     uint32_t outValue;
    257 
    258     while (height > 0) {
    259         opLineEnd = op+3*width;
    260 
    261         while (op < opLineEnd) {
    262             outValue = (redTable[(*ip >> in->redShift) & in->redMax] |
    263                        greenTable[(*ip >> in->greenShift) & in->greenMax] |
    264                        blueTable[(*ip >> in->blueShift) & in->blueMax]);
    265 	    memcpy(op,&outValue,3);
    266 	    op += 3;
    267             ip++;
    268         }
    269         ip += ipextra;
    270         height--;
    271     }
    272 }
    273 
    274 #undef IN_T
    275 #undef OUT_T
    276 #undef rfbTranslateWithSingleTable24toOUT
    277 #undef rfbTranslateWithRGBTables24toOUT
    278 #undef rfbTranslateWithSingleTableINto24
    279 #undef rfbTranslateWithRGBTablesINto24
    280 
    281 #endif
    282