Merge pull request #3545 from akallabeth/legacy_rfx_fixes

Fixed Windows 7 RFX issues.
This commit is contained in:
Bernhard Miklautz 2016-10-13 13:01:53 +02:00 committed by GitHub
commit 5a5f091b7c
5 changed files with 418 additions and 405 deletions

View File

@ -970,96 +970,96 @@ static BOOL xf_gdi_surface_update_frame(xfContext* xfc, UINT16 tx, UINT16 ty,
return ret; return ret;
} }
static BOOL xf_gdi_update_screen(xfContext* xfc,
const SURFACE_BITS_COMMAND* cmd,
const BYTE* pSrcData)
{
BOOL ret;
XImage* image;
if (!xfc || !pSrcData)
return FALSE;
XSetFunction(xfc->display, xfc->gc, GXcopy);
XSetFillStyle(xfc->display, xfc->gc, FillSolid);
image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0,
(char*) pSrcData, cmd->width, cmd->height, xfc->scanline_pad, 0);
if (image)
{
XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0,
cmd->destLeft, cmd->destTop, cmd->width, cmd->height);
XFree(image);
ret = xf_gdi_surface_update_frame(xfc, cmd->destLeft, cmd->destTop, cmd->width,
cmd->height);
}
XSetClipMask(xfc->display, xfc->gc, None);
return ret;
}
static BOOL xf_gdi_surface_bits(rdpContext* context, static BOOL xf_gdi_surface_bits(rdpContext* context,
const SURFACE_BITS_COMMAND* cmd) const SURFACE_BITS_COMMAND* cmd)
{ {
XImage* image;
BYTE* pSrcData; BYTE* pSrcData;
BYTE* pDstData;
xfContext* xfc = (xfContext*) context; xfContext* xfc = (xfContext*) context;
BOOL ret = TRUE; BOOL ret = FALSE;
rdpGdi* gdi = context->gdi; DWORD format;
REGION16 invalidRegion; DWORD stride;
rdpGdi* gdi;
if (!context || !cmd || !context->gdi)
return FALSE;
gdi = context->gdi;
stride = cmd->width * GetBytesPerPixel(gdi->dstFormat);
xf_lock_x11(xfc, FALSE); xf_lock_x11(xfc, FALSE);
switch (cmd->codecID) switch (cmd->codecID)
{ {
case RDP_CODEC_ID_REMOTEFX: case RDP_CODEC_ID_REMOTEFX:
format = PIXEL_FORMAT_BGRX32;
if (!rfx_process_message(context->codecs->rfx, cmd->bitmapData, if (!rfx_process_message(context->codecs->rfx, cmd->bitmapData,
PIXEL_FORMAT_XRGB32, cmd->bitmapDataLength, format, cmd->bitmapDataLength,
cmd->destLeft, cmd->destTop, 0, 0,
gdi->primary_buffer, gdi->dstFormat, gdi->stride, gdi->primary_buffer, gdi->dstFormat, stride,
gdi->height, &invalidRegion)) gdi->height, NULL))
{ goto fail;
WLog_ERR(TAG, "Failed to process RemoteFX message");
xf_unlock_x11(xfc, FALSE);
return FALSE;
}
XRectangle rect;
rect.x = cmd->destLeft;
rect.y = cmd->destTop;
rect.width = cmd->width;
rect.height = cmd->height;
XSetFunction(xfc->display, xfc->gc, GXcopy);
XSetFillStyle(xfc->display, xfc->gc, FillSolid);
XSetClipRectangles(xfc->display, xfc->gc, cmd->destLeft, cmd->destTop,
&rect, 1, YXBanded);
/* Invalidate the updated region */
if (!xf_gdi_surface_update_frame(xfc, rect.x, rect.y,
rect.width, rect.height))
ret = FALSE;
XSetClipMask(xfc->display, xfc->gc, None);
break; break;
case RDP_CODEC_ID_NSCODEC: case RDP_CODEC_ID_NSCODEC:
if (!nsc_process_message(context->codecs->nsc, cmd->bpp, cmd->width, format = FREERDP_VFLIP_PIXEL_FORMAT(gdi->dstFormat);
cmd->height,
cmd->bitmapData, cmd->bitmapDataLength, if (!nsc_process_message(context->codecs->nsc, cmd->bpp, cmd->width,
gdi->primary_buffer, gdi->dstFormat, 0, 0, 0, cmd->width, cmd->height)) cmd->height, cmd->bitmapData, cmd->bitmapDataLength,
{ gdi->primary_buffer, format, stride,
xf_unlock_x11(xfc, FALSE); 0, 0, cmd->width, cmd->height))
return FALSE; goto fail;
}
XSetFunction(xfc->display, xfc->gc, GXcopy);
XSetFillStyle(xfc->display, xfc->gc, FillSolid);
pDstData = gdi->primary_buffer;
image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0,
(char*) pDstData, cmd->width, cmd->height, xfc->scanline_pad, 0);
XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0,
cmd->destLeft, cmd->destTop, cmd->width, cmd->height);
XFree(image);
ret = xf_gdi_surface_update_frame(xfc, cmd->destLeft, cmd->destTop, cmd->width,
cmd->height);
XSetClipMask(xfc->display, xfc->gc, None);
break; break;
case RDP_CODEC_ID_NONE: case RDP_CODEC_ID_NONE:
XSetFunction(xfc->display, xfc->gc, GXcopy);
XSetFillStyle(xfc->display, xfc->gc, FillSolid);
pSrcData = cmd->bitmapData; pSrcData = cmd->bitmapData;
pDstData = gdi->primary_buffer; format = PIXEL_FORMAT_BGRX32_VF;
freerdp_image_copy(pDstData, gdi->dstFormat, 0, 0, 0,
cmd->width, cmd->height, pSrcData, if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, stride,
PIXEL_FORMAT_BGRX32_VF, 0, 0, 0, &xfc->context.gdi->palette); 0, 0,
image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, cmd->width, cmd->height, pSrcData,
(char*) pDstData, cmd->width, cmd->height, xfc->scanline_pad, 0); format, 0, 0, 0, &xfc->context.gdi->palette))
XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, goto fail;
cmd->destLeft, cmd->destTop,
cmd->width, cmd->height);
XFree(image);
ret = xf_gdi_surface_update_frame(xfc, cmd->destLeft, cmd->destTop, cmd->width,
cmd->height);
XSetClipMask(xfc->display, xfc->gc, None);
break; break;
default: default:
WLog_ERR(TAG, "Unsupported codecID %d", cmd->codecID); WLog_ERR(TAG, "Unsupported codecID %d", cmd->codecID);
ret = TRUE;
goto fail;
} }
ret = xf_gdi_update_screen(xfc, cmd, gdi->primary_buffer);
fail:
xf_unlock_x11(xfc, FALSE); xf_unlock_x11(xfc, FALSE);
return ret; return ret;
} }

View File

