~ubuntu-branches/ubuntu/vivid/freerdp/vivid

« back to all changes in this revision

Viewing changes to libfreerdp/codec/mppc_enc.c

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2014-11-11 12:20:50 UTC
  • mfrom: (1.2.5)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20141111122050-7z628f4ab38qxad5
Tags: upstream-1.1.0~git20140921.1.440916e+dfsg1
ImportĀ upstreamĀ versionĀ 1.1.0~git20140921.1.440916e+dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * FreeRDP: A Remote Desktop Protocol Implementation
 
3
 * Implements Microsoft Point to Point Compression (MPPC) protocol
 
4
 *
 
5
 * Copyright 2012 Laxmikant Rashinkar <LK.Rashinkar@gmail.com>
 
6
 * Copyright 2012 Jay Sorg <jay.sorg@gmail.com>
 
7
 *
 
8
 * Licensed under the Apache License, Version 2.0 (the "License");
 
9
 * you may not use this file except in compliance with the License.
 
10
 * You may obtain a copy of the License at
 
11
 *
 
12
 *     http://www.apache.org/licenses/LICENSE-2.0
 
13
 *
 
14
 * Unless required by applicable law or agreed to in writing, software
 
15
 * distributed under the License is distributed on an "AS IS" BASIS,
 
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
17
 * See the License for the specific language governing permissions and
 
18
 * limitations under the License.
 
19
 */
 
20
 
 
21
#ifdef HAVE_CONFIG_H
 
22
#include "config.h"
 
23
#endif
 
24
 
 
25
#include <stdio.h>
 
26
#include <stdlib.h>
 
27
#include <string.h>
 
28
 
 
29
#include <winpr/crt.h>
 
30
 
 
31
#include <freerdp/codec/mppc_dec.h>
 
32
#include <freerdp/codec/mppc_enc.h>
 
33
 
 
34
#define MPPC_ENC_DEBUG 0
 
35
 
 
36
/* local defines */
 
37
 
 
38
#define RDP_40_HIST_BUF_LEN (1024 * 8) /* RDP 4.0 uses 8K history buf */
 
39
#define RDP_50_HIST_BUF_LEN (1024 * 64) /* RDP 5.0 uses 64K history buf */
 
40
 
 
41
#define CRC_INIT 0xFFFF
 
42
#define CRC(crcval, newchar) crcval = (crcval >> 8) ^ crc_table[(crcval ^ newchar) & 0x00ff]
 
43
 
 
44
/* CRC16 defs */
 
45
static const UINT16 crc_table[256] =
 
46
{
 
47
        0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
 
48
        0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
 
49
        0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
 
50
        0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
 
51
        0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
 
52
        0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
 
53
        0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
 
54
        0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
 
55
        0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
 
56
        0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
 
57
        0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
 
58
        0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
 
59
        0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
 
60
        0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
 
61
        0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
 
62
        0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
 
63
        0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
 
64
        0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
 
65
        0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
 
66
        0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
 
67
        0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
 
68
        0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
 
69
        0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
 
70
        0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
 
71
        0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
 
72
        0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
 
73
        0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
 
74
        0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
 
75
        0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
 
76
        0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
 
77
        0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
 
78
        0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
 
79
};
 
80
 
 
81
/*****************************************************************************
 
82
                     insert 2 bits into outputBuffer
 
83
******************************************************************************/
 
84
#define insert_2_bits(_data) \
 
85
do \
 
86
{ \
 
87
        if ((bits_left >= 3) && (bits_left <= 8)) \
 
88
        { \
 
89
                i = bits_left - 2; \
 
90
                outputBuffer[opb_index] |= _data << i; \
 
91
                bits_left = i; \
 
92
        } \
 
93
        else \
 
94
        { \
 
95
                i = 2 - bits_left; \
 
96
                j = 8 - i; \
 
97
                outputBuffer[opb_index++] |= _data >> i; \
 
98
                outputBuffer[opb_index] |= _data << j; \
 
99
                bits_left = j; \
 
100
        } \
 
101
} while (0)
 
102
 
 
103
/*****************************************************************************
 
104
                     insert 3 bits into outputBuffer
 
105
******************************************************************************/
 
106
#define insert_3_bits(_data) \
 
107
do \
 
108
{ \
 
109
        if ((bits_left >= 4) && (bits_left <= 8)) \
 
110
        { \
 
111
                i = bits_left - 3; \
 
112
                outputBuffer[opb_index] |= _data << i; \
 
113
                bits_left = i; \
 
114
        } \
 
115
        else \
 
116
        { \
 
117
                i = 3 - bits_left; \
 
118
                j = 8 - i; \
 
119
                outputBuffer[opb_index++] |= _data >> i; \
 
120
                outputBuffer[opb_index] |= _data << j; \
 
121
                bits_left = j; \
 
122
        } \
 
123
} while (0)
 
124
 
 
125
/*****************************************************************************
 
126
                     insert 4 bits into outputBuffer
 
127
******************************************************************************/
 
128
#define insert_4_bits(_data) \
 
129
do \
 
