/[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 19 - (show annotations)
Sun Oct 8 01:59:25 2000 UTC (23 years, 8 months ago) by matty
File MIME type: text/plain
File size: 4384 byte(s)
Bicolour was slightly broken (dodgy x++ without going through normal
loop). Hopefully this should be the last of our bitmap decompression
problems.

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

  ViewVC Help
Powered by ViewVC 1.1.26