示例#1
0
static void rfx_process_message_context(RFX_CONTEXT* context, STREAM* s)
{
	uint8 ctxId;
	uint16 tileSize;
	uint16 properties;

	rfx_parse_message_context(s, &ctxId, &tileSize, &properties);

	DEBUG_RFX("ctxId %d tileSize %d properties 0x%X.", ctxId, tileSize, properties);

	context->flags = (properties & 0x0007);

	if (context->flags == CODEC_MODE)
		DEBUG_RFX("codec is in image mode.");
	else
		DEBUG_RFX("codec is in video mode.");

	switch ((properties & 0x1E00) >> 9)
	{
		case CLW_ENTROPY_RLGR1:
			context->mode = RLGR1;
			DEBUG_RFX("RLGR1.");
			break;

		case CLW_ENTROPY_RLGR3:
			context->mode = RLGR3;
			DEBUG_RFX("RLGR3.");
			break;

		default:
			DEBUG_WARN("unknown RLGR algorithm.");
			break;
	}
}
示例#2
0
int isNeonSupported()
{
#if defined(ANDROID)
    if (android_getCpuFamily() != ANDROID_CPU_FAMILY_ARM)
    {
        DEBUG_RFX("NEON optimization disabled - No ARM CPU found");
        return 0;
    }

    uint64_t features = android_getCpuFeatures();
    if ((features & ANDROID_CPU_ARM_FEATURE_ARMv7))
    {
        if (features & ANDROID_CPU_ARM_FEATURE_NEON)
        {
            DEBUG_RFX("NEON optimization enabled!");
            return 1;
        }
        DEBUG_RFX("NEON optimization disabled - CPU not NEON capable");
    }
    else
        DEBUG_RFX("NEON optimization disabled - No ARMv7 CPU found");

    return 0;
#else
    return 1;
#endif
}
示例#3
0
文件: rfx.c 项目: Arkantos7/FreeRDP
static void rfx_process_message_channels(RFX_CONTEXT* context, STREAM* s)
{
	BYTE channelId;
	BYTE numChannels;

	stream_read_BYTE(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.
	 */
	if (numChannels < 1)
	{
		DEBUG_WARN("numChannels:%d, expected:1", numChannels);
		return;
	}

	/* RFX_CHANNELT */
	stream_read_BYTE(s, channelId); /* channelId (1 byte) */
	stream_read_UINT16(s, context->width); /* width (2 bytes) */
	stream_read_UINT16(s, context->height); /* height (2 bytes) */

	/* Now, only the first monitor can be used, therefore the other channels will be ignored. */
	stream_seek(s, 5 * (numChannels - 1));

	DEBUG_RFX("numChannels %d id %d, %dx%d.",
		numChannels, channelId, context->width, context->height);
}
示例#4
0
文件: rfx.c 项目: nour8394/FreeRDP
static BOOL rfx_process_message_codec_versions(RFX_CONTEXT* context, STREAM* s)
{
	BYTE numCodecs;

	if (stream_get_left(s) < 1)
	{
		DEBUG_WARN("RfxCodecVersion packet too small");
		return FALSE;
	}
	stream_read_BYTE(s, numCodecs); /* numCodecs (1 byte), must be set to 0x01 */

	if (numCodecs != 1)
	{
		DEBUG_WARN("numCodecs: %d, expected:1", numCodecs);
		return FALSE;
	}

	if (stream_get_left(s) <  2 * numCodecs)
	{
		DEBUG_WARN("RfxCodecVersion packet too small for numCodecs=%d", numCodecs);
		return FALSE;
	}

	/* RFX_CODEC_VERSIONT */
	stream_read_BYTE(s, context->codec_id); /* codecId (1 byte) */
	stream_read_BYTE(s, context->codec_version); /* version (2 bytes) */

	DEBUG_RFX("id %d version 0x%X.", context->codec_id, context->codec_version);
	return TRUE;
}
示例#5
0
文件: rfx.c 项目: authentic8/FreeRDP
static BOOL rfx_process_message_codec_versions(RFX_CONTEXT* context, wStream* s)
{
	BYTE numCodecs;

	if (Stream_GetRemainingLength(s) < 1)
	{
		DEBUG_WARN("RfxCodecVersion packet too small");
		return FALSE;
	}
	Stream_Read_UINT8(s, numCodecs); /* numCodecs (1 byte), must be set to 0x01 */

	if (numCodecs != 1)
	{
		DEBUG_WARN("numCodecs: %d, expected:1", numCodecs);
		return FALSE;
	}

	if (Stream_GetRemainingLength(s) <  2 * numCodecs)
	{
		DEBUG_WARN("RfxCodecVersion packet too small for numCodecs=%d", numCodecs);
		return FALSE;
	}

	/* RFX_CODEC_VERSIONT */
	Stream_Read_UINT8(s, context->codec_id); /* codecId (1 byte) */
	Stream_Read_UINT8(s, context->codec_version); /* version (2 bytes) */

	DEBUG_RFX("id %d version 0x%X.", context->codec_id, context->codec_version);
	return TRUE;
}
示例#6
0
文件: rfx.c 项目: nour8394/FreeRDP
static BOOL rfx_process_message_sync(RFX_CONTEXT* context, STREAM* s)
{
	UINT32 magic;

	/* RFX_SYNC */
	if (stream_get_left(s) < 6)
	{
		DEBUG_WARN("RfxSync packet too small");
		return FALSE;
	}
	stream_read_UINT32(s, magic); /* magic (4 bytes), 0xCACCACCA */

	if (magic != WF_MAGIC)
	{
		DEBUG_WARN("invalid magic number 0x%X", magic);
		return FALSE;
	}

	stream_read_UINT16(s, context->version); /* version (2 bytes), WF_VERSION_1_0 (0x0100) */

	if (context->version != WF_VERSION_1_0)
	{
		DEBUG_WARN("unknown version number 0x%X", context->version);
		return FALSE;
	}

	DEBUG_RFX("version 0x%X", context->version);
	return TRUE;
}
示例#7
0
文件: rfx.c 项目: Arkantos7/FreeRDP
static void rfx_process_message_tile(RFX_CONTEXT* context, RFX_TILE* tile, STREAM* s)
{
	BYTE quantIdxY;
	BYTE quantIdxCb;
	BYTE quantIdxCr;
	UINT16 xIdx, yIdx;
	UINT16 YLen, CbLen, CrLen;

	/* RFX_TILE */
	stream_read_BYTE(s, quantIdxY); /* quantIdxY (1 byte) */
	stream_read_BYTE(s, quantIdxCb); /* quantIdxCb (1 byte) */
	stream_read_BYTE(s, quantIdxCr); /* quantIdxCr (1 byte) */
	stream_read_UINT16(s, xIdx); /* xIdx (2 bytes) */
	stream_read_UINT16(s, yIdx); /* yIdx (2 bytes) */
	stream_read_UINT16(s, YLen); /* YLen (2 bytes) */
	stream_read_UINT16(s, CbLen); /* CbLen (2 bytes) */
	stream_read_UINT16(s, CrLen); /* CrLen (2 bytes) */

	DEBUG_RFX("quantIdxY:%d quantIdxCb:%d quantIdxCr:%d xIdx:%d yIdx:%d YLen:%d CbLen:%d CrLen:%d",
		quantIdxY, quantIdxCb, quantIdxCr, xIdx, yIdx, YLen, CbLen, CrLen);

	tile->x = xIdx * 64;
	tile->y = yIdx * 64;

	rfx_decode_rgb(context, s,
		YLen, context->quants + (quantIdxY * 10),
		CbLen, context->quants + (quantIdxCb * 10),
		CrLen, context->quants + (quantIdxCr * 10),
		tile->data);
}
示例#8
0
文件: rfx.c 项目: Arkantos7/FreeRDP
static void rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s)
{
	int i;

	stream_seek_BYTE(s); /* regionFlags (1 byte) */
	stream_read_UINT16(s, message->num_rects); /* numRects (2 bytes) */

	if (message->num_rects < 1)
	{
		DEBUG_WARN("no rects.");
		return;
	}

	if (message->rects != NULL)
		message->rects = (RFX_RECT*) realloc(message->rects, message->num_rects * sizeof(RFX_RECT));
	else
		message->rects = (RFX_RECT*) malloc(message->num_rects * sizeof(RFX_RECT));

	/* rects */
	for (i = 0; i < message->num_rects; i++)
	{
		/* RFX_RECT */
		stream_read_UINT16(s, message->rects[i].x); /* x (2 bytes) */
		stream_read_UINT16(s, message->rects[i].y); /* y (2 bytes) */
		stream_read_UINT16(s, message->rects[i].width); /* width (2 bytes) */
		stream_read_UINT16(s, message->rects[i].height); /* height (2 bytes) */

		DEBUG_RFX("rect %d (%d %d %d %d).",
			i, message->rects[i].x, message->rects[i].y, message->rects[i].width, message->rects[i].height);
	}
}
示例#9
0
static void rfx_process_message_frame_begin(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s)
{
	uint32 frameIdx;
	uint16 numRegions;

	rfx_parse_message_frame_begin(s, &frameIdx, &numRegions);

	DEBUG_RFX("RFX_FRAME_BEGIN: frameIdx:%d numRegions:%d", frameIdx, numRegions);
}
示例#10
0
文件: rfx.c 项目: nour8394/FreeRDP
static BOOL rfx_process_message_context(RFX_CONTEXT* context, STREAM* s)
{
	BYTE ctxId;
	UINT16 tileSize;
	UINT16 properties;

	if (stream_get_left(s) < 5)
	{
		DEBUG_WARN("RfxMessageContext packet too small");
		return FALSE;
	}

	stream_read_BYTE(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, properties); /* properties (2 bytes) */

	DEBUG_RFX("ctxId %d tileSize %d properties 0x%X.", ctxId, tileSize, properties);

	context->properties = properties;
	context->flags = (properties & 0x0007);

	if (context->flags == CODEC_MODE)
		DEBUG_RFX("codec is in image mode.");
	else
		DEBUG_RFX("codec is in video mode.");

	switch ((properties & 0x1E00) >> 9)
	{
		case CLW_ENTROPY_RLGR1:
			context->mode = RLGR1;
			DEBUG_RFX("RLGR1.");
			break;

		case CLW_ENTROPY_RLGR3:
			context->mode = RLGR3;
			DEBUG_RFX("RLGR3.");
			break;

		default:
			DEBUG_WARN("unknown RLGR algorithm.");
			break;
	}
	return TRUE;
}
示例#11
0
文件: rfx.c 项目: Arkantos7/FreeRDP
static void rfx_process_message_frame_begin(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s)
{
	UINT32 frameIdx;
	UINT16 numRegions;

	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) */

	DEBUG_RFX("RFX_FRAME_BEGIN: frameIdx:%d numRegions:%d", frameIdx, numRegions);
}
示例#12
0
void rfx_init_neon(RFX_CONTEXT * context)
{
	if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE))
	{
		DEBUG_RFX("Using NEON optimizations");

		IF_PROFILER(context->priv->prof_rfx_ycbcr_to_rgb->name = "rfx_decode_YCbCr_to_RGB_NEON");
		IF_PROFILER(context->priv->prof_rfx_quantization_decode->name = "rfx_quantization_decode_NEON");
		IF_PROFILER(context->priv->prof_rfx_dwt_2d_decode->name = "rfx_dwt_2d_decode_NEON");

		context->quantization_decode = rfx_quantization_decode_NEON;
		context->dwt_2d_decode = rfx_dwt_2d_decode_NEON;
	}
}
示例#13
0
static void rfx_process_message_codec_versions(RFX_CONTEXT* context, STREAM* s)
{
	uint8 numCodecs;

	rfx_parse_message_codec_versions(s, &numCodecs, &context->codec_id, &context->codec_version);

	if (numCodecs != 1)
	{
		DEBUG_WARN("numCodecs: %d, expected:1", numCodecs);
		return;
	}

	DEBUG_RFX("id %d version 0x%X.", context->codec_id, context->codec_version);
}
示例#14
0
static void rfx_process_message_context(RFX_CONTEXT* context, STREAM* s)
{
	uint8 ctxId;
	uint16 tileSize;
	uint16 properties;

	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, properties); /* properties (2 bytes) */

	DEBUG_RFX("ctxId %d tileSize %d properties 0x%X.", ctxId, tileSize, properties);

	context->properties = properties;
	context->flags = (properties & 0x0007);

	if (context->flags == CODEC_MODE)
		DEBUG_RFX("codec is in image mode.");
	else
		DEBUG_RFX("codec is in video mode.");

	switch ((properties & 0x1E00) >> 9)
	{
		case CLW_ENTROPY_RLGR1:
			context->mode = RLGR1;
			DEBUG_RFX("RLGR1.");
			break;

		case CLW_ENTROPY_RLGR3:
			context->mode = RLGR3;
			DEBUG_RFX("RLGR3.");
			break;

		default:
			DEBUG_WARN("unknown RLGR algorithm.");
			break;
	}
}
示例#15
0
文件: rfx.c 项目: nour8394/FreeRDP
static BOOL rfx_process_message_frame_begin(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s)
{
	UINT32 frameIdx;
	UINT16 numRegions;

	if (stream_get_left(s) < 6)
	{
		DEBUG_WARN("RfxMessageFrameBegin packet too small");
		return FALSE;
	}
	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) */

	DEBUG_RFX("RFX_FRAME_BEGIN: frameIdx:%d numRegions:%d", frameIdx, numRegions);
	return TRUE;
}
示例#16
0
void rfx_init_neon(RFX_CONTEXT * context)
{


    if(isNeonSupported())
    {
        DEBUG_RFX("Using NEON optimizations");

        IF_PROFILER(context->priv->prof_rfx_decode_ycbcr_to_rgb->name = "rfx_decode_YCbCr_to_RGB_NEON");
        IF_PROFILER(context->priv->prof_rfx_quantization_decode->name = "rfx_quantization_decode_NEON");
        IF_PROFILER(context->priv->prof_rfx_dwt_2d_decode->name = "rfx_dwt_2d_decode_NEON");

        context->decode_ycbcr_to_rgb = rfx_decode_YCbCr_to_RGB_NEON;
        context->quantization_decode = rfx_quantization_decode_NEON;
        context->dwt_2d_decode = rfx_dwt_2d_decode_NEON;
    }
}
示例#17
0
void rfx_init_sse(RFX_CONTEXT * context)
{
		DEBUG_RFX("Using SSE2 optimizations");

		IF_PROFILER(context->prof_rfx_decode_YCbCr_to_RGB->name = "rfx_decode_YCbCr_to_RGB_SSE2");
		IF_PROFILER(context->prof_rfx_encode_RGB_to_YCbCr->name = "rfx_encode_RGB_to_YCbCr_SSE2");
		IF_PROFILER(context->prof_rfx_quantization_decode->name = "rfx_quantization_decode_SSE2");
		IF_PROFILER(context->prof_rfx_quantization_encode->name = "rfx_quantization_encode_SSE2");
		IF_PROFILER(context->prof_rfx_dwt_2d_decode->name = "rfx_dwt_2d_decode_SSE2");
		IF_PROFILER(context->prof_rfx_dwt_2d_encode->name = "rfx_dwt_2d_encode_SSE2");
		
		context->decode_YCbCr_to_RGB = rfx_decode_YCbCr_to_RGB_SSE2;
		context->encode_RGB_to_YCbCr = rfx_encode_RGB_to_YCbCr_SSE2;
		context->quantization_decode = rfx_quantization_decode_SSE2;
		context->quantization_encode = rfx_quantization_encode_SSE2;
		context->dwt_2d_decode = rfx_dwt_2d_decode_SSE2;
		context->dwt_2d_encode = rfx_dwt_2d_encode_SSE2;
}
示例#18
0
文件: rfx.c 项目: Arkantos7/FreeRDP
static void rfx_process_message_codec_versions(RFX_CONTEXT* context, STREAM* s)
{
	BYTE numCodecs;

	stream_read_BYTE(s, numCodecs); /* numCodecs (1 byte), must be set to 0x01 */

	if (numCodecs != 1)
	{
		DEBUG_WARN("numCodecs: %d, expected:1", numCodecs);
		return;
	}

	/* RFX_CODEC_VERSIONT */
	stream_read_BYTE(s, context->codec_id); /* codecId (1 byte) */
	stream_read_BYTE(s, context->codec_version); /* version (2 bytes) */

	DEBUG_RFX("id %d version 0x%X.", context->codec_id, context->codec_version);
}
示例#19
0
void rfx_init_sse2(RFX_CONTEXT* context)
{
	DEBUG_RFX("Using SSE2 optimizations");

	IF_PROFILER(context->priv->prof_rfx_decode_ycbcr_to_rgb->name = "rfx_decode_ycbcr_to_rgb_sse2");
	IF_PROFILER(context->priv->prof_rfx_encode_rgb_to_ycbcr->name = "rfx_encode_rgb_to_ycbcr_sse2");
	IF_PROFILER(context->priv->prof_rfx_quantization_decode->name = "rfx_quantization_decode_sse2");
	IF_PROFILER(context->priv->prof_rfx_quantization_encode->name = "rfx_quantization_encode_sse2");
	IF_PROFILER(context->priv->prof_rfx_dwt_2d_decode->name = "rfx_dwt_2d_decode_sse2");
	IF_PROFILER(context->priv->prof_rfx_dwt_2d_encode->name = "rfx_dwt_2d_encode_sse2");

	context->decode_ycbcr_to_rgb = rfx_decode_ycbcr_to_rgb_sse2;
	context->encode_rgb_to_ycbcr = rfx_encode_rgb_to_ycbcr_sse2;
	context->quantization_decode = rfx_quantization_decode_sse2;
	context->quantization_encode = rfx_quantization_encode_sse2;
	context->dwt_2d_decode = rfx_dwt_2d_decode_sse2;
	context->dwt_2d_encode = rfx_dwt_2d_encode_sse2;
}
示例#20
0
文件: rfx_sse2.c 项目: blazee/FreeRDP
void rfx_init_sse2(RFX_CONTEXT* context)
{

	if (!IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE))
		return;

	DEBUG_RFX("Using SSE2 optimizations");

	IF_PROFILER(context->priv->prof_rfx_quantization_decode->name = "rfx_quantization_decode_sse2");
	IF_PROFILER(context->priv->prof_rfx_quantization_encode->name = "rfx_quantization_encode_sse2");
	IF_PROFILER(context->priv->prof_rfx_dwt_2d_decode->name = "rfx_dwt_2d_decode_sse2");
	IF_PROFILER(context->priv->prof_rfx_dwt_2d_encode->name = "rfx_dwt_2d_encode_sse2");

	context->quantization_decode = rfx_quantization_decode_sse2;
	context->quantization_encode = rfx_quantization_encode_sse2;
	context->dwt_2d_decode = rfx_dwt_2d_decode_sse2;
	context->dwt_2d_encode = rfx_dwt_2d_encode_sse2;
}
示例#21
0
文件: rfx.c 项目: nour8394/FreeRDP
static BOOL rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s)
{
	int i;

	if (stream_get_left(s) < 3)
	{
		DEBUG_WARN("RfxMessageRegion packet too small");
		return FALSE;
	}

	stream_seek_BYTE(s); /* regionFlags (1 byte) */
	stream_read_UINT16(s, message->num_rects); /* numRects (2 bytes) */

	if (message->num_rects < 1)
	{
		DEBUG_WARN("no rects.");
		return TRUE;
	}

	if (stream_get_left(s) < 8 * message->num_rects)
	{
		DEBUG_WARN("RfxMessageRegion packet too small for num_rects=%d", message->num_rects);
		return FALSE;
	}

	if (message->rects != NULL)
		message->rects = (RFX_RECT*) realloc(message->rects, message->num_rects * sizeof(RFX_RECT));
	else
		message->rects = (RFX_RECT*) malloc(message->num_rects * sizeof(RFX_RECT));

	/* rects */
	for (i = 0; i < message->num_rects; i++)
	{
		/* RFX_RECT */
		stream_read_UINT16(s, message->rects[i].x); /* x (2 bytes) */
		stream_read_UINT16(s, message->rects[i].y); /* y (2 bytes) */
		stream_read_UINT16(s, message->rects[i].width); /* width (2 bytes) */
		stream_read_UINT16(s, message->rects[i].height); /* height (2 bytes) */

		DEBUG_RFX("rect %d (%d %d %d %d).",
			i, message->rects[i].x, message->rects[i].y, message->rects[i].width, message->rects[i].height);
	}
	return TRUE;
}
示例#22
0
static void rfx_process_message_channels(RFX_CONTEXT* context, STREAM* s)
{
	context->channels = rfx_parse_message_channels(s, &context->num_channels, context->channels);
	/* In RDVH sessions, numChannels will represent the number of virtual monitors
	 * configured and does not always be set to 0x01 as [MS-RDPRFX] said.
	 */
	if (context->num_channels < 1)
	{
		DEBUG_WARN("numChannels:%d, expected:1", context->num_channels);
		return;
	}

	/* Now, only the first monitor can be used, therefore the other channels will be ignored. */
	context->width = context->channels[0].width;
	context->height = context->channels[0].height;

	DEBUG_RFX("numChannels %d id %d, %dx%d",
		context->num_channels, context->channels[0].channelId, context->width, context->height);
}
示例#23
0
static void rfx_process_message_sync(RFX_CONTEXT* context, STREAM* s)
{
	uint32 magic;

	rfx_parse_message_sync(s, &magic, &context->version);

	if (magic != WF_MAGIC)
	{
		DEBUG_WARN("invalid magic number 0x%X", magic);
		return;
	}

	if (context->version != WF_VERSION_1_0)
	{
		DEBUG_WARN("unknown version number 0x%X", context->version);
		return;
	}

	DEBUG_RFX("version 0x%X", context->version);
}
示例#24
0
文件: rfx.c 项目: nour8394/FreeRDP
static void rfx_compose_message_tile(RFX_CONTEXT* context, STREAM* s,
	BYTE* tile_data, int tile_width, int tile_height, int rowstride,
	const UINT32* quantVals, int quantIdxY, int quantIdxCb, int quantIdxCr,
	int xIdx, int yIdx)
{
	int YLen = 0;
	int CbLen = 0;
	int CrLen = 0;
	int start_pos, end_pos;

	stream_check_size(s, 19);
	start_pos = stream_get_pos(s);

	stream_write_UINT16(s, CBT_TILE); /* BlockT.blockType */
	stream_seek_UINT32(s); /* set BlockT.blockLen later */
	stream_write_BYTE(s, quantIdxY);
	stream_write_BYTE(s, quantIdxCb);
	stream_write_BYTE(s, quantIdxCr);
	stream_write_UINT16(s, xIdx);
	stream_write_UINT16(s, yIdx);

	stream_seek(s, 6); /* YLen, CbLen, CrLen */

	rfx_encode_rgb(context, tile_data, tile_width, tile_height, rowstride,
		quantVals + quantIdxY * 10, quantVals + quantIdxCb * 10, quantVals + quantIdxCr * 10,
		s, &YLen, &CbLen, &CrLen);

	DEBUG_RFX("xIdx=%d yIdx=%d width=%d height=%d YLen=%d CbLen=%d CrLen=%d",
		xIdx, yIdx, tile_width, tile_height, YLen, CbLen, CrLen);

	end_pos = stream_get_pos(s);

	stream_set_pos(s, start_pos + 2);
	stream_write_UINT32(s, 19 + YLen + CbLen + CrLen); /* BlockT.blockLen */
	stream_set_pos(s, start_pos + 13);
	stream_write_UINT16(s, YLen);
	stream_write_UINT16(s, CbLen);
	stream_write_UINT16(s, CrLen);

	stream_set_pos(s, end_pos);
}
示例#25
0
文件: rfx.c 项目: authentic8/FreeRDP
static void rfx_compose_message_tile(RFX_CONTEXT* context, wStream* s,
	BYTE* tile_data, int tile_width, int tile_height, int rowstride,
	const UINT32* quantVals, int quantIdxY, int quantIdxCb, int quantIdxCr,
	int xIdx, int yIdx)
{
	int YLen = 0;
	int CbLen = 0;
	int CrLen = 0;
	int start_pos, end_pos;

	Stream_EnsureRemainingCapacity(s, 19);
	start_pos = Stream_GetPosition(s);

	Stream_Write_UINT16(s, CBT_TILE); /* BlockT.blockType */
	Stream_Seek_UINT32(s); /* set BlockT.blockLen later */
	Stream_Write_UINT8(s, quantIdxY);
	Stream_Write_UINT8(s, quantIdxCb);
	Stream_Write_UINT8(s, quantIdxCr);
	Stream_Write_UINT16(s, xIdx);
	Stream_Write_UINT16(s, yIdx);

	Stream_Seek(s, 6); /* YLen, CbLen, CrLen */

	rfx_encode_rgb(context, tile_data, tile_width, tile_height, rowstride,
		quantVals + quantIdxY * 10, quantVals + quantIdxCb * 10, quantVals + quantIdxCr * 10,
		s, &YLen, &CbLen, &CrLen);

	DEBUG_RFX("xIdx=%d yIdx=%d width=%d height=%d YLen=%d CbLen=%d CrLen=%d",
		xIdx, yIdx, tile_width, tile_height, YLen, CbLen, CrLen);

	end_pos = Stream_GetPosition(s);

	Stream_SetPosition(s, start_pos + 2);
	Stream_Write_UINT32(s, 19 + YLen + CbLen + CrLen); /* BlockT.blockLen */
	Stream_SetPosition(s, start_pos + 13);
	Stream_Write_UINT16(s, YLen);
	Stream_Write_UINT16(s, CbLen);
	Stream_Write_UINT16(s, CrLen);

	Stream_SetPosition(s, end_pos);
}
示例#26
0
文件: rfx.c 项目: authentic8/FreeRDP
static BOOL rfx_process_message_channels(RFX_CONTEXT* context, wStream* s)
{
	BYTE channelId;
	BYTE numChannels;

	if (Stream_GetRemainingLength(s) < 1)
	{
		DEBUG_WARN("RfxMessageChannels packet too small");
		return FALSE;
	}

	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.
	 */
	if (numChannels < 1)
	{
		DEBUG_WARN("numChannels:%d, expected:1", numChannels);
		return TRUE;
	}

	if (Stream_GetRemainingLength(s) < numChannels * 5)
	{
		DEBUG_WARN("RfxMessageChannels packet too small for numChannels=%d", numChannels);
		return FALSE;
	}

	/* RFX_CHANNELT */
	Stream_Read_UINT8(s, channelId); /* channelId (1 byte) */
	Stream_Read_UINT16(s, context->width); /* width (2 bytes) */
	Stream_Read_UINT16(s, context->height); /* height (2 bytes) */

	/* Now, only the first monitor can be used, therefore the other channels will be ignored. */
	Stream_Seek(s, 5 * (numChannels - 1));

	DEBUG_RFX("numChannels %d id %d, %dx%d.",
		numChannels, channelId, context->width, context->height);
	return TRUE;
}
示例#27
0
文件: rfx.c 项目: Arkantos7/FreeRDP
static void rfx_process_message_sync(RFX_CONTEXT* context, STREAM* s)
{
	UINT32 magic;

	/* RFX_SYNC */
	stream_read_UINT32(s, magic); /* magic (4 bytes), 0xCACCACCA */

	if (magic != WF_MAGIC)
	{
		DEBUG_WARN("invalid magic number 0x%X", magic);
		return;
	}

	stream_read_UINT16(s, context->version); /* version (2 bytes), WF_VERSION_1_0 (0x0100) */

	if (context->version != WF_VERSION_1_0)
	{
		DEBUG_WARN("unknown version number 0x%X", context->version);
		return;
	}

	DEBUG_RFX("version 0x%X", context->version);
}
示例#28
0
文件: rfx.c 项目: nour8394/FreeRDP
static BOOL rfx_process_message_tile(RFX_CONTEXT* context, RFX_TILE* tile, STREAM* s)
{
	BYTE quantIdxY;
	BYTE quantIdxCb;
	BYTE quantIdxCr;
	UINT16 xIdx, yIdx;
	UINT16 YLen, CbLen, CrLen;

	if (stream_get_left(s) < 13)
	{
		DEBUG_WARN("RfxMessageTile packet too small");
		return FALSE;
	}

	/* RFX_TILE */
	stream_read_BYTE(s, quantIdxY); /* quantIdxY (1 byte) */
	stream_read_BYTE(s, quantIdxCb); /* quantIdxCb (1 byte) */
	stream_read_BYTE(s, quantIdxCr); /* quantIdxCr (1 byte) */
	stream_read_UINT16(s, xIdx); /* xIdx (2 bytes) */
	stream_read_UINT16(s, yIdx); /* yIdx (2 bytes) */
	stream_read_UINT16(s, YLen); /* YLen (2 bytes) */
	stream_read_UINT16(s, CbLen); /* CbLen (2 bytes) */
	stream_read_UINT16(s, CrLen); /* CrLen (2 bytes) */

	DEBUG_RFX("quantIdxY:%d quantIdxCb:%d quantIdxCr:%d xIdx:%d yIdx:%d YLen:%d CbLen:%d CrLen:%d",
		quantIdxY, quantIdxCb, quantIdxCr, xIdx, yIdx, YLen, CbLen, CrLen);

	tile->x = xIdx * 64;
	tile->y = yIdx * 64;

	return rfx_decode_rgb(context, s,
		YLen, context->quants + (quantIdxY * 10),
		CbLen, context->quants + (quantIdxCb * 10),
		CrLen, context->quants + (quantIdxCr * 10),
		tile->data, 64 * 4);
}
示例#29
0
文件: rfx.c 项目: nour8394/FreeRDP
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;
}
示例#30
0
文件: rfx.c 项目: nour8394/FreeRDP
static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s)
{
	int i;
	int pos;
	BYTE quant;
	UINT32* quants;
	UINT16 subtype;
	UINT32 blockLen;
	UINT32 blockType;
	UINT32 tilesDataSize;
	PTP_WORK* work_objects = NULL;
	RFX_TILE_WORK_PARAM* params = NULL;

	if (stream_get_left(s) < 14)
	{
		DEBUG_WARN("RfxMessageTileSet packet too small");
		return FALSE;
	}

	stream_read_UINT16(s, subtype); /* subtype (2 bytes) must be set to CBT_TILESET (0xCAC2) */

	if (subtype != CBT_TILESET)
	{
		DEBUG_WARN("invalid subtype, expected CBT_TILESET.");
		return FALSE;
	}

	stream_seek_UINT16(s); /* idx (2 bytes), must be set to 0x0000 */
	stream_seek_UINT16(s); /* properties (2 bytes) */

	stream_read_BYTE(s, context->num_quants); /* numQuant (1 byte) */
	stream_seek_BYTE(s); /* tileSize (1 byte), must be set to 0x40 */

	if (context->num_quants < 1)
	{
		DEBUG_WARN("no quantization value.");
		return TRUE;
	}

	stream_read_UINT16(s, message->num_tiles); /* numTiles (2 bytes) */

	if (message->num_tiles < 1)
	{
		DEBUG_WARN("no tiles.");
		return TRUE;
	}

	stream_read_UINT32(s, tilesDataSize); /* tilesDataSize (4 bytes) */

	if (context->quants != NULL)
		context->quants = (UINT32*) realloc((void*) context->quants, context->num_quants * 10 * sizeof(UINT32));
	else
		context->quants = (UINT32*) malloc(context->num_quants * 10 * sizeof(UINT32));
	quants = context->quants;

	/* quantVals */
	if (stream_get_left(s) < context->num_quants * 5)
	{
		DEBUG_WARN("RfxMessageTileSet packet too small for num_quants=%d", context->num_quants);
		return FALSE;
	}

	for (i = 0; i < context->num_quants; i++)
	{
		/* RFX_CODEC_QUANT */
		stream_read_BYTE(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);
		stream_read_BYTE(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);
		stream_read_BYTE(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);
		stream_read_BYTE(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);
		stream_read_BYTE(s, quant);
		*quants++ = (quant & 0x0F);
		*quants++ = (quant >> 4);

		DEBUG_RFX("quant %d (%d %d %d %d %d %d %d %d %d %d).",
			i, context->quants[i * 10], context->quants[i * 10 + 1],
			context->quants[i * 10 + 2], context->quants[i * 10 + 3],
			context->quants[i * 10 + 4], context->quants[i * 10 + 5],
			context->quants[i * 10 + 6], context->quants[i * 10 + 7],
			context->quants[i * 10 + 8], context->quants[i * 10 + 9]);
	}

	message->tiles = (RFX_TILE**) malloc(sizeof(RFX_TILE*) * message->num_tiles);
	ZeroMemory(message->tiles, sizeof(RFX_TILE*) * message->num_tiles);

	if (context->priv->UseThreads)
	{
		work_objects = (PTP_WORK*) malloc(sizeof(PTP_WORK) * message->num_tiles);
		params = (RFX_TILE_WORK_PARAM*) malloc(sizeof(RFX_TILE_WORK_PARAM) * message->num_tiles);
	}

	/* tiles */
	for (i = 0; i < message->num_tiles; i++)
	{
		/* RFX_TILE */
		if (stream_get_left(s) < 6)
		{
			DEBUG_WARN("RfxMessageTileSet packet too small to read tile %d/%d", i, message->num_tiles);
			return FALSE;
		}

		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_get_left(s) < blockLen - 6)
		{
			DEBUG_WARN("RfxMessageTileSet not enough bytes to read tile %d/%d with blocklen=%d", i, message->num_tiles, blockLen);
			return FALSE;
		}

		pos = stream_get_pos(s) - 6 + blockLen;

		if (blockType != CBT_TILE)
		{
			DEBUG_WARN("unknown block type 0x%X, expected CBT_TILE (0xCAC3).", blockType);
			break;
		}

		message->tiles[i] = rfx_tile_pool_take(context);

		if (context->priv->UseThreads)
		{
			params[i].context = context;
			params[i].tile = message->tiles[i];
			CopyMemory(&(params[i].s), s, sizeof(STREAM));

			work_objects[i] = CreateThreadpoolWork((PTP_WORK_CALLBACK) rfx_process_message_tile_work_callback,
					(void*) &params[i], &context->priv->ThreadPoolEnv);

			SubmitThreadpoolWork(work_objects[i]);
		}
		else
		{
			rfx_process_message_tile(context, message->tiles[i], s);
		}

		stream_set_pos(s, pos);
	}

	if (context->priv->UseThreads)
	{
		for (i = 0; i < message->num_tiles; i++)
			WaitForThreadpoolWorkCallbacks(work_objects[i], FALSE);

		free(work_objects);
		free(params);
	}
	return TRUE;
}