/[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 36 - (hide annotations)
Sat Sep 15 14:30:46 2001 UTC (22 years, 9 months ago) by matty
File MIME type: text/plain
File size: 5024 byte(s)
OSF1/Alpha build fixes.

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

  ViewVC Help
Powered by ViewVC 1.1.26