remotefx: don't require data messages to come all in one chunk

The spec doesn't require that FRAME_BEGIN, REGION, TILESET, and FRAME_END come all in one
chunk. This patch adds the necessary state saving.
A unitary test is also added.
This commit is contained in:
David Fort 2018-11-30 11:37:23 +01:00
parent 4108fc51a9
commit 579a13b054
4 changed files with 371 additions and 346 deletions

View File

@ -155,6 +155,8 @@ struct _RFX_CONTEXT
/* decoded header blocks */
UINT32 decodedHeaderBlocks;
UINT16 expectedDataBlockType;
RFX_MESSAGE currentMessage;
/* routines */
void (*quantization_decode)(INT16* buffer, const UINT32* quantization_values);

View File

@ -82,27 +82,20 @@ static const UINT32 rfx_default_quantization_values[] =
static void rfx_profiler_create(RFX_CONTEXT* context)
{
PROFILER_CREATE(context->priv->prof_rfx_decode_rgb, "rfx_decode_rgb")
PROFILER_CREATE(context->priv->prof_rfx_decode_component,
"rfx_decode_component")
PROFILER_CREATE(context->priv->prof_rfx_decode_component, "rfx_decode_component")
PROFILER_CREATE(context->priv->prof_rfx_rlgr_decode, "rfx_rlgr_decode")
PROFILER_CREATE(context->priv->prof_rfx_differential_decode,
"rfx_differential_decode")
PROFILER_CREATE(context->priv->prof_rfx_quantization_decode,
"rfx_quantization_decode")
PROFILER_CREATE(context->priv->prof_rfx_differential_decode, "rfx_differential_decode")
PROFILER_CREATE(context->priv->prof_rfx_quantization_decode, "rfx_quantization_decode")
PROFILER_CREATE(context->priv->prof_rfx_dwt_2d_decode, "rfx_dwt_2d_decode")
PROFILER_CREATE(context->priv->prof_rfx_ycbcr_to_rgb, "prims->yCbCrToRGB")
PROFILER_CREATE(context->priv->prof_rfx_encode_rgb, "rfx_encode_rgb")
PROFILER_CREATE(context->priv->prof_rfx_encode_component,
"rfx_encode_component")
PROFILER_CREATE(context->priv->prof_rfx_encode_component, "rfx_encode_component")
PROFILER_CREATE(context->priv->prof_rfx_rlgr_encode, "rfx_rlgr_encode")
PROFILER_CREATE(context->priv->prof_rfx_differential_encode,
"rfx_differential_encode")
PROFILER_CREATE(context->priv->prof_rfx_quantization_encode,
"rfx_quantization_encode")
PROFILER_CREATE(context->priv->prof_rfx_differential_encode, "rfx_differential_encode")
PROFILER_CREATE(context->priv->prof_rfx_quantization_encode, "rfx_quantization_encode")
PROFILER_CREATE(context->priv->prof_rfx_dwt_2d_encode, "rfx_dwt_2d_encode")
PROFILER_CREATE(context->priv->prof_rfx_rgb_to_ycbcr, "prims->RGBToYCbCr")
PROFILER_CREATE(context->priv->prof_rfx_encode_format_rgb,
"rfx_encode_format_rgb")
PROFILER_CREATE(context->priv->prof_rfx_encode_format_rgb, "rfx_encode_format_rgb")
}
static void rfx_profiler_free(RFX_CONTEXT* context)
@ -220,6 +213,7 @@ RFX_CONTEXT* rfx_context_new(BOOL encoder)
return NULL;
context->encoder = encoder;
context->currentMessage.freeArray = TRUE;
context->priv = priv = (RFX_CONTEXT_PRIV*)calloc(1, sizeof(RFX_CONTEXT_PRIV));
if (!priv)
@ -341,6 +335,7 @@ RFX_CONTEXT* rfx_context_new(BOOL encoder)
context->rlgr_encode = rfx_rlgr_encode;
RFX_INIT_SIMD(context);
context->state = RFX_STATE_SEND_HEADERS;
context->expectedDataBlockType = WBT_FRAME_BEGIN;
return context;
error_threadPool_minimum:
CloseThreadpool(priv->ThreadPool);
@ -367,6 +362,7 @@ void rfx_context_free(RFX_CONTEXT* context)
assert(NULL != context->priv->TilePool);
assert(NULL != context->priv->BufferPool);
priv = context->priv;
rfx_message_free(context, &context->currentMessage);
free(context->quants);
ObjectPool_Free(priv->TilePool);
rfx_profiler_print(context);
@ -413,6 +409,7 @@ BOOL rfx_context_reset(RFX_CONTEXT* context, UINT32 width, UINT32 height)
context->width = width;
context->height = height;
context->state = RFX_STATE_SEND_HEADERS;
context->expectedDataBlockType = WBT_FRAME_BEGIN;
context->frameIdx = 0;
return TRUE;
}
@ -430,16 +427,13 @@ static BOOL rfx_process_message_sync(RFX_CONTEXT* context, wStream* s)
}
Stream_Read_UINT32(s, magic); /* magic (4 bytes), 0xCACCACCA */
if (magic != WF_MAGIC)
{
WLog_ERR(TAG, "invalid magic number 0x%08"PRIX32"", magic);
return FALSE;
}
Stream_Read_UINT16(s,
context->version); /* version (2 bytes), WF_VERSION_1_0 (0x0100) */
Stream_Read_UINT16(s, context->version); /* version (2 bytes), WF_VERSION_1_0 (0x0100) */
if (context->version != WF_VERSION_1_0)
{
WLog_ERR(TAG, "invalid version number 0x%08"PRIX32"", context->version);
@ -463,10 +457,8 @@ static BOOL rfx_process_message_codec_versions(RFX_CONTEXT* context, wStream* s)
}
Stream_Read_UINT8(s, numCodecs); /* numCodecs (1 byte), must be set to 0x01 */
Stream_Read_UINT8(s,
context->codec_id); /* codecId (1 byte), must be set to 0x01 */
Stream_Read_UINT16(s,
context->codec_version); /* version (2 bytes), must be set to WF_VERSION_1_0 (0x0100) */
Stream_Read_UINT8(s, context->codec_id); /* codecId (1 byte), must be set to 0x01 */
Stream_Read_UINT16(s, context->codec_version); /* version (2 bytes), must be set to WF_VERSION_1_0 (0x0100) */
if (numCodecs != 1)
{
@ -505,8 +497,7 @@ static BOOL rfx_process_message_channels(RFX_CONTEXT* context, wStream* s)
return FALSE;
}
Stream_Read_UINT8(s,
numChannels); /* numChannels (1 byte), must bet set to 0x01 */
Stream_Read_UINT8(s, numChannels); /* numChannels (1 byte), must bet set to 0x01 */
/* In RDVH sessions, numChannels will represent the number of virtual monitors
* configured and does not always be set to 0x01 as [MS-RDPRFX] said.
@ -565,8 +556,7 @@ static BOOL rfx_process_message_context(RFX_CONTEXT* context, wStream* s)
}
Stream_Read_UINT8(s, ctxId); /* ctxId (1 byte), must be set to 0x00 */
Stream_Read_UINT16(s,
tileSize); /* tileSize (2 bytes), must be set to CT_TILE_64x64 (0x0040) */
Stream_Read_UINT16(s, tileSize); /* tileSize (2 bytes), must be set to CT_TILE_64x64 (0x0040) */
Stream_Read_UINT16(s, properties); /* properties (2 bytes) */
WLog_Print(context->priv->log, WLOG_DEBUG,
"ctxId %"PRIu8" tileSize %"PRIu16" properties 0x%04"PRIX16".",
@ -612,7 +602,7 @@ static BOOL rfx_process_message_frame_begin(RFX_CONTEXT* context,
if (*pExpectedBlockType != WBT_FRAME_BEGIN)
{
WLog_ERR(TAG, "%s: message unexpeced", __FUNCTION__);
WLog_ERR(TAG, "%s: message unexpected wants WBT_FRAME_BEGIN", __FUNCTION__);
return FALSE;
}
@ -624,8 +614,7 @@ static BOOL rfx_process_message_frame_begin(RFX_CONTEXT* context,
return FALSE;
}
Stream_Read_UINT32(s,
frameIdx); /* frameIdx (4 bytes), if codec is in video mode, must be ignored */
Stream_Read_UINT32(s, frameIdx); /* frameIdx (4 bytes), if codec is in video mode, must be ignored */
Stream_Read_UINT16(s, numRegions); /* numRegions (2 bytes) */
WLog_Print(context->priv->log, WLOG_DEBUG,
"RFX_FRAME_BEGIN: frameIdx: %"PRIu32" numRegions: %"PRIu16"", frameIdx, numRegions);
@ -637,7 +626,7 @@ static BOOL rfx_process_message_frame_end(RFX_CONTEXT* context,
{
if (*pExpectedBlockType != WBT_FRAME_END)
{
WLog_ERR(TAG, "%s: message unexpeced", __FUNCTION__);
WLog_ERR(TAG, "%s: message unexpected, wants WBT_FRAME_END", __FUNCTION__);
return FALSE;
}
@ -652,10 +641,11 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context,
int i;
UINT16 regionType;
UINT16 numTileSets;
RFX_RECT *tmpRects;
if (*pExpectedBlockType != WBT_REGION)
{
WLog_ERR(TAG, "%s: message unexpeced", __FUNCTION__);
WLog_ERR(TAG, "%s: message unexpected wants WBT_REGION", __FUNCTION__);
return FALSE;
}
@ -678,10 +668,12 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context,
See [MS-RDPRFX] (revision >= 17.0) 2.2.2.3.3 TS_RFX_REGION
https://msdn.microsoft.com/en-us/library/ff635233.aspx
*/
if (!(message->rects = (RFX_RECT*) malloc(sizeof(RFX_RECT))))
tmpRects = realloc(message->rects, sizeof(RFX_RECT));
if (!tmpRects)
return FALSE;
message->numRects = 1;
message->rects = tmpRects;
message->rects->x = 0;
message->rects->y = 0;
message->rects->width = context->width;
@ -696,8 +688,10 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context,
return FALSE;
}
if (!(message->rects = (RFX_RECT*) calloc(message->numRects, sizeof(RFX_RECT))))
tmpRects = realloc(message->rects, message->numRects * sizeof(RFX_RECT));
if (!tmpRects)
return FALSE;
message->rects = tmpRects;
/* rects */
for (i = 0; i < message->numRects; i++)
@ -720,10 +714,8 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context,
return FALSE;
}
Stream_Read_UINT16(s,
regionType); /* regionType (2 bytes): MUST be set to CBT_REGION (0xCAC1) */
Stream_Read_UINT16(s,
numTileSets); /* numTilesets (2 bytes): MUST be set to 0x0001. */
Stream_Read_UINT16(s, regionType); /*regionType (2 bytes): MUST be set to CBT_REGION (0xCAC1)*/
Stream_Read_UINT16(s, numTileSets); /*numTilesets (2 bytes): MUST be set to 0x0001.*/
if (regionType != CBT_REGION)
{
@ -756,15 +748,16 @@ static void CALLBACK rfx_process_message_tile_work_callback(
}
static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
RFX_MESSAGE* message, wStream* s, UINT16* pExpecedBlockType)
RFX_MESSAGE* message, wStream* s, UINT16* pExpectedBlockType)
{
BOOL rc;
int i, close_cnt;
size_t pos;
BYTE quant;
RFX_TILE* tile;
RFX_TILE** tmpTiles;
UINT32* quants;
UINT16 subtype;
UINT16 subtype, numTiles;
UINT32 blockLen;
UINT32 blockType;
UINT32 tilesDataSize;
@ -772,13 +765,13 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
RFX_TILE_PROCESS_WORK_PARAM* params = NULL;
void* pmem;
if (*pExpecedBlockType != WBT_EXTENSION)
if (*pExpectedBlockType != WBT_EXTENSION)
{
WLog_ERR(TAG, "%s: message unexpeced", __FUNCTION__);
WLog_ERR(TAG, "%s: message unexpected wants a tileset", __FUNCTION__);
return FALSE;
}
*pExpecedBlockType = WBT_FRAME_END;
*pExpectedBlockType = WBT_FRAME_END;
if (Stream_GetRemainingLength(s) < 14)
{
@ -786,9 +779,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
return FALSE;
}
Stream_Read_UINT16(s,
subtype); /* subtype (2 bytes) must be set to CBT_TILESET (0xCAC2) */
Stream_Read_UINT16(s, subtype); /* subtype (2 bytes) must be set to CBT_TILESET (0xCAC2) */
if (subtype != CBT_TILESET)
{
WLog_ERR(TAG, "invalid subtype, expected CBT_TILESET.");
@ -806,9 +797,8 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
return FALSE;
}
Stream_Read_UINT16(s, message->numTiles); /* numTiles (2 bytes) */
if (message->numTiles < 1)
Stream_Read_UINT16(s, numTiles); /* numTiles (2 bytes) */
if (numTiles < 1)
{
/* Windows Server 2012 (not R2) can send empty tile sets */
return TRUE;
@ -816,8 +806,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
Stream_Read_UINT32(s, tilesDataSize); /* tilesDataSize (4 bytes) */
if (!(pmem = realloc((void*) context->quants,
context->numQuant * 10 * sizeof(UINT32))))
if (!(pmem = realloc((void*)context->quants, context->numQuant * 10 * sizeof(UINT32))))
return FALSE;
quants = context->quants = (UINT32*) pmem;
@ -857,13 +846,19 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
context->quants[i * 10 + 8], context->quants[i * 10 + 9]);
}
if (!(message->tiles = (RFX_TILE**) calloc(message->numTiles,
sizeof(RFX_TILE*))))
for (i = 0; i < message->numTiles; i++)
{
message->numTiles = 0;
return FALSE;
ObjectPool_Return(context->priv->TilePool, message->tiles[i]);
message->tiles[i] = NULL;
}
tmpTiles = (RFX_TILE**)realloc(message->tiles, numTiles * sizeof(RFX_TILE *));
if (!tmpTiles)
return FALSE;
message->tiles = tmpTiles;
message->numTiles = numTiles;
if (context->priv->UseThreads)
{
work_objects = (PTP_WORK*) calloc(message->numTiles, sizeof(PTP_WORK));
@ -907,8 +902,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
break;
}
Stream_Read_UINT16(s,
blockType); /* blockType (2 bytes), must be set to CBT_TILE (0xCAC3) */
Stream_Read_UINT16(s, blockType); /* blockType (2 bytes), must be set to CBT_TILE (0xCAC3) */
Stream_Read_UINT32(s, blockLen); /* blockLen (4 bytes) */
if (Stream_GetRemainingLength(s) < blockLen - 6)
@ -1003,53 +997,48 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, UINT32 length,
UINT32 dstStride, UINT32 dstHeight,
REGION16* invalidRegion)
{
size_t pos;
REGION16 updateRegion;
UINT32 blockLen;
UINT32 blockType;
RFX_MESSAGE* message = NULL;
wStream* s = NULL;
RFX_MESSAGE* message = &context->currentMessage;
wStream inStream, *s = &inStream;
BOOL ok = TRUE;
UINT16 expectedDataBlockType = WBT_FRAME_BEGIN;
if (!context || !data || !length)
goto fail;
return FALSE;
if (!(s = Stream_New((BYTE*)data, length)))
goto fail;
if (!(message = (RFX_MESSAGE*) calloc(1, sizeof(RFX_MESSAGE))))
goto fail;
Stream_StaticInit(s, (BYTE*)data, length);
message->freeRects = TRUE;
while (ok && Stream_GetRemainingLength(s) > 6)
{
wStream subStream;
size_t extraBlockLen = 0;
/* RFX_BLOCKT */
Stream_Read_UINT16(s, blockType); /* blockType (2 bytes) */
Stream_Read_UINT32(s, blockLen); /* blockLen (4 bytes) */
WLog_Print(context->priv->log, WLOG_DEBUG, "blockType 0x%"PRIX32" blockLen %"PRIu32"",
blockType, blockLen);
if (blockLen == 0)
if (blockLen < 6)
{
WLog_ERR(TAG, "zero blockLen");
goto fail;
WLog_ERR(TAG, "blockLen too small(%"PRIu32")", blockLen);
return FALSE;
}
if (Stream_GetRemainingLength(s) < blockLen - 6)
{
WLog_ERR(TAG, "%s: packet too small for blocklen=%"PRIu32"", __FUNCTION__, blockLen);
goto fail;
return FALSE;
}
pos = Stream_GetPosition(s) - 6 + blockLen;
if (blockType > WBT_CONTEXT
&& context->decodedHeaderBlocks != _RFX_DECODED_HEADERS)
{
WLog_ERR(TAG, "%s: incomplete header blocks processing", __FUNCTION__);
goto fail;
return FALSE;
}
if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION)
@ -1059,16 +1048,16 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, UINT32 length,
UINT8 channelId;
if (Stream_GetRemainingLength(s) < 2)
goto fail;
return FALSE;
extraBlockLen = 2;
Stream_Read_UINT8(s, codecId); /* codecId (1 byte) must be set to 0x01 */
Stream_Read_UINT8(s,
channelId); /* channelId (1 byte) 0xFF or 0x00, see below */
Stream_Read_UINT8(s, channelId); /* channelId (1 byte) 0xFF or 0x00, see below */
if (codecId != 0x01)
{
WLog_ERR(TAG, "%s: invalid codecId 0x%02"PRIX8"", __FUNCTION__, codecId);
goto fail;
return FALSE;
}
if (blockType == WBT_CONTEXT)
@ -1078,7 +1067,7 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, UINT32 length,
{
WLog_ERR(TAG, "%s: invalid channelId 0x%02"PRIX8" for blockType 0x%08"PRIX32"", __FUNCTION__,
channelId, blockType);
goto fail;
return FALSE;
}
}
else
@ -1088,11 +1077,14 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, UINT32 length,
{
WLog_ERR(TAG, "%s: invalid channelId 0x%02"PRIX8" for blockType WBT_CONTEXT",
__FUNCTION__, channelId);
goto fail;
return FALSE;
}
}
}
Stream_StaticInit(&subStream, Stream_Pointer(s), blockLen - (6 + extraBlockLen));
Stream_Seek(s, blockLen - (6 + extraBlockLen));
switch (blockType)
{
/* Header messages:
@ -1100,19 +1092,19 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, UINT32 length,
* in the stream at a later stage. The header messages can be repeated.
*/
case WBT_SYNC:
ok = rfx_process_message_sync(context, s);
ok = rfx_process_message_sync(context, &subStream);
break;
case WBT_CONTEXT:
ok = rfx_process_message_context(context, s);
ok = rfx_process_message_context(context, &subStream);
break;
case WBT_CODEC_VERSIONS:
ok = rfx_process_message_codec_versions(context, s);
ok = rfx_process_message_codec_versions(context, &subStream);
break;
case WBT_CHANNELS:
ok = rfx_process_message_channels(context, s);
ok = rfx_process_message_channels(context, &subStream);
break;
/* Data messages:
@ -1123,28 +1115,25 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, UINT32 length,
*/
case WBT_FRAME_BEGIN:
ok = rfx_process_message_frame_begin(context, message, s,
&expectedDataBlockType);
ok = rfx_process_message_frame_begin(context, message, &subStream, &context->expectedDataBlockType);
break;
case WBT_REGION:
ok = rfx_process_message_region(context, message, s, &expectedDataBlockType);
ok = rfx_process_message_region(context, message, &subStream, &context->expectedDataBlockType);
break;
case WBT_EXTENSION:
ok = rfx_process_message_tileset(context, message, s, &expectedDataBlockType);
ok = rfx_process_message_tileset(context, message, &subStream, &context->expectedDataBlockType);
break;
case WBT_FRAME_END:
ok = rfx_process_message_frame_end(context, message, s, &expectedDataBlockType);
ok = rfx_process_message_frame_end(context, message, &subStream, &context->expectedDataBlockType);
break;
default:
WLog_ERR(TAG, "%s: unknown blockType 0x%"PRIX32"", __FUNCTION__, blockType);
goto fail;
return FALSE;
}
Stream_SetPosition(s, pos);
}
if (ok)
@ -1195,7 +1184,7 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, UINT32 length,
tile->data, context->pixel_format, stride, nXSrc, nYSrc, NULL, FREERDP_FLIP_NONE))
{
region16_uninit(&updateRegion);
goto fail;
return FALSE;
}
if (invalidRegion)
@ -1206,14 +1195,9 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, UINT32 length,
}
region16_uninit(&clippingRects);
Stream_Free(s, FALSE);
rfx_message_free(context, message);
return TRUE;
}
fail:
Stream_Free(s, FALSE);
rfx_message_free(context, message);
return FALSE;
}
@ -1271,8 +1255,7 @@ static void rfx_update_context_properties(RFX_CONTEXT* context)
properties |= (context->flags << 1); /* flags */
properties |= (COL_CONV_ICT << 4); /* cct */
properties |= (CLW_XFORM_DWT_53_A << 6); /* xft */
properties |= ((context->mode == RLGR1 ? CLW_ENTROPY_RLGR1 : CLW_ENTROPY_RLGR3)
<< 10); /* et */
properties |= ((context->mode == RLGR1 ? CLW_ENTROPY_RLGR1 : CLW_ENTROPY_RLGR3) << 10); /* et */
properties |= (SCALAR_QUANTIZATION << 14); /* qt */
context->properties = properties;
}

