libfreerdp-codec: remove old MPPC decompressor, fix RDP4 MPPC
This commit is contained in:
parent
891a10c4f6
commit
98f98c95e9
@ -25,6 +25,10 @@
|
||||
|
||||
#include <winpr/bitstream.h>
|
||||
|
||||
#define PACKET_COMPRESSED 0x20
|
||||
#define PACKET_AT_FRONT 0x40
|
||||
#define PACKET_FLUSHED 0x80
|
||||
|
||||
struct _MPPC_CONTEXT
|
||||
{
|
||||
wBitStream* bs;
|
||||
@ -45,6 +49,7 @@ extern "C" {
|
||||
FREERDP_API UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32* pSize);
|
||||
FREERDP_API UINT32 mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE** ppDstData, UINT32* pSize, UINT32 flags);
|
||||
|
||||
FREERDP_API void mppc_set_compression_level(MPPC_CONTEXT* mppc, DWORD CompressionLevel);
|
||||
FREERDP_API void mppc_context_reset(MPPC_CONTEXT* mppc);
|
||||
|
||||
FREERDP_API MPPC_CONTEXT* mppc_context_new(DWORD CompressionLevel, BOOL Compressor);
|
||||
|
@ -24,11 +24,7 @@
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
|
||||
/* Compression Types */
|
||||
|
||||
#define PACKET_COMPRESSED 0x20
|
||||
#define PACKET_AT_FRONT 0x40
|
||||
#define PACKET_FLUSHED 0x80
|
||||
#include <freerdp/codec/mppc.h>
|
||||
|
||||
#define RDP6_HISTORY_BUF_SIZE 65536
|
||||
#define RDP6_OFFSET_CACHE_SIZE 8
|
||||
@ -41,11 +37,7 @@ struct rdp_mppc_dec
|
||||
BYTE* history_ptr;
|
||||
};
|
||||
|
||||
FREERDP_API int decompress_rdp(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, UINT32* roff, UINT32* rlen);
|
||||
FREERDP_API int decompress_rdp_4(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, UINT32* roff, UINT32* rlen);
|
||||
FREERDP_API int decompress_rdp_5(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, UINT32* roff, UINT32* rlen);
|
||||
FREERDP_API int decompress_rdp_6(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, UINT32* roff, UINT32* rlen);
|
||||
FREERDP_API int decompress_rdp_61(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, UINT32* roff, UINT32* rlen);
|
||||
|
||||
FREERDP_API struct rdp_mppc_dec* mppc_dec_new(void);
|
||||
FREERDP_API void mppc_dec_free(struct rdp_mppc_dec* dec);
|
||||
|
@ -777,6 +777,20 @@ UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32*
|
||||
return Flags;
|
||||
}
|
||||
|
||||
void mppc_set_compression_level(MPPC_CONTEXT* mppc, DWORD CompressionLevel)
|
||||
{
|
||||
if (CompressionLevel < 1)
|
||||
{
|
||||
mppc->CompressionLevel = 0;
|
||||
mppc->HistoryBufferSize = 8192;
|
||||
}
|
||||
else
|
||||
{
|
||||
mppc->CompressionLevel = 1;
|
||||
mppc->HistoryBufferSize = 65536;
|
||||
}
|
||||
}
|
||||
|
||||
void mppc_context_reset(MPPC_CONTEXT* mppc)
|
||||
{
|
||||
ZeroMemory(&(mppc->HistoryBuffer), sizeof(mppc->HistoryBuffer));
|
||||
|
@ -129,935 +129,6 @@ UINT32 transposebits(UINT32 x)
|
||||
*(_s) = *((_s) + (_i)); \
|
||||
*((_s) + (_i)) = t; } while(0)
|
||||
|
||||
int decompress_rdp(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, UINT32* roff, UINT32* rlen)
|
||||
{
|
||||
UINT32 type = ctype & 0x0F;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case PACKET_COMPR_TYPE_8K:
|
||||
return decompress_rdp_4(dec, cbuf, len, ctype, roff, rlen);
|
||||
break;
|
||||
|
||||
case PACKET_COMPR_TYPE_64K:
|
||||
return decompress_rdp_5(dec, cbuf, len, ctype, roff, rlen);
|
||||
break;
|
||||
|
||||
case PACKET_COMPR_TYPE_RDP6:
|
||||
return decompress_rdp_6(dec, cbuf, len, ctype, roff, rlen);
|
||||
break;
|
||||
|
||||
case PACKET_COMPR_TYPE_RDP61:
|
||||
return decompress_rdp_61(dec, cbuf, len, ctype, roff, rlen);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "mppc.c: invalid RDP compression code 0x%2.2x\n", type);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* decompress RDP 4 data
|
||||
*
|
||||
* @param rdp per session information
|
||||
* @param cbuf compressed data
|
||||
* @param len length of compressed data
|
||||
* @param ctype compression flags
|
||||
* @param roff starting offset of uncompressed data
|
||||
* @param rlen length of uncompressed data
|
||||
*
|
||||
* @return True on success, False on failure
|
||||
*/
|
||||
|
||||
int decompress_rdp_4(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, UINT32* roff, UINT32* rlen)
|
||||
{
|
||||
BYTE* history_buf; /* uncompressed data goes here */
|
||||
BYTE* history_ptr; /* points to next free slot in history_buf */
|
||||
UINT32 d32; /* we process 4 compressed bytes at a time */
|
||||
UINT16 copy_offset; /* location to copy data from */
|
||||
UINT16 lom; /* length of match */
|
||||
BYTE* src_ptr; /* used while copying compressed data */
|
||||
BYTE* cptr; /* points to next byte in cbuf */
|
||||
BYTE cur_byte; /* last byte fetched from cbuf */
|
||||
unsigned int bits_left; /* bits left in d34 for processing */
|
||||
unsigned int cur_bits_left; /* bits left in cur_byte for processing */
|
||||
int tmp;
|
||||
UINT32 i32;
|
||||
|
||||
fprintf(stderr, "decompress_rdp_4:\n");
|
||||
|
||||
if ((dec == NULL) || (dec->history_buf == NULL))
|
||||
{
|
||||
fprintf(stderr, "decompress_rdp_4: null\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
src_ptr = 0;
|
||||
cptr = cbuf;
|
||||
copy_offset = 0;
|
||||
lom = 0;
|
||||
bits_left = 0;
|
||||
cur_bits_left = 0;
|
||||
d32 = 0;
|
||||
cur_byte = 0;
|
||||
*rlen = 0;
|
||||
|
||||
/* get start of history buffer */
|
||||
history_buf = dec->history_buf;
|
||||
|
||||
/* get next free slot in history buffer */
|
||||
history_ptr = dec->history_ptr;
|
||||
*roff = history_ptr - history_buf;
|
||||
|
||||
if (ctype & PACKET_AT_FRONT)
|
||||
{
|
||||
/* place compressed data at start of history buffer */
|
||||
history_ptr = dec->history_buf;
|
||||
dec->history_ptr = dec->history_buf;
|
||||
*roff = 0;
|
||||
}
|
||||
|
||||
if (ctype & PACKET_FLUSHED)
|
||||
{
|
||||
/* re-init history buffer */
|
||||
history_ptr = dec->history_buf;
|
||||
memset(history_buf, 0, RDP6_HISTORY_BUF_SIZE);
|
||||
*roff = 0;
|
||||
}
|
||||
|
||||
if ((ctype & PACKET_COMPRESSED) != PACKET_COMPRESSED)
|
||||
{
|
||||
/* data in cbuf is not compressed - copy to history buf as is */
|
||||
memcpy(history_ptr, cbuf, len);
|
||||
history_ptr += len;
|
||||
*rlen = history_ptr - dec->history_ptr;
|
||||
dec->history_ptr = history_ptr;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* load initial data */
|
||||
tmp = 24;
|
||||
while (cptr < cbuf + len)
|
||||
{
|
||||
i32 = *cptr++;
|
||||
d32 |= i32 << tmp;
|
||||
bits_left += 8;
|
||||
tmp -= 8;
|
||||
if (tmp < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cptr < cbuf + len)
|
||||
{
|
||||
cur_byte = *cptr++;
|
||||
cur_bits_left = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_bits_left = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** start uncompressing data in cbuf
|
||||
*/
|
||||
|
||||
while (bits_left >= 8)
|
||||
{
|
||||
/*
|
||||
value 0xxxxxxx = literal, not encoded
|
||||
value 10xxxxxx = literal, encoded
|
||||
value 1111xxxx = copy offset 0 - 63
|
||||
value 1110xxxx = copy offset 64 - 319
|
||||
value 110xxxxx = copy offset 320 - 8191
|
||||
*/
|
||||
|
||||
/*
|
||||
at this point, we are guaranteed that d32 has 32 bits to
|
||||
be processed, unless we have reached end of cbuf
|
||||
*/
|
||||
|
||||
copy_offset = 0;
|
||||
|
||||
if ((d32 & 0x80000000) == 0)
|
||||
{
|
||||
/* got a literal */
|
||||
*history_ptr++ = d32 >> 24;
|
||||
d32 <<= 8;
|
||||
bits_left -= 8;
|
||||
}
|
||||
else if ((d32 & 0xc0000000) == 0x80000000)
|
||||
{
|
||||
/* got encoded literal */
|
||||
d32 <<= 2;
|
||||
*history_ptr++ = (d32 >> 25) | 0x80;
|
||||
d32 <<= 7;
|
||||
bits_left -= 9;
|
||||
}
|
||||
else if ((d32 & 0xf0000000) == 0xf0000000)
|
||||
{
|
||||
/* got copy offset in range 0 - 63, */
|
||||
/* with 6 bit copy offset */
|
||||
d32 <<= 4;
|
||||
copy_offset = d32 >> 26;
|
||||
d32 <<= 6;
|
||||
bits_left -= 10;
|
||||
}
|
||||
else if ((d32 & 0xf0000000) == 0xe0000000)
|
||||
{
|
||||
/* got copy offset in range 64 - 319, */
|
||||
/* with 8 bit copy offset */
|
||||
d32 <<= 4;
|
||||
copy_offset = d32 >> 24;
|
||||
copy_offset += 64;
|
||||
d32 <<= 8;
|
||||
bits_left -= 12;
|
||||
}
|
||||
else if ((d32 & 0xe0000000) == 0xc0000000)
|
||||
{
|
||||
/* got copy offset in range 320 - 8191, */
|
||||
/* with 13 bits copy offset */
|
||||
d32 <<= 3;
|
||||
copy_offset = d32 >> 19;
|
||||
copy_offset += 320;
|
||||
d32 <<= 13;
|
||||
bits_left -= 16;
|
||||
}
|
||||
|
||||
/*
|
||||
** get more bits before we process length of match
|
||||
*/
|
||||
|
||||
/* how may bits do we need to get? */
|
||||
assert(bits_left <= 32);
|
||||
tmp = 32 - bits_left;
|
||||
|
||||
while (tmp)
|
||||
{
|
||||
if (cur_bits_left < tmp)
|
||||
{
|
||||
/* we have less bits than we need */
|
||||
i32 = cur_byte >> (8 - cur_bits_left);
|
||||
d32 |= (i32 << ((32 - bits_left) - cur_bits_left)) & 0xFFFFFFFF;
|
||||
bits_left += cur_bits_left;
|
||||
tmp -= cur_bits_left;
|
||||
if (cptr < cbuf + len)
|
||||
{
|
||||
/* more compressed data available */
|
||||
cur_byte = *cptr++;
|
||||
cur_bits_left = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no more compressed data available */
|
||||
tmp = 0;
|
||||
cur_bits_left = 0;
|
||||
}
|
||||
}
|
||||
else if (cur_bits_left > tmp)
|
||||
{
|
||||
/* we have more bits than we need */
|
||||
d32 |= cur_byte >> (8 - tmp);
|
||||
cur_byte <<= tmp;
|
||||
cur_bits_left -= tmp;
|
||||
bits_left = 32;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we have just the right amount of bits */
|
||||
d32 |= cur_byte >> (8 - tmp);
|
||||
bits_left = 32;
|
||||
if (cptr < cbuf + len)
|
||||
{
|
||||
cur_byte = *cptr++;
|
||||
cur_bits_left = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_bits_left = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!copy_offset)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
** compute Length of Match
|
||||
*/
|
||||
|
||||
/*
|
||||
lengh of match Encoding (binary header + LoM bits
|
||||
-------------- ----------------------------------
|
||||
3 0
|
||||
4...7 10 + 2 lower bits of L-o-M
|
||||
8...15 110 + 3 lower bits of L-o-M
|
||||
16...31 1110 + 4 lower bits of L-o-M
|
||||
32...63 11110 + 5 lower bits of L-o-M
|
||||
64...127 111110 + 6 lower bits of L-o-M
|
||||
128...255 1111110 + 7 lower bits of L-o-M
|
||||
256...511 11111110 + 8 lower bits of L-o-M
|
||||
512...1023 111111110 + 9 lower bits of L-o-M
|
||||
1024...2047 1111111110 + 10 lower bits of L-o-M
|
||||
2048...4095 11111111110 + 11 lower bits of L-o-M
|
||||
4096...8191 111111111110 + 12 lower bits of L-o-M
|
||||
*/
|
||||
|
||||
if ((d32 & 0x80000000) == 0)
|
||||
{
|
||||
/* lom is fixed to 3 */
|
||||
lom = 3;
|
||||
d32 <<= 1;
|
||||
bits_left -= 1;
|
||||
}
|
||||
else if ((d32 & 0xc0000000) == 0x80000000)
|
||||
{
|
||||
/* 2 lower bits of LoM */
|
||||
lom = ((d32 >> 28) & 0x03) + 4;
|
||||
d32 <<= 4;
|
||||
bits_left -= 4;
|
||||
}
|
||||
else if ((d32 & 0xe0000000) == 0xc0000000)
|
||||
{
|
||||
/* 3 lower bits of LoM */
|
||||
lom = ((d32 >> 26) & 0x07) + 8;
|
||||
d32 <<= 6;
|
||||
bits_left -= 6;
|
||||
}
|
||||
else if ((d32 & 0xf0000000) == 0xe0000000)
|
||||
{
|
||||
/* 4 lower bits of LoM */
|
||||
lom = ((d32 >> 24) & 0x0f) + 16;
|
||||
d32 <<= 8;
|
||||
bits_left -= 8;
|
||||
}
|
||||
else if ((d32 & 0xf8000000) == 0xf0000000)
|
||||
{
|
||||
/* 5 lower bits of LoM */
|
||||
lom = ((d32 >> 22) & 0x1f) + 32;
|
||||
d32 <<= 10;
|
||||
bits_left -= 10;
|
||||
}
|
||||
else if ((d32 & 0xfc000000) == 0xf8000000)
|
||||
{
|
||||
/* 6 lower bits of LoM */
|
||||
lom = ((d32 >> 20) & 0x3f) + 64;
|
||||
d32 <<= 12;
|
||||
bits_left -= 12;
|
||||
}
|
||||
else if ((d32 & 0xfe000000) == 0xfc000000)
|
||||
{
|
||||
/* 7 lower bits of LoM */
|
||||
lom = ((d32 >> 18) & 0x7f) + 128;
|
||||
d32 <<= 14;
|
||||
bits_left -= 14;
|
||||
}
|
||||
else if ((d32 & 0xff000000) == 0xfe000000)
|
||||
{
|
||||
/* 8 lower bits of LoM */
|
||||
lom = ((d32 >> 16) & 0xff) + 256;
|
||||
d32 <<= 16;
|
||||
bits_left -= 16;
|
||||
}
|
||||
else if ((d32 & 0xff800000) == 0xff000000)
|
||||
{
|
||||
/* 9 lower bits of LoM */
|
||||
lom = ((d32 >> 14) & 0x1ff) + 512;
|
||||
d32 <<= 18;
|
||||
bits_left -= 18;
|
||||
}
|
||||
else if ((d32 & 0xffc00000) == 0xff800000)
|
||||
{
|
||||
/* 10 lower bits of LoM */
|
||||
lom = ((d32 >> 12) & 0x3ff) + 1024;
|
||||
d32 <<= 20;
|
||||
bits_left -= 20;
|
||||
}
|
||||
else if ((d32 & 0xffe00000) == 0xffc00000)
|
||||
{
|
||||
/* 11 lower bits of LoM */
|
||||
lom = ((d32 >> 10) & 0x7ff) + 2048;
|
||||
d32 <<= 22;
|
||||
bits_left -= 22;
|
||||
}
|
||||
else if ((d32 & 0xfff00000) == 0xffe00000)
|
||||
{
|
||||
/* 12 lower bits of LoM */
|
||||
lom = ((d32 >> 8) & 0xfff) + 4096;
|
||||
d32 <<= 24;
|
||||
bits_left -= 24;
|
||||
}
|
||||
|
||||
/* now that we have copy_offset and LoM, process them */
|
||||
|
||||
src_ptr = history_ptr - copy_offset;
|
||||
if (src_ptr >= dec->history_buf)
|
||||
{
|
||||
/* data does not wrap around */
|
||||
while (lom > 0)
|
||||
{
|
||||
*history_ptr++ = *src_ptr++;
|
||||
lom--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
src_ptr = dec->history_buf_end - (copy_offset - (history_ptr - dec->history_buf));
|
||||
src_ptr++;
|
||||
while (lom && (src_ptr <= dec->history_buf_end))
|
||||
{
|
||||
*history_ptr++ = *src_ptr++;
|
||||
lom--;
|
||||
}
|
||||
|
||||
src_ptr = dec->history_buf;
|
||||
while (lom > 0)
|
||||
{
|
||||
*history_ptr++ = *src_ptr++;
|
||||
lom--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** get more bits before we restart the loop
|
||||
*/
|
||||
|
||||
/* how may bits do we need to get? */
|
||||
assert(bits_left <= 32);
|
||||
assert(cur_bits_left <= bits_left);
|
||||
tmp = 32 - bits_left;
|
||||
|
||||
while (tmp)
|
||||
{
|
||||
if (cur_bits_left < tmp)
|
||||
{
|
||||
/* we have less bits than we need */
|
||||
i32 = cur_byte >> (8 - cur_bits_left);
|
||||
d32 |= (i32 << ((32 - bits_left) - cur_bits_left)) & 0xFFFFFFFF;
|
||||
bits_left += cur_bits_left;
|
||||
tmp -= cur_bits_left;
|
||||
if (cptr < cbuf + len)
|
||||
{
|
||||
/* more compressed data available */
|
||||
cur_byte = *cptr++;
|
||||
cur_bits_left = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no more compressed data available */
|
||||
tmp = 0;
|
||||
cur_bits_left = 0;
|
||||
}
|
||||
}
|
||||
else if (cur_bits_left > tmp)
|
||||
{
|
||||
/* we have more bits than we need */
|
||||
d32 |= cur_byte >> (8 - tmp);
|
||||
cur_byte <<= tmp;
|
||||
cur_bits_left -= tmp;
|
||||
bits_left = 32;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we have just the right amount of bits */
|
||||
d32 |= cur_byte >> (8 - tmp);
|
||||
bits_left = 32;
|
||||
if (cptr < cbuf + len)
|
||||
{
|
||||
cur_byte = *cptr++;
|
||||
cur_bits_left = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_bits_left = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* end while (bits_left >= 8) */
|
||||
|
||||
*rlen = history_ptr - dec->history_ptr;
|
||||
|
||||
dec->history_ptr = history_ptr;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* decompress RDP 5 data
|
||||
*
|
||||
* @param rdp per session information
|
||||
* @param cbuf compressed data
|
||||
* @param len length of compressed data
|
||||
* @param ctype compression flags
|
||||
* @param roff starting offset of uncompressed data
|
||||
* @param rlen length of uncompressed data
|
||||
*
|
||||
* @return True on success, False on failure
|
||||
*/
|
||||
|
||||
int decompress_rdp_5(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, UINT32* roff, UINT32* rlen)
|
||||
{
|
||||
BYTE* history_buf; /* uncompressed data goes here */
|
||||
BYTE* history_ptr; /* points to next free slot in bistory_buf */
|
||||
UINT32 d32; /* we process 4 compressed bytes at a time */
|
||||
UINT16 copy_offset; /* location to copy data from */
|
||||
UINT16 lom; /* length of match */
|
||||
BYTE* src_ptr; /* used while copying compressed data */
|
||||
BYTE* cptr; /* points to next byte in cbuf */
|
||||
BYTE cur_byte; /* last byte fetched from cbuf */
|
||||
int bits_left; /* bits left in d32 for processing */
|
||||
int cur_bits_left; /* bits left in cur_byte for processing */
|
||||
int tmp;
|
||||
UINT32 i32;
|
||||
|
||||
if ((dec == NULL) || (dec->history_buf == NULL))
|
||||
{
|
||||
fprintf(stderr, "decompress_rdp_5: null\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
src_ptr = 0;
|
||||
cptr = cbuf;
|
||||
copy_offset = 0;
|
||||
lom = 0;
|
||||
bits_left = 0;
|
||||
cur_bits_left = 0;
|
||||
d32 = 0;
|
||||
cur_byte = 0;
|
||||
*rlen = 0;
|
||||
|
||||
/* get start of history buffer */
|
||||
history_buf = dec->history_buf;
|
||||
|
||||
/* get next free slot in history buffer */
|
||||
history_ptr = dec->history_ptr;
|
||||
*roff = history_ptr - history_buf;
|
||||
|
||||
if (ctype & PACKET_AT_FRONT)
|
||||
{
|
||||
/* place compressed data at start of history buffer */
|
||||
history_ptr = dec->history_buf;
|
||||
dec->history_ptr = dec->history_buf;
|
||||
*roff = 0;
|
||||
}
|
||||
|
||||
if (ctype & PACKET_FLUSHED)
|
||||
{
|
||||
/* re-init history buffer */
|
||||
history_ptr = dec->history_buf;
|
||||
memset(history_buf, 0, RDP6_HISTORY_BUF_SIZE);
|
||||
*roff = 0;
|
||||
}
|
||||
|
||||
if ((ctype & PACKET_COMPRESSED) != PACKET_COMPRESSED)
|
||||
{
|
||||
/* data in cbuf is not compressed - copy to history buf as is */
|
||||
memcpy(history_ptr, cbuf, len);
|
||||
history_ptr += len;
|
||||
*rlen = history_ptr - dec->history_ptr;
|
||||
dec->history_ptr = history_ptr;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* load initial data */
|
||||
tmp = 24;
|
||||
while (cptr < cbuf + len)
|
||||
{
|
||||
i32 = *cptr++;
|
||||
d32 |= i32 << tmp;
|
||||
bits_left += 8;
|
||||
tmp -= 8;
|
||||
if (tmp < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cptr < cbuf + len)
|
||||
{
|
||||
cur_byte = *cptr++;
|
||||
cur_bits_left = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_bits_left = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** start uncompressing data in cbuf
|
||||
*/
|
||||
|
||||
while (bits_left >= 8)
|
||||
{
|
||||
/*
|
||||
value 0xxxxxxx = literal, not encoded
|
||||
value 10xxxxxx = literal, encoded
|
||||
value 11111xxx = copy offset 0 - 63
|
||||
value 11110xxx = copy offset 64 - 319
|
||||
value 1110xxxx = copy offset 320 - 2367
|
||||
value 110xxxxx = copy offset 2368+
|
||||
*/
|
||||
|
||||
/*
|
||||
at this point, we are guaranteed that d32 has 32 bits to
|
||||
be processed, unless we have reached end of cbuf
|
||||
*/
|
||||
|
||||
copy_offset = 0;
|
||||
|
||||
if ((d32 & 0x80000000) == 0)
|
||||
{
|
||||
/* got a literal */
|
||||
*history_ptr++ = d32 >> 24;
|
||||
d32 <<= 8;
|
||||
bits_left -= 8;
|
||||
}
|
||||
else if ((d32 & 0xc0000000) == 0x80000000)
|
||||
{
|
||||
/* got encoded literal */
|
||||
d32 <<= 2;
|
||||
*history_ptr++ = (d32 >> 25) | 0x80;
|
||||
d32 <<= 7;
|
||||
bits_left -= 9;
|
||||
}
|
||||
else if ((d32 & 0xf8000000) == 0xf8000000)
|
||||
{
|
||||
/* got copy offset in range 0 - 63, */
|
||||
/* with 6 bit copy offset */
|
||||
d32 <<= 5;
|
||||
copy_offset = d32 >> 26;
|
||||
d32 <<= 6;
|
||||
bits_left -= 11;
|
||||
}
|
||||
else if ((d32 & 0xf8000000) == 0xf0000000)
|
||||
{
|
||||
/* got copy offset in range 64 - 319, */
|
||||
/* with 8 bit copy offset */
|
||||
d32 <<= 5;
|
||||
copy_offset = d32 >> 24;
|
||||
copy_offset += 64;
|
||||
d32 <<= 8;
|
||||
bits_left -= 13;
|
||||
}
|
||||
else if ((d32 & 0xf0000000) == 0xe0000000)
|
||||
{
|
||||
/* got copy offset in range 320 - 2367, */
|
||||
/* with 11 bits copy offset */
|
||||
d32 <<= 4;
|
||||
copy_offset = d32 >> 21;
|
||||
copy_offset += 320;
|
||||
d32 <<= 11;
|
||||
bits_left -= 15;
|
||||
}
|
||||
else if ((d32 & 0xe0000000) == 0xc0000000)
|
||||
{
|
||||
/* got copy offset in range 2368+, */
|
||||
/* with 16 bits copy offset */
|
||||
d32 <<= 3;
|
||||
copy_offset = d32 >> 16;
|
||||
copy_offset += 2368;
|
||||
d32 <<= 16;
|
||||
bits_left -= 19;
|
||||
}
|
||||
|
||||
/*
|
||||
** get more bits before we process length of match
|
||||
*/
|
||||
|
||||
/* how may bits do we need to get? */
|
||||
assert(bits_left <= 32);
|
||||
assert(cur_bits_left <= bits_left);
|
||||
tmp = 32 - bits_left;
|
||||
|
||||
while (tmp)
|
||||
{
|
||||
if (cur_bits_left < tmp)
|
||||
{
|
||||
/* we have less bits than we need */
|
||||
i32 = cur_byte >> (8 - cur_bits_left);
|
||||
d32 |= (i32 << ((32 - bits_left) - cur_bits_left)) & 0xFFFFFFFF;
|
||||
bits_left += cur_bits_left;
|
||||
tmp -= cur_bits_left;
|
||||
if (cptr < cbuf + len)
|
||||
{
|
||||
/* more compressed data available */
|
||||
cur_byte = *cptr++;
|
||||
cur_bits_left = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no more compressed data available */
|
||||
tmp = 0;
|
||||
cur_bits_left = 0;
|
||||
}
|
||||
}
|
||||
else if (cur_bits_left > tmp)
|
||||
{
|
||||
/* we have more bits than we need */
|
||||
d32 |= cur_byte >> (8 - tmp);
|
||||
cur_byte <<= tmp;
|
||||
cur_bits_left -= tmp;
|
||||
bits_left = 32;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we have just the right amount of bits */
|
||||
d32 |= cur_byte >> (8 - tmp);
|
||||
bits_left = 32;
|
||||
if (cptr < cbuf + len)
|
||||
{
|
||||
cur_byte = *cptr++;
|
||||
cur_bits_left = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_bits_left = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!copy_offset)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
** compute Length of Match
|
||||
*/
|
||||
|
||||
/*
|
||||
lengh of match Encoding (binary header + LoM bits
|
||||
-------------- ----------------------------------
|
||||
3 0
|
||||
4..7 10 + 2 lower bits of LoM
|
||||
8..15 110 + 3 lower bits of LoM
|
||||
16..31 1110 + 4 lower bits of LoM
|
||||
32..63 1111-0 + 5 lower bits of LoM
|
||||
64..127 1111-10 + 6 lower bits of LoM
|
||||
128..255 1111-110 + 7 lower bits of LoM
|
||||
256..511 1111-1110 + 8 lower bits of LoM
|
||||
512..1023 1111-1111-0 + 9 lower bits of LoM
|
||||
1024..2047 1111-1111-10 + 10 lower bits of LoM
|
||||
2048..4095 1111-1111-110 + 11 lower bits of LoM
|
||||
4096..8191 1111-1111-1110 + 12 lower bits of LoM
|
||||
8192..16383 1111-1111-1111-0 + 13 lower bits of LoM
|
||||
16384..32767 1111-1111-1111-10 + 14 lower bits of LoM
|
||||
32768..65535 1111-1111-1111-110 + 15 lower bits of LoM
|
||||
*/
|
||||
|
||||
if ((d32 & 0x80000000) == 0)
|
||||
{
|
||||
/* lom is fixed to 3 */
|
||||
lom = 3;
|
||||
d32 <<= 1;
|
||||
bits_left -= 1;
|
||||
}
|
||||
else if ((d32 & 0xc0000000) == 0x80000000)
|
||||
{
|
||||
/* 2 lower bits of LoM */
|
||||
lom = ((d32 >> 28) & 0x03) + 4;
|
||||
d32 <<= 4;
|
||||
bits_left -= 4;
|
||||
}
|
||||
else if ((d32 & 0xe0000000) == 0xc0000000)
|
||||
{
|
||||
/* 3 lower bits of LoM */
|
||||
lom = ((d32 >> 26) & 0x07) + 8;
|
||||
d32 <<= 6;
|
||||
bits_left -= 6;
|
||||
}
|
||||
else if ((d32 & 0xf0000000) == 0xe0000000)
|
||||
{
|
||||
/* 4 lower bits of LoM */
|
||||
lom = ((d32 >> 24) & 0x0f) + 16;
|
||||
d32 <<= 8;
|
||||
bits_left -= 8;
|
||||
}
|
||||
else if ((d32 & 0xf8000000) == 0xf0000000)
|
||||
{
|
||||
/* 5 lower bits of LoM */
|
||||
lom = ((d32 >> 22) & 0x1f) + 32;
|
||||
d32 <<= 10;
|
||||
bits_left -= 10;
|
||||
}
|
||||
else if ((d32 & 0xfc000000) == 0xf8000000)
|
||||
{
|
||||
/* 6 lower bits of LoM */
|
||||
lom = ((d32 >> 20) & 0x3f) + 64;
|
||||
d32 <<= 12;
|
||||
bits_left -= 12;
|
||||
}
|
||||
else if ((d32 & 0xfe000000) == 0xfc000000)
|
||||
{
|
||||
/* 7 lower bits of LoM */
|
||||
lom = ((d32 >> 18) & 0x7f) + 128;
|
||||
d32 <<= 14;
|
||||
bits_left -= 14;
|
||||
}
|
||||
else if ((d32 & 0xff000000) == 0xfe000000)
|
||||
{
|
||||
/* 8 lower bits of LoM */
|
||||
lom = ((d32 >> 16) & 0xff) + 256;
|
||||
d32 <<= 16;
|
||||
bits_left -= 16;
|
||||
}
|
||||
else if ((d32 & 0xff800000) == 0xff000000)
|
||||
{
|
||||
/* 9 lower bits of LoM */
|
||||
lom = ((d32 >> 14) & 0x1ff) + 512;
|
||||
d32 <<= 18;
|
||||
bits_left -= 18;
|
||||
}
|
||||
else if ((d32 & 0xffc00000) == 0xff800000)
|
||||
{
|
||||
/* 10 lower bits of LoM */
|
||||
lom = ((d32 >> 12) & 0x3ff) + 1024;
|
||||
d32 <<= 20;
|
||||
bits_left -= 20;
|
||||
}
|
||||
else if ((d32 & 0xffe00000) == 0xffc00000)
|
||||
{
|
||||
/* 11 lower bits of LoM */
|
||||
lom = ((d32 >> 10) & 0x7ff) + 2048;
|
||||
d32 <<= 22;
|
||||
bits_left -= 22;
|
||||
}
|
||||
else if ((d32 & 0xfff00000) == 0xffe00000)
|
||||
{
|
||||
/* 12 lower bits of LoM */
|
||||
lom = ((d32 >> 8) & 0xfff) + 4096;
|
||||
d32 <<= 24;
|
||||
bits_left -= 24;
|
||||
}
|
||||
else if ((d32 & 0xfff80000) == 0xfff00000)
|
||||
{
|
||||
/* 13 lower bits of LoM */
|
||||
lom = ((d32 >> 6) & 0x1fff) + 8192;
|
||||
d32 <<= 26;
|
||||
bits_left -= 26;
|
||||
}
|
||||
else if ((d32 & 0xfffc0000) == 0xfff80000)
|
||||
{
|
||||
/* 14 lower bits of LoM */
|
||||
lom = ((d32 >> 4) & 0x3fff) + 16384;
|
||||
d32 <<= 28;
|
||||
bits_left -= 28;
|
||||
}
|
||||
else if ((d32 & 0xfffe0000) == 0xfffc0000)
|
||||
{
|
||||
/* 15 lower bits of LoM */
|
||||
lom = ((d32 >> 2) & 0x7fff) + 32768;
|
||||
d32 <<= 30;
|
||||
bits_left -= 30;
|
||||
}
|
||||
|
||||
/* now that we have copy_offset and LoM, process them */
|
||||
|
||||
src_ptr = history_ptr - copy_offset;
|
||||
if (src_ptr >= dec->history_buf)
|
||||
{
|
||||
/* data does not wrap around */
|
||||
while (lom > 0)
|
||||
{
|
||||
*history_ptr++ = *src_ptr++;
|
||||
lom--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
src_ptr = dec->history_buf_end - (copy_offset - (history_ptr - dec->history_buf));
|
||||
src_ptr++;
|
||||
while (lom && (src_ptr <= dec->history_buf_end))
|
||||
{
|
||||
*history_ptr++ = *src_ptr++;
|
||||
lom--;
|
||||
}
|
||||
|
||||
src_ptr = dec->history_buf;
|
||||
while (lom > 0)
|
||||
{
|
||||
*history_ptr++ = *src_ptr++;
|
||||
lom--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** get more bits before we restart the loop
|
||||
*/
|
||||
|
||||
/* how may bits do we need to get? */
|
||||
assert(bits_left <= 32);
|
||||
assert(cur_bits_left <= bits_left);
|
||||
tmp = 32 - bits_left;
|
||||
|
||||
while (tmp)
|
||||
{
|
||||
if (cur_bits_left < tmp)
|
||||
{
|
||||
/* we have less bits than we need */
|
||||
i32 = cur_byte >> (8 - cur_bits_left);
|
||||
d32 |= (i32 << ((32 - bits_left) - cur_bits_left)) & 0xFFFFFFFF;
|
||||
bits_left += cur_bits_left;
|
||||
tmp -= cur_bits_left;
|
||||
if (cptr < cbuf + len)
|
||||
{
|
||||
/* more compressed data available */
|
||||
cur_byte = *cptr++;
|
||||
cur_bits_left = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no more compressed data available */
|
||||
tmp = 0;
|
||||
cur_bits_left = 0;
|
||||
}
|
||||
}
|
||||
else if (cur_bits_left > tmp)
|
||||
{
|
||||
/* we have more bits than we need */
|
||||
d32 |= cur_byte >> (8 - tmp);
|
||||
cur_byte <<= tmp;
|
||||
cur_bits_left -= tmp;
|
||||
bits_left = 32;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we have just the right amount of bits */
|
||||
d32 |= cur_byte >> (8 - tmp);
|
||||
bits_left = 32;
|
||||
if (cptr < cbuf + len)
|
||||
{
|
||||
cur_byte = *cptr++;
|
||||
cur_bits_left = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_bits_left = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} /* end while (cptr < cbuf + len) */
|
||||
|
||||
*rlen = history_ptr - dec->history_ptr;
|
||||
|
||||
dec->history_ptr = history_ptr;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* decompress RDP 6 data
|
||||
*
|
||||
@ -1395,24 +466,6 @@ int decompress_rdp_6(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, U
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* decompress RDP 6.1 data
|
||||
*
|
||||
* @param rdp per session information
|
||||
* @param cbuf compressed data
|
||||
* @param len length of compressed data
|
||||
* @param ctype compression flags
|
||||
* @param roff starting offset of uncompressed data
|
||||
* @param rlen length of uncompressed data
|
||||
*
|
||||
* @return True on success, False on failure
|
||||
*/
|
||||
|
||||
int decompress_rdp_61(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, UINT32* roff, UINT32* rlen)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* allocate space to store history buffer
|
||||
*
|
||||
|
@ -4,8 +4,6 @@
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/codec/mppc.h>
|
||||
#include <freerdp/codec/mppc_dec.h>
|
||||
#include <freerdp/codec/mppc_enc.h>
|
||||
|
||||
static BYTE TEST_RDP5_COMPRESSED_DATA[] =
|
||||
{
|
||||
@ -599,92 +597,6 @@ static BYTE TEST_RDP5_UNCOMPRESSED_DATA[] =
|
||||
0x0b, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x0a, 0x40, 0xc8,
|
||||
};
|
||||
|
||||
int test_mppc_old()
|
||||
{
|
||||
BOOL status;
|
||||
UINT32 roff;
|
||||
UINT32 rlen;
|
||||
struct rdp_mppc_enc* enc;
|
||||
struct rdp_mppc_dec* rmppc;
|
||||
|
||||
/* Decompression */
|
||||
|
||||
rmppc = mppc_dec_new();
|
||||
|
||||
status = decompress_rdp_5(rmppc, TEST_RDP5_COMPRESSED_DATA,
|
||||
sizeof(TEST_RDP5_COMPRESSED_DATA), PACKET_COMPRESSED, &roff, &rlen);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
printf("RDP5 decompression failure: %d\n", status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (memcmp(TEST_RDP5_UNCOMPRESSED_DATA, rmppc->history_buf, sizeof(TEST_RDP5_UNCOMPRESSED_DATA)) != 0)
|
||||
{
|
||||
printf("RDP5 decompression failure\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mppc_dec_free(rmppc);
|
||||
rmppc = mppc_dec_new();
|
||||
|
||||
/* Compression */
|
||||
|
||||
enc = mppc_enc_new(PROTO_RDP_50);
|
||||
|
||||
status = compress_rdp(enc, TEST_RDP5_UNCOMPRESSED_DATA, sizeof(TEST_RDP5_UNCOMPRESSED_DATA));
|
||||
|
||||
if (!status)
|
||||
{
|
||||
printf("RDP5 decompression failure: %d\n", status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (enc->flags & PACKET_COMPRESSED)
|
||||
{
|
||||
status = decompress_rdp_5(rmppc, (BYTE*) enc->outputBuffer,
|
||||
enc->bytes_in_opb, enc->flags, &roff, &rlen);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
printf("RDP5 compression/decompression failure: %d\n", status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rlen != sizeof(TEST_RDP5_UNCOMPRESSED_DATA))
|
||||
{
|
||||
printf("RDP5 compression/decompression failure: size mismatch: Actual: %d, Expected: %d\n",
|
||||
rlen, (int) sizeof(TEST_RDP5_UNCOMPRESSED_DATA));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (memcmp(TEST_RDP5_UNCOMPRESSED_DATA, &rmppc->history_buf[roff], rlen) != 0)
|
||||
{
|
||||
printf("RDP5 compression/decompression failure\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (enc->bytes_in_opb != sizeof(TEST_RDP5_UNCOMPRESSED_DATA))
|
||||
{
|
||||
printf("RDP5 decompression failure: size mismatch: Actual: %d, Expected: %d\n",
|
||||
enc->bytes_in_opb, (int) sizeof(TEST_RDP5_UNCOMPRESSED_DATA));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (memcmp(TEST_RDP5_COMPRESSED_DATA, enc->outputBuffer, sizeof(TEST_RDP5_COMPRESSED_DATA)) != 0)
|
||||
{
|
||||
printf("RDP5 decompression failure\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mppc_enc_free(enc);
|
||||
mppc_dec_free(rmppc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* for.whom.the.bell.tolls,.the.bell.tolls.for.thee!
|
||||
|
@ -35,6 +35,7 @@ int bulk_decompress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstD
|
||||
{
|
||||
case PACKET_COMPR_TYPE_8K:
|
||||
size = SrcSize;
|
||||
mppc_set_compression_level(bulk->mppcRecv, 0);
|
||||
mppc_decompress(bulk->mppcRecv, pSrcData, ppDstData, &size, flags);
|
||||
*pDstSize = size;
|
||||
status = 1;
|
||||
@ -43,6 +44,7 @@ int bulk_decompress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstD
|
||||
|
||||
case PACKET_COMPR_TYPE_64K:
|
||||
size = SrcSize;
|
||||
mppc_set_compression_level(bulk->mppcRecv, 1);
|
||||
mppc_decompress(bulk->mppcRecv, pSrcData, ppDstData, &size, flags);
|
||||
*pDstSize = size;
|
||||
status = 1;
|
||||
@ -92,9 +94,7 @@ void bulk_reset(rdpBulk* bulk)
|
||||
mppc_context_reset(bulk->mppcRecv);
|
||||
|
||||
mppc_dec_free(bulk->mppc_dec);
|
||||
mppc_enc_free(bulk->mppc_enc);
|
||||
bulk->mppc_dec = mppc_dec_new();
|
||||
bulk->mppc_enc = mppc_enc_new(PROTO_RDP_50);
|
||||
}
|
||||
|
||||
rdpBulk* bulk_new(rdpContext* context)
|
||||
@ -111,7 +111,6 @@ rdpBulk* bulk_new(rdpContext* context)
|
||||
bulk->mppcRecv = mppc_context_new(1, FALSE);
|
||||
|
||||
bulk->mppc_dec = mppc_dec_new();
|
||||
bulk->mppc_enc = mppc_enc_new(PROTO_RDP_50);
|
||||
}
|
||||
|
||||
return bulk;
|
||||
@ -125,7 +124,6 @@ void bulk_free(rdpBulk* bulk)
|
||||
mppc_context_free(bulk->mppcRecv);
|
||||
|
||||
mppc_dec_free(bulk->mppc_dec);
|
||||
mppc_enc_free(bulk->mppc_enc);
|
||||
|
||||
free(bulk);
|
||||
}
|
||||
|
@ -35,7 +35,6 @@ struct rdp_bulk
|
||||
MPPC_CONTEXT* mppcRecv;
|
||||
BYTE OutputBuffer[65536];
|
||||
struct rdp_mppc_dec* mppc_dec;
|
||||
struct rdp_mppc_enc* mppc_enc;
|
||||
};
|
||||
|
||||
int bulk_decompress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32 flags);
|
||||
|
Loading…
Reference in New Issue
Block a user