diff --git a/contrib/libtests/pngvalid.c b/contrib/libtests/pngvalid.c index 2c17268a6..28a7ab83f 100644 --- a/contrib/libtests/pngvalid.c +++ b/contrib/libtests/pngvalid.c @@ -116,6 +116,16 @@ typedef png_byte *png_const_bytep; # define png_const_structp png_structp #endif +#ifndef RELEASE_BUILD + /* RELEASE_BUILD is true for releases and release candidates: */ +# define RELEASE_BUILD (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC) +#endif +#if RELEASE_BUILD +# define debugonly(something) +#else /* !RELEASE_BUILD */ +# define debugonly(something) something +#endif /* !RELEASE_BUILD */ + #include /* For floating point constants */ #include /* For malloc */ #include /* For memcpy, memset */ @@ -276,7 +286,8 @@ make_four_random_bytes(png_uint_32* seed, png_bytep bytes) make_random_bytes(seed, bytes, 4); } -#if defined PNG_READ_SUPPORTED || defined PNG_WRITE_tRNS_SUPPORTED +#if defined PNG_READ_SUPPORTED || defined PNG_WRITE_tRNS_SUPPORTED ||\ + defined PNG_WRITE_FILTER_SUPPORTED static void randomize(void *pv, size_t size) { @@ -284,19 +295,55 @@ randomize(void *pv, size_t size) make_random_bytes(random_seed, pv, size); } -#define RANDOMIZE(this) randomize(&(this), sizeof (this)) -#endif /* READ || WRITE_tRNS */ +#define R8(this) randomize(&(this), sizeof (this)) -#ifdef PNG_READ_TRANSFORMS_SUPPORTED +static void r16(png_uint_16p p16, size_t count) +{ + size_t i; + + for (i=0; i= PNG_FILTER_VALUE_LAST ? PNG_ALL_FILTERS : nfilter); + { + int filters = 8 << random_mod(PNG_FILTER_VALUE_LAST); - if (nfilter-- == 0) - nfilter = PNG_FILTER_VALUE_LAST-1; + if (pass == 0 && y == 0 && + (filters < PNG_FILTER_UP || w == 1U)) + filters |= PNG_FILTER_UP; + + png_set_filter(pp, 0/*method*/, filters); + } # endif png_write_row(pp, row); @@ -4244,62 +4322,71 @@ make_error(png_store* const ps, png_byte const colour_type, #undef exception__env /* And clear these flags */ - ps->expect_error = 0; ps->expect_warning = 0; - /* Now write the whole image, just to make sure that the detected, or - * undetected, errro has not created problems inside libpng. - */ - if (png_get_rowbytes(pp, pi) != - transform_rowsize(pp, colour_type, bit_depth)) - png_error(pp, "row size incorrect"); + if (ps->expect_error) + ps->expect_error = 0; else { - int npasses = set_write_interlace_handling(pp, interlace_type); - int pass; + /* Now write the whole image, just to make sure that the detected, or + * undetected, errro has not created problems inside libpng. This + * doesn't work if there was a png_error in png_write_info because that + * can abort before PLTE was written. + */ + if (png_get_rowbytes(pp, pi) != + transform_rowsize(pp, colour_type, bit_depth)) + png_error(pp, "row size incorrect"); - if (npasses != npasses_from_interlace_type(pp, interlace_type)) - png_error(pp, "write: png_set_interlace_handling failed"); - - for (pass=0; pass 0) - interlace_row(buffer, buffer, - bit_size(pp, colour_type, bit_depth), w, pass, - 0/*data always bigendian*/); - else - continue; - } -# endif /* do_own_interlace */ + if (interlace_type == PNG_INTERLACE_ADAM7) + { + /* The row must not be written if it doesn't exist, + * notice that there are two conditions here, either the + * row isn't ever in the pass or the row would be but + * isn't wide enough to contribute any pixels. In fact + * the wPass test can be used to skip the whole y loop + * in this case. + */ + if (PNG_ROW_IN_INTERLACE_PASS(y, pass) && + PNG_PASS_COLS(w, pass) > 0) + interlace_row(buffer, buffer, + bit_size(pp, colour_type, bit_depth), w, pass, + 0/*data always bigendian*/); + else + continue; + } +# endif /* do_own_interlace */ - png_write_row(pp, buffer); + png_write_row(pp, buffer); + } } - } - } + } /* image writing */ - png_write_end(pp, pi); + png_write_end(pp, pi); + } /* The following deletes the file that was just written. */ store_write_reset(ps); @@ -6257,7 +6344,7 @@ transform_range_check(png_const_structp pp, unsigned int r, unsigned int g, unsigned int max = (1U< limit || !(out >= in_min && out <= in_max)) + if (debugonly(err > limit ||) !(out >= in_min && out <= in_max)) { char message[256]; size_t pos; @@ -7213,7 +7300,7 @@ image_transform_png_set_rgb_to_gray_ini(const image_transform *this, png_uint_32 ru; double total; - RANDOMIZE(ru); + R32(ru); data.green_coefficient = total = (ru & 0xffff) / 65535.; ru >>= 16; data.red_coefficient = (1 - total) * (ru & 0xffff) / 65535.; @@ -7274,14 +7361,12 @@ image_transform_png_set_rgb_to_gray_ini(const image_transform *this, * When DIGITIZE is set because a pre-1.7 version of libpng is being * tested allow a bigger slack. * - * NOTE: this magic number was determined by experiment to be about - * 1.263. There's no great merit to the value below, however it only - * affects the limit used for checking for internal calculation errors, - * not the actual limit imposed by pngvalid on the output errors. + * NOTE: this number only affects the internal limit check in pngvalid, + * it has no effect on the limits applied to the libpng values. */ that->pm->limit += pow( # if DIGITIZE - 1.3 + 2.0 # else 1.0 # endif @@ -7443,7 +7528,7 @@ image_transform_png_set_rgb_to_gray_mod(const image_transform *this, /* Image now has RGB channels... */ # if DIGITIZE { - const png_modifier *pm = display->pm; + png_modifier *pm = display->pm; const unsigned int sample_depth = that->sample_depth; const unsigned int calc_depth = (pm->assume_16_bit_calculations ? 16 : sample_depth); @@ -7592,9 +7677,11 @@ image_transform_png_set_rgb_to_gray_mod(const image_transform *this, else { err = fabs(grayhi-gray); + if (fabs(gray - graylo) > err) err = fabs(graylo-gray); +#if !RELEASE_BUILD /* Check that this worked: */ if (err > pm->limit) { @@ -7605,11 +7692,13 @@ image_transform_png_set_rgb_to_gray_mod(const image_transform *this, pos = safecatd(buffer, sizeof buffer, pos, err, 6); pos = safecat(buffer, sizeof buffer, pos, " exceeds limit "); pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6); - png_error(pp, buffer); + png_warning(pp, buffer); + pm->limit = err; } +#endif /* !RELEASE_BUILD */ } } -# else /* DIGITIZE */ +# else /* !DIGITIZE */ { double r = that->redf; double re = that->rede; @@ -7668,7 +7757,7 @@ image_transform_png_set_rgb_to_gray_mod(const image_transform *this, * lookups in the calculation and each introduces a quantization * error defined by the table size. */ - const png_modifier *pm = display->pm; + png_modifier *pm = display->pm; double in_qe = (that->sample_depth > 8 ? .5/65535 : .5/255); double out_qe = (that->sample_depth > 8 ? .5/65535 : (pm->assume_16_bit_calculations ? .5/(1<max_gamma_8) : @@ -7718,6 +7807,7 @@ image_transform_png_set_rgb_to_gray_mod(const image_transform *this, else err -= in_qe; +#if !RELEASE_BUILD /* Validate that the error is within limits (this has caused * problems before, it's much easier to detect them here.) */ @@ -7730,8 +7820,10 @@ image_transform_png_set_rgb_to_gray_mod(const image_transform *this, pos = safecatd(buffer, sizeof buffer, pos, err, 6); pos = safecat(buffer, sizeof buffer, pos, " exceeds limit "); pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6); - png_error(pp, buffer); + png_warning(pp, buffer); + pm->limit = err; } +#endif /* !RELEASE_BUILD */ } } # endif /* !DIGITIZE */ @@ -7802,7 +7894,7 @@ image_transform_png_set_background_set(const image_transform *this, * so we need to know what that is! The background colour is stored in the * transform_display. */ - RANDOMIZE(random_bytes); + R8(random_bytes); /* Read the random value, for colour type 3 the background colour is actually * expressed as a 24bit rgb, not an index. @@ -7830,7 +7922,7 @@ image_transform_png_set_background_set(const image_transform *this, /* Extract the background colour from this image_pixel, but make sure the * unused fields of 'back' are garbage. */ - RANDOMIZE(back); + R8(back); if (colour_type & PNG_COLOR_MASK_COLOR) { @@ -8136,7 +8228,7 @@ image_transform_png_set_filler_set(const image_transform *this, * filler. The 'filler' value has all 32 bits set, but only bit_depth * will be used. At this point we don't know bit_depth. */ - RANDOMIZE(data.filler); + R32(data.filler); data.flags = random_choice(); png_set_filler(pp, data.filler, data.flags); @@ -8209,7 +8301,7 @@ image_transform_png_set_add_alpha_set(const image_transform *this, * filler. The 'filler' value has all 32 bits set, but only bit_depth * will be used. At this point we don't know bit_depth. */ - RANDOMIZE(data.filler); + R32(data.filler); data.flags = random_choice(); png_set_add_alpha(pp, data.filler, data.flags); @@ -11296,6 +11388,9 @@ int main(int argc, char **argv) else if (strcmp(*argv, "-w") == 0 || strcmp(*argv, "--strict") == 0) + pm.this.treat_warnings_as_errors = 1; /* NOTE: this is the default! */ + + else if (strcmp(*argv, "--nostrict") == 0) pm.this.treat_warnings_as_errors = 0; else if (strcmp(*argv, "--speed") == 0)