130
{ \
 
131
        if ((bits_left >= 5) && (bits_left <= 8)) \
 
132
        { \
 
133
                i = bits_left - 4; \
 
134
                outputBuffer[opb_index] |= _data << i; \
 
135
                bits_left = i; \
 
136
        } \
 
137
        else \
 
138
        { \
 
139
                i = 4 - bits_left; \
 
140
                j = 8 - i; \
 
141
                outputBuffer[opb_index++] |= _data >> i; \
 
142
                outputBuffer[opb_index] |= _data << j; \
 
143
                bits_left = j; \
 
144
        } \
 
145
} while (0)
 
146
 
 
147
/*****************************************************************************
 
148
                     insert 5 bits into outputBuffer
 
149
******************************************************************************/
 
150
#define insert_5_bits(_data) \
 
151
do \
 
152
{ \
 
153
        if ((bits_left >= 6) && (bits_left <= 8)) \
 
154
        { \
 
155
                i = bits_left - 5; \
 
156
                outputBuffer[opb_index] |= _data << i; \
 
157
                bits_left = i; \
 
158
        } \
 
159
        else \
 
160
        { \
 
161
                i = 5 - bits_left; \
 
162
                j = 8 - i; \
 
163
                outputBuffer[opb_index++] |= _data >> i; \
 
164
                outputBuffer[opb_index] |= _data << j; \
 
165
                bits_left = j; \
 
166
        } \
 
167
} while (0)
 
168
 
 
169
/*****************************************************************************
 
170
                     insert 6 bits into outputBuffer
 
171
******************************************************************************/
 
172
#define insert_6_bits(_data) \
 
173
do \
 
174
{ \
 
175
        if ((bits_left >= 7) && (bits_left <= 8)) \
 
176
        { \
 
177
                i = bits_left - 6; \
 
178
                outputBuffer[opb_index] |= (_data << i); \
 
179
                bits_left = i; \
 
180
        } \
 
181
        else \
 
182
        { \
 
183
                i = 6 - bits_left; \
 
184
                j = 8 - i; \
 
185
                outputBuffer[opb_index++] |= (_data >> i); \
 
186
                outputBuffer[opb_index] |= (_data << j); \
 
187
                bits_left = j; \
 
188
        } \
 
189
} while (0)
 
190
 
 
191
/*****************************************************************************
 
192
                     insert 7 bits into outputBuffer
 
193
******************************************************************************/
 
194
#define insert_7_bits(_data) \
 
195
do \
 
196
{ \
 
197
        if (bits_left == 8) \
 
198
        { \
 
199
                outputBuffer[opb_index] |= _data << 1; \
 
200
                bits_left = 1; \
 
201
        } \
 
202
        else \
 
203
        { \
 
204
                i = 7 - bits_left; \
 
205
                j = 8 - i; \
 
206
                outputBuffer[opb_index++] |= _data >> i; \
 
207
                outputBuffer[opb_index] |= _data << j; \
 
208
                bits_left = j; \
 
209
        } \
 
210
} while (0)
 
211
 
 
212
/*****************************************************************************
 
213
                     insert 8 bits into outputBuffer
 
214
******************************************************************************/
 
215
#define insert_8_bits(_data) \
 
216
do \
 
217
{ \
 
218
        if (bits_left == 8) \
 
219
        { \
 
220
                outputBuffer[opb_index++] |= _data; \
 
221
                bits_left = 8; \
 
222
        } \
 
223
        else \
 
224
        { \
 
225
                i = 8 - bits_left; \
 
226
                j = 8 - i; \
 
227
                outputBuffer[opb_index++] |= _data >> i; \
 
228
                outputBuffer[opb_index] |= _data << j; \
 
229
                bits_left = j; \
 
230
        } \
 
231
} while (0)
 
232
 
 
233
/*****************************************************************************
 
234
                     insert 9 bits into outputBuffer
 
235
******************************************************************************/
 
236
#define insert_9_bits(_data16) \
 
237
do \
 
238
{ \
 
239
        i = 9 - bits_left; \
 
240
        j = 8 - i; \
 
241
        outputBuffer[opb_index++] |= (char) (_data16 >> i); \
 
242
        outputBuffer[opb_index] |= (char) (_data16 << j); \
 
243
        bits_left = j; \
 
244
        if (bits_left == 0) \
 
245
        { \
 
246
                opb_index++; \
 
247
                bits_left = 8; \
 
248
        } \
 
249
} while (0)
 
250
 
 
251
/*****************************************************************************
 
252
                     insert 10 bits into outputBuffer
 
253
******************************************************************************/
 
254
#define insert_10_bits(_data16) \
 
255
do \
 
256
{ \
 
257
        i = 10 - bits_left; \
 
258
        if ((bits_left >= 3) && (bits_left <= 8)) \
 
259
        { \
 
260
                j = 8 - i; \
 
261
                outputBuffer[opb_index++] |= (char) (_data16 >> i); \
 
262
                outputBuffer[opb_index] |= (char) (_data16 << j); \
 
263
                bits_left = j; \
 
264
        } \
 
265
        else \
 
266
        { \
 
267
                j = i - 8; \
 
268
                k = 8 - j; \
 
269
                outputBuffer[opb_index++] |= (char) (_data16 >> i); \
 
270
                outputBuffer[opb_index++] |= (char) (_data16 >> j); \
 
271
                outputBuffer[opb_index] |= (char) (_data16 << k); \
 
272
                bits_left = k; \
 
273
        } \
 
274
} while (0)
 
