fix disconnect bug in libvncserver
[presencevnc] / libvnc / libvncserver / tabletrans24template.c
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
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