Fixed endianess issues of zgfx decoder.
This commit is contained in:
parent
a834ef8243
commit
dbdc4f4933
@ -110,17 +110,16 @@ static const ZGFX_TOKEN ZGFX_TOKEN_TABLE[] =
|
|||||||
_zgfx->bits = _zgfx->BitsCurrent >> _zgfx->cBitsCurrent; \
|
_zgfx->bits = _zgfx->BitsCurrent >> _zgfx->cBitsCurrent; \
|
||||||
_zgfx->BitsCurrent &= ((1 << _zgfx->cBitsCurrent) - 1);
|
_zgfx->BitsCurrent &= ((1 << _zgfx->cBitsCurrent) - 1);
|
||||||
|
|
||||||
static void zgfx_history_buffer_ring_write(ZGFX_CONTEXT* zgfx, const BYTE* src, UINT32 count)
|
static void zgfx_history_buffer_ring_write(ZGFX_CONTEXT* zgfx, const BYTE* src, size_t count)
|
||||||
{
|
{
|
||||||
UINT32 front;
|
UINT32 front;
|
||||||
UINT32 residue;
|
|
||||||
|
|
||||||
if (count <= 0)
|
if (count <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (count > zgfx->HistoryBufferSize)
|
if (count > zgfx->HistoryBufferSize)
|
||||||
{
|
{
|
||||||
residue = count - zgfx->HistoryBufferSize;
|
const size_t residue = count - zgfx->HistoryBufferSize;
|
||||||
count = zgfx->HistoryBufferSize;
|
count = zgfx->HistoryBufferSize;
|
||||||
src += residue;
|
src += residue;
|
||||||
zgfx->HistoryIndex = (zgfx->HistoryIndex + residue) % zgfx->HistoryBufferSize;
|
zgfx->HistoryIndex = (zgfx->HistoryIndex + residue) % zgfx->HistoryBufferSize;
|
||||||
@ -190,7 +189,7 @@ static void zgfx_history_buffer_ring_read(ZGFX_CONTEXT* zgfx, int offset, BYTE*
|
|||||||
while ((bytesLeft -= bytes) > 0);
|
while ((bytesLeft -= bytes) > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, const BYTE* pbSegment, UINT32 cbSegment)
|
static BOOL zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, wStream* stream, size_t segmentSize)
|
||||||
{
|
{
|
||||||
BYTE c;
|
BYTE c;
|
||||||
BYTE flags;
|
BYTE flags;
|
||||||
@ -200,21 +199,23 @@ static int zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, const BYTE* pbSegment, UI
|
|||||||
int inPrefix;
|
int inPrefix;
|
||||||
UINT32 count;
|
UINT32 count;
|
||||||
UINT32 distance;
|
UINT32 distance;
|
||||||
|
BYTE* pbSegment;
|
||||||
|
size_t cbSegment = segmentSize - 1;
|
||||||
|
|
||||||
if (cbSegment < 1)
|
if ((Stream_GetRemainingLength(stream) < segmentSize) || (segmentSize < 1))
|
||||||
return -1;
|
return FALSE;
|
||||||
|
|
||||||
flags = pbSegment[0]; /* header (1 byte) */
|
Stream_Read_UINT8(stream, flags); /* header (1 byte) */
|
||||||
pbSegment++;
|
|
||||||
cbSegment--;
|
|
||||||
zgfx->OutputCount = 0;
|
zgfx->OutputCount = 0;
|
||||||
|
pbSegment = Stream_Pointer(stream);
|
||||||
|
Stream_Seek(stream, cbSegment);
|
||||||
|
|
||||||
if (!(flags & PACKET_COMPRESSED))
|
if (!(flags & PACKET_COMPRESSED))
|
||||||
{
|
{
|
||||||
zgfx_history_buffer_ring_write(zgfx, pbSegment, cbSegment);
|
zgfx_history_buffer_ring_write(zgfx, pbSegment, cbSegment);
|
||||||
CopyMemory(zgfx->OutputBuffer, pbSegment, cbSegment);
|
CopyMemory(zgfx->OutputBuffer, pbSegment, cbSegment);
|
||||||
zgfx->OutputCount = cbSegment;
|
zgfx->OutputCount = cbSegment;
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
zgfx->pbInputCurrent = pbSegment;
|
zgfx->pbInputCurrent = pbSegment;
|
||||||
@ -308,31 +309,30 @@ static int zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, const BYTE* pbSegment, UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData,
|
int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData,
|
||||||
UINT32* pDstSize, UINT32 flags)
|
UINT32* pDstSize, UINT32 flags)
|
||||||
{
|
{
|
||||||
int status;
|
int status = -1;
|
||||||
BYTE descriptor;
|
BYTE descriptor;
|
||||||
|
wStream* stream = Stream_New((BYTE*)pSrcData, SrcSize);
|
||||||
|
|
||||||
if (SrcSize < 1)
|
if (Stream_GetRemainingLength(stream) < 1)
|
||||||
return -1;
|
goto fail;
|
||||||
|
|
||||||
descriptor = pSrcData[0]; /* descriptor (1 byte) */
|
Stream_Read_UINT8(stream, descriptor); /* descriptor (1 byte) */
|
||||||
|
|
||||||
if (descriptor == ZGFX_SEGMENTED_SINGLE)
|
if (descriptor == ZGFX_SEGMENTED_SINGLE)
|
||||||
{
|
{
|
||||||
status = zgfx_decompress_segment(zgfx, &pSrcData[1], SrcSize - 1);
|
if (!zgfx_decompress_segment(zgfx, stream, Stream_GetRemainingLength(stream)))
|
||||||
|
goto fail;
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
*ppDstData = (BYTE*) malloc(zgfx->OutputCount);
|
*ppDstData = (BYTE*) malloc(zgfx->OutputCount);
|
||||||
|
|
||||||
if (!*ppDstData)
|
if (!*ppDstData)
|
||||||
return -1;
|
goto fail;
|
||||||
|
|
||||||
*pDstSize = zgfx->OutputCount;
|
*pDstSize = zgfx->OutputCount;
|
||||||
CopyMemory(*ppDstData, zgfx->OutputBuffer, zgfx->OutputCount);
|
CopyMemory(*ppDstData, zgfx->OutputBuffer, zgfx->OutputCount);
|
||||||
@ -346,52 +346,63 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
|
|||||||
UINT32 uncompressedSize;
|
UINT32 uncompressedSize;
|
||||||
BYTE* pConcatenated;
|
BYTE* pConcatenated;
|
||||||
segmentOffset = 7;
|
segmentOffset = 7;
|
||||||
segmentCount = *((UINT16*) &pSrcData[1]); /* segmentCount (2 bytes) */
|
|
||||||
uncompressedSize = *((UINT32*) &pSrcData[3]); /* uncompressedSize (4 bytes) */
|
if (Stream_GetRemainingLength(stream) < 6)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
Stream_Read_UINT16(stream, segmentCount); /* segmentCount (2 bytes) */
|
||||||
|
Stream_Read_UINT32(stream, uncompressedSize); /* uncompressedSize (4 bytes) */
|
||||||
|
|
||||||
|
if (Stream_GetRemainingLength(stream) < segmentCount * sizeof(UINT32))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
pConcatenated = (BYTE*) malloc(uncompressedSize);
|
pConcatenated = (BYTE*) malloc(uncompressedSize);
|
||||||
|
|
||||||
if (!pConcatenated)
|
if (!pConcatenated)
|
||||||
return -1;
|
goto fail;
|
||||||
|
|
||||||
*ppDstData = pConcatenated;
|
*ppDstData = pConcatenated;
|
||||||
*pDstSize = uncompressedSize;
|
*pDstSize = uncompressedSize;
|
||||||
|
|
||||||
for (segmentNumber = 0; segmentNumber < segmentCount; segmentNumber++)
|
for (segmentNumber = 0; segmentNumber < segmentCount; segmentNumber++)
|
||||||
{
|
{
|
||||||
segmentSize = *((UINT32*) &pSrcData[segmentOffset]); /* segmentSize (4 bytes) */
|
if (Stream_GetRemainingLength(stream) < sizeof(UINT32))
|
||||||
segmentOffset += 4;
|
goto fail;
|
||||||
status = zgfx_decompress_segment(zgfx, &pSrcData[segmentOffset], segmentSize);
|
|
||||||
|
|
||||||
if (status < 0)
|
Stream_Read_UINT32(stream, segmentSize); /* segmentSize (4 bytes) */
|
||||||
return status;
|
|
||||||
|
if (!zgfx_decompress_segment(zgfx, stream, segmentSize))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
segmentOffset += segmentSize;
|
|
||||||
CopyMemory(pConcatenated, zgfx->OutputBuffer, zgfx->OutputCount);
|
CopyMemory(pConcatenated, zgfx->OutputBuffer, zgfx->OutputCount);
|
||||||
pConcatenated += zgfx->OutputCount;
|
pConcatenated += zgfx->OutputCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return -1;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
status = 1;
|
||||||
|
fail:
|
||||||
|
Stream_Free(stream, FALSE);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zgfx_compress_segment(ZGFX_CONTEXT* zgfx, wStream* s, const BYTE* pSrcData,
|
static BOOL zgfx_compress_segment(ZGFX_CONTEXT* zgfx, wStream* s, const BYTE* pSrcData,
|
||||||
UINT32 SrcSize, UINT32* pFlags)
|
UINT32 SrcSize, UINT32* pFlags)
|
||||||
{
|
{
|
||||||
/* FIXME: Currently compression not implemented. Just copy the raw source */
|
/* FIXME: Currently compression not implemented. Just copy the raw source */
|
||||||
if (!Stream_EnsureRemainingCapacity(s, SrcSize + 1))
|
if (!Stream_EnsureRemainingCapacity(s, SrcSize + 1))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*pFlags) |= ZGFX_PACKET_COMPR_TYPE_RDP8; /* RDP 8.0 compression format */
|
(*pFlags) |= ZGFX_PACKET_COMPR_TYPE_RDP8; /* RDP 8.0 compression format */
|
||||||
Stream_Write_UINT8(s, (*pFlags)); /* header (1 byte) */
|
Stream_Write_UINT8(s, (*pFlags)); /* header (1 byte) */
|
||||||
Stream_Write(s, pSrcData, SrcSize);
|
Stream_Write(s, pSrcData, SrcSize);
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zgfx_compress_to_stream(ZGFX_CONTEXT* zgfx, wStream* sDst, const BYTE* pUncompressed,
|
int zgfx_compress_to_stream(ZGFX_CONTEXT* zgfx, wStream* sDst, const BYTE* pUncompressed,
|
||||||
@ -448,10 +459,8 @@ int zgfx_compress_to_stream(ZGFX_CONTEXT* zgfx, wStream* sDst, const BYTE* pUnco
|
|||||||
|
|
||||||
posDataStart = Stream_GetPosition(sDst);
|
posDataStart = Stream_GetPosition(sDst);
|
||||||
|
|
||||||
if ((status = zgfx_compress_segment(zgfx, sDst, pSrcData, SrcSize, pFlags)) < 0)
|
if (!zgfx_compress_segment(zgfx, sDst, pSrcData, SrcSize, pFlags))
|
||||||
{
|
return -1;
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (posDstSize)
|
if (posDstSize)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user