diff --git a/include/freerdp/codec/rfx.h b/include/freerdp/codec/rfx.h index daf2dd8d4..352a2d969 100644 --- a/include/freerdp/codec/rfx.h +++ b/include/freerdp/codec/rfx.h @@ -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 diff --git a/libfreerdp/codec/progressive.c b/libfreerdp/codec/progressive.c index e1015de7d..91da60b6b 100644 --- a/libfreerdp/codec/progressive.c +++ b/libfreerdp/codec/progressive.c @@ -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, diff --git a/libfreerdp/codec/progressive.h b/libfreerdp/codec/progressive.h index 860807fea..5c5f2a68b 100644 --- a/libfreerdp/codec/progressive.h +++ b/libfreerdp/codec/progressive.h @@ -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; diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index a0254264f..0cc290274 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -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; } diff --git a/libfreerdp/codec/rfx_constants.h b/libfreerdp/codec/rfx_constants.h index a07c356c0..e8405a84a 100644 --- a/libfreerdp/codec/rfx_constants.h +++ b/libfreerdp/codec/rfx_constants.h @@ -20,6 +20,8 @@ #ifndef FREERDP_LIB_CODEC_RFX_CONSTANTS_H #define FREERDP_LIB_CODEC_RFX_CONSTANTS_H +#include + /* 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 */