mirror of https://github.com/FreeRDP/FreeRDP
libfreerdp-codec: MPPC cleanup
This commit is contained in:
parent
ad7ed25d30
commit
baeefd1263
|
@ -70,7 +70,7 @@ const UINT32 MPPC_MATCH_TABLE[256] =
|
|||
0x97E91668, 0x9885E5FB, 0x9922B58E, 0x99BF8521, 0x9A5C54B4, 0x9AF92447, 0x9B95F3DA, 0x9C32C36D
|
||||
};
|
||||
|
||||
#define DEBUG_MPPC 1
|
||||
//#define DEBUG_MPPC 1
|
||||
|
||||
UINT32 mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE** ppDstData, UINT32* pSize, UINT32 flags)
|
||||
{
|
||||
|
@ -82,9 +82,12 @@ UINT32 mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE** ppDstData, UIN
|
|||
BYTE* HistoryBuffer;
|
||||
BYTE* HistoryPtr;
|
||||
UINT32 HistoryOffset;
|
||||
UINT32 CompressionLevel;
|
||||
wBitStream* bs = mppc->bs;
|
||||
|
||||
HistoryBuffer = mppc->HistoryBuffer;
|
||||
CompressionLevel = mppc->CompressionLevel;
|
||||
|
||||
*ppDstData = HistoryBuffer;
|
||||
|
||||
BitStream_Attach(bs, pSrcData, *pSize);
|
||||
|
@ -158,7 +161,7 @@ UINT32 mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE** ppDstData, UIN
|
|||
|
||||
CopyOffset = 0;
|
||||
|
||||
if (mppc->CompressionLevel) /* RDP5 */
|
||||
if (CompressionLevel) /* RDP5 */
|
||||
{
|
||||
if ((accumulator & 0xF8000000) == 0xF8000000)
|
||||
{
|
||||
|
@ -370,7 +373,7 @@ UINT32 mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE** ppDstData, UIN
|
|||
LengthOfMatch = ((accumulator >> 8) & 0x0FFF) + 0x1000;
|
||||
BitStream_Shift(bs, 24);
|
||||
}
|
||||
else if (((accumulator & 0xFFF80000) == 0xFFF00000) && mppc->CompressionLevel) /* RDP5 */
|
||||
else if (((accumulator & 0xFFF80000) == 0xFFF00000) && CompressionLevel) /* RDP5 */
|
||||
{
|
||||
/**
|
||||
* LengthOfMatch [8192, 16383]
|
||||
|
@ -380,7 +383,7 @@ UINT32 mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE** ppDstData, UIN
|
|||
LengthOfMatch = ((accumulator >> 6) & 0x1FFF) + 0x2000;
|
||||
BitStream_Shift(bs, 26);
|
||||
}
|
||||
else if (((accumulator & 0xFFFC0000) == 0xFFF80000) && mppc->CompressionLevel) /* RDP5 */
|
||||
else if (((accumulator & 0xFFFC0000) == 0xFFF80000) && CompressionLevel) /* RDP5 */
|
||||
{
|
||||
/**
|
||||
* LengthOfMatch [16384, 32767]
|
||||
|
@ -390,7 +393,7 @@ UINT32 mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE** ppDstData, UIN
|
|||
LengthOfMatch = ((accumulator >> 4) & 0x3FFF) + 0x4000;
|
||||
BitStream_Shift(bs, 28);
|
||||
}
|
||||
else if (((accumulator & 0xFFFE0000) == 0xFFFC0000) && mppc->CompressionLevel) /* RDP5 */
|
||||
else if (((accumulator & 0xFFFE0000) == 0xFFFC0000) && CompressionLevel) /* RDP5 */
|
||||
{
|
||||
/**
|
||||
* LengthOfMatch [32768, 65535]
|
||||
|
@ -432,21 +435,23 @@ UINT32 mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE** ppDstData, UIN
|
|||
UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32* pSize)
|
||||
{
|
||||
UINT32 Flags;
|
||||
BYTE* pMatch;
|
||||
BYTE* pSrcEnd;
|
||||
BYTE* pDstEnd;
|
||||
DWORD CopyOffset;
|
||||
DWORD LengthOfMatch;
|
||||
BYTE* MatchPtr;
|
||||
UINT32 MatchIndex;
|
||||
UINT32 accumulator;
|
||||
DWORD CopyOffset;
|
||||
DWORD LengthOfMatch;
|
||||
BYTE* HistoryBuffer;
|
||||
BYTE* HistoryPtr;
|
||||
UINT32 HistoryOffset;
|
||||
UINT32 HistoryBufferSize;
|
||||
UINT32 CompressionLevel;
|
||||
wBitStream* bs = mppc->bs;
|
||||
|
||||
HistoryBuffer = mppc->HistoryBuffer;
|
||||
HistoryBufferSize = mppc->HistoryBufferSize;
|
||||
CompressionLevel = mppc->CompressionLevel;
|
||||
|
||||
HistoryPtr = mppc->HistoryPtr;
|
||||
HistoryOffset = mppc->HistoryOffset;
|
||||
|
@ -455,18 +460,18 @@ UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32*
|
|||
|
||||
CopyMemory(&(HistoryBuffer[HistoryOffset]), pSrcData, *pSize);
|
||||
|
||||
if (((HistoryOffset + *pSize) < (mppc->HistoryBufferSize - 3)) && HistoryOffset)
|
||||
if (((HistoryOffset + *pSize) < (HistoryBufferSize - 3)) && HistoryOffset)
|
||||
{
|
||||
Flags = mppc->CompressionLevel;
|
||||
Flags = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
HistoryOffset = 0;
|
||||
Flags = PACKET_AT_FRONT | mppc->CompressionLevel;
|
||||
Flags = PACKET_AT_FRONT;
|
||||
}
|
||||
|
||||
HistoryPtr = &(HistoryBuffer[HistoryOffset]);
|
||||
HistoryOffset += *pSize;
|
||||
HistoryPtr = &(HistoryBuffer[0]);
|
||||
|
||||
pSrcEnd = &(HistoryBuffer[*pSize - 1]);
|
||||
pDstEnd = &(pDstData[*pSize - 1]);
|
||||
|
@ -474,18 +479,18 @@ UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32*
|
|||
while (HistoryPtr < (pSrcEnd - 2))
|
||||
{
|
||||
MatchIndex = MPPC_MATCH_INDEX(HistoryPtr[0], HistoryPtr[1], HistoryPtr[2]);
|
||||
pMatch = &(HistoryBuffer[mppc->MatchBuffer[MatchIndex]]);
|
||||
MatchPtr = &(HistoryBuffer[mppc->MatchBuffer[MatchIndex]]);
|
||||
|
||||
//if (&pMatch[1] != HistoryPtr)
|
||||
/* if (&MatchPtr[1] != HistoryPtr) */
|
||||
mppc->MatchBuffer[MatchIndex] = (UINT16) (HistoryPtr - HistoryBuffer);
|
||||
|
||||
if (mppc->HistoryPtr < HistoryPtr)
|
||||
mppc->HistoryPtr = HistoryPtr;
|
||||
|
||||
if ((HistoryPtr[0] != pMatch[0]) || (HistoryPtr[1] != pMatch[1]) ||
|
||||
(HistoryPtr[2] != pMatch[2]) || (&pMatch[2] > mppc->HistoryPtr) ||
|
||||
(pMatch == HistoryPtr) || (&pMatch[1] == HistoryPtr) ||
|
||||
(pMatch == HistoryBuffer))
|
||||
if ((HistoryPtr[0] != MatchPtr[0]) || (HistoryPtr[1] != MatchPtr[1]) ||
|
||||
(HistoryPtr[2] != MatchPtr[2]) || (&MatchPtr[2] > mppc->HistoryPtr) ||
|
||||
(MatchPtr == HistoryPtr) || (&MatchPtr[1] == HistoryPtr) ||
|
||||
(MatchPtr == HistoryBuffer))
|
||||
{
|
||||
accumulator = *(HistoryPtr);
|
||||
|
||||
|
@ -493,6 +498,14 @@ UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32*
|
|||
//printf("%c", accumulator);
|
||||
#endif
|
||||
|
||||
if (((bs->position / 8) + 2) > (*pSize - 1))
|
||||
{
|
||||
Flags = PACKET_FLUSHED;
|
||||
ZeroMemory(HistoryBuffer, HistoryBufferSize);
|
||||
ZeroMemory(mppc->MatchBuffer, sizeof(mppc->MatchBuffer));
|
||||
return Flags;
|
||||
}
|
||||
|
||||
if (accumulator < 0x80)
|
||||
{
|
||||
/* 8 bits of literal are encoded as-is */
|
||||
|
@ -510,12 +523,17 @@ UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32*
|
|||
else
|
||||
{
|
||||
LengthOfMatch = 3;
|
||||
CopyOffset = (HistoryBufferSize - 1) & (HistoryPtr - pMatch);
|
||||
HistoryPtr += 3;
|
||||
MatchPtr += 3;
|
||||
|
||||
while ((HistoryPtr[LengthOfMatch] == pMatch[LengthOfMatch]) &&
|
||||
(((HistoryPtr - HistoryBuffer) + LengthOfMatch) < (*pSize - 1)))
|
||||
CopyOffset = (HistoryBufferSize - 1) & (HistoryPtr - MatchPtr);
|
||||
|
||||
while ((*HistoryPtr == *MatchPtr) && /* (MatchPtr <= mppc->HistoryPtr) && */
|
||||
((HistoryPtr - HistoryBuffer) < (*pSize - 1)))
|
||||
{
|
||||
LengthOfMatch++;
|
||||
HistoryPtr++;
|
||||
MatchPtr++;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MPPC
|
||||
|
@ -524,7 +542,15 @@ UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32*
|
|||
|
||||
/* Encode CopyOffset */
|
||||
|
||||
if (mppc->CompressionLevel) /* RDP5 */
|
||||
if (((bs->position / 8) + 7) > (*pSize - 1))
|
||||
{
|
||||
Flags = PACKET_FLUSHED;
|
||||
ZeroMemory(HistoryBuffer, HistoryBufferSize);
|
||||
ZeroMemory(mppc->MatchBuffer, sizeof(mppc->MatchBuffer));
|
||||
return Flags;
|
||||
}
|
||||
|
||||
if (CompressionLevel) /* RDP5 */
|
||||
{
|
||||
if (CopyOffset < 64)
|
||||
{
|
||||
|
@ -646,26 +672,24 @@ UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32*
|
|||
accumulator = 0xFFE000 | (LengthOfMatch & 0x0FFF);
|
||||
BitStream_Write_Bits(bs, accumulator, 24);
|
||||
}
|
||||
else if (((LengthOfMatch >= 8192) && (LengthOfMatch < 16384)) && mppc->CompressionLevel) /* RDP5 */
|
||||
else if (((LengthOfMatch >= 8192) && (LengthOfMatch < 16384)) && CompressionLevel) /* RDP5 */
|
||||
{
|
||||
/* 1111111111110 + 13 lower bits of LengthOfMatch */
|
||||
accumulator = 0x3FFC000 | (LengthOfMatch & 0x1FFF);
|
||||
BitStream_Write_Bits(bs, accumulator, 26);
|
||||
}
|
||||
else if (((LengthOfMatch >= 16384) && (LengthOfMatch < 32768)) && mppc->CompressionLevel) /* RDP5 */
|
||||
else if (((LengthOfMatch >= 16384) && (LengthOfMatch < 32768)) && CompressionLevel) /* RDP5 */
|
||||
{
|
||||
/* 11111111111110 + 14 lower bits of LengthOfMatch */
|
||||
accumulator = 0xFFF8000 | (LengthOfMatch & 0x3FFF);
|
||||
BitStream_Write_Bits(bs, accumulator, 28);
|
||||
}
|
||||
else if (((LengthOfMatch >= 32768) && (LengthOfMatch < 65536)) && mppc->CompressionLevel) /* RDP5 */
|
||||
else if (((LengthOfMatch >= 32768) && (LengthOfMatch < 65536)) && CompressionLevel) /* RDP5 */
|
||||
{
|
||||
/* 111111111111110 + 15 lower bits of LengthOfMatch */
|
||||
accumulator = 0x3FFF0000 | (LengthOfMatch & 0x7FFF);
|
||||
BitStream_Write_Bits(bs, accumulator, 30);
|
||||
}
|
||||
|
||||
HistoryPtr += LengthOfMatch;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -674,7 +698,7 @@ UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32*
|
|||
while (HistoryPtr <= pSrcEnd)
|
||||
{
|
||||
MatchIndex = MPPC_MATCH_INDEX(HistoryPtr[0], HistoryPtr[1], HistoryPtr[2]);
|
||||
pMatch = &(HistoryBuffer[mppc->MatchBuffer[MatchIndex]]);
|
||||
MatchPtr = &(HistoryBuffer[mppc->MatchBuffer[MatchIndex]]);
|
||||
mppc->MatchBuffer[MatchIndex] = (UINT16) (HistoryPtr - HistoryBuffer);
|
||||
|
||||
accumulator = *(HistoryPtr);
|
||||
|
@ -683,6 +707,14 @@ UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32*
|
|||
//printf("%c", accumulator);
|
||||
#endif
|
||||
|
||||
if (((bs->position / 8) + 2) > (*pSize - 1))
|
||||
{
|
||||
Flags = PACKET_FLUSHED;
|
||||
ZeroMemory(HistoryBuffer, HistoryBufferSize);
|
||||
ZeroMemory(mppc->MatchBuffer, sizeof(mppc->MatchBuffer));
|
||||
return Flags;
|
||||
}
|
||||
|
||||
if (accumulator < 0x80)
|
||||
{
|
||||
/* 8 bits of literal are encoded as-is */
|
||||
|
@ -702,10 +734,9 @@ UINT32 mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, UINT32*
|
|||
|
||||
Flags |= PACKET_COMPRESSED;
|
||||
*pSize = ((bs->position + 7) / 8);
|
||||
mppc->HistoryOffset = HistoryPtr - HistoryBuffer;
|
||||
|
||||
mppc->HistoryPtr = HistoryPtr;
|
||||
mppc->HistoryOffset = HistoryOffset;
|
||||
mppc->HistoryOffset = HistoryPtr - HistoryBuffer;
|
||||
|
||||
#ifdef DEBUG_MPPC
|
||||
printf("\n");
|
||||
|
|
|
@ -958,6 +958,8 @@ int test_MppcCompressBufferRdp5()
|
|||
MPPC_CONTEXT* mppc;
|
||||
UINT32 expectedSize;
|
||||
BYTE OutputBuffer[65536];
|
||||
MPPC_CONTEXT* mppcRecv;
|
||||
BYTE* pDstData = NULL;
|
||||
|
||||
mppc = mppc_context_new(1, TRUE);
|
||||
|
||||
|
@ -968,13 +970,29 @@ int test_MppcCompressBufferRdp5()
|
|||
flags = mppc_compress(mppc, pSrcData, OutputBuffer, &size);
|
||||
printf("flags: 0x%04X size: %d\n", flags, size);
|
||||
|
||||
mppcRecv = mppc_context_new(1, FALSE);
|
||||
|
||||
pSrcData = (BYTE*) OutputBuffer;
|
||||
flags = PACKET_AT_FRONT | PACKET_COMPRESSED | 1;
|
||||
expectedSize = sizeof(TEST_RDP5_UNCOMPRESSED_DATA);
|
||||
|
||||
flags = mppc_decompress(mppcRecv, pSrcData, &pDstData, &size, flags);
|
||||
printf("flags: 0x%04X size: %d\n", flags, size);
|
||||
|
||||
if (size != expectedSize)
|
||||
{
|
||||
printf("MppcCompressBufferRdp5: output size mismatch: Actual: %d, Expected: %d\n", size, expectedSize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (memcmp(pDstData, TEST_RDP5_UNCOMPRESSED_DATA, size) != 0)
|
||||
{
|
||||
printf("MppcCompressBufferRdp5: output mismatch: Decompress(Compress(X)) != X\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mppc_context_free(mppc);
|
||||
mppc_context_free(mppcRecv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1017,7 +1035,6 @@ int test_MppcDecompressBufferRdp5()
|
|||
|
||||
int TestFreeRDPCodecMppc(int argc, char* argv[])
|
||||
{
|
||||
#if 1
|
||||
if (test_MppcCompressBellsRdp5() < 0)
|
||||
return -1;
|
||||
|
||||
|
@ -1029,14 +1046,12 @@ int TestFreeRDPCodecMppc(int argc, char* argv[])
|
|||
|
||||
if (test_MppcDecompressBellsRdp4() < 0)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
test_MppcCompressBufferRdp5();
|
||||
#else
|
||||
if (test_MppcCompressBufferRdp5() < 0)
|
||||
return -1;
|
||||
|
||||
if (test_MppcDecompressBufferRdp5() < 0)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
//test_mppc_old();
|
||||
|
||||
|
|
Loading…
Reference in New Issue