275
 
 
276
/*****************************************************************************
 
277
                     insert 11 bits into outputBuffer
 
278
******************************************************************************/
 
279
#define insert_11_bits(_data16) \
 
280
do \
 
281
{ \
 
282
        i = 11 - bits_left; \
 
283
        if ((bits_left >= 4) && (bits_left <= 8)) \
 
284
        { \
 
285
                j = 8 - i; \
 
286
                outputBuffer[opb_index++] |= (char) (_data16 >> i); \
 
287
                outputBuffer[opb_index] |= (char) (_data16 << j); \
 
288
                bits_left = j; \
 
289
        } \
 
290
        else \
 
291
        { \
 
292
                j = i - 8;                                \
 
293
                k = 8 - j; \
 
294
                outputBuffer[opb_index++] |= (char) (_data16 >> i); \
 
295
                outputBuffer[opb_index++] |= (char) (_data16 >> j); \
 
296
                outputBuffer[opb_index] |= (char) (_data16 << k); \
 
297
                bits_left = k; \
 
298
        } \
 
299
} while (0)
 
300
 
 
301
/*****************************************************************************
 
302
                     insert 12 bits into outputBuffer
 
303
******************************************************************************/
 
304
#define insert_12_bits(_data16) \
 
305
do \
 
306
{ \
 
307
        i = 12 - bits_left; \
 
308
        if ((bits_left >= 5) && (bits_left <= 8)) \
 
309
        { \
 
310
                j = 8 - i; \
 
311
                outputBuffer[opb_index++] |= (char) (_data16 >> i); \
 
312
                outputBuffer[opb_index] |= (char) (_data16 << j); \
 
313
                bits_left = j; \
 
314
        } \
 
315
        else \
 
316
        { \
 
317
                j = i - 8; \
 
318
                k = 8 - j; \
 
319
                outputBuffer[opb_index++] |= (char) (_data16 >> i); \
 
320
                outputBuffer[opb_index++] |= (char) (_data16 >> j); \
 
321
                outputBuffer[opb_index] |= (char) (_data16 << k); \
 
322
                bits_left = k; \
 
323
        } \
 
324
} while (0)
 
325
 
 
326
/*****************************************************************************
 
327
                     insert 13 bits into outputBuffer
 
328
******************************************************************************/
 
329
#define insert_13_bits(_data16) \
 
330
do \
 
331
{ \
 
332
        i = 13 - bits_left; \
 
333
        if ((bits_left >= 6) && (bits_left <= 8)) \
 
334
        { \
 
335
                j = 8 - i; \
 
336
                outputBuffer[opb_index++] |= (char) (_data16 >> i); \
 
337
                outputBuffer[opb_index] |= (char) (_data16 << j); \
 
338
                bits_left = j; \
 
339
        } \
 
340
        else \
 
341
        { \
 
342
                j = i - 8; \
 
343
                k = 8 - j; \
 
344
                outputBuffer[opb_index++] |= (char) (_data16 >> i); \
 
345
                outputBuffer[opb_index++] |= (char) (_data16 >> j); \
 
346
                outputBuffer[opb_index] |= (char) (_data16 << k); \
 
347
                bits_left = k; \
 
348
        } \
 
349
} while (0)
 
350
 
 
351
/*****************************************************************************
 
352
                     insert 14 bits into outputBuffer
 
353
******************************************************************************/
 
354
#define insert_14_bits(_data16) \
 
355
do \
 
356
{ \
 
357
        i = 14 - bits_left; \
 
358
        if ((bits_left >= 7) && (bits_left <= 8)) \
 
359
        { \
 
360
                j = 8 - i; \
 
361
                outputBuffer[opb_index++] |= (char) (_data16 >> i); \
 
362
                outputBuffer[opb_index] |= (char) (_data16 << j); \
 
363
                bits_left = j; \
 
364
        } \
 
365
        else \
 
366
        { \
 
367
                j = i - 8; \
 
368
                k = 8 - j; \
 
369
                outputBuffer[opb_index++] |= (char) (_data16 >> i); \
 
370
                outputBuffer[opb_index++] |= (char) (_data16 >> j); \
 
371
                outputBuffer[opb_index] |= (char) (_data16 << k); \
 
372
                bits_left = k; \
 
373
        } \
 
374
} while (0)
 
375
 
 
376
/*****************************************************************************
 
377
                     insert 15 bits into outputBuffer
 
378
******************************************************************************/
 
379
#define insert_15_bits(_data16) \
 
380
do \
 
