Squashed commit of the following:

commit fc4b42b1d56f95efeb1b9fe42dc35b7d98d246bb
Merge: 74516c7 9eb1413
Author: John Bowler <jbowler@acm.org>
Date:   Sun Nov 22 19:37:54 2015 -0800

    Merge branch 'libpng17' into libpng17-filter-enhancements

commit 74516c7257f1a28a69985684c5673caa390c700a
Author: John Bowler <jbowler@acm.org>
Date:   Sun Nov 22 19:32:43 2015 -0800

    Make check full pass on gcc/g++ x86_64

    Signed-off-by: John Bowler <jbowler@acm.org>

commit e891e34737fc0bc9ee873a5d56b83c1e777b990c
Author: John Bowler <jbowler@acm.org>
Date:   Sun Nov 22 12:01:37 2015 -0800

    Checkpoint: write buffering changes

    This version fails in pngvalid --size because of an error handling very narrow
    images, otherwise a standard build passes make check.

    Signed-off-by: John Bowler <jbowler@acm.org>

commit 457a046ebdab737eefb477126cf855e49df6de50
Author: John Bowler <jbowler@acm.org>
Date:   Sun Nov 22 06:39:36 2015 -0800

    Fix previous bad merge

commit b4f426c97267317637d43f41fe0b05d1659bc63d
Merge: 07b9b90 a3458a6
Author: John Bowler <jbowler@acm.org>
Date:   Sun Nov 22 06:32:34 2015 -0800

    Merge branch 'libpng17' into libpng17-filter-enhancements

commit 07b9b90dfd653b744dbc3710b096facf6b4605f6
Merge: ed43306 5592e0b
Author: John Bowler <jbowler@acm.org>
Date:   Sat Nov 21 17:07:23 2015 -0800

    Merge branch 'libpng17' into libpng17-filter-enhancements

commit ed43306599f7039a90187862db82273fca3a4c3d
Merge: 772aed7 d3c0359
Author: John Bowler <jbowler@acm.org>
Date:   Tue Nov 17 17:47:26 2015 -0800

    Merge branch 'libpng17' into libpng17-filter-enhancements

commit 772aed72378df9c8fccc5a4594b095d02d410a9c
Merge: 73ae431 801608f
Author: John Bowler <jbowler@acm.org>
Date:   Mon Nov 16 14:26:38 2015 -0800

    Merge branch 'libpng17' into libpng17-filter-enhancements

commit 73ae4316cb6db7d7f6756583a1c213c35ca4e3f4
Merge: 687e6e3 c09b3ab
Author: John Bowler <jbowler@acm.org>
Date:   Sun Nov 15 09:31:30 2015 -0800

    Merge branch 'libpng17' into libpng17-filter-enhancements

commit 687e6e393e9d0220c2a12ec474aa01b83c5e9f25
Merge: fedd6da e916d9b
Author: John Bowler <jbowler@acm.org>
Date:   Thu Nov 5 08:45:14 2015 -0800

    Merge branch 'libpng17' into libpng17-filter-enhancements

commit fedd6da8798a14b2e002b0bc1379f5a09a03598a
Merge: 2e2fc5f ea41fd2
Author: John Bowler <jbowler@acm.org>
Date:   Tue Nov 3 21:05:01 2015 -0800

    Merge branch 'libpng17' into libpng17-filter-enhancements

commit 2e2fc5f6d7678b710c52b7ea081ac4add677d8d5
Merge: 990d5f8 5b05197
Author: John Bowler <jbowler@acm.org>
Date:   Mon Oct 12 08:28:30 2015 -0700

    Merge branch 'libpng17' into libpng17-filter-enhancements

commit 990d5f88688635dc0888657b689e30ffe7e7a7b3
Author: John Bowler <jbowler@acm.org>
Date:   Sun Oct 4 17:04:53 2015 -0700

    Read row buffer changes

    The read code now allocates one row buffer of the size of the input PNG row and,
    only if required, one buffer of the size of the output.

    The output buffer is required for the progressive reader (always) and for the
    sequential reader if libpng is de-interlacing an image (because the output row
    is used multiple times if png_read_row is called with a display row parameter.)

    This should reduce memory utilization by libpng significantly, but it has no
    detectable effect on overall performance figures of the test programs, these are
    probably dominated by memory allocations for the whole image within the test
    programs.

    Signed-off-by: John Bowler <jbowler@acm.org>

commit 527bf989bf0e30440f9e07a5544a6ebb1d6fd039
Merge: 50ebbc2 9099254
Author: John Bowler <jbowler@acm.org>
Date:   Sat Oct 3 13:39:17 2015 -0700

    Merge branch 'libpng17' into libpng17-filter-enhancements

