From 88bee1fa6d7b057ef5d2e494643c8fd219c6e132 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 5 May 2014 20:47:30 -0400 Subject: [PATCH] libfreerdp-codec: start working on xcrush compressor --- include/freerdp/codec/xcrush.h | 1 + libfreerdp/codec/xcrush.c | 122 +++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) diff --git a/include/freerdp/codec/xcrush.h b/include/freerdp/codec/xcrush.h index cbe1a898e..180b35aea 100644 --- a/include/freerdp/codec/xcrush.h +++ b/include/freerdp/codec/xcrush.h @@ -51,6 +51,7 @@ struct _XCRUSH_CONTEXT UINT32 HistoryOffset; UINT32 HistoryBufferSize; BYTE HistoryBuffer[2000000]; + BYTE BlockBuffer[16384]; }; typedef struct _XCRUSH_CONTEXT XCRUSH_CONTEXT; diff --git a/libfreerdp/codec/xcrush.c b/libfreerdp/codec/xcrush.c index 9b7f66d62..e36b01f01 100644 --- a/libfreerdp/codec/xcrush.c +++ b/libfreerdp/codec/xcrush.c @@ -190,8 +190,130 @@ int xcrush_decompress(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, BY return status; } +int xcrush_compress_l1(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags) +{ + UINT32 Flags = 0; + UINT32 HistoryOffset = 0; + BYTE* HistoryPtr = NULL; + BYTE* HistoryBuffer = NULL; + + HistoryOffset = xcrush->HistoryOffset; + HistoryBuffer = xcrush->HistoryBuffer; + HistoryPtr = &HistoryBuffer[HistoryOffset]; + + CopyMemory(HistoryPtr, pSrcData, SrcSize); + xcrush->HistoryOffset += SrcSize; + + if (SrcSize <= 50) + { + Flags |= L1_NO_COMPRESSION; + } + else + { + + } + + *pFlags = Flags; + + return 1; +} + int xcrush_compress(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32* pFlags) { + int status = 0; + UINT32 DstSize = 0; + BYTE* pDstData = NULL; + BYTE* CompressedData = NULL; + UINT32 CompressedDataSize = 0; + BYTE* OriginalData = NULL; + UINT32 OriginalDataSize = 0; + UINT32 Level1ComprFlags = 0; + UINT32 Level2ComprFlags = 0; + UINT32 CompressionLevel = 3; + + if (SrcSize > 16384) + return -1; + + if ((SrcSize + 2) > *pDstSize) + return -1; + + OriginalData = pDstData; + OriginalDataSize = *pDstSize; + + pDstData = xcrush->BlockBuffer; + DstSize = sizeof(xcrush->BlockBuffer); + + status = xcrush_compress_l1(xcrush, pSrcData, SrcSize, &pDstData, &DstSize, &Level1ComprFlags); + + if (status < 0) + return status; + + if (Level1ComprFlags & L1_COMPRESSED) + { + CompressedData = pDstData; + CompressedDataSize = DstSize; + + if (CompressedDataSize > SrcSize) + return -1; + } + else + { + CompressedData = pSrcData; + CompressedDataSize = DstSize; + + if (CompressedDataSize != SrcSize) + return -1; + } + + status = 1; + + pDstData = OriginalData + 2; + DstSize = OriginalDataSize - 2; + + if (DstSize > 50) + { + status = mppc_compress(xcrush->mppc, CompressedData, CompressedDataSize, &pDstData, &DstSize, &Level2ComprFlags); + } + + if (status < 0) + return status; + + if (!(Level2ComprFlags & PACKET_COMPRESSED) || (Level2ComprFlags & PACKET_FLUSHED)) + { + if (CompressedDataSize > DstSize) + return -1; + + DstSize = CompressedDataSize; + CopyMemory(pDstData, CompressedData, CompressedDataSize); + } + + if (Level2ComprFlags & PACKET_COMPRESSED) + { + + } + else + { + if (Level2ComprFlags & PACKET_FLUSHED) + { + + } + else + { + + } + } + + Level1ComprFlags |= L1_INNER_COMPRESSION; + + OriginalData[0] = (BYTE) Level1ComprFlags; + OriginalData[1] = (BYTE) Level2ComprFlags; + + if (*pDstSize < (DstSize + 2)) + return -1; + + *pDstSize = DstSize + 2; + *pFlags = PACKET_COMPRESSED | CompressionLevel; + return 1; }