Fixed decoder arguments, use const correct ones

This commit is contained in:
Armin Novak 2022-04-27 08:33:19 +02:00 committed by akallabeth
parent d68327ad74
commit 83bb37d174
12 changed files with 512 additions and 360 deletions

View File

@ -35,7 +35,8 @@ extern "C"
#endif
FREERDP_API int mppc_compress(MPPC_CONTEXT* mppc, const BYTE* pSrcData, UINT32 SrcSize,
BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags);
BYTE* pDstBuffer, const BYTE** ppDstData, UINT32* pDstSize,
UINT32* pFlags);
FREERDP_API int mppc_decompress(MPPC_CONTEXT* mppc, const BYTE* pSrcData, UINT32 SrcSize,
const BYTE** ppDstData, UINT32* pDstSize, UINT32 flags);

View File

@ -35,7 +35,8 @@ extern "C"
#endif
FREERDP_API int ncrush_compress(NCRUSH_CONTEXT* ncrush, const BYTE* pSrcData, UINT32 SrcSize,
BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags);
BYTE* pDstBuffer, const BYTE** ppDstData, UINT32* pDstSize,
UINT32* pFlags);
FREERDP_API int ncrush_decompress(NCRUSH_CONTEXT* ncrush, const BYTE* pSrcData, UINT32 SrcSize,
const BYTE** ppDstData, UINT32* pDstSize, UINT32 flags);

View File

@ -33,7 +33,8 @@ extern "C"
#endif
FREERDP_API int xcrush_compress(XCRUSH_CONTEXT* xcrush, const BYTE* pSrcData, UINT32 SrcSize,
BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags);
BYTE* pDstBuffer, const BYTE** ppDstData, UINT32* pDstSize,
UINT32* pFlags);
FREERDP_API int xcrush_decompress(XCRUSH_CONTEXT* xcrush, const BYTE* pSrcData, UINT32 SrcSize,
const BYTE** ppDstData, UINT32* pDstSize, UINT32 flags);

View File

