diff --git a/ANNOUNCE b/ANNOUNCE index e0cf2f792..1a78be98a 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -354,7 +354,10 @@ version 1.5.0beta43 [August 11, 2010] Also added scripts/chkfmt to validate the format of all the files that can reasonably be validated (it is suggested to run "make distclean" before checking, because some machine generated files have long lines.) - Reformatted the CHANGES file to be more consistent throughout. + Reformatted the CHANGES file to be more consistent throughout. + Made changes to address various issues identified by GCC, mostly + signed/unsigned and shortening problems on assignment but also a few + difficult to optimize (for GCC) loops. Send comments/corrections/commendations to png-mng-implement at lists.sf.net: (subscription required; visit diff --git a/CHANGES b/CHANGES index e1cf546a3..4d03cbca1 100644 --- a/CHANGES +++ b/CHANGES @@ -2990,7 +2990,10 @@ Version 1.5.0beta43 [August 11, 2010] Also added scripts/chkfmt to validate the format of all the files that can reasonably be validated (it is suggested to run "make distclean" before checking, because some machine generated files have long lines.) - Reformatted the CHANGES file to be more consistent throughout. + Reformatted the CHANGES file to be more consistent throughout. + Made changes to address various issues identified by GCC, mostly + signed/unsigned and shortening problems on assignment but also a few + difficult to optimize (for GCC) loops. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/png.c b/png.c index e51722b1c..f6623d02b 100644 --- a/png.c +++ b/png.c @@ -396,7 +396,7 @@ png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask, if (info_ptr->unknown_chunks_num) { - for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++) + for (i = 0; i < info_ptr->unknown_chunks_num; i++) png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i); png_free(png_ptr, info_ptr->unknown_chunks); @@ -1344,7 +1344,7 @@ png_ascii_from_fp(png_structp png_ptr, png_charp ascii, png_size_t size, while (exp > 0) { - exponent[cdigits++] = 48 + exp % 10; + exponent[cdigits++] = (char)(48 + exp % 10); exp /= 10; } @@ -1580,7 +1580,7 @@ png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, result = -result; /* Check for overflow. */ - if (negative && result <= 0 || !negative && result >= 0) + if ((negative && result <= 0) || (!negative && result >= 0)) { *res = result; return 1; @@ -1792,7 +1792,7 @@ png_8bit_l2[128] = #endif }; -static png_uint_32 +static png_int_32 png_log8bit(unsigned int x) { unsigned int log = 0; @@ -1814,7 +1814,8 @@ png_log8bit(unsigned int x) if ((x & 0x80) == 0) log += 1, x <<= 1; - return (log << 16) + ((png_8bit_l2[x-128]+32768)>>16); + /* result is at most 19 bits, so this cast is safe: */ + return (png_int_32)((log << 16) + ((png_8bit_l2[x-128]+32768)>>16)); } /* The above gives exact (to 16 binary places) log2 values for 8 bit images, @@ -1847,7 +1848,7 @@ png_log8bit(unsigned int x) * Zero (257): 0 * End (258): 23499 */ -static png_uint_32 +static png_int_32 png_log16bit(png_uint_32 x) { unsigned int log = 0; @@ -1894,7 +1895,8 @@ png_log16bit(png_uint_32 x) else log -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12); - return (log + 2048) >> 12; + /* Safe, because the result can't have more than 20 bits: */ + return (png_int_32)((log + 2048) >> 12); } /* The 'exp()' case must invert the above, taking a 20 bit fixed point @@ -1941,9 +1943,9 @@ for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"} #endif static png_uint_32 -png_exp(png_uint_32 x) +png_exp(png_fixed_point x) { - if (x <= 0xfffff) /* Else zero */ + if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */ { /* Obtain a 4 bit approximation */ png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf]; @@ -1980,11 +1982,16 @@ png_exp(png_uint_32 x) return e; } + /* Check for overflow */ + if (x <= 0) + return png_32bit_exp[0]; + + /* Else underflow */ return 0; } static png_byte -png_exp8bit(png_uint_32 log) +png_exp8bit(png_fixed_point log) { /* Get a 32 bit value: */ png_uint_32 x = png_exp(log); @@ -1994,18 +2001,18 @@ png_exp8bit(png_uint_32 log) * step. */ x -= x >> 8; - return (x + 0x7fffffU) >> 24; + return (png_byte)((x + 0x7fffffU) >> 24); } static png_uint_16 -png_exp16bit(png_uint_32 log) +png_exp16bit(png_fixed_point log) { /* Get a 32 bit value: */ png_uint_32 x = png_exp(log); /* Convert the 32 bit value to 0..65535 by multiplying by 65536-1: */ x -= x >> 16; - return (x + 32767U) >> 16; + return (png_uint_16)((x + 32767U) >> 16); } #endif /* FLOATING_ARITHMETIC */ @@ -2018,7 +2025,7 @@ png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma) double r = floor(255*pow(value/255.,gamma*.00001)+.5); return (png_byte)r; # else - png_uint_32 log = png_log8bit(value); + png_int_32 log = png_log8bit(value); png_fixed_point res; if (png_muldiv(&res, gamma, log, PNG_FP_1)) @@ -2041,7 +2048,7 @@ png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma) double r = floor(65535*pow(value/65535.,gamma*.00001)+.5); return (png_uint_16)r; # else - png_uint_32 log = png_log16bit(value); + png_int_32 log = png_log16bit(value); png_fixed_point res; if (png_muldiv(&res, gamma, log, PNG_FP_1)) @@ -2200,12 +2207,12 @@ png_build_16to8_table(png_structp png_ptr, png_uint_16pp *ptable, 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); + png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma); /* Adjust (round) to (16-shift) bits: */ - bound = (png_uint_16)(((png_uint_32)bound * max + 32768U)/65535U); + bound = (bound * max + 32768U)/65535U + 1U; - while (last <= bound) + while (last < bound) { table[last & (0xffU >> shift)][last >> (8U - shift)] = out; last++; @@ -2244,7 +2251,7 @@ png_build_8bit_table(png_structp png_ptr, png_bytepp ptable, * we don't need to allocate > 64K chunks for a full 16-bit table. */ void /* PRIVATE */ -png_build_gamma_table(png_structp png_ptr, png_byte bit_depth) +png_build_gamma_table(png_structp png_ptr, int bit_depth) { png_debug(1, "in png_build_gamma_table"); @@ -2302,8 +2309,8 @@ png_build_gamma_table(png_structp png_ptr, png_byte bit_depth) * ..<(n+1 << gamma_shift)-1> * */ - if (sig_bit > 0) - shift = 16U - sig_bit; /* shift == insignificant bits */ + if (sig_bit > 0 && sig_bit < 16U) + shift = (png_byte)(16U - sig_bit); /* shift == insignificant bits */ else shift = 0; /* keep all 16 bits */ diff --git a/png.h b/png.h index 017dbec3b..c2828219f 100644 --- a/png.h +++ b/png.h @@ -1878,7 +1878,7 @@ PNG_EXPORT(void, png_set_unknown_chunks,(png_structp png_ptr, 174); PNG_EXPORT(void, png_set_unknown_chunk_location, (png_structp png_ptr, png_infop info_ptr, int chunk, int location),,175); -PNG_EXPORT(png_uint_32,png_get_unknown_chunks,(png_structp png_ptr, +PNG_EXPORT(int,png_get_unknown_chunks,(png_structp png_ptr, png_infop info_ptr, png_unknown_chunkpp entries),,176); #endif diff --git a/pnginfo.h b/pnginfo.h index 81e2fca70..c43454cc4 100644 --- a/pnginfo.h +++ b/pnginfo.h @@ -229,7 +229,7 @@ defined(PNG_READ_BACKGROUND_SUPPORTED) defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) /* Storage for unknown chunks that the library doesn't recognize. */ png_unknown_chunkp unknown_chunks; - png_size_t unknown_chunks_num; + int unknown_chunks_num; #endif #ifdef PNG_iCCP_SUPPORTED diff --git a/pngpread.c b/pngpread.c index 7b85bf0e6..f22e2259d 100644 --- a/pngpread.c +++ b/pngpread.c @@ -1120,6 +1120,7 @@ png_push_process_row(png_structp png_ptr) break; } + case 6: { png_push_have_row(png_ptr, png_ptr->row_buf + 1); diff --git a/pngpriv.h b/pngpriv.h index a3b0dc36c..c46375cdc 100644 --- a/pngpriv.h +++ b/pngpriv.h @@ -1188,7 +1188,7 @@ PNG_EXTERN png_uint_16 png_gamma_16bit_correct PNGARG((unsigned int value, PNG_EXTERN png_byte png_gamma_8bit_correct PNGARG((unsigned int value, png_fixed_point gamma)); PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr, - png_byte bit_depth)); + int bit_depth)); #endif /* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */ diff --git a/pngrtran.c b/pngrtran.c index 00724e9f1..b8d278bae 100644 --- a/pngrtran.c +++ b/pngrtran.c @@ -1273,7 +1273,8 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) #ifdef PNG_READ_BACKGROUND_SUPPORTED if (png_ptr->transformations & PNG_BACKGROUND) { - info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; + info_ptr->color_type = (png_byte)(info_ptr->color_type & + ~PNG_COLOR_MASK_ALPHA); info_ptr->num_trans = 0; info_ptr->background = png_ptr->background; } @@ -2609,8 +2610,9 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) } } } - row_info->channels -= (png_byte)2; - row_info->color_type &= ~PNG_COLOR_MASK_COLOR; + row_info->channels -= 2; + row_info->color_type = (png_byte)(row_info->color_type & + ~PNG_COLOR_MASK_COLOR); row_info->pixel_depth = (png_byte)(row_info->channels * row_info->bit_depth); row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); @@ -3408,7 +3410,8 @@ png_do_background(png_row_infop row_info, png_bytep row, if (row_info->color_type & PNG_COLOR_MASK_ALPHA) { - row_info->color_type &= ~PNG_COLOR_MASK_ALPHA; + row_info->color_type = (png_byte)(row_info->color_type & + ~PNG_COLOR_MASK_ALPHA); row_info->channels--; row_info->pixel_depth = (png_byte)(row_info->channels * row_info->bit_depth); @@ -3715,9 +3718,8 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, row_info->rowbytes = row_width; } - switch (row_info->bit_depth) + else if (row_info->bit_depth == 8) { - case 8: { if (trans_alpha != NULL) { @@ -3763,7 +3765,6 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, row_info->color_type = 2; row_info->channels = 3; } - break; } } } @@ -3897,8 +3898,8 @@ png_do_expand(png_row_infop row_info, png_bytep row, else if (row_info->bit_depth == 16) { - png_byte gray_high = (gray >> 8) & 0xff; - png_byte gray_low = gray & 0xff; + png_byte gray_high = (png_byte)((gray >> 8) & 0xff); + png_byte gray_low = (png_byte)(gray & 0xff); sp = row + row_info->rowbytes - 1; dp = row + (row_info->rowbytes << 1) - 1; for (i = 0; i < row_width; i++) @@ -3931,9 +3932,9 @@ png_do_expand(png_row_infop row_info, png_bytep row, { if (row_info->bit_depth == 8) { - png_byte red = trans_value->red & 0xff; - png_byte green = trans_value->green & 0xff; - png_byte blue = trans_value->blue & 0xff; + png_byte red = (png_byte)(trans_value->red & 0xff); + png_byte green = (png_byte)(trans_value->green & 0xff); + png_byte blue = (png_byte)(trans_value->blue & 0xff); sp = row + (png_size_t)row_info->rowbytes - 1; dp = row + (png_size_t)(row_width << 2) - 1; for (i = 0; i < row_width; i++) @@ -3951,12 +3952,12 @@ png_do_expand(png_row_infop row_info, png_bytep row, } else if (row_info->bit_depth == 16) { - png_byte red_high = (trans_value->red >> 8) & 0xff; - png_byte green_high = (trans_value->green >> 8) & 0xff; - png_byte blue_high = (trans_value->blue >> 8) & 0xff; - png_byte red_low = trans_value->red & 0xff; - png_byte green_low = trans_value->green & 0xff; - png_byte blue_low = trans_value->blue & 0xff; + png_byte red_high = (png_byte)((trans_value->red >> 8) & 0xff); + png_byte green_high = (png_byte)((trans_value->green >> 8) & 0xff); + png_byte blue_high = (png_byte)((trans_value->blue >> 8) & 0xff); + png_byte red_low = (png_byte)(trans_value->red & 0xff); + png_byte green_low = (png_byte)(trans_value->green & 0xff); + png_byte blue_low = (png_byte)(trans_value->blue & 0xff); sp = row + row_info->rowbytes - 1; dp = row + (png_size_t)(row_width << 3) - 1; for (i = 0; i < row_width; i++) diff --git a/pngrutil.c b/pngrutil.c index 43f25bfa8..5d8ba69c9 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -262,14 +262,15 @@ png_inflate(png_structp png_ptr, png_bytep data, png_size_t size, */ if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0) { + png_size_t space = avail; /* > 0, see above */ if (output != 0 && output_size > count) { - int copy = output_size - count; - if (avail < copy) - copy = avail; + png_size_t copy = output_size - count; + if (space < copy) + copy = space; png_memcpy(output + count, png_ptr->zbuf, copy); } - count += avail; + count += space; } if (ret == Z_OK) @@ -497,6 +498,7 @@ png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) /* Find number of channels */ switch (png_ptr->color_type) { + default: /* invalid, png_set_IHDR calls png_error */ case PNG_COLOR_TYPE_GRAY: case PNG_COLOR_TYPE_PALETTE: png_ptr->channels = 1; diff --git a/pngset.c b/pngset.c index b45442600..17b020fd5 100644 --- a/pngset.c +++ b/pngset.c @@ -948,8 +948,8 @@ png_set_unknown_chunks(png_structp png_ptr, return; np = (png_unknown_chunkp)png_malloc_warn(png_ptr, - (png_size_t)((info_ptr->unknown_chunks_num + num_unknowns) * - png_sizeof(png_unknown_chunk))); + (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) * + png_sizeof(png_unknown_chunk)); if (np == NULL) { @@ -959,7 +959,8 @@ png_set_unknown_chunks(png_structp png_ptr, } png_memcpy(np, info_ptr->unknown_chunks, - info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk)); + (png_size_t)info_ptr->unknown_chunks_num * + png_sizeof(png_unknown_chunk)); png_free(png_ptr, info_ptr->unknown_chunks); info_ptr->unknown_chunks = NULL; @@ -999,12 +1000,13 @@ png_set_unknown_chunks(png_structp png_ptr, info_ptr->unknown_chunks_num += num_unknowns; info_ptr->free_me |= PNG_FREE_UNKN; } + void PNGAPI png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr, int chunk, int location) { if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk < - (int)info_ptr->unknown_chunks_num) + info_ptr->unknown_chunks_num) info_ptr->unknown_chunks[chunk].location = (png_byte)location; } #endif diff --git a/pngtest.c b/pngtest.c index 1299c260a..a46d94bcd 100644 --- a/pngtest.c +++ b/pngtest.c @@ -1145,19 +1145,19 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED { png_unknown_chunkp unknowns; - int num_unknowns = (int)png_get_unknown_chunks(read_ptr, read_info_ptr, + int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr, &unknowns); if (num_unknowns) { - png_size_t i; + int i; png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns, num_unknowns); /* Copy the locations from the read_info_ptr. The automatically * generated locations in write_info_ptr are wrong because we * haven't written anything yet. */ - for (i = 0; i < (png_size_t)num_unknowns; i++) + for (i = 0; i < num_unknowns; i++) png_set_unknown_chunk_location(write_ptr, write_info_ptr, i, unknowns[i].location); } @@ -1318,21 +1318,19 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED { png_unknown_chunkp unknowns; - int num_unknowns; - - num_unknowns = (int)png_get_unknown_chunks(read_ptr, end_info_ptr, + int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr, &unknowns); if (num_unknowns) { - png_size_t i; + int i; png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns, num_unknowns); /* Copy the locations from the read_info_ptr. The automatically * generated locations in write_end_info_ptr are wrong because we * haven't written the end_info yet. */ - for (i = 0; i < (png_size_t)num_unknowns; i++) + for (i = 0; i < num_unknowns; i++) png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i, unknowns[i].location); } diff --git a/pngtrans.c b/pngtrans.c index fff503245..1c47061d9 100644 --- a/pngtrans.c +++ b/pngtrans.c @@ -581,7 +581,8 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) } if (flags & PNG_FLAG_STRIP_ALPHA) - row_info->color_type &= ~PNG_COLOR_MASK_ALPHA; + row_info->color_type = (png_byte)(row_info->color_type & + ~PNG_COLOR_MASK_ALPHA); } } #endif diff --git a/pngvalid.c b/pngvalid.c index c17164c0b..ce7b66317 100644 --- a/pngvalid.c +++ b/pngvalid.c @@ -82,40 +82,35 @@ next_format(png_bytep colour_type, png_bytep bit_depth) *colour_type = 0, *bit_depth = 1; return 1; } - else switch (*colour_type) + + *bit_depth = (png_byte)(*bit_depth << 1); + + /* Palette images are restricted to 8 bit depth */ + if (*bit_depth <= 8 || (*colour_type != 3 && *bit_depth <= 16)) + return 1; + + /* Move to the next color type, or return 0 at the end. */ + switch (*colour_type) { case 0: - *bit_depth <<= 1; - if (*bit_depth <= 16) return 1; *colour_type = 2; *bit_depth = 8; return 1; case 2: - *bit_depth <<= 1; - if (*bit_depth <= 16) return 1; *colour_type = 3; *bit_depth = 1; return 1; case 3: - *bit_depth <<= 1; - if (*bit_depth <= 8) return 1; *colour_type = 4; *bit_depth = 8; return 1; case 4: - *bit_depth <<= 1; - if (*bit_depth <= 16) return 1; *colour_type = 6; *bit_depth = 8; return 1; - case 6: - *bit_depth <<= 1; - if (*bit_depth <= 16) return 1; - break; + default: + return 0; } - - /* Here at the end. */ - return 0; } static unsigned int @@ -171,10 +166,10 @@ typedef struct png_store_file typedef struct png_store { jmp_buf jmpbuf; - int verbose; + unsigned int verbose :1; + unsigned int treat_warnings_as_errors :1; int nerrors; int nwarnings; - int treat_warnings_as_errors; char test[64]; /* Name of test */ char error[128]; /* Read fields */ @@ -690,9 +685,9 @@ typedef struct png_modification * to add the chunk before the relevant chunk. */ png_uint_32 add; - int modified :1; /* Chunk was modified */ - int added :1; /* Chunk was added */ - int removed :1; /* Chunk was removed */ + unsigned int modified :1; /* Chunk was modified */ + unsigned int added :1; /* Chunk was added */ + unsigned int removed :1; /* Chunk was removed */ } png_modification; static void modification_reset(png_modification *pmm) @@ -1142,11 +1137,19 @@ standard_row(png_structp pp, png_byte buffer[STD_ROWMAX], png_byte colour_type, ++i; } return; + + default: + break; } png_error(pp, "internal error"); } +/* This is just to do the right cast - could be changed to a function to check + * 'bd' but there isn't much point. + */ +#define DEPTH(bd) ((png_byte)(1U << (bd))) + static void make_standard(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, int PNG_CONST bdloIn, int PNG_CONST bdhi) @@ -1181,7 +1184,7 @@ make_standard(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, continue; } - bit_depth = 1U << bdlo; + bit_depth = DEPTH(bdlo); h = standard_height(pp, colour_type, bit_depth), png_set_IHDR(pp, pi, standard_width(pp, colour_type, bit_depth), h, bit_depth, colour_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, @@ -1239,7 +1242,7 @@ test_standard(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, for (; bdlo <= bdhi; ++bdlo) { - png_byte bit_depth = 1U << bdlo; + png_byte bit_depth = DEPTH(bdlo); png_uint_32 h, y; size_t cb; png_structp pp; @@ -1761,6 +1764,8 @@ gamma_test(png_modifier *pm, PNG_CONST png_byte colour_type, /* Log the summary values too. */ if (colour_type == 0 || colour_type == 4) switch (bit_depth) { + case 1: + break; case 2: if (maxerrout > pm->error_gray_2) pm->error_gray_2 = maxerrout; break; case 4: @@ -1769,6 +1774,8 @@ gamma_test(png_modifier *pm, PNG_CONST png_byte colour_type, if (maxerrout > pm->error_gray_8) pm->error_gray_8 = maxerrout; break; case 16: if (maxerrout > pm->error_gray_16) pm->error_gray_16 = maxerrout; break; + default: + png_error(pp, "bad bit depth (internal: 1)"); } else if (colour_type == 2 || colour_type == 6) switch (bit_depth) { @@ -1776,6 +1783,8 @@ gamma_test(png_modifier *pm, PNG_CONST png_byte colour_type, if (maxerrout > pm->error_color_8) pm->error_color_8 = maxerrout; break; case 16: if (maxerrout > pm->error_color_16) pm->error_color_16 = maxerrout; break; + default: + png_error(pp, "bad bit depth (internal: 2)"); } } @@ -2029,7 +2038,7 @@ int main(int argc, PNG_CONST char **argv) else if (strcmp(*argv, "-l") == 0) pm.log = 1; else if (strcmp(*argv, "-q") == 0) - pm.this.verbose = pm.log = summary = 0; + summary = pm.this.verbose = pm.log = 0; else if (strcmp(*argv, "-g") == 0) pm.ngammas = (sizeof gammas)/(sizeof gammas[0]); else if (strcmp(*argv, "-w") == 0) @@ -2073,7 +2082,7 @@ int main(int argc, PNG_CONST char **argv) /* Perform the standard and gamma tests. */ if (!speed) perform_standard_test(&pm); - perform_gamma_test(&pm, speed, summary && !speed); + perform_gamma_test(&pm, speed != 0, summary && !speed); if (summary && !speed) printf("Results using %s point arithmetic %s\n", #if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || PNG_LIBPNG_VER < 10500 diff --git a/pngwrite.c b/pngwrite.c index 34131db2c..ea34a7cae 100644 --- a/pngwrite.c +++ b/pngwrite.c @@ -712,6 +712,7 @@ png_write_row(png_structp png_ptr, png_const_bytep row) return; } break; + case 1: if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) { @@ -719,6 +720,7 @@ png_write_row(png_structp png_ptr, png_const_bytep row) return; } break; + case 2: if ((png_ptr->row_number & 0x07) != 4) { @@ -726,6 +728,7 @@ png_write_row(png_structp png_ptr, png_const_bytep row) return; } break; + case 3: if ((png_ptr->row_number & 0x03) || png_ptr->width < 3) { @@ -733,6 +736,7 @@ png_write_row(png_structp png_ptr, png_const_bytep row) return; } break; + case 4: if ((png_ptr->row_number & 0x03) != 2) { @@ -740,6 +744,7 @@ png_write_row(png_structp png_ptr, png_const_bytep row) return; } break; + case 5: if ((png_ptr->row_number & 0x01) || png_ptr->width < 2) { @@ -747,6 +752,7 @@ png_write_row(png_structp png_ptr, png_const_bytep row) return; } break; + case 6: if (!(png_ptr->row_number & 0x01)) { @@ -754,6 +760,9 @@ png_write_row(png_structp png_ptr, png_const_bytep row) return; } break; + + default: /* error: ignore it */ + break; } } #endif @@ -782,10 +791,10 @@ png_write_row(png_structp png_ptr, png_const_bytep row) #ifdef PNG_WRITE_INTERLACING_SUPPORTED /* Handle interlacing */ if (png_ptr->interlaced && png_ptr->pass < 6 && - (png_ptr->transformations & PNG_INTERLACE)) + (png_ptr->transformations & PNG_INTERLACE)) { png_do_write_interlace(&(png_ptr->row_info), - png_ptr->row_buf + 1, png_ptr->pass); + png_ptr->row_buf + 1, png_ptr->pass); /* This should always get caught above, but still ... */ if (!(png_ptr->row_info.width)) { @@ -810,7 +819,7 @@ png_write_row(png_structp png_ptr, png_const_bytep row) * 5. The color_type is RGB or RGBA */ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && - (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) + (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) { /* Intrapixel differencing */ png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); @@ -931,20 +940,20 @@ png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) { if (png_ptr != NULL) { - png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - if (png_ptr->num_chunk_list) - { - png_free(png_ptr, png_ptr->chunk_list); - png_ptr->num_chunk_list = 0; - } + if (png_ptr->num_chunk_list) + { + png_free(png_ptr, png_ptr->chunk_list); + png_ptr->num_chunk_list = 0; + } #endif } #ifdef PNG_USER_MEM_SUPPORTED png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, - (png_voidp)mem_ptr); + (png_voidp)mem_ptr); #else png_destroy_struct((png_voidp)info_ptr); #endif @@ -1104,7 +1113,8 @@ png_set_filter(png_structp png_ptr, int method, int filters) if (png_ptr->prev_row == NULL) { png_warning(png_ptr, "Can't add Up filter after starting"); - png_ptr->do_filter &= ~PNG_FILTER_UP; + png_ptr->do_filter = (png_byte)(png_ptr->do_filter & + ~PNG_FILTER_UP); } else @@ -1120,7 +1130,8 @@ png_set_filter(png_structp png_ptr, int method, int filters) if (png_ptr->prev_row == NULL) { png_warning(png_ptr, "Can't add Average filter after starting"); - png_ptr->do_filter &= ~PNG_FILTER_AVG; + png_ptr->do_filter = (png_byte)(png_ptr->do_filter & + ~PNG_FILTER_AVG); } else @@ -1284,8 +1295,8 @@ png_init_filter_heuristics(png_structp png_ptr, int heuristic_method, #ifdef PNG_FLOATING_POINT_SUPPORTED void PNGAPI png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, - int num_weights, png_const_doublep filter_weights, - png_const_doublep filter_costs) + int num_weights, png_const_doublep filter_weights, + png_const_doublep filter_costs) { png_debug(1, "in png_set_filter_heuristics"); @@ -1339,8 +1350,8 @@ png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, #ifdef PNG_FIXED_POINT_SUPPORTED void PNGAPI png_set_filter_heuristics_fixed(png_structp png_ptr, int heuristic_method, - int num_weights, png_const_fixed_point_p filter_weights, - png_const_fixed_point_p filter_costs) + int num_weights, png_const_fixed_point_p filter_weights, + png_const_fixed_point_p filter_costs) { png_debug(1, "in png_set_filter_heuristics_fixed"); @@ -1382,11 +1393,21 @@ png_set_filter_heuristics_fixed(png_structp png_ptr, int heuristic_method, 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_uint_32 tmp; - png_ptr->filter_costs[i] = (png_uint_16) - ((PNG_COST_FACTOR * filter_costs[i] +PNG_FP_HALF)/PNG_FP_1); + /* Use a 32 bit unsigned temporary here because otherwise the + * intermediate value will be a 32 bit *signed* integer (ANSI rules) + * and this will get the wrong answer on division. + */ + tmp = PNG_COST_FACTOR*PNG_FP_1 + (filter_costs[i]/2); + tmp /= filter_costs[i]; + + png_ptr->inv_filter_costs[i] = (png_uint_16)tmp; + + tmp = PNG_COST_FACTOR * filter_costs[i] + PNG_FP_HALF; + tmp /= PNG_FP_1; + + png_ptr->filter_costs[i] = (png_uint_16)tmp; } } } @@ -1444,10 +1465,10 @@ png_set_compression_window_bits(png_structp png_ptr, int window_bits) #ifndef WBITS_8_OK /* Avoid libpng bug with 256-byte windows */ if (window_bits == 8) - { - png_warning(png_ptr, "Compression window is being reset to 512"); - window_bits = 9; - } + { + png_warning(png_ptr, "Compression window is being reset to 512"); + window_bits = 9; + } #endif png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS; @@ -1497,7 +1518,7 @@ png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr #ifdef PNG_INFO_IMAGE_SUPPORTED void PNGAPI png_write_png(png_structp png_ptr, png_infop info_ptr, - int transforms, voidp params) + int transforms, voidp params) { if (png_ptr == NULL || info_ptr == NULL) return; diff --git a/pngwutil.c b/pngwutil.c index 435288e44..59141ce21 100644 --- a/pngwutil.c +++ b/pngwutil.c @@ -740,11 +740,13 @@ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) half_z_window_size >>= 1; } z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); - if (data[0] != (png_byte)z_cmf) + if (data[0] != z_cmf) { + int tmp; data[0] = (png_byte)z_cmf; - data[1] &= 0xe0; - data[1] += (png_byte)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f); + tmp = data[1] & 0xe0; + tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; + data[1] = (png_byte)tmp; } } } @@ -1868,14 +1870,14 @@ png_write_finish_row(png_structp png_ptr) break; png_ptr->usr_width = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; png_ptr->num_rows = (png_ptr->height + - png_pass_yinc[png_ptr->pass] - 1 - - png_pass_ystart[png_ptr->pass]) / - png_pass_yinc[png_ptr->pass]; + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; if (png_ptr->transformations & PNG_INTERLACE) break; @@ -1920,6 +1922,7 @@ png_write_finish_row(png_structp png_ptr) { if (png_ptr->zstream.msg != NULL) png_error(png_ptr, png_ptr->zstream.msg); + else png_error(png_ptr, "zlib error"); } @@ -1999,6 +2002,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) break; } + case 2: { png_bytep sp; @@ -2035,6 +2039,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) break; } + case 4: { png_bytep sp; @@ -2068,6 +2073,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) *dp = (png_byte)d; break; } + default: { png_bytep sp; @@ -2135,8 +2141,8 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) #ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS) { - /* These will never be selected so we need not test them. */ - filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH); + /* These will never be selected so we need not test them. */ + filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH); } #endif @@ -2275,10 +2281,10 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) { lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; } } @@ -2303,6 +2309,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) sum += (v < 128) ? v : 256 - v; } + for (lp = row_buf + 1; i < row_bytes; i++, rp++, lp++, dp++) {