From c686d434b710ffc08b542145992a3c2bc90cdaeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 9 Mar 2014 17:32:49 -0400 Subject: [PATCH] libfreerdp-codec: initial RDP4/RDP5 MPPC compression test case success --- libfreerdp/codec/mppc.c | 64 +---------- libfreerdp/codec/test/TestFreeRDPCodecMppc.c | 25 +++++ winpr/include/winpr/bitstream.h | 44 ++------ winpr/libwinpr/utils/collections/BitStream.c | 111 +++++++++++++++++++ 4 files changed, 144 insertions(+), 100 deletions(-) diff --git a/libfreerdp/codec/mppc.c b/libfreerdp/codec/mppc.c index b8130920c..bf5f93129 100644 --- a/libfreerdp/codec/mppc.c +++ b/libfreerdp/codec/mppc.c @@ -72,66 +72,6 @@ const UINT32 MPPC_MATCH_TABLE[256] = #define DEBUG_MPPC 1 -void BitStream_Prefetch(wBitStream* bs) -{ - (bs->prefetch) = 0; - if ((bs->pointer - bs->buffer) < (bs->capacity + 4)) - (bs->prefetch) |= (*(bs->pointer + 4) << 24); - if ((bs->pointer - bs->buffer) < (bs->capacity + 5)) - (bs->prefetch) |= (*(bs->pointer + 5) << 16); - if ((bs->pointer - bs->buffer) < (bs->capacity + 6)) - (bs->prefetch) |= (*(bs->pointer + 6) << 8); - if ((bs->pointer - bs->buffer) < (bs->capacity + 7)) - (bs->prefetch) |= (*(bs->pointer + 7) << 0); -} - -void BitStream_Fetch(wBitStream* bs) -{ - (bs->accumulator) = 0; - if ((bs->pointer - bs->buffer) < (bs->capacity + 0)) - (bs->accumulator) |= (*(bs->pointer + 0) << 24); - if ((bs->pointer - bs->buffer) < (bs->capacity + 1)) - (bs->accumulator) |= (*(bs->pointer + 1) << 16); - if ((bs->pointer - bs->buffer) < (bs->capacity + 2)) - (bs->accumulator) |= (*(bs->pointer + 2) << 8); - if ((bs->pointer - bs->buffer) < (bs->capacity + 3)) - (bs->accumulator) |= (*(bs->pointer + 3) << 0); - - BitStream_Prefetch(bs); -} - -void BitStream_Shift(wBitStream* bs, UINT32 nbits) -{ - bs->accumulator <<= nbits; - bs->position += nbits; - bs->offset += nbits; - - if (bs->offset < 32) - { - bs->mask = ((1 << nbits) - 1); - bs->accumulator |= ((bs->prefetch >> (32 - nbits)) & bs->mask); - bs->prefetch <<= nbits; - } - else - { - bs->mask = ((1 << nbits) - 1); - bs->accumulator |= ((bs->prefetch >> (32 - nbits)) & bs->mask); - bs->prefetch <<= nbits; - - bs->offset -= 32; - bs->pointer += 4; - - BitStream_Prefetch(bs); - - if (bs->offset) - { - bs->mask = ((1 << bs->offset) - 1); - bs->accumulator |= ((bs->prefetch >> (32 - bs->offset)) & bs->mask); - bs->prefetch <<= bs->offset; - } - } -} - UINT32 mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32* pSize, UINT32 flags) { BYTE Literal; @@ -735,9 +675,7 @@ UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32* while (pHistoryPtr <= pEnd) { MatchIndex = MPPC_MATCH_INDEX(pHistoryPtr[0], pHistoryPtr[1], pHistoryPtr[2]); - pMatch = &(HistoryBuffer[mppc->MatchBuffer[MatchIndex]]); - mppc->MatchBuffer[MatchIndex] = (UINT16) HistoryPtr; accumulator = *(pHistoryPtr); @@ -759,7 +697,7 @@ UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32* } HistoryPtr++; - pHistoryPtr++; + pHistoryPtr = &(HistoryBuffer[HistoryPtr]); } } diff --git a/libfreerdp/codec/test/TestFreeRDPCodecMppc.c b/libfreerdp/codec/test/TestFreeRDPCodecMppc.c index 84a6dac22..2f4989c39 100644 --- a/libfreerdp/codec/test/TestFreeRDPCodecMppc.c +++ b/libfreerdp/codec/test/TestFreeRDPCodecMppc.c @@ -726,6 +726,17 @@ int test_mppc_old() * 01101100 Literal 'l' * 01110011 Literal 's' * 00101100 Literal ',' + * 11111+010000 CopyOffset 16 + * 110+111 LengthOfMatch 15 + * 00101110 Literal '.' + * 01100110 Literal 'f' + * 11111+101000 CopyOffset 40 + * 0 LengthOfMatch 3 + * 11111+100011 CopyOffset 35 + * 0 LengthOfMatch 3 + * 01100101 Literal 'e' + * 00100001 Literal '!' + * 0000000 Trailing Bits * * RDP4: * 01100110 Literal 'f' @@ -810,6 +821,13 @@ int test_MppcCompressBellsRdp5() if (memcmp(OutputBuffer, TEST_MPPC_BELLS_RDP5, size) != 0) { printf("MppcCompressBellsRdp5: output mismatch\n"); + + printf("Actual\n"); + BitDump(OutputBuffer, size * 8, 0); + + printf("Expected\n"); + BitDump(TEST_MPPC_BELLS_RDP5, size * 8, 0); + return -1; } @@ -847,6 +865,13 @@ int test_MppcCompressBellsRdp4() if (memcmp(OutputBuffer, TEST_MPPC_BELLS_RDP4, size) != 0) { printf("MppcCompressBellsRdp4: output mismatch\n"); + + printf("Actual\n"); + BitDump(OutputBuffer, size * 8, 0); + + printf("Expected\n"); + BitDump(TEST_MPPC_BELLS_RDP4, size * 8, 0); + return -1; } diff --git a/winpr/include/winpr/bitstream.h b/winpr/include/winpr/bitstream.h index c15f0720e..4f988b6e2 100644 --- a/winpr/include/winpr/bitstream.h +++ b/winpr/include/winpr/bitstream.h @@ -39,43 +39,6 @@ struct _wBitStream }; typedef struct _wBitStream wBitStream; -#define BitStream_Attach(_bs, _buffer, _capacity) { \ - _bs->position = 0; \ - _bs->buffer = _buffer; \ - _bs->offset = 0; \ - _bs->accumulator = 0; \ - _bs->pointer = _bs->buffer; \ - _bs->capacity = _capacity; \ - _bs->length = _bs->capacity * 8; \ -} - -#define BitStream_Write_Bits(_bs, _bits, _nbits) { \ - _bs->accumulator |= (_bits << _bs->offset); \ - _bs->position += _nbits; \ - _bs->offset += _nbits; \ - if (_bs->offset >= 32) { \ - *((UINT32*) _bs->pointer) = (_bs->accumulator); \ - _bs->offset = _bs->offset - 32; \ - _bs->accumulator = _bits >> (_nbits - _bs->offset); \ - _bs->pointer += 4; \ - } \ -} - -#define BitStream_Flush(_bs) { \ - if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 3)) { \ - *((UINT32*) _bs->pointer) = (_bs->accumulator); \ - } else { \ - if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 0)) \ - *(_bs->pointer + 0) = (_bs->accumulator >> 0); \ - if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 1)) \ - *(_bs->pointer + 1) = (_bs->accumulator >> 8); \ - if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 2)) \ - *(_bs->pointer + 2) = (_bs->accumulator >> 16); \ - if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 3)) \ - *(_bs->pointer + 3) = (_bs->accumulator >> 24); \ - } \ -} - #define BITDUMP_MSB_FIRST 0x00000001 #define BITDUMP_STDERR 0x00000002 @@ -83,6 +46,13 @@ typedef struct _wBitStream wBitStream; extern "C" { #endif +WINPR_API void BitStream_Attach(wBitStream* bs, BYTE* buffer, UINT32 capacity); +WINPR_API void BitStream_Write_Bits(wBitStream* bs, UINT32 bits, UINT32 nbits); +WINPR_API void BitStream_Flush(wBitStream* bs); +WINPR_API void BitStream_Prefetch(wBitStream* bs); +WINPR_API void BitStream_Fetch(wBitStream* bs); +WINPR_API void BitStream_Shift(wBitStream* bs, UINT32 nbits); + WINPR_API void BitDump(const BYTE* buffer, UINT32 length, UINT32 flags); WINPR_API wBitStream* BitStream_New(); diff --git a/winpr/libwinpr/utils/collections/BitStream.c b/winpr/libwinpr/utils/collections/BitStream.c index 35ca916d9..2a1b2ccd7 100644 --- a/winpr/libwinpr/utils/collections/BitStream.c +++ b/winpr/libwinpr/utils/collections/BitStream.c @@ -183,6 +183,117 @@ void BitDump(const BYTE* buffer, UINT32 length, UINT32 flags) printf("\n"); } +void BitStream_Attach(wBitStream* bs, BYTE* buffer, UINT32 capacity) +{ + bs->position = 0; + bs->buffer = buffer; + bs->offset = 0; + bs->accumulator = 0; + bs->pointer = bs->buffer; + bs->capacity = capacity; + bs->length = bs->capacity * 8; +} + +void BitStream_Flush(wBitStream* bs) +{ + if ((bs->pointer - bs->buffer) < (bs->capacity + 0)) + *(bs->pointer + 0) = (bs->accumulator >> 24); + if ((bs->pointer - bs->buffer) < (bs->capacity + 1)) + *(bs->pointer + 1) = (bs->accumulator >> 16); + if ((bs->pointer - bs->buffer) < (bs->capacity + 2)) + *(bs->pointer + 2) = (bs->accumulator >> 8); + if ((bs->pointer - bs->buffer) < (bs->capacity + 3)) + *(bs->pointer + 3) = (bs->accumulator >> 0); +} + +void BitStream_Prefetch(wBitStream* bs) +{ + (bs->prefetch) = 0; + if ((bs->pointer - bs->buffer) < (bs->capacity + 4)) + (bs->prefetch) |= (*(bs->pointer + 4) << 24); + if ((bs->pointer - bs->buffer) < (bs->capacity + 5)) + (bs->prefetch) |= (*(bs->pointer + 5) << 16); + if ((bs->pointer - bs->buffer) < (bs->capacity + 6)) + (bs->prefetch) |= (*(bs->pointer + 6) << 8); + if ((bs->pointer - bs->buffer) < (bs->capacity + 7)) + (bs->prefetch) |= (*(bs->pointer + 7) << 0); +} + +void BitStream_Fetch(wBitStream* bs) +{ + (bs->accumulator) = 0; + + if ((bs->pointer - bs->buffer) < (bs->capacity + 0)) + (bs->accumulator) |= (*(bs->pointer + 0) << 24); + if ((bs->pointer - bs->buffer) < (bs->capacity + 1)) + (bs->accumulator) |= (*(bs->pointer + 1) << 16); + if ((bs->pointer - bs->buffer) < (bs->capacity + 2)) + (bs->accumulator) |= (*(bs->pointer + 2) << 8); + if ((bs->pointer - bs->buffer) < (bs->capacity + 3)) + (bs->accumulator) |= (*(bs->pointer + 3) << 0); + + BitStream_Prefetch(bs); +} + +void BitStream_Write_Bits(wBitStream* bs, UINT32 bits, UINT32 nbits) +{ + bs->position += nbits; + bs->offset += nbits; + + if (bs->offset < 32) + { + bs->accumulator |= (bits << (32 - bs->offset)); + } + else + { + bs->offset -= 32; + bs->mask = ((1 << (nbits - bs->offset)) - 1); + bs->accumulator |= ((bits >> bs->offset) & bs->mask); + + BitStream_Flush(bs); + bs->accumulator = 0; + bs->pointer += 4; + + if (bs->offset) + { + bs->mask = ((1 << bs->offset) - 1); + bs->accumulator |= ((bits & bs->mask) << (32 - bs->offset)); + } + } +} + +void BitStream_Shift(wBitStream* bs, UINT32 nbits) +{ + bs->accumulator <<= nbits; + bs->position += nbits; + bs->offset += nbits; + + if (bs->offset < 32) + { + bs->mask = ((1 << nbits) - 1); + bs->accumulator |= ((bs->prefetch >> (32 - nbits)) & bs->mask); + bs->prefetch <<= nbits; + } + else + { + bs->mask = ((1 << nbits) - 1); + bs->accumulator |= ((bs->prefetch >> (32 - nbits)) & bs->mask); + bs->prefetch <<= nbits; + + bs->offset -= 32; + bs->pointer += 4; + + BitStream_Prefetch(bs); + + if (bs->offset) + { + bs->mask = ((1 << bs->offset) - 1); + bs->accumulator |= ((bs->prefetch >> (32 - bs->offset)) & bs->mask); + bs->prefetch <<= bs->offset; + } + } +} + wBitStream* BitStream_New() { wBitStream* bs = NULL;