/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 345 - (hide annotations)
Thu Mar 27 13:08:57 2003 UTC (21 years, 2 months 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 forsberg 345 /* -*- c-basic-offset: 8 -*-
2 matty 3 rdesktop: A Remote Desktop Protocol client.
3     Bitmap decompression routines
4 matthewc 207 Copyright (C) Matthew Chapman 1999-2002
5 jsorg71 309
6 matty 3 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 jsorg71 309
11 matty 3 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 jsorg71 309
16 matty 3 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 matty 10 #include "rdesktop.h"
22 matty 3
23 matty 7 #define CVAL(p) (*(p++))
24 matty 3
25 astrand 321 static uint32
26 astrand 318 cvalx(unsigned char **input, int Bpp)
27 jsorg71 314 {
28     uint32 rv = 0;
29     memcpy(&rv, *input, Bpp);
30     *input += Bpp;
31     return rv;
32     }
33    
34 astrand 321 static void
35 astrand 318 setli(unsigned char *input, int offset, uint32 value, int Bpp)
36 jsorg71 314 {
37     input += offset * Bpp;
38     memcpy(input, &value, Bpp);
39     }
40    
41 astrand 321 static uint32
42 astrand 318 getli(unsigned char *input, int offset, int Bpp)
43 jsorg71 314 {
44     uint32 rv = 0;
45     input += offset * Bpp;
46     memcpy(&rv, input, Bpp);
47     return rv;
48     }
49    
50 matty 28 #define UNROLL8(exp) { exp exp exp exp exp exp exp exp }
51 matty 3
52 matty 28 #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 matty 25 BOOL
71 astrand 318 bitmap_decompress(unsigned char *output, int width, int height, unsigned char *input, int size,
72     int Bpp)
73 matty 3 {
74     unsigned char *end = input + size;
75 matty 10 unsigned char *prevline = NULL, *line = NULL;
76 matty 7 int opcode, count, offset, isfillormix, x = width;
77 matty 19 int lastopcode = -1, insertmix = False, bicolour = False;
78 jsorg71 309 uint8 code;
79 jsorg71 314 uint32 colour1 = 0, colour2 = 0;
80 jsorg71 309 uint8 mixmask, mask = 0;
81 jsorg71 314 uint32 mix = 0xffffffff;
82 jsorg71 309 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 jsorg71 314 count = (opcode < 0xb) ? 8 : 1;
111 jsorg71 309 }
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 jsorg71 314 colour1 = cvalx(&input, Bpp);
149 jsorg71 309 case 3: /* Colour */
150 jsorg71 314 colour2 = cvalx(&input, Bpp);
151 jsorg71 309 break;
152     case 6: /* SetMix/Mix */
153     case 7: /* SetMix/FillOrMix */
154 jsorg71 314 mix = cvalx(&input, Bpp);
155 jsorg71 309 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 jsorg71 314 line = output + height * width * Bpp;
186 jsorg71 309 }
187    
188     switch (opcode)
189     {
190     case 0: /* Fill */
191     if (insertmix)
192     {
193     if (prevline == NULL)
194 jsorg71 314 setli(line, x, mix, Bpp);
195 jsorg71 309 else
196 astrand 318 setli(line, x,
197     getli(prevline, x, Bpp) ^ mix, Bpp);
198 jsorg71 309
199     insertmix = False;
200     count--;
201     x++;
202     }
203    
204     if (prevline == NULL)
205     {
206 astrand 318 REPEAT(setli(line, x, 0, Bpp))}
207 jsorg71 309 else
208     {
209 astrand 318 REPEAT(setli
210     (line, x, getli(prevline, x, Bpp), Bpp));
211 jsorg71 309 }
212     break;
213    
214     case 1: /* Mix */
215     if (prevline == NULL)
216     {
217 jsorg71 314 REPEAT(setli(line, x, mix, Bpp));
218 jsorg71 309 }
219     else
220     {
221 astrand 318 REPEAT(setli
222     (line, x, getli(prevline, x, Bpp) ^ mix,
223     Bpp));
224 jsorg71 309 }
225     break;
226    
227     case 2: /* Fill or Mix */
228     if (prevline == NULL)
229     {
230     REPEAT(MASK_UPDATE();
231 jsorg71 314 if (mask & mixmask) setli(line, x, mix, Bpp);
232 jsorg71 309 else
233 jsorg71 314 setli(line, x, 0, Bpp););
234 jsorg71 309 }
235     else
236     {
237     REPEAT(MASK_UPDATE();
238     if (mask & mixmask)
239 astrand 318 setli(line, x, getli(prevline, x, Bpp) ^ mix,
240     Bpp);
241 jsorg71 309 else
242 astrand 318 setli(line, x, getli(prevline, x, Bpp),
243     Bpp););
244 jsorg71 309 }
245     break;
246    
247     case 3: /* Colour */
248 jsorg71 314 REPEAT(setli(line, x, colour2, Bpp));
249 jsorg71 309 break;
250    
251     case 4: /* Copy */
252 jsorg71 314 REPEAT(setli(line, x, cvalx(&input, Bpp), Bpp));
253 jsorg71 309 break;
254    
255     case 8: /* Bicolour */
256     REPEAT(if (bicolour)
257     {
258 jsorg71 314 setli(line, x, colour2, Bpp); bicolour = False;}
259 jsorg71 309 else
260     {
261 astrand 318 setli(line, x, colour1, Bpp); bicolour = True;
262     count++;}
263 jsorg71 309 );
264     break;
265    
266     case 0xd: /* White */
267 jsorg71 314 REPEAT(setli(line, x, 0xffffffff, Bpp));
268 jsorg71 309 break;
269    
270     case 0xe: /* Black */
271 jsorg71 314 REPEAT(setli(line, x, 0, Bpp));
272 jsorg71 309 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