diff --git a/ANNOUNCE b/ANNOUNCE index 78a83b585..054ad26bb 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,5 +1,5 @@ -Libpng 1.4.1alpha02 - November 28, 2009 +Libpng 1.4.1alpha02 - November 29, 2009 This is not intended to be a public release. It will be replaced within a few weeks by a public version or by another test version. @@ -29,13 +29,19 @@ Changes since the last public release (1.4.0beta107): version 1.4.1alpha01 [November 27, 2009] Based on 1.4.0beta107 -version 1.4.1alpha02 [November 28, 2009] +version 1.4.1alpha02 [November 29, 2009] Restored premultiplied alpha feature from version 1.4.0beta105. Added "double gamma" to parameters for png_set_premultiply_alpha(). Added "float gamma_premultiply" member to the png_struct. Moved PNG_DIVIDE_BY_255, PNG_8_BIT_PREMULTIPLY(), etc., from png.h to pngpriv.h Updated documentation about png_set_premultiply_alpha(). + Always expand pixels to 16-bit samples when premultiplying. + In pngconf.h, require PNG_GAMMA_SUPPORTED to be defined when defining + PNG_READ_PREMULTIPLY_ALPHA_SUPPORTED + Eliminated PNG_DIVIDE_BY_255 and PNG_8_BIT_PREMULTIPLY macros + leaving only PNG_DIVIDE_BY_65535 and PNG_16_BIT_PREMULTIPLY + because we will always work with 16 bits. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/CHANGES b/CHANGES index 9798141fc..de136070c 100644 --- a/CHANGES +++ b/CHANGES @@ -2411,13 +2411,19 @@ version 1.4.0beta107 [November 27, 2009] version 1.4.1alpha01 [November 27, 2009] Based on 1.4.0beta107 -version 1.4.1alpha02 [November 28, 2009] +version 1.4.1alpha02 [November 29, 2009] Restored premultiplied alpha feature from version 1.4.0beta105. Added "double gamma" to parameters for png_set_premultiply_alpha(). Added "float gamma_premultiply" member to the png_struct. Moved PNG_DIVIDE_BY_255, PNG_8_BIT_PREMULTIPLY(), etc., from png.h to pngpriv.h Updated documentation about png_set_premultiply_alpha(). + Always expand pixels to 16-bit samples when premultiplying. + In pngconf.h, require PNG_GAMMA_SUPPORTED to be defined when defining + PNG_READ_PREMULTIPLY_ALPHA_SUPPORTED + Eliminated PNG_DIVIDE_BY_255 and PNG_8_BIT_PREMULTIPLY macros + leaving only PNG_DIVIDE_BY_65535 and PNG_16_BIT_PREMULTIPLY + because we will always work with 16 bits. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/png.h b/png.h index c4c5d24cd..bd4f19c0a 100644 --- a/png.h +++ b/png.h @@ -1,7 +1,7 @@ /* png.h - header file for PNG reference library * - * libpng version 1.4.1alpha02 - November 28, 2009 + * libpng version 1.4.1alpha02 - November 29, 2009 * Copyright (c) 1998-2009 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) @@ -11,7 +11,7 @@ * Authors and maintainers: * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger - * libpng versions 0.97, January 1998, through 1.4.1alpha02 - November 28, 2009: Glenn + * libpng versions 0.97, January 1998, through 1.4.1alpha02 - November 29, 2009: Glenn * See also "Contributing Authors", below. * * Note about libpng version numbers: @@ -164,7 +164,7 @@ * * This code is released under the libpng license. * - * libpng versions 1.2.6, August 15, 2004, through 1.4.1alpha02, November 28, 2009, are + * libpng versions 1.2.6, August 15, 2004, through 1.4.1alpha02, November 29, 2009, are * Copyright (c) 2004, 2006-2007 Glenn Randers-Pehrson, and are * distributed according to the same disclaimer and license as libpng-1.2.5 * with the following individual added to the list of Contributing Authors: @@ -340,7 +340,7 @@ /* Version information for png.h - this should match the version in png.c */ #define PNG_LIBPNG_VER_STRING "1.4.1alpha02" #define PNG_HEADER_VERSION_STRING \ - " libpng version 1.4.1alpha02 - November 28, 2009\n" + " libpng version 1.4.1alpha02 - November 29, 2009\n" #define PNG_LIBPNG_VER_SONUM 14 #define PNG_LIBPNG_VER_DLLNUM 14 @@ -1339,7 +1339,7 @@ struct png_struct_def /* New member added in libpng-1.4.1 */ #ifdef PNG_READ_PREMULTIPLY_ALPHA_SUPPORTED - float gamma_premultiply; + float gamma_premultiply PNG_DEPSTRUCT; #endif }; diff --git a/pngconf.h b/pngconf.h index 9c29604f3..463166f11 100644 --- a/pngconf.h +++ b/pngconf.h @@ -1,7 +1,7 @@ /* pngconf.h - machine configurable file for libpng * - * libpng version 1.4.1alpha02 - November 28, 2009 + * libpng version 1.4.1alpha02 - November 29, 2009 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2009 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) @@ -524,7 +524,7 @@ # define PNG_READ_INVERT_ALPHA_SUPPORTED # endif # ifndef PNG_NO_READ_PREMULTIPLY_ALPHA -# define PNG_READ_PREMULTIPLY_ALPHA_SUPPORTED +# define PNG_READ_PREMULTIPLY_ALPHA_SUPPORTED # endif # ifndef PNG_NO_READ_STRIP_ALPHA # define PNG_READ_STRIP_ALPHA_SUPPORTED @@ -861,6 +861,13 @@ # define PNG_TEXT_SUPPORTED #endif +# /* Premultiply will not work without gamma support. */ +# ifdef PNG_READ_PREMULTIPLY_ALPHA_SUPPORTED +# ifndef PNG_READ_GAMMA_SUPPORTED +# undef PNG_READ_PREMULTIPLY_ALPHA_SUPPORTED +# endif +# endif + #endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */ #ifndef PNG_NO_READ_UNKNOWN_CHUNKS diff --git a/pngrtran.c b/pngrtran.c index 32248c018..c71eafb2c 100644 --- a/pngrtran.c +++ b/pngrtran.c @@ -1,7 +1,7 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * Last changed in libpng 1.4.0 [November 28, 2009] + * Last changed in libpng 1.4.0 [November 29, 2009] * Copyright (c) 1998-2009 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) @@ -151,7 +151,7 @@ png_set_premultiply_alpha(png_structp png_ptr, double gamma) png_ptr->transformations |= (PNG_PREMULTIPLY_ALPHA | PNG_EXPAND_tRNS); png_ptr->transformations |= - PNG_EXPAND; /* This shouldn't be necessary */ + PNG_EXPAND; png_ptr->flags &= ~PNG_FLAG_ROW_INIT; /* Check for overflow */ if (gamma == 0 || gamma > 21474.83) @@ -902,8 +902,11 @@ png_init_read_transformations(png_structp png_ptr) png_ptr->transformations &= ~PNG_GAMMA; } - if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) && - png_ptr->gamma != 0.0) + if ((png_ptr->transformations & (PNG_GAMMA | +#ifdef PNG_READ_PREMULTIPLY_ALPHA_SUPPORTED + PNG_PREMULTIPLY_ALPHA | +#endif + PNG_RGB_TO_GRAY )) && png_ptr->gamma != 0.0) { png_build_gamma_table(png_ptr); #ifdef PNG_READ_BACKGROUND_SUPPORTED @@ -1298,6 +1301,11 @@ defined(PNG_READ_USER_TRANSFORM_SUPPORTED) } #endif +# ifdef PNG_READ_PREMULTIPLY_ALPHA_SUPPORTED + if (png_ptr->transformations & PNG_PREMULTIPLY_ALPHA) + info_ptr->bit_depth = 16; +#endif + info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); @@ -1430,8 +1438,17 @@ png_do_read_transformations(png_structp png_ptr) #endif #ifdef PNG_READ_16_TO_8_SUPPORTED +# ifdef PNG_READ_PREMULTIPLY_ALPHA_SUPPORTED + /* Do this after the PREMULTIPLY operation */ + if (!(png_ptr->transformations & PNG_PREMULTIPLY_ALPHA)) + { + if (png_ptr->transformations & PNG_16_TO_8) + png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1); + } +# else if (png_ptr->transformations & PNG_16_TO_8) png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1); +# endif #endif #ifdef PNG_READ_BACKGROUND_SUPPORTED @@ -1513,9 +1530,30 @@ png_do_read_transformations(png_structp png_ptr) #endif #ifdef PNG_READ_PREMULTIPLY_ALPHA_SUPPORTED + + /* TO DO: build 16-bit gamma tables */ + + /* TO DO: expand pixels to 16 bits either here or (better) inside + * png_do_read_premultiply_alpha + */ + if (png_ptr->transformations & PNG_PREMULTIPLY_ALPHA) png_do_read_premultiply_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); + +# ifdef PNG_READ_16_TO_8_SUPPORTED + if (!(png_ptr->transformations & PNG_PREMULTIPLY_ALPHA)) + { + if (png_ptr->transformations & PNG_16_TO_8) + png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1); + } +# endif + + /* TO DO: apply png_ptr->gamma_premultiply to the premultiplied + * samples, using either the 8-bit or 16-bit gamma table as + * appropriate. + */ + #endif #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED @@ -2008,30 +2046,17 @@ png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) void /* PRIVATE */ png_do_read_premultiply_alpha(png_row_infop row_info, png_bytep row) { + + /* TO DO: expand to 16 bits, then apply gamma + * before premultiply + */ + png_debug(1, "in png_do_read_premultiply_alpha"); { png_uint_32 row_width = row_info->width; if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - /* This premultiplies the pixels with the alpha channel in RGBA */ - if (row_info->bit_depth == 8) - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_16 a = 0; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - a = *(--sp); --dp; - sp--; *(--dp) = PNG_8_BIT_PREMULTIPLY((*sp), a); - sp--; *(--dp) = PNG_8_BIT_PREMULTIPLY((*sp), a); - sp--; *(--dp) = PNG_8_BIT_PREMULTIPLY((*sp), a); - } - } - /* This premultiplies the pixels with the alpha channel in RRGGBBAA */ - else { png_uint_16p sp = (png_uint_16p)(row + row_info->rowbytes); png_uint_16p dp = sp; @@ -2049,22 +2074,6 @@ png_do_read_premultiply_alpha(png_row_infop row_info, png_bytep row) } else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { - /* This premultiplies the pixels with the alpha channel in GA */ - if (row_info->bit_depth == 8) - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_16 a = 0; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - a = *(--sp); --dp; - sp--; *(--dp) = PNG_8_BIT_PREMULTIPLY((*sp), a); - } - } - /* This premultiplies the pixels with the alpha channel in GGAA */ - else { png_uint_16p sp = (png_uint_16p) (row + row_info->rowbytes); png_uint_16p dp = sp; @@ -3880,6 +3889,24 @@ png_do_expand(png_row_infop row_info, png_bytep row, row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); } +#ifdef PNG_READ_PREMULTIPLY_ALPHA_SUPPORTED + if (row_info->bit_depth == 8) + { + if (row_info->bit_depth == 8) + { + png_bytep sp = row + (png_size_t)row_width; + png_bytep dp = sp + (png_size_t)row_width; + for (i = 1; i < row_width; i++) + { + *(--dp) = *(--sp); + *(--dp) = *(sp); + } + } + row_info->pixel_depth *= 2; + row_info->rowbytes *= 2; + } +#endif + } } #endif