Imported Upstream version 1.6.39
[platform/upstream/libpng.git] / contrib / tools / pngcp.c
1 /* pngcp.c
2  *
3  * Copyright (c) 2016,2022 John Cunningham Bowler
4  *
5  * This code is released under the libpng license.
6  * For conditions of distribution and use, see the disclaimer
7  * and license in png.h
8  *
9  * This is an example of copying a PNG without changes using the png_read_png
10  * and png_write_png interfaces.  A considerable number of options are provided
11  * to manipulate the compression of the PNG data and other compressed chunks.
12  *
13  * For a more extensive example that uses the transforms see
14  * contrib/libtests/pngimage.c in the libpng distribution.
15  *
16  * This code is not intended for installation in a release system; the command
17  * line options are not documented and most of the behavior is intended for
18  * testing libpng performance, both speed and compression.
19  */
20
21 #include "pnglibconf.h" /* To find how libpng was configured. */
22
23 #ifdef PNG_PNGCP_TIMING_SUPPORTED
24    /* WARNING:
25     *
26     * This test is here to allow POSIX.1b extensions to be used if enabled in
27     * the compile; specifically the code requires_POSIX_C_SOURCE support of
28     * 199309L or later to enable clock_gettime use.
29     *
30     * IF this causes problems THEN compile with a strict ANSI C compiler and let
31     * this code turn on the POSIX features that it minimally requires.
32     *
33     * IF this does not work there is probably a bug in your ANSI C compiler or
34     * your POSIX implementation.
35     */
36 #  define _POSIX_C_SOURCE 199309L
37 #else /* No timing support required */
38 #  define _POSIX_SOURCE 1
39 #endif
40
41 #if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
42 #  include <config.h>
43 #endif
44
45 #include <stdio.h>
46
47 /* Define the following to use this test against your installed libpng, rather
48  * than the one being built here:
49  */
50 #ifdef PNG_FREESTANDING_TESTS
51 #  include <png.h>
52 #else
53 #  include "../../png.h"
54 #endif
55
56 #if PNG_LIBPNG_VER < 10700
57    /* READ_PNG and WRITE_PNG were not defined, so: */
58 #  ifdef PNG_INFO_IMAGE_SUPPORTED
59 #     ifdef PNG_SEQUENTIAL_READ_SUPPORTED
60 #        define PNG_READ_PNG_SUPPORTED
61 #     endif /* SEQUENTIAL_READ */
62 #     ifdef PNG_WRITE_SUPPORTED
63 #        define PNG_WRITE_PNG_SUPPORTED
64 #     endif /* WRITE */
65 #  endif /* INFO_IMAGE */
66 #endif /* pre 1.7.0 */
67
68 #if (defined(PNG_READ_PNG_SUPPORTED)) && (defined(PNG_WRITE_PNG_SUPPORTED))
69 #include <stdarg.h>
70 #include <stdlib.h>
71 #include <string.h>
72 #include <errno.h>
73 #include <limits.h>
74 #include <assert.h>
75
76 #include <unistd.h>
77 #include <sys/stat.h>
78
79 #include <zlib.h>
80
81 #ifndef PNG_SETJMP_SUPPORTED
82 #  include <setjmp.h> /* because png.h did *not* include this */
83 #endif
84
85 #ifdef __cplusplus
86 #  define voidcast(type, value) static_cast<type>(value)
87 #else
88 #  define voidcast(type, value) (value)
89 #endif /* __cplusplus */
90
91 #ifdef __GNUC__
92    /* Many versions of GCC erroneously report that local variables unmodified
93     * within the scope of a setjmp may be clobbered.  This hacks round the
94     * problem (sometimes) without harming other compilers.
95     */
96 #  define gv volatile
97 #else
98 #  define gv
99 #endif
100
101 /* 'CLOCK_PROCESS_CPUTIME_ID' is one of the clock timers for clock_gettime.  It
102  * need not be supported even when clock_gettime is available.  It returns the
103  * 'CPU' time the process has consumed.  'CPU' time is assumed to include time
104  * when the CPU is actually blocked by a pending cache fill but not time
105  * waiting for page faults.  The attempt is to get a measure of the actual time
106  * the implementation takes to read a PNG ignoring the potentially very large IO
107  * overhead.
108  */
109 #ifdef PNG_PNGCP_TIMING_SUPPORTED
110 #  include <time.h>   /* clock_gettime and associated definitions */
111 #  ifndef CLOCK_PROCESS_CPUTIME_ID
112       /* Prevent inclusion of the spurious code: */
113 #     undef PNG_PNGCP_TIMING_SUPPORTED
114 #  endif
115 #endif /* PNGCP_TIMING */
116
117 /* So if the timing feature has been activated: */
118
119 /* This structure is used to control the test of a single file. */
120 typedef enum
121 {
122    VERBOSE,        /* switches on all messages */
123    INFORMATION,
124    WARNINGS,       /* switches on warnings */
125    LIBPNG_WARNING,
126    APP_WARNING,
127    ERRORS,         /* just errors */
128    APP_FAIL,       /* continuable error - no need to longjmp */
129    LIBPNG_ERROR,   /* this and higher cause a longjmp */
130    LIBPNG_BUG,     /* erroneous behavior in libpng */
131    APP_ERROR,      /* such as out-of-memory in a callback */
132    QUIET,          /* no normal messages */
133    USER_ERROR,     /* such as file-not-found */
134    INTERNAL_ERROR
135 } error_level;
136 #define LEVEL_MASK      0xf   /* where the level is in 'options' */
137
138 #define STRICT          0x010 /* Fail on warnings as well as errors */
139 #define LOG             0x020 /* Log pass/fail to stdout */
140 #define CONTINUE        0x040 /* Continue on APP_FAIL errors */
141 #define SIZES           0x080 /* Report input and output sizes */
142 #define SEARCH          0x100 /* Search IDAT compression options */
143 #define NOWRITE         0x200 /* Do not write an output file */
144 #ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
145 #  define IGNORE_INDEX  0x400 /* Ignore out of range palette indices (BAD!) */
146 #  ifdef PNG_GET_PALETTE_MAX_SUPPORTED
147 #     define FIX_INDEX  0x800 /* 'Fix' out of range palette indices (OK) */
148 #  endif /* GET_PALETTE_MAX */
149 #endif /* CHECK_FOR_INVALID_INDEX */
150 #define OPTION     0x80000000 /* Used for handling options */
151 #define LIST       0x80000001 /* Used for handling options */
152
153 /* Result masks apply to the result bits in the 'results' field below; these
154  * bits are simple 1U<<error_level.  A pass requires either nothing worse than
155  * warnings (--relaxes) or nothing worse than information (--strict)
156  */
157 #define RESULT_STRICT(r)   (((r) & ~((1U<<WARNINGS)-1)) == 0)
158 #define RESULT_RELAXED(r)  (((r) & ~((1U<<ERRORS)-1)) == 0)
159
160 /* OPTION DEFINITIONS */
161 static const char range_lo[] = "low";
162 static const char range_hi[] = "high";
163 static const char all[] = "all";
164 #define RANGE(lo,hi) { range_lo, lo }, { range_hi, hi }
165 typedef struct value_list
166 {
167    const char *name;  /* the command line name of the value */
168    int         value; /* the actual value to use */
169 }  value_list;
170
171 static const value_list
172 #ifdef PNG_SW_COMPRESS_png_level
173 vl_compression[] =
174 {
175    /* Overall compression control.  The order controls the search order for
176     * 'all'.  Since the search is for the smallest the order used is low memory
177     * then high speed.
178     */
179    { "low-memory",      PNG_COMPRESSION_LOW_MEMORY },
180    { "high-speed",      PNG_COMPRESSION_HIGH_SPEED },
181    { "high-read-speed", PNG_COMPRESSION_HIGH_READ_SPEED },
182    { "low",             PNG_COMPRESSION_LOW },
183    { "medium",          PNG_COMPRESSION_MEDIUM },
184    { "old",             PNG_COMPRESSION_COMPAT },
185    { "high",            PNG_COMPRESSION_HIGH },
186    { all, 0 }
187 },
188 #endif /* SW_COMPRESS_png_level */
189
190 #if defined(PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED) ||\
191     defined(PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED)
192 vl_strategy[] =
193 {
194    /* This controls the order of search. */
195    { "huffman", Z_HUFFMAN_ONLY },
196    { "RLE", Z_RLE },
197    { "fixed", Z_FIXED }, /* the remainder do window searches */
198    { "filtered", Z_FILTERED },
199    { "default", Z_DEFAULT_STRATEGY },
200    { all, 0 }
201 },
202 #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
203 vl_windowBits_text[] =
204 {
205    { "default", MAX_WBITS/*from zlib*/ },
206    { "minimum", 8 },
207    RANGE(8, MAX_WBITS/*from zlib*/),
208    { all, 0 }
209 },
210 #endif /* text compression */
211 vl_level[] =
212 {
213    { "default", Z_DEFAULT_COMPRESSION /* this is -1 */ },
214    { "none", Z_NO_COMPRESSION },
215    { "speed", Z_BEST_SPEED },
216    { "best", Z_BEST_COMPRESSION },
217    { "0", Z_NO_COMPRESSION },
218    RANGE(1, 9), /* this deliberately excludes '0' */
219    { all, 0 }
220 },
221 vl_memLevel[] =
222 {
223    { "max", MAX_MEM_LEVEL }, /* zlib maximum */
224    { "1", 1 }, /* zlib minimum */
225    { "default", 8 }, /* zlib default */
226    { "2", 2 },
227    { "3", 3 },
228    { "4", 4 },
229    { "5", 5 }, /* for explicit testing */
230    RANGE(6, MAX_MEM_LEVEL/*zlib*/), /* exclude 5 and below: zlib bugs */
231    { all, 0 }
232 },
233 #endif /* WRITE_CUSTOMIZE_*COMPRESSION */
234 #ifdef PNG_WRITE_FILTER_SUPPORTED
235 vl_filter[] =
236 {
237    { all,      PNG_ALL_FILTERS   },
238    { "off",    PNG_NO_FILTERS    },
239    { "none",   PNG_FILTER_NONE   },
240    { "sub",    PNG_FILTER_SUB    },
241    { "up",     PNG_FILTER_UP     },
242    { "avg",    PNG_FILTER_AVG    },
243    { "paeth",  PNG_FILTER_PAETH  }
244 },
245 #endif /* WRITE_FILTER */
246 #ifdef PNG_PNGCP_TIMING_SUPPORTED
247 #  define PNGCP_TIME_READ  1
248 #  define PNGCP_TIME_WRITE 2
249 vl_time[] =
250 {
251    { "both",  PNGCP_TIME_READ+PNGCP_TIME_WRITE },
252    { "off",   0 },
253    { "read",  PNGCP_TIME_READ },
254    { "write", PNGCP_TIME_WRITE }
255 },
256 #endif /* PNGCP_TIMING */
257 vl_IDAT_size[] = /* for png_set_IDAT_size */
258 {
259    { "default", 0x7FFFFFFF },
260    { "minimal", 1 },
261    RANGE(1, 0x7FFFFFFF)
262 },
263 #ifndef PNG_SW_IDAT_size
264    /* Pre 1.7 API: */
265 #  define png_set_IDAT_size(p,v) png_set_compression_buffer_size(p, v)
266 #endif /* !SW_IDAT_size */
267 #define SL 8 /* stack limit in display, below */
268 vl_log_depth[] = { { "on", 1 }, { "off", 0 }, RANGE(0, SL) },
269 vl_on_off[] = { { "on", 1 }, { "off", 0 } };
270
271 #ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
272 static value_list
273 vl_windowBits_IDAT[] =
274 {
275    { "default", MAX_WBITS },
276    { "small", 9 },
277    RANGE(8, MAX_WBITS), /* modified by set_windowBits_hi */
278    { all, 0 }
279 };
280 #endif /* IDAT compression */
281
282 typedef struct option
283 {
284    const char       *name;         /* name of the option */
285    png_uint_32       opt;          /* an option, or OPTION or LIST */
286    png_byte          search;       /* Search on --search */
287    png_byte          value_count;  /* length of the list of values: */
288    const value_list *values;       /* values for OPTION or LIST */
289 }  option;
290
291 static const option options[] =
292 {
293    /* struct display options, these are set when the command line is read */
294 #  define S(n,v) { #n, v, 0, 2, vl_on_off },
295    S(verbose,  VERBOSE)
296    S(warnings, WARNINGS)
297    S(errors,   ERRORS)
298    S(quiet,    QUIET)
299    S(strict,   STRICT)
300    S(log,      LOG)
301    S(continue, CONTINUE)
302    S(sizes,    SIZES)
303    S(search,   SEARCH)
304    S(nowrite,  NOWRITE)
305 #  ifdef IGNORE_INDEX
306       S(ignore-palette-index, IGNORE_INDEX)
307 #  endif /* IGNORE_INDEX */
308 #  ifdef FIX_INDEX
309       S(fix-palette-index, FIX_INDEX)
310 #  endif /* FIX_INDEX */
311 #  undef S
312
313    /* OPTION settings, these and LIST settings are read on demand */
314 #  define VLNAME(name) vl_ ## name
315 #  define VLSIZE(name) voidcast(png_byte,\
316                            (sizeof VLNAME(name))/(sizeof VLNAME(name)[0]))
317 #  define VL(oname, name, type, search)\
318    { oname, type, search, VLSIZE(name), VLNAME(name) },
319 #  define VLO(oname, name, search) VL(oname, name, OPTION, search)
320
321 #  ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
322 #     define VLCIDAT(name) VLO(#name, name, 1/*search*/)
323 #     ifdef PNG_SW_COMPRESS_level
324 #        define VLCiCCP(name) VLO("ICC-profile-" #name, name, 0/*search*/)
325 #     else
326 #        define VLCiCCP(name)
327 #     endif
328 #  else
329 #     define VLCIDAT(name)
330 #     define VLCiCCP(name)
331 #  endif /* WRITE_CUSTOMIZE_COMPRESSION */
332
333 #  ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
334 #     define VLCzTXt(name) VLO("text-" #name, name, 0/*search*/)
335 #  else
336 #     define VLCzTXt(name)
337 #  endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
338
339 #  define VLC(name) VLCIDAT(name) VLCiCCP(name) VLCzTXt(name)
340
341 #  ifdef PNG_SW_COMPRESS_png_level
342       /* The libpng compression level isn't searched because it just sets the
343        * other things that are searched!
344        */
345       VLO("compression", compression, 0)
346       VLO("text-compression", compression, 0)
347       VLO("ICC-profile-compression", compression, 0)
348 #  endif /* SW_COMPRESS_png_level */
349    VLC(strategy)
350    VLO("windowBits", windowBits_IDAT, 1)
351 #  ifdef PNG_SW_COMPRESS_windowBits
352       VLO("ICC-profile-windowBits", windowBits_text/*sic*/, 0)
353 #  endif
354    VLO("text-windowBits", windowBits_text, 0)
355    VLC(level)
356    VLC(memLevel)
357    VLO("IDAT-size", IDAT_size, 0)
358    VLO("log-depth", log_depth, 0)
359
360 #  undef VLO
361
362    /* LIST settings */
363 #  define VLL(name, search) VL(#name, name, LIST, search)
364 #ifdef PNG_WRITE_FILTER_SUPPORTED
365    VLL(filter, 0)
366 #endif /* WRITE_FILTER */
367 #ifdef PNG_PNGCP_TIMING_SUPPORTED
368    VLL(time, 0)
369 #endif /* PNGCP_TIMING */
370 #  undef VLL
371 #  undef VL
372 };
373
374 #ifdef __cplusplus
375    static const size_t option_count((sizeof options)/(sizeof options[0]));
376 #else /* !__cplusplus */
377 #  define option_count ((sizeof options)/(sizeof options[0]))
378 #endif /* !__cplusplus */
379
380 static const char *
381 cts(int ct)
382 {
383    switch (ct)
384    {
385       case PNG_COLOR_TYPE_PALETTE:     return "P";
386       case PNG_COLOR_TYPE_GRAY:        return "G";
387       case PNG_COLOR_TYPE_GRAY_ALPHA:  return "GA";
388       case PNG_COLOR_TYPE_RGB:         return "RGB";
389       case PNG_COLOR_TYPE_RGB_ALPHA:   return "RGBA";
390       default:                         return "INVALID";
391    }
392 }
393
394 struct display
395 {
396    jmp_buf          error_return;      /* Where to go to on error */
397    unsigned int     errset;            /* error_return is set */
398
399    const char      *operation;         /* What is happening */
400    const char      *filename;          /* The name of the original file */
401    const char      *output_file;       /* The name of the output file */
402
403    /* Used on both read and write: */
404    FILE            *fp;
405
406    /* Used on a read, both the original read and when validating a written
407     * image.
408     */
409    png_alloc_size_t read_size;
410    png_structp      read_pp;
411    png_infop        ip;
412 #  if PNG_LIBPNG_VER < 10700 && defined PNG_TEXT_SUPPORTED
413       png_textp     text_ptr; /* stash of text chunks */
414       int           num_text;
415       int           text_stashed;
416 #  endif /* pre 1.7 */
417
418 #  ifdef PNG_PNGCP_TIMING_SUPPORTED
419       struct timespec   read_time;
420       struct timespec   read_time_total;
421       struct timespec   write_time;
422       struct timespec   write_time_total;
423 #  endif /* PNGCP_TIMING */
424
425    /* Used to write a new image (the original info_ptr is used) */
426 #  define MAX_SIZE ((png_alloc_size_t)(-1))
427    png_alloc_size_t write_size;
428    png_alloc_size_t best_size;
429    png_structp      write_pp;
430
431    /* Base file information */
432    png_alloc_size_t size;
433    png_uint_32      w;
434    png_uint_32      h;
435    int              bpp;
436    png_byte         ct;
437    int              no_warnings;       /* Do not output libpng warnings */
438    int              min_windowBits;    /* The windowBits range is 8..8 */
439
440    /* Options handling */
441    png_uint_32      results;             /* A mask of errors seen */
442    png_uint_32      options;             /* See display_log below */
443    png_byte         entry[option_count]; /* The selected entry+1 of an option
444                                           * that appears on the command line, or
445                                           * 0 if it was not given. */
446    int              value[option_count]; /* Corresponding value */
447
448    /* Compression exhaustive testing */
449    /* Temporary variables used only while testing a single collection of
450     * settings:
451     */
452    unsigned int     csp;               /* next stack entry to use */
453    unsigned int     nsp;               /* highest active entry+1 found so far */
454
455    /* Values used while iterating through all the combinations of settings for a
456     * single file:
457     */
458    unsigned int     tsp;               /* nsp from the last run; this is the
459                                         * index+1 of the highest active entry on
460                                         * this run; this entry will be advanced.
461                                         */
462    int              opt_string_start;  /* Position in buffer for the first
463                                         * searched option; non-zero if earlier
464                                         * options were set on the command line.
465                                         */
466    struct stack
467    {
468       png_alloc_size_t best_size;      /* Best so far for this option */
469       png_alloc_size_t lo_size;
470       png_alloc_size_t hi_size;
471       int              lo, hi;         /* For binary chop of a range */
472       int              best_val;       /* Best value found so far */
473       int              opt_string_end; /* End of the option string in 'curr' */
474       png_byte         opt;            /* The option being tested */
475       png_byte         entry;          /* The next value entry to be tested */
476       png_byte         end;            /* This is the last entry */
477    }                stack[SL];         /* Stack of entries being tested */
478    char             curr[32*SL];       /* current options being tested */
479    char             best[32*SL];       /* best options */
480
481    char             namebuf[FILENAME_MAX]; /* output file name */
482 };
483
484 static void
485 display_init(struct display *dp)
486    /* Call this only once right at the start to initialize the control
487     * structure, the (struct buffer) lists are maintained across calls - the
488     * memory is not freed.
489     */
490 {
491    memset(dp, 0, sizeof *dp);
492    dp->operation = "internal error";
493    dp->filename = "command line";
494    dp->output_file = "no output file";
495    dp->options = WARNINGS; /* default to !verbose, !quiet */
496    dp->fp = NULL;
497    dp->read_pp = NULL;
498    dp->ip = NULL;
499    dp->write_pp = NULL;
500    dp->min_windowBits = -1; /* this is an OPTIND, so -1 won't match anything */
501 #  if PNG_LIBPNG_VER < 10700 && defined PNG_TEXT_SUPPORTED
502       dp->text_ptr = NULL;
503       dp->num_text = 0;
504       dp->text_stashed = 0;
505 #  endif /* pre 1.7 */
506 }
507
508 static void
509 display_clean_read(struct display *dp, int freeinfo)
510 {
511    if (dp->read_pp != NULL)
512       png_destroy_read_struct(&dp->read_pp, freeinfo ? &dp->ip : NULL, NULL);
513
514    if (dp->fp != NULL)
515    {
516       FILE *fp = dp->fp;
517       dp->fp = NULL;
518       (void)fclose(fp);
519    }
520 }
521
522 static void
523 display_clean_write(struct display *dp, int freeinfo)
524 {
525    if (dp->fp != NULL)
526    {
527       FILE *fp = dp->fp;
528       dp->fp = NULL;
529       (void)fclose(fp);
530    }
531
532    if (dp->write_pp != NULL)
533       png_destroy_write_struct(&dp->write_pp, freeinfo ? &dp->ip : NULL);
534 }
535
536 static void
537 display_clean(struct display *dp)
538 {
539    display_clean_read(dp, 1/*freeinfo*/);
540    display_clean_write(dp, 1/*freeinfo*/);
541    dp->output_file = NULL;
542
543 #  if PNG_LIBPNG_VER < 10700 && defined PNG_TEXT_SUPPORTED
544       /* This is actually created and used by the write code, but only
545        * once; it has to be retained for subsequent writes of the same file.
546        */
547       if (dp->text_stashed)
548       {
549          dp->text_stashed = 0;
550          dp->num_text = 0;
551          free(dp->text_ptr);
552          dp->text_ptr = NULL;
553       }
554 #  endif /* pre 1.7 */
555
556    /* leave the filename for error detection */
557    dp->results = 0; /* reset for next time */
558 }
559
560 static void
561 display_destroy(struct display *dp)
562 {
563    /* Release any memory held in the display. */
564    display_clean(dp);
565 }
566
567 static struct display *
568 get_dp(png_structp pp)
569    /* The display pointer is always stored in the png_struct error pointer */
570 {
571    struct display *dp = (struct display*)png_get_error_ptr(pp);
572
573    if (dp == NULL)
574    {
575       fprintf(stderr, "pngcp: internal error (no display)\n");
576       exit(99); /* prevents a crash */
577    }
578
579    return dp;
580 }
581
582 /* error handling */
583 #ifdef __GNUC__
584 #  define VGATTR __attribute__((__format__ (__printf__,3,4)))
585    /* Required to quiet GNUC warnings when the compiler sees a stdarg function
586     * that calls one of the stdio v APIs.
587     */
588 #else
589 #  define VGATTR
590 #endif
591 static void VGATTR
592 display_log(struct display *dp, error_level level, const char *fmt, ...)
593    /* 'level' is as above, fmt is a stdio style format string.  This routine
594     * does not return if level is above LIBPNG_WARNING
595     */
596 {
597    dp->results |= 1U << level;
598
599    if (level > (error_level)(dp->options & LEVEL_MASK))
600    {
601       const char *lp;
602       va_list ap;
603
604       switch (level)
605       {
606          case INFORMATION:    lp = "information"; break;
607          case LIBPNG_WARNING: lp = "warning(libpng)"; break;
608          case APP_WARNING:    lp = "warning(pngcp)"; break;
609          case APP_FAIL:       lp = "error(continuable)"; break;
610          case LIBPNG_ERROR:   lp = "error(libpng)"; break;
611          case LIBPNG_BUG:     lp = "bug(libpng)"; break;
612          case APP_ERROR:      lp = "error(pngcp)"; break;
613          case USER_ERROR:     lp = "error(user)"; break;
614
615          case INTERNAL_ERROR: /* anything unexpected is an internal error: */
616          case VERBOSE: case WARNINGS: case ERRORS: case QUIET:
617          default:             lp = "bug(pngcp)"; break;
618       }
619
620       fprintf(stderr, "%s: %s: %s",
621          dp->filename != NULL ? dp->filename : "<stdin>", lp, dp->operation);
622
623       fprintf(stderr, ": ");
624
625       va_start(ap, fmt);
626       vfprintf(stderr, fmt, ap);
627       va_end(ap);
628
629       fputc('\n', stderr);
630    }
631    /* else do not output any message */
632
633    /* Errors cause this routine to exit to the fail code */
634    if (level > APP_FAIL || (level > ERRORS && !(dp->options & CONTINUE)))
635    {
636       if (dp->errset)
637          longjmp(dp->error_return, level);
638
639       else
640          exit(99);
641    }
642 }
643
644 #if PNG_LIBPNG_VER < 10700 && defined PNG_TEXT_SUPPORTED
645 static void
646 text_stash(struct display *dp)
647 {
648    /* libpng 1.6 and earlier fixed a bug whereby text chunks were written
649     * multiple times by png_write_png; the issue was that png_write_png passed
650     * the same png_info to both png_write_info and png_write_end.  Rather than
651     * fixing it by recording the information in the png_struct, or by recording
652     * where to write the chunks, the fix made was to change the 'compression'
653     * field of the chunk to invalid values, rendering the png_info somewhat
654     * useless.
655     *
656     * The only fix for this given that we use the png_info more than once is to
657     * make a copy of the text chunks and png_set_text it each time.  This adds a
658     * text chunks, so they get replicated, but only the new set gets written
659     * each time.  This uses memory like crazy but there is no way to delete the
660     * useless chunks from the png_info.
661     *
662     * To make this slightly more efficient only the top level structure is
663     * copied; since the old strings are actually preserved (in 1.6 and earlier)
664     * this happens to work.
665     */
666    png_textp chunks = NULL;
667
668    dp->num_text = png_get_text(dp->write_pp, dp->ip, &chunks, NULL);
669
670    if (dp->num_text > 0)
671    {
672       dp->text_ptr = voidcast(png_textp, malloc(dp->num_text * sizeof *chunks));
673
674       if (dp->text_ptr == NULL)
675          display_log(dp, APP_ERROR, "text chunks: stash malloc failed");
676
677       else
678          memcpy(dp->text_ptr, chunks, dp->num_text * sizeof *chunks);
679    }
680
681    dp->text_stashed = 1; /* regardless of whether there are chunks or not */
682 }
683
684 #define text_stash(dp) if (!dp->text_stashed) text_stash(dp)
685
686 static void
687 text_restore(struct display *dp)
688 {
689    /* libpng makes a copy, so this is fine: */
690    if (dp->text_ptr != NULL)
691       png_set_text(dp->write_pp, dp->ip, dp->text_ptr, dp->num_text);
692 }
693
694 #define text_restore(dp) if (dp->text_stashed) text_restore(dp)
695
696 #else
697 #define text_stash(dp) ((void)0)
698 #define text_restore(dp) ((void)0)
699 #endif /* pre 1.7 */
700
701 /* OPTIONS:
702  *
703  * The command handles options of the forms:
704  *
705  *    --option
706  *       Turn an option on (Option)
707  *    --no-option
708  *       Turn an option off (Option)
709  *    --option=value
710  *       Set an option to a value (Value)
711  *    --option=val1,val2,val3
712  *       Set an option to a bitmask constructed from the values (List)
713  */
714 static png_byte
715 option_index(struct display *dp, const char *opt, size_t len)
716    /* Return the index (in options[]) of the given option, outputs an error if
717     * it does not exist.  Takes the name of the option and a length (number of
718     * characters in the name).
719     */
720 {
721    png_byte j;
722
723    for (j=0; j<option_count; ++j)
724       if (strncmp(options[j].name, opt, len) == 0 && options[j].name[len] == 0)
725          return j;
726
727    /* If the setjmp buffer is set the code is asking for an option index; this
728     * is bad.  Otherwise this is the command line option parsing.
729     */
730    display_log(dp, dp->errset ? INTERNAL_ERROR : USER_ERROR,
731          "%.*s: unknown option", (int)/*SAFE*/len, opt);
732    abort(); /* NOT REACHED */
733 }
734
735 /* This works for an option name (no quotes): */
736 #define OPTIND(dp, name) option_index(dp, #name, (sizeof #name)-1)
737
738 static int
739 get_option(struct display *dp, const char *opt, int *value)
740 {
741    png_byte i = option_index(dp, opt, strlen(opt));
742
743    if (dp->entry[i]) /* option was set on command line */
744    {
745       *value = dp->value[i];
746       return 1;
747    }
748
749    else
750       return 0;
751 }
752
753 static int
754 set_opt_string_(struct display *dp, unsigned int sp, png_byte opt,
755       const char *entry_name)
756    /* Add the appropriate option string to dp->curr. */
757 {
758    int offset, add;
759
760    if (sp > 0)
761       offset = dp->stack[sp-1].opt_string_end;
762
763    else
764       offset = dp->opt_string_start;
765
766    if (entry_name == range_lo)
767       add = sprintf(dp->curr+offset, " --%s=%d", options[opt].name,
768             dp->value[opt]);
769
770    else
771       add = sprintf(dp->curr+offset, " --%s=%s", options[opt].name, entry_name);
772
773    if (add < 0)
774       display_log(dp, INTERNAL_ERROR, "sprintf failed");
775
776    assert(offset+add < (int)/*SAFE*/sizeof dp->curr);
777    return offset+add;
778 }
779
780 static void
781 set_opt_string(struct display *dp, unsigned int sp)
782    /* Add the appropriate option string to dp->curr. */
783 {
784    dp->stack[sp].opt_string_end = set_opt_string_(dp, sp, dp->stack[sp].opt,
785       options[dp->stack[sp].opt].values[dp->stack[sp].entry].name);
786 }
787
788 static void
789 record_opt(struct display *dp, png_byte opt, const char *entry_name)
790    /* Record this option in dp->curr; called for an option not being searched,
791     * the caller passes in the name of the value, or range_lo to use the
792     * numerical value.
793     */
794 {
795    unsigned int sp = dp->csp; /* stack entry of next searched option */
796
797    if (sp >= dp->tsp)
798    {
799       /* At top of stack; add the opt string for this entry to the previous
800        * searched entry or the start of the dp->curr buffer if there is nothing
801        * on the stack yet (sp == 0).
802        */
803       int offset = set_opt_string_(dp, sp, opt, entry_name);
804
805       if (sp > 0)
806          dp->stack[sp-1].opt_string_end = offset;
807
808       else
809          dp->opt_string_start = offset;
810    }
811
812    /* else do nothing: option already recorded */
813 }
814
815 static int
816 opt_list_end(struct display *dp, png_byte opt, png_byte entry)
817 {
818    if (options[opt].values[entry].name == range_lo)
819       return entry+1U >= options[opt].value_count /* missing range_hi */ ||
820          options[opt].values[entry+1U].name != range_hi /* likewise */ ||
821          options[opt].values[entry+1U].value <= dp->value[opt] /* range end */;
822
823    else
824       return entry+1U >= options[opt].value_count /* missing 'all' */ ||
825          options[opt].values[entry+1U].name == all /* last entry */;
826 }
827
828 static void
829 push_opt(struct display *dp, unsigned int sp, png_byte opt, int search)
830    /* Push a new option onto the stack, initializing the new stack entry
831     * appropriately; this does all the work of next_opt (setting end/nsp) for
832     * the first entry in the list.
833     */
834 {
835    png_byte entry;
836    const char *entry_name;
837
838    assert(sp == dp->tsp && sp < SL);
839
840    /* The starting entry is entry 0 unless there is a range in which case it is
841     * the entry corresponding to range_lo:
842     */
843    entry = options[opt].value_count;
844    assert(entry > 0U);
845
846    do
847    {
848       entry_name = options[opt].values[--entry].name;
849       if (entry_name == range_lo)
850          break;
851    }
852    while (entry > 0U);
853
854    dp->tsp = sp+1U;
855    dp->stack[sp].best_size =
856       dp->stack[sp].lo_size =
857       dp->stack[sp].hi_size = MAX_SIZE;
858
859    if (search && entry_name == range_lo) /* search this range */
860    {
861       dp->stack[sp].lo = options[opt].values[entry].value;
862       /* check for a mal-formed RANGE above: */
863       assert(entry+1 < options[opt].value_count &&
864              options[opt].values[entry+1].name == range_hi);
865       dp->stack[sp].hi = options[opt].values[entry+1].value;
866    }
867
868    else
869    {
870       /* next_opt will just iterate over the range. */
871       dp->stack[sp].lo = INT_MAX;
872       dp->stack[sp].hi = INT_MIN; /* Prevent range chop */
873    }
874
875    dp->stack[sp].opt = opt;
876    dp->stack[sp].entry = entry;
877    dp->stack[sp].best_val = dp->value[opt] = options[opt].values[entry].value;
878
879    set_opt_string(dp, sp);
880
881    /* This works for the search case too; if the range has only one entry 'end'
882     * will be marked here.
883     */
884    if (opt_list_end(dp, opt, entry))
885    {
886       dp->stack[sp].end = 1;
887       /* Skip the warning if pngcp did this itself.  See the code in
888        * set_windowBits_hi.
889        */
890       if (opt != dp->min_windowBits)
891          display_log(dp, APP_WARNING, "%s: only testing one value",
892                options[opt].name);
893    }
894
895    else
896    {
897       dp->stack[sp].end = 0;
898       dp->nsp = dp->tsp;
899    }
900
901    /* Do a lazy cache of the text chunks for libpng 1.6 and earlier; this is
902     * because they can only be written once(!) so if we are going to re-use the
903     * png_info we need a copy.
904     */
905    text_stash(dp);
906 }
907
908 static void
909 next_opt(struct display *dp, unsigned int sp)
910    /* Return the next value for this option.  When called 'sp' is expected to be
911     * the topmost stack entry - only the topmost entry changes each time round -
912     * and there must be a valid entry to return.  next_opt will set dp->nsp to
913     * sp+1 if more entries are available, otherwise it will not change it and
914     * set dp->stack[s].end to true.
915     */
916 {
917    int search = 0;
918    png_byte entry, opt;
919    const char *entry_name;
920
921    /* dp->stack[sp] must be the top stack entry and it must be active: */
922    assert(sp+1U == dp->tsp && !dp->stack[sp].end);
923
924    opt = dp->stack[sp].opt;
925    entry = dp->stack[sp].entry;
926    assert(entry+1U < options[opt].value_count);
927    entry_name = options[opt].values[entry].name;
928    assert(entry_name != NULL);
929
930    /* For ranges increment the value but don't change the entry, for all other
931     * cases move to the next entry and load its value:
932     */
933    if (entry_name == range_lo) /* a range */
934    {
935       /* A range can be iterated over or searched.  The default iteration option
936        * is indicated by hi < lo on the stack, otherwise the range being search
937        * is [lo..hi] (inclusive).
938        */
939       if (dp->stack[sp].lo > dp->stack[sp].hi)
940          dp->value[opt]++;
941
942       else
943       {
944          /* This is the best size found for this option value: */
945          png_alloc_size_t best_size = dp->stack[sp].best_size;
946          int lo = dp->stack[sp].lo;
947          int hi = dp->stack[sp].hi;
948          int val = dp->value[opt];
949
950          search = 1; /* end is determined here */
951          assert(best_size < MAX_SIZE);
952
953          if (val == lo)
954          {
955             /* Finding the best for the low end of the range: */
956             dp->stack[sp].lo_size = best_size;
957             assert(hi > val);
958
959             if (hi == val+1) /* only 2 entries */
960                dp->stack[sp].end = 1;
961
962             val = hi;
963          }
964
965          else if (val == hi)
966          {
967             dp->stack[sp].hi_size = best_size;
968             assert(val > lo+1); /* else 'end' set above */
969
970             if (val == lo+2) /* only three entries to test */
971                dp->stack[sp].end = 1;
972
973             val = (lo + val)/2;
974          }
975
976          else
977          {
978             png_alloc_size_t lo_size = dp->stack[sp].lo_size;
979             png_alloc_size_t hi_size = dp->stack[sp].hi_size;
980
981             /* lo and hi should have been tested. */
982             assert(lo_size < MAX_SIZE && hi_size < MAX_SIZE);
983
984             /* These cases arise with the 'probe' handling below when there is a
985              * dip or peak in the size curve.
986              */
987             if (val < lo) /* probing a new lo */
988             {
989                /* Swap lo and val: */
990                dp->stack[sp].lo = val;
991                dp->stack[sp].lo_size = best_size;
992                val = lo;
993                best_size = lo_size;
994                lo = dp->stack[sp].lo;
995                lo_size = dp->stack[sp].lo_size;
996             }
997
998             else if (val > hi) /* probing a new hi */
999             {
1000                /* Swap hi and val: */
1001                dp->stack[sp].hi = val;
1002                dp->stack[sp].hi_size = best_size;
1003                val = hi;
1004                best_size = hi_size;
1005                hi = dp->stack[sp].hi;
1006                hi_size = dp->stack[sp].hi_size;
1007             }
1008
1009             /* The following should be true or something got messed up above. */
1010             assert(lo < val && val < hi);
1011
1012             /* If there are only four entries (lo, val, hi plus one more) just
1013              * test the remaining entry.
1014              */
1015             if (hi == lo+3)
1016             {
1017                /* Because of the 'probe' code val can either be lo+1 or hi-1; we
1018                 * need to test the other.
1019                 */
1020                val = lo + ((val == lo+1) ? 2 : 1);
1021                assert(lo < val && val < hi);
1022                dp->stack[sp].end = 1;
1023             }
1024
1025             else
1026             {
1027                /* There are at least 2 entries still untested between lo and hi,
1028                 * i.e. hi >= lo+4.  'val' is the midpoint +/- 0.5
1029                 *
1030                 * Separate out the four easy cases when lo..val..hi are
1031                 * monotonically decreased or (more weird) increasing:
1032                 */
1033                assert(hi > lo+3);
1034
1035                if (lo_size <= best_size && best_size <= hi_size)
1036                {
1037                   /* Select the low range; testing this first favours the low
1038                    * range over the high range when everything comes out equal.
1039                    * Because of the probing 'val' may be lo+1.  In that case end
1040                    * the search and set 'val' to lo+2.
1041                    */
1042                   if (val == lo+1)
1043                   {
1044                      ++val;
1045                      dp->stack[sp].end = 1;
1046                   }
1047
1048                   else
1049                   {
1050                      dp->stack[sp].hi = hi = val;
1051                      dp->stack[sp].hi_size = best_size;
1052                      val = (lo + val) / 2;
1053                   }
1054                }
1055
1056                else if (lo_size >= best_size && best_size >= hi_size)
1057                {
1058                   /* Monotonically decreasing size; this is the expected case.
1059                    * Select the high end of the range.  As above, val may be
1060                    * hi-1.
1061                    */
1062                   if (val == hi-1)
1063                   {
1064                      --val;
1065                      dp->stack[sp].end = 1;
1066                   }
1067
1068                   else
1069                   {
1070                      dp->stack[sp].lo = lo = val;
1071                      dp->stack[sp].lo_size = best_size;
1072                      val = (val + hi) / 2;
1073                   }
1074                }
1075
1076                /* If both those tests failed 'best_size' is either greater than
1077                 * or less than both lo_size and hi_size.  There is a peak or dip
1078                 * in the curve of sizes from lo to hi and val is on the peak or
1079                 * dip.
1080                 *
1081                 * Because the ranges being searched as so small (level is 1..9,
1082                 * windowBits 8..15, memLevel 1..9) there will only be at most
1083                 * three untested values between lo..val and val..hi, so solve
1084                 * the problem by probing down from hi or up from lo, whichever
1085                 * is the higher.
1086                 *
1087                 * This is the place where 'val' is set to outside the range
1088                 * lo..hi, described as 'probing', though maybe 'narrowing' would
1089                 * be more accurate.
1090                 */
1091                else if (lo_size <= hi_size) /* down from hi */
1092                {
1093                   dp->stack[sp].hi = val;
1094                   dp->stack[sp].hi_size = best_size;
1095                   val = --hi;
1096                }
1097
1098                else /* up from low */
1099                {
1100                   dp->stack[sp].lo = val;
1101                   dp->stack[sp].lo_size = best_size;
1102                   val = ++lo;
1103                }
1104
1105                /* lo and hi are still the true range limits, check for the end
1106                 * condition.
1107                 */
1108                assert(hi > lo+1);
1109                if (hi <= lo+2)
1110                   dp->stack[sp].end = 1;
1111             }
1112          }
1113
1114          assert(val != dp->stack[sp].best_val); /* should be a new value */
1115          dp->value[opt] = val;
1116          dp->stack[sp].best_size = MAX_SIZE;
1117       }
1118    }
1119
1120    else
1121    {
1122       /* Increment 'entry' */
1123       dp->value[opt] = options[opt].values[++entry].value;
1124       dp->stack[sp].entry = entry;
1125    }
1126
1127    set_opt_string(dp, sp);
1128
1129    if (!search && opt_list_end(dp, opt, entry)) /* end of list */
1130       dp->stack[sp].end = 1;
1131
1132    else if (!dp->stack[sp].end) /* still active after all these tests */
1133       dp->nsp = dp->tsp;
1134 }
1135
1136 static int
1137 compare_option(const struct display *dp, unsigned int sp)
1138 {
1139    int opt = dp->stack[sp].opt;
1140
1141    /* If the best so far is numerically less than the current value the
1142     * current set of options is invariably worse.
1143     */
1144    if (dp->stack[sp].best_val < dp->value[opt])
1145       return -1;
1146
1147    /* Lists of options are searched out of numerical order (currently only
1148     * strategy), so only return +1 here when a range is being searched.
1149     */
1150    else if (dp->stack[sp].best_val > dp->value[opt])
1151    {
1152       if (dp->stack[sp].lo <= dp->stack[sp].hi /*searching*/)
1153          return 1;
1154
1155       else
1156          return -1;
1157    }
1158
1159    else
1160       return 0; /* match; current value is the best one */
1161 }
1162
1163 static int
1164 advance_opt(struct display *dp, png_byte opt, int search)
1165 {
1166    unsigned int sp = dp->csp++; /* my stack entry */
1167
1168    assert(sp >= dp->nsp); /* nsp starts off zero */
1169
1170    /* If the entry was active in the previous run dp->stack[sp] is already
1171     * set up and dp->tsp will be greater than sp, otherwise a new entry
1172     * needs to be created.
1173     *
1174     * dp->nsp is handled this way:
1175     *
1176     * 1) When an option is pushed onto the stack dp->nsp and dp->tsp are
1177     *    both set (by push_opt) to the next stack entry *unless* there is
1178     *    only one entry in the new list, in which case dp->stack[sp].end
1179     *    is set.
1180     *
1181     * 2) For the top stack entry next_opt is called.  The entry must be
1182     *    active (dp->stack[sp].end is not set) and either 'nsp' or 'end'
1183     *    will be updated as appropriate.
1184     *
1185     * 3) For lower stack entries nsp is set unless the stack entry is
1186     *    already at the end.  This means that when all the higher entries
1187     *    are popped this entry will be too.
1188     */
1189    if (sp >= dp->tsp)
1190    {
1191       push_opt(dp, sp, opt, search); /* This sets tsp to sp+1 */
1192       return 1; /* initialized */
1193    }
1194
1195    else
1196    {
1197       int ret = 0; /* unchanged */
1198
1199       /* An option that is already on the stack; update best_size and best_val
1200        * if appropriate.  On the first run there are no previous values and
1201        * dp->write_size will be MAX_SIZE, however on the first run dp->tsp
1202        * starts off as 0.
1203        */
1204       assert(dp->write_size > 0U && dp->write_size < MAX_SIZE);
1205
1206       if (dp->stack[sp].best_size > dp->write_size ||
1207           (dp->stack[sp].best_size == dp->write_size &&
1208            compare_option(dp, sp) > 0))
1209       {
1210          dp->stack[sp].best_size = dp->write_size;
1211          dp->stack[sp].best_val = dp->value[opt];
1212       }
1213
1214       if (sp+1U >= dp->tsp)
1215       {
1216          next_opt(dp, sp);
1217          ret = 1; /* advanced */
1218       }
1219
1220       else if (!dp->stack[sp].end) /* Active, not at top of stack */
1221          dp->nsp = sp+1U;
1222
1223       return ret; /* advanced || unchanged */
1224    }
1225 }
1226
1227 static int
1228 getallopts_(struct display *dp, png_byte opt, int *value, int record)
1229    /* Like getop but iterate over all the values if the option was set to "all".
1230     */
1231 {
1232    if (dp->entry[opt]) /* option was set on command line */
1233    {
1234       /* Simple, single value, entries don't have a stack frame and have a fixed
1235        * value (it doesn't change once set on the command line).  Otherwise the
1236        * value (entry) selected from the command line is 'all':
1237        */
1238       const char *entry_name = options[opt].values[dp->entry[opt]-1].name;
1239
1240       if (entry_name == all)
1241          (void)advance_opt(dp, opt, 0/*do not search; iterate*/);
1242
1243       else if (record)
1244          record_opt(dp, opt, entry_name);
1245
1246       *value = dp->value[opt];
1247       return 1; /* set */
1248    }
1249
1250    else
1251       return 0; /* not set */
1252 }
1253
1254 static int
1255 getallopts(struct display *dp, const char *opt_str, int *value)
1256 {
1257    return getallopts_(dp, option_index(dp, opt_str, strlen(opt_str)), value, 0);
1258 }
1259
1260 static int
1261 getsearchopts(struct display *dp, const char *opt_str, int *value)
1262    /* As above except that if the option was not set try a search */
1263 {
1264    png_byte istrat;
1265    png_byte opt = option_index(dp, opt_str, strlen(opt_str));
1266    int record = options[opt].search;
1267    const char *entry_name;
1268
1269    /* If it was set on the command line honour the setting, including 'all'
1270     * which will override the built in search:
1271     */
1272    if (getallopts_(dp, opt, value, record))
1273       return 1;
1274
1275    else if (!record) /* not a search option */
1276       return 0; /* unset and not searched */
1277
1278    /* Otherwise decide what to do here. */
1279    istrat = OPTIND(dp, strategy);
1280    entry_name = range_lo; /* record the value, not the name */
1281
1282    if (opt == istrat) /* search all strategies */
1283       (void)advance_opt(dp, opt, 0/*iterate*/), record=0;
1284
1285    else if (opt == OPTIND(dp, level))
1286    {
1287       /* Both RLE and HUFFMAN don't benefit from level increases */
1288       if (dp->value[istrat] == Z_RLE || dp->value[istrat] == Z_HUFFMAN_ONLY)
1289          dp->value[opt] = 1;
1290
1291       else /* fixed, filtered or default */
1292          (void)advance_opt(dp, opt, 1/*search*/), record=0;
1293    }
1294
1295    else if (opt == OPTIND(dp, windowBits))
1296    {
1297       /* Changing windowBits for strategies that do not search the window is
1298        * pointless.  Huffman-only does not search, RLE only searches backwards
1299        * one byte, so given that the maximum string length is 258, a windowBits
1300        * of 9 is always sufficient.
1301        */
1302       if (dp->value[istrat] == Z_HUFFMAN_ONLY)
1303          dp->value[opt] = 8;
1304
1305       else if (dp->value[istrat] == Z_RLE)
1306          dp->value[opt] = 9;
1307
1308       else /* fixed, filtered or default */
1309          (void)advance_opt(dp, opt, 1/*search*/), record=0;
1310    }
1311
1312    else if (opt == OPTIND(dp, memLevel))
1313    {
1314 #     if 0
1315          (void)advance_opt(dp, opt, 0/*all*/), record=0;
1316 #     else
1317          dp->value[opt] = MAX_MEM_LEVEL;
1318 #     endif
1319    }
1320
1321    else /* something else */
1322       assert(0=="reached");
1323
1324    if (record)
1325       record_opt(dp, opt, entry_name);
1326
1327    /* One of the above searched options: */
1328    *value = dp->value[opt];
1329    return 1;
1330 }
1331
1332 static int
1333 find_val(struct display *dp, png_byte opt, const char *str, size_t len)
1334    /* Like option_index but sets (index+i) of the entry in options[opt] that
1335     * matches str[0..len-1] into dp->entry[opt] as well as returning the actual
1336     * value.
1337     */
1338 {
1339    int rlo = INT_MAX, rhi = INT_MIN;
1340    png_byte j, irange = 0;
1341
1342    for (j=1U; j<=options[opt].value_count; ++j)
1343    {
1344       if (strncmp(options[opt].values[j-1U].name, str, len) == 0 &&
1345           options[opt].values[j-1U].name[len] == 0)
1346       {
1347          dp->entry[opt] = j;
1348          return options[opt].values[j-1U].value;
1349       }
1350       else if (options[opt].values[j-1U].name == range_lo)
1351          rlo = options[opt].values[j-1U].value, irange = j;
1352       else if (options[opt].values[j-1U].name == range_hi)
1353          rhi = options[opt].values[j-1U].value;
1354    }
1355
1356    /* No match on the name, but there may be a range. */
1357    if (irange > 0)
1358    {
1359       char *ep = NULL;
1360       long l = strtol(str, &ep, 0);
1361
1362       if (ep == str+len && l >= rlo && l <= rhi)
1363       {
1364          dp->entry[opt] = irange; /* range_lo */
1365          return (int)/*SAFE*/l;
1366       }
1367    }
1368
1369    display_log(dp, dp->errset ? INTERNAL_ERROR : USER_ERROR,
1370          "%s: unknown value setting '%.*s'", options[opt].name,
1371          (int)/*SAFE*/len, str);
1372    abort(); /* NOT REACHED */
1373 }
1374
1375 static int
1376 opt_check(struct display *dp, const char *arg)
1377 {
1378    assert(dp->errset == 0);
1379
1380    if (arg != NULL && arg[0] == '-' && arg[1] == '-')
1381    {
1382       int i = 0, negate = (strncmp(arg+2, "no-", 3) == 0), val;
1383       png_byte j;
1384
1385       if (negate)
1386          arg += 5; /* --no- */
1387
1388       else
1389          arg += 2; /* -- */
1390
1391       /* Find the length (expect arg\0 or arg=) */
1392       while (arg[i] != 0 && arg[i] != '=') ++i;
1393
1394       /* So arg[0..i-1] is the argument name, this does not return if this isn't
1395        * a valid option name.
1396        */
1397       j = option_index(dp, arg, i);
1398
1399       /* It matcheth an option; check the remainder. */
1400       if (arg[i] == 0) /* no specified value, use the default */
1401       {
1402          val = options[j].values[negate].value;
1403          dp->entry[j] = (png_byte)/*SAFE*/(negate + 1U);
1404       }
1405
1406       else
1407       {
1408          const char *list = arg + (i+1);
1409
1410          /* Expect a single value here unless this is a list, in which case
1411           * multiple values are combined.
1412           */
1413          if (options[j].opt != LIST)
1414          {
1415             /* find_val sets 'dp->entry[j]' to a non-zero value: */
1416             val = find_val(dp, j, list, strlen(list));
1417
1418             if (negate)
1419             {
1420                if (options[j].opt < OPTION)
1421                   val = !val;
1422
1423                else
1424                {
1425                   display_log(dp, USER_ERROR,
1426                         "%.*s: option=arg cannot be negated", i, arg);
1427                   abort(); /* NOT REACHED */
1428                }
1429             }
1430          }
1431
1432          else /* multiple options separated by ',' characters */
1433          {
1434             /* --no-option negates list values from the default, which should
1435              * therefore be 'all'.  Notice that if the option list is empty in
1436              * this case nothing will be removed and therefore --no-option= is
1437              * the same as --option.
1438              */
1439             if (negate)
1440                val = options[j].values[0].value;
1441
1442             else
1443                val = 0;
1444
1445             while (*list != 0) /* allows option= which sets 0 */
1446             {
1447                /* A value is terminated by the end of the list or a ','
1448                 * character.
1449                 */
1450                int v, iv;
1451
1452                iv = 0; /* an index into 'list' */
1453                while (list[++iv] != 0 && list[iv] != ',') {}
1454
1455                v = find_val(dp, j, list, iv);
1456
1457                if (negate)
1458                   val &= ~v;
1459
1460                else
1461                   val |= v;
1462
1463                list += iv;
1464                if (*list != 0)
1465                   ++list; /* skip the ',' */
1466             }
1467          }
1468       }
1469
1470       /* 'val' is the new value, store it for use later and debugging: */
1471       dp->value[j] = val;
1472
1473       if (options[j].opt < LEVEL_MASK)
1474       {
1475          /* The handling for error levels is to set the level. */
1476          if (val) /* Set this level */
1477             dp->options = (dp->options & ~LEVEL_MASK) | options[j].opt;
1478
1479          else
1480             display_log(dp, USER_ERROR,
1481       "%.*s: messages cannot be turned off individually; set a message level",
1482                   i, arg);
1483       }
1484
1485       else if (options[j].opt < OPTION)
1486       {
1487          if (val)
1488             dp->options |= options[j].opt;
1489
1490          else
1491             dp->options &= ~options[j].opt;
1492       }
1493
1494       return 1; /* this is an option */
1495    }
1496
1497    else
1498       return 0; /* not an option */
1499 }
1500
1501 #ifdef PNG_PNGCP_TIMING_SUPPORTED
1502 static void
1503 set_timer(struct display *dp, struct timespec *timer)
1504 {
1505    /* Do the timing using clock_gettime and the per-process timer. */
1506    if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, timer))
1507    {
1508       display_log(dp, APP_ERROR,
1509             "CLOCK_PROCESS_CPUTIME_ID: %s: timing disabled\n", strerror(errno));
1510       dp->value[OPTIND(dp,time)] = 0; /* i.e. off */
1511    }
1512 }
1513
1514 static void
1515 start_timer(struct display *dp, int what)
1516 {
1517    if ((dp->value[OPTIND(dp,time)] & what) != 0)
1518       set_timer(dp, what == PNGCP_TIME_READ ? &dp->read_time : &dp->write_time);
1519 }
1520
1521 static void
1522 end_timer(struct display *dp, int what)
1523 {
1524    if ((dp->value[OPTIND(dp,time)] & what) != 0)
1525    {
1526       struct timespec t, tmp;
1527
1528       set_timer(dp, &t);
1529
1530       if (what == PNGCP_TIME_READ)
1531          tmp = dp->read_time;
1532
1533       else
1534          tmp = dp->write_time;
1535
1536       t.tv_sec -= tmp.tv_sec;
1537       t.tv_nsec -= tmp.tv_nsec;
1538
1539       if (t.tv_nsec < 0)
1540       {
1541          --(t.tv_sec);
1542          t.tv_nsec += 1000000000L;
1543       }
1544
1545       if (what == PNGCP_TIME_READ)
1546          dp->read_time = t, tmp = dp->read_time_total;
1547
1548       else
1549          dp->write_time = t, tmp = dp->write_time_total;
1550
1551       tmp.tv_sec += t.tv_sec;
1552       tmp.tv_nsec += t.tv_nsec;
1553
1554       if (tmp.tv_nsec >= 1000000000L)
1555       {
1556          ++(tmp.tv_sec);
1557          tmp.tv_nsec -= 1000000000L;
1558       }
1559
1560       if (what == PNGCP_TIME_READ)
1561          dp->read_time_total = tmp;
1562
1563       else
1564          dp->write_time_total = tmp;
1565    }
1566 }
1567
1568 static void
1569 print_time(const char *what, struct timespec t)
1570 {
1571    printf("%s %.2lu.%.9ld", what, (unsigned long)t.tv_sec, t.tv_nsec);
1572 }
1573 #else /* !PNGCP_TIMING */
1574 #define start_timer(dp, what) ((void)0)
1575 #define end_timer(dp, what) ((void)0)
1576 #endif /* !PNGCP_TIMING */
1577
1578 /* The following is used in main to verify that the final argument is a
1579  * directory:
1580  */
1581 static int
1582 checkdir(const char *pathname)
1583 {
1584    struct stat buf;
1585    return stat(pathname, &buf) == 0 && S_ISDIR(buf.st_mode);
1586 }
1587
1588 /* Work out whether a path is valid (if not a display_log occurs), a directory
1589  * (1 is returned) or a file *or* non-existent (0 is returned).
1590  *
1591  * Used for a write path.
1592  */
1593 static int
1594 isdir(struct display *dp, const char *pathname)
1595 {
1596    if (pathname == NULL)
1597       return 0; /* stdout */
1598
1599    else if (pathname[0] == 0)
1600       return 1; /* empty string */
1601
1602    else
1603    {
1604       struct stat buf;
1605       int ret = stat(pathname, &buf);
1606
1607       if (ret == 0) /* the entry exists */
1608       {
1609          if (S_ISDIR(buf.st_mode))
1610             return 1;
1611
1612          /* Else expect an object that exists and can be written: */
1613          if (access(pathname, W_OK) != 0)
1614             display_log(dp, USER_ERROR, "%s: cannot be written (%s)", pathname,
1615                   strerror(errno));
1616
1617          return 0; /* file (exists, can be written) */
1618       }
1619
1620       else /* an error */
1621       {
1622          /* Non-existence is fine, other errors are not: */
1623          if (errno != ENOENT)
1624             display_log(dp, USER_ERROR, "%s: invalid output name (%s)",
1625                   pathname, strerror(errno));
1626
1627          return 0; /* file (does not exist) */
1628       }
1629    }
1630 }
1631
1632 static void
1633 makename(struct display *dp, const char *dir, const char *infile)
1634 {
1635    /* Make a name for an output file (and check it). */
1636    dp->namebuf[0] = 0;
1637
1638    if (dir == NULL || infile == NULL)
1639       display_log(dp, INTERNAL_ERROR, "NULL name to makename");
1640
1641    else
1642    {
1643       size_t dsize = strlen(dir);
1644
1645       if (dsize <= (sizeof dp->namebuf)-2) /* Allow for name + '/' + '\0' */
1646       {
1647          size_t isize = strlen(infile);
1648          size_t istart = isize-1;
1649
1650          /* This should fail before here: */
1651          if (infile[istart] == '/')
1652             display_log(dp, INTERNAL_ERROR, "infile with trailing /");
1653
1654          memcpy(dp->namebuf, dir, dsize);
1655          if (dsize > 0 && dp->namebuf[dsize-1] != '/')
1656             dp->namebuf[dsize++] = '/';
1657
1658          /* Find the rightmost non-/ character: */
1659          while (istart > 0 && infile[istart-1] != '/')
1660             --istart;
1661
1662          isize -= istart;
1663          infile += istart;
1664
1665          if (dsize+isize < (sizeof dp->namebuf)) /* dsize + infile + '\0' */
1666          {
1667             memcpy(dp->namebuf+dsize, infile, isize+1);
1668
1669             if (isdir(dp, dp->namebuf))
1670                display_log(dp, USER_ERROR, "%s: output file is a directory",
1671                      dp->namebuf);
1672          }
1673
1674          else
1675          {
1676             dp->namebuf[dsize] = 0; /* allowed for: -2 at start */
1677             display_log(dp, USER_ERROR, "%s%s: output file name too long",
1678                   dp->namebuf, infile);
1679          }
1680       }
1681
1682       else
1683          display_log(dp, USER_ERROR, "%s: output directory name too long", dir);
1684    }
1685 }
1686
1687 /* error handler callbacks for libpng */
1688 static void PNGCBAPI
1689 display_warning(png_structp pp, png_const_charp warning)
1690 {
1691    struct display *dp = get_dp(pp);
1692
1693    /* This is used to prevent repeated warnings while searching */
1694    if (!dp->no_warnings)
1695       display_log(get_dp(pp), LIBPNG_WARNING, "%s", warning);
1696 }
1697
1698 static void PNGCBAPI
1699 display_error(png_structp pp, png_const_charp error)
1700 {
1701    struct display *dp = get_dp(pp);
1702
1703    display_log(dp, LIBPNG_ERROR, "%s", error);
1704 }
1705
1706 static void
1707 display_start_read(struct display *dp, const char *filename)
1708 {
1709    if (filename != NULL)
1710    {
1711       dp->filename = filename;
1712       dp->fp = fopen(filename, "rb");
1713    }
1714
1715    else
1716    {
1717       dp->filename = "<stdin>";
1718       dp->fp = stdin;
1719    }
1720
1721    dp->w = dp->h = 0U;
1722    dp->bpp = 0U;
1723    dp->size = 0U;
1724    dp->read_size = 0U;
1725
1726    if (dp->fp == NULL)
1727       display_log(dp, USER_ERROR, "file open failed (%s)", strerror(errno));
1728 }
1729
1730 static void PNGCBAPI
1731 read_function(png_structp pp, png_bytep data, size_t size)
1732 {
1733    struct display *dp = get_dp(pp);
1734
1735    if (size == 0U || fread(data, size, 1U, dp->fp) == 1U)
1736       dp->read_size += size;
1737
1738    else
1739    {
1740       if (feof(dp->fp))
1741          display_log(dp, LIBPNG_ERROR, "PNG file truncated");
1742       else
1743          display_log(dp, LIBPNG_ERROR, "PNG file read failed (%s)",
1744                strerror(errno));
1745    }
1746 }
1747
1748 static void
1749 read_png(struct display *dp, const char *filename)
1750 {
1751    /* This is an assumption of the code; it may happen if a previous write fails
1752     * and there is a bug in the cleanup handling below (look for setjmp).
1753     * Passing freeinfo==1 to display_clean_read below avoids a second error
1754     * on dp->ip != NULL below.
1755     */
1756    if (dp->read_pp != NULL)
1757    {
1758       display_log(dp, APP_FAIL, "unexpected png_read_struct");
1759       display_clean_read(dp, 1/*freeinfo*/); /* recovery */
1760    }
1761
1762    display_start_read(dp, filename);
1763
1764    dp->read_pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, dp,
1765       display_error, display_warning);
1766    if (dp->read_pp == NULL)
1767       display_log(dp, LIBPNG_ERROR, "failed to create read struct");
1768
1769 #  ifdef PNG_BENIGN_ERRORS_SUPPORTED
1770       png_set_benign_errors(dp->read_pp, 1/*allowed*/);
1771 #  endif /* BENIGN_ERRORS */
1772
1773 #  ifdef FIX_INDEX
1774       if ((dp->options & FIX_INDEX) != 0)
1775          png_set_check_for_invalid_index(dp->read_pp, 1/*on, no warning*/);
1776 #     ifdef IGNORE_INDEX
1777          else
1778 #     endif /* IGNORE_INDEX */
1779 #  endif /* FIX_INDEX */
1780 #  ifdef IGNORE_INDEX
1781       if ((dp->options & IGNORE_INDEX) != 0) /* DANGEROUS */
1782          png_set_check_for_invalid_index(dp->read_pp, -1/*off completely*/);
1783 #  endif /* IGNORE_INDEX */
1784
1785    if (dp->ip != NULL)
1786    {
1787       /* UNEXPECTED: some problem in the display_clean function calls! */
1788       display_log(dp, APP_FAIL, "read_png: freeing old info struct");
1789       png_destroy_info_struct(dp->read_pp, &dp->ip);
1790    }
1791
1792    /* The png_read_png API requires us to make the info struct, but it does the
1793     * call to png_read_info.
1794     */
1795    dp->ip = png_create_info_struct(dp->read_pp);
1796    if (dp->ip == NULL)
1797       png_error(dp->read_pp, "failed to create info struct");
1798
1799    /* Set the IO handling */
1800    png_set_read_fn(dp->read_pp, dp, read_function);
1801
1802 #  ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
1803       png_set_keep_unknown_chunks(dp->read_pp, PNG_HANDLE_CHUNK_ALWAYS, NULL,
1804             0);
1805 #  endif /* HANDLE_AS_UNKNOWN */
1806
1807 #  ifdef PNG_SET_USER_LIMITS_SUPPORTED
1808       /* Remove the user limits, if any */
1809       png_set_user_limits(dp->read_pp, 0x7fffffff, 0x7fffffff);
1810 #  endif /* SET_USER_LIMITS */
1811
1812    /* Now read the PNG. */
1813    start_timer(dp, PNGCP_TIME_READ);
1814    png_read_png(dp->read_pp, dp->ip, 0U/*transforms*/, NULL/*params*/);
1815    end_timer(dp, PNGCP_TIME_READ);
1816    dp->w = png_get_image_width(dp->read_pp, dp->ip);
1817    dp->h = png_get_image_height(dp->read_pp, dp->ip);
1818    dp->ct = png_get_color_type(dp->read_pp, dp->ip);
1819    dp->bpp = png_get_bit_depth(dp->read_pp, dp->ip) *
1820              png_get_channels(dp->read_pp, dp->ip);
1821    {
1822       /* png_get_rowbytes should never return 0 because the value is set by the
1823        * first call to png_set_IHDR, which should have happened by now, but just
1824        * in case:
1825        */
1826       png_alloc_size_t rb = png_get_rowbytes(dp->read_pp, dp->ip);
1827
1828       if (rb == 0)
1829          png_error(dp->read_pp, "invalid row byte count from libpng");
1830
1831       /* The size calc can overflow. */
1832       if ((MAX_SIZE-dp->h)/rb < dp->h)
1833          png_error(dp->read_pp, "image too large");
1834
1835       dp->size = rb * dp->h + dp->h/*filter byte*/;
1836    }
1837
1838 #ifdef FIX_INDEX
1839    if (dp->ct == PNG_COLOR_TYPE_PALETTE && (dp->options & FIX_INDEX) != 0)
1840    {
1841       int max = png_get_palette_max(dp->read_pp, dp->ip);
1842       png_colorp palette = NULL;
1843       int num = -1;
1844
1845       if (png_get_PLTE(dp->read_pp, dp->ip, &palette, &num) != PNG_INFO_PLTE
1846           || max < 0 || num <= 0 || palette == NULL)
1847          display_log(dp, LIBPNG_ERROR, "invalid png_get_PLTE result");
1848
1849       if (max >= num)
1850       {
1851          /* 'Fix' the palette. */
1852          int i;
1853          png_color newpal[256];
1854
1855          for (i=0; i<num; ++i)
1856             newpal[i] = palette[i];
1857
1858          /* Fill in any remainder with a warning color: */
1859          for (; i<=max; ++i)
1860          {
1861             newpal[i].red = 0xbe;
1862             newpal[i].green = 0xad;
1863             newpal[i].blue = 0xed;
1864          }
1865
1866          png_set_PLTE(dp->read_pp, dp->ip, newpal, i);
1867       }
1868    }
1869 #endif /* FIX_INDEX */
1870
1871    /* NOTE: dp->ip is where all the information about the PNG that was just read
1872     * is stored.  It can be used to write and write again a single PNG file,
1873     * however be aware that prior to libpng 1.7 text chunks could only be
1874     * written once; this is a bug which would require a significant code rewrite
1875     * to fix, it has been there in several versions of libpng (it was introduced
1876     * to fix another bug involving duplicate writes of the text chunks.)
1877     */
1878    display_clean_read(dp, 0/*freeiinfo*/);
1879    dp->operation = "none";
1880 }
1881
1882 static void
1883 display_start_write(struct display *dp, const char *filename)
1884 {
1885    assert(dp->fp == NULL);
1886
1887    if ((dp->options & NOWRITE) != 0)
1888       dp->output_file = "<no write>";
1889
1890    else
1891    {
1892       if (filename != NULL)
1893       {
1894          dp->output_file = filename;
1895          dp->fp = fopen(filename, "wb");
1896       }
1897
1898       else
1899       {
1900          dp->output_file = "<stdout>";
1901          dp->fp = stdout;
1902       }
1903
1904       if (dp->fp == NULL)
1905          display_log(dp, USER_ERROR, "%s: file open failed (%s)",
1906                dp->output_file, strerror(errno));
1907    }
1908 }
1909
1910 static void PNGCBAPI
1911 write_function(png_structp pp, png_bytep data, size_t size)
1912 {
1913    struct display *dp = get_dp(pp);
1914
1915    /* The write fail is classed as a USER_ERROR, so --quiet does not turn it
1916     * off, this seems more likely to be correct.
1917     */
1918    if (dp->fp == NULL || fwrite(data, size, 1U, dp->fp) == 1U)
1919    {
1920       dp->write_size += size;
1921       if (dp->write_size < size || dp->write_size == MAX_SIZE)
1922          png_error(pp, "IDAT size overflow");
1923    }
1924
1925    else
1926       display_log(dp, USER_ERROR, "%s: PNG file write failed (%s)",
1927             dp->output_file, strerror(errno));
1928 }
1929
1930 /* Compression option, 'method' is never set: there is no choice.
1931  *
1932  * IMPORTANT: the order of the entries in this macro determines the preference
1933  * order when two different combos of two of these options produce an IDAT of
1934  * the same size.  The logic here is to put the things that affect the decoding
1935  * of the PNG image ahead of those that are relevant only to the encoding.
1936  */
1937 #define SET_COMPRESSION\
1938    SET(strategy, strategy);\
1939    SET(windowBits, window_bits);\
1940    SET(level, level);\
1941    SET(memLevel, mem_level);
1942
1943 #ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
1944 static void
1945 search_compression(struct display *dp)
1946 {
1947    /* Like set_compression below but use a more restricted search than 'all' */
1948    int val;
1949
1950 #  define SET(name, func) if (getsearchopts(dp, #name, &val))\
1951       png_set_compression_ ## func(dp->write_pp, val);
1952    SET_COMPRESSION
1953 #  undef SET
1954 }
1955
1956 static void
1957 set_compression(struct display *dp)
1958 {
1959    int val;
1960
1961 #  define SET(name, func) if (getallopts(dp, #name, &val))\
1962       png_set_compression_ ## func(dp->write_pp, val);
1963    SET_COMPRESSION
1964 #  undef SET
1965 }
1966
1967 #ifdef PNG_SW_COMPRESS_level /* 1.7.0+ */
1968 static void
1969 set_ICC_profile_compression(struct display *dp)
1970 {
1971    int val;
1972
1973 #  define SET(name, func) if (getallopts(dp, "ICC-profile-" #name, &val))\
1974       png_set_ICC_profile_compression_ ## func(dp->write_pp, val);
1975    SET_COMPRESSION
1976 #  undef SET
1977 }
1978 #else
1979 #  define set_ICC_profile_compression(dp) ((void)0)
1980 #endif
1981 #else
1982 #  define search_compression(dp) ((void)0)
1983 #  define set_compression(dp) ((void)0)
1984 #  define set_ICC_profile_compression(dp) ((void)0)
1985 #endif /* WRITE_CUSTOMIZE_COMPRESSION */
1986
1987 #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
1988 static void
1989 set_text_compression(struct display *dp)
1990 {
1991    int val;
1992
1993 #  define SET(name, func) if (getallopts(dp, "text-" #name, &val))\
1994       png_set_text_compression_ ## func(dp->write_pp, val);
1995    SET_COMPRESSION
1996 #  undef SET
1997 }
1998 #else
1999 #  define set_text_compression(dp) ((void)0)
2000 #endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
2001
2002 static void
2003 write_png(struct display *dp, const char *destname)
2004 {
2005    /* If this test fails png_write_png would fail *silently* below; this
2006     * is not helpful, so catch the problem now and give up:
2007     */
2008    if (dp->ip == NULL)
2009       display_log(dp, INTERNAL_ERROR, "missing png_info");
2010
2011    /* This is an assumption of the code; it may happen if a previous
2012     * write fails and there is a bug in the cleanup handling below.
2013     */
2014    if (dp->write_pp != NULL)
2015    {
2016       display_log(dp, APP_FAIL, "unexpected png_write_struct");
2017       display_clean_write(dp, 0/*!freeinfo*/);
2018    }
2019
2020    display_start_write(dp, destname);
2021
2022    dp->write_pp = png_create_write_struct(PNG_LIBPNG_VER_STRING, dp,
2023       display_error, display_warning);
2024
2025    if (dp->write_pp == NULL)
2026       display_log(dp, LIBPNG_ERROR, "failed to create write png_struct");
2027
2028 #  ifdef PNG_BENIGN_ERRORS_SUPPORTED
2029       png_set_benign_errors(dp->write_pp, 1/*allowed*/);
2030 #  endif /* BENIGN_ERRORS */
2031
2032    png_set_write_fn(dp->write_pp, dp, write_function, NULL/*flush*/);
2033
2034 #ifdef IGNORE_INDEX
2035    if ((dp->options & IGNORE_INDEX) != 0) /* DANGEROUS */
2036       png_set_check_for_invalid_index(dp->write_pp, -1/*off completely*/);
2037 #endif /* IGNORE_INDEX */
2038
2039    /* Restore the text chunks when using libpng 1.6 or less; this is a macro
2040     * which expands to nothing in 1.7+  In earlier versions it tests
2041     * dp->text_stashed, which is only set (below) *after* the first write.
2042     */
2043    text_restore(dp);
2044
2045 #  ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2046       png_set_keep_unknown_chunks(dp->write_pp, PNG_HANDLE_CHUNK_ALWAYS, NULL,
2047             0);
2048 #  endif /* HANDLE_AS_UNKNOWN */
2049
2050 #  ifdef PNG_SET_USER_LIMITS_SUPPORTED
2051       /* Remove the user limits, if any */
2052       png_set_user_limits(dp->write_pp, 0x7fffffff, 0x7fffffff);
2053 #  endif
2054
2055    /* OPTION HANDLING */
2056    /* compression outputs, IDAT and zTXt/iTXt: */
2057    dp->tsp = dp->nsp;
2058    dp->nsp = dp->csp = 0;
2059 #  ifdef PNG_SW_COMPRESS_png_level
2060       {
2061          int val;
2062
2063          /* This sets everything, but then the following options just override
2064           * the specific settings for ICC profiles and text.
2065           */
2066          if (getallopts(dp, "compression", &val))
2067             png_set_compression(dp->write_pp, val);
2068
2069          if (getallopts(dp, "ICC-profile-compression", &val))
2070             png_set_ICC_profile_compression(dp->write_pp, val);
2071
2072          if (getallopts(dp, "text-compression", &val))
2073             png_set_text_compression(dp->write_pp, val);
2074       }
2075 #  endif /* png_level support */
2076    if (dp->options & SEARCH)
2077       search_compression(dp);
2078    else
2079       set_compression(dp);
2080    set_ICC_profile_compression(dp);
2081    set_text_compression(dp);
2082
2083    {
2084       int val;
2085
2086       /* The permitted range is 1..0x7FFFFFFF, so the cast is safe */
2087       if (get_option(dp, "IDAT-size", &val))
2088          png_set_IDAT_size(dp->write_pp, val);
2089    }
2090
2091    /* filter handling */
2092 #  ifdef PNG_WRITE_FILTER_SUPPORTED
2093       {
2094          int val;
2095
2096          if (get_option(dp, "filter", &val))
2097             png_set_filter(dp->write_pp, PNG_FILTER_TYPE_BASE, val);
2098       }
2099 #  endif /* WRITE_FILTER */
2100
2101    /* This just uses the 'read' info_struct directly, it contains the image. */
2102    dp->write_size = 0U;
2103    start_timer(dp, PNGCP_TIME_WRITE);
2104    png_write_png(dp->write_pp, dp->ip, 0U/*transforms*/, NULL/*params*/);
2105    end_timer(dp, PNGCP_TIME_WRITE);
2106
2107    /* Make sure the file was written ok: */
2108    if (dp->fp != NULL)
2109    {
2110       FILE *fp = dp->fp;
2111       dp->fp = NULL;
2112       if (fclose(fp))
2113          display_log(dp, APP_ERROR, "%s: write failed (%s)",
2114                destname == NULL ? "stdout" : destname, strerror(errno));
2115    }
2116
2117    dp->operation = "none";
2118 }
2119
2120 static void
2121 set_windowBits_hi(struct display *dp)
2122 {
2123    /* windowBits is in the range 8..15 but zlib maps '8' to '9' so it is only
2124     * worth using if the data size is 256 byte or less.
2125     */
2126    int wb = MAX_WBITS; /* for large images */
2127    int i = VLSIZE(windowBits_IDAT);
2128
2129    while (wb > 8 && dp->size <= 1U<<(wb-1)) --wb;
2130
2131    while (--i >= 0) if (VLNAME(windowBits_IDAT)[i].name == range_hi) break;
2132
2133    assert(i > 1); /* vl_windowBits_IDAT always has a RANGE() */
2134    VLNAME(windowBits_IDAT)[i].value = wb;
2135
2136    assert(VLNAME(windowBits_IDAT)[--i].name == range_lo);
2137    VLNAME(windowBits_IDAT)[i].value = wb > 8 ? 9 : 8;
2138
2139    /* If wb == 8 then any search has been restricted to just one windowBits
2140     * entry.  Record that here to avoid producing a spurious app-level warning
2141     * above.
2142     */
2143    if (wb == 8)
2144       dp->min_windowBits = OPTIND(dp, windowBits);
2145 }
2146
2147 static int
2148 better_options(const struct display *dp)
2149 {
2150    /* Are these options better than the best found so far?  Normally the
2151     * options are tested in preference order, best first, however when doing a
2152     * search operation on a range the range values are tested out of order.  In
2153     * that case preferable options will get tested later.
2154     *
2155     * This function looks through the stack from the bottom up looking for an
2156     * option that does not match the current best value.  When it finds one it
2157     * checks to see if it is more or less desirable and returns true or false
2158     * as appropriate.
2159     *
2160     * Notice that this means that the order options are pushed onto the stack
2161     * conveys a priority; lower/earlier options are more important than later
2162     * ones.
2163     */
2164    unsigned int sp;
2165
2166    for (sp=0; sp<dp->csp; ++sp)
2167    {
2168       int c = compare_option(dp, sp);
2169
2170       if (c < 0)
2171          return 0; /* worse */
2172
2173       else if (c > 0)
2174          return 1; /* better */
2175    }
2176
2177    assert(0 && "unreached");
2178 }
2179
2180 static void
2181 print_search_results(struct display *dp)
2182 {
2183    assert(dp->filename != NULL);
2184    printf("%s [%ld x %ld %d bpp %s, %lu bytes] %lu -> %lu with '%s'\n",
2185       dp->filename, (unsigned long)dp->w, (unsigned long)dp->h, dp->bpp,
2186       cts(dp->ct), (unsigned long)dp->size, (unsigned long)dp->read_size,
2187       (unsigned long)dp->best_size, dp->best);
2188    fflush(stdout);
2189 }
2190
2191 static void
2192 log_search(struct display *dp, unsigned int log_depth)
2193 {
2194    /* Log, and reset, the search so far: */
2195    if (dp->nsp/*next entry to change*/ <= log_depth)
2196    {
2197       print_search_results(dp);
2198       /* Start again with this entry: */
2199       dp->best_size = MAX_SIZE;
2200    }
2201 }
2202
2203 static void
2204 cp_one_file(struct display *dp, const char *filename, const char *destname)
2205 {
2206    unsigned int log_depth;
2207
2208    dp->filename = filename;
2209    dp->operation = "read";
2210    dp->no_warnings = 0;
2211
2212    /* Read it then write it: */
2213    if (filename != NULL && access(filename, R_OK) != 0)
2214       display_log(dp, USER_ERROR, "%s: invalid file name (%s)",
2215             filename, strerror(errno));
2216
2217    read_png(dp, filename);
2218
2219    /* But 'destname' may be a directory. */
2220    dp->operation = "write";
2221
2222    /* Limit the upper end of the windowBits range for this file */
2223    set_windowBits_hi(dp);
2224
2225    /* For logging, depth to log: */
2226    {
2227       int val;
2228
2229       if (get_option(dp, "log-depth", &val) && val >= 0)
2230          log_depth = (unsigned int)/*SAFE*/val;
2231
2232       else
2233          log_depth = 0U;
2234    }
2235
2236    if (destname != NULL) /* else stdout */
2237    {
2238       if (isdir(dp, destname))
2239       {
2240          makename(dp, destname, filename);
2241          destname = dp->namebuf;
2242       }
2243
2244       else if (access(destname, W_OK) != 0 && errno != ENOENT)
2245          display_log(dp, USER_ERROR, "%s: invalid output name (%s)", destname,
2246                strerror(errno));
2247    }
2248
2249    dp->nsp = 0;
2250    dp->curr[0] = 0; /* acts as a flag for the caller */
2251    dp->opt_string_start = 0;
2252    dp->best[0] = 0; /* safety */
2253    dp->best_size = MAX_SIZE;
2254    write_png(dp, destname);
2255
2256    /* Initialize the 'best' fields: */
2257    strcpy(dp->best, dp->curr);
2258    dp->best_size = dp->write_size;
2259
2260    if (dp->nsp > 0) /* iterating over lists */
2261    {
2262       char *tmpname, tmpbuf[(sizeof dp->namebuf) + 4];
2263       assert(dp->curr[0] == ' ' && dp->tsp > 0);
2264
2265       /* Cancel warnings on subsequent writes */
2266       log_search(dp, log_depth);
2267       dp->no_warnings = 1;
2268
2269       /* Make a temporary name for the subsequent tests: */
2270       if (destname != NULL)
2271       {
2272          strcpy(tmpbuf, destname);
2273          strcat(tmpbuf, ".tmp"); /* space for .tmp allocated above */
2274          tmpname = tmpbuf;
2275       }
2276
2277       else
2278          tmpname = NULL; /* stdout */
2279
2280       /* Loop to find the best option. */
2281       do
2282       {
2283          /* Clean before each write_png; this just removes *dp->write_pp which
2284           * cannot be reused.
2285           */
2286          display_clean_write(dp, 0/*!freeinfo*/);
2287          write_png(dp, tmpname);
2288
2289          /* And compare the sizes (the write function makes sure write_size
2290           * doesn't overflow.)
2291           */
2292          assert(dp->csp > 0);
2293
2294          if (dp->write_size < dp->best_size ||
2295              (dp->write_size == dp->best_size && better_options(dp)))
2296          {
2297             if (destname != NULL && rename(tmpname, destname) != 0)
2298                display_log(dp, APP_ERROR, "rename %s %s failed (%s)", tmpname,
2299                      destname, strerror(errno));
2300
2301             strcpy(dp->best, dp->curr);
2302             dp->best_size = dp->write_size;
2303          }
2304
2305          else if (tmpname != NULL && unlink(tmpname) != 0)
2306             display_log(dp, APP_WARNING, "unlink %s failed (%s)", tmpname,
2307                   strerror(errno));
2308
2309          log_search(dp, log_depth);
2310       }
2311       while (dp->nsp > 0);
2312
2313       /* Do this for the 'sizes' option so that it reports the correct size. */
2314       dp->write_size = dp->best_size;
2315    }
2316
2317    display_clean_write(dp, 1/*freeinfo*/);
2318 }
2319
2320 static int
2321 cppng(struct display *dp, const char *file, const char *gv dest)
2322    /* Exists solely to isolate the setjmp clobbers which some versions of GCC
2323     * erroneously generate.
2324     */
2325 {
2326    int ret = setjmp(dp->error_return);
2327
2328    if (ret == 0)
2329    {
2330       dp->errset = 1;
2331       cp_one_file(dp, file, dest);
2332       dp->errset = 0;
2333       return 0;
2334    }
2335
2336    else
2337    {
2338       dp->errset = 0;
2339
2340       if (ret < ERRORS) /* shouldn't longjmp on warnings */
2341          display_log(dp, INTERNAL_ERROR, "unexpected return code %d", ret);
2342
2343       return ret;
2344    }
2345 }
2346
2347 int
2348 main(int argc, char **argv)
2349 {
2350    /* For each file on the command line test it with a range of transforms */
2351    int option_end;
2352    struct display d;
2353
2354    display_init(&d);
2355
2356    d.operation = "options";
2357    for (option_end = 1;
2358         option_end < argc && opt_check(&d, argv[option_end]);
2359         ++option_end)
2360    {
2361    }
2362
2363    /* Do a quick check on the directory target case; when there are more than
2364     * two arguments the last one must be a directory.
2365     */
2366    if (!(d.options & NOWRITE) && option_end+2 < argc && !checkdir(argv[argc-1]))
2367    {
2368       fprintf(stderr,
2369             "pngcp: %s: directory required with more than two arguments\n",
2370             argv[argc-1]);
2371       return 99;
2372    }
2373
2374    {
2375       int errors = 0;
2376       int i = option_end;
2377
2378       /* Do this at least once; if there are no arguments stdin/stdout are used.
2379        */
2380       d.operation = "files";
2381       do
2382       {
2383          const char *infile = NULL;
2384          const char *outfile = NULL;
2385          int ret;
2386
2387          if (i < argc)
2388          {
2389             infile = argv[i++];
2390             if (!(d.options & NOWRITE) && i < argc)
2391                outfile = argv[argc-1];
2392          }
2393
2394          ret = cppng(&d, infile, outfile);
2395
2396          if (ret)
2397          {
2398             if (ret > QUIET) /* abort on user or internal error */
2399                return 99;
2400
2401             /* An error: the output is meaningless */
2402          }
2403
2404          else if (d.best[0] != 0)
2405          {
2406             /* This result may already have been output, in which case best_size
2407              * has been reset.
2408              */
2409             if (d.best_size < MAX_SIZE)
2410                print_search_results(&d);
2411          }
2412
2413          else if (d.options & SIZES)
2414          {
2415             printf("%s [%ld x %ld %d bpp %s, %lu bytes] %lu -> %lu [0x%lx]\n",
2416                   infile, (unsigned long)d.w, (unsigned long)d.h, d.bpp,
2417                   cts(d.ct), (unsigned long)d.size, (unsigned long)d.read_size,
2418                   (unsigned long)d.write_size, (unsigned long)d.results);
2419             fflush(stdout);
2420          }
2421
2422          /* Here on any return, including failures, except user/internal issues
2423           */
2424          {
2425             int pass = (d.options & STRICT) ?
2426                RESULT_STRICT(d.results) : RESULT_RELAXED(d.results);
2427
2428             if (!pass)
2429                ++errors;
2430
2431             if (d.options & LOG)
2432             {
2433                int j;
2434
2435                printf("%s: pngcp", pass ? "PASS" : "FAIL");
2436
2437                for (j=1; j<option_end; ++j)
2438                   printf(" %s", argv[j]);
2439
2440                if (infile != NULL)
2441                   printf(" %s", infile);
2442
2443 #              ifdef PNG_PNGCP_TIMING_SUPPORTED
2444                   /* When logging output the files for each file, if enabled. */
2445                   if ((d.value[OPTIND(&d,time)] & PNGCP_TIME_READ) != 0)
2446                      print_time(" read", d.read_time);
2447
2448                   if ((d.value[OPTIND(&d,time)] & PNGCP_TIME_WRITE) != 0)
2449                      print_time(" write", d.write_time);
2450 #              endif /* PNGCP_TIMING */
2451
2452                printf("\n");
2453                fflush(stdout);
2454             }
2455          }
2456
2457          display_clean(&d);
2458       }
2459       while (i+!(d.options & NOWRITE) < argc);
2460          /* I.e. for write cases after the first time through the loop require
2461           * there to be at least two arguments left and for the last one to be a
2462           * directory (this was checked above).
2463           */
2464
2465       /* Release allocated memory */
2466       display_destroy(&d);
2467
2468 #     ifdef PNG_PNGCP_TIMING_SUPPORTED
2469          {
2470             int output = 0;
2471
2472             if ((d.value[OPTIND(&d,time)] & PNGCP_TIME_READ) != 0)
2473                print_time("read", d.read_time_total), output = 1;
2474
2475             if ((d.value[OPTIND(&d,time)] & PNGCP_TIME_WRITE) != 0)
2476             {
2477                if (output) putchar(' ');
2478                print_time("write", d.write_time_total);
2479                output = 1;
2480             }
2481
2482             if (output) putchar('\n');
2483          }
2484 #     endif /* PNGCP_TIMING */
2485
2486       return errors != 0;
2487    }
2488 }
2489 #else /* !READ_PNG || !WRITE_PNG */
2490 int
2491 main(void)
2492 {
2493    fprintf(stderr, "pngcp: no support for png_read/write_image\n");
2494    return 77;
2495 }
2496 #endif /* !READ_PNG || !WRITE_PNG */