Merge pull request #5547 from akallabeth/color_convert_fix

Fix #5543: 16 bit color to 32bit color conversion.
This commit is contained in:
Martin Fleisz 2019-09-02 14:34:59 +02:00 committed by GitHub
commit 473806a0b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 135 additions and 25 deletions

View File

@ -365,13 +365,25 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
/* 16bpp formats */
case PIXEL_FORMAT_RGB16:
if (_r)
*_r = (BYTE)(((color >> 11) & 0x1F) << 3);
{
const UINT32 c = (color >> 11) & 0x1F;
const UINT32 val = (c << 3) + c / 4;
*_r = (BYTE) (val > 255 ? 255 : val);
}
if (_g)
*_g = (BYTE)(((color >> 5) & 0x3F) << 2);
{
const UINT32 c = (color >> 5) & 0x3F;
const UINT32 val = (c << 2) + c / 4 / 2;
*_g = (BYTE) (val > 255 ? 255 : val);
}
if (_b)
*_b = (BYTE)((color & 0x1F) << 3);
{
const UINT32 c = (color) & 0x1F;
const UINT32 val = (c << 3) + c / 4;
*_b = (BYTE) (val > 255 ? 255 : val);
}
if (_a)
*_a = 0xFF;
@ -379,29 +391,53 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
break;
case PIXEL_FORMAT_BGR16:
if (_b)
*_b = (BYTE)(((color >> 11) & 0x1F) << 3);
if (_r)
{
const UINT32 c = (color) & 0x1F;
const UINT32 val = (c << 3) + c / 4;
*_r = (BYTE) (val > 255 ? 255 : val);
}
if (_g)
*_g = (BYTE)(((color >> 5) & 0x3F) << 2);
{
const UINT32 c = (color >> 5) & 0x3F;
const UINT32 val = (c << 2) + c / 4 / 2;
*_g = (BYTE) (val > 255 ? 255 : val);
}
if (_r)
*_r = (BYTE)((color & 0x1F) << 3);
if (_b)
{
const UINT32 c = (color >> 11) & 0x1F;
const UINT32 val = (c << 3) + c / 4;
*_b = (BYTE) (val > 255 ? 255 : val);
}
if (_a)
*_a = 0xFF;
break;
case PIXEL_FORMAT_ARGB15:
case PIXEL_FORMAT_ARGB15:
if (_r)
*_r = (BYTE)(((color >> 10) & 0x1F) << 3);
{
const UINT32 c = (color >> 10) & 0x1F;
const UINT32 val = (c << 3) + c / 4;
*_r = (BYTE) (val > 255 ? 255 : val);
}
if (_g)
*_g = (BYTE)(((color >> 5) & 0x1F) << 3);
{
const UINT32 c = (color >> 5) & 0x1F;
const UINT32 val = (c << 3) + c / 4;
*_g = (BYTE) (val > 255 ? 255 : val);
}
if (_b)
*_b = (BYTE)((color & 0x1F) << 3);
{
const UINT32 c = (color) & 0x1F;
const UINT32 val = (c << 3) + c / 4;
*_b = (BYTE) (val > 255 ? 255 : val);
}
if (_a)
*_a = color & 0x8000 ? 0xFF : 0x00;
@ -409,14 +445,26 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
break;
case PIXEL_FORMAT_ABGR15:
if (_b)
*_b = (BYTE)(((color >> 10) & 0x1F) << 3);
if (_r)
{
const UINT32 c = (color) & 0x1F;
const UINT32 val = (c << 3) + c / 4;
*_r = (BYTE) (val > 255 ? 255 : val);
}
if (_g)
*_g = (BYTE)(((color >> 5) & 0x1F) << 3);
{
const UINT32 c = (color >> 5) & 0x1F;
const UINT32 val = (c << 3) + c / 4;
*_g = (BYTE) (val > 255 ? 255 : val);
}
if (_r)
*_r = (BYTE)((color & 0x1F) << 3);
if (_b)
{
const UINT32 c = (color >> 10) & 0x1F;
const UINT32 val = (c << 3) + c / 4;
*_b = (BYTE) (val > 255 ? 255 : val);
}
if (_a)
*_a = color & 0x8000 ? 0xFF : 0x00;
@ -426,13 +474,25 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
/* 15bpp formats */
case PIXEL_FORMAT_RGB15:
if (_r)
*_r = (BYTE)(((color >> 10) & 0x1F) << 3);
{
const UINT32 c = (color >> 10) & 0x1F;
const UINT32 val = (c << 3) + c / 4;
*_r = (BYTE) (val > 255 ? 255 : val);
}
if (_g)
*_g = (BYTE)(((color >> 5) & 0x1F) << 3);
{
const UINT32 c = (color >> 5) & 0x1F;
const UINT32 val = (c << 3) + c / 4;
*_g = (BYTE) (val > 255 ? 255 : val);
}
if (_b)
*_b = (BYTE)((color & 0x1F) << 3);
{
const UINT32 c = (color) & 0x1F;
const UINT32 val = (c << 3) + c / 4;
*_b = (BYTE) (val > 255 ? 255 : val);
}
if (_a)
*_a = 0xFF;
@ -440,14 +500,26 @@ static INLINE void SplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g,
break;
case PIXEL_FORMAT_BGR15:
if (_b)
*_b = (BYTE)(((color >> 10) & 0x1F) << 3);
if (_r)
{
const UINT32 c = (color) & 0x1F;
const UINT32 val = (c << 3) + c / 4;
*_r = (BYTE) (val > 255 ? 255 : val);
}
if (_g)
*_g = (BYTE)(((color >> 5) & 0x1F) << 3);
{
const UINT32 c = (color >> 5) & 0x1F;
const UINT32 val = (c << 3) + c / 4;
*_g = (BYTE) (val > 255 ? 255 : val);
}
if (_r)
*_r = (BYTE)((color & 0x1F) << 3);
if (_b)
{
const UINT32 c = (color >> 10) & 0x1F;
const UINT32 val = (c << 3) + c / 4;
*_b = (BYTE) (val > 255 ? 255 : val);
}
if (_a)
*_a = 0xFF;

