From 4009a76e9724e2ef936add6d3d7c05ca4d143500 Mon Sep 17 00:00:00 2001 From: Glenn Randers-Pehrson Date: Sat, 31 Jul 2010 06:34:36 -0500 Subject: [PATCH] [devel] Implemented remaining "_fixed" functions and corrected warnings that were recently introduced, mostly resulting from safe but uncast assignments to shorter integers. Also added a zlib VStudio release library project because the latest zlib Official Windows build does not include such a thing. --- ANNOUNCE | 11 +- CHANGES | 7 +- png.c | 116 +++++++-- pngerror.c | 6 +- pngget.c | 31 ++- pngpread.c | 11 +- pngrutil.c | 6 +- pngset.c | 32 ++- pngwrite.c | 290 +++++++++++++++-------- projects/vstudio/libpng/libpng.vcxproj | 4 +- projects/vstudio/pngtest/pngtest.vcxproj | 4 +- projects/vstudio/readme.txt | 2 +- projects/vstudio/zlib.props | 2 +- projects/vstudio/zlib/zlib.vcxproj | 38 ++- scripts/pnglibconf.dfa | 4 +- scripts/pngwin.def | 6 +- scripts/symbols.def | 6 +- 17 files changed, 422 insertions(+), 154 deletions(-) diff --git a/ANNOUNCE b/ANNOUNCE index 61db465c6..b39087333 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,5 +1,5 @@ -Libpng 1.5.0beta38 - July 30, 2010 +Libpng 1.5.0beta38 - July 31, 2010 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. @@ -226,7 +226,7 @@ version 1.5.0beta24 [May 7, 2010] offset of the png_ptr->rowbuf pointer into png_ptr->big_row_buf. Added more blank lines for readability. -version 1.5.0beta25 [July 30, 2010] +version 1.5.0beta25 [July 31, 2010] In pngpread.c: png_push_have_row() add check for new_row > height Removed the now-redundant check for out-of-bounds new_row from example.c @@ -315,7 +315,12 @@ version 1.5.0beta37 [July 30, 2010] a compiler warning. Replaced oFFs 0,0 with oFFs -10,20 in pngtest.png -version 1.5.0beta38 [July 30, 2010] +version 1.5.0beta38 [July 31, 2010] + Implemented remaining "_fixed" functions. + Corrected a number of recently introduced warnings mostly resulting from + safe but uncast assignments to shorter integers. Also added a zlib + VStudio release library project because the latest zlib Official Windows + build does not include such a thing. Send comments/corrections/commendations to png-mng-implement at lists.sf.net: (subscription required; visit diff --git a/CHANGES b/CHANGES index b36f92d2f..2fe021501 100644 --- a/CHANGES +++ b/CHANGES @@ -2797,7 +2797,12 @@ version 1.5.0beta37 [July 30, 2010] a compiler warning. Replaced oFFs 0,0 with oFFs -10,20 in pngtest.png -version 1.5.0beta38 [July 30, 2010] +version 1.5.0beta38 [July 31, 2010] + Implemented remaining "_fixed" functions. + Corrected a number of recently introduced warnings mostly resulting from + safe but uncast assignments to shorter integers. Also added a zlib + VStudio release library project because the latest zlib Official Windows + build does not include such a thing. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/png.c b/png.c index b3ce8f405..8b52f0306 100644 --- a/png.c +++ b/png.c @@ -1,7 +1,7 @@ /* png.c - location for general purpose libpng functions * - * Last changed in libpng 1.5.0 [July 30, 2010] + * Last changed in libpng 1.5.0 [July 31, 2010] * Copyright (c) 1998-2010 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.) @@ -560,13 +560,13 @@ png_get_copyright(png_structp png_ptr) #else # ifdef __STDC__ return ((png_charp) PNG_STRING_NEWLINE \ - "libpng version 1.5.0beta38 - July 30, 2010" PNG_STRING_NEWLINE \ + "libpng version 1.5.0beta38 - July 31, 2010" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2010 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ PNG_STRING_NEWLINE); # else - return ((png_charp) "libpng version 1.5.0beta38 - July 30, 2010\ + return ((png_charp) "libpng version 1.5.0beta38 - July 31, 2010\ Copyright (c) 1998-2010 Glenn Randers-Pehrson\ Copyright (c) 1996-1997 Andreas Dilger\ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."); @@ -1289,7 +1289,7 @@ png_ascii_from_fp(png_structp png_ptr, png_charp ascii, png_size_t size, if (exp == 0) *ascii++ = 46, --size; /* counted above */ --exp; } - *ascii++ = 48 + (int)d, ++cdigits; + *ascii++ = (char)(48 + (int)d), ++cdigits; } } while (cdigits+czero-clead < (int)precision && fp > DBL_MIN); @@ -1379,6 +1379,79 @@ png_ascii_from_fp(png_structp png_ptr, png_charp ascii, png_size_t size, } # endif /* FLOATING_POINT */ + +# ifdef PNG_FIXED_POINT_SUPPORTED +/* Function to format a fixed point value in ASCII. + */ +void /* PRIVATE */ +png_ascii_from_fixed(png_structp png_ptr, png_charp ascii, png_size_t size, + png_fixed_point fp) +{ + /* Require space for 10 decimal digits, a decimal point, a minus sign and a + * trailing \0, 13 characters: + */ + if (size > 12) + { + png_uint_32 num; + + /* Avoid overflow here on the minimum integer. */ + if (fp < 0) + *ascii++ = 45, --size, num = -fp; + else + num = fp; + + if (num <= 0x80000000U) /* else overflowed */ + { + unsigned ndigits = 0, first = 16/*flag value*/; + char digits[10]; + + while (num) + { + /* Split the low digit off num: */ + unsigned tmp = num/10; + num -= tmp*10; + digits[ndigits++] = (char)(48 + num); + /* Record the first non-zero digit, note that this is a number + * starting at 1, it's not actually the array index. + */ + if (first == 16 && num > 0) + first = ndigits; + num = tmp; + } + + if (ndigits > 0) + { + while (ndigits > 5) *ascii++ = digits[--ndigits]; + /* The remaining digits are fractional digits, ndigits is '5' or + * smaller at this point. It is certainly not zero. Check for a + * non-zero fractional digit: + */ + if (first <= 5) + { + unsigned i; + *ascii++ = 46; /* decimal point */ + /* ndigits may be <5 for small numbers, output leading zeros then + * ndigits digits to first: + */ + i = 5; + while (ndigits < i) *ascii++ = 48, --i; + while (ndigits >= first) *ascii++ = digits[--ndigits]; + /* Don't output the trailing zeros! */ + } + } + else + *ascii++ = 48; + + /* And null terminate the string: */ + *ascii = 0; + return; + } + } + + /* Here on buffer too small. */ + png_error(png_ptr, "ASCII conversion buffer too small"); +} +# endif /* FIXED_POINT */ #endif /* READ_SCAL */ #if defined(PNG_FLOATING_POINT_SUPPORTED) &&\ @@ -1391,12 +1464,13 @@ png_fixed(png_structp png_ptr, double fp, png_const_charp text) if (r <= 2147483647. && r >= -2147483648.) return (png_fixed_point)r; - png_fixed_error(png_ptr, text, fp); - return 0; + png_fixed_error(png_ptr, text); + return 0; /*NOT REACHED*/ } #endif -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) +#if defined(PNG_READ_GAMMA_SUPPORTED) ||\ + defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG__READ_pHYs_SUPPORTED) /* muldiv functions */ /* This API takes signed arguments and rounds the result to the nearest * integer (or, for a fixed point number - the standard argument - to @@ -1945,13 +2019,13 @@ png_gamma_8bit_correct(unsigned value, png_fixed_point gamma) if (png_muldiv(&res, gamma, log, PNG_FP_1)) return png_exp8bit(res); -# endif - /* Overflow. */ - value = 0; + /* Overflow. */ + value = 0; +# endif } - return value; + return (png_byte)value; } png_uint_16 @@ -1968,13 +2042,13 @@ png_gamma_16bit_correct(unsigned value, png_fixed_point gamma) if (png_muldiv(&res, gamma, log, PNG_FP_1)) return png_exp16bit(res); -# endif - /* Overflow. */ - value = 0; + /* Overflow. */ + value = 0; +# endif } - return value; + return (png_uint_16)value; } /* This does the right thing based on the bit_depth field of the @@ -2044,7 +2118,7 @@ png_build_16bit_table(png_structp png_ptr, png_uint_16pp *ptable, unsigned j; for (j = 0; j < 256; j++) { - png_uint_16 ig = (j << (8-shift)) + i; + png_uint_32 ig = (j << (8-shift)) + i; # ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED /* Inline the 'max' scaling operation: */ sub_table[j] = (png_uint_16)floor(65535*pow(ig/(double)max, @@ -2070,7 +2144,7 @@ png_build_16bit_table(png_structp png_ptr, png_uint_16pp *ptable, if (shift) ig = (ig * 65535U + max_by_2)/max; - sub_table[j] = ig; + sub_table[j] = (png_uint_16)ig; } } } @@ -2119,13 +2193,13 @@ png_build_16to8_table(png_structp png_ptr, png_uint_16pp *ptable, for (i = 0; i < 255; ++i) /* 8 bit output value */ { /* Find the corresponding maximum input value */ - png_uint_16 out = i * 257U; /* 16 bit output value */ + png_uint_16 out = (png_uint_16)(i * 257U); /* 16 bit output value */ /* Find the boundary value in 16 bits: */ png_uint_16 bound = png_gamma_16bit_correct(out+128U, gamma); /* Adjust (round) to (16-shift) bits: */ - bound = (bound * max + 32768)/65535; + bound = (png_uint_16)(((png_uint_32)bound * max + 32768U)/65535U); while (last <= bound) { @@ -2156,8 +2230,8 @@ png_build_8bit_table(png_structp png_ptr, png_bytepp ptable, if (png_gamma_significant(gamma)) for (i=0; i<256; i++) table[i] = png_gamma_8bit_correct(i, gamma); - else for (i=0; i<245; ++i) - table[i] = i; + else for (i=0; i<256; ++i) + table[i] = (png_byte)i; } /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit diff --git a/pngerror.c b/pngerror.c index 363460eb2..7b40d4865 100644 --- a/pngerror.c +++ b/pngerror.c @@ -1,7 +1,7 @@ /* pngerror.c - stub functions for i/o and memory allocation * - * Last changed in libpng 1.5.0 [July 30, 2010] + * Last changed in libpng 1.5.0 [July 31, 2010] * Copyright (c) 1998-2010 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.) @@ -240,7 +240,7 @@ png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message) #ifdef PNG_ERROR_TEXT_SUPPORTED #ifdef PNG_FLOATING_POINT_SUPPORTED void -png_fixed_error(png_structp png_ptr, png_const_charp name, double value) +png_fixed_error(png_structp png_ptr, png_const_charp name) { # define fixed_message "fixed point overflow in " # define fixed_message_ln ((sizeof fixed_message)-1) @@ -254,9 +254,7 @@ png_fixed_error(png_structp png_ptr, png_const_charp name, double value) ++iin; } msg[fixed_message_ln + iin] = 0; - /* To discover 'value' put a breakpoint here: */ png_error(png_ptr, msg); - value = value; /* Quiet the compiler */ } #endif #endif diff --git a/pngget.c b/pngget.c index 9634f807f..c3e5591a7 100644 --- a/pngget.c +++ b/pngget.c @@ -1,7 +1,7 @@ /* pngget.c - retrieval of values from info struct * - * Last changed in libpng 1.4.1 [July 30, 2010] + * Last changed in libpng 1.4.1 [July 31, 2010] * Copyright (c) 1998-2010 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.) @@ -182,7 +182,7 @@ float PNGAPI png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) -#ifdef PNG_pHYs_SUPPORTED +#ifdef PNG_READ_pHYs_SUPPORTED if (info_ptr->valid & PNG_INFO_pHYs) { @@ -202,6 +202,27 @@ png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr) } #endif +#ifdef PNG_FIXED_POINT_SUPPORTED +png_fixed_point PNGAPI +png_get_pixel_aspect_ratio_fixed(png_structp png_ptr, png_infop info_ptr) +{ +#ifdef PNG_READ_pHYs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) + && info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0) + { + png_fixed_point res; + + png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed"); + + if (png_muldiv(&res, info_ptr->y_pixels_per_unit, PNG_FP_1, + info_ptr->x_pixels_per_unit)) + return res; + } +#endif + return 0; +} +#endif + png_int_32 PNGAPI png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr) { @@ -728,6 +749,7 @@ png_get_pCAL(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_sCAL_SUPPORTED #ifdef PNG_FIXED_POINT_SUPPORTED +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED png_uint_32 PNGAPI png_get_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int *unit, png_fixed_point *width, png_fixed_point *height) @@ -736,7 +758,7 @@ png_get_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, (info_ptr->valid & PNG_INFO_sCAL)) { *unit = info_ptr->scal_unit; - /*TODO: make this work */ + /*TODO: make this work without FP support */ *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width"); *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), "sCAL height"); @@ -745,7 +767,8 @@ png_get_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, return(0); } -#endif +#endif /*FLOATING_ARITHMETIC*/ +#endif /*FIXED_POINT*/ #ifdef PNG_FLOATING_POINT_SUPPORTED png_uint_32 PNGAPI png_get_sCAL(png_structp png_ptr, png_infop info_ptr, diff --git a/pngpread.c b/pngpread.c index c15a5d93d..55609e275 100644 --- a/pngpread.c +++ b/pngpread.c @@ -1,7 +1,7 @@ /* pngpread.c - read a png file in push mode * - * Last changed in libpng 1.5.0 [July 30, 2010] + * Last changed in libpng 1.5.0 [July 31, 2010] * Copyright (c) 1998-2010 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.) @@ -1212,8 +1212,9 @@ png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 { if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) { - png_error(png_ptr, "Out of place tEXt"); info_ptr = info_ptr; /* To quiet some compiler warnings */ + png_error(png_ptr, "Out of place tEXt"); + /*NOT REACHED*/ } #ifdef PNG_MAX_MALLOC_64K @@ -1308,8 +1309,9 @@ png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 { if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) { - png_error(png_ptr, "Out of place zTXt"); info_ptr = info_ptr; /* To quiet some compiler warnings */ + png_error(png_ptr, "Out of place zTXt"); + /*NOT REACHED*/ } #ifdef PNG_MAX_MALLOC_64K @@ -1511,8 +1513,9 @@ png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 { if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) { - png_error(png_ptr, "Out of place iTXt"); info_ptr = info_ptr; /* To quiet some compiler warnings */ + png_error(png_ptr, "Out of place iTXt"); + /*NOT REACHED*/ } #ifdef PNG_MAX_MALLOC_64K diff --git a/pngrutil.c b/pngrutil.c index 918ecc766..c0da7e12b 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -1,7 +1,7 @@ /* pngrutil.c - utilities to read a PNG file * - * Last changed in libpng 1.4.1 [July 30, 2010] + * Last changed in libpng 1.4.1 [July 31, 2010] * Copyright (c) 1998-2010 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.) @@ -3074,8 +3074,8 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, } default: png_error(png_ptr, "Ignoring bad adaptive filter type"); - *row = 0; - break; + /*NOT REACHED */ + break; } } diff --git a/pngset.c b/pngset.c index 4b63b1ea8..5daebbf48 100644 --- a/pngset.c +++ b/pngset.c @@ -1,7 +1,7 @@ /* pngset.c - storage of image information into info struct * - * Last changed in libpng 1.5.0 [July 30, 2010] + * Last changed in libpng 1.5.0 [July 31, 2010] * Copyright (c) 1998-2010 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.) @@ -318,11 +318,11 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, #endif #ifdef PNG_sCAL_SUPPORTED -void PNGFAPI +void PNGAPI png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, int unit, png_charp swidth, png_charp sheight) { - png_size_t lengthw, lengthh; + png_size_t lengthw = 0, lengthh = 0; png_debug1(1, "in %s storage function", "sCAL"); @@ -407,6 +407,32 @@ png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width, } } #endif + +#ifdef PNG_FIXED_POINT_SUPPORTED +void PNGAPI +png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit, + png_fixed_point width, png_fixed_point height) +{ + png_debug1(1, "in %s storage function", "sCAL"); + + /* Check the arguments. */ + if (width <= 0) + png_warning(png_ptr, "Invalid sCAL width ignored"); + else if (height <= 0) + png_warning(png_ptr, "Invalid sCAL height ignored"); + else + { + /* Convert 'width' and 'height' to ASCII. */ + char swidth[PNG_sCAL_MAX_DIGITS+1]; + char sheight[PNG_sCAL_MAX_DIGITS+1]; + + png_ascii_from_fixed(png_ptr, swidth, sizeof swidth, width); + png_ascii_from_fixed(png_ptr, sheight, sizeof sheight, height); + + png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); + } +} +#endif #endif #ifdef PNG_pHYs_SUPPORTED diff --git a/pngwrite.c b/pngwrite.c index a7f69db9b..2961b5e53 100644 --- a/pngwrite.c +++ b/pngwrite.c @@ -1,7 +1,7 @@ /* pngwrite.c - general routines to write a PNG file * - * Last changed in libpng 1.5.0 [July 30, 2010] + * Last changed in libpng 1.5.0 [July 31, 2010] * Copyright (c) 1998-2010 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.) @@ -447,6 +447,8 @@ png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr, } /* Alternate initialize png_ptr structure, and allocate any memory needed */ +static void png_reset_filter_heuristics(png_structp png_ptr); /* forward decl */ + png_structp PNGAPI png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, @@ -574,8 +576,7 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, png_set_write_fn(png_ptr, NULL, NULL, NULL); #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT, - 1, NULL, NULL); + png_reset_filter_heuristics(png_ptr); #endif return (png_ptr); @@ -999,9 +1000,8 @@ png_write_destroy(png_structp png_ptr) #endif #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - png_free(png_ptr, png_ptr->prev_filters); - png_free(png_ptr, png_ptr->filter_weights); - png_free(png_ptr, png_ptr->inv_filter_weights); + /* Use this to save a little code space, it doesn't free the filter_costs */ + png_reset_filter_heuristics(png_ptr); png_free(png_ptr, png_ptr->filter_costs); png_free(png_ptr, png_ptr->inv_filter_costs); #endif @@ -1165,41 +1165,59 @@ png_set_filter(png_structp png_ptr, int method, int filters) * better compression. */ #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */ -void PNGAPI -png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, - int num_weights, png_doublep filter_weights, - png_doublep filter_costs) +/* Conveneince reset API. */ +static void +png_reset_filter_heuristics(png_structp png_ptr) { - int i; + /* Clear out any old values in the 'weights' - this must be done because if + * the app calls set_filter_heuristics multiple times with different + * 'num_weights' values we would otherwise potentially have wrong sized + * arrays. + */ + png_ptr->num_prev_filters = 0; + png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED; + if (png_ptr->prev_filters != NULL) + { + png_bytep old = png_ptr->prev_filters; + png_ptr->prev_filters = NULL; + png_free(png_ptr, old); + } + if (png_ptr->filter_weights != NULL) + { + png_uint_16p old = png_ptr->filter_weights; + png_ptr->filter_weights = NULL; + png_free(png_ptr, old); + } - png_debug(1, "in png_set_filter_heuristics"); + if (png_ptr->inv_filter_weights != NULL) + { + png_uint_16p old = png_ptr->inv_filter_weights; + png_ptr->inv_filter_weights = NULL; + png_free(png_ptr, old); + } + /* Leave the filter_costs - this array is fixed size. */ +} + +static int +png_init_filter_heuristics(png_structp png_ptr, int heuristic_method, + int num_weights) +{ if (png_ptr == NULL) - return; + return 0; - if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST) + /* Clear out the arrays */ + png_reset_filter_heuristics(png_ptr); + + /* Check arguments; the 'reset' function makes the correct settings for the + * unweighted case, but we must handle the weight case by initializing the + * arrays for the caller. + */ + if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { - png_warning(png_ptr, "Unknown filter heuristic method"); - return; - } + int i; - if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT) - { - heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED; - } - - if (num_weights < 0 || filter_weights == NULL || - heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED) - { - num_weights = 0; - } - - png_ptr->num_prev_filters = (png_byte)num_weights; - png_ptr->heuristic_method = (png_byte)heuristic_method; - - if (num_weights > 0) - { - if (png_ptr->prev_filters == NULL) + if (num_weights > 0) { png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr, (png_uint_32)(png_sizeof(png_byte) * num_weights)); @@ -1209,85 +1227,169 @@ png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, { png_ptr->prev_filters[i] = 255; } + + png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); + + png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); + + for (i = 0; i < num_weights; i++) + { + png_ptr->inv_filter_weights[i] = + png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; + } + + /* Safe to set this now */ + png_ptr->num_prev_filters = (png_byte)num_weights; } - if (png_ptr->filter_weights == NULL) + /* If, in the future, there are other filter methods, this would + * need to be based on png_ptr->filter. + */ + if (png_ptr->filter_costs == NULL) { - png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); + png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); - png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); - - for (i = 0; i < num_weights; i++) - { - png_ptr->inv_filter_weights[i] = - png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; - } + png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); } - for (i = 0; i < num_weights; i++) - { - if (filter_weights[i] < 0.0) - { - png_ptr->inv_filter_weights[i] = - png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; - } - - else - { - png_ptr->inv_filter_weights[i] = - (png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5); - - png_ptr->filter_weights[i] = - (png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5); - } - } - } - - /* If, in the future, there are other filter methods, this would - * need to be based on png_ptr->filter. - */ - if (png_ptr->filter_costs == NULL) - { - png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); - - png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); - for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) { - png_ptr->inv_filter_costs[i] = - png_ptr->filter_costs[i] = PNG_COST_FACTOR; + png_ptr->inv_filter_costs[i] = + png_ptr->filter_costs[i] = PNG_COST_FACTOR; } + + /* All the arrays are inited, safe to set this: */ + png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_WEIGHTED; + + /* Return the 'ok' code. */ + return 1; } - - /* Here is where we set the relative costs of the different filters. We - * should take the desired compression level into account when setting - * the costs, so that Paeth, for instance, has a high relative cost at low - * compression levels, while it has a lower relative cost at higher - * compression settings. The filter types are in order of increasing - * relative cost, so it would be possible to do this with an algorithm. - */ - for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) + else if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT || + heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED) { - if (filter_costs == NULL || filter_costs[i] < 0.0) + return 1; + } + else + { + png_warning(png_ptr, "Unknown filter heuristic method"); + return 0; + } +} + +/* Provide floating and fixed point APIs */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, + int num_weights, png_doublep filter_weights, png_doublep filter_costs) +{ + png_debug(1, "in png_set_filter_heuristics"); + + /* The internal API allocates all the arrays and ensures that the elements of + * those arrays are set to the default value. + */ + if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) + return; + + /* If using the weighted method copy in the weights. */ + if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int i; + for (i = 0; i < num_weights; i++) { - png_ptr->inv_filter_costs[i] = - png_ptr->filter_costs[i] = PNG_COST_FACTOR; + if (filter_weights[i] <= 0.0) + { + png_ptr->inv_filter_weights[i] = + png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; + } + + else + { + png_ptr->inv_filter_weights[i] = + (png_uint_16)(PNG_WEIGHT_FACTOR*filter_weights[i]+.5); + + png_ptr->filter_weights[i] = + (png_uint_16)(PNG_WEIGHT_FACTOR/filter_weights[i]+.5); + } } - else if (filter_costs[i] >= 1.0) + /* Here is where we set the relative costs of the different filters. We + * should take the desired compression level into account when setting + * the costs, so that Paeth, for instance, has a high relative cost at low + * compression levels, while it has a lower relative cost at higher + * compression settings. The filter types are in order of increasing + * relative cost, so it would be possible to do this with an algorithm. + */ + for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) if (filter_costs[i] >= 1.0) { - png_ptr->inv_filter_costs[i] = - (png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5); + png_ptr->inv_filter_costs[i] = + (png_uint_16)(PNG_COST_FACTOR / filter_costs[i] + .5); - png_ptr->filter_costs[i] = - (png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5); + png_ptr->filter_costs[i] = + (png_uint_16)(PNG_COST_FACTOR * filter_costs[i] + .5); } } } +#endif /* FLOATING_POINT */ + +#ifdef PNG_FIXED_POINT_SUPPORTED +void PNGAPI +png_set_filter_heuristics_fixed(png_structp png_ptr, int heuristic_method, + int num_weights, png_fixed_point_p filter_weights, + png_fixed_point_p filter_costs) +{ + png_debug(1, "in png_set_filter_heuristics_fixed"); + + /* The internal API allocates all the arrays and ensures that the elements of + * those arrays are set to the default value. + */ + if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) + return; + + /* If using the weighted method copy in the weights. */ + if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int i; + for (i = 0; i < num_weights; i++) + { + if (filter_weights[i] <= 0) + { + png_ptr->inv_filter_weights[i] = + png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; + } + + else + { + png_ptr->inv_filter_weights[i] = (png_uint_16) + ((PNG_WEIGHT_FACTOR*filter_weights[i]+PNG_FP_HALF)/PNG_FP_1); + + png_ptr->filter_weights[i] = (png_uint_16)((PNG_WEIGHT_FACTOR* + PNG_FP_1+(filter_weights[i]/2))/filter_weights[i]); + } + } + + /* Here is where we set the relative costs of the different filters. We + * should take the desired compression level into account when setting + * the costs, so that Paeth, for instance, has a high relative cost at low + * compression levels, while it has a lower relative cost at higher + * compression settings. The filter types are in order of increasing + * relative cost, so it would be possible to do this with an algorithm. + */ + for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) + if (filter_costs[i] >= PNG_FP_1) + { + png_ptr->inv_filter_costs[i] = (png_uint_16)((PNG_COST_FACTOR* + PNG_FP_1+(filter_costs[i]/2)) / filter_costs[i]); + + png_ptr->filter_costs[i] = (png_uint_16) + ((PNG_COST_FACTOR * filter_costs[i] +PNG_FP_HALF)/PNG_FP_1); + } + } +} +#endif /* FIXED_POINT */ #endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ void PNGAPI diff --git a/projects/vstudio/libpng/libpng.vcxproj b/projects/vstudio/libpng/libpng.vcxproj index 892e63247..619fd882a 100644 --- a/projects/vstudio/libpng/libpng.vcxproj +++ b/projects/vstudio/libpng/libpng.vcxproj @@ -120,7 +120,7 @@ ProgramDatabase Disabled EnableFastChecks - MultiThreadedDebugDLL + MultiThreadedDebug WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true true @@ -176,7 +176,7 @@ Level4 Use ProgramDatabase - MultiThreadedDLL + MultiThreaded true true WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) diff --git a/projects/vstudio/pngtest/pngtest.vcxproj b/projects/vstudio/pngtest/pngtest.vcxproj index 21dcf7f64..d73d51484 100644 --- a/projects/vstudio/pngtest/pngtest.vcxproj +++ b/projects/vstudio/pngtest/pngtest.vcxproj @@ -114,7 +114,7 @@ ProgramDatabase Disabled EnableFastChecks - MultiThreadedDebugDLL + MultiThreadedDebug WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories) 4996 @@ -179,7 +179,7 @@ NotUsing ProgramDatabase Full - MultiThreadedDLL + MultiThreaded false true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) diff --git a/projects/vstudio/readme.txt b/projects/vstudio/readme.txt index 5c3fdcbce..de8b45a30 100644 --- a/projects/vstudio/readme.txt +++ b/projects/vstudio/readme.txt @@ -1,7 +1,7 @@ VisualStudio instructions -libpng version 1.5.0beta38 - July 30, 2010 +libpng version 1.5.0beta38 - July 31, 2010 Copyright (c) 1998-2010 Glenn Randers-Pehrson diff --git a/projects/vstudio/zlib.props b/projects/vstudio/zlib.props index 7103f0afc..2c13d9e97 100644 --- a/projects/vstudio/zlib.props +++ b/projects/vstudio/zlib.props @@ -2,7 +2,7 @@