@ -45,6 +45,12 @@
#define FREERDP_PIXEL_FORMAT_FLIP_MASKED(_format) (_format & 0x3FFFFFFF) #define FREERDP_PIXEL_FORMAT_FLIP_MASKED(_format) (_format & 0x3FFFFFFF)
#define FREERDP_VFLIP_PIXEL_FORMAT(format) \
FREERDP_PIXEL_FORMAT_FLIP_MASKED(format) | (FREERDP_PIXEL_FLIP_VERTICAL << 30)
#define FREERDP_HFLIP_PIXEL_FORMAT(format) \
FREERDP_PIXEL_FORMAT_FLIP_MASKED(format) | (FREERDP_PIXEL_FLIP_HORIZONTAL << 30)
/*** Design considerations /*** Design considerations
* *
* The format naming scheme is based on byte position in memory. * The format naming scheme is based on byte position in memory.
@ -168,128 +174,128 @@ static const char* GetColorFormatName(UINT32 format)
{ {
switch (format) switch (format)
{ {
/* 32bpp formats */ /* 32bpp formats */
case PIXEL_FORMAT_ARGB32: case PIXEL_FORMAT_ARGB32:
return "PIXEL_FORMAT_ARGB32"; return "PIXEL_FORMAT_ARGB32";
case PIXEL_FORMAT_ARGB32_VF: case PIXEL_FORMAT_ARGB32_VF:
return "PIXEL_FORMAT_ARGB32_VF"; return "PIXEL_FORMAT_ARGB32_VF";
case PIXEL_FORMAT_XRGB32: case PIXEL_FORMAT_XRGB32:
return "PIXEL_FORMAT_XRGB32"; return "PIXEL_FORMAT_XRGB32";
case PIXEL_FORMAT_XRGB32_VF: case PIXEL_FORMAT_XRGB32_VF:
return "PIXEL_FORMAT_XRGB32_VF"; return "PIXEL_FORMAT_XRGB32_VF";
case PIXEL_FORMAT_ABGR32: case PIXEL_FORMAT_ABGR32:
return "PIXEL_FORMAT_ABGR32"; return "PIXEL_FORMAT_ABGR32";
case PIXEL_FORMAT_ABGR32_VF: case PIXEL_FORMAT_ABGR32_VF:
return "PIXEL_FORMAT_ABGR32_VF"; return "PIXEL_FORMAT_ABGR32_VF";
case PIXEL_FORMAT_XBGR32: case PIXEL_FORMAT_XBGR32:
return "PIXEL_FORMAT_XBGR32"; return "PIXEL_FORMAT_XBGR32";
case PIXEL_FORMAT_XBGR32_VF: case PIXEL_FORMAT_XBGR32_VF:
return "PIXEL_FORMAT_XBGR32_VF"; return "PIXEL_FORMAT_XBGR32_VF";
case PIXEL_FORMAT_BGRA32: case PIXEL_FORMAT_BGRA32:
return "PIXEL_FORMAT_BGRA32"; return "PIXEL_FORMAT_BGRA32";
case PIXEL_FORMAT_BGRA32_VF: case PIXEL_FORMAT_BGRA32_VF:
return "PIXEL_FORMAT_BGRA32_VF"; return "PIXEL_FORMAT_BGRA32_VF";
case PIXEL_FORMAT_BGRX32: case PIXEL_FORMAT_BGRX32:
return "PIXEL_FORMAT_BGRX32"; return "PIXEL_FORMAT_BGRX32";
case PIXEL_FORMAT_BGRX32_VF: case PIXEL_FORMAT_BGRX32_VF:
return "PIXEL_FORMAT_BGRX32_VF"; return "PIXEL_FORMAT_BGRX32_VF";
case PIXEL_FORMAT_RGBA32: case PIXEL_FORMAT_RGBA32:
return "PIXEL_FORMAT_RGBA32"; return "PIXEL_FORMAT_RGBA32";
case PIXEL_FORMAT_RGBA32_VF: case PIXEL_FORMAT_RGBA32_VF:
return "PIXEL_FORMAT_RGBA32_VF"; return "PIXEL_FORMAT_RGBA32_VF";
case PIXEL_FORMAT_RGBX32: case PIXEL_FORMAT_RGBX32:
return "PIXEL_FORMAT_RGBX32"; return "PIXEL_FORMAT_RGBX32";
case PIXEL_FORMAT_RGBX32_VF: case PIXEL_FORMAT_RGBX32_VF:
return "PIXEL_FORMAT_RGBX32_VF"; return "PIXEL_FORMAT_RGBX32_VF";
/* 24bpp formats */ /* 24bpp formats */
case PIXEL_FORMAT_RGB24: case PIXEL_FORMAT_RGB24:
return "PIXEL_FORMAT_RGB24"; return "PIXEL_FORMAT_RGB24";
case PIXEL_FORMAT_RGB24_VF: case PIXEL_FORMAT_RGB24_VF:
return "PIXEL_FORMAT_RGB24_VF"; return "PIXEL_FORMAT_RGB24_VF";
case PIXEL_FORMAT_BGR24: case PIXEL_FORMAT_BGR24:
return "PIXEL_FORMAT_BGR24"; return "PIXEL_FORMAT_BGR24";
case PIXEL_FORMAT_BGR24_VF: case PIXEL_FORMAT_BGR24_VF:
return "PIXEL_FORMAT_BGR24_VF"; return "PIXEL_FORMAT_BGR24_VF";
/* 16bpp formats */ /* 16bpp formats */
case PIXEL_FORMAT_RGB16: case PIXEL_FORMAT_RGB16:
return "PIXEL_FORMAT_RGB16"; return "PIXEL_FORMAT_RGB16";
case PIXEL_FORMAT_RGB16_VF: case PIXEL_FORMAT_RGB16_VF:
return "PIXEL_FORMAT_RGB16_VF"; return "PIXEL_FORMAT_RGB16_VF";
case PIXEL_FORMAT_BGR16: case PIXEL_FORMAT_BGR16:
return "PIXEL_FORMAT_BGR16"; return "PIXEL_FORMAT_BGR16";
case PIXEL_FORMAT_BGR16_VF: case PIXEL_FORMAT_BGR16_VF:
return "PIXEL_FORMAT_BGR16_VF"; return "PIXEL_FORMAT_BGR16_VF";
case PIXEL_FORMAT_ARGB15: case PIXEL_FORMAT_ARGB15:
return "PIXEL_FORMAT_ARGB15"; return "PIXEL_FORMAT_ARGB15";
case PIXEL_FORMAT_ARGB15_VF: case PIXEL_FORMAT_ARGB15_VF:
return "PIXEL_FORMAT_ARGB15_VF"; return "PIXEL_FORMAT_ARGB15_VF";
case PIXEL_FORMAT_RGB15: case PIXEL_FORMAT_RGB15:
return "PIXEL_FORMAT_RGB15"; return "PIXEL_FORMAT_RGB15";
case PIXEL_FORMAT_RGB15_VF: case PIXEL_FORMAT_RGB15_VF:
return "PIXEL_FORMAT_ABGR15"; return "PIXEL_FORMAT_ABGR15";
case PIXEL_FORMAT_ABGR15: case PIXEL_FORMAT_ABGR15:
return ""; return "";
case PIXEL_FORMAT_ABGR15_VF: case PIXEL_FORMAT_ABGR15_VF:
return "PIXEL_FORMAT_ABGR15_VF"; return "PIXEL_FORMAT_ABGR15_VF";
case PIXEL_FORMAT_BGR15: case PIXEL_FORMAT_BGR15:
return "PIXEL_FORMAT_BGR15"; return "PIXEL_FORMAT_BGR15";
case PIXEL_FORMAT_BGR15_VF: case PIXEL_FORMAT_BGR15_VF:
return "PIXEL_FORMAT_BGR15_VF"; return "PIXEL_FORMAT_BGR15_VF";
/* 8bpp formats */ /* 8bpp formats */
case PIXEL_FORMAT_RGB8: case PIXEL_FORMAT_RGB8:
return "PIXEL_FORMAT_RGB8"; return "PIXEL_FORMAT_RGB8";
case PIXEL_FORMAT_RGB8_VF: case PIXEL_FORMAT_RGB8_VF:
return "PIXEL_FORMAT_RGB8_VF"; return "PIXEL_FORMAT_RGB8_VF";
/* 4 bpp formats */ /* 4 bpp formats */
case PIXEL_FORMAT_A4: case PIXEL_FORMAT_A4:
return "PIXEL_FORMAT_A4"; return "PIXEL_FORMAT_A4";
case PIXEL_FORMAT_A4_VF: case PIXEL_FORMAT_A4_VF:
return "PIXEL_FORMAT_A4_VF"; return "PIXEL_FORMAT_A4_VF";
/* 1bpp formats */ /* 1bpp formats */
case PIXEL_FORMAT_MONO: case PIXEL_FORMAT_MONO:
return "PIXEL_FORMAT_MONO"; return "PIXEL_FORMAT_MONO";
case PIXEL_FORMAT_MONO_VF: case PIXEL_FORMAT_MONO_VF:
return "PIXEL_FORMAT_MONO_VF"; return "PIXEL_FORMAT_MONO_VF";
default: default:
return "UNKNOWN"; return "UNKNOWN";
} }
} }
@ -313,9 +319,9 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
switch (FREERDP_PIXEL_FORMAT_FLIP_MASKED(format)) switch (FREERDP_PIXEL_FORMAT_FLIP_MASKED(format))
{ {
/* 32bpp formats */ /* 32bpp formats */
case PIXEL_FORMAT_ARGB32: case PIXEL_FORMAT_ARGB32:
if (_a) if (_a)
*_a = color >> 24; *_a = color >> 24;
if (_r) if (_r)
@ -327,10 +333,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
if (_b) if (_b)
*_b = color; *_b = color;
break; break;
case PIXEL_FORMAT_XRGB32: case PIXEL_FORMAT_XRGB32:
if (_r) if (_r)
*_r = color >> 16; *_r = color >> 16;
if (_g) if (_g)
@ -342,10 +348,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
if (_a) if (_a)
*_a = 0xFF; *_a = 0xFF;
break; break;
case PIXEL_FORMAT_ABGR32: case PIXEL_FORMAT_ABGR32:
if (_a) if (_a)
*_a = color >> 24; *_a = color >> 24;
if (_b) if (_b)
@ -357,10 +363,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
if (_r) if (_r)
*_r = color; *_r = color;
break; break;
case PIXEL_FORMAT_XBGR32: case PIXEL_FORMAT_XBGR32:
if (_b) if (_b)
*_b = color >> 16; *_b = color >> 16;
if (_g) if (_g)
@ -372,10 +378,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
if (_a) if (_a)
*_a = 0xFF; *_a = 0xFF;
break; break;
case PIXEL_FORMAT_RGBA32: case PIXEL_FORMAT_RGBA32:
if (_r) if (_r)
*_r = color >> 24; *_r = color >> 24;
if (_g) if (_g)
@ -387,10 +393,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
if (_a) if (_a)
*_a = color; *_a = color;
break; break;
case PIXEL_FORMAT_RGBX32: case PIXEL_FORMAT_RGBX32:
if (_r) if (_r)
*_r = color >> 24; *_r = color >> 24;
if (_g) if (_g)
@ -402,10 +408,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
if (_a) if (_a)
*_a = 0xFF; *_a = 0xFF;
break; break;
case PIXEL_FORMAT_BGRA32: case PIXEL_FORMAT_BGRA32:
if (_b) if (_b)
*_b = color >> 24; *_b = color >> 24;
if (_g) if (_g)
@ -417,10 +423,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
if (_a) if (_a)
*_a = color; *_a = color;
break; break;
case PIXEL_FORMAT_BGRX32: case PIXEL_FORMAT_BGRX32:
if (_b) if (_b)
*_b = color >> 24; *_b = color >> 24;
if (_g) if (_g)
@ -432,11 +438,11 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
if (_a) if (_a)
*_a = 0xFF; *_a = 0xFF;
break; break;
/* 24bpp formats */ /* 24bpp formats */
case PIXEL_FORMAT_RGB24: case PIXEL_FORMAT_RGB24:
if (_r) if (_r)
*_r = color >> 16; *_r = color >> 16;
if (_g) if (_g)
@ -448,10 +454,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
if (_a) if (_a)
*_a = 0xFF; *_a = 0xFF;
break; break;
case PIXEL_FORMAT_BGR24: case PIXEL_FORMAT_BGR24:
if (_b) if (_b)
*_b = color >> 16; *_b = color >> 16;
if (_g) if (_g)
@ -463,11 +469,11 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
if (_a) if (_a)
*_a = 0xFF; *_a = 0xFF;
break; break;
/* 16bpp formats */ /* 16bpp formats */
case PIXEL_FORMAT_RGB16: case PIXEL_FORMAT_RGB16:
if (_r) if (_r)
*_r = ((color >> 11) & 0x1F) << 3; *_r = ((color >> 11) & 0x1F) << 3;
if (_g) if (_g)
@ -479,10 +485,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
if (_a) if (_a)
*_a = 0xFF; *_a = 0xFF;
break; break;
case PIXEL_FORMAT_BGR16: case PIXEL_FORMAT_BGR16:
if (_b) if (_b)
*_b = ((color >> 11) & 0x1F) << 3; *_b = ((color >> 11) & 0x1F) << 3;
if (_g) if (_g)
@ -494,10 +500,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
if (_a) if (_a)
*_a = 0xFF; *_a = 0xFF;
break; break;
case PIXEL_FORMAT_ARGB15: case PIXEL_FORMAT_ARGB15:
if (_r) if (_r)
*_r = ((color >> 10) & 0x1F) << 3; *_r = ((color >> 10) & 0x1F) << 3;
if (_g) if (_g)
@ -509,10 +515,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
if (_a) if (_a)
*_a = color & 0x8000 ? 0xFF : 0x00; *_a = color & 0x8000 ? 0xFF : 0x00;
break; break;
case PIXEL_FORMAT_ABGR15: case PIXEL_FORMAT_ABGR15:
if (_b) if (_b)
*_b = ((color >> 10) & 0x1F) << 3; *_b = ((color >> 10) & 0x1F) << 3;
if (_g) if (_g)
@ -524,11 +530,11 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
if (_a) if (_a)
*_a = color & 0x8000 ? 0xFF : 0x00; *_a = color & 0x8000 ? 0xFF : 0x00;
break; break;
/* 15bpp formats */ /* 15bpp formats */
case PIXEL_FORMAT_RGB15: case PIXEL_FORMAT_RGB15:
if (_r) if (_r)
*_r = ((color >> 10) & 0x1F) << 3; *_r = ((color >> 10) & 0x1F) << 3;
if (_g) if (_g)
@ -540,10 +546,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
if (_a) if (_a)
*_a = 0xFF; *_a = 0xFF;
break; break;
case PIXEL_FORMAT_BGR15: case PIXEL_FORMAT_BGR15:
if (_b) if (_b)
*_b = ((color >> 10) & 0x1F) << 3; *_b = ((color >> 10) & 0x1F) << 3;
if (_g) if (_g)
@ -555,21 +561,21 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
if (_a) if (_a)
*_a = 0xFF; *_a = 0xFF;
break; break;
/* 8bpp formats */ /* 8bpp formats */
case PIXEL_FORMAT_RGB8: case PIXEL_FORMAT_RGB8:
if (color <= 0xFF) if (color <= 0xFF)
{ {
tmp = palette->palette[color]; tmp = palette->palette[color];
SplitColor(tmp, palette->format, _r, _g, _b, _a, NULL); SplitColor(tmp, palette->format, _r, _g, _b, _a, NULL);
} }
break; break;
/* 1bpp formats */ /* 1bpp formats */
case PIXEL_FORMAT_MONO: case PIXEL_FORMAT_MONO:
if (_r) if (_r)
*_r = (color) ? 0xFF : 0x00; *_r = (color) ? 0xFF : 0x00;
if (_g) if (_g)
@ -581,13 +587,13 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
if (_a) if (_a)
*_a = (color) ? 0xFF : 0x00; *_a = (color) ? 0xFF : 0x00;
break; break;
/* 4 bpp formats */ /* 4 bpp formats */
case PIXEL_FORMAT_A4: case PIXEL_FORMAT_A4:
default: default:
WLog_ERR("xxxxx", "Unsupported format %s", GetColorFormatName(format)); WLog_ERR("xxxxx", "Unsupported format %s", GetColorFormatName(format));
break; break;
} }
} }
@ -613,75 +619,75 @@ static INLINE UINT32 GetColor(UINT32 format, BYTE r, BYTE g, BYTE b, BYTE a)
switch (FREERDP_PIXEL_FORMAT_FLIP_MASKED(format)) switch (FREERDP_PIXEL_FORMAT_FLIP_MASKED(format))
{ {
/* 32bpp formats */ /* 32bpp formats */
case PIXEL_FORMAT_ARGB32: case PIXEL_FORMAT_ARGB32:
return (_a << 24) | (_r << 16) | (_g << 8) | _b; return (_a << 24) | (_r << 16) | (_g << 8) | _b;
case PIXEL_FORMAT_XRGB32: case PIXEL_FORMAT_XRGB32:
return (_r << 16) | (_g << 8) | _b; return (_r << 16) | (_g << 8) | _b;
case PIXEL_FORMAT_ABGR32: case PIXEL_FORMAT_ABGR32:
return (_a << 24) | (_b << 16) | (_g << 8) | _r; return (_a << 24) | (_b << 16) | (_g << 8) | _r;
case PIXEL_FORMAT_XBGR32: case PIXEL_FORMAT_XBGR32:
return (_b << 16) | (_g << 8) | _r; return (_b << 16) | (_g << 8) | _r;
case PIXEL_FORMAT_RGBA32: case PIXEL_FORMAT_RGBA32:
return (_r << 24) | (_g << 16) | (_b << 8) | _a; return (_r << 24) | (_g << 16) | (_b << 8) | _a;
case PIXEL_FORMAT_RGBX32: case PIXEL_FORMAT_RGBX32:
return (_r << 24) | (_g << 16) | (_b << 8) | _a; return (_r << 24) | (_g << 16) | (_b << 8) | _a;
case PIXEL_FORMAT_BGRA32: case PIXEL_FORMAT_BGRA32:
return (_b << 24) | (_g << 16) | (_r << 8) | _a; return (_b << 24) | (_g << 16) | (_r << 8) | _a;
case PIXEL_FORMAT_BGRX32: case PIXEL_FORMAT_BGRX32:
return (_b << 24) | (_g << 16) | (_r << 8) | _a; return (_b << 24) | (_g << 16) | (_r << 8) | _a;
/* 24bpp formats */ /* 24bpp formats */
case PIXEL_FORMAT_RGB24: case PIXEL_FORMAT_RGB24:
return (_r << 16) | (_g << 8) | _b; return (_r << 16) | (_g << 8) | _b;
case PIXEL_FORMAT_BGR24: case PIXEL_FORMAT_BGR24:
return (_b << 16) | (_g << 8) | _r; return (_b << 16) | (_g << 8) | _r;
/* 16bpp formats */ /* 16bpp formats */
case PIXEL_FORMAT_RGB16: case PIXEL_FORMAT_RGB16:
return (((_r >> 3) & 0x1F) << 11) | (((_g >> 2) & 0x3F) << 5) | (( return (((_r >> 3) & 0x1F) << 11) | (((_g >> 2) & 0x3F) << 5) | ((
_b >> 3) & 0x1F); _b >> 3) & 0x1F);
case PIXEL_FORMAT_BGR16: case PIXEL_FORMAT_BGR16:
return (((_b >> 3) & 0x1F) << 11) | (((_g >> 2) & 0x3F) << 5) | (( return (((_b >> 3) & 0x1F) << 11) | (((_g >> 2) & 0x3F) << 5) | ((
_r >> 3) & 0x1F); _r >> 3) & 0x1F);
case PIXEL_FORMAT_ARGB15: case PIXEL_FORMAT_ARGB15:
return (((_r >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | (( return (((_r >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | ((
_b >> 3) & 0x1F) | (_a ? 0x8000 : 0x0000); _b >> 3) & 0x1F) | (_a ? 0x8000 : 0x0000);
case PIXEL_FORMAT_ABGR15: case PIXEL_FORMAT_ABGR15:
return (((_b >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | (( return (((_b >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | ((
_r >> 3) & 0x1F) | (_a ? 0x8000 : 0x0000); _r >> 3) & 0x1F) | (_a ? 0x8000 : 0x0000);
/* 15bpp formats */ /* 15bpp formats */
case PIXEL_FORMAT_RGB15: case PIXEL_FORMAT_RGB15:
return (((_r >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | (( return (((_r >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | ((
_b >> 3) & 0x1F); _b >> 3) & 0x1F);
case PIXEL_FORMAT_BGR15: case PIXEL_FORMAT_BGR15:
return (((_b >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | (( return (((_b >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | ((
_r >> 3) & 0x1F); _r >> 3) & 0x1F);
/* 8bpp formats */ /* 8bpp formats */
case PIXEL_FORMAT_RGB8: case PIXEL_FORMAT_RGB8:
/* 4 bpp formats */ /* 4 bpp formats */
case PIXEL_FORMAT_A4: case PIXEL_FORMAT_A4:
/* 1bpp formats */ /* 1bpp formats */
case PIXEL_FORMAT_MONO: case PIXEL_FORMAT_MONO:
default: default:
WLog_ERR("xxxxx", "Unsupported format %s", GetColorFormatName(format)); WLog_ERR("xxxxx", "Unsupported format %s", GetColorFormatName(format));
return 0; return 0;
} }
} }
@ -728,37 +734,37 @@ static INLINE UINT32 ReadColor(const BYTE* src, UINT32 format)
switch (GetBitsPerPixel(format)) switch (GetBitsPerPixel(format))
{ {
case 32: case 32:
color = ((UINT32)src[0] << 24) | ((UINT32)src[1] << 16) | color = ((UINT32)src[0] << 24) | ((UINT32)src[1] << 16) |
((UINT32)src[2] << 8) | src[3]; ((UINT32)src[2] << 8) | src[3];
break; break;
case 24: case 24:
color = ((UINT32)src[0] << 16) | ((UINT32)src[1] << 8) | src[2]; color = ((UINT32)src[0] << 16) | ((UINT32)src[1] << 8) | src[2];
break; break;
case 16: case 16:
color = ((UINT32)src[1] << 8) | src[0]; color = ((UINT32)src[1] << 8) | src[0];
break; break;
case 15: case 15:
color = ((UINT32)src[1] << 8) | src[0]; color = ((UINT32)src[1] << 8) | src[0];
if (!ColorHasAlpha(format)) if (!ColorHasAlpha(format))
color = color & 0x7FFF; color = color & 0x7FFF;
break; break;
case 8: case 8:
case 4: case 4:
case 1: case 1:
color = *src; color = *src;
break; break;
default: default:
WLog_ERR("xxxxx", "Unsupported format %s", GetColorFormatName(format)); WLog_ERR("xxxxx", "Unsupported format %s", GetColorFormatName(format));
color = 0; color = 0;
break; break;
} }
return color; return color;
@ -778,39 +784,39 @@ static INLINE BOOL WriteColor(BYTE* dst, UINT32 format, UINT32 color)
{ {
switch (GetBitsPerPixel(format)) switch (GetBitsPerPixel(format))
{ {
case 32: case 32:
dst[0] = color >> 24; dst[0] = color >> 24;
dst[1] = color >> 16; dst[1] = color >> 16;
dst[2] = color >> 8; dst[2] = color >> 8;
dst[3] = color; dst[3] = color;
break; break;
case 24: case 24:
dst[0] = color >> 16; dst[0] = color >> 16;
dst[1] = color >> 8; dst[1] = color >> 8;
dst[2] = color; dst[2] = color;
break; break;
case 16: case 16:
dst[1] = color >> 8; dst[1] = color >> 8;
dst[0] = color; dst[0] = color;
break; break;
case 15: case 15:
if (!ColorHasAlpha(format)) if (!ColorHasAlpha(format))
color = color & 0x7FFF; color = color & 0x7FFF;
dst[1] = color >> 8; dst[1] = color >> 8;
dst[0] = color; dst[0] = color;
break; break;
case 8: case 8:
dst[0] = color; dst[0] = color;
break; break;
default: default:
WLog_ERR("xxxxx", "Unsupported format %s", GetColorFormatName(format)); WLog_ERR("xxxxx", "Unsupported format %s", GetColorFormatName(format));
return FALSE; return FALSE;
} }
return TRUE; return TRUE;

View File

@ -407,7 +407,7 @@ BOOL nsc_process_message(NSC_CONTEXT* context, UINT16 bpp,
if (!freerdp_image_copy(pDstData, DstFormat, nDstStride, nXDst, nYDst, if (!freerdp_image_copy(pDstData, DstFormat, nDstStride, nXDst, nYDst,
width, height, context->BitmapData, width, height, context->BitmapData,
PIXEL_FORMAT_BGRX32_VF, 0, 0, 0, NULL)) PIXEL_FORMAT_BGRA32, 0, 0, 0, NULL))
return FALSE; return FALSE;
return TRUE; return TRUE;

View File

@ -83,28 +83,28 @@ 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_rgb, "rfx_decode_rgb");
PROFILER_CREATE(context->priv->prof_rfx_decode_component, PROFILER_CREATE(context->priv->prof_rfx_decode_component,
"rfx_decode_component"); "rfx_decode_component");
PROFILER_CREATE(context->priv->prof_rfx_rlgr_decode, "rfx_rlgr_decode"); PROFILER_CREATE(context->priv->prof_rfx_rlgr_decode, "rfx_rlgr_decode");
PROFILER_CREATE(context->priv->prof_rfx_differential_decode, PROFILER_CREATE(context->priv->prof_rfx_differential_decode,
"rfx_differential_decode"); "rfx_differential_decode");
PROFILER_CREATE(context->priv->prof_rfx_quantization_decode, PROFILER_CREATE(context->priv->prof_rfx_quantization_decode,
"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_dwt_2d_decode, "rfx_dwt_2d_decode");
PROFILER_CREATE(context->priv->prof_rfx_ycbcr_to_rgb, "prims->yCbCrToRGB"); PROFILER_CREATE(context->priv->prof_rfx_ycbcr_to_rgb, "prims->yCbCrToRGB");
PROFILER_CREATE(context->priv->prof_rfx_decode_format_rgb, PROFILER_CREATE(context->priv->prof_rfx_decode_format_rgb,
"rfx_decode_format_rgb"); "rfx_decode_format_rgb");
PROFILER_CREATE(context->priv->prof_rfx_encode_rgb, "rfx_encode_rgb"); PROFILER_CREATE(context->priv->prof_rfx_encode_rgb, "rfx_encode_rgb");
PROFILER_CREATE(context->priv->prof_rfx_encode_component, PROFILER_CREATE(context->priv->prof_rfx_encode_component,
"rfx_encode_component"); "rfx_encode_component");
PROFILER_CREATE(context->priv->prof_rfx_rlgr_encode, "rfx_rlgr_encode"); PROFILER_CREATE(context->priv->prof_rfx_rlgr_encode, "rfx_rlgr_encode");
PROFILER_CREATE(context->priv->prof_rfx_differential_encode, PROFILER_CREATE(context->priv->prof_rfx_differential_encode,
"rfx_differential_encode"); "rfx_differential_encode");
PROFILER_CREATE(context->priv->prof_rfx_quantization_encode, PROFILER_CREATE(context->priv->prof_rfx_quantization_encode,
"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_dwt_2d_encode, "rfx_dwt_2d_encode");
PROFILER_CREATE(context->priv->prof_rfx_rgb_to_ycbcr, "prims->RGBToYCbCr"); PROFILER_CREATE(context->priv->prof_rfx_rgb_to_ycbcr, "prims->RGBToYCbCr");
PROFILER_CREATE(context->priv->prof_rfx_encode_format_rgb, PROFILER_CREATE(context->priv->prof_rfx_encode_format_rgb,
"rfx_encode_format_rgb"); "rfx_encode_format_rgb");
} }
static void rfx_profiler_free(RFX_CONTEXT* context) static void rfx_profiler_free(RFX_CONTEXT* context)
@ -275,7 +275,7 @@ RFX_CONTEXT* rfx_context_new(BOOL encoder)
verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
GetVersionExA(&verinfo); GetVersionExA(&verinfo);
isVistaOrLater = ((verinfo.dwMajorVersion >= 6) isVistaOrLater = ((verinfo.dwMajorVersion >= 6)
&& (verinfo.dwMinorVersion >= 0)) ? TRUE : FALSE; && (verinfo.dwMinorVersion >= 0)) ? TRUE : FALSE;
priv->UseThreads = isVistaOrLater; priv->UseThreads = isVistaOrLater;
} }
#else #else
@ -285,22 +285,22 @@ RFX_CONTEXT* rfx_context_new(BOOL encoder)
priv->MinThreadCount = sysinfo.dwNumberOfProcessors; priv->MinThreadCount = sysinfo.dwNumberOfProcessors;
priv->MaxThreadCount = 0; priv->MaxThreadCount = 0;
status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, RFX_KEY, 0, status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, RFX_KEY, 0,
KEY_READ | KEY_WOW64_64KEY, &hKey); KEY_READ | KEY_WOW64_64KEY, &hKey);
if (status == ERROR_SUCCESS) if (status == ERROR_SUCCESS)
{ {
dwSize = sizeof(dwValue); dwSize = sizeof(dwValue);
if (RegQueryValueEx(hKey, _T("UseThreads"), NULL, &dwType, (BYTE*) &dwValue, if (RegQueryValueEx(hKey, _T("UseThreads"), NULL, &dwType, (BYTE*) &dwValue,
&dwSize) == ERROR_SUCCESS) &dwSize) == ERROR_SUCCESS)
priv->UseThreads = dwValue ? 1 : 0; priv->UseThreads = dwValue ? 1 : 0;
if (RegQueryValueEx(hKey, _T("MinThreadCount"), NULL, &dwType, (BYTE*) &dwValue, if (RegQueryValueEx(hKey, _T("MinThreadCount"), NULL, &dwType, (BYTE*) &dwValue,
&dwSize) == ERROR_SUCCESS) &dwSize) == ERROR_SUCCESS)
priv->MinThreadCount = dwValue; priv->MinThreadCount = dwValue;
if (RegQueryValueEx(hKey, _T("MaxThreadCount"), NULL, &dwType, (BYTE*) &dwValue, if (RegQueryValueEx(hKey, _T("MaxThreadCount"), NULL, &dwType, (BYTE*) &dwValue,
&dwSize) == ERROR_SUCCESS) &dwSize) == ERROR_SUCCESS)
priv->MaxThreadCount = dwValue; priv->MaxThreadCount = dwValue;
RegCloseKey(hKey); RegCloseKey(hKey);
@ -378,7 +378,7 @@ void rfx_context_free(RFX_CONTEXT* context)
free(priv->tileWorkParams); free(priv->tileWorkParams);
#ifdef WITH_PROFILER #ifdef WITH_PROFILER
WLog_VRB(TAG, WLog_VRB(TAG,
"WARNING: Profiling results probably unusable with multithreaded RemoteFX codec!"); "WARNING: Profiling results probably unusable with multithreaded RemoteFX codec!");
#endif #endif
} }
@ -436,7 +436,7 @@ static BOOL rfx_process_message_sync(RFX_CONTEXT* context, wStream* s)
} }
Stream_Read_UINT16(s, Stream_Read_UINT16(s,
context->version); /* version (2 bytes), WF_VERSION_1_0 (0x0100) */ context->version); /* version (2 bytes), WF_VERSION_1_0 (0x0100) */
if (context->version != WF_VERSION_1_0) if (context->version != WF_VERSION_1_0)
{ {
@ -462,9 +462,9 @@ 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, numCodecs); /* numCodecs (1 byte), must be set to 0x01 */
Stream_Read_UINT8(s, Stream_Read_UINT8(s,
context->codec_id); /* codecId (1 byte), must be set to 0x01 */ context->codec_id); /* codecId (1 byte), must be set to 0x01 */
Stream_Read_UINT16(s, Stream_Read_UINT16(s,
context->codec_version); /* version (2 bytes), must be set to WF_VERSION_1_0 (0x0100) */ context->codec_version); /* version (2 bytes), must be set to WF_VERSION_1_0 (0x0100) */
if (numCodecs != 1) if (numCodecs != 1)
{ {
@ -481,12 +481,12 @@ static BOOL rfx_process_message_codec_versions(RFX_CONTEXT* context, wStream* s)
if (context->codec_version != WF_VERSION_1_0) if (context->codec_version != WF_VERSION_1_0)
{ {
WLog_ERR(TAG, "%s: invalid codec version (0x%04X)", __FUNCTION__, WLog_ERR(TAG, "%s: invalid codec version (0x%04X)", __FUNCTION__,
context->codec_version); context->codec_version);
return FALSE; return FALSE;
} }
WLog_Print(context->priv->log, WLOG_DEBUG, "id %d version 0x%X.", WLog_Print(context->priv->log, WLOG_DEBUG, "id %d version 0x%X.",
context->codec_id, context->codec_version); context->codec_id, context->codec_version);
context->decodedHeaderBlocks |= _RFX_DECODED_VERSIONS; context->decodedHeaderBlocks |= _RFX_DECODED_VERSIONS;
return TRUE; return TRUE;
} }
@ -504,7 +504,7 @@ static BOOL rfx_process_message_channels(RFX_CONTEXT* context, wStream* s)
} }
Stream_Read_UINT8(s, Stream_Read_UINT8(s,
numChannels); /* numChannels (1 byte), must bet set to 0x01 */ numChannels); /* numChannels (1 byte), must bet set to 0x01 */
/* In RDVH sessions, numChannels will represent the number of virtual monitors /* In RDVH sessions, numChannels will represent the number of virtual monitors
* configured and does not always be set to 0x01 as [MS-RDPRFX] said. * configured and does not always be set to 0x01 as [MS-RDPRFX] said.
@ -518,7 +518,7 @@ static BOOL rfx_process_message_channels(RFX_CONTEXT* context, wStream* s)
if (Stream_GetRemainingLength(s) < (size_t)(numChannels * 5)) if (Stream_GetRemainingLength(s) < (size_t)(numChannels * 5))
{ {
WLog_ERR(TAG, "RfxMessageChannels packet too small for numChannels=%d", WLog_ERR(TAG, "RfxMessageChannels packet too small for numChannels=%d",
numChannels); numChannels);
return FALSE; return FALSE;
} }
@ -537,14 +537,14 @@ static BOOL rfx_process_message_channels(RFX_CONTEXT* context, wStream* s)
if (!context->width || !context->height) if (!context->width || !context->height)
{ {
WLog_ERR(TAG, "%s: invalid channel with/height: %ux%u", __FUNCTION__, WLog_ERR(TAG, "%s: invalid channel with/height: %ux%u", __FUNCTION__,
context->width, context->height); context->width, context->height);
return FALSE; return FALSE;
} }
/* Now, only the first monitor can be used, therefore the other channels will be ignored. */ /* Now, only the first monitor can be used, therefore the other channels will be ignored. */
Stream_Seek(s, 5 * (numChannels - 1)); Stream_Seek(s, 5 * (numChannels - 1));
WLog_Print(context->priv->log, WLOG_DEBUG, "numChannels %d id %d, %dx%d.", WLog_Print(context->priv->log, WLOG_DEBUG, "numChannels %d id %d, %dx%d.",
numChannels, channelId, context->width, context->height); numChannels, channelId, context->width, context->height);
context->decodedHeaderBlocks |= _RFX_DECODED_CHANNELS; context->decodedHeaderBlocks |= _RFX_DECODED_CHANNELS;
return TRUE; return TRUE;
} }
@ -564,11 +564,11 @@ 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_UINT8(s, ctxId); /* ctxId (1 byte), must be set to 0x00 */
Stream_Read_UINT16(s, Stream_Read_UINT16(s,
tileSize); /* tileSize (2 bytes), must be set to CT_TILE_64x64 (0x0040) */ tileSize); /* tileSize (2 bytes), must be set to CT_TILE_64x64 (0x0040) */
Stream_Read_UINT16(s, properties); /* properties (2 bytes) */ Stream_Read_UINT16(s, properties); /* properties (2 bytes) */
WLog_Print(context->priv->log, WLOG_DEBUG, WLog_Print(context->priv->log, WLOG_DEBUG,
"ctxId %d tileSize %d properties 0x%X.", "ctxId %d tileSize %d properties 0x%X.",
ctxId, tileSize, properties); ctxId, tileSize, properties);
context->properties = properties; context->properties = properties;
context->flags = (properties & 0x0007); context->flags = (properties & 0x0007);
@ -603,7 +603,7 @@ static BOOL rfx_process_message_context(RFX_CONTEXT* context, wStream* s)
} }
static BOOL rfx_process_message_frame_begin(RFX_CONTEXT* context, static BOOL rfx_process_message_frame_begin(RFX_CONTEXT* context,
RFX_MESSAGE* message, wStream* s, UINT16* pExpectedBlockType) RFX_MESSAGE* message, wStream* s, UINT16* pExpectedBlockType)
{ {
UINT32 frameIdx; UINT32 frameIdx;
UINT16 numRegions; UINT16 numRegions;
@ -623,15 +623,15 @@ static BOOL rfx_process_message_frame_begin(RFX_CONTEXT* context,
} }
Stream_Read_UINT32(s, Stream_Read_UINT32(s,
frameIdx); /* frameIdx (4 bytes), if codec is in video mode, must be ignored */ frameIdx); /* frameIdx (4 bytes), if codec is in video mode, must be ignored */
Stream_Read_UINT16(s, numRegions); /* numRegions (2 bytes) */ Stream_Read_UINT16(s, numRegions); /* numRegions (2 bytes) */
WLog_Print(context->priv->log, WLOG_DEBUG, WLog_Print(context->priv->log, WLOG_DEBUG,
"RFX_FRAME_BEGIN: frameIdx: %d numRegions: %d", frameIdx, numRegions); "RFX_FRAME_BEGIN: frameIdx: %d numRegions: %d", frameIdx, numRegions);
return TRUE; return TRUE;
} }
static BOOL rfx_process_message_frame_end(RFX_CONTEXT* context, static BOOL rfx_process_message_frame_end(RFX_CONTEXT* context,
RFX_MESSAGE* message, wStream* s, UINT16* pExpectedBlockType) RFX_MESSAGE* message, wStream* s, UINT16* pExpectedBlockType)
{ {
if (*pExpectedBlockType != WBT_FRAME_END) if (*pExpectedBlockType != WBT_FRAME_END)
{ {
@ -645,7 +645,7 @@ static BOOL rfx_process_message_frame_end(RFX_CONTEXT* context,
} }
static BOOL rfx_process_message_region(RFX_CONTEXT* context, static BOOL rfx_process_message_region(RFX_CONTEXT* context,
RFX_MESSAGE* message, wStream* s, UINT16* pExpectedBlockType) RFX_MESSAGE* message, wStream* s, UINT16* pExpectedBlockType)
{ {
int i; int i;
UINT16 regionType; UINT16 regionType;
@ -690,7 +690,7 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context,
if (Stream_GetRemainingLength(s) < (size_t)(8 * message->numRects)) if (Stream_GetRemainingLength(s) < (size_t)(8 * message->numRects))
{ {
WLog_ERR(TAG, "%s: packet too small for num_rects=%d", __FUNCTION__, WLog_ERR(TAG, "%s: packet too small for num_rects=%d", __FUNCTION__,
message->numRects); message->numRects);
return FALSE; return FALSE;
} }
@ -707,8 +707,8 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context,
Stream_Read_UINT16(s, rect->width); /* width (2 bytes) */ Stream_Read_UINT16(s, rect->width); /* width (2 bytes) */
Stream_Read_UINT16(s, rect->height); /* height (2 bytes) */ Stream_Read_UINT16(s, rect->height); /* height (2 bytes) */
WLog_Print(context->priv->log, WLOG_DEBUG, "rect %d (x,y=%d,%d w,h=%d %d).", i, WLog_Print(context->priv->log, WLOG_DEBUG, "rect %d (x,y=%d,%d w,h=%d %d).", i,
rect->x, rect->y, rect->x, rect->y,
rect->width, rect->height); rect->width, rect->height);
} }
if (Stream_GetRemainingLength(s) < 4) if (Stream_GetRemainingLength(s) < 4)
@ -718,9 +718,9 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context,
} }
Stream_Read_UINT16(s, Stream_Read_UINT16(s,
regionType); /* regionType (2 bytes): MUST be set to CBT_REGION (0xCAC1) */ regionType); /* regionType (2 bytes): MUST be set to CBT_REGION (0xCAC1) */
Stream_Read_UINT16(s, Stream_Read_UINT16(s,
numTileSets); /* numTilesets (2 bytes): MUST be set to 0x0001. */ numTileSets); /* numTilesets (2 bytes): MUST be set to 0x0001. */
if (regionType != CBT_REGION) if (regionType != CBT_REGION)
{ {
@ -753,7 +753,7 @@ static void CALLBACK rfx_process_message_tile_work_callback(
} }
static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
RFX_MESSAGE* message, wStream* s, UINT16* pExpecedBlockType) RFX_MESSAGE* message, wStream* s, UINT16* pExpecedBlockType)
{ {
BOOL rc; BOOL rc;
int i, close_cnt; int i, close_cnt;
@ -784,7 +784,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
} }
Stream_Read_UINT16(s, Stream_Read_UINT16(s,
subtype); /* subtype (2 bytes) must be set to CBT_TILESET (0xCAC2) */ subtype); /* subtype (2 bytes) must be set to CBT_TILESET (0xCAC2) */
if (subtype != CBT_TILESET) if (subtype != CBT_TILESET)
{ {
@ -814,7 +814,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
Stream_Read_UINT32(s, tilesDataSize); /* tilesDataSize (4 bytes) */ Stream_Read_UINT32(s, tilesDataSize); /* tilesDataSize (4 bytes) */
if (!(pmem = realloc((void*) context->quants, if (!(pmem = realloc((void*) context->quants,
context->numQuant * 10 * sizeof(UINT32)))) context->numQuant * 10 * sizeof(UINT32))))
return FALSE; return FALSE;
quants = context->quants = (UINT32*) pmem; quants = context->quants = (UINT32*) pmem;
@ -823,7 +823,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
if (Stream_GetRemainingLength(s) < (size_t)(context->numQuant * 5)) if (Stream_GetRemainingLength(s) < (size_t)(context->numQuant * 5))
{ {
WLog_ERR(TAG, "RfxMessageTileSet packet too small for num_quants=%d", WLog_ERR(TAG, "RfxMessageTileSet packet too small for num_quants=%d",
context->numQuant); context->numQuant);
return FALSE; return FALSE;
} }
@ -846,16 +846,16 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
*quants++ = (quant & 0x0F); *quants++ = (quant & 0x0F);
*quants++ = (quant >> 4); *quants++ = (quant >> 4);
WLog_Print(context->priv->log, WLOG_DEBUG, WLog_Print(context->priv->log, WLOG_DEBUG,
"quant %d (%d %d %d %d %d %d %d %d %d %d).", "quant %d (%d %d %d %d %d %d %d %d %d %d).",
i, context->quants[i * 10], context->quants[i * 10 + 1], i, context->quants[i * 10], context->quants[i * 10 + 1],
context->quants[i * 10 + 2], context->quants[i * 10 + 3], context->quants[i * 10 + 2], context->quants[i * 10 + 3],
context->quants[i * 10 + 4], context->quants[i * 10 + 5], context->quants[i * 10 + 4], context->quants[i * 10 + 5],
context->quants[i * 10 + 6], context->quants[i * 10 + 7], context->quants[i * 10 + 6], context->quants[i * 10 + 7],
context->quants[i * 10 + 8], context->quants[i * 10 + 9]); context->quants[i * 10 + 8], context->quants[i * 10 + 9]);
} }
if (!(message->tiles = (RFX_TILE**) calloc(message->numTiles, if (!(message->tiles = (RFX_TILE**) calloc(message->numTiles,
sizeof(RFX_TILE*)))) sizeof(RFX_TILE*))))
{ {
message->numTiles = 0; message->numTiles = 0;
return FALSE; return FALSE;
@ -865,7 +865,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
{ {
work_objects = (PTP_WORK*) calloc(message->numTiles, sizeof(PTP_WORK)); work_objects = (PTP_WORK*) calloc(message->numTiles, sizeof(PTP_WORK));
params = (RFX_TILE_PROCESS_WORK_PARAM*) calloc(message->numTiles, params = (RFX_TILE_PROCESS_WORK_PARAM*) calloc(message->numTiles,
sizeof(RFX_TILE_PROCESS_WORK_PARAM)); sizeof(RFX_TILE_PROCESS_WORK_PARAM));
if (!work_objects) if (!work_objects)
{ {
@ -899,20 +899,20 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
if (Stream_GetRemainingLength(s) < 6) if (Stream_GetRemainingLength(s) < 6)
{ {
WLog_ERR(TAG, "RfxMessageTileSet packet too small to read tile %d/%d", i, WLog_ERR(TAG, "RfxMessageTileSet packet too small to read tile %d/%d", i,
message->numTiles); message->numTiles);
rc = FALSE; rc = FALSE;
break; break;
} }
Stream_Read_UINT16(s, Stream_Read_UINT16(s,
blockType); /* blockType (2 bytes), must be set to CBT_TILE (0xCAC3) */ blockType); /* blockType (2 bytes), must be set to CBT_TILE (0xCAC3) */
Stream_Read_UINT32(s, blockLen); /* blockLen (4 bytes) */ Stream_Read_UINT32(s, blockLen); /* blockLen (4 bytes) */
if (Stream_GetRemainingLength(s) < blockLen - 6) if (Stream_GetRemainingLength(s) < blockLen - 6)
{ {
WLog_ERR(TAG, WLog_ERR(TAG,
"RfxMessageTileSet not enough bytes to read tile %d/%d with blocklen=%d", "RfxMessageTileSet not enough bytes to read tile %d/%d with blocklen=%d",
i, message->numTiles, blockLen); i, message->numTiles, blockLen);
rc = FALSE; rc = FALSE;
break; break;
} }
@ -922,7 +922,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
if (blockType != CBT_TILE) if (blockType != CBT_TILE)
{ {
WLog_ERR(TAG, "unknown block type 0x%X, expected CBT_TILE (0xCAC3).", WLog_ERR(TAG, "unknown block type 0x%X, expected CBT_TILE (0xCAC3).",
blockType); blockType);
rc = FALSE; rc = FALSE;
break; break;
} }
@ -951,8 +951,8 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
params[i].tile = message->tiles[i]; params[i].tile = message->tiles[i];
if (!(work_objects[i] = CreateThreadpoolWork((PTP_WORK_CALLBACK) if (!(work_objects[i] = CreateThreadpoolWork((PTP_WORK_CALLBACK)
rfx_process_message_tile_work_callback, rfx_process_message_tile_work_callback,
(void*) &params[i], &context->priv->ThreadPoolEnv))) (void*) &params[i], &context->priv->ThreadPoolEnv)))
{ {
WLog_ERR(TAG, "CreateThreadpoolWork failed."); WLog_ERR(TAG, "CreateThreadpoolWork failed.");
rc = FALSE; rc = FALSE;
@ -995,11 +995,11 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context,
} }
BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data,
UINT32 format, UINT32 length, UINT32 format, UINT32 length,
UINT32 left, UINT32 top, UINT32 left, UINT32 top,
BYTE* dst, UINT32 dstFormat, BYTE* dst, UINT32 dstFormat,
UINT32 dstStride, UINT32 dstHeight, UINT32 dstStride, UINT32 dstHeight,
REGION16* invalidRegion) REGION16* invalidRegion)
{ {
int pos; int pos;
REGION16 updateRegion; REGION16 updateRegion;
@ -1027,7 +1027,7 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data,
Stream_Read_UINT16(s, blockType); /* blockType (2 bytes) */ Stream_Read_UINT16(s, blockType); /* blockType (2 bytes) */
Stream_Read_UINT32(s, blockLen); /* blockLen (4 bytes) */ Stream_Read_UINT32(s, blockLen); /* blockLen (4 bytes) */
WLog_Print(context->priv->log, WLOG_DEBUG, "blockType 0x%X blockLen %d", WLog_Print(context->priv->log, WLOG_DEBUG, "blockType 0x%X blockLen %d",
blockType, blockLen); blockType, blockLen);
if (blockLen == 0) if (blockLen == 0)
{ {
@ -1061,7 +1061,7 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data,
Stream_Read_UINT8(s, codecId); /* codecId (1 byte) must be set to 0x01 */ Stream_Read_UINT8(s, codecId); /* codecId (1 byte) must be set to 0x01 */
Stream_Read_UINT8(s, Stream_Read_UINT8(s,
channelId); /* channelId (1 byte) 0xFF or 0x00, see below */ channelId); /* channelId (1 byte) 0xFF or 0x00, see below */
if (codecId != 0x01) if (codecId != 0x01)
{ {
@ -1075,7 +1075,7 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data,
if (channelId != 0xFF) if (channelId != 0xFF)
{ {
WLog_ERR(TAG, "%s: invalid channelId 0x%02X for blockType 0x%04X", __FUNCTION__, WLog_ERR(TAG, "%s: invalid channelId 0x%02X for blockType 0x%04X", __FUNCTION__,
channelId, blockType); channelId, blockType);
goto fail; goto fail;
} }
} }
@ -1085,7 +1085,7 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data,
if (channelId != 0x00) if (channelId != 0x00)
{ {
WLog_ERR(TAG, "%s: invalid channelId 0x%02X for blockType WBT_CONTEXT", WLog_ERR(TAG, "%s: invalid channelId 0x%02X for blockType WBT_CONTEXT",
__FUNCTION__, channelId); __FUNCTION__, channelId);
goto fail; goto fail;
} }
} }
@ -1122,7 +1122,7 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data,
case WBT_FRAME_BEGIN: case WBT_FRAME_BEGIN:
ok = rfx_process_message_frame_begin(context, message, s, ok = rfx_process_message_frame_begin(context, message, s,
&expectedDataBlockType); &expectedDataBlockType);
break; break;
case WBT_REGION: case WBT_REGION:
@ -1178,14 +1178,17 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data,
for (j = 0; j < nbUpdateRects; j++) for (j = 0; j < nbUpdateRects; j++)
{ {
UINT32 stride = 64 * GetBytesPerPixel(format);
UINT32 nXDst = updateRects[j].left; UINT32 nXDst = updateRects[j].left;
UINT32 nYDst = updateRects[j].top; UINT32 nYDst = updateRects[j].top;
UINT32 nWidth = updateRects[j].right - updateRects[j].left; UINT32 nXSrc = nXDst - updateRect.left;
UINT32 nHeight = updateRects[j].bottom - updateRects[j].top; UINT32 nYSrc = nYDst - updateRect.top;
UINT32 nWidth = MIN(64, updateRects[j].right - updateRects[j].left);
UINT32 nHeight = MIN(64, updateRects[j].bottom - updateRects[j].top);
if (!freerdp_image_copy(dst, dstFormat, dstStride, if (!freerdp_image_copy(dst, dstFormat, dstStride,
nXDst, nYDst, nWidth, nHeight, nXDst, nYDst, nWidth, nHeight,
tile->data, format, 64 * GetBytesPerPixel(format), 0, 0, NULL)) tile->data, format, stride, nXSrc, nYSrc, NULL))
goto fail; goto fail;
if (invalidRegion) if (invalidRegion)
@ -1263,7 +1266,7 @@ static void rfx_update_context_properties(RFX_CONTEXT* context)
properties |= (COL_CONV_ICT << 4); /* cct */ properties |= (COL_CONV_ICT << 4); /* cct */
properties |= (CLW_XFORM_DWT_53_A << 6); /* xft */ properties |= (CLW_XFORM_DWT_53_A << 6); /* xft */
properties |= ((context->mode == RLGR1 ? CLW_ENTROPY_RLGR1 : CLW_ENTROPY_RLGR3) properties |= ((context->mode == RLGR1 ? CLW_ENTROPY_RLGR1 : CLW_ENTROPY_RLGR3)
<< 10); /* et */ << 10); /* et */
properties |= (SCALAR_QUANTIZATION << 14); /* qt */ properties |= (SCALAR_QUANTIZATION << 14); /* qt */
context->properties = properties; context->properties = properties;
} }
@ -1309,7 +1312,7 @@ static void rfx_write_message_context(RFX_CONTEXT* context, wStream* s)
properties |= (COL_CONV_ICT << 3); /* cct */ properties |= (COL_CONV_ICT << 3); /* cct */
properties |= (CLW_XFORM_DWT_53_A << 5); /* xft */ properties |= (CLW_XFORM_DWT_53_A << 5); /* xft */
properties |= ((context->mode == RLGR1 ? CLW_ENTROPY_RLGR1 : CLW_ENTROPY_RLGR3) properties |= ((context->mode == RLGR1 ? CLW_ENTROPY_RLGR1 : CLW_ENTROPY_RLGR3)
<< 9); /* et */ << 9); /* et */
properties |= (SCALAR_QUANTIZATION << 13); /* qt */ properties |= (SCALAR_QUANTIZATION << 13); /* qt */
Stream_Write_UINT16(s, properties); /* properties (2 bytes) */ Stream_Write_UINT16(s, properties); /* properties (2 bytes) */
rfx_update_context_properties(context); rfx_update_context_properties(context);
@ -1363,7 +1366,7 @@ struct _RFX_TILE_COMPOSE_WORK_PARAM
}; };
void CALLBACK rfx_compose_message_tile_work_callback(PTP_CALLBACK_INSTANCE void CALLBACK rfx_compose_message_tile_work_callback(PTP_CALLBACK_INSTANCE
instance, void* context, PTP_WORK work) instance, void* context, PTP_WORK work)
{ {
RFX_TILE_COMPOSE_WORK_PARAM* param = (RFX_TILE_COMPOSE_WORK_PARAM*) context; RFX_TILE_COMPOSE_WORK_PARAM* param = (RFX_TILE_COMPOSE_WORK_PARAM*) context;
rfx_encode_rgb(param->context, param->tile); rfx_encode_rgb(param->context, param->tile);
@ -1371,7 +1374,7 @@ void CALLBACK rfx_compose_message_tile_work_callback(PTP_CALLBACK_INSTANCE
static BOOL computeRegion(const RFX_RECT* rects, int numRects, REGION16* region, static BOOL computeRegion(const RFX_RECT* rects, int numRects, REGION16* region,
int width, int height) int width, int height)
{ {
int i; int i;
const RFX_RECT* rect = rects; const RFX_RECT* rect = rects;
@ -1408,7 +1411,7 @@ BOOL setupWorkers(RFX_CONTEXT* context, int nbTiles)
priv->workObjects = (PTP_WORK*) pmem; priv->workObjects = (PTP_WORK*) pmem;
if (!(pmem = realloc((void*) priv->tileWorkParams, if (!(pmem = realloc((void*) priv->tileWorkParams,
sizeof(RFX_TILE_COMPOSE_WORK_PARAM) * nbTiles))) sizeof(RFX_TILE_COMPOSE_WORK_PARAM) * nbTiles)))
return FALSE; return FALSE;
priv->tileWorkParams = (RFX_TILE_COMPOSE_WORK_PARAM*) pmem; priv->tileWorkParams = (RFX_TILE_COMPOSE_WORK_PARAM*) pmem;
@ -1416,8 +1419,8 @@ BOOL setupWorkers(RFX_CONTEXT* context, int nbTiles)
} }
RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects,
int numRects, int numRects,
BYTE* data, int width, int height, int scanline) BYTE* data, int width, int height, int scanline)
{ {
UINT32 i, maxNbTiles, maxTilesX, maxTilesY; UINT32 i, maxNbTiles, maxTilesX, maxTilesY;
UINT32 xIdx, yIdx, regionNbRects; UINT32 xIdx, yIdx, regionNbRects;
@ -1453,11 +1456,11 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects,
if (!context->numQuant) if (!context->numQuant)
{ {
if (!(context->quants = (UINT32*) malloc(sizeof( if (!(context->quants = (UINT32*) malloc(sizeof(
rfx_default_quantization_values)))) rfx_default_quantization_values))))
goto skip_encoding_loop; goto skip_encoding_loop;
CopyMemory(context->quants, &rfx_default_quantization_values, CopyMemory(context->quants, &rfx_default_quantization_values,
sizeof(rfx_default_quantization_values)); sizeof(rfx_default_quantization_values));
context->numQuant = 1; context->numQuant = 1;
context->quantIdxY = 0; context->quantIdxY = 0;
context->quantIdxCb = 0; context->quantIdxCb = 0;
@ -1575,9 +1578,9 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects,
workParam->tile = tile; workParam->tile = tile;
if (!(*workObject = CreateThreadpoolWork( if (!(*workObject = CreateThreadpoolWork(
(PTP_WORK_CALLBACK)rfx_compose_message_tile_work_callback, (PTP_WORK_CALLBACK)rfx_compose_message_tile_work_callback,
(void*) workParam, (void*) workParam,
&context->priv->ThreadPoolEnv))) &context->priv->ThreadPoolEnv)))
{ {
goto skip_encoding_loop; goto skip_encoding_loop;
} }
@ -1605,7 +1608,7 @@ skip_encoding_loop:
if (message->numTiles > 0) if (message->numTiles > 0)
{ {
void* pmem = realloc((void*) message->tiles, void* pmem = realloc((void*) message->tiles,
sizeof(RFX_TILE*) * message->numTiles); sizeof(RFX_TILE*) * message->numTiles);
if (pmem) if (pmem)
message->tiles = (RFX_TILE**) pmem; message->tiles = (RFX_TILE**) pmem;
@ -1654,7 +1657,7 @@ skip_encoding_loop:
} }
RFX_MESSAGE* rfx_split_message(RFX_CONTEXT* context, RFX_MESSAGE* message, RFX_MESSAGE* rfx_split_message(RFX_CONTEXT* context, RFX_MESSAGE* message,
int* numMessages, int maxDataSize) int* numMessages, int maxDataSize)
{ {
int i, j; int i, j;
UINT32 tileDataSize; UINT32 tileDataSize;
@ -1685,7 +1688,7 @@ RFX_MESSAGE* rfx_split_message(RFX_CONTEXT* context, RFX_MESSAGE* message,
messages[j].freeArray = TRUE; messages[j].freeArray = TRUE;
if (!(messages[j].tiles = (RFX_TILE**) calloc(message->numTiles, if (!(messages[j].tiles = (RFX_TILE**) calloc(message->numTiles,
sizeof(RFX_TILE*)))) sizeof(RFX_TILE*))))
goto free_messages; goto free_messages;
} }
@ -1708,19 +1711,19 @@ free_messages:
} }
RFX_MESSAGE* rfx_encode_messages(RFX_CONTEXT* context, const RFX_RECT* rects, RFX_MESSAGE* rfx_encode_messages(RFX_CONTEXT* context, const RFX_RECT* rects,
int numRects, int numRects,
BYTE* data, int width, int height, int scanline, int* numMessages, BYTE* data, int width, int height, int scanline, int* numMessages,
int maxDataSize) int maxDataSize)
{ {
RFX_MESSAGE* message; RFX_MESSAGE* message;
RFX_MESSAGE* messageList; RFX_MESSAGE* messageList;
if (!(message = rfx_encode_message(context, rects, numRects, data, width, if (!(message = rfx_encode_message(context, rects, numRects, data, width,
height, scanline))) height, scanline)))
return NULL; return NULL;
if (!(messageList = rfx_split_message(context, message, numMessages, if (!(messageList = rfx_split_message(context, message, numMessages,
maxDataSize))) maxDataSize)))
{ {
message->freeRects = TRUE; message->freeRects = TRUE;
rfx_message_free(context, message); rfx_message_free(context, message);
@ -1732,7 +1735,7 @@ RFX_MESSAGE* rfx_encode_messages(RFX_CONTEXT* context, const RFX_RECT* rects,
} }
static BOOL rfx_write_message_tileset(RFX_CONTEXT* context, wStream* s, static BOOL rfx_write_message_tileset(RFX_CONTEXT* context, wStream* s,
RFX_MESSAGE* message) RFX_MESSAGE* message)
{ {
int i; int i;
RFX_TILE* tile; RFX_TILE* tile;
@ -1773,14 +1776,14 @@ static BOOL rfx_write_message_tileset(RFX_CONTEXT* context, wStream* s,
#ifdef WITH_DEBUG_RFX #ifdef WITH_DEBUG_RFX
WLog_Print(context->priv->log, WLOG_DEBUG, WLog_Print(context->priv->log, WLOG_DEBUG,
"numQuant: %d numTiles: %d tilesDataSize: %d", "numQuant: %d numTiles: %d tilesDataSize: %d",
message->numQuant, message->numTiles, message->tilesDataSize); message->numQuant, message->numTiles, message->tilesDataSize);
#endif #endif
return TRUE; return TRUE;
} }
static BOOL rfx_write_message_frame_begin(RFX_CONTEXT* context, wStream* s, static BOOL rfx_write_message_frame_begin(RFX_CONTEXT* context, wStream* s,
RFX_MESSAGE* message) RFX_MESSAGE* message)
{ {
if (!Stream_EnsureRemainingCapacity(s, 14)) if (!Stream_EnsureRemainingCapacity(s, 14))
return FALSE; return FALSE;
@ -1795,7 +1798,7 @@ static BOOL rfx_write_message_frame_begin(RFX_CONTEXT* context, wStream* s,
} }
static BOOL rfx_write_message_region(RFX_CONTEXT* context, wStream* s, static BOOL rfx_write_message_region(RFX_CONTEXT* context, wStream* s,
RFX_MESSAGE* message) RFX_MESSAGE* message)
{ {
int i; int i;
UINT32 blockLen; UINT32 blockLen;
@ -1827,7 +1830,7 @@ static BOOL rfx_write_message_region(RFX_CONTEXT* context, wStream* s,
} }
BOOL rfx_write_message_frame_end(RFX_CONTEXT* context, wStream* s, BOOL rfx_write_message_frame_end(RFX_CONTEXT* context, wStream* s,
RFX_MESSAGE* message) RFX_MESSAGE* message)
{ {
if (!Stream_EnsureRemainingCapacity(s, 8)) if (!Stream_EnsureRemainingCapacity(s, 8))
return FALSE; return FALSE;
@ -1861,14 +1864,14 @@ BOOL rfx_write_message(RFX_CONTEXT* context, wStream* s, RFX_MESSAGE* message)
} }
BOOL rfx_compose_message(RFX_CONTEXT* context, wStream* s, BOOL rfx_compose_message(RFX_CONTEXT* context, wStream* s,
const RFX_RECT* rects, int numRects, BYTE* data, int width, int height, const RFX_RECT* rects, int numRects, BYTE* data, int width, int height,
int scanline) int scanline)
{ {
RFX_MESSAGE* message; RFX_MESSAGE* message;
BOOL ret = TRUE; BOOL ret = TRUE;
if (!(message = rfx_encode_message(context, rects, numRects, data, width, if (!(message = rfx_encode_message(context, rects, numRects, data, width,
height, scanline))) height, scanline)))
return FALSE; return FALSE;
ret = rfx_write_message(context, s, message); ret = rfx_write_message(context, s, message);

View File

@ -946,6 +946,7 @@ BOOL gdi_surface_frame_marker(rdpContext* context,
static BOOL gdi_surface_bits(rdpContext* context, static BOOL gdi_surface_bits(rdpContext* context,
const SURFACE_BITS_COMMAND* cmd) const SURFACE_BITS_COMMAND* cmd)
{ {
DWORD format;
rdpGdi* gdi; rdpGdi* gdi;
if (!context || !cmd) if (!context || !cmd)
@ -961,40 +962,42 @@ static BOOL gdi_surface_bits(rdpContext* context,
switch (cmd->codecID) switch (cmd->codecID)
{ {
case RDP_CODEC_ID_REMOTEFX: case RDP_CODEC_ID_REMOTEFX:
format = PIXEL_FORMAT_BGRX32;
if (!rfx_process_message(context->codecs->rfx, cmd->bitmapData,
format,
cmd->bitmapDataLength,
cmd->destLeft, cmd->destTop,
gdi->primary_buffer, gdi->dstFormat,
gdi->stride, gdi->height, NULL))
{ {
if (!rfx_process_message(context->codecs->rfx, cmd->bitmapData, WLog_ERR(TAG, "Failed to process RemoteFX message");
PIXEL_FORMAT_BGRX32, return FALSE;
cmd->bitmapDataLength,
0, 0,
gdi->primary_buffer, gdi->dstFormat,
cmd->width * GetBytesPerPixel(gdi->dstFormat),
cmd->height, NULL))
{
WLog_ERR(TAG, "Failed to process RemoteFX message");
return FALSE;
}
} }
break; break;
case RDP_CODEC_ID_NSCODEC: case RDP_CODEC_ID_NSCODEC:
{ format = FREERDP_VFLIP_PIXEL_FORMAT(gdi->dstFormat);
if (!nsc_process_message(context->codecs->nsc, cmd->bpp, cmd->width,
cmd->height, cmd->bitmapData, if (!nsc_process_message(context->codecs->nsc, cmd->bpp, cmd->width,
cmd->bitmapDataLength, gdi->primary_buffer, cmd->height, cmd->bitmapData,
gdi->dstFormat, gdi->stride, cmd->destLeft, cmd->destTop, cmd->bitmapDataLength, gdi->primary_buffer,
cmd->width, cmd->height)) format, gdi->stride, cmd->destLeft, cmd->destTop,
return FALSE; cmd->width, cmd->height))
} return FALSE;
break; break;
case RDP_CODEC_ID_NONE: case RDP_CODEC_ID_NONE:
{ format = PIXEL_FORMAT_BGRX32_VF;
if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, gdi->stride,
cmd->destLeft, cmd->destTop, cmd->width, cmd->height, if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, gdi->stride,
cmd->bitmapData, PIXEL_FORMAT_XRGB32_VF, 0, 0, 0, cmd->destLeft, cmd->destTop, cmd->width, cmd->height,
&gdi->palette)) cmd->bitmapData, format, 0, 0, 0,
return FALSE; &gdi->palette))
} return FALSE;
break; break;
default: default:
@ -1002,7 +1005,8 @@ static BOOL gdi_surface_bits(rdpContext* context,
break; break;
} }
if (!gdi_InvalidateRegion(gdi->primary->hdc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height)) if (!gdi_InvalidateRegion(gdi->primary->hdc, cmd->destLeft, cmd->destTop,
cmd->width, cmd->height))
{ {
WLog_ERR(TAG, "Failed to update invalid region"); WLog_ERR(TAG, "Failed to update invalid region");
return FALSE; return FALSE;