From 404ae7d83c59de69a6b988e0e9fc561dbda6d6ae Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 11 Oct 2016 14:34:07 +0200 Subject: [PATCH 1/6] Fixed Windows 7 RFX issues. --- client/X11/xf_gdi.c | 97 ++++++++++++++++++-------------------------- libfreerdp/gdi/gdi.c | 8 ++-- 2 files changed, 44 insertions(+), 61 deletions(-) diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index 6c8827baf..d53f37441 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -970,48 +970,49 @@ static BOOL xf_gdi_surface_update_frame(xfContext* xfc, UINT16 tx, UINT16 ty, 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); + 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, const SURFACE_BITS_COMMAND* cmd) { - XImage* image; BYTE* pSrcData; - BYTE* pDstData; xfContext* xfc = (xfContext*) context; - BOOL ret = TRUE; + BOOL ret = FALSE; rdpGdi* gdi = context->gdi; - REGION16 invalidRegion; xf_lock_x11(xfc, FALSE); switch (cmd->codecID) { case RDP_CODEC_ID_REMOTEFX: if (!rfx_process_message(context->codecs->rfx, cmd->bitmapData, - PIXEL_FORMAT_XRGB32, cmd->bitmapDataLength, + PIXEL_FORMAT_BGRX32, cmd->bitmapDataLength, cmd->destLeft, cmd->destTop, gdi->primary_buffer, gdi->dstFormat, gdi->stride, - gdi->height, &invalidRegion)) - { - WLog_ERR(TAG, "Failed to process RemoteFX message"); - xf_unlock_x11(xfc, FALSE); - return FALSE; - } + gdi->height, NULL)) + goto fail; - 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); + ret = xf_gdi_update_screen(xfc, cmd, gdi->primary_buffer); break; case RDP_CODEC_ID_NSCODEC: @@ -1019,47 +1020,29 @@ static BOOL xf_gdi_surface_bits(rdpContext* context, cmd->height, cmd->bitmapData, cmd->bitmapDataLength, gdi->primary_buffer, gdi->dstFormat, 0, 0, 0, cmd->width, cmd->height)) - { - xf_unlock_x11(xfc, FALSE); - 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); + ret = xf_gdi_update_screen(xfc, cmd, gdi->primary_buffer); break; case RDP_CODEC_ID_NONE: - XSetFunction(xfc->display, xfc->gc, GXcopy); - XSetFillStyle(xfc->display, xfc->gc, FillSolid); pSrcData = cmd->bitmapData; - pDstData = gdi->primary_buffer; - freerdp_image_copy(pDstData, gdi->dstFormat, 0, 0, 0, - cmd->width, cmd->height, pSrcData, - PIXEL_FORMAT_BGRX32_VF, 0, 0, 0, &xfc->context.gdi->palette); - 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); + + if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, 0, 0, 0, + cmd->width, cmd->height, pSrcData, + PIXEL_FORMAT_BGRX32_VF, 0, 0, 0, &xfc->context.gdi->palette)) + goto fail; + + ret = xf_gdi_update_screen(xfc, cmd, gdi->primary_buffer); break; default: WLog_ERR(TAG, "Unsupported codecID %d", cmd->codecID); + ret = TRUE; + break; } +fail: xf_unlock_x11(xfc, FALSE); return ret; } diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index 719a16067..88d1b57e5 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -1024,10 +1024,9 @@ static BOOL gdi_surface_bits(rdpContext* context, if (!rfx_process_message(context->codecs->rfx, cmd->bitmapData, PIXEL_FORMAT_BGRX32, cmd->bitmapDataLength, - 0, 0, + cmd->destLeft, cmd->destTop, gdi->primary_buffer, gdi->dstFormat, - cmd->width * GetBytesPerPixel(gdi->dstFormat), - cmd->height, NULL)) + gdi->stride, gdi->height, NULL)) { WLog_ERR(TAG, "Failed to process RemoteFX message"); return FALSE; @@ -1061,7 +1060,8 @@ static BOOL gdi_surface_bits(rdpContext* context, 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"); return FALSE; From 8286fa4b9696ebb097151ca43c4d8bef68aaa283 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 11 Oct 2016 18:44:50 +0200 Subject: [PATCH 2/6] Fixed format flip and offsets for GDI. --- client/X11/xf_gdi.c | 19 +- include/freerdp/codec/color.h | 436 +++++++++++++++++----------------- libfreerdp/gdi/gdi.c | 54 +++-- 3 files changed, 263 insertions(+), 246 deletions(-) diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index d53f37441..950ab7dab 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -999,14 +999,17 @@ static BOOL xf_gdi_surface_bits(rdpContext* context, BYTE* pSrcData; xfContext* xfc = (xfContext*) context; BOOL ret = FALSE; + DWORD format; rdpGdi* gdi = context->gdi; xf_lock_x11(xfc, FALSE); switch (cmd->codecID) { case RDP_CODEC_ID_REMOTEFX: + format = PIXEL_FORMAT_BGRX32; + if (!rfx_process_message(context->codecs->rfx, cmd->bitmapData, - PIXEL_FORMAT_BGRX32, cmd->bitmapDataLength, + format, cmd->bitmapDataLength, cmd->destLeft, cmd->destTop, gdi->primary_buffer, gdi->dstFormat, gdi->stride, gdi->height, NULL)) @@ -1016,10 +1019,12 @@ static BOOL xf_gdi_surface_bits(rdpContext* context, break; 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, cmd->bitmapDataLength, - gdi->primary_buffer, gdi->dstFormat, 0, 0, 0, cmd->width, cmd->height)) + cmd->height, cmd->bitmapData, cmd->bitmapDataLength, + gdi->primary_buffer, format, gdi->stride, + cmd->destLeft, cmd->destTop, cmd->width, cmd->height)) goto fail; ret = xf_gdi_update_screen(xfc, cmd, gdi->primary_buffer); @@ -1027,10 +1032,12 @@ static BOOL xf_gdi_surface_bits(rdpContext* context, case RDP_CODEC_ID_NONE: pSrcData = cmd->bitmapData; + format = PIXEL_FORMAT_BGRX32_VF; - if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, 0, 0, 0, + if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, gdi->stride, + cmd->destLeft, cmd->destTop, cmd->width, cmd->height, pSrcData, - PIXEL_FORMAT_BGRX32_VF, 0, 0, 0, &xfc->context.gdi->palette)) + format, 0, 0, 0, &xfc->context.gdi->palette)) goto fail; ret = xf_gdi_update_screen(xfc, cmd, gdi->primary_buffer); diff --git a/include/freerdp/codec/color.h b/include/freerdp/codec/color.h index 79f9e69ce..0598b7bf8 100644 --- a/include/freerdp/codec/color.h +++ b/include/freerdp/codec/color.h @@ -45,6 +45,12 @@ #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 * * The format naming scheme is based on byte position in memory. @@ -168,128 +174,128 @@ static const char* GetColorFormatName(UINT32 format) { switch (format) { - /* 32bpp formats */ - case PIXEL_FORMAT_ARGB32: - return "PIXEL_FORMAT_ARGB32"; + /* 32bpp formats */ + case PIXEL_FORMAT_ARGB32: + return "PIXEL_FORMAT_ARGB32"; - case PIXEL_FORMAT_ARGB32_VF: - return "PIXEL_FORMAT_ARGB32_VF"; + case PIXEL_FORMAT_ARGB32_VF: + return "PIXEL_FORMAT_ARGB32_VF"; - case PIXEL_FORMAT_XRGB32: - return "PIXEL_FORMAT_XRGB32"; + case PIXEL_FORMAT_XRGB32: + return "PIXEL_FORMAT_XRGB32"; - case PIXEL_FORMAT_XRGB32_VF: - return "PIXEL_FORMAT_XRGB32_VF"; + case PIXEL_FORMAT_XRGB32_VF: + return "PIXEL_FORMAT_XRGB32_VF"; - case PIXEL_FORMAT_ABGR32: - return "PIXEL_FORMAT_ABGR32"; + case PIXEL_FORMAT_ABGR32: + return "PIXEL_FORMAT_ABGR32"; - case PIXEL_FORMAT_ABGR32_VF: - return "PIXEL_FORMAT_ABGR32_VF"; + case PIXEL_FORMAT_ABGR32_VF: + return "PIXEL_FORMAT_ABGR32_VF"; - case PIXEL_FORMAT_XBGR32: - return "PIXEL_FORMAT_XBGR32"; + case PIXEL_FORMAT_XBGR32: + return "PIXEL_FORMAT_XBGR32"; - case PIXEL_FORMAT_XBGR32_VF: - return "PIXEL_FORMAT_XBGR32_VF"; + case PIXEL_FORMAT_XBGR32_VF: + return "PIXEL_FORMAT_XBGR32_VF"; - case PIXEL_FORMAT_BGRA32: - return "PIXEL_FORMAT_BGRA32"; + case PIXEL_FORMAT_BGRA32: + return "PIXEL_FORMAT_BGRA32"; - case PIXEL_FORMAT_BGRA32_VF: - return "PIXEL_FORMAT_BGRA32_VF"; + case PIXEL_FORMAT_BGRA32_VF: + return "PIXEL_FORMAT_BGRA32_VF"; - case PIXEL_FORMAT_BGRX32: - return "PIXEL_FORMAT_BGRX32"; + case PIXEL_FORMAT_BGRX32: + return "PIXEL_FORMAT_BGRX32"; - case PIXEL_FORMAT_BGRX32_VF: - return "PIXEL_FORMAT_BGRX32_VF"; + case PIXEL_FORMAT_BGRX32_VF: + return "PIXEL_FORMAT_BGRX32_VF"; - case PIXEL_FORMAT_RGBA32: - return "PIXEL_FORMAT_RGBA32"; + case PIXEL_FORMAT_RGBA32: + return "PIXEL_FORMAT_RGBA32"; - case PIXEL_FORMAT_RGBA32_VF: - return "PIXEL_FORMAT_RGBA32_VF"; + case PIXEL_FORMAT_RGBA32_VF: + return "PIXEL_FORMAT_RGBA32_VF"; - case PIXEL_FORMAT_RGBX32: - return "PIXEL_FORMAT_RGBX32"; + case PIXEL_FORMAT_RGBX32: + return "PIXEL_FORMAT_RGBX32"; - case PIXEL_FORMAT_RGBX32_VF: - return "PIXEL_FORMAT_RGBX32_VF"; + case PIXEL_FORMAT_RGBX32_VF: + return "PIXEL_FORMAT_RGBX32_VF"; /* 24bpp formats */ - case PIXEL_FORMAT_RGB24: - return "PIXEL_FORMAT_RGB24"; + case PIXEL_FORMAT_RGB24: + return "PIXEL_FORMAT_RGB24"; - case PIXEL_FORMAT_RGB24_VF: - return "PIXEL_FORMAT_RGB24_VF"; + case PIXEL_FORMAT_RGB24_VF: + return "PIXEL_FORMAT_RGB24_VF"; - case PIXEL_FORMAT_BGR24: - return "PIXEL_FORMAT_BGR24"; + case PIXEL_FORMAT_BGR24: + return "PIXEL_FORMAT_BGR24"; - case PIXEL_FORMAT_BGR24_VF: - return "PIXEL_FORMAT_BGR24_VF"; + case PIXEL_FORMAT_BGR24_VF: + return "PIXEL_FORMAT_BGR24_VF"; /* 16bpp formats */ - case PIXEL_FORMAT_RGB16: - return "PIXEL_FORMAT_RGB16"; + case PIXEL_FORMAT_RGB16: + return "PIXEL_FORMAT_RGB16"; - case PIXEL_FORMAT_RGB16_VF: - return "PIXEL_FORMAT_RGB16_VF"; + case PIXEL_FORMAT_RGB16_VF: + return "PIXEL_FORMAT_RGB16_VF"; - case PIXEL_FORMAT_BGR16: - return "PIXEL_FORMAT_BGR16"; + case PIXEL_FORMAT_BGR16: + return "PIXEL_FORMAT_BGR16"; - case PIXEL_FORMAT_BGR16_VF: - return "PIXEL_FORMAT_BGR16_VF"; + case PIXEL_FORMAT_BGR16_VF: + return "PIXEL_FORMAT_BGR16_VF"; - case PIXEL_FORMAT_ARGB15: - return "PIXEL_FORMAT_ARGB15"; + case PIXEL_FORMAT_ARGB15: + return "PIXEL_FORMAT_ARGB15"; - case PIXEL_FORMAT_ARGB15_VF: - return "PIXEL_FORMAT_ARGB15_VF"; + case PIXEL_FORMAT_ARGB15_VF: + return "PIXEL_FORMAT_ARGB15_VF"; - case PIXEL_FORMAT_RGB15: - return "PIXEL_FORMAT_RGB15"; + case PIXEL_FORMAT_RGB15: + return "PIXEL_FORMAT_RGB15"; - case PIXEL_FORMAT_RGB15_VF: - return "PIXEL_FORMAT_ABGR15"; + case PIXEL_FORMAT_RGB15_VF: + return "PIXEL_FORMAT_ABGR15"; - case PIXEL_FORMAT_ABGR15: - return ""; + case PIXEL_FORMAT_ABGR15: + return ""; - case PIXEL_FORMAT_ABGR15_VF: - return "PIXEL_FORMAT_ABGR15_VF"; + case PIXEL_FORMAT_ABGR15_VF: + return "PIXEL_FORMAT_ABGR15_VF"; - case PIXEL_FORMAT_BGR15: - return "PIXEL_FORMAT_BGR15"; + case PIXEL_FORMAT_BGR15: + return "PIXEL_FORMAT_BGR15"; - case PIXEL_FORMAT_BGR15_VF: - return "PIXEL_FORMAT_BGR15_VF"; + case PIXEL_FORMAT_BGR15_VF: + return "PIXEL_FORMAT_BGR15_VF"; /* 8bpp formats */ - case PIXEL_FORMAT_RGB8: - return "PIXEL_FORMAT_RGB8"; + case PIXEL_FORMAT_RGB8: + return "PIXEL_FORMAT_RGB8"; - case PIXEL_FORMAT_RGB8_VF: - return "PIXEL_FORMAT_RGB8_VF"; + case PIXEL_FORMAT_RGB8_VF: + return "PIXEL_FORMAT_RGB8_VF"; /* 4 bpp formats */ - case PIXEL_FORMAT_A4: - return "PIXEL_FORMAT_A4"; + case PIXEL_FORMAT_A4: + return "PIXEL_FORMAT_A4"; - case PIXEL_FORMAT_A4_VF: - return "PIXEL_FORMAT_A4_VF"; + case PIXEL_FORMAT_A4_VF: + return "PIXEL_FORMAT_A4_VF"; /* 1bpp formats */ - case PIXEL_FORMAT_MONO: - return "PIXEL_FORMAT_MONO"; + case PIXEL_FORMAT_MONO: + return "PIXEL_FORMAT_MONO"; - case PIXEL_FORMAT_MONO_VF: - return "PIXEL_FORMAT_MONO_VF"; + case PIXEL_FORMAT_MONO_VF: + return "PIXEL_FORMAT_MONO_VF"; - default: - return "UNKNOWN"; + default: + 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)) { - /* 32bpp formats */ - case PIXEL_FORMAT_ARGB32: - if (_a) + /* 32bpp formats */ + case PIXEL_FORMAT_ARGB32: + if (_a) *_a = color >> 24; if (_r) @@ -327,10 +333,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, if (_b) *_b = color; - break; + break; - case PIXEL_FORMAT_XRGB32: - if (_r) + case PIXEL_FORMAT_XRGB32: + if (_r) *_r = color >> 16; if (_g) @@ -342,10 +348,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, if (_a) *_a = 0xFF; - break; + break; - case PIXEL_FORMAT_ABGR32: - if (_a) + case PIXEL_FORMAT_ABGR32: + if (_a) *_a = color >> 24; if (_b) @@ -357,10 +363,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, if (_r) *_r = color; - break; + break; - case PIXEL_FORMAT_XBGR32: - if (_b) + case PIXEL_FORMAT_XBGR32: + if (_b) *_b = color >> 16; if (_g) @@ -372,10 +378,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, if (_a) *_a = 0xFF; - break; + break; - case PIXEL_FORMAT_RGBA32: - if (_r) + case PIXEL_FORMAT_RGBA32: + if (_r) *_r = color >> 24; if (_g) @@ -387,10 +393,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, if (_a) *_a = color; - break; + break; - case PIXEL_FORMAT_RGBX32: - if (_r) + case PIXEL_FORMAT_RGBX32: + if (_r) *_r = color >> 24; if (_g) @@ -402,10 +408,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, if (_a) *_a = 0xFF; - break; + break; - case PIXEL_FORMAT_BGRA32: - if (_b) + case PIXEL_FORMAT_BGRA32: + if (_b) *_b = color >> 24; if (_g) @@ -417,10 +423,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, if (_a) *_a = color; - break; + break; - case PIXEL_FORMAT_BGRX32: - if (_b) + case PIXEL_FORMAT_BGRX32: + if (_b) *_b = color >> 24; if (_g) @@ -432,11 +438,11 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, if (_a) *_a = 0xFF; - break; + break; /* 24bpp formats */ - case PIXEL_FORMAT_RGB24: - if (_r) + case PIXEL_FORMAT_RGB24: + if (_r) *_r = color >> 16; if (_g) @@ -448,10 +454,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, if (_a) *_a = 0xFF; - break; + break; - case PIXEL_FORMAT_BGR24: - if (_b) + case PIXEL_FORMAT_BGR24: + if (_b) *_b = color >> 16; if (_g) @@ -463,11 +469,11 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, if (_a) *_a = 0xFF; - break; + break; /* 16bpp formats */ - case PIXEL_FORMAT_RGB16: - if (_r) + case PIXEL_FORMAT_RGB16: + if (_r) *_r = ((color >> 11) & 0x1F) << 3; if (_g) @@ -479,10 +485,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, if (_a) *_a = 0xFF; - break; + break; - case PIXEL_FORMAT_BGR16: - if (_b) + case PIXEL_FORMAT_BGR16: + if (_b) *_b = ((color >> 11) & 0x1F) << 3; if (_g) @@ -494,10 +500,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, if (_a) *_a = 0xFF; - break; + break; - case PIXEL_FORMAT_ARGB15: - if (_r) + case PIXEL_FORMAT_ARGB15: + if (_r) *_r = ((color >> 10) & 0x1F) << 3; if (_g) @@ -509,10 +515,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, if (_a) *_a = color & 0x8000 ? 0xFF : 0x00; - break; + break; - case PIXEL_FORMAT_ABGR15: - if (_b) + case PIXEL_FORMAT_ABGR15: + if (_b) *_b = ((color >> 10) & 0x1F) << 3; if (_g) @@ -524,11 +530,11 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, if (_a) *_a = color & 0x8000 ? 0xFF : 0x00; - break; + break; /* 15bpp formats */ - case PIXEL_FORMAT_RGB15: - if (_r) + case PIXEL_FORMAT_RGB15: + if (_r) *_r = ((color >> 10) & 0x1F) << 3; if (_g) @@ -540,10 +546,10 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, if (_a) *_a = 0xFF; - break; + break; - case PIXEL_FORMAT_BGR15: - if (_b) + case PIXEL_FORMAT_BGR15: + if (_b) *_b = ((color >> 10) & 0x1F) << 3; if (_g) @@ -555,21 +561,21 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, if (_a) *_a = 0xFF; - break; + break; /* 8bpp formats */ - case PIXEL_FORMAT_RGB8: - if (color <= 0xFF) + case PIXEL_FORMAT_RGB8: + if (color <= 0xFF) { tmp = palette->palette[color]; SplitColor(tmp, palette->format, _r, _g, _b, _a, NULL); } - break; + break; /* 1bpp formats */ - case PIXEL_FORMAT_MONO: - if (_r) + case PIXEL_FORMAT_MONO: + if (_r) *_r = (color) ? 0xFF : 0x00; if (_g) @@ -581,13 +587,13 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, if (_a) *_a = (color) ? 0xFF : 0x00; - break; + break; /* 4 bpp formats */ - case PIXEL_FORMAT_A4: - default: - WLog_ERR("xxxxx", "Unsupported format %s", GetColorFormatName(format)); - break; + case PIXEL_FORMAT_A4: + default: + WLog_ERR("xxxxx", "Unsupported format %s", GetColorFormatName(format)); + 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)) { - /* 32bpp formats */ - case PIXEL_FORMAT_ARGB32: - return (_a << 24) | (_r << 16) | (_g << 8) | _b; + /* 32bpp formats */ + case PIXEL_FORMAT_ARGB32: + return (_a << 24) | (_r << 16) | (_g << 8) | _b; - case PIXEL_FORMAT_XRGB32: - return (_r << 16) | (_g << 8) | _b; + case PIXEL_FORMAT_XRGB32: + return (_r << 16) | (_g << 8) | _b; - case PIXEL_FORMAT_ABGR32: - return (_a << 24) | (_b << 16) | (_g << 8) | _r; + case PIXEL_FORMAT_ABGR32: + return (_a << 24) | (_b << 16) | (_g << 8) | _r; - case PIXEL_FORMAT_XBGR32: - return (_b << 16) | (_g << 8) | _r; + case PIXEL_FORMAT_XBGR32: + return (_b << 16) | (_g << 8) | _r; - case PIXEL_FORMAT_RGBA32: - return (_r << 24) | (_g << 16) | (_b << 8) | _a; + case PIXEL_FORMAT_RGBA32: + return (_r << 24) | (_g << 16) | (_b << 8) | _a; - case PIXEL_FORMAT_RGBX32: - return (_r << 24) | (_g << 16) | (_b << 8) | _a; + case PIXEL_FORMAT_RGBX32: + return (_r << 24) | (_g << 16) | (_b << 8) | _a; - case PIXEL_FORMAT_BGRA32: - return (_b << 24) | (_g << 16) | (_r << 8) | _a; + case PIXEL_FORMAT_BGRA32: + return (_b << 24) | (_g << 16) | (_r << 8) | _a; - case PIXEL_FORMAT_BGRX32: - return (_b << 24) | (_g << 16) | (_r << 8) | _a; + case PIXEL_FORMAT_BGRX32: + return (_b << 24) | (_g << 16) | (_r << 8) | _a; /* 24bpp formats */ - case PIXEL_FORMAT_RGB24: - return (_r << 16) | (_g << 8) | _b; + case PIXEL_FORMAT_RGB24: + return (_r << 16) | (_g << 8) | _b; - case PIXEL_FORMAT_BGR24: - return (_b << 16) | (_g << 8) | _r; + case PIXEL_FORMAT_BGR24: + return (_b << 16) | (_g << 8) | _r; /* 16bpp formats */ - case PIXEL_FORMAT_RGB16: - return (((_r >> 3) & 0x1F) << 11) | (((_g >> 2) & 0x3F) << 5) | (( + case PIXEL_FORMAT_RGB16: + return (((_r >> 3) & 0x1F) << 11) | (((_g >> 2) & 0x3F) << 5) | (( _b >> 3) & 0x1F); - case PIXEL_FORMAT_BGR16: - return (((_b >> 3) & 0x1F) << 11) | (((_g >> 2) & 0x3F) << 5) | (( + case PIXEL_FORMAT_BGR16: + return (((_b >> 3) & 0x1F) << 11) | (((_g >> 2) & 0x3F) << 5) | (( _r >> 3) & 0x1F); - case PIXEL_FORMAT_ARGB15: - return (((_r >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | (( + case PIXEL_FORMAT_ARGB15: + return (((_r >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | (( _b >> 3) & 0x1F) | (_a ? 0x8000 : 0x0000); - case PIXEL_FORMAT_ABGR15: - return (((_b >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | (( + case PIXEL_FORMAT_ABGR15: + return (((_b >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | (( _r >> 3) & 0x1F) | (_a ? 0x8000 : 0x0000); /* 15bpp formats */ - case PIXEL_FORMAT_RGB15: - return (((_r >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | (( + case PIXEL_FORMAT_RGB15: + return (((_r >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | (( _b >> 3) & 0x1F); - case PIXEL_FORMAT_BGR15: - return (((_b >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | (( + case PIXEL_FORMAT_BGR15: + return (((_b >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | (( _r >> 3) & 0x1F); /* 8bpp formats */ - case PIXEL_FORMAT_RGB8: + case PIXEL_FORMAT_RGB8: /* 4 bpp formats */ - case PIXEL_FORMAT_A4: + case PIXEL_FORMAT_A4: /* 1bpp formats */ - case PIXEL_FORMAT_MONO: - default: - WLog_ERR("xxxxx", "Unsupported format %s", GetColorFormatName(format)); - return 0; + case PIXEL_FORMAT_MONO: + default: + WLog_ERR("xxxxx", "Unsupported format %s", GetColorFormatName(format)); + return 0; } } @@ -728,37 +734,37 @@ static INLINE UINT32 ReadColor(const BYTE* src, UINT32 format) switch (GetBitsPerPixel(format)) { - case 32: - color = ((UINT32)src[0] << 24) | ((UINT32)src[1] << 16) | + case 32: + color = ((UINT32)src[0] << 24) | ((UINT32)src[1] << 16) | ((UINT32)src[2] << 8) | src[3]; - break; + break; - case 24: - color = ((UINT32)src[0] << 16) | ((UINT32)src[1] << 8) | src[2]; - break; + case 24: + color = ((UINT32)src[0] << 16) | ((UINT32)src[1] << 8) | src[2]; + break; - case 16: - color = ((UINT32)src[1] << 8) | src[0]; - break; + case 16: + color = ((UINT32)src[1] << 8) | src[0]; + break; - case 15: - color = ((UINT32)src[1] << 8) | src[0]; + case 15: + color = ((UINT32)src[1] << 8) | src[0]; if (!ColorHasAlpha(format)) color = color & 0x7FFF; - break; + break; - case 8: - case 4: - case 1: - color = *src; - break; + case 8: + case 4: + case 1: + color = *src; + break; - default: - WLog_ERR("xxxxx", "Unsupported format %s", GetColorFormatName(format)); + default: + WLog_ERR("xxxxx", "Unsupported format %s", GetColorFormatName(format)); color = 0; - break; + break; } return color; @@ -778,39 +784,39 @@ static INLINE BOOL WriteColor(BYTE* dst, UINT32 format, UINT32 color) { switch (GetBitsPerPixel(format)) { - case 32: - dst[0] = color >> 24; + case 32: + dst[0] = color >> 24; dst[1] = color >> 16; dst[2] = color >> 8; dst[3] = color; - break; + break; - case 24: - dst[0] = color >> 16; + case 24: + dst[0] = color >> 16; dst[1] = color >> 8; dst[2] = color; - break; + break; - case 16: - dst[1] = color >> 8; + case 16: + dst[1] = color >> 8; dst[0] = color; - break; + break; - case 15: - if (!ColorHasAlpha(format)) + case 15: + if (!ColorHasAlpha(format)) color = color & 0x7FFF; dst[1] = color >> 8; dst[0] = color; - break; + break; - case 8: - dst[0] = color; - break; + case 8: + dst[0] = color; + break; - default: - WLog_ERR("xxxxx", "Unsupported format %s", GetColorFormatName(format)); - return FALSE; + default: + WLog_ERR("xxxxx", "Unsupported format %s", GetColorFormatName(format)); + return FALSE; } return TRUE; diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index 88d1b57e5..d0bd55af2 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -1005,6 +1005,7 @@ BOOL gdi_surface_frame_marker(rdpContext* context, static BOOL gdi_surface_bits(rdpContext* context, const SURFACE_BITS_COMMAND* cmd) { + DWORD format; rdpGdi* gdi; if (!context || !cmd) @@ -1020,39 +1021,42 @@ static BOOL gdi_surface_bits(rdpContext* context, switch (cmd->codecID) { 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, - PIXEL_FORMAT_BGRX32, - cmd->bitmapDataLength, - cmd->destLeft, cmd->destTop, - gdi->primary_buffer, gdi->dstFormat, - gdi->stride, gdi->height, NULL)) - { - WLog_ERR(TAG, "Failed to process RemoteFX message"); - return FALSE; - } + WLog_ERR(TAG, "Failed to process RemoteFX message"); + return FALSE; } + break; case RDP_CODEC_ID_NSCODEC: - { - if (!nsc_process_message(context->codecs->nsc, cmd->bpp, cmd->width, - cmd->height, cmd->bitmapData, - cmd->bitmapDataLength, gdi->primary_buffer, - gdi->dstFormat, gdi->stride, cmd->destLeft, cmd->destTop, - cmd->width, cmd->height)) - return FALSE; - } + format = FREERDP_VFLIP_PIXEL_FORMAT(gdi->dstFormat); + + if (!nsc_process_message(context->codecs->nsc, cmd->bpp, cmd->width, + cmd->height, cmd->bitmapData, + cmd->bitmapDataLength, gdi->primary_buffer, + format, gdi->stride, cmd->destLeft, cmd->destTop, + cmd->width, cmd->height)) + return FALSE; + break; case RDP_CODEC_ID_NONE: - { - if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, gdi->stride, - cmd->destLeft, cmd->destTop, cmd->width, cmd->height, - cmd->bitmapData, PIXEL_FORMAT_XRGB32_VF, 0, 0, 0, - &gdi->palette)) - return FALSE; - } + format = PIXEL_FORMAT_XRGB32_VF; + + if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, gdi->stride, + cmd->destLeft, cmd->destTop, cmd->width, cmd->height, + cmd->bitmapData, format, 0, 0, 0, + &gdi->palette)) + return FALSE; + break; default: From 985ca171ff3e4ae99c36a78144be90eeb6e13b2a Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 12 Oct 2016 09:21:21 +0200 Subject: [PATCH 3/6] Respecting tile offsets. --- libfreerdp/codec/rfx.c | 199 +++++++++++++++++++++-------------------- 1 file changed, 101 insertions(+), 98 deletions(-) diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index 69aee0305..57fa88334 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -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_component, - "rfx_decode_component"); + "rfx_decode_component"); PROFILER_CREATE(context->priv->prof_rfx_rlgr_decode, "rfx_rlgr_decode"); PROFILER_CREATE(context->priv->prof_rfx_differential_decode, - "rfx_differential_decode"); + "rfx_differential_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_ycbcr_to_rgb, "prims->yCbCrToRGB"); 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_component, - "rfx_encode_component"); + "rfx_encode_component"); PROFILER_CREATE(context->priv->prof_rfx_rlgr_encode, "rfx_rlgr_encode"); PROFILER_CREATE(context->priv->prof_rfx_differential_encode, - "rfx_differential_encode"); + "rfx_differential_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_rgb_to_ycbcr, "prims->RGBToYCbCr"); 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) @@ -275,7 +275,7 @@ RFX_CONTEXT* rfx_context_new(BOOL encoder) verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); GetVersionExA(&verinfo); isVistaOrLater = ((verinfo.dwMajorVersion >= 6) - && (verinfo.dwMinorVersion >= 0)) ? TRUE : FALSE; + && (verinfo.dwMinorVersion >= 0)) ? TRUE : FALSE; priv->UseThreads = isVistaOrLater; } #else @@ -285,22 +285,22 @@ RFX_CONTEXT* rfx_context_new(BOOL encoder) priv->MinThreadCount = sysinfo.dwNumberOfProcessors; priv->MaxThreadCount = 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) { dwSize = sizeof(dwValue); if (RegQueryValueEx(hKey, _T("UseThreads"), NULL, &dwType, (BYTE*) &dwValue, - &dwSize) == ERROR_SUCCESS) + &dwSize) == ERROR_SUCCESS) priv->UseThreads = dwValue ? 1 : 0; if (RegQueryValueEx(hKey, _T("MinThreadCount"), NULL, &dwType, (BYTE*) &dwValue, - &dwSize) == ERROR_SUCCESS) + &dwSize) == ERROR_SUCCESS) priv->MinThreadCount = dwValue; if (RegQueryValueEx(hKey, _T("MaxThreadCount"), NULL, &dwType, (BYTE*) &dwValue, - &dwSize) == ERROR_SUCCESS) + &dwSize) == ERROR_SUCCESS) priv->MaxThreadCount = dwValue; RegCloseKey(hKey); @@ -378,7 +378,7 @@ void rfx_context_free(RFX_CONTEXT* context) free(priv->tileWorkParams); #ifdef WITH_PROFILER WLog_VRB(TAG, - "WARNING: Profiling results probably unusable with multithreaded RemoteFX codec!"); + "WARNING: Profiling results probably unusable with multithreaded RemoteFX codec!"); #endif } @@ -436,7 +436,7 @@ static BOOL rfx_process_message_sync(RFX_CONTEXT* context, wStream* 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) { @@ -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, - 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, - 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) { @@ -481,12 +481,12 @@ static BOOL rfx_process_message_codec_versions(RFX_CONTEXT* context, wStream* s) if (context->codec_version != WF_VERSION_1_0) { WLog_ERR(TAG, "%s: invalid codec version (0x%04X)", __FUNCTION__, - context->codec_version); + context->codec_version); return FALSE; } 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; return TRUE; } @@ -504,7 +504,7 @@ static BOOL rfx_process_message_channels(RFX_CONTEXT* context, wStream* 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 * 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)) { WLog_ERR(TAG, "RfxMessageChannels packet too small for numChannels=%d", - numChannels); + numChannels); return FALSE; } @@ -537,14 +537,14 @@ static BOOL rfx_process_message_channels(RFX_CONTEXT* context, wStream* s) if (!context->width || !context->height) { WLog_ERR(TAG, "%s: invalid channel with/height: %ux%u", __FUNCTION__, - context->width, context->height); + context->width, context->height); return FALSE; } /* Now, only the first monitor can be used, therefore the other channels will be ignored. */ Stream_Seek(s, 5 * (numChannels - 1)); 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; 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_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) */ WLog_Print(context->priv->log, WLOG_DEBUG, - "ctxId %d tileSize %d properties 0x%X.", - ctxId, tileSize, properties); + "ctxId %d tileSize %d properties 0x%X.", + ctxId, tileSize, properties); context->properties = properties; 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, - RFX_MESSAGE* message, wStream* s, UINT16* pExpectedBlockType) + RFX_MESSAGE* message, wStream* s, UINT16* pExpectedBlockType) { UINT32 frameIdx; UINT16 numRegions; @@ -623,15 +623,15 @@ static BOOL rfx_process_message_frame_begin(RFX_CONTEXT* context, } 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) */ 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; } 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) { @@ -645,7 +645,7 @@ static BOOL rfx_process_message_frame_end(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; UINT16 regionType; @@ -690,7 +690,7 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context, if (Stream_GetRemainingLength(s) < (size_t)(8 * message->numRects)) { WLog_ERR(TAG, "%s: packet too small for num_rects=%d", __FUNCTION__, - message->numRects); + message->numRects); 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->height); /* height (2 bytes) */ WLog_Print(context->priv->log, WLOG_DEBUG, "rect %d (x,y=%d,%d w,h=%d %d).", i, - rect->x, rect->y, - rect->width, rect->height); + rect->x, rect->y, + rect->width, rect->height); } if (Stream_GetRemainingLength(s) < 4) @@ -718,9 +718,9 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context, } 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, - numTileSets); /* numTilesets (2 bytes): MUST be set to 0x0001. */ + numTileSets); /* numTilesets (2 bytes): MUST be set to 0x0001. */ 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, - RFX_MESSAGE* message, wStream* s, UINT16* pExpecedBlockType) + RFX_MESSAGE* message, wStream* s, UINT16* pExpecedBlockType) { BOOL rc; int i, close_cnt; @@ -784,7 +784,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, } 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) { @@ -814,7 +814,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, Stream_Read_UINT32(s, tilesDataSize); /* tilesDataSize (4 bytes) */ if (!(pmem = realloc((void*) context->quants, - context->numQuant * 10 * sizeof(UINT32)))) + context->numQuant * 10 * sizeof(UINT32)))) return FALSE; 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)) { WLog_ERR(TAG, "RfxMessageTileSet packet too small for num_quants=%d", - context->numQuant); + context->numQuant); return FALSE; } @@ -846,16 +846,16 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, *quants++ = (quant & 0x0F); *quants++ = (quant >> 4); WLog_Print(context->priv->log, WLOG_DEBUG, - "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]); + "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]); } if (!(message->tiles = (RFX_TILE**) calloc(message->numTiles, - sizeof(RFX_TILE*)))) + sizeof(RFX_TILE*)))) { message->numTiles = 0; 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)); params = (RFX_TILE_PROCESS_WORK_PARAM*) calloc(message->numTiles, - sizeof(RFX_TILE_PROCESS_WORK_PARAM)); + sizeof(RFX_TILE_PROCESS_WORK_PARAM)); if (!work_objects) { @@ -899,20 +899,20 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, if (Stream_GetRemainingLength(s) < 6) { WLog_ERR(TAG, "RfxMessageTileSet packet too small to read tile %d/%d", i, - message->numTiles); + message->numTiles); rc = FALSE; break; } 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) */ if (Stream_GetRemainingLength(s) < blockLen - 6) { WLog_ERR(TAG, - "RfxMessageTileSet not enough bytes to read tile %d/%d with blocklen=%d", - i, message->numTiles, blockLen); + "RfxMessageTileSet not enough bytes to read tile %d/%d with blocklen=%d", + i, message->numTiles, blockLen); rc = FALSE; break; } @@ -922,7 +922,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, if (blockType != CBT_TILE) { WLog_ERR(TAG, "unknown block type 0x%X, expected CBT_TILE (0xCAC3).", - blockType); + blockType); rc = FALSE; break; } @@ -951,8 +951,8 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, params[i].tile = message->tiles[i]; if (!(work_objects[i] = CreateThreadpoolWork((PTP_WORK_CALLBACK) - rfx_process_message_tile_work_callback, - (void*) ¶ms[i], &context->priv->ThreadPoolEnv))) + rfx_process_message_tile_work_callback, + (void*) ¶ms[i], &context->priv->ThreadPoolEnv))) { WLog_ERR(TAG, "CreateThreadpoolWork failed."); 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, - UINT32 format, UINT32 length, - UINT32 left, UINT32 top, - BYTE* dst, UINT32 dstFormat, - UINT32 dstStride, UINT32 dstHeight, - REGION16* invalidRegion) + UINT32 format, UINT32 length, + UINT32 left, UINT32 top, + BYTE* dst, UINT32 dstFormat, + UINT32 dstStride, UINT32 dstHeight, + REGION16* invalidRegion) { int pos; 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_UINT32(s, blockLen); /* blockLen (4 bytes) */ WLog_Print(context->priv->log, WLOG_DEBUG, "blockType 0x%X blockLen %d", - blockType, blockLen); + blockType, blockLen); 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, - channelId); /* channelId (1 byte) 0xFF or 0x00, see below */ + channelId); /* channelId (1 byte) 0xFF or 0x00, see below */ if (codecId != 0x01) { @@ -1075,7 +1075,7 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, if (channelId != 0xFF) { WLog_ERR(TAG, "%s: invalid channelId 0x%02X for blockType 0x%04X", __FUNCTION__, - channelId, blockType); + channelId, blockType); goto fail; } } @@ -1085,7 +1085,7 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, if (channelId != 0x00) { WLog_ERR(TAG, "%s: invalid channelId 0x%02X for blockType WBT_CONTEXT", - __FUNCTION__, channelId); + __FUNCTION__, channelId); goto fail; } } @@ -1122,7 +1122,7 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, case WBT_FRAME_BEGIN: ok = rfx_process_message_frame_begin(context, message, s, - &expectedDataBlockType); + &expectedDataBlockType); break; case WBT_REGION: @@ -1178,14 +1178,17 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, for (j = 0; j < nbUpdateRects; j++) { + UINT32 stride = 64 * GetBytesPerPixel(format); UINT32 nXDst = updateRects[j].left; UINT32 nYDst = updateRects[j].top; - UINT32 nWidth = updateRects[j].right - updateRects[j].left; - UINT32 nHeight = updateRects[j].bottom - updateRects[j].top; + UINT32 nXSrc = nXDst - updateRect.left; + 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, - nXDst, nYDst, nWidth, nHeight, - tile->data, format, 64 * GetBytesPerPixel(format), 0, 0, NULL)) + nXDst, nYDst, nWidth, nHeight, + tile->data, format, stride, nXSrc, nYSrc, NULL)) goto fail; if (invalidRegion) @@ -1263,7 +1266,7 @@ static void rfx_update_context_properties(RFX_CONTEXT* context) properties |= (COL_CONV_ICT << 4); /* cct */ properties |= (CLW_XFORM_DWT_53_A << 6); /* xft */ properties |= ((context->mode == RLGR1 ? CLW_ENTROPY_RLGR1 : CLW_ENTROPY_RLGR3) - << 10); /* et */ + << 10); /* et */ properties |= (SCALAR_QUANTIZATION << 14); /* qt */ 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 |= (CLW_XFORM_DWT_53_A << 5); /* xft */ properties |= ((context->mode == RLGR1 ? CLW_ENTROPY_RLGR1 : CLW_ENTROPY_RLGR3) - << 9); /* et */ + << 9); /* et */ properties |= (SCALAR_QUANTIZATION << 13); /* qt */ Stream_Write_UINT16(s, properties); /* properties (2 bytes) */ 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 - 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_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, - int width, int height) + int width, int height) { int i; const RFX_RECT* rect = rects; @@ -1408,7 +1411,7 @@ BOOL setupWorkers(RFX_CONTEXT* context, int nbTiles) priv->workObjects = (PTP_WORK*) pmem; if (!(pmem = realloc((void*) priv->tileWorkParams, - sizeof(RFX_TILE_COMPOSE_WORK_PARAM) * nbTiles))) + sizeof(RFX_TILE_COMPOSE_WORK_PARAM) * nbTiles))) return FALSE; 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, - int numRects, - BYTE* data, int width, int height, int scanline) + int numRects, + BYTE* data, int width, int height, int scanline) { UINT32 i, maxNbTiles, maxTilesX, maxTilesY; 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->quants = (UINT32*) malloc(sizeof( - rfx_default_quantization_values)))) + rfx_default_quantization_values)))) goto skip_encoding_loop; CopyMemory(context->quants, &rfx_default_quantization_values, - sizeof(rfx_default_quantization_values)); + sizeof(rfx_default_quantization_values)); context->numQuant = 1; context->quantIdxY = 0; context->quantIdxCb = 0; @@ -1575,9 +1578,9 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, workParam->tile = tile; if (!(*workObject = CreateThreadpoolWork( - (PTP_WORK_CALLBACK)rfx_compose_message_tile_work_callback, - (void*) workParam, - &context->priv->ThreadPoolEnv))) + (PTP_WORK_CALLBACK)rfx_compose_message_tile_work_callback, + (void*) workParam, + &context->priv->ThreadPoolEnv))) { goto skip_encoding_loop; } @@ -1605,7 +1608,7 @@ skip_encoding_loop: if (message->numTiles > 0) { void* pmem = realloc((void*) message->tiles, - sizeof(RFX_TILE*) * message->numTiles); + sizeof(RFX_TILE*) * message->numTiles); if (pmem) message->tiles = (RFX_TILE**) pmem; @@ -1654,7 +1657,7 @@ skip_encoding_loop: } RFX_MESSAGE* rfx_split_message(RFX_CONTEXT* context, RFX_MESSAGE* message, - int* numMessages, int maxDataSize) + int* numMessages, int maxDataSize) { int i, j; UINT32 tileDataSize; @@ -1685,7 +1688,7 @@ RFX_MESSAGE* rfx_split_message(RFX_CONTEXT* context, RFX_MESSAGE* message, messages[j].freeArray = TRUE; if (!(messages[j].tiles = (RFX_TILE**) calloc(message->numTiles, - sizeof(RFX_TILE*)))) + sizeof(RFX_TILE*)))) goto free_messages; } @@ -1708,19 +1711,19 @@ free_messages: } RFX_MESSAGE* rfx_encode_messages(RFX_CONTEXT* context, const RFX_RECT* rects, - int numRects, - BYTE* data, int width, int height, int scanline, int* numMessages, - int maxDataSize) + int numRects, + BYTE* data, int width, int height, int scanline, int* numMessages, + int maxDataSize) { RFX_MESSAGE* message; RFX_MESSAGE* messageList; if (!(message = rfx_encode_message(context, rects, numRects, data, width, - height, scanline))) + height, scanline))) return NULL; if (!(messageList = rfx_split_message(context, message, numMessages, - maxDataSize))) + maxDataSize))) { message->freeRects = TRUE; 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, - RFX_MESSAGE* message) + RFX_MESSAGE* message) { int i; RFX_TILE* tile; @@ -1773,14 +1776,14 @@ static BOOL rfx_write_message_tileset(RFX_CONTEXT* context, wStream* s, #ifdef WITH_DEBUG_RFX WLog_Print(context->priv->log, WLOG_DEBUG, - "numQuant: %d numTiles: %d tilesDataSize: %d", - message->numQuant, message->numTiles, message->tilesDataSize); + "numQuant: %d numTiles: %d tilesDataSize: %d", + message->numQuant, message->numTiles, message->tilesDataSize); #endif return TRUE; } static BOOL rfx_write_message_frame_begin(RFX_CONTEXT* context, wStream* s, - RFX_MESSAGE* message) + RFX_MESSAGE* message) { if (!Stream_EnsureRemainingCapacity(s, 14)) 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, - RFX_MESSAGE* message) + RFX_MESSAGE* message) { int i; 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, - RFX_MESSAGE* message) + RFX_MESSAGE* message) { if (!Stream_EnsureRemainingCapacity(s, 8)) 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, - const RFX_RECT* rects, int numRects, BYTE* data, int width, int height, - int scanline) + const RFX_RECT* rects, int numRects, BYTE* data, int width, int height, + int scanline) { RFX_MESSAGE* message; BOOL ret = TRUE; if (!(message = rfx_encode_message(context, rects, numRects, data, width, - height, scanline))) + height, scanline))) return FALSE; ret = rfx_write_message(context, s, message); From 25c7372fe68508b0baed79936e1d0fd9487a7667 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 12 Oct 2016 09:32:05 +0200 Subject: [PATCH 4/6] Fixed offset and stride for X11 surface bits. --- client/X11/xf_gdi.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index 950ab7dab..e684c59e1 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -984,11 +984,16 @@ static BOOL xf_gdi_update_screen(xfContext* xfc, 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); - 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); + + 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; } @@ -1000,7 +1005,14 @@ static BOOL xf_gdi_surface_bits(rdpContext* context, xfContext* xfc = (xfContext*) context; BOOL ret = FALSE; DWORD format; - rdpGdi* gdi = context->gdi; + 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); switch (cmd->codecID) @@ -1010,12 +1022,11 @@ static BOOL xf_gdi_surface_bits(rdpContext* context, if (!rfx_process_message(context->codecs->rfx, cmd->bitmapData, format, cmd->bitmapDataLength, - cmd->destLeft, cmd->destTop, - gdi->primary_buffer, gdi->dstFormat, gdi->stride, + 0, 0, + gdi->primary_buffer, gdi->dstFormat, stride, gdi->height, NULL)) goto fail; - ret = xf_gdi_update_screen(xfc, cmd, gdi->primary_buffer); break; case RDP_CODEC_ID_NSCODEC: @@ -1023,32 +1034,31 @@ static BOOL xf_gdi_surface_bits(rdpContext* context, if (!nsc_process_message(context->codecs->nsc, cmd->bpp, cmd->width, cmd->height, cmd->bitmapData, cmd->bitmapDataLength, - gdi->primary_buffer, format, gdi->stride, - cmd->destLeft, cmd->destTop, cmd->width, cmd->height)) + gdi->primary_buffer, format, stride, + 0, 0, cmd->width, cmd->height)) goto fail; - ret = xf_gdi_update_screen(xfc, cmd, gdi->primary_buffer); break; case RDP_CODEC_ID_NONE: pSrcData = cmd->bitmapData; format = PIXEL_FORMAT_BGRX32_VF; - if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, gdi->stride, - cmd->destLeft, cmd->destTop, + if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, stride, + 0, 0, cmd->width, cmd->height, pSrcData, format, 0, 0, 0, &xfc->context.gdi->palette)) goto fail; - ret = xf_gdi_update_screen(xfc, cmd, gdi->primary_buffer); break; default: WLog_ERR(TAG, "Unsupported codecID %d", cmd->codecID); ret = TRUE; - break; + goto fail; } + ret = xf_gdi_update_screen(xfc, cmd, gdi->primary_buffer); fail: xf_unlock_x11(xfc, FALSE); return ret; From 714e704352ebf60f7c43014ff53d1ec766b0d3fa Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 12 Oct 2016 09:32:59 +0200 Subject: [PATCH 5/6] Color format for surface bits unified. --- libfreerdp/gdi/gdi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index d0bd55af2..7bdeb0b54 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -1049,7 +1049,7 @@ static BOOL gdi_surface_bits(rdpContext* context, break; case RDP_CODEC_ID_NONE: - format = PIXEL_FORMAT_XRGB32_VF; + format = PIXEL_FORMAT_BGRX32_VF; if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, gdi->stride, cmd->destLeft, cmd->destTop, cmd->width, cmd->height, From 79e8a6d61cdef74bbab79df5f66fb47a5419f1df Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 11 Oct 2016 16:13:19 +0200 Subject: [PATCH 6/6] Reverted NSC format, decoded data is always BGRA! --- libfreerdp/codec/nsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfreerdp/codec/nsc.c b/libfreerdp/codec/nsc.c index 52388108f..487aaf299 100644 --- a/libfreerdp/codec/nsc.c +++ b/libfreerdp/codec/nsc.c @@ -407,7 +407,7 @@ BOOL nsc_process_message(NSC_CONTEXT* context, UINT16 bpp, if (!freerdp_image_copy(pDstData, DstFormat, nDstStride, nXDst, nYDst, width, height, context->BitmapData, - PIXEL_FORMAT_BGRX32_VF, 0, 0, 0, NULL)) + PIXEL_FORMAT_BGRA32, 0, 0, 0, NULL)) return FALSE; return TRUE;