Added patch to force conversion of 8 bpp grayscale PNG images to 32 bpp BGRA.

This commit is contained in:
Sebastian Lackner 2016-06-04 03:04:10 +02:00
parent 953ae16ca9
commit c2158ca405
7 changed files with 394 additions and 0 deletions

View File

@ -0,0 +1,93 @@
From e7ff152bab130c0775500e50b640b7e95bc56495 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Fri, 3 Jun 2016 13:25:06 +0800
Subject: windowscodecs/tests: Add a test for loading PNG grayscale images.
---
dlls/windowscodecs/tests/pngformat.c | 58 +++++++++++++++++++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/dlls/windowscodecs/tests/pngformat.c b/dlls/windowscodecs/tests/pngformat.c
index 34cb533..296866f 100644
--- a/dlls/windowscodecs/tests/pngformat.c
+++ b/dlls/windowscodecs/tests/pngformat.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 Dmitry Timoshkov
+ * Copyright 2012,2016 Dmitry Timoshkov
* Copyright 2012 Hans Leidekker for CodeWeavers
*
* This library is free software; you can redistribute it and/or
@@ -579,6 +579,61 @@ static void test_png_palette(void)
IWICBitmapDecoder_Release(decoder);
}
+/* RGB 24 bpp 1x1 pixel PNG image */
+static const char png_1x1_data[] = {
+ 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,
+ 0x00,0x00,0x00,0x0d,'I','H','D','R',0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,0xde,
+ 0x00,0x00,0x00,0x0c,'I','D','A','T',0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,0xe7,
+ 0x00,0x00,0x00,0x00,'I','E','N','D',0xae,0x42,0x60,0x82
+};
+
+static void test_color_formats(void)
+{
+ static const struct
+ {
+ char bit_depth, color_type;
+ const GUID *format;
+ } td[] =
+ {
+ /* 2 - PNG_COLOR_TYPE_RGB */
+ { 8, 2, &GUID_WICPixelFormat24bppBGR },
+ /* 0 - PNG_COLOR_TYPE_GRAY */
+ { 1, 0, &GUID_WICPixelFormatBlackWhite },
+ { 2, 0, &GUID_WICPixelFormat2bppGray },
+ { 4, 0, &GUID_WICPixelFormat4bppGray },
+ { 8, 0, &GUID_WICPixelFormat8bppGray },
+ { 16, 0, &GUID_WICPixelFormat16bppGray },
+ };
+ char buf[sizeof(png_1x1_data)];
+ HRESULT hr;
+ IWICBitmapDecoder *decoder;
+ IWICBitmapFrameDecode *frame;
+ GUID format;
+ int i;
+
+ for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
+ {
+ memcpy(buf, png_1x1_data, sizeof(png_1x1_data));
+ buf[24] = td[i].bit_depth;
+ buf[25] = td[i].color_type;
+
+ decoder = create_decoder(buf, sizeof(buf));
+ ok(decoder != NULL, "Failed to load PNG image data\n");
+ if (!decoder) continue;
+
+ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
+ ok(hr == S_OK, "GetFrame error %#x\n", hr);
+
+ hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
+ ok(hr == S_OK, "GetPixelFormat error %#x\n", hr);
+ ok(IsEqualGUID(&format, td[i].format),
+ "expected %s, got %s\n", wine_dbgstr_guid(td[i].format), wine_dbgstr_guid(&format));
+
+ IWICBitmapFrameDecode_Release(frame);
+ IWICBitmapDecoder_Release(decoder);
+ }
+}
+
START_TEST(pngformat)
{
HRESULT hr;
@@ -591,6 +646,7 @@ START_TEST(pngformat)
test_color_contexts();
test_png_palette();
+ test_color_formats();
IWICImagingFactory_Release(factory);
CoUninitialize();
--
2.8.0

View File

@ -0,0 +1,97 @@
From 1184612f4eca0f6a09150a42f8b56dce76ffd6b1 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Fri, 3 Jun 2016 13:20:14 +0800
Subject: gdiplus/tests: Add a test for loading PNG grayscale images.
---
dlls/gdiplus/tests/image.c | 60 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 59 insertions(+), 1 deletion(-)
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index 6a51714..0c28c9e 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -2,7 +2,7 @@
* Unit test suite for images
*
* Copyright (C) 2007 Google (Evan Stade)
- * Copyright (C) 2012 Dmitry Timoshkov
+ * Copyright (C) 2012,2016 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -4725,6 +4725,63 @@ static void test_createeffect(void)
}
}
+/* RGB 24 bpp 1x1 pixel PNG image */
+static const char png_1x1_data[] = {
+ 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,
+ 0x00,0x00,0x00,0x0d,'I','H','D','R',0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,0xde,
+ 0x00,0x00,0x00,0x0c,'I','D','A','T',0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,0xe7,
+ 0x00,0x00,0x00,0x00,'I','E','N','D',0xae,0x42,0x60,0x82
+};
+
+static void test_png_color_formats(void)
+{
+ static const struct
+ {
+ char bit_depth, color_type;
+ PixelFormat format;
+ } td[] =
+ {
+ /* 2 - PNG_COLOR_TYPE_RGB */
+ { 8, 2, PixelFormat24bppRGB },
+ /* 0 - PNG_COLOR_TYPE_GRAY */
+ { 1, 0, PixelFormat1bppIndexed },
+ { 2, 0, PixelFormat32bppARGB },
+ { 4, 0, PixelFormat32bppARGB },
+ { 8, 0, PixelFormat32bppARGB },
+ { 16, 0, PixelFormat32bppARGB },
+ };
+ BYTE buf[sizeof(png_1x1_data)];
+ GpStatus status;
+ GpImage *image;
+ ImageType type;
+ PixelFormat format;
+ int i;
+
+ for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
+ {
+ memcpy(buf, png_1x1_data, sizeof(png_1x1_data));
+ buf[24] = td[i].bit_depth;
+ buf[25] = td[i].color_type;
+
+ image = load_image(buf, sizeof(buf));
+ ok(image != NULL, "%d: failed to load image data\n", i);
+ if (!image) continue;
+
+ status = GdipGetImageType(image, &type);
+ ok(status == Ok, "%u: GdipGetImageType error %d\n", i, status);
+ ok(type == ImageTypeBitmap, "%d: wrong image type %d\n", i, type);
+
+ status = GdipGetImagePixelFormat(image, &format);
+ expect(Ok, status);
+todo_wine_if(td[i].bit_depth == 8 && td[i].color_type == 0)
+ ok(format == td[i].format ||
+ broken(td[i].bit_depth == 1 && td[i].color_type == 0 && format == PixelFormat32bppARGB), /* XP */
+ "%d: expected %#x, got %#x\n", i, td[i].format, format);
+
+ GdipDisposeImage(image);
+ }
+}
+
START_TEST(image)
{
struct GdiplusStartupInput gdiplusStartupInput;
@@ -4737,6 +4794,7 @@ START_TEST(image)
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
+ test_png_color_formats();
test_supported_encoders();
test_CloneBitmapArea();
test_ARGB_conversion();
--
2.8.0

View File

@ -0,0 +1,69 @@
From c833d4e659d164dd69842d0c4deb39427a600fab Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Fri, 3 Jun 2016 13:47:06 +0800
Subject: gdiplus: Force conversion of 8 bpp grayscale PNG images to 32 bpp
BGRA.
---
dlls/gdiplus/image.c | 32 +++++++++++++++++++++++++++++++-
dlls/gdiplus/tests/image.c | 1 -
2 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index d1a5593..a8d8f2d 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -3951,7 +3951,37 @@ static GpStatus decode_image_jpeg(IStream* stream, GpImage **image)
static GpStatus decode_image_png(IStream* stream, GpImage **image)
{
- return decode_image_wic(stream, &GUID_ContainerFormatPng, png_metadata_reader, image);
+ IWICBitmapDecoder *decoder;
+ IWICBitmapFrameDecode *frame;
+ GpStatus status;
+ HRESULT hr;
+ GUID format;
+ BOOL force_conversion = FALSE;
+
+ status = initialize_decoder_wic(stream, &GUID_ContainerFormatPng, &decoder);
+ if (status != Ok)
+ return status;
+
+ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
+ if (hr == S_OK)
+ {
+ hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
+ if (hr == S_OK)
+ {
+ if (IsEqualGUID(&format, &GUID_WICPixelFormat8bppGray))
+ force_conversion = TRUE;
+ status = decode_frame_wic(decoder, force_conversion, 0, png_metadata_reader, image);
+ }
+ else
+ status = hresult_to_status(hr);
+
+ IWICBitmapFrameDecode_Release(frame);
+ }
+ else
+ status = hresult_to_status(hr);
+
+ IWICBitmapDecoder_Release(decoder);
+ return status;
}
static GpStatus decode_image_gif(IStream* stream, GpImage **image)
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index 0c28c9e..b4682f7 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -4773,7 +4773,6 @@ static void test_png_color_formats(void)
status = GdipGetImagePixelFormat(image, &format);
expect(Ok, status);
-todo_wine_if(td[i].bit_depth == 8 && td[i].color_type == 0)
ok(format == td[i].format ||
broken(td[i].bit_depth == 1 && td[i].color_type == 0 && format == PixelFormat32bppARGB), /* XP */
"%d: expected %#x, got %#x\n", i, td[i].format, format);
--
2.8.0

View File

@ -0,0 +1,62 @@
From faf32d6f405bb427714ea2b3767981df1a8c2f65 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Fri, 3 Jun 2016 18:49:57 +0800
Subject: gdiplus/tests: Add a test for image flags to PNG grayscale image
tests.
---
dlls/gdiplus/tests/image.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index b4682f7..10b0477 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -4739,22 +4739,24 @@ static void test_png_color_formats(void)
{
char bit_depth, color_type;
PixelFormat format;
+ UINT flags;
} td[] =
{
/* 2 - PNG_COLOR_TYPE_RGB */
- { 8, 2, PixelFormat24bppRGB },
+ { 8, 2, PixelFormat24bppRGB, ImageFlagsColorSpaceRGB },
/* 0 - PNG_COLOR_TYPE_GRAY */
- { 1, 0, PixelFormat1bppIndexed },
- { 2, 0, PixelFormat32bppARGB },
- { 4, 0, PixelFormat32bppARGB },
- { 8, 0, PixelFormat32bppARGB },
- { 16, 0, PixelFormat32bppARGB },
+ { 1, 0, PixelFormat1bppIndexed, ImageFlagsColorSpaceRGB },
+ { 2, 0, PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY },
+ { 4, 0, PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY },
+ { 8, 0, PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY },
+ { 16, 0, PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY },
};
BYTE buf[sizeof(png_1x1_data)];
GpStatus status;
GpImage *image;
ImageType type;
PixelFormat format;
+ UINT flags;
int i;
for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
@@ -4777,6 +4779,13 @@ static void test_png_color_formats(void)
broken(td[i].bit_depth == 1 && td[i].color_type == 0 && format == PixelFormat32bppARGB), /* XP */
"%d: expected %#x, got %#x\n", i, td[i].format, format);
+ status = GdipGetImageFlags(image, &flags);
+ expect(Ok, status);
+todo_wine_if(td[i].bit_depth > 1 && td[i].color_type == 0)
+ ok((flags & td[i].flags) == td[i].flags ||
+ broken(td[i].bit_depth == 1 && td[i].color_type == 0 && (flags & ImageFlagsColorSpaceGRAY)), /* XP */
+ "%d: expected %#x, got %#x\n", i, td[i].flags, flags);
+
GdipDisposeImage(image);
}
}
--
2.8.0

