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@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
rfbTranslateWithSingleTable24to24(char * table,rfbPixelFormat * in,rfbPixelFormat * out,char * iptr,char * optr,int bytesBetweenInputLines,int width,int height)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
rfbTranslateWithRGBTables24to24(char * table,rfbPixelFormat * in,rfbPixelFormat * out,char * iptr,char * optr,int bytesBetweenInputLines,int width,int height)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
rfbTranslateWithSingleTable24toOUT(char * table,rfbPixelFormat * in,rfbPixelFormat * out,char * iptr,char * optr,int bytesBetweenInputLines,int width,int height)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
rfbTranslateWithRGBTables24toOUT(char * table,rfbPixelFormat * in,rfbPixelFormat * out,char * iptr,char * optr,int bytesBetweenInputLines,int width,int height)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
rfbTranslateWithSingleTableINto24(char * table,rfbPixelFormat * in,rfbPixelFormat * out,char * iptr,char * optr,int bytesBetweenInputLines,int width,int height)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
rfbTranslateWithRGBTablesINto24(char * table,rfbPixelFormat * in,rfbPixelFormat * out,char * iptr,char * optr,int bytesBetweenInputLines,int width,int height)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