commit 50ebbc2c9a24cf1a6b428db53d55fbd5af4d6be6
Merge: 21a7f40 2cd6d56
Author: John Bowler <jbowler@acm.org>
Date:   Sat Oct 3 11:16:32 2015 -0700

    Merge branch 'libpng17' into libpng17-filter-enhancements

commit 21a7f401ab40c79ead9e35882a8066e2cf1d6902
Merge: b512e1c 15a143e
Author: John Bowler <jbowler@acm.org>
Date:   Wed Sep 30 19:01:23 2015 -0700

    Merge branch 'libpng17' into libpng17-filter-enhancements

commit b512e1c2c5bfe6df8b6dca32f862d325ec22115e
Author: John Bowler <jbowler@acm.org>
Date:   Wed Sep 30 17:33:34 2015 -0700

    Transform rewrite: perform transforms in small chunks

    The intent of this change is to reduce the memory footprint during transform
    sequences by performing transforms in fixed (small) sized blocks of pixels.
    The change is incomplete; the filter code still works row-by-row, so the whole
    tranform also works row-by-row, the intent is to fix this so that everything
    works in small(ish) chunks.

    At present the change has no discernable effect on pngvalid --speed or pngstest
    with (e.g.) rgb-8-1.8.png; user time and (minor) page faults are the same in old
    and new versions.  The same applies to real-world 15MP PNG images; even on these
    the presence of the filter code causes a cyclical progress through memory which
    will interfere with any caching otherwise possible (useful word, 'otherwise'.)

    Signed-off-by: John Bowler <jbowler@acm.org>

commit 781cb3699b92beb0e6bc5e03cef8fba820267082
Author: John Bowler <jbowler@acm.org>
Date:   Wed Sep 30 17:12:53 2015 -0700

    Fix NO_WRITE_INTERLACE in pngvalid.c

    The support for writing interlaced images directly from libpng 1.7 was
    unintentionally disabled (INTERLACE_LAST was defined incorrectly, excluding the
    interlaced images).  This obscured the fact that the transform and error test
    case generators lacked the support for writing interlaced images from libpng.

    Signed-off-by: John Bowler <jbowler@acm.org>

commit 406ee2fd7946a384f1d7713712dc646080c5c52c
Author: John Bowler <jbowler@acm.org>
Date:   Wed Sep 30 17:11:40 2015 -0700

    Add pngvalid --transform --interlace test

    This increases code coverage by generating test cases with smaller length rows
    as a result of the interlacing.  Without this packswap handling was incompletely
    tested.

    Signed-off-by: John Bowler <jbowler@acm.org>

Signed-off-by: John Bowler <jbowler@acm.org>
This commit is contained in:
John Bowler
2015-11-22 19:41:41 -08:00
parent 9eb14136d8
commit 0f2554a5e6
18 changed files with 2299 additions and 2053 deletions

View File

