mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2024-11-27 11:54:44 +08:00
libfreerdp-codec: produce correct LOM/CO sequences
This commit is contained in:
parent
dbe7e7aae2
commit
cea902deb8
@ -23,9 +23,12 @@
|
|||||||
#include <freerdp/api.h>
|
#include <freerdp/api.h>
|
||||||
#include <freerdp/types.h>
|
#include <freerdp/types.h>
|
||||||
|
|
||||||
|
#include <winpr/collections.h>
|
||||||
|
|
||||||
struct _MPPC_CONTEXT
|
struct _MPPC_CONTEXT
|
||||||
{
|
{
|
||||||
DWORD Flags;
|
DWORD Flags;
|
||||||
|
wBitStream* bs;
|
||||||
BOOL Compressor;
|
BOOL Compressor;
|
||||||
DWORD HistoryPtr;
|
DWORD HistoryPtr;
|
||||||
BYTE* pHistoryPtr;
|
BYTE* pHistoryPtr;
|
||||||
|
@ -23,12 +23,16 @@
|
|||||||
|
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
#include <winpr/print.h>
|
#include <winpr/print.h>
|
||||||
|
#include <winpr/collections.h>
|
||||||
|
|
||||||
#include <freerdp/codec/mppc_enc.h>
|
#include <freerdp/codec/mppc_enc.h>
|
||||||
#include <freerdp/codec/mppc_dec.h>
|
#include <freerdp/codec/mppc_dec.h>
|
||||||
|
|
||||||
#include <freerdp/codec/mppc.h>
|
#include <freerdp/codec/mppc.h>
|
||||||
|
|
||||||
|
#define MPPC_MATCH_INDEX(_sym1, _sym2, _sym3) \
|
||||||
|
((((MPPC_MATCH_TABLE[_sym3] << 16) + (MPPC_MATCH_TABLE[_sym2] << 8) + MPPC_MATCH_TABLE[_sym1]) & 0x07FFF000) >> 12)
|
||||||
|
|
||||||
const UINT32 MPPC_MATCH_TABLE[256] =
|
const UINT32 MPPC_MATCH_TABLE[256] =
|
||||||
{
|
{
|
||||||
0x00000000, 0x009CCF93, 0x01399F26, 0x01D66EB9, 0x02733E4C, 0x03100DDF, 0x03ACDD72, 0x0449AD05,
|
0x00000000, 0x009CCF93, 0x01399F26, 0x01D66EB9, 0x02733E4C, 0x03100DDF, 0x03ACDD72, 0x0449AD05,
|
||||||
@ -70,8 +74,10 @@ int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, int size)
|
|||||||
DWORD Flags = 0;
|
DWORD Flags = 0;
|
||||||
BYTE* pMatch;
|
BYTE* pMatch;
|
||||||
DWORD MatchIndex;
|
DWORD MatchIndex;
|
||||||
|
UINT32 accumulator;
|
||||||
BYTE* pEnd;
|
BYTE* pEnd;
|
||||||
//BYTE* OutputBuffer = pDstData;
|
|
||||||
|
BitStream_Attach(mppc->bs, pDstData, size);
|
||||||
|
|
||||||
if (((mppc->HistoryOffset + size) < (mppc->HistoryBufferSize - 3)) /* && mppc->HistoryOffset */)
|
if (((mppc->HistoryOffset + size) < (mppc->HistoryBufferSize - 3)) /* && mppc->HistoryOffset */)
|
||||||
{
|
{
|
||||||
@ -108,27 +114,32 @@ int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, int size)
|
|||||||
|
|
||||||
pEnd = &(mppc->HistoryBuffer[size - 1]);
|
pEnd = &(mppc->HistoryBuffer[size - 1]);
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
while (mppc->pHistoryPtr < (pEnd - 2))
|
while (mppc->pHistoryPtr < (pEnd - 2))
|
||||||
{
|
{
|
||||||
MatchIndex = ((((MPPC_MATCH_TABLE[mppc->pHistoryPtr[2]] << 16) +
|
MatchIndex = MPPC_MATCH_INDEX(mppc->pHistoryPtr[0], mppc->pHistoryPtr[1], mppc->pHistoryPtr[2]);
|
||||||
(MPPC_MATCH_TABLE[mppc->pHistoryPtr[1]] << 8) +
|
|
||||||
MPPC_MATCH_TABLE[mppc->pHistoryPtr[0]]) & 0x07FFF000) >> 12);
|
|
||||||
|
|
||||||
pMatch = &(mppc->HistoryBuffer[mppc->MatchBuffer[MatchIndex]]);
|
pMatch = &(mppc->HistoryBuffer[mppc->MatchBuffer[MatchIndex]]);
|
||||||
|
|
||||||
mppc->MatchBuffer[MatchIndex] = (UINT16) mppc->HistoryPtr;
|
mppc->MatchBuffer[MatchIndex] = (UINT16) mppc->HistoryPtr;
|
||||||
|
|
||||||
printf("[%d] MatchIndex: %d pMatch: %p pHistoryPtr: %p HistoryPtr: %d\n",
|
if ((mppc->pHistoryPtr[0] != pMatch[0]) || (mppc->pHistoryPtr[1] != pMatch[1]) ||
|
||||||
index, (int) MatchIndex, pMatch, mppc->pHistoryPtr, (int) mppc->HistoryPtr);
|
(mppc->pHistoryPtr[2] != pMatch[2]) || (mppc->pHistoryPtr == pMatch))
|
||||||
|
|
||||||
if ((mppc->pHistoryPtr[0] != pMatch[0]) || (mppc->pHistoryPtr[1] != pMatch[1])
|
|
||||||
|| (mppc->pHistoryPtr[2] != pMatch[2]) || (mppc->pHistoryPtr == pMatch))
|
|
||||||
{
|
{
|
||||||
printf("no match: %c%c%c %c%c%c\n",
|
accumulator = *(mppc->pHistoryPtr);
|
||||||
mppc->pHistoryPtr[0], mppc->pHistoryPtr[1], mppc->pHistoryPtr[2],
|
|
||||||
pMatch[0], pMatch[1], pMatch[2]);
|
printf("%c", accumulator);
|
||||||
|
|
||||||
|
if (accumulator < 0x80)
|
||||||
|
{
|
||||||
|
/* 8 bits of literal are encoded as-is */
|
||||||
|
BitStream_Write_Bits(mppc->bs, accumulator, 8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* bits 10 followed by lower 7 bits of literal */
|
||||||
|
accumulator = 0x100 | (accumulator & 0x7F);
|
||||||
|
BitStream_Write_Bits(mppc->bs, accumulator, 9);
|
||||||
|
}
|
||||||
|
|
||||||
mppc->HistoryPtr++;
|
mppc->HistoryPtr++;
|
||||||
mppc->pHistoryPtr = &(mppc->HistoryBuffer[mppc->HistoryPtr]);
|
mppc->pHistoryPtr = &(mppc->HistoryBuffer[mppc->HistoryPtr]);
|
||||||
@ -136,25 +147,56 @@ int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, BYTE* pDstData, int size)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
DWORD CopyOffset;
|
DWORD CopyOffset;
|
||||||
DWORD LengthOfMatch = 3;
|
DWORD LengthOfMatch = 1;
|
||||||
|
|
||||||
CopyOffset = (DWORD) (mppc->pHistoryPtr - pMatch);
|
CopyOffset = (DWORD) (mppc->pHistoryPtr - pMatch);
|
||||||
|
|
||||||
while ((mppc->pHistoryPtr[LengthOfMatch] == pMatch[LengthOfMatch]) &&
|
while ((mppc->pHistoryPtr[LengthOfMatch] == pMatch[LengthOfMatch]) &&
|
||||||
((mppc->HistoryPtr + LengthOfMatch) < (size - 1)))
|
((mppc->HistoryPtr + LengthOfMatch) < (size - 1)))
|
||||||
{
|
{
|
||||||
|
MatchIndex = MPPC_MATCH_INDEX(mppc->pHistoryPtr[LengthOfMatch],
|
||||||
|
mppc->pHistoryPtr[LengthOfMatch + 1], mppc->pHistoryPtr[LengthOfMatch + 2]);
|
||||||
|
|
||||||
|
mppc->MatchBuffer[MatchIndex] = (UINT16) (mppc->HistoryPtr + LengthOfMatch);
|
||||||
|
|
||||||
LengthOfMatch++;
|
LengthOfMatch++;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("MATCH: <%d, %d> %.*s\n",
|
printf("<%d,%d>", (int) CopyOffset, (int) LengthOfMatch);
|
||||||
(int) CopyOffset, (int) LengthOfMatch,
|
|
||||||
(int) LengthOfMatch, pMatch);
|
|
||||||
|
|
||||||
mppc->HistoryPtr += LengthOfMatch;
|
mppc->HistoryPtr += LengthOfMatch;
|
||||||
mppc->pHistoryPtr = &(mppc->HistoryBuffer[mppc->HistoryPtr]);
|
mppc->pHistoryPtr = &(mppc->HistoryBuffer[mppc->HistoryPtr]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
index++;
|
/* Encode trailing symbols as literals */
|
||||||
|
|
||||||
|
while (mppc->pHistoryPtr <= pEnd)
|
||||||
|
{
|
||||||
|
MatchIndex = MPPC_MATCH_INDEX(mppc->pHistoryPtr[0], mppc->pHistoryPtr[1], mppc->pHistoryPtr[2]);
|
||||||
|
|
||||||
|
pMatch = &(mppc->HistoryBuffer[mppc->MatchBuffer[MatchIndex]]);
|
||||||
|
|
||||||
|
mppc->MatchBuffer[MatchIndex] = (UINT16) mppc->HistoryPtr;
|
||||||
|
|
||||||
|
accumulator = *(mppc->pHistoryPtr);
|
||||||
|
|
||||||
|
printf("%c", accumulator);
|
||||||
|
|
||||||
|
if (accumulator < 0x80)
|
||||||
|
{
|
||||||
|
/* 8 bits of literal are encoded as-is */
|
||||||
|
BitStream_Write_Bits(mppc->bs, accumulator, 8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* bits 10 followed by lower 7 bits of literal */
|
||||||
|
accumulator = 0x100 | (accumulator & 0x7F);
|
||||||
|
BitStream_Write_Bits(mppc->bs, accumulator, 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
mppc->HistoryPtr++;
|
||||||
|
mppc->pHistoryPtr = &(mppc->HistoryBuffer[mppc->HistoryPtr]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -193,6 +235,8 @@ MPPC_CONTEXT* mppc_context_new(DWORD CompressionLevel, BOOL Compressor)
|
|||||||
|
|
||||||
ZeroMemory(&(mppc->HistoryBuffer), sizeof(mppc->HistoryBuffer));
|
ZeroMemory(&(mppc->HistoryBuffer), sizeof(mppc->HistoryBuffer));
|
||||||
ZeroMemory(&(mppc->MatchBuffer), sizeof(mppc->MatchBuffer));
|
ZeroMemory(&(mppc->MatchBuffer), sizeof(mppc->MatchBuffer));
|
||||||
|
|
||||||
|
mppc->bs = BitStream_New();
|
||||||
}
|
}
|
||||||
|
|
||||||
return mppc;
|
return mppc;
|
||||||
@ -202,6 +246,8 @@ void mppc_context_free(MPPC_CONTEXT* mppc)
|
|||||||
{
|
{
|
||||||
if (mppc)
|
if (mppc)
|
||||||
{
|
{
|
||||||
|
BitStream_Free(mppc->bs);
|
||||||
|
|
||||||
free(mppc);
|
free(mppc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -701,6 +701,7 @@ int TestFreeRDPCodecMppc(int argc, char* argv[])
|
|||||||
printf("%s\n", pSrcData);
|
printf("%s\n", pSrcData);
|
||||||
|
|
||||||
mppc_compress(mppc, pSrcData, OutputBuffer, size);
|
mppc_compress(mppc, pSrcData, OutputBuffer, size);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
mppc_context_free(mppc);
|
mppc_context_free(mppc);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user