View File

@ -152,6 +152,41 @@ fail:
PROFILER_FREE(profiler_decomp);
return rc;
}
static BOOL TestColorConversion(void)
{
const UINT32 formats[] = {
PIXEL_FORMAT_RGB15,
PIXEL_FORMAT_BGR15,
PIXEL_FORMAT_ABGR15,
PIXEL_FORMAT_ARGB15,
PIXEL_FORMAT_BGR16,
PIXEL_FORMAT_RGB16
};
UINT32 x;
/* Check color conversion 15/16 -> 32bit maps to proper values */
for (x=0; x<ARRAYSIZE(formats); x++)
{
const UINT32 dstFormat = PIXEL_FORMAT_RGBA32;
const UINT32 format = formats[x];
const UINT32 colorLow = FreeRDPGetColor(format, 0, 0, 0, 255);
const UINT32 colorHigh = FreeRDPGetColor(format, 255, 255, 255, 255);
const UINT32 colorLow32 = FreeRDPConvertColor(colorLow, format, dstFormat, NULL);
const UINT32 colorHigh32 = FreeRDPConvertColor(colorHigh, format, dstFormat, NULL);
BYTE r, g, b, a;
SplitColor(colorLow32, dstFormat, &r, &g, &b, &a, NULL);
if ((r != 0) || (g != 0) || (b != 0))
return FALSE;
SplitColor(colorHigh32, dstFormat, &r, &g, &b, &a, NULL);
if ((r != 255) || (g != 255) || (b != 255))
return FALSE;
}
return TRUE;
}
int TestFreeRDPCodecInterleaved(int argc, char* argv[])
{
BITMAP_INTERLEAVED_CONTEXT* encoder, * decoder;
@ -173,6 +208,9 @@ int TestFreeRDPCodecInterleaved(int argc, char* argv[])
if (!run_encode_decode(15, encoder, decoder))
goto fail;
if (!TestColorConversion())
goto fail;
rc = 0;
fail:
bitmap_interleaved_context_free(encoder);