/[rdesktop]/sourceforge.net/trunk/rdesktop/mppc.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/mppc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 684 - (hide annotations)
Tue Apr 27 13:05:32 2004 UTC (20 years, 1 month ago) by n-ki
File MIME type: text/plain
File size: 5615 byte(s)
contains mppc decompression code

1 n-ki 684 #include <stdio.h>
2     #include <string.h>
3    
4     #include "rdesktop.h"
5    
6     /* mppc-like??? decompression */
7     /* http://www.faqs.org/rfcs/rfc2118.html */
8    
9     /* TODO: research the below statements */
10    
11     /* there exists one or more patents */
12     /* related to compression algorithms */
13    
14     /* since we are only decompressing I */
15     /* think the end-user is safe. */
16    
17     /* even if that isn't true, aren't you */
18     /* already paying royalties */
19     /* through the CAL licenses? */
20    
21     /* the dictionary is empty when init. like */
22     /* LZ78, which is not patented */
23    
24    
25     RDPCOMP mppc_dict;
26    
27     int
28     mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen)
29     {
30     int k, walker_len = 0, walker;
31     int i = 0;
32     int next_offset, match_off;
33     int match_len;
34     int old_offset, match_bits;
35    
36     signed char *dict = &(mppc_dict.hist);
37    
38     if ((ctype & RDP_MPPC_COMPRESSED) == 0)
39     {
40     *roff = 0;
41     *rlen = clen;
42     return 0;
43     }
44    
45     if ((ctype & RDP_MPPC_RESET) != 0)
46     {
47     mppc_dict.roff = 0;
48     }
49    
50     if ((ctype & RDP_MPPC_FLUSH) != 0)
51     {
52     memset(dict, 0, RDP_MPPC_DICT_SIZE);
53     mppc_dict.roff = 0;
54     }
55    
56     *roff = 0;
57     *rlen = 0;
58    
59     walker = mppc_dict.roff;
60    
61     next_offset = walker;
62     old_offset = next_offset;
63     *roff = old_offset;
64     if (clen == 0)
65     return 0;
66     clen += i;
67    
68     do
69     {
70     if (walker_len == 0)
71     {
72     if (i >= clen)
73     break;
74     walker = data[i++] << 24;
75     walker_len = 8;
76     }
77     if (walker >= 0)
78     {
79     if (walker_len < 8)
80     {
81     if (i >= clen)
82     {
83     if (walker != 0)
84     return -1;
85     break;
86     }
87     walker |= (data[i++] & 0xff) << (24 - walker_len);
88     walker_len += 8;
89     }
90     if (next_offset >= RDP_MPPC_DICT_SIZE)
91     return -1;
92     dict[next_offset++] = (((uint32) walker) >> ((uint32) 24));
93     walker <<= 8;
94     walker_len -= 8;
95     continue;
96     }
97     walker <<= 1;
98     /* fetch next 8-bits */
99     if (--walker_len == 0)
100     {
101     if (i >= clen)
102     return -1;
103     walker = data[i++] << 24;
104     walker_len = 8;
105     }
106     /* literal decoding */
107     if (walker >= 0)
108     {
109     if (walker_len < 8)
110     {
111     if (i >= clen)
112     return -1;
113     walker |= (data[i++] & 0xff) << (24 - walker_len);
114     walker_len += 8;
115     }
116     if (next_offset >= RDP_MPPC_DICT_SIZE)
117     return -1;
118     dict[next_offset++] = (uint8) (walker >> 24 | 0x80);
119     walker <<= 8;
120     walker_len -= 8;
121     continue;
122     }
123    
124     /* decode offset */
125     /* length pair */
126     walker <<= 1;
127     if (--walker_len < 2)
128     {
129     if (i >= clen)
130     return -1;
131     walker |= (data[i++] & 0xff) << (24 - walker_len);
132     walker_len += 8;
133     }
134     /* offset decoding where offset len is:
135     -63: 1111 followed by the lower 6 bits of the value
136     64-319: 1110 followed by the lower 8 bits of the value ( value - 64 )
137     320-8191: 110 followed by the lower 13 bits of the value ( value - 320 )
138     */
139     switch (((uint32) walker) >> ((uint32) 30))
140     {
141     case 3: /* - 63 */
142     if (walker_len < 8)
143     {
144     if (i >= clen)
145     return -1;
146     walker |= (data[i++] & 0xff) << (24 - walker_len);
147     walker_len += 8;
148     }
149     walker <<= 2;
150     match_off = ((uint32) walker) >> ((uint32) 26);
151     walker <<= 6;
152     walker_len -= 8;
153     break;
154    
155     case 2: /* 64 - 319 */
156     for (; walker_len < 10; walker_len += 8)
157     {
158     if (i >= clen)
159     return -1;
160     walker |= (data[i++] & 0xff) << (24 - walker_len);
161     }
162    
163     walker <<= 2;
164     match_off = (((uint32) walker) >> ((uint32) 24)) + 64;
165     walker <<= 8;
166     walker_len -= 10;
167     break;
168    
169     default: /* 320 - 8191 */
170     for (; walker_len < 14; walker_len += 8)
171     {
172     if (i >= clen)
173     return -1;
174     walker |= (data[i++] & 0xff) << (24 - walker_len);
175     }
176    
177     match_off = (walker >> 18) + 320;
178     walker <<= 14;
179     walker_len -= 14;
180     break;
181     }
182     if (walker_len == 0)
183     {
184     if (i >= clen)
185     return -1;
186     walker = data[i++] << 24;
187     walker_len = 8;
188     }
189    
190     /* decode length of match */
191     match_len = 0;
192     if (walker >= 0)
193     { /* special case - length of 3 is in bit 0 */
194     match_len = 3;
195     walker <<= 1;
196     walker_len--;
197     }
198     else
199     {
200     /* this is how it works len of:
201     4-7: 10 followed by 2 bits of the value
202     8-15: 110 followed by 3 bits of the value
203     16-31: 1110 followed by 4 bits of the value
204     32-63: .... and so forth
205     64-127:
206     128-255:
207     256-511:
208     512-1023:
209     1024-2047:
210     2048-4095:
211     4096-8191:
212    
213     i.e. 4097 is encoded as: 111111111110 000000000001
214     meaning 4096 + 1...
215     */
216     match_bits = 11; /* 11 bits of value at most */
217     do
218     {
219     walker <<= 1;
220     if (--walker_len == 0)
221     {
222     if (i >= clen)
223     return -1;
224     walker = data[i++] << 24;
225     walker_len = 8;
226     }
227     if (walker >= 0)
228     break;
229     if (--match_bits == 0)
230     {
231     return -1;
232     }
233     }
234     while (1);
235     match_len = 13 - match_bits;
236     walker <<= 1;
237     if (--walker_len < match_len)
238     {
239     for (; walker_len < match_len; walker_len += 8)
240     {
241     if (i >= clen)
242     {
243     return -1;
244     }
245     walker |= (data[i++] & 0xff) << (24 - walker_len);
246     }
247     }
248    
249     match_bits = match_len;
250     match_len =
251     walker >> 32 - match_bits & ~(-1 << match_bits) | 1 << match_bits;
252     walker <<= match_bits;
253     walker_len -= match_bits;
254     }
255     if (next_offset + match_len >= RDP_MPPC_DICT_SIZE)
256     {
257     return -1;
258     }
259     /* memory areas can overlap - meaning we can't use memXXX functions */
260     k = next_offset - match_off & (RDP_MPPC_DICT_SIZE - 1);
261     do
262     {
263     dict[next_offset++] = dict[k++];
264     }
265     while (--match_len != 0);
266     }
267     while (1);
268    
269     /* store history offset */
270     mppc_dict.roff = next_offset;
271    
272     *roff = old_offset;
273     *rlen = next_offset - old_offset;
274    
275     return 0;
276     }

  ViewVC Help
Powered by ViewVC 1.1.26