Module: wine Branch: master Commit: 66b126b67539d23c61645e1dcff2191d42fc0249 URL: http://source.winehq.org/git/wine.git/?a=commit;h=66b126b67539d23c61645e1dcf...
Author: Vincent Povirk vincent@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@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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