/[rdesktop]/sourceforge.net/tags/RDESKTOP-1-3-1/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/tags/RDESKTOP-1-3-1/rdesktop/bitmap.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 314 - (hide annotations)
Fri Feb 7 23:43:37 2003 UTC (21 years, 4 months ago) by jsorg71
Original Path: sourceforge.net/trunk/rdesktop/bitmap.c
File MIME type: text/plain
File size: 5591 byte(s)
one bitmap decomp function to handle all colour depths

1 matty 3 /*
2     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 jsorg71 314 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 matty 28 #define UNROLL8(exp) { exp exp exp exp exp exp exp exp }
48 matty 3
49 matty 28 #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 matty 25 BOOL
68 jsorg71 314 bitmap_decompress(unsigned char *output, int width, int height, unsigned char *input, int size, int Bpp)
69 matty 3 {
70     unsigned char *end = input + size;
71 matty 10 unsigned char *prevline = NULL, *line = NULL;
72 matty 7 int opcode, count, offset, isfillormix, x = width;
73 matty 19 int lastopcode = -1, insertmix = False, bicolour = False;
74 jsorg71 309 uint8 code;
75 jsorg71 314 uint32 colour1 = 0, colour2 = 0;
76 jsorg71 309 uint8 mixmask, mask = 0;
77 jsorg71 314 uint32 mix = 0xffffffff;
78 jsorg71 309 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 jsorg71 314 count = (opcode < 0xb) ? 8 : 1;
107 jsorg71 309 }
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 jsorg71 314 colour1 = cvalx(&input, Bpp);
145 jsorg71 309 case 3: /* Colour */
146 jsorg71 314 colour2 = cvalx(&input, Bpp);
147 jsorg71 309 break;
148     case 6: /* SetMix/Mix */
149     case 7: /* SetMix/FillOrMix */
150 jsorg71 314 mix = cvalx(&input, Bpp);
151 jsorg71 309 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 jsorg71 314 line = output + height * width * Bpp;
182 jsorg71 309 }
183    
184     switch (opcode)
185     {
186     case 0: /* Fill */
187     if (insertmix)
188     {
189     if (prevline == NULL)
190 jsorg71 314 setli(line, x, mix, Bpp);
191 jsorg71 309 else
192 jsorg71 314 setli(line, x, getli(prevline, x, Bpp) ^ mix, Bpp);
193 jsorg71 309
194     insertmix = False;
195     count--;
196     x++;
197     }
198    
199     if (prevline == NULL)
200     {
201 jsorg71 314 REPEAT(setli(line, x, 0, Bpp))
202 jsorg71 309 }
203     else
204     {
205 jsorg71 314 REPEAT(setli(line, x, getli(prevline, x, Bpp), Bpp));
206 jsorg71 309 }
207     break;
208    
209     case 1: /* Mix */
210     if (prevline == NULL)
211     {
212 jsorg71 314 REPEAT(setli(line, x, mix, Bpp));
213 jsorg71 309 }
214     else
215     {
216 jsorg71 314 REPEAT(setli(line, x, getli(prevline, x, Bpp) ^ mix, Bpp));
217 jsorg71 309 }
218     break;
219    
220     case 2: /* Fill or Mix */
221     if (prevline == NULL)
222     {
223     REPEAT(MASK_UPDATE();
224 jsorg71 314 if (mask & mixmask) setli(line, x, mix, Bpp);
225 jsorg71 309 else
226 jsorg71 314 setli(line, x, 0, Bpp););
227 jsorg71 309 }
228     else
229     {
230     REPEAT(MASK_UPDATE();
231     if (mask & mixmask)
232 jsorg71 314 setli(line, x, getli(prevline, x, Bpp) ^ mix, Bpp);
233 jsorg71 309 else
234 jsorg71 314 setli(line, x, getli(prevline, x, Bpp), Bpp););
235 jsorg71 309 }
236     break;
237    
238     case 3: /* Colour */
239 jsorg71 314 REPEAT(setli(line, x, colour2, Bpp));
240 jsorg71 309 break;
241    
242     case 4: /* Copy */
243 jsorg71 314 REPEAT(setli(line, x, cvalx(&input, Bpp), Bpp));
244 jsorg71 309 break;
245    
246     case 8: /* Bicolour */
247     REPEAT(if (bicolour)
248     {
249 jsorg71 314 setli(line, x, colour2, Bpp); bicolour = False;}
250 jsorg71 309 else
251     {
252 jsorg71 314 setli(line, x, colour1, Bpp); bicolour = True; count++;}
253 jsorg71 309 );
254     break;
255    
256     case 0xd: /* White */
257 jsorg71 314 REPEAT(setli(line, x, 0xffffffff, Bpp));
258 jsorg71 309 break;
259    
260     case 0xe: /* Black */
261 jsorg71 314 REPEAT(setli(line, x, 0, Bpp));
262 jsorg71 309 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