381
{ \
 
382
        i = 15 - bits_left; \
 
383
        if (bits_left == 8) \
 
384
        { \
 
385
                j = 8 - i; \
 
386
                outputBuffer[opb_index++] |= (char) (_data16 >> i); \
 
387
                outputBuffer[opb_index] |= (char) (_data16 << j); \
 
388
                bits_left = j; \
 
389
        } \
 
390
        else \
 
391
        { \
 
392
                j = i - 8; \
 
393
                k = 8 - j; \
 
394
                outputBuffer[opb_index++] |= (char) (_data16 >> i); \
 
395
                outputBuffer[opb_index++] |= (char) (_data16 >> j); \
 
396
                outputBuffer[opb_index] |= (char) (_data16 << k); \
 
397
                bits_left = k; \
 
398
        } \
 
399
} while (0)
 
400
 
 
401
/*****************************************************************************
 
402
                     insert 16 bits into outputBuffer
 
403
******************************************************************************/
 
404
#define insert_16_bits(_data16) \
 
405
do \
 
406
{ \
 
407
        i = 16 - bits_left; \
 
408
        j = i - 8; \
 
409
        k = 8 - j; \
 
410
        outputBuffer[opb_index++] |= (char) (_data16 >> i); \
 
411
        outputBuffer[opb_index++] |= (char) (_data16 >> j); \
 
412
        outputBuffer[opb_index] |= (char) (_data16 << k); \
 
413
        bits_left = k; \
 
414
} while (0)
 
415
 
 
416
#if MPPC_ENC_DEBUG
 
417
#define DLOG(_args) printf _args
 
418
#else
 
419
#define DLOG(_args) do { } while (0)
 
420
#endif
 
421
 
 
422
/**
 
423
 * Initialize mppc_enc structure
 
424
 *
 
425
 * @param   protocol_type   PROTO_RDP_40 or PROTO_RDP_50
 
426
 *
 
427
 * @return  struct rdp_mppc_enc* or nil on failure
 
428
 */
 
429
 
 
430
struct rdp_mppc_enc* mppc_enc_new(int protocol_type)
 
431
{
 
432
        struct rdp_mppc_enc* enc;
 
433
 
 
434
        enc = (struct rdp_mppc_enc*) malloc(sizeof(struct rdp_mppc_enc));
 
435
        ZeroMemory(enc, sizeof(struct rdp_mppc_enc));
 
436
 
 
437
        if (enc == NULL)
 
438
                return NULL;
 
439
 
 
440
        switch (protocol_type)
 
441
        {
 
442
                case PROTO_RDP_40:
 
443
                        enc->protocol_type = PROTO_RDP_40;
 
444
                        enc->buf_len = RDP_40_HIST_BUF_LEN;
 
445
                        break;
 
446
 
 
447
                case PROTO_RDP_50:
 
448
                        enc->protocol_type = PROTO_RDP_50;
 
449
                        enc->buf_len = RDP_50_HIST_BUF_LEN;
 
450
                        break;
 
451
 
 
452
                default:
 
453
                        free(enc);
 
454
                        return NULL;
 
455
        }
 
456
 
 
457
        enc->first_pkt = 1;
 
458
        enc->historyBuffer = (char*) malloc(enc->buf_len);
 
459
        ZeroMemory(enc->historyBuffer, enc->buf_len);
 
460
 
 
461
        if (enc->historyBuffer == NULL)
 
462
        {
 
463
                free(enc);
 
464
                return NULL;
 
465
        }
 
466
 
 
467
        enc->outputBufferPlus = (char*) malloc(enc->buf_len + 64);
 
468
        ZeroMemory(enc->outputBufferPlus, enc->buf_len + 64);
 
469
 
 
470
        if (enc->outputBufferPlus == NULL)
 
471
        {
 
472
                free(enc->historyBuffer);
 
473
                free(enc);
 
474
                return NULL;
 
475
        }
 
476
 
 
477
        enc->outputBuffer = enc->outputBufferPlus + 64;
 
478
        enc->hash_table = (UINT16*) malloc(enc->buf_len * 2);
 
479
        ZeroMemory(enc->hash_table, enc->buf_len * 2);
 
480
 
 
481
        if (enc->hash_table == NULL)
 
482
        {
 
483
                free(enc->historyBuffer);
 
484
                free(enc->outputBufferPlus);
 
485
                free(enc);
 
486
                return NULL;
 
487
        }
 
488
 
 
489
        return enc;
 
490
}
 
491
 
 
492
/**
 
493
 * deinit mppc_enc structure
 
494
 *
 
495
 * @param   enc  struct to be deinited
 
496
 */
 
497
 
 
498
void mppc_enc_free(struct rdp_mppc_enc* enc)
 
499
{
 
500
        if (enc == NULL)
 
501
                return;
 
502
        free(enc->historyBuffer);
 
503
        free(enc->outputBufferPlus);
 
504
        free(enc->hash_table);
 
505
        free(enc);
 
506
}
 
507
 
 
508
/**
 
509
 * encode (compress) data
 
510
 *
 
511
 * @param   enc           encoder state info
 
512
 * @param   srcData       uncompressed data
 
513
 * @param   len           length of srcData
 
514
 *
 
515
 * @return  TRUE on success, FALSE on failure
 
516
 */
 
517
 
 
518
BOOL compress_rdp(struct rdp_mppc_enc* enc, BYTE* srcData, int len)
 
