Fix ColorFidelity use
authorArmin Novak <armin.novak@thincast.com>
Mon, 18 Jan 2021 08:18:55 +0000 (09:18 +0100)
committerakallabeth <akallabeth@users.noreply.github.com>
Thu, 25 Feb 2021 08:51:41 +0000 (09:51 +0100)
(cherry picked from commit 8187ab7732dd0184e1123b1c39790a246f9912a6)

include/freerdp/codec/planar.h
libfreerdp/codec/planar.c
libfreerdp/core/settings.c
libfreerdp/gdi/graphics.c

index 245b93f..fdf92ac 100644 (file)
@@ -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,
index bedd2ed..f31c2d4 100644 (file)
 
 #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;
-               }
+               case PIXEL_FORMAT_BGRA32:
+                       for (x = 0; x < width; x++)
+                       {
+                               *(*ppRgba)++ = *(*ppB)++;
+                               *(*ppRgba)++ = *(*ppG)++;
+                               *(*ppRgba)++ = *(*ppR)++;
+                               *(*ppRgba)++ = *(*ppA)++;
+                       }
 
-               return TRUE;
+                       return TRUE;
 
-       default:
-               if (ppA)
-               {
+               case PIXEL_FORMAT_BGRX32:
                        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)++ = 0xFF;
                        }
-               }
-               else
-               {
-                       const BYTE alpha = 0xFF;
 
-                       for (x = 0; x < width; x++)
+                       return TRUE;
+
+               default:
+                       if (ppA)
                        {
-                               UINT32 color = FreeRDPGetColor(DstFormat, *(*ppR)++, *(*ppG)++, *(*ppB)++, alpha);
-                               WriteColor(*ppRgba, DstFormat, color);
-                               *ppRgba += GetBytesPerPixel(DstFormat);
+                               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;
 
-               return TRUE;
+                               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;
+}
index ed30bbb..2ea2137 100644 (file)
@@ -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;
index 60d82ae..3bcf373 100644 (file)
@@ -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))