libfreerdp-codec: start hooking new NCrush decompressor
This commit is contained in:
parent
20019f10b2
commit
698cae2052
@ -32,8 +32,9 @@ struct _NCRUSH_CONTEXT
|
||||
BOOL Compressor;
|
||||
BYTE* HistoryPtr;
|
||||
UINT32 HistoryOffset;
|
||||
UINT32 HistoryBufferSize;
|
||||
UINT32 HistoryEndOffset;
|
||||
BYTE HistoryBuffer[65536];
|
||||
UINT32 HistoryBufferFence;
|
||||
UINT32 OffsetCache[4];
|
||||
};
|
||||
typedef struct _NCRUSH_CONTEXT NCRUSH_CONTEXT;
|
||||
@ -45,6 +46,8 @@ extern "C" {
|
||||
FREERDP_API int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData, UINT32* pDstSize, UINT32* pFlags);
|
||||
FREERDP_API int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32 flags);
|
||||
|
||||
FREERDP_API void ncrush_context_reset(NCRUSH_CONTEXT* ncrush);
|
||||
|
||||
FREERDP_API NCRUSH_CONTEXT* ncrush_context_new(BOOL Compressor);
|
||||
FREERDP_API void ncrush_context_free(NCRUSH_CONTEXT* ncrush);
|
||||
|
||||
|
@ -1115,6 +1115,7 @@ UINT32 LOMBaseLUT[30] =
|
||||
|
||||
int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32 flags)
|
||||
{
|
||||
UINT32 index;
|
||||
UINT32 bits;
|
||||
UINT32 nbits;
|
||||
BYTE* SrcPtr;
|
||||
@ -1125,6 +1126,7 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
UINT32 BitLength;
|
||||
UINT32 MaskedBits;
|
||||
UINT32 CopyOffset;
|
||||
UINT32 CopyLength;
|
||||
UINT32 OldCopyOffset;
|
||||
UINT32 LengthOfMatch;
|
||||
UINT32 CopyOffsetIndex;
|
||||
@ -1132,30 +1134,36 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
BYTE* HistoryPtr;
|
||||
BYTE* HistoryBuffer;
|
||||
BYTE* HistoryBufferEnd;
|
||||
UINT32 HistoryBufferSize;
|
||||
UINT32 CopyOffsetBits = 0;
|
||||
UINT32 CopyOffsetBase = 0;
|
||||
UINT32 LengthOfMatchBits = 0;
|
||||
UINT32 LengthOfMatchBase = 0;
|
||||
BYTE* CopyOffsetPtr = NULL;
|
||||
|
||||
if (ncrush->HistoryEndOffset != 65535)
|
||||
return -1;
|
||||
|
||||
HistoryBuffer = ncrush->HistoryBuffer;
|
||||
HistoryBufferSize = ncrush->HistoryBufferSize;
|
||||
HistoryBufferEnd = &HistoryBuffer[HistoryBufferSize - 1];
|
||||
HistoryBufferEnd = &HistoryBuffer[ncrush->HistoryEndOffset];
|
||||
|
||||
if (flags & PACKET_AT_FRONT)
|
||||
{
|
||||
printf("PACKET_AT_FRONT\n");
|
||||
|
||||
if ((ncrush->HistoryPtr - 32768) <= HistoryBuffer)
|
||||
return -1;
|
||||
|
||||
CopyMemory(HistoryBuffer, (ncrush->HistoryPtr - 32768), 32768);
|
||||
MoveMemory(HistoryBuffer, (ncrush->HistoryPtr - 32768), 32768);
|
||||
ncrush->HistoryPtr = &(HistoryBuffer[32768]);
|
||||
ZeroMemory(&HistoryBuffer[32768], 32768);
|
||||
}
|
||||
|
||||
if (flags & PACKET_FLUSHED)
|
||||
{
|
||||
printf("PACKET_FLUSHED\n");
|
||||
|
||||
ncrush->HistoryPtr = HistoryBuffer;
|
||||
ZeroMemory(HistoryBuffer, ncrush->HistoryBufferSize);
|
||||
ZeroMemory(HistoryBuffer, sizeof(ncrush->HistoryBuffer));
|
||||
ZeroMemory(&(ncrush->OffsetCache), sizeof(ncrush->OffsetCache));
|
||||
}
|
||||
|
||||
@ -1163,6 +1171,8 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
|
||||
if (!(flags & PACKET_COMPRESSED))
|
||||
{
|
||||
printf("PACKET_UNCOMPRESSED\n");
|
||||
|
||||
CopyMemory(HistoryPtr, pSrcData, SrcSize);
|
||||
HistoryPtr += SrcSize;
|
||||
ncrush->HistoryPtr = HistoryPtr;
|
||||
@ -1203,10 +1213,8 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
*HistoryPtr++ = Literal;
|
||||
}
|
||||
|
||||
if (IndexLEC <= 256)
|
||||
{
|
||||
if (IndexLEC == 256)
|
||||
break; /* EOS */
|
||||
}
|
||||
|
||||
CopyOffsetIndex = IndexLEC - 257;
|
||||
|
||||
@ -1238,11 +1246,11 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
Mask = *((UINT16*) &HuffTableMask[(2 * LengthOfMatchBits) + 3]);
|
||||
MaskedBits = bits & Mask;
|
||||
|
||||
LengthOfMatchBase += MaskedBits;
|
||||
|
||||
bits >>= LengthOfMatchBits;
|
||||
nbits -= LengthOfMatchBits;
|
||||
|
||||
LengthOfMatchBase += MaskedBits;
|
||||
|
||||
NCrushFetchBits();
|
||||
}
|
||||
|
||||
@ -1288,11 +1296,11 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
Mask = *((UINT16*) &HuffTableMask[(2 * LengthOfMatchBits) + 3]);
|
||||
MaskedBits = bits & Mask;
|
||||
|
||||
LengthOfMatchBase += MaskedBits;
|
||||
|
||||
bits >>= LengthOfMatchBits;
|
||||
nbits -= LengthOfMatchBits;
|
||||
|
||||
LengthOfMatchBase += MaskedBits;
|
||||
|
||||
NCrushFetchBits();
|
||||
}
|
||||
|
||||
@ -1305,45 +1313,70 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
CopyOffsetPtr = HistoryPtr - CopyOffset;
|
||||
LengthOfMatch = LengthOfMatchBase;
|
||||
|
||||
if ((HistoryPtr >= &HistoryBufferEnd[-LengthOfMatch]) ||
|
||||
(CopyOffsetPtr >= &HistoryBufferEnd[-LengthOfMatch]))
|
||||
{
|
||||
if (HistoryPtr >= &HistoryBufferEnd[-LengthOfMatch])
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (LengthOfMatch < 2)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (LengthOfMatch == 2)
|
||||
|
||||
index = 0;
|
||||
CopyLength = (LengthOfMatch > CopyOffset) ? CopyOffset : LengthOfMatch;
|
||||
|
||||
if (CopyOffsetPtr >= HistoryBuffer)
|
||||
{
|
||||
HistoryPtr[0] = CopyOffsetPtr[0];
|
||||
HistoryPtr[1] = CopyOffsetPtr[1];
|
||||
HistoryPtr += 2;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (LengthOfMatch > 0)
|
||||
while (CopyLength > 0)
|
||||
{
|
||||
*HistoryPtr++ = *CopyOffsetPtr++;
|
||||
CopyLength--;
|
||||
}
|
||||
|
||||
while (LengthOfMatch > CopyOffset)
|
||||
{
|
||||
index = ((index >= CopyOffset)) ? 0 : index;
|
||||
*HistoryPtr++ = *(CopyOffsetPtr + index++);
|
||||
LengthOfMatch--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyOffsetPtr = HistoryBufferEnd - (CopyOffset - (HistoryPtr - HistoryBuffer));
|
||||
CopyOffsetPtr++;
|
||||
|
||||
while (CopyLength && (CopyOffsetPtr <= HistoryBufferEnd))
|
||||
{
|
||||
*HistoryPtr++ = *CopyOffsetPtr++;
|
||||
CopyLength--;
|
||||
}
|
||||
|
||||
CopyOffsetPtr = HistoryBuffer;
|
||||
|
||||
while (LengthOfMatch > CopyOffset)
|
||||
{
|
||||
index = ((index >= CopyOffset)) ? 0 : index;
|
||||
*HistoryPtr++ = *(CopyOffsetPtr + index++);
|
||||
LengthOfMatch--;
|
||||
}
|
||||
}
|
||||
|
||||
LengthOfMatch = LengthOfMatchBase;
|
||||
|
||||
if (LengthOfMatch == 2)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IndexLEC == 256)
|
||||
{
|
||||
*pDstSize = HistoryPtr - ncrush->HistoryPtr;
|
||||
*ppDstData = ncrush->HistoryPtr;
|
||||
ncrush->HistoryPtr = HistoryPtr;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
if (IndexLEC != 256)
|
||||
return -1;
|
||||
|
||||
if (ncrush->HistoryBufferFence != 0xABABABAB)
|
||||
{
|
||||
printf("NCrushDecompress: history buffer fence was overwritten, potential buffer overflow detected\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*pDstSize = HistoryPtr - ncrush->HistoryPtr;
|
||||
*ppDstData = ncrush->HistoryPtr;
|
||||
ncrush->HistoryPtr = HistoryPtr;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1352,6 +1385,15 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ncrush_context_reset(NCRUSH_CONTEXT* ncrush)
|
||||
{
|
||||
ZeroMemory(&(ncrush->HistoryBuffer), sizeof(ncrush->HistoryBuffer));
|
||||
ZeroMemory(&(ncrush->OffsetCache), sizeof(ncrush->OffsetCache));
|
||||
|
||||
ncrush->HistoryOffset = 0;
|
||||
ncrush->HistoryPtr = &(ncrush->HistoryBuffer[ncrush->HistoryOffset]);
|
||||
}
|
||||
|
||||
NCRUSH_CONTEXT* ncrush_context_new(BOOL Compressor)
|
||||
{
|
||||
NCRUSH_CONTEXT* ncrush;
|
||||
@ -1362,10 +1404,12 @@ NCRUSH_CONTEXT* ncrush_context_new(BOOL Compressor)
|
||||
{
|
||||
ncrush->Compressor = Compressor;
|
||||
|
||||
ncrush->HistoryBufferSize = 65536;
|
||||
ZeroMemory(&(ncrush->HistoryBuffer), sizeof(ncrush->HistoryBuffer));
|
||||
ZeroMemory(&(ncrush->OffsetCache), sizeof(ncrush->OffsetCache));
|
||||
|
||||
ncrush->HistoryEndOffset = 65535;
|
||||
ZeroMemory(&(ncrush->HistoryBuffer), sizeof(ncrush->HistoryBuffer));
|
||||
ncrush->HistoryBufferFence = 0xABABABAB;
|
||||
|
||||
ncrush->HistoryOffset = 0;
|
||||
ncrush->HistoryPtr = &(ncrush->HistoryBuffer[ncrush->HistoryOffset]);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
#include "bulk.h"
|
||||
|
||||
//#define WITH_BULK_DEBUG 1
|
||||
#define WITH_BULK_DEBUG 1
|
||||
|
||||
UINT32 bulk_compression_level(rdpBulk* bulk)
|
||||
{
|
||||
@ -42,8 +42,6 @@ UINT32 bulk_compression_max_size(rdpBulk* bulk)
|
||||
int bulk_decompress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32 flags)
|
||||
{
|
||||
int status = -1;
|
||||
UINT32 roff = 0;
|
||||
UINT32 rlen = 0;
|
||||
UINT32 CompressedBytes;
|
||||
UINT32 UncompressedBytes;
|
||||
UINT32 type = flags & 0x0F;
|
||||
@ -61,9 +59,7 @@ int bulk_decompress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstD
|
||||
break;
|
||||
|
||||
case PACKET_COMPR_TYPE_RDP6:
|
||||
status = decompress_rdp_6(bulk->mppc_dec, pSrcData, SrcSize, flags, &roff, &rlen);
|
||||
*ppDstData = (bulk->mppc_dec->history_buf + roff);
|
||||
*pDstSize = rlen;
|
||||
status = ncrush_decompress(bulk->ncrushRecv, pSrcData, SrcSize, ppDstData, pDstSize, flags);
|
||||
break;
|
||||
|
||||
case PACKET_COMPR_TYPE_RDP61:
|
||||
@ -91,10 +87,17 @@ int bulk_decompress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstD
|
||||
CompressionRatio = ((double) CompressedBytes) / ((double) UncompressedBytes);
|
||||
TotalCompressionRatio = ((double) bulk->TotalCompressedBytes) / ((double) bulk->TotalUncompressedBytes);
|
||||
|
||||
printf("Compression Ratio: %f Total: %f\n", CompressionRatio, TotalCompressionRatio);
|
||||
printf("Type: %d Compression Ratio: %f Total: %f %d / %d\n",
|
||||
type, CompressionRatio, TotalCompressionRatio, CompressedBytes, UncompressedBytes);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef WITH_BULK_DEBUG
|
||||
printf("Decompression failure!\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -140,9 +143,7 @@ void bulk_reset(rdpBulk* bulk)
|
||||
{
|
||||
mppc_context_reset(bulk->mppcSend);
|
||||
mppc_context_reset(bulk->mppcRecv);
|
||||
|
||||
mppc_dec_free(bulk->mppc_dec);
|
||||
bulk->mppc_dec = mppc_dec_new();
|
||||
ncrush_context_reset(bulk->ncrushRecv);
|
||||
}
|
||||
|
||||
rdpBulk* bulk_new(rdpContext* context)
|
||||
@ -158,7 +159,7 @@ rdpBulk* bulk_new(rdpContext* context)
|
||||
bulk->mppcSend = mppc_context_new(1, TRUE);
|
||||
bulk->mppcRecv = mppc_context_new(1, FALSE);
|
||||
|
||||
bulk->mppc_dec = mppc_dec_new();
|
||||
bulk->ncrushRecv = ncrush_context_new(FALSE);
|
||||
|
||||
bulk->CompressionLevel = context->settings->CompressionLevel;
|
||||
|
||||
@ -176,7 +177,7 @@ void bulk_free(rdpBulk* bulk)
|
||||
mppc_context_free(bulk->mppcSend);
|
||||
mppc_context_free(bulk->mppcRecv);
|
||||
|
||||
mppc_dec_free(bulk->mppc_dec);
|
||||
ncrush_context_free(bulk->ncrushRecv);
|
||||
|
||||
free(bulk);
|
||||
}
|
||||
|
@ -25,8 +25,7 @@ typedef struct rdp_bulk rdpBulk;
|
||||
#include "rdp.h"
|
||||
|
||||
#include <freerdp/codec/mppc.h>
|
||||
#include <freerdp/codec/mppc_enc.h>
|
||||
#include <freerdp/codec/mppc_dec.h>
|
||||
#include <freerdp/codec/ncrush.h>
|
||||
|
||||
struct rdp_bulk
|
||||
{
|
||||
@ -35,8 +34,8 @@ struct rdp_bulk
|
||||
UINT32 CompressionMaxSize;
|
||||
MPPC_CONTEXT* mppcSend;
|
||||
MPPC_CONTEXT* mppcRecv;
|
||||
NCRUSH_CONTEXT* ncrushRecv;
|
||||
BYTE OutputBuffer[65536];
|
||||
struct rdp_mppc_dec* mppc_dec;
|
||||
|
||||
UINT64 TotalCompressedBytes;
|
||||
UINT64 TotalUncompressedBytes;
|
||||
|
Loading…
Reference in New Issue
Block a user