519
{
 
520
        if ((enc == NULL) || (srcData == NULL) || (len <= 0) || (len > enc->buf_len))
 
521
                return FALSE;
 
522
 
 
523
        switch (enc->protocol_type)
 
524
        {
 
525
                case PROTO_RDP_40:
 
526
                        return compress_rdp_4(enc, srcData, len);
 
527
                        break;
 
528
 
 
529
                case PROTO_RDP_50:
 
530
                        return compress_rdp_5(enc, srcData, len);
 
531
                        break;
 
532
        }
 
533
 
 
534
        return FALSE;
 
535
}
 
536
 
 
537
/**
 
538
 * encode (compress) data using RDP 4.0 protocol
 
539
 *
 
540
 * @param   enc           encoder state info
 
541
 * @param   srcData       uncompressed data
 
542
 * @param   len           length of srcData
 
543
 *
 
544
 * @return  TRUE on success, FALSE on failure
 
545
 */
 
546
 
 
547
BOOL compress_rdp_4(struct rdp_mppc_enc* enc, BYTE* srcData, int len)
 
548
{
 
549
        /* RDP 4.0 encoding not yet implemented */
 
550
        return FALSE;
 
551
}
 
552
 
 
553
/**
 
554
 * encode (compress) data using RDP 5.0 protocol using hash table
 
555
 *
 
556
 * @param   enc           encoder state info
 
557
 * @param   srcData       uncompressed data
 
558
 * @param   len           length of srcData
 
559
 *
 
560
 * @return  TRUE on success, FALSE on failure
 
561
 */
 
562
 
 
563
BOOL compress_rdp_5(struct rdp_mppc_enc* enc, BYTE* srcData, int len)
 