@@ -558,7 +558,7 @@ png_run_transform_list_backwards(png_structp png_ptr, png_transform_controlp tc)
/* Better late than never (if this fires a memory overwrite has happened):
*/
affirm(max_depth <= png_ptr->row_max_pixel);
affirm(max_depth <= png_ptr->row_max_pixel_depth);
}
}
#endif /* WRITE */
@@ -832,52 +832,42 @@ png_set_check_for_invalid_index(png_structrp png_ptr, int enabled)
void /* PRIVATE */
png_init_row_info(png_structrp png_ptr)
{
unsigned int max_depth = PNG_PIXEL_DEPTH(*png_ptr);
/* PNG pixels never exceed 64 bits in depth: */
const png_byte png_depth =
png_check_bits(png_ptr, PNG_PIXEL_DEPTH(*png_ptr), 7U);
#ifdef PNG_TRANSFORM_MECH_SUPPORTED
# ifdef PNG_PALETTE_MAX_SUPPORTED
/* The palette index check stuff is *on* automatically. To handle this
* add it here, if it is supported.
*
* The logic here is a little complex because of the plethora of
* #defines controlling this stuff.
*/
# undef PNG_READ_CHECK_PALETTE
# undef PNG_WRITE_CHECK_PALETTE
# if defined(PNG_READ_GET_PALETTE_MAX_SUPPORTED) ||\
defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED)
# ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
# define PNG_READ_CHECK_PALETTE \
(png_ptr->read_struct && !png_ptr->palette_index_check_disabled)
# else
# define PNG_READ_CHECK_PALETTE (png_ptr->read_struct)
# ifdef PNG_TRANSFORM_MECH_SUPPORTED
/* The palette index check stuff is *on* automatically. To handle this
* add it here, if it is supported.
*/
# ifdef PNG_PALETTE_MAX_SUPPORTED
/* The logic here is a little complex because of the plethora of
* #defines controlling this stuff.
*/
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE/* fast escape */ && (
# if defined (PNG_READ_GET_PALETTE_MAX_SUPPORTED) ||\
defined (PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED)
(png_ptr->read_struct
# ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
&& !png_ptr->palette_index_check_disabled)
# endif /* READ_CHECK_FOR_INVALID_INDEX */
# else /* no READ support */
0
# endif /* READ checks */
||
# if defined (PNG_WRITE_GET_PALETTE_MAX_SUPPORTED) ||\
defined (PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
(!png_ptr->read_struct
# ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
&& !png_ptr->palette_index_check_disabled)
# endif /* WRITE_CHECK_FOR_INVALID_INDEX */
# else /* no WRITE support */
0
# endif /* WRITE checks */
))
png_add_transform(png_ptr, 0/*size*/, palette_max_init,
PNG_TR_CHECK_PALETTE);
# endif
# else /* no READ support */
# define PNG_READ_CHECK_PALETTE 0
# endif
# if defined(PNG_WRITE_GET_PALETTE_MAX_SUPPORTED) ||\
defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
# ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
# define PNG_WRITE_CHECK_PALETTE \
(!png_ptr->read_struct && !png_ptr->palette_index_check_disabled)
# else
# define PNG_WRITE_CHECK_PALETTE (!png_ptr->read_struct)
# endif
# else /* no WRITE support */
# define PNG_WRITE_CHECK_PALETTE 0
# endif
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE/* fast escape */ &&
(PNG_READ_CHECK_PALETTE || PNG_WRITE_CHECK_PALETTE))
{
png_add_transform(png_ptr, 0/*size*/, palette_max_init,
PNG_TR_CHECK_PALETTE);
}
# undef PNG_READ_CHECK_PALETTE
# undef PNG_WRITE_CHECK_PALETTE
# endif /* PALETTE_MAX */
/* Application transforms may change the format of the data or, when
* producing interlaced images, the number of pixels in a line. This code
@@ -894,9 +884,9 @@ png_init_row_info(png_structrp png_ptr)
affirm(tc.bit_depth <= 32);
png_ptr->row_bit_depth = png_check_bits(png_ptr, tc.bit_depth, 6);
png_ptr->row_range = png_check_bits(png_ptr, tc.range, 3);
# ifdef PNG_READ_GAMMA_SUPPORTED
png_ptr->row_gamma = tc.gamma;
# endif /* READ_GAMMA */
# ifdef PNG_READ_GAMMA_SUPPORTED
png_ptr->row_gamma = tc.gamma;
# endif /* READ_GAMMA */
/* The above may have cancelled all the transforms in the list. */
if (png_ptr->transform_list != NULL)
@@ -905,25 +895,60 @@ png_init_row_info(png_structrp png_ptr)
* maximum pixel depth. At this point the transforms can swap
* out their initialization code.
*/
unsigned int depth = init_transform_mech(png_ptr, &tc, 0/*final*/);
unsigned int max_depth =
init_transform_mech(png_ptr, &tc, 0/*final*/);
if (depth > max_depth)
max_depth = depth;
# ifdef PNG_READ_TRANSFORMS_SUPPORTED
/* Set this now because it only gets resolved finally at this
* point.
/* init_transform_mech is expected to take the input depth into
* account:
*/
png_ptr->invalid_info = tc.invalid_info;
# endif /* READ_TRANSFORMS */
debug(max_depth >= png_depth);
if (max_depth < png_depth)
max_depth = png_depth;
affirm(max_depth <= (png_ptr->read_struct ? 128U : 64U));
# ifdef PNG_READ_TRANSFORMS_SUPPORTED
/* Set this now because it only gets resolved finally at this
* point.
*/
png_ptr->invalid_info = tc.invalid_info;
# endif /* READ_TRANSFORMS */
/* And check the transform fields: */
affirm(png_ptr->row_format == tc.format &&
png_ptr->row_range == tc.range &&
png_ptr->row_bit_depth == tc.bit_depth);
# ifdef PNG_READ_GAMMA_SUPPORTED
affirm(png_ptr->row_gamma == tc.gamma);
# endif /* READ_GAMMA */
# ifdef PNG_READ_GAMMA_SUPPORTED
affirm(png_ptr->row_gamma == tc.gamma);
# endif /* READ_GAMMA */
png_ptr->row_max_pixel_depth =
png_check_bits(png_ptr, max_depth, 8U);
/* On 'read' input_depth is the PNG pixel depth and output_depth is
* the depth of the pixels passed to the application, but on 'write'
* the transform list is reversed so output_depth is the PNG depth
* and input_depth the application depth.
*/
{
const png_byte app_depth =
png_check_bits(png_ptr, PNG_TC_PIXEL_DEPTH(tc), 8U);
affirm(app_depth <= max_depth);
if (png_ptr->read_struct)
{
png_ptr->row_input_pixel_depth = png_depth;
png_ptr->row_output_pixel_depth = app_depth;
}
else
{
png_ptr->row_input_pixel_depth = app_depth;
png_ptr->row_output_pixel_depth = png_depth;
}
return; /* to skip the default settings below */
}
}
}
@@ -934,46 +959,27 @@ png_init_row_info(png_structrp png_ptr)
png_ptr->row_bit_depth = png_check_bits(png_ptr, png_ptr->bit_depth,
6);
png_ptr->row_range = 0;
# ifdef PNG_READ_GAMMA_SUPPORTED
if ((png_ptr->colorspace.flags &
(PNG_COLORSPACE_INVALID|PNG_COLORSPACE_HAVE_GAMMA)) ==
PNG_COLORSPACE_HAVE_GAMMA)
png_ptr->row_gamma = png_ptr->colorspace.gamma;
# endif /* READ_GAMMA */
# ifdef PNG_READ_TRANSFORMS_SUPPORTED
png_ptr->invalid_info = 0U;
# endif /* READ_TRANSFORMS */
# ifdef PNG_READ_GAMMA_SUPPORTED
if ((png_ptr->colorspace.flags &
(PNG_COLORSPACE_INVALID|PNG_COLORSPACE_HAVE_GAMMA)) ==
PNG_COLORSPACE_HAVE_GAMMA)
png_ptr->row_gamma = png_ptr->colorspace.gamma;
# endif /* READ_GAMMA */
# ifdef PNG_READ_TRANSFORMS_SUPPORTED
png_ptr->invalid_info = 0U;
# endif /* READ_TRANSFORMS */
}
# endif /* TRANSFORM_MECH */
/* 'max_depth' is now the maximum size of a pixel, including intermediate
* results during the transforms. The current limit is 4 32-bit channels:
*/
affirm(max_depth <= 128);
png_ptr->row_max_pixel = png_check_bits(png_ptr, max_depth, 8);
#endif /* TRANSFORM_MECH */
/* png_calc_rowbytes does a png_error on overflow. This is how the libpng
* code validates that there won't be overflows on future PNG_ROWBYTES
* calls.
*
* The largest integer we can guarantee with ANSI-C is a 32-bit one (unsigned
* long). To allow the row to be accessed as png_uint_32[] this code sets
* the allocation to a multiple of 4:
/* We get here if there are no transforms therefore no change to the pixel
* bit depths.
*/
{
png_alloc_size_t rowbytes = png_calc_rowbytes(png_ptr, max_depth,
png_ptr->width);
png_alloc_size_t alloc = (rowbytes + 3U) & ~3U;
if (alloc < rowbytes)
png_error(png_ptr, "PNG row exceeds system limits");
png_ptr->row_allocated_bytes = alloc;
}
png_ptr->row_output_pixel_depth = png_ptr->row_max_pixel_depth =
png_ptr->row_input_pixel_depth = png_depth;
}
#if defined(PNG_READ_DEINTERLACE_SUPPORTED) || \
defined(PNG_WRITE_INTERLACING_SUPPORTED)
defined(PNG_WRITE_INTERLACE_SUPPORTED)
int PNGAPI
png_set_interlace_handling(png_structrp png_ptr)
{
@@ -999,26 +1005,25 @@ png_set_interlace_handling(png_structrp png_ptr)
else /* write */
{
# ifdef PNG_WRITE_INTERLACING_SUPPORTED
# ifdef PNG_WRITE_INTERLACE_SUPPORTED
if (png_ptr->interlaced)
{
png_ptr->do_interlace = 1;
png_set_write_interlace(png_ptr);
return PNG_INTERLACE_ADAM7_PASSES;
}
return 1;
# else /* !WRITE_INTERLACING */
# else /* !WRITE_INTERLACE */
png_app_error(png_ptr, "no interlace support");
/* return 0 below */
# endif /* !WRITE_INTERLACING */
# endif /* !WRITE_INTERLACE */
}
}
/* API CHANGE: 1.7.0: returns 0 if called with a NULL png_ptr */
return 0;
}
#endif /* READ_DEINTERLACE || WRITE_INTERLACING */
#endif /* READ_DEINTERLACE || WRITE_INTERLACE */
#ifdef PNG_MNG_READ_FEATURES_SUPPORTED
/* Undoes intrapixel differencing, this is called immediately after the PNG