Vincent Povirk : windowscodecs: Generate a palette for color-keyed grayscale PNG's.
Alexandre Julliard
julliard at winehq.org
Fri Sep 8 15:03:21 CDT 2017
Module: wine
Branch: master
Commit: 66b126b67539d23c61645e1dcff2191d42fc0249
URL: http://source.winehq.org/git/wine.git/?a=commit;h=66b126b67539d23c61645e1dcff2191d42fc0249
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Thu Sep 7 15:52:05 2017 -0500
windowscodecs: Generate a palette for color-keyed grayscale PNG's.
Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
configure | 16 -----
configure.ac | 4 +-
dlls/windowscodecs/pngformat.c | 124 +++++++++++++++++++----------------
dlls/windowscodecs/tests/pngformat.c | 8 +--
include/config.h.in | 3 -
5 files changed, 73 insertions(+), 82 deletions(-)
diff --git a/configure b/configure
index 5138198..47a41cd 100755
--- a/configure
+++ b/configure
@@ -13890,23 +13890,7 @@ cat >>confdefs.h <<_ACEOF
#define SONAME_LIBPNG "$ac_cv_lib_soname_png"
_ACEOF
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <png.h>
-int
-main ()
-{
-typeof(png_set_expand_gray_1_2_4_to_8) *p
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-$as_echo "#define HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8 1" >>confdefs.h
-
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
else
PNG_CFLAGS=""
diff --git a/configure.ac b/configure.ac
index a2ef1b4..cd5a50b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1647,9 +1647,7 @@ then
[AC_CHECK_HEADERS([png.h])
if test "$ac_cv_header_png_h" = "yes"
then
- WINE_CHECK_SONAME(png,png_create_read_struct,
- [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <png.h>]],[[typeof(png_set_expand_gray_1_2_4_to_8) *p]])],
- [AC_DEFINE(HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8,1,[Define to 1 if libpng has the png_set_expand_gray_1_2_4_to_8 function.])])],
+ WINE_CHECK_SONAME(png,png_create_read_struct,,
[PNG_CFLAGS=""],[$PNG_LIBS -lm -lz],[[libpng[[0-9]]*]])
else
PNG_CFLAGS=""
diff --git a/dlls/windowscodecs/pngformat.c b/dlls/windowscodecs/pngformat.c
index b4fd346..9e837ca 100644
--- a/dlls/windowscodecs/pngformat.c
+++ b/dlls/windowscodecs/pngformat.c
@@ -319,11 +319,6 @@ MAKE_FUNCPTR(png_get_tRNS);
MAKE_FUNCPTR(png_set_bgr);
MAKE_FUNCPTR(png_set_crc_action);
MAKE_FUNCPTR(png_set_error_fn);
-#ifdef HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8
-MAKE_FUNCPTR(png_set_expand_gray_1_2_4_to_8);
-#else
-MAKE_FUNCPTR(png_set_gray_1_2_4_to_8);
-#endif
MAKE_FUNCPTR(png_set_filler);
MAKE_FUNCPTR(png_set_filter);
MAKE_FUNCPTR(png_set_gray_to_rgb);
@@ -388,11 +383,6 @@ static void *load_libpng(void)
LOAD_FUNCPTR(png_set_bgr);
LOAD_FUNCPTR(png_set_crc_action);
LOAD_FUNCPTR(png_set_error_fn);
-#ifdef HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8
- LOAD_FUNCPTR(png_set_expand_gray_1_2_4_to_8);
-#else
- LOAD_FUNCPTR(png_set_gray_1_2_4_to_8);
-#endif
LOAD_FUNCPTR(png_set_filler);
LOAD_FUNCPTR(png_set_filter);
LOAD_FUNCPTR(png_set_gray_to_rgb);
@@ -651,43 +641,18 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
/* check for color-keyed alpha */
transparency = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans, &num_trans, &trans_values);
- if (transparency && color_type != PNG_COLOR_TYPE_PALETTE)
+ if (transparency && (color_type == PNG_COLOR_TYPE_RGB ||
+ (color_type == PNG_COLOR_TYPE_GRAY && bit_depth == 16)))
{
/* expand to RGBA */
if (color_type == PNG_COLOR_TYPE_GRAY)
- {
- if (bit_depth < 8)
- {
-#ifdef HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8
- ppng_set_expand_gray_1_2_4_to_8(This->png_ptr);
-#else
- ppng_set_gray_1_2_4_to_8(This->png_ptr);
-#endif
- bit_depth = 8;
- }
ppng_set_gray_to_rgb(This->png_ptr);
- }
ppng_set_tRNS_to_alpha(This->png_ptr);
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
}
switch (color_type)
{
- case PNG_COLOR_TYPE_GRAY:
- This->bpp = bit_depth;
- switch (bit_depth)
- {
- case 1: This->format = &GUID_WICPixelFormatBlackWhite; break;
- case 2: This->format = &GUID_WICPixelFormat2bppGray; break;
- case 4: This->format = &GUID_WICPixelFormat4bppGray; break;
- case 8: This->format = &GUID_WICPixelFormat8bppGray; break;
- case 16: This->format = &GUID_WICPixelFormat16bppGray; break;
- default:
- ERR("invalid grayscale bit depth: %i\n", bit_depth);
- hr = E_FAIL;
- goto end;
- }
- break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
/* WIC does not support grayscale alpha formats so use RGBA */
ppng_set_gray_to_rgb(This->png_ptr);
@@ -707,6 +672,25 @@ static HRESULT WINAPI PngDecoder_Initialize(IWICBitmapDecoder *iface, IStream *p
goto end;
}
break;
+ case PNG_COLOR_TYPE_GRAY:
+ This->bpp = bit_depth;
+ if (!transparency)
+ {
+ switch (bit_depth)
+ {
+ case 1: This->format = &GUID_WICPixelFormatBlackWhite; break;
+ case 2: This->format = &GUID_WICPixelFormat2bppGray; break;
+ case 4: This->format = &GUID_WICPixelFormat4bppGray; break;
+ case 8: This->format = &GUID_WICPixelFormat8bppGray; break;
+ case 16: This->format = &GUID_WICPixelFormat16bppGray; break;
+ default:
+ ERR("invalid grayscale bit depth: %i\n", bit_depth);
+ hr = E_FAIL;
+ goto end;
+ }
+ break;
+ }
+ /* else fall through */
case PNG_COLOR_TYPE_PALETTE:
This->bpp = bit_depth;
switch (bit_depth)
@@ -1034,7 +1018,7 @@ static HRESULT WINAPI PngDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface,
IWICPalette *pIPalette)
{
PngDecoder *This = impl_from_IWICBitmapFrameDecode(iface);
- png_uint_32 ret;
+ png_uint_32 ret, color_type, bit_depth;
png_colorp png_palette;
int num_palette;
WICColor palette[256];
@@ -1048,30 +1032,58 @@ static HRESULT WINAPI PngDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface,
EnterCriticalSection(&This->lock);
- ret = ppng_get_PLTE(This->png_ptr, This->info_ptr, &png_palette, &num_palette);
- if (!ret)
- {
- hr = WINCODEC_ERR_PALETTEUNAVAILABLE;
- goto end;
- }
+ color_type = ppng_get_color_type(This->png_ptr, This->info_ptr);
+ bit_depth = ppng_get_bit_depth(This->png_ptr, This->info_ptr);
- if (num_palette > 256)
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
{
- ERR("palette has %i colors?!\n", num_palette);
- hr = E_FAIL;
- goto end;
+ ret = ppng_get_PLTE(This->png_ptr, This->info_ptr, &png_palette, &num_palette);
+ if (!ret)
+ {
+ hr = WINCODEC_ERR_PALETTEUNAVAILABLE;
+ goto end;
+ }
+
+ if (num_palette > 256)
+ {
+ ERR("palette has %i colors?!\n", num_palette);
+ hr = E_FAIL;
+ goto end;
+ }
+
+ ret = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans_alpha, &num_trans, &trans_values);
+ if (!ret) num_trans = 0;
+
+ for (i=0; i<num_palette; i++)
+ {
+ BYTE alpha = (i < num_trans) ? trans_alpha[i] : 0xff;
+ palette[i] = (alpha << 24 |
+ png_palette[i].red << 16|
+ png_palette[i].green << 8|
+ png_palette[i].blue);
+ }
}
+ else if (color_type == PNG_COLOR_TYPE_GRAY) {
+ ret = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans_alpha, &num_trans, &trans_values);
- ret = ppng_get_tRNS(This->png_ptr, This->info_ptr, &trans_alpha, &num_trans, &trans_values);
- if (!ret) num_trans = 0;
+ if (!ret)
+ {
+ hr = WINCODEC_ERR_PALETTEUNAVAILABLE;
+ goto end;
+ }
- for (i=0; i<num_palette; i++)
+ num_palette = 1 << bit_depth;
+
+ for (i=0; i<num_palette; i++)
+ {
+ BYTE alpha = (i == trans_values[0].gray) ? 0 : 0xff;
+ BYTE val = i * 255 / (num_palette - 1);
+ palette[i] = (alpha << 24 | val << 16 | val << 8 | val);
+ }
+ }
+ else
{
- BYTE alpha = (i < num_trans) ? trans_alpha[i] : 0xff;
- palette[i] = (alpha << 24 |
- png_palette[i].red << 16|
- png_palette[i].green << 8|
- png_palette[i].blue);
+ hr = WINCODEC_ERR_PALETTEUNAVAILABLE;
}
end:
diff --git a/dlls/windowscodecs/tests/pngformat.c b/dlls/windowscodecs/tests/pngformat.c
index f34711d..4b84cce 100644
--- a/dlls/windowscodecs/tests/pngformat.c
+++ b/dlls/windowscodecs/tests/pngformat.c
@@ -674,10 +674,10 @@ static void test_color_formats(void)
{ 24, 2, NULL, NULL, NULL },
{ 32, 2, NULL, NULL, NULL },
/* 0 - PNG_COLOR_TYPE_GRAY */
- { 1, 0, &GUID_WICPixelFormatBlackWhite, &GUID_WICPixelFormatBlackWhite, &GUID_WICPixelFormat1bppIndexed, TRUE },
- { 2, 0, &GUID_WICPixelFormat2bppGray, &GUID_WICPixelFormat2bppGray, &GUID_WICPixelFormat2bppIndexed, TRUE },
- { 4, 0, &GUID_WICPixelFormat4bppGray, &GUID_WICPixelFormat4bppGray, &GUID_WICPixelFormat4bppIndexed, TRUE },
- { 8, 0, &GUID_WICPixelFormat8bppGray, &GUID_WICPixelFormat8bppGray, &GUID_WICPixelFormat8bppIndexed, TRUE },
+ { 1, 0, &GUID_WICPixelFormatBlackWhite, &GUID_WICPixelFormatBlackWhite, &GUID_WICPixelFormat1bppIndexed },
+ { 2, 0, &GUID_WICPixelFormat2bppGray, &GUID_WICPixelFormat2bppGray, &GUID_WICPixelFormat2bppIndexed },
+ { 4, 0, &GUID_WICPixelFormat4bppGray, &GUID_WICPixelFormat4bppGray, &GUID_WICPixelFormat4bppIndexed },
+ { 8, 0, &GUID_WICPixelFormat8bppGray, &GUID_WICPixelFormat8bppGray, &GUID_WICPixelFormat8bppIndexed },
{ 16, 0, &GUID_WICPixelFormat16bppGray, &GUID_WICPixelFormat16bppGray, &GUID_WICPixelFormat64bppRGBA },
{ 24, 0, NULL, NULL, NULL },
{ 32, 0, NULL, NULL, NULL },
diff --git a/include/config.h.in b/include/config.h.in
index b0b5925..dd7a3a2 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -711,9 +711,6 @@
/* Define to 1 if you have the <png.h> header file. */
#undef HAVE_PNG_H
-/* Define to 1 if libpng has the png_set_expand_gray_1_2_4_to_8 function. */
-#undef HAVE_PNG_SET_EXPAND_GRAY_1_2_4_TO_8
-
/* Define to 1 if you have the `poll' function. */
#undef HAVE_POLL
More information about the wine-cvs
mailing list