564
{
 
565
        char* outputBuffer;     /* points to enc->outputBuffer */
 
566
        char* hptr_end;         /* points to end of history data */
 
567
        char* historyPointer;   /* points to first byte of srcData in historyBuffer */
 
568
        char* hbuf_start;       /* points to start of history buffer */
 
569
        char* cptr1;
 
570
        char* cptr2;
 
571
        int opb_index;          /* index into outputBuffer */
 
572
        int bits_left;          /* unused bits in current byte in outputBuffer */
 
573
        UINT32 copy_offset;     /* pattern match starts here... */
 
574
        UINT32 lom;             /* ...and matches this many bytes */
 
575
        int last_crc_index;     /* don't compute CRC beyond this index */
 
576
        UINT16 *hash_table;     /* hash table for pattern matching */
 
577
 
 
578
        UINT32 i;
 
579
        UINT32 j;
 
580
        UINT32 k;
 
581
        UINT32 x;
 
582
        BYTE  data;
 
583
        UINT16 data16;
 
584
        UINT32 historyOffset;
 
585
        UINT16 crc;
 
586
        UINT32 ctr;
 
587
        UINT32 saved_ctr;
 
588
        UINT32 data_end;
 
589
        BYTE byte_val;
 
590
 
 
591
        crc = 0;
 
592
        opb_index = 0;
 
593
        bits_left = 8;
 
594
        copy_offset = 0;
 
595
        hash_table = enc->hash_table;
 
596
        hbuf_start = enc->historyBuffer;
 
597
        outputBuffer = enc->outputBuffer;
 
598
        memset(outputBuffer, 0, len);
 
599
        enc->flags = PACKET_COMPR_TYPE_64K;
 
600
        if (enc->first_pkt)
 
601
        {
 
602
                enc->first_pkt = 0;
 
603
                enc->flagsHold |= PACKET_AT_FRONT;
 
604
        }
 
605
 
 
606
        if ((enc->historyOffset + len) > enc->buf_len)
 
607
        {
 
608
                /* historyBuffer cannot hold srcData - rewind it */
 
609
                enc->historyOffset = 0;
 
610
                enc->flagsHold |= PACKET_AT_FRONT;
 
611
                memset(hash_table, 0, enc->buf_len * 2);
 
612
        }
 
613
 
 
614
        /* point to next free byte in historyBuffer */
 
615
        historyOffset = enc->historyOffset;
 
616
 
 
617
        /* add / append new data to historyBuffer */
 
618
        memcpy(&(enc->historyBuffer[historyOffset]), srcData, len);
 
619
 
 
620
        /* point to start of data to be compressed */
 
621
        historyPointer = &(enc->historyBuffer[historyOffset]);
 
622
 
 
623
        ctr = copy_offset = lom = 0;
 
624
 
 
625
        /* if we are at start of history buffer, do not attempt to compress */
 
626
        /* first 2 bytes,because minimum LoM is 3                           */
 
627
        if (historyOffset == 0)
 
628
        {
 
629
                /* encode first two bytes are literals */
 
630
                for (x = 0; x < 2; x++)
 
631
                {
 
632
                        data = *(historyPointer + x);
 
633
                        DLOG(("%.2x ", (unsigned char) data));
 
634
                        if (data & 0x80)
 
635
                        {
 
636
                                /* insert encoded literal */
 
637
                                insert_2_bits(0x02);
 
638
                                data &= 0x7f;
 
639
                                insert_7_bits(data);
 
640
                        }
 
641
                        else
 
642
                        {
 
643
                                /* insert literal */
 
644
                                insert_8_bits(data);
 
645
                        }
 
646
                }
 
647
 
 
648
                /* store hash for first two entries in historyBuffer */
 
649
                crc = CRC_INIT;
 
650
                byte_val = enc->historyBuffer[0];
 
651
                CRC(crc, byte_val);
 
652
                byte_val = enc->historyBuffer[1];
 
653
                CRC(crc, byte_val);
 
654
                byte_val = enc->historyBuffer[2];
 
655
                CRC(crc, byte_val);
 
656
                hash_table[crc] = 0;
 
657
 
 
658
                crc = CRC_INIT;
 
659
                byte_val = enc->historyBuffer[1];
 
660
                CRC(crc, byte_val);
 
661
                byte_val = enc->historyBuffer[2];
 
662
                CRC(crc, byte_val);
 
663
                byte_val = enc->historyBuffer[3];
 
664
                CRC(crc, byte_val);
 
665
                hash_table[crc] = 1;
 
666
 
 
667
                /* first two bytes have already been processed */
 
668
                ctr = 2;
 
669
        }
 
670
 
 
671
        enc->historyOffset += len;
 
672
 
 
673
        /* point to last byte in new data */
 
674
        hptr_end = &(enc->historyBuffer[enc->historyOffset - 1]);
 
675
 
 
676
        /* do not compute CRC beyond this */
 
677
        last_crc_index = enc->historyOffset - 3;
 
678
 
 
679
        /* do not search for pattern match beyond this */
 
680
        data_end = len - 2;
 
681
 
 
682
        /* start compressing data */
 
683
 
 
684
        while (ctr < data_end)
 
685
        {
 
686
                cptr1 = historyPointer + ctr;
 
687
 
 
688
                crc = CRC_INIT;
 
689
                byte_val = *cptr1;
 
690
                CRC(crc, byte_val);
 
691
                byte_val = *(cptr1 + 1);
 
692
                CRC(crc, byte_val);
 
693
                byte_val = *(cptr1 + 2);
 
694
                CRC(crc, byte_val);
 
695
 
 
696
                /* cptr2 points to start of pattern match */
 
697
                cptr2 = hbuf_start + hash_table[crc];
 
698
                copy_offset = cptr1 - cptr2;
 
699
 
 
700
                /* save current entry */
 
701
                hash_table[crc] = cptr1 - hbuf_start;
 
702
 
 
703
                /* double check that we have a pattern match */
 
704
                if ((*cptr1 != *cptr2) ||
 
705
                        (*(cptr1 + 1) != *(cptr2 + 1)) ||
 
706
                        (*(cptr1 + 2) != *(cptr2 + 2)))
 
707
                {
 
708
                        /* no match found; encode literal byte */
 
709
                        data = *cptr1;
 
710
 
 
711
                        DLOG(("%.2x ", (unsigned char) data));
 
712
                        if (data < 0x80)
 
713
                        {
 
714
                                /* literal byte < 0x80 */
 
715
                                insert_8_bits(data);
 
716
                        }
 
717
                        else
 
718
                        {
 
719
                                /* literal byte >= 0x80 */
 
720
                                insert_2_bits(0x02);
 
721
                                data &= 0x7f;
 
722
                                insert_7_bits(data);
 
723
                        }
 
724
                        ctr++;
 
725
                        continue;
 
726
                }
 
727
 
 
728
                /* we have a match - compute Length of Match */
 
729
                cptr1 += 3;
 
730
                cptr2 += 3;
 
731
                lom = 3;
 
732
                while ((cptr1 <= hptr_end) && (*(cptr1++) == *(cptr2++)))
 
733
                {
 
734
                        lom++;
 
735
                }
 
736
                saved_ctr = ctr + lom;
 
737
                DLOG(("<%d: %ld,%d> ",  (historyPointer + ctr) - hbuf_start, copy_offset, lom));
 
738
 
 
739
                /* compute CRC for matching segment and store in hash table */
 
740
 
 
741
                cptr1 = historyPointer + ctr;
 
742
                if (cptr1 + lom > hbuf_start + last_crc_index)
 
743
                {
 
744
                        /* we have gone beyond last_crc_index - go back */
 
745
                        j = last_crc_index - (cptr1 - hbuf_start);
 
746
                }
 
747
                else
 
748
                {
 
749
                        j = lom - 1;
 
750
                }
 
751
                ctr++;
 
752
                for (i = 0; i < j; i++)
 
753
                {
 
754
                        cptr1 = historyPointer + ctr;
 
755
 
 
756
                        /* compute CRC on triplet */
 
757
                        crc = CRC_INIT;
 
758
                        byte_val = *(cptr1++);
 
759
                        CRC(crc, byte_val);
 
760
                        byte_val = *(cptr1++);
 
761
                        CRC(crc, byte_val);
 
762
                        byte_val = *(cptr1++);
 
763
                        CRC(crc, byte_val);
 
764
 
 
765
                        /* save current entry */
 
766
                        hash_table[crc] = (cptr1 - 3) - hbuf_start;
 
767
 
 
768
                        /* point to next triplet */
 
769
                        ctr++;
 
770
                }
 
771
                ctr = saved_ctr;
 
772
 
 
773
                /* encode copy_offset and insert into output buffer */
 
774
 
 
775
                if (copy_offset <= 63) /* (copy_offset >= 0) is always true */
 
776
                {
 
777
                        /* insert binary header */
 
778
                        data = 0x1f;
 
779
                        insert_5_bits(data);
 
780
 
 
781
                        /* insert 6 bits of copy_offset */
 
782
                        data = (char) (copy_offset & 0x3f);
 
783
                        insert_6_bits(data);
 
784
                }
 
785
                else if ((copy_offset >= 64) && (copy_offset <= 319))
 
786
                {
 
787
                        /* insert binary header */
 
788
                        data = 0x1e;
 
789
                        insert_5_bits(data);
 
790
 
 
791
                        /* insert 8 bits of copy offset */
 
792
                        data = (char) (copy_offset - 64);
 
793
                        insert_8_bits(data);
 
794
                }
 
795
                else if ((copy_offset >= 320) && (copy_offset <= 2367))
 
796
                {
 
797
                        /* insert binary header */
 
798
                        data = 0x0e;
 
799
                        insert_4_bits(data);
 
800
 
 
801
                        /* insert 11 bits of copy offset */
 
802
                        data16 = copy_offset - 320;;
 
803
                        insert_11_bits(data16);
 
804
                }
 
805
                else
 
806
                {
 
807
                        /* copy_offset is 2368+ */
 
808
 
 
809
                        /* insert binary header */
 
810
                        data = 0x06;
 
811
                        insert_3_bits(data);
 
812
 
 
813
                        /* insert 16 bits of copy offset */
 
814
                        data16 = copy_offset - 2368;;
 
815
                        insert_16_bits(data16);
 
816
                }
 
817
 
 
818
                /* encode length of match and insert into output buffer */
 
819
 
 
820
                if (lom == 3)
 
821
                {
 
822
                        /* binary header is 'zero'; since outputBuffer is zero */
 
823
                        /* filled, all we have to do is update bits_left */
 
824
                        bits_left--;
 
825
                        if (bits_left == 0)
 
826
                        {
 
827
                                opb_index++;
 
828
                                bits_left = 8;
 
829
                        }
 
830
                }
 
831
                else if ((lom >= 4) && (lom <= 7))
 
832
                {
 
833
                        /* insert binary header */
 
834
                        data = 0x02;
 
835
                        insert_2_bits(data);
 
836
 
 
837
                        /* insert lower 2 bits of LoM */
 
838
                        data = (char) (lom - 4);
 
839
                        insert_2_bits(data);
 
840
                }
 
841
                else if ((lom >= 8) && (lom <= 15))
 
842
                {
 
843
                        /* insert binary header */
 
844
                        data = 0x06;
 
845
                        insert_3_bits(data);
 
846
 
 
847
                        /* insert lower 3 bits of LoM */
 
848
                        data = (char) (lom - 8);
 
849
                        insert_3_bits(data);
 
850
                }
 
851
                else if ((lom >= 16) && (lom <= 31))
 
852
                {
 
853
                        /* insert binary header */
 
854
                        data = 0x0e;
 
855
                        insert_4_bits(data);
 
856
 
 
857
                        /* insert lower 4 bits of LoM */
 
858
                        data = (char) (lom - 16);
 
859
                        insert_4_bits(data);
 
860
                }
 
861
                else if ((lom >= 32) && (lom <= 63))
 
862
                {
 
863
                        /* insert binary header */
 
864
                        data = 0x1e;
 
865
                        insert_5_bits(data);
 
866
 
 
867
                        /* insert lower 5 bits of LoM */
 
868
                        data = (char) (lom - 32);
 
869
                        insert_5_bits(data);
 
870
                }
 
871
                else if ((lom >= 64) && (lom <= 127))
 
872
                {
 
873
                        /* insert binary header */
 
874
                        data = 0x3e;
 
875
                        insert_6_bits(data);
 
876
 
 
877
                        /* insert lower 6 bits of LoM */
 
878
                        data = (char) (lom - 64);
 
879
                        insert_6_bits(data);
 
880
                }
 
881
                else if ((lom >= 128) && (lom <= 255))
 
882
                {
 
883
                        /* insert binary header */
 
884
                        data = 0x7e;
 
885
                        insert_7_bits(data);
 
886
 
 
887
                        /* insert lower 7 bits of LoM */
 
888
                        data = (char) (lom - 128);
 
889
                        insert_7_bits(data);
 
890
                }
 
891
                else if ((lom >= 256) && (lom <= 511))
 
892
                {
 
893
                        /* insert binary header */
 
894
                        data = 0xfe;
 
895
                        insert_8_bits(data);
 
896
 
 
897
                        /* insert lower 8 bits of LoM */
 
898
                        data = (char) (lom - 256);
 
899
                        insert_8_bits(data);
 
900
                }
 
901
                else if ((lom >= 512) && (lom <= 1023))
 
902
                {
 
903
                        /* insert binary header */
 
904
                        data16 = 0x1fe;
 
905
                        insert_9_bits(data16);
 
906
 
 
907
                        /* insert lower 9 bits of LoM */
 
908
                        data16 = lom - 512;
 
909
                        insert_9_bits(data16);
 
910
                }
 
911
                else if ((lom >= 1024) && (lom <= 2047))
 
912
                {
 
913
                        /* insert binary header */
 
914
                        data16 = 0x3fe;
 
915
                        insert_10_bits(data16);
 
916
 
 
917
                        /* insert 10 lower bits of LoM */
 
918
                        data16 = lom - 1024;
 
919
                        insert_10_bits(data16);
 
920
                }
 
921
                else if ((lom >= 2048) && (lom <= 4095))
 
922
                {
 
923
                        /* insert binary header */
 
924
                        data16 = 0x7fe;
 
925
                        insert_11_bits(data16);
 
926
 
 
927
                        /* insert 11 lower bits of LoM */
 
928
                        data16 = lom - 2048;
 
929
                        insert_11_bits(data16);
 
930
                }
 
931
                else if ((lom >= 4096) && (lom <= 8191))
 
932
                {
 
933
                        /* insert binary header */
 
934
                        data16 = 0xffe;
 
935
                        insert_12_bits(data16);
 
936
 
 
937
                        /* insert 12 lower bits of LoM */
 
938
                        data16 = lom - 4096;
 
939
                        insert_12_bits(data16);
 
940
                }
 
941
                else if ((lom >= 8192) && (lom <= 16383))
 
942
                {
 
943
                        /* insert binary header */
 
944
                        data16 = 0x1ffe;
 
945
                        insert_13_bits(data16);
 
946
 
 
947
                        /* insert 13 lower bits of LoM */
 
948
                        data16 = lom - 8192;
 
949
                        insert_13_bits(data16);
 
950
                }
 
951
                else if ((lom >= 16384) && (lom <= 32767))
 
952
                {
 
953
                        /* insert binary header */
 
954
                        data16 = 0x3ffe;
 
955
                        insert_14_bits(data16);
 
956
 
 
957
                        /* insert 14 lower bits of LoM */
 
958
                        data16 = lom - 16384;
 
959
                        insert_14_bits(data16);
 
960
                }
 
961
                else if ((lom >= 32768) && (lom <= 65535))
 
962
                {
 
963
                        /* insert binary header */
 
964
                        data16 = 0x7ffe;
 
965
                        insert_15_bits(data16);
 
966
 
 
967
                        /* insert 15 lower bits of LoM */
 
968
                        data16 = lom - 32768;
 
969
                        insert_15_bits(data16);
 
970
                }
 
971
        } /* end while (ctr < data_end) */
 
972
 
 
973
        /* add remaining data to the output */
 
974
        while (len - ctr > 0)
 
975
        {
 
976
                data = srcData[ctr];
 
977
                DLOG(("%.2x ", (unsigned char) data));
 
978
                if (data < 0x80)
 
979
                {
 
980
                        /* literal byte < 0x80 */
 
981
                        insert_8_bits(data);
 
982
                }
 
983
                else
 
984
                {
 
985
                        /* literal byte >= 0x80 */
 
986
                        insert_2_bits(0x02);
 
987
                        data &= 0x7f;
 
988
                        insert_7_bits(data);
 
989
                }
 
990
                ctr++;
 
991
        }
 
992
 
 
993
        /* if bits_left == 8, opb_index has already been incremented */
 
994
        if ((bits_left == 8) && (opb_index > len))
 
995
        {
 
996
                /* compressed data longer than uncompressed data */
 
997
                /* give up */
 
998
                enc->historyOffset = 0;
 
999
                memset(hash_table, 0, enc->buf_len * 2);
 
1000
                enc->flagsHold |= PACKET_FLUSHED;
 
1001
                enc->first_pkt = 1;
 
1002
                return TRUE;
 
1003
        }
 
1004
        else if (opb_index + 1 > len)
 
1005
        {
 
1006
                /* compressed data longer than uncompressed data */
 
1007
                /* give up */
 
1008
                enc->historyOffset = 0;
 
1009
                memset(hash_table, 0, enc->buf_len * 2);
 
1010
                enc->flagsHold |= PACKET_FLUSHED;
 
1011
                enc->first_pkt = 1;
 
1012
                return TRUE;
 
1013
        }
 
1014
 
 
1015
        /* if bits_left != 8, increment opb_index, which is zero indexed */
 
1016
        if (bits_left != 8)
 
1017
        {
 
1018
                opb_index++;
 
1019
        }
 
1020
 
 
1021
        if (opb_index > len)
 
1022
        {
 
1023
                /* give up */
 
1024
                enc->historyOffset = 0;
 
1025
                memset(hash_table, 0, enc->buf_len * 2);
 
1026
                enc->flagsHold |= PACKET_FLUSHED;
 
1027
                enc->first_pkt = 1;
 
1028
                return TRUE;
 
1029
        }
 
1030
        enc->flags |= PACKET_COMPRESSED;
 
1031
        enc->bytes_in_opb = opb_index;
 
1032
 
 
1033
        enc->flags |= enc->flagsHold;
 
1034
        enc->flagsHold = 0;
 
1035
        DLOG(("\n"));
 
1036
 
 
1037
        return TRUE;
 
1038
}