@ -17,6 +17,7 @@
* limitations under the License.
*/
#include <winpr/assert.h>
#include <freerdp/config.h>
#include <winpr/crt.h>
@ -29,6 +30,8 @@
#define TAG FREERDP_TAG("codec.mppc")
//#define DEBUG_MPPC 1
#define MPPC_MATCH_INDEX(_sym1, _sym2, _sym3) \
((((MPPC_MATCH_TABLE[_sym3] << 16) + (MPPC_MATCH_TABLE[_sym2] << 8) + \
MPPC_MATCH_TABLE[_sym1]) & \
@ -37,14 +40,14 @@
struct s_MPPC_CONTEXT
{
wBitStream* bs;
BOOL Compressor;
BYTE* HistoryPtr;
UINT32 HistoryOffset;
UINT32 HistoryBufferSize;
BYTE HistoryBuffer[65536];
UINT16 MatchBuffer[32768];
UINT32 CompressionLevel;
ALIGN64 wBitStream* bs;
ALIGN64 BOOL Compressor;
ALIGN64 BYTE* HistoryPtr;
ALIGN64 UINT32 HistoryOffset;
ALIGN64 UINT32 HistoryBufferSize;
ALIGN64 BYTE HistoryBuffer[65536];
ALIGN64 UINT16 MatchBuffer[32768];
ALIGN64 UINT32 CompressionLevel;
};
static const UINT32 MPPC_MATCH_TABLE[256] = {
@ -82,8 +85,6 @@ static const UINT32 MPPC_MATCH_TABLE[256] = {
0x97E91668, 0x9885E5FB, 0x9922B58E, 0x99BF8521, 0x9A5C54B4, 0x9AF92447, 0x9B95F3DA, 0x9C32C36D
};
//#define DEBUG_MPPC 1
int mppc_decompress(MPPC_CONTEXT* mppc, const BYTE* pSrcData, UINT32 SrcSize,
const BYTE** ppDstData, UINT32* pDstSize, UINT32 flags)
{
@ -97,8 +98,19 @@ int mppc_decompress(MPPC_CONTEXT* mppc, const BYTE* pSrcData, UINT32 SrcSize,
BYTE* HistoryBufferEnd;
UINT32 HistoryBufferSize;
UINT32 CompressionLevel;
wBitStream* bs = mppc->bs;
wBitStream* bs;
WINPR_ASSERT(mppc);
WINPR_ASSERT(pSrcData);
WINPR_ASSERT(ppDstData);
WINPR_ASSERT(pDstSize);
bs = mppc->bs;
WINPR_ASSERT(bs);
HistoryBuffer = mppc->HistoryBuffer;
WINPR_ASSERT(HistoryBuffer);
HistoryBufferSize = mppc->HistoryBufferSize;
HistoryBufferEnd = &HistoryBuffer[HistoryBufferSize - 1];
CompressionLevel = mppc->CompressionLevel;
@ -395,7 +407,7 @@ int mppc_decompress(MPPC_CONTEXT* mppc, const BYTE* pSrcData, UINT32 SrcSize,
return -1003;
}
#ifdef DEBUG_MPPC
#if defined(DEBUG_MPPC)
WLog_DBG(TAG, "<%" PRIu32 ",%" PRIu32 ">", CopyOffset, LengthOfMatch);
#endif
@ -420,8 +432,8 @@ int mppc_decompress(MPPC_CONTEXT* mppc, const BYTE* pSrcData, UINT32 SrcSize,
return 1;
}
int mppc_compress(MPPC_CONTEXT* mppc, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData,
UINT32* pDstSize, UINT32* pFlags)
int mppc_compress(MPPC_CONTEXT* mppc, const BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstBuffer,
const BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags)
{
const BYTE* pSrcPtr;
const BYTE* pSrcEnd;
@ -440,8 +452,21 @@ int mppc_compress(MPPC_CONTEXT* mppc, const BYTE* pSrcData, UINT32 SrcSize, BYTE
UINT32 HistoryBufferSize;
BYTE Sym1, Sym2, Sym3;
UINT32 CompressionLevel;
wBitStream* bs = mppc->bs;
wBitStream* bs;
WINPR_ASSERT(mppc);
WINPR_ASSERT(pSrcData);
WINPR_ASSERT(pDstBuffer);
WINPR_ASSERT(ppDstData);
WINPR_ASSERT(pDstSize);
WINPR_ASSERT(pFlags);
bs = mppc->bs;
WINPR_ASSERT(bs);
HistoryBuffer = mppc->HistoryBuffer;
WINPR_ASSERT(HistoryBuffer);
HistoryBufferSize = mppc->HistoryBufferSize;
CompressionLevel = mppc->CompressionLevel;
HistoryOffset = mppc->HistoryOffset;
@ -462,7 +487,8 @@ int mppc_compress(MPPC_CONTEXT* mppc, const BYTE* pSrcData, UINT32 SrcSize, BYTE
}
HistoryPtr = &(HistoryBuffer[HistoryOffset]);
pDstData = *ppDstData;
pDstData = pDstBuffer;
*ppDstData = pDstBuffer;
if (!pDstData)
return -1;
@ -506,7 +532,7 @@ int mppc_compress(MPPC_CONTEXT* mppc, const BYTE* pSrcData, UINT32 SrcSize, BYTE
}
accumulator = Sym1;
#ifdef DEBUG_MPPC
#if defined(DEBUG_MPPC)
WLog_DBG(TAG, "%" PRIu32 "", accumulator);
#endif
@ -538,7 +564,7 @@ int mppc_compress(MPPC_CONTEXT* mppc, const BYTE* pSrcData, UINT32 SrcSize, BYTE
LengthOfMatch++;
}
#ifdef DEBUG_MPPC
#if defined(DEBUG_MPPC)
WLog_DBG(TAG, "<%" PRIu32 ",%" PRIu32 ">", CopyOffset, LengthOfMatch);
#endif
@ -715,7 +741,7 @@ int mppc_compress(MPPC_CONTEXT* mppc, const BYTE* pSrcData, UINT32 SrcSize, BYTE
}
accumulator = *pSrcPtr;
#ifdef DEBUG_MPPC
#if defined(DEBUG_MPPC)
WLog_DBG(TAG, "%" PRIu32 "", accumulator);
#endif
@ -752,6 +778,8 @@ int mppc_compress(MPPC_CONTEXT* mppc, const BYTE* pSrcData, UINT32 SrcSize, BYTE
void mppc_set_compression_level(MPPC_CONTEXT* mppc, DWORD CompressionLevel)
{
WINPR_ASSERT(mppc);
if (CompressionLevel < 1)
{
mppc->CompressionLevel = 0;
@ -766,6 +794,8 @@ void mppc_set_compression_level(MPPC_CONTEXT* mppc, DWORD CompressionLevel)
void mppc_context_reset(MPPC_CONTEXT* mppc, BOOL flush)
{
WINPR_ASSERT(mppc);
ZeroMemory(&(mppc->HistoryBuffer), sizeof(mppc->HistoryBuffer));
ZeroMemory(&(mppc->MatchBuffer), sizeof(mppc->MatchBuffer));
@ -783,36 +813,36 @@ void mppc_context_reset(MPPC_CONTEXT* mppc, BOOL flush)
MPPC_CONTEXT* mppc_context_new(DWORD CompressionLevel, BOOL Compressor)
{
MPPC_CONTEXT* mppc;
mppc = calloc(1, sizeof(MPPC_CONTEXT));
MPPC_CONTEXT* mppc = calloc(1, sizeof(MPPC_CONTEXT));
if (mppc)
if (!mppc)
goto fail;
mppc->Compressor = Compressor;
if (CompressionLevel < 1)
{
mppc->Compressor = Compressor;
if (CompressionLevel < 1)
{
mppc->CompressionLevel = 0;
mppc->HistoryBufferSize = 8192;
}
else
{
mppc->CompressionLevel = 1;
mppc->HistoryBufferSize = 65536;
}
mppc->bs = BitStream_New();
if (!mppc->bs)
{
free(mppc);
return NULL;
}
mppc_context_reset(mppc, FALSE);
mppc->CompressionLevel = 0;
mppc->HistoryBufferSize = 8192;
}
else
{
mppc->CompressionLevel = 1;
mppc->HistoryBufferSize = 65536;
}
mppc->bs = BitStream_New();
if (!mppc->bs)
goto fail;
mppc_context_reset(mppc, FALSE);
return mppc;
fail:
mppc_context_free(mppc);
return NULL;
}
void mppc_context_free(MPPC_CONTEXT* mppc)

View File

@ -19,6 +19,8 @@
* limitations under the License.
*/
#include <winpr/assert.h>
#include <freerdp/config.h>
#include <winpr/crt.h>
@ -32,18 +34,18 @@
struct s_NCRUSH_CONTEXT
{
BOOL Compressor;
BYTE* HistoryPtr;
UINT32 HistoryOffset;
UINT32 HistoryEndOffset;
UINT32 HistoryBufferSize;
BYTE HistoryBuffer[65536];
UINT32 HistoryBufferFence;
UINT32 OffsetCache[4];
UINT16 HashTable[65536];
UINT16 MatchTable[65536];
BYTE HuffTableCopyOffset[1024];
BYTE HuffTableLOM[4096];
ALIGN64 BOOL Compressor;
ALIGN64 BYTE* HistoryPtr;
ALIGN64 UINT32 HistoryOffset;
ALIGN64 UINT32 HistoryEndOffset;
ALIGN64 UINT32 HistoryBufferSize;
ALIGN64 BYTE HistoryBuffer[65536];
ALIGN64 UINT32 HistoryBufferFence;
ALIGN64 UINT32 OffsetCache[4];
ALIGN64 UINT16 HashTable[65536];
ALIGN64 UINT16 MatchTable[65536];
ALIGN64 BYTE HuffTableCopyOffset[1024];
ALIGN64 BYTE HuffTableLOM[4096];
};
static const UINT16 HuffTableLEC[8192] = {
@ -1916,14 +1918,19 @@ static const UINT32 LOMBaseLUT[30] = {
static INLINE UINT16 get_word(const BYTE* data)
{
UINT16 tmp = *data++;
UINT16 tmp;
WINPR_ASSERT(data);
tmp = *data++;
tmp |= *data << 8;
return tmp;
}
static INLINE UINT32 get_dword(const BYTE* data)
{
UINT32 tmp = *data++;
UINT32 tmp;
WINPR_ASSERT(data);
tmp = *data++;
tmp |= (UINT32)*data++ << 8U;
tmp |= (UINT32)*data++ << 16U;
tmp |= (UINT32)*data++ << 24U;
@ -1933,6 +1940,11 @@ static INLINE UINT32 get_dword(const BYTE* data)
static INLINE BOOL NCrushFetchBits(const BYTE** SrcPtr, const BYTE** SrcEnd, INT32* nbits,
UINT32* bits)
{
WINPR_ASSERT(SrcPtr);
WINPR_ASSERT(SrcEnd);
WINPR_ASSERT(nbits);
WINPR_ASSERT(bits);
if (*nbits < 16)
{
if ((*SrcPtr + 1) >= *SrcEnd)
@ -1962,6 +1974,10 @@ static INLINE BOOL NCrushFetchBits(const BYTE** SrcPtr, const BYTE** SrcEnd, INT
static INLINE void NCrushWriteStart(UINT32* bits, UINT32* offset, UINT32* accumulator)
{
WINPR_ASSERT(bits);
WINPR_ASSERT(offset);
WINPR_ASSERT(accumulator);
*bits = 0;
*offset = 0;
*accumulator = 0;
@ -1970,6 +1986,10 @@ static INLINE void NCrushWriteStart(UINT32* bits, UINT32* offset, UINT32* accumu
static INLINE void NCrushWriteBits(BYTE** DstPtr, UINT32* accumulator, UINT32* offset, UINT32 _bits,
UINT32 _nbits)
{
WINPR_ASSERT(DstPtr);
WINPR_ASSERT(accumulator);
WINPR_ASSERT(offset);
*accumulator |= _bits << *offset;
*offset += _nbits;
@ -1984,6 +2004,8 @@ static INLINE void NCrushWriteBits(BYTE** DstPtr, UINT32* accumulator, UINT32* o
static INLINE void NCrushWriteFinish(BYTE** DstPtr, UINT32 accumulator)
{
WINPR_ASSERT(DstPtr);
*(*DstPtr)++ = accumulator & 0xFF;
*(*DstPtr)++ = (accumulator >> 8) & 0xFF;
}
@ -2016,6 +2038,11 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, const BYTE* pSrcData, UINT32 SrcSi
UINT32 LengthOfMatchBits;
UINT32 LengthOfMatchBase;
WINPR_ASSERT(ncrush);
WINPR_ASSERT(pSrcData);
WINPR_ASSERT(ppDstData);
WINPR_ASSERT(pDstSize);
if (ncrush->HistoryEndOffset != 65535)
return -1001;
@ -2247,13 +2274,14 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, const BYTE* pSrcData, UINT32 SrcSi
static int ncrush_hash_table_add(NCRUSH_CONTEXT* ncrush, const BYTE* pSrcData, UINT32 SrcSize,
UINT32 HistoryOffset)
{
const BYTE* SrcPtr;
const BYTE* SrcPtr = pSrcData;
UINT32 Hash;
UINT32 Offset;
UINT32 EndOffset;
SrcPtr = pSrcData;
Offset = HistoryOffset;
EndOffset = Offset + SrcSize - 8;
UINT32 Offset = HistoryOffset;
UINT32 EndOffset = Offset + SrcSize - 8;
WINPR_ASSERT(ncrush);
WINPR_ASSERT(pSrcData);
WINPR_ASSERT(Offset + SrcSize >= 8);
while (Offset < EndOffset)
{
@ -2272,6 +2300,10 @@ static int ncrush_find_match_length(const BYTE* Ptr1, const BYTE* Ptr2, BYTE* Hi
BYTE val1, val2;
const BYTE* Ptr = Ptr1;
WINPR_ASSERT(Ptr1);
WINPR_ASSERT(Ptr2);
WINPR_ASSERT(HistoryPtr);
do
{
if (Ptr1 > HistoryPtr)
@ -2296,6 +2328,9 @@ static int ncrush_find_best_match(NCRUSH_CONTEXT* ncrush, UINT16 HistoryOffset,
UINT16 MatchOffset;
BYTE* HistoryBuffer;
WINPR_ASSERT(ncrush);
WINPR_ASSERT(pMatchOffset);
if (!ncrush->MatchTable[HistoryOffset])
return -1;
@ -2407,6 +2442,9 @@ static int ncrush_move_encoder_windows(NCRUSH_CONTEXT* ncrush, BYTE* HistoryPtr)
int NewMatch;
UINT32 HistoryOffset;
WINPR_ASSERT(ncrush);
WINPR_ASSERT(HistoryPtr);
if (HistoryPtr < &ncrush->HistoryBuffer[32768])
return -1;
@ -2444,8 +2482,8 @@ static int ncrush_move_encoder_windows(NCRUSH_CONTEXT* ncrush, BYTE* HistoryPtr)
return 1;
}
int ncrush_compress(NCRUSH_CONTEXT* ncrush, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData,
UINT32* pDstSize, UINT32* pFlags)
int ncrush_compress(NCRUSH_CONTEXT* ncrush, const BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstBuffer,
const BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags)
{
BYTE Literal;
const BYTE* SrcPtr;
@ -2460,8 +2498,8 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, const BYTE* pSrcData, UINT32 SrcSize
BYTE* HistoryPtr;
BYTE* pDstData;
UINT32 DstSize;
BOOL PacketAtFront;
BOOL PacketFlushed;
BOOL PacketAtFront = FALSE;
BOOL PacketFlushed = FALSE;
UINT32 MatchLength;
UINT32 IndexLEC;
UINT32 IndexLOM;
@ -2479,12 +2517,19 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, const BYTE* pSrcData, UINT32 SrcSize
BYTE* HistoryBufferEndPtr;
UINT32 CopyOffsetIndex;
UINT32 CopyOffsetBits;
UINT32 CompressionLevel;
CompressionLevel = 2;
UINT32 CompressionLevel = 2;
WINPR_ASSERT(ncrush);
WINPR_ASSERT(ncrush);
WINPR_ASSERT(pSrcData);
WINPR_ASSERT(pDstBuffer);
WINPR_ASSERT(ppDstData);
WINPR_ASSERT(pDstSize);
WINPR_ASSERT(pFlags);
HistoryBuffer = ncrush->HistoryBuffer;
*pFlags = 0;
PacketFlushed = FALSE;
PacketAtFront = FALSE;
if ((SrcSize + ncrush->HistoryOffset) >= 65529)
{
@ -2509,7 +2554,8 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, const BYTE* pSrcData, UINT32 SrcSize
*pFlags = 0;
}
pDstData = *ppDstData;
pDstData = pDstBuffer;
*ppDstData = pDstBuffer;
if (!pDstData)
return -1002;
@ -2799,6 +2845,8 @@ static int ncrush_generate_tables(NCRUSH_CONTEXT* context)
int j, l;
k = 0;
WINPR_ASSERT(context);
for (i = 0; i < 28; i++)
{
for (j = 0; j < 1 << LOMBitsLUT[i]; j++)
@ -2849,6 +2897,8 @@ static int ncrush_generate_tables(NCRUSH_CONTEXT* context)
void ncrush_context_reset(NCRUSH_CONTEXT* ncrush, BOOL flush)
{
WINPR_ASSERT(ncrush);
ZeroMemory(&(ncrush->HistoryBuffer), sizeof(ncrush->HistoryBuffer));
ZeroMemory(&(ncrush->OffsetCache), sizeof(ncrush->OffsetCache));
ZeroMemory(&(ncrush->MatchTable), sizeof(ncrush->MatchTable));
@ -2864,27 +2914,30 @@ void ncrush_context_reset(NCRUSH_CONTEXT* ncrush, BOOL flush)
NCRUSH_CONTEXT* ncrush_context_new(BOOL Compressor)
{
NCRUSH_CONTEXT* ncrush;
ncrush = (NCRUSH_CONTEXT*)calloc(1, sizeof(NCRUSH_CONTEXT));
NCRUSH_CONTEXT* ncrush = (NCRUSH_CONTEXT*)calloc(1, sizeof(NCRUSH_CONTEXT));
if (ncrush)
if (!ncrush)
goto fail;
ncrush->Compressor = Compressor;
ncrush->HistoryBufferSize = 65536;
ncrush->HistoryEndOffset = ncrush->HistoryBufferSize - 1;
ncrush->HistoryBufferFence = 0xABABABAB;
ncrush->HistoryOffset = 0;
ncrush->HistoryPtr = &(ncrush->HistoryBuffer[ncrush->HistoryOffset]);
if (ncrush_generate_tables(ncrush) < 0)
{
ncrush->Compressor = Compressor;
ZeroMemory(&(ncrush->OffsetCache), sizeof(ncrush->OffsetCache));
ncrush->HistoryBufferSize = 65536;
ncrush->HistoryEndOffset = ncrush->HistoryBufferSize - 1;
ZeroMemory(&(ncrush->HistoryBuffer), sizeof(ncrush->HistoryBuffer));
ncrush->HistoryBufferFence = 0xABABABAB;
ncrush->HistoryOffset = 0;
ncrush->HistoryPtr = &(ncrush->HistoryBuffer[ncrush->HistoryOffset]);
if (ncrush_generate_tables(ncrush) < 0)
WLog_DBG(TAG, "ncrush_context_new: failed to initialize tables");
ncrush_context_reset(ncrush, FALSE);
WLog_DBG(TAG, "ncrush_context_new: failed to initialize tables");
goto fail;
}
ncrush_context_reset(ncrush, FALSE);
return ncrush;
fail:
ncrush_context_free(ncrush);
return NULL;
}
void ncrush_context_free(NCRUSH_CONTEXT* ncrush)

View File

@ -739,24 +739,19 @@ static int test_MppcCompressBellsRdp5(void)
int rc = -1;
int status;
UINT32 Flags;
UINT32 SrcSize;
const BYTE* pSrcData;
UINT32 DstSize;
BYTE* pDstData;
MPPC_CONTEXT* mppc;
UINT32 expectedSize;
BYTE OutputBuffer[65536];
mppc = mppc_context_new(1, TRUE);
BYTE OutputBuffer[65536] = { 0 };
const UINT32 SrcSize = sizeof(TEST_MPPC_BELLS) - 1;
const BYTE* pSrcData = (const BYTE*)TEST_MPPC_BELLS;
UINT32 DstSize = sizeof(OutputBuffer);
const BYTE* pDstData = NULL;
const UINT32 expectedSize = sizeof(TEST_MPPC_BELLS_RDP5) - 1;
MPPC_CONTEXT* mppc = mppc_context_new(1, TRUE);
if (!mppc)
return -1;
SrcSize = sizeof(TEST_MPPC_BELLS) - 1;
pSrcData = (const BYTE*)TEST_MPPC_BELLS;
expectedSize = sizeof(TEST_MPPC_BELLS_RDP5) - 1;
DstSize = sizeof(OutputBuffer);
pDstData = OutputBuffer;
status = mppc_compress(mppc, pSrcData, SrcSize, &pDstData, &DstSize, &Flags);
status = mppc_compress(mppc, pSrcData, SrcSize, OutputBuffer, &pDstData, &DstSize, &Flags);
if (status < 0)
goto fail;
@ -792,24 +787,18 @@ static int test_MppcCompressBellsRdp4(void)
int rc = -1;
int status;
UINT32 Flags;
const BYTE* pSrcData;
UINT32 SrcSize;
UINT32 DstSize;
BYTE* pDstData;
MPPC_CONTEXT* mppc;
UINT32 expectedSize;
BYTE OutputBuffer[65536];
mppc = mppc_context_new(0, TRUE);
BYTE OutputBuffer[65536] = { 0 };
const BYTE* pSrcData = (const BYTE*)TEST_MPPC_BELLS;
const UINT32 SrcSize = sizeof(TEST_MPPC_BELLS) - 1;
UINT32 DstSize = sizeof(OutputBuffer);
const BYTE* pDstData = NULL;
const UINT32 expectedSize = sizeof(TEST_MPPC_BELLS_RDP4) - 1;
MPPC_CONTEXT* mppc = mppc_context_new(0, TRUE);
if (!mppc)
return -1;
SrcSize = sizeof(TEST_MPPC_BELLS) - 1;
pSrcData = (const BYTE*)TEST_MPPC_BELLS;
expectedSize = sizeof(TEST_MPPC_BELLS_RDP4) - 1;
DstSize = sizeof(OutputBuffer);
pDstData = OutputBuffer;
status = mppc_compress(mppc, pSrcData, SrcSize, &pDstData, &DstSize, &Flags);
status = mppc_compress(mppc, pSrcData, SrcSize, OutputBuffer, &pDstData, &DstSize, &Flags);
if (status < 0)
goto fail;
@ -939,24 +928,18 @@ static int test_MppcCompressIslandRdp5(void)
int rc = -1;
int status;
UINT32 Flags;
UINT32 SrcSize;
const BYTE* pSrcData;
UINT32 DstSize;
BYTE* pDstData;
MPPC_CONTEXT* mppc;
UINT32 expectedSize;
BYTE OutputBuffer[65536];
mppc = mppc_context_new(1, TRUE);
BYTE OutputBuffer[65536] = { 0 };
const UINT32 SrcSize = sizeof(TEST_ISLAND_DATA) - 1;
const BYTE* pSrcData = (const BYTE*)TEST_ISLAND_DATA;
const UINT32 expectedSize = sizeof(TEST_ISLAND_DATA_RDP5) - 1;
UINT32 DstSize = sizeof(OutputBuffer);
const BYTE* pDstData = NULL;
MPPC_CONTEXT* mppc = mppc_context_new(1, TRUE);
if (!mppc)
return -1;
SrcSize = sizeof(TEST_ISLAND_DATA) - 1;
pSrcData = (const BYTE*)TEST_ISLAND_DATA;
expectedSize = sizeof(TEST_ISLAND_DATA_RDP5) - 1;
DstSize = sizeof(OutputBuffer);
pDstData = OutputBuffer;
status = mppc_compress(mppc, pSrcData, SrcSize, &pDstData, &DstSize, &Flags);
status = mppc_compress(mppc, pSrcData, SrcSize, OutputBuffer, &pDstData, &DstSize, &Flags);
if (status < 0)
goto fail;
@ -992,24 +975,19 @@ static int test_MppcCompressBufferRdp5(void)
int rc = -1;
int status;
UINT32 Flags;
const BYTE* pSrcData;
UINT32 SrcSize;
UINT32 DstSize;
BYTE* pDstData;
MPPC_CONTEXT* mppc;
UINT32 expectedSize;
BYTE OutputBuffer[65536];
mppc = mppc_context_new(1, TRUE);
BYTE OutputBuffer[65536] = { 0 };
const UINT32 SrcSize = sizeof(TEST_RDP5_UNCOMPRESSED_DATA);
const BYTE* pSrcData = (const BYTE*)TEST_RDP5_UNCOMPRESSED_DATA;
const UINT32 expectedSize = sizeof(TEST_RDP5_COMPRESSED_DATA);
UINT32 DstSize = sizeof(OutputBuffer);
const BYTE* pDstData = NULL;
MPPC_CONTEXT* mppc = mppc_context_new(1, TRUE);
if (!mppc)
return -1;
SrcSize = sizeof(TEST_RDP5_UNCOMPRESSED_DATA);
pSrcData = (const BYTE*)TEST_RDP5_UNCOMPRESSED_DATA;
expectedSize = sizeof(TEST_RDP5_COMPRESSED_DATA);
DstSize = sizeof(OutputBuffer);
pDstData = OutputBuffer;
status = mppc_compress(mppc, pSrcData, SrcSize, &pDstData, &DstSize, &Flags);
status = mppc_compress(mppc, pSrcData, SrcSize, OutputBuffer, &pDstData, &DstSize, &Flags);
if (status < 0)
goto fail;

View File

@ -15,24 +15,18 @@ static BOOL test_NCrushCompressBells(void)
BOOL rc = FALSE;
int status;
UINT32 Flags;
UINT32 SrcSize;
const BYTE* pSrcData;
UINT32 DstSize;
BYTE* pDstData;
UINT32 expectedSize;
BYTE OutputBuffer[65536];
const BYTE* pDstData = NULL;
BYTE OutputBuffer[65536] = { 0 };
const UINT32 SrcSize = sizeof(TEST_BELLS_DATA) - 1;
const BYTE* pSrcData = TEST_BELLS_DATA;
const UINT32 expectedSize = sizeof(TEST_BELLS_NCRUSH) - 1;
UINT32 DstSize = sizeof(OutputBuffer);
NCRUSH_CONTEXT* ncrush = ncrush_context_new(TRUE);
if (!ncrush)
return rc;
SrcSize = sizeof(TEST_BELLS_DATA) - 1;
pSrcData = (const BYTE*)TEST_BELLS_DATA;
expectedSize = sizeof(TEST_BELLS_NCRUSH) - 1;
pDstData = OutputBuffer;
DstSize = sizeof(OutputBuffer);
ZeroMemory(OutputBuffer, sizeof(OutputBuffer));
status = ncrush_compress(ncrush, pSrcData, SrcSize, &pDstData, &DstSize, &Flags);
status = ncrush_compress(ncrush, pSrcData, SrcSize, OutputBuffer, &pDstData, &DstSize, &Flags);
if (status < 0)
goto fail;

View File

@ -42,109 +42,90 @@ static const BYTE TEST_ISLAND_DATA_XCRUSH[] =
"\x03\xbb\x43\x7b\x6f\xa8\xe5\x8b\xd0\xf0\xe8\xde\xd8\xd8\xe7\xec"
"\xf3\xa7\xe4\x7c\xa7\xe2\x9f\x01\x99\x4b\x80";
static int test_XCrushCompressBells(void)
static void test_dump(const char* fkt, const void* generated, size_t generated_size,
const void* expected, size_t expected_size)
{
int status;
UINT32 Flags;
UINT32 SrcSize;
const BYTE* pSrcData;
UINT32 DstSize;
BYTE* pDstData;
UINT32 expectedSize;
BYTE OutputBuffer[65536];
XCRUSH_CONTEXT* xcrush;
xcrush = xcrush_context_new(TRUE);
SrcSize = sizeof(TEST_BELLS_DATA) - 1;
pSrcData = (const BYTE*)TEST_BELLS_DATA;
expectedSize = sizeof(TEST_BELLS_DATA_XCRUSH) - 1;
pDstData = OutputBuffer;
DstSize = sizeof(OutputBuffer);
ZeroMemory(OutputBuffer, sizeof(OutputBuffer));
status = xcrush_compress(xcrush, pSrcData, SrcSize, &pDstData, &DstSize, &Flags);
printf("status: %d Flags: 0x%08" PRIX32 " DstSize: %" PRIu32 "\n", status, Flags, DstSize);
if (DstSize != expectedSize)
{
printf("XCrushCompressBells: output size mismatch: Actual: %" PRIu32 ", Expected: %" PRIu32
"\n",
DstSize, expectedSize);
printf("Actual\n");
BitDump(__FUNCTION__, WLOG_INFO, pDstData, DstSize * 8, 0);
printf("Expected\n");
BitDump(__FUNCTION__, WLOG_INFO, TEST_BELLS_DATA_XCRUSH, expectedSize * 8, 0);
return -1;
}
if (memcmp(pDstData, TEST_BELLS_DATA_XCRUSH, DstSize) != 0)
{
printf("XCrushCompressBells: output mismatch\n");
printf("Actual\n");
BitDump(__FUNCTION__, WLOG_INFO, pDstData, DstSize * 8, 0);
printf("Expected\n");
BitDump(__FUNCTION__, WLOG_INFO, TEST_BELLS_DATA_XCRUSH, expectedSize * 8, 0);
return -1;
}
xcrush_context_free(xcrush);
return 1;
printf("[%s] output size mismatch: Actual: %" PRIuz ", Expected: %" PRIuz "\n", fkt,
generated_size, expected_size);
printf("[%s] Actual\n", fkt);
BitDump(fkt, WLOG_INFO, generated, generated_size * 8ull, 0);
printf("[%s] Expected\n", fkt);
BitDump(fkt, WLOG_INFO, expected, expected_size * 8ull, 0);
}
static int test_XCrushCompressIsland(void)
static BOOL test_compare(const char* fkt, const void* generated, size_t generated_size,
const void* expected, size_t expected_size)
{
int status;
UINT32 Flags;
UINT32 SrcSize;
const BYTE* pSrcData;
UINT32 DstSize;
BYTE* pDstData;
UINT32 expectedSize;
BYTE OutputBuffer[65536];
XCRUSH_CONTEXT* xcrush;
xcrush = xcrush_context_new(TRUE);
SrcSize = sizeof(TEST_ISLAND_DATA) - 1;
pSrcData = (const BYTE*)TEST_ISLAND_DATA;
expectedSize = sizeof(TEST_ISLAND_DATA_XCRUSH) - 1;
pDstData = OutputBuffer;
DstSize = sizeof(OutputBuffer);
ZeroMemory(OutputBuffer, sizeof(OutputBuffer));
status = xcrush_compress(xcrush, pSrcData, SrcSize, &pDstData, &DstSize, &Flags);
printf("status: %d Flags: 0x%08" PRIX32 " DstSize: %" PRIu32 "\n", status, Flags, DstSize);
if (DstSize != expectedSize)
if (generated_size != expected_size)
{
printf("XCrushCompressIsland: output size mismatch: Actual: %" PRIu32 ", Expected: %" PRIu32
"\n",
DstSize, expectedSize);
printf("Actual\n");
BitDump(__FUNCTION__, WLOG_INFO, pDstData, DstSize * 8, 0);
printf("Expected\n");
BitDump(__FUNCTION__, WLOG_INFO, TEST_ISLAND_DATA_XCRUSH, expectedSize * 8, 0);
return -1;
test_dump(fkt, generated, generated_size, expected, expected_size);
return FALSE;
}
if (memcmp(pDstData, TEST_ISLAND_DATA_XCRUSH, DstSize) != 0)
if (memcmp(generated, expected, generated_size) != 0)
{
printf("XCrushCompressIsland: output mismatch\n");
printf("Actual\n");
BitDump(__FUNCTION__, WLOG_INFO, pDstData, DstSize * 8, 0);
printf("Expected\n");
BitDump(__FUNCTION__, WLOG_INFO, TEST_ISLAND_DATA_XCRUSH, expectedSize * 8, 0);
return -1;
test_dump(fkt, generated, generated_size, expected, expected_size);
return FALSE;
}
return TRUE;
}
static BOOL test_run(const char* fkt, const void* src, UINT32 src_size, const void* expected,
size_t expected_size)
{
BOOL rc = FALSE;
int status = -1;
UINT32 Flags = 0;
const BYTE* pDstData = NULL;
BYTE OutputBuffer[65536] = { 0 };
UINT32 DstSize = sizeof(OutputBuffer);
XCRUSH_CONTEXT* xcrush = xcrush_context_new(TRUE);
if (!xcrush)
return -1;
status = xcrush_compress(xcrush, src, src_size, OutputBuffer, &pDstData, &DstSize, &Flags);
printf("[%s] status: %d Flags: 0x%08" PRIX32 " DstSize: %" PRIu32 "\n", fkt, status, Flags,
DstSize);
rc = test_compare(fkt, pDstData, DstSize, expected, expected_size);
xcrush_context_free(xcrush);
return 1;
return rc;
}
struct test_argument
{
const char* name;
const void* src;
UINT32 src_size;
const void* expected;
size_t expected_size;
};
static const struct test_argument tests[] = {
{ "XCrushCompressIsland", TEST_ISLAND_DATA, sizeof(TEST_ISLAND_DATA) - 1,
TEST_ISLAND_DATA_XCRUSH, sizeof(TEST_ISLAND_DATA_XCRUSH) - 1 }
#if 0
,{ "XCrushCompressBells", TEST_BELLS_DATA, sizeof(TEST_BELLS_DATA) - 1, TEST_BELLS_DATA_XCRUSH,
sizeof(TEST_BELLS_DATA_XCRUSH) - 1 }
#endif
};
int TestFreeRDPCodecXCrush(int argc, char* argv[])
{
int rc = 0;
size_t x;
WINPR_UNUSED(argc);
WINPR_UNUSED(argv);
// if (test_XCrushCompressBells() < 0)
// return -1;
if (test_XCrushCompressIsland() < 0)
return -1;
for (x = 0; x < ARRAYSIZE(tests); x++)
{
const struct test_argument* arg = &tests[x];
return 0;
if (!test_run(arg->name, arg->src, arg->src_size, arg->expected, arg->expected_size))
rc = -1;
}
return rc;
}

View File

@ -19,6 +19,7 @@
* limitations under the License.
*/
#include <winpr/assert.h>
#include <freerdp/config.h>
#include <winpr/crt.h>
@ -71,31 +72,29 @@ typedef struct
struct s_XCRUSH_CONTEXT
{
BOOL Compressor;
MPPC_CONTEXT* mppc;
BYTE* HistoryPtr;
UINT32 HistoryOffset;
UINT32 HistoryBufferSize;
BYTE HistoryBuffer[2000000];
BYTE BlockBuffer[16384];
UINT32 CompressionFlags;
UINT32 SignatureIndex;
UINT32 SignatureCount;
XCRUSH_SIGNATURE Signatures[1000];
UINT32 ChunkHead;
UINT32 ChunkTail;
XCRUSH_CHUNK Chunks[65534];
UINT16 NextChunks[65536];
UINT32 OriginalMatchCount;
UINT32 OptimizedMatchCount;
XCRUSH_MATCH_INFO OriginalMatches[1000];
XCRUSH_MATCH_INFO OptimizedMatches[1000];
ALIGN64 BOOL Compressor;
ALIGN64 MPPC_CONTEXT* mppc;
ALIGN64 BYTE* HistoryPtr;
ALIGN64 UINT32 HistoryOffset;
ALIGN64 UINT32 HistoryBufferSize;
ALIGN64 BYTE HistoryBuffer[2000000];
ALIGN64 BYTE BlockBuffer[16384];
ALIGN64 UINT32 CompressionFlags;
ALIGN64 UINT32 SignatureIndex;
ALIGN64 UINT32 SignatureCount;
ALIGN64 XCRUSH_SIGNATURE Signatures[1000];
ALIGN64 UINT32 ChunkHead;
ALIGN64 UINT32 ChunkTail;
ALIGN64 XCRUSH_CHUNK Chunks[65534];
ALIGN64 UINT16 NextChunks[65536];
ALIGN64 UINT32 OriginalMatchCount;
ALIGN64 UINT32 OptimizedMatchCount;
ALIGN64 XCRUSH_MATCH_INFO OriginalMatches[1000];
ALIGN64 XCRUSH_MATCH_INFO OptimizedMatches[1000];
};
#ifdef DEBUG_XCRUSH
//#define DEBUG_XCRUSH 1
#if defined(DEBUG_XCRUSH)
static const char* xcrush_get_level_2_compression_flags_string(UINT32 flags)
{
flags &= 0xE0;
@ -167,6 +166,9 @@ static UINT32 xcrush_update_hash(const BYTE* data, UINT32 size)
const BYTE* end;
UINT32 seed = 5381; /* same value as in djb2 */
WINPR_ASSERT(data);
WINPR_ASSERT(size >= 4);
if (size > 32)
{
size = 32;
@ -186,9 +188,12 @@ static UINT32 xcrush_update_hash(const BYTE* data, UINT32 size)
static int xcrush_append_chunk(XCRUSH_CONTEXT* xcrush, const BYTE* data, UINT32* beg, UINT32 end)
{
UINT16 seed;
UINT32 size;
WINPR_ASSERT(xcrush);
WINPR_ASSERT(data);
WINPR_ASSERT(beg);
if (xcrush->SignatureIndex >= xcrush->SignatureCount)
return 0;
@ -199,7 +204,7 @@ static int xcrush_append_chunk(XCRUSH_CONTEXT* xcrush, const BYTE* data, UINT32*
if (size >= 15)
{
seed = xcrush_update_hash(&data[*beg], (UINT16)size);
UINT32 seed = xcrush_update_hash(&data[*beg], (UINT16)size);
xcrush->Signatures[xcrush->SignatureIndex].size = size;
xcrush->Signatures[xcrush->SignatureIndex].seed = seed;
xcrush->SignatureIndex++;
@ -216,6 +221,11 @@ static int xcrush_compute_chunks(XCRUSH_CONTEXT* xcrush, const BYTE* data, UINT3
UINT32 offset = 0;
UINT32 rotation = 0;
UINT32 accumulator = 0;
WINPR_ASSERT(xcrush);
WINPR_ASSERT(data);
WINPR_ASSERT(pIndex);
*pIndex = 0;
xcrush->SignatureIndex = 0;
@ -293,6 +303,8 @@ static void xcrush_clear_hash_table_range(XCRUSH_CONTEXT* xcrush, UINT32 beg, UI
{
UINT32 index;
WINPR_ASSERT(xcrush);
for (index = 0; index < 65536; index++)
{
if (xcrush->NextChunks[index] >= beg)
@ -322,6 +334,8 @@ static int xcrush_find_next_matching_chunk(XCRUSH_CONTEXT* xcrush, XCRUSH_CHUNK*
UINT32 index;
XCRUSH_CHUNK* next = NULL;
WINPR_ASSERT(xcrush);
if (!chunk)
return -4001; /* error */
@ -341,6 +355,7 @@ static int xcrush_find_next_matching_chunk(XCRUSH_CONTEXT* xcrush, XCRUSH_CHUNK*
}
}
WINPR_ASSERT(pNextChunk);
*pNextChunk = next;
return 1;
}
@ -351,6 +366,8 @@ static int xcrush_insert_chunk(XCRUSH_CONTEXT* xcrush, XCRUSH_SIGNATURE* signatu
UINT32 seed;
UINT32 index;
WINPR_ASSERT(xcrush);
if (xcrush->ChunkHead >= 65530)
{
xcrush->ChunkHead = 1;
@ -379,6 +396,7 @@ static int xcrush_insert_chunk(XCRUSH_CONTEXT* xcrush, XCRUSH_SIGNATURE* signatu
if (xcrush->NextChunks[seed] >= 65534)
return -3003; /* error */
WINPR_ASSERT(pPrevChunk);
*pPrevChunk = &xcrush->Chunks[xcrush->NextChunks[seed]];
}
@ -401,13 +419,15 @@ static int xcrush_find_match_length(XCRUSH_CONTEXT* xcrush, UINT32 MatchOffset,
BYTE* ForwardMatchPtr;
BYTE* ReverseMatchPtr;
BYTE* HistoryBufferEnd;
UINT32 ReverseMatchLength;
UINT32 ForwardMatchLength;
UINT32 ReverseMatchLength = 0;
UINT32 ForwardMatchLength = 0;
UINT32 TotalMatchLength;
BYTE* HistoryBuffer;
UINT32 HistoryBufferSize;
ForwardMatchLength = 0;
ReverseMatchLength = 0;
WINPR_ASSERT(xcrush);
WINPR_ASSERT(MatchInfo);
HistoryBuffer = xcrush->HistoryBuffer;
HistoryBufferSize = xcrush->HistoryBufferSize;
HistoryBufferEnd = &HistoryBuffer[HistoryOffset + SrcSize];
@ -496,6 +516,9 @@ static int xcrush_find_all_matches(XCRUSH_CONTEXT* xcrush, UINT32 SignatureIndex
XCRUSH_MATCH_INFO MatchInfo = { 0 };
XCRUSH_MATCH_INFO MaxMatchInfo = { 0 };
XCRUSH_SIGNATURE* Signatures = NULL;
WINPR_ASSERT(xcrush);
Signatures = xcrush->Signatures;
for (i = 0; i < SignatureIndex; i++)
@ -584,19 +607,19 @@ static int xcrush_find_all_matches(XCRUSH_CONTEXT* xcrush, UINT32 SignatureIndex
static int xcrush_optimize_matches(XCRUSH_CONTEXT* xcrush)
{
UINT32 i, j;
UINT32 MatchDiff;
UINT32 PrevMatchEnd;
UINT32 TotalMatchLength;
UINT32 OriginalMatchCount;
UINT32 OptimizedMatchCount;
UINT32 i, j = 0;
UINT32 MatchDiff = 0;
UINT32 PrevMatchEnd = 0;
UINT32 TotalMatchLength = 0;
UINT32 OriginalMatchCount = 0;
UINT32 OptimizedMatchCount = 0;
XCRUSH_MATCH_INFO* OriginalMatch;
XCRUSH_MATCH_INFO* OptimizedMatch;
XCRUSH_MATCH_INFO* OriginalMatches;
XCRUSH_MATCH_INFO* OptimizedMatches;
j = 0;
PrevMatchEnd = 0;
TotalMatchLength = 0;
WINPR_ASSERT(xcrush);
OriginalMatches = xcrush->OriginalMatches;
OriginalMatchCount = xcrush->OriginalMatchCount;
OptimizedMatches = xcrush->OptimizedMatches;
@ -661,6 +684,12 @@ static int xcrush_generate_output(XCRUSH_CONTEXT* xcrush, BYTE* OutputBuffer, UI
UINT32 MatchOffsetDiff;
UINT32 HistoryOffsetDiff;
RDP61_MATCH_DETAILS* MatchDetails;
WINPR_ASSERT(xcrush);
WINPR_ASSERT(OutputBuffer);
WINPR_ASSERT(OutputSize >= 2);
WINPR_ASSERT(pDstSize);
MatchCount = xcrush->OptimizedMatchCount;
OutputEnd = &OutputBuffer[OutputSize];
@ -728,6 +757,10 @@ static int xcrush_generate_output(XCRUSH_CONTEXT* xcrush, BYTE* OutputBuffer, UI
static INLINE size_t xcrush_copy_bytes(BYTE* dst, const BYTE* src, size_t num)
{
size_t diff, rest, end, a;
WINPR_ASSERT(dst);
WINPR_ASSERT(src);
if (src + num < dst || src > dst + num)
{
memcpy(dst, src, num);
@ -770,9 +803,15 @@ static int xcrush_decompress_l1(XCRUSH_CONTEXT* xcrush, const BYTE* pSrcData, UI
UINT32 MatchHistoryOffset = 0;
const RDP61_MATCH_DETAILS* MatchDetails = NULL;
WINPR_ASSERT(xcrush);
if (SrcSize < 1)
return -1001;
WINPR_ASSERT(pSrcData);
WINPR_ASSERT(ppDstData);
WINPR_ASSERT(pDstSize);
if (flags & L1_PACKET_AT_FRONT)
xcrush->HistoryOffset = 0;
@ -875,9 +914,15 @@ int xcrush_decompress(XCRUSH_CONTEXT* xcrush, const BYTE* pSrcData, UINT32 SrcSi
BYTE Level1ComprFlags;
BYTE Level2ComprFlags;
WINPR_ASSERT(xcrush);
if (SrcSize < 2)
return -1;
WINPR_ASSERT(pSrcData);
WINPR_ASSERT(ppDstData);
WINPR_ASSERT(pDstSize);
Level1ComprFlags = pSrcData[0];
Level2ComprFlags = pSrcData[1];
pSrcData += 2;
@ -907,7 +952,7 @@ int xcrush_decompress(XCRUSH_CONTEXT* xcrush, const BYTE* pSrcData, UINT32 SrcSi
}
static int xcrush_compress_l1(XCRUSH_CONTEXT* xcrush, const BYTE* pSrcData, UINT32 SrcSize,
BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags)
BYTE* pDstData, UINT32* pDstSize, UINT32* pFlags)
{
int status = 0;
UINT32 Flags = 0;
@ -916,6 +961,13 @@ static int xcrush_compress_l1(XCRUSH_CONTEXT* xcrush, const BYTE* pSrcData, UINT
BYTE* HistoryBuffer = NULL;
UINT32 SignatureIndex = 0;
WINPR_ASSERT(xcrush);
WINPR_ASSERT(pSrcData);
WINPR_ASSERT(SrcSize > 0);
WINPR_ASSERT(pDstData);
WINPR_ASSERT(pDstSize);
WINPR_ASSERT(pFlags);
if (xcrush->HistoryOffset + SrcSize + 8 > xcrush->HistoryBufferSize)
{
xcrush->HistoryOffset = 0;
@ -952,8 +1004,7 @@ static int xcrush_compress_l1(XCRUSH_CONTEXT* xcrush, const BYTE* pSrcData, UINT
if (xcrush->OptimizedMatchCount)
{
status =
xcrush_generate_output(xcrush, *ppDstData, SrcSize, HistoryOffset, pDstSize);
status = xcrush_generate_output(xcrush, pDstData, SrcSize, HistoryOffset, pDstSize);
if (status < 0)
return status;
@ -973,8 +1024,8 @@ static int xcrush_compress_l1(XCRUSH_CONTEXT* xcrush, const BYTE* pSrcData, UINT
return 1;
}
int xcrush_compress(XCRUSH_CONTEXT* xcrush, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData,
UINT32* pDstSize, UINT32* pFlags)
int xcrush_compress(XCRUSH_CONTEXT* xcrush, const BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstBuffer,
const BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags)
{
int status = 0;
UINT32 DstSize = 0;
@ -987,17 +1038,25 @@ int xcrush_compress(XCRUSH_CONTEXT* xcrush, const BYTE* pSrcData, UINT32 SrcSize
UINT32 Level2ComprFlags = 0;
UINT32 CompressionLevel = 3;
WINPR_ASSERT(xcrush);
WINPR_ASSERT(pSrcData);
WINPR_ASSERT(SrcSize > 0);
WINPR_ASSERT(ppDstData);
WINPR_ASSERT(pDstSize);
WINPR_ASSERT(pFlags);
if (SrcSize > 16384)
return -1001;
if ((SrcSize + 2) > *pDstSize)
return -1002;
OriginalData = *ppDstData;
OriginalData = pDstBuffer;
*ppDstData = pDstBuffer;
OriginalDataSize = SrcSize;
pDstData = xcrush->BlockBuffer;
CompressedDataSize = SrcSize;
status = xcrush_compress_l1(xcrush, pSrcData, SrcSize, &pDstData, &CompressedDataSize,
status = xcrush_compress_l1(xcrush, pSrcData, SrcSize, pDstData, &CompressedDataSize,
&Level1ComprFlags);
if (status < 0)
@ -1024,8 +1083,9 @@ int xcrush_compress(XCRUSH_CONTEXT* xcrush, const BYTE* pSrcData, UINT32 SrcSize
if (CompressedDataSize > 50)
{
status = mppc_compress(xcrush->mppc, CompressedData, CompressedDataSize, &pDstData,
&DstSize, &Level2ComprFlags);
const BYTE* pUnusedDstData = NULL;
status = mppc_compress(xcrush->mppc, CompressedData, CompressedDataSize, pDstData,
&pUnusedDstData, &DstSize, &Level2ComprFlags);
}
if (status < 0)
@ -1075,6 +1135,8 @@ int xcrush_compress(XCRUSH_CONTEXT* xcrush, const BYTE* pSrcData, UINT32 SrcSize
void xcrush_context_reset(XCRUSH_CONTEXT* xcrush, BOOL flush)
{
WINPR_ASSERT(xcrush);
xcrush->SignatureIndex = 0;
xcrush->SignatureCount = 1000;
ZeroMemory(&(xcrush->Signatures), sizeof(XCRUSH_SIGNATURE) * xcrush->SignatureCount);
@ -1095,19 +1157,23 @@ void xcrush_context_reset(XCRUSH_CONTEXT* xcrush, BOOL flush)
XCRUSH_CONTEXT* xcrush_context_new(BOOL Compressor)
{
XCRUSH_CONTEXT* xcrush;
xcrush = (XCRUSH_CONTEXT*)calloc(1, sizeof(XCRUSH_CONTEXT));
XCRUSH_CONTEXT* xcrush = (XCRUSH_CONTEXT*)calloc(1, sizeof(XCRUSH_CONTEXT));
if (xcrush)
{
xcrush->Compressor = Compressor;
xcrush->mppc = mppc_context_new(1, Compressor);
xcrush->HistoryOffset = 0;
xcrush->HistoryBufferSize = 2000000;
xcrush_context_reset(xcrush, FALSE);
}
if (!xcrush)
goto fail;
xcrush->Compressor = Compressor;
xcrush->mppc = mppc_context_new(1, Compressor);
if (!xcrush->mppc)
goto fail;
xcrush->HistoryBufferSize = 2000000;
xcrush_context_reset(xcrush, FALSE);
return xcrush;
fail:
xcrush_context_free(xcrush);
return NULL;
}
void xcrush_context_free(XCRUSH_CONTEXT* xcrush)

View File

@ -17,28 +17,31 @@
* limitations under the License.
*/
#include <winpr/assert.h>
#include <freerdp/config.h>
#include "bulk.h"
#define TAG "com.freerdp.core"
//#define WITH_BULK_DEBUG 1
//#define WITH_BULK_DEBUG 1
struct rdp_bulk
{
rdpContext* context;
UINT32 CompressionLevel;
UINT32 CompressionMaxSize;
MPPC_CONTEXT* mppcSend;
MPPC_CONTEXT* mppcRecv;
NCRUSH_CONTEXT* ncrushRecv;
NCRUSH_CONTEXT* ncrushSend;
XCRUSH_CONTEXT* xcrushRecv;
XCRUSH_CONTEXT* xcrushSend;
BYTE OutputBuffer[65536];
ALIGN64 rdpContext* context;
ALIGN64 UINT32 CompressionLevel;
ALIGN64 UINT32 CompressionMaxSize;
ALIGN64 MPPC_CONTEXT* mppcSend;
ALIGN64 MPPC_CONTEXT* mppcRecv;
ALIGN64 NCRUSH_CONTEXT* ncrushRecv;
ALIGN64 NCRUSH_CONTEXT* ncrushSend;
ALIGN64 XCRUSH_CONTEXT* xcrushRecv;
ALIGN64 XCRUSH_CONTEXT* xcrushSend;
ALIGN64 BYTE OutputBuffer[65536];
};
#if WITH_BULK_DEBUG
#if defined(WITH_BULK_DEBUG)
static INLINE const char* bulk_get_compression_flags_string(UINT32 flags)
{
flags &= BULK_COMPRESSION_FLAGS_MASK;
@ -66,7 +69,11 @@ static INLINE const char* bulk_get_compression_flags_string(UINT32 flags)
static UINT32 bulk_compression_level(rdpBulk* bulk)
{
rdpSettings* settings = bulk->context->settings;
rdpSettings* settings;
WINPR_ASSERT(bulk);
WINPR_ASSERT(bulk->context);
settings = bulk->context->settings;
WINPR_ASSERT(settings);
bulk->CompressionLevel = (settings->CompressionLevel >= PACKET_COMPR_TYPE_RDP61)
? PACKET_COMPR_TYPE_RDP61
: settings->CompressionLevel;
@ -75,25 +82,31 @@ static UINT32 bulk_compression_level(rdpBulk* bulk)
UINT32 bulk_compression_max_size(rdpBulk* bulk)
{
WINPR_ASSERT(bulk);
bulk_compression_level(bulk);
bulk->CompressionMaxSize = (bulk->CompressionLevel < PACKET_COMPR_TYPE_64K) ? 8192 : 65536;
return bulk->CompressionMaxSize;
}
#if WITH_BULK_DEBUG
static INLINE int bulk_compress_validate(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize,
BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags)
#if defined(WITH_BULK_DEBUG)
static INLINE int bulk_compress_validate(rdpBulk* bulk, const BYTE* pSrcData, UINT32 SrcSize,
const BYTE* pDstData, UINT32 DstSize, UINT32 Flags)
{
int status;
BYTE* _pSrcData = NULL;
BYTE* _pDstData = NULL;
UINT32 _SrcSize = 0;
UINT32 _DstSize = 0;
UINT32 _Flags = 0;
_pSrcData = *ppDstData;
_SrcSize = *pDstSize;
_Flags = *pFlags | bulk->CompressionLevel;
status = bulk_decompress(bulk, _pSrcData, _SrcSize, &_pDstData, &_DstSize, _Flags);
const BYTE* v_pSrcData = NULL;
const BYTE* v_pDstData = NULL;
UINT32 v_SrcSize = 0;
UINT32 v_DstSize = 0;
UINT32 v_Flags = 0;
WINPR_ASSERT(bulk);
WINPR_ASSERT(pSrcData);
WINPR_ASSERT(pDstData);
v_pSrcData = pDstData;
v_SrcSize = DstSize;
v_Flags = Flags | bulk->CompressionLevel;
status = bulk_decompress(bulk, v_pSrcData, v_SrcSize, &v_pDstData, &v_DstSize, v_Flags);
if (status < 0)
{
@ -101,22 +114,22 @@ static INLINE int bulk_compress_validate(rdpBulk* bulk, BYTE* pSrcData, UINT32 S
return status;
}
if (_DstSize != SrcSize)
if (v_DstSize != SrcSize)
{
WLog_DBG(TAG,
"compression/decompression size mismatch: Actual: %" PRIu32 ", Expected: %" PRIu32
"",
_DstSize, SrcSize);
v_DstSize, SrcSize);
return -1;
}
if (memcmp(_pDstData, pSrcData, SrcSize) != 0)
if (memcmp(v_pDstData, pSrcData, SrcSize) != 0)
{
WLog_DBG(TAG, "compression/decompression input/output mismatch! flags: 0x%08" PRIX32 "",
_Flags);
v_Flags);
#if 1
WLog_DBG(TAG, "Actual:");
winpr_HexDump(TAG, WLOG_DEBUG, _pDstData, SrcSize);
winpr_HexDump(TAG, WLOG_DEBUG, v_pDstData, SrcSize);
WLog_DBG(TAG, "Expected:");
winpr_HexDump(TAG, WLOG_DEBUG, pSrcData, SrcSize);
#endif
@ -136,7 +149,16 @@ int bulk_decompress(rdpBulk* bulk, const BYTE* pSrcData, UINT32 SrcSize, const B
UINT32 CompressedBytes;
UINT32 UncompressedBytes;
double CompressionRatio;
WINPR_ASSERT(bulk);
WINPR_ASSERT(bulk->context);
WINPR_ASSERT(pSrcData);
WINPR_ASSERT(ppDstData);
WINPR_ASSERT(pDstSize);
metrics = bulk->context->metrics;
WINPR_ASSERT(metrics);
bulk_compression_max_size(bulk);
type = flags & BULK_COMPRESSION_TYPE_MASK;
@ -211,15 +233,23 @@ int bulk_decompress(rdpBulk* bulk, const BYTE* pSrcData, UINT32 SrcSize, const B
return status;
}
int bulk_compress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize,
UINT32* pFlags)
int bulk_compress(rdpBulk* bulk, const BYTE* pSrcData, UINT32 SrcSize, const BYTE** ppDstData,
UINT32* pDstSize, UINT32* pFlags)
{
int status = -1;
rdpMetrics* metrics;
UINT32 CompressedBytes;
UINT32 UncompressedBytes;
double CompressionRatio;
WINPR_ASSERT(bulk);
WINPR_ASSERT(bulk->context);
WINPR_ASSERT(pSrcData);
WINPR_ASSERT(ppDstData);
WINPR_ASSERT(pDstSize);
metrics = bulk->context->metrics;
WINPR_ASSERT(metrics);
if ((SrcSize <= 50) || (SrcSize >= 16384))
{
@ -228,7 +258,6 @@ int bulk_compress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstDat
return 0;
}
*ppDstData = bulk->OutputBuffer;
*pDstSize = sizeof(bulk->OutputBuffer);
bulk_compression_level(bulk);
bulk_compression_max_size(bulk);
@ -238,15 +267,16 @@ int bulk_compress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstDat
case PACKET_COMPR_TYPE_8K:
case PACKET_COMPR_TYPE_64K:
mppc_set_compression_level(bulk->mppcSend, bulk->CompressionLevel);
status = mppc_compress(bulk->mppcSend, pSrcData, SrcSize, ppDstData, pDstSize, pFlags);
status = mppc_compress(bulk->mppcSend, pSrcData, SrcSize, bulk->OutputBuffer, ppDstData,
pDstSize, pFlags);
break;
case PACKET_COMPR_TYPE_RDP6:
status =
ncrush_compress(bulk->ncrushSend, pSrcData, SrcSize, ppDstData, pDstSize, pFlags);
status = ncrush_compress(bulk->ncrushSend, pSrcData, SrcSize, bulk->OutputBuffer,
ppDstData, pDstSize, pFlags);
break;
case PACKET_COMPR_TYPE_RDP61:
status =
xcrush_compress(bulk->xcrushSend, pSrcData, SrcSize, ppDstData, pDstSize, pFlags);
status = xcrush_compress(bulk->xcrushSend, pSrcData, SrcSize, bulk->OutputBuffer,
ppDstData, pDstSize, pFlags);
break;
case PACKET_COMPR_TYPE_RDP8:
WLog_ERR(TAG, "Unsupported bulk compression type %08" PRIx32, bulk->CompressionLevel);
@ -279,9 +309,9 @@ int bulk_compress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstDat
#endif
}
#if WITH_BULK_DEBUG
#if defined(WITH_BULK_DEBUG)
if (bulk_compress_validate(bulk, pSrcData, SrcSize, ppDstData, pDstSize, pFlags) < 0)
if (bulk_compress_validate(bulk, pSrcData, SrcSize, *ppDstData, *pDstSize, *pFlags) < 0)
status = -1;
#endif
@ -303,21 +333,38 @@ void bulk_reset(rdpBulk* bulk)
rdpBulk* bulk_new(rdpContext* context)
{
rdpBulk* bulk;
WINPR_ASSERT(context);
bulk = (rdpBulk*)calloc(1, sizeof(rdpBulk));
if (bulk)
{
bulk->context = context;
bulk->mppcSend = mppc_context_new(1, TRUE);
bulk->mppcRecv = mppc_context_new(1, FALSE);
bulk->ncrushRecv = ncrush_context_new(FALSE);
bulk->ncrushSend = ncrush_context_new(TRUE);
bulk->xcrushRecv = xcrush_context_new(FALSE);
bulk->xcrushSend = xcrush_context_new(TRUE);
bulk->CompressionLevel = context->settings->CompressionLevel;
}
if (!bulk)
goto fail;
bulk->context = context;
bulk->mppcSend = mppc_context_new(1, TRUE);
if (!bulk->mppcSend)
goto fail;
bulk->mppcRecv = mppc_context_new(1, FALSE);
if (!bulk->mppcRecv)
goto fail;
bulk->ncrushRecv = ncrush_context_new(FALSE);
if (!bulk->ncrushRecv)
goto fail;
bulk->ncrushSend = ncrush_context_new(TRUE);
if (!bulk->ncrushSend)
goto fail;
bulk->xcrushRecv = xcrush_context_new(FALSE);
if (!bulk->xcrushRecv)
goto fail;
bulk->xcrushSend = xcrush_context_new(TRUE);
if (!bulk->xcrushSend)
goto fail;
bulk->CompressionLevel = context->settings->CompressionLevel;
return bulk;
fail:
bulk_free(bulk);
return NULL;
}
void bulk_free(rdpBulk* bulk)

View File

@ -36,8 +36,8 @@ FREERDP_LOCAL UINT32 bulk_compression_max_size(rdpBulk* bulk);
FREERDP_LOCAL int bulk_decompress(rdpBulk* bulk, const BYTE* pSrcData, UINT32 SrcSize,
const BYTE** ppDstData, UINT32* pDstSize, UINT32 flags);
FREERDP_LOCAL int bulk_compress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData,
UINT32* pDstSize, UINT32* pFlags);
FREERDP_LOCAL int bulk_compress(rdpBulk* bulk, const BYTE* pSrcData, UINT32 SrcSize,
const BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags);
FREERDP_LOCAL void bulk_reset(rdpBulk* bulk);

View File

@ -1124,10 +1124,10 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
for (fragment = 0; (totalLength > 0) || (fragment == 0); fragment++)
{
BYTE* pSrcData;
const BYTE* pSrcData;
UINT32 SrcSize;
UINT32 DstSize = 0;
BYTE* pDstData = NULL;
const BYTE* pDstData = NULL;
UINT32 compressionFlags = 0;
BYTE pad = 0;
BYTE* pSignature = NULL;
@ -1137,7 +1137,7 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
fpUpdateHeader.compressionFlags = 0;
fpUpdateHeader.updateCode = updateCode;
fpUpdateHeader.size = (totalLength > maxLength) ? maxLength : totalLength;
pSrcData = pDstData = Stream_Pointer(s);
pSrcData = Stream_Pointer(s);
SrcSize = DstSize = fpUpdateHeader.size;
if (rdp->sec_flags & SEC_ENCRYPT)