View File

@ -0,0 +1,45 @@
From c0115ba521b2be3e061ffbe022ba4c10c78c0706 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Fri, 3 Jun 2016 18:39:37 +0800
Subject: gdiplus: Set correct color space flags for grayscale images.
---
dlls/gdiplus/image.c | 9 ++++++++-
dlls/gdiplus/tests/image.c | 1 -
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index a8d8f2d..38af3d5 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -3709,7 +3709,14 @@ static GpStatus decode_frame_wic(IWICBitmapDecoder *decoder, BOOL force_conversi
if (status == Ok)
{
/* Native GDI+ used to be smarter, but since Win7 it just sets these flags. */
- bitmap->image.flags |= ImageFlagsReadOnly|ImageFlagsHasRealPixelSize|ImageFlagsHasRealDPI|ImageFlagsColorSpaceRGB;
+ bitmap->image.flags |= ImageFlagsReadOnly|ImageFlagsHasRealPixelSize|ImageFlagsHasRealDPI;
+ if (IsEqualGUID(&wic_format, &GUID_WICPixelFormat2bppGray) ||
+ IsEqualGUID(&wic_format, &GUID_WICPixelFormat4bppGray) ||
+ IsEqualGUID(&wic_format, &GUID_WICPixelFormat8bppGray) ||
+ IsEqualGUID(&wic_format, &GUID_WICPixelFormat16bppGray))
+ bitmap->image.flags |= ImageFlagsColorSpaceGRAY;
+ else
+ bitmap->image.flags |= ImageFlagsColorSpaceRGB;
bitmap->image.frame_count = frame_count;
bitmap->image.current_frame = active_frame;
bitmap->image.decoder = decoder;
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index 10b0477..3e64c3a 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -4781,7 +4781,6 @@ static void test_png_color_formats(void)
status = GdipGetImageFlags(image, &flags);
expect(Ok, status);
-todo_wine_if(td[i].bit_depth > 1 && td[i].color_type == 0)
ok((flags & td[i].flags) == td[i].flags ||
broken(td[i].bit_depth == 1 && td[i].color_type == 0 && (flags & ImageFlagsColorSpaceGRAY)), /* XP */
"%d: expected %#x, got %#x\n", i, td[i].flags, flags);
--
2.8.0

View File

@ -0,0 +1 @@
Fixes: [38622] Force conversion of 8 bpp grayscale PNG images to 32 bpp BGRA

View File

@ -153,6 +153,7 @@ patch_enable_all ()
enable_gdi32_Path_Metafile="$1"
enable_gdi32_Symbol_Truetype_Font="$1"
enable_gdiplus_GdipCreateMetafileFromStream="$1"
enable_gdiplus_Grayscale_PNG="$1"
enable_hal_KeQueryPerformanceCounter="$1"
enable_hid_HidP_TranslateUsagesToI8042ScanCodes="$1"
enable_hnetcfg_INetFwAuthorizedApplication="$1"
@ -639,6 +640,9 @@ patch_enable ()
gdiplus-GdipCreateMetafileFromStream)
enable_gdiplus_GdipCreateMetafileFromStream="$2"
;;
gdiplus-Grayscale_PNG)
enable_gdiplus_Grayscale_PNG="$2"
;;
hal-KeQueryPerformanceCounter)
enable_hal_KeQueryPerformanceCounter="$2"
;;
@ -3833,6 +3837,29 @@ if test "$enable_gdiplus_GdipCreateMetafileFromStream" -eq 1; then
) >> "$patchlist"
fi
# Patchset gdiplus-Grayscale_PNG
# |
# | This patchset fixes the following Wine bugs:
# | * [#38622] Force conversion of 8 bpp grayscale PNG images to 32 bpp BGRA
# |
# | Modified files:
# | * dlls/gdiplus/image.c, dlls/gdiplus/tests/image.c, dlls/windowscodecs/tests/pngformat.c
# |
if test "$enable_gdiplus_Grayscale_PNG" -eq 1; then
patch_apply gdiplus-Grayscale_PNG/0001-windowscodecs-tests-Add-a-test-for-loading-PNG-grays.patch
patch_apply gdiplus-Grayscale_PNG/0002-gdiplus-tests-Add-a-test-for-loading-PNG-grayscale-i.patch
patch_apply gdiplus-Grayscale_PNG/0003-gdiplus-Force-conversion-of-8-bpp-grayscale-PNG-imag.patch
patch_apply gdiplus-Grayscale_PNG/0004-gdiplus-tests-Add-a-test-for-image-flags-to-PNG-gray.patch
patch_apply gdiplus-Grayscale_PNG/0005-gdiplus-Set-correct-color-space-flags-for-grayscale-.patch
(
echo '+ { "Dmitry Timoshkov", "windowscodecs/tests: Add a test for loading PNG grayscale images.", 1 },';
echo '+ { "Dmitry Timoshkov", "gdiplus/tests: Add a test for loading PNG grayscale images.", 1 },';
echo '+ { "Dmitry Timoshkov", "gdiplus: Force conversion of 8 bpp grayscale PNG images to 32 bpp BGRA.", 1 },';
echo '+ { "Dmitry Timoshkov", "gdiplus/tests: Add a test for image flags to PNG grayscale image tests.", 1 },';
echo '+ { "Dmitry Timoshkov", "gdiplus: Set correct color space flags for grayscale images.", 1 },';
) >> "$patchlist"
fi
# Patchset hal-KeQueryPerformanceCounter
# |
# | This patchset fixes the following Wine bugs: