/[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 30 - (hide annotations)
Fri Sep 14 13:51:38 2001 UTC (22 years, 8 months ago) by matty
File MIME type: text/plain
File size: 5018 byte(s)
Portability fixes, including elimination of variable argument macros.
Rudimentary configure script.
Miscellaneous cleanups.

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

  ViewVC Help
Powered by ViewVC 1.1.26