jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngtest.c
changeset 43359 269efd520e13
parent 43358 9e2d943b5b66
parent 43353 2498f60f2ef1
child 43361 b580f96a38b4
equal deleted inserted replaced
43358:9e2d943b5b66 43359:269efd520e13
     1 /*
       
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     3  *
       
     4  * This code is free software; you can redistribute it and/or modify it
       
     5  * under the terms of the GNU General Public License version 2 only, as
       
     6  * published by the Free Software Foundation.  Oracle designates this
       
     7  * particular file as subject to the "Classpath" exception as provided
       
     8  * by Oracle in the LICENSE file that accompanied this code.
       
     9  *
       
    10  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    13  * version 2 for more details (a copy is included in the LICENSE file that
       
    14  * accompanied this code).
       
    15  *
       
    16  * You should have received a copy of the GNU General Public License version
       
    17  * 2 along with this work; if not, write to the Free Software Foundation,
       
    18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    19  *
       
    20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    21  * or visit www.oracle.com if you need additional information or have any
       
    22  * questions.
       
    23  */
       
    24 
       
    25 /* pngtest.c - a simple test program to test libpng
       
    26  *
       
    27  * This file is available under and governed by the GNU General Public
       
    28  * License version 2 only, as published by the Free Software Foundation.
       
    29  * However, the following notice accompanied the original version of this
       
    30  * file and, per its terms, should not be removed:
       
    31  *
       
    32  * Last changed in libpng 1.5.25 [December 3, 2015]
       
    33  * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
       
    34  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
       
    35  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
       
    36  *
       
    37  * This code is released under the libpng license.
       
    38  * For conditions of distribution and use, see the disclaimer
       
    39  * and license in png.h
       
    40  *
       
    41  * This program reads in a PNG image, writes it out again, and then
       
    42  * compares the two files.  If the files are identical, this shows that
       
    43  * the basic chunk handling, filtering, and (de)compression code is working
       
    44  * properly.  It does not currently test all of the transforms, although
       
    45  * it probably should.
       
    46  *
       
    47  * The program will report "FAIL" in certain legitimate cases:
       
    48  * 1) when the compression level or filter selection method is changed.
       
    49  * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192.
       
    50  * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks
       
    51  *    exist in the input file.
       
    52  * 4) others not listed here...
       
    53  * In these cases, it is best to check with another tool such as "pngcheck"
       
    54  * to see what the differences between the two files are.
       
    55  *
       
    56  * If a filename is given on the command-line, then this file is used
       
    57  * for the input, rather than the default "pngtest.png".  This allows
       
    58  * testing a wide variety of files easily.  You can also test a number
       
    59  * of files at once by typing "pngtest -m file1.png file2.png ..."
       
    60  */
       
    61 
       
    62 #define _POSIX_SOURCE 1
       
    63 
       
    64 #include <stdio.h>
       
    65 #include <stdlib.h>
       
    66 #include <string.h>
       
    67 
       
    68 /* Defined so I can write to a file on gui/windowing platforms */
       
    69 /*  #define STDERR stderr  */
       
    70 #define STDERR stdout   /* For DOS */
       
    71 
       
    72 #include "png.h"
       
    73 
       
    74 /* 1.6.1 added support for the configure test harness, which uses 77 to indicate
       
    75  * a skipped test, in earlier versions we need to succeed on a skipped test, so:
       
    76  */
       
    77 #if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
       
    78 #  define SKIP 77
       
    79 #else
       
    80 #  define SKIP 0
       
    81 #endif
       
    82 
       
    83 /* Known chunks that exist in pngtest.png must be supported or pngtest will fail
       
    84  * simply as a result of re-ordering them.  This may be fixed in 1.7
       
    85  *
       
    86  * pngtest allocates a single row buffer for each row and overwrites it,
       
    87  * therefore if the write side doesn't support the writing of interlaced images
       
    88  * nothing can be done for an interlaced image (and the code below will fail
       
    89  * horribly trying to write extra data after writing garbage).
       
    90  */
       
    91 #if defined PNG_READ_SUPPORTED && /* else nothing can be done */\
       
    92    defined PNG_READ_bKGD_SUPPORTED &&\
       
    93    defined PNG_READ_cHRM_SUPPORTED &&\
       
    94    defined PNG_READ_gAMA_SUPPORTED &&\
       
    95    defined PNG_READ_oFFs_SUPPORTED &&\
       
    96    defined PNG_READ_pCAL_SUPPORTED &&\
       
    97    defined PNG_READ_pHYs_SUPPORTED &&\
       
    98    defined PNG_READ_sBIT_SUPPORTED &&\
       
    99    defined PNG_READ_sCAL_SUPPORTED &&\
       
   100    defined PNG_READ_sRGB_SUPPORTED &&\
       
   101    defined PNG_READ_sPLT_SUPPORTED &&\
       
   102    defined PNG_READ_tEXt_SUPPORTED &&\
       
   103    defined PNG_READ_tIME_SUPPORTED &&\
       
   104    defined PNG_READ_zTXt_SUPPORTED &&\
       
   105    (defined PNG_WRITE_INTERLACING_SUPPORTED || PNG_LIBPNG_VER >= 10700)
       
   106 
       
   107 #ifdef PNG_ZLIB_HEADER
       
   108 #  include PNG_ZLIB_HEADER /* defined by pnglibconf.h from 1.7 */
       
   109 #else
       
   110 #  include "zlib.h"
       
   111 #endif
       
   112 
       
   113 /* Copied from pngpriv.h but only used in error messages below. */
       
   114 #ifndef PNG_ZBUF_SIZE
       
   115 #  define PNG_ZBUF_SIZE 8192
       
   116 #endif
       
   117 #define FCLOSE(file) fclose(file)
       
   118 
       
   119 #ifndef PNG_STDIO_SUPPORTED
       
   120 typedef FILE                * png_FILE_p;
       
   121 #endif
       
   122 
       
   123 /* Makes pngtest verbose so we can find problems. */
       
   124 #ifndef PNG_DEBUG
       
   125 #  define PNG_DEBUG 0
       
   126 #endif
       
   127 
       
   128 #if PNG_DEBUG > 1
       
   129 #  define pngtest_debug(m)        ((void)fprintf(stderr, m "\n"))
       
   130 #  define pngtest_debug1(m,p1)    ((void)fprintf(stderr, m "\n", p1))
       
   131 #  define pngtest_debug2(m,p1,p2) ((void)fprintf(stderr, m "\n", p1, p2))
       
   132 #else
       
   133 #  define pngtest_debug(m)        ((void)0)
       
   134 #  define pngtest_debug1(m,p1)    ((void)0)
       
   135 #  define pngtest_debug2(m,p1,p2) ((void)0)
       
   136 #endif
       
   137 
       
   138 #if !PNG_DEBUG
       
   139 #  define SINGLE_ROWBUF_ALLOC  /* Makes buffer overruns easier to nail */
       
   140 #endif
       
   141 
       
   142 #ifndef PNG_UNUSED
       
   143 #  define PNG_UNUSED(param) (void)param;
       
   144 #endif
       
   145 
       
   146 /* Turn on CPU timing
       
   147 #define PNGTEST_TIMING
       
   148 */
       
   149 
       
   150 #ifndef PNG_FLOATING_POINT_SUPPORTED
       
   151 #undef PNGTEST_TIMING
       
   152 #endif
       
   153 
       
   154 #ifdef PNGTEST_TIMING
       
   155 static float t_start, t_stop, t_decode, t_encode, t_misc;
       
   156 #include <time.h>
       
   157 #endif
       
   158 
       
   159 #ifdef PNG_TIME_RFC1123_SUPPORTED
       
   160 #define PNG_tIME_STRING_LENGTH 29
       
   161 static int tIME_chunk_present = 0;
       
   162 static char tIME_string[PNG_tIME_STRING_LENGTH] = "tIME chunk is not present";
       
   163 
       
   164 #if PNG_LIBPNG_VER < 10619
       
   165 #define png_convert_to_rfc1123_buffer(ts, t) tIME_to_str(read_ptr, ts, t)
       
   166 
       
   167 static int
       
   168 tIME_to_str(png_structp png_ptr, png_charp ts, png_const_timep t)
       
   169 {
       
   170     png_const_charp str = png_convert_to_rfc1123(png_ptr, t);
       
   171 
       
   172     if (str == NULL)
       
   173         return 0;
       
   174 
       
   175     strcpy(ts, str);
       
   176     return 1;
       
   177 }
       
   178 #endif /* older libpng */
       
   179 #endif
       
   180 
       
   181 static int verbose = 0;
       
   182 static int strict = 0;
       
   183 static int relaxed = 0;
       
   184 static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */
       
   185 static int error_count = 0; /* count calls to png_error */
       
   186 static int warning_count = 0; /* count calls to png_warning */
       
   187 
       
   188 /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
       
   189 #ifndef png_jmpbuf
       
   190 #  define png_jmpbuf(png_ptr) png_ptr->jmpbuf
       
   191 #endif
       
   192 
       
   193 /* Defines for unknown chunk handling if required. */
       
   194 #ifndef PNG_HANDLE_CHUNK_ALWAYS
       
   195 #  define PNG_HANDLE_CHUNK_ALWAYS       3
       
   196 #endif
       
   197 #ifndef PNG_HANDLE_CHUNK_IF_SAFE
       
   198 #  define PNG_HANDLE_CHUNK_IF_SAFE      2
       
   199 #endif
       
   200 
       
   201 /* Utility to save typing/errors, the argument must be a name */
       
   202 #define MEMZERO(var) ((void)memset(&var, 0, sizeof var))
       
   203 
       
   204 /* Example of using row callbacks to make a simple progress meter */
       
   205 static int status_pass = 1;
       
   206 static int status_dots_requested = 0;
       
   207 static int status_dots = 1;
       
   208 
       
   209 static void PNGCBAPI
       
   210 read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
       
   211 {
       
   212    if (png_ptr == NULL || row_number > PNG_UINT_31_MAX)
       
   213       return;
       
   214 
       
   215    if (status_pass != pass)
       
   216    {
       
   217       fprintf(stdout, "\n Pass %d: ", pass);
       
   218       status_pass = pass;
       
   219       status_dots = 31;
       
   220    }
       
   221 
       
   222    status_dots--;
       
   223 
       
   224    if (status_dots == 0)
       
   225    {
       
   226       fprintf(stdout, "\n         ");
       
   227       status_dots=30;
       
   228    }
       
   229 
       
   230    fprintf(stdout, "r");
       
   231 }
       
   232 
       
   233 #ifdef PNG_WRITE_SUPPORTED
       
   234 static void PNGCBAPI
       
   235 write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
       
   236 {
       
   237    if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7)
       
   238       return;
       
   239 
       
   240    fprintf(stdout, "w");
       
   241 }
       
   242 #endif
       
   243 
       
   244 
       
   245 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
       
   246 /* Example of using a user transform callback (doesn't do anything at present).
       
   247  */
       
   248 static void PNGCBAPI
       
   249 read_user_callback(png_structp png_ptr, png_row_infop row_info, png_bytep data)
       
   250 {
       
   251    PNG_UNUSED(png_ptr)
       
   252    PNG_UNUSED(row_info)
       
   253    PNG_UNUSED(data)
       
   254 }
       
   255 #endif
       
   256 
       
   257 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
       
   258 /* Example of using user transform callback (we don't transform anything,
       
   259  * but merely count the zero samples)
       
   260  */
       
   261 
       
   262 static png_uint_32 zero_samples;
       
   263 
       
   264 static void PNGCBAPI
       
   265 count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
       
   266 {
       
   267    png_bytep dp = data;
       
   268    if (png_ptr == NULL)
       
   269       return;
       
   270 
       
   271    /* Contents of row_info:
       
   272     *  png_uint_32 width      width of row
       
   273     *  png_uint_32 rowbytes   number of bytes in row
       
   274     *  png_byte color_type    color type of pixels
       
   275     *  png_byte bit_depth     bit depth of samples
       
   276     *  png_byte channels      number of channels (1-4)
       
   277     *  png_byte pixel_depth   bits per pixel (depth*channels)
       
   278     */
       
   279 
       
   280     /* Counts the number of zero samples (or zero pixels if color_type is 3 */
       
   281 
       
   282     if (row_info->color_type == 0 || row_info->color_type == 3)
       
   283     {
       
   284        int pos = 0;
       
   285        png_uint_32 n, nstop;
       
   286 
       
   287        for (n = 0, nstop=row_info->width; n<nstop; n++)
       
   288        {
       
   289           if (row_info->bit_depth == 1)
       
   290           {
       
   291              if (((*dp << pos++ ) & 0x80) == 0)
       
   292                 zero_samples++;
       
   293 
       
   294              if (pos == 8)
       
   295              {
       
   296                 pos = 0;
       
   297                 dp++;
       
   298              }
       
   299           }
       
   300 
       
   301           if (row_info->bit_depth == 2)
       
   302           {
       
   303              if (((*dp << (pos+=2)) & 0xc0) == 0)
       
   304                 zero_samples++;
       
   305 
       
   306              if (pos == 8)
       
   307              {
       
   308                 pos = 0;
       
   309                 dp++;
       
   310              }
       
   311           }
       
   312 
       
   313           if (row_info->bit_depth == 4)
       
   314           {
       
   315              if (((*dp << (pos+=4)) & 0xf0) == 0)
       
   316                 zero_samples++;
       
   317 
       
   318              if (pos == 8)
       
   319              {
       
   320                 pos = 0;
       
   321                 dp++;
       
   322              }
       
   323           }
       
   324 
       
   325           if (row_info->bit_depth == 8)
       
   326              if (*dp++ == 0)
       
   327                 zero_samples++;
       
   328 
       
   329           if (row_info->bit_depth == 16)
       
   330           {
       
   331              if ((*dp | *(dp+1)) == 0)
       
   332                 zero_samples++;
       
   333              dp+=2;
       
   334           }
       
   335        }
       
   336     }
       
   337     else /* Other color types */
       
   338     {
       
   339        png_uint_32 n, nstop;
       
   340        int channel;
       
   341        int color_channels = row_info->channels;
       
   342        if (row_info->color_type > 3)
       
   343           color_channels--;
       
   344 
       
   345        for (n = 0, nstop=row_info->width; n<nstop; n++)
       
   346        {
       
   347           for (channel = 0; channel < color_channels; channel++)
       
   348           {
       
   349              if (row_info->bit_depth == 8)
       
   350                 if (*dp++ == 0)
       
   351                    zero_samples++;
       
   352 
       
   353              if (row_info->bit_depth == 16)
       
   354              {
       
   355                 if ((*dp | *(dp+1)) == 0)
       
   356                    zero_samples++;
       
   357 
       
   358                 dp+=2;
       
   359              }
       
   360           }
       
   361           if (row_info->color_type > 3)
       
   362           {
       
   363              dp++;
       
   364              if (row_info->bit_depth == 16)
       
   365                 dp++;
       
   366           }
       
   367        }
       
   368     }
       
   369 }
       
   370 #endif /* WRITE_USER_TRANSFORM */
       
   371 
       
   372 #ifndef PNG_STDIO_SUPPORTED
       
   373 /* START of code to validate stdio-free compilation */
       
   374 /* These copies of the default read/write functions come from pngrio.c and
       
   375  * pngwio.c.  They allow "don't include stdio" testing of the library.
       
   376  * This is the function that does the actual reading of data.  If you are
       
   377  * not reading from a standard C stream, you should create a replacement
       
   378  * read_data function and use it at run time with png_set_read_fn(), rather
       
   379  * than changing the library.
       
   380  */
       
   381 
       
   382 #ifdef PNG_IO_STATE_SUPPORTED
       
   383 void
       
   384 pngtest_check_io_state(png_structp png_ptr, png_size_t data_length,
       
   385    png_uint_32 io_op);
       
   386 void
       
   387 pngtest_check_io_state(png_structp png_ptr, png_size_t data_length,
       
   388    png_uint_32 io_op)
       
   389 {
       
   390    png_uint_32 io_state = png_get_io_state(png_ptr);
       
   391    int err = 0;
       
   392 
       
   393    /* Check if the current operation (reading / writing) is as expected. */
       
   394    if ((io_state & PNG_IO_MASK_OP) != io_op)
       
   395       png_error(png_ptr, "Incorrect operation in I/O state");
       
   396 
       
   397    /* Check if the buffer size specific to the current location
       
   398     * (file signature / header / data / crc) is as expected.
       
   399     */
       
   400    switch (io_state & PNG_IO_MASK_LOC)
       
   401    {
       
   402    case PNG_IO_SIGNATURE:
       
   403       if (data_length > 8)
       
   404          err = 1;
       
   405       break;
       
   406    case PNG_IO_CHUNK_HDR:
       
   407       if (data_length != 8)
       
   408          err = 1;
       
   409       break;
       
   410    case PNG_IO_CHUNK_DATA:
       
   411       break;  /* no restrictions here */
       
   412    case PNG_IO_CHUNK_CRC:
       
   413       if (data_length != 4)
       
   414          err = 1;
       
   415       break;
       
   416    default:
       
   417       err = 1;  /* uninitialized */
       
   418    }
       
   419    if (err != 0)
       
   420       png_error(png_ptr, "Bad I/O state or buffer size");
       
   421 }
       
   422 #endif
       
   423 
       
   424 static void PNGCBAPI
       
   425 pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
       
   426 {
       
   427    png_size_t check = 0;
       
   428    png_voidp io_ptr;
       
   429 
       
   430    /* fread() returns 0 on error, so it is OK to store this in a png_size_t
       
   431     * instead of an int, which is what fread() actually returns.
       
   432     */
       
   433    io_ptr = png_get_io_ptr(png_ptr);
       
   434    if (io_ptr != NULL)
       
   435    {
       
   436       check = fread(data, 1, length, (png_FILE_p)io_ptr);
       
   437    }
       
   438 
       
   439    if (check != length)
       
   440    {
       
   441       png_error(png_ptr, "Read Error");
       
   442    }
       
   443 
       
   444 #ifdef PNG_IO_STATE_SUPPORTED
       
   445    pngtest_check_io_state(png_ptr, length, PNG_IO_READING);
       
   446 #endif
       
   447 }
       
   448 
       
   449 #ifdef PNG_WRITE_FLUSH_SUPPORTED
       
   450 static void PNGCBAPI
       
   451 pngtest_flush(png_structp png_ptr)
       
   452 {
       
   453    /* Do nothing; fflush() is said to be just a waste of energy. */
       
   454    PNG_UNUSED(png_ptr)   /* Stifle compiler warning */
       
   455 }
       
   456 #endif
       
   457 
       
   458 /* This is the function that does the actual writing of data.  If you are
       
   459  * not writing to a standard C stream, you should create a replacement
       
   460  * write_data function and use it at run time with png_set_write_fn(), rather
       
   461  * than changing the library.
       
   462  */
       
   463 static void PNGCBAPI
       
   464 pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
       
   465 {
       
   466    png_size_t check;
       
   467 
       
   468    check = fwrite(data, 1, length, (png_FILE_p)png_get_io_ptr(png_ptr));
       
   469 
       
   470    if (check != length)
       
   471    {
       
   472       png_error(png_ptr, "Write Error");
       
   473    }
       
   474 
       
   475 #ifdef PNG_IO_STATE_SUPPORTED
       
   476    pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING);
       
   477 #endif
       
   478 }
       
   479 #endif /* !STDIO */
       
   480 
       
   481 /* This function is called when there is a warning, but the library thinks
       
   482  * it can continue anyway.  Replacement functions don't have to do anything
       
   483  * here if you don't want to.  In the default configuration, png_ptr is
       
   484  * not used, but it is passed in case it may be useful.
       
   485  */
       
   486 typedef struct
       
   487 {
       
   488    PNG_CONST char *file_name;
       
   489 }  pngtest_error_parameters;
       
   490 
       
   491 static void PNGCBAPI
       
   492 pngtest_warning(png_structp png_ptr, png_const_charp message)
       
   493 {
       
   494    PNG_CONST char *name = "UNKNOWN (ERROR!)";
       
   495    pngtest_error_parameters *test =
       
   496       (pngtest_error_parameters*)png_get_error_ptr(png_ptr);
       
   497 
       
   498    ++warning_count;
       
   499 
       
   500    if (test != NULL && test->file_name != NULL)
       
   501       name = test->file_name;
       
   502 
       
   503    fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
       
   504 }
       
   505 
       
   506 /* This is the default error handling function.  Note that replacements for
       
   507  * this function MUST NOT RETURN, or the program will likely crash.  This
       
   508  * function is used by default, or if the program supplies NULL for the
       
   509  * error function pointer in png_set_error_fn().
       
   510  */
       
   511 static void PNGCBAPI
       
   512 pngtest_error(png_structp png_ptr, png_const_charp message)
       
   513 {
       
   514    ++error_count;
       
   515 
       
   516    pngtest_warning(png_ptr, message);
       
   517    /* We can return because png_error calls the default handler, which is
       
   518     * actually OK in this case.
       
   519     */
       
   520 }
       
   521 
       
   522 /* END of code to validate stdio-free compilation */
       
   523 
       
   524 /* START of code to validate memory allocation and deallocation */
       
   525 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
       
   526 
       
   527 /* Allocate memory.  For reasonable files, size should never exceed
       
   528  * 64K.  However, zlib may allocate more than 64K if you don't tell
       
   529  * it not to.  See zconf.h and png.h for more information.  zlib does
       
   530  * need to allocate exactly 64K, so whatever you call here must
       
   531  * have the ability to do that.
       
   532  *
       
   533  * This piece of code can be compiled to validate max 64K allocations
       
   534  * by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K.
       
   535  */
       
   536 typedef struct memory_information
       
   537 {
       
   538    png_alloc_size_t          size;
       
   539    png_voidp                 pointer;
       
   540    struct memory_information *next;
       
   541 } memory_information;
       
   542 typedef memory_information *memory_infop;
       
   543 
       
   544 static memory_infop pinformation = NULL;
       
   545 static int current_allocation = 0;
       
   546 static int maximum_allocation = 0;
       
   547 static int total_allocation = 0;
       
   548 static int num_allocations = 0;
       
   549 
       
   550 png_voidp PNGCBAPI png_debug_malloc PNGARG((png_structp png_ptr,
       
   551     png_alloc_size_t size));
       
   552 void PNGCBAPI png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr));
       
   553 
       
   554 png_voidp
       
   555 PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size)
       
   556 {
       
   557 
       
   558    /* png_malloc has already tested for NULL; png_create_struct calls
       
   559     * png_debug_malloc directly, with png_ptr == NULL which is OK
       
   560     */
       
   561 
       
   562    if (size == 0)
       
   563       return (NULL);
       
   564 
       
   565    /* This calls the library allocator twice, once to get the requested
       
   566       buffer and once to get a new free list entry. */
       
   567    {
       
   568       /* Disable malloc_fn and free_fn */
       
   569       memory_infop pinfo;
       
   570       png_set_mem_fn(png_ptr, NULL, NULL, NULL);
       
   571       pinfo = (memory_infop)png_malloc(png_ptr,
       
   572          (sizeof *pinfo));
       
   573       pinfo->size = size;
       
   574       current_allocation += size;
       
   575       total_allocation += size;
       
   576       num_allocations ++;
       
   577 
       
   578       if (current_allocation > maximum_allocation)
       
   579          maximum_allocation = current_allocation;
       
   580 
       
   581       pinfo->pointer = png_malloc(png_ptr, size);
       
   582       /* Restore malloc_fn and free_fn */
       
   583 
       
   584       png_set_mem_fn(png_ptr,
       
   585           NULL, png_debug_malloc, png_debug_free);
       
   586 
       
   587       if (size != 0 && pinfo->pointer == NULL)
       
   588       {
       
   589          current_allocation -= size;
       
   590          total_allocation -= size;
       
   591          png_error(png_ptr,
       
   592            "out of memory in pngtest->png_debug_malloc");
       
   593       }
       
   594 
       
   595       pinfo->next = pinformation;
       
   596       pinformation = pinfo;
       
   597       /* Make sure the caller isn't assuming zeroed memory. */
       
   598       memset(pinfo->pointer, 0xdd, pinfo->size);
       
   599 
       
   600       if (verbose != 0)
       
   601          printf("png_malloc %lu bytes at %p\n", (unsigned long)size,
       
   602             pinfo->pointer);
       
   603 
       
   604       return (png_voidp)(pinfo->pointer);
       
   605    }
       
   606 }
       
   607 
       
   608 /* Free a pointer.  It is removed from the list at the same time. */
       
   609 void PNGCBAPI
       
   610 png_debug_free(png_structp png_ptr, png_voidp ptr)
       
   611 {
       
   612    if (png_ptr == NULL)
       
   613       fprintf(STDERR, "NULL pointer to png_debug_free.\n");
       
   614 
       
   615    if (ptr == 0)
       
   616    {
       
   617 #if 0 /* This happens all the time. */
       
   618       fprintf(STDERR, "WARNING: freeing NULL pointer\n");
       
   619 #endif
       
   620       return;
       
   621    }
       
   622 
       
   623    /* Unlink the element from the list. */
       
   624    if (pinformation != NULL)
       
   625    {
       
   626       memory_infop *ppinfo = &pinformation;
       
   627 
       
   628       for (;;)
       
   629       {
       
   630          memory_infop pinfo = *ppinfo;
       
   631 
       
   632          if (pinfo->pointer == ptr)
       
   633          {
       
   634             *ppinfo = pinfo->next;
       
   635             current_allocation -= pinfo->size;
       
   636             if (current_allocation < 0)
       
   637                fprintf(STDERR, "Duplicate free of memory\n");
       
   638             /* We must free the list element too, but first kill
       
   639                the memory that is to be freed. */
       
   640             memset(ptr, 0x55, pinfo->size);
       
   641             free(pinfo);
       
   642             pinfo = NULL;
       
   643             break;
       
   644          }
       
   645 
       
   646          if (pinfo->next == NULL)
       
   647          {
       
   648             fprintf(STDERR, "Pointer %p not found\n", ptr);
       
   649             break;
       
   650          }
       
   651 
       
   652          ppinfo = &pinfo->next;
       
   653       }
       
   654    }
       
   655 
       
   656    /* Finally free the data. */
       
   657    if (verbose != 0)
       
   658       printf("Freeing %p\n", ptr);
       
   659 
       
   660    if (ptr != NULL)
       
   661       free(ptr);
       
   662    ptr = NULL;
       
   663 }
       
   664 #endif /* USER_MEM && DEBUG */
       
   665 /* END of code to test memory allocation/deallocation */
       
   666 
       
   667 
       
   668 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
       
   669 /* Demonstration of user chunk support of the sTER and vpAg chunks */
       
   670 
       
   671 /* (sTER is a public chunk not yet known by libpng.  vpAg is a private
       
   672 chunk used in ImageMagick to store "virtual page" size).  */
       
   673 
       
   674 static struct user_chunk_data
       
   675 {
       
   676    png_const_infop info_ptr;
       
   677    png_uint_32     vpAg_width, vpAg_height;
       
   678    png_byte        vpAg_units;
       
   679    png_byte        sTER_mode;
       
   680    int             location[2];
       
   681 }
       
   682 user_chunk_data;
       
   683 
       
   684 /* Used for location and order; zero means nothing. */
       
   685 #define have_sTER   0x01
       
   686 #define have_vpAg   0x02
       
   687 #define before_PLTE 0x10
       
   688 #define before_IDAT 0x20
       
   689 #define after_IDAT  0x40
       
   690 
       
   691 static void
       
   692 init_callback_info(png_const_infop info_ptr)
       
   693 {
       
   694    MEMZERO(user_chunk_data);
       
   695    user_chunk_data.info_ptr = info_ptr;
       
   696 }
       
   697 
       
   698 static int
       
   699 set_location(png_structp png_ptr, struct user_chunk_data *data, int what)
       
   700 {
       
   701    int location;
       
   702 
       
   703    if ((data->location[0] & what) != 0 || (data->location[1] & what) != 0)
       
   704       return 0; /* already have one of these */
       
   705 
       
   706    /* Find where we are (the code below zeroes info_ptr to indicate that the
       
   707     * chunks before the first IDAT have been read.)
       
   708     */
       
   709    if (data->info_ptr == NULL) /* after IDAT */
       
   710       location = what | after_IDAT;
       
   711 
       
   712    else if (png_get_valid(png_ptr, data->info_ptr, PNG_INFO_PLTE) != 0)
       
   713       location = what | before_IDAT;
       
   714 
       
   715    else
       
   716       location = what | before_PLTE;
       
   717 
       
   718    if (data->location[0] == 0)
       
   719       data->location[0] = location;
       
   720 
       
   721    else
       
   722       data->location[1] = location;
       
   723 
       
   724    return 1; /* handled */
       
   725 }
       
   726 
       
   727 static int PNGCBAPI
       
   728 read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk)
       
   729 {
       
   730    struct user_chunk_data *my_user_chunk_data =
       
   731       (struct user_chunk_data*)png_get_user_chunk_ptr(png_ptr);
       
   732 
       
   733    if (my_user_chunk_data == NULL)
       
   734       png_error(png_ptr, "lost user chunk pointer");
       
   735 
       
   736    /* Return one of the following:
       
   737     *    return (-n);  chunk had an error
       
   738     *    return (0);  did not recognize
       
   739     *    return (n);  success
       
   740     *
       
   741     * The unknown chunk structure contains the chunk data:
       
   742     * png_byte name[5];
       
   743     * png_byte *data;
       
   744     * png_size_t size;
       
   745     *
       
   746     * Note that libpng has already taken care of the CRC handling.
       
   747     */
       
   748 
       
   749    if (chunk->name[0] == 115 && chunk->name[1] ==  84 &&     /* s  T */
       
   750        chunk->name[2] ==  69 && chunk->name[3] ==  82)       /* E  R */
       
   751       {
       
   752          /* Found sTER chunk */
       
   753          if (chunk->size != 1)
       
   754             return (-1); /* Error return */
       
   755 
       
   756          if (chunk->data[0] != 0 && chunk->data[0] != 1)
       
   757             return (-1);  /* Invalid mode */
       
   758 
       
   759          if (set_location(png_ptr, my_user_chunk_data, have_sTER) != 0)
       
   760          {
       
   761             my_user_chunk_data->sTER_mode=chunk->data[0];
       
   762             return (1);
       
   763          }
       
   764 
       
   765          else
       
   766             return (0); /* duplicate sTER - give it to libpng */
       
   767       }
       
   768 
       
   769    if (chunk->name[0] != 118 || chunk->name[1] != 112 ||    /* v  p */
       
   770        chunk->name[2] !=  65 || chunk->name[3] != 103)      /* A  g */
       
   771       return (0); /* Did not recognize */
       
   772 
       
   773    /* Found ImageMagick vpAg chunk */
       
   774 
       
   775    if (chunk->size != 9)
       
   776       return (-1); /* Error return */
       
   777 
       
   778    if (set_location(png_ptr, my_user_chunk_data, have_vpAg) == 0)
       
   779       return (0);  /* duplicate vpAg */
       
   780 
       
   781    my_user_chunk_data->vpAg_width = png_get_uint_31(png_ptr, chunk->data);
       
   782    my_user_chunk_data->vpAg_height = png_get_uint_31(png_ptr, chunk->data + 4);
       
   783    my_user_chunk_data->vpAg_units = chunk->data[8];
       
   784 
       
   785    return (1);
       
   786 }
       
   787 
       
   788 #ifdef PNG_WRITE_SUPPORTED
       
   789 static void
       
   790 write_sTER_chunk(png_structp write_ptr)
       
   791 {
       
   792    png_byte sTER[5] = {115,  84,  69,  82, '\0'};
       
   793 
       
   794    if (verbose != 0)
       
   795       fprintf(STDERR, "\n stereo mode = %d\n", user_chunk_data.sTER_mode);
       
   796 
       
   797    png_write_chunk(write_ptr, sTER, &user_chunk_data.sTER_mode, 1);
       
   798 }
       
   799 
       
   800 static void
       
   801 write_vpAg_chunk(png_structp write_ptr)
       
   802 {
       
   803    png_byte vpAg[5] = {118, 112,  65, 103, '\0'};
       
   804 
       
   805    png_byte vpag_chunk_data[9];
       
   806 
       
   807    if (verbose != 0)
       
   808       fprintf(STDERR, " vpAg = %lu x %lu, units = %d\n",
       
   809         (unsigned long)user_chunk_data.vpAg_width,
       
   810         (unsigned long)user_chunk_data.vpAg_height,
       
   811         user_chunk_data.vpAg_units);
       
   812 
       
   813    png_save_uint_32(vpag_chunk_data, user_chunk_data.vpAg_width);
       
   814    png_save_uint_32(vpag_chunk_data + 4, user_chunk_data.vpAg_height);
       
   815    vpag_chunk_data[8] = user_chunk_data.vpAg_units;
       
   816    png_write_chunk(write_ptr, vpAg, vpag_chunk_data, 9);
       
   817 }
       
   818 
       
   819 static void
       
   820 write_chunks(png_structp write_ptr, int location)
       
   821 {
       
   822    int i;
       
   823 
       
   824    /* Notice that this preserves the original chunk order, however chunks
       
   825     * intercepted by the callback will be written *after* chunks passed to
       
   826     * libpng.  This will actually reverse a pair of sTER chunks or a pair of
       
   827     * vpAg chunks, resulting in an error later.  This is not worth worrying
       
   828     * about - the chunks should not be duplicated!
       
   829     */
       
   830    for (i=0; i<2; ++i)
       
   831    {
       
   832       if (user_chunk_data.location[i] == (location | have_sTER))
       
   833          write_sTER_chunk(write_ptr);
       
   834 
       
   835       else if (user_chunk_data.location[i] == (location | have_vpAg))
       
   836          write_vpAg_chunk(write_ptr);
       
   837    }
       
   838 }
       
   839 #endif /* WRITE */
       
   840 #else /* !READ_USER_CHUNKS */
       
   841 #  define write_chunks(pp,loc) ((void)0)
       
   842 #endif
       
   843 /* END of code to demonstrate user chunk support */
       
   844 
       
   845 /* START of code to check that libpng has the required text support; this only
       
   846  * checks for the write support because if read support is missing the chunk
       
   847  * will simply not be reported back to pngtest.
       
   848  */
       
   849 #ifdef PNG_TEXT_SUPPORTED
       
   850 static void
       
   851 pngtest_check_text_support(png_structp png_ptr, png_textp text_ptr,
       
   852    int num_text)
       
   853 {
       
   854    while (num_text > 0)
       
   855    {
       
   856       switch (text_ptr[--num_text].compression)
       
   857       {
       
   858          case PNG_TEXT_COMPRESSION_NONE:
       
   859             break;
       
   860 
       
   861          case PNG_TEXT_COMPRESSION_zTXt:
       
   862 #           ifndef PNG_WRITE_zTXt_SUPPORTED
       
   863                ++unsupported_chunks;
       
   864                /* In libpng 1.7 this now does an app-error, so stop it: */
       
   865                text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
       
   866 #           endif
       
   867             break;
       
   868 
       
   869          case PNG_ITXT_COMPRESSION_NONE:
       
   870          case PNG_ITXT_COMPRESSION_zTXt:
       
   871 #           ifndef PNG_WRITE_iTXt_SUPPORTED
       
   872                ++unsupported_chunks;
       
   873                text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
       
   874 #           endif
       
   875             break;
       
   876 
       
   877          default:
       
   878             /* This is an error */
       
   879             png_error(png_ptr, "invalid text chunk compression field");
       
   880             break;
       
   881       }
       
   882    }
       
   883 }
       
   884 #endif
       
   885 /* END of code to check that libpng has the required text support */
       
   886 
       
   887 /* Test one file */
       
   888 static int
       
   889 test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       
   890 {
       
   891    static png_FILE_p fpin;
       
   892    static png_FILE_p fpout;  /* "static" prevents setjmp corruption */
       
   893    pngtest_error_parameters error_parameters;
       
   894    png_structp read_ptr;
       
   895    png_infop read_info_ptr, end_info_ptr;
       
   896 #ifdef PNG_WRITE_SUPPORTED
       
   897    png_structp write_ptr;
       
   898    png_infop write_info_ptr;
       
   899    png_infop write_end_info_ptr;
       
   900 #ifdef PNG_WRITE_FILTER_SUPPORTED
       
   901    int interlace_preserved = 1;
       
   902 #endif /* WRITE_FILTER */
       
   903 #else /* !WRITE */
       
   904    png_structp write_ptr = NULL;
       
   905    png_infop write_info_ptr = NULL;
       
   906    png_infop write_end_info_ptr = NULL;
       
   907 #endif /* !WRITE */
       
   908    png_bytep row_buf;
       
   909    png_uint_32 y;
       
   910    png_uint_32 width, height;
       
   911    volatile int num_passes;
       
   912    int pass;
       
   913    int bit_depth, color_type;
       
   914 
       
   915    row_buf = NULL;
       
   916    error_parameters.file_name = inname;
       
   917 
       
   918    if ((fpin = fopen(inname, "rb")) == NULL)
       
   919    {
       
   920       fprintf(STDERR, "Could not find input file %s\n", inname);
       
   921       return (1);
       
   922    }
       
   923 
       
   924    if ((fpout = fopen(outname, "wb")) == NULL)
       
   925    {
       
   926       fprintf(STDERR, "Could not open output file %s\n", outname);
       
   927       FCLOSE(fpin);
       
   928       return (1);
       
   929    }
       
   930 
       
   931    pngtest_debug("Allocating read and write structures");
       
   932 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
       
   933    read_ptr =
       
   934       png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL,
       
   935       NULL, NULL, NULL, png_debug_malloc, png_debug_free);
       
   936 #else
       
   937    read_ptr =
       
   938       png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
       
   939 #endif
       
   940    png_set_error_fn(read_ptr, &error_parameters, pngtest_error,
       
   941       pngtest_warning);
       
   942 
       
   943 #ifdef PNG_WRITE_SUPPORTED
       
   944 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
       
   945    write_ptr =
       
   946       png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL,
       
   947       NULL, NULL, NULL, png_debug_malloc, png_debug_free);
       
   948 #else
       
   949    write_ptr =
       
   950       png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
       
   951 #endif
       
   952    png_set_error_fn(write_ptr, &error_parameters, pngtest_error,
       
   953       pngtest_warning);
       
   954 #endif
       
   955    pngtest_debug("Allocating read_info, write_info and end_info structures");
       
   956    read_info_ptr = png_create_info_struct(read_ptr);
       
   957    end_info_ptr = png_create_info_struct(read_ptr);
       
   958 #ifdef PNG_WRITE_SUPPORTED
       
   959    write_info_ptr = png_create_info_struct(write_ptr);
       
   960    write_end_info_ptr = png_create_info_struct(write_ptr);
       
   961 #endif
       
   962 
       
   963 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
       
   964    init_callback_info(read_info_ptr);
       
   965    png_set_read_user_chunk_fn(read_ptr, &user_chunk_data,
       
   966      read_user_chunk_callback);
       
   967 #endif
       
   968 
       
   969 #ifdef PNG_SETJMP_SUPPORTED
       
   970    pngtest_debug("Setting jmpbuf for read struct");
       
   971    if (setjmp(png_jmpbuf(read_ptr)))
       
   972    {
       
   973       fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
       
   974       png_free(read_ptr, row_buf);
       
   975       row_buf = NULL;
       
   976       png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
       
   977 #ifdef PNG_WRITE_SUPPORTED
       
   978       png_destroy_info_struct(write_ptr, &write_end_info_ptr);
       
   979       png_destroy_write_struct(&write_ptr, &write_info_ptr);
       
   980 #endif
       
   981       FCLOSE(fpin);
       
   982       FCLOSE(fpout);
       
   983       return (1);
       
   984    }
       
   985 
       
   986 #ifdef PNG_WRITE_SUPPORTED
       
   987    pngtest_debug("Setting jmpbuf for write struct");
       
   988 
       
   989    if (setjmp(png_jmpbuf(write_ptr)))
       
   990    {
       
   991       fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
       
   992       png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
       
   993       png_destroy_info_struct(write_ptr, &write_end_info_ptr);
       
   994 #ifdef PNG_WRITE_SUPPORTED
       
   995       png_destroy_write_struct(&write_ptr, &write_info_ptr);
       
   996 #endif
       
   997       FCLOSE(fpin);
       
   998       FCLOSE(fpout);
       
   999       return (1);
       
  1000    }
       
  1001 #endif
       
  1002 #endif
       
  1003 
       
  1004    if (strict != 0)
       
  1005    {
       
  1006       /* Treat png_benign_error() as errors on read */
       
  1007       png_set_benign_errors(read_ptr, 0);
       
  1008 
       
  1009 #ifdef PNG_WRITE_SUPPORTED
       
  1010       /* Treat them as errors on write */
       
  1011       png_set_benign_errors(write_ptr, 0);
       
  1012 #endif
       
  1013 
       
  1014       /* if strict is not set, then app warnings and errors are treated as
       
  1015        * warnings in release builds, but not in unstable builds; this can be
       
  1016        * changed with '--relaxed'.
       
  1017        */
       
  1018    }
       
  1019 
       
  1020    else if (relaxed != 0)
       
  1021    {
       
  1022       /* Allow application (pngtest) errors and warnings to pass */
       
  1023       png_set_benign_errors(read_ptr, 1);
       
  1024 
       
  1025 #ifdef PNG_WRITE_SUPPORTED
       
  1026       png_set_benign_errors(write_ptr, 1);
       
  1027 #endif
       
  1028    }
       
  1029 
       
  1030    pngtest_debug("Initializing input and output streams");
       
  1031 #ifdef PNG_STDIO_SUPPORTED
       
  1032    png_init_io(read_ptr, fpin);
       
  1033 #  ifdef PNG_WRITE_SUPPORTED
       
  1034    png_init_io(write_ptr, fpout);
       
  1035 #  endif
       
  1036 #else
       
  1037    png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data);
       
  1038 #  ifdef PNG_WRITE_SUPPORTED
       
  1039    png_set_write_fn(write_ptr, (png_voidp)fpout,  pngtest_write_data,
       
  1040 #    ifdef PNG_WRITE_FLUSH_SUPPORTED
       
  1041       pngtest_flush);
       
  1042 #    else
       
  1043       NULL);
       
  1044 #    endif
       
  1045 #  endif
       
  1046 #endif
       
  1047 
       
  1048    if (status_dots_requested == 1)
       
  1049    {
       
  1050 #ifdef PNG_WRITE_SUPPORTED
       
  1051       png_set_write_status_fn(write_ptr, write_row_callback);
       
  1052 #endif
       
  1053       png_set_read_status_fn(read_ptr, read_row_callback);
       
  1054    }
       
  1055 
       
  1056    else
       
  1057    {
       
  1058 #ifdef PNG_WRITE_SUPPORTED
       
  1059       png_set_write_status_fn(write_ptr, NULL);
       
  1060 #endif
       
  1061       png_set_read_status_fn(read_ptr, NULL);
       
  1062    }
       
  1063 
       
  1064 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
       
  1065    png_set_read_user_transform_fn(read_ptr, read_user_callback);
       
  1066 #endif
       
  1067 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
       
  1068    zero_samples = 0;
       
  1069    png_set_write_user_transform_fn(write_ptr, count_zero_samples);
       
  1070 #endif
       
  1071 
       
  1072 #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
       
  1073    /* Preserve all the unknown chunks, if possible.  If this is disabled then,
       
  1074     * even if the png_{get,set}_unknown_chunks stuff is enabled, we can't use
       
  1075     * libpng to *save* the unknown chunks on read (because we can't switch the
       
  1076     * save option on!)
       
  1077     *
       
  1078     * Notice that if SET_UNKNOWN_CHUNKS is *not* supported read will discard all
       
  1079     * unknown chunks and write will write them all.
       
  1080     */
       
  1081 #ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
       
  1082    png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS,
       
  1083       NULL, 0);
       
  1084 #endif
       
  1085 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
       
  1086    png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS,
       
  1087       NULL, 0);
       
  1088 #endif
       
  1089 #endif
       
  1090 
       
  1091    pngtest_debug("Reading info struct");
       
  1092    png_read_info(read_ptr, read_info_ptr);
       
  1093 
       
  1094 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
       
  1095    /* This is a bit of a hack; there is no obvious way in the callback function
       
  1096     * to determine that the chunks before the first IDAT have been read, so
       
  1097     * remove the info_ptr (which is only used to determine position relative to
       
  1098     * PLTE) here to indicate that we are after the IDAT.
       
  1099     */
       
  1100    user_chunk_data.info_ptr = NULL;
       
  1101 #endif
       
  1102 
       
  1103    pngtest_debug("Transferring info struct");
       
  1104    {
       
  1105       int interlace_type, compression_type, filter_type;
       
  1106 
       
  1107       if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
       
  1108           &color_type, &interlace_type, &compression_type, &filter_type) != 0)
       
  1109       {
       
  1110          png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
       
  1111             color_type, interlace_type, compression_type, filter_type);
       
  1112          /* num_passes may not be available below if interlace support is not
       
  1113           * provided by libpng for both read and write.
       
  1114           */
       
  1115          switch (interlace_type)
       
  1116          {
       
  1117             case PNG_INTERLACE_NONE:
       
  1118                num_passes = 1;
       
  1119                break;
       
  1120 
       
  1121             case PNG_INTERLACE_ADAM7:
       
  1122                num_passes = 7;
       
  1123                break;
       
  1124 
       
  1125             default:
       
  1126                png_error(read_ptr, "invalid interlace type");
       
  1127                /*NOT REACHED*/
       
  1128          }
       
  1129       }
       
  1130 
       
  1131       else
       
  1132          png_error(read_ptr, "png_get_IHDR failed");
       
  1133    }
       
  1134 #ifdef PNG_FIXED_POINT_SUPPORTED
       
  1135 #ifdef PNG_cHRM_SUPPORTED
       
  1136    {
       
  1137       png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
       
  1138          blue_y;
       
  1139 
       
  1140       if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y,
       
  1141          &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
       
  1142       {
       
  1143          png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x,
       
  1144             red_y, green_x, green_y, blue_x, blue_y);
       
  1145       }
       
  1146    }
       
  1147 #endif
       
  1148 #ifdef PNG_gAMA_SUPPORTED
       
  1149    {
       
  1150       png_fixed_point gamma;
       
  1151 
       
  1152       if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma) != 0)
       
  1153          png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma);
       
  1154    }
       
  1155 #endif
       
  1156 #else /* Use floating point versions */
       
  1157 #ifdef PNG_FLOATING_POINT_SUPPORTED
       
  1158 #ifdef PNG_cHRM_SUPPORTED
       
  1159    {
       
  1160       double white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
       
  1161          blue_y;
       
  1162 
       
  1163       if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
       
  1164          &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
       
  1165       {
       
  1166          png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
       
  1167             red_y, green_x, green_y, blue_x, blue_y);
       
  1168       }
       
  1169    }
       
  1170 #endif
       
  1171 #ifdef PNG_gAMA_SUPPORTED
       
  1172    {
       
  1173       double gamma;
       
  1174 
       
  1175       if (png_get_gAMA(read_ptr, read_info_ptr, &gamma) != 0)
       
  1176          png_set_gAMA(write_ptr, write_info_ptr, gamma);
       
  1177    }
       
  1178 #endif
       
  1179 #endif /* Floating point */
       
  1180 #endif /* Fixed point */
       
  1181 #ifdef PNG_iCCP_SUPPORTED
       
  1182    {
       
  1183       png_charp name;
       
  1184       png_bytep profile;
       
  1185       png_uint_32 proflen;
       
  1186       int compression_type;
       
  1187 
       
  1188       if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,
       
  1189                       &profile, &proflen) != 0)
       
  1190       {
       
  1191          png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,
       
  1192                       profile, proflen);
       
  1193       }
       
  1194    }
       
  1195 #endif
       
  1196 #ifdef PNG_sRGB_SUPPORTED
       
  1197    {
       
  1198       int intent;
       
  1199 
       
  1200       if (png_get_sRGB(read_ptr, read_info_ptr, &intent) != 0)
       
  1201          png_set_sRGB(write_ptr, write_info_ptr, intent);
       
  1202    }
       
  1203 #endif
       
  1204    {
       
  1205       png_colorp palette;
       
  1206       int num_palette;
       
  1207 
       
  1208       if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette) != 0)
       
  1209          png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
       
  1210    }
       
  1211 #ifdef PNG_bKGD_SUPPORTED
       
  1212    {
       
  1213       png_color_16p background;
       
  1214 
       
  1215       if (png_get_bKGD(read_ptr, read_info_ptr, &background) != 0)
       
  1216       {
       
  1217          png_set_bKGD(write_ptr, write_info_ptr, background);
       
  1218       }
       
  1219    }
       
  1220 #endif
       
  1221 #ifdef PNG_hIST_SUPPORTED
       
  1222    {
       
  1223       png_uint_16p hist;
       
  1224 
       
  1225       if (png_get_hIST(read_ptr, read_info_ptr, &hist) != 0)
       
  1226          png_set_hIST(write_ptr, write_info_ptr, hist);
       
  1227    }
       
  1228 #endif
       
  1229 #ifdef PNG_oFFs_SUPPORTED
       
  1230    {
       
  1231       png_int_32 offset_x, offset_y;
       
  1232       int unit_type;
       
  1233 
       
  1234       if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y,
       
  1235           &unit_type) != 0)
       
  1236       {
       
  1237          png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
       
  1238       }
       
  1239    }
       
  1240 #endif
       
  1241 #ifdef PNG_pCAL_SUPPORTED
       
  1242    {
       
  1243       png_charp purpose, units;
       
  1244       png_charpp params;
       
  1245       png_int_32 X0, X1;
       
  1246       int type, nparams;
       
  1247 
       
  1248       if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
       
  1249          &nparams, &units, &params) != 0)
       
  1250       {
       
  1251          png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
       
  1252             nparams, units, params);
       
  1253       }
       
  1254    }
       
  1255 #endif
       
  1256 #ifdef PNG_pHYs_SUPPORTED
       
  1257    {
       
  1258       png_uint_32 res_x, res_y;
       
  1259       int unit_type;
       
  1260 
       
  1261       if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y,
       
  1262           &unit_type) != 0)
       
  1263          png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
       
  1264    }
       
  1265 #endif
       
  1266 #ifdef PNG_sBIT_SUPPORTED
       
  1267    {
       
  1268       png_color_8p sig_bit;
       
  1269 
       
  1270       if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit) != 0)
       
  1271          png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
       
  1272    }
       
  1273 #endif
       
  1274 #ifdef PNG_sCAL_SUPPORTED
       
  1275 #if defined(PNG_FLOATING_POINT_SUPPORTED) && \
       
  1276    defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
       
  1277    {
       
  1278       int unit;
       
  1279       double scal_width, scal_height;
       
  1280 
       
  1281       if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,
       
  1282          &scal_height) != 0)
       
  1283       {
       
  1284          png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);
       
  1285       }
       
  1286    }
       
  1287 #else
       
  1288 #ifdef PNG_FIXED_POINT_SUPPORTED
       
  1289    {
       
  1290       int unit;
       
  1291       png_charp scal_width, scal_height;
       
  1292 
       
  1293       if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,
       
  1294           &scal_height) != 0)
       
  1295       {
       
  1296          png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width,
       
  1297              scal_height);
       
  1298       }
       
  1299    }
       
  1300 #endif
       
  1301 #endif
       
  1302 #endif
       
  1303 
       
  1304 #ifdef PNG_sPLT_SUPPORTED
       
  1305    {
       
  1306        png_sPLT_tp entries;
       
  1307 
       
  1308        int num_entries = (int) png_get_sPLT(read_ptr, read_info_ptr, &entries);
       
  1309        if (num_entries)
       
  1310        {
       
  1311            png_set_sPLT(write_ptr, write_info_ptr, entries, num_entries);
       
  1312        }
       
  1313    }
       
  1314 #endif
       
  1315 
       
  1316 #ifdef PNG_TEXT_SUPPORTED
       
  1317    {
       
  1318       png_textp text_ptr;
       
  1319       int num_text;
       
  1320 
       
  1321       if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
       
  1322       {
       
  1323          pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text);
       
  1324 
       
  1325          pngtest_check_text_support(read_ptr, text_ptr, num_text);
       
  1326 
       
  1327          if (verbose != 0)
       
  1328          {
       
  1329             int i;
       
  1330 
       
  1331             printf("\n");
       
  1332             for (i=0; i<num_text; i++)
       
  1333             {
       
  1334                printf("   Text compression[%d]=%d\n",
       
  1335                      i, text_ptr[i].compression);
       
  1336             }
       
  1337          }
       
  1338 
       
  1339          png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
       
  1340       }
       
  1341    }
       
  1342 #endif
       
  1343 #ifdef PNG_tIME_SUPPORTED
       
  1344    {
       
  1345       png_timep mod_time;
       
  1346 
       
  1347       if (png_get_tIME(read_ptr, read_info_ptr, &mod_time) != 0)
       
  1348       {
       
  1349          png_set_tIME(write_ptr, write_info_ptr, mod_time);
       
  1350 #ifdef PNG_TIME_RFC1123_SUPPORTED
       
  1351          if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0)
       
  1352             tIME_string[(sizeof tIME_string) - 1] = '\0';
       
  1353 
       
  1354          else
       
  1355          {
       
  1356             strncpy(tIME_string, "*** invalid time ***", (sizeof tIME_string));
       
  1357             tIME_string[(sizeof tIME_string) - 1] = '\0';
       
  1358          }
       
  1359 
       
  1360          tIME_chunk_present++;
       
  1361 #endif /* TIME_RFC1123 */
       
  1362       }
       
  1363    }
       
  1364 #endif
       
  1365 #ifdef PNG_tRNS_SUPPORTED
       
  1366    {
       
  1367       png_bytep trans_alpha;
       
  1368       int num_trans;
       
  1369       png_color_16p trans_color;
       
  1370 
       
  1371       if (png_get_tRNS(read_ptr, read_info_ptr, &trans_alpha, &num_trans,
       
  1372          &trans_color) != 0)
       
  1373       {
       
  1374          int sample_max = (1 << bit_depth);
       
  1375          /* libpng doesn't reject a tRNS chunk with out-of-range samples */
       
  1376          if (!((color_type == PNG_COLOR_TYPE_GRAY &&
       
  1377              (int)trans_color->gray > sample_max) ||
       
  1378              (color_type == PNG_COLOR_TYPE_RGB &&
       
  1379              ((int)trans_color->red > sample_max ||
       
  1380              (int)trans_color->green > sample_max ||
       
  1381              (int)trans_color->blue > sample_max))))
       
  1382             png_set_tRNS(write_ptr, write_info_ptr, trans_alpha, num_trans,
       
  1383                trans_color);
       
  1384       }
       
  1385    }
       
  1386 #endif
       
  1387 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
       
  1388    {
       
  1389       png_unknown_chunkp unknowns;
       
  1390       int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr,
       
  1391          &unknowns);
       
  1392 
       
  1393       if (num_unknowns != 0)
       
  1394       {
       
  1395          png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns,
       
  1396            num_unknowns);
       
  1397 #if PNG_LIBPNG_VER < 10600
       
  1398          /* Copy the locations from the read_info_ptr.  The automatically
       
  1399           * generated locations in write_end_info_ptr are wrong prior to 1.6.0
       
  1400           * because they are reset from the write pointer (removed in 1.6.0).
       
  1401           */
       
  1402          {
       
  1403             int i;
       
  1404             for (i = 0; i < num_unknowns; i++)
       
  1405               png_set_unknown_chunk_location(write_ptr, write_info_ptr, i,
       
  1406                 unknowns[i].location);
       
  1407          }
       
  1408 #endif
       
  1409       }
       
  1410    }
       
  1411 #endif
       
  1412 
       
  1413 #ifdef PNG_WRITE_SUPPORTED
       
  1414    pngtest_debug("Writing info struct");
       
  1415 
       
  1416    /* Write the info in two steps so that if we write the 'unknown' chunks here
       
  1417     * they go to the correct place.
       
  1418     */
       
  1419    png_write_info_before_PLTE(write_ptr, write_info_ptr);
       
  1420 
       
  1421    write_chunks(write_ptr, before_PLTE); /* before PLTE */
       
  1422 
       
  1423    png_write_info(write_ptr, write_info_ptr);
       
  1424 
       
  1425    write_chunks(write_ptr, before_IDAT); /* after PLTE */
       
  1426 #endif
       
  1427 
       
  1428 #ifdef SINGLE_ROWBUF_ALLOC
       
  1429    pngtest_debug("Allocating row buffer...");
       
  1430    row_buf = (png_bytep)png_malloc(read_ptr,
       
  1431       png_get_rowbytes(read_ptr, read_info_ptr));
       
  1432 
       
  1433    pngtest_debug1("\t0x%08lx", (unsigned long)row_buf);
       
  1434 #endif /* SINGLE_ROWBUF_ALLOC */
       
  1435    pngtest_debug("Writing row data");
       
  1436 
       
  1437 #if defined(PNG_READ_INTERLACING_SUPPORTED) &&\
       
  1438    defined(PNG_WRITE_INTERLACING_SUPPORTED)
       
  1439    /* Both must be defined for libpng to be able to handle the interlace,
       
  1440     * otherwise it gets handled below by simply reading and writing the passes
       
  1441     * directly.
       
  1442     */
       
  1443    if (png_set_interlace_handling(read_ptr) != num_passes)
       
  1444       png_error(write_ptr,
       
  1445             "png_set_interlace_handling(read): wrong pass count ");
       
  1446    if (png_set_interlace_handling(write_ptr) != num_passes)
       
  1447       png_error(write_ptr,
       
  1448             "png_set_interlace_handling(write): wrong pass count ");
       
  1449 #else /* png_set_interlace_handling not called on either read or write */
       
  1450 #  define calc_pass_height
       
  1451 #endif /* not using libpng interlace handling */
       
  1452 
       
  1453 #ifdef PNGTEST_TIMING
       
  1454    t_stop = (float)clock();
       
  1455    t_misc += (t_stop - t_start);
       
  1456    t_start = t_stop;
       
  1457 #endif
       
  1458    for (pass = 0; pass < num_passes; pass++)
       
  1459    {
       
  1460 #     ifdef calc_pass_height
       
  1461          png_uint_32 pass_height;
       
  1462 
       
  1463          if (num_passes == 7) /* interlaced */
       
  1464          {
       
  1465             if (PNG_PASS_COLS(width, pass) > 0)
       
  1466                pass_height = PNG_PASS_ROWS(height, pass);
       
  1467 
       
  1468             else
       
  1469                pass_height = 0;
       
  1470          }
       
  1471 
       
  1472          else /* not interlaced */
       
  1473             pass_height = height;
       
  1474 #     else
       
  1475 #        define pass_height height
       
  1476 #     endif
       
  1477 
       
  1478       pngtest_debug1("Writing row data for pass %d", pass);
       
  1479       for (y = 0; y < pass_height; y++)
       
  1480       {
       
  1481 #ifndef SINGLE_ROWBUF_ALLOC
       
  1482          pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y);
       
  1483 
       
  1484          row_buf = (png_bytep)png_malloc(read_ptr,
       
  1485             png_get_rowbytes(read_ptr, read_info_ptr));
       
  1486 
       
  1487          pngtest_debug2("\t0x%08lx (%lu bytes)", (unsigned long)row_buf,
       
  1488             (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr));
       
  1489 
       
  1490 #endif /* !SINGLE_ROWBUF_ALLOC */
       
  1491          png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1);
       
  1492 
       
  1493 #ifdef PNG_WRITE_SUPPORTED
       
  1494 #ifdef PNGTEST_TIMING
       
  1495          t_stop = (float)clock();
       
  1496          t_decode += (t_stop - t_start);
       
  1497          t_start = t_stop;
       
  1498 #endif
       
  1499          png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
       
  1500 #ifdef PNGTEST_TIMING
       
  1501          t_stop = (float)clock();
       
  1502          t_encode += (t_stop - t_start);
       
  1503          t_start = t_stop;
       
  1504 #endif
       
  1505 #endif /* WRITE */
       
  1506 
       
  1507 #ifndef SINGLE_ROWBUF_ALLOC
       
  1508          pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y);
       
  1509          png_free(read_ptr, row_buf);
       
  1510          row_buf = NULL;
       
  1511 #endif /* !SINGLE_ROWBUF_ALLOC */
       
  1512       }
       
  1513    }
       
  1514 
       
  1515 #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
       
  1516 #  ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
       
  1517       png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1);
       
  1518 #  endif
       
  1519 #  ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
       
  1520       png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1);
       
  1521 #  endif
       
  1522 #endif
       
  1523 
       
  1524    pngtest_debug("Reading and writing end_info data");
       
  1525 
       
  1526    png_read_end(read_ptr, end_info_ptr);
       
  1527 #ifdef PNG_TEXT_SUPPORTED
       
  1528    {
       
  1529       png_textp text_ptr;
       
  1530       int num_text;
       
  1531 
       
  1532       if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0)
       
  1533       {
       
  1534          pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text);
       
  1535 
       
  1536          pngtest_check_text_support(read_ptr, text_ptr, num_text);
       
  1537 
       
  1538          if (verbose != 0)
       
  1539          {
       
  1540             int i;
       
  1541 
       
  1542             printf("\n");
       
  1543             for (i=0; i<num_text; i++)
       
  1544             {
       
  1545                printf("   Text compression[%d]=%d\n",
       
  1546                      i, text_ptr[i].compression);
       
  1547             }
       
  1548          }
       
  1549 
       
  1550          png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text);
       
  1551       }
       
  1552    }
       
  1553 #endif
       
  1554 #ifdef PNG_tIME_SUPPORTED
       
  1555    {
       
  1556       png_timep mod_time;
       
  1557 
       
  1558       if (png_get_tIME(read_ptr, end_info_ptr, &mod_time) != 0)
       
  1559       {
       
  1560          png_set_tIME(write_ptr, write_end_info_ptr, mod_time);
       
  1561 #ifdef PNG_TIME_RFC1123_SUPPORTED
       
  1562          if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0)
       
  1563             tIME_string[(sizeof tIME_string) - 1] = '\0';
       
  1564 
       
  1565          else
       
  1566          {
       
  1567             strncpy(tIME_string, "*** invalid time ***", sizeof tIME_string);
       
  1568             tIME_string[(sizeof tIME_string)-1] = '\0';
       
  1569          }
       
  1570 
       
  1571          tIME_chunk_present++;
       
  1572 #endif /* TIME_RFC1123 */
       
  1573       }
       
  1574    }
       
  1575 #endif
       
  1576 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
       
  1577    {
       
  1578       png_unknown_chunkp unknowns;
       
  1579       int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr,
       
  1580          &unknowns);
       
  1581 
       
  1582       if (num_unknowns != 0)
       
  1583       {
       
  1584          png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,
       
  1585            num_unknowns);
       
  1586 #if PNG_LIBPNG_VER < 10600
       
  1587          /* Copy the locations from the read_info_ptr.  The automatically
       
  1588           * generated locations in write_end_info_ptr are wrong prior to 1.6.0
       
  1589           * because they are reset from the write pointer (removed in 1.6.0).
       
  1590           */
       
  1591          {
       
  1592             int i;
       
  1593             for (i = 0; i < num_unknowns; i++)
       
  1594               png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i,
       
  1595                 unknowns[i].location);
       
  1596          }
       
  1597 #endif
       
  1598       }
       
  1599    }
       
  1600 #endif
       
  1601 
       
  1602 #ifdef PNG_WRITE_SUPPORTED
       
  1603 #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
       
  1604    /* Normally one would use Z_DEFAULT_STRATEGY for text compression.
       
  1605     * This is here just to make pngtest replicate the results from libpng
       
  1606     * versions prior to 1.5.4, and to test this new API.
       
  1607     */
       
  1608    png_set_text_compression_strategy(write_ptr, Z_FILTERED);
       
  1609 #endif
       
  1610 
       
  1611    /* When the unknown vpAg/sTER chunks are written by pngtest the only way to
       
  1612     * do it is to write them *before* calling png_write_end.  When unknown
       
  1613     * chunks are written by libpng, however, they are written just before IEND.
       
  1614     * There seems to be no way round this, however vpAg/sTER are not expected
       
  1615     * after IDAT.
       
  1616     */
       
  1617    write_chunks(write_ptr, after_IDAT);
       
  1618 
       
  1619    png_write_end(write_ptr, write_end_info_ptr);
       
  1620 #endif
       
  1621 
       
  1622 #ifdef PNG_EASY_ACCESS_SUPPORTED
       
  1623    if (verbose != 0)
       
  1624    {
       
  1625       png_uint_32 iwidth, iheight;
       
  1626       iwidth = png_get_image_width(write_ptr, write_info_ptr);
       
  1627       iheight = png_get_image_height(write_ptr, write_info_ptr);
       
  1628       fprintf(STDERR, "\n Image width = %lu, height = %lu\n",
       
  1629          (unsigned long)iwidth, (unsigned long)iheight);
       
  1630    }
       
  1631 #endif
       
  1632 
       
  1633    pngtest_debug("Destroying data structs");
       
  1634 #ifdef SINGLE_ROWBUF_ALLOC
       
  1635    pngtest_debug("destroying row_buf for read_ptr");
       
  1636    png_free(read_ptr, row_buf);
       
  1637    row_buf = NULL;
       
  1638 #endif /* SINGLE_ROWBUF_ALLOC */
       
  1639    pngtest_debug("destroying read_ptr, read_info_ptr, end_info_ptr");
       
  1640    png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
       
  1641 #ifdef PNG_WRITE_SUPPORTED
       
  1642    pngtest_debug("destroying write_end_info_ptr");
       
  1643    png_destroy_info_struct(write_ptr, &write_end_info_ptr);
       
  1644    pngtest_debug("destroying write_ptr, write_info_ptr");
       
  1645    png_destroy_write_struct(&write_ptr, &write_info_ptr);
       
  1646 #endif
       
  1647    pngtest_debug("Destruction complete.");
       
  1648 
       
  1649    FCLOSE(fpin);
       
  1650    FCLOSE(fpout);
       
  1651 
       
  1652    /* Summarize any warnings or errors and in 'strict' mode fail the test.
       
  1653     * Unsupported chunks can result in warnings, in that case ignore the strict
       
  1654     * setting, otherwise fail the test on warnings as well as errors.
       
  1655     */
       
  1656    if (error_count > 0)
       
  1657    {
       
  1658       /* We don't really expect to get here because of the setjmp handling
       
  1659        * above, but this is safe.
       
  1660        */
       
  1661       fprintf(STDERR, "\n  %s: %d libpng errors found (%d warnings)",
       
  1662          inname, error_count, warning_count);
       
  1663 
       
  1664       if (strict != 0)
       
  1665          return (1);
       
  1666    }
       
  1667 
       
  1668 #  ifdef PNG_WRITE_SUPPORTED
       
  1669       /* If there is no write support nothing was written! */
       
  1670       else if (unsupported_chunks > 0)
       
  1671       {
       
  1672          fprintf(STDERR, "\n  %s: unsupported chunks (%d)%s",
       
  1673             inname, unsupported_chunks, strict ? ": IGNORED --strict!" : "");
       
  1674       }
       
  1675 #  endif
       
  1676 
       
  1677    else if (warning_count > 0)
       
  1678    {
       
  1679       fprintf(STDERR, "\n  %s: %d libpng warnings found",
       
  1680          inname, warning_count);
       
  1681 
       
  1682       if (strict != 0)
       
  1683          return (1);
       
  1684    }
       
  1685 
       
  1686    pngtest_debug("Opening files for comparison");
       
  1687    if ((fpin = fopen(inname, "rb")) == NULL)
       
  1688    {
       
  1689       fprintf(STDERR, "Could not find file %s\n", inname);
       
  1690       return (1);
       
  1691    }
       
  1692 
       
  1693    if ((fpout = fopen(outname, "rb")) == NULL)
       
  1694    {
       
  1695       fprintf(STDERR, "Could not find file %s\n", outname);
       
  1696       FCLOSE(fpin);
       
  1697       return (1);
       
  1698    }
       
  1699 
       
  1700 #if defined (PNG_WRITE_SUPPORTED) /* else nothing was written */ &&\
       
  1701     defined (PNG_WRITE_FILTER_SUPPORTED)
       
  1702    if (interlace_preserved != 0) /* else the files will be changed */
       
  1703    {
       
  1704       for (;;)
       
  1705       {
       
  1706          static int wrote_question = 0;
       
  1707          png_size_t num_in, num_out;
       
  1708          char inbuf[256], outbuf[256];
       
  1709 
       
  1710          num_in = fread(inbuf, 1, sizeof inbuf, fpin);
       
  1711          num_out = fread(outbuf, 1, sizeof outbuf, fpout);
       
  1712 
       
  1713          if (num_in != num_out)
       
  1714          {
       
  1715             fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
       
  1716                     inname, outname);
       
  1717 
       
  1718             if (wrote_question == 0 && unsupported_chunks == 0)
       
  1719             {
       
  1720                fprintf(STDERR,
       
  1721          "   Was %s written with the same maximum IDAT chunk size (%d bytes),",
       
  1722                  inname, PNG_ZBUF_SIZE);
       
  1723                fprintf(STDERR,
       
  1724                  "\n   filtering heuristic (libpng default), compression");
       
  1725                fprintf(STDERR,
       
  1726                  " level (zlib default),\n   and zlib version (%s)?\n\n",
       
  1727                  ZLIB_VERSION);
       
  1728                wrote_question = 1;
       
  1729             }
       
  1730 
       
  1731             FCLOSE(fpin);
       
  1732             FCLOSE(fpout);
       
  1733 
       
  1734             if (strict != 0 && unsupported_chunks == 0)
       
  1735               return (1);
       
  1736 
       
  1737             else
       
  1738               return (0);
       
  1739          }
       
  1740 
       
  1741          if (num_in == 0)
       
  1742             break;
       
  1743 
       
  1744          if (memcmp(inbuf, outbuf, num_in))
       
  1745          {
       
  1746             fprintf(STDERR, "\nFiles %s and %s are different\n", inname,
       
  1747                outname);
       
  1748 
       
  1749             if (wrote_question == 0 && unsupported_chunks == 0)
       
  1750             {
       
  1751                fprintf(STDERR,
       
  1752          "   Was %s written with the same maximum IDAT chunk size (%d bytes),",
       
  1753                     inname, PNG_ZBUF_SIZE);
       
  1754                fprintf(STDERR,
       
  1755                  "\n   filtering heuristic (libpng default), compression");
       
  1756                fprintf(STDERR,
       
  1757                  " level (zlib default),\n   and zlib version (%s)?\n\n",
       
  1758                  ZLIB_VERSION);
       
  1759                wrote_question = 1;
       
  1760             }
       
  1761 
       
  1762             FCLOSE(fpin);
       
  1763             FCLOSE(fpout);
       
  1764 
       
  1765             /* NOTE: the unsupported_chunks escape is permitted here because
       
  1766              * unsupported text chunk compression will result in the compression
       
  1767              * mode being changed (to NONE) yet, in the test case, the result
       
  1768              * can be exactly the same size!
       
  1769              */
       
  1770             if (strict != 0 && unsupported_chunks == 0)
       
  1771               return (1);
       
  1772 
       
  1773             else
       
  1774               return (0);
       
  1775          }
       
  1776       }
       
  1777    }
       
  1778 #endif /* WRITE && WRITE_FILTER */
       
  1779 
       
  1780    FCLOSE(fpin);
       
  1781    FCLOSE(fpout);
       
  1782 
       
  1783    return (0);
       
  1784 }
       
  1785 
       
  1786 /* Input and output filenames */
       
  1787 #ifdef RISCOS
       
  1788 static PNG_CONST char *inname = "pngtest/png";
       
  1789 static PNG_CONST char *outname = "pngout/png";
       
  1790 #else
       
  1791 static PNG_CONST char *inname = "pngtest.png";
       
  1792 static PNG_CONST char *outname = "pngout.png";
       
  1793 #endif
       
  1794 
       
  1795 int
       
  1796 main(int argc, char *argv[])
       
  1797 {
       
  1798    int multiple = 0;
       
  1799    int ierror = 0;
       
  1800 
       
  1801    png_structp dummy_ptr;
       
  1802 
       
  1803    fprintf(STDERR, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
       
  1804    fprintf(STDERR, "   with zlib   version %s\n", ZLIB_VERSION);
       
  1805    fprintf(STDERR, "%s", png_get_copyright(NULL));
       
  1806    /* Show the version of libpng used in building the library */
       
  1807    fprintf(STDERR, " library (%lu):%s",
       
  1808       (unsigned long)png_access_version_number(),
       
  1809       png_get_header_version(NULL));
       
  1810 
       
  1811    /* Show the version of libpng used in building the application */
       
  1812    fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER,
       
  1813       PNG_HEADER_VERSION_STRING);
       
  1814 
       
  1815    /* Do some consistency checking on the memory allocation settings, I'm
       
  1816     * not sure this matters, but it is nice to know, the first of these
       
  1817     * tests should be impossible because of the way the macros are set
       
  1818     * in pngconf.h
       
  1819     */
       
  1820 #if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
       
  1821       fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n");
       
  1822 #endif
       
  1823    /* I think the following can happen. */
       
  1824 #if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
       
  1825       fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n");
       
  1826 #endif
       
  1827 
       
  1828    if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
       
  1829    {
       
  1830       fprintf(STDERR,
       
  1831          "Warning: versions are different between png.h and png.c\n");
       
  1832       fprintf(STDERR, "  png.h version: %s\n", PNG_LIBPNG_VER_STRING);
       
  1833       fprintf(STDERR, "  png.c version: %s\n\n", png_libpng_ver);
       
  1834       ++ierror;
       
  1835    }
       
  1836 
       
  1837    if (argc > 1)
       
  1838    {
       
  1839       if (strcmp(argv[1], "-m") == 0)
       
  1840       {
       
  1841          multiple = 1;
       
  1842          status_dots_requested = 0;
       
  1843       }
       
  1844 
       
  1845       else if (strcmp(argv[1], "-mv") == 0 ||
       
  1846                strcmp(argv[1], "-vm") == 0 )
       
  1847       {
       
  1848          multiple = 1;
       
  1849          verbose = 1;
       
  1850          status_dots_requested = 1;
       
  1851       }
       
  1852 
       
  1853       else if (strcmp(argv[1], "-v") == 0)
       
  1854       {
       
  1855          verbose = 1;
       
  1856          status_dots_requested = 1;
       
  1857          inname = argv[2];
       
  1858       }
       
  1859 
       
  1860       else if (strcmp(argv[1], "--strict") == 0)
       
  1861       {
       
  1862          status_dots_requested = 0;
       
  1863          verbose = 1;
       
  1864          inname = argv[2];
       
  1865          strict++;
       
  1866          relaxed = 0;
       
  1867       }
       
  1868 
       
  1869       else if (strcmp(argv[1], "--relaxed") == 0)
       
  1870       {
       
  1871          status_dots_requested = 0;
       
  1872          verbose = 1;
       
  1873          inname = argv[2];
       
  1874          strict = 0;
       
  1875          relaxed++;
       
  1876       }
       
  1877 
       
  1878       else
       
  1879       {
       
  1880          inname = argv[1];
       
  1881          status_dots_requested = 0;
       
  1882       }
       
  1883    }
       
  1884 
       
  1885    if (multiple == 0 && argc == 3 + verbose)
       
  1886      outname = argv[2 + verbose];
       
  1887 
       
  1888    if ((multiple == 0 && argc > 3 + verbose) ||
       
  1889        (multiple != 0 && argc < 2))
       
  1890    {
       
  1891      fprintf(STDERR,
       
  1892        "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
       
  1893         argv[0], argv[0]);
       
  1894      fprintf(STDERR,
       
  1895        "  reads/writes one PNG file (without -m) or multiple files (-m)\n");
       
  1896      fprintf(STDERR,
       
  1897        "  with -m %s is used as a temporary file\n", outname);
       
  1898      exit(1);
       
  1899    }
       
  1900 
       
  1901    if (multiple != 0)
       
  1902    {
       
  1903       int i;
       
  1904 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
       
  1905       int allocation_now = current_allocation;
       
  1906 #endif
       
  1907       for (i=2; i<argc; ++i)
       
  1908       {
       
  1909          int kerror;
       
  1910          fprintf(STDERR, "\n Testing %s:", argv[i]);
       
  1911 #if PNG_DEBUG > 0
       
  1912          fprintf(STDERR, "\n");
       
  1913 #endif
       
  1914          kerror = test_one_file(argv[i], outname);
       
  1915          if (kerror == 0)
       
  1916          {
       
  1917 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
       
  1918             fprintf(STDERR, "\n PASS (%lu zero samples)\n",
       
  1919                (unsigned long)zero_samples);
       
  1920 #else
       
  1921             fprintf(STDERR, " PASS\n");
       
  1922 #endif
       
  1923 #ifdef PNG_TIME_RFC1123_SUPPORTED
       
  1924             if (tIME_chunk_present != 0)
       
  1925                fprintf(STDERR, " tIME = %s\n", tIME_string);
       
  1926 
       
  1927             tIME_chunk_present = 0;
       
  1928 #endif /* TIME_RFC1123 */
       
  1929          }
       
  1930 
       
  1931          else
       
  1932          {
       
  1933             fprintf(STDERR, " FAIL\n");
       
  1934             ierror += kerror;
       
  1935          }
       
  1936 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
       
  1937          if (allocation_now != current_allocation)
       
  1938             fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
       
  1939                current_allocation - allocation_now);
       
  1940 
       
  1941          if (current_allocation != 0)
       
  1942          {
       
  1943             memory_infop pinfo = pinformation;
       
  1944 
       
  1945             fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
       
  1946                current_allocation);
       
  1947 
       
  1948             while (pinfo != NULL)
       
  1949             {
       
  1950                fprintf(STDERR, " %lu bytes at %p\n",
       
  1951                  (unsigned long)pinfo->size,
       
  1952                  pinfo->pointer);
       
  1953                pinfo = pinfo->next;
       
  1954             }
       
  1955          }
       
  1956 #endif
       
  1957       }
       
  1958 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
       
  1959          fprintf(STDERR, " Current memory allocation: %10d bytes\n",
       
  1960             current_allocation);
       
  1961          fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
       
  1962             maximum_allocation);
       
  1963          fprintf(STDERR, " Total   memory allocation: %10d bytes\n",
       
  1964             total_allocation);
       
  1965          fprintf(STDERR, "     Number of allocations: %10d\n",
       
  1966             num_allocations);
       
  1967 #endif
       
  1968    }
       
  1969 
       
  1970    else
       
  1971    {
       
  1972       int i;
       
  1973       for (i = 0; i<3; ++i)
       
  1974       {
       
  1975          int kerror;
       
  1976 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
       
  1977          int allocation_now = current_allocation;
       
  1978 #endif
       
  1979          if (i == 1)
       
  1980             status_dots_requested = 1;
       
  1981 
       
  1982          else if (verbose == 0)
       
  1983             status_dots_requested = 0;
       
  1984 
       
  1985          if (i == 0 || verbose == 1 || ierror != 0)
       
  1986          {
       
  1987             fprintf(STDERR, "\n Testing %s:", inname);
       
  1988 #if PNG_DEBUG > 0
       
  1989             fprintf(STDERR, "\n");
       
  1990 #endif
       
  1991          }
       
  1992 
       
  1993          kerror = test_one_file(inname, outname);
       
  1994 
       
  1995          if (kerror == 0)
       
  1996          {
       
  1997             if (verbose == 1 || i == 2)
       
  1998             {
       
  1999 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
       
  2000                 fprintf(STDERR, "\n PASS (%lu zero samples)\n",
       
  2001                    (unsigned long)zero_samples);
       
  2002 #else
       
  2003                 fprintf(STDERR, " PASS\n");
       
  2004 #endif
       
  2005 #ifdef PNG_TIME_RFC1123_SUPPORTED
       
  2006              if (tIME_chunk_present != 0)
       
  2007                 fprintf(STDERR, " tIME = %s\n", tIME_string);
       
  2008 #endif /* TIME_RFC1123 */
       
  2009             }
       
  2010          }
       
  2011 
       
  2012          else
       
  2013          {
       
  2014             if (verbose == 0 && i != 2)
       
  2015             {
       
  2016                fprintf(STDERR, "\n Testing %s:", inname);
       
  2017 #if PNG_DEBUG > 0
       
  2018                fprintf(STDERR, "\n");
       
  2019 #endif
       
  2020             }
       
  2021 
       
  2022             fprintf(STDERR, " FAIL\n");
       
  2023             ierror += kerror;
       
  2024          }
       
  2025 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
       
  2026          if (allocation_now != current_allocation)
       
  2027              fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
       
  2028                current_allocation - allocation_now);
       
  2029 
       
  2030          if (current_allocation != 0)
       
  2031          {
       
  2032              memory_infop pinfo = pinformation;
       
  2033 
       
  2034              fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
       
  2035                 current_allocation);
       
  2036 
       
  2037              while (pinfo != NULL)
       
  2038              {
       
  2039                 fprintf(STDERR, " %lu bytes at %p\n",
       
  2040                    (unsigned long)pinfo->size, pinfo->pointer);
       
  2041                 pinfo = pinfo->next;
       
  2042              }
       
  2043           }
       
  2044 #endif
       
  2045        }
       
  2046 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
       
  2047        fprintf(STDERR, " Current memory allocation: %10d bytes\n",
       
  2048           current_allocation);
       
  2049        fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
       
  2050           maximum_allocation);
       
  2051        fprintf(STDERR, " Total   memory allocation: %10d bytes\n",
       
  2052           total_allocation);
       
  2053        fprintf(STDERR, "     Number of allocations: %10d\n",
       
  2054             num_allocations);
       
  2055 #endif
       
  2056    }
       
  2057 
       
  2058 #ifdef PNGTEST_TIMING
       
  2059    t_stop = (float)clock();
       
  2060    t_misc += (t_stop - t_start);
       
  2061    t_start = t_stop;
       
  2062    fprintf(STDERR, " CPU time used = %.3f seconds",
       
  2063       (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
       
  2064    fprintf(STDERR, " (decoding %.3f,\n",
       
  2065       t_decode/(float)CLOCKS_PER_SEC);
       
  2066    fprintf(STDERR, "        encoding %.3f ,",
       
  2067       t_encode/(float)CLOCKS_PER_SEC);
       
  2068    fprintf(STDERR, " other %.3f seconds)\n\n",
       
  2069       t_misc/(float)CLOCKS_PER_SEC);
       
  2070 #endif
       
  2071 
       
  2072    if (ierror == 0)
       
  2073       fprintf(STDERR, " libpng passes test\n");
       
  2074 
       
  2075    else
       
  2076       fprintf(STDERR, " libpng FAILS test\n");
       
  2077 
       
  2078    dummy_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
       
  2079    fprintf(STDERR, " Default limits:\n");
       
  2080    fprintf(STDERR, "  width_max  = %lu\n",
       
  2081       (unsigned long) png_get_user_width_max(dummy_ptr));
       
  2082    fprintf(STDERR, "  height_max = %lu\n",
       
  2083       (unsigned long) png_get_user_height_max(dummy_ptr));
       
  2084    if (png_get_chunk_cache_max(dummy_ptr) == 0)
       
  2085       fprintf(STDERR, "  cache_max  = unlimited\n");
       
  2086    else
       
  2087       fprintf(STDERR, "  cache_max  = %lu\n",
       
  2088          (unsigned long) png_get_chunk_cache_max(dummy_ptr));
       
  2089    if (png_get_chunk_malloc_max(dummy_ptr) == 0)
       
  2090       fprintf(STDERR, "  malloc_max = unlimited\n");
       
  2091    else
       
  2092       fprintf(STDERR, "  malloc_max = %lu\n",
       
  2093          (unsigned long) png_get_chunk_malloc_max(dummy_ptr));
       
  2094    png_destroy_read_struct(&dummy_ptr, NULL, NULL);
       
  2095 
       
  2096    return (int)(ierror != 0);
       
  2097 }
       
  2098 #else
       
  2099 int
       
  2100 main(void)
       
  2101 {
       
  2102    fprintf(STDERR,
       
  2103       " test ignored because libpng was not built with read support\n");
       
  2104    /* And skip this test */
       
  2105    return SKIP;
       
  2106 }
       
  2107 #endif
       
  2108 
       
  2109 /* Generate a compiler error if there is an old png.h in the search path. */
       
  2110 typedef png_libpng_version_1_6_23 Your_png_h_is_not_version_1_6_23;