/[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 10 - (show annotations)
Tue Aug 15 10:23:24 2000 UTC (23 years, 8 months ago) by matty
File MIME type: text/plain
File size: 4185 byte(s)
Major commit of work from laptop - done in various free moments.
Implemented encryption layer and some basic licensing negotiation.
Reorganised code somewhat. While this is not quite as clean, it is
a lot faster - our parser speed was becoming a bottle-neck.

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;
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) && (x != width))
92 insertmix = True;
93 break;
94 case 8: /* Bicolour */
95 colour1 = CVAL(input);
96 case 3: /* Colour */
97 colour2 = CVAL(input);
98 break;
99 case 6: /* SetMix/Mix */
100 case 7: /* SetMix/FillOrMix */
101 mix = CVAL(input);
102 opcode -= 5;
103 break;
104 }
105 lastopcode = opcode;
106
107 /* Output body */
108 while (count > 0)
109 {
110 if (x >= width)
111 {
112 if (height <= 0)
113 return False;
114
115 x = 0;
116 height--;
117
118 prevline = line;
119 line = output + height * width;
120 }
121
122 switch (opcode)
123 {
124 case 0: /* Fill */
125 if (insertmix)
126 {
127 if (prevline == NULL)
128 line[x] = mix;
129 else
130 line[x] = prevline[x] ^ mix;
131
132 insertmix = False;
133 count--;
134 x++;
135 }
136
137 if (prevline == NULL)
138 REPEAT(line[x] = 0)
139 else
140 REPEAT(line[x] = prevline[x])
141 break;
142
143 case 1: /* Mix */
144 if (prevline == NULL)
145 REPEAT(line[x] = mix)
146 else
147 REPEAT(line[x] = prevline[x] ^ mix)
148 break;
149
150 case 2: /* Fill or Mix */
151 if (prevline == NULL)
152 REPEAT(
153 MASK_UPDATE();
154
155 if (mask & mixmask)
156 line[x] = mix;
157 else
158 line[x] = 0;
159 )
160 else
161 REPEAT(
162 MASK_UPDATE();
163
164 if (mask & mixmask)
165 line[x] = prevline[x] ^ mix;
166 else
167 line[x] = prevline[x];
168 )
169 break;
170
171 case 3: /* Colour */
172 REPEAT(line[x] = colour2)
173 break;
174
175 case 4: /* Copy */
176 REPEAT(line[x] = CVAL(input))
177 break;
178
179 case 8: /* Bicolour */
180 REPEAT(line[x] = colour1; line[++x] = colour2)
181 break;
182
183 case 13: /* White */
184 REPEAT(line[x] = 0xff)
185 break;
186
187 case 14: /* Black */
188 REPEAT(line[x] = 0x00)
189 break;
190
191 default:
192 NOTIMP("bitmap opcode 0x%x\n", opcode);
193 return False;
194 }
195 }
196 }
197
198 return True;
199 }

  ViewVC Help
Powered by ViewVC 1.1.26