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