mirror of https://github.com/FreeRDP/FreeRDP
[codec,rfx] added missing RFX encoder API calls
This commit is contained in:
parent
ff303a9bda
commit
a41360e3b0
|
@ -118,11 +118,21 @@ extern "C"
|
|||
FREERDP_API void rfx_context_free(RFX_CONTEXT* context);
|
||||
|
||||
FREERDP_API BOOL rfx_context_reset(RFX_CONTEXT* context, UINT32 width, UINT32 height);
|
||||
|
||||
FREERDP_API BOOL rfx_context_set_mode(RFX_CONTEXT* context, RLGR_MODE mode);
|
||||
FREERDP_API RLGR_MODE rfx_context_get_mode(RFX_CONTEXT* context);
|
||||
|
||||
FREERDP_API void rfx_context_set_pixel_format(RFX_CONTEXT* context, UINT32 pixel_format);
|
||||
FREERDP_API UINT32 rfx_context_get_pixel_format(RFX_CONTEXT* context);
|
||||
|
||||
FREERDP_API void rfx_context_set_palette(RFX_CONTEXT* context, const BYTE* palette);
|
||||
FREERDP_API const BYTE* rfx_context_get_palette(RFX_CONTEXT* context);
|
||||
|
||||
FREERDP_API UINT32 rfx_context_get_frame_idx(const RFX_CONTEXT* context);
|
||||
|
||||
FREERDP_API BOOL rfx_write_message_progressive_simple(RFX_CONTEXT* rfx, wStream* s,
|
||||
const RFX_MESSAGE* msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "rfx_quantization.h"
|
||||
#include "rfx_dwt.h"
|
||||
#include "rfx_rlgr.h"
|
||||
#include "rfx_constants.h"
|
||||
#include "rfx_types.h"
|
||||
#include "progressive.h"
|
||||
|
||||
|
@ -54,42 +55,6 @@ typedef struct
|
|||
BOOL mode;
|
||||
} RFX_PROGRESSIVE_UPGRADE_STATE;
|
||||
|
||||
static INLINE BOOL progressive_write_tile_simple(PROGRESSIVE_CONTEXT* progressive, wStream* s,
|
||||
const RFX_TILE* tile);
|
||||
|
||||
static const char* progressive_get_block_type_string(UINT16 blockType)
|
||||
{
|
||||
switch (blockType)
|
||||
{
|
||||
case PROGRESSIVE_WBT_SYNC:
|
||||
return "PROGRESSIVE_WBT_SYNC";
|
||||
|
||||
case PROGRESSIVE_WBT_FRAME_BEGIN:
|
||||
return "PROGRESSIVE_WBT_FRAME_BEGIN";
|
||||
|
||||
case PROGRESSIVE_WBT_FRAME_END:
|
||||
return "PROGRESSIVE_WBT_FRAME_END";
|
||||
|
||||
case PROGRESSIVE_WBT_CONTEXT:
|
||||
return "PROGRESSIVE_WBT_CONTEXT";
|
||||
|
||||
case PROGRESSIVE_WBT_REGION:
|
||||
return "PROGRESSIVE_WBT_REGION";
|
||||
|
||||
case PROGRESSIVE_WBT_TILE_SIMPLE:
|
||||
return "PROGRESSIVE_WBT_TILE_SIMPLE";
|
||||
|
||||
case PROGRESSIVE_WBT_TILE_FIRST:
|
||||
return "PROGRESSIVE_WBT_TILE_FIRST";
|
||||
|
||||
case PROGRESSIVE_WBT_TILE_UPGRADE:
|
||||
return "PROGRESSIVE_WBT_TILE_UPGRADE";
|
||||
|
||||
default:
|
||||
return "PROGRESSIVE_WBT_UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void progressive_component_codec_quant_read(wStream* s,
|
||||
RFX_COMPONENT_CODEC_QUANT* quantVal)
|
||||
{
|
||||
|
@ -1691,7 +1656,7 @@ static void CALLBACK progressive_process_tiles_tile_work_callback(PTP_CALLBACK_I
|
|||
default:
|
||||
WLog_Print(param->progressive->log, WLOG_ERROR, "Invalid block type %04" PRIx16 " (%s)",
|
||||
param->tile->blockType,
|
||||
progressive_get_block_type_string(param->tile->blockType));
|
||||
rfx_get_progressive_block_type_string(param->tile->blockType));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1728,7 +1693,7 @@ static INLINE SSIZE_T progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive
|
|||
|
||||
#if defined(WITH_DEBUG_CODECS)
|
||||
WLog_Print(progressive->log, WLOG_DEBUG, "%s",
|
||||
progressive_get_block_type_string(blockType));
|
||||
rfx_get_progressive_block_type_string(blockType));
|
||||
#endif
|
||||
|
||||
if (blockLen < 6)
|
||||
|
@ -1761,7 +1726,7 @@ static INLINE SSIZE_T progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive
|
|||
break;
|
||||
default:
|
||||
WLog_ERR(TAG, "Invalid block type %04" PRIx16 " (%s)", blockType,
|
||||
progressive_get_block_type_string(blockType));
|
||||
rfx_get_progressive_block_type_string(blockType));
|
||||
return -1039;
|
||||
}
|
||||
|
||||
|
@ -1838,7 +1803,7 @@ static INLINE SSIZE_T progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive
|
|||
if (status < 0)
|
||||
{
|
||||
WLog_Print(progressive->log, WLOG_ERROR, "Failed to decompress %s at %" PRIu16,
|
||||
progressive_get_block_type_string(tile->blockType), index);
|
||||
rfx_get_progressive_block_type_string(tile->blockType), index);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
@ -1866,182 +1831,6 @@ fail:
|
|||
return (SSIZE_T)(end - start);
|
||||
}
|
||||
|
||||
static INLINE BOOL progressive_write_wb_sync(PROGRESSIVE_CONTEXT* progressive, wStream* s)
|
||||
{
|
||||
const UINT32 blockLen = 12;
|
||||
WINPR_ASSERT(progressive);
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, blockLen))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT16(s, PROGRESSIVE_WBT_SYNC); /* blockType (2 bytes) */
|
||||
Stream_Write_UINT32(s, blockLen); /* blockLen (4 bytes) */
|
||||
Stream_Write_UINT32(s, 0xCACCACCA); /* magic (4 bytes) */
|
||||
Stream_Write_UINT16(s, 0x0100); /* version (2 bytes) */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INLINE BOOL progressive_write_wb_context(PROGRESSIVE_CONTEXT* progressive, wStream* s)
|
||||
{
|
||||
const UINT32 blockLen = 10;
|
||||
WINPR_ASSERT(progressive);
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, blockLen))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT16(s, PROGRESSIVE_WBT_CONTEXT); /* blockType (2 bytes) */
|
||||
Stream_Write_UINT32(s, blockLen); /* blockLen (4 bytes) */
|
||||
Stream_Write_UINT8(s, 0); /* ctxId (1 byte) */
|
||||
Stream_Write_UINT16(s, 64); /* tileSize (2 bytes) */
|
||||
Stream_Write_UINT8(s, 0); /* flags (1 byte) */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INLINE BOOL progressive_write_region(PROGRESSIVE_CONTEXT* progressive, wStream* s,
|
||||
const RFX_MESSAGE* msg)
|
||||
{
|
||||
/* RFX_PROGRESSIVE_REGION */
|
||||
UINT32 blockLen = 18;
|
||||
UINT32 tilesDataSize = 0;
|
||||
const size_t start = Stream_GetPosition(s);
|
||||
|
||||
WINPR_ASSERT(progressive);
|
||||
WINPR_ASSERT(s);
|
||||
WINPR_ASSERT(msg);
|
||||
|
||||
blockLen += msg->numRects * 8;
|
||||
blockLen += msg->numQuant * 5;
|
||||
tilesDataSize = msg->numTiles * 22UL;
|
||||
for (UINT16 i = 0; i < msg->numTiles; i++)
|
||||
{
|
||||
const RFX_TILE* tile = msg->tiles[i];
|
||||
WINPR_ASSERT(tile);
|
||||
tilesDataSize += tile->YLen + tile->CbLen + tile->CrLen;
|
||||
}
|
||||
blockLen += tilesDataSize;
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, blockLen))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT16(s, PROGRESSIVE_WBT_REGION); /* blockType (2 bytes) */
|
||||
Stream_Write_UINT32(s, blockLen); /* blockLen (4 bytes) */
|
||||
Stream_Write_UINT8(s, 64); /* tileSize (1 byte) */
|
||||
Stream_Write_UINT16(s, msg->numRects); /* numRects (2 bytes) */
|
||||
WINPR_ASSERT(msg->numQuant <= UINT8_MAX);
|
||||
Stream_Write_UINT8(s, (UINT8)msg->numQuant); /* numQuant (1 byte) */
|
||||
Stream_Write_UINT8(s, 0); /* numProgQuant (1 byte) */
|
||||
Stream_Write_UINT8(s, 0); /* flags (1 byte) */
|
||||
Stream_Write_UINT16(s, msg->numTiles); /* numTiles (2 bytes) */
|
||||
Stream_Write_UINT32(s, tilesDataSize); /* tilesDataSize (4 bytes) */
|
||||
|
||||
for (UINT16 i = 0; i < msg->numRects; i++)
|
||||
{
|
||||
/* TS_RFX_RECT */
|
||||
const RFX_RECT* r = &msg->rects[i];
|
||||
Stream_Write_UINT16(s, r->x); /* x (2 bytes) */
|
||||
Stream_Write_UINT16(s, r->y); /* y (2 bytes) */
|
||||
Stream_Write_UINT16(s, r->width); /* width (2 bytes) */
|
||||
Stream_Write_UINT16(s, r->height); /* height (2 bytes) */
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: The RFX_COMPONENT_CODEC_QUANT structure differs from the
|
||||
* TS_RFX_CODEC_QUANT ([MS-RDPRFX] section 2.2.2.1.5) structure with respect
|
||||
* to the order of the bands.
|
||||
* 0 1 2 3 4 5 6 7 8 9
|
||||
* RDPRFX: LL3, LH3, HL3, HH3, LH2, HL2, HH2, LH1, HL1, HH1
|
||||
* RDPEGFX: LL3, HL3, LH3, HH3, HL2, LH2, HH2, HL1, LH1, HH1
|
||||
*/
|
||||
for (UINT16 i = 0; i < msg->numQuant; i++)
|
||||
{
|
||||
const UINT32* qv = &msg->quantVals[i * 10];
|
||||
/* RFX_COMPONENT_CODEC_QUANT */
|
||||
Stream_Write_UINT8(s, (UINT8)(qv[0] + (qv[2] << 4))); /* LL3 (4-bit), HL3 (4-bit) */
|
||||
Stream_Write_UINT8(s, (UINT8)(qv[1] + (qv[3] << 4))); /* LH3 (4-bit), HH3 (4-bit) */
|
||||
Stream_Write_UINT8(s, (UINT8)(qv[5] + (qv[4] << 4))); /* HL2 (4-bit), LH2 (4-bit) */
|
||||
Stream_Write_UINT8(s, (UINT8)(qv[6] + (qv[8] << 4))); /* HH2 (4-bit), HL1 (4-bit) */
|
||||
Stream_Write_UINT8(s, (UINT8)(qv[7] + (qv[9] << 4))); /* LH1 (4-bit), HH1 (4-bit) */
|
||||
}
|
||||
|
||||
for (UINT16 i = 0; i < msg->numTiles; i++)
|
||||
{
|
||||
const RFX_TILE* tile = msg->tiles[i];
|
||||
if (!progressive_write_tile_simple(progressive, s, tile))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const size_t end = Stream_GetPosition(s);
|
||||
const size_t used = end - start;
|
||||
return (used == blockLen);
|
||||
}
|
||||
|
||||
static INLINE BOOL progressive_write_frame_begin(PROGRESSIVE_CONTEXT* progressive, wStream* s,
|
||||
const RFX_MESSAGE* msg)
|
||||
{
|
||||
const UINT32 blockLen = 12;
|
||||
WINPR_ASSERT(progressive);
|
||||
WINPR_ASSERT(s);
|
||||
WINPR_ASSERT(msg);
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, blockLen))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT16(s, PROGRESSIVE_WBT_FRAME_BEGIN); /* blockType (2 bytes) */
|
||||
Stream_Write_UINT32(s, blockLen); /* blockLen (4 bytes) */
|
||||
Stream_Write_UINT32(s, msg->frameIdx); /* frameIndex (4 bytes) */
|
||||
Stream_Write_UINT16(s, 1); /* regionCount (2 bytes) */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INLINE BOOL progressive_write_frame_end(PROGRESSIVE_CONTEXT* progressive, wStream* s)
|
||||
{
|
||||
const UINT32 blockLen = 6;
|
||||
WINPR_ASSERT(progressive);
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, blockLen))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT16(s, PROGRESSIVE_WBT_FRAME_END); /* blockType (2 bytes) */
|
||||
Stream_Write_UINT32(s, blockLen); /* blockLen (4 bytes) */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
INLINE BOOL progressive_write_tile_simple(PROGRESSIVE_CONTEXT* progressive, wStream* s,
|
||||
const RFX_TILE* tile)
|
||||
{
|
||||
UINT32 blockLen;
|
||||
WINPR_ASSERT(progressive);
|
||||
WINPR_ASSERT(s);
|
||||
WINPR_ASSERT(tile);
|
||||
|
||||
blockLen = 22 + tile->YLen + tile->CbLen + tile->CrLen;
|
||||
if (!Stream_EnsureRemainingCapacity(s, blockLen))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT16(s, PROGRESSIVE_WBT_TILE_SIMPLE); /* blockType (2 bytes) */
|
||||
Stream_Write_UINT32(s, blockLen); /* blockLen (4 bytes) */
|
||||
Stream_Write_UINT8(s, tile->quantIdxY); /* quantIdxY (1 byte) */
|
||||
Stream_Write_UINT8(s, tile->quantIdxCb); /* quantIdxCb (1 byte) */
|
||||
Stream_Write_UINT8(s, tile->quantIdxCr); /* quantIdxCr (1 byte) */
|
||||
Stream_Write_UINT16(s, tile->xIdx); /* xIdx (2 bytes) */
|
||||
Stream_Write_UINT16(s, tile->yIdx); /* yIdx (2 bytes) */
|
||||
Stream_Write_UINT8(s, 0); /* flags (1 byte) */
|
||||
Stream_Write_UINT16(s, tile->YLen); /* YLen (2 bytes) */
|
||||
Stream_Write_UINT16(s, tile->CbLen); /* CbLen (2 bytes) */
|
||||
Stream_Write_UINT16(s, tile->CrLen); /* CrLen (2 bytes) */
|
||||
Stream_Write_UINT16(s, 0); /* tailLen (2 bytes) */
|
||||
Stream_Write(s, tile->YData, tile->YLen); /* YData */
|
||||
Stream_Write(s, tile->CbData, tile->CbLen); /* CbData */
|
||||
Stream_Write(s, tile->CrData, tile->CrLen); /* CrData */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INLINE SSIZE_T progressive_wb_sync(PROGRESSIVE_CONTEXT* progressive, wStream* s,
|
||||
UINT16 blockType, UINT32 blockLen)
|
||||
{
|
||||
|
@ -2660,29 +2449,7 @@ BOOL progressive_rfx_write_message_progressive_simple(PROGRESSIVE_CONTEXT* progr
|
|||
WINPR_ASSERT(s);
|
||||
WINPR_ASSERT(msg);
|
||||
context = progressive->rfx_context;
|
||||
WINPR_ASSERT(context);
|
||||
if (context->mode != RLGR1)
|
||||
{
|
||||
WLog_ERR(TAG, "error, RLGR1 mode is required!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!progressive_write_wb_sync(progressive, s))
|
||||
return FALSE;
|
||||
|
||||
if (!progressive_write_wb_context(progressive, s))
|
||||
return FALSE;
|
||||
|
||||
if (!progressive_write_frame_begin(progressive, s, msg))
|
||||
return FALSE;
|
||||
|
||||
if (!progressive_write_region(progressive, s, msg))
|
||||
return FALSE;
|
||||
|
||||
if (!progressive_write_frame_end(progressive, s))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
return rfx_write_message_progressive_simple(context, s, msg);
|
||||
}
|
||||
|
||||
int progressive_compress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcData, UINT32 SrcSize,
|
||||
|
|
|
@ -32,15 +32,6 @@
|
|||
|
||||
#define RFX_DWT_REDUCE_EXTRAPOLATE 0x01
|
||||
|
||||
#define PROGRESSIVE_WBT_SYNC 0xCCC0
|
||||
#define PROGRESSIVE_WBT_FRAME_BEGIN 0xCCC1
|
||||
#define PROGRESSIVE_WBT_FRAME_END 0xCCC2
|
||||
#define PROGRESSIVE_WBT_CONTEXT 0xCCC3
|
||||
#define PROGRESSIVE_WBT_REGION 0xCCC4
|
||||
#define PROGRESSIVE_WBT_TILE_SIMPLE 0xCCC5
|
||||
#define PROGRESSIVE_WBT_TILE_FIRST 0xCCC6
|
||||
#define PROGRESSIVE_WBT_TILE_UPGRADE 0xCCC7
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE LL3;
|
||||
|
|
|
@ -77,6 +77,9 @@
|
|||
*/
|
||||
static const UINT32 rfx_default_quantization_values[] = { 6, 6, 6, 6, 7, 7, 8, 8, 8, 9 };
|
||||
|
||||
static INLINE BOOL rfx_write_progressive_tile_simple(RFX_CONTEXT* rfx, wStream* s,
|
||||
const RFX_TILE* tile);
|
||||
|
||||
static void rfx_profiler_create(RFX_CONTEXT* context)
|
||||
{
|
||||
if (!context || !context->priv)
|
||||
|
@ -419,12 +422,24 @@ void rfx_context_set_pixel_format(RFX_CONTEXT* context, UINT32 pixel_format)
|
|||
context->bits_per_pixel = FreeRDPGetBitsPerPixel(pixel_format);
|
||||
}
|
||||
|
||||
UINT32 rfx_context_get_pixel_format(RFX_CONTEXT* context)
|
||||
{
|
||||
WINPR_ASSERT(context);
|
||||
return context->pixel_format;
|
||||
}
|
||||
|
||||
void rfx_context_set_palette(RFX_CONTEXT* context, const BYTE* palette)
|
||||
{
|
||||
WINPR_ASSERT(context);
|
||||
context->palette = palette;
|
||||
}
|
||||
|
||||
const BYTE* rfx_context_get_palette(RFX_CONTEXT* context)
|
||||
{
|
||||
WINPR_ASSERT(context);
|
||||
return context->palette;
|
||||
}
|
||||
|
||||
BOOL rfx_context_reset(RFX_CONTEXT* context, UINT32 width, UINT32 height)
|
||||
{
|
||||
if (!context)
|
||||
|
@ -2139,14 +2154,253 @@ BOOL rfx_context_set_mode(RFX_CONTEXT* context, RLGR_MODE mode)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
RLGR_MODE rfx_context_get_mode(RFX_CONTEXT* context)
|
||||
{
|
||||
WINPR_ASSERT(context);
|
||||
return context->mode;
|
||||
}
|
||||
|
||||
UINT32 rfx_context_get_frame_idx(const RFX_CONTEXT* context)
|
||||
{
|
||||
WINPR_ASSERT(context);
|
||||
return context->frameIdx;
|
||||
}
|
||||
|
||||
UINT32 rfx_message_get_frame_idx(const RFX_MESSAGE* message)
|
||||
static INLINE BOOL rfx_write_progressive_wb_sync(RFX_CONTEXT* rfx, wStream* s)
|
||||
{
|
||||
WINPR_ASSERT(message);
|
||||
return message->frameIdx;
|
||||
const UINT32 blockLen = 12;
|
||||
WINPR_ASSERT(rfx);
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, blockLen))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT16(s, PROGRESSIVE_WBT_SYNC); /* blockType (2 bytes) */
|
||||
Stream_Write_UINT32(s, blockLen); /* blockLen (4 bytes) */
|
||||
Stream_Write_UINT32(s, 0xCACCACCA); /* magic (4 bytes) */
|
||||
Stream_Write_UINT16(s, 0x0100); /* version (2 bytes) */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INLINE BOOL rfx_write_progressive_wb_context(RFX_CONTEXT* rfx, wStream* s)
|
||||
{
|
||||
const UINT32 blockLen = 10;
|
||||
WINPR_ASSERT(rfx);
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, blockLen))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT16(s, PROGRESSIVE_WBT_CONTEXT); /* blockType (2 bytes) */
|
||||
Stream_Write_UINT32(s, blockLen); /* blockLen (4 bytes) */
|
||||
Stream_Write_UINT8(s, 0); /* ctxId (1 byte) */
|
||||
Stream_Write_UINT16(s, 64); /* tileSize (2 bytes) */
|
||||
Stream_Write_UINT8(s, 0); /* flags (1 byte) */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INLINE BOOL rfx_write_progressive_region(RFX_CONTEXT* rfx, wStream* s,
|
||||
const RFX_MESSAGE* msg)
|
||||
{
|
||||
/* RFX_REGION */
|
||||
UINT32 blockLen = 18;
|
||||
UINT32 tilesDataSize = 0;
|
||||
const size_t start = Stream_GetPosition(s);
|
||||
|
||||
WINPR_ASSERT(rfx);
|
||||
WINPR_ASSERT(s);
|
||||
WINPR_ASSERT(msg);
|
||||
|
||||
blockLen += msg->numRects * 8;
|
||||
blockLen += msg->numQuant * 5;
|
||||
tilesDataSize = msg->numTiles * 22UL;
|
||||
for (UINT16 i = 0; i < msg->numTiles; i++)
|
||||
{
|
||||
const RFX_TILE* tile = msg->tiles[i];
|
||||
WINPR_ASSERT(tile);
|
||||
tilesDataSize += tile->YLen + tile->CbLen + tile->CrLen;
|
||||
}
|
||||
blockLen += tilesDataSize;
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, blockLen))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT16(s, PROGRESSIVE_WBT_REGION); /* blockType (2 bytes) */
|
||||
Stream_Write_UINT32(s, blockLen); /* blockLen (4 bytes) */
|
||||
Stream_Write_UINT8(s, 64); /* tileSize (1 byte) */
|
||||
Stream_Write_UINT16(s, msg->numRects); /* numRects (2 bytes) */
|
||||
WINPR_ASSERT(msg->numQuant <= UINT8_MAX);
|
||||
Stream_Write_UINT8(s, (UINT8)msg->numQuant); /* numQuant (1 byte) */
|
||||
Stream_Write_UINT8(s, 0); /* numProgQuant (1 byte) */
|
||||
Stream_Write_UINT8(s, 0); /* flags (1 byte) */
|
||||
Stream_Write_UINT16(s, msg->numTiles); /* numTiles (2 bytes) */
|
||||
Stream_Write_UINT32(s, tilesDataSize); /* tilesDataSize (4 bytes) */
|
||||
|
||||
for (UINT16 i = 0; i < msg->numRects; i++)
|
||||
{
|
||||
/* TS_RFX_RECT */
|
||||
const RFX_RECT* r = &msg->rects[i];
|
||||
Stream_Write_UINT16(s, r->x); /* x (2 bytes) */
|
||||
Stream_Write_UINT16(s, r->y); /* y (2 bytes) */
|
||||
Stream_Write_UINT16(s, r->width); /* width (2 bytes) */
|
||||
Stream_Write_UINT16(s, r->height); /* height (2 bytes) */
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: The RFX_COMPONENT_CODEC_QUANT structure differs from the
|
||||
* TS_RFX_CODEC_QUANT ([MS-RDPRFX] section 2.2.2.1.5) structure with respect
|
||||
* to the order of the bands.
|
||||
* 0 1 2 3 4 5 6 7 8 9
|
||||
* RDPRFX: LL3, LH3, HL3, HH3, LH2, HL2, HH2, LH1, HL1, HH1
|
||||
* RDPEGFX: LL3, HL3, LH3, HH3, HL2, LH2, HH2, HL1, LH1, HH1
|
||||
*/
|
||||
for (UINT16 i = 0; i < msg->numQuant; i++)
|
||||
{
|
||||
const UINT32* qv = &msg->quantVals[i * 10];
|
||||
/* RFX_COMPONENT_CODEC_QUANT */
|
||||
Stream_Write_UINT8(s, (UINT8)(qv[0] + (qv[2] << 4))); /* LL3 (4-bit), HL3 (4-bit) */
|
||||
Stream_Write_UINT8(s, (UINT8)(qv[1] + (qv[3] << 4))); /* LH3 (4-bit), HH3 (4-bit) */
|
||||
Stream_Write_UINT8(s, (UINT8)(qv[5] + (qv[4] << 4))); /* HL2 (4-bit), LH2 (4-bit) */
|
||||
Stream_Write_UINT8(s, (UINT8)(qv[6] + (qv[8] << 4))); /* HH2 (4-bit), HL1 (4-bit) */
|
||||
Stream_Write_UINT8(s, (UINT8)(qv[7] + (qv[9] << 4))); /* LH1 (4-bit), HH1 (4-bit) */
|
||||
}
|
||||
|
||||
for (UINT16 i = 0; i < msg->numTiles; i++)
|
||||
{
|
||||
const RFX_TILE* tile = msg->tiles[i];
|
||||
if (!rfx_write_progressive_tile_simple(rfx, s, tile))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const size_t end = Stream_GetPosition(s);
|
||||
const size_t used = end - start;
|
||||
return (used == blockLen);
|
||||
}
|
||||
|
||||
static INLINE BOOL rfx_write_progressive_frame_begin(RFX_CONTEXT* rfx, wStream* s,
|
||||
const RFX_MESSAGE* msg)
|
||||
{
|
||||
const UINT32 blockLen = 12;
|
||||
WINPR_ASSERT(rfx);
|
||||
WINPR_ASSERT(s);
|
||||
WINPR_ASSERT(msg);
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, blockLen))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT16(s, PROGRESSIVE_WBT_FRAME_BEGIN); /* blockType (2 bytes) */
|
||||
Stream_Write_UINT32(s, blockLen); /* blockLen (4 bytes) */
|
||||
Stream_Write_UINT32(s, msg->frameIdx); /* frameIndex (4 bytes) */
|
||||
Stream_Write_UINT16(s, 1); /* regionCount (2 bytes) */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INLINE BOOL rfx_write_progressive_frame_end(RFX_CONTEXT* rfx, wStream* s)
|
||||
{
|
||||
const UINT32 blockLen = 6;
|
||||
WINPR_ASSERT(rfx);
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, blockLen))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT16(s, PROGRESSIVE_WBT_FRAME_END); /* blockType (2 bytes) */
|
||||
Stream_Write_UINT32(s, blockLen); /* blockLen (4 bytes) */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INLINE BOOL rfx_write_progressive_tile_simple(RFX_CONTEXT* rfx, wStream* s,
|
||||
const RFX_TILE* tile)
|
||||
{
|
||||
UINT32 blockLen;
|
||||
WINPR_ASSERT(rfx);
|
||||
WINPR_ASSERT(s);
|
||||
WINPR_ASSERT(tile);
|
||||
|
||||
blockLen = 22 + tile->YLen + tile->CbLen + tile->CrLen;
|
||||
if (!Stream_EnsureRemainingCapacity(s, blockLen))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT16(s, PROGRESSIVE_WBT_TILE_SIMPLE); /* blockType (2 bytes) */
|
||||
Stream_Write_UINT32(s, blockLen); /* blockLen (4 bytes) */
|
||||
Stream_Write_UINT8(s, tile->quantIdxY); /* quantIdxY (1 byte) */
|
||||
Stream_Write_UINT8(s, tile->quantIdxCb); /* quantIdxCb (1 byte) */
|
||||
Stream_Write_UINT8(s, tile->quantIdxCr); /* quantIdxCr (1 byte) */
|
||||
Stream_Write_UINT16(s, tile->xIdx); /* xIdx (2 bytes) */
|
||||
Stream_Write_UINT16(s, tile->yIdx); /* yIdx (2 bytes) */
|
||||
Stream_Write_UINT8(s, 0); /* flags (1 byte) */
|
||||
Stream_Write_UINT16(s, tile->YLen); /* YLen (2 bytes) */
|
||||
Stream_Write_UINT16(s, tile->CbLen); /* CbLen (2 bytes) */
|
||||
Stream_Write_UINT16(s, tile->CrLen); /* CrLen (2 bytes) */
|
||||
Stream_Write_UINT16(s, 0); /* tailLen (2 bytes) */
|
||||
Stream_Write(s, tile->YData, tile->YLen); /* YData */
|
||||
Stream_Write(s, tile->CbData, tile->CbLen); /* CbData */
|
||||
Stream_Write(s, tile->CrData, tile->CrLen); /* CrData */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const char* rfx_get_progressive_block_type_string(UINT16 blockType)
|
||||
{
|
||||
switch (blockType)
|
||||
{
|
||||
case PROGRESSIVE_WBT_SYNC:
|
||||
return "PROGRESSIVE_WBT_SYNC";
|
||||
|
||||
case PROGRESSIVE_WBT_FRAME_BEGIN:
|
||||
return "PROGRESSIVE_WBT_FRAME_BEGIN";
|
||||
|
||||
case PROGRESSIVE_WBT_FRAME_END:
|
||||
return "PROGRESSIVE_WBT_FRAME_END";
|
||||
|
||||
case PROGRESSIVE_WBT_CONTEXT:
|
||||
return "PROGRESSIVE_WBT_CONTEXT";
|
||||
|
||||
case PROGRESSIVE_WBT_REGION:
|
||||
return "PROGRESSIVE_WBT_REGION";
|
||||
|
||||
case PROGRESSIVE_WBT_TILE_SIMPLE:
|
||||
return "PROGRESSIVE_WBT_TILE_SIMPLE";
|
||||
|
||||
case PROGRESSIVE_WBT_TILE_FIRST:
|
||||
return "PROGRESSIVE_WBT_TILE_FIRST";
|
||||
|
||||
case PROGRESSIVE_WBT_TILE_UPGRADE:
|
||||
return "PROGRESSIVE_WBT_TILE_UPGRADE";
|
||||
|
||||
default:
|
||||
return "PROGRESSIVE_WBT_UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
BOOL rfx_write_message_progressive_simple(RFX_CONTEXT* context, wStream* s, const RFX_MESSAGE* msg)
|
||||
{
|
||||
WINPR_ASSERT(s);
|
||||
WINPR_ASSERT(msg);
|
||||
WINPR_ASSERT(context);
|
||||
|
||||
if (context->mode != RLGR1)
|
||||
{
|
||||
WLog_ERR(TAG, "error, RLGR1 mode is required!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!rfx_write_progressive_wb_sync(context, s))
|
||||
return FALSE;
|
||||
|
||||
if (!rfx_write_progressive_wb_context(context, s))
|
||||
return FALSE;
|
||||
|
||||
if (!rfx_write_progressive_frame_begin(context, s, msg))
|
||||
return FALSE;
|
||||
|
||||
if (!rfx_write_progressive_region(context, s, msg))
|
||||
return FALSE;
|
||||
|
||||
if (!rfx_write_progressive_frame_end(context, s))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#ifndef FREERDP_LIB_CODEC_RFX_CONSTANTS_H
|
||||
#define FREERDP_LIB_CODEC_RFX_CONSTANTS_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
|
||||
/* sync */
|
||||
#define WF_MAGIC 0xCACCACCA
|
||||
#define WF_VERSION_1_0 0x0100
|
||||
|
@ -37,6 +39,15 @@
|
|||
#define CBT_TILESET 0xCAC2
|
||||
#define CBT_TILE 0xCAC3
|
||||
|
||||
#define PROGRESSIVE_WBT_SYNC 0xCCC0
|
||||
#define PROGRESSIVE_WBT_FRAME_BEGIN 0xCCC1
|
||||
#define PROGRESSIVE_WBT_FRAME_END 0xCCC2
|
||||
#define PROGRESSIVE_WBT_CONTEXT 0xCCC3
|
||||
#define PROGRESSIVE_WBT_REGION 0xCCC4
|
||||
#define PROGRESSIVE_WBT_TILE_SIMPLE 0xCCC5
|
||||
#define PROGRESSIVE_WBT_TILE_FIRST 0xCCC6
|
||||
#define PROGRESSIVE_WBT_TILE_UPGRADE 0xCCC7
|
||||
|
||||
/* tileSize */
|
||||
#define CT_TILE_64x64 0x0040
|
||||
|
||||
|
@ -56,4 +67,15 @@
|
|||
/* properties.qt */
|
||||
#define SCALAR_QUANTIZATION 0x1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
FREERDP_LOCAL const char* rfx_get_progressive_block_type_string(UINT16 blockType);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FREERDP_LIB_CODEC_RFX_CONSTANTS_H */
|
||||
|
|
Loading…
Reference in New Issue