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/include/freerdp/utils/pcap.h b/include/freerdp/utils/pcap.h index 4b23343b2..43ce42f68 100644 --- a/include/freerdp/utils/pcap.h +++ b/include/freerdp/utils/pcap.h @@ -49,7 +49,11 @@ typedef struct _pcap_record pcap_record; struct _pcap_record { pcap_record_header header; - void* data; + union + { + void* data; + const void* cdata; + }; UINT32 length; pcap_record* next; }; @@ -76,7 +80,7 @@ extern "C" FREERDP_API rdpPcap* pcap_open(char* name, BOOL write); FREERDP_API void pcap_close(rdpPcap* pcap); - FREERDP_API BOOL pcap_add_record(rdpPcap* pcap, void* data, UINT32 length); + FREERDP_API BOOL pcap_add_record(rdpPcap* pcap, const void* data, UINT32 length); FREERDP_API BOOL pcap_has_next_record(rdpPcap* pcap); FREERDP_API BOOL pcap_get_next_record(rdpPcap* pcap, pcap_record* record); FREERDP_API BOOL pcap_get_next_record_header(rdpPcap* pcap, pcap_record* record); 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/codec/progressive.c b/libfreerdp/codec/progressive.c index d67b11fd2..6c5f7eecd 100644 --- a/libfreerdp/codec/progressive.c +++ b/libfreerdp/codec/progressive.c @@ -2510,7 +2510,7 @@ int progressive_compress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcData, rects = (RFX_RECT*)Stream_Buffer(progressive->rects); if (invalidRegion) { - RECTANGLE_16* r = region16_rects(invalidRegion, NULL); + const RECTANGLE_16* r = region16_rects(invalidRegion, NULL); for (x = 0; x < numRects; x++) { rects[x].x = r[x].left; diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index f05cb1e38..1bcba6ec1 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -415,9 +415,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)) diff --git a/libfreerdp/utils/pcap.c b/libfreerdp/utils/pcap.c index 6f6ed258a..923391023 100644 --- a/libfreerdp/utils/pcap.c +++ b/libfreerdp/utils/pcap.c @@ -95,10 +95,10 @@ static BOOL pcap_read_record(rdpPcap* pcap, pcap_record* record) static BOOL pcap_write_record(rdpPcap* pcap, pcap_record* record) { return pcap_write_record_header(pcap, &record->header) && - (fwrite(record->data, record->length, 1, pcap->fp) == 1); + (fwrite(record->cdata, record->length, 1, pcap->fp) == 1); } -BOOL pcap_add_record(rdpPcap* pcap, void* data, UINT32 length) +BOOL pcap_add_record(rdpPcap* pcap, const void* data, UINT32 length) { pcap_record* record; struct timeval tp; @@ -126,7 +126,7 @@ BOOL pcap_add_record(rdpPcap* pcap, void* data, UINT32 length) if (pcap->record == NULL) pcap->record = record; - record->data = data; + record->cdata = data; record->length = length; record->header.incl_len = length; record->header.orig_len = length;