From 847de7f4ae683f737d95adb0d6b2f1b451541f06 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 18 Jan 2021 09:18:55 +0100 Subject: [PATCH] Fix ColorFidelity use (cherry picked from commit 8187ab7732dd0184e1123b1c39790a246f9912a6) --- include/freerdp/codec/planar.h | 4 + libfreerdp/codec/planar.c | 152 ++++++++++++++++++++++++--------- libfreerdp/core/settings.c | 4 +- libfreerdp/gdi/graphics.c | 2 + 4 files changed, 121 insertions(+), 41 deletions(-) diff --git a/include/freerdp/codec/planar.h b/include/freerdp/codec/planar.h index 245b93fb2..fdf92acf0 100644 --- a/include/freerdp/codec/planar.h +++ b/include/freerdp/codec/planar.h @@ -97,6 +97,8 @@ struct _BITMAP_PLANAR_CONTEXT BYTE* pTempData; UINT32 nTempStep; + + BOOL bgr; }; #ifdef __cplusplus @@ -116,6 +118,8 @@ extern "C" UINT32 height); FREERDP_API void freerdp_bitmap_planar_context_free(BITMAP_PLANAR_CONTEXT* context); + FREERDP_API void freerdp_planar_switch_bgr(BITMAP_PLANAR_CONTEXT* planar, BOOL bgr); + FREERDP_API BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* planar, const BYTE* pSrcData, UINT32 SrcSize, UINT32 nSrcWidth, UINT32 nSrcHeight, BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep, diff --git a/libfreerdp/codec/planar.c b/libfreerdp/codec/planar.c index bedd2ed7a..f31c2d46a 100644 --- a/libfreerdp/codec/planar.c +++ b/libfreerdp/codec/planar.c @@ -33,6 +33,69 @@ #define TAG FREERDP_TAG("codec") +static INLINE UINT32 planar_invert_format(BITMAP_PLANAR_CONTEXT* planar, BOOL alpha, + UINT32 DstFormat) +{ + + if (planar->bgr && alpha) + { + switch (DstFormat) + { + case PIXEL_FORMAT_ARGB32: + DstFormat = PIXEL_FORMAT_ABGR32; + break; + case PIXEL_FORMAT_XRGB32: + DstFormat = PIXEL_FORMAT_XBGR32; + break; + case PIXEL_FORMAT_ABGR32: + DstFormat = PIXEL_FORMAT_ARGB32; + break; + case PIXEL_FORMAT_XBGR32: + DstFormat = PIXEL_FORMAT_XRGB32; + break; + case PIXEL_FORMAT_BGRA32: + DstFormat = PIXEL_FORMAT_RGBA32; + break; + case PIXEL_FORMAT_BGRX32: + DstFormat = PIXEL_FORMAT_RGBX32; + break; + case PIXEL_FORMAT_RGBA32: + DstFormat = PIXEL_FORMAT_BGRA32; + break; + case PIXEL_FORMAT_RGBX32: + DstFormat = PIXEL_FORMAT_BGRX32; + break; + case PIXEL_FORMAT_RGB24: + DstFormat = PIXEL_FORMAT_BGR24; + break; + case PIXEL_FORMAT_BGR24: + DstFormat = PIXEL_FORMAT_RGB24; + break; + case PIXEL_FORMAT_RGB16: + DstFormat = PIXEL_FORMAT_BGR16; + break; + case PIXEL_FORMAT_BGR16: + DstFormat = PIXEL_FORMAT_RGB16; + break; + case PIXEL_FORMAT_ARGB15: + DstFormat = PIXEL_FORMAT_ABGR15; + break; + case PIXEL_FORMAT_RGB15: + DstFormat = PIXEL_FORMAT_BGR15; + break; + case PIXEL_FORMAT_ABGR15: + DstFormat = PIXEL_FORMAT_ARGB15; + break; + case PIXEL_FORMAT_BGR15: + DstFormat = PIXEL_FORMAT_RGB15; + break; + default: + break; + } + } + return DstFormat; +} + static INLINE BOOL freerdp_bitmap_planar_compress_plane_rle(const BYTE* plane, UINT32 width, UINT32 height, BYTE* outPlane, UINT32* dstSize); @@ -391,52 +454,54 @@ static INLINE BOOL writeLine(BYTE** ppRgba, UINT32 DstFormat, UINT32 width, cons switch (DstFormat) { - case PIXEL_FORMAT_BGRA32: - for (x = 0; x < width; x++) - { - *(*ppRgba)++ = *(*ppB)++; - *(*ppRgba)++ = *(*ppG)++; - *(*ppRgba)++ = *(*ppR)++; - *(*ppRgba)++ = *(*ppA)++; - } - - return TRUE; - - case PIXEL_FORMAT_BGRX32: - for (x = 0; x < width; x++) - { - *(*ppRgba)++ = *(*ppB)++; - *(*ppRgba)++ = *(*ppG)++; - *(*ppRgba)++ = *(*ppR)++; - *(*ppRgba)++ = 0xFF; - } - - return TRUE; - - default: - if (ppA) - { + case PIXEL_FORMAT_BGRA32: for (x = 0; x < width; x++) { - BYTE alpha = *(*ppA)++; - UINT32 color = FreeRDPGetColor(DstFormat, *(*ppR)++, *(*ppG)++, *(*ppB)++, alpha); - WriteColor(*ppRgba, DstFormat, color); - *ppRgba += GetBytesPerPixel(DstFormat); + *(*ppRgba)++ = *(*ppB)++; + *(*ppRgba)++ = *(*ppG)++; + *(*ppRgba)++ = *(*ppR)++; + *(*ppRgba)++ = *(*ppA)++; } - } - else - { - const BYTE alpha = 0xFF; + return TRUE; + + case PIXEL_FORMAT_BGRX32: for (x = 0; x < width; x++) { - UINT32 color = FreeRDPGetColor(DstFormat, *(*ppR)++, *(*ppG)++, *(*ppB)++, alpha); - WriteColor(*ppRgba, DstFormat, color); - *ppRgba += GetBytesPerPixel(DstFormat); + *(*ppRgba)++ = *(*ppB)++; + *(*ppRgba)++ = *(*ppG)++; + *(*ppRgba)++ = *(*ppR)++; + *(*ppRgba)++ = 0xFF; } - } - return TRUE; + return TRUE; + + default: + if (ppA) + { + for (x = 0; x < width; x++) + { + BYTE alpha = *(*ppA)++; + UINT32 color = + FreeRDPGetColor(DstFormat, *(*ppR)++, *(*ppG)++, *(*ppB)++, alpha); + WriteColor(*ppRgba, DstFormat, color); + *ppRgba += GetBytesPerPixel(DstFormat); + } + } + else + { + const BYTE alpha = 0xFF; + + for (x = 0; x < width; x++) + { + UINT32 color = + FreeRDPGetColor(DstFormat, *(*ppR)++, *(*ppG)++, *(*ppB)++, alpha); + WriteColor(*ppRgba, DstFormat, color); + *ppRgba += GetBytesPerPixel(DstFormat); + } + } + + return TRUE; } } @@ -550,6 +615,8 @@ BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* planar, const BYTE* pSrcData, UINT rle = (FormatHeader & PLANAR_FORMAT_HEADER_RLE) ? TRUE : FALSE; alpha = (FormatHeader & PLANAR_FORMAT_HEADER_NA) ? FALSE : TRUE; + DstFormat = planar_invert_format(planar, alpha, DstFormat); + if (alpha) useAlpha = ColorHasAlpha(DstFormat); @@ -1241,6 +1308,9 @@ BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context, const BYTE* planeSize = width * height; + if (!context->AllowSkipAlpha) + format = planar_invert_format(context, TRUE, format); + if (!freerdp_split_color_planes(data, format, width, height, scanline, context->planes)) return NULL; @@ -1396,6 +1466,7 @@ BOOL freerdp_bitmap_planar_context_reset(BITMAP_PLANAR_CONTEXT* context, UINT32 if (!context) return FALSE; + context->bgr = FALSE; context->maxWidth = width; context->maxHeight = height; context->maxPlaneSize = context->maxWidth * context->maxHeight; @@ -1467,3 +1538,8 @@ void freerdp_bitmap_planar_context_free(BITMAP_PLANAR_CONTEXT* context) free(context->rlePlanesBuffer); free(context); } + +void freerdp_planar_switch_bgr(BITMAP_PLANAR_CONTEXT* planar, BOOL bgr) +{ + planar->bgr = bgr; +} diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index ed30bbbe6..2ea213722 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -414,9 +414,7 @@ rdpSettings* freerdp_settings_new(DWORD flags) settings->DrawGdiPlusEnabled = FALSE; settings->DrawAllowSkipAlpha = TRUE; settings->DrawAllowColorSubsampling = TRUE; - /* [MS-RDPEGDI] 3.1.9.1.2 Color Space Conversion states that MS servers - * send invalid YCoCg data if this flag is set, deactivate. */ - settings->DrawAllowDynamicColorFidelity = FALSE; + settings->DrawAllowDynamicColorFidelity = TRUE; settings->FrameMarkerCommandEnabled = TRUE; settings->SurfaceFrameMarkerEnabled = TRUE; settings->AllowCacheWaitingList = TRUE; diff --git a/libfreerdp/gdi/graphics.c b/libfreerdp/gdi/graphics.c index 60d82ae99..3bcf3730d 100644 --- a/libfreerdp/gdi/graphics.c +++ b/libfreerdp/gdi/graphics.c @@ -162,6 +162,8 @@ static BOOL gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, const } else { + freerdp_planar_switch_bgr(context->codecs->planar, + context->settings->DrawAllowDynamicColorFidelity); if (!planar_decompress(context->codecs->planar, pSrcData, SrcSize, DstWidth, DstHeight, bitmap->data, bitmap->format, 0, 0, 0, DstWidth, DstHeight, TRUE))