diff --git a/ANNOUNCE b/ANNOUNCE index 23d23ecc6..485520478 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,5 +1,5 @@ -Libpng 1.6.1beta07 - March 4, 2013 +Libpng 1.6.1beta07 - March 7, 2013 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. @@ -79,7 +79,19 @@ Version 1.6.1beta06 [March 4, 2013] settings to depend on options and options can now set (or override) the defaults for settings. -Version 1.6.1beta07 [March 4, 2013] +Version 1.6.1beta07 [March 7, 2013] + Corrected simplified API default gamma for color-mapped output, added + a flag to change default. In 1.6.0 when the simplified API was used + to produce color-mapped output from an input image with no gamma + information the gamma assumed for the input could be different from + that assumed for non-color-mapped output. In particular 16-bit depth + input files were assumed to be sRGB encoded, whereas in the 'direct' + case they were assumed to have linear data. This was an error. The + fix makes the simplified API treat all input files the same way and + adds a new flag to the png_image::flags member to allow the + application/user to specify that 16-bit files contain sRGB data + rather than the default linear. + Fixed bugs in the pngpixel and makepng test programs. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/CHANGES b/CHANGES index a00683af6..f8f952473 100644 --- a/CHANGES +++ b/CHANGES @@ -4435,7 +4435,19 @@ Version 1.6.1beta06 [March 4, 2013] settings to depend on options and options can now set (or override) the defaults for settings. -Version 1.6.1beta07 [March 4, 2013] +Version 1.6.1beta07 [March 7, 2013] + Corrected simplified API default gamma for color-mapped output, added + a flag to change default. In 1.6.0 when the simplified API was used + to produce color-mapped output from an input image with no gamma + information the gamma assumed for the input could be different from + that assumed for non-color-mapped output. In particular 16-bit depth + input files were assumed to be sRGB encoded, whereas in the 'direct' + case they were assumed to have linear data. This was an error. The + fix makes the simplified API treat all input files the same way and + adds a new flag to the png_image::flags member to allow the + application/user to specify that 16-bit files contain sRGB data + rather than the default linear. + Fixed bugs in the pngpixel and makepng test programs. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/contrib/examples/pngpixel.c b/contrib/examples/pngpixel.c index d82ef83d0..410476031 100644 --- a/contrib/examples/pngpixel.c +++ b/contrib/examples/pngpixel.c @@ -37,7 +37,7 @@ component(png_const_bytep row, png_uint_32 x, unsigned int c, * bytes wide. Since the row fitted into memory, however, the following must * work: */ - png_uint_32 bit_offset_hi = bit_depth * ((x >> 6) * channels + c); + png_uint_32 bit_offset_hi = bit_depth * ((x >> 6) * channels); png_uint_32 bit_offset_lo = bit_depth * ((x & 0x3f) * channels + c); row = (png_const_bytep)(((PNG_CONST png_byte (*)[8])row) + bit_offset_hi); diff --git a/contrib/libtests/makepng.c b/contrib/libtests/makepng.c index 3b2e92f4f..6df320453 100644 --- a/contrib/libtests/makepng.c +++ b/contrib/libtests/makepng.c @@ -440,7 +440,7 @@ generate_row(png_bytep row, size_t rowbytes, unsigned int y, int color_type, /* Palette with fixed color: the image rows are all 0 and the image width * is 16. */ - memset(row, rowbytes, 0); + memset(row, 0, rowbytes); } else if (colors[0] == channels_of_type(color_type)) @@ -624,8 +624,8 @@ write_png(const char **name, FILE *fp, int color_type, int bit_depth, gamma_table[0] = 0; - for (i=0; i<255; ++i) - gamma_table[i] = (png_byte)floor(pow(i/255.,conv) * 255 + 127.5); + for (i=1; i<255; ++i) + gamma_table[i] = (png_byte)floor(pow(i/255.,conv) * 255 + .5); gamma_table[255] = 255; } diff --git a/contrib/libtests/pngstest.c b/contrib/libtests/pngstest.c index 543e50bd0..8b55b2ab9 100644 --- a/contrib/libtests/pngstest.c +++ b/contrib/libtests/pngstest.c @@ -315,6 +315,7 @@ compare_16bit(int v1, int v2, int error_limit, int multiple_algorithms) #define KEEP_GOING 32 #define ACCUMULATE 64 #define FAST_WRITE 128 +#define sRGB_16BIT 256 static void print_opts(png_uint_32 opts) @@ -335,6 +336,8 @@ print_opts(png_uint_32 opts) printf(" --accumulate"); if (!(opts & FAST_WRITE)) /* --fast is currently the default */ printf(" --slow"); + if (opts & sRGB_16BIT) + printf(" --sRGB-16bit"); } #define FORMAT_NO_CHANGE 0x80000000 /* additional flag */ @@ -3026,6 +3029,10 @@ read_file(Image *image, png_uint_32 format, png_const_colorp background) return logerror(image, "file init: ", image->file_name, ""); } + /* This must be set after the begin_read call: */ + if (image->opts & sRGB_16BIT) + image->image.flags |= PNG_IMAGE_FLAG_16BIT_sRGB; + /* Have an initialized image with all the data we need plus, maybe, an * allocated file (myfile) or buffer (mybuffer) that need to be freed. */ @@ -3488,6 +3495,10 @@ main(int argc, char **argv) opts &= ~KEEP_GOING; else if (strcmp(arg, "--strict") == 0) opts |= STRICT; + else if (strcmp(arg, "--sRGB-16bit") == 0) + opts |= sRGB_16BIT; + else if (strcmp(arg, "--linear-16bit") == 0) + opts &= ~sRGB_16BIT; else if (strcmp(arg, "--tmpfile") == 0) { if (c+1 < argc) diff --git a/png.h b/png.h index abd252870..1322984e3 100644 --- a/png.h +++ b/png.h @@ -1,7 +1,7 @@ /* png.h - header file for PNG reference library * - * libpng version 1.6.1beta07 - March 4, 2013 + * libpng version 1.6.1beta07 - March 7, 2013 * Copyright (c) 1998-2013 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.6.1beta07 - March 4, 2013: Glenn + * libpng versions 0.97, January 1998, through 1.6.1beta07 - March 7, 2013: Glenn * See also "Contributing Authors", below. * * Note about libpng version numbers: @@ -201,7 +201,7 @@ * * This code is released under the libpng license. * - * libpng versions 1.2.6, August 15, 2004, through 1.6.1beta07, March 4, 2013, are + * libpng versions 1.2.6, August 15, 2004, through 1.6.1beta07, March 7, 2013, are * Copyright (c) 2004, 2006-2013 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: @@ -313,7 +313,7 @@ * Y2K compliance in libpng: * ========================= * - * March 4, 2013 + * March 7, 2013 * * Since the PNG Development group is an ad-hoc body, we can't make * an official declaration. @@ -381,7 +381,7 @@ /* Version information for png.h - this should match the version in png.c */ #define PNG_LIBPNG_VER_STRING "1.6.1beta07" #define PNG_HEADER_VERSION_STRING \ - " libpng version 1.6.1beta07 - March 4, 2013\n" + " libpng version 1.6.1beta07 - March 7, 2013\n" #define PNG_LIBPNG_VER_SONUM 16 #define PNG_LIBPNG_VER_DLLNUM 16 @@ -3098,6 +3098,24 @@ typedef struct * slight speed gain. */ +#define PNG_IMAGE_FLAG_16BIT_sRGB 0x04 + /* On read if the image is a 16-bit per component image and there is no gAMA + * or sRGB chunk assume that the components are sRGB encoded. Notice that + * images output by the simplified API always have gamma information; setting + * this flag only affects the interpretation of 16-bit images from an + * external source. It is recommended that the application expose this flag + * to the user; the user can normally easily recognize the difference between + * linear and sRGB encoding. This flag has no effect on write - the data + * passed to the write APIs must have the correct encoding (as defined + * above.) + * + * If the flag is not set (the default) input 16-bit per component data is + * assumed to be linear. + * + * NOTE: the flag can only be set after the png_image_begin_read_ call, + * because that call initializes the 'flags' field. + */ + #ifdef PNG_SIMPLIFIED_READ_SUPPORTED /* READ APIs * --------- @@ -3148,7 +3166,7 @@ PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image, * PNG_FORMAT_FLAG_LINEAR *not* set. * * For linear output removing the alpha channel is always done by compositing - * on black and background is ignored.: + * on black and background is ignored. * * colormap must be supplied when PNG_FORMAT_FLAG_COLORMAP is set. It must * be at least the size (in bytes) returned by PNG_IMAGE_COLORMAP_SIZE. diff --git a/pngread.c b/pngread.c index e4fa21551..b1751ace8 100644 --- a/pngread.c +++ b/pngread.c @@ -2004,6 +2004,28 @@ png_image_read_colormap(png_voidp argument) else back_b = back_r = back_g = 255; + /* Default the input file gamma if required - this is necessary because + * libpng assumes that if no gamma information is present the data is in the + * output format, but the simplified API deduces the gamma from the input + * format. + */ + if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0) + { + /* Do this directly, not using the png_colorspace functions, to ensure + * that it happens even if the colorspace is invalid (though probably if + * it is the setting will be ignored) Note that the same thing can be + * achieved at the application interface with png_set_gAMA. + */ + if (png_ptr->bit_depth == 16 && + (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) + png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR; + + else + png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE; + + png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; + } + /* Decide what to do based on the PNG color type of the input data. The * utility function png_create_colormap_entry deals with most aspects of the * output transformations; this code works out how to produce bytes of @@ -3547,7 +3569,8 @@ png_image_read_direct(png_voidp argument) { png_fixed_point input_gamma_default; - if (base_format & PNG_FORMAT_FLAG_LINEAR) + if ((base_format & PNG_FORMAT_FLAG_LINEAR) && + (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) input_gamma_default = PNG_GAMMA_LINEAR; else input_gamma_default = PNG_DEFAULT_sRGB;