[devel] Fixed interlace image handling and add test cases (John Bowler)

This commit is contained in:
John Bowler 2010-12-19 06:22:23 -06:00 committed by Glenn Randers-Pehrson
parent 4c93a7cb6f
commit 660c6e4d70
9 changed files with 1299 additions and 280 deletions

View File

@ -1,5 +1,5 @@
Libpng 1.5.0beta58 - December 9, 2010 Libpng 1.5.0beta58 - December 10, 2010
This is not intended to be a public release. It will be replaced 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. 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. offset of the png_ptr->rowbuf pointer into png_ptr->big_row_buf.
Added more blank lines for readability. Added more blank lines for readability.
version 1.5.0beta25 [December 9, 2010] version 1.5.0beta25 [December 10, 2010]
In pngpread.c: png_push_have_row() add check for new_row > height 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 Removed the now-redundant check for out-of-bounds new_row from example.c
@ -473,7 +473,8 @@ Version 1.5.0beta57 [December 9, 2010]
Added "--with-zprefix=<string>" to configure.ac Added "--with-zprefix=<string>" to configure.ac
Updated the prebuilt configuration files to autoconf version 2.68 Updated the prebuilt configuration files to autoconf version 2.68
Version 1.5.0beta58 [December 9, 2010] Version 1.5.0beta58 [December 19, 2010]
Fixed interlace image handling and add test cases (John Bowler)
Send comments/corrections/commendations to png-mng-implement at lists.sf.net: Send comments/corrections/commendations to png-mng-implement at lists.sf.net:
(subscription required; visit (subscription required; visit

View File

@ -3111,7 +3111,8 @@ Version 1.5.0beta57 [December 9, 2010]
Added "--with-zprefix=<string>" to configure.ac Added "--with-zprefix=<string>" to configure.ac
Updated the prebuilt configuration files to autoconf version 2.68 Updated the prebuilt configuration files to autoconf version 2.68
Version 1.5.0beta58 [December 9, 2010] Version 1.5.0beta58 [December 19, 2010]
Fixed interlace image handling and add test cases (John Bowler)
Send comments/corrections/commendations to png-mng-implement at lists.sf.net Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit (subscription required; visit

View File

@ -1,6 +1,6 @@
libpng-manual.txt - A description on how to use and modify libpng libpng-manual.txt - A description on how to use and modify libpng
libpng version 1.5.0beta58 - December 9, 2010 libpng version 1.5.0beta58 - December 10, 2010
Updated and distributed by Glenn Randers-Pehrson Updated and distributed by Glenn Randers-Pehrson
<glennrp at users.sourceforge.net> <glennrp at users.sourceforge.net>
Copyright (c) 1998-2010 Glenn Randers-Pehrson Copyright (c) 1998-2010 Glenn Randers-Pehrson
@ -11,7 +11,7 @@ libpng-manual.txt - A description on how to use and modify libpng
Based on: Based on:
libpng versions 0.97, January 1998, through 1.5.0beta58 - December 9, 2010 libpng versions 0.97, January 1998, through 1.5.0beta58 - December 10, 2010
Updated and distributed by Glenn Randers-Pehrson Updated and distributed by Glenn Randers-Pehrson
Copyright (c) 1998-2010 Glenn Randers-Pehrson Copyright (c) 1998-2010 Glenn Randers-Pehrson
@ -1475,13 +1475,15 @@ a single row_pointer instead of an array of row_pointers:
If the file is interlaced (interlace_type != 0 in the IHDR chunk), things If the file is interlaced (interlace_type != 0 in the IHDR chunk), things
get somewhat harder. The only current (PNG Specification version 1.2) get somewhat harder. The only current (PNG Specification version 1.2)
interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7) interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7);
is a somewhat complicated 2D interlace scheme, known as Adam7, that a somewhat complicated 2D interlace scheme, known as Adam7, that
breaks down an image into seven smaller images of varying size, based breaks down an image into seven smaller images of varying size, based
on an 8x8 grid. on an 8x8 grid. This number is defined (from libpng 1.5) as
PNG_INTERLACE_ADAM7_PASSES in png.h
libpng can fill out those images or it can give them to you "as is". libpng can fill out those images or it can give them to you "as is".
If you want them filled out, there are two ways to do that. The one It is almost always better to have libpng handle the interlacing for you.
If you want the images filled out, there are two ways to do that. The one
mentioned in the PNG specification is to expand each pixel to cover mentioned in the PNG specification is to expand each pixel to cover
those pixels that have not been read yet (the "rectangle" method). those pixels that have not been read yet (the "rectangle" method).
This results in a blocky image for the first pass, which gradually This results in a blocky image for the first pass, which gradually
@ -1491,65 +1493,20 @@ rest of the image remaining whatever colors they were initialized to
before the start of the read. The first method usually looks better, before the start of the read. The first method usually looks better,
but tends to be slower, as there are more pixels to put in the rows. but tends to be slower, as there are more pixels to put in the rows.
If you don't want libpng to handle the interlacing details, just call If, as is likely, you want libpng to expand the images, call this before
png_read_rows() seven times to read in all seven images. Each of the calling png_start_read_image() or png_read_update_info():
images is a valid image by itself, or they can all be combined on an
8x8 grid to form a single image (although if you intend to combine them
you would be far better off using the libpng interlace handling).
The first pass will return an image 1/8 as wide as the entire image
(every 8th column starting in column 0) and 1/8 as high as the original
(every 8th row starting in row 0), the second will be 1/8 as wide
(starting in column 4) and 1/8 as high (also starting in row 0). The
third pass will be 1/4 as wide (every 4th pixel starting in column 0) and
1/8 as high (every 8th row starting in row 4), and the fourth pass will
be 1/4 as wide and 1/4 as high (every 4th column starting in column 2,
and every 4th row starting in row 0). The fifth pass will return an
image 1/2 as wide, and 1/4 as high (starting at column 0 and row 2),
while the sixth pass will be 1/2 as wide and 1/2 as high as the original
(starting in column 1 and row 0). The seventh and final pass will be as
wide as the original, and 1/2 as high, containing all of the odd
numbered scanlines. Phew!
If you want to retrieve the separate images you must pass the correct
number of rows to each successive call of png_read_rows().
Calculating the number isn't quite as straightforward as the previous
paragraph might suggest; think about what happens with an image with a odd
number of rows, which passes get the extra row? To help you libpng 1.5.0
implements a function to return the number of rows and columns in the current
pass:
int number_of_rows = png_get_num_rows(png_ptr);
int number_of_cols = png_get_num_cols(png_ptr);
Simply call that before each call to png_read_rows(). You must call
png_start_read_image() (or png_read_update_info) before the first call to
ensure that the number libpng holds internally has been updated.
For very small interlaced images the number of rows or columns in a pass
can be zero.
You don't need to call png_read_rows() in this case, libpng will simply
skip to the next pass.
If you want libpng to expand the images, call this before calling
png_start_read_image() or png_read_update_info():
if (interlace_type == PNG_INTERLACE_ADAM7) if (interlace_type == PNG_INTERLACE_ADAM7)
number_of_passes number_of_passes
= png_set_interlace_handling(png_ptr); = png_set_interlace_handling(png_ptr);
This will return the number of passes needed. Currently, this This will return the number of passes needed. Currently, this is seven,
is seven, but may change if another interlace type is added. but may change if another interlace type is added. This function can be
This function can be called even if the file is not interlaced, called even if the file is not interlaced, where it will return one pass.
where it will return one pass. You then need to read the whole image 'number_of_passes' times. Each time
will distribute the pixels from the current pass to the correct place in
If you need to get the number of passes later (for example after the call the output image, so you need to supply the same rows to png_read_rows in
to png_start_read_image()) just call: each pass.
number_of_passes = png_get_num_passes(png_ptr);
This function just returns the number - it doesn't make any changes to the
libpng state.
If you are not going to display the image after each pass, but are If you are not going to display the image after each pass, but are
going to wait until the entire image is read in, use the sparkle going to wait until the entire image is read in, use the sparkle
@ -1575,6 +1532,94 @@ the second parameter NULL.
png_read_rows(png_ptr, NULL, row_pointers, png_read_rows(png_ptr, NULL, row_pointers,
number_of_rows); number_of_rows);
If you don't want libpng to handle the interlacing details, just call
png_read_rows() PNG_INTERLACE_ADAM7_PASSES times to read in all the images.
Each of the images is a valid image by itself, however you will almost
certainly need to distribute the pixels from each sub-image to the
correct place. This is where everything gets very tricky.
If you want to retrieve the separate images you must pass the correct
number of rows to each successive call of png_read_rows(). The calculation
gets pretty complicated for small images, where some sub-images may
not even exist because either their width or height ends up zero.
libpng provides two macros to help you in 1.5 and later versions:
png_uint_32 width = PNG_PASS_COLS(image_width, pass_number);
png_uint_32 height = PNG_PASS_ROWS(image_height, pass_number);
Respectively these tell you the width and height of the sub-image
corresponding to the numbered pass. 'pass' is in in the range 0 to 6 -
this can be confusing because the specification refers to the same passes
as 1 to 7! Be careful, you must check both the width and height before
calling png_read_rows() and not call it for that pass if either is zero.
You can, of course, read each sub-image row by row. If you want to
produce optimal code to make a pixel-by-pixel transformation of an
interlaced image this is the best approach; read each row of each pass,
transform it, and write it out to a new interlaced image.
If you want to de-interlace the image yourself libpng provides further
macros to help that tell you where to place the pixels in the output image.
Because the interlacing scheme is rectangular - sub-image pixels are always
arranged on a rectangular grid - all you need to know for each pass is the
starting column and row in the output image of the first pixel plus the
spacing between each pixel. As of libpng 1.5 there are four macros to
retrieve this information:
png_uint_32 x = PNG_PASS_START_COL(pass);
png_uint_32 y = PNG_PASS_START_ROW(pass);
png_uint_32 xStep = 1U << PNG_PASS_COL_SHIFT(pass);
png_uint_32 yStep = 1U << PNG_PASS_ROW_SHIFT(pass);
These allow you to write the obvious loop:
png_uint_32 input_y = 0;
png_uint_32 output_y = PNG_PASS_START_ROW(pass);
while (output_y < output_image_height)
{
png_uint_32 input_x = 0;
png_uint_32 output_x = PNG_PASS_START_COL(pass);
while (output_x < output_image_width)
{
image[output_y][output_x] = subimage[pass][input_y][input_x++];
output_x += xStep;
}
++input_y;
ouput_y += yStep;
}
Notice that the steps between successive output rows and columns are
returned as shifts. This is possible because the pixels in the subimages
are always a power of 2 apart - 1, 2, 4 or 8 pixels - in the original
image. In practice you may need to directly calculate the output coordinate
given an input coordinate. libpng provides two further macros for this
purpose:
png_uint_32 output_x = PNG_COL_FROM_PASS_COL(input_x, pass);
png_uint_32 output_y = PNG_ROW_FROM_PASS_ROW(input_y, pass);
Finally a pair of macros are provided to tell you if a particular image
row or column appears in a given pass:
int col_in_pass = PNG_COL_IN_INTERLACE_PASS(output_x, pass);
int row_in_pass = PNG_ROW_IN_INTERLACE_PASS(output_y, pass);
Bear in mind that you will probably also need to check the width and height
of the pass in addition to the above to be sure the pass even exists!
With any luck you are convinced by now that you don't want to do your own
interlace handling. In reality normally the only good reason for doing this
is if you are processing PNG files on a pixel-by-pixel basis and don't want
to load the whole file into memory when it is interlaced.
libpng includes a test program, pngvalid, that illustrates reading and
writing of interlaced images. If you can't get interlacing to work in your
code and don't want to leave it to libpng (the recommended approach) see
how pngvalid.c does it.
Finishing a sequential read Finishing a sequential read
After you are finished reading the image through the After you are finished reading the image through the
@ -1780,6 +1825,9 @@ png_infop info_ptr;
any). You may start getting rows before any). You may start getting rows before
png_process_data() returns, so this is your png_process_data() returns, so this is your
last chance to prepare for that. last chance to prepare for that.
This is where you turn on interlace handling,
assuming you don't want to do it yourself.
*/ */
} }
@ -1800,14 +1848,22 @@ png_infop info_ptr;
supplying them because it may make your life supplying them because it may make your life
easier. easier.
For the non-NULL rows of interlaced images, If you did not turn on interlace handling then
the callback is called for each row of each
sub-image when the image is interlaced. In this
case 'row_num' is the row in the sub-image, not
the row in the output image as it is in all other
cases.
For the non-NULL rows of interlaced images when
you have switched on libpng interlace handling,
you must call png_progressive_combine_row() you must call png_progressive_combine_row()
passing in the row and the old row. You can passing in the row and the old row. You can
call this function for NULL rows (it will just call this function for NULL rows (it will just
return) and for non-interlaced images (it just return) and for non-interlaced images (it just
does the memcpy for you) if it will make the does the memcpy for you) if it will make the
code easier. Thus, you can just do this for code easier. Thus, you can just do this for
all cases: all cases if you switch on interlace handling;
*/ */
png_progressive_combine_row(png_ptr, old_row, png_progressive_combine_row(png_ptr, old_row,
@ -1983,11 +2039,10 @@ filter types.
PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH| PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH|
PNG_ALL_FILTERS); PNG_ALL_FILTERS);
If an application If an application wants to start and stop using particular filters during
wants to start and stop using particular filters during compression, compression, it should start out with all of the filters (to ensure that
it should start out with all of the filters (to ensure that the previous the previous row of pixels will be stored in case it's needed later),
row of pixels will be stored in case it's needed later), and then add and then add and remove them after the start of compression.
and remove them after the start of compression.
If you are writing a PNG datastream that is to be embedded in a MNG If you are writing a PNG datastream that is to be embedded in a MNG
datastream, the second parameter can be either 0 or 64. datastream, the second parameter can be either 0 or 64.
@ -2586,25 +2641,39 @@ for details of which pixels to write when.
If you don't want libpng to handle the interlacing details, just If you don't want libpng to handle the interlacing details, just
use png_set_interlace_handling() and call png_write_rows() the use png_set_interlace_handling() and call png_write_rows() the
correct number of times to write all seven sub-images. correct number of times to write all the sub-images
(png_set_interlace_handling() returns the number of sub-images.)
If you want libpng to build the sub-images, call this before you start If you want libpng to build the sub-images, call this before you start
writing any rows: writing any rows:
number_of_passes = number_of_passes = png_set_interlace_handling(png_ptr);
png_set_interlace_handling(png_ptr);
This will return the number of passes needed. Currently, this is seven, This will return the number of passes needed. Currently, this is seven,
but may change if another interlace type is added. but may change if another interlace type is added.
Then write the complete image number_of_passes times. Then write the complete image number_of_passes times.
png_write_rows(png_ptr, row_pointers, png_write_rows(png_ptr, row_pointers, number_of_rows);
number_of_rows);
As some of these rows are not used, and thus return immediately, you may Think carefully before you write an interlaced image. Typically code that
want to read about interlacing in the PNG specification, and only update reads such images reads all the image data into memory, uncompressed, before
the rows that are actually used. doing any processing. Only code that can display an image on the fly can
take advantage of the interlacing and even then the image has to be exactly
the correct size for the output device, because scaling an image requires
adjacent pixels and these are not available until all the passes have been
read.
If you do write an interlaced image you will hardly ever need to handle
the interlacing yourself. Call png_set_interlace_handling() and use the
approach described above.
The only time it is conceivable that you will really need to write an
interlaced image pass-by-pass is when you have read one pass by pass and
made some pixel-by-pixel transformation to it, as described in the read
code above. In this case use the PNG_PASS_ROWS and PNG_PASS_COLS macros
to determine the size of each sub-image in turn and simply write the rows
you obtained from the read code.
Finishing a sequential write Finishing a sequential write
@ -3382,9 +3451,10 @@ Any program that compiled against libpng 1.4 and did not use deprecated
features or access internal library structures should compile and work features or access internal library structures should compile and work
against libpng 1.5. against libpng 1.5.
libpng 1.5.0 adds png_get_num_ functions to help in the reading of libpng 1.5.0 adds PNG_ PASS macros to help in the reading and writing of
interlaced images. The functions return the number of interlace passes interlaced images. The macros return the number of rows and columns in
and the number of rows and columns in each pass. each pass and information that can be used to de-interlace and (if
absolutely necessary) interlace an image.
libpng 1.5.0 adds an API png_longjmp(png_ptr, value). This API calls libpng 1.5.0 adds an API png_longjmp(png_ptr, value). This API calls
the application provided png_longjmp_ptr on the internal, but application the application provided png_longjmp_ptr on the internal, but application
@ -3740,7 +3810,7 @@ Other rules can be inferred by inspecting the libpng source.
XIV. Y2K Compliance in libpng XIV. Y2K Compliance in libpng
December 9, 2010 December 10, 2010
Since the PNG Development group is an ad-hoc body, we can't make Since the PNG Development group is an ad-hoc body, we can't make
an official declaration. an official declaration.

81
png.h
View File

@ -1,7 +1,7 @@
/* png.h - header file for PNG reference library /* png.h - header file for PNG reference library
* *
* libpng version 1.5.0beta58 - December 9, 2010 * libpng version 1.5.0beta58 - December 10, 2010
* Copyright (c) 1998-2010 Glenn Randers-Pehrson * Copyright (c) 1998-2010 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -11,7 +11,7 @@
* Authors and maintainers: * Authors and maintainers:
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat * 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.89c, June 1996, through 0.96, May 1997: Andreas Dilger
* libpng versions 0.97, January 1998, through 1.5.0beta58 - December 9, 2010: Glenn * libpng versions 0.97, January 1998, through 1.5.0beta58 - December 10, 2010: Glenn
* See also "Contributing Authors", below. * See also "Contributing Authors", below.
* *
* Note about libpng version numbers: * Note about libpng version numbers:
@ -173,7 +173,7 @@
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* *
* libpng versions 1.2.6, August 15, 2004, through 1.5.0beta58, December 9, 2010, are * libpng versions 1.2.6, August 15, 2004, through 1.5.0beta58, December 10, 2010, are
* Copyright (c) 2004, 2006-2010 Glenn Randers-Pehrson, and are * Copyright (c) 2004, 2006-2010 Glenn Randers-Pehrson, and are
* distributed according to the same disclaimer and license as libpng-1.2.5 * distributed according to the same disclaimer and license as libpng-1.2.5
* with the following individual added to the list of Contributing Authors: * with the following individual added to the list of Contributing Authors:
@ -285,7 +285,7 @@
* Y2K compliance in libpng: * Y2K compliance in libpng:
* ========================= * =========================
* *
* December 9, 2010 * December 10, 2010
* *
* Since the PNG Development group is an ad-hoc body, we can't make * Since the PNG Development group is an ad-hoc body, we can't make
* an official declaration. * an official declaration.
@ -349,7 +349,7 @@
/* Version information for png.h - this should match the version in png.c */ /* Version information for png.h - this should match the version in png.c */
#define PNG_LIBPNG_VER_STRING "1.5.0beta58" #define PNG_LIBPNG_VER_STRING "1.5.0beta58"
#define PNG_HEADER_VERSION_STRING \ #define PNG_HEADER_VERSION_STRING \
" libpng version 1.5.0beta58 - December 9, 2010\n" " libpng version 1.5.0beta58 - December 10, 2010\n"
#define PNG_LIBPNG_VER_SONUM 15 #define PNG_LIBPNG_VER_SONUM 15
#define PNG_LIBPNG_VER_DLLNUM 15 #define PNG_LIBPNG_VER_DLLNUM 15
@ -1135,20 +1135,6 @@ PNG_EXPORT(44, void, png_set_shift, (png_structp png_ptr, png_const_color_8p
PNG_EXPORT(45, int, png_set_interlace_handling, (png_structp png_ptr)); PNG_EXPORT(45, int, png_set_interlace_handling, (png_structp png_ptr));
#endif #endif
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
/* Alternatively call this to get the number of rows in the current pass.
* Call this after png_read_update_info or png_start_read_image; if you
* call it before it will just return the image height (which is also what
* it returns for a non-interlaced image!).
*
* NOTE: you need to call these to find out how many times to call
* png_read_row if you handle your own de-interlacing.
*/
PNG_EXPORT(215, int, png_get_num_passes, (png_structp png_ptr));
PNG_EXPORT(216, png_uint_32, png_get_num_rows, (png_structp png_ptr));
PNG_EXPORT(218, png_uint_32, png_get_num_cols, (png_structp png_ptr));
#endif
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
/* Invert monochrome files */ /* Invert monochrome files */
PNG_EXPORT(46, void, png_set_invert_mono, (png_structp png_ptr)); PNG_EXPORT(46, void, png_set_invert_mono, (png_structp png_ptr));
@ -1159,7 +1145,7 @@ PNG_EXPORT(46, void, png_set_invert_mono, (png_structp png_ptr));
PNG_FP_EXPORT(47, void, png_set_background, (png_structp png_ptr, PNG_FP_EXPORT(47, void, png_set_background, (png_structp png_ptr,
png_const_color_16p background_color, int background_gamma_code, png_const_color_16p background_color, int background_gamma_code,
int need_expand, double background_gamma)); int need_expand, double background_gamma));
PNG_FIXED_EXPORT(217, void, png_set_background_fixed, (png_structp png_ptr, PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structp png_ptr,
png_const_color_16p background_color, int background_gamma_code, png_const_color_16p background_color, int background_gamma_code,
int need_expand, png_fixed_point background_gamma)); int need_expand, png_fixed_point background_gamma));
#endif #endif
@ -2072,6 +2058,59 @@ PNG_EXPORT(200, png_const_bytep, png_get_io_chunk_name, (png_structp png_ptr));
# define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */ # define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */
#endif /* ?PNG_IO_STATE_SUPPORTED */ #endif /* ?PNG_IO_STATE_SUPPORTED */
/* Interlace support. The following macros are always defined so that if
* libpng interlace handling is turned off the macros may be used to handle
* interlaced images within the application.
*/
#define PNG_INTERLACE_ADAM7_PASSES 7
/* Two macros to return the first row and first column of the original,
* full, image which appears in a given pass. 'pass' is in the range 0
* to 6 and the result is in the range 0 to 7.
*/
#define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7)
#define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7)
/* Two macros to help evaluate the number of rows or columns in each
* pass. This is expressed as a shift - effectively log2 of the number or
* rows or columns in each 8x8 tile of the original image.
*/
#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)
#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)
/* Hence two macros to determine the number of rows or columns in a given
* pass of an image given its height or width. In fact these macros may
* return non-zero even though the sub-image is empty, because the other
* dimension may be empty for a small image.
*/
#define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\
-1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))
#define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\
-1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))
/* For the progressive reader it is necessary to find the row in the output
* image given a row in an interlaced image, so two more macros:
*/
#define PNG_ROW_FROM_PASS_ROW(yIn, pass) \
(((yIn)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))
#define PNG_COL_FROM_PASS_COL(xIn, pass) \
(((xIn)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))
/* Two macros which return a boolean (0 or 1) saying whether the given row
* or column is in a particular pass. These use a common utility macro that
* returns a mask for a given pass - the offset 'off' selects the row or
* column version. The mask has the appropriate bit set for each column in
* the tile.
*/
#define PNG_PASS_MASK(pass,off) ( \
((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \
((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U))
#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \
((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)
#define PNG_COL_IN_INTERLACE_PASS(x, pass) \
((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)
#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED #ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
/* With these routines we avoid an integer divide, which will be slower on /* With these routines we avoid an integer divide, which will be slower on
* most machines. However, it does take more operations than the corresponding * most machines. However, it does take more operations than the corresponding
@ -2174,7 +2213,7 @@ PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i));
* one to use is one more than this.) * one to use is one more than this.)
*/ */
#ifdef PNG_EXPORT_LAST_ORDINAL #ifdef PNG_EXPORT_LAST_ORDINAL
PNG_EXPORT_LAST_ORDINAL(218); PNG_EXPORT_LAST_ORDINAL(215);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -3293,15 +3293,12 @@ png_read_finish_row(png_structp png_ptr)
png_pass_yinc[png_ptr->pass] - 1 - png_pass_yinc[png_ptr->pass] - 1 -
png_pass_ystart[png_ptr->pass]) / png_pass_ystart[png_ptr->pass]) /
png_pass_yinc[png_ptr->pass]; png_pass_yinc[png_ptr->pass];
if (!(png_ptr->num_rows))
continue;
} }
else /* if (png_ptr->transformations & PNG_INTERLACE) */ else /* if (png_ptr->transformations & PNG_INTERLACE) */
break; break; /* libpng deinterlacing sees every row */
} while (png_ptr->iwidth == 0); } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0);
if (png_ptr->pass < 7) if (png_ptr->pass < 7)
return; return;
@ -3614,55 +3611,4 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
png_ptr->flags |= PNG_FLAG_ROW_INIT; png_ptr->flags |= PNG_FLAG_ROW_INIT;
} }
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
int PNGAPI
png_get_num_passes(png_structp png_ptr)
{
if (png_ptr != NULL)
{
if (png_ptr->interlaced)
return 7;
else
return 1;
}
/* Here on error */
return 0;
}
png_uint_32 PNGAPI
png_get_num_rows(png_structp png_ptr)
{
if (png_ptr != NULL)
{
if (png_ptr->flags & PNG_FLAG_ROW_INIT)
return png_ptr->num_rows;
else
png_error(png_ptr, "Call png_start_read_image or png_read_update_info "
"before png_get_num_rows");
}
/* Here on error */
return 0;
}
png_uint_32 PNGAPI
png_get_num_cols(png_structp png_ptr)
{
if (png_ptr != NULL)
{
if (png_ptr->flags & PNG_FLAG_ROW_INIT)
return png_ptr->iwidth;
else
png_error(png_ptr, "Call png_start_read_image or png_read_update_info "
"before png_get_num_cols");
}
/* Here on error */
return 0;
}
#endif /* SEQUENTIAL READ */
#endif /* PNG_READ_SUPPORTED */ #endif /* PNG_READ_SUPPORTED */

