/[rdesktop]/sourceforge.net/trunk/rdesktop/bitmap.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /sourceforge.net/trunk/rdesktop/bitmap.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 314 - (show annotations)
Fri Feb 7 23:43:37 2003 UTC (21 years, 3 months ago) by jsorg71
File MIME type: text/plain
File size: 5591 byte(s)
one bitmap decomp function to handle all colour depths

1 /*
2 rdesktop: A Remote Desktop Protocol client.
3 Bitmap decompression routines
4 Copyright (C) Matthew Chapman 1999-2002
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "rdesktop.h"
22
23 #define CVAL(p) (*(p++))
24
25 uint32 cvalx(unsigned char **input, int Bpp)
26 {
27 uint32 rv = 0;
28 memcpy(&rv, *input, Bpp);
29 *input += Bpp;
30 return rv;
31 }
32
33 void setli(unsigned char * input, int offset, uint32 value, int Bpp)
34 {
35 input += offset * Bpp;
36 memcpy(input, &value, Bpp);
37 }
38
39 uint32 getli(unsigned char * input, int offset, int Bpp)
40 {
41 uint32 rv = 0;
42 input += offset * Bpp;
43 memcpy(&rv, input, Bpp);
44 return rv;
45 }
46
47 #define UNROLL8(exp) { exp exp exp exp exp exp exp exp }
48
49 #define REPEAT(statement) \
50 { \
51 while((count & ~0x7) && ((x+8) < width)) \
52 UNROLL8( statement; count--; x++; ); \
53 \
54 while((count > 0) && (x < width)) { statement; count--; x++; } \
55 }
56
57 #define MASK_UPDATE() \
58 { \
59 mixmask <<= 1; \
60 if (mixmask == 0) \
61 { \
62 mask = fom_mask ? fom_mask : CVAL(input); \
63 mixmask = 1; \
64 } \
65 }
66
67 BOOL
68 bitmap_decompress(unsigned char *output, int width, int height, unsigned char *input, int size, int Bpp)
69 {
70 unsigned char *end = input + size;
71 unsigned char *prevline = NULL, *line = NULL;
72 int opcode, count, offset, isfillormix, x = width;
73 int lastopcode = -1, insertmix = False, bicolour = False;
74 uint8 code;
75 uint32 colour1 = 0, colour2 = 0;
76 uint8 mixmask, mask = 0;
77 uint32 mix = 0xffffffff;
78 int fom_mask = 0;
79
80 while (input < end)
81 {
82 fom_mask = 0;
83 code = CVAL(input);
84 opcode = code >> 4;
85
86 /* Handle different opcode forms */
87 switch (opcode)
88 {
89 case 0xc:
90 case 0xd:
91 case 0xe:
92 opcode -= 6;
93 count = code & 0xf;
94 offset = 16;
95 break;
96
97 case 0xf:
98 opcode = code & 0xf;
99 if (opcode < 9)
100 {
101 count = CVAL(input);
102 count |= CVAL(input) << 8;
103 }
104 else
105 {
106 count = (opcode < 0xb) ? 8 : 1;
107 }
108 offset = 0;
109 break;
110
111 default:
112 opcode >>= 1;
113 count = code & 0x1f;
114 offset = 32;
115 break;
116 }
117
118 /* Handle strange cases for counts */
119 if (offset != 0)
120 {
121 isfillormix = ((opcode == 2) || (opcode == 7));
122
123 if (count == 0)
124 {
125 if (isfillormix)
126 count = CVAL(input) + 1;
127 else
128 count = CVAL(input) + offset;
129 }
130 else if (isfillormix)
131 {
132 count <<= 3;
133 }
134 }
135
136 /* Read preliminary data */
137 switch (opcode)
138 {
139 case 0: /* Fill */
140 if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
141 insertmix = True;
142 break;
143 case 8: /* Bicolour */
144 colour1 = cvalx(&input, Bpp);
145 case 3: /* Colour */
146 colour2 = cvalx(&input, Bpp);
147 break;
148 case 6: /* SetMix/Mix */
149 case 7: /* SetMix/FillOrMix */
150 mix = cvalx(&input, Bpp);
151 opcode -= 5;
152 break;
153 case 9: /* FillOrMix_1 */
154 mask = 0x03;
155 opcode = 0x02;
156 fom_mask = 3;
157 break;
158 case 0x0a: /* FillOrMix_2 */
159 mask = 0x05;
160 opcode = 0x02;
161 fom_mask = 5;
162 break;
163
164 }
165
166 lastopcode = opcode;
167 mixmask = 0;
168
169 /* Output body */
170 while (count > 0)
171 {
172 if (x >= width)
173 {
174 if (height <= 0)
175 return False;
176
177 x = 0;
178 height--;
179
180 prevline = line;
181 line = output + height * width * Bpp;
182 }
183
184 switch (opcode)
185 {
186 case 0: /* Fill */
187 if (insertmix)
188 {
189 if (prevline == NULL)
190 setli(line, x, mix, Bpp);
191 else
192 setli(line, x, getli(prevline, x, Bpp) ^ mix, Bpp);
193
194 insertmix = False;
195 count--;
196 x++;
197 }
198
199 if (prevline == NULL)
200 {
201 REPEAT(setli(line, x, 0, Bpp))
202 }
203 else
204 {
205 REPEAT(setli(line, x, getli(prevline, x, Bpp), Bpp));
206 }
207 break;
208
209 case 1: /* Mix */
210 if (prevline == NULL)
211 {
212 REPEAT(setli(line, x, mix, Bpp));
213 }
214 else
215 {
216 REPEAT(setli(line, x, getli(prevline, x, Bpp) ^ mix, Bpp));
217 }
218 break;
219
220 case 2: /* Fill or Mix */
221 if (prevline == NULL)
222 {
223 REPEAT(MASK_UPDATE();
224 if (mask & mixmask) setli(line, x, mix, Bpp);
225 else
226 setli(line, x, 0, Bpp););
227 }
228 else
229 {
230 REPEAT(MASK_UPDATE();
231 if (mask & mixmask)
232 setli(line, x, getli(prevline, x, Bpp) ^ mix, Bpp);
233 else
234 setli(line, x, getli(prevline, x, Bpp), Bpp););
235 }
236 break;
237
238 case 3: /* Colour */
239 REPEAT(setli(line, x, colour2, Bpp));
240 break;
241
242 case 4: /* Copy */
243 REPEAT(setli(line, x, cvalx(&input, Bpp), Bpp));
244 break;
245
246 case 8: /* Bicolour */
247 REPEAT(if (bicolour)
248 {
249 setli(line, x, colour2, Bpp); bicolour = False;}
250 else
251 {
252 setli(line, x, colour1, Bpp); bicolour = True; count++;}
253 );
254 break;
255
256 case 0xd: /* White */
257 REPEAT(setli(line, x, 0xffffffff, Bpp));
258 break;
259
260 case 0xe: /* Black */
261 REPEAT(setli(line, x, 0, Bpp));
262 break;
263
264 default:
265 unimpl("bitmap opcode 0x%x\n", opcode);
266 return False;
267 }
268 }
269 }
270
271 return True;
272 }
273

  ViewVC Help
Powered by ViewVC 1.1.26