RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length) { int pos; STREAM* s; UINT32 blockLen; UINT32 blockType; RFX_MESSAGE* message; message = (RFX_MESSAGE*) malloc(sizeof(RFX_MESSAGE)); ZeroMemory(message, sizeof(RFX_MESSAGE)); s = stream_new(0); stream_attach(s, data, length); while (stream_get_left(s) > 6) { /* RFX_BLOCKT */ stream_read_UINT16(s, blockType); /* blockType (2 bytes) */ stream_read_UINT32(s, blockLen); /* blockLen (4 bytes) */ DEBUG_RFX("blockType 0x%X blockLen %d", blockType, blockLen); if (blockLen == 0) { DEBUG_WARN("zero blockLen"); break; } if (stream_get_left(s) < blockLen - 6) { DEBUG_WARN("rfx_process_message: packet too small for blocklen=%d", blockLen); break; } pos = stream_get_pos(s) - 6 + blockLen; if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION) { /* RFX_CODEC_CHANNELT */ /* codecId (1 byte) must be set to 0x01 */ /* channelId (1 byte) must be set to 0x00 */ if (!stream_skip(s, 2)) { DEBUG_WARN("rfx_process_message: unable to skip RFX_CODEC_CHANNELT"); break; } } switch (blockType) { case WBT_SYNC: rfx_process_message_sync(context, s); break; case WBT_CODEC_VERSIONS: rfx_process_message_codec_versions(context, s); break; case WBT_CHANNELS: rfx_process_message_channels(context, s); break; case WBT_CONTEXT: rfx_process_message_context(context, s); break; case WBT_FRAME_BEGIN: rfx_process_message_frame_begin(context, message, s); break; case WBT_FRAME_END: rfx_process_message_frame_end(context, message, s); break; case WBT_REGION: rfx_process_message_region(context, message, s); break; case WBT_EXTENSION: rfx_process_message_tileset(context, message, s); break; default: DEBUG_WARN("unknown blockType 0x%X", blockType); break; } stream_set_pos(s, pos); } stream_detach(s); stream_free(s); return message; }
RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length) { int pos; UINT32 blockLen; UINT32 blockType; RFX_MESSAGE* message = NULL; wStream* s = NULL; BOOL ok = TRUE; UINT16 expectedDataBlockType = WBT_FRAME_BEGIN; if (!context || !data || !length) goto fail; if (!(s = Stream_New(data, length))) goto fail; if (!(message = (RFX_MESSAGE*) calloc(1, sizeof(RFX_MESSAGE)))) goto fail; message->freeRects = TRUE; while (ok && Stream_GetRemainingLength(s) > 6) { /* 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%X blockLen %d", blockType, blockLen); if (blockLen == 0) { WLog_ERR(TAG, "zero blockLen"); goto fail; } if (Stream_GetRemainingLength(s) < blockLen - 6) { WLog_ERR(TAG, "%s: packet too small for blocklen=%d", __FUNCTION__, blockLen); goto fail; } 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; } if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION) { /* RFX_CODEC_CHANNELT */ UINT8 codecId; UINT8 channelId; if (Stream_GetRemainingLength(s) < 2) goto fail; 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 */ if (codecId != 0x01) { WLog_ERR(TAG, "%s: invalid codecId 0x%02X", __FUNCTION__, codecId); goto fail; } if (blockType == WBT_CONTEXT) { /* If the blockType is set to WBT_CONTEXT, then channelId MUST be set to 0xFF.*/ if (channelId != 0xFF) { WLog_ERR(TAG, "%s: invalid channelId 0x%02X for blockType 0x%04X", __FUNCTION__, channelId, blockType); goto fail; } } else { /* For all other values of blockType, channelId MUST be set to 0x00. */ if (channelId != 0x00) { WLog_ERR(TAG, "%s: invalid channelId 0x%02X for blockType WBT_CONTEXT", __FUNCTION__, channelId); goto fail; } } } switch (blockType) { /* Header messages: * The stream MUST start with the header messages and any of these headers can appear * in the stream at a later stage. The header messages can be repeated. */ case WBT_SYNC: ok = rfx_process_message_sync(context, s); break; case WBT_CONTEXT: ok = rfx_process_message_context(context, s); break; case WBT_CODEC_VERSIONS: ok = rfx_process_message_codec_versions(context, s); break; case WBT_CHANNELS: ok = rfx_process_message_channels(context, s); break; /* Data messages: * The data associated with each encoded frame or image is always bracketed by the * TS_RFX_FRAME_BEGIN (section 2.2.2.3.1) and TS_RFX_FRAME_END (section 2.2.2.3.2) messages. * There MUST only be one TS_RFX_REGION (section 2.2.2.3.3) message per frame and one TS_RFX_TILESET * (section 2.2.2.3.4) message per TS_RFX_REGION. */ case WBT_FRAME_BEGIN: ok = rfx_process_message_frame_begin(context, message, s, &expectedDataBlockType); break; case WBT_REGION: ok = rfx_process_message_region(context, message, s, &expectedDataBlockType); break; case WBT_EXTENSION: ok = rfx_process_message_tileset(context, message, s, &expectedDataBlockType); break; case WBT_FRAME_END: ok = rfx_process_message_frame_end(context, message, s, &expectedDataBlockType); break; default: WLog_ERR(TAG, "%s: unknown blockType 0x%X", __FUNCTION__, blockType); goto fail; } Stream_SetPosition(s, pos); } if (ok) { Stream_Free(s, FALSE); return message; } fail: Stream_Free(s, FALSE); rfx_message_free(context, message); return NULL; }
RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, uint8* data, uint32 length) { int pos; STREAM* s; uint32 blockLen; uint32 blockType; RFX_MESSAGE* message; s = stream_new(0); message = xnew(RFX_MESSAGE); stream_attach(s, data, length); while (stream_get_left(s) > 6) { /* RFX_BLOCKT */ stream_read_uint16(s, blockType); /* blockType (2 bytes) */ stream_read_uint32(s, blockLen); /* blockLen (4 bytes) */ DEBUG_RFX("blockType 0x%X blockLen %d", blockType, blockLen); if (blockLen == 0) { DEBUG_WARN("zero blockLen"); break; } pos = stream_get_pos(s) - 6 + blockLen; if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION) { /* RFX_CODEC_CHANNELT */ /* codecId (1 byte) must be set to 0x01 */ /* channelId (1 byte) must be set to 0x00 */ stream_seek(s, 2); } switch (blockType) { case WBT_SYNC: rfx_process_message_sync(context, s); break; case WBT_CODEC_VERSIONS: rfx_process_message_codec_versions(context, s); break; case WBT_CHANNELS: rfx_process_message_channels(context, s); break; case WBT_CONTEXT: rfx_process_message_context(context, s); break; case WBT_FRAME_BEGIN: rfx_process_message_frame_begin(context, message, s); break; case WBT_FRAME_END: rfx_process_message_frame_end(context, message, s); break; case WBT_REGION: rfx_process_message_region(context, message, s); break; case WBT_EXTENSION: rfx_process_message_tileset(context, message, s); break; default: DEBUG_WARN("unknown blockType 0x%X", blockType); break; } stream_set_pos(s, pos); } stream_detach(s); stream_free(s); return message; }
RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, uint8* data, uint32 length, RECTANGLE_16* dst_rect) { int pos; STREAM* s; uint32 blockLen; uint32 blockType; RFX_CONTEXT_CVT_PRIV* priv; RFX_MESSAGE* message; s = stream_new(0); message = rfx_message_new(); if (dst_rect) memcpy(&message->dst_rect, dst_rect, sizeof(RECTANGLE_16)); stream_attach(s, data, length); while (stream_get_left(s) > 6) { /* RFX_BLOCKT */ stream_read_uint16(s, blockType); /* blockType (2 bytes) */ stream_read_uint32(s, blockLen); /* blockLen (4 bytes) */ DEBUG_RFX("blockType 0x%X blockLen %d", blockType, blockLen); if (blockLen == 0) { DEBUG_WARN("zero blockLen"); break; } pos = stream_get_pos(s) - 6 + blockLen; if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION) { /* RFX_CODEC_CHANNELT */ /* codecId (1 byte) must be set to 0x01 */ /* channelId (1 byte) must be set to 0x00 */ stream_seek(s, 2); } switch (blockType) { case WBT_SYNC: rfx_process_message_sync(context, s); break; case WBT_CODEC_VERSIONS: rfx_process_message_codec_versions(context, s); break; case WBT_CHANNELS: rfx_process_message_channels(context, s); break; case WBT_CONTEXT: rfx_process_message_context(context, s); break; case WBT_FRAME_BEGIN: rfx_process_message_frame_begin(context, message, s); break; case WBT_FRAME_END: rfx_process_message_frame_end(context, message, s); break; case WBT_REGION: rfx_process_message_region(context, message, s); break; case WBT_EXTENSION: priv = (RFX_CONTEXT_CVT_PRIV*) context->priv; if (priv->rfx_op_mode == RDVH_OPT) rfx_cvt_rdvh_opt_process_message_tileset(context, message, s); else rfx_cvt_process_message_tileset(context, message, s); break; default: DEBUG_WARN("unknown blockType 0x%X", blockType); break; } stream_set_pos(s, pos); } stream_detach(s); stream_free(s); return message; }
RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length) { int pos; wStream* s; UINT32 blockLen; UINT32 blockType; RFX_MESSAGE* message; message = (RFX_MESSAGE*) malloc(sizeof(RFX_MESSAGE)); ZeroMemory(message, sizeof(RFX_MESSAGE)); message->freeRects = TRUE; s = Stream_New(data, length); while (Stream_GetRemainingLength(s) > 6) { /* 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%X blockLen %d", blockType, blockLen); if (blockLen == 0) { DEBUG_WARN("zero blockLen"); break; } if (Stream_GetRemainingLength(s) < blockLen - 6) { DEBUG_WARN("rfx_process_message: packet too small for blocklen=%d", blockLen); break; } pos = Stream_GetPosition(s) - 6 + blockLen; if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION) { /* RFX_CODEC_CHANNELT */ /* codecId (1 byte) must be set to 0x01 */ /* channelId (1 byte) must be set to 0x00 */ if (!Stream_SafeSeek(s, 2)) { DEBUG_WARN("rfx_process_message: unable to skip RFX_CODEC_CHANNELT"); break; } } switch (blockType) { case WBT_SYNC: rfx_process_message_sync(context, s); break; case WBT_CODEC_VERSIONS: rfx_process_message_codec_versions(context, s); break; case WBT_CHANNELS: rfx_process_message_channels(context, s); break; case WBT_CONTEXT: rfx_process_message_context(context, s); break; case WBT_FRAME_BEGIN: rfx_process_message_frame_begin(context, message, s); break; case WBT_FRAME_END: rfx_process_message_frame_end(context, message, s); break; case WBT_REGION: rfx_process_message_region(context, message, s); break; case WBT_EXTENSION: rfx_process_message_tileset(context, message, s); break; default: DEBUG_WARN("unknown blockType 0x%X", blockType); break; } Stream_SetPosition(s, pos); } Stream_Free(s, FALSE); return message; }