/[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 345 - (show annotations)
Thu Mar 27 13:08:57 2003 UTC (21 years, 1 month ago) by forsberg
File MIME type: text/plain
File size: 5716 byte(s)
Added a line telling emacs that the basic offset is 8.

1 /* -*- c-basic-offset: 8 -*-
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 static uint32
26 cvalx(unsigned char **input, int Bpp)
27 {
28 uint32 rv = 0;
29 memcpy(&rv, *input, Bpp);
30 *input += Bpp;
31 return rv;
32 }
33
34 static void
35 setli(unsigned char *input, int offset, uint32 value, int Bpp)
36 {
37 input += offset * Bpp;
38 memcpy(input, &value, Bpp);
39 }
40
41 static uint32
42 getli(unsigned char *input, int offset, int Bpp)
43 {
44 uint32 rv = 0;
45 input += offset * Bpp;
46 memcpy(&rv, input, Bpp);
47 return rv;
48 }
49
50 #define UNROLL8(exp) { exp exp exp exp exp exp exp exp }
51
52 #define REPEAT(statement) \
53 { \
54 while((count & ~0x7) && ((x+8) < width)) \
55 UNROLL8( statement; count--; x++; ); \
56 \
57 while((count > 0) && (x < width)) { statement; count--; x++; } \
58 }
59
60 #define MASK_UPDATE() \
61 { \
62 mixmask <<= 1; \
63 if (mixmask == 0) \
64 { \
65 mask = fom_mask ? fom_mask : CVAL(input); \
66 mixmask = 1; \
67 } \
68 }
69
70 BOOL
71 bitmap_decompress(unsigned char *output, int width, int height, unsigned char *input, int size,
72 int Bpp)
73 {
74 unsigned char *end = input + size;
75 unsigned char *prevline = NULL, *line = NULL;
76 int opcode, count, offset, isfillormix, x = width;
77 int lastopcode = -1, insertmix = False, bicolour = False;
78 uint8 code;
79 uint32 colour1 = 0, colour2 = 0;
80 uint8 mixmask, mask = 0;
81 uint32 mix = 0xffffffff;
82 int fom_mask = 0;
83
84 while (input < end)
85 {
86 fom_mask = 0;
87 code = CVAL(input);
88 opcode = code >> 4;
89
90 /* Handle different opcode forms */
91 switch (opcode)
92 {
93 case 0xc:
94 case 0xd:
95 case 0xe:
96 opcode -= 6;
97 count = code & 0xf;
98 offset = 16;
99 break;
100
101 case 0xf:
102 opcode = code & 0xf;
103 if (opcode < 9)
104 {
105 count = CVAL(input);
106 count |= CVAL(input) << 8;
107 }
108 else
109 {
110 count = (opcode < 0xb) ? 8 : 1;
111 }
112 offset = 0;
113 break;
114
115 default:
116 opcode >>= 1;
117 count = code & 0x1f;
118 offset = 32;
119 break;
120 }
121
122 /* Handle strange cases for counts */
123 if (offset != 0)
124 {
125 isfillormix = ((opcode == 2) || (opcode == 7));
126
127 if (count == 0)
128 {
129 if (isfillormix)
130 count = CVAL(input) + 1;
131 else
132 count = CVAL(input) + offset;
133 }
134 else if (isfillormix)
135 {
136 count <<= 3;
137 }
138 }
139
140 /* Read preliminary data */
141 switch (opcode)
142 {
143 case 0: /* Fill */
144 if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
145 insertmix = True;
146 break;
147 case 8: /* Bicolour */
148 colour1 = cvalx(&input, Bpp);
149 case 3: /* Colour */
150 colour2 = cvalx(&input, Bpp);
151 break;
152 case 6: /* SetMix/Mix */
153 case 7: /* SetMix/FillOrMix */
154 mix = cvalx(&input, Bpp);
155 opcode -= 5;
156 break;
157 case 9: /* FillOrMix_1 */
158 mask = 0x03;
159 opcode = 0x02;
160 fom_mask = 3;
161 break;
162 case 0x0a: /* FillOrMix_2 */
163 mask = 0x05;
164 opcode = 0x02;
165 fom_mask = 5;
166 break;
167
168 }
169
170 lastopcode = opcode;
171 mixmask = 0;
172
173 /* Output body */
174 while (count > 0)
175 {
176 if (x >= width)
177 {
178 if (height <= 0)
179 return False;
180
181 x = 0;
182 height--;
183
184 prevline = line;
185 line = output + height * width * Bpp;
186 }
187
188 switch (opcode)
189 {
190 case 0: /* Fill */
191 if (insertmix)
192 {
193 if (prevline == NULL)
194 setli(line, x, mix, Bpp);
195 else
196 setli(line, x,
197 getli(prevline, x, Bpp) ^ mix, Bpp);
198
199 insertmix = False;
200 count--;
201 x++;
202 }
203
204 if (prevline == NULL)
205 {
206 REPEAT(setli(line, x, 0, Bpp))}
207 else
208 {
209 REPEAT(setli
210 (line, x, getli(prevline, x, Bpp), Bpp));
211 }
212 break;
213
214 case 1: /* Mix */
215 if (prevline == NULL)
216 {
217 REPEAT(setli(line, x, mix, Bpp));
218 }
219 else
220 {
221 REPEAT(setli
222 (line, x, getli(prevline, x, Bpp) ^ mix,
223 Bpp));
224 }
225 break;
226
227 case 2: /* Fill or Mix */
228 if (prevline == NULL)
229 {
230 REPEAT(MASK_UPDATE();
231 if (mask & mixmask) setli(line, x, mix, Bpp);
232 else
233 setli(line, x, 0, Bpp););
234 }
235 else
236 {
237 REPEAT(MASK_UPDATE();
238 if (mask & mixmask)
239 setli(line, x, getli(prevline, x, Bpp) ^ mix,
240 Bpp);
241 else
242 setli(line, x, getli(prevline, x, Bpp),
243 Bpp););
244 }
245 break;
246
247 case 3: /* Colour */
248 REPEAT(setli(line, x, colour2, Bpp));
249 break;
250
251 case 4: /* Copy */
252 REPEAT(setli(line, x, cvalx(&input, Bpp), Bpp));
253 break;
254
255 case 8: /* Bicolour */
256 REPEAT(if (bicolour)
257 {
258 setli(line, x, colour2, Bpp); bicolour = False;}
259 else
260 {
261 setli(line, x, colour1, Bpp); bicolour = True;
262 count++;}
263 );
264 break;
265
266 case 0xd: /* White */
267 REPEAT(setli(line, x, 0xffffffff, Bpp));
268 break;
269
270 case 0xe: /* Black */
271 REPEAT(setli(line, x, 0, Bpp));
272 break;
273
274 default:
275 unimpl("bitmap opcode 0x%x\n", opcode);
276 return False;
277 }
278 }
279 }
280
281 return True;
282 }

  ViewVC Help
Powered by ViewVC 1.1.26