View File

@ -77,18 +77,12 @@ BOOL rfx_decode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, BYTE* rgb_buffer,
cb_quants = context->quants + (tile->quantIdxCb * 10);
cr_quants = context->quants + (tile->quantIdxCr * 10);
pBuffer = (BYTE*) BufferPool_Take(context->priv->BufferPool, -1);
pSrcDst[0] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 0) +
16])); /* y_r_buffer */
pSrcDst[1] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 1) +
16])); /* cb_g_buffer */
pSrcDst[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) +
16])); /* cr_b_buffer */
rfx_decode_component(context, y_quants, tile->YData, tile->YLen,
pSrcDst[0]); /* YData */
rfx_decode_component(context, cb_quants, tile->CbData, tile->CbLen,
pSrcDst[1]); /* CbData */
rfx_decode_component(context, cr_quants, tile->CrData, tile->CrLen,
pSrcDst[2]); /* CrData */
pSrcDst[0] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 0) + 16])); /* y_r_buffer */
pSrcDst[1] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 1) + 16])); /* cb_g_buffer */
pSrcDst[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* cr_b_buffer */
rfx_decode_component(context, y_quants, tile->YData, tile->YLen, pSrcDst[0]); /* YData */
rfx_decode_component(context, cb_quants, tile->CbData, tile->CbLen, pSrcDst[1]); /* CbData */
rfx_decode_component(context, cr_quants, tile->CrData, tile->CrLen, pSrcDst[2]); /* CrData */
PROFILER_ENTER(context->priv->prof_rfx_ycbcr_to_rgb)
if (prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**)pSrcDst, 64 * sizeof(INT16),

View File

@ -4,244 +4,209 @@
#include <freerdp/freerdp.h>
#include <freerdp/codec/rfx.h>
/**
* The following is an annotated dump of a TS_RFX_TILESET message containing a single encoded 64x64 tile.
*
*
* c7 cc -> TS_RFX_TILESET::CodecChannelT::blockType = WBT_EXTENSION
* 3e 0b 00 00 -> TS_RFX_TILESET::CodecChannelT::blockLen = 2878
* 01 -> TS_RFX_TILESET::codecId = 1
* 00 -> TS_RFX_TILESET::channelId = 0
* c2 ca -> TS_RFX_TILESET::subtype = CBT_TILESET
* 00 00 -> TS_RFX_TILESET::idx = 0x00
* 51 50 -> TS_RFX_TILESET::properties
* TS_RFX_TILESET::properties::lt = TRUE (1)
* TS_RFX_TILESET::properties::flags = VIDEO_MODE (0)
* TS_RFX_TILESET::properties::cct = COL_CONV_ICT (1)
* TS_RFX_TILESET::properties::xft = CLW_XFORM_DWT_53_A (1)
* TS_RFX_TILESET::properties::et = CLW_ENTROPY_RLGR3 (4)
* TS_RFX_TILESET::properties::qt = SCALAR_QUANTIZATION (1)
* 01 -> TS_RFX_TILESET::numQuant = 1
* 40 -> TS_RFX_TILESET::tileSize = 64
* 01 00 -> TS_RFX_TILESET::numTiles = 1
* 23 0b 00 00 -> TS_RFX_TILESET::tilesDataSize = 2851
* 66 66 77 88 98 -> TS_RFX_TILESET::quantVals
* TS_RFX_TILESET::quantVals::LL3 = 6
* TS_RFX_TILESET::quantVals::LH3 = 6
* TS_RFX_TILESET::quantVals::HL3 = 6
* TS_RFX_TILESET::quantVals::HH3 = 6
* TS_RFX_TILESET::quantVals::LH2 = 7
* TS_RFX_TILESET::quantVals::HL2 = 7
* TS_RFX_TILESET::quantVals::HH2 = 8
* TS_RFX_TILESET::quantVals::LH1 = 8
* TS_RFX_TILESET::quantVals::HL1 = 8
* TS_RFX_TILESET::quantVals::HH1 = 9
*
* TS_RFX_TILE message (section 2.2.2.3.4.1).
*
* c3 ca -> TS_RFX_TILE::BlockT::blockType = CBT_TILE
* 23 0b -> TS_RFX_TILE::BlockT::blockLen = 2851
* 00 -> TS_RFX_TILE::quantIdxY = 0
* 00 -> TS_RFX_TILE::quantIdxCb = 0
* 00 -> TS_RFX_TILE::quantIdxCr = 0
* 00 00 -> TS_RFX_TILE::xIdx = 0
* 00 00 -> TS_RFX_TILE::yIdx = 0
* ae 03 -> TS_RFX_TILE::YLen = 942
* cf 03 -> TS_RFX_TILE::CbLen = 975
* 93 03 -> TS_RFX_TILE::CrLen = 915
* 0000002e:000003db -> TS_RFX_TILE::YData
* 000003dc:000007aa -> TS_RFX_TILE::CbData
* 000007ab:00000b3d -> TS_RFX_TILE::CrData
*/
const BYTE TEST_RFX_TILESET[2878] =
"\xc7\xcc\x3e\x0b\x00\x00\x01\x01\xc2\xca\x00\x00\x51\x50\x01\x40"
"\x01\x00\x23\x0b\x00\x00\x66\x66\x77\x88\x98\xc3\xca\x23\x0b\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\xae\x03\xcf\x03\x93\x03\xc0\x01"
"\x01\x15\x48\x99\xc7\x41\xa1\x12\x68\x11\xdc\x22\x29\x74\xef\xfd"
"\x20\x92\xe0\x4e\xa8\x69\x3b\xfd\x41\x83\xbf\x28\x53\x0c\x1f\xe2"
"\x54\x0c\x77\x7c\xa3\x05\x7c\x30\xd0\x9c\xe8\x09\x39\x1a\x5d\xff"
"\xe2\x01\x22\x13\x80\x90\x87\xd2\x9f\xfd\xfd\x50\x09\x0d\x24\xa0"
"\x8f\xab\xfe\x3c\x04\x84\xc6\x9c\xde\xf8\x80\xc3\x22\x50\xaf\x4c"
"\x2a\x7f\xfe\xe0\x5c\xa9\x52\x8a\x06\x7d\x3d\x09\x03\x65\xa3\xaf"
"\xd2\x61\x1f\x72\x04\x50\x8d\x3e\x16\x4a\x3f\xff\xfd\x41\x42\x87"
"\x24\x37\x06\x17\x2e\x56\x05\x9c\x1c\xb3\x84\x6a\xff\xfb\x43\x8b"
"\xa3\x7a\x32\x43\x28\xe1\x1f\x50\x54\xfc\xca\xa5\xdf\xff\x08\x04"
"\x48\x15\x61\xd9\x76\x43\xf8\x2a\x07\xe9\x65\xf7\xc6\x89\x2d\x40"
"\xa1\xc3\x35\x8d\xf5\xed\xf5\x91\xae\x2f\xcc\x01\xce\x03\x48\xc0"
"\x8d\x63\xf4\xfd\x50\x20\x2d\x0c\x9b\xb0\x8d\x13\xc0\x8a\x09\x52"
"\x1b\x02\x6e\x42\x3b\xd0\x13\x4e\x84\x01\x26\x88\x6a\x04\x84\x34"
"\x2a\xa5\x00\xba\x54\x48\x58\xea\x54\x02\xb4\x1d\xa7\xfa\x47\x82"
"\xec\x7a\x77\xfd\x00\x92\x66\x62\x04\xa6\x9b\xff\xf6\x80\xc0\x69"
"\x01\xc2\x3e\x90\x14\x20\x2f\xfc\x40\x96\x59\x58\x0c\xb1\x13\x68"
"\x20\x2e\xb5\xf5\xdf\xff\xf8\xfc\x56\x88\x60\x24\x53\xb5\x41\x46"
"\x5f\xf8\xf1\x7e\xde\x4a\x08\x97\xe0\x55\x03\x8f\xe5\x75\x61\x03"
"\xf2\xe1\x90\x01\xa2\x8e\x88\x04\x98\x05\x93\x6b\xff\xea\xc0\x60"
"\xa1\x88\x04\x49\xbf\xf7\xff\x8c\xb4\x59\x90\x80\x30\x64\x53\xff"
"\xf5\xc4\x48\xda\xda\xcb\x80\x38\x61\x57\xb2\xaf\x00\xe8\x7b\x46"
"\xe6\xd8\x02\x03\x8a\x06\x18\x14\x32\x83\xd0\x8a\xee\xbc\x81\xb4"
"\x28\xc4\x7f\xf9\xa1\x69\x00\x91\xc5\x51\xff\xfe\x3f\xe9\xf1\x70"
"\x30\x24\x10\xa7\xcb\x1f\x8a\x24\x93\xed\x83\x00\x36\x20\xd1\x50"
"\xe7\xd8\xad\x58\x20\x09\x22\x80\xd0\xca\x5d\x1a\xd7\xf1\x60\x75"
"\x2a\xf2\xd7\xf8\xc0\x32\x45\x86\x00\x43\x01\xfe\x80\xf7\x42\x81"
"\x74\x84\x4c\xa1\x60\x4c\xcb\x14\x58\x01\x4d\x18\xa1\xaa\x47\x0e"
"\x11\x1a\x40\x7d\x41\x02\xe3\x30\xcd\x33\x81\x34\x06\x46\x83\xa2"
"\x47\x1c\x04\xaa\x20\x12\xa2\x8b\x81\xc4\x9c\xa0\x2e\x06\x32\xf8"
"\x86\x85\x01\xe8\x70\xf9\x46\x09\x6a\xbf\xe0\xf5\xa4\xc8\x78\xe7"
"\xd2\x97\x0b\xbc\x3c\x97\xff\xd5\x40\x94\xb2\xc1\x18\x18\x11\x1f"
"\x43\xc1\x18\xc3\x83\x7f\x9a\x31\xc4\x8e\x70\x56\xda\xf6\x17\xde"
"\xd1\x02\x0d\x42\x21\x13\xdc\x3a\x3c\x40\x9e\xf4\x01\x43\xea\x0c"
"\x46\x73\xa2\x7b\x0c\x80\xff\xe4\xad\x2e\x09\xb4\x63\xb0\x8c\x54"
"\x59\xfa\xac\x76\x36\x10\x05\xf0\x98\x88\x83\x42\x00\x20\x71\xcc"
"\xc1\xa9\x97\x3e\x5a\x0d\x04\x50\x92\x23\x20\x0d\x0a\x1c\x57\xd7"
"\xff\x10\xf2\x03\x0f\x58\x1b\xa5\x11\xf8\xf1\xb4\x12\xdb\x1a\x48"
"\x56\x1f\xe3\xc7\x50\xe9\x16\xb4\xbc\xb0\x40\x93\xea\xb5\x5b\x2f"
"\xfc\x50\x0a\x6f\xcc\x25\xe0\x06\xab\x5f\x24\xfe\x8b\xcb\x42\x43"
"\x7e\x69\x02\x25\xc7\x38\x00\x6e\xe5\x80\xa8\xa4\x30\x44\x15\x8f"
"\xe9\x0c\xd3\xa6\xc2\x14\x34\x4a\xfe\x03\x7f\x06\xa5\x91\x02\x54"
"\xf1\xa1\xa1\x53\xbf\x11\xf2\x8f\x83\x67\x80\x09\x08\x12\x3f\xfd"
"\x44\x91\xc2\x83\x30\x50\x07\x02\x82\x4d\x31\x34\x06\x41\x79\x6f"
"\xf0\xcc\x03\x79\x00\x2c\x05\x24\xec\x8d\x29\x15\xaf\x44\xc8\xeb"
"\x4f\xe1\xfd\xf1\x41\x48\x81\x08\xaf\xfe\x51\x48\xce\xe7\xf9\xb6"
"\x0a\x30\x83\x11\xf0\x0c\x3b\xd2\xa6\x24\x24\xef\x25\xfa\x5a\x3e"
"\x92\x3e\x79\x0e\x35\x61\xc8\xaa\x1c\x2e\x9a\x27\x7f\xff\xf0\x7d"
"\x30\x5b\xbc\x91\xff\xfe\x43\x24\x28\x66\xa7\x70\x99\x28\x6e\x2b"
"\x18\x2b\xd4\xa1\x77\x3b\x96\x9f\xf7\xeb\xbe\x1f\x04\x34\x75\x84"
"\x31\x42\x4c\x65\xaa\x09\x50\xa0\xc4\x51\x31\xd3\x26\x3a\x1b\xf4"
"\x6e\x4a\x4e\x17\x25\x84\x78\x7d\x2c\x3f\x46\x18\xca\x5f\xf9\xe5"
"\x38\x2f\xd8\x71\x94\x94\xe2\xcc\xa3\x15\xb0\xda\xa9\xcb\x58\xe4"
"\x18\x77\x93\x8a\x51\xc6\x23\xc4\x4e\x6d\xd9\x14\x1e\x9b\x8d\xbc"
"\xcb\x9d\xc4\x18\x05\xf5\xa9\x29\xf8\x6d\x29\x38\xc7\x44\xe5\x3a"
"\xcd\xba\x61\x98\x4a\x57\x02\x96\x42\x02\xd9\x37\x11\xde\x2d\xd4"
"\x3f\xfe\x61\xe7\x33\xd7\x89\x4a\xdd\xb0\x34\x47\xf4\xdc\xad\xaa"
"\xc9\x9d\x7e\x6d\x4b\xcc\xdc\x17\x89\x57\xfd\xbb\x37\x75\x47\x5a"
"\xec\x2c\x6e\x3c\x15\x92\x54\x64\x2c\xab\x9e\xab\x2b\xdd\x3c\x66"
"\xa0\x8f\x47\x5e\x93\x1a\x37\x16\xf4\x89\x23\x00\x00\xb0\x33\x56"
"\xfa\x14\x1e\xff\x48\x7a\x7e\x0f\x10\x1f\xf4\x91\xc8\x10\x56\x84"
"\xff\x08\xec\xb4\xac\x0e\x0f\xff\xad\xc5\xe0\x1a\x2f\x82\x04\x9f"
"\x91\xc2\x0e\xfe\x48\x36\x79\x01\x42\x14\xff\xfe\x30\xf0\x08\x18"
"\xf1\x81\x45\x9a\x60\xc1\x79\xf0\x14\x12\x10\xce\xea\x31\x5a\xff"
"\xfc\x20\x13\x82\x2f\xc9\x02\x1f\x81\xcb\x00\xe1\x10\xd2\xb4\xbe"
"\x87\xff\xb0\x1e\x27\x81\xb7\x04\x06\x3c\xc2\x04\xf6\x06\x0e\x28"
"\xbc\x40\xbf\x12\x1e\x86\xd4\x6a\x7f\x18\x1b\x96\x85\x4c\x16\x80"
"\xdf\x2c\xa5\x8d\x86\xa3\x4a\x8a\xb4\x1b\xa1\x38\xa9\xd5\xff\xff"
"\xea\x06\x20\xd2\x95\x1e\xf4\x2f\xb2\x12\x0e\x61\x78\x4a\x17\x52"
"\x5d\xe4\x25\x1f\xfe\xc0\xb3\x1f\xff\xff\xec\x02\x82\x80\x90\x41"
"\x88\xde\x48\x2c\x42\x52\x0b\x2f\x43\x7e\x50\x78\xf2\x67\x78\x41"
"\x34\x3d\xc8\x0f\x67\xa1\xeb\x21\xfe\xc0\x1f\x22\x60\x41\x6c\x00"
"\x92\x4b\x60\x10\xd0\x0d\x01\x35\x05\x0e\x87\xa2\xa0\x5d\x1f\xa3"
"\xaf\x7f\xf1\xbe\x8f\xcd\xa5\x00\x1c\x10\x40\x15\x76\x81\x05\xef"
"\xee\x00\x60\x84\x00\x99\x40\x4a\x82\x17\xe9\xfc\xc4\x7f\xff\xfd"
"\x04\x80\x06\x06\xdc\xaf\xa7\x7e\x94\x75\x74\x01\x00\xe0\x91\x00"
"\x85\x7f\x8e\xd6\x0b\x20\x21\x30\xca\x62\x8e\x07\x04\xe9\x45\x40"
"\x5f\x47\x4a\x30\x15\x41\xcb\xdf\xff\xfc\xbf\xc3\xb4\x46\x6a\x01"
"\x40\xd0\xa7\x34\x18\x24\x1c\x2a\x45\xfe\xa8\x05\x08\x61\xfd\xa8"
"\x80\x71\x01\x25\x9c\xc1\x47\x17\x37\x02\x7a\x15\xff\xf3\x01\x45"
"\x7f\xd6\x80\x60\x83\x67\xf8\x9d\x2f\xf4\xdd\x8c\x30\x01\x51\x42"
"\xbc\x43\x7a\x6b\x9f\x84\x1e\x00\x48\xc1\xe0\xb7\xe0\x7e\x99\xf2"
"\x4a\xe9\x40\x02\x81\xc3\x00\x24\x3a\xc5\x52\x0f\x91\xc8\x68\x25"
"\x40\x99\xa4\x25\x1a\x04\xd0\xa2\x91\xdd\xeb\x93\x00\x21\x49\x24"
"\x8b\x40\x75\x38\x14\xa1\xfd\x3f\x88\x25\xbf\x32\x00\xe3\x19\xfc"
"\xb9\xf8\x6f\x81\xc0\x01\xb3\x93\x20\x09\x08\x25\x84\xe1\x34\xd4"
"\x1b\x48\x88\x11\xa0\x15\x59\xd7\x07\x81\x81\x3b\xa1\x40\x2e\x2f"
"\x48\x70\x09\xc4\x76\x49\x0f\x2e\x50\x2e\x46\x19\xa4\x16\xa2\x1b"
"\x84\xa2\x89\x58\xfc\x4f\x3f\x40\x90\x4c\xa3\x01\x32\x09\x02\x80"
"\x9c\x91\x13\x2c\xba\xde\x5d\x99\xf2\xff\xff\x3d\x5a\x1f\xa9\x02"
"\x90\x8f\xf3\x08\xbd\x01\xf8\xd0\x2a\x95\x41\x0c\x40\x0a\x20\xc4"
"\xd4\xcc\x6b\x0f\xf0\x80\xb1\x5d\x28\x3d\x08\xc2\xf8\x31\x02\x49"
"\x88\x14\x28\xed\xe8\x86\x3b\x00\x9f\x95\x06\x37\x15\xa4\x59\xc8"
"\x80\xb6\x10\xf0\xe5\xb8\x18\x00\x56\x1c\xff\x95\x21\x0e\x7f\x2b"
"\xc5\x08\x59\x10\xe1\x46\x31\x8d\xec\xe0\xa1\x99\xbb\x21\xff\xfe"
"\x30\x10\xd0\x05\xe3\x08\x50\xfc\xf3\x0e\x00\x8d\x68\x8e\x07\xa6"
"\x80\x34\x42\xed\x1f\x88\x00\xf0\x8a\x21\xae\xf7\xfb\x80\x28\x86"
"\x0f\xff\xff\x82\xea\x47\x95\x91\xe0\x04\x01\x44\x0c\x29\xff\x0e"
"\x33\xe8\xc0\x54\x04\x23\xfc\x81\x5b\xf0\x3c\x07\x10\x70\x30\xd8"
"\x21\x6f\xef\xde\x46\x09\x43\xfa\x5f\xff\x0d\x72\x30\xdd\x00\xdb"
"\xe4\x48\x24\x97\x08\x46\xb1\x49\xc4\x4d\x80\x12\x60\xff\xa4\xa6"
"\xff\xf6\x8c\x00\x40\x05\x02\xb4\x0f\xf0\x3e\xfc\x84\x38\x81\x94"
"\x8b\xfe\x49\xef\xc0\x10\x49\x88\x28\xa2\x1c\x2a\x8b\x64\xd4\x86"
"\xd7\xff\xff\xff\xeb\x91\x6b\x11\x10\x00\x69\x4c\xbf\xb4\x1c\xd8"
"\x00\x07\x16\x80\x60\x0a\x1c\x82\x42\x27\x82\x43\xc9\x0a\x64\x20"
"\x5a\x5f\x4e\xbf\x8c\x38\x82\x36\x02\x07\x72\x79\x07\x23\xb4\xbb"
"\x57\x5f\xe8\x04\xdd\x39\xe9\x07\x95\xbe\x04\x2b\xdd\x8e\x22\xdc"
"\x14\x2c\x61\xa3\xa9\xcd\x4f\x82\x5d\xa0\x44\xdf\xf4\x96\xff\xf5"
"\x2b\xff\xfe\x01\x19\xd2\xa2\x9e\x43\xa5\x7f\xf0\x4c\x4c\x2b\x3c"
"\x33\xe2\x55\xff\x04\x06\x29\x2c\x0d\x22\x5d\x7c\x93\xba\x18\xaf"
"\xf9\x32\xa6\xc3\x99\x46\x79\xe3\x06\xa6\x38\x8b\x92\x22\x4b\xdb"
"\x1b\x36\x20\xb0\x6c\x20\xce\x37\x42\xe1\x66\xd4\x49\x34\x42\x8b"
"\xfa\x9c\x12\x99\xdc\x06\x87\xfa\x46\xf8\x2f\x04\xa9\xd8\x82\x07"
"\xa6\x30\x0f\xc0\xdf\x35\xe8\x90\xf0\xff\xff\xa8\xe0\xd7\x02\x60"
"\x1a\xc3\x20\x28\xa2\x31\x29\x3c\xeb\x04\xa5\xdd\x48\x0e\x82\xa4"
"\xb6\x56\x22\x06\x57\xe0\xda\x10\x27\x31\x0e\x11\x77\xfe\x02\x60"
"\x16\x48\x81\x8c\x0d\x05\x17\x7f\xcb\xbb\x7e\x25\x2a\x41\xfd\x8a"
"\x7f\xc9\x36\x7c\xe0\x98\x7e\x92\xef\x7e\x06\x03\x13\x3e\x20\x3a"
"\xbf\x4c\xc3\x0f\x2e\x80\x74\xbf\x39\x3c\xf0\xa6\xb2\xe9\x3f\x41"
"\x55\x1f\x2c\xf5\xd2\x7e\x8c\xae\x4e\xaa\x61\x3c\xbc\x3f\xc4\xc7"
"\x36\xdc\x23\xc8\xb8\x52\xe2\x8a\x80\x18\x00\x00\xb2\x46\xa2\x56"
"\x0d\x12\x94\xaa\xbd\x01\x07\xff\xfa\x34\x0c\x5f\xf8\x0c\x12\x50"
"\xaf\xd6\xd1\x89\x40\xa4\xff\xe0\xce\xc4\x49\x25\x9d\xc1\xff\x7e"
"\x60\x24\x5d\xcc\x10\xc0\xbe\x5a\x12\xd3\xc3\xfe\x2d\x40\x7c\x28"
"\x9e\x71\x01\xd2\x6e\x86\x0b\xc8\xf2\x9b\x45\x08\x4c\x04\x52\x7e"
"\xf2\x7e\xd9\xcc\x0b\x1c\x20\x80\xae\xaf\xfe\xb0\x6d\x23\xf2\x41"
"\xe3\x2e\x20\x11\x4b\x74\x89\xdd\xff\xa8\x38\xa3\x95\x82\x15\xf0"
"\xd0\xd5\xf1\x92\x8e\xee\xc0\x26\x81\xe9\x47\xff\xee\x0d\x20\x34"
"\x31\x3a\xef\x40\xb2\x29\x47\x19\x7f\x04\x27\xf1\x90\x85\x09\x86"
"\x7d\x42\xe2\x54\x5d\x5f\xe8\x0e\xd0\x2c\xaa\x16\xbf\x04\xa7\xf8"
"\xa2\x46\x0b\x08\x7a\x79\xe9\x28\x62\x7c\x33\xf4\x0b\x14\x82\xfa"
"\x61\xeb\xc1\xff\x4c\xa4\x11\x7f\x03\x68\x44\xc1\x1f\x81\x3a\x6c"
"\x77\x95\x02\x2b\x53\x80\xe5\x10\x1e\x90\xe8\xfd\x1f\xa6\x40\x0b"
"\x13\xff\x4e\x4d\x7f\x52\xe8\xaf\x9a\xc1\x80\x0f\x0a\x14\x02\x3c"
"\xc0\x09\x13\xe7\xdc\xc0\x1a\x28\xa0\xe4\x83\x8e\x03\x88\xd5\xaf"
"\x1a\xbd\x91\x00\xb7\x4e\xba\xdf\xf8\xdb\xcc\x02\x43\xc4\x14\x2a"
"\x3f\xc8\x0d\x09\x1c\x44\xf4\x01\x3c\xca\x28\x56\x80\xa6\x85\x00"
"\xea\x3e\x8f\xeb\x9f\xfc\x6e\x07\xc4\xe0\x30\x78\xa0\x1e\x6f\x54"
"\x78\x51\xff\x56\x4a\x01\x47\x02\x4c\x21\x3b\xfb\x90\x0a\xcc\x1d"
"\xd2\x47\xff\xfc\x70\x18\x22\xc0\xb9\x2f\xe9\x7f\x91\xd3\x66\x2f"
"\x80\x2c\x24\xa7\xfa\x84\x51\xab\x6b\x72\x00\xab\x33\x04\xcf\x43"
"\xff\x17\x51\x84\x0c\x01\x50\x10\x8f\x90\x34\x41\x44\x84\x8e\x08"
"\x19\x04\x48\x50\x84\x38\x3d\x02\x52\xf9\x7c\xd2\xd0\x1f\x13\x42"
"\xa0\x21\x41\xc4\x02\x02\x3d\x09\xc8\xfd\x60\x7d\x35\x4f\x7f\xff"
"\xf9\x97\x6a\xd8\x00\xc3\x83\x00\x09\x50\x4b\x90\x8a\xc7\x94\x4d"
"\x47\xc1\x62\x32\x28\x24\x09\x52\x2e\x2e\x1c\x96\x44\xa0\x09\xc8"
"\xce\x64\xa9\x1c\x19\x0e\x52\x3e\x3e\x19\x93\xa0\x36\x26\x22\x08"
"\x9a\x00\xdd\x66\x3a\x93\xd5\x89\xd1\x40\x06\xd4\xa8\x22\x73\x7b"
"\x3d\x3f\xe3\x04\x94\xff\xff\xff\xff\x0c\x56\x77\xac\xe0\xc4\x06"
"\x1f\xb8\xa5\x80\xfd\x68\x1c\x32\x16\x03\xde\x71\x2a\x3d\x14\x19"
"\xbe\xc2\x88\xd9\x24\x92\x5f\xc5\x90\x0a\x85\xc2\x3f\x87\x03\xa8"
"\x26\x17\xc4\x06\x86\x12\x87\x76\x0a\x48\x16\xed\x96\x93\xec\x1b"
"\x30\x73\xe8\x1a\x3f\xff\x4d\xce\x40\xf3\x0c\x51\x4b\x84\x9e\x67"
"\x2b\x15\x40\x1a\xa0\xfc\x10\x0f\xd8\x81\x35\x87\xff\x98\x0f\x40"
"\x00\xba\xc0\x71\xe2\x00\x18\x28\xb3\x82\xcc\x80\x6a\xa0\x43\xff"
"\x2d\xd6\x04\x8a\x68\xff\xff\xff\xfc\x1a\xf3\x1a\x2a\x06\xc0\x01"
"\x40\x0c\x30\xc1\xd0\xd7\x4f\xcb\x74\x1f\x07\xd3\xb4\x0d\x88\x98"
"\xea\xda\x9f\xce\x2b\x3c\x55\xb3\x40\x14\xff\xff\xff\xea\xdb\x9b"
"\x92\xd8\x68\x08\x0b\x41\x09\x26\x40\x8c\xf1\xb0\x9a\x98\xc0\x80"
"\x8b\xf0\x3d\xe7\xec\x19\x68\x21\x03\x29\x7f\xe1\x6d\x4c\x0f\x01"
"\xd1\x51\x01\x1a\x50\x2a\x59\x27\x80\xc1\x6e\x33\xf1\x80\xe1\x49"
"\x08\xe9\x17\xff\xff\xff\x80\x5a\x10\x10\x36\x5e\xca\xf8\x3a\x00"
"\x1e\xb0\x06\x84\x01\xf3\x07\x1b\x4a\xc0\x1e\x21\x43\x8e\xa5\x55"
"\x77\xc7\x65\x7c\xc2\xdf\x5e\x0c\x42\x20\xd2\x48\x61\xc8\x1c\x65"
"\xf8\xfe\x4c\x88\x71\x1f\x82\x50\x81\xa3\x54\x09\x13\x28\x52\xf5"
"\xe0\x82\xc3\x06\x7f\xfa\x2c\xcf\xf8\xf4\x7f\xff\xfd\x01\x49\xa4"
"\xb8\xde\x62\x84\xfe\xed\x65\x1f\x3c\x3c\xb2\x50\x76\x30\x5b\x03"
"\xc0\x08\xa6\x64\x90\xc8\xcd\x14\x6e\x69\x46\x7a\xc6\x1c\x87\xd7"
"\x48\x7b\x49\x05\x2d\x5e\x7f\xcb\x67\xf0\xd9\x0d\x1e\x9e\x53\xb7"
"\x64\xa5\xa5\x10\x39\x06\x11\x3f\xb1\xa9\xa6\xe8\x4d\x47\x77\xda"
"\x43\x76\x89\x45\x09\x70\xc2\x38\x0f\x09\x6f\xe7\x2d\x82\x35\x07"
"\xfe\x64\x18\x2e\xb8\x04\x42\x54\x80\x43\x12\x6c\x9a\x55\xc9\x0a"
"\xa0\x79\x47\x52\x65\x2a\xff\x50\x11\xc9\x4e\xfe\x5b\x30\xa4\xe8"
"\x30\x63\xff\x21\x12\x1b\xdc\x1c\x01\x41\x51\x1f\xff\xfa\xc3\xe3"
"\x55\xf1\x66\xe2\xd5\x78\x5e\xfa\x4d\xf2\x61\x01\x26\x15\xa9\xf9"
"\xd9\x32\x41\x90\x36\x4e\xae\xe3\x0b\x16\x56\x8c\x6e\x42\x5d\xd8"
"\x1e\xfe\x1d\x40\x3a\x50\x9f\x09\x14\xeb\x6e\x48\x7a\x91\x88\x7b"
"\x7d\x8f\x72\x42\x39\xb0\x1c\x65\x18\x23\x8b\x60\x30\x00";
static BYTE encodeHeaderSample[] = {
/* as in 4.2.2 */
0xc0, 0xcc, 0x0c, 0x00, 0x00, 0x00, 0xca, 0xac, 0xcc, 0xca, 0x00, 0x01, 0xc3, 0xcc, 0x0d, 0x00,
0x00, 0x00, 0x01, 0xff, 0x00, 0x40, 0x00, 0x28, 0xa8, 0xc1, 0xcc, 0x0a, 0x00, 0x00, 0x00, 0x01,
0x01, 0x00, 0x01, 0xc2, 0xcc, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x00, 0x40, 0x00
};
/**
* 64x64 XRGB Image
*/
static BYTE encodeDataSample[] = {
/* FRAME_BEGIN as in 4.2.3 */
0xc4, 0xcc, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
const UINT32 TEST_RFX_XRGB_IMAGE[4096] =
{
/* REGION as in 4.2.3 */
0xc6, 0xcc, 0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
0x00, 0x40, 0x00, 0xc1, 0xca, 0x01, 0x00,
/* TILESET as in 4.2.4.1 */
0xc7, 0xcc, 0x3e, 0x0b, 0x00, 0x00, 0x01, 0x00, 0xc2, 0xca, 0x00, 0x00, 0x51, 0x50, 0x01, 0x40,
0x01, 0x00, 0x23, 0x0b, 0x00, 0x00, 0x66, 0x66, 0x77, 0x88, 0x98, 0xc3, 0xca, 0x23, 0x0b, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0x03, 0xcf, 0x03, 0x93, 0x03, 0xc0, 0x01,
0x01, 0x15, 0x48, 0x99, 0xc7, 0x41, 0xa1, 0x12, 0x68, 0x11, 0xdc, 0x22, 0x29, 0x74, 0xef, 0xfd,
0x20, 0x92, 0xe0, 0x4e, 0xa8, 0x69, 0x3b, 0xfd, 0x41, 0x83, 0xbf, 0x28, 0x53, 0x0c, 0x1f, 0xe2,
0x54, 0x0c, 0x77, 0x7c, 0xa3, 0x05, 0x7c, 0x30, 0xd0, 0x9c, 0xe8, 0x09, 0x39, 0x1a, 0x5d, 0xff,
0xe2, 0x01, 0x22, 0x13, 0x80, 0x90, 0x87, 0xd2, 0x9f, 0xfd, 0xfd, 0x50, 0x09, 0x0d, 0x24, 0xa0,
0x8f, 0xab, 0xfe, 0x3c, 0x04, 0x84, 0xc6, 0x9c, 0xde, 0xf8, 0x80, 0xc3, 0x22, 0x50, 0xaf, 0x4c,
0x2a, 0x7f, 0xfe, 0xe0, 0x5c, 0xa9, 0x52, 0x8a, 0x06, 0x7d, 0x3d, 0x09, 0x03, 0x65, 0xa3, 0xaf,
0xd2, 0x61, 0x1f, 0x72, 0x04, 0x50, 0x8d, 0x3e, 0x16, 0x4a, 0x3f, 0xff, 0xfd, 0x41, 0x42, 0x87,
0x24, 0x37, 0x06, 0x17, 0x2e, 0x56, 0x05, 0x9c, 0x1c, 0xb3, 0x84, 0x6a, 0xff, 0xfb, 0x43, 0x8b,
0xa3, 0x7a, 0x32, 0x43, 0x28, 0xe1, 0x1f, 0x50, 0x54, 0xfc, 0xca, 0xa5, 0xdf, 0xff, 0x08, 0x04,
0x48, 0x15, 0x61, 0xd9, 0x76, 0x43, 0xf8, 0x2a, 0x07, 0xe9, 0x65, 0xf7, 0xc6, 0x89, 0x2d, 0x40,
0xa1, 0xc3, 0x35, 0x8d, 0xf5, 0xed, 0xf5, 0x91, 0xae, 0x2f, 0xcc, 0x01, 0xce, 0x03, 0x48, 0xc0,
0x8d, 0x63, 0xf4, 0xfd, 0x50, 0x20, 0x2d, 0x0c, 0x9b, 0xb0, 0x8d, 0x13, 0xc0, 0x8a, 0x09, 0x52,
0x1b, 0x02, 0x6e, 0x42, 0x3b, 0xd0, 0x13, 0x4e, 0x84, 0x01, 0x26, 0x88, 0x6a, 0x04, 0x84, 0x34,
0x2a, 0xa5, 0x00, 0xba, 0x54, 0x48, 0x58, 0xea, 0x54, 0x02, 0xb4, 0x1d, 0xa7, 0xfa, 0x47, 0x82,
0xec, 0x7a, 0x77, 0xfd, 0x00, 0x92, 0x66, 0x62, 0x04, 0xa6, 0x9b, 0xff, 0xf6, 0x80, 0xc0, 0x69,
0x01, 0xc2, 0x3e, 0x90, 0x14, 0x20, 0x2f, 0xfc, 0x40, 0x96, 0x59, 0x58, 0x0c, 0xb1, 0x13, 0x68,
0x20, 0x2e, 0xb5, 0xf5, 0xdf, 0xff, 0xf8, 0xfc, 0x56, 0x88, 0x60, 0x24, 0x53, 0xb5, 0x41, 0x46,
0x5f, 0xf8, 0xf1, 0x7e, 0xde, 0x4a, 0x08, 0x97, 0xe0, 0x55, 0x03, 0x8f, 0xe5, 0x75, 0x61, 0x03,
0xf2, 0xe1, 0x90, 0x01, 0xa2, 0x8e, 0x88, 0x04, 0x98, 0x05, 0x93, 0x6b, 0xff, 0xea, 0xc0, 0x60,
0xa1, 0x88, 0x04, 0x49, 0xbf, 0xf7, 0xff, 0x8c, 0xb4, 0x59, 0x90, 0x80, 0x30, 0x64, 0x53, 0xff,
0xf5, 0xc4, 0x48, 0xda, 0xda, 0xcb, 0x80, 0x38, 0x61, 0x57, 0xb2, 0xaf, 0x00, 0xe8, 0x7b, 0x46,
0xe6, 0xd8, 0x02, 0x03, 0x8a, 0x06, 0x18, 0x14, 0x32, 0x83, 0xd0, 0x8a, 0xee, 0xbc, 0x81, 0xb4,
0x28, 0xc4, 0x7f, 0xf9, 0xa1, 0x69, 0x00, 0x91, 0xc5, 0x51, 0xff, 0xfe, 0x3f, 0xe9, 0xf1, 0x70,
0x30, 0x24, 0x10, 0xa7, 0xcb, 0x1f, 0x8a, 0x24, 0x93, 0xed, 0x83, 0x00, 0x36, 0x20, 0xd1, 0x50,
0xe7, 0xd8, 0xad, 0x58, 0x20, 0x09, 0x22, 0x80, 0xd0, 0xca, 0x5d, 0x1a, 0xd7, 0xf1, 0x60, 0x75,
0x2a, 0xf2, 0xd7, 0xf8, 0xc0, 0x32, 0x45, 0x86, 0x00, 0x43, 0x01, 0xfe, 0x80, 0xf7, 0x42, 0x81,
0x74, 0x84, 0x4c, 0xa1, 0x60, 0x4c, 0xcb, 0x14, 0x58, 0x01, 0x4d, 0x18, 0xa1, 0xaa, 0x47, 0x0e,
0x11, 0x1a, 0x40, 0x7d, 0x41, 0x02, 0xe3, 0x30, 0xcd, 0x33, 0x81, 0x34, 0x06, 0x46, 0x83, 0xa2,
0x47, 0x1c, 0x04, 0xaa, 0x20, 0x12, 0xa2, 0x8b, 0x81, 0xc4, 0x9c, 0xa0, 0x2e, 0x06, 0x32, 0xf8,
0x86, 0x85, 0x01, 0xe8, 0x70, 0xf9, 0x46, 0x09, 0x6a, 0xbf, 0xe0, 0xf5, 0xa4, 0xc8, 0x78, 0xe7,
0xd2, 0x97, 0x0b, 0xbc, 0x3c, 0x97, 0xff, 0xd5, 0x40, 0x94, 0xb2, 0xc1, 0x18, 0x18, 0x11, 0x1f,
0x43, 0xc1, 0x18, 0xc3, 0x83, 0x7f, 0x9a, 0x31, 0xc4, 0x8e, 0x70, 0x56, 0xda, 0xf6, 0x17, 0xde,
0xd1, 0x02, 0x0d, 0x42, 0x21, 0x13, 0xdc, 0x3a, 0x3c, 0x40, 0x9e, 0xf4, 0x01, 0x43, 0xea, 0x0c,
0x46, 0x73, 0xa2, 0x7b, 0x0c, 0x80, 0xff, 0xe4, 0xad, 0x2e, 0x09, 0xb4, 0x63, 0xb0, 0x8c, 0x54,
0x59, 0xfa, 0xac, 0x76, 0x36, 0x10, 0x05, 0xf0, 0x98, 0x88, 0x83, 0x42, 0x00, 0x20, 0x71, 0xcc,
0xc1, 0xa9, 0x97, 0x3e, 0x5a, 0x0d, 0x04, 0x50, 0x92, 0x23, 0x20, 0x0d, 0x0a, 0x1c, 0x57, 0xd7,
0xff, 0x10, 0xf2, 0x03, 0x0f, 0x58, 0x1b, 0xa5, 0x11, 0xf8, 0xf1, 0xb4, 0x12, 0xdb, 0x1a, 0x48,
0x56, 0x1f, 0xe3, 0xc7, 0x50, 0xe9, 0x16, 0xb4, 0xbc, 0xb0, 0x40, 0x93, 0xea, 0xb5, 0x5b, 0x2f,
0xfc, 0x50, 0x0a, 0x6f, 0xcc, 0x25, 0xe0, 0x06, 0xab, 0x5f, 0x24, 0xfe, 0x8b, 0xcb, 0x42, 0x43,
0x7e, 0x69, 0x02, 0x25, 0xc7, 0x38, 0x00, 0x6e, 0xe5, 0x80, 0xa8, 0xa4, 0x30, 0x44, 0x15, 0x8f,
0xe9, 0x0c, 0xd3, 0xa6, 0xc2, 0x14, 0x34, 0x4a, 0xfe, 0x03, 0x7f, 0x06, 0xa5, 0x91, 0x02, 0x54,
0xf1, 0xa1, 0xa1, 0x53, 0xbf, 0x11, 0xf2, 0x8f, 0x83, 0x67, 0x80, 0x09, 0x08, 0x12, 0x3f, 0xfd,
0x44, 0x91, 0xc2, 0x83, 0x30, 0x50, 0x07, 0x02, 0x82, 0x4d, 0x31, 0x34, 0x06, 0x41, 0x79, 0x6f,
0xf0, 0xcc, 0x03, 0x79, 0x00, 0x2c, 0x05, 0x24, 0xec, 0x8d, 0x29, 0x15, 0xaf, 0x44, 0xc8, 0xeb,
0x4f, 0xe1, 0xfd, 0xf1, 0x41, 0x48, 0x81, 0x08, 0xaf, 0xfe, 0x51, 0x48, 0xce, 0xe7, 0xf9, 0xb6,
0x0a, 0x30, 0x83, 0x11, 0xf0, 0x0c, 0x3b, 0xd2, 0xa6, 0x24, 0x24, 0xef, 0x25, 0xfa, 0x5a, 0x3e,
0x92, 0x3e, 0x79, 0x0e, 0x35, 0x61, 0xc8, 0xaa, 0x1c, 0x2e, 0x9a, 0x27, 0x7f, 0xff, 0xf0, 0x7d,
0x30, 0x5b, 0xbc, 0x91, 0xff, 0xfe, 0x43, 0x24, 0x28, 0x66, 0xa7, 0x70, 0x99, 0x28, 0x6e, 0x2b,
0x18, 0x2b, 0xd4, 0xa1, 0x77, 0x3b, 0x96, 0x9f, 0xf7, 0xeb, 0xbe, 0x1f, 0x04, 0x34, 0x75, 0x84,
0x31, 0x42, 0x4c, 0x65, 0xaa, 0x09, 0x50, 0xa0, 0xc4, 0x51, 0x31, 0xd3, 0x26, 0x3a, 0x1b, 0xf4,
0x6e, 0x4a, 0x4e, 0x17, 0x25, 0x84, 0x78, 0x7d, 0x2c, 0x3f, 0x46, 0x18, 0xca, 0x5f, 0xf9, 0xe5,
0x38, 0x2f, 0xd8, 0x71, 0x94, 0x94, 0xe2, 0xcc, 0xa3, 0x15, 0xb0, 0xda, 0xa9, 0xcb, 0x58, 0xe4,
0x18, 0x77, 0x93, 0x8a, 0x51, 0xc6, 0x23, 0xc4, 0x4e, 0x6d, 0xd9, 0x14, 0x1e, 0x9b, 0x8d, 0xbc,
0xcb, 0x9d, 0xc4, 0x18, 0x05, 0xf5, 0xa9, 0x29, 0xf8, 0x6d, 0x29, 0x38, 0xc7, 0x44, 0xe5, 0x3a,
0xcd, 0xba, 0x61, 0x98, 0x4a, 0x57, 0x02, 0x96, 0x42, 0x02, 0xd9, 0x37, 0x11, 0xde, 0x2d, 0xd4,
0x3f, 0xfe, 0x61, 0xe7, 0x33, 0xd7, 0x89, 0x4a, 0xdd, 0xb0, 0x34, 0x47, 0xf4, 0xdc, 0xad, 0xaa,
0xc9, 0x9d, 0x7e, 0x6d, 0x4b, 0xcc, 0xdc, 0x17, 0x89, 0x57, 0xfd, 0xbb, 0x37, 0x75, 0x47, 0x5a,
0xec, 0x2c, 0x6e, 0x3c, 0x15, 0x92, 0x54, 0x64, 0x2c, 0xab, 0x9e, 0xab, 0x2b, 0xdd, 0x3c, 0x66,
0xa0, 0x8f, 0x47, 0x5e, 0x93, 0x1a, 0x37, 0x16, 0xf4, 0x89, 0x23, 0x00, 0x00, 0xb0, 0x33, 0x56,
0xfa, 0x14, 0x1e, 0xff, 0x48, 0x7a, 0x7e, 0x0f, 0x10, 0x1f, 0xf4, 0x91, 0xc8, 0x10, 0x56, 0x84,
0xff, 0x08, 0xec, 0xb4, 0xac, 0x0e, 0x0f, 0xff, 0xad, 0xc5, 0xe0, 0x1a, 0x2f, 0x82, 0x04, 0x9f,
0x91, 0xc2, 0x0e, 0xfe, 0x48, 0x36, 0x79, 0x01, 0x42, 0x14, 0xff, 0xfe, 0x30, 0xf0, 0x08, 0x18,
0xf1, 0x81, 0x45, 0x9a, 0x60, 0xc1, 0x79, 0xf0, 0x14, 0x12, 0x10, 0xce, 0xea, 0x31, 0x5a, 0xff,
0xfc, 0x20, 0x13, 0x82, 0x2f, 0xc9, 0x02, 0x1f, 0x81, 0xcb, 0x00, 0xe1, 0x10, 0xd2, 0xb4, 0xbe,
0x87, 0xff, 0xb0, 0x1e, 0x27, 0x81, 0xb7, 0x04, 0x06, 0x3c, 0xc2, 0x04, 0xf6, 0x06, 0x0e, 0x28,
0xbc, 0x40, 0xbf, 0x12, 0x1e, 0x86, 0xd4, 0x6a, 0x7f, 0x18, 0x1b, 0x96, 0x85, 0x4c, 0x16, 0x80,
0xdf, 0x2c, 0xa5, 0x8d, 0x86, 0xa3, 0x4a, 0x8a, 0xb4, 0x1b, 0xa1, 0x38, 0xa9, 0xd5, 0xff, 0xff,
0xea, 0x06, 0x20, 0xd2, 0x95, 0x1e, 0xf4, 0x2f, 0xb2, 0x12, 0x0e, 0x61, 0x78, 0x4a, 0x17, 0x52,
0x5d, 0xe4, 0x25, 0x1f, 0xfe, 0xc0, 0xb3, 0x1f, 0xff, 0xff, 0xec, 0x02, 0x82, 0x80, 0x90, 0x41,
0x88, 0xde, 0x48, 0x2c, 0x42, 0x52, 0x0b, 0x2f, 0x43, 0x7e, 0x50, 0x78, 0xf2, 0x67, 0x78, 0x41,
0x34, 0x3d, 0xc8, 0x0f, 0x67, 0xa1, 0xeb, 0x21, 0xfe, 0xc0, 0x1f, 0x22, 0x60, 0x41, 0x6c, 0x00,
0x92, 0x4b, 0x60, 0x10, 0xd0, 0x0d, 0x01, 0x35, 0x05, 0x0e, 0x87, 0xa2, 0xa0, 0x5d, 0x1f, 0xa3,
0xaf, 0x7f, 0xf1, 0xbe, 0x8f, 0xcd, 0xa5, 0x00, 0x1c, 0x10, 0x40, 0x15, 0x76, 0x81, 0x05, 0xef,
0xee, 0x00, 0x60, 0x84, 0x00, 0x99, 0x40, 0x4a, 0x82, 0x17, 0xe9, 0xfc, 0xc4, 0x7f, 0xff, 0xfd,
0x04, 0x80, 0x06, 0x06, 0xdc, 0xaf, 0xa7, 0x7e, 0x94, 0x75, 0x74, 0x01, 0x00, 0xe0, 0x91, 0x00,
0x85, 0x7f, 0x8e, 0xd6, 0x0b, 0x20, 0x21, 0x30, 0xca, 0x62, 0x8e, 0x07, 0x04, 0xe9, 0x45, 0x40,
0x5f, 0x47, 0x4a, 0x30, 0x15, 0x41, 0xcb, 0xdf, 0xff, 0xfc, 0xbf, 0xc3, 0xb4, 0x46, 0x6a, 0x01,
0x40, 0xd0, 0xa7, 0x34, 0x18, 0x24, 0x1c, 0x2a, 0x45, 0xfe, 0xa8, 0x05, 0x08, 0x61, 0xfd, 0xa8,
0x80, 0x71, 0x01, 0x25, 0x9c, 0xc1, 0x47, 0x17, 0x37, 0x02, 0x7a, 0x15, 0xff, 0xf3, 0x01, 0x45,
0x7f, 0xd6, 0x80, 0x60, 0x83, 0x67, 0xf8, 0x9d, 0x2f, 0xf4, 0xdd, 0x8c, 0x30, 0x01, 0x51, 0x42,
0xbc, 0x43, 0x7a, 0x6b, 0x9f, 0x84, 0x1e, 0x00, 0x48, 0xc1, 0xe0, 0xb7, 0xe0, 0x7e, 0x99, 0xf2,
0x4a, 0xe9, 0x40, 0x02, 0x81, 0xc3, 0x00, 0x24, 0x3a, 0xc5, 0x52, 0x0f, 0x91, 0xc8, 0x68, 0x25,
0x40, 0x99, 0xa4, 0x25, 0x1a, 0x04, 0xd0, 0xa2, 0x91, 0xdd, 0xeb, 0x93, 0x00, 0x21, 0x49, 0x24,
0x8b, 0x40, 0x75, 0x38, 0x14, 0xa1, 0xfd, 0x3f, 0x88, 0x25, 0xbf, 0x32, 0x00, 0xe3, 0x19, 0xfc,
0xb9, 0xf8, 0x6f, 0x81, 0xc0, 0x01, 0xb3, 0x93, 0x20, 0x09, 0x08, 0x25, 0x84, 0xe1, 0x34, 0xd4,
0x1b, 0x48, 0x88, 0x11, 0xa0, 0x15, 0x59, 0xd7, 0x07, 0x81, 0x81, 0x3b, 0xa1, 0x40, 0x2e, 0x2f,
0x48, 0x70, 0x09, 0xc4, 0x76, 0x49, 0x0f, 0x2e, 0x50, 0x2e, 0x46, 0x19, 0xa4, 0x16, 0xa2, 0x1b,
0x84, 0xa2, 0x89, 0x58, 0xfc, 0x4f, 0x3f, 0x40, 0x90, 0x4c, 0xa3, 0x01, 0x32, 0x09, 0x02, 0x80,
0x9c, 0x91, 0x13, 0x2c, 0xba, 0xde, 0x5d, 0x99, 0xf2, 0xff, 0xff, 0x3d, 0x5a, 0x1f, 0xa9, 0x02,
0x90, 0x8f, 0xf3, 0x08, 0xbd, 0x01, 0xf8, 0xd0, 0x2a, 0x95, 0x41, 0x0c, 0x40, 0x0a, 0x20, 0xc4,
0xd4, 0xcc, 0x6b, 0x0f, 0xf0, 0x80, 0xb1, 0x5d, 0x28, 0x3d, 0x08, 0xc2, 0xf8, 0x31, 0x02, 0x49,
0x88, 0x14, 0x28, 0xed, 0xe8, 0x86, 0x3b, 0x00, 0x9f, 0x95, 0x06, 0x37, 0x15, 0xa4, 0x59, 0xc8,
0x80, 0xb6, 0x10, 0xf0, 0xe5, 0xb8, 0x18, 0x00, 0x56, 0x1c, 0xff, 0x95, 0x21, 0x0e, 0x7f, 0x2b,
0xc5, 0x08, 0x59, 0x10, 0xe1, 0x46, 0x31, 0x8d, 0xec, 0xe0, 0xa1, 0x99, 0xbb, 0x21, 0xff, 0xfe,
0x30, 0x10, 0xd0, 0x05, 0xe3, 0x08, 0x50, 0xfc, 0xf3, 0x0e, 0x00, 0x8d, 0x68, 0x8e, 0x07, 0xa6,
0x80, 0x34, 0x42, 0xed, 0x1f, 0x88, 0x00, 0xf0, 0x8a, 0x21, 0xae, 0xf7, 0xfb, 0x80, 0x28, 0x86,
0x0f, 0xff, 0xff, 0x82, 0xea, 0x47, 0x95, 0x91, 0xe0, 0x04, 0x01, 0x44, 0x0c, 0x29, 0xff, 0x0e,
0x33, 0xe8, 0xc0, 0x54, 0x04, 0x23, 0xfc, 0x81, 0x5b, 0xf0, 0x3c, 0x07, 0x10, 0x70, 0x30, 0xd8,
0x21, 0x6f, 0xef, 0xde, 0x46, 0x09, 0x43, 0xfa, 0x5f, 0xff, 0x0d, 0x72, 0x30, 0xdd, 0x00, 0xdb,
0xe4, 0x48, 0x24, 0x97, 0x08, 0x46, 0xb1, 0x49, 0xc4, 0x4d, 0x80, 0x12, 0x60, 0xff, 0xa4, 0xa6,
0xff, 0xf6, 0x8c, 0x00, 0x40, 0x05, 0x02, 0xb4, 0x0f, 0xf0, 0x3e, 0xfc, 0x84, 0x38, 0x81, 0x94,
0x8b, 0xfe, 0x49, 0xef, 0xc0, 0x10, 0x49, 0x88, 0x28, 0xa2, 0x1c, 0x2a, 0x8b, 0x64, 0xd4, 0x86,
0xd7, 0xff, 0xff, 0xff, 0xeb, 0x91, 0x6b, 0x11, 0x10, 0x00, 0x69, 0x4c, 0xbf, 0xb4, 0x1c, 0xd8,
0x00, 0x07, 0x16, 0x80, 0x60, 0x0a, 0x1c, 0x82, 0x42, 0x27, 0x82, 0x43, 0xc9, 0x0a, 0x64, 0x20,
0x5a, 0x5f, 0x4e, 0xbf, 0x8c, 0x38, 0x82, 0x36, 0x02, 0x07, 0x72, 0x79, 0x07, 0x23, 0xb4, 0xbb,
0x57, 0x5f, 0xe8, 0x04, 0xdd, 0x39, 0xe9, 0x07, 0x95, 0xbe, 0x04, 0x2b, 0xdd, 0x8e, 0x22, 0xdc,
0x14, 0x2c, 0x61, 0xa3, 0xa9, 0xcd, 0x4f, 0x82, 0x5d, 0xa0, 0x44, 0xdf, 0xf4, 0x96, 0xff, 0xf5,
0x2b, 0xff, 0xfe, 0x01, 0x19, 0xd2, 0xa2, 0x9e, 0x43, 0xa5, 0x7f, 0xf0, 0x4c, 0x4c, 0x2b, 0x3c,
0x33, 0xe2, 0x55, 0xff, 0x04, 0x06, 0x29, 0x2c, 0x0d, 0x22, 0x5d, 0x7c, 0x93, 0xba, 0x18, 0xaf,
0xf9, 0x32, 0xa6, 0xc3, 0x99, 0x46, 0x79, 0xe3, 0x06, 0xa6, 0x38, 0x8b, 0x92, 0x22, 0x4b, 0xdb,
0x1b, 0x36, 0x20, 0xb0, 0x6c, 0x20, 0xce, 0x37, 0x42, 0xe1, 0x66, 0xd4, 0x49, 0x34, 0x42, 0x8b,
0xfa, 0x9c, 0x12, 0x99, 0xdc, 0x06, 0x87, 0xfa, 0x46, 0xf8, 0x2f, 0x04, 0xa9, 0xd8, 0x82, 0x07,
0xa6, 0x30, 0x0f, 0xc0, 0xdf, 0x35, 0xe8, 0x90, 0xf0, 0xff, 0xff, 0xa8, 0xe0, 0xd7, 0x02, 0x60,
0x1a, 0xc3, 0x20, 0x28, 0xa2, 0x31, 0x29, 0x3c, 0xeb, 0x04, 0xa5, 0xdd, 0x48, 0x0e, 0x82, 0xa4,
0xb6, 0x56, 0x22, 0x06, 0x57, 0xe0, 0xda, 0x10, 0x27, 0x31, 0x0e, 0x11, 0x77, 0xfe, 0x02, 0x60,
0x16, 0x48, 0x81, 0x8c, 0x0d, 0x05, 0x17, 0x7f, 0xcb, 0xbb, 0x7e, 0x25, 0x2a, 0x41, 0xfd, 0x8a,
0x7f, 0xc9, 0x36, 0x7c, 0xe0, 0x98, 0x7e, 0x92, 0xef, 0x7e, 0x06, 0x03, 0x13, 0x3e, 0x20, 0x3a,
0xbf, 0x4c, 0xc3, 0x0f, 0x2e, 0x80, 0x74, 0xbf, 0x39, 0x3c, 0xf0, 0xa6, 0xb2, 0xe9, 0x3f, 0x41,
0x55, 0x1f, 0x2c, 0xf5, 0xd2, 0x7e, 0x8c, 0xae, 0x4e, 0xaa, 0x61, 0x3c, 0xbc, 0x3f, 0xc4, 0xc7,
0x36, 0xdc, 0x23, 0xc8, 0xb8, 0x52, 0xe2, 0x8a, 0x80, 0x18, 0x00, 0x00, 0xb2, 0x46, 0xa2, 0x56,
0x0d, 0x12, 0x94, 0xaa, 0xbd, 0x01, 0x07, 0xff, 0xfa, 0x34, 0x0c, 0x5f, 0xf8, 0x0c, 0x12, 0x50,
0xaf, 0xd6, 0xd1, 0x89, 0x40, 0xa4, 0xff, 0xe0, 0xce, 0xc4, 0x49, 0x25, 0x9d, 0xc1, 0xff, 0x7e,
0x60, 0x24, 0x5d, 0xcc, 0x10, 0xc0, 0xbe, 0x5a, 0x12, 0xd3, 0xc3, 0xfe, 0x2d, 0x40, 0x7c, 0x28,
0x9e, 0x71, 0x01, 0xd2, 0x6e, 0x86, 0x0b, 0xc8, 0xf2, 0x9b, 0x45, 0x08, 0x4c, 0x04, 0x52, 0x7e,
0xf2, 0x7e, 0xd9, 0xcc, 0x0b, 0x1c, 0x20, 0x80, 0xae, 0xaf, 0xfe, 0xb0, 0x6d, 0x23, 0xf2, 0x41,
0xe3, 0x2e, 0x20, 0x11, 0x4b, 0x74, 0x89, 0xdd, 0xff, 0xa8, 0x38, 0xa3, 0x95, 0x82, 0x15, 0xf0,
0xd0, 0xd5, 0xf1, 0x92, 0x8e, 0xee, 0xc0, 0x26, 0x81, 0xe9, 0x47, 0xff, 0xee, 0x0d, 0x20, 0x34,
0x31, 0x3a, 0xef, 0x40, 0xb2, 0x29, 0x47, 0x19, 0x7f, 0x04, 0x27, 0xf1, 0x90, 0x85, 0x09, 0x86,
0x7d, 0x42, 0xe2, 0x54, 0x5d, 0x5f, 0xe8, 0x0e, 0xd0, 0x2c, 0xaa, 0x16, 0xbf, 0x04, 0xa7, 0xf8,
0xa2, 0x46, 0x0b, 0x08, 0x7a, 0x79, 0xe9, 0x28, 0x62, 0x7c, 0x33, 0xf4, 0x0b, 0x14, 0x82, 0xfa,
0x61, 0xeb, 0xc1, 0xff, 0x4c, 0xa4, 0x11, 0x7f, 0x03, 0x68, 0x44, 0xc1, 0x1f, 0x81, 0x3a, 0x6c,
0x77, 0x95, 0x02, 0x2b, 0x53, 0x80, 0xe5, 0x10, 0x1e, 0x90, 0xe8, 0xfd, 0x1f, 0xa6, 0x40, 0x0b,
0x13, 0xff, 0x4e, 0x4d, 0x7f, 0x52, 0xe8, 0xaf, 0x9a, 0xc1, 0x80, 0x0f, 0x0a, 0x14, 0x02, 0x3c,
0xc0, 0x09, 0x13, 0xe7, 0xdc, 0xc0, 0x1a, 0x28, 0xa0, 0xe4, 0x83, 0x8e, 0x03, 0x88, 0xd5, 0xaf,
0x1a, 0xbd, 0x91, 0x00, 0xb7, 0x4e, 0xba, 0xdf, 0xf8, 0xdb, 0xcc, 0x02, 0x43, 0xc4, 0x14, 0x2a,
0x3f, 0xc8, 0x0d, 0x09, 0x1c, 0x44, 0xf4, 0x01, 0x3c, 0xca, 0x28, 0x56, 0x80, 0xa6, 0x85, 0x00,
0xea, 0x3e, 0x8f, 0xeb, 0x9f, 0xfc, 0x6e, 0x07, 0xc4, 0xe0, 0x30, 0x78, 0xa0, 0x1e, 0x6f, 0x54,
0x78, 0x51, 0xff, 0x56, 0x4a, 0x01, 0x47, 0x02, 0x4c, 0x21, 0x3b, 0xfb, 0x90, 0x0a, 0xcc, 0x1d,
0xd2, 0x47, 0xff, 0xfc, 0x70, 0x18, 0x22, 0xc0, 0xb9, 0x2f, 0xe9, 0x7f, 0x91, 0xd3, 0x66, 0x2f,
0x80, 0x2c, 0x24, 0xa7, 0xfa, 0x84, 0x51, 0xab, 0x6b, 0x72, 0x00, 0xab, 0x33, 0x04, 0xcf, 0x43,
0xff, 0x17, 0x51, 0x84, 0x0c, 0x01, 0x50, 0x10, 0x8f, 0x90, 0x34, 0x41, 0x44, 0x84, 0x8e, 0x08,
0x19, 0x04, 0x48, 0x50, 0x84, 0x38, 0x3d, 0x02, 0x52, 0xf9, 0x7c, 0xd2, 0xd0, 0x1f, 0x13, 0x42,
0xa0, 0x21, 0x41, 0xc4, 0x02, 0x02, 0x3d, 0x09, 0xc8, 0xfd, 0x60, 0x7d, 0x35, 0x4f, 0x7f, 0xff,
0xf9, 0x97, 0x6a, 0xd8, 0x00, 0xc3, 0x83, 0x00, 0x09, 0x50, 0x4b, 0x90, 0x8a, 0xc7, 0x94, 0x4d,
0x47, 0xc1, 0x62, 0x32, 0x28, 0x24, 0x09, 0x52, 0x2e, 0x2e, 0x1c, 0x96, 0x44, 0xa0, 0x09, 0xc8,
0xce, 0x64, 0xa9, 0x1c, 0x19, 0x0e, 0x52, 0x3e, 0x3e, 0x19, 0x93, 0xa0, 0x36, 0x26, 0x22, 0x08,
0x9a, 0x00, 0xdd, 0x66, 0x3a, 0x93, 0xd5, 0x89, 0xd1, 0x40, 0x06, 0xd4, 0xa8, 0x22, 0x73, 0x7b,
0x3d, 0x3f, 0xe3, 0x04, 0x94, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x56, 0x77, 0xac, 0xe0, 0xc4, 0x06,
0x1f, 0xb8, 0xa5, 0x80, 0xfd, 0x68, 0x1c, 0x32, 0x16, 0x03, 0xde, 0x71, 0x2a, 0x3d, 0x14, 0x19,
0xbe, 0xc2, 0x88, 0xd9, 0x24, 0x92, 0x5f, 0xc5, 0x90, 0x0a, 0x85, 0xc2, 0x3f, 0x87, 0x03, 0xa8,
0x26, 0x17, 0xc4, 0x06, 0x86, 0x12, 0x87, 0x76, 0x0a, 0x48, 0x16, 0xed, 0x96, 0x93, 0xec, 0x1b,
0x30, 0x73, 0xe8, 0x1a, 0x3f, 0xff, 0x4d, 0xce, 0x40, 0xf3, 0x0c, 0x51, 0x4b, 0x84, 0x9e, 0x67,
0x2b, 0x15, 0x40, 0x1a, 0xa0, 0xfc, 0x10, 0x0f, 0xd8, 0x81, 0x35, 0x87, 0xff, 0x98, 0x0f, 0x40,
0x00, 0xba, 0xc0, 0x71, 0xe2, 0x00, 0x18, 0x28, 0xb3, 0x82, 0xcc, 0x80, 0x6a, 0xa0, 0x43, 0xff,
0x2d, 0xd6, 0x04, 0x8a, 0x68, 0xff, 0xff, 0xff, 0xfc, 0x1a, 0xf3, 0x1a, 0x2a, 0x06, 0xc0, 0x01,
0x40, 0x0c, 0x30, 0xc1, 0xd0, 0xd7, 0x4f, 0xcb, 0x74, 0x1f, 0x07, 0xd3, 0xb4, 0x0d, 0x88, 0x98,
0xea, 0xda, 0x9f, 0xce, 0x2b, 0x3c, 0x55, 0xb3, 0x40, 0x14, 0xff, 0xff, 0xff, 0xea, 0xdb, 0x9b,
0x92, 0xd8, 0x68, 0x08, 0x0b, 0x41, 0x09, 0x26, 0x40, 0x8c, 0xf1, 0xb0, 0x9a, 0x98, 0xc0, 0x80,
0x8b, 0xf0, 0x3d, 0xe7, 0xec, 0x19, 0x68, 0x21, 0x03, 0x29, 0x7f, 0xe1, 0x6d, 0x4c, 0x0f, 0x01,
0xd1, 0x51, 0x01, 0x1a, 0x50, 0x2a, 0x59, 0x27, 0x80, 0xc1, 0x6e, 0x33, 0xf1, 0x80, 0xe1, 0x49,
0x08, 0xe9, 0x17, 0xff, 0xff, 0xff, 0x80, 0x5a, 0x10, 0x10, 0x36, 0x5e, 0xca, 0xf8, 0x3a, 0x00,
0x1e, 0xb0, 0x06, 0x84, 0x01, 0xf3, 0x07, 0x1b, 0x4a, 0xc0, 0x1e, 0x21, 0x43, 0x8e, 0xa5, 0x55,
0x77, 0xc7, 0x65, 0x7c, 0xc2, 0xdf, 0x5e, 0x0c, 0x42, 0x20, 0xd2, 0x48, 0x61, 0xc8, 0x1c, 0x65,
0xf8, 0xfe, 0x4c, 0x88, 0x71, 0x1f, 0x82, 0x50, 0x81, 0xa3, 0x54, 0x09, 0x13, 0x28, 0x52, 0xf5,
0xe0, 0x82, 0xc3, 0x06, 0x7f, 0xfa, 0x2c, 0xcf, 0xf8, 0xf4, 0x7f, 0xff, 0xfd, 0x01, 0x49, 0xa4,
0xb8, 0xde, 0x62, 0x84, 0xfe, 0xed, 0x65, 0x1f, 0x3c, 0x3c, 0xb2, 0x50, 0x76, 0x30, 0x5b, 0x03,
0xc0, 0x08, 0xa6, 0x64, 0x90, 0xc8, 0xcd, 0x14, 0x6e, 0x69, 0x46, 0x7a, 0xc6, 0x1c, 0x87, 0xd7,
0x48, 0x7b, 0x49, 0x05, 0x2d, 0x5e, 0x7f, 0xcb, 0x67, 0xf0, 0xd9, 0x0d, 0x1e, 0x9e, 0x53, 0xb7,
0x64, 0xa5, 0xa5, 0x10, 0x39, 0x06, 0x11, 0x3f, 0xb1, 0xa9, 0xa6, 0xe8, 0x4d, 0x47, 0x77, 0xda,
0x43, 0x76, 0x89, 0x45, 0x09, 0x70, 0xc2, 0x38, 0x0f, 0x09, 0x6f, 0xe7, 0x2d, 0x82, 0x35, 0x07,
0xfe, 0x64, 0x18, 0x2e, 0xb8, 0x04, 0x42, 0x54, 0x80, 0x43, 0x12, 0x6c, 0x9a, 0x55, 0xc9, 0x0a,
0xa0, 0x79, 0x47, 0x52, 0x65, 0x2a, 0xff, 0x50, 0x11, 0xc9, 0x4e, 0xfe, 0x5b, 0x30, 0xa4, 0xe8,
0x30, 0x63, 0xff, 0x21, 0x12, 0x1b, 0xdc, 0x1c, 0x01, 0x41, 0x51, 0x1f, 0xff, 0xfa, 0xc3, 0xe3,
0x55, 0xf1, 0x66, 0xe2, 0xd5, 0x78, 0x5e, 0xfa, 0x4d, 0xf2, 0x61, 0x01, 0x26, 0x15, 0xa9, 0xf9,
0xd9, 0x32, 0x41, 0x90, 0x36, 0x4e, 0xae, 0xe3, 0x0b, 0x16, 0x56, 0x8c, 0x6e, 0x42, 0x5d, 0xd8,
0x1e, 0xfe, 0x1d, 0x40, 0x3a, 0x50, 0x9f, 0x09, 0x14, 0xeb, 0x6e, 0x48, 0x7a, 0x91, 0x88, 0x7b,
0x7d, 0x8f, 0x72, 0x42, 0x39, 0xb0, 0x1c, 0x65, 0x18, 0x23, 0x8b, 0x60, 0x30, 0x00,
/* FRAME_END as in 4.2.3 */
0xc5, 0xcc, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00
};
static UINT32 refImage[] = { /* 4.2.4.4 Inverse Color Conversion */
0x00229cdf, 0x00249de0, 0x00259fe2, 0x002ca5e8, 0x00229cdf, 0x00229ce0, 0x00239de0, 0x00229ce0,
0x00229cdf, 0x00229cdf, 0x00239ce0, 0x00249ce0, 0x00249ce0, 0x00219ce3, 0x001e9ce6, 0x00209ae2,
0x002299dd, 0x002199de, 0x00209adf, 0x00209ae0, 0x001f9be0, 0x001e9ae0, 0x001d99e0, 0x001c98e0,
@ -756,7 +721,88 @@ const UINT32 TEST_RFX_XRGB_IMAGE[4096] =
0x00169ff8, 0x00159ef7, 0x00149df7, 0x00139cf6, 0x00129bf5, 0x00129bf5, 0x00129bf5, 0x00129bf5
};
#define IMG_WIDTH 64
#define IMG_HEIGHT 64
#define FORMAT_SIZE 4
#define FORMAT PIXEL_FORMAT_XRGB32
static INLINE size_t fuzzyCompare(BYTE b1, BYTE b2)
{
if (b1 > b2)
return b1 - b2;
return b2 - b1;
}
static BOOL fuzzyCompareImage(const UINT32 *refImage, const BYTE *img, size_t npixels) {
size_t i;
size_t totalDelta = 0;
for(i = 0; i < npixels; i++, refImage++)
{
BYTE A = *img++;
BYTE R = *img++;
BYTE G = *img++;
BYTE B = *img++;
size_t delta;
if (A != 0x00)
return FALSE;
delta = fuzzyCompare(R, (*refImage & 0x00ff0000) >> 16);
if (delta > 1)
return FALSE;
totalDelta += delta;
delta = fuzzyCompare(G, (*refImage & 0x0000ff00) >> 8);
if (delta > 1)
return FALSE;
totalDelta += delta;
delta = fuzzyCompare(B, (*refImage & 0x0000ff));
if (delta > 1)
return FALSE;
totalDelta += delta;
}
WLog_DBG("test", "totalDelta=%d (npixels=%d)", totalDelta, npixels);
return TRUE;
}
int TestFreeRDPCodecRemoteFX(int argc, char* argv[])
{
REGION16 region;
RFX_CONTEXT* context;
BYTE *dest;
size_t stride = FORMAT_SIZE * IMG_WIDTH;
context = rfx_context_new(FALSE);
if (!context)
return -1;
dest = calloc(IMG_WIDTH * IMG_HEIGHT, FORMAT_SIZE);
if (!dest)
return -2;
region16_init(&region);
if (!rfx_process_message(context, encodeHeaderSample, sizeof(encodeHeaderSample), 0, 0, dest, FORMAT,
stride, IMG_HEIGHT, &region))
return -3;
region16_clear(&region);
if(!rfx_process_message(context, encodeDataSample, sizeof(encodeDataSample), 0, 0, dest, FORMAT,
stride, IMG_HEIGHT, &region))
return -4;
region16_print(&region);
#if 0
FILE *f = fopen("/tmp/windows.data", "w");
fwrite(dest, IMG_WIDTH * IMG_HEIGHT, FORMAT_SIZE, f);
fclose(f);
#endif
if (!fuzzyCompareImage(refImage, dest, IMG_WIDTH * IMG_HEIGHT))
return -5;
return 0;
}