Merge pull request #6723 from akallabeth/color_fidelity_fix

Color fidelity fix
This commit is contained in:
Martin Fleisz 2021-01-19 14:14:47 +01:00 committed by GitHub
commit bd7b43a7d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 131 additions and 47 deletions

View 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,

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View 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))

View File

@ -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;