/[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 82 - (hide annotations)
Tue Jul 30 07:18:48 2002 UTC (21 years, 10 months ago) by astrand
File MIME type: text/plain
File size: 4908 byte(s)
Changed max line length to 100

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

  ViewVC Help
Powered by ViewVC 1.1.26