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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 25 - (show annotations)
Sat Jan 6 03:47:04 2001 UTC (23 years, 4 months ago) by matty
File MIME type: text/plain
File size: 4542 byte(s)
Changed indentation style (-psl).

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

  ViewVC Help
Powered by ViewVC 1.1.26