ReactOS  0.4.12-dev-721-g03c3dd5
mppc.c File Reference
#include <stdio.h>
#include <string.h>
#include "precomp.h"
Include dependency graph for mppc.c:

Go to the source code of this file.

Functions

int mppc_expand (uint8 *data, uint32 clen, uint8 ctype, uint32 *roff, uint32 *rlen)
 

Variables

RDPCOMP g_mppc_dict
 

Function Documentation

◆ mppc_expand()

int mppc_expand ( uint8 data,
uint32  clen,
uint8  ctype,
uint32 roff,
uint32 rlen 
)

Definition at line 58 of file mppc.c.

59 {
60  int k, walker_len = 0, walker;
61  uint32 i = 0;
62  int next_offset, match_off;
63  int match_len;
64  int old_offset, match_bits;
65  RD_BOOL big = ctype & RDP_MPPC_BIG ? True : False;
66 
67  uint8 *dict = g_mppc_dict.hist;
68 
69  if ((ctype & RDP_MPPC_COMPRESSED) == 0)
70  {
71  *roff = 0;
72  *rlen = clen;
73  return 0;
74  }
75 
76  if ((ctype & RDP_MPPC_RESET) != 0)
77  {
78  g_mppc_dict.roff = 0;
79  }
80 
81  if ((ctype & RDP_MPPC_FLUSH) != 0)
82  {
83  memset(dict, 0, RDP_MPPC_DICT_SIZE);
84  g_mppc_dict.roff = 0;
85  }
86 
87  *roff = 0;
88  *rlen = 0;
89 
90  walker = g_mppc_dict.roff;
91 
92  next_offset = walker;
93  old_offset = next_offset;
94  *roff = old_offset;
95  if (clen == 0)
96  return 0;
97  clen += i;
98 
99  do
100  {
101  if (walker_len == 0)
102  {
103  if (i >= clen)
104  break;
105  walker = data[i++] << 24;
106  walker_len = 8;
107  }
108  if (walker >= 0)
109  {
110  if (walker_len < 8)
111  {
112  if (i >= clen)
113  {
114  if (walker != 0)
115  return -1;
116  break;
117  }
118  walker |= (data[i++] & 0xff) << (24 - walker_len);
119  walker_len += 8;
120  }
121  if (next_offset >= RDP_MPPC_DICT_SIZE)
122  return -1;
123  dict[next_offset++] = (((uint32) walker) >> ((uint32) 24));
124  walker <<= 8;
125  walker_len -= 8;
126  continue;
127  }
128  walker <<= 1;
129  /* fetch next 8-bits */
130  if (--walker_len == 0)
131  {
132  if (i >= clen)
133  return -1;
134  walker = data[i++] << 24;
135  walker_len = 8;
136  }
137  /* literal decoding */
138  if (walker >= 0)
139  {
140  if (walker_len < 8)
141  {
142  if (i >= clen)
143  return -1;
144  walker |= (data[i++] & 0xff) << (24 - walker_len);
145  walker_len += 8;
146  }
147  if (next_offset >= RDP_MPPC_DICT_SIZE)
148  return -1;
149  dict[next_offset++] = (uint8) (walker >> 24 | 0x80);
150  walker <<= 8;
151  walker_len -= 8;
152  continue;
153  }
154 
155  /* decode offset */
156  /* length pair */
157  walker <<= 1;
158  if (--walker_len < (big ? 3 : 2))
159  {
160  if (i >= clen)
161  return -1;
162  walker |= (data[i++] & 0xff) << (24 - walker_len);
163  walker_len += 8;
164  }
165 
166  if (big)
167  {
168  /* offset decoding where offset len is:
169  -63: 11111 followed by the lower 6 bits of the value
170  64-319: 11110 followed by the lower 8 bits of the value ( value - 64 )
171  320-2367: 1110 followed by lower 11 bits of the value ( value - 320 )
172  2368-65535: 110 followed by lower 16 bits of the value ( value - 2368 )
173  */
174  switch (((uint32) walker) >> ((uint32) 29))
175  {
176  case 7: /* - 63 */
177  for (; walker_len < 9; walker_len += 8)
178  {
179  if (i >= clen)
180  return -1;
181  walker |= (data[i++] & 0xff) << (24 - walker_len);
182  }
183  walker <<= 3;
184  match_off = ((uint32) walker) >> ((uint32) 26);
185  walker <<= 6;
186  walker_len -= 9;
187  break;
188 
189  case 6: /* 64 - 319 */
190  for (; walker_len < 11; walker_len += 8)
191  {
192  if (i >= clen)
193  return -1;
194  walker |= (data[i++] & 0xff) << (24 - walker_len);
195  }
196 
197  walker <<= 3;
198  match_off = (((uint32) walker) >> ((uint32) 24)) + 64;
199  walker <<= 8;
200  walker_len -= 11;
201  break;
202 
203  case 5:
204  case 4: /* 320 - 2367 */
205  for (; walker_len < 13; walker_len += 8)
206  {
207  if (i >= clen)
208  return -1;
209  walker |= (data[i++] & 0xff) << (24 - walker_len);
210  }
211 
212  walker <<= 2;
213  match_off = (((uint32) walker) >> ((uint32) 21)) + 320;
214  walker <<= 11;
215  walker_len -= 13;
216  break;
217 
218  default: /* 2368 - 65535 */
219  for (; walker_len < 17; walker_len += 8)
220  {
221  if (i >= clen)
222  return -1;
223  walker |= (data[i++] & 0xff) << (24 - walker_len);
224  }
225 
226  walker <<= 1;
227  match_off = (((uint32) walker) >> ((uint32) 16)) + 2368;
228  walker <<= 16;
229  walker_len -= 17;
230  break;
231  }
232  }
233  else
234  {
235  /* offset decoding where offset len is:
236  -63: 1111 followed by the lower 6 bits of the value
237  64-319: 1110 followed by the lower 8 bits of the value ( value - 64 )
238  320-8191: 110 followed by the lower 13 bits of the value ( value - 320 )
239  */
240  switch (((uint32) walker) >> ((uint32) 30))
241  {
242  case 3: /* - 63 */
243  if (walker_len < 8)
244  {
245  if (i >= clen)
246  return -1;
247  walker |= (data[i++] & 0xff) << (24 - walker_len);
248  walker_len += 8;
249  }
250  walker <<= 2;
251  match_off = ((uint32) walker) >> ((uint32) 26);
252  walker <<= 6;
253  walker_len -= 8;
254  break;
255 
256  case 2: /* 64 - 319 */
257  for (; walker_len < 10; walker_len += 8)
258  {
259  if (i >= clen)
260  return -1;
261  walker |= (data[i++] & 0xff) << (24 - walker_len);
262  }
263 
264  walker <<= 2;
265  match_off = (((uint32) walker) >> ((uint32) 24)) + 64;
266  walker <<= 8;
267  walker_len -= 10;
268  break;
269 
270  default: /* 320 - 8191 */
271  for (; walker_len < 14; walker_len += 8)
272  {
273  if (i >= clen)
274  return -1;
275  walker |= (data[i++] & 0xff) << (24 - walker_len);
276  }
277 
278  match_off = (walker >> 18) + 320;
279  walker <<= 14;
280  walker_len -= 14;
281  break;
282  }
283  }
284  if (walker_len == 0)
285  {
286  if (i >= clen)
287  return -1;
288  walker = data[i++] << 24;
289  walker_len = 8;
290  }
291 
292  /* decode length of match */
293  match_len = 0;
294  if (walker >= 0)
295  { /* special case - length of 3 is in bit 0 */
296  match_len = 3;
297  walker <<= 1;
298  walker_len--;
299  }
300  else
301  {
302  /* this is how it works len of:
303  4-7: 10 followed by 2 bits of the value
304  8-15: 110 followed by 3 bits of the value
305  16-31: 1110 followed by 4 bits of the value
306  32-63: .... and so forth
307  64-127:
308  128-255:
309  256-511:
310  512-1023:
311  1024-2047:
312  2048-4095:
313  4096-8191:
314 
315  i.e. 4097 is encoded as: 111111111110 000000000001
316  meaning 4096 + 1...
317  */
318  match_bits = big ? 14 : 11; /* 11 or 14 bits of value at most */
319  do
320  {
321  walker <<= 1;
322  if (--walker_len == 0)
323  {
324  if (i >= clen)
325  return -1;
326  walker = data[i++] << 24;
327  walker_len = 8;
328  }
329  if (walker >= 0)
330  break;
331  if (--match_bits == 0)
332  {
333  return -1;
334  }
335  }
336  while (1);
337  match_len = (big ? 16 : 13) - match_bits;
338  walker <<= 1;
339  if (--walker_len < match_len)
340  {
341  for (; walker_len < match_len; walker_len += 8)
342  {
343  if (i >= clen)
344  {
345  return -1;
346  }
347  walker |= (data[i++] & 0xff) << (24 - walker_len);
348  }
349  }
350 
351  match_bits = match_len;
352  match_len =
353  ((walker >> (32 - match_bits)) & (~(-1 << match_bits))) | (1 <<
354  match_bits);
355  walker <<= match_bits;
356  walker_len -= match_bits;
357  }
358  if (next_offset + match_len >= RDP_MPPC_DICT_SIZE)
359  {
360  return -1;
361  }
362  /* memory areas can overlap - meaning we can't use memXXX functions */
363  k = (next_offset - match_off) & (big ? 65535 : 8191);
364  do
365  {
366  dict[next_offset++] = dict[k++];
367  }
368  while (--match_len != 0);
369  }
370  while (1);
371 
372  /* store history offset */
373  g_mppc_dict.roff = next_offset;
374 
375  *roff = old_offset;
376  *rlen = next_offset - old_offset;
377 
378  return 0;
379 }
#define RDP_MPPC_COMPRESSED
Definition: constants.h:355
unsigned int uint32
Definition: types.h:32
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define RDP_MPPC_DICT_SIZE
Definition: constants.h:358
int RD_BOOL
Definition: types.h:21
#define True
Definition: types.h:24
#define False
Definition: types.h:25
Definition: _ctype.h:58
unsigned char uint8
Definition: types.h:28
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define RDP_MPPC_RESET
Definition: constants.h:356
RDPCOMP g_mppc_dict
Definition: mppc.c:55
#define RDP_MPPC_BIG
Definition: constants.h:354
uint32 roff
Definition: types.h:190
#define RDP_MPPC_FLUSH
Definition: constants.h:357
uint8 hist[RDP_MPPC_DICT_SIZE]
Definition: types.h:191
#define memset(x, y, z)
Definition: compat.h:39
int k
Definition: mpi.c:3369

Referenced by process_data_pdu(), and rdp5_process().

Variable Documentation

◆ g_mppc_dict

RDPCOMP g_mppc_dict

Definition at line 55 of file mppc.c.

Referenced by mppc_expand(), process_data_pdu(), and rdp5_process().