libfreerdp-codec: initial RDP4/RDP5 MPPC compression test case success

This commit is contained in:
Marc-André Moreau 2014-03-09 17:32:49 -04:00
parent ccf71a1fa3
commit c686d434b7
4 changed files with 144 additions and 100 deletions

View File

@ -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]);
}
}

View File

@ -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;
}

View File

@ -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();

View File

@ -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;