1184
pngvalid.c

File diff suppressed because it is too large Load Diff

View File

@ -230,7 +230,4 @@ EXPORTS
png_get_y_offset_inches_fixed @212 png_get_y_offset_inches_fixed @212
png_set_sCAL_fixed @213 png_set_sCAL_fixed @213
png_get_sCAL_fixed @214 png_get_sCAL_fixed @214
png_get_num_passes @215 png_set_background_fixed @215
png_get_num_rows @216
png_set_background_fixed @217
png_get_num_cols @218

View File

@ -220,7 +220,4 @@ EXPORTS
png_get_y_offset_inches_fixed @212 png_get_y_offset_inches_fixed @212
png_set_sCAL_fixed @213 png_set_sCAL_fixed @213
png_get_sCAL_fixed @214 png_get_sCAL_fixed @214
png_get_num_passes @215 png_set_background_fixed @215
png_get_num_rows @216
png_set_background_fixed @217
png_get_num_cols @218

View File

@ -7,8 +7,14 @@ err=0
echo >> pngtest-log.txt echo >> pngtest-log.txt
echo "============ pngvalid-simple.sh ==============" >> pngtest-log.txt echo "============ pngvalid-simple.sh ==============" >> pngtest-log.txt
echo "Running test-pngvalid-simple.sh" echo "Running test-pngvalid-simple.sh"
# The options to test are:
#
# --progressive-read, --interlace on the 'transform' images
# --progressive-read on the 'size' images
#
for opts in "" --progressive-read --interlace \ for opts in "" --progressive-read --interlace \
"--progressive-read --interlace" "--progressive-read --interlace" "--nostandard --size" \
"--nostandard --size --progressive-read"
do do
if ./pngvalid --nogamma $opts >> pngtest-log.txt 2>&1 if ./pngvalid --nogamma $opts >> pngtest-log.txt 2>&1
then then