"Fossies" - the Fresh Open Source Software Archive

Member "pngcrush-1.8.13/pngcrush.c" (21 Aug 2017, 341871 Bytes) of package /linux/privat/pngcrush-1.8.13.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "pngcrush.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.8.12_vs_1.8.13.

    1 
    2 /* pngcrush.c - recompresses png files
    3  * Copyright (C) 1998-2002, 2006-2017 Glenn Randers-Pehrson
    4  *                                   (glennrp at users.sf.net)
    5  * Portions Copyright (C) 2005 Greg Roelofs
    6  */
    7 
    8 #define PNGCRUSH_VERSION "1.8.13"
    9 
   10 #undef BLOCKY_DEINTERLACE
   11 
   12 /* This software is released under a license derived from the libpng
   13  * license (see LICENSE, below).
   14  *
   15  * The most recent version of pngcrush can be found at SourceForge in
   16  * http://pmt.sf.net/pngcrush/
   17  *
   18  * This program reads in a PNG image, and writes it out again, with the
   19  * optimum filter_method and zlib_level.  It uses brute force (trying
   20  * filter_method none, and libpng adaptive filtering, with compression
   21  * levels 3 and 9).
   22  *
   23  * Optionally, it can remove unwanted chunks or add gAMA, sRGB, bKGD,
   24  * tEXt/zTXt, and tRNS chunks.  It will remove some chunks such as gAMA,
   25  * cHRM, pHYs, and oFFs when their data fields contain all zero, which is a
   26  * mistake.
   27  *
   28  * Uses libpng and zlib.  This program was based upon libpng's pngtest.c.
   29  *
   30  * NOTICES:
   31  *
   32  * If you have modified this source, you may insert additional notices
   33  * immediately after this sentence.
   34  *
   35  * COPYRIGHT:
   36  *
   37  * Copyright (C) 1998-2002, 2006-2017 Glenn Randers-Pehrson
   38  *                                   (glennrp at users.sf.net)
   39  * Portions Copyright (C) 2005 Greg Roelofs
   40  *
   41  * LICENSE:
   42  *
   43  * Permission is hereby irrevocably granted to everyone to use, copy, modify,
   44  * and distribute this source code, or portions hereof, or executable programs
   45  * compiled from it, for any purpose, without payment of any fee, subject to
   46  * the following restrictions:
   47  *
   48  * 1. The origin of this source code must not be misrepresented.
   49  *
   50  * 2. Altered versions must be plainly marked as such and must not be
   51  *    misrepresented as being the original source.
   52  *
   53  * 3. This Copyright notice, disclaimers, and license may not be removed
   54  *    or altered from any source or altered source distribution.
   55  *
   56  * DISCLAIMERS:
   57  *
   58  * The pngcrush computer program is supplied "AS IS".  The Author disclaims all
   59  * warranties, expressed or implied, including, without limitation, the
   60  * warranties of merchantability and of fitness for any purpose.  The
   61  * Author assumes no liability for direct, indirect, incidental, special,
   62  * exemplary, or consequential damages, which may result from the use of
   63  * the computer program, even if advised of the possibility of such damage.
   64  * There is no warranty against interference with your enjoyment of the
   65  * computer program or against infringement.  There is no warranty that my
   66  * efforts or the computer program will fulfill any of your particular purposes
   67  * or needs.  This computer program is provided with all faults, and the entire
   68  * risk of satisfactory quality, performance, accuracy, and effort is with
   69  * the user.
   70  *
   71  * EXPORT CONTROL
   72  *
   73  * I am not a lawyer, but I believe that the Export Control Classification
   74  * Number (ECCN) for pngcrush is EAR99, which means not subject to export
   75  * controls or International Traffic in Arms Regulations (ITAR) because it
   76  * and cexcept.c, libpng, and zlib, which may be bundled with pngcrush, are
   77  * all open source, publicly available software, that do not contain any
   78  * encryption software. See the EAR, paragraphs 734.3(b)(3) and 734.7(b).
   79  *
   80  * TRADEMARK:
   81  *
   82  * The name "pngcrush" has not been registered by the Copyright owner
   83  * as a trademark in any jurisdiction.  However, because pngcrush has
   84  * been distributed and maintained world-wide, continually since 1998,
   85  * the Copyright owner claims "common-law trademark protection" in any
   86  * jurisdiction where common-law trademark is recognized.
   87  *
   88  * CEXCEPT COPYRIGHT, DISCLAIMER, and LICENSE:
   89  *
   90  * The cexcept.h header file which is bundled with this software
   91  * is conveyed under the license and disclaimer described in lines 10
   92  * through 18 of cexcept.h.
   93  *
   94  * LIBPNG COPYRIGHT, DISCLAIMER, and LICENSE:
   95  *
   96  * If libpng is bundled with this software, it is conveyed under the
   97  * libpng license (see COPYRIGHT NOTICE, DISCLAIMER, and LICENSE, in png.h).
   98  *
   99  * If intel_init.c and filter_sse2_intrinsics.c are bundled with this
  100  * software, they are conveyed under the libpng license (see the
  101  * copyright notices within those files and the COPYRIGHT NOTICE, DISCLAIMER,
  102  * and LICENSE in png.h).
  103  *
  104  * ZLIB COPYRIGHT, DISCLAIMER, and LICENSE:
  105  *
  106  * If zlib is bundled with this software, it is conveyed under the
  107  * zlib license (see the copyright notice, disclaimer, and license
  108  * appearing in zlib.h).
  109  *
  110  * ACKNOWLEDGMENTS:
  111  *
  112  * Thanks to Greg Roelofs for various bug fixes, suggestions, and
  113  * occasionally creating Linux executables.
  114  *
  115  * Thanks to Stephan Levavej for some helpful suggestions about gcc compiler
  116  * options and for a suggestion to increase the Z_MEM_LEVEL from default.
  117  *
  118  * Thanks to others who have made bug reports and suggestions mentioned
  119  * in the change log.
  120  *
  121  * CAUTION:
  122  *
  123  * There is another version of pngcrush that has been distributed by
  124  * Apple since mid-2008 as a part of the Xcode SDK.   Although it claims
  125  * to be pngcrush by Glenn Randers-Pehrson, it has additional options
  126  * "-iPhone", "-speed", "-revert-iphone-optimizations", and perhaps others.
  127  * It is an "altered version".  I've seen output from a 2006 version that
  128  * says on its help screen, "and modified by Apple as indicated in the
  129  * sources".
  130  *
  131  * It writes files that have the PNG 8-byte signature but are not valid PNG
  132  * files (instead they are "IOS-optimized PNG files"), due to at least
  133  *
  134  *  1. the presence of the CgBI chunk ahead of the IHDR chunk;
  135  *  2. nonstandard deflate compression in IDAT, iCCP, and perhaps zTXt chunks
  136  *     (I believe this only amounts to the omission of the zlib header from
  137  *     the IDAT and perhaps other compressed chunks);
  138  *  3. Omission of the CRC bytes from the IDAT chunk and perhaps other chunks;
  139  *  4. the use of premultiplied alpha in color_type 6 files; and
  140  *  5. the sample order, which is ARGB instead of RGBA in color_type 6 files.
  141  *
  142  * See http://iphonedevwiki.net/index.php/CgBI_file_format for more info.
  143  *
  144  * Although there is no loss in converting a CgBI PNG back to a regular
  145  * PNG file, the original PNG file cannot be losslessly recovered from such
  146  * files because of the losses that occurred during the conversion to
  147  * premultiplied alpha.
  148  *
  149  * Most PNG decoders will recognize the fact that an unknown critical
  150  * chunk "CgBI" is present and will immediately reject the file.
  151  *
  152  * It is said that the Xcode version of pngcrush is automatically applied
  153  * when PNG files are prepared for downloading to the iPhone unless the
  154  * user takes special measures to prevent it.
  155  *
  156  * It is said that the Xcode pngcrush does have a command to undo the
  157  * premultiplied alpha.  It's not theoretically possible, however, to recover
  158  * the original file without loss.  The underlying color data will either be
  159  * reduced in precision, or, in the case of fully-transparent pixels,
  160  * completely lost.
  161  *
  162  * I have not seen the source for the Xcode version of pngcrush.  All I
  163  * know, for now, is from running "strings -a" on an old copy of the
  164  * executable, looking at two Xcode-PNG files, and reading Apple's patent
  165  * application <http://www.freepatentsonline.com/y2008/0177769.html>.  Anyone
  166  * who does have access to the revised pngcrush code cannot show it to me
  167  * anyhow because of their Non-Disclosure Agreement with Apple.
  168  */
  169 
  170 /* To do (TODO, TO DO):
  171  *
  172  *   (As noted below, some of the features that aren't yet implemented
  173  *   in pngcrush are already available in ImageMagick; you can try a
  174  *   workflow that makes a first pass over the image with ImageMagick
  175  *   to select the bit depth, color type, interlacing, etc., and then makes
  176  *   another pass with pngcrush to optimize the compression, and finally
  177  *   makes a pass with libpng's "pngfix" app to optimize the zlib CMF
  178  *   bytes.)
  179  *
  180  *   0. Make pngcrush optionally operate as a filter, writing the crushed PNG
  181  *   to standard output, if an output file is not given, and reading
  182  *   the source file from standard input if no input file is given.
  183  *
  184  *   1. Reset CINFO to reflect decoder's required window size (instead of
  185  *   libz-1.1.3 encoder's required window size, which is 262 bytes larger).
  186  *   See discussion about zlib in png-list archives for April 2001.
  187  *   libpng-1.2.9 does some of this and libpng-1.5.4 does better.
  188  *   But neither has access to the entire datastream, so pngcrush could
  189  *   do even better.
  190  *
  191  *   This has no effect on the "crushed" filesize.  The reason for setting
  192  *   CINFO properly is to provide the *decoder* with information that will
  193  *   allow it to request only the minimum amount of memory required to decode
  194  *   the image (note that libpng-based decoders don't make use of this
  195  *   hint, because of the large number of files found in the wild that have
  196  *   incorrect CMF bytes).
  197  *
  198  *   In the meantime, one can just run
  199  *
  200  *      pc input.png crushed.png
  201  *
  202  *      where the "pc" script is the following:
  203  *
  204  *      #!/bin/sh
  205  *      cp $1 temp-$$.png
  206  *      for w in 512 1 2 4 8 16 32
  207  *      do
  208  *      pngcrush -ow -w $w -brute temp-$$.png
  209  *      done
  210  *      mv temp-$$.png $2
  211  *
  212  *   It turns out that sometimes this finds a smaller compressed PNG
  213  *   than plain "pngcrush -brute input.png crushed.png" finds.
  214  *
  215  *   There are several ways that pngcrush could implement this.
  216  *
  217  *      a. Revise the bundled zlib to report the maximum window size that
  218  *      it actually used, then rewrite CINFO to contain the next power-of-two
  219  *      size equal or larger than the size.  This method would of course
  220  *      only work when pngcrush is built with the bundled zlib, and won't
  221  *      work with zopfli compression.
  222  *
  223  *      b. Do additional trials after the best filter method, strategy,
  224  *      and compression level have been determined, using those settings
  225  *      and reducing the window size until the measured filesize increases,
  226  *      then choosing the smallest size which did not cause the filesize
  227  *      to increase.  This is expensive.
  228  *
  229  *      c. After the trials are complete, replace CINFO with smaller
  230  *      settings, then attempt to decode the zlib datastream, and choose
  231  *      the smallest setting whose datastream can still be decoded
  232  *      successfully.  This is likely to be the simplest and fastest
  233  *      solution; however, it will only work with a version of libpng
  234  *      in which the decoder actually uses the CINFO hint.
  235  *      This seems to be the only method that would work with zopfli
  236  *      compression which always writes "7" (i.e., a 32k window) in CINFO.
  237  *
  238  *      d. The simplest is to use pngfix, which comes with libpng16 and
  239  *      later, as a final step:
  240  *
  241  *           pngcrush input.png temp.png
  242  *           pngfix --optimize --out=output.png temp.png
  243  *           # To do: find out if this works with zopfli output
  244  *
  245  *   2. Check for the possiblity of using the tRNS chunk instead of
  246  *      the full alpha channel.  If all of the transparent pixels are
  247  *      fully transparent, and they all have the same underlying color,
  248  *      and no opaque pixel has that same color, then write a tRNS
  249  *      chunk and reduce the color-type to 0 or 2. This is a lossless
  250  *      operation.  ImageMagick already does this, as of version 6.7.0.
  251  *      If the lossy "-blacken" option is present, do that operation first.
  252  *
  253  *   3. Add choice of interlaced or non-interlaced output. Currently you
  254  *   can change interlaced to non-interlaced and vice versa by using
  255  *   ImageMagick before running pngcrush.  Note, when implementing this,
  256  *   disallow changing interlacing if APNG chunks are being copied.
  257  *
  258  *   4. Use a better compression algorithm for "deflating" (result must
  259  *   still be readable with zlib!)  e.g., http://en.wikipedia.org/wiki/7-Zip
  260  *   says that the 7-zip deflate compressor achieves better compression
  261  *   (smaller files) than zlib.  If tests show that this would be worth
  262  *   while, incorporate the 7-zip compressor as an optional alternative
  263  *   or additional method of pngcrush compression. See the GPL-licensed code
  264  *   at http://en.wikipedia.org/wiki/AdvanceCOMP and note that if this
  265  *   is incorporated in pngcrush, then pngcrush would have to be re-licensed,
  266  *   or released in two versions, one libpng-licensed and one GPL-licensed!
  267  *
  268  *   Also consider Google's "zopfli" compressor, which is said to slow but
  269  *   achieves better compression.  It is Apache-2.0 licensed and available from
  270  *   a GIT repository at SourceForge (see https://code.google.com/p/zopfli/).
  271  *   See also the "pngzop" directory under the pmt.sourceforge.net project.
  272  *   Note paragraph 1.c above; zopfli always writes "7" in CINFO.  See
  273  *   my "pmt/pngzop" project at SourceForge and GitHub.
  274  *
  275  *   5. Optionally recognize any sRGB iCCP profile and replace it with the
  276  *   sRGB chunk.  Turn this option on if the "-reduce" option is on.  Also,
  277  *   if "-reduce" is on, delete any gAMA and cHRM chunks if the sRGB chunk
  278  *   is being written.
  279  *
  280  *   6. Accept "--long-option".  For starters, just accept -long_option
  281  *   and --long_option equally.
  282  *
  283  *   7. Implement a "copy_idat" option that simply copies the IDAT data,
  284  *   implemented as "-m 176". This will still repackage the IDAT chunks
  285  *   in a possibly different IDAT chunk size.
  286  *
  287  *   8. Implement palette-building (from ImageMagick-6.7.0 or later, minus
  288  *   the "PNG8" part) -- actually ImageMagick puts the transparent colors
  289  *   first, then the semitransparent colors, and finally the opaque colors,
  290  *   and does not sort colors by frequency of use but just adds them
  291  *   to the palette/colormap as it encounters them, so it might be improved.
  292  *   Also it might be made faster by using a hash table as was partially
  293  *   implemented in pngcrush-1.6.x.  If the latter is done, also port that
  294  *   back to ImageMagick/GraphicsMagick.  See also ppmhist from the NetPBM
  295  *   package which counts RGB pixels in an image; this and its supporting
  296  *   lib/libppmcmap.c would need to be revised to count RGBA pixels instead.
  297  *
  298  *   9. Improve the -help output and/or write a good man page.
  299  *
  300  *   10. Finish pplt (MNG partial palette) feature.
  301  *
  302  *   11. Remove text-handling and color-handling features and put
  303  *   those in a separate program or programs, to avoid unnecessary
  304  *   recompressing.  Note that in pngcrush-1.7.34, pngcrush began doing
  305  *   this extra work only once instead of for every trial, so the potential
  306  *   benefit in CPU savings is much smaller now.
  307  *
  308  *   12. Add a "pcRu" ancillary chunk that keeps track of the best method,
  309  *   methods already tried, and whether "loco crushing" was effective.
  310  *
  311  *   13. Try both transformed and untransformed colors when "-loco" is used.
  312  *
  313  *   14. Move the Photoshop-fixing stuff into a separate program.
  314  *
  315  *   15. GRR: More generally (superset of previous 3 items):  split into
  316  *   separate "edit" and "crush" programs (or functions).  Former is fully
  317  *   libpng-aware, much like current pngcrush; latter makes little or no use of
  318  *   libpng (maybe IDAT-compression parts only?), instead handling virtually
  319  *   all chunks as opaque binary blocks that are copied to output file _once_,
  320  *   with IDATs alone replaced (either by best in-memory result or by original
  321  *   _data_ resplit into bigger IDATs, if pngcrush cannot match/beat).  "edit"
  322  *   version should be similar to current code but more efficient:  make
  323  *   _one_ pass through args list, creating table of PNG_UINTs for removal;
  324  *   then make initial pass through PNG image, creating (in-order) table of
  325  *   all chunks (and byte offsets?) and marking each as "keep" or "remove"
  326  *   according to args table.  Could start with static table of 16 or 32 slots,
  327  *   then double size & copy if run out of room:  still O(n) algorithm.
  328  *
  329  *   16. With libpng17, png_write throws an "affirm()" with tc.format=256
  330  *   when attempting to write a sub-8-bit grayscale image.
  331  *
  332  *   17. Figure out why we aren't calling png_read_update_info() and fix.
  333  *
  334  *   18. Fix ADLER32 checksum handling in conjunction with iCCP chunk
  335  *   reading.
  336  *
  337  *   19. Fix Coverity "TOCTOU" warning about our "stat()" usage.
  338  *
  339  *   20. Warn about removing copyright and license info appearing in
  340  *   PNG text chunks.
  341  *
  342  *   21. Implement the "eXIf" chunk if it is approved by the PNG
  343  *   Development Group.  Optionally, remove preview and thumbnail
  344  *   images from the Exif profile contained in the eXIf chunk.
  345  *
  346  */
  347 
  348 #if 0 /* changelog */
  349 
  350 Change log:
  351 
  352 Version 1.8.13 (built with libpng-1.6.32 and zlib-1.2.11)
  353   Add "exit(0)" after processing "-version" argument, to avoid
  354     displaying the Usage information (bug report by Peter Hagan,
  355     Issue #76).
  356   Fix problem with MacOS prior to Sierra; it uses CLOCK_MONOTONIC
  357     for some other purpose (bug report and help developing patch by
  358     Github user "ilovezfs", Homebrew/homebrew-core PR#16391).
  359 
  360 Version 1.8.12 (built with libpng-1.6.31 and zlib-1.2.11)
  361   Added POWERPC-VSX support.
  362   Report whether using optimizations.
  363   Added filter_method 6 (same as filter 5 with -speed).
  364   Added "methods" 149-176 (that use filter_method 6).
  365   Changed default verbosity from 1 (normal) to 0 (quiet). Use "-v" to get
  366     the previous default behavior and "-v -v" to get the previous "verbose"
  367     behavior. The "-s" (silent) and "-q" (quiet) options behave as before.
  368 
  369 Version 1.8.11 (built with libpng-1.6.28 and zlib-1.2.11)
  370   Use png_set_option(PNG_IGNORE_ADLER32) to control ADLER32 handling.
  371   Changed LD=gcc to LD=$(CC) in Makefile and Makefile-nolib (suggested
  372     by Helmut G in Bug#850927 of some GIT project)
  373 
  374 Version 1.8.10 (built with libpng-1.6.26 and zlib-1.2.8.1)
  375   Changed ADLER32 checksum handling to only use inflateValidate()
  376     during IDAT chunk handling; it broke iCCP chunk handling.
  377 
  378 Version 1.8.9 (built with libpng-1.6.26 and zlib-1.2.8.1)
  379   Added "-warn" option, to show only warnings.
  380   Enabled method 149. For now it writes uncompressed IDAT but in
  381     a future version of pngcrush it will just copy the IDAT data.
  382 
  383 Version 1.8.8 (built with libpng-1.6.26beta06 and zlib-1.2.8.1)
  384   Fixed "nolib" build (bug report by Hanspeter Niederstrasser).
  385     Make sure we use system-png.h, and not the local file.  It is now
  386     possible to build either the regular pngcrush or the "nolib"
  387     pngcrush in the complete pngcrush source directory (use
  388     "make clean" before rebuilding!)
  389   Fixed timing when using "clock()". Sometimes an additional second
  390     was added when the timer crossed a one-second boundary, since
  391     version 1.8.5.
  392   Upgrade libpng to version 1.6.26beta06 and zlib to 1.2.8.1.
  393   Use zlib-1.2.8.1 new "inflateValidate()" function to avoid checking
  394     ADLER32 checksums. Version 1.8.7 did not work when the "-fix"
  395     option was used.
  396 
  397 Version 1.8.7 (built with libpng-1.6.25 and zlib-1.2.8)
  398   Do not check the ADLER32 CRC while reading except during the final write
  399     pass (requires libpng-1.6.26 or later and zlib-1.2.4 or later).
  400     This saves some CPU time, around five to ten percent, in decoding.
  401   Do not calculate the ADLER32 CRC while writing except during the final
  402     write pass (writing raw deflate streams instead of zlib streams to
  403     the IDAT chunks; these are invalid PNGs but since all we do is count
  404     the bytes that does not matter). This saves some CPU time in encoding
  405     but it is barely perceptible. Requires zlib 1.2.4 or later and modified
  406     pngwutil.c.
  407 
  408 Version 1.8.6 (built with libpng-1.6.25 and zlib-1.2.8)
  409   Enabled ARM_NEON support.
  410   Fixed error in handling of timer wraparound when interval exceeds one
  411     second.
  412   Disable high resolution timers by default in Makefile.  To enable them,
  413     you must enable/disable relevant CPPFLAGS and LIBS in Makefile.
  414 
  415 Version 1.8.5 (built with libpng-1.6.24 and zlib-1.2.8)
  416   Added "-benchmark n" option.  It runs the main loop "n" times, and
  417     records the minimum value for each timer.
  418   After checking for CLOCK_ID, use clock() if none is found.
  419   Avoid some timing when verbose<0 ("-s" or "--silent")
  420   Added PNGCRUSH_CHECK_CRC (off by default) to use libpng default
  421     CRC checking. Otherwise, CRC are only computed and checked during
  422     the first read pass and while writing.
  423   Accept "--option" (for now, by simply skipping the first "-").
  424 
  425 Version 1.8.4 (built with libpng-1.6.24 and zlib-1.2.8)
  426   Fixed handling of CLOCK_ID, removed some "//"-delimited comments.
  427     Revised intel_init.c to always optimize 4bpp images, because the
  428     poor optimization noted previously has been fixed.
  429 
  430 Version 1.8.3 (built with libpng-1.6.24 and zlib-1.2.8)
  431   Fixed bug introduced in 1.8.2 that causes trial 10 to be skipped when
  432     using the default heuristic method.
  433   Fixed incorrect typecast in call to png_create_write_struct_2() (Bug
  434     report by Richard K. Lloyd).
  435   Added intel_init.c, filter_sse2_intrinsics.c, and Makefile-sse,
  436     to enable INTEL SSE optimization.  Revised intel_init.c to optionally
  437     only optimize 4bpp images, because the optimization appears to slow
  438     down reading of 3bpp images.
  439   Added PNGCRUSH_TIMERS (nanosecond resolution using clock_gettime), to
  440     measure defiltering time in png_read_filter_row(). For now, this only
  441     works with a modified libpng, on platforms that provide "clock_gettime()".
  442     To enable all timers, define PNGCRUSH_TIMERS=11.
  443   Revised "-q" to show a short summary of results (final size and timing)
  444   To do: Add ZLIB_AMALGAMATED configuration; currently produces different output
  445     https://blog.forrestthewoods.com/
  446     improving-open-source-with-amalgamation-cf293592c5f4#.g9fb2tyhs
  447     (added #ifndef NO_GZ / #endif to skip the gz* code in zlib_amalg.[ch]).
  448   Added LIBPNG_UNIFIED configuration.
  449 
  450 Version 1.8.2 (built with libpng-1.6.23 and zlib-1.2.8)
  451   Fixed filesize reduction report when "-ow" option is used (Bug report #68).
  452   When a single method is specified, turn -reduce off by default and skip
  453     trial 0.
  454 
  455 Version 1.8.1 (built with libpng-1.6.21 and zlib-1.2.8)
  456   Added the LICENSE file to the tar and zip distributions.
  457   Made "-force" force output even when the IDAT is larger, and added
  458     "-noforce" option; "-noforce" is now the default behavior (Bug
  459     report #68 at SourceForge by "wintakeall")
  460   Use right filename in filesize reduction report (overwrite?inname:outname)
  461     (bug report #69 by "wintakeall").
  462   Removed some superfluous spaces from the Copyright statement.
  463   Added "-speed" option; it avoids using the AVG or PAETH filters which
  464     are slower to decode.
  465 
  466 Version 1.8.0 (built with libpng-1.6.21 and zlib-1.2.8)
  467   Made "-reduce" and "-force" the default behavior.  Removed obsolete
  468     options "-plte_len", "-cc", "-nocc", "-double_gamma", "-already_crushed",
  469     and "-bit_depth". Removed "things_have_changed" code.
  470 
  471 Version 1.7.92 (built with libpng-1.6.20 and zlib-1.2.8)
  472   Deleted png_read_update_info() statement that was mistakenly added to
  473     version 1.7.89. It caused "bad adaptive filter value" errors.
  474 
  475 Version 1.7.91 (built with libpng-1.6.20 and zlib-1.2.8)
  476   Suppress warning about "damaged LZ stream" when bailing out and building
  477     with libpng-1.7.0beta.
  478   Added a LICENSE file to the distribution. It points to the actual
  479     license appearing in the NOTICES section near the top of pngcrush.c
  480   Show if pngcrush is built with bundled or system libpng and zlib.
  481   Fixed segfault while writing a -loco MNG (bug found with AFL, reported
  482     by Brian Carpenter). Bug was introduced in pngcrush-1.7.35.
  483 
  484 Version 1.7.88 (built with libpng-1.6.19 and zlib-1.2.8)
  485   Eliminated a potential overflow while adding iTXt chunk (over-length
  486     text_lang or text_lang_key), reported by Coverity.
  487 
  488 Version 1.7.87 (built with libpng-1.6.18 and zlib-1.2.8)
  489   Fixed a double-free bug (CVE-2015-7700). There was a "free" of the
  490     sPLT chunk structure in pngcrush and then again in png.c (Bug report
  491     by Brian Carpenter).
  492   Added common-law trademark notice and export control information.
  493   Rearranged some paragraphs in the comments at the beginning of pngcrush.c
  494   Increased some buffer sizes in an attempt to prevent possible overflows.
  495 
  496 Version 1.7.86 (built with libpng-1.6.18 and zlib-1.2.8)
  497   Increased maximum size of a text chunk input from 260 to 2048
  498     (STR_BUF_SIZE) bytes, to agree with the help screen (bug report by
  499     Tamas Jursonovics).
  500   Fixed bug that caused text chunks after IDAT to be written only when
  501     the "-save" option is used.
  502 
  503 Version 1.7.85 (built with libpng-1.6.16 and zlib-1.2.8)
  504   Improved reporting of invalid chunk names. Does not try to put
  505     non-printable characters in STDERR; displays hex numbers instead.
  506   Fixed include path for utime.h on MSVC (Louis McLaughlin).
  507   Eliminated "FAR" memory support (it was removed from libpng at version
  508     1.6.0).
  509   Disabled the "-already_crushed" option which does not really work well.
  510 
  511 Version 1.7.84 (built with libpng-1.6.16 and zlib-1.2.8)
  512   Cleaned up more Coverity-scan warnings. Fixing those also fixed
  513     CVE-2015-2158.
  514 
  515 Version 1.7.83 (built with libpng-1.6.16 and zlib-1.2.8)
  516   Cleaned up some Coverity-scan warnings.  Unfortunately one of these
  517     changes introduced the vulnerability reported in CVE-2015-2158.
  518 
  519 Version 1.7.82 (built with libpng-1.6.16 and zlib-1.2.8)
  520 
  521 Version 1.7.81 (built with libpng-1.6.15 and zlib-1.2.8)
  522   Fixed off-by-one error in calculation of plte_len. Bug reports by
  523     Ivan Kuchin and Frederic Kayser.
  524 
  525 Version 1.7.80 (built with libpng-1.6.14 and zlib-1.2.8)
  526   Added "-reduce_palette" and "-noreduce_palette" options.  Enable
  527     reduce_palette when the "-new" or "-reduce" option is used.
  528 
  529 Version 1.7.79 (built with libpng-1.6.14 and zlib-1.2.8)
  530   Fixed bug in -plte_len N option.
  531 
  532 Version 1.7.78 (built with libpng-1.6.14 and zlib-1.2.8)
  533   Made "-s" and "-silent" options suppress libpng warnings.
  534 
  535 Version 1.7.77 (built with libpng-1.6.13 and zlib-1.2.8)
  536   Updated libpng to version 1.6.13.
  537 
  538 Version 1.7.76 (built with libpng-1.6.12 and zlib-1.2.8)
  539   Updated libpng to version 1.6.12.
  540 
  541 Version 1.7.75 (built with libpng-1.6.10 and zlib-1.2.8)
  542   Reverted libpng to version 1.6.10 due to a misplaced statement in png.c
  543 
  544 Version 1.7.74 (built with libpng-1.6.11 and zlib-1.2.8)
  545   Fixed "-zmem" option (only "-zm" would work since version 1.7.62).
  546 
  547 Version 1.7.73 (built with libpng-1.6.10 and zlib-1.2.8)
  548   Restored calls to png_set_crc_action() which had been removed from
  549     version 1.7.72 for some testing and inadvertently not restored. 
  550   Changed "fix" internal variable name to "salvage" (still set with "-fix")
  551   Added code to fix/salvage PNG with "bad adaptive filter value" error.
  552   Avoid calculating CRC during compression trials except for the last trial,
  553     when the output is actually written.
  554   Fixed a bug with reducing 16-bit images to 8-bit using "-reduce" option.
  555     
  556 Version 1.7.72 (built with libpng-1.6.10 and zlib-1.2.8)
  557 
  558 Version 1.7.71 (built with libpng-1.6.9 and zlib-1.2.8)
  559   Built the Windows binaries using -DTOO_FAR=32767; neglected to do this
  560     in versions 1.7.42 through 1.7.70, which caused the Windows binaries
  561     to produce different (usually a few bytes larger) results than Linux.
  562     Thanks to F. Kayser for reporting the discrepancy.
  563 
  564 Version 1.7.70 (built with libpng-1.6.8 and zlib-1.2.8)
  565 
  566 Version 1.7.69 (built with libpng-1.6.6 and zlib-1.2.8)
  567   Updated libpng to version 1.6.6.
  568 
  569 Version 1.7.68 (built with libpng-1.6.4 and zlib-1.2.8)
  570   Check for NULL return from malloc().
  571   Undefine CLOCKS_PER_SECOND "1000" found in some version of MinGW.
  572   Replaced most "atoi(argv[++i])" with "pngcrush_get_long" which does
  573     "BUMP_I; strtol(argv[i],ptr,10)" and added pngcrush_check_long macro
  574     to detect malformed or missing parameters (debian bug 716149).
  575   Added global_things_have_changed=1 when reading -bkgd.
  576   The "-bit_depth N" option did not work reliably and has been removed.
  577 
  578 Version 1.7.67 (built with libpng-1.5.17 and zlib-1.2.8)
  579   Fixed handling of "-text" and "-ztext" options for text input. They had been
  580     reduced to "-t" and "-z" with an incorrect argument (3 instead of 2) in
  581     version 1.7.62. Bug report and patch from Tsukasa Oi.
  582 
  583 Version 1.7.66 (built with libpng-1.5.17 and zlib-1.2.8)
  584   Revised pngcrush_examine_pixels_fn() to fix some incorrect reductions.
  585 
  586 Version 1.7.65 (built with libpng-1.5.17 and zlib-1.2.8)
  587   Do not allow any colortype or depth reductions if acTL is present.
  588   Added warnings to explain why any requested reductions were not allowed.
  589 
  590 Version 1.7.64 (built with libpng-1.5.17 and zlib-1.2.8)
  591 
  592 Version 1.7.63 (built with libpng-1.5.16 and zlib-1.2.8)
  593   Add "int dowildcard=-1;" in an attempt to get wildcard arguments working
  594     in the cross-compiled MinGW executables.
  595 
  596 Version 1.7.62 (built with libpng-1.5.16 and zlib-1.2.8)
  597   Remove old filename before renaming, when using the "-ow" option on
  598     any Windows platform, not just CYGWIN (see log entry for pngcrush-1.7.43).
  599   Reverted error with handling single-character options like "-v", introduced
  600     in 1.7.61.
  601 
  602 Version 1.7.61 (built with libpng-1.5.16 and zlib-1.2.8)
  603   Check sBIT chunk data to see if reduction to gray or to 8-bit is permitted,
  604     i.e., the RGB sBIT values are equal to each other or the sBIT values are
  605     not greater than 8, respectively.
  606   Do not try to make_opaque if the tRNS chunk is found.
  607   Added warning when ignoring an invalid commandline option.
  608   Improved brute_force handling with specified level, filter, or strategy.
  609 
  610 Version 1.7.60 (built with libpng-1.5.16 and zlib-1.2.8)
  611   Revise -reduce so reducing from color-type 6 to grayscale works.
  612   Issue a warning if reducing bit depth or color type would violate various
  613     chunk dependencies, and do not perform the action:
  614     Do not reduce to grayscale if a color bKGD chunk, sBIT or iCCP chunk
  615        is present.
  616     Do not reduce bit depth if bKGD or sBIT chunk is present.
  617     Do not reduce palette length if the hIST chunk is present.
  618   Set "found_iCCP" flag to zero to avoid re-reading a bad iCCP chunk.
  619 
  620 Version 1.7.59 (built with libpng-1.5.16 and zlib-1.2.8)
  621   Show the acTL chunk in the chunk list in verbose output.
  622   Fixed several bugs reported by pornel at users.sf.net:
  623     Do not call png_set_benign_errors when PNG_BENIGN_ERRORS_SUPPORTED
  624       is not defined
  625     Renamed PNG_UNUSED() macro PNGCRUSH_UNUSED().
  626     Moved a closing bracket inside the PNGCRUSH_LOCO block.
  627     Moved the declaration of "new_mng" outside a PNGCRUSH_LOCO block.
  628     Put reference to "input_format" inside a PNGCRUSH_LOCO block.
  629     Moved declarations of mng_out and mngname inside a PNGCRUSH_LOCO block.
  630 
  631 Version 1.7.58 (built with libpng-1.5.15 and zlib-1.2.7-1)
  632   Do not enable reduce_palette by default for "-reduce", "-new", or "-old".
  633     It still is failing for some files.
  634 
  635 Version 1.7.57 (built with libpng-1.5.15 and zlib-1.2.7-1)
  636   Added "-new" option that turns on "-reduce" which will be
  637     the default setting for version 1.8.0 and beyond.
  638   Added "-old" option that turns off "-reduce" which is the
  639     current default setting.
  640   Updated copyright year for zlib-1.2.7-1.
  641   Reverted to libpng-1.5.15 to be able to read old PNG files with TOO FAR
  642     errors.  This will of course only work with the embedded libpng.
  643 
  644 Version 1.7.56 (built with libpng-1.6.1 and zlib-1.2.7-1)
  645   Only use pngcrush_debug_malloc() and pngcrush_debug_free() if the result
  646     is going to be shown.
  647   Added PNG_PASS_ROWS, PNG_UNUSED, and other macro definitions, when building
  648     with libpng-1.4.x and older libpng versions.
  649   Multiplied rowbytes by 8/bit_depth when using the system library because
  650     we do not call png_read_transform_info(). This prevents a crash when
  651     reading sub-8-bit input files.
  652 
  653 Version 1.7.55 (built with libpng-1.6.1 and zlib-1.2.7-1)
  654 
  655 Version 1.7.54 (built with libpng-1.6.1rc01 and zlib-1.2.7-1)
  656 
  657 Version 1.7.53 (built with libpng-1.6.1rc01 and zlib-1.2.7)
  658   Removed plte_len stuff from the "To do" list because it is done.
  659   Shorten the indexed-PNG tRNS chunk length if it has more entries than the PLTE chunk.
  660 
  661 Version 1.7.52 (built with libpng-1.6.1beta06 and zlib-1.2.7)
  662   Added license info for cexcept.h, libpng, and zlib.
  663   Added consideration of "zopfli" compression to the "To do" list.
  664   Fixed a typo that caused a cHRM chunk to be "found" if an iCCP chunk
  665     were present.
  666   Reset best_byte_count before trial loop.
  667   Revise global png_set_keep_unknown_chunks() calls to avoid a libpng16
  668     warning.
  669   Reset "intent" to "specified_intent" before trial loop.
  670   Reset "plte_len" to "specified_plte_len" before trial loop.
  671   Initialize length of each trial to 0x7fffffff so any untried method
  672     is not the "best method".
  673  
  674 Version 1.7.51 (built with libpng-1.6.0 and zlib-1.2.7)
  675   Added "-noreduce" option, in preparation for "-reduce" becoming the
  676     default behaviour in version 1.8.0.  This turns off lossless bit depth,
  677     color type, palette reduction, and opaque alpha channel removal.
  678   Zero out the high byte of transparent color for color-type 0 and 2,
  679     when reducing from 16 bits to 8.
  680   Undefined a bunch of stuff in pngcrush.h that we do not use, saves about
  681     100 kbytes of executable file size in addition to about 50k saved by
  682     undefining the simplified API.
  683   Fixed double-underscore typo in an #ifdef in png.c
  684   If "-reduce" is on and the background index is larger than the reduced
  685     palette_length+1, reduce it to the palette_length+1.
  686   Increased required_window_size if necessary to account for slightly larger
  687     size of interlaced files due to additional filter bytes and padding.
  688 
  689 Version 1.7.50 (built with libpng-1.6.0 and zlib-1.2.7)
  690   Removed completed items from the "To do" list.
  691   Ignore the argument of the "plte_len" argument and just set the
  692     "reduce_palette" flag.
  693 
  694 Version 1.7.49 (built with libpng-1.5.14 and zlib-1.2.7)
  695   Use png_set_benign_errors() to allow certain errors in the input file
  696     to be handled as warnings.
  697   Skip PNG_ABORT redefinition when using libpng-1.4.0 and later.
  698   Implemented "-reduce" option to identify and reduce all-gray images,
  699     all-opaque images, unused PLTE entries, and 16-bit images that can be
  700     reduced losslessly to 8-bit.
  701 
  702 Version 1.7.48 (built with libpng-1.5.14 and zlib-1.2.7)
  703   Reserved method==0 for examining the pixels during trial 0, if necessary.
  704     Changed blacken_fn() to separate pngcrush_examine_pixels_fn() and
  705     pngcrush_transform_pixels_fn() callback functions.  The "examine"
  706     function is only done during trial 0; it sets a flag whether
  707     any fully transparent pixels were found, and pngcrush only runs
  708     pngcrush_transform_pixels_fn() if necessary.
  709   This is in preparation for future versions, which will examine other
  710     conditions such as if the image is opaque or gray or can be losslessly
  711     reduced in bit depth, set flags in trial 0 and accomplish the
  712     transformations in the remaining trials (see the To do list starting
  713     about line 200 in the pngcrush.c source).
  714   Removed "PNGCRUSH_COUNT_COLORS" blocks again.
  715 
  716 Version 1.7.47 (built with libpng-1.5.13 and zlib-1.2.7)
  717   Do not do the heuristic trials of the first 10 methods when -brute is
  718     specified, because it did not save time as I hoped.
  719   Fixed a mistake in 1.7.45 and 1.7.46 that caused the output file to
  720     not be written.
  721 
  722 Version 1.7.46 (built with libpng-1.5.13 and zlib-1.2.7)
  723   Moved the new level 0 methods to the end of the trial list (methods 137-148)
  724 
  725 Version 1.7.45 (built with libpng-1.5.13 and zlib-1.2.7)
  726   Added method 0 (uncompressed). "-m 0" now simply turns on method 0.
  727   Added "-try10" option that has the same effect that "-m 0" previously did,
  728     namely to try only the first ten methods.
  729   Inserted new methods 17 through 21 with zlib level 0.
  730   Do the heuristic trials of the first 10 methods when -brute is specified,
  731     to get quickly to a small solution, so we can bail out of most of the
  732     remaining trials early. Previously these 10 methods were skipped during
  733     a -brute run.
  734   Removed the "-reduce" line from the help screen when PNGCRUSH_COUNT_COLORS
  735     is disabled.
  736 
  737 Version 1.7.44 (built with libpng-1.5.14 and zlib-1.2.7)
  738 
  739 Version 1.7.43 (built with libpng-1.5.13 and zlib-1.2.7)
  740   Added "remove(inname)" before "rename(outname, inname)" when using the "-ow"
  741     option on CYGWIN/MinGW because "rename()" does not work if the target file
  742     exists.
  743   Use the bundled "zlib.h" when PNGCRUSH_H is defined, otherwise use the
  744     system <zlib.h>.
  745 
  746 Version 1.7.42 (built with libpng-1.5.13 and zlib-1.2.7)
  747   Use malloc() and free() instead of png_malloc_default() and
  748     png_free_default().  This will be required to run with libpng-1.7.x.
  749   Revised the PNG_ABORT definition in pngcrush.h to work with libpng-1.7.x.
  750   Revised zutil.h to avoid redefining ptrdiff_t on MinGW/CYGWIN platforms.
  751 
  752 Version 1.7.41 (built with libpng-1.5.13 and zlib-1.2.7)
  753   Reverted to version 1.7.38.  Versions 1.7.39 and 1.7.40 failed to
  754     open an output file.
  755 
  756 Version 1.7.40 (built with libpng-1.5.13 and zlib-1.2.7)
  757   Revised the "To do" list.
  758 
  759 Version 1.7.39 (built with libpng-1.5.13 and zlib-1.2.7)
  760   Removed "PNGCRUSH_COUNT_COLORS" blocks which I no longer intend to
  761     implement because that feature is already available in ImageMagick.  Kept
  762     "reduce_to_gray" and "it_is_opaque" flags which I do hope to implement
  763     soon.
  764   Changed NULL to pngcrush_default_read_data in png_set_read_fn() calls, to fix
  765     an insignificant error introduced in pngcrush-1.7.14, that caused most
  766     reads to not go through the alternate read function.  Also always set this
  767     function, instead of depending on STDIO_SUPPORTED.
  768 
  769 Version 1.7.38 (built with libpng-1.5.13 and zlib-1.2.7)
  770   Bail out of a trial if byte count exceeds best byte count so far.  This
  771     avoids wasting CPU time on trial compressions of trials that exceed the
  772     best compression found so far.
  773   Added -bail and -nobail options.  Use -nobail to get a complete report
  774     of filesizes; otherwise the report just says ">N" for any trial
  775     that exceeds size N where N is the best size achieved so far.
  776   Added -blacken option, to enable changing the color samples of any
  777     fully-transparent pixels to zero in PNG files with color-type 4 or 6,
  778     potentially improving their compressibility. Note that this is an
  779     irreversible lossy change: the underlying colors of all fully transparent
  780     pixels are lost, if they were not already black.
  781 
  782 Version 1.7.37 (built with libpng-1.5.12 and zlib-1.2.7)
  783   Reverted pngcrush.c back to 1.7.35 and fixed the bug with PLTE handling.
  784 
  785 Version 1.7.36 (built with libpng-1.5.12 and zlib-1.2.7)
  786   Reverted pngcrush.c to version 1.7.34 because pngcrush is failing with
  787     some paletted PNGs.
  788   Separated CFLAGS and CPPFLAGS in the makefile (with "-I" and "-DZ_SOLO"
  789     in CPPFLAGS)
  790 
  791 Version 1.7.35 (built with libpng-1.5.12 and zlib-1.2.7)
  792   Removed FOPEN of fpout except for the last trial.  The open files caused
  793     "pngcrush -brute -e _ext.png *.png" to fail on the 10th file (about the
  794     1024th compression trial) due to being unable to open the output file.
  795 
  796 Version 1.7.34 (built with libpng-1.5.12 and zlib-1.2.7)
  797   Compute and report sum of critical chunk lengths IHDR, PLTE, IDAT, and IEND,
  798     plus the 8-byte PNG signature instead of just the total IDAT data length.
  799     Simplify finding the lengths from the trial compressions, by replacing
  800     the write function with one that simply counts the bytes that would have
  801     been written to a trial PNG, instead of actually writing a PNG, reading it
  802     back, and counting the IDAT bytes.
  803   Removed comments about the system library having to be libpng14 or earlier.
  804     This restriction was fixed in version 1.7.20.
  805 
  806 Version 1.7.33  (built with libpng-1.5.12 and zlib-1.2.7)
  807   Ignore all ancillary chunks except during the final trial.  This can be
  808     significantly faster when large ancillary chunks such as iCCP and zTXt
  809     are present.
  810 
  811 Version 1.7.32  (built with libpng-1.5.12 and zlib-1.2.7)
  812   Fixed bug introduced in 1.7.30: Do not call png_set_check_for_invalid_index()
  813     when nosave != 0 (otherwise pngcrush crashes with the "-n" option).
  814 
  815 Version 1.7.31  (built with libpng-1.5.11 and zlib-1.2.7)
  816   Dropped *.tar.bz2 from distribution.
  817   Added a comma that was missing from one of the "usage" strings (error
  818     introduced in version 1.7.29).
  819 
  820 Version 1.7.30  (built with libpng-1.5.11 and zlib-1.2.7)
  821   Only run the new (in libpng-1.5.10) test of palette indexes during the
  822     first trial.
  823 
  824 Version 1.7.29  (built with libpng-1.5.10 and zlib-1.2.7)
  825   Set "things_have_changed" flag when adding text chunks, so the "-force"
  826     option is no longer necessary when adding text to an already-compressed
  827     file.
  828   Direct usage message and error messages to stderr instead of stdout. If
  829     anyone is still using DOS they may have to change the "if 0" at line
  830     990 to "if 1".  If you need to have the messages on standard output
  831     as in the past, use 2>&1 to redirect them.
  832   Added "pngcrush -n -v files.png" to the usage message.
  833 
  834 Version 1.7.28  (built with libpng-1.5.10 and zlib-1.2.7)
  835   Write proper copyright year for zlib, depending upon ZLIB_VERNUM
  836 
  837 Version 1.7.27  (built with libpng-1.5.10 and zlib-1.2.6)
  838   Increased row_buf malloc to row_bytes+64 instead of row_bytes+16, to
  839     match the size of big_row_buf in pngrutil.c (it is 48 in libpng14, 15, 16,
  840     and 64 in libpng10, 12.  Otherwise there is a double-free crash when the
  841     row_buf is destroyed.
  842 
  843 Version 1.7.26  (built with libpng-1.5.10 and zlib-1.2.6)
  844   Increased the text_text buffer from 2048 to 10*2048 (Ralph Giles), and
  845     changed an incorrect test for keyword length "< 180" to "< 80".  The
  846     text_text buffer was inadvertently reduced from 20480 to 2048 in
  847     pngcrush-1.7.9.
  848   Added -DZ_SOLO to CFLAGS, needed to compile zlib-1.2.6.
  849   Changed user limits to width and height max 500000, malloc max 2MB,
  850     cache max 500.
  851   Added -nolimits option which sets the user limits to the default
  852     unlimited values.
  853 
  854 Version 1.7.25  (built with libpng-1.5.9 and zlib-1.2.5)
  855 
  856 Version 1.7.24  (built with libpng-1.5.7 and zlib-1.2.5)
  857   Do not append a slash to the directory name if it already has one.
  858 
  859 Version 1.7.23  (built with libpng-1.5.7 and zlib-1.2.5)
  860   Ignore any attempt to use "-ow" with the "-d" or "-e" options, with warning.
  861   Include zlib.h if ZLIB_H is not defined (instead of checking the libpng
  862     version; see entry below for pngcrush-1.7.14), and include string.h
  863     if _STRING_H_ is not defined (because libpng-1.6 does not include string.h)
  864   Define SLASH = backslash on Windows platforms so the "-d" option will work..
  865 
  866 Version 1.7.22  (built with libpng-1.5.6 and zlib-1.2.5)
  867   Added "-ow" (overwrite) option.  The input file is overwritten and the
  868     output file is just used temporarily and removed after it is copied
  869     over the input file..  If you do not specify an output file, "pngout.png"
  870     is used as the temporary file. Caution: the temporary file must be on
  871     the same filesystem as the input file.  Contributed by a group of students
  872     of the University of Paris who were taking the "Understanding of Programs"
  873     course and wished to gain familiarity with an open-source program.
  874 
  875 Version 1.7.21  (built with libpng-1.5.6 and zlib-1.2.5)
  876   Defined TOO_FAR=32767 in Makefile (instead of in pngcrush.h)
  877 
  878 Version 1.7.20  (built with libpng-1.5.5 and zlib-1.2.5)
  879   Removed the call to png_read_transform_info() when the system libpng
  880     is being used, so it can be built with a system libpng.
  881 
  882 Version 1.7.19  (built with libpng-1.5.5 and zlib-1.2.5)
  883   pngcrush-1.7.18 failed to read interlaced PNGs.  Reverted the change
  884     from calling png_read_transform_info() to png_read_update_info().
  885     Since png_read_transform_info() is not exported we again cannot build
  886     with the system libpng15.
  887 
  888 Version 1.7.18  (built with libpng-1.5.5 and zlib-1.2.5)
  889   This version will work with either a "system" libpng14 or libpng15, or with
  890     the embedded libpng15.  The deprecated usage of libpng png_struct members
  891     and unexported functions has been removed.
  892   Fixing "too far back" errors does not work with libpng15.
  893   Revised the format of the time report (all on one line so you can get
  894     a nice compact report by piping the output to "grep coding").
  895 
  896 Version 1.7.17  (built with libpng-1.5.5beta08 and zlib-1.2.5)
  897   Changed "#if !defined(PNG_NO_STDIO)" to "#ifdef PNG_STDIO_SUPPORTED"
  898     as recommended in the libpng documentation.
  899   Added PNG_UINT_32_NAME macro and used it to simplify chunk_type integer
  900     definitions.
  901 
  902 Version 1.7.16  (built with libpng-1.5.4 and zlib-1.2.5)
  903   Only report best method==0 if pngcrush cannot match the input filesize.
  904     Otherwise, if there is no improvement, report the first matching method.
  905 
  906 Version 1.7.15  (built with libpng-1.5.2rc02 and zlib-1.2.5)
  907   Force bit_depth to 1, 2, or 4 when -plte_len is <=2, <=4, or <=16 and
  908     the -bit_depth option is not present, to avoid writing invalid palette
  909     indexes.
  910 
  911 Version 1.7.14  (built with libpng-1.5.1beta08 and zlib-1.2.5)
  912   Removed WIN32_WCE support (libpng has dropped it already)
  913   Include zlib.h and define png_memcpy, etc., and revise the
  914     png_get_iCCP() and png_set_iCCP() calls to be able to build
  915     with bundled libpng-1.5.x.  Pngcrush cannot be built yet with
  916     a system libpng-1.5.x.
  917   Dropped most of pngcrush.h, that eliminates various parts of libpng.
  918 
  919 Version 1.7.13  (built with libpng-1.4.5 and zlib-1.2.5)
  920 
  921 Version 1.7.12  (built with libpng-1.4.4beta05 and zlib-1.2.5)
  922 
  923 Version 1.7.11  (built with libpng-1.4.2 and zlib-1.2.5)
  924 
  925 Version 1.7.10  (built with libpng-1.4.1 and zlib-1.2.3.9)
  926   Added missing "(...)" in png_get_uint_32().
  927   Only compile png_get_uint_32(), etc., when PNG_LIBPNG_VER < 1.2.9
  928   Revised help info for "-zitxt".
  929 
  930 Version 1.7.9  (built with libpng-1.4.1 and zlib-1.2.3.9)
  931   Defined TOO_FAR == 32767 in pngcrush.h (instead of in deflate.c)
  932   Revised the "nolib" Makefiles to remove reference to gzio.c and
  933     pnggccrd.c
  934   Imposed user limits of chunk_malloc_max=4000000 and chunk_cache_max=500.
  935 
  936 Version 1.7.8  (built with libpng-1.4.0 and zlib-1.2.3.5)
  937   Removed gzio.c
  938 
  939 Version 1.7.7  (built with libpng-1.4.0 and zlib-1.2.3.4)
  940   Updated bundled libpng to version 1.4.0.
  941   Check the "-plte_len n" option for out-of-range value of n.
  942   Changed local variable "write" to "z_write" in inffast.c (zlib-1.2.3.4)
  943     to avoid shadowed declaration warning.
  944 
  945 Version 1.7.6  (built with libpng-1.4.0rc02 and zlib-1.2.3.2)
  946   Change some "#if defined(X)" to "#ifdef X" according to libpng coding style.
  947   Added some defines to suppress pedantic warnings from libpng-1.2.41beta15
  948     and later.  A warning about deprecated access to png_ptr->zstream is
  949     otherwise unavoidable.  When building the embedded libpng, a warning
  950     about png_default_error() returning is also otherwise unavoidable.
  951   Write premultiplied alpha if output extension is .ppng and
  952     PNG_READ_PREMULTIPLIED_ALPHA_SUPPORTED is set (needs libpng-1.5.0).
  953   Check the "-m method" option for out-of-range method value.
  954 
  955 Version 1.7.5  (built with libpng-1.2.41beta14 and zlib-1.2.3.2)
  956 
  957 Version 1.7.4  (built with libpng-1.2.40rc01 and zlib-1.2.3.2)
  958   Use unmodified pngconf.h from libpng-1.2.41beta05 or later.
  959 
  960 Version 1.7.3  (built with libpng-1.2.40 and zlib-1.2.3.2)
  961   Print contents of text chunks after IDAT, even when the -n option
  962     is used.  This requires a slight modification of pngconf.h,
  963     when libpng-1.2.x is used.
  964 
  965 Version 1.7.2  (built with libpng-1.2.40 and zlib-1.2.3.2)
  966   Added check for "verbose" on some printf statements.
  967 
  968 Version 1.7.1  (built with libpng-1.2.39 and zlib-1.2.3.2)
  969   Revised some prototypes to eliminate "Shadowed Declaration" warnings.
  970   Moved warning about discarding APNG chunks to the end.
  971   Replaced *.tar.lzma with *.tar.xz in the distribution.
  972 
  973 Version 1.7.0  (built with libpng-1.2.38 and zlib-1.2.3.2)
  974   Save (but do not recompress) APNG chunks if the output file has the
  975     ".apng" extension and the color_type and bit_depth are not changed.
  976 
  977 Version 1.6.20 (built with libpng-1.2.38 and zlib-1.2.3.2)
  978   Changed local variable "write" to "wwrite" in inffast.c (zlib) to avoid
  979     shadowed declaration warning.
  980 
  981 Version 1.6.19 (built with libpng-1.2.37 and zlib-1.2.3.2)
  982   Added missing braces that cause an incorrect png_error() to be issued.
  983 
  984 Version 1.6.18 (built with libpng-1.2.37 and zlib-1.2.3.2)
  985   Removed extra FCLOSE(fpin) and FCLOSE(fpout) in the first Catch{} block,
  986     since they get removed anyway right after that (Hanno Boeck).
  987   Define PNG_NO_READ|WRITE_cHRM and PNG_NO_READ_|WRITEiCCP in pngcrush.h
  988     and reordered pngcrush.h
  989 
  990 Version 1.6.17 (built with libpng-1.2.36 and zlib-1.2.3.2)
  991   Defined TOO_FAR == 32767 in deflate.c (again).  The definition
  992     has continually been inadvertently omitted during zlib updates
  993     since pngcrush version 1.6.4.
  994   Revised handling of xcode files so at least we can get printout
  995     of IHDR values with "pngcrush -fix -n -v xcode.png".
  996   Moved ChangeLog.txt back into pngcrush.c so it does not get lost.
  997   Removed single quotes from the ChangeLog.
  998 
  999 Version 1.6.16 (built with libpng-1.2.35 and zlib-1.2.3.2)
 1000   Added -newtimestamp and -oldtimestamp options and changed
 1001     default condition to timestamping the output file with
 1002     the current time (i.e., -newtimestamp is default)
 1003   If the -oldtimestamp option is used then the output file
 1004     has the same timestamp as the input file.
 1005   Added CgBI chunk detection.
 1006 
 1007 Version 1.6.15 (built with libpng-1.2.35 and zlib-1.2.3.2)
 1008   Fixes some missing typecasts on png_malloc() calls, patch from
 1009     an anonymous reporter to the SourceForge bug tracker.
 1010   Added -time_stamp option to change time stamping from default
 1011     condition.
 1012 
 1013 Version 1.6.14 (built with libpng-1.2.35 and zlib-1.2.3.2)
 1014   Avoids CVE-2009-0040.
 1015 
 1016 Version 1.6.12 (built with libpng-1.2.34 and zlib-1.2.3.2)
 1017 
 1018 Version 1.6.11 (built with libpng-1.2.33 and zlib-1.2.3.2)
 1019   Eliminated a memory leak in libpng with writing bad tEXt chunks.
 1020 
 1021 Version 1.6.10 (built with libpng-1.2.31 and zlib-1.2.3.2)
 1022   Add sTER chunk support.
 1023 
 1024 Version 1.6.9 (built with libpng-1.2.31 and zlib-1.2.3.2)
 1025   Updated cexcept.h to version 2.0.1
 1026   Add missing curly brackets.
 1027 
 1028 Version 1.6.8 (built with libpng-1.2.29 and zlib-1.2.3.2)
 1029   Fixed bug with handling of -z and -zi options.
 1030 
 1031 Version 1.6.7 (built with libpng-1.2.29 and zlib-1.2.3.2)
 1032   Moved PNG_UINT_CHNK and some other defines from pngcrush.h to pngcrush.c
 1033   Reject invalid color_type or bit_depth.
 1034 
 1035 Version 1.6.6 (built with libpng-1.2.29 and zlib-1.2.3.2)
 1036   Added dSIG support.  Pngcrush will not rewrite an image containing
 1037   a dSIG chunk immediately following the IHDR chunk, unless the
 1038   dSIG is explicitly removed with "-rem dSIG" or explicitly kept
 1039   with "-keep dSIG".  In the latter case the saved dSIG chunks will
 1040   become invalid if any changes are made to the datastream.
 1041 
 1042   Fixed bug in writing unknown chunks from the end_info_ptr.
 1043 
 1044 Version 1.6.5 (built with libpng-1.2.29 and zlib-1.2.3.2)
 1045   Discontinued adding a new gAMA chunk when writing sRGB chunk.
 1046 
 1047 Version 1.6.4 (built with libpng-1.2.9rc1 and zlib-1.2.3)
 1048   Fixed bug in handling of undocumented -trns_a option (Michal Politowski).
 1049   Fixed bug with "nosave" handling of unknown chunks.
 1050 
 1051 Version 1.6.3 (built with libpng-1.2.9beta11 and zlib-1.2.3)
 1052 
 1053   Fixed documentation of iTXt input (Shlomi Tal).
 1054   Removed #define PNG_INTERNAL and provided prototypes for some
 1055   internal libpng functions that are duplicated in pngcrush.c
 1056 
 1057 Version 1.6.2 (built with libpng-1.2.8 and zlib-1.2.3)
 1058 
 1059   Fixed bug with "PNG_ROWBYTES" usage, introduced in version 1.6.0.
 1060   The bug could cause a crash and only affects the "nolib" builds.
 1061 
 1062   Converted C++ style (// ...) comments to C style (/* ... */).
 1063 
 1064   Defined TOO_FAR == 32767 in deflate.c (again).  The definition was
 1065   omitted from version 1.6.0 when zlib was upgraded to version 1.2.3.
 1066 
 1067 Version 1.6.1 (distributed as 1.6.0, built with libpng-1.2.8 and zlib-1.2.3)
 1068 
 1069   Copied non-exported libpng functions from libpng into pngcrush, to make
 1070   pngcrush play more nicely with shared libpng.  These are not compiled
 1071   when a static library is being built with the bundled libpng and
 1072   pngcrush.h is included.
 1073 
 1074 Version 1.6.0-grr (built with libpng-1.2.4 and zlib-1.1.4pc or zlib-1.2.2)
 1075 
 1076   Moved ChangeLog out of pngcrush.c comments and into a separate file.
 1077 
 1078   Filtered pngcrush.c through "indent -kr" and "expand" for readability.
 1079 
 1080   Moved 550 lines of usage/help/copyright/license/version info to separate
 1081   function(s) and cleaned up significantly.
 1082 
 1083   Added some comments for ease of navigation and readability.
 1084 
 1085   Stripped out a bunch of ancient-libpng compatibility stuff.
 1086 
 1087   Defined PNG_UINT_* macros (pngcrush.h for now).
 1088 
 1089   Fixed unknown-chunk handling ("-rem alla" and "-rem gifx" now work).
 1090 
 1091   Created modified version of makefile that supports external zlib.
 1092 
 1093   Added support for methods using Z_RLE zlib strategy (zlib 1.2.x only).
 1094 
 1095   Documented -huffman option in usage screen.
 1096 
 1097   Added IDAT statistics to final per-file summary.
 1098 
 1099   Added utime() support to give output files same timestamps as input files.
 1100 
 1101 Version 1.5.10 (built with libpng-1.2.4 and zlib-1.1.4pc)
 1102 
 1103   Fixed bug, introduced in 1.5.9, that caused defaults for method 0 to
 1104   be used instead of copying the original image, when the original was
 1105   already smallest.
 1106 
 1107 Version 1.5.9 (built with libpng-1.2.4beta3 and zlib-1.1.4pc)
 1108 
 1109   Work around CPU timer wraparound at 2G microseconds.
 1110 
 1111   Upgraded zlib from 1.1.3 to 1.1.4.  Pngcrush is believed not to
 1112   be vulnerable to the zlib-1.1.3 buffer-overflow bug.
 1113 
 1114   Choose the first instance of smallest IDAT instead of the last,
 1115   for faster final recompression, suggested by TSamuel.
 1116 
 1117 Version 1.5.8 (built with libpng-1.2.1)
 1118 
 1119   Added -trns_a option for entering a tRNS array.
 1120 
 1121 Version 1.5.7 (built with libpng-1.2.0)
 1122 
 1123   Added setargv.obj to Makefile.msc to expand wildcards, e.g., *.png
 1124 
 1125   Use constant string "pngcrush" instead of argv[0] when appropriate.
 1126 
 1127   Only check stats for infile==outfile once per input file, or not at all
 1128   if "-nofilecheck" option is present or if a directory was created.
 1129 
 1130   Fixed bugs with changing bit_depth of grayscale images.
 1131 
 1132 Version 1.5.6 (built with libpng-1.0.12)
 1133 
 1134   Eliminated extra "Removed the cHNK chunk" messages generated by version
 1135   1.5.5 when "-rem alla" or "-rem allb" is used.
 1136 
 1137   All unknown chunks including safe-to-copy chunks are now removed in
 1138   response to the "-rem alla" or "-rem allb" options.
 1139 
 1140   Issue a warning if the user tries "-cc" option when it is not supported.
 1141 
 1142 Version 1.5.5 (built with libpng-1.0.12)
 1143 
 1144   Reset reduce_to_gray and it_is_opaque flags prior to processing each
 1145   image.
 1146 
 1147   Enable removal of safe-to-copy chunks that are being handled as unknown
 1148   e.g., "-rem time".
 1149 
 1150 Version 1.5.4 (built with libpng-1.0.11)
 1151 
 1152   Added 262 to the length of uncompressed data when calculating
 1153   required_window_size, to account for zlib/deflate implementation.
 1154 
 1155   Added "-bit_depth n" to the help screen.
 1156 
 1157   Call png_set_packing() when increasing bit_depth to 2 or 4.
 1158 
 1159   Added warning about not overwriting an existing tRNS chunk.
 1160 
 1161   Reduced the memory usage
 1162 
 1163   Write 500K IDAT chunks even when system libpng is being used.
 1164 
 1165   Ignore all-zero cHRM chunks, with a warning.
 1166 
 1167 Version 1.5.3 (built with libpng-1.0.9beta5)
 1168 
 1169   Added "-loco" option (writes MNG files with filter_method 64)
 1170 
 1171   "-dir" and "-ext" options are no longer mutually exclusive, e.g.:
 1172   pngcrush -loco -dir Crushed -ext .mng *.png
 1173 
 1174 Version 1.5.2 (built with libpng-1.0.9beta1)
 1175 
 1176   Added "-iccp" option.
 1177 
 1178   Increased the zlib memory level, which improves compression (typically
 1179   about 1.3 percent for photos) at the expense of increased memory usage.
 1180 
 1181   Enabled the "-max max_idat_size" option, even when max_idat_size
 1182   exceeds the default 1/2 megabyte size.
 1183 
 1184   Added missing "png_ptr" argument to png_error() call
 1185 
 1186   Added "-loco" option, to enable the LOCO color transformation
 1187   (R->R-G, G, B->B-G) while writing a MNG with filter_method 64. Undo
 1188   the transformation and write the regular PNG filter_method (0) if the
 1189   MNG filter_method 64 is detected.
 1190 
 1191   Revised the "-help" output slightly and improved the "-version" output.
 1192 
 1193   The "-already[_crushed]" option is now ignored if the "-force" option
 1194   is present or if chunks are being added, deleted, or modified.
 1195 
 1196   Improved "things_have_changed" behavior (now, when set in a particular
 1197   file, it is not set for all remaining files)
 1198 
 1199 Version 1.5.1 (built with libpng-1.0.8)
 1200 
 1201   Disabled color counting by default and made it controllable with new
 1202   -cc and -no_cc commandline arguments.
 1203 
 1204   Added some #ifdef PNGCRUSH_COUNT_COLORS around code that needs it.
 1205 
 1206   Revised count_colors() attempting to avoid stack corruption that has
 1207   been observed on RedHat 6.2
 1208 
 1209   Added the word "irrevocably" to the license and changed "without fee"
 1210   to "without payment of any fee".
 1211 
 1212 Version 1.5.0 (built with libpng-1.0.8)
 1213 
 1214   After encountering an image with a bad Photoshop iCCP chunk, pngcrush
 1215   1.4.5 through 1.4.8 write sRGB and gAMA=45455 chunks in all
 1216   remaining PNG files on the command line.  This has been fixed so the
 1217   correction is only applied to the particular bad input file.
 1218 
 1219 Version 1.4.8 (built with libpng-1.0.8rc1)
 1220 
 1221   Detect and remove all-opaque alpha channel.
 1222   Detect and reduce all-gray truecolor images to grayscale.
 1223 
 1224 Version 1.4.7 (built with libpng-1.0.8rc1)
 1225 
 1226   Restored the "-ext" option that was inadvertently overridden with
 1227   a new "-exit" option in version 1.4.6 ("-exit" is used to force an
 1228   "exit" instead of a "return" from the main program).
 1229 
 1230 Version 1.4.6 (built with libpng-1.0.8rc1)
 1231 
 1232   Fixed bug in color-counting of noninterlaced images.
 1233 
 1234   Added capability of processing multiple rows at a time (disabled by
 1235   default because it turns out to be no faster).
 1236 
 1237   Replaced "return" statements in main() with "exit" statements.
 1238   Force exit instead of return with "-exit" argument.
 1239 
 1240   Added the UCITA disclaimers to the help output.
 1241 
 1242 Version 1.4.5 (built with libpng-1.0.7rc2 and cexcept-1.0.0)
 1243 
 1244   Added color-counting and palette-building capability (enable by
 1245   defining PNGCRUSH_COUNT_COLORS).  In a future version, this will
 1246   give pngcrush the ability to reduce RGBA images to indexed-color
 1247   or grayscale when fewer than 257 RGBA combinations are present,
 1248   and no color is present that requires 16-bit precision.  For now,
 1249   it only reports the frequencies.
 1250 
 1251   Added "-fix" option, for fixing bad CRCs and other correctable
 1252   conditions.
 1253 
 1254   Write sBIT.alpha=1 when adding an opaque alpha channel and sBIT
 1255   is present.
 1256 
 1257   Identify the erroneous 2615-byte sRGB monitor profile being written
 1258   by Photoshop 5.5, which causes many apps to crash, and replace it with
 1259   an sRGB chunk.
 1260 
 1261   Added a check for input and output on different devices before rejecting
 1262   the output file as being the same as the input file based on inode.
 1263 
 1264   Added some UCITA language to the disclaimer.
 1265 
 1266 Version 1.4.4 (built with libpng-1.0.6i and cexcept-0.6.3)
 1267 
 1268   Can be built on RISC OS platforms, thanks to Darren Salt.
 1269 
 1270 Version 1.4.3 (built with libpng-1.0.6h and cexcept-0.6.3)
 1271 
 1272   Reduced scope of Try/Catch blocks to avoid nesting them, and
 1273   removed returns from within the Try blocks, where they are not
 1274   allowed.
 1275 
 1276   Removed direct access to the png structure when possible, and isolated
 1277   the remaining direct accesses to the png structure into new
 1278   png_get_compression_buffer_size(), png_set_compression_buffer_size(),
 1279   and png_set_unknown_chunk_location() functions that were installed
 1280   in libpng version 1.0.6g.
 1281 
 1282 Version 1.4.2 (built with libpng-1.0.6f and cexcept-0.6.0)
 1283 
 1284   Removes extra IDAT chunks (such as found in some POV-ray PNGs) with
 1285   a warning instead of bailing out (this feature requires libpng-1.0.6f
 1286   or later, compiled with "#define PNG_ABORT()").
 1287 
 1288   Removed old setjmp interface entirely.
 1289 
 1290 Version 1.4.1 (built with libpng-1.0.6e and cexcept-0.6.0)
 1291 
 1292   Uses cexcept.h for error handling instead of the libpng built-in
 1293   setjmp/longjmp mechanism.  See http://cexcept.sf.net/
 1294 
 1295   Pngcrush.c will now run when compiled with old versions of libpng back
 1296   to version 0.96, although some features will not be available.
 1297 
 1298 Version 1.4.0 (built with libpng-1.0.6 + libpng-1.0.6-patch-a)
 1299 
 1300 Version 1.3.6 (built with libpng-1.0.5v)
 1301 
 1302   RGB to Grayscale conversion is more accurate (15-bit instead of 8-bit)
 1303   and now uses only integer arithmetic.
 1304 
 1305   "#ifdefed" out PNG_READ_DITHER
 1306 
 1307   Changed "Compressed" to "Uncompressed" in help for -itxt.
 1308 
 1309   Stifled some compiler warnings
 1310 
 1311 Version 1.3.5 (built with libpng-1.0.5s)
 1312 
 1313   Add test on stat_buf.st_size to verify fpin==fpout, because stat in
 1314   MSVC++6.0 standard version returns stat_buf.st_ino=0 for all files.
 1315 
 1316   Revised pngcrush.h to make it easier to control PNG_ZBUF_SIZE and
 1317   PNG_NO_FLOATING_POINT_SUPPORTED from a makefile.
 1318 
 1319   Restored ability to enter "replace_gamma" value as a float even when
 1320   floating point arithmetic is not enabled.
 1321 
 1322   Enabled removing tEXt, zTXt, or iTXt chunks by chunk type, i.e.,
 1323   "-rem tEXt" only removes tEXt chunks, while "-rem text" removes all
 1324   three types of text chunk.
 1325 
 1326   Removed definition of TOO_FAR from pngcrush.h
 1327 
 1328   Uses new libpng error handler; if a file has errors, pngcrush now will
 1329   continue on and compress the remaining files instead of bailing out.
 1330 
 1331 Version 1.3.4 (built with libpng-1.0.5m)
 1332 
 1333   Do not allow pngcrush to overwrite the input file.
 1334 
 1335 Version 1.3.3 (built with libpng-1.0.5m)
 1336 
 1337   Restored ability to enter gamma as a float even when floating point
 1338   arithmetic is not enabled.
 1339 
 1340 Version 1.3.2 (built with libpng-1.0.5k)
 1341 
 1342   Renamed "dirname" to "directory_name" to avoid conflict with "dirname"
 1343   that appears in string.h on some platforms.
 1344 
 1345   Fixed "PNG_NO_FLOAING_POINT" typo in pngcrush.h
 1346 
 1347   "#ifdefed" out parts of the help screen for options that are unsupported.
 1348 
 1349 Version 1.3.1 (built with libpng-1.0.5k): Eliminated some spurious warnings
 1350   that were being issued by libpng-1.0.5j.  Added  -itxt, -ztxt, and
 1351   -zitxt descriptions to the help screen.
 1352 
 1353   Dropped explicit support for pCAL, hIST, sCAL, sPLT, iCCP, tIME, and
 1354   cHRM chunks and handle them as unknown but safe-to-copy instead, using
 1355   new png_handle_as_unknown function available in libpng-1.0.5k.
 1356 
 1357 Version 1.3.0 (built with libpng-1.0.5j): Added support for handling
 1358   unknown chunks.
 1359 
 1360   pngcrush is now fixed-point only, unless PNG_NO_FLOATING_POINT_SUPPORTED
 1361   is undefined in pngcrush.h.
 1362 
 1363   Added support for the iCCP, iTXt, sCAL, and sPLT chunks, which
 1364   are now supported by libpng (since libpng-1.0.5j).  None of these have
 1365   been adequately tested.
 1366 
 1367   "#ifdefed" out more unused code (weighted filters and progressive read;
 1368   this saves about 15k in the size of the executable).
 1369 
 1370   Moved the special definitions from pngconf.h into a new pngcrush.h
 1371 
 1372   Disallow 256-byte compression window size when writing, to work around
 1373   an apparent zlib bug.  Either deflate was producing incorrect results in a
 1374   21x21 4-bit image or inflate was decoding it incorrectly; the uncompressed
 1375   stream is 252 bytes, which is uncomfortably close to the resulting
 1376   256-byte compression  window.  This workaround can be removed when zlib
 1377   is fixed.
 1378 
 1379   The "-m method" can be used any of the 124 methods, without having to
 1380   specify the filter, level, and strategy, instead of just the first 10.
 1381 
 1382 Version 1.2.1 (built with libpng-1.0.5f): Fixed -srgb parameter so it
 1383   really does take an argument, and so it continues to use "0" if an
 1384   integer does not follow the -srgb.
 1385 
 1386   Added "-plte_len n" argument for truncating the PLTE.  Be sure not to
 1387   truncate it to less than the greatest index actually appearing in IDAT.
 1388 
 1389 Version 1.2.0: Removed registration requirement.  Added open source
 1390   license.  Redefined TOO_FAR=32k in deflate.c.
 1391 
 1392 Changes prior to going "open source":
 1393 
 1394 Version 1.1.8: built with libpng-1.0.5a.  Runs OK with pngvcrd.c.
 1395 
 1396 Version 1.1.7: added ability to add tEXt/zTXt chunks.  Fixed bug with
 1397 closing a file that was not opened when using "pngcrush -n".  Fixed
 1398 bug with tEXt/zTXt chunks after IDAT not being copied.
 1399 Added alpha to the displayed palette table.  Rebuilt with libpng-1.0.5.
 1400 
 1401 Version 1.1.6: fixed bug with one file left open after each image is
 1402 processed
 1403 
 1404 Version 1.1.5: Shorten or remove tRNS chunks that are all opaque or have
 1405 opaque entries at the end.  Added timing report.
 1406 
 1407 Version 1.1.4: added ability to restrict brute_force to one or more filter
 1408   types, compression levels, or compression strategies.
 1409 
 1410 #endif /* end of changelog */
 1411 
 1412 static int verbose = 0;
 1413 static int show_warnings = 0; /* =1 to show warnings even with verbose < 0 */
 1414 static int copy_idat = 0; /* = 1 to simply copy the IDAT chunk data */
 1415 
 1416 /* Experimental: define these if you wish, but, good luck.
 1417 #define PNGCRUSH_COUNT_COLORS
 1418 #define PNGCRUSH_MULTIPLE_ROWS
 1419 */
 1420 
 1421 #define PNGCRUSH_LARGE
 1422 
 1423 #define PNGCRUSH_ROWBYTES(pixel_bits, width) \
 1424     ((pixel_bits) >= 8 ? \
 1425     ((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \
 1426     (( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) )
 1427 
 1428 /* Suppress libpng pedantic warnings */
 1429 #if 0
 1430 #define PNG_DEPSTRUCT   /* Access to this struct member is deprecated */
 1431 #endif
 1432 
 1433 #ifndef PNGCRUSH_TIMERS
 1434 # define PNGCRUSH_TIMERS 4
 1435 #endif
 1436 
 1437 #if PNGCRUSH_TIMERS > 0
 1438 
 1439 /* TIMER function
 1440    ===== ====================== 
 1441    set in pngcrush.c:
 1442      0   total time
 1443      1   total decode
 1444      2   total encode
 1445      3   total other
 1446    set in pngread.c:
 1447      4   decode deinterlace
 1448      5   decode filter 0 (none)
 1449      6   decode filter 1 (sub)
 1450      7   decode filter 2 (up)
 1451      8   decode filter 3 (avg)
 1452      9   decode filter 4 (paeth)
 1453    set in pngwutil.c:
 1454     10   encode filter setup
 1455 */
 1456 #undef _POSIX_C_SOURCE
 1457 #define _POSIX_C_SOURCE 199309L /* for clock_gettime */
 1458 
 1459 #include <time.h>
 1460 
 1461 #ifdef CLOCKS_PER_SECOND
 1462 #  if CLOCKS_PER_SECOND == '"1000"'
 1463 #    undef CLOCKS_PER_SEC
 1464 #  endif
 1465 #endif
 1466 
 1467 #ifndef CLOCKS_PER_SEC
 1468 #  define CLOCKS_PER_SEC 1000
 1469 #endif
 1470 
 1471 #ifdef __STDC__
 1472 #  define TIME_T clock_t
 1473 #else
 1474 #  if CLOCKS_PER_SEC <= 100
 1475 #    define TIME_T long
 1476 #  else
 1477 #    define TIME_T float
 1478 #  endif
 1479 #endif
 1480 
 1481 #ifdef __APPLE__
 1482 #  include <AvailabilityMacros.h>
 1483 #endif
 1484 
 1485 /* As in GraphicsMagick */
 1486 #  if PNGCRUSH_USE_CLOCK_GETTIME == 0
 1487 #    define PNGCRUSH_USING_CLOCK "clock()"
 1488 #  elif defined(CLOCK_HIGHRES) /* Solaris */
 1489 #    define PNGCRUSH_CLOCK_ID CLOCK_HIGHRES
 1490 #    define PNGCRUSH_USING_CLOCK "clock_gettime(CLOCK_HIGHRES,&t)"
 1491 #    define PNGCRUSH_USE_CLOCK_GETTIME 1
 1492 #  elif defined(CLOCK_MONOTONIC_RAW) /* Linux */
 1493 #    define PNGCRUSH_CLOCK_ID CLOCK_MONOTONIC_RAW
 1494 #    define PNGCRUSH_USING_CLOCK "clock_gettime(CLOCK_MONOTONIC_RAW,&t)"
 1495 #    define PNGCRUSH_USE_CLOCK_GETTIME 1
 1496 #  elif defined(CLOCK_MONOTONIC_PRECISE) /* FreeBSD */
 1497 #    define PNGCRUSH_CLOCK_ID CLOCK_MONOTONIC_PRECISE
 1498 #    define PNGCRUSH_USING_CLOCK "clock_gettime(CLOCK_MONOTONIC_PRECISE,&t)"
 1499 #    define PNGCRUSH_USE_CLOCK_GETTIME 1
 1500 #  elif defined(CLOCK_MONOTONIC) /* Linux, FreeBSD & macOS Sierra & up */ && \
 1501      !(defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED < 101200)
 1502 #    define PNGCRUSH_CLOCK_ID CLOCK_MONOTONIC
 1503 #    define PNGCRUSH_USING_CLOCK "clock_gettime(CLOCK_MONOTONIC,&t)"
 1504 #    define PNGCRUSH_USE_CLOCK_GETTIME 1
 1505 #  else
 1506 #    define PNGCRUSH_USING_CLOCK "clock()"
 1507 #    undef PNGCRUSH_USE_CLOCK_GETTIME
 1508 #    define PNGCRUSH_USE_CLOCK_GETTIME 0
 1509 #  endif
 1510 #else /* PNGCRUSH_TIMERS */
 1511 #    define PNGCRUSH_USING_CLOCK "clock()"
 1512 #    define PNGCRUSH_USE_CLOCK_GETTIME 0
 1513 #endif
 1514 
 1515 #ifndef LIBPNG_UNIFIED
 1516 #include <png.h>
 1517 #define PNGCRUSH_TIMER_UINT_API extern unsigned int PNGAPI
 1518 #define PNGCRUSH_TIMER_VOID_API extern void PNGAPI
 1519 #else
 1520 #define PNGCRUSH_TIMER_UINT_API unsigned int
 1521 #define PNGCRUSH_TIMER_VOID_API void
 1522 #endif
 1523 
 1524 #define PNGCRUSH_TIMER_DECODE 1
 1525 #define PNGCRUSH_TIMER_ENCODE 2
 1526 #define PNGCRUSH_TIMER_MISC   3
 1527 #define PNGCRUSH_TIMER_TOTAL  0 
 1528 
 1529 static unsigned int pngcrush_timer_hits[PNGCRUSH_TIMERS];
 1530 static unsigned int pngcrush_timer_secs[PNGCRUSH_TIMERS];
 1531 static unsigned int pngcrush_timer_nsec[PNGCRUSH_TIMERS];
 1532 static unsigned int pngcrush_clock_secs[PNGCRUSH_TIMERS];
 1533 static unsigned int pngcrush_clock_nsec[PNGCRUSH_TIMERS];
 1534 
 1535 PNGCRUSH_TIMER_UINT_API
 1536 pngcrush_timer_get_seconds(unsigned int n);
 1537 PNGCRUSH_TIMER_UINT_API
 1538 pngcrush_timer_get_hits(unsigned int n);
 1539 PNGCRUSH_TIMER_UINT_API
 1540 pngcrush_timer_get_nanoseconds(unsigned int n);
 1541 PNGCRUSH_TIMER_VOID_API
 1542 pngcrush_timer_reset(unsigned int n);
 1543 PNGCRUSH_TIMER_VOID_API
 1544 pngcrush_timer_start(unsigned int n);
 1545 PNGCRUSH_TIMER_VOID_API
 1546 pngcrush_timer_stop(unsigned int n);
 1547 
 1548 #if PNGCRUSH_TIMERS > 0
 1549 PNGCRUSH_TIMER_UINT_API
 1550 pngcrush_timer_get_hits(unsigned int n)
 1551 {
 1552    if (n < PNGCRUSH_TIMERS)
 1553    {
 1554       return pngcrush_timer_hits[n];
 1555    }
 1556    return 0;
 1557 }
 1558 PNGCRUSH_TIMER_UINT_API
 1559 pngcrush_timer_get_seconds(unsigned int n)
 1560 {
 1561    if (n < PNGCRUSH_TIMERS)
 1562    {
 1563       return pngcrush_timer_secs[n];
 1564    }
 1565    return 0;
 1566 }
 1567 PNGCRUSH_TIMER_UINT_API
 1568 pngcrush_timer_get_nanoseconds(unsigned int n)
 1569 {
 1570    if (n < PNGCRUSH_TIMERS)
 1571    {
 1572       return pngcrush_timer_nsec[n];
 1573    }
 1574    return 0;
 1575 }
 1576 PNGCRUSH_TIMER_VOID_API
 1577 pngcrush_timer_reset(unsigned int n)
 1578 {
 1579    if (n < PNGCRUSH_TIMERS)
 1580    {
 1581       pngcrush_timer_secs[n] = 0;
 1582       pngcrush_timer_nsec[n] = 0;
 1583       pngcrush_timer_hits[n] = 0;
 1584    }
 1585 }
 1586 PNGCRUSH_TIMER_VOID_API
 1587 pngcrush_timer_start(unsigned int n)
 1588 {
 1589    if (verbose >= 0 && n < PNGCRUSH_TIMERS)
 1590    {
 1591 #if PNGCRUSH_USE_CLOCK_GETTIME
 1592       struct timespec t;
 1593       clock_gettime(PNGCRUSH_CLOCK_ID, &t);
 1594       pngcrush_clock_secs[n] = t.tv_sec;
 1595       pngcrush_clock_nsec[n] = t.tv_nsec;
 1596 #else
 1597      TIME_T t = clock();
 1598      pngcrush_clock_secs[n] = t/CLOCKS_PER_SEC;
 1599      pngcrush_clock_nsec[n] = (t*1000000000/CLOCKS_PER_SEC) -
 1600        pngcrush_clock_secs[n]*1000000000;
 1601 #endif
 1602    }
 1603 }
 1604 PNGCRUSH_TIMER_VOID_API
 1605 pngcrush_timer_stop(unsigned int n)
 1606 {
 1607    if (verbose >= 0 && n < PNGCRUSH_TIMERS)
 1608    {
 1609       unsigned long seconds;
 1610       unsigned long nseconds;
 1611       unsigned long delta_secs;
 1612       unsigned long delta_nsec;
 1613 #if PNGCRUSH_USE_CLOCK_GETTIME
 1614       struct timespec t;
 1615       clock_gettime(PNGCRUSH_CLOCK_ID, &t);
 1616       seconds = t.tv_sec;
 1617       nseconds = t.tv_nsec;
 1618 #else
 1619      TIME_T t = clock();
 1620      seconds = t/CLOCKS_PER_SEC;
 1621      nseconds = (t*1000000000/CLOCKS_PER_SEC) - seconds*1000000000;
 1622 #endif
 1623       delta_secs = (unsigned int)seconds - pngcrush_clock_secs[n];
 1624       if ((unsigned long)nseconds < pngcrush_clock_nsec[n])
 1625       {
 1626          delta_nsec  = 1000000000;
 1627          delta_secs--;
 1628       }
 1629       else
 1630       {
 1631          delta_nsec  = 0;
 1632       }
 1633 
 1634       delta_nsec  += (unsigned long)nseconds - pngcrush_clock_nsec[n];
 1635       pngcrush_timer_secs[n] += delta_secs;
 1636       pngcrush_timer_nsec[n] += delta_nsec;
 1637 
 1638       if (pngcrush_timer_nsec[n] >= 1000000000)
 1639       {
 1640          pngcrush_timer_nsec[n] -= 1000000000;
 1641          pngcrush_timer_secs[n]++;
 1642       }
 1643 
 1644       pngcrush_clock_secs[n] = (unsigned long)seconds;
 1645       pngcrush_clock_nsec[n] = (unsigned long)nseconds;
 1646       pngcrush_timer_hits[n]++;
 1647    }
 1648 }
 1649 
 1650 static unsigned long pngcrush_timer_min_secs[PNGCRUSH_TIMERS];
 1651 static unsigned long pngcrush_timer_min_nsec[PNGCRUSH_TIMERS];
 1652 #endif /* PNGCRUSH_TIMERS */
 1653 
 1654 
 1655 #ifdef ZLIB_AMALGAMATED
 1656 /* See
 1657  https://blog.forrestthewoods.com/
 1658  improving-open-source-with-amalgamation-cf293592c5f4#.g9fb2tyhs
 1659  */
 1660 #include "zlib_amalg.c"
 1661 #define ZLIB_H
 1662 #endif /* ZLIB_AMALGAMATED */
 1663 
 1664 #ifdef ZLIB_UNIFIED  /* Not working */
 1665 #include "zutil.h"
 1666 
 1667 #include "adler32.c"
 1668 #undef DO1
 1669 #undef DO8
 1670 
 1671 #include "compress.c"
 1672 #include "crc32.c"
 1673 #include "deflate.c"
 1674 #include "infback.c"
 1675 #undef PULLBYTE
 1676 
 1677 #include "inffast.c"
 1678 #undef CHECK
 1679 #undef CODES
 1680 #undef DISTS
 1681 #undef DONE
 1682 #undef LENGTH
 1683 #undef LENS
 1684 
 1685 #include "inflate.c"
 1686 #undef CHECK
 1687 #undef CODES
 1688 #undef DISTS
 1689 #undef DONE
 1690 #undef LENGTH
 1691 #undef LENS
 1692 #undef PULLBYTE
 1693 
 1694 #include "inftrees.c"
 1695 #undef CHECK
 1696 #undef CODES
 1697 #undef DISTS
 1698 #undef DONE
 1699 #undef LENGTH
 1700 #undef LENS
 1701 
 1702 #include "trees.c"
 1703 #include "uncompr.c"
 1704 #include "zutil.c"
 1705 #endif /* ZLIB_UNIFIED */
 1706 
 1707 #ifdef LIBPNG_UNIFIED
 1708 #include "pngcrush.h"
 1709 #include "png.c"
 1710 #include "pngerror.c"
 1711 #include "pngget.c"
 1712 #include "pngmem.c"
 1713 #include "pngpread.c"
 1714 #include "pngread.c"
 1715 #include "pngrio.c"
 1716 #include "pngrtran.c"
 1717 #include "pngrutil.c"
 1718 #include "pngset.c"
 1719 #include "pngtrans.c"
 1720 #include "pngwio.c"
 1721 #include "pngwrite.c"
 1722 #include "pngwtran.c"
 1723 #include "pngwutil.c"
 1724 #ifdef PNGCRUSH_USE_ARM_NEON
 1725 # include "arm_init.c"
 1726 # include "filter_neon_intrinsics.c"
 1727 #endif
 1728 #ifdef PNGCRUSH_USE_MIPS_NSA
 1729 # include "mips_init.c"
 1730 # include "filter_msa_intrinsics.c"
 1731 #endif
 1732 #ifdef PNGCRUSH_USE_INTEL_SSE
 1733 # include "intel_init.c"
 1734 # include "filter_sse2_intrinsics.c"
 1735 #endif
 1736 #ifdef PNGCRUSH_USE_POWERPC_VSX
 1737 # include "powerpc_init.c"
 1738 # include "filter_vsx_intrinsics.c"
 1739 #endif
 1740 #endif /* LIBPNG_UNIFIED */
 1741 
 1742 #include "png.h"
 1743 
 1744 #ifndef PNGCBAPI  /* Needed when building with libpng-1.4.x and earlier */
 1745 # define PNGCBAPI PNGAPI
 1746 #endif
 1747 
 1748 /* internal libpng macros */
 1749 
 1750 #ifdef PNG_LIBPNG_VER
 1751 #define PNGCRUSH_LIBPNG_VER PNG_LIBPNG_VER
 1752 #else
 1753 /*
 1754  * This must agree with PNG_LIBPNG_VER; you have to define it manually
 1755  * here if you are using libpng-1.0.6h or earlier
 1756  */
 1757 #define PNGCRUSH_LIBPNG_VER 10007
 1758 #endif
 1759 
 1760 #define PNGCRUSH_UNUSED(param) (void)param;
 1761 #define pngcrush_get_uint_31 png_get_uint_31
 1762 #define pngcrush_get_uint_32 png_get_uint_32
 1763 #define pngcrush_save_uint_32 png_save_uint_32
 1764 
 1765 #undef PNG_ABORT
 1766 #if (PNGCRUSH_LIBPNG_VER < 10400)
 1767 /* This allows png_default_error() to return, when it is called after our
 1768  * own exception handling, which only returns after "Too many IDAT's",
 1769  * or anything else that we might want to handle as a warning instead of
 1770  * an error.  Doesn't work in libpng-1.4.0 and later; there we use
 1771  * png_benign_error() instead.
 1772  */
 1773 #  define PNG_ABORT() (void)0
 1774 #elif (PNGCRUSH_LIBPNG_VER < 10700)
 1775 #  define PNG_ABORT() abort()
 1776 #else
 1777 #  define PNG_ABORT abort();
 1778 #endif
 1779 
 1780 #if (PNGCRUSH_LIBPNG_VER < 10500)
 1781 /* Two macros to return the first row and first column of the original,
 1782  * full, image which appears in a given pass.  'pass' is in the range 0
 1783  * to 6 and the result is in the range 0 to 7.
 1784  */
 1785 #define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7)
 1786 #define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7)
 1787 
 1788 /* A macro to return the offset between pixels in the output row for a pair of
 1789  * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that
 1790  * follows.  Note that ROW_OFFSET is the offset from one row to the next whereas
 1791  * COL_OFFSET is from one column to the next, within a row.
 1792  */
 1793 #define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8)
 1794 #define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1))
 1795 
 1796 /* Two macros to help evaluate the number of rows or columns in each
 1797  * pass.  This is expressed as a shift - effectively log2 of the number or
 1798  * rows or columns in each 8x8 tile of the original image.
 1799  */
 1800 #define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)
 1801 #define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)
 1802 
 1803 /* Hence two macros to determine the number of rows or columns in a given
 1804  * pass of an image given its height or width.  In fact these macros may
 1805  * return non-zero even though the sub-image is empty, because the other
 1806  * dimension may be empty for a small image.
 1807  */
 1808 #define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\
 1809    -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))
 1810 #define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\
 1811    -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))
 1812 #endif /* PNGCRUSH_LIBPNG_VER < 10500 */
 1813 
 1814 #if PNGCRUSH_LIBPNG_VER >= 10500
 1815 #if !defined(ZLIB_AMALGAMATED) && !defined(ZLIB_UNIFIED)
 1816    /* "#include <zlib.h>" is not provided by libpng15 */
 1817 #ifdef PNGCRUSH_H
 1818    /* Use the bundled zlib */
 1819 #  include "zlib.h"
 1820 #else
 1821    /* Use the system zlib */
 1822 #  include <zlib.h>
 1823 #endif
 1824 #endif /* ZLIB_AMALGAMATED || ZLIB_UNIFIED */
 1825 
 1826    /* Not provided by libpng16 */
 1827 #  include <string.h>
 1828 
 1829    /* The following became unavailable in libpng16 (and were
 1830     * deprecated in libpng14 and 15)
 1831     */
 1832 #  ifdef _WINDOWS_  /* Favor Windows over C runtime fns */
 1833 #    define png_memcmp  memcmp
 1834 #    define png_memcpy  CopyMemory
 1835 #    define png_memset  memset
 1836 #  else
 1837 #    define png_memcmp  memcmp      /* SJT: added */
 1838 #    define png_memcpy  memcpy
 1839 #    define png_memset  memset
 1840 #  endif
 1841 #endif /* PNGCRUSH_LIBPNG_VER >= 10500 */
 1842 
 1843 #if PNGCRUSH_LIBPNG_VER < 10800 || defined(PNGCRUSH_H)
 1844 
 1845 /* Changed in version 0.99 */
 1846 #if PNGCRUSH_LIBPNG_VER < 99
 1847 #  undef PNG_CONST
 1848 #  ifndef PNG_NO_CONST
 1849 #    define PNG_CONST const
 1850 #  else
 1851 #    define PNG_CONST
 1852 #  endif
 1853 #endif
 1854 
 1855 #ifndef LIBPNG_UNIFIED
 1856 #define PNG_IDAT const png_byte png_IDAT[5] = { 73,  68,  65,  84, '\0'}
 1857 #define PNG_IHDR const png_byte png_IHDR[5] = { 73,  72,  68,  82, '\0'}
 1858 #define PNG_acTL const png_byte png_acTL[5] = { 97,  99,  84,  76, '\0'}
 1859 #define PNG_dSIG const png_byte png_dSIG[5] = {100,  83,  73,  71, '\0'}
 1860 #define PNG_fcTL const png_byte png_fcTL[5] = {102,  99,  84,  76, '\0'}
 1861 #define PNG_fdAT const png_byte png_fdAT[5] = {102, 100,  65,  84, '\0'}
 1862 #define PNG_iCCP const png_byte png_iCCP[5] = {105,  67,  67,  80, '\0'}
 1863 #define PNG_IEND const png_byte png_IEND[5] = { 73,  69,  78,  68, '\0'}
 1864 #endif
 1865 
 1866 /* GRR 20050220:  added these, which apparently aren't defined anywhere else */
 1867 /* GRP 20110714:  define PNG_UINT_32_NAME macro and used that instead */
 1868 #define PNG_UINT_32_NAME(a,b,c,d) \
 1869                     ((png_uint_32) ((a) & 0xff) << 24  | \
 1870                     ((png_uint_32) (b) << 16) | \
 1871                     ((png_uint_32) (c) <<  8) | \
 1872                     ((png_uint_32) (d)      ))
 1873 #ifndef PNG_UINT_IHDR
 1874 #  define PNG_UINT_IHDR PNG_UINT_32_NAME(73, 72, 68, 82)
 1875 #endif
 1876 
 1877 #ifndef PNG_UINT_IDAT
 1878 #  define PNG_UINT_IDAT PNG_UINT_32_NAME(73, 68, 65, 84)
 1879 #endif
 1880 
 1881 #ifndef PNG_UINT_IEND
 1882 #  define PNG_UINT_IEND PNG_UINT_32_NAME(73, 69, 78, 68)
 1883 #endif
 1884 
 1885 #ifndef PNG_UINT_PLTE
 1886 #  define PNG_UINT_PLTE PNG_UINT_32_NAME(80, 76, 84, 69)
 1887 #endif
 1888 
 1889 #ifndef PNG_UINT_bKGD
 1890 #  define PNG_UINT_bKGD PNG_UINT_32_NAME(98, 75, 71, 68)
 1891 #endif
 1892 
 1893 /* glennrp added CgBI at pngcrush-1.6.16 */
 1894 #ifndef PNG_UINT_CgBI
 1895 #  define PNG_UINT_CgBI PNG_UINT_32_NAME(67,103, 66, 73)
 1896 #endif
 1897 
 1898 /* glennrp added acTL, fcTL, and fdAT at pngcrush-1.7.0 */
 1899 #  define PNG_UINT_acTL PNG_UINT_32_NAME(97, 99, 84, 76)
 1900 #  define PNG_UINT_fcTL PNG_UINT_32_NAME(102, 99, 84, 76)
 1901 #  define PNG_UINT_fdAT PNG_UINT_32_NAME(102,100, 65, 84)
 1902 
 1903 #ifndef PNG_UINT_cHRM
 1904 #  define PNG_UINT_cHRM PNG_UINT_32_NAME(99, 72, 82, 77)
 1905 #endif
 1906 
 1907 #ifndef PNG_UINT_dSIG
 1908 #  define PNG_UINT_dSIG PNG_UINT_32_NAME(100, 83, 73, 71)
 1909 #endif
 1910 
 1911 #ifndef PNG_UINT_gAMA
 1912 #  define PNG_UINT_gAMA PNG_UINT_32_NAME(103, 65, 77, 65)
 1913 #endif
 1914 
 1915 #ifndef PNG_UINT_hIST
 1916 #  define PNG_UINT_hIST PNG_UINT_32_NAME(104, 73, 83, 84)
 1917 #endif
 1918 
 1919 #ifndef PNG_UINT_iCCP
 1920 #  define PNG_UINT_iCCP PNG_UINT_32_NAME(105, 67, 67, 80)
 1921 #endif
 1922 
 1923 #ifndef PNG_UINT_iTXt
 1924 #  define PNG_UINT_iTXt PNG_UINT_32_NAME(105, 84, 88, 116)
 1925 #endif
 1926 
 1927 #ifndef PNG_UINT_oFFs
 1928 #  define PNG_UINT_oFFs PNG_UINT_32_NAME(111, 70, 70, 115)
 1929 #endif
 1930 
 1931 #ifndef PNG_UINT_pCAL
 1932 #  define PNG_UINT_pCAL PNG_UINT_32_NAME(112, 67, 65, 76)
 1933 #endif
 1934 
 1935 #ifndef PNG_UINT_pHYs
 1936 #  define PNG_UINT_pHYs PNG_UINT_32_NAME(112, 72, 89, 115)
 1937 #endif
 1938 
 1939 #ifndef PNG_UINT_sBIT
 1940 #  define PNG_UINT_sBIT PNG_UINT_32_NAME(115, 66, 73, 84)
 1941 #endif
 1942 
 1943 #ifndef PNG_UINT_sCAL
 1944 #  define PNG_UINT_sCAL PNG_UINT_32_NAME(115, 67, 65, 76)
 1945 #endif
 1946 
 1947 #ifndef PNG_UINT_sPLT
 1948 #  define PNG_UINT_sPLT PNG_UINT_32_NAME(115, 80, 76, 84)
 1949 #endif
 1950 
 1951 #ifndef PNG_UINT_sRGB
 1952 #  define PNG_UINT_sRGB PNG_UINT_32_NAME(115, 82, 71, 66)
 1953 #endif
 1954 
 1955 /* glennrp added sTER at pngcrush-1.6.10 */
 1956 #ifndef PNG_UINT_sTER
 1957 #  define PNG_UINT_sTER PNG_UINT_32_NAME(115, 84, 69, 82)
 1958 #endif
 1959 
 1960 #ifndef PNG_UINT_tEXt
 1961 #  define PNG_UINT_tEXt PNG_UINT_32_NAME(116, 69, 88, 116)
 1962 #endif
 1963 
 1964 #ifndef PNG_UINT_tIME
 1965 #  define PNG_UINT_tIME PNG_UINT_32_NAME(116, 73, 77, 69)
 1966 #endif
 1967 
 1968 #ifndef PNG_UINT_tRNS
 1969 #  define PNG_UINT_tRNS PNG_UINT_32_NAME(116, 82, 78, 83)
 1970 #endif
 1971 
 1972 #ifndef PNG_UINT_zTXt
 1973 #  define PNG_UINT_zTXt PNG_UINT_32_NAME(122, 84, 88, 116)
 1974 #endif
 1975 
 1976 #ifndef LIBPNG_UNIFIED
 1977 #define PNG_FLAG_CRC_ANCILLARY_USE        0x0100
 1978 #define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200
 1979 #define PNG_FLAG_CRC_CRITICAL_USE         0x0400
 1980 #define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800
 1981 #define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
 1982                                      PNG_FLAG_CRC_ANCILLARY_NOWARN)
 1983 #define PNG_PACK               0x0004
 1984 #define PNG_DITHER             0x0040
 1985 #define PNG_BACKGROUND         0x0080
 1986 #define PNG_16_TO_8            0x0400
 1987 #define PNG_RGBA               0x0800
 1988 #define PNG_EXPAND             0x1000
 1989 #define PNG_GAMMA              0x2000
 1990 #define PNG_GRAY_TO_RGB        0x4000
 1991 #define PNG_FILLER             0x8000L
 1992 #define PNG_USER_TRANSFORM   0x100000L
 1993 #define PNG_RGB_TO_GRAY      0x600000L  /* two bits, RGB_TO_GRAY_ERR|WARN */
 1994 #endif /* LIBPNG_UNIFIED */
 1995 
 1996 /*
 1997  * We don't need some of the extra libpng transformations
 1998  * so they are ifdef'ed out in pngcrush.h, which is included by
 1999  * pngcrush's local copy of libpng's pngconf.h which is included
 2000  * by png.h
 2001  *
 2002  */
 2003 
 2004 /* Defined so I can write to a file on gui/windowing platforms */
 2005 #if 0 /* Change this to "#if 1" if you need to. */
 2006 #  define STDERR stdout /* for DOS */
 2007 #else
 2008 #  define STDERR stderr
 2009 #endif
 2010 
 2011 #ifdef PNG_MNG_FEATURES_SUPPORTED
 2012 # define PNGCRUSH_LOCO
 2013 #endif
 2014 
 2015 #ifdef PNGCRUSH_H
 2016 int png_ignore_crc = 0;
 2017 #else
 2018 png_uint_32 pngcrush_crc;
 2019 #endif
 2020 
 2021 #ifndef PNG_UINT_31_MAX
 2022 #define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
 2023 #endif
 2024 
 2025 /* These macros were renamed in libpng-1.2.6 */
 2026 #ifndef PNG_HANDLE_CHUNK_ALWAYS
 2027 #define PNG_HANDLE_CHUNK_ALWAYS  HANDLE_CHUNK_ALWAYS
 2028 #define PNG_HANDLE_CHUNK_NEVER   HANDLE_CHUNK_NEVER
 2029 #define PNG_HANDLE_CHUNK_IF_SAFE HANDLE_CHUNK_IF_SAFE
 2030 #endif
 2031 
 2032 #if defined(__DJGPP__) && ((__DJGPP__ == 2) && (__DJGPP_MINOR__ == 0))
 2033 #  include <libc/dosio.h>     /* for _USE_LFN, djgpp 2.0 only */
 2034 #endif
 2035 
 2036 #if ( defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||  \
 2037    defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) || \
 2038    defined(__DJGPP__) )
 2039 #  define SLASH "\\"
 2040 #  define DOT "."
 2041 #else
 2042 #  ifdef __riscos
 2043 #    define SLASH "."
 2044 #    define DOT "/"
 2045 #  else
 2046 #    define SLASH "/"
 2047 #    define DOT "."
 2048 #  endif
 2049 #endif
 2050 
 2051 #define BACK_SLASH "\\"
 2052 #define FWD_SLASH "/"
 2053 
 2054 #ifndef GAS_VERSION
 2055 #  define GAS_VERSION "2.9.5(?)"  /* used only in help/usage screen */
 2056 #endif
 2057 
 2058 #if !defined(__TURBOC__) && !defined(_MSC_VER) && !defined(_MBCS) && \
 2059     !defined(__riscos)
 2060 #  include <unistd.h>
 2061 #endif
 2062 
 2063 #ifndef __riscos
 2064 #  include <sys/types.h>
 2065 #  include <sys/stat.h>
 2066 #  ifndef _MSC_VER
 2067 #    include <utime.h>
 2068 #  else
 2069 #    include <sys/utime.h>
 2070 #  endif
 2071 #endif
 2072 
 2073 #include <stdio.h>
 2074 #include <stdlib.h>
 2075 #include <time.h>
 2076 #include <assert.h>
 2077 #include <errno.h>
 2078 
 2079 #if defined(_MBCS) || defined(WIN32) || defined(__WIN32__)
 2080 #  include <direct.h>
 2081 #endif
 2082 
 2083 #define DEFAULT_MODE     0
 2084 #define DIRECTORY_MODE   1
 2085 #define EXTENSION_MODE   2
 2086 #define DIREX_MODE       3
 2087 #define OVERWRITE_MODE   4
 2088 #define FOPEN(file, how) fopen(file, how)
 2089 #define FCLOSE(file)     {fclose(file); file=NULL;--number_of_open_files;};
 2090 
 2091 #define P0 if(last_trial && verbose > 0)printf
 2092 #define P1 if(verbose > 1)printf
 2093 #define P2 if(verbose > 2)printf
 2094 
 2095 #define STRNGIFY_STAGE1(x) #x
 2096 #define STRNGIFY(x) STRNGIFY_STAGE1(x)
 2097 
 2098 #define STR_BUF_SIZE      2048
 2099 #define MAX_IDAT_SIZE     524288L
 2100 #define MAX_METHODS       177
 2101 #define MAX_METHODSP1     (MAX_METHODS+1)
 2102 #define DEFAULT_METHODS   10
 2103 #define FAKE_PAUSE_STRING "P"
 2104 
 2105 #ifdef Z_RLE
 2106 #  define NUM_STRATEGIES  4
 2107 #else
 2108 #  define NUM_STRATEGIES  3
 2109 #endif
 2110 
 2111 #ifdef __TURBOC__
 2112 #  include <mem.h>
 2113 #endif
 2114 
 2115 struct options_help
 2116 {
 2117     int verbosity;          /* if verbose >= this value, then print line */
 2118     const char *textline;   /* static string with newline chopped off */
 2119 };
 2120 
 2121 #ifdef MINGW32
 2122    /* enable commandline wildcard interpretation (doesn't necessarily work!) */
 2123    int _dowildcard = 1;
 2124 #endif
 2125 
 2126 /* Input and output filenames */
 2127 static PNG_CONST char *progname;
 2128 static PNG_CONST char *inname = "pngtest" DOT "png";
 2129 static PNG_CONST char *outname = "pngout" DOT "png";
 2130 #ifdef PNGCRUSH_LOCO
 2131 static PNG_CONST char *mngname = "mngout" DOT "mng";
 2132 #endif
 2133 static PNG_CONST char *directory_name = "pngcrush" DOT "bak";
 2134 static PNG_CONST char *extension = "_C" DOT "png";
 2135 
 2136 static png_uint_32 width, height;
 2137 static png_uint_32 measured_idat_length;
 2138 static int found_bKGD = 0;
 2139 static int found_color_bKGD = 0;
 2140 #ifdef PNG_cHRM_SUPPORTED
 2141 static int found_cHRM = 0;
 2142 #endif
 2143 static int found_gAMA = 0;
 2144 static int found_hIST = 0;
 2145 static int found_iCCP = 0;
 2146 static int found_IDAT = 0;
 2147 static int found_sBIT = 0;
 2148 static int found_sBIT_max = 0;
 2149 static int found_sBIT_different_RGB_bits = 0;
 2150 static int found_sRGB = 0;
 2151 static int found_tRNS = 0;
 2152 
 2153 static int premultiply = 0;
 2154 static int printed_version_info = 0;
 2155 static int interlace_method = 0;
 2156 #if (PNGCRUSH_LIBPNG_VER < 10400)
 2157 png_size_t max_bytes;
 2158 #else
 2159 png_alloc_size_t max_bytes;
 2160 #endif
 2161 
 2162        /* 0: not premultipled
 2163         * 1: premultiplied input (input has .ppng suffix)
 2164         * 2: premultiplied output (output has .ppng suffix)
 2165         * 3: premultiplied input and output (both have .ppng suffix)
 2166         *
 2167         *    .png -> .ppng is OK, do premultiplication.
 2168         *    .ppng -> .ppng is OK, simply copy data.
 2169         *    .ppng -> .ppng is not OK because colors are irretrievably lost.
 2170         *    .ppng -> no output (pngcrush -n) is OK.
 2171         *
 2172         * To do: Implement this stuff!
 2173         */
 2174 
 2175 static int found_CgBI = 0;
 2176 static int found_any_chunk = 0;
 2177 static int save_apng_chunks = 0; /* 0: output not .apng 1: .apng 2: rejected */
 2178 static int found_acTL_chunk = 0; /* 0: not found, 1: found, 2: rejected */
 2179 static int image_is_immutable = 0;
 2180 static int pngcrush_must_exit = 0;
 2181 static int all_chunks_are_safe = 0;
 2182 static int number_of_open_files;
 2183 static int do_pplt = 0;
 2184 #ifdef PNGCRUSH_MULTIPLE_ROWS
 2185 static png_uint_32 max_rows_at_a_time = 1;
 2186 static png_uint_32 rows_at_a_time;
 2187 #endif
 2188 char pplt_string[STR_BUF_SIZE];
 2189 char *ip, *op, *dot;
 2190 char in_string[STR_BUF_SIZE];
 2191 char prog_string[STR_BUF_SIZE];
 2192 char out_string[STR_BUF_SIZE];
 2193 char in_extension[STR_BUF_SIZE];
 2194 static int text_inputs = 0;
 2195 int text_where[10];           /* 0: no text; 1: before PLTE; 2: after PLTE */
 2196 int text_compression[10];     /* -1: uncompressed tEXt; 0: compressed zTXt
 2197                                   1: uncompressed iTXt; 2: compressed iTXt */
 2198 char text_text[11*STR_BUF_SIZE+1]; /* It would be nice to png_malloc this but we
 2199                                     don't have a png_ptr yet when we need it. */
 2200 char text_keyword[11*80+1];
 2201 
 2202 /* PNG_iTXt_SUPPORTED */
 2203 char text_lang[881];
 2204 char text_lang_key[881];
 2205 
 2206 /* PNG_iCCP_SUPPORTED */
 2207 int iccp_length = 0;
 2208 char *iccp_text;
 2209 char *iccp_file;
 2210 char iccp_name[80];
 2211 
 2212 int best;
 2213 
 2214 char buffer[256];
 2215 
 2216 /* Set up the "cexcept" Try/Throw/Catch exception handler. */
 2217 #include "cexcept.h"
 2218 define_exception_type(const char *);
 2219 extern struct exception_context the_exception_context[1];
 2220 struct exception_context the_exception_context[1];
 2221 png_const_charp msg;
 2222 
 2223 static png_uint_32 input_length;
 2224 static png_uint_32 total_input_length = 0;
 2225 static png_uint_32 total_output_length = 0;
 2226 static int pngcrush_mode = DEFAULT_MODE;
 2227 static int resolution = 0;
 2228 static int remove_chunks = 0;
 2229 static int output_color_type;
 2230 static int output_bit_depth;
 2231 static int force_output_color_type = 8;
 2232 static int force_output_bit_depth = 0;
 2233 static int input_color_type;
 2234 static int input_bit_depth;
 2235 static int trial;
 2236 static int last_trial = 0;
 2237 static png_uint_32 pngcrush_write_byte_count;
 2238 static png_uint_32 pngcrush_best_byte_count=0xffffffff;
 2239 
 2240 static int salvage = 0;
 2241 static int bail = 0;  /* if 0, bail out of trials early */
 2242 static int check_crc = 0;  /* if 0, skip CRC and ADLER32 checks */
 2243                            /* otherwise check both */
 2244 static int force = 1; /* if 1, force output even if IDAT is larger */
 2245 static unsigned int benchmark_iterations = 0;
 2246 
 2247 
 2248 static int blacken = 0; /* if 0, or 2 after the first trial,
 2249                            do not blacken color samples */
 2250 
 2251 /* Delete these in pngcrush-1.8.0 */
 2252 #if 0
 2253 static int make_gray = 0; /* if 0, 2, or 3 after the first trial,
 2254                            do not change color_type to gray */
 2255 static int make_opaque = 0; /* if 0, 2, or 3 after the first trial,
 2256                            do not change color_type to opaque */
 2257 static int make_8_bit = 0; /* if 0, 2, or 3 after the first trial,
 2258                            do not reduce bit_depth from 16 */
 2259 static int reduce_palette = 0;
 2260 #endif
 2261 
 2262 /* Activate these in pngcrush-1.8.0 */
 2263 #if 1
 2264 static int noreduce = 1; /* if 0, "-reduce" was specified */
 2265 static int make_gray = 1; /* if 0, 2, or 3 after the first trial,
 2266                            do not change color_type to gray */
 2267 static int make_opaque = 1; /* if 0, 2, or 3 after the first trial,
 2268                            do not change color_type to opaque */
 2269 static int make_8_bit = 1; /* if 0, 2, or 3 after the first trial,
 2270                            do not reduce bit_depth from 16 */
 2271 static int reduce_palette = 1;
 2272 #endif
 2273 
 2274 static int compression_window;
 2275 static int default_compression_window = 15;
 2276 static int force_compression_window = 0;
 2277 static int compression_mem_level = 9;
 2278 static int final_method = 0;
 2279 static int brute_force = 0;
 2280 static int brute_force_level = 0;
 2281 static int brute_force_filter = 0;
 2282 static int brute_force_strategy = 0;
 2283 static int brute_force_levels[10] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
 2284 static int brute_force_filters[6] = { 1, 1, 1, 1, 1, 1 };
 2285 #ifdef Z_RLE
 2286 static int brute_force_strategies[NUM_STRATEGIES] = { 1, 1, 1, 1 };
 2287 #else
 2288 static int brute_force_strategies[NUM_STRATEGIES] = { 1, 1, 1 };
 2289 #endif
 2290 static int speed = 0;
 2291 static int method = 10;
 2292 static int pauses = 0;
 2293 static int nosave = 0;    /* 0: save; 1: do not save */
 2294 static int overwrite = 0; /* 1: overwrite the input file instead of
 2295                                 creating a new output file */
 2296 static int nofilecheck = 0;
 2297 static int no_limits = 0;
 2298 static int new_mng = 0;
 2299 static png_bytep row_buf;
 2300 #ifdef PNGCRUSH_MULTIPLE_ROWS
 2301 static png_bytepp row_pointers;
 2302 #endif
 2303 static int z_strategy;
 2304 static int best_of_three;
 2305 static int methods_specified = 0;
 2306 static int specified_intent = -1;
 2307 static int intent = -1;
 2308 static int ster_mode = -1;
 2309 static int new_time_stamp = 1;
 2310 static int plte_len = -1;
 2311 #ifdef PNG_FIXED_POINT_SUPPORTED
 2312 static int specified_gamma = 0;
 2313 static int image_specified_gamma = 0;
 2314 static int force_specified_gamma = 0;
 2315 #else
 2316 static double specified_gamma = 0.0;
 2317 static double image_specified_gamma = 0;
 2318 static double force_specified_gamma = 0.0;
 2319 #endif
 2320 static int double_gamma = 0;
 2321 
 2322 static int names;
 2323 static int first_name;
 2324 
 2325 static int have_trns = 0;
 2326 static png_uint_16 trns_index = 0;
 2327 static png_uint_16 trns_red = 0;
 2328 static png_uint_16 trns_green = 0;
 2329 static png_uint_16 trns_blue = 0;
 2330 static png_uint_16 trns_gray = 0;
 2331 
 2332 static png_byte trns_array[256];
 2333 static png_byte trans_in[256];
 2334 static png_uint_16 num_trans_in;
 2335 
 2336 #if defined(PNG_READ_tRNS_SUPPORTED) && defined(PNG_WRITE_tRNS_SUPPORTED)
 2337        png_bytep trans;
 2338        int num_trans;
 2339        png_color_16p trans_values;
 2340 #endif
 2341 
 2342 static int have_bkgd = 0;
 2343 static png_uint_16 bkgd_red = 0;
 2344 static png_uint_16 bkgd_green = 0;
 2345 static png_uint_16 bkgd_blue = 0;
 2346 static png_byte bkgd_index = 0;
 2347 
 2348 static png_colorp palette;
 2349 static int num_palette;
 2350 
 2351 #ifdef REORDER_PALETTE
 2352 static png_byte palette_reorder[256];
 2353 #endif
 2354 
 2355 static png_structp read_ptr, write_ptr, mng_ptr;
 2356 static png_infop read_info_ptr, write_info_ptr;
 2357 static png_infop end_info_ptr;
 2358 static png_infop write_end_info_ptr;
 2359 static FILE *fpin, *fpout;
 2360 png_uint_32 measure_idats(FILE * fp);
 2361 #ifdef PNGCRUSH_LOCO
 2362 static FILE *mng_out;
 2363 static int do_loco = 0;
 2364 static int input_format = 0;    /* 0: PNG  1: MNG */
 2365 static int output_format = 0;
 2366 #endif
 2367 static int do_color_count;
 2368 png_uint_32 pngcrush_measure_idat(png_structp png_ptr);
 2369 
 2370 static png_uint_32 idat_length[MAX_METHODSP1];
 2371 static int filter_type, zlib_level;
 2372 static png_bytep png_row_filters = NULL;
 2373 
 2374 #if PNGCRUSH_TIMERS > 0
 2375 unsigned int pc_timer;
 2376 static float t_filter[PNGCRUSH_TIMERS] = {0};
 2377 static png_uint_32 filter_count[PNGCRUSH_TIMERS] = {0};
 2378 png_uint_32 t_sec;
 2379 png_uint_32 t_nsec;
 2380 #endif
 2381 
 2382 static png_uint_32 max_idat_size = MAX_IDAT_SIZE; /* increases the IDAT size */
 2383 
 2384 #if 0 /* disabled */
 2385 static png_uint_32 crushed_idat_size = 0x3ffffffL;
 2386 static int already_crushed = 0;
 2387 #endif
 2388 
 2389 int ia;
 2390 
 2391 #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
 2392 static /* const */ png_byte chunks_to_ignore[] = {
 2393 
 2394      98,  75,  71 , 68, '\0',  /* bKGD */
 2395      99,  72,  82,  77, '\0',  /* cHRM */
 2396     103,  65,  77,  65, '\0',  /* gAMA */
 2397     104,  73,  83,  84, '\0',  /* hIST */
 2398     105,  67,  67,  80, '\0',  /* iCCP */
 2399     105,  84,  88, 116, '\0',  /* iTXt */
 2400     111,  70,  70, 115, '\0',  /* oFFs */
 2401     112,  67,  65,  76, '\0',  /* pCAL */
 2402     112,  72,  89, 115, '\0',  /* pHYs */
 2403     115,  66,  73,  84, '\0',  /* sBIT */
 2404     115,  67,  65,  76, '\0',  /* sCAL */
 2405     115,  80,  76,  84, '\0',  /* sPLT */
 2406     115,  82,  71,  66, '\0',  /* sRGB */
 2407     115,  84,  69,  82, '\0',  /* sTER */
 2408     116,  69,  88, 116, '\0',  /* tEXt */
 2409     116,  73,  77,  69, '\0',  /* tIME */
 2410     116,  82,  78,  83, '\0',  /* tRNS */
 2411     122,  84,  88, 116, '\0'   /* zTXt */
 2412 };
 2413 #endif
 2414 
 2415 /* Prototypes */
 2416 static void pngcrush_cexcept_error(png_structp png_ptr,
 2417   png_const_charp message);
 2418 
 2419 static void pngcrush_warning(png_structp png_ptr,
 2420   png_const_charp message);
 2421 
 2422 void PNGCBAPI pngcrush_default_read_data(png_structp png_ptr, png_bytep data,
 2423   png_size_t length);
 2424 
 2425 #ifdef PNGCRUSH_H
 2426 void png_read_transform_info(png_structp png_ptr, png_infop info_ptr);
 2427 #endif
 2428 
 2429 void PNGCBAPI pngcrush_default_write_data(png_structp png_ptr, png_bytep data,
 2430   png_size_t length);
 2431 
 2432 void pngcrush_write_png(png_structp write_pointer, png_bytep data,
 2433      png_size_t length);
 2434 
 2435 #ifdef PNG_USER_MEM_SUPPORTED
 2436 png_voidp pngcrush_debug_malloc(png_structp png_ptr, png_uint_32 size);
 2437 void pngcrush_debug_free(png_structp png_ptr, png_voidp ptr);
 2438 #endif
 2439 
 2440 void pngcrush_pause(void);
 2441 
 2442 #ifdef __riscos
 2443 static int fileexists(const char *name)
 2444 static int filesize(const char *name)
 2445 static int mkdir(const char *name, int ignored)
 2446 static void setfiletype(const char *name)
 2447 #endif
 2448 
 2449 int keep_unknown_chunk(png_const_charp name, char *argv[]);
 2450 int keep_chunk(png_const_charp name, char *argv[]);
 2451 void show_result(void);
 2452 png_uint_32 measure_idats(FILE * fp);
 2453 png_uint_32 pngcrush_measure_idat(png_structp png_ptr);
 2454 
 2455 void print_version_info(void);
 2456 void print_usage(int retval);
 2457 
 2458 #ifdef PNGCRUSH_H
 2459 /* Use unexported functions in the embedded libpng */
 2460 # define pngcrush_reset_crc(png_ptr) png_reset_crc(png_ptr)
 2461 # define pngcrush_calculate_crc(png_ptr, ptr, length) \
 2462   png_calculate_crc(png_ptr, ptr, length)
 2463 # define pngcrush_crc_read(png_ptr, buf, length) \
 2464   png_crc_read(png_ptr, buf, length)
 2465 # define pngcrush_crc_error(png_ptr) png_crc_error(png_ptr)
 2466 # define pngcrush_crc_finish(png_ptr, skip) png_crc_finish(png_ptr, skip)
 2467 
 2468 #else
 2469 /*
 2470  * ============================================================
 2471  * We aren't using the bundled libpng functions, so we must
 2472  * reproduce the libpng routines that aren't exported by libpng
 2473  * ============================================================
 2474  */
 2475 
 2476 # if (PNGCRUSH_LIBPNG_VER >= 10209)
 2477 #   ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
 2478 #     undef pngcrush_get_uint_32
 2479 png_uint_32 pngcrush_get_uint_32(png_bytep buf);
 2480 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
 2481 png_uint_32 /* PRIVATE */
 2482 pngcrush_get_uint_32(png_bytep buf)
 2483 {
 2484    png_uint_32 i = ((png_uint_32) (*buf & 0xff) << 24) +
 2485        (*(buf + 1) << 16) + (*(buf + 2) <<  8) + (*(buf + 3)) ;
 2486 
 2487    return (i);
 2488 }
 2489 #   else /*! BIG_ENDIAN */
 2490 #      define pngcrush_get_uint_32(buf) ( *((png_uint_32p) (buf)))
 2491 #   endif /* BIG_ENDIAN */
 2492 
 2493 #   undef pngcrush_get_uint_31
 2494 png_uint_32 pngcrush_get_uint_31(png_structp png_ptr, png_bytep buf);
 2495 png_uint_32 /* PRIVATE */
 2496 pngcrush_get_uint_31(png_structp png_ptr, png_bytep buf)
 2497 {
 2498    png_uint_32 i = pngcrush_get_uint_32(buf);
 2499    if (i > PNG_UINT_31_MAX)
 2500    {
 2501      i=0;
 2502      png_error(png_ptr, "PNG unsigned integer out of range.\n");
 2503    }
 2504    return (i);
 2505 }
 2506 
 2507 #   undef pngcrush_save_uint_32
 2508 void pngcrush_save_uint_32(png_bytep buf, png_uint_32 i);
 2509 void /* PRIVATE */
 2510 pngcrush_save_uint_32(png_bytep buf, png_uint_32 i)
 2511 {
 2512    buf[0] = (png_byte)((i >> 24) & 0xff);
 2513    buf[1] = (png_byte)((i >> 16) & 0xff);
 2514    buf[2] = (png_byte)((i >> 8) & 0xff);
 2515    buf[3] = (png_byte)(i & 0xff);
 2516 }
 2517 # endif  /* PNGCRUSH_LIBPNG_VER < 10209 */
 2518 
 2519 /*
 2520  * Reset the CRC variable to 32 bits of 1's.  Care must be taken
 2521  * in case CRC is > 32 bits to leave the top bits 0.
 2522  */
 2523 void PNGAPI
 2524 pngcrush_reset_crc(png_structp png_ptr)
 2525 {
 2526    pngcrush_crc = crc32(0, Z_NULL, 0);
 2527 }
 2528 /*
 2529  * Calculate the CRC over a section of data.  We can only pass as
 2530  * much data to this routine as the largest single buffer size.  We
 2531  * also check that this data will actually be used before going to the
 2532  * trouble of calculating it.
 2533  */
 2534 void PNGAPI
 2535 pngcrush_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
 2536 {
 2537    pngcrush_crc = crc32(pngcrush_crc, ptr, (uInt)length);
 2538 }
 2539 
 2540 /* Read data, and (optionally) run it through the CRC. */
 2541 void PNGAPI
 2542 pngcrush_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
 2543 {
 2544    pngcrush_default_read_data(png_ptr, buf, length);
 2545    pngcrush_calculate_crc(png_ptr, buf, length);
 2546 }
 2547 
 2548 /* Compare the CRC stored in the PNG file with that calculated by libpng from
 2549  * the data it has read thus far.
 2550  */
 2551 int PNGAPI
 2552 pngcrush_crc_error(png_structp png_ptr)
 2553 {
 2554    png_byte crc_bytes[4];
 2555    png_uint_32 crc;
 2556 
 2557    pngcrush_default_read_data(png_ptr, crc_bytes, 4);
 2558 
 2559    crc = pngcrush_get_uint_32(crc_bytes);
 2560    return ((int)(crc != pngcrush_crc));
 2561 }
 2562 
 2563 /*
 2564  * Optionally skip data and then check the CRC.  Depending on whether we
 2565  * are reading a ancillary or critical chunk, and how the program has set
 2566  * things up, we may calculate the CRC on the data and print a message.
 2567  * Returns '1' if there was a CRC error, '0' otherwise.
 2568  */
 2569 int PNGAPI
 2570 pngcrush_crc_finish(png_structp png_ptr, png_uint_32 skip)
 2571 {
 2572    png_size_t i;
 2573    png_byte bytes[1024];
 2574    png_size_t istop = 1024;
 2575 
 2576    for (i = (png_size_t)skip; i > istop; i -= istop)
 2577    {
 2578       pngcrush_crc_read(png_ptr, bytes, (png_size_t)1024);
 2579    }
 2580    if (i)
 2581    {
 2582       pngcrush_crc_read(png_ptr, bytes, i);
 2583    }
 2584 
 2585    if (pngcrush_crc_error(png_ptr))
 2586    {
 2587       {
 2588          png_chunk_error(png_ptr, "CRC error");
 2589       }
 2590       return (1);
 2591    }
 2592 
 2593    return (0);
 2594 }
 2595 #endif /* PNGCRUSH_H */
 2596 
 2597 #ifdef PNG_STDIO_SUPPORTED
 2598 /*
 2599  * This is the function that does the actual reading of data.  If you are
 2600  * not reading from a standard C stream, you should create a replacement
 2601  * read_data function and use it at run time with png_set_read_fn(), rather
 2602  * than changing the library.
 2603  */
 2604 void PNGCBAPI pngcrush_default_read_data(png_structp png_ptr, png_bytep data,
 2605    png_size_t length)
 2606 {
 2607    png_FILE_p io_ptr;
 2608 
 2609    if (length == 0)
 2610       png_error(png_ptr, "Read Error: invalid length requested");
 2611 
 2612    io_ptr = png_get_io_ptr(png_ptr);
 2613 
 2614    if (fileno(io_ptr) == -1)
 2615       png_error(png_ptr, "Read Error: invalid io_ptr");
 2616 
 2617    /*
 2618     * fread() returns 0 on error, so it is OK to store this in a png_size_t
 2619     * instead of an int, which is what fread() actually returns.
 2620     */
 2621    if ((png_size_t)fread((void *)data, sizeof (png_byte), length,
 2622         io_ptr) != length)
 2623    {
 2624       png_error(png_ptr, "Read Error: invalid length returned");
 2625 #if PNGCRUSH_LIBPNG_VER >= 10700
 2626       PNG_ABORT
 2627 #else
 2628       PNG_ABORT();
 2629 #endif
 2630    }
 2631 
 2632    clearerr(io_ptr);
 2633 
 2634    if (ferror(io_ptr))
 2635    {
 2636       clearerr(io_ptr);
 2637       png_error(png_ptr, "Read Error: error returned by fread()");
 2638    }
 2639 
 2640    if (feof(io_ptr))
 2641    {
 2642       clearerr(io_ptr);
 2643       png_error(png_ptr, "Read Error: unexpected end of file");
 2644    }
 2645 
 2646    clearerr(io_ptr);
 2647 }
 2648 #endif /* PNG_STDIO_SUPPORTED */
 2649 
 2650 #ifdef PNG_STDIO_SUPPORTED
 2651 /*
 2652  * This is the function that does the actual writing of data.  If you are
 2653  * not writing to a standard C stream, you should create a replacement
 2654  * write_data function and use it at run time with png_set_write_fn(), rather
 2655  * than changing the library.
 2656  */
 2657 void PNGCBAPI pngcrush_default_write_data(png_structp png_ptr, png_bytep data,
 2658    png_size_t length)
 2659 {
 2660    png_uint_32 check;
 2661    png_FILE_p io_ptr;
 2662 
 2663    io_ptr = png_get_io_ptr(png_ptr);
 2664 
 2665    check = fwrite(data, 1, length, io_ptr);
 2666    if (check != length)
 2667       png_error(png_ptr, "Write Error");
 2668 }
 2669 #endif /* PNG_STDIO_SUPPORTED */
 2670 
 2671 static void pngcrush_warning(png_structp png_ptr,
 2672    png_const_charp warning_msg)
 2673 {
 2674 #if (PNGCRUSH_LIBPNG_VER >= 10700)
 2675    /* don't warn about damaged LZ stream due to bailing */
 2676    if (bail == 0 && !strcmp(warning_msg, "damaged LZ stream"))
 2677       return;
 2678 #endif
 2679 
 2680    if (verbose >= 0)
 2681       fprintf(stderr, "pngcrush: %s\n", warning_msg);
 2682    else
 2683    {
 2684       if (show_warnings)
 2685          fprintf(stderr, "%s: %s\n", inname, warning_msg);
 2686    }
 2687    return;
 2688 }
 2689 
 2690 /* cexcept interface */
 2691 
 2692 static void pngcrush_cexcept_error(png_structp png_ptr,
 2693    png_const_charp err_msg)
 2694 {
 2695 
 2696 #if 0
 2697 /* Handle "bad adaptive filter value" error.  */
 2698    if (!strcmp(err_msg, "bad adaptive filter value")) {
 2699 #ifdef PNG_CONSOLE_IO_SUPPORTED
 2700         fprintf(stderr, "\nIn %s, correcting %s\n", inname,err_msg);
 2701 #else
 2702         pngcrush_warning(png_ptr, err_msg);
 2703 #endif
 2704      return;
 2705     }
 2706 
 2707 #if PNGCRUSH_LIBPNG_VER < 10400
 2708 /* Handle "Too many IDAT's found" error.  In libpng-1.4.x this became
 2709  * a benign error, "Too many IDATs found".  This scheme will not work
 2710  * in libpng-1.5.0 and later.
 2711  */
 2712 #  ifdef PNGCRUSH_H  /* Why would this not work with the system library? */
 2713     if (!strcmp(err_msg, "Too many IDAT's found")) {
 2714 #    ifdef PNG_CONSOLE_IO_SUPPORTED
 2715         fprintf(stderr, "\nIn %s, correcting %s\n", inname,err_msg);
 2716 #    else
 2717         pngcrush_warning(png_ptr, err_msg);
 2718 #    endif
 2719      return;
 2720     }
 2721 #  endif /* PNGCRUSH_H */
 2722 #endif /* PNGCRUSH_LIBPNG_VER */
 2723 #endif /* 0 */
 2724 
 2725     {
 2726         Throw err_msg;
 2727     }
 2728 }
 2729 
 2730 
 2731 /* START of code to validate memory allocation and deallocation */
 2732 #ifdef PNG_USER_MEM_SUPPORTED
 2733 
 2734 /*
 2735  * Allocate memory.  For reasonable files, size should never exceed
 2736  * 64K.  However, zlib may allocate more then 64K if you don't tell
 2737  * it not to.  See zconf.h and png.h for more information.  zlib does
 2738  * need to allocate exactly 64K, so whatever you call here must
 2739  * have the ability to do that.
 2740  *
 2741  * This piece of code can be compiled to validate max 64K allocations
 2742  * by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K.
 2743  */
 2744 typedef struct memory_information {
 2745     png_uint_32 size;
 2746     png_voidp pointer;
 2747     struct memory_information *next;
 2748 } memory_information;
 2749 typedef memory_information *memory_infop;
 2750 
 2751 static memory_infop pinformation = NULL;
 2752 static int current_allocation = 0;
 2753 static int maximum_allocation = 0;
 2754 
 2755 
 2756 png_voidp pngcrush_debug_malloc(png_structp png_ptr, png_uint_32 size)
 2757 {
 2758 
 2759     /*
 2760      * png_malloc has already tested for NULL; png_create_struct calls
 2761      * pngcrush_debug_malloc directly (with png_ptr == NULL prior to
 2762      * libpng-1.2.0 which is OK since we are not using a user mem_ptr)
 2763      */
 2764 
 2765     if (size == 0)
 2766         return (png_voidp) (NULL);
 2767 
 2768     /*
 2769      * This calls the library allocator twice, once to get the requested
 2770      * buffer and once to get a new free list entry.
 2771      */
 2772     {
 2773         memory_infop pinfo = (memory_infop)malloc(sizeof *pinfo);
 2774         if (pinfo == NULL)
 2775            return (png_voidp) (NULL);
 2776         pinfo->size = size;
 2777         current_allocation += size;
 2778         if (current_allocation > maximum_allocation)
 2779             maximum_allocation = current_allocation;
 2780         pinfo->pointer = malloc(size);
 2781         pinfo->next = pinformation;
 2782         pinformation = pinfo;
 2783         /* Make sure the caller isn't assuming zeroed memory. */
 2784         png_memset(pinfo->pointer, 0xdd, pinfo->size);
 2785         if (verbose > 2)
 2786             fprintf(STDERR, "Pointer %p allocated %lu bytes\n",
 2787                     (png_voidp) pinfo->pointer, (unsigned long)size);
 2788         return (png_voidp) (pinfo->pointer);
 2789     }
 2790 }
 2791 
 2792 /* Free a pointer.  It is removed from the list at the same time. */
 2793 void pngcrush_debug_free(png_structp png_ptr, png_voidp ptr)
 2794 {
 2795     if (png_ptr == NULL)
 2796         fprintf(STDERR, "NULL pointer to pngcrush_debug_free.\n");
 2797     if (ptr == 0) {
 2798 #if 0 /* This happens all the time. */
 2799         fprintf(STDERR, "WARNING: freeing NULL pointer\n");
 2800 #endif /* 0 */
 2801         return;
 2802     }
 2803 
 2804     /* Unlink the element from the list. */
 2805     {
 2806         memory_infop *ppinfo = &pinformation;
 2807         for (;;) {
 2808             memory_infop pinfo = *ppinfo;
 2809             if (pinfo->pointer == ptr) {
 2810                 *ppinfo = pinfo->next;
 2811                 current_allocation -= pinfo->size;
 2812                 if (current_allocation < 0)
 2813                     fprintf(STDERR, "Duplicate free of memory\n");
 2814                 /* We must free the list element too, but first kill
 2815                    the memory that is to be freed. */
 2816                 memset(ptr, 0x55, pinfo->size);
 2817                 if (verbose > 2)
 2818                     fprintf(STDERR, "Pointer %p freed %lu bytes\n",
 2819                         (png_voidp) ptr, (unsigned long)pinfo->size);
 2820                 free(pinfo);
 2821                 break;
 2822             }
 2823             if (pinfo->next == NULL) {
 2824                 fprintf(STDERR, "Pointer %p not found\n",
 2825                     (png_voidp) ptr);
 2826                 break;
 2827             }
 2828             ppinfo = &pinfo->next;
 2829         }
 2830     }
 2831 
 2832     /* Finally free the data. */
 2833     free(ptr);
 2834 }
 2835 
 2836 #endif /* PNG_USER_MEM_SUPPORTED */
 2837 /* END of code to test memory allocation/deallocation */
 2838 
 2839 
 2840 
 2841 
 2842 void pngcrush_pause(void)
 2843 {
 2844     if (pauses > 0) {
 2845         char keystroke;
 2846         fprintf(STDERR, "Press [ENTER] key to continue.\n");
 2847         keystroke = (char) getc(stdin);
 2848         keystroke = keystroke;  /* stifle compiler warning */
 2849     }
 2850 }
 2851 
 2852 
 2853 void png_skip_chunk(png_structp png_ptr)
 2854 {
 2855   png_byte buff[4] = { 0, 0, 0, 0 };
 2856   int ib;
 2857   unsigned long length;
 2858 
 2859   /* read the length field */
 2860   pngcrush_default_read_data(png_ptr, buff, 4);
 2861   length = pngcrush_get_uint_31(png_ptr,buff);
 2862   /* read the chunk name */
 2863   pngcrush_default_read_data(png_ptr, buff, 4);
 2864   if (verbose > 0)
 2865     printf("Skipping %c%c%c%c chunk.\n",buff[0],buff[1],
 2866       buff[2],buff[3]);
 2867   /* skip the data and CRC */
 2868   for (ib=0; ib<length+4; ib++)
 2869   {
 2870      png_byte junk[1] = { 0 };
 2871      pngcrush_default_read_data(png_ptr, junk, 1);
 2872   }
 2873 }
 2874 
 2875 #ifndef __riscos
 2876 #  define setfiletype(x)
 2877 
 2878 #else /* defined(__riscos) */
 2879 #  include <kernel.h>
 2880 
 2881 /* The riscos/acorn support was contributed by Darren Salt. */
 2882 static int fileexists(const char *name)
 2883 {
 2884 # ifdef __acorn
 2885     int ret;
 2886     return _swix(8, 3 | 1 << 31, 17, name, &ret) ? 0 : ret;
 2887 # else
 2888     _kernel_swi_regs r;
 2889     r.r[0] = 17;
 2890     r.r[1] = (int) name;
 2891     return _kernel_swi(8, &r, &r) ? 0 : r.r[0];
 2892 # endif
 2893 }
 2894 
 2895 
 2896 static int filesize(const char *name)
 2897 {
 2898 # ifdef __acorn
 2899     int ret;
 2900     return _swix(8, 3 | 1 << 27, 17, name, &ret) ? 0 : ret;
 2901 # else
 2902     _kernel_swi_regs r;
 2903     r.r[0] = 17;
 2904     r.r[1] = (int) name;
 2905     return _kernel_swi(8, &r, &r) ? 0 : r.r[4];
 2906 # endif
 2907 }
 2908 
 2909 
 2910 static int mkdir(const char *name, int ignored)
 2911 {
 2912 # ifdef __acorn
 2913     _swi(8, 0x13, 8, name, 0);
 2914     return 0;
 2915 # else
 2916     _kernel_swi_regs r;
 2917     r.r[0] = 8;
 2918     r.r[1] = (int) name;
 2919     r.r[4] = r.r[3] = r.r[2] = 0;
 2920     return (int) _kernel_swi(8 | 1 << 31, &r, &r);
 2921 # endif
 2922 }
 2923 
 2924 
 2925 static void setfiletype(const char *name)
 2926 {
 2927 # ifdef __acorn
 2928     _swi(8, 7, 18, name, 0xB60);
 2929 # else
 2930     _kernel_swi_regs r;
 2931     r.r[0] = 18;
 2932     r.r[1] = (int) name;
 2933     r.r[2] = 0xB60;
 2934     _kernel_swi(8 | 1 << 31, &r, &r);
 2935 # endif
 2936 }
 2937 
 2938 #endif /* defined(__riscos) */
 2939 
 2940 
 2941 
 2942 
 2943 /*
 2944  * GRR:  basically boolean; first arg is chunk name-string (e.g., "tIME" or
 2945  *       "alla"); second is always full argv[] command line
 2946  *     - remove_chunks is argv index of *last* -rem arg on command line
 2947  *       (would be more efficient to build table at time of cmdline processing!)
 2948  *       (i.e., build removal_list with names or unique IDs or whatever--skip
 2949  *        excessive string-processing on every single one)
 2950  *     - reprocesses command line _every_ time called, looking for -rem opts...
 2951  *     - just like keep_chunk() except that latter sets things_have_changed
 2952  *       variable and debug stmts say "Removed chunk" (but caller actually does
 2953  *       so, by choosing not to copy chunk to new file)
 2954  *     - for any given chunk name, "name" must either match exact command-line
 2955  *       arg (e.g., -rem fOOb), OR it must match one of the official PNG chunk
 2956  *       names explicitly listed below AND command-line arg either used all-
 2957  *       lowercase form or one of "all[ab]" options
 2958  */
 2959 int keep_unknown_chunk(png_const_charp name, char *argv[])
 2960 {
 2961     int i;
 2962     if (remove_chunks == 0)
 2963         return 1;   /* no -rem options, so always keeping */
 2964     for (i = 1; i <= remove_chunks; i++) {
 2965         if (!strncmp(argv[i], "-rem", 4)) {
 2966             int allb = 0;
 2967             i++;
 2968             if (!strncmp(argv[i], "all", 3)) {
 2969                 allb++;  /* all but gamma, but not doing gamma here */
 2970             }
 2971             if (!strncmp(argv[i], name, 4) /* exact chunk-name match in args */
 2972                 /* ...or exact match for one of known set, plus args included
 2973                  * either "alla", "allb", or all-lowercase form of "name" */
 2974                 || (!strncmp(name, "cHRM", 4)
 2975                     && (!strncmp(argv[i], "chrm", 4) || allb))
 2976                 || (!strncmp(name, "dSIG", 4)
 2977                     && (!strncmp(argv[i], "dsig", 4) || allb))
 2978                 || (!strncmp(name, "gIFg", 4)
 2979                     && (!strncmp(argv[i], "gifg", 4) || allb))
 2980                 || (!strncmp(name, "gIFt", 4)
 2981                     && (!strncmp(argv[i], "gift", 4) || allb))
 2982                 || (!strncmp(name, "gIFx", 4)
 2983                     && (!strncmp(argv[i], "gifx", 4) || allb))
 2984                 || (!strncmp(name, "hIST", 4)
 2985                     && (!strncmp(argv[i], "hist", 4) || allb))
 2986                 || (!strncmp(name, "iCCP", 4)
 2987                     && (!strncmp(argv[i], "iccp", 4) || allb))
 2988                 || (!strncmp(name, "pCAL", 4)
 2989                     && (!strncmp(argv[i], "pcal", 4) || allb))
 2990                 || (!strncmp(name, "sCAL", 4)
 2991                     && (!strncmp(argv[i], "scal", 4) || allb))
 2992                 || (!strncmp(name, "sPLT", 4)
 2993                     && (!strncmp(argv[i], "splt", 4) || allb))
 2994                 || (!strncmp(name, "tIME", 4)
 2995                     && (!strncmp(argv[i], "time", 4) || allb)))
 2996             {
 2997                 return 0;
 2998             }
 2999         }
 3000     }
 3001     return 1;
 3002 }
 3003 
 3004 
 3005 
 3006 
 3007 int keep_chunk(png_const_charp name, char *argv[])
 3008 {
 3009     int i;
 3010     if (verbose > 2 && last_trial)
 3011         fprintf(STDERR, "   Read the %s chunk.\n", name);
 3012     if (remove_chunks == 0)
 3013         return 1;
 3014     if (verbose > 1 && last_trial)
 3015         fprintf(STDERR, "     Check for removal of the %s chunk.\n", name);
 3016     for (i = 1; i <= remove_chunks; i++) {
 3017         if (!strncmp(argv[i], "-rem", 4)) {
 3018             int alla = 0;
 3019             int allb = 0;
 3020             int allt = 0;
 3021             i++;
 3022             if (!strncmp(argv[i], "all", 3)) {
 3023                 allt++;         /* all forms of text chunk are ancillary */
 3024                 allb++;         /* all ancillaries but gamma... */
 3025                 if (!strncmp(argv[i], "alla", 4))
 3026                     alla++;     /* ...no, all ancillaries, period */
 3027             } else if (!strncmp(argv[i], "text", 4)) {
 3028                 allt++;         /* all forms of text chunk */
 3029             }
 3030             if (!strncmp(argv[i], name, 4)  /* exact chunk-name match in args
 3031                 * ...or exact match for one of known set, plus args included
 3032                 * either "alla", "allb", or all-lowercase form of "name": */
 3033                 || (!strncmp(name, "PLTE", 4)
 3034                     && (!strncmp(argv[i], "plte", 4)        ))
 3035                 || (!strncmp(name, "bKGD", 4)
 3036                     && (!strncmp(argv[i], "bkgd", 4) || allb))
 3037                 || (!strncmp(name, "cHRM", 4)
 3038                     && (!strncmp(argv[i], "chrm", 4) || allb))
 3039                 || (!strncmp(name, "dSIG", 4)
 3040                     && (!strncmp(argv[i], "dsig", 4) || allb))
 3041                 || (!strncmp(name, "gAMA", 4)
 3042                     && (!strncmp(argv[i], "gama", 4) || alla))
 3043                 || (!strncmp(name, "gIFg", 4)
 3044                     && (!strncmp(argv[i], "gifg", 4) || allb))
 3045                 || (!strncmp(name, "gIFt", 4)
 3046                     && (!strncmp(argv[i], "gift", 4) || allb))
 3047                 || (!strncmp(name, "gIFx", 4)
 3048                     && (!strncmp(argv[i], "gifx", 4) || allb))
 3049                 || (!strncmp(name, "hIST", 4)
 3050                     && (!strncmp(argv[i], "hist", 4) || allb))
 3051                 || (!strncmp(name, "iCCP", 4)
 3052                     && (!strncmp(argv[i], "iccp", 4) || allb))
 3053                 || (!strncmp(name, "iTXt", 4)
 3054                     && (!strncmp(argv[i], "itxt", 4) || allt))
 3055                 || (!strncmp(name, "oFFs", 4)
 3056                     && (!strncmp(argv[i], "offs", 4) || allb))
 3057                 || (!strncmp(name, "pHYs", 4)
 3058                     && (!strncmp(argv[i], "phys", 4) || allb))
 3059                 || (!strncmp(name, "pCAL", 4)
 3060                     && (!strncmp(argv[i], "pcal", 4) || allb))
 3061                 || (!strncmp(name, "sBIT", 4)
 3062                     && (!strncmp(argv[i], "sbit", 4) || allb))
 3063                 || (!strncmp(name, "sCAL", 4)
 3064                     && (!strncmp(argv[i], "scal", 4) || allb))
 3065                 || (!strncmp(name, "sRGB", 4)
 3066                     && (!strncmp(argv[i], "srgb", 4) || allb))
 3067                 || (!strncmp(name, "sTER", 4)
 3068                     && (!strncmp(argv[i], "ster", 4) || allb))
 3069                 || (!strncmp(name, "sPLT", 4)
 3070                     && (!strncmp(argv[i], "splt", 4) || allb))
 3071                 || (!strncmp(name, "tEXt", 4)
 3072                     && (                                allt))
 3073                 || (!strncmp(name, "tIME", 4)
 3074                     && (!strncmp(argv[i], "time", 4) || allb))
 3075                 || (!strncmp(name, "tRNS", 4)
 3076                     && (!strncmp(argv[i], "trns", 4)        ))
 3077                 || (!strncmp(name, "zTXt", 4)
 3078                     && (!strncmp(argv[i], "ztxt", 4) || allt)) )
 3079             {
 3080                 /* (caller actually does the removal--by failing to create
 3081                  * copy) */
 3082                 if (verbose > 0 && last_trial)
 3083                     fprintf(STDERR, "   Removed the %s chunk.\n", name);
 3084                 return 0;
 3085             }
 3086         }
 3087     }
 3088     if (verbose > 1 && last_trial)
 3089         fprintf(STDERR, "   Preserving the %s chunk.\n", name);
 3090     return 1;
 3091 }
 3092 
 3093 
 3094 
 3095 
 3096 void show_result(void)
 3097 {
 3098     if (total_output_length) {
 3099         if (total_input_length == total_output_length)
 3100             fprintf(STDERR, "   Overall result: no change\n");
 3101         else if (total_input_length > total_output_length)
 3102             fprintf(STDERR,
 3103                     "   Overall result: %4.2f%% reduction, %lu bytes\n",
 3104                     (100.0 -
 3105                      (100.0 * total_output_length) / total_input_length),
 3106                     (unsigned long)(total_input_length-total_output_length));
 3107         else
 3108             fprintf(STDERR,
 3109                     "   Overall result: %4.2f%% increase, %lu bytes\n",
 3110                     -(100.0 -
 3111                       (100.0 * total_output_length) / total_input_length),
 3112                     (unsigned long)(total_output_length - total_input_length));
 3113     }
 3114 
 3115 #if PNGCRUSH_TIMERS > 0
 3116     for (pc_timer=0;pc_timer < PNGCRUSH_TIMERS; pc_timer++)
 3117     {
 3118       filter_count[pc_timer]+=pngcrush_timer_get_hits(pc_timer);
 3119       t_sec=pngcrush_timer_get_seconds(pc_timer);
 3120       t_nsec=pngcrush_timer_get_nanoseconds(pc_timer);
 3121       t_filter[pc_timer] = (float)t_nsec/1000000000.;
 3122       if (t_sec)
 3123         t_filter[pc_timer] += (float)t_sec;
 3124     }
 3125 
 3126 #  if PNGCRUSH_TIMERS >= 3
 3127     if (benchmark_iterations > 0 && verbose >= 0)
 3128     {
 3129       fprintf(STDERR, "   CPU time decode %.4f,", t_filter[1]);
 3130       fprintf(STDERR, " encode %.4f,", t_filter[2]);
 3131       fprintf(STDERR, " other %.4f,", t_filter[3]);
 3132       fprintf(STDERR, " total %.4f sec\n", t_filter[0]);
 3133     }
 3134 #endif
 3135 
 3136    if (verbose <= 0)
 3137      return;
 3138 
 3139 #  if PNGCRUSH_TIMERS > 9
 3140     {
 3141     float total_t_filter=0;
 3142     float total_filter_count=0;
 3143     for (pc_timer = 5; pc_timer < 10; pc_timer++)
 3144     {
 3145       total_t_filter+=t_filter[pc_timer];
 3146       total_filter_count+=filter_count[pc_timer];
 3147     }
 3148     if (total_filter_count > 0)
 3149     {
 3150       for (pc_timer = 5; pc_timer < 10; pc_timer++)
 3151       {
 3152         fprintf(STDERR, "     filter[%u] defilter time = %15.9f, count = %lu\n",
 3153             pc_timer-5, t_filter[pc_timer],
 3154            (unsigned long)filter_count[pc_timer]);
 3155       }
 3156       fprintf(STDERR, "     total defilter time     = %15.9f, count = %lu\n",
 3157         total_t_filter, (unsigned long) total_filter_count);
 3158       }
 3159     }
 3160 #  endif
 3161 #  if PNGCRUSH_TIMERS > 4
 3162     {
 3163       if (filter_count[4] > 0)
 3164         fprintf(STDERR, "     deinterlace time        = %15.9f, count = %lu\n",
 3165              t_filter[4], (unsigned long)filter_count[4]);
 3166     }
 3167 #  endif
 3168 #  if PNGCRUSH_USE_CLOCK_GETTIME != 0
 3169 #  if PNGCRUSH_TIMERS > 1
 3170     {
 3171       fprintf(STDERR, "     total decode time       = %15.9f, count = %lu\n",
 3172            t_filter[1], (unsigned long)filter_count[1]);
 3173     }
 3174 #  endif
 3175 #  if PNGCRUSH_TIMERS > 10
 3176     {
 3177       if (filter_count[10] > 0)
 3178         fprintf(STDERR, "     filter setup time       = %15.9f, count = %lu\n",
 3179              t_filter[10], (unsigned long)filter_count[10]);
 3180     }
 3181 #  endif
 3182 #  if PNGCRUSH_TIMERS > 2
 3183     {
 3184       fprintf(STDERR, "     total encode time       = %15.9f, count = %lu\n",
 3185            t_filter[2], (unsigned long)filter_count[2]);
 3186     }
 3187 #  endif
 3188 #  if PNGCRUSH_TIMERS > 3
 3189     {
 3190       fprintf(STDERR, "     total misc time         = %15.9f, count = %lu\n",
 3191            t_filter[3], (unsigned long)filter_count[3]);
 3192     }
 3193 #  endif
 3194 #  if PNGCRUSH_TIMERS > 0
 3195     {
 3196       fprintf(STDERR, "     total time              = %15.9f, count = %lu\n",
 3197            t_filter[0], (unsigned long)filter_count[0]);
 3198     }
 3199 #  endif
 3200 #  endif
 3201 #else
 3202 #  ifdef PNGCRUSH_TIMERS
 3203     fprintf(STDERR, "   CPU time defilter = 0.000000\n");
 3204     fprintf(STDERR, "   (PNGCRUSH_TIMERS=%d)\n\n", (int)PNGCRUSH_TIMERS);
 3205 #  endif
 3206 #endif
 3207 
 3208 #ifdef PNG_USER_MEM_SUPPORTED
 3209     if (current_allocation) {
 3210         memory_infop pinfo = pinformation;
 3211         fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
 3212                 current_allocation);
 3213         while (pinfo != NULL) {
 3214             fprintf(STDERR, "%10lu bytes at %p\n", (unsigned long)pinfo->size,
 3215                     (png_voidp) pinfo->pointer);
 3216             free(pinfo->pointer);
 3217             pinfo = pinfo->next;
 3218         }
 3219     }
 3220 #endif /* PNG_USER_MEM_SUPPORTED */
 3221     if (found_acTL_chunk == 2)
 3222         fprintf(STDERR,
 3223         "   **** Discarded APNG chunks. ****\n");
 3224 }
 3225 
 3226 void pngcrush_write_png(png_structp write_pointer, png_bytep data,
 3227      png_size_t length)
 3228 {
 3229     pngcrush_write_byte_count += (int) length;
 3230     if (nosave == 0 && last_trial == 1)
 3231       pngcrush_default_write_data(write_pointer, data, length);
 3232 }
 3233 
 3234 static void pngcrush_flush(png_structp png_ptr)
 3235 {
 3236    /* Do nothing. */
 3237    PNGCRUSH_UNUSED(png_ptr)
 3238 }
 3239 
 3240 
 3241 void pngcrush_examine_pixels_fn(png_structp png_ptr, png_row_infop
 3242     row_info, png_bytep data)
 3243 {
 3244    if (blacken == 1 || make_gray == 1 || make_opaque == 1)
 3245    {
 3246       /* Check if there are any fully transparent pixels.  If one is found,
 3247        * without the underlying color already black, set blacken==2. If the
 3248        * PNG colortype does not support an alpha channel, set blacken==3.
 3249        *
 3250        * Check if there are any transparent pixels.  If one is found,
 3251        * set make_opaque==2. If the PNG colortype does not support an alpha
 3252        * channel, set make_opaque==3.
 3253        *
 3254        * Check if there are any non-gray pixels.  If one is found,
 3255        * set make_gray == 2. If the PNG colortype is already gray, set
 3256        * make_gray = 3.
 3257        *
 3258        * Check if any 16-bit pixels do not have identical high and low
 3259        * bytes.  If one is found, set make_8_bit == 2. If the PNG bit_depth
 3260        * is not 16-bits, set make_8_bit = 3.
 3261        *
 3262        * Find the maximum palette entry present in the IDAT chunks of
 3263        * an indexed PNG.
 3264        *
 3265        */
 3266 
 3267       int i;
 3268 
 3269       if (row_info->color_type < 4)
 3270       {
 3271         blacken = 3;  /* It doesn't have an alpha channel */
 3272         /* To do: check if tRNS chunk can be removed from color type 0 or 2 */
 3273         make_opaque = 3;
 3274       }
 3275 
 3276       if (row_info->color_type == 0 || row_info->color_type == 4)
 3277         make_gray = 3; /* It's already gray! */
 3278 
 3279       if (row_info->color_type == 3)
 3280         make_gray = 3; /* Don't change indexed PNG */
 3281 
 3282       if (row_info->bit_depth < 16)
 3283         make_8_bit = 3;
 3284 
 3285       i = (int) row_info->rowbytes-1;
 3286 
 3287       if ((row_info->color_type == 2 || row_info->color_type == 6) &&
 3288           make_gray == 1) /* RGB */
 3289       {
 3290         if (row_info->bit_depth == 8)
 3291           {
 3292             int incr=3;
 3293             if (row_info->color_type == 6)
 3294             {
 3295                incr=4;
 3296                i--;
 3297             }
 3298             for ( ; i > 0 ; )
 3299             {
 3300                if (data[i] != data[i-1] || data[i] != data[i-2])
 3301                  {
 3302                    make_gray = 2;
 3303                  }
 3304 
 3305                i-=incr;
 3306             }
 3307           }
 3308 
 3309         else /* bit depth == 16 */
 3310           {
 3311             int incr = 6;
 3312             if (row_info->color_type == 6)
 3313             {
 3314                incr = 8;
 3315                i-=2;
 3316             }
 3317             for ( ; i > 0 ; )
 3318             {
 3319                if (data[i] != data[i-2] || data[i] != data[i-4] ||
 3320                    data[i-1] != data[i-3] || data[i-1] != data[i-5])
 3321                {
 3322                   make_gray = 2;
 3323                }
 3324                i-=incr;
 3325             }
 3326           }
 3327       }
 3328 
 3329       else if (row_info->color_type == 4 && (blacken == 1 ||
 3330                make_opaque == 1)) /* GA */
 3331       {
 3332         i = (int) row_info->rowbytes-1;
 3333 
 3334         if (row_info->bit_depth == 8)
 3335           {
 3336             for ( ; i > 0 ; )
 3337             {
 3338                if (blacken == 1 && data[i] == 0 &&  data[i-1] != 0)
 3339                {
 3340                    blacken = 2;
 3341                }
 3342 
 3343                if (make_opaque == 1 && data[i] != 255)
 3344                {
 3345                    make_opaque = 2;
 3346                }
 3347                i-=2;
 3348             }
 3349           }
 3350 
 3351         else /* bit depth == 16 */
 3352           {
 3353             for ( ; i > 0 ; )
 3354             {
 3355                if (blacken == 1 && (data[i] == 0 && data[i-1] == 0) &&
 3356                    (data[i-2] != 0 || data[i-3] != 0))
 3357                {
 3358                   blacken = 2;
 3359                }
 3360 
 3361                if (make_opaque == 1 && (data[i] != 255 || data[i-1] != 255))
 3362                {
 3363                    make_opaque = 2;
 3364                }
 3365                i-=4;
 3366             }
 3367           }
 3368       }
 3369 
 3370       /* color_type == 6, RGBA */
 3371       if (row_info->color_type == 6 && (blacken == 1 || make_gray == 1 ||
 3372                make_opaque == 1))
 3373       {
 3374         i = (int) row_info->rowbytes-1;
 3375 
 3376         if (row_info->bit_depth == 8)
 3377           {
 3378             for ( ; i > 0 ; )
 3379             {
 3380                if (blacken == 1 && data[i] == 0 &&
 3381                    (data[i-1] != 0 || data[i-2] != 0 || data[i-3] != 0))
 3382                  {
 3383                    blacken = 2;
 3384                  }
 3385 
 3386                if (make_gray == 1 &&
 3387                   (data[i-1] != data[i-2] || data[i-1] != data[i-3]))
 3388                  {
 3389                    make_gray = 2;
 3390                  }
 3391 
 3392                if (make_opaque == 1 && data[i] != 255)
 3393                  {
 3394                    make_opaque = 2;
 3395                  }
 3396 
 3397                i-=4;
 3398             }
 3399           }
 3400 
 3401         else /* bit depth == 16 */
 3402           {
 3403             for ( ; i > 0 ; )
 3404             {
 3405                if (blacken == 1 && (data[i] == 0 && data[i-1]== 0) &&
 3406                    (data[i-2] != 0 || data[i-3] != 0 || data[i-4] != 0 ||
 3407                    data[i-5] != 0 || data[i-6] != 0 || data[i-7] != 0))
 3408                  {
 3409                    blacken = 2;
 3410                  }
 3411 
 3412                if (make_gray == 1 &&
 3413                    (data[i-2] != data[i-4] || data[i-2] != data[i-6] ||
 3414                    data[i-3] != data[i-5] || data[i-3] != data[i-7]))
 3415                  {
 3416                    make_gray = 2;
 3417                  }
 3418 
 3419                if (make_opaque == 1 && (data[i] != 255 || data[i-1] != 255))
 3420                  {
 3421                    make_opaque = 2;
 3422                  }
 3423 
 3424                i-=8;
 3425             }
 3426           }
 3427       }
 3428    }
 3429 
 3430    if (make_8_bit == 1)
 3431    {
 3432       int i;
 3433       i = (int) row_info->rowbytes-1;
 3434 
 3435       if (row_info->color_type == 0)
 3436       {
 3437          for ( ; i > 0 ; )
 3438          {
 3439                if (data[i] != data[i-1])
 3440                   make_8_bit = 2;
 3441                i-=2;
 3442          }
 3443       }
 3444 
 3445       if (row_info->color_type == 2)
 3446       {
 3447          for ( ; i > 0 ; )
 3448          {
 3449                if (data[i] != data[i-1] || data[i-2] != data[i-3] ||
 3450                    data[i-4] != data [i-5])
 3451                   make_8_bit = 2;
 3452                i-=6;
 3453          }
 3454       }
 3455 
 3456       if (row_info->color_type == 4)
 3457       {
 3458          for ( ; i > 0 ; )
 3459          {
 3460                if (data[i] != data[i-1] || data[i-2] != data[i-3])
 3461                   make_8_bit = 2;
 3462                i-=4;
 3463          }
 3464       }
 3465 
 3466       if (row_info->color_type == 6)
 3467       {
 3468          for ( ; i > 0 ; )
 3469          {
 3470                if (data[i] != data[i-1] || data[i-2] != data[i-3] ||
 3471                    data[i-4] != data [i-5] || data[i-6] != data[i-7])
 3472                   make_8_bit = 2;
 3473                i-=8;
 3474          }
 3475       }
 3476    }
 3477 
 3478    if (reduce_palette == 1 && row_info->color_type == 3)
 3479    {
 3480       int i;
 3481       i = (int) row_info->rowbytes-1;
 3482       
 3483       for ( ; i > 0 ; i--)
 3484       {
 3485          if (data[i] >= plte_len)
 3486             plte_len = data[i] + 1;
 3487       }
 3488    }
 3489 }
 3490 
 3491 void pngcrush_transform_pixels_fn(png_structp png_ptr, png_row_infop row_info,
 3492      png_bytep data)
 3493 {
 3494 
 3495    int i;
 3496 
 3497    if (blacken == 2)
 3498    {
 3499    /* change the underlying color of any fully transparent pixels to black */
 3500       i=(int) row_info->rowbytes-1;
 3501 
 3502       if (row_info->color_type == 4) /* GA */
 3503       {
 3504         if (row_info->bit_depth == 8)
 3505           {
 3506             for ( ; i > 0 ; )
 3507             {
 3508                if (data[i] == 0 &&  data[i-1] != 0)
 3509                   {
 3510                      data[i-1]=0;
 3511                   }
 3512                i-=2;
 3513             }
 3514           }
 3515 
 3516         else /* bit depth == 16 */
 3517           {
 3518             for ( ; i > 0 ; )
 3519             {
 3520                if (data[i] == 0 && data[i-1] == 0)
 3521                   {
 3522                     data[i-2]=0;
 3523                     data[i-3]=0;
 3524                   }
 3525                i-=4;
 3526             }
 3527           }
 3528       }
 3529 
 3530       else /* color_type == 6, RGBA */
 3531       {
 3532         if (row_info->bit_depth == 8)
 3533           {
 3534             for ( ; i > 0 ; )
 3535             {
 3536                if (data[i] == 0)
 3537                  {
 3538                    data[i-1]=0;
 3539                    data[i-2]=0;
 3540                    data[i-3]=0;
 3541                  }
 3542                i-=4;
 3543             }
 3544           }
 3545 
 3546         else /* bit depth == 16 */
 3547           {
 3548             for ( ; i > 0 ; )
 3549             {
 3550                if (data[i] == 0 && data[i-1] == 0)
 3551                  {
 3552                    data[i-2]=0;
 3553                    data[i-3]=0;
 3554                    data[i-4]=0;
 3555                    data[i-5]=0;
 3556                    data[i-6]=0;
 3557                    data[i-7]=0;
 3558                  }
 3559                i-=8;
 3560             }
 3561           }
 3562       }
 3563    }
 3564 }
 3565 
 3566 
 3567 int main(int argc, char *argv[])
 3568 {
 3569     unsigned int bench = 0;
 3570     png_uint_32 y;
 3571     int bit_depth = 0;
 3572     int color_type = 0;
 3573     int num_pass, pass;
 3574     int num_methods;
 3575 
 3576     int try10 = 0;
 3577 
 3578     char *endptr = NULL;
 3579 
 3580     /* try_method[n]: 0 means try this method;
 3581      *
 3582      *              : 1 means do not try this method.
 3583      */
 3584     int try_method[MAX_METHODSP1];
 3585     int methods_enabled = 0;
 3586     int last_method = MAX_METHODS;
 3587 
 3588     int fm[MAX_METHODSP1];
 3589     int lv[MAX_METHODSP1];
 3590     int zs[MAX_METHODSP1];
 3591     int lev, strat, filt;
 3592 
 3593 #ifdef PNG_gAMA_SUPPORTED
 3594 #  ifdef PNG_FIXED_POINT_SUPPORTED
 3595     png_fixed_point file_gamma = 0;
 3596 #  else
 3597     double file_gamma = 0.;
 3598 #  endif
 3599 #endif
 3600     char *cp;
 3601     int i;
 3602 
 3603 #if PNGCRUSH_TIMERS >= 0
 3604     for (pc_timer=0;pc_timer< PNGCRUSH_TIMERS; pc_timer++)
 3605     {
 3606         pngcrush_timer_reset(pc_timer);
 3607         pngcrush_timer_min_secs[pc_timer]=0xffffffff;
 3608         pngcrush_timer_min_nsec[pc_timer]=0xffffffff;
 3609     }
 3610     pngcrush_timer_start(PNGCRUSH_TIMER_TOTAL);
 3611     pngcrush_timer_start(PNGCRUSH_TIMER_MISC);
 3612 #endif
 3613 
 3614     if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
 3615     {
 3616         fprintf(STDERR,
 3617                 "Warning: versions are different between png.h and png.c\n");
 3618         fprintf(STDERR, "  png.h version: %s\n", PNG_LIBPNG_VER_STRING);
 3619         fprintf(STDERR, "  png.c version: %s\n\n", png_libpng_ver);
 3620     }
 3621 
 3622     row_buf = (png_bytep) NULL;
 3623     P2(" row_buf = %p\n",row_buf);
 3624     number_of_open_files = 0;
 3625     do_color_count = 0;
 3626     PNGCRUSH_UNUSED(do_color_count) /* silence compiler warning */
 3627 
 3628     strncpy(prog_string, argv[0], STR_BUF_SIZE);
 3629     prog_string[STR_BUF_SIZE-1] = '\0';
 3630     progname = prog_string;
 3631     for (i = 0, cp = prog_string; *cp != '\0'; i++, cp++)
 3632     {
 3633 #ifdef __riscos
 3634         if (*cp == '.' || *cp == ':')
 3635             progname = ++cp;
 3636 #else
 3637         if (*cp == '\\' || *cp == '/')
 3638             progname = ++cp;
 3639 #endif
 3640     }
 3641 
 3642     /*
 3643      * Definition of methods ("canonical list" is methods 11 and up)
 3644      */
 3645     for (i = 0; i <= MAX_METHODS; i++)
 3646     {
 3647         try_method[i] = 1;  /* 1 means do not try this method */
 3648         fm[i] = 6; lv[i] = 9; zs[i] = 1;  /* default:  method 136 */
 3649     }
 3650 
 3651 
 3652     fm[0] = 0;   lv[0] = 0;   zs[0] = 0;   /* method  0 == uncompressed */
 3653     fm[1] = 0;   lv[1] = 4;   zs[1] = 0;   /* method  1 == method  53 */
 3654     fm[2] = 1;   lv[2] = 4;   zs[2] = 0;   /* method  2 == method  54 */
 3655  /* fm[3] = 6;*/ lv[3] = 4;/* zs[3] = 1;*/ /* method  3 == method 161 */
 3656     fm[4] = 0;/* lv[4] = 9;   zs[4] = 1;*/ /* method  4 == method 119 */
 3657     fm[5] = 1;/* lv[5] = 9;   zs[5] = 0;*/ /* method  5 == method 114 */
 3658  /* fm[6] = 6;   lv[6] = 9;*/ zs[6] = 0;   /* method  6 == method 157 */
 3659     fm[7] = 0;/* lv[7] = 9;*/ zs[7] = 0;   /* method  7 == method 113 */
 3660     fm[8] = 1;/* lv[8] = 9;   zs[8] = 1;*/ /* method  8 == method 120 */
 3661  /* fm[9] = 6;*/ lv[9] = 2;   zs[9] = 2;   /* method  9 == method xxx */
 3662  /* fm[10]= 6;   lv[10]= 9;   zs[10]= 1;*/ /* method 10 == method 166 */
 3663 
 3664     /* methods 11 through 16
 3665      *
 3666      * [strategy 2 (Z_HUFFMAN_ONLY) is independent of zlib compression level]
 3667      */
 3668     method = 11;
 3669     for (filt = 0; filt <= 5; filt++)
 3670     {
 3671         fm[method] = filt;
 3672         lv[method] = 2;
 3673         zs[method] = 2;
 3674         method++;
 3675     }
 3676 
 3677     /*
 3678      * methods 17 through 136 (10*2*6 = 120)
 3679      */
 3680     for (lev = 1; lev <= 9; lev++)
 3681     {
 3682         for (strat = 0; strat <= 1; strat++)
 3683         {
 3684             for (filt = 0; filt <= 5; filt++)
 3685             {
 3686                 fm[method] = filt;
 3687                 lv[method] = lev;
 3688                 zs[method] = strat;
 3689                 method++;
 3690             }
 3691         }
 3692     }
 3693 
 3694 #ifdef Z_RLE
 3695     /* methods 125 through 136
 3696      *
 3697      * [strategy 3 (Z_RLE) is mostly independent of level; 1-3 and 4-9 are
 3698      * same]
 3699      */
 3700     for (filt = 0; filt <= 5; filt++)
 3701     {
 3702         fm[method] = filt;
 3703         lv[method] = 1;
 3704         zs[method] = 3;
 3705         method++;
 3706     }
 3707     for (filt = 0; filt <= 5; filt++)
 3708     {
 3709         fm[method] = filt;
 3710         lv[method] = 4;
 3711         zs[method] = 3;
 3712         method++;
 3713     }
 3714 #endif /* Z_RLE */
 3715 
 3716     /* methods 137 through 148 (12*1*1 = 12), level 0 */
 3717 
 3718     for (strat = 0; strat <= 1; strat++)
 3719     {
 3720         for (filt = 0; filt <= 5; filt++)
 3721         {
 3722             fm[method] = filt;
 3723             lv[method] = 0;
 3724             zs[method] = strat;
 3725             method++;
 3726         }
 3727     }
 3728 
 3729     /*
 3730      * methods 149 through 176 (9*3*1 + 1 = 28), speedy
 3731      */
 3732     for (strat = 0; strat <= 3; strat++)
 3733     {
 3734         for (lev = 1; lev <= 9; lev++)
 3735         {
 3736            lv[method] = lev;
 3737            zs[method] = strat;
 3738            fm[method] = 6;
 3739            method++;
 3740            if (strat == 2)
 3741               break; /* HUFFMAN ONLY is independent of level */
 3742         }
 3743     }
 3744 
 3745 
 3746     num_methods = method;   /* GRR */
 3747 
 3748     /* method 177 */
 3749     fm[method] = 0; lv[method] = 0; zs[method] = 0;  /* copy_idat */
 3750     method++;
 3751 
 3752 #define pngcrush_get_long strtol(argv[i],&endptr,10)
 3753 
 3754 #define pngcrush_check_long \
 3755     {if (errno || endptr == argv[i] || *endptr != '\0') \
 3756       { fprintf(STDERR, "pngcrush: malformed or missing argument\n"); \
 3757         exit(1); \
 3758       } \
 3759     }
 3760 
 3761 #define BUMP_I \
 3762         { i++; \
 3763         if(i >= argc) {fprintf(STDERR,"pngcrush: insufficient parameters\n");\
 3764         exit(1);} }
 3765 
 3766     names = 1;
 3767 
 3768     /* ===================================================================== */
 3769     /* FIXME:  move args-processing block into separate function (470 lines) */
 3770     for (i = 1; i < argc; i++)
 3771     {
 3772         errno=0;
 3773 
 3774         if (!strncmp(argv[i], "--", 2))
 3775             argv[i]++;
 3776 
 3777         if (!strncmp(argv[i], "-", 1))
 3778             names++;
 3779 
 3780         /* GRR:  start of giant else-if block */
 3781 
 3782         if (!strncmp(argv[i], "-bail", 5))
 3783             bail=0;
 3784 
 3785         if (!strncmp(argv[i], "-bench", 6))
 3786         {
 3787             names++;
 3788             BUMP_I;
 3789             benchmark_iterations = (unsigned int) pngcrush_get_long;
 3790             pngcrush_check_long;
 3791         }
 3792 
 3793         else if (!strncmp(argv[i], "-bkgd", 5) ||
 3794                  !strncmp(argv[i], "-bKGD", 5))
 3795         {
 3796             names += 3;
 3797             have_bkgd = 1;
 3798             BUMP_I;
 3799             bkgd_red = (png_uint_16) pngcrush_get_long;
 3800             pngcrush_check_long;
 3801             BUMP_I;
 3802             bkgd_green = (png_uint_16) pngcrush_get_long;
 3803             pngcrush_check_long;
 3804             BUMP_I;
 3805             bkgd_blue = (png_uint_16) pngcrush_get_long;
 3806             pngcrush_check_long;
 3807             bkgd_index = 0;
 3808         }
 3809 
 3810         else if (!strncmp(argv[i], "-blacken", 8))
 3811             blacken=1;
 3812 
 3813         else if (!strncmp(argv[i], "-brute", 6))
 3814             /* brute force:  try everything */
 3815         {
 3816             methods_specified = 1;
 3817             brute_force++;
 3818             for (method = 1; method < num_methods; method++)
 3819                 try_method[method] = 0;
 3820             if (brute_force_filter == 0)
 3821                 for (filt = 0; filt < 6; filt++)
 3822                     brute_force_filters[filt] = 0;
 3823             if (brute_force_level == 0)
 3824                 for (lev = 0; lev < 10; lev++)
 3825                     brute_force_levels[lev] = 0;
 3826             if (brute_force_strategy == 0)
 3827                 for (strat = 0; strat < NUM_STRATEGIES; strat++)
 3828                     brute_force_strategies[strat] = 0;
 3829         }
 3830 
 3831         else if (!strncmp(argv[i], "-check", 6))
 3832         {
 3833             check_crc = 1;
 3834         }
 3835 
 3836         else if (!strncmp(argv[i], "-c", 3) || !strncmp(argv[i], "-col", 4))
 3837         {
 3838             names++;
 3839             BUMP_I;
 3840             force_output_color_type = pngcrush_get_long;
 3841             pngcrush_check_long;
 3842         }
 3843 
 3844         else if (!strncmp(argv[i], "-d", 3) || !strncmp(argv[i], "-dir", 4))
 3845         {
 3846             BUMP_I;
 3847             if (pngcrush_mode == EXTENSION_MODE)
 3848                 pngcrush_mode = DIREX_MODE;
 3849             else
 3850                 pngcrush_mode = DIRECTORY_MODE;
 3851             directory_name = argv[names++];
 3852         }
 3853 
 3854         else if (!strncmp(argv[i], "-exit", 5))
 3855         {
 3856             pngcrush_must_exit = 1;
 3857         }
 3858 
 3859         else if (!strncmp(argv[i], "-e", 3) || !strncmp(argv[i], "-ext", 4))
 3860         {
 3861             BUMP_I;
 3862             if (pngcrush_mode == DIRECTORY_MODE)
 3863                 pngcrush_mode = DIREX_MODE;
 3864             else
 3865                 pngcrush_mode = EXTENSION_MODE;
 3866             extension = argv[names++];
 3867         }
 3868 
 3869         else if (!strncmp(argv[i], "-fast", 5))
 3870         {
 3871             /* try two fast filters */
 3872             methods_specified = 1;
 3873             try_method[16] = 0;
 3874             try_method[53] = 0;
 3875         }
 3876 
 3877         else if (!strncmp(argv[i], "-force", 6))
 3878         {
 3879             force = 1;
 3880         }
 3881 
 3882         else if (!strncmp(argv[i], "-fix", 4))
 3883         {
 3884             salvage++;
 3885         }
 3886 
 3887         else if (!strncmp(argv[i], "-f", 3) || !strncmp(argv[i], "-fil", 4))
 3888         {
 3889             int specified_filter;
 3890             BUMP_I;
 3891             specified_filter = pngcrush_get_long;
 3892             pngcrush_check_long;
 3893             if (specified_filter > 5 || specified_filter < 0)
 3894                 specified_filter = 5;
 3895             names++;
 3896             if (brute_force == 0)
 3897                 fm[method] = specified_filter;
 3898             else
 3899             {
 3900                 if (brute_force_filter == 0)
 3901                   for (filt = 0; filt < 6; filt++)
 3902                     brute_force_filters[filt] = 1;
 3903                 brute_force_filters[specified_filter] = 0;
 3904                 brute_force_filter++;
 3905             }
 3906         }
 3907 
 3908 #ifdef PNG_gAMA_SUPPORTED
 3909         else if (!strncmp(argv[i], "-g", 3) || !strncmp(argv[i], "-gam", 4))
 3910         {
 3911             names++;
 3912             BUMP_I;
 3913             found_gAMA=1;
 3914             if (specified_intent < 0)
 3915             {
 3916 #ifdef PNG_FIXED_POINT_SUPPORTED
 3917                 int c;
 3918                 char number[16];
 3919                 char *n = number;
 3920                 int nzeroes = -1;
 3921                 int length = strlen(argv[i]);
 3922                 for (c = 0; c < length; c++)
 3923                 {
 3924                     if (*(argv[i] + c) == '.')
 3925                     {
 3926                         nzeroes = 5;
 3927                     }
 3928                     else if (nzeroes)
 3929                     {
 3930                         *n++ = *(argv[i] + c);
 3931                         nzeroes--;
 3932                     }
 3933                 }
 3934                 for (c = 0; c < nzeroes; c++)
 3935                     *n++ = '0';
 3936                 *n = '\0';
 3937                 specified_gamma = strtol(number,&endptr,10);
 3938 #else
 3939                 specified_gamma = strtof(argv[i],&endptr);
 3940 #endif
 3941                 pngcrush_check_long;
 3942             }
 3943         }
 3944 #endif /* PNG_gAMA_SUPPORTED */
 3945 
 3946         else if (!strncmp(argv[i], "-h", 3) || !strncmp(argv[i], "-hel", 4))
 3947         {
 3948             ++verbose;
 3949             print_version_info();
 3950             printed_version_info++;
 3951             print_usage(0);   /* this exits */
 3952         }
 3953 
 3954         else if (!strncmp(argv[i], "-huffman", 8))
 3955         {
 3956             /* try all filters with huffman */
 3957             methods_specified = 1;
 3958             for (method = 11; method <= 16; method++)
 3959             {
 3960                 try_method[method] = 0;
 3961             }
 3962         }
 3963 
 3964 #ifdef PNG_iCCP_SUPPORTED
 3965         else if (!strncmp(argv[i], "-iccp", 5))
 3966         {
 3967             FILE *iccp_fn;
 3968             if (iccp_length)
 3969                 free(iccp_text);
 3970             BUMP_I;
 3971             iccp_length = pngcrush_get_long;
 3972             pngcrush_check_long;
 3973             names += 3;
 3974             BUMP_I;
 3975             strncpy(iccp_name, argv[i], 80);
 3976             iccp_name[79] = '\0';
 3977             BUMP_I;
 3978             iccp_file = argv[i];
 3979             if ((iccp_fn = FOPEN(iccp_file, "rb")) == NULL) {
 3980                 fprintf(STDERR, "Could not find file: %s\n", iccp_file);
 3981                 iccp_length = 0;
 3982             }
 3983             else
 3984             {
 3985                 int ic;
 3986                 number_of_open_files++;
 3987                 iccp_text = (char*)malloc(iccp_length);
 3988                 if (iccp_text == NULL)
 3989                 {
 3990                    fprintf(STDERR, "malloc of iccp_text failed\n");
 3991                    iccp_length = 0;
 3992                 }
 3993 
 3994                 for (ic = 0; ic < iccp_length; ic++)
 3995                 {
 3996                     png_size_t num_in;
 3997                     num_in = fread((void *)buffer, 1, 1, iccp_fn);
 3998 
 3999                     if (!num_in)
 4000                         break;
 4001 
 4002                     iccp_text[ic] = buffer[0];
 4003                 }
 4004 
 4005                 FCLOSE(iccp_fn);
 4006             }
 4007         }
 4008 #endif /* PNG_iCCP_SUPPORTED */
 4009 
 4010         else if (!strncmp(argv[i], "-keep", 5))
 4011         {
 4012             names++;
 4013             BUMP_I;
 4014             if (!strncmp(argv[i], "-dSIG", 5)
 4015                     && (!strncmp(argv[i], "-dsig", 5) ))
 4016               found_any_chunk=1;
 4017         }
 4018 
 4019         else if (!strncmp(argv[i], "-l", 3) || !strncmp(argv[i], "-lev", 4))
 4020         {
 4021             int specified_level;
 4022             BUMP_I;
 4023             specified_level = pngcrush_get_long;
 4024             pngcrush_check_long;
 4025             if (specified_level > 9 || specified_level < 0)
 4026                 specified_level = 9;
 4027             names++;
 4028             if (brute_force == 0)
 4029                 lv[method] = specified_level;
 4030             else
 4031             {
 4032                 if (brute_force_level == 0)
 4033                     for (lev = 0; lev < 10; lev++)
 4034                         brute_force_levels[lev] = 1;
 4035                 brute_force_levels[specified_level] = 0;
 4036                 brute_force_level++;
 4037             }
 4038         }
 4039 
 4040         else if (!strncmp(argv[i], "-loco", 5))
 4041         {
 4042 #ifdef PNGCRUSH_LOCO
 4043             do_loco = 1;
 4044 #else
 4045             fprintf
 4046                 (STDERR,"Cannot do -loco because libpng was compiled"
 4047                  " without MNG features");
 4048 #endif
 4049         }
 4050 
 4051         else if (!strncmp(argv[i], "-max", 4))
 4052         {
 4053             names++;
 4054             BUMP_I;
 4055             max_idat_size = (png_uint_32) pngcrush_get_long;
 4056             pngcrush_check_long;
 4057             if (max_idat_size == 0 || max_idat_size > PNG_UINT_31_MAX)
 4058                 max_idat_size = PNG_ZBUF_SIZE;
 4059         }
 4060 
 4061         else if (!strncmp(argv[i], "-m", 3) || !strncmp(argv[i], "-met", 4))
 4062         {
 4063             names++;
 4064             BUMP_I;
 4065             method = pngcrush_get_long;
 4066             pngcrush_check_long;
 4067             if (method >= 1 && method <= MAX_METHODS)
 4068             {
 4069               methods_specified = 1;
 4070               brute_force = 0;
 4071               try_method[method] = 0;
 4072             }
 4073             else
 4074             {
 4075               fprintf(STDERR, "\n  Ignoring invalid method: %d\n",
 4076                       method);
 4077               method = MAX_METHODS;
 4078             }
 4079         }
 4080 
 4081 #ifdef PNGCRUSH_LOCO
 4082         else if (!strncmp(argv[i], "-mng", 4))
 4083         {
 4084             names++;
 4085             BUMP_I;
 4086             mngname = argv[i];
 4087             new_mng++;
 4088         }
 4089 #endif
 4090 
 4091         else if (!strncmp(argv[i], "-new", 4))
 4092         {
 4093             make_opaque = 1;                 /* -reduce */
 4094             make_gray = 1;                   /* -reduce */
 4095             make_8_bit = 1;                  /* -reduce */
 4096             reduce_palette = 1;              /* -reduce */
 4097         }
 4098 
 4099         else if (!strncmp(argv[i], "-nobail", 7))
 4100             bail=1;
 4101 
 4102         else if (!strncmp(argv[i], "-nocheck", 8))
 4103         {
 4104             check_crc = 0;
 4105         }
 4106 
 4107         else if (!strncmp(argv[i], "-nofilecheck", 5))
 4108         {
 4109             nofilecheck++;
 4110         }
 4111         else if (!strncmp(argv[i], "-noforce", 6))
 4112         {
 4113             force = 0;
 4114         }
 4115 
 4116 
 4117         else if (!strncmp(argv[i], "-nolimits", 5))
 4118         {
 4119             no_limits++;
 4120         }
 4121 
 4122         else if (!strncmp(argv[i], "-noreduce_pal", 13))
 4123         {
 4124             reduce_palette = 0;
 4125         }
 4126 
 4127         else if (!strncmp(argv[i], "-noreduce", 9))
 4128         {
 4129             make_opaque = 0;
 4130             make_gray = 0;
 4131             make_8_bit = 0;
 4132             reduce_palette = 0;
 4133         }
 4134 
 4135         else if (!strncmp(argv[i], "-n", 3) || !strncmp(argv[i], "-nos", 4))
 4136         {
 4137             /* no save; I just use this for testing decode speed */
 4138             /* also to avoid saving if a CgBI chunk was found */
 4139             nosave++;
 4140             pngcrush_mode = EXTENSION_MODE;
 4141         }
 4142 
 4143         else if (!strncmp(argv[i], "-oldtimestamp", 5))
 4144         {
 4145             new_time_stamp=0;
 4146         }
 4147 
 4148         else if (!strncmp(argv[i], "-old", 4))
 4149         {
 4150             make_opaque = 0;                 /* no -reduce */
 4151             make_gray = 0;                   /* no -reduce */
 4152             make_8_bit = 0;                  /* no -reduce */
 4153             reduce_palette = 0;              /* no -reduce */
 4154         }
 4155 
 4156         else if(!strncmp(argv[i], "-ow",3))
 4157         {
 4158             overwrite = 1;
 4159         }
 4160 
 4161         else if (!strncmp(argv[i], "-pplt", 3))
 4162         {
 4163             names++;
 4164             do_pplt++;
 4165             BUMP_I;
 4166             strncpy(pplt_string, argv[i], STR_BUF_SIZE);
 4167             pplt_string[STR_BUF_SIZE-1] = '\0';
 4168         }
 4169 
 4170         else if (!strncmp(argv[i], "-premultiply", 5))
 4171         {
 4172             premultiply=2;
 4173         }
 4174 
 4175         else if (!strncmp(argv[i], "-p", 3) || !strncmp(argv[i], "-pau", 4))
 4176         {
 4177             pauses++;
 4178         }
 4179 
 4180         else if (!strncmp(argv[i], "-q", 3) || !strncmp(argv[i], "-qui", 4))
 4181         {
 4182             /* quiet, does not suppress warnings or timing */
 4183             verbose = 0;
 4184         }
 4185 
 4186         else if (!strncmp(argv[i], "-reduce_pal", 11))
 4187         {
 4188             reduce_palette = 1;
 4189         }
 4190 
 4191         else if (!strncmp(argv[i], "-reduce", 7))
 4192         {
 4193             noreduce = 0;
 4194             make_opaque = 1;
 4195             make_gray = 1;
 4196             make_8_bit = 1;
 4197             reduce_palette = 1;
 4198         }
 4199 
 4200 #ifdef PNG_gAMA_SUPPORTED
 4201         else if (!strncmp(argv[i], "-replace_gamma", 4))
 4202         {
 4203             names++;
 4204             BUMP_I;
 4205             found_gAMA=1;
 4206             {
 4207 #ifdef PNG_FIXED_POINT_SUPPORTED
 4208                 int c;
 4209                 char number[16];
 4210                 char *n = number;
 4211                 int nzeroes = -1;
 4212                 int length = strlen(argv[i]);
 4213                 for (c = 0; c < length; c++)
 4214                 {
 4215                     if (*(argv[i] + c) == '.')
 4216                     {
 4217                         nzeroes = 5;
 4218                     }
 4219                     else if (nzeroes)
 4220                     {
 4221                         *n++ = *(argv[i] + c);
 4222                         nzeroes--;
 4223                     }
 4224                 }
 4225                 for (c = 0; c < nzeroes; c++)
 4226                     *n++ = '0';
 4227                 *n = '\0';
 4228                 force_specified_gamma = strtol(number,&endptr,10);
 4229 #else
 4230                 force_specified_gamma = strtof(argv[i],&endptr);
 4231 #endif
 4232                 pngcrush_check_long;
 4233             }
 4234         }
 4235 #endif /* PNG_gAMA_SUPPORTED */
 4236 
 4237 #ifdef PNG_pHYs_SUPPORTED
 4238         else if (!strncmp(argv[i], "-res", 4))
 4239         {
 4240             names++;
 4241             BUMP_I;
 4242             resolution = pngcrush_get_long;
 4243             pngcrush_check_long;
 4244         }
 4245 #endif
 4246 
 4247 #ifdef Z_RLE
 4248         else if (!strncmp(argv[i], "-rle", 4))
 4249         {
 4250             /* try all filters with RLE */
 4251             methods_specified = 1;
 4252             for (method = 125; method <= 136; method++)
 4253             {
 4254                 try_method[method] = 0;
 4255             }
 4256         }
 4257 #endif
 4258 
 4259 #ifdef PNGCRUSH_MULTIPLE_ROWS
 4260         else if (!strncmp(argv[i], "-rows", 5))
 4261         {
 4262             names++;
 4263             BUMP_I;
 4264             max_rows_at_a_time = pngcrush_get_long;
 4265             pngcrush_check_long;
 4266         }
 4267 #endif
 4268 
 4269         else if (!strncmp(argv[i], "-r", 3) || !strncmp(argv[i], "-rem", 4))
 4270         {
 4271             remove_chunks = i;
 4272             names++;
 4273             BUMP_I;
 4274             if (!strncmp(argv[i], "-dSIG", 5)
 4275                  && (!strncmp(argv[i], "-dsig", 5)))
 4276                image_is_immutable=0;
 4277         }
 4278 
 4279         else if (!strncmp(argv[i], "-save", 5))
 4280         {
 4281             all_chunks_are_safe++;
 4282         }
 4283 
 4284         else if (!strncmp(argv[i], "-speed", 6))
 4285         {
 4286             speed = 1;
 4287         }
 4288 
 4289         else if (!strncmp(argv[i], "-srgb", 5) ||
 4290                    !strncmp(argv[i], "-sRGB", 5))
 4291         {
 4292 #ifdef PNG_gAMA_SUPPORTED
 4293 #  ifdef PNG_FIXED_POINT_SUPPORTED
 4294             specified_gamma = 45455L;
 4295 #  else
 4296             specified_gamma = 0.45455;
 4297 #  endif
 4298 #endif
 4299             specified_intent = 0;
 4300             BUMP_I;
 4301             if (!strncmp(argv[i], "0", 1) ||
 4302                 !strncmp(argv[i], "1", 1) ||
 4303                 !strncmp(argv[i], "2", 1) ||
 4304                 !strncmp(argv[i], "3", 1))
 4305             {
 4306                 names++;
 4307                 specified_intent = (int) pngcrush_get_long;
 4308                 pngcrush_check_long;
 4309             } else
 4310                 i--;
 4311         }
 4312 
 4313         else if (!strncmp(argv[i], "-ster", 5) ||
 4314                    !strncmp(argv[i], "-sTER", 5))
 4315         {
 4316             BUMP_I;
 4317             ster_mode = -1;
 4318             if (!strncmp(argv[i], "0", 1) ||
 4319                 !strncmp(argv[i], "1", 1))
 4320             {
 4321                 names++;
 4322                 ster_mode = (int) pngcrush_get_long;
 4323                 pngcrush_check_long;
 4324             }
 4325             else
 4326                 i--;
 4327         }
 4328 
 4329         else if (!strncmp(argv[i], "-s", 3) || !strncmp(argv[i], "-sil", 4))
 4330         {
 4331             /* silent, suppresses warnings, timing, and results */
 4332             verbose = -1;
 4333         }
 4334 
 4335         else if (!strncmp(argv[i], "-text", 5)
 4336                  || !strncmp(argv[i], "-tEXt", 5) ||
 4337 #ifdef PNG_iTXt_SUPPORTED
 4338                  !strncmp(argv[i], "-itxt", 5)
 4339                  || !strncmp(argv[i], "-iTXt", 5)
 4340                  || !strncmp(argv[i], "-zitxt", 6)
 4341                  || !strncmp(argv[i], "-ziTXt", 6) ||
 4342 #endif
 4343                  !strncmp(argv[i], "-ztxt", 5)
 4344                  || !strncmp(argv[i], "-zTXt", 5))
 4345         {
 4346             i += 2;
 4347             BUMP_I;
 4348             i -= 3;
 4349             if (strlen(argv[i + 2]) < 80 &&
 4350                 strlen(argv[i + 3]) < STR_BUF_SIZE &&
 4351                 text_inputs < 10)
 4352             {
 4353 #ifdef PNG_iTXt_SUPPORTED
 4354                 if (!strncmp(argv[i], "-zi", 3))
 4355                 {
 4356                     text_compression[text_inputs] =
 4357                         PNG_ITXT_COMPRESSION_zTXt;
 4358                     /* names += 2; */
 4359                 }
 4360                 else
 4361 #endif
 4362                 if (!strncmp(argv[i], "-z", 2))
 4363                     text_compression[text_inputs] =
 4364                         PNG_TEXT_COMPRESSION_zTXt;
 4365                 else if (!strncmp(argv[i], "-t", 2))
 4366                     text_compression[text_inputs] =
 4367                         PNG_TEXT_COMPRESSION_NONE;
 4368 #ifdef PNG_iTXt_SUPPORTED
 4369                 else
 4370                 {
 4371                     text_compression[text_inputs] =
 4372                         PNG_ITXT_COMPRESSION_NONE;
 4373                     /* names += 2; */
 4374                 }
 4375 #endif
 4376                 names += 3;
 4377                 if (!strncmp(argv[++i], "b", 1))
 4378                     text_where[text_inputs] = 1;
 4379                 if (!strncmp(argv[i], "a", 1))
 4380                     text_where[text_inputs] = 2;
 4381                 strncpy(&text_keyword[text_inputs * 80], argv[++i],
 4382                     80);
 4383                 text_keyword[text_inputs * 80 + 79] = '\0';
 4384 #ifdef PNG_iTXt_SUPPORTED
 4385                 if (text_compression[text_inputs] <= 0)
 4386                 {
 4387                     text_lang[text_inputs * 80] = '\0';
 4388                     text_lang_key[text_inputs * 80] = '\0';
 4389                 }
 4390                 else
 4391                 {
 4392                     i += 2;
 4393                     BUMP_I;
 4394                     i -= 3;
 4395                     names += 2;
 4396                     strncpy(&text_lang[text_inputs * 80], argv[++i], 80);
 4397                     text_lang[text_inputs * 80 + 79] = '\0';
 4398                     /* libpng-1.0.5j and later */
 4399                     strncpy(&text_lang_key[text_inputs * 80], argv[++i], 80);
 4400                     text_lang_key[text_inputs * 80 + 79] = '\0';
 4401                 }
 4402 #endif
 4403                 strncpy(&text_text[text_inputs * STR_BUF_SIZE], argv[++i],
 4404                     STR_BUF_SIZE);
 4405                 text_text[(text_inputs + 1) * STR_BUF_SIZE - 1] = '\0';
 4406                 text_inputs++;
 4407             } else {
 4408                 if (text_inputs > 9)
 4409                     fprintf(STDERR,
 4410                             "too many text/zTXt inputs; only 10 allowed\n");
 4411                 else
 4412                     fprintf(STDERR,
 4413                             "keyword exceeds 79 characters or text"
 4414                             " exceeds 2047 characters\n");
 4415                 i += 3;
 4416                 names += 3;
 4417 #ifdef PNG_iTXt_SUPPORTED
 4418                 if (!strncmp(argv[i], "-i", 3) || !strncmp(argv[i], "-itx", 4))
 4419                 {
 4420                     i++;
 4421                     BUMP_I;
 4422                     names += 2;
 4423                 }
 4424 #endif
 4425             }
 4426         }
 4427 
 4428         else if (!strncmp(argv[i], "-time_stamp", 5) ||  /* legacy */
 4429                  !strncmp(argv[i], "-newtimestamp", 5))
 4430             new_time_stamp=1;
 4431 
 4432 #ifdef PNG_tRNS_SUPPORTED
 4433         else if (!strncmp(argv[i], "-trns_a", 7) ||
 4434                  !strncmp(argv[i], "-tRNS_a", 7))
 4435         {
 4436             num_trans_in = (png_uint_16) pngcrush_get_long;
 4437             pngcrush_check_long;
 4438             if (num_trans_in > 256)
 4439                num_trans_in = 256;
 4440             trns_index=num_trans_in-1;
 4441             have_trns = 1;
 4442             for (ia = 0; ia < num_trans_in; ia++)
 4443             {
 4444                 BUMP_I;
 4445                 trans_in[ia] = (png_byte) pngcrush_get_long;
 4446                 pngcrush_check_long;
 4447             }
 4448             names += 1 + num_trans_in;
 4449         }
 4450 
 4451         else if (!strncmp(argv[i], "-trns", 5) ||
 4452                    !strncmp(argv[i], "-tRNS", 5))
 4453         {
 4454             names += 5;
 4455             have_trns = 1;
 4456             BUMP_I;
 4457             trns_index = (png_uint_16) pngcrush_get_long;
 4458             pngcrush_check_long;
 4459             BUMP_I;
 4460             trns_red = (png_uint_16) pngcrush_get_long;
 4461             pngcrush_check_long;
 4462             BUMP_I;
 4463             trns_green = (png_uint_16) pngcrush_get_long;
 4464             pngcrush_check_long;
 4465             BUMP_I;
 4466             trns_blue = (png_uint_16) pngcrush_get_long;
 4467             pngcrush_check_long;
 4468             BUMP_I;
 4469             trns_gray = (png_uint_16) pngcrush_get_long;
 4470             pngcrush_check_long;
 4471         }
 4472 #endif /* tRNS */
 4473 
 4474         else if(!strncmp(argv[i], "-try10",6))
 4475         {
 4476             try10 = 1;
 4477         }
 4478 
 4479         else if (!strncmp(argv[i], "-version", 8))
 4480         {
 4481             fprintf(STDERR, " pngcrush ");
 4482             fprintf(STDERR, PNGCRUSH_VERSION);
 4483             fprintf(STDERR, ", uses libpng ");
 4484             fprintf(STDERR, PNG_LIBPNG_VER_STRING);
 4485             fprintf(STDERR, " and zlib ");
 4486             fprintf(STDERR, ZLIB_VERSION);
 4487             fprintf(STDERR, "\n Check http://pmt.sf.net/\n");
 4488             fprintf(STDERR, " for the most recent version.\n");
 4489             verbose = 0;
 4490             exit(0);
 4491         }
 4492 
 4493         else if (!strncmp(argv[i], "-v", 3) || !strncmp(argv[i], "-ver", 4))
 4494         {
 4495             verbose++;
 4496         }
 4497 
 4498         else if (!strncmp(argv[i], "-warn", 5))
 4499         {
 4500             show_warnings++;
 4501             verbose = -1;
 4502         }
 4503 
 4504         else if (!strncmp(argv[i], "-w", 3) || !strncmp(argv[i], "-win", 4))
 4505         {
 4506             BUMP_I;
 4507             default_compression_window = pngcrush_get_long;
 4508             pngcrush_check_long;
 4509             force_compression_window++;
 4510             names++;
 4511         }
 4512 
 4513         else if (!strncmp(argv[i], "-zm", 4) || !strncmp(argv[i], "-zmem", 5))
 4514         {
 4515             BUMP_I;
 4516             compression_mem_level = pngcrush_get_long;
 4517             pngcrush_check_long;
 4518             names++;
 4519         }
 4520 
 4521         else if (!strncmp(argv[i], "-z", 3))
 4522         {
 4523             int specified_strategy;
 4524             BUMP_I;
 4525             specified_strategy = pngcrush_get_long;
 4526             pngcrush_check_long;
 4527             if (specified_strategy > 2 || specified_strategy < 0)
 4528                 specified_strategy = 0;
 4529             names++;
 4530             if (brute_force == 0)
 4531                 zs[method] = specified_strategy;
 4532             else
 4533             {
 4534                 if (brute_force_strategy == 0)
 4535                     for (strat = 0; strat < 2; strat++)
 4536                         brute_force_strategies[strat] = 1;
 4537                 brute_force_strategies[specified_strategy] = 0;
 4538                 brute_force_strategy++;
 4539             }
 4540         }
 4541 
 4542         else if (!strncmp(argv[i], "-", 1))
 4543         {
 4544             if (verbose > 0 && printed_version_info == 0)
 4545             {
 4546               print_version_info();
 4547               printed_version_info++;
 4548             }
 4549             fprintf(STDERR, "\n  Ignoring invalid option: %s\n",
 4550                     argv[i]);
 4551         } /* GRR:  end of giant if-else block */
 4552     } /* end of loop over args ============================================ */
 4553 
 4554     if (verbose > 0 && printed_version_info == 0)
 4555         print_version_info();
 4556 
 4557     if (default_compression_window == 32)
 4558         default_compression_window = 15;
 4559     else if (default_compression_window == 16)
 4560         default_compression_window = 14;
 4561     else if (default_compression_window == 8)
 4562         default_compression_window = 13;
 4563     else if (default_compression_window == 4)
 4564         default_compression_window = 12;
 4565     else if (default_compression_window == 2)
 4566         default_compression_window = 11;
 4567     else if (default_compression_window == 1)
 4568         default_compression_window = 10;
 4569     else if (default_compression_window == 512)
 4570         default_compression_window = 9;
 4571     /* Use of compression window size 256 is not recommended. */
 4572     else if (default_compression_window == 256)
 4573         default_compression_window = 8;
 4574     else if (default_compression_window == 0)
 4575         /* do nothing */;
 4576     else if (default_compression_window != 15) {
 4577         fprintf(STDERR, "Invalid window size (%d); using window size=4\n",
 4578                 default_compression_window);
 4579         default_compression_window = 12;
 4580     }
 4581 
 4582     if (pngcrush_mode == DEFAULT_MODE)
 4583     {
 4584         if (argc - names == 2)
 4585         {
 4586             inname = argv[names];
 4587             outname = argv[names + 1];
 4588         }
 4589 
 4590         else if (overwrite)
 4591         {
 4592             inname = argv[names];
 4593         }
 4594 
 4595         else
 4596         {
 4597             if ((argc - names == 1 || nosave))
 4598             {
 4599                 inname = argv[names];
 4600             }
 4601             if (verbose > 0 && !nosave)
 4602             {
 4603                 print_usage(1);   /* this exits */
 4604             }
 4605         }
 4606     }
 4607 
 4608     first_name = names;
 4609 
 4610     if (benchmark_iterations)
 4611         bench=1;
 4612     else
 4613         bench=0;
 4614     
 4615     for (; bench <= benchmark_iterations; bench++)
 4616     {
 4617         if (benchmark_iterations > 0)
 4618         {
 4619             P1("  Pngcrush benchmark iteration %d\n",bench);
 4620             names = first_name;
 4621         }
 4622 
 4623 #if PNGCRUSH_TIMERS > 0
 4624         for (pc_timer = 0; pc_timer < PNGCRUSH_TIMERS; pc_timer++)
 4625         {
 4626             pngcrush_timer_reset(pc_timer);
 4627             filter_count[pc_timer]=0;
 4628         }
 4629         pngcrush_timer_start(PNGCRUSH_TIMER_TOTAL);
 4630         pngcrush_timer_start(PNGCRUSH_TIMER_MISC);
 4631 #endif
 4632 
 4633     for (ia = 0; ia < 256; ia++)
 4634         trns_array[ia]=255;
 4635 
 4636     for (;;)  /* loop on input files */
 4637     {
 4638         methods_enabled = 0;
 4639         last_trial = 0;
 4640 
 4641         if (png_row_filters != NULL)
 4642         {
 4643             free(png_row_filters);
 4644             png_row_filters = NULL;
 4645         }
 4646 
 4647         image_specified_gamma = 0;
 4648         intent=specified_intent;
 4649         
 4650         inname = argv[names++];
 4651 
 4652         if (inname == NULL)
 4653         {
 4654 #if PNGCRUSH_TIMERS > 0
 4655             pngcrush_timer_stop(PNGCRUSH_TIMER_MISC);
 4656             pngcrush_timer_stop(PNGCRUSH_TIMER_TOTAL);
 4657 #endif
 4658             if (verbose >= 0)
 4659             {
 4660                 show_result();
 4661             }
 4662             break;
 4663         }
 4664 
 4665         if (pngcrush_mode == DIRECTORY_MODE || pngcrush_mode == DIREX_MODE) {
 4666             int inlen, outlen;
 4667 #ifndef __riscos
 4668             struct stat stat_buf;
 4669             if (stat(directory_name, &stat_buf))
 4670 #else
 4671             if (fileexists(directory_name) & 2)
 4672 #endif
 4673             {
 4674 #if defined(_MBCS) || defined(WIN32) || defined(__WIN32__)
 4675                 if (_mkdir(directory_name))
 4676 #else
 4677                 if (mkdir(directory_name, 0755))
 4678 #endif
 4679                 {
 4680                     fprintf(STDERR,
 4681                       "pngcrush: could not create directory %s\n",
 4682                       directory_name);
 4683                     exit(1);
 4684                 }
 4685                 nofilecheck = 1;
 4686             }
 4687             outlen = strlen(directory_name);
 4688             if (outlen >= STR_BUF_SIZE-1)
 4689             {
 4690                 fprintf(STDERR,
 4691                   "pngcrush: directory %s is too long for buffer\n",
 4692                   directory_name);
 4693                 exit(1);
 4694             }
 4695 
 4696             strcpy(out_string, directory_name);
 4697             /* Append a slash if it hasn't already got one at the end. */
 4698             if (out_string[outlen-1] != SLASH[0] &&
 4699                 out_string[outlen-1] != FWD_SLASH[0] &&
 4700                 out_string[outlen-1] != BACK_SLASH[0])
 4701               out_string[outlen++] = SLASH[0];   /* (assume SLASH is 1 byte) */
 4702             out_string[outlen] = '\0';
 4703 
 4704             inlen = strlen(inname);
 4705             if (inlen >= STR_BUF_SIZE)
 4706             {
 4707                 fprintf(STDERR,
 4708                    "pngcrush: filename %s is too long for buffer\n", inname);
 4709                 exit(1);
 4710             }
 4711             strcpy(in_string, inname);
 4712             in_string[inlen] = '\0';
 4713 #ifdef __riscos
 4714             op = strrchr(in_string, '.');
 4715             if (!op)
 4716                 op = in_string;
 4717             else
 4718                 op++;
 4719 #else
 4720             op = in_string;
 4721             ip = in_string + inlen - 1;   /* start at last char in string */
 4722             while (ip > in_string)
 4723             {
 4724                 if (*ip == '\\' || *ip == '/')
 4725                 {
 4726                     op = ip + 1;
 4727                     break;
 4728                 }
 4729                 --ip;
 4730             }
 4731 #endif
 4732 
 4733             if (outlen + (inlen - (op - in_string)) >= STR_BUF_SIZE)
 4734             {
 4735                 fprintf(STDERR,
 4736                    "pngcrush: full path is too long for buffer\n");
 4737                 exit(1);
 4738             }
 4739             strcpy(out_string+outlen, op);
 4740             /*outlen += inlen - (op - in_string); */
 4741             outname = out_string;
 4742         }
 4743 
 4744         if (overwrite && (pngcrush_mode == EXTENSION_MODE ||
 4745             pngcrush_mode == DIRECTORY_MODE ||
 4746             pngcrush_mode == DIREX_MODE))
 4747         {
 4748             if (overwrite > 0)
 4749             {
 4750                P1( "Ignoring \"-ow\"; cannot use it with \"-d\" or \"-e\"");
 4751                overwrite=0;
 4752             }
 4753         }
 4754 
 4755         /*
 4756          * FIXME:  need same input-validation fixes (as above) here, too
 4757          *
 4758          * FIXME:  what was the point of setting in_string and out_string in
 4759          *         DIREX_MODE above if going to do all over again here?
 4760          */
 4761         if (pngcrush_mode == EXTENSION_MODE || pngcrush_mode == DIREX_MODE)
 4762         {
 4763             ip = in_string;
 4764             in_string[0] = '\0';
 4765             if (pngcrush_mode == EXTENSION_MODE)
 4766                 strncat(in_string, inname, STR_BUF_SIZE-1);
 4767             else
 4768                 strncat(in_string, outname, STR_BUF_SIZE-1);
 4769             ip = in_string;
 4770             op = dot = out_string;
 4771             while (*ip != '\0')
 4772             {
 4773                 *op++ = *ip++;
 4774 #ifdef __riscos
 4775                 if (*ip == '/')
 4776                     dot = op;
 4777 #else
 4778                 if (*ip == '.')
 4779                     dot = op;
 4780 #endif
 4781             }
 4782             *op = '\0';
 4783 
 4784             if (dot != out_string)
 4785                 *dot = '\0';
 4786 
 4787             in_extension[0] = '\0';
 4788             if (dot != out_string)
 4789             {
 4790                 strncat(in_extension, ++dot, STR_BUF_SIZE - 1);
 4791             }
 4792 
 4793             strncat(out_string, extension, STR_BUF_SIZE - 1);
 4794             outname = out_string;
 4795         }
 4796 
 4797         if ((outname[strlen(outname) - 4] == 'p') &&
 4798             (outname[strlen(outname) - 3] == 'p') &&
 4799             (outname[strlen(outname) - 2] == 'n') &&
 4800             (outname[strlen(outname) - 1] == 'g'))
 4801         {
 4802            /* Writing a *.ppng (png with premultiplied alpha) */
 4803             premultiply=2;
 4804 #ifndef PNG_READ_PREMULTIPLY_ALPHA_SUPPORTED
 4805             png_error(read_ptr, "Premultiplied alpha is not supported");
 4806 #endif
 4807         }
 4808 
 4809         if ((outname[strlen(outname) - 4] == 'a') &&
 4810             (outname[strlen(outname) - 3] == 'p') &&
 4811             (outname[strlen(outname) - 2] == 'n') &&
 4812             (outname[strlen(outname) - 1] == 'g'))
 4813         {
 4814            /* Writing an APNG */
 4815            save_apng_chunks=1;
 4816         }
 4817 
 4818         if (nosave < 2)
 4819         {
 4820             P1( "Opening file %s for length measurement\n",
 4821                        inname);
 4822 
 4823             if ((fpin = FOPEN(inname, "rb")) == NULL)
 4824             {
 4825                 fprintf(STDERR, "Could not find file: %s\n", inname);
 4826                 continue;
 4827             }
 4828             number_of_open_files++;
 4829 
 4830 #ifdef PNGCRUSH_LOCO
 4831             if (new_mng)
 4832             {
 4833 
 4834 #  ifdef PNG_USER_MEM_SUPPORTED
 4835                if (verbose > 0)
 4836                   mng_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING,
 4837                     (png_voidp) NULL, (png_error_ptr) pngcrush_cexcept_error,
 4838                     (png_error_ptr) pngcrush_warning, (png_voidp) NULL, 
 4839                     (png_malloc_ptr) pngcrush_debug_malloc,
 4840                     (png_free_ptr) pngcrush_debug_free);
 4841                else
 4842 #  endif
 4843                   mng_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
 4844                     (png_voidp) NULL,
 4845                     (png_error_ptr) pngcrush_cexcept_error,
 4846                     (png_error_ptr) pngcrush_warning);
 4847                if (mng_ptr == NULL)
 4848                   fprintf(STDERR, "pngcrush could not create mng_ptr");
 4849 
 4850                if ((mng_out = FOPEN(mngname, "wb")) == NULL)
 4851                {
 4852                   fprintf(STDERR,
 4853                       "pngcrush: could not open output file %s\n",
 4854                       mngname);
 4855                   FCLOSE(fpin);
 4856                   exit(1);
 4857                }
 4858                number_of_open_files++;
 4859                png_init_io(mng_ptr, mng_out);
 4860                png_set_write_fn(mng_ptr, (png_voidp) mng_out,
 4861                                 (png_rw_ptr) pngcrush_write_png,
 4862                                 pngcrush_flush);
 4863             }
 4864 #endif /* PNGCRUSH_LOCO */
 4865 
 4866             idat_length[0] = measure_idats(fpin);
 4867 
 4868 #ifdef PNGCRUSH_LOCO
 4869             if (new_mng)
 4870             {
 4871                     png_destroy_write_struct(&mng_ptr, NULL);
 4872                     FCLOSE(mng_out);
 4873             }
 4874 #endif
 4875 
 4876             FCLOSE(fpin);
 4877 
 4878 
 4879             if (verbose >= 0 && bench < 2)
 4880             {
 4881                 if (nosave)
 4882                 {
 4883                   fprintf(STDERR, "  %s:\n", inname);
 4884                 }
 4885                 else if (overwrite)
 4886                 {
 4887                   fprintf(STDERR,
 4888                     "  Recompressing IDAT chunks in %s\n", inname);
 4889                 }
 4890                 else
 4891                 {
 4892                   fprintf(STDERR,
 4893                     "  Recompressing IDAT chunks in %s to %s\n",
 4894                     inname, outname);
 4895                 }
 4896                 fprintf(STDERR,
 4897                   "   Total length of data found in critical chunks        "
 4898                   "    =%10lu\n", (unsigned long)idat_length[0]);
 4899                 fflush(STDERR);
 4900             }
 4901 
 4902             if (idat_length[0] == 0)
 4903                 continue;
 4904 
 4905         }
 4906 
 4907         else
 4908             idat_length[0] = 1;
 4909 
 4910         if (image_is_immutable)
 4911         {
 4912             fprintf(STDERR,
 4913               "   Image %s has a dSIG chunk and is immutable.\n", inname);
 4914         }
 4915 
 4916         if (!image_is_immutable)
 4917         {
 4918 
 4919         if (force_output_color_type != 8 &&
 4920             force_output_color_type != 0 &&
 4921             force_output_color_type != 2 &&
 4922             force_output_color_type != 3 &&
 4923             force_output_color_type != 4 &&
 4924             force_output_color_type != 6)
 4925         {
 4926             fprintf(STDERR, "\n  Ignoring invalid color_type: %d\n",
 4927               force_output_color_type);
 4928             force_output_color_type=8;
 4929         }
 4930         output_color_type = force_output_color_type;
 4931 
 4932         output_bit_depth = force_output_bit_depth;
 4933 
 4934         best_of_three = 1;
 4935         pngcrush_best_byte_count=0xffffffff;
 4936 
 4937         if (blacken == 1 || make_gray == 1 || make_opaque == 1 ||
 4938             reduce_palette == 1)
 4939         {
 4940            try_method[0] = 0;
 4941         }
 4942 
 4943         /*
 4944          * From the PNG spec, various dependencies among chunk types
 4945          *   must be accounted for during any reduction of color type
 4946          *   or bit depth:
 4947          *
 4948          * IHDR valid bit depth depends on color type
 4949          *   valid filter type depends on color type (for MNG extensions)
 4950          * tRNS depends on color type
 4951          *   depends on num_palette for color type 3 (palette)
 4952          * iCCP valid profile depends on color type
 4953          * sBIT depends on color type and bit depth
 4954          * bKGD depends on color type and bit depth
 4955          * hIST depends on num_palette
 4956          *
 4957          * Chunk types present have been detected in the first pass over
 4958          *   the file, in the measure_idat() function.
 4959          */
 4960 
 4961         if (make_gray)
 4962         {
 4963            if ((found_iCCP && keep_unknown_chunk("iCCP", argv)) ||
 4964                (found_color_bKGD && keep_unknown_chunk("bKGD", argv)) ||
 4965                found_acTL_chunk == 1 ||
 4966                (found_sBIT_different_RGB_bits &&
 4967                keep_unknown_chunk("sBIT", argv)))
 4968            {
 4969               P1 ("Cannot change colortype to gray when iCCP,"
 4970                   " acTL, bKGD with color, or sBIT chunk is present\n");
 4971               make_gray = 0;
 4972            }
 4973            else
 4974            {
 4975               make_gray = 1;
 4976               try_method[0] = 0;
 4977            }
 4978         }
 4979 
 4980         if (make_opaque)
 4981         {
 4982            if (found_tRNS || found_acTL_chunk == 1)
 4983            {
 4984              P1("Cannot remove the alpha channel when tRNS"
 4985                   " or acTL chunk is present\n");
 4986              make_opaque = 0;
 4987            }
 4988            else
 4989            {
 4990              make_opaque = 1;
 4991              try_method[0] = 0;
 4992            }
 4993         }
 4994 
 4995         if (make_8_bit)
 4996         {
 4997            if ((found_bKGD && keep_unknown_chunk("bKGD", argv)) ||
 4998               found_acTL_chunk == 1 ||
 4999               (found_sBIT_max > 8 && keep_unknown_chunk("sBIT", argv)))
 5000            {
 5001               P1 ("Cannot reduce bit depth to 8 when bKGD,"
 5002                   " sBIT or acTL chunk is present\n");
 5003               make_8_bit = 0;
 5004            }
 5005            else
 5006            {
 5007              make_8_bit = 1;
 5008              try_method[0] = 0;
 5009            }
 5010         }
 5011 
 5012         if (input_color_type == 3 && reduce_palette)
 5013         {
 5014            if ((found_hIST && keep_unknown_chunk("hIST", argv)) ||
 5015               found_acTL_chunk == 1)
 5016            {
 5017              P1("Cannot reduce palette length when hIST"
 5018                  " or acTL chunk is present\n");
 5019              reduce_palette = 0;
 5020              plte_len = -1;
 5021            }
 5022            else
 5023            {
 5024              try_method[0] = 0;
 5025              plte_len = 0;
 5026            }
 5027         }
 5028 
 5029         /* Handle specified brute_force options */
 5030         if (brute_force_level || brute_force_filter || brute_force_strategy)
 5031         {
 5032            for (method = 1; method < num_methods; method++)
 5033            {
 5034              int option;
 5035 
 5036              try_method[method]=1;
 5037              if (brute_force_level)
 5038              {
 5039                 for (option = 0; option < 10; option++)
 5040                    if (option == lv[method])
 5041                       try_method[method]=brute_force_levels[option];
 5042              }
 5043 
 5044              if ((try_method[method] == 0) && brute_force_filter)
 5045              {
 5046                 for (option = 0; option < 6; option++)
 5047                    if (option == fm[method])
 5048                       try_method[method]=brute_force_filters[option];
 5049              }
 5050 
 5051              if ((try_method[method] == 0) && brute_force_strategy)
 5052              {
 5053                 for (option = 0; option < NUM_STRATEGIES; option++)
 5054                    if (option == zs[method])
 5055                       try_method[method]=brute_force_strategies[option];
 5056              }
 5057 
 5058              if (method && method < 11)
 5059                 try_method[method] = 1;
 5060            }
 5061 
 5062            if (speed)
 5063            {
 5064              /* Do not try AVG or PAETH */
 5065              for (method = 1; method < num_methods; method++)
 5066              {
 5067                if (try_method[method] == 0 && (fm[method] == 3 ||
 5068                    fm[method] == 4 || fm[method] == 5))
 5069                      try_method[method] = 1;
 5070              }
 5071            }
 5072          }
 5073 
 5074         if (methods_specified == 0 || try10 != 0)
 5075         {
 5076             for (i = 0; i <= DEFAULT_METHODS; i++)
 5077                 try_method[i] = 0;
 5078 
 5079             try_method[6] = try10;
 5080         }
 5081 
 5082         for (i = 1; i <= MAX_METHODS; i++)
 5083         {
 5084            methods_enabled += (1 - try_method[i]);
 5085         }
 5086         P1("%d methods enabled\n",methods_enabled);
 5087 /* Skip trial 0 when a single method was specified and -reduce was not */
 5088         if (methods_specified != 0 && noreduce != 0)
 5089         {
 5090           if (methods_enabled == 1)
 5091           {
 5092              try_method[0] = 1;
 5093              make_opaque = 0;
 5094              make_gray = 0;
 5095              make_8_bit = 0;
 5096              reduce_palette = 0;
 5097           }
 5098         }
 5099 
 5100         last_method = 0;
 5101         for (i = 1; i <= MAX_METHODS; i++)
 5102         {
 5103            if (try_method[i] == 0)
 5104               last_method = i;
 5105         }
 5106 
 5107         if (methods_enabled > 1)
 5108            last_method++;
 5109 
 5110         P1("   pngcrush: methods     = %d\n",methods_enabled);
 5111         P1("   pngcrush: last_method = %d\n",last_method);
 5112         
 5113         if (methods_enabled == 1 && last_method == 176)
 5114            copy_idat = 1;
 5115 
 5116         best_of_three = 1;
 5117 
 5118 #ifndef __riscos
 5119         {
 5120             /* COVERITY complains about TOCTOU when inname is used later */
 5121             struct stat stat_buf;
 5122             stat(inname, &stat_buf);
 5123             input_length = (unsigned long) stat_buf.st_size;
 5124         }
 5125 #else
 5126         input_length = (unsigned long) filesize(inname);
 5127 #endif
 5128 
 5129         /* ////////////////////////////////////////////////////////////////////
 5130         ////////////////                                   ////////////////////
 5131         ////////////////  START OF MAIN LOOP OVER METHODS  ////////////////////
 5132         ////////////////                                   ////////////////////
 5133         //////////////////////////////////////////////////////////////////// */
 5134 
 5135         /* MAX_METHODS is 177 */
 5136         P1("\n\nENTERING MAIN LOOP OVER %d METHODS\n", MAX_METHODS);
 5137         for (trial = 0; trial <= last_method; trial++)
 5138         {
 5139             if (nosave || trial == last_method)
 5140                last_trial = 1;
 5141 
 5142             if (verbose > 1)
 5143             fprintf(STDERR, "pngcrush: trial = %d\n",trial);
 5144 
 5145             pngcrush_write_byte_count=0;
 5146 #ifdef PNGCRUSH_H
 5147 # if ZLIB_VERNUM > 0x1240
 5148             if (last_trial == 0)
 5149                pngcrush_write_byte_count=6; /* zlib header that isn't written */
 5150 # endif
 5151 #endif
 5152 
 5153             found_IDAT = 0;
 5154 
 5155             if (trial != 0)
 5156                idat_length[trial] = (png_uint_32) 0xffffffff;
 5157 
 5158             /* this part of if-block is for final write-the-best-file
 5159                iteration */
 5160             if (trial == last_method)
 5161             {
 5162                 png_uint_32 best_length;
 5163 
 5164                 if (methods_enabled == 1)
 5165                 {
 5166                    best = trial;
 5167                    best_length = idat_length[trial];
 5168                 }
 5169                 else
 5170                 {
 5171                    int j;
 5172 
 5173                    /* check lengths */
 5174                    best = 0;  /* i.e., input file */
 5175                    best_length = (png_uint_32) 0xffffffff;
 5176                    for (j = 0; j <= last_method; j++)
 5177                    {
 5178                        if (best == 0 && best_length == idat_length[j])
 5179                        {
 5180                            /* If no change, report the first match */
 5181                            best = j;
 5182                        }
 5183                        if ((force == 0 || j != 0) &&
 5184                             best_length > idat_length[j])
 5185                        {
 5186                            best_length = idat_length[j];
 5187                            best = j;
 5188                        }
 5189                        if (j > 148 && j < 176 && best_length == idat_length[j])
 5190                        {
 5191                            /* break ties in favor of method 6 */
 5192                            best = j;
 5193                        }
 5194                    }
 5195                 }
 5196 
 5197                 if (image_is_immutable ||
 5198                      (idat_length[best] == idat_length[0] &&
 5199                      force == 0 && nosave == 0))
 5200                 {
 5201                     /* just copy input to output */
 5202 
 5203                     P2("prepare to copy input to output\n");
 5204                     pngcrush_pause();
 5205 
 5206                     if ((fpin = FOPEN(inname, "rb")) == NULL)
 5207                     {
 5208                         fprintf(STDERR, "Could not find input file %s\n",
 5209                                 inname);
 5210                         continue;
 5211                     }
 5212 
 5213                     number_of_open_files++;
 5214                     if ((fpout = FOPEN(outname, "wb")) == NULL)
 5215                     {
 5216                         fprintf(STDERR,
 5217                            "pngcrush: could not open output file %s\n",
 5218                            outname);
 5219                         FCLOSE(fpin);
 5220                         exit(1);
 5221                     }
 5222 
 5223                     number_of_open_files++;
 5224                     P2("copying input to output...");
 5225 
 5226                     for (;;)
 5227                     {
 5228                         png_size_t num_in, num_out;
 5229 
 5230                         num_in = fread((void *)buffer, 1, 1, fpin);
 5231                         if (!num_in)
 5232                             break;
 5233                         num_out = fwrite(buffer, 1, 1, fpout);
 5234                         if (num_out != num_in)
 5235                             P2("copy error.\n");
 5236                     }
 5237                     P2("copy complete.\n");
 5238                     pngcrush_pause();
 5239                     FCLOSE(fpin);
 5240                     FCLOSE(fpout);
 5241                     setfiletype(outname);
 5242                     break;
 5243                 }
 5244 
 5245                 filter_type = fm[best];
 5246                 zlib_level = lv[best];
 5247                 if (zs[best] == 1)
 5248                     z_strategy = Z_FILTERED;
 5249                 else if (zs[best] == 2)
 5250                     z_strategy = Z_HUFFMAN_ONLY;
 5251 #ifdef Z_RLE
 5252                 else if (zs[best] == 3)
 5253                     z_strategy = Z_RLE;
 5254 #endif
 5255                 else /* if (zs[best] == 0) */
 5256                     z_strategy = Z_DEFAULT_STRATEGY;
 5257             }
 5258 
 5259             else /* Trial < last_method */
 5260             {
 5261                 if (trial > 2 && trial < 5 && idat_length[trial - 1]
 5262                     < idat_length[best_of_three])
 5263                     best_of_three = trial - 1;
 5264 
 5265                 if (try_method[trial])
 5266                 {
 5267                     P2("skipping \"late\" trial %d\n", trial);
 5268                     continue;
 5269                 }
 5270 
 5271                 /* default behavior is to do the heuristics (6 of the first
 5272                  * 10 methods). try10 means try all of 1-10.
 5273                  */
 5274                 if (!methods_specified && try10 == 0)
 5275                 {
 5276                     if ((trial == 4 || trial == 7) && best_of_three != 1)
 5277                     {
 5278                         P2("skipping \"early\" trial %d\n", trial);
 5279                         continue;
 5280                     }
 5281                     if ((trial == 5 || trial == 8) && best_of_three != 2)
 5282                     {
 5283                         P2("skipping \"early\" trial %d\n", trial);
 5284                         continue;
 5285                     }
 5286                     if ((trial == 6 || trial == 9 || trial == 10)
 5287                         && best_of_three != 3)
 5288                     {
 5289                         P2("skipping \"early\" trial %d\n", trial);
 5290                         continue;
 5291                     }
 5292                 }
 5293                 filter_type = fm[trial];
 5294                 zlib_level = lv[trial];
 5295                 if (zs[trial] == 1)
 5296                     z_strategy = Z_FILTERED;
 5297                 else if (zs[trial] == 2)
 5298                     z_strategy = Z_HUFFMAN_ONLY;
 5299 #ifdef Z_RLE
 5300                 else if (zs[trial] == 3)
 5301                     z_strategy = Z_RLE;
 5302 #endif
 5303                 else /* if (zs[trial] == 0) */
 5304                     z_strategy = Z_DEFAULT_STRATEGY;
 5305                 final_method = trial;
 5306                 if (!nosave)
 5307                 {
 5308                     P2("\n\n------------------------------------------------\n"
 5309                        "Begin trial %d, filter %d, strategy %d, level %d\n",
 5310                        trial, filter_type, z_strategy, zlib_level);
 5311                 }
 5312             }
 5313 
 5314             P2("prepare to open files.\n");
 5315             pngcrush_pause();
 5316 
 5317             if ((fpin = FOPEN(inname, "rb")) == NULL)
 5318             {
 5319                 fprintf(STDERR, "Could not find input file %s\n", inname);
 5320                 continue;
 5321             }
 5322             number_of_open_files++;
 5323 
 5324             if (last_trial && nosave == 0)
 5325             {
 5326 #ifndef __riscos
 5327                 /* Can't sensibly check this on RISC OS without opening a file
 5328                    for update or output
 5329                  */
 5330                 struct stat stat_in, stat_out;
 5331                 if (last_trial && !nofilecheck
 5332                     && (stat(inname, &stat_in) == 0)
 5333                     && (stat(outname, &stat_out) == 0) &&
 5334 #if defined(_MSC_VER) || defined(__MINGW32__)   /* maybe others? */
 5335                     /* MSVC++6.0 will erroneously return 0 for both files, so
 5336                        we simply check the size instead.  It is possible that
 5337                        we will erroneously reject the attempt when inputsize
 5338                        and outputsize are equal, for different files
 5339                      */
 5340                     (stat_in.st_size == stat_out.st_size) &&
 5341 #else
 5342                     (stat_in.st_ino == stat_out.st_ino) &&
 5343 #endif
 5344                     (stat_in.st_dev == stat_out.st_dev))
 5345                 {
 5346                     fprintf(STDERR,
 5347                             "\n   pngcrush: cannot overwrite input file %s\n",
 5348                             outname);
 5349                     P1("   st_ino=%d, st_size=%d\n\n",
 5350                        (int) stat_in.st_ino, (int) stat_in.st_size);
 5351                     FCLOSE(fpin);
 5352                     exit(1);
 5353                 }
 5354 #endif
 5355                 if ((fpout = FOPEN(outname, "wb")) == NULL)
 5356                 {
 5357                     fprintf(STDERR,
 5358                             "pngcrush: could not open output file %s\n",
 5359                             outname);
 5360                     FCLOSE(fpin);
 5361                     exit(1);
 5362                 }
 5363 
 5364                 number_of_open_files++;
 5365             }
 5366 
 5367             P2("files are opened.\n");
 5368             pngcrush_pause();
 5369 
 5370 /* OK to ignore any warning about the address of exception__prev in "Try" */
 5371             Try {
 5372                 png_uint_32 row_length;
 5373                 P1( "Allocating read and write structures\n");
 5374 #ifdef PNG_USER_MEM_SUPPORTED
 5375                 if (verbose > 0)
 5376                    read_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING,
 5377                      (png_voidp) NULL,
 5378                      (png_error_ptr) pngcrush_cexcept_error,
 5379                      (png_error_ptr) pngcrush_warning,
 5380                      (png_voidp) NULL,
 5381                      (png_malloc_ptr) pngcrush_debug_malloc,
 5382                      (png_free_ptr) pngcrush_debug_free);
 5383                 else
 5384 #endif /* PNG_USER_MEM_SUPPORTED */
 5385                    read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
 5386                      (png_voidp) NULL,
 5387                      (png_error_ptr) pngcrush_cexcept_error,
 5388                      (png_error_ptr) pngcrush_warning);
 5389                 if (read_ptr == NULL)
 5390                     Throw "pngcrush could not create read_ptr";
 5391 
 5392 #ifdef PNG_BENIGN_ERRORS_SUPPORTED
 5393 # if PNGCRUSH_LIBPNG_VER >= 10400
 5394                 /* Allow certain errors in the input file to be handled
 5395                  * as warnings.
 5396                  */
 5397                 png_set_benign_errors(read_ptr, 1);
 5398 # endif
 5399 #endif
 5400 
 5401 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
 5402                 if (no_limits == 0)
 5403                 {
 5404 # if PNGCRUSH_LIBPNG_VER >= 10400
 5405                    png_set_user_limits(read_ptr, 500000L, 500000L);
 5406                    png_set_chunk_cache_max(read_ptr, 500);
 5407 # endif
 5408 # if PNGCRUSH_LIBPNG_VER >= 10401
 5409                    png_set_chunk_malloc_max(read_ptr, 2000000L);
 5410 # endif
 5411                 }
 5412 #endif /* PNG_SET_USER_LIMITS_SUPPORTED */
 5413 
 5414 #if defined(PNG_MAXIMUM_INFLATE_WINDOW) && defined(PNG_OPTION_ON)
 5415                 if (salvage)
 5416                 {
 5417                    P1(" Setting MAXIMUM_INFLATE_WINDOW\n");
 5418                    png_set_option(read_ptr, PNG_MAXIMUM_INFLATE_WINDOW,
 5419                        PNG_OPTION_ON);
 5420                 }
 5421 #endif
 5422 
 5423 #if 0
 5424                 /* Use a smaller decompression buffer for speed */
 5425                 png_set_compression_buffer_size(read_ptr,
 5426                     (png_size_t)256);
 5427 #endif /* 0 */
 5428 
 5429     /* Change the underlying color of any fully transparent pixel to black.
 5430      * Remove the alpha channel from any fully-opaque image.
 5431      * Change any all-gray image to a gray colortype.
 5432      * Reduce 16-bit image to 8-bit if possible without loss.
 5433      */
 5434     if (trial == 0 &&
 5435         (blacken == 1 || make_gray == 1 || make_opaque == 1 ||
 5436         make_8_bit == 1 || reduce_palette == 1))
 5437     {
 5438       P1(" Examine image for possible lossless reductions\n");
 5439       png_set_read_user_transform_fn(read_ptr, pngcrush_examine_pixels_fn);
 5440     }
 5441 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
 5442                 if (last_trial == 0)
 5443                 {
 5444                    png_set_keep_unknown_chunks(read_ptr,
 5445                         PNG_HANDLE_CHUNK_NEVER, (png_bytep) NULL, 0);
 5446 
 5447                    png_set_keep_unknown_chunks(read_ptr,
 5448                         PNG_HANDLE_CHUNK_NEVER, chunks_to_ignore,
 5449                         sizeof (chunks_to_ignore)/5);
 5450                 }
 5451 #endif
 5452 
 5453                 if (nosave == 0)
 5454                 {
 5455 #ifdef PNG_USER_MEM_SUPPORTED
 5456                    if (verbose > 0)
 5457                        write_ptr = png_create_write_struct_2(
 5458                          PNG_LIBPNG_VER_STRING,
 5459                          (png_voidp) NULL,
 5460                          (</