]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libpng/lib/dist/pngvalid.c
update
[l4.git] / l4 / pkg / libpng / lib / dist / pngvalid.c
1
2 /* pngvalid.c - validate libpng by constructing then reading png files.
3  *
4  * Last changed in libpng 1.5.2 [March 31, 2011]
5  * Copyright (c) 2011 Glenn Randers-Pehrson
6  * Written by John Cunningham Bowler
7  *
8  * This code is released under the libpng license.
9  * For conditions of distribution and use, see the disclaimer
10  * and license in png.h
11  *
12  * NOTES:
13  *   This is a C program that is intended to be linked against libpng.  It
14  *   generates bitmaps internally, stores them as PNG files (using the
15  *   sequential write code) then reads them back (using the sequential
16  *   read code) and validates that the result has the correct data.
17  *
18  *   The program can be modified and extended to test the correctness of
19  *   transformations performed by libpng.
20  */
21
22 #include "png.h"
23 #if PNG_LIBPNG_VER < 10500
24 /* This delibarately lacks the PNG_CONST. */
25 typedef png_byte *png_const_bytep;
26
27 /* This is copied from 1.5.1 png.h: */
28 #define PNG_INTERLACE_ADAM7_PASSES 7
29 #define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7)
30 #define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7)
31 #define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)
32 #define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)
33 #define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\
34    -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))
35 #define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\
36    -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))
37 #define PNG_ROW_FROM_PASS_ROW(yIn, pass) \
38    (((yIn)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))
39 #define PNG_COL_FROM_PASS_COL(xIn, pass) \
40    (((xIn)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))
41 #define PNG_PASS_MASK(pass,off) ( \
42    ((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \
43    ((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U))
44 #define PNG_ROW_IN_INTERLACE_PASS(y, pass) \
45    ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)
46 #define PNG_COL_IN_INTERLACE_PASS(x, pass) \
47    ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)
48
49 /* These are needed too for the defualt build: */
50 #define PNG_WRITE_16BIT_SUPPORTED
51 #define PNG_READ_16BIT_SUPPORTED
52 #endif
53
54 #include "zlib.h"   /* For crc32 */
55
56 #include <float.h>  /* For floating point constants */
57 #include <stdlib.h> /* For malloc */
58 #include <string.h> /* For memcpy, memset */
59 #include <math.h>   /* For floor */
60
61 /* Unused formal parameter errors are removed using the following macro which is
62  * expected to have no bad effects on performance.
63  */
64 #ifndef UNUSED
65 #  if defined(__GNUC__) || defined(_MSC_VER)
66 #     define UNUSED(param) (void)param;
67 #  else
68 #     define UNUSED(param)
69 #  endif
70 #endif
71
72 /***************************** EXCEPTION HANDLING *****************************/
73 #include "contrib/visupng/cexcept.h"
74 struct png_store;
75 define_exception_type(struct png_store*);
76
77 /* The following are macros to reduce typing everywhere where the well known
78  * name 'the_exception_context' must be defined.
79  */
80 #define anon_context(ps) struct exception_context *the_exception_context = \
81    &(ps)->exception_context
82 #define context(ps,fault) anon_context(ps); png_store *fault
83
84 /******************************* UTILITIES ************************************/
85 /* Error handling is particularly problematic in production code - error
86  * handlers often themselves have bugs which lead to programs that detect
87  * minor errors crashing.  The following functions deal with one very
88  * common class of errors in error handlers - attempting to format error or
89  * warning messages into buffers that are too small.
90  */
91 static size_t safecat(char *buffer, size_t bufsize, size_t pos,
92    PNG_CONST char *cat)
93 {
94    while (pos < bufsize && cat != NULL && *cat != 0)
95       buffer[pos++] = *cat++;
96
97    if (pos >= bufsize)
98       pos = bufsize-1;
99
100    buffer[pos] = 0;
101    return pos;
102 }
103
104 static size_t safecatn(char *buffer, size_t bufsize, size_t pos, int n)
105 {
106    char number[64];
107    sprintf(number, "%d", n);
108    return safecat(buffer, bufsize, pos, number);
109 }
110
111 static size_t safecatd(char *buffer, size_t bufsize, size_t pos, double d,
112     int precision)
113 {
114    char number[64];
115    sprintf(number, "%.*f", precision, d);
116    return safecat(buffer, bufsize, pos, number);
117 }
118
119 static PNG_CONST char invalid[] = "invalid";
120 static PNG_CONST char sep[] = ": ";
121
122 /* NOTE: this is indexed by ln2(bit_depth)! */
123 static PNG_CONST char *bit_depths[8] =
124 {
125    "1", "2", "4", "8", "16", invalid, invalid, invalid
126 };
127
128 static PNG_CONST char *colour_types[8] =
129 {
130    "greyscale", invalid, "truecolour", "indexed-colour",
131    "greyscale with alpha", invalid, "truecolour with alpha", invalid
132 };
133
134 /* To get log-bit-depth from bit depth, returns 0 to 7 (7 on error). */
135 static unsigned int
136 log2depth(png_byte bit_depth)
137 {
138    switch (bit_depth)
139    {
140       case 1:
141          return 0;
142
143       case 2:
144          return 1;
145
146       case 4:
147          return 2;
148
149       case 8:
150          return 3;
151
152       case 16:
153          return 4;
154
155       default:
156          return 7;
157    }
158 }
159
160 /* A numeric ID based on PNG file characteristics.  The 'do_interlace' field
161  * simply records whether pngvalid did the interlace itself or whether it
162  * was done by libpng.  Width and height must be less than 256.
163  */
164 #define FILEID(col, depth, interlace, width, height, do_interlace) \
165    ((png_uint_32)((col) + ((depth)<<3) + ((interlace)<<8) + \
166     (((do_interlace)!=0)<<15) + ((width)<<16) + ((height)<<24)))
167
168 #define COL_FROM_ID(id) ((png_byte)((id)& 0x7U))
169 #define DEPTH_FROM_ID(id) ((png_byte)(((id) >> 3) & 0x1fU))
170 #define INTERLACE_FROM_ID(id) ((int)(((id) >> 8) & 0x3))
171 #define DO_INTERLACE_FROM_ID(id) ((int)(((id)>>15) & 1))
172 #define WIDTH_FROM_ID(id) (((id)>>16) & 0xff)
173 #define HEIGHT_FROM_ID(id) (((id)>>24) & 0xff)
174
175 /* Utility to construct a standard name for a standard image. */
176 static size_t
177 standard_name(char *buffer, size_t bufsize, size_t pos, png_byte colour_type,
178     int log_bit_depth, int interlace_type, png_uint_32 w, png_uint_32 h,
179     int do_interlace)
180 {
181    pos = safecat(buffer, bufsize, pos, colour_types[colour_type]);
182    pos = safecat(buffer, bufsize, pos, " ");
183    pos = safecat(buffer, bufsize, pos, bit_depths[log_bit_depth]);
184    pos = safecat(buffer, bufsize, pos, " bit ");
185
186    if (interlace_type != PNG_INTERLACE_NONE)
187       pos = safecat(buffer, bufsize, pos, "interlaced");
188    if (do_interlace)
189       pos = safecat(buffer, bufsize, pos, "(pngvalid)");
190    else
191       pos = safecat(buffer, bufsize, pos, "(libpng)");
192    if (w > 0 || h > 0)
193    {
194       pos = safecat(buffer, bufsize, pos, " ");
195       pos = safecatn(buffer, bufsize, pos, w);
196       pos = safecat(buffer, bufsize, pos, "x");
197       pos = safecatn(buffer, bufsize, pos, h);
198    }
199
200    return pos;
201 }
202
203 static size_t
204 standard_name_from_id(char *buffer, size_t bufsize, size_t pos, png_uint_32 id)
205 {
206    return standard_name(buffer, bufsize, pos, COL_FROM_ID(id),
207       log2depth(DEPTH_FROM_ID(id)), INTERLACE_FROM_ID(id),
208       WIDTH_FROM_ID(id), HEIGHT_FROM_ID(id), DO_INTERLACE_FROM_ID(id));
209 }
210
211 /* Convenience API and defines to list valid formats.  Note that 16 bit read and
212  * write support is required to do 16 bit read tests (we must be able to make a
213  * 16 bit image to test!)
214  */
215 #ifdef PNG_WRITE_16BIT_SUPPORTED
216 #  define WRITE_BDHI 4
217 #  ifdef PNG_READ_16BIT_SUPPORTED
218 #     define READ_BDHI 4
219 #     define DO_16BIT
220 #  endif
221 #else
222 #  define WRITE_BDHI 3
223 #endif
224 #ifndef DO_16BIT
225 #  define READ_BDHI 3
226 #endif
227
228 static int
229 next_format(png_bytep colour_type, png_bytep bit_depth)
230 {
231    if (*bit_depth == 0)
232    {
233       *colour_type = 0, *bit_depth = 1;
234       return 1;
235    }
236
237    *bit_depth = (png_byte)(*bit_depth << 1);
238
239    /* Palette images are restricted to 8 bit depth */
240    if (*bit_depth <= 8
241 #     ifdef DO_16BIT
242          || (*colour_type != 3 && *bit_depth <= 16)
243 #     endif
244       )
245       return 1;
246
247    /* Move to the next color type, or return 0 at the end. */
248    switch (*colour_type)
249    {
250       case 0:
251          *colour_type = 2;
252          *bit_depth = 8;
253          return 1;
254
255       case 2:
256          *colour_type = 3;
257          *bit_depth = 1;
258          return 1;
259
260       case 3:
261          *colour_type = 4;
262          *bit_depth = 8;
263          return 1;
264
265       case 4:
266          *colour_type = 6;
267          *bit_depth = 8;
268          return 1;
269
270       default:
271          return 0;
272    }
273 }
274
275 static unsigned int
276 sample(png_const_bytep row, png_byte colour_type, png_byte bit_depth,
277     png_uint_32 x, unsigned int sample_index)
278 {
279    png_uint_32 bit_index, result;
280
281    /* Find a sample index for the desired sample: */
282    x *= bit_depth;
283    bit_index = x;
284
285    if ((colour_type & 1) == 0) /* !palette */
286    {
287       if (colour_type & 2)
288          bit_index *= 3;
289
290       if (colour_type & 4)
291          bit_index += x; /* Alpha channel */
292
293       if (colour_type & (2+4))
294          bit_index += sample_index * bit_depth; /* Multiple channels: select one */
295    }
296
297    /* Return the sample from the row as an integer. */
298    row += bit_index >> 3;
299    result = *row;
300
301    if (bit_depth == 8)
302       return result;
303
304    else if (bit_depth > 8)
305       return (result << 8) + *++row;
306
307    /* Less than 8 bits per sample. */
308    bit_index &= 7;
309    return (result >> (8-bit_index-bit_depth)) & ((1U<<bit_depth)-1);
310 }
311
312 /* Copy a single pixel, of a given size, from one buffer to another -
313  * while this is basically bit addressed there is an implicit assumption
314  * that pixels 8 or more bits in size are byte aligned and that pixels
315  * do not otherwise cross byte boundaries.  (This is, so far as I know,
316  * universally true in bitmap computer graphics.  [JCB 20101212])
317  *
318  * NOTE: The to and from buffers may be the same.
319  */
320 static void
321 pixel_copy(png_bytep toBuffer, png_uint_32 toIndex,
322    png_const_bytep fromBuffer, png_uint_32 fromIndex, unsigned int pixelSize)
323 {
324    /* Assume we can multiply by 'size' without overflow because we are
325     * just working in a single buffer.
326     */
327    toIndex *= pixelSize;
328    fromIndex *= pixelSize;
329    if (pixelSize < 8) /* Sub-byte */
330    {
331       /* Mask to select the location of the copied pixel: */
332       unsigned int destMask = ((1U<<pixelSize)-1) << (8-pixelSize-(toIndex&7));
333       /* The following read the entire pixels and clears the extra: */
334       unsigned int destByte = toBuffer[toIndex >> 3] & ~destMask;
335       unsigned int sourceByte = fromBuffer[fromIndex >> 3];
336
337       /* Don't rely on << or >> supporting '0' here, just in case: */
338       fromIndex &= 7;
339       if (fromIndex > 0) sourceByte <<= fromIndex;
340       if ((toIndex & 7) > 0) sourceByte >>= toIndex & 7;
341
342       toBuffer[toIndex >> 3] = (png_byte)(destByte | (sourceByte & destMask));
343    }
344    else /* One or more bytes */
345       memmove(toBuffer+(toIndex>>3), fromBuffer+(fromIndex>>3), pixelSize>>3);
346 }
347
348 /* Compare pixels - they are assumed to start at the first byte in the
349  * given buffers.
350  */
351 static int
352 pixel_cmp(png_const_bytep pa, png_const_bytep pb, png_uint_32 bit_width)
353 {
354    if (memcmp(pa, pb, bit_width>>3) == 0)
355    {
356       png_uint_32 p;
357
358       if ((bit_width & 7) == 0) return 0;
359
360       /* Ok, any differences? */
361       p = pa[bit_width >> 3];
362       p ^= pb[bit_width >> 3];
363
364       if (p == 0) return 0;
365
366       /* There are, but they may not be significant, remove the bits
367        * after the end (the low order bits in PNG.)
368        */
369       bit_width &= 7;
370       p >>= 8-bit_width;
371
372       if (p == 0) return 0;
373    }
374
375    return 1; /* Different */
376 }
377
378 /*************************** BASIC PNG FILE WRITING ***************************/
379 /* A png_store takes data from the sequential writer or provides data
380  * to the sequential reader.  It can also store the result of a PNG
381  * write for later retrieval.
382  */
383 #define STORE_BUFFER_SIZE 500 /* arbitrary */
384 typedef struct png_store_buffer
385 {
386    struct png_store_buffer*  prev;    /* NOTE: stored in reverse order */
387    png_byte                  buffer[STORE_BUFFER_SIZE];
388 } png_store_buffer;
389
390 #define FILE_NAME_SIZE 64
391
392 typedef struct png_store_file
393 {
394    struct png_store_file*  next;      /* as many as you like... */
395    char                    name[FILE_NAME_SIZE];
396    png_uint_32             id;        /* must be correct (see FILEID) */
397    png_size_t              datacount; /* In this (the last) buffer */
398    png_store_buffer        data;      /* Last buffer in file */
399 } png_store_file;
400
401 /* The following is a pool of memory allocated by a single libpng read or write
402  * operation.
403  */
404 typedef struct store_pool
405 {
406    struct png_store    *store;   /* Back pointer */
407    struct store_memory *list;    /* List of allocated memory */
408    png_byte             mark[4]; /* Before and after data */
409
410    /* Statistics for this run. */
411    png_alloc_size_t     max;     /* Maximum single allocation */
412    png_alloc_size_t     current; /* Current allocation */
413    png_alloc_size_t     limit;   /* Highest current allocation */
414    png_alloc_size_t     total;   /* Total allocation */
415
416    /* Overall statistics (retained across successive runs). */
417    png_alloc_size_t     max_max;
418    png_alloc_size_t     max_limit;
419    png_alloc_size_t     max_total;
420 } store_pool;
421
422 typedef struct png_store
423 {
424    /* For cexcept.h exception handling - simply store one of these;
425     * the context is a self pointer but it may point to a different
426     * png_store (in fact it never does in this program.)
427     */
428    struct exception_context
429                       exception_context;
430
431    unsigned int       verbose :1;
432    unsigned int       treat_warnings_as_errors :1;
433    unsigned int       expect_error :1;
434    unsigned int       expect_warning :1;
435    unsigned int       saw_warning :1;
436    unsigned int       speed :1;
437    unsigned int       progressive :1; /* use progressive read */
438    unsigned int       validated :1;   /* used as a temporary flag */
439    int                nerrors;
440    int                nwarnings;
441    char               test[128]; /* Name of test */
442    char               error[256];
443
444    /* Read fields */
445    png_structp        pread;    /* Used to read a saved file */
446    png_infop          piread;
447    png_store_file*    current;  /* Set when reading */
448    png_store_buffer*  next;     /* Set when reading */
449    png_size_t         readpos;  /* Position in *next */
450    png_byte*          image;    /* Buffer for reading interlaced images */
451    size_t             cb_image; /* Size of this buffer */
452    store_pool         read_memory_pool;
453
454    /* Write fields */
455    png_store_file*    saved;
456    png_structp        pwrite;   /* Used when writing a new file */
457    png_infop          piwrite;
458    png_size_t         writepos; /* Position in .new */
459    char               wname[FILE_NAME_SIZE];
460    png_store_buffer   new;      /* The end of the new PNG file being written. */
461    store_pool         write_memory_pool;
462 } png_store;
463
464 /* Initialization and cleanup */
465 static void
466 store_pool_mark(png_byte *mark)
467 {
468    /* Generate a new mark.  This uses a boring repeatable algorithm and it is
469     * implemented here so that it gives the same set of numbers on every
470     * architecture.  It's a linear congruential generator (Knuth or Sedgewick
471     * "Algorithms") but it comes from the 'feedback taps' table in Horowitz and
472     * Hill, "The Art of Electronics".
473     */
474    static png_uint_32 u0 = 0x12345678, u1 = 1;
475
476    /* There are thirty three bits, the next bit in the sequence is bit-33 XOR
477     * bit-20.  The top 1 bit is in u1, the bottom 32 are in u0.
478     */
479    int i;
480    for (i=0; i<4; ++i)
481    {
482       /* First generate 8 new bits then shift them in at the end. */
483       png_uint_32 u = ((u0 >> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff;
484       u1 <<= 8;
485       u1 |= u0 >> 24;
486       u0 <<= 8;
487       u0 |= u;
488       *mark++ = (png_byte)u;
489    }
490 }
491
492 /* Use this for random 32 bit values, this function makes sure the result is
493  * non-zero.
494  */
495 static png_uint_32
496 random_32(void)
497 {
498
499    for(;;)
500    {
501       png_byte mark[4];
502       png_uint_32 result;
503
504       store_pool_mark(mark);
505       result = png_get_uint_32(mark);
506
507       if (result != 0)
508          return result;
509    }
510 }
511
512 static void
513 store_pool_init(png_store *ps, store_pool *pool)
514 {
515    memset(pool, 0, sizeof *pool);
516
517    pool->store = ps;
518    pool->list = NULL;
519    pool->max = pool->current = pool->limit = pool->total = 0;
520    pool->max_max = pool->max_limit = pool->max_total = 0;
521    store_pool_mark(pool->mark);
522 }
523
524 static void
525 store_init(png_store* ps)
526 {
527    memset(ps, 0, sizeof *ps);
528    init_exception_context(&ps->exception_context);
529    store_pool_init(ps, &ps->read_memory_pool);
530    store_pool_init(ps, &ps->write_memory_pool);
531    ps->verbose = 0;
532    ps->treat_warnings_as_errors = 0;
533    ps->expect_error = 0;
534    ps->expect_warning = 0;
535    ps->saw_warning = 0;
536    ps->speed = 0;
537    ps->progressive = 0;
538    ps->validated = 0;
539    ps->nerrors = ps->nwarnings = 0;
540    ps->pread = NULL;
541    ps->piread = NULL;
542    ps->saved = ps->current = NULL;
543    ps->next = NULL;
544    ps->readpos = 0;
545    ps->image = NULL;
546    ps->cb_image = 0;
547    ps->pwrite = NULL;
548    ps->piwrite = NULL;
549    ps->writepos = 0;
550    ps->new.prev = NULL;
551 }
552
553 /* This somewhat odd function is used when reading an image to ensure that the
554  * buffer is big enough - this is why a png_structp is available.
555  */
556 static void
557 store_ensure_image(png_store *ps, png_structp pp, size_t cb)
558 {
559    if (ps->cb_image < cb)
560    {
561       if (ps->image != NULL)
562       {
563          free(ps->image-1);
564          ps->cb_image = 0;
565       }
566
567       /* The buffer is deliberately mis-aligned. */
568       ps->image = malloc(cb+1);
569       if (ps->image == NULL)
570          png_error(pp, "OOM allocating image buffer");
571
572       ++(ps->image);
573       ps->cb_image = cb;
574    }
575
576    /* And, for error checking, the whole buffer is set to '1' - this
577     * matches what happens with the 'size' test images on write and also
578     * matches the unused bits in the test rows.
579     */
580    memset(ps->image, 0xff, cb);
581 }
582
583 static void
584 store_freebuffer(png_store_buffer* psb)
585 {
586    if (psb->prev)
587    {
588       store_freebuffer(psb->prev);
589       free(psb->prev);
590       psb->prev = NULL;
591    }
592 }
593
594 static void
595 store_freenew(png_store *ps)
596 {
597    store_freebuffer(&ps->new);
598    ps->writepos = 0;
599 }
600
601 static void
602 store_storenew(png_store *ps)
603 {
604    png_store_buffer *pb;
605
606    if (ps->writepos != STORE_BUFFER_SIZE)
607       png_error(ps->pwrite, "invalid store call");
608
609    pb = malloc(sizeof *pb);
610
611    if (pb == NULL)
612       png_error(ps->pwrite, "store new: OOM");
613
614    *pb = ps->new;
615    ps->new.prev = pb;
616    ps->writepos = 0;
617 }
618
619 static void
620 store_freefile(png_store_file **ppf)
621 {
622    if (*ppf != NULL)
623    {
624       store_freefile(&(*ppf)->next);
625
626       store_freebuffer(&(*ppf)->data);
627       (*ppf)->datacount = 0;
628       free(*ppf);
629       *ppf = NULL;
630    }
631 }
632
633 /* Main interface to file storeage, after writing a new PNG file (see the API
634  * below) call store_storefile to store the result with the given name and id.
635  */
636 static void
637 store_storefile(png_store *ps, png_uint_32 id)
638 {
639    png_store_file *pf = malloc(sizeof *pf);
640    if (pf == NULL)
641       png_error(ps->pwrite, "storefile: OOM");
642    safecat(pf->name, sizeof pf->name, 0, ps->wname);
643    pf->id = id;
644    pf->data = ps->new;
645    pf->datacount = ps->writepos;
646    ps->new.prev = NULL;
647    ps->writepos = 0;
648
649    /* And save it. */
650    pf->next = ps->saved;
651    ps->saved = pf;
652 }
653
654 /* Generate an error message (in the given buffer) */
655 static size_t
656 store_message(png_store *ps, png_structp pp, char *buffer, size_t bufsize,
657    size_t pos, PNG_CONST char *msg)
658 {
659    if (pp != NULL && pp == ps->pread)
660    {
661       /* Reading a file */
662       pos = safecat(buffer, bufsize, pos, "read: ");
663
664       if (ps->current != NULL)
665       {
666          pos = safecat(buffer, bufsize, pos, ps->current->name);
667          pos = safecat(buffer, bufsize, pos, sep);
668       }
669    }
670
671    else if (pp != NULL && pp == ps->pwrite)
672    {
673       /* Writing a file */
674       pos = safecat(buffer, bufsize, pos, "write: ");
675       pos = safecat(buffer, bufsize, pos, ps->wname);
676       pos = safecat(buffer, bufsize, pos, sep);
677    }
678
679    else
680    {
681       /* Neither reading nor writing (or a memory error in struct delete) */
682       pos = safecat(buffer, bufsize, pos, "pngvalid: ");
683    }
684
685    if (ps->test[0] != 0)
686    {
687       pos = safecat(buffer, bufsize, pos, ps->test);
688       pos = safecat(buffer, bufsize, pos, sep);
689    }
690    pos = safecat(buffer, bufsize, pos, msg);
691    return pos;
692 }
693
694 /* Log an error or warning - the relevant count is always incremented. */
695 static void
696 store_log(png_store* ps, png_structp pp, png_const_charp message, int is_error)
697 {
698    /* The warning is copied to the error buffer if there are no errors and it is
699     * the first warning.  The error is copied to the error buffer if it is the
700     * first error (overwriting any prior warnings).
701     */
702    if (is_error ? (ps->nerrors)++ == 0 :
703        (ps->nwarnings)++ == 0 && ps->nerrors == 0)
704       store_message(ps, pp, ps->error, sizeof ps->error, 0, message);
705
706    if (ps->verbose)
707    {
708       char buffer[256];
709       size_t pos;
710
711       if (is_error)
712          pos = safecat(buffer, sizeof buffer, 0, "error: ");
713       else
714          pos = safecat(buffer, sizeof buffer, 0, "warning: ");
715
716       store_message(ps, pp, buffer, sizeof buffer, pos, message);
717       fputs(buffer, stderr);
718       fputc('\n', stderr);
719    }
720 }
721
722 /* Functions to use as PNG callbacks. */
723 static void
724 store_error(png_structp pp, png_const_charp message) /* PNG_NORETURN */
725 {
726    png_store *ps = png_get_error_ptr(pp);
727
728    if (!ps->expect_error)
729       store_log(ps, pp, message, 1 /* error */);
730
731    /* And finally throw an exception. */
732    {
733       struct exception_context *the_exception_context = &ps->exception_context;
734       Throw ps;
735    }
736 }
737
738 static void
739 store_warning(png_structp pp, png_const_charp message)
740 {
741    png_store *ps = png_get_error_ptr(pp);
742
743    if (!ps->expect_warning)
744       store_log(ps, pp, message, 0 /* warning */);
745    else
746       ps->saw_warning = 1;
747 }
748
749 static void
750 store_write(png_structp pp, png_bytep pb, png_size_t st)
751 {
752    png_store *ps = png_get_io_ptr(pp);
753
754    if (ps->pwrite != pp)
755       png_error(pp, "store state damaged");
756
757    while (st > 0)
758    {
759       size_t cb;
760
761       if (ps->writepos >= STORE_BUFFER_SIZE)
762          store_storenew(ps);
763
764       cb = st;
765
766       if (cb > STORE_BUFFER_SIZE - ps->writepos)
767          cb = STORE_BUFFER_SIZE - ps->writepos;
768
769       memcpy(ps->new.buffer + ps->writepos, pb, cb);
770       pb += cb;
771       st -= cb;
772       ps->writepos += cb;
773    }
774 }
775
776 static void
777 store_flush(png_structp pp)
778 {
779    UNUSED(pp) /*DOES NOTHING*/
780 }
781
782 static size_t
783 store_read_buffer_size(png_store *ps)
784 {
785    /* Return the bytes available for read in the current buffer. */
786    if (ps->next != &ps->current->data)
787       return STORE_BUFFER_SIZE;
788
789    return ps->current->datacount;
790 }
791
792 /* Return total bytes available for read. */
793 static size_t
794 store_read_buffer_avail(png_store *ps)
795 {
796    if (ps->current != NULL && ps->next != NULL)
797    {
798       png_store_buffer *next = &ps->current->data;
799       size_t cbAvail = ps->current->datacount;
800
801       while (next != ps->next && next != NULL)
802       {
803          next = next->prev;
804          cbAvail += STORE_BUFFER_SIZE;
805       }
806
807       if (next != ps->next)
808          png_error(ps->pread, "buffer read error");
809
810       if (cbAvail > ps->readpos)
811          return cbAvail - ps->readpos;
812    }
813
814    return 0;
815 }
816
817 static int
818 store_read_buffer_next(png_store *ps)
819 {
820    png_store_buffer *pbOld = ps->next;
821    png_store_buffer *pbNew = &ps->current->data;
822    if (pbOld != pbNew)
823    {
824       while (pbNew != NULL && pbNew->prev != pbOld)
825          pbNew = pbNew->prev;
826
827       if (pbNew != NULL)
828       {
829          ps->next = pbNew;
830          ps->readpos = 0;
831          return 1;
832       }
833
834       png_error(ps->pread, "buffer lost");
835    }
836
837    return 0; /* EOF or error */
838 }
839
840 /* Need separate implementation and callback to allow use of the same code
841  * during progressive read, where the io_ptr is set internally by libpng.
842  */
843 static void
844 store_read_imp(png_store *ps, png_bytep pb, png_size_t st)
845 {
846    if (ps->current == NULL || ps->next == NULL)
847       png_error(ps->pread, "store state damaged");
848
849    while (st > 0)
850    {
851       size_t cbAvail = store_read_buffer_size(ps) - ps->readpos;
852
853       if (cbAvail > 0)
854       {
855          if (cbAvail > st) cbAvail = st;
856          memcpy(pb, ps->next->buffer + ps->readpos, cbAvail);
857          st -= cbAvail;
858          pb += cbAvail;
859          ps->readpos += cbAvail;
860       }
861
862       else if (!store_read_buffer_next(ps))
863          png_error(ps->pread, "read beyond end of file");
864    }
865 }
866
867 static void
868 store_read(png_structp pp, png_bytep pb, png_size_t st)
869 {
870    png_store *ps = png_get_io_ptr(pp);
871
872    if (ps == NULL || ps->pread != pp)
873       png_error(pp, "bad store read call");
874
875    store_read_imp(ps, pb, st);
876 }
877
878 static void
879 store_progressive_read(png_store *ps, png_structp pp, png_infop pi)
880 {
881    /* Notice that a call to store_read will cause this function to fail because
882     * readpos will be set.
883     */
884    if (ps->pread != pp || ps->current == NULL || ps->next == NULL)
885       png_error(pp, "store state damaged (progressive)");
886
887    do
888    {
889       if (ps->readpos != 0)
890          png_error(pp, "store_read called during progressive read");
891
892       png_process_data(pp, pi, ps->next->buffer, store_read_buffer_size(ps));
893    }
894    while (store_read_buffer_next(ps));
895 }
896
897 /***************************** MEMORY MANAGEMENT*** ***************************/
898 /* A store_memory is simply the header for an allocated block of memory.  The
899  * pointer returned to libpng is just after the end of the header block, the
900  * allocated memory is followed by a second copy of the 'mark'.
901  */
902 typedef struct store_memory
903 {
904    store_pool          *pool;    /* Originating pool */
905    struct store_memory *next;    /* Singly linked list */
906    png_alloc_size_t     size;    /* Size of memory allocated */
907    png_byte             mark[4]; /* ID marker */
908 } store_memory;
909
910 /* Handle a fatal error in memory allocation.  This calls png_error if the
911  * libpng struct is non-NULL, else it outputs a message and returns.  This means
912  * that a memory problem while libpng is running will abort (png_error) the
913  * handling of particular file while one in cleanup (after the destroy of the
914  * struct has returned) will simply keep going and free (or attempt to free)
915  * all the memory.
916  */
917 static void
918 store_pool_error(png_store *ps, png_structp pp, PNG_CONST char *msg)
919 {
920    if (pp != NULL)
921       png_error(pp, msg);
922
923    /* Else we have to do it ourselves.  png_error eventually calls store_log,
924     * above.  store_log accepts a NULL png_structp - it just changes what gets
925     * output by store_message.
926     */
927    store_log(ps, pp, msg, 1 /* error */);
928 }
929
930 static void
931 store_memory_free(png_structp pp, store_pool *pool, store_memory *memory)
932 {
933    /* Note that pp may be NULL (see store_pool_delete below), the caller has
934     * found 'memory' in pool->list *and* unlinked this entry, so this is a valid
935     * pointer (for sure), but the contents may have been trashed.
936     */
937    if (memory->pool != pool)
938       store_pool_error(pool->store, pp, "memory corrupted (pool)");
939
940    else if (memcmp(memory->mark, pool->mark, sizeof memory->mark) != 0)
941       store_pool_error(pool->store, pp, "memory corrupted (start)");
942
943    /* It should be safe to read the size field now. */
944    else
945    {
946       png_alloc_size_t cb = memory->size;
947
948       if (cb > pool->max)
949          store_pool_error(pool->store, pp, "memory corrupted (size)");
950
951       else if (memcmp((png_bytep)(memory+1)+cb, pool->mark, sizeof pool->mark)
952          != 0)
953          store_pool_error(pool->store, pp, "memory corrupted (end)");
954
955       /* Finally give the library a chance to find problems too: */
956       else
957          {
958          pool->current -= cb;
959          free(memory);
960          }
961    }
962 }
963
964 static void
965 store_pool_delete(png_store *ps, store_pool *pool)
966 {
967    if (pool->list != NULL)
968    {
969       fprintf(stderr, "%s: %s %s: memory lost (list follows):\n", ps->test,
970          pool == &ps->read_memory_pool ? "read" : "write",
971          pool == &ps->read_memory_pool ? (ps->current != NULL ?
972             ps->current->name : "unknown file") : ps->wname);
973       ++ps->nerrors;
974
975       do
976       {
977          store_memory *next = pool->list;
978          pool->list = next->next;
979          next->next = NULL;
980
981          fprintf(stderr, "\t%lu bytes @ %p\n",
982              (unsigned long)next->size, (PNG_CONST void*)(next+1));
983          /* The NULL means this will always return, even if the memory is
984           * corrupted.
985           */
986          store_memory_free(NULL, pool, next);
987       }
988       while (pool->list != NULL);
989    }
990
991    /* And reset the other fields too for the next time. */
992    if (pool->max > pool->max_max) pool->max_max = pool->max;
993    pool->max = 0;
994    if (pool->current != 0) /* unexpected internal error */
995       fprintf(stderr, "%s: %s %s: memory counter mismatch (internal error)\n",
996          ps->test, pool == &ps->read_memory_pool ? "read" : "write",
997          pool == &ps->read_memory_pool ? (ps->current != NULL ?
998             ps->current->name : "unknown file") : ps->wname);
999    pool->current = 0;
1000
1001    if (pool->limit > pool->max_limit)
1002       pool->max_limit = pool->limit;
1003
1004    pool->limit = 0;
1005
1006    if (pool->total > pool->max_total)
1007       pool->max_total = pool->total;
1008
1009    pool->total = 0;
1010
1011    /* Get a new mark too. */
1012    store_pool_mark(pool->mark);
1013 }
1014
1015 /* The memory callbacks: */
1016 static png_voidp
1017 store_malloc(png_structp pp, png_alloc_size_t cb)
1018 {
1019    store_pool *pool = png_get_mem_ptr(pp);
1020    store_memory *new = malloc(cb + (sizeof *new) + (sizeof pool->mark));
1021
1022    if (new != NULL)
1023    {
1024       if (cb > pool->max)
1025          pool->max = cb;
1026
1027       pool->current += cb;
1028
1029       if (pool->current > pool->limit)
1030          pool->limit = pool->current;
1031
1032       pool->total += cb;
1033
1034       new->size = cb;
1035       memcpy(new->mark, pool->mark, sizeof new->mark);
1036       memcpy((png_byte*)(new+1) + cb, pool->mark, sizeof pool->mark);
1037       new->pool = pool;
1038       new->next = pool->list;
1039       pool->list = new;
1040       ++new;
1041    }
1042
1043    else
1044       store_pool_error(pool->store, pp, "out of memory");
1045
1046    return new;
1047 }
1048
1049 static void
1050 store_free(png_structp pp, png_voidp memory)
1051 {
1052    store_pool *pool = png_get_mem_ptr(pp);
1053    store_memory *this = memory, **test;
1054
1055    /* First check that this 'memory' really is valid memory - it must be in the
1056     * pool list.  If it is, use the shared memory_free function to free it.
1057     */
1058    --this;
1059    for (test = &pool->list; *test != this; test = &(*test)->next)
1060    {
1061       if (*test == NULL)
1062       {
1063          store_pool_error(pool->store, pp, "bad pointer to free");
1064          return;
1065       }
1066    }
1067
1068    /* Unlink this entry, *test == this. */
1069    *test = this->next;
1070    this->next = NULL;
1071    store_memory_free(pp, pool, this);
1072 }
1073
1074 /* Setup functions. */
1075 /* Cleanup when aborting a write or after storing the new file. */
1076 static void
1077 store_write_reset(png_store *ps)
1078 {
1079    if (ps->pwrite != NULL)
1080    {
1081       anon_context(ps);
1082
1083       Try
1084          png_destroy_write_struct(&ps->pwrite, &ps->piwrite);
1085
1086       Catch_anonymous
1087       {
1088          /* memory corruption: continue. */
1089       }
1090
1091       ps->pwrite = NULL;
1092       ps->piwrite = NULL;
1093    }
1094
1095    /* And make sure that all the memory has been freed - this will output
1096     * spurious errors in the case of memory corruption above, but this is safe.
1097     */
1098    store_pool_delete(ps, &ps->write_memory_pool);
1099
1100    store_freenew(ps);
1101 }
1102
1103 /* The following is the main write function, it returns a png_struct and,
1104  * optionally, a png_info suitable for writiing a new PNG file.  Use
1105  * store_storefile above to record this file after it has been written.  The
1106  * returned libpng structures as destroyed by store_write_reset above.
1107  */
1108 static png_structp
1109 set_store_for_write(png_store *ps, png_infopp ppi,
1110    PNG_CONST char * volatile name)
1111 {
1112    anon_context(ps);
1113
1114    Try
1115    {
1116       if (ps->pwrite != NULL)
1117          png_error(ps->pwrite, "write store already in use");
1118
1119       store_write_reset(ps);
1120       safecat(ps->wname, sizeof ps->wname, 0, name);
1121
1122       /* Don't do the slow memory checks if doing a speed test. */
1123       if (ps->speed)
1124          ps->pwrite = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1125             ps, store_error, store_warning);
1126
1127       else
1128          ps->pwrite = png_create_write_struct_2(PNG_LIBPNG_VER_STRING,
1129             ps, store_error, store_warning, &ps->write_memory_pool,
1130             store_malloc, store_free);
1131
1132       png_set_write_fn(ps->pwrite, ps, store_write, store_flush);
1133
1134       if (ppi != NULL)
1135          *ppi = ps->piwrite = png_create_info_struct(ps->pwrite);
1136    }
1137
1138    Catch_anonymous
1139       return NULL;
1140
1141    return ps->pwrite;
1142 }
1143
1144 /* Cleanup when finished reading (either due to error or in the success case).
1145  */
1146 static void
1147 store_read_reset(png_store *ps)
1148 {
1149    if (ps->pread != NULL)
1150    {
1151       anon_context(ps);
1152
1153       Try
1154          png_destroy_read_struct(&ps->pread, &ps->piread, NULL);
1155
1156       Catch_anonymous
1157       {
1158          /* error already output: continue */
1159       }
1160
1161       ps->pread = NULL;
1162       ps->piread = NULL;
1163    }
1164
1165    /* Always do this to be safe. */
1166    store_pool_delete(ps, &ps->read_memory_pool);
1167
1168    ps->current = NULL;
1169    ps->next = NULL;
1170    ps->readpos = 0;
1171    ps->validated = 0;
1172 }
1173
1174 static void
1175 store_read_set(png_store *ps, png_uint_32 id)
1176 {
1177    png_store_file *pf = ps->saved;
1178
1179    while (pf != NULL)
1180    {
1181       if (pf->id == id)
1182       {
1183          ps->current = pf;
1184          ps->next = NULL;
1185          store_read_buffer_next(ps);
1186          return;
1187       }
1188
1189       pf = pf->next;
1190    }
1191
1192       {
1193       size_t pos;
1194       char msg[FILE_NAME_SIZE+64];
1195
1196       pos = standard_name_from_id(msg, sizeof msg, 0, id);
1197       pos = safecat(msg, sizeof msg, pos, ": file not found");
1198       png_error(ps->pread, msg);
1199       }
1200 }
1201
1202 /* The main interface for reading a saved file - pass the id number of the file
1203  * to retrieve.  Ids must be unique or the earlier file will be hidden.  The API
1204  * returns a png_struct and, optionally, a png_info.  Both of these will be
1205  * destroyed by store_read_reset above.
1206  */
1207 static png_structp
1208 set_store_for_read(png_store *ps, png_infopp ppi, png_uint_32 id,
1209    PNG_CONST char *name)
1210 {
1211    /* Set the name for png_error */
1212    safecat(ps->test, sizeof ps->test, 0, name);
1213
1214    if (ps->pread != NULL)
1215       png_error(ps->pread, "read store already in use");
1216
1217    store_read_reset(ps);
1218
1219    /* Both the create APIs can return NULL if used in their default mode
1220     * (because there is no other way of handling an error because the jmp_buf
1221     * by default is stored in png_struct and that has not been allocated!)
1222     * However, given that store_error works correctly in these circumstances
1223     * we don't ever expect NULL in this program.
1224     */
1225    if (ps->speed)
1226       ps->pread = png_create_read_struct(PNG_LIBPNG_VER_STRING, ps,
1227           store_error, store_warning);
1228
1229    else
1230       ps->pread = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, ps,
1231           store_error, store_warning, &ps->read_memory_pool, store_malloc,
1232           store_free);
1233
1234    if (ps->pread == NULL)
1235    {
1236       struct exception_context *the_exception_context = &ps->exception_context;
1237
1238       store_log(ps, NULL, "png_create_read_struct returned NULL (unexpected)",
1239          1 /*error*/);
1240
1241       Throw ps;
1242    }
1243
1244    store_read_set(ps, id);
1245
1246    if (ppi != NULL)
1247       *ppi = ps->piread = png_create_info_struct(ps->pread);
1248
1249    return ps->pread;
1250 }
1251
1252 /* The overall cleanup of a store simply calls the above then removes all the
1253  * saved files.  This does not delete the store itself.
1254  */
1255 static void
1256 store_delete(png_store *ps)
1257 {
1258    store_write_reset(ps);
1259    store_read_reset(ps);
1260    store_freefile(&ps->saved);
1261
1262    if (ps->image != NULL)
1263    {
1264       free(ps->image-1);
1265       ps->image = NULL;
1266       ps->cb_image = 0;
1267    }
1268 }
1269
1270 /*********************** PNG FILE MODIFICATION ON READ ************************/
1271 /* Files may be modified on read.  The following structure contains a complete
1272  * png_store together with extra members to handle modification and a special
1273  * read callback for libpng.  To use this the 'modifications' field must be set
1274  * to a list of png_modification structures that actually perform the
1275  * modification, otherwise a png_modifier is functionally equivalent to a
1276  * png_store.  There is a special read function, set_modifier_for_read, which
1277  * replaces set_store_for_read.
1278  */
1279 typedef struct png_modifier
1280 {
1281    png_store               this;             /* I am a png_store */
1282    struct png_modification *modifications;   /* Changes to make */
1283
1284    enum modifier_state
1285    {
1286       modifier_start,                        /* Initial value */
1287       modifier_signature,                    /* Have a signature */
1288       modifier_IHDR                          /* Have an IHDR */
1289    }                        state;           /* My state */
1290
1291    /* Information from IHDR: */
1292    png_byte                 bit_depth;       /* From IHDR */
1293    png_byte                 colour_type;     /* From IHDR */
1294
1295    /* While handling PLTE, IDAT and IEND these chunks may be pended to allow
1296     * other chunks to be inserted.
1297     */
1298    png_uint_32              pending_len;
1299    png_uint_32              pending_chunk;
1300
1301    /* Test values */
1302    double                  *gammas;
1303    unsigned int             ngammas;
1304
1305    /* Lowest sbit to test (libpng fails for sbit < 8) */
1306    png_byte                 sbitlow;
1307
1308    /* Error control - these are the limits on errors accepted by the gamma tests
1309     * below.
1310     */
1311    double                   maxout8;  /* Maximum output value error */
1312    double                   maxabs8;  /* Absolute sample error 0..1 */
1313    double                   maxpc8;   /* Percentage sample error 0..100% */
1314    double                   maxout16; /* Maximum output value error */
1315    double                   maxabs16; /* Absolute sample error 0..1 */
1316    double                   maxpc16;  /* Percentage sample error 0..100% */
1317
1318    /* Logged 8 and 16 bit errors ('output' values): */
1319    double                   error_gray_2;
1320    double                   error_gray_4;
1321    double                   error_gray_8;
1322    double                   error_gray_16;
1323    double                   error_color_8;
1324    double                   error_color_16;
1325
1326    /* Flags: */
1327    /* Whether or not to interlace. */
1328    int                      interlace_type :9; /* int, but must store '1' */
1329
1330    /* Run the standard tests? */
1331    unsigned int             test_standard :1;
1332
1333    /* Run the odd-sized image and interlace read/write tests? */
1334    unsigned int             test_size :1;
1335
1336    /* Run tests on reading with a combiniation of transforms, */
1337    unsigned int             test_transform :1;
1338
1339    /* When to use the use_input_precision option: */
1340    unsigned int             use_input_precision :1;
1341    unsigned int             use_input_precision_sbit :1;
1342    unsigned int             use_input_precision_16to8 :1;
1343
1344    /* Which gamma tests to run: */
1345    unsigned int             test_gamma_threshold :1;
1346    unsigned int             test_gamma_transform :1; /* main tests */
1347    unsigned int             test_gamma_sbit :1;
1348    unsigned int             test_gamma_strip16 :1;
1349
1350    unsigned int             log :1;   /* Log max error */
1351
1352    /* Buffer information, the buffer size limits the size of the chunks that can
1353     * be modified - they must fit (including header and CRC) into the buffer!
1354     */
1355    size_t                   flush;           /* Count of bytes to flush */
1356    size_t                   buffer_count;    /* Bytes in buffer */
1357    size_t                   buffer_position; /* Position in buffer */
1358    png_byte                 buffer[1024];
1359 } png_modifier;
1360
1361 static double abserr(png_modifier *pm, png_byte bit_depth)
1362 {
1363    return bit_depth == 16 ? pm->maxabs16 : pm->maxabs8;
1364 }
1365
1366 static double pcerr(png_modifier *pm, png_byte bit_depth)
1367 {
1368    return (bit_depth == 16 ? pm->maxpc16 : pm->maxpc8) * .01;
1369 }
1370
1371 static double outerr(png_modifier *pm, png_byte bit_depth)
1372 {
1373    /* There is a serious error in the 2 and 4 bit grayscale transform because
1374     * the gamma table value (8 bits) is simply shifted, not rounded, so the
1375     * error in 4 bit greyscale gamma is up to the value below.  This is a hack
1376     * to allow pngvalid to succeed:
1377     */
1378    if (bit_depth == 2)
1379       return .73182-.5;
1380
1381    if (bit_depth == 4)
1382       return .90644-.5;
1383
1384    if (bit_depth == 16)
1385      return pm->maxout16;
1386
1387    return pm->maxout8;
1388 }
1389
1390 /* This returns true if the test should be stopped now because it has already
1391  * failed and it is running silently.
1392  */
1393 static int fail(png_modifier *pm)
1394 {
1395    return !pm->log && !pm->this.verbose && (pm->this.nerrors > 0 ||
1396        (pm->this.treat_warnings_as_errors && pm->this.nwarnings > 0));
1397 }
1398
1399 static void
1400 modifier_init(png_modifier *pm)
1401 {
1402    memset(pm, 0, sizeof *pm);
1403    store_init(&pm->this);
1404    pm->modifications = NULL;
1405    pm->state = modifier_start;
1406    pm->sbitlow = 1U;
1407    pm->maxout8 = pm->maxpc8 = pm->maxabs8 = 0;
1408    pm->maxout16 = pm->maxpc16 = pm->maxabs16 = 0;
1409    pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = 0;
1410    pm->error_gray_16 = pm->error_color_8 = pm->error_color_16 = 0;
1411    pm->interlace_type = PNG_INTERLACE_NONE;
1412    pm->test_standard = 0;
1413    pm->test_size = 0;
1414    pm->test_transform = 0;
1415    pm->use_input_precision = 0;
1416    pm->use_input_precision_sbit = 0;
1417    pm->use_input_precision_16to8 = 0;
1418    pm->test_gamma_threshold = 0;
1419    pm->test_gamma_transform = 0;
1420    pm->test_gamma_sbit = 0;
1421    pm->test_gamma_strip16 = 0;
1422    pm->log = 0;
1423
1424    /* Rely on the memset for all the other fields - there are no pointers */
1425 }
1426
1427 /* One modification structure must be provided for each chunk to be modified (in
1428  * fact more than one can be provided if multiple separate changes are desired
1429  * for a single chunk.)  Modifications include adding a new chunk when a
1430  * suitable chunk does not exist.
1431  *
1432  * The caller of modify_fn will reset the CRC of the chunk and record 'modified'
1433  * or 'added' as appropriate if the modify_fn returns 1 (true).  If the
1434  * modify_fn is NULL the chunk is simply removed.
1435  */
1436 typedef struct png_modification
1437 {
1438    struct png_modification *next;
1439    png_uint_32              chunk;
1440
1441    /* If the following is NULL all matching chunks will be removed: */
1442    int                    (*modify_fn)(struct png_modifier *pm,
1443                                struct png_modification *me, int add);
1444
1445    /* If the following is set to PLTE, IDAT or IEND and the chunk has not been
1446     * found and modified (and there is a modify_fn) the modify_fn will be called
1447     * to add the chunk before the relevant chunk.
1448     */
1449    png_uint_32              add;
1450    unsigned int             modified :1;     /* Chunk was modified */
1451    unsigned int             added    :1;     /* Chunk was added */
1452    unsigned int             removed  :1;     /* Chunk was removed */
1453 } png_modification;
1454
1455 static void modification_reset(png_modification *pmm)
1456 {
1457    if (pmm != NULL)
1458    {
1459       pmm->modified = 0;
1460       pmm->added = 0;
1461       pmm->removed = 0;
1462       modification_reset(pmm->next);
1463    }
1464 }
1465
1466 static void
1467 modification_init(png_modification *pmm)
1468 {
1469    memset(pmm, 0, sizeof *pmm);
1470    pmm->next = NULL;
1471    pmm->chunk = 0;
1472    pmm->modify_fn = NULL;
1473    pmm->add = 0;
1474    modification_reset(pmm);
1475 }
1476
1477 static void
1478 modifier_reset(png_modifier *pm)
1479 {
1480    store_read_reset(&pm->this);
1481    pm->modifications = NULL;
1482    pm->state = modifier_start;
1483    pm->bit_depth = pm->colour_type = 0;
1484    pm->pending_len = pm->pending_chunk = 0;
1485    pm->flush = pm->buffer_count = pm->buffer_position = 0;
1486 }
1487
1488 /* Convenience macros. */
1489 #define CHUNK(a,b,c,d) (((a)<<24)+((b)<<16)+((c)<<8)+(d))
1490 #define CHUNK_IHDR CHUNK(73,72,68,82)
1491 #define CHUNK_PLTE CHUNK(80,76,84,69)
1492 #define CHUNK_IDAT CHUNK(73,68,65,84)
1493 #define CHUNK_IEND CHUNK(73,69,78,68)
1494 #define CHUNK_cHRM CHUNK(99,72,82,77)
1495 #define CHUNK_gAMA CHUNK(103,65,77,65)
1496 #define CHUNK_sBIT CHUNK(115,66,73,84)
1497 #define CHUNK_sRGB CHUNK(115,82,71,66)
1498
1499 /* The guts of modification are performed during a read. */
1500 static void
1501 modifier_crc(png_bytep buffer)
1502 {
1503    /* Recalculate the chunk CRC - a complete chunk must be in
1504     * the buffer, at the start.
1505     */
1506    uInt datalen = png_get_uint_32(buffer);
1507    png_save_uint_32(buffer+datalen+8, crc32(0L, buffer+4, datalen+4));
1508 }
1509
1510 static void
1511 modifier_setbuffer(png_modifier *pm)
1512 {
1513    modifier_crc(pm->buffer);
1514    pm->buffer_count = png_get_uint_32(pm->buffer)+12;
1515    pm->buffer_position = 0;
1516 }
1517
1518 /* Separate the callback into the actual implementation (which is passed the
1519  * png_modifier explicitly) and the callback, which gets the modifier from the
1520  * png_struct.
1521  */
1522 static void
1523 modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st)
1524 {
1525    while (st > 0)
1526    {
1527       size_t cb;
1528       png_uint_32 len, chunk;
1529       png_modification *mod;
1530
1531       if (pm->buffer_position >= pm->buffer_count) switch (pm->state)
1532       {
1533          static png_byte sign[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
1534          case modifier_start:
1535             store_read_imp(&pm->this, pm->buffer, 8); /* size of signature. */
1536             pm->buffer_count = 8;
1537             pm->buffer_position = 0;
1538
1539             if (memcmp(pm->buffer, sign, 8) != 0)
1540                png_error(pm->this.pread, "invalid PNG file signature");
1541             pm->state = modifier_signature;
1542             break;
1543
1544          case modifier_signature:
1545             store_read_imp(&pm->this, pm->buffer, 13+12); /* size of IHDR */
1546             pm->buffer_count = 13+12;
1547             pm->buffer_position = 0;
1548
1549             if (png_get_uint_32(pm->buffer) != 13 ||
1550                 png_get_uint_32(pm->buffer+4) != CHUNK_IHDR)
1551                png_error(pm->this.pread, "invalid IHDR");
1552
1553             /* Check the list of modifiers for modifications to the IHDR. */
1554             mod = pm->modifications;
1555             while (mod != NULL)
1556             {
1557                if (mod->chunk == CHUNK_IHDR && mod->modify_fn &&
1558                    (*mod->modify_fn)(pm, mod, 0))
1559                   {
1560                   mod->modified = 1;
1561                   modifier_setbuffer(pm);
1562                   }
1563
1564                /* Ignore removal or add if IHDR! */
1565                mod = mod->next;
1566             }
1567
1568             /* Cache information from the IHDR (the modified one.) */
1569             pm->bit_depth = pm->buffer[8+8];
1570             pm->colour_type = pm->buffer[8+8+1];
1571
1572             pm->state = modifier_IHDR;
1573             pm->flush = 0;
1574             break;
1575
1576          case modifier_IHDR:
1577          default:
1578             /* Read a new chunk and process it until we see PLTE, IDAT or
1579              * IEND.  'flush' indicates that there is still some data to
1580              * output from the preceding chunk.
1581              */
1582             if ((cb = pm->flush) > 0)
1583             {
1584                if (cb > st) cb = st;
1585                pm->flush -= cb;
1586                store_read_imp(&pm->this, pb, cb);
1587                pb += cb;
1588                st -= cb;
1589                if (st <= 0) return;
1590             }
1591
1592             /* No more bytes to flush, read a header, or handle a pending
1593              * chunk.
1594              */
1595             if (pm->pending_chunk != 0)
1596             {
1597                png_save_uint_32(pm->buffer, pm->pending_len);
1598                png_save_uint_32(pm->buffer+4, pm->pending_chunk);
1599                pm->pending_len = 0;
1600                pm->pending_chunk = 0;
1601             }
1602             else
1603                store_read_imp(&pm->this, pm->buffer, 8);
1604
1605             pm->buffer_count = 8;
1606             pm->buffer_position = 0;
1607
1608             /* Check for something to modify or a terminator chunk. */
1609             len = png_get_uint_32(pm->buffer);
1610             chunk = png_get_uint_32(pm->buffer+4);
1611
1612             /* Terminators first, they may have to be delayed for added
1613              * chunks
1614              */
1615             if (chunk == CHUNK_PLTE || chunk == CHUNK_IDAT ||
1616                 chunk == CHUNK_IEND)
1617             {
1618                mod = pm->modifications;
1619
1620                while (mod != NULL)
1621                {
1622                   if ((mod->add == chunk ||
1623                       (mod->add == CHUNK_PLTE && chunk == CHUNK_IDAT)) &&
1624                       mod->modify_fn != NULL && !mod->modified && !mod->added)
1625                   {
1626                      /* Regardless of what the modify function does do not run
1627                       * this again.
1628                       */
1629                      mod->added = 1;
1630
1631                      if ((*mod->modify_fn)(pm, mod, 1 /*add*/))
1632                      {
1633                         /* Reset the CRC on a new chunk */
1634                         if (pm->buffer_count > 0)
1635                            modifier_setbuffer(pm);
1636
1637                         else
1638                            {
1639                            pm->buffer_position = 0;
1640                            mod->removed = 1;
1641                            }
1642
1643                         /* The buffer has been filled with something (we assume)
1644                          * so output this.  Pend the current chunk.
1645                          */
1646                         pm->pending_len = len;
1647                         pm->pending_chunk = chunk;
1648                         break; /* out of while */
1649                      }
1650                   }
1651
1652                   mod = mod->next;
1653                }
1654
1655                /* Don't do any further processing if the buffer was modified -
1656                 * otherwise the code will end up modifying a chunk that was
1657                 * just added.
1658                 */
1659                if (mod != NULL)
1660                   break; /* out of switch */
1661             }
1662
1663             /* If we get to here then this chunk may need to be modified.  To
1664              * do this it must be less than 1024 bytes in total size, otherwise
1665              * it just gets flushed.
1666              */
1667             if (len+12 <= sizeof pm->buffer)
1668             {
1669                store_read_imp(&pm->this, pm->buffer+pm->buffer_count,
1670                    len+12-pm->buffer_count);
1671                pm->buffer_count = len+12;
1672
1673                /* Check for a modification, else leave it be. */
1674                mod = pm->modifications;
1675                while (mod != NULL)
1676                {
1677                   if (mod->chunk == chunk)
1678                   {
1679                      if (mod->modify_fn == NULL)
1680                      {
1681                         /* Remove this chunk */
1682                         pm->buffer_count = pm->buffer_position = 0;
1683                         mod->removed = 1;
1684                         break; /* Terminate the while loop */
1685                      }
1686
1687                      else if ((*mod->modify_fn)(pm, mod, 0))
1688                      {
1689                         mod->modified = 1;
1690                         /* The chunk may have been removed: */
1691                         if (pm->buffer_count == 0)
1692                         {
1693                            pm->buffer_position = 0;
1694                            break;
1695                         }
1696                         modifier_setbuffer(pm);
1697                      }
1698                   }
1699
1700                   mod = mod->next;
1701                }
1702             }
1703
1704             else
1705                pm->flush = len+12 - pm->buffer_count; /* data + crc */
1706
1707             /* Take the data from the buffer (if there is any). */
1708             break;
1709       }
1710
1711       /* Here to read from the modifier buffer (not directly from
1712        * the store, as in the flush case above.)
1713        */
1714       cb = pm->buffer_count - pm->buffer_position;
1715
1716       if (cb > st)
1717          cb = st;
1718
1719       memcpy(pb, pm->buffer + pm->buffer_position, cb);
1720       st -= cb;
1721       pb += cb;
1722       pm->buffer_position += cb;
1723    }
1724 }
1725
1726 /* The callback: */
1727 static void
1728 modifier_read(png_structp pp, png_bytep pb, png_size_t st)
1729 {
1730    png_modifier *pm = png_get_io_ptr(pp);
1731
1732    if (pm == NULL || pm->this.pread != pp)
1733       png_error(pp, "bad modifier_read call");
1734
1735    modifier_read_imp(pm, pb, st);
1736 }
1737
1738 /* Like store_progressive_read but the data is getting changed as we go so we
1739  * need a local buffer.
1740  */
1741 static void
1742 modifier_progressive_read(png_modifier *pm, png_structp pp, png_infop pi)
1743 {
1744    if (pm->this.pread != pp || pm->this.current == NULL ||
1745        pm->this.next == NULL)
1746       png_error(pp, "store state damaged (progressive)");
1747
1748    /* This is another Horowitz and Hill random noise generator.  In this case
1749     * the aim is to stress the progressive reader with truely horrible variable
1750     * buffer sizes in the range 1..500, so a sequence of 9 bit random numbers
1751     * is generated.  We could probably just count from 1 to 32767 and get as
1752     * good a result.
1753     */
1754    for (;;)
1755    {
1756       static png_uint_32 noise = 1;
1757       png_size_t cb, cbAvail;
1758       png_byte buffer[512];
1759
1760       /* Generate 15 more bits of stuff: */
1761       noise = (noise << 9) | ((noise ^ (noise >> (9-5))) & 0x1ff);
1762       cb = noise & 0x1ff;
1763
1764       /* Check that this number of bytes are available (in the current buffer.)
1765        * (This doesn't quite work - the modifier might delete a chunk; unlikely
1766        * but possible, it doesn't happen at present because the modifier only
1767        * adds chunks to standard images.)
1768        */
1769       cbAvail = store_read_buffer_avail(&pm->this);
1770       if (pm->buffer_count > pm->buffer_position)
1771          cbAvail += pm->buffer_count - pm->buffer_position;
1772
1773       if (cb > cbAvail)
1774       {
1775          /* Check for EOF: */
1776          if (cbAvail == 0)
1777             break;
1778
1779          cb = cbAvail;
1780       }
1781
1782       modifier_read_imp(pm, buffer, cb);
1783       png_process_data(pp, pi, buffer, cb);
1784    }
1785
1786    /* Check the invariants at the end (if this fails it's a problem in this
1787     * file!)
1788     */
1789    if (pm->buffer_count > pm->buffer_position ||
1790        pm->this.next != &pm->this.current->data ||
1791        pm->this.readpos < pm->this.current->datacount)
1792       png_error(pp, "progressive read implementation error");
1793 }
1794
1795 /* Set up a modifier. */
1796 static png_structp
1797 set_modifier_for_read(png_modifier *pm, png_infopp ppi, png_uint_32 id,
1798     PNG_CONST char *name)
1799 {
1800    /* Do this first so that the modifier fields are cleared even if an error
1801     * happens allocating the png_struct.  No allocation is done here so no
1802     * cleanup is required.
1803     */
1804    pm->state = modifier_start;
1805    pm->bit_depth = 0;
1806    pm->colour_type = 255;
1807
1808    pm->pending_len = 0;
1809    pm->pending_chunk = 0;
1810    pm->flush = 0;
1811    pm->buffer_count = 0;
1812    pm->buffer_position = 0;
1813
1814    return set_store_for_read(&pm->this, ppi, id, name);
1815 }
1816
1817 /***************************** STANDARD PNG FILES *****************************/
1818 /* Standard files - write and save standard files. */
1819 /* There are two basic forms of standard images.  Those which attempt to have
1820  * all the possible pixel values (not possible for 16bpp images, but a range of
1821  * values are produced) and those which have a range of image sizes.  The former
1822  * are used for testing transforms, in particular gamma correction and bit
1823  * reduction and increase.  The latter are reserved for testing the behavior of
1824  * libpng with respect to 'odd' image sizes - particularly small images where
1825  * rows become 1 byte and interlace passes disappear.
1826  *
1827  * The first, most useful, set are the 'transform' images, the second set of
1828  * small images are the 'size' images.
1829  *
1830  * The transform files are constructed with rows which fit into a 1024 byte row
1831  * buffer.  This makes allocation easier below.  Further regardless of the file
1832  * format every row has 128 pixels (giving 1024 bytes for 64bpp formats).
1833  *
1834  * Files are stored with no gAMA or sBIT chunks, with a PLTE only when needed
1835  * and with an ID derived from the colour type, bit depth and interlace type
1836  * as above (FILEID).  The width (128) and height (variable) are not stored in
1837  * the FILEID - instead the fields are set to 0, indicating a transform file.
1838  *
1839  * The size files ar constructed with rows a maximum of 128 bytes wide, allowing
1840  * a maximum width of 16 pixels (for the 64bpp case.)  They also have a maximum
1841  * height of 16 rows.  The width and height are stored in the FILEID and, being
1842  * non-zero, indicate a size file.
1843  */
1844
1845 /* The number of passes is related to the interlace type. There wass no libpng
1846  * API to determine this prior to 1.5, so we need an inquiry function:
1847  */
1848 static int
1849 npasses_from_interlace_type(png_structp pp, int interlace_type)
1850 {
1851    switch (interlace_type)
1852    {
1853    default:
1854       png_error(pp, "invalid interlace type");
1855
1856    case PNG_INTERLACE_NONE:
1857       return 1;
1858
1859    case PNG_INTERLACE_ADAM7:
1860       return PNG_INTERLACE_ADAM7_PASSES;
1861    }
1862 }
1863
1864 static unsigned int
1865 bit_size(png_structp pp, png_byte colour_type, png_byte bit_depth)
1866 {
1867    switch (colour_type)
1868    {
1869       case 0:  return bit_depth;
1870
1871       case 2:  return 3*bit_depth;
1872
1873       case 3:  return bit_depth;
1874
1875       case 4:  return 2*bit_depth;
1876
1877       case 6:  return 4*bit_depth;
1878
1879       default: png_error(pp, "invalid color type");
1880    }
1881 }
1882
1883 #define TRANSFORM_WIDTH  128U
1884 #define TRANSFORM_ROWMAX (TRANSFORM_WIDTH*8U)
1885 #define SIZE_ROWMAX (16*8U) /* 16 pixels, max 8 bytes each - 128 bytes */
1886 #define STANDARD_ROWMAX TRANSFORM_ROWMAX /* The larger of the two */
1887
1888 /* So the maximum image sizes are as follows.  A 'transform' image may require
1889  * more than 65535 bytes.  The size images are a maximum of 2046 bytes.
1890  */
1891 #define TRANSFORM_IMAGEMAX (TRANSFORM_ROWMAX * (png_uint_32)2048)
1892 #define SIZE_IMAGEMAX (SIZE_ROWMAX * 16U)
1893
1894 static size_t
1895 transform_rowsize(png_structp pp, png_byte colour_type, png_byte bit_depth)
1896 {
1897    return (TRANSFORM_WIDTH * bit_size(pp, colour_type, bit_depth)) / 8;
1898 }
1899
1900 /* transform_width(pp, colour_type, bit_depth) current returns the same number
1901  * every time, so just use a macro:
1902  */
1903 #define transform_width(pp, colour_type, bit_depth) TRANSFORM_WIDTH
1904
1905 static png_uint_32
1906 transform_height(png_structp pp, png_byte colour_type, png_byte bit_depth)
1907 {
1908    switch (bit_size(pp, colour_type, bit_depth))
1909    {
1910       case 1:
1911       case 2:
1912       case 4:
1913          return 1;   /* Total of 128 pixels */
1914
1915       case 8:
1916          return 2;   /* Total of 256 pixels/bytes */
1917
1918       case 16:
1919          return 512; /* Total of 65536 pixels */
1920
1921       case 24:
1922       case 32:
1923          return 512; /* 65536 pixels */
1924
1925       case 48:
1926       case 64:
1927          return 2048;/* 4 x 65536 pixels. */
1928
1929       default:
1930          return 0;   /* Error, will be caught later */
1931    }
1932 }
1933
1934 /* The following can only be defined here, now we have the definitions
1935  * of the transform image sizes.
1936  */
1937 static png_uint_32
1938 standard_width(png_structp pp, png_uint_32 id)
1939 {
1940    png_uint_32 width = WIDTH_FROM_ID(id);
1941    UNUSED(pp)
1942
1943    if (width == 0)
1944       width = transform_width(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));
1945
1946    return width;
1947 }
1948
1949 static png_uint_32
1950 standard_height(png_structp pp, png_uint_32 id)
1951 {
1952    png_uint_32 height = HEIGHT_FROM_ID(id);
1953
1954    if (height == 0)
1955       height = transform_height(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));
1956
1957    return height;
1958 }
1959
1960 static png_uint_32
1961 standard_rowsize(png_structp pp, png_uint_32 id)
1962 {
1963    png_uint_32 width = standard_width(pp, id);
1964
1965    /* This won't overflow: */
1966    width *= bit_size(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));
1967    return (width + 7) / 8;
1968 }
1969
1970 static void
1971 transform_row(png_structp pp, png_byte buffer[TRANSFORM_ROWMAX],
1972    png_byte colour_type, png_byte bit_depth, png_uint_32 y)
1973 {
1974    png_uint_32 v = y << 7;
1975    png_uint_32 i = 0;
1976
1977    switch (bit_size(pp, colour_type, bit_depth))
1978    {
1979       case 1:
1980          while (i<128/8) buffer[i] = v & 0xff, v += 17, ++i;
1981          return;
1982
1983       case 2:
1984          while (i<128/4) buffer[i] = v & 0xff, v += 33, ++i;
1985          return;
1986
1987       case 4:
1988          while (i<128/2) buffer[i] = v & 0xff, v += 65, ++i;
1989          return;
1990
1991       case 8:
1992          /* 256 bytes total, 128 bytes in each row set as follows: */
1993          while (i<128) buffer[i] = v & 0xff, ++v, ++i;
1994          return;
1995
1996       case 16:
1997          /* Generate all 65536 pixel values in order, which includes the 8 bit
1998           * GA case as well as the 16 bit G case.
1999           */
2000          while (i<128)
2001             buffer[2*i] = (v>>8) & 0xff, buffer[2*i+1] = v & 0xff, ++v, ++i;
2002
2003          return;
2004
2005       case 24:
2006          /* 65535 pixels, but rotate the values. */
2007          while (i<128)
2008          {
2009             /* Three bytes per pixel, r, g, b, make b by r^g */
2010             buffer[3*i+0] = (v >> 8) & 0xff;
2011             buffer[3*i+1] = v & 0xff;
2012             buffer[3*i+2] = ((v >> 8) ^ v) & 0xff;
2013             ++v;
2014             ++i;
2015          }
2016
2017          return;
2018
2019       case 32:
2020          /* 65535 pixels, r, g, b, a; just replicate */
2021          while (i<128)
2022          {
2023             buffer[4*i+0] = (v >> 8) & 0xff;
2024             buffer[4*i+1] = v & 0xff;
2025             buffer[4*i+2] = (v >> 8) & 0xff;
2026             buffer[4*i+3] = v & 0xff;
2027             ++v;
2028             ++i;
2029          }
2030
2031          return;
2032
2033       case 48:
2034          /* y is maximum 2047, giving 4x65536 pixels, make 'r' increase by 1 at
2035           * each pixel, g increase by 257 (0x101) and 'b' by 0x1111:
2036           */
2037          while (i<128)
2038          {
2039             png_uint_32 t = v++;
2040             buffer[6*i+0] = (t >> 8) & 0xff;
2041             buffer[6*i+1] = t & 0xff;
2042             t *= 257;
2043             buffer[6*i+2] = (t >> 8) & 0xff;
2044             buffer[6*i+3] = t & 0xff;
2045             t *= 17;
2046             buffer[6*i+4] = (t >> 8) & 0xff;
2047             buffer[6*i+5] = t & 0xff;
2048             ++i;
2049          }
2050
2051          return;
2052
2053       case 64:
2054          /* As above in the 32 bit case. */
2055          while (i<128)
2056          {
2057             png_uint_32 t = v++;
2058             buffer[8*i+0] = (t >> 8) & 0xff;
2059             buffer[8*i+1] = t & 0xff;
2060             buffer[8*i+4] = (t >> 8) & 0xff;
2061             buffer[8*i+5] = t & 0xff;
2062             t *= 257;
2063             buffer[8*i+2] = (t >> 8) & 0xff;
2064             buffer[8*i+3] = t & 0xff;
2065             buffer[8*i+6] = (t >> 8) & 0xff;
2066             buffer[8*i+7] = t & 0xff;
2067             ++i;
2068          }
2069          return;
2070
2071       default:
2072          break;
2073    }
2074
2075    png_error(pp, "internal error");
2076 }
2077
2078 /* This is just to do the right cast - could be changed to a function to check
2079  * 'bd' but there isn't much point.
2080  */
2081 #define DEPTH(bd) ((png_byte)(1U << (bd)))
2082
2083 /* Make a standardized image given a an image colour type, bit depth and
2084  * interlace type.  The standard images have a very restricted range of
2085  * rows and heights and are used for testing transforms rather than image
2086  * layout details.  See make_size_images below for a way to make images
2087  * that test odd sizes along with the libpng interlace handling.
2088  */
2089 static void
2090 make_transform_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type,
2091     png_byte PNG_CONST bit_depth, int interlace_type, png_const_charp name)
2092 {
2093    context(ps, fault);
2094
2095    Try
2096    {
2097       png_infop pi;
2098       png_structp pp = set_store_for_write(ps, &pi, name);
2099       png_uint_32 h;
2100
2101       /* In the event of a problem return control to the Catch statement below
2102        * to do the clean up - it is not possible to 'return' directly from a Try
2103        * block.
2104        */
2105       if (pp == NULL)
2106          Throw ps;
2107
2108       h = transform_height(pp, colour_type, bit_depth);
2109
2110       png_set_IHDR(pp, pi, transform_width(pp, colour_type, bit_depth), h,
2111          bit_depth, colour_type, interlace_type,
2112          PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
2113
2114       if (colour_type == 3) /* palette */
2115       {
2116          unsigned int i = 0;
2117          png_color pal[256];
2118
2119          do
2120             pal[i].red = pal[i].green = pal[i].blue = (png_byte)i;
2121          while(++i < 256U);
2122
2123          png_set_PLTE(pp, pi, pal, 256);
2124       }
2125
2126       png_write_info(pp, pi);
2127
2128       if (png_get_rowbytes(pp, pi) !=
2129           transform_rowsize(pp, colour_type, bit_depth))
2130          png_error(pp, "row size incorrect");
2131
2132       else
2133       {
2134          /* Somewhat confusingly this must be called *after* png_write_info
2135           * because if it is called before, the information in *pp has not been
2136           * updated to reflect the interlaced image.
2137           */
2138          int npasses = png_set_interlace_handling(pp);
2139          int pass;
2140
2141          if (npasses != npasses_from_interlace_type(pp, interlace_type))
2142             png_error(pp, "write: png_set_interlace_handling failed");
2143
2144          for (pass=0; pass<npasses; ++pass)
2145          {
2146             png_uint_32 y;
2147
2148             for (y=0; y<h; ++y)
2149             {
2150                png_byte buffer[TRANSFORM_ROWMAX];
2151
2152                transform_row(pp, buffer, colour_type, bit_depth, y);
2153                png_write_row(pp, buffer);
2154             }
2155          }
2156       }
2157
2158       png_write_end(pp, pi);
2159
2160       /* And store this under the appropriate id, then clean up. */
2161       store_storefile(ps, FILEID(colour_type, bit_depth, interlace_type,
2162          0, 0, 0));
2163
2164       store_write_reset(ps);
2165    }
2166
2167    Catch(fault)
2168    {
2169       /* Use the png_store returned by the exception. This may help the compiler
2170        * because 'ps' is not used in this branch of the setjmp.  Note that fault
2171        * and ps will always be the same value.
2172        */
2173       store_write_reset(fault);
2174    }
2175 }
2176
2177 static void
2178 make_standard(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, int bdlo,
2179     int PNG_CONST bdhi)
2180 {
2181    for (; bdlo <= bdhi; ++bdlo)
2182    {
2183       int interlace_type;
2184
2185       for (interlace_type = PNG_INTERLACE_NONE;
2186            interlace_type < PNG_INTERLACE_LAST; ++interlace_type)
2187       {
2188          char name[FILE_NAME_SIZE];
2189
2190          standard_name(name, sizeof name, 0, colour_type, bdlo, interlace_type,
2191             0, 0, 0);
2192          make_transform_image(ps, colour_type, DEPTH(bdlo), interlace_type,
2193             name);
2194       }
2195    }
2196 }
2197
2198 static void
2199 make_transform_images(png_store *ps)
2200 {
2201    /* This is in case of errors. */
2202    safecat(ps->test, sizeof ps->test, 0, "make standard images");
2203
2204    /* Arguments are colour_type, low bit depth, high bit depth
2205     */
2206    make_standard(ps, 0, 0, WRITE_BDHI);
2207    make_standard(ps, 2, 3, WRITE_BDHI);
2208    make_standard(ps, 3, 0, 3 /*palette: max 8 bits*/);
2209    make_standard(ps, 4, 3, WRITE_BDHI);
2210    make_standard(ps, 6, 3, WRITE_BDHI);
2211 }
2212
2213 /* The following two routines use the PNG interlace support macros from
2214  * png.h to interlace or deinterlace rows.
2215  */
2216 static void
2217 interlace_row(png_bytep buffer, png_const_bytep imageRow,
2218    unsigned int pixel_size, png_uint_32 w, int pass)
2219 {
2220    png_uint_32 xin, xout, xstep;
2221
2222    /* Note that this can, trivially, be optimized to a memcpy on pass 7, the
2223     * code is presented this way to make it easier to understand.  In practice
2224     * consult the code in the libpng source to see other ways of doing this.
2225     */
2226    xin = PNG_PASS_START_COL(pass);
2227    xstep = 1U<<PNG_PASS_COL_SHIFT(pass);
2228
2229    for (xout=0; xin<w; xin+=xstep)
2230    {
2231       pixel_copy(buffer, xout, imageRow, xin, pixel_size);
2232       ++xout;
2233    }
2234 }
2235
2236 static void
2237 deinterlace_row(png_bytep buffer, png_const_bytep row,
2238    unsigned int pixel_size, png_uint_32 w, int pass)
2239 {
2240    /* The inverse of the above, 'row' is part of row 'y' of the output image,
2241     * in 'buffer'.  The image is 'w' wide and this is pass 'pass', distribute
2242     * the pixels of row into buffer and return the number written (to allow
2243     * this to be checked).
2244     */
2245    png_uint_32 xin, xout, xstep;
2246
2247    xout = PNG_PASS_START_COL(pass);
2248    xstep = 1U<<PNG_PASS_COL_SHIFT(pass);
2249
2250    for (xin=0; xout<w; xout+=xstep)
2251    {
2252       pixel_copy(buffer, xout, row, xin, pixel_size);
2253       ++xin;
2254    }
2255 }
2256
2257 /* Build a single row for the 'size' test images, this fills in only the
2258  * first bit_width bits of the sample row.
2259  */
2260 static void
2261 size_row(png_byte buffer[SIZE_ROWMAX], png_uint_32 bit_width, png_uint_32 y)
2262 {
2263    /* height is in the range 1 to 16, so: */
2264    y = ((y & 1) << 7) + ((y & 2) << 6) + ((y & 4) << 5) + ((y & 8) << 4);
2265    /* the following ensures bits are set in small images: */
2266    y ^= 0xA5;
2267
2268    while (bit_width >= 8)
2269       *buffer++ = (png_byte)y++, bit_width -= 8;
2270
2271    /* There may be up to 7 remaining bits, these go in the most significant
2272     * bits of the byte.
2273     */
2274    if (bit_width > 0)
2275    {
2276       png_uint_32 mask = (1U<<(8-bit_width))-1;
2277       *buffer = (png_byte)((*buffer & mask) | (y & ~mask));
2278    }
2279 }
2280
2281 static void
2282 make_size_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type,
2283     png_byte PNG_CONST bit_depth, int PNG_CONST interlace_type,
2284     png_uint_32 PNG_CONST w, png_uint_32 PNG_CONST h,
2285     int PNG_CONST do_interlace)
2286 {
2287    context(ps, fault);
2288
2289    Try
2290    {
2291       png_infop pi;
2292       png_structp pp;
2293       unsigned int pixel_size;
2294
2295       /* Make a name and get an appropriate id for the store: */
2296       char name[FILE_NAME_SIZE];
2297       PNG_CONST png_uint_32 id = FILEID(colour_type, bit_depth, interlace_type,
2298          w, h, do_interlace);
2299
2300       standard_name_from_id(name, sizeof name, 0, id);
2301       pp = set_store_for_write(ps, &pi, name);
2302
2303       /* In the event of a problem return control to the Catch statement below
2304        * to do the clean up - it is not possible to 'return' directly from a Try
2305        * block.
2306        */
2307       if (pp == NULL)
2308          Throw ps;
2309
2310       png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type,
2311          PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
2312
2313       /* Same palette as make_transform_image - I don' think there is any
2314        * benefit from using a different one (JB 20101211)
2315        */
2316       if (colour_type == 3) /* palette */
2317       {
2318          unsigned int i = 0;
2319          png_color pal[256];
2320
2321          do
2322             pal[i].red = pal[i].green = pal[i].blue = (png_byte)i;
2323          while(++i < 256U);
2324
2325          png_set_PLTE(pp, pi, pal, 256);
2326       }
2327
2328       png_write_info(pp, pi);
2329
2330       /* Calculate the bit size, divide by 8 to get the byte size - this won't
2331        * overflow because we know the w values are all small enough even for
2332        * a system where 'unsigned int' is only 16 bits.
2333        */
2334       pixel_size = bit_size(pp, colour_type, bit_depth);
2335       if (png_get_rowbytes(pp, pi) != ((w * pixel_size) + 7) / 8)
2336          png_error(pp, "row size incorrect");
2337
2338       else
2339       {
2340          int npasses = npasses_from_interlace_type(pp, interlace_type);
2341          png_uint_32 y;
2342          int pass;
2343          png_byte image[16][SIZE_ROWMAX];
2344
2345          /* To help consistent error detection make the parts of this buffer
2346           * that aren't set below all '1':
2347           */
2348          memset(image, 0xff, sizeof image);
2349
2350          if (!do_interlace && npasses != png_set_interlace_handling(pp))
2351             png_error(pp, "write: png_set_interlace_handling failed");
2352
2353          /* Prepare the whole image first to avoid making it 7 times: */
2354          for (y=0; y<h; ++y)
2355             size_row(image[y], w * pixel_size, y);
2356
2357          for (pass=0; pass<npasses; ++pass)
2358          {
2359             /* The following two are for checking the macros: */
2360             PNG_CONST png_uint_32 wPass = PNG_PASS_COLS(w, pass);
2361
2362             /* If do_interlace is set we don't call png_write_row for every
2363              * row because some of them are empty.  In fact, for a 1x1 image,
2364              * most of them are empty!
2365              */
2366             for (y=0; y<h; ++y)
2367             {
2368                png_const_bytep row = image[y];
2369                png_byte tempRow[SIZE_ROWMAX];
2370
2371                /* If do_interlace *and* the image is interlaced we
2372                 * need a reduced interlace row, this may be reduced
2373                 * to empty.
2374                 */
2375                if (do_interlace && interlace_type == PNG_INTERLACE_ADAM7)
2376                {
2377                   /* The row must not be written if it doesn't exist, notice
2378                    * that there are two conditions here, either the row isn't
2379                    * ever in the pass or the row would be but isn't wide
2380                    * enough to contribute any pixels.  In fact the wPass test
2381                    * can be used to skip the whole y loop in this case.
2382                    */
2383                   if (PNG_ROW_IN_INTERLACE_PASS(y, pass) && wPass > 0)
2384                   {
2385                      /* Set to all 1's for error detection (libpng tends to
2386                       * set unset things to 0).
2387                       */
2388                      memset(tempRow, 0xff, sizeof tempRow);
2389                      interlace_row(tempRow, row, pixel_size, w, pass);
2390                      row = tempRow;
2391                   }
2392                   else
2393                      continue;
2394                }
2395
2396                /* Only get to here if the row has some pixels in it. */
2397                png_write_row(pp, row);
2398             }
2399          }
2400       }
2401
2402       png_write_end(pp, pi);
2403
2404       /* And store this under the appropriate id, then clean up. */
2405       store_storefile(ps, id);
2406
2407       store_write_reset(ps);
2408    }
2409
2410    Catch(fault)
2411    {
2412       /* Use the png_store returned by the exception. This may help the compiler
2413        * because 'ps' is not used in this branch of the setjmp.  Note that fault
2414        * and ps will always be the same value.
2415        */
2416       store_write_reset(fault);
2417    }
2418 }
2419
2420 static void
2421 make_size(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, int bdlo,
2422     int PNG_CONST bdhi)
2423 {
2424    for (; bdlo <= bdhi; ++bdlo)
2425    {
2426       png_uint_32 width;
2427
2428       for (width = 1; width <= 16; ++width)
2429       {
2430          png_uint_32 height;
2431
2432          for (height = 1; height <= 16; ++height)
2433          {
2434             /* The four combinations of DIY interlace and interlace or not -
2435              * no interlace + DIY should be identical to no interlace with
2436              * libpng doing it.
2437              */
2438             make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE,
2439                width, height, 0);
2440             make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE,
2441                width, height, 1);
2442             make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7,
2443                width, height, 0);
2444             make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7,
2445                width, height, 1);
2446          }
2447       }
2448    }
2449 }
2450
2451 static void
2452 make_size_images(png_store *ps)
2453 {
2454    /* This is in case of errors. */
2455    safecat(ps->test, sizeof ps->test, 0, "make size images");
2456
2457    /* Arguments are colour_type, low bit depth, high bit depth
2458     */
2459    make_size(ps, 0, 0, WRITE_BDHI);
2460    make_size(ps, 2, 3, WRITE_BDHI);
2461    make_size(ps, 3, 0, 3 /*palette: max 8 bits*/);
2462    make_size(ps, 4, 3, WRITE_BDHI);
2463    make_size(ps, 6, 3, WRITE_BDHI);
2464 }
2465
2466 /* Return a row based on image id and 'y' for checking: */
2467 static void
2468 standard_row(png_structp pp, png_byte std[STANDARD_ROWMAX], png_uint_32 id,
2469    png_uint_32 y)
2470 {
2471    if (WIDTH_FROM_ID(id) == 0)
2472       transform_row(pp, std, COL_FROM_ID(id), DEPTH_FROM_ID(id), y);
2473    else
2474       size_row(std, WIDTH_FROM_ID(id) * bit_size(pp, COL_FROM_ID(id),
2475          DEPTH_FROM_ID(id)), y);
2476 }
2477
2478 /* Tests - individual test cases */
2479 /* Like 'make_standard' but errors are deliberately introduced into the calls
2480  * to ensure that they get detected - it should not be possible to write an
2481  * invalid image with libpng!
2482  */
2483 static void
2484 sBIT0_error_fn(png_structp pp, png_infop pi)
2485 {
2486    /* 0 is invalid... */
2487    png_color_8 bad;
2488    bad.red = bad.green = bad.blue = bad.gray = bad.alpha = 0;
2489    png_set_sBIT(pp, pi, &bad);
2490 }
2491
2492 static void
2493 sBIT_error_fn(png_structp pp, png_infop pi)
2494 {
2495    png_byte bit_depth;
2496    png_color_8 bad;
2497
2498    if (png_get_color_type(pp, pi) == PNG_COLOR_TYPE_PALETTE)
2499       bit_depth = 8;
2500
2501    else
2502       bit_depth = png_get_bit_depth(pp, pi);
2503
2504    /* Now we know the bit depth we can easily generate an invalid sBIT entry */
2505    bad.red = bad.green = bad.blue = bad.gray = bad.alpha =
2506       (png_byte)(bit_depth+1);
2507    png_set_sBIT(pp, pi, &bad);
2508 }
2509
2510 static PNG_CONST struct
2511 {
2512    void          (*fn)(png_structp, png_infop);
2513    PNG_CONST char *msg;
2514    unsigned int    warning :1; /* the error is a warning... */
2515 } error_test[] =
2516     {
2517        { sBIT0_error_fn, "sBIT(0): failed to detect error", 1 },
2518        { sBIT_error_fn, "sBIT(too big): failed to detect error", 1 },
2519     };
2520
2521 static void
2522 make_error(png_store* volatile ps, png_byte PNG_CONST colour_type,
2523     png_byte bit_depth, int interlace_type, int test, png_const_charp name)
2524 {
2525    context(ps, fault);
2526
2527    Try
2528    {
2529       png_structp pp;
2530       png_infop pi;
2531
2532       pp = set_store_for_write(ps, &pi, name);
2533
2534       if (pp == NULL)
2535          Throw ps;
2536
2537       png_set_IHDR(pp, pi, transform_width(pp, colour_type, bit_depth),
2538          transform_height(pp, colour_type, bit_depth), bit_depth, colour_type,
2539          interlace_type, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
2540
2541       if (colour_type == 3) /* palette */
2542       {
2543          unsigned int i = 0;
2544          png_color pal[256];
2545
2546          do
2547             pal[i].red = pal[i].green = pal[i].blue = (png_byte)i;
2548          while(++i < 256U);
2549
2550          png_set_PLTE(pp, pi, pal, 256);
2551       }
2552
2553       /* Time for a few errors, these are in various optional chunks, the
2554        * standard tests test the standard chunks pretty well.
2555        */
2556 #     define exception__prev exception_prev_1
2557 #     define exception__env exception_env_1
2558       Try
2559       {
2560          /* Expect this to throw: */
2561          ps->expect_error = !error_test[test].warning;
2562          ps->expect_warning = error_test[test].warning;
2563          ps->saw_warning = 0;
2564          error_test[test].fn(pp, pi);
2565
2566          /* Normally the error is only detected here: */
2567          png_write_info(pp, pi);
2568
2569          /* And handle the case where it was only a warning: */
2570          if (ps->expect_warning && ps->saw_warning)
2571             Throw ps;
2572
2573          /* If we get here there is a problem, we have success - no error or
2574           * no warning - when we shouldn't have success.  Log an error.
2575           */
2576          store_log(ps, pp, error_test[test].msg, 1 /*error*/);
2577       }
2578
2579       Catch (fault)
2580          ps = fault; /* expected exit, make sure ps is not clobbered */
2581 #undef exception__prev
2582 #undef exception__env
2583
2584       /* And clear these flags */
2585       ps->expect_error = 0;
2586       ps->expect_warning = 0;
2587
2588       /* Now write the whole image, just to make sure that the detected, or
2589        * undetected, errro has not created problems inside libpng.
2590        */
2591       if (png_get_rowbytes(pp, pi) !=
2592           transform_rowsize(pp, colour_type, bit_depth))
2593          png_error(pp, "row size incorrect");
2594
2595       else
2596       {
2597          png_uint_32 h = transform_height(pp, colour_type, bit_depth);
2598          int npasses = png_set_interlace_handling(pp);
2599          int pass;
2600
2601          if (npasses != npasses_from_interlace_type(pp, interlace_type))
2602             png_error(pp, "write: png_set_interlace_handling failed");
2603
2604          for (pass=0; pass<npasses; ++pass)
2605          {
2606             png_uint_32 y;
2607
2608             for (y=0; y<h; ++y)
2609             {
2610                png_byte buffer[TRANSFORM_ROWMAX];
2611
2612                transform_row(pp, buffer, colour_type, bit_depth, y);
2613                png_write_row(pp, buffer);
2614             }
2615          }
2616       }
2617
2618       png_write_end(pp, pi);
2619
2620       /* The following deletes the file that was just written. */
2621       store_write_reset(ps);
2622    }
2623
2624    Catch(fault)
2625    {
2626       store_write_reset(fault);
2627    }
2628 }
2629
2630 static int
2631 make_errors(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type,
2632     int bdlo, int PNG_CONST bdhi)
2633 {
2634    for (; bdlo <= bdhi; ++bdlo)
2635    {
2636       int interlace_type;
2637
2638       for (interlace_type = PNG_INTERLACE_NONE;
2639            interlace_type < PNG_INTERLACE_LAST; ++interlace_type)
2640       {
2641          unsigned int test;
2642          char name[FILE_NAME_SIZE];
2643
2644          standard_name(name, sizeof name, 0, colour_type, bdlo, interlace_type,
2645             0, 0, 0);
2646
2647          for (test=0; test<(sizeof error_test)/(sizeof error_test[0]); ++test)
2648          {
2649             make_error(&pm->this, colour_type, DEPTH(bdlo), interlace_type,
2650                test, name);
2651
2652             if (fail(pm))
2653                return 0;
2654          }
2655       }
2656    }
2657
2658    return 1; /* keep going */
2659 }
2660
2661 static void
2662 perform_error_test(png_modifier *pm)
2663 {
2664    /* Need to do this here because we just write in this test. */
2665    safecat(pm->this.test, sizeof pm->this.test, 0, "error test");
2666
2667    if (!make_errors(pm, 0, 0, WRITE_BDHI))
2668       return;
2669
2670    if (!make_errors(pm, 2, 3, WRITE_BDHI))
2671       return;
2672
2673    if (!make_errors(pm, 3, 0, 3))
2674       return;
2675
2676    if (!make_errors(pm, 4, 3, WRITE_BDHI))
2677       return;
2678
2679    if (!make_errors(pm, 6, 3, WRITE_BDHI))
2680       return;
2681 }
2682
2683 /* Because we want to use the same code in both the progressive reader and the
2684  * sequential reader it is necessary to deal with the fact that the progressive
2685  * reader callbacks only have one parameter (png_get_progressive_ptr()), so this
2686  * must contain all the test parameters and all the local variables directly
2687  * accessible to the sequential reader implementation.
2688  *
2689  * The technique adopted is to reinvent part of what Dijkstra termed a
2690  * 'display'; an array of pointers to the stack frames of enclosing functions so
2691  * that a nested function definition can access the local (C auto) variables of
2692  * the functions that contain its definition.  In fact C provides the first
2693  * pointer (the local variables - the stack frame pointer) and the last (the
2694  * global variables - the BCPL global vector typically implemented as global
2695  * addresses), this code requires one more pointer to make the display - the
2696  * local variables (and function call parameters) of the function that actually
2697  * invokes either the progressive or sequential reader.
2698  *
2699  * Perhaps confusingly this technique is confounded with classes - the
2700  * 'standard_display' defined here is sub-classed as the 'gamma_display' below.
2701  * A gamma_display is a standard_display, taking advantage of the ANSI-C
2702  * requirement that the pointer to the first member of a structure must be the
2703  * same as the pointer to the structure.  This allows us to reuse standard_
2704  * functions in the gamma test code; something that could not be done with
2705  * nested funtions!
2706  */
2707 typedef struct standard_palette_entry /* pngvalid format palette! */
2708 {
2709    png_byte red;
2710    png_byte green;
2711    png_byte blue;
2712    png_byte alpha;
2713 } standard_palette[256];
2714
2715 typedef struct standard_display
2716 {
2717    png_store*  ps;             /* Test parameters (passed to the function) */
2718    png_byte    colour_type;
2719    png_byte    bit_depth;
2720    png_byte    red_sBIT;       /* Input data sBIT values. */
2721    png_byte    green_sBIT;
2722    png_byte    blue_sBIT;
2723    png_byte    alpha_sBIT;
2724    int         interlace_type;
2725    png_uint_32 id;             /* Calculated file ID */
2726    png_uint_32 w;              /* Width of image */
2727    png_uint_32 h;              /* Height of image */
2728    int         npasses;        /* Number of interlaced passes */
2729    png_uint_32 pixel_size;     /* Width of one pixel in bits */
2730    png_uint_32 bit_width;      /* Width of output row in bits */
2731    size_t      cbRow;          /* Bytes in a row of the output image */
2732    int         do_interlace;   /* Do interlacing internally */
2733    int         is_transparent; /* Transparecy information was present. */
2734    struct
2735    {
2736       png_uint_16 red;
2737       png_uint_16 green;
2738       png_uint_16 blue;
2739    }           transparent;    /* The transparent color, if set. */
2740    standard_palette
2741                palette;
2742 } standard_display;
2743
2744 static void
2745 standard_display_init(standard_display *dp, png_store* ps, png_uint_32 id,
2746    int do_interlace)
2747 {
2748    dp->ps = ps;
2749    dp->colour_type = COL_FROM_ID(id);
2750    dp->bit_depth = DEPTH_FROM_ID(id);
2751    dp->alpha_sBIT = dp->blue_sBIT = dp->green_sBIT = dp->alpha_sBIT =
2752       dp->bit_depth;
2753    dp->interlace_type = INTERLACE_FROM_ID(id);
2754    dp->id = id;
2755    /* All the rest are filled in after the read_info: */
2756    dp->w = 0;
2757    dp->h = 0;
2758    dp->npasses = 0;
2759    dp->pixel_size = 0;
2760    dp->bit_width = 0;
2761    dp->cbRow = 0;
2762    dp->do_interlace = do_interlace;
2763    dp->is_transparent = 0;
2764    /* Preset the transparent color to black: */
2765    memset(&dp->transparent, 0, sizeof dp->transparent);
2766    /* Preset the palette to full intensity/opaque througout: */
2767    memset(dp->palette, 0xff, sizeof dp->palette);
2768
2769 }
2770
2771 /* Call this only if the colour type is 3 - PNG_COLOR_TYPE_PALETTE - otherwise
2772  * it will png_error out.  The API returns true if tRNS information was
2773  * present.
2774  */
2775 static int
2776 standard_palette_init(standard_palette palette, png_structp pp, png_infop pi)
2777 {
2778    png_colorp pal;
2779    png_bytep trans_alpha;
2780    int num;
2781
2782    pal = 0;
2783    num = -1;
2784    if (png_get_PLTE(pp, pi, &pal, &num) & PNG_INFO_PLTE)
2785    {
2786       int i;
2787
2788       for (i=0; i<num; ++i)
2789       {
2790          palette[i].red = pal[i].red;
2791          palette[i].green = pal[i].green;
2792          palette[i].blue = pal[i].blue;
2793       }
2794
2795       /* Mark the remainder of the entries with a flag value: */
2796       for (; i<256; ++i)
2797          palette[i].red = palette[i].green = palette[i].blue = 126;
2798    }
2799
2800    else /* !png_get_PLTE */
2801       png_error(pp, "validate: missing PLTE with color type 3");
2802
2803    trans_alpha = 0;
2804    num = -1;
2805    if (png_get_tRNS(pp, pi, &trans_alpha, &num, 0) & PNG_INFO_tRNS)
2806    {
2807       int i;
2808
2809       /* Any of these are crash-worthy - given the implementation of
2810        * png_get_tRNS up to 1.5 an app won't crash if it just checks the
2811        * result above and fails to check that the variables it passed have
2812        * actually been filled in!  Note that if the app were to pass the
2813        * last, png_color_16p, variable too it couldn't rely on this.
2814        */
2815       if (trans_alpha == 0 || num <= 0 || num > 256)
2816          png_error(pp, "validate: unexpected png_get_tRNS (palette) result");
2817
2818       for (i=0; i<num; ++i)
2819          palette[i].alpha = trans_alpha[i];
2820
2821       for (; i<256; ++i)
2822          palette[i].alpha = 255;
2823
2824       return 1; /* transparency */
2825    }
2826
2827    else
2828    {
2829       /* No transparency - just set the alpha channel to opaque. */
2830       int i;
2831
2832       for (i=0; i<256; ++i)
2833          palette[i].alpha = 255;
2834
2835       return 0; /* no transparency */
2836    }
2837 }
2838
2839 /* By passing a 'standard_display' the progressive callbacks can be used
2840  * directly by the sequential code, the functions suffixed "_imp" are the
2841  * implementations, the functions without the suffix are the callbacks.
2842  *
2843  * The code for the info callback is split into two because this callback calls
2844  * png_read_update_info or png_start_read_image and what gets called depends on
2845  * whether the info needs updating (we want to test both calls in pngvalid.)
2846  */
2847 static void
2848 standard_info_part1(standard_display *dp, png_structp pp, png_infop pi)
2849 {
2850    if (png_get_bit_depth(pp, pi) != dp->bit_depth)
2851       png_error(pp, "validate: bit depth changed");
2852
2853    if (png_get_color_type(pp, pi) != dp->colour_type)
2854       png_error(pp, "validate: color type changed");
2855
2856    if (png_get_filter_type(pp, pi) != PNG_FILTER_TYPE_BASE)
2857       png_error(pp, "validate: filter type changed");
2858
2859    if (png_get_interlace_type(pp, pi) != dp->interlace_type)
2860       png_error(pp, "validate: interlacing changed");
2861
2862    if (png_get_compression_type(pp, pi) != PNG_COMPRESSION_TYPE_BASE)
2863       png_error(pp, "validate: compression type changed");
2864
2865    dp->w = png_get_image_width(pp, pi);
2866
2867    if (dp->w != standard_width(pp, dp->id))
2868       png_error(pp, "validate: image width changed");
2869
2870    dp->h = png_get_image_height(pp, pi);
2871
2872    if (dp->h != standard_height(pp, dp->id))
2873       png_error(pp, "validate: image height changed");
2874
2875    /* Record (but don't check at present) the input sBIT according to the colour
2876     * type information.
2877     */
2878    {
2879       png_color_8p sBIT = 0;
2880
2881       if (png_get_sBIT(pp, pi, &sBIT) & PNG_INFO_sBIT)
2882       {
2883          int sBIT_invalid = 0;
2884
2885          if (sBIT == 0)
2886             png_error(pp, "validate: unexpected png_get_sBIT result");
2887
2888          if (dp->colour_type & PNG_COLOR_MASK_COLOR)
2889          {
2890             if (sBIT->red == 0 || sBIT->red > dp->bit_depth)
2891                sBIT_invalid = 1;
2892             else
2893                dp->red_sBIT = sBIT->red;
2894
2895             if (sBIT->green == 0 || sBIT->green > dp->bit_depth)
2896                sBIT_invalid = 1;
2897             else
2898                dp->green_sBIT = sBIT->green;
2899
2900             if (sBIT->blue == 0 || sBIT->blue > dp->bit_depth)
2901                sBIT_invalid = 1;
2902             else
2903                dp->blue_sBIT = sBIT->blue;
2904          }
2905
2906          else /* !COLOR */
2907          {
2908             if (sBIT->gray == 0 || sBIT->gray > dp->bit_depth)
2909                sBIT_invalid = 1;
2910             else
2911                dp->blue_sBIT = dp->green_sBIT = dp->red_sBIT = sBIT->gray;
2912          }
2913
2914          /* All 8 bits in tRNS for a palette image are significant - see the
2915           * spec.
2916           */
2917          if (dp->colour_type & PNG_COLOR_MASK_ALPHA)
2918          {
2919             if (sBIT->alpha == 0 || sBIT->alpha > dp->bit_depth)
2920                sBIT_invalid = 1;
2921             else
2922                dp->alpha_sBIT = sBIT->alpha;
2923          }
2924
2925          if (sBIT_invalid)
2926             png_error(pp, "validate: sBIT value out of range");
2927       }
2928    }
2929
2930    /* Important: this is validating the value *before* any transforms have been
2931     * put in place.  It doesn't matter for the standard tests, where there are
2932     * no transforms, but it does for other tests where rowbytes may change after
2933     * png_read_update_info.
2934     */
2935    if (png_get_rowbytes(pp, pi) != standard_rowsize(pp, dp->id))
2936       png_error(pp, "validate: row size changed");
2937
2938    /* The palette is never read for non-palette images, even though it is valid
2939     * - this could be changed.
2940     */
2941    if (dp->colour_type == 3) /* palette */
2942    {
2943       int i;
2944
2945       dp->is_transparent = standard_palette_init(dp->palette, pp, pi);
2946
2947       /* And validate the result. */
2948       for (i=0; i<256; ++i)
2949          if (dp->palette[i].red != i || dp->palette[i].green != i ||
2950             dp->palette[i].blue != i)
2951             png_error(pp, "validate: color type 3 PLTE chunk changed");
2952    }
2953
2954    /* In any case always check for a tranparent color: */
2955    {
2956       png_color_16p trans_color = 0;
2957
2958       if (png_get_tRNS(pp, pi, 0, 0, &trans_color) & PNG_INFO_tRNS)
2959       {
2960          if (trans_color == 0)
2961             png_error(pp, "validate: unexpected png_get_tRNS (color) result");
2962
2963          switch (dp->colour_type)
2964          {
2965          case 0:
2966             dp->transparent.red = dp->transparent.green = dp->transparent.blue =
2967                trans_color->gray;
2968             dp->is_transparent = 1;
2969             break;
2970
2971          case 2:
2972             dp->transparent.red = trans_color->red;
2973             dp->transparent.green = trans_color->green;
2974             dp->transparent.blue = trans_color->blue;
2975             dp->is_transparent = 1;
2976             break;
2977
2978          case 3:
2979             /* Not expected because it should result in the array case
2980              * above.
2981              */
2982             png_error(pp, "validate: unexpected png_get_tRNS result");
2983             break;
2984
2985          default:
2986             png_error(pp, "validate: invalid tRNS chunk with alpha image");
2987          }
2988       }
2989    }
2990
2991    /* Read the number of passes - expected to match the value used when
2992     * creating the image (interlaced or not).  This has the side effect of
2993     * turning on interlace handling (if do_interlace is not set.)
2994     */
2995    dp->npasses = npasses_from_interlace_type(pp, dp->interlace_type);
2996    if (!dp->do_interlace && dp->npasses != png_set_interlace_handling(pp))
2997       png_error(pp, "validate: file changed interlace type");
2998
2999    /* Caller calls png_read_update_info or png_start_read_image now, then calls
3000     * part2.
3001     */
3002 }
3003
3004 /* This must be called *after* the png_read_update_info call to get the correct
3005  * 'rowbytes' value, otherwise png_get_rowbytes will refer to the untransformed
3006  * image.
3007  */
3008 static void
3009 standard_info_part2(standard_display *dp, png_structp pp, png_infop pi,
3010     int nImages)
3011 {
3012    /* Record cbRow now that it can be found. */
3013    dp->pixel_size = bit_size(pp, png_get_color_type(pp, pi),
3014       png_get_bit_depth(pp, pi));
3015    dp->bit_width = png_get_image_width(pp, pi) * dp->pixel_size;
3016    dp->cbRow = png_get_rowbytes(pp, pi);
3017
3018    /* Validate the rowbytes here again. */
3019    if (dp->cbRow != (dp->bit_width+7)/8)
3020       png_error(pp, "bad png_get_rowbytes calculation");
3021
3022    /* Then ensure there is enough space for the output image(s). */
3023    store_ensure_image(dp->ps, pp, nImages * dp->cbRow * dp->h);
3024 }
3025
3026 static void
3027 standard_info_imp(standard_display *dp, png_structp pp, png_infop pi,
3028     int nImages)
3029 {
3030    /* Note that the validation routine has the side effect of turning on
3031     * interlace handling in the subsequent code.
3032     */
3033    standard_info_part1(dp, pp, pi);
3034
3035    /* And the info callback has to call this (or png_read_update_info - see
3036     * below in the png_modifier code for that variant.
3037     */
3038    png_start_read_image(pp);
3039
3040    /* Validate the height, width and rowbytes plus ensure that sufficient buffer
3041     * exists for decoding the image.
3042     */
3043    standard_info_part2(dp, pp, pi, nImages);
3044 }
3045
3046 static void
3047 standard_info(png_structp pp, png_infop pi)
3048 {
3049    standard_display *dp = png_get_progressive_ptr(pp);
3050
3051    /* Call with nImages==1 because the progressive reader can only produce one
3052     * image.
3053     */
3054    standard_info_imp(dp, pp, pi, 1 /*only one image*/);
3055 }
3056
3057 static void
3058 progressive_row(png_structp pp, png_bytep new_row, png_uint_32 y, int pass)
3059 {
3060    PNG_CONST standard_display *dp = png_get_progressive_ptr(pp);
3061
3062    /* When handling interlacing some rows will be absent in each pass, the
3063     * callback still gets called, but with a NULL pointer.  This is checked
3064     * in the 'else' clause below.  We need our own 'cbRow', but we can't call
3065     * png_get_rowbytes because we got no info structure.
3066     */
3067    if (new_row != NULL)
3068    {
3069       png_bytep row;
3070
3071       /* In the case where the reader doesn't do the interlace it gives
3072        * us the y in the sub-image:
3073        */
3074       if (dp->do_interlace && dp->interlace_type == PNG_INTERLACE_ADAM7)
3075       {
3076          /* Use this opportunity to validate the png 'current' APIs: */
3077          if (y != png_get_current_row_number(pp))
3078             png_error(pp, "png_get_current_row_number is broken");
3079
3080          if (pass != png_get_current_pass_number(pp))
3081             png_error(pp, "png_get_current_pass_number is broken");
3082
3083          y = PNG_ROW_FROM_PASS_ROW(y, pass);
3084       }
3085
3086       /* Validate this just in case. */
3087       if (y >= dp->h)
3088          png_error(pp, "invalid y to progressive row callback");
3089
3090       row = dp->ps->image + y * dp->cbRow;
3091
3092       /* Combine the new row into the old: */
3093       if (dp->do_interlace)
3094       {
3095          if (dp->interlace_type == PNG_INTERLACE_ADAM7)
3096             deinterlace_row(row, new_row, dp->pixel_size, dp->w, pass);
3097          else
3098             memcpy(row, new_row, dp->cbRow);
3099       }
3100       else
3101          png_progressive_combine_row(pp, row, new_row);
3102    } else if (dp->interlace_type == PNG_INTERLACE_ADAM7 &&
3103       PNG_ROW_IN_INTERLACE_PASS(y, pass) &&
3104       PNG_PASS_COLS(dp->w, pass) > 0)
3105       png_error(pp, "missing row in progressive de-interlacing");
3106 }
3107
3108 static void
3109 sequential_row(standard_display *dp, png_structp pp, png_infop pi,
3110     PNG_CONST png_bytep pImage, PNG_CONST png_bytep pDisplay)
3111 {
3112    PNG_CONST int         npasses = dp->npasses;
3113    PNG_CONST int         do_interlace = dp->do_interlace &&
3114       dp->interlace_type == PNG_INTERLACE_ADAM7;
3115    PNG_CONST png_uint_32 height = standard_height(pp, dp->id);
3116    PNG_CONST png_uint_32 width = standard_width(pp, dp->id);
3117    PNG_CONST size_t      cbRow = dp->cbRow;
3118    int pass;
3119
3120    for (pass=0; pass<npasses; ++pass)
3121    {
3122       png_uint_32 y;
3123       png_uint_32 wPass = PNG_PASS_COLS(width, pass);
3124       png_bytep pRow1 = pImage;
3125       png_bytep pRow2 = pDisplay;
3126
3127       for (y=0; y<height; ++y)
3128       {
3129          if (do_interlace)
3130          {
3131             /* wPass may be zero or this row may not be in this pass.
3132              * png_read_row must not be called in either case.
3133              */
3134             if (wPass > 0 && PNG_ROW_IN_INTERLACE_PASS(y, pass))
3135             {
3136                /* Read the row into a pair of temporary buffers, then do the
3137                 * merge here into the output rows.
3138                 */
3139                png_byte row[STANDARD_ROWMAX], display[STANDARD_ROWMAX];
3140
3141                /* The following aids (to some extent) error detection - we can
3142                 * see where png_read_row wrote.  Use opposite values in row and
3143                 * display to make this easier.
3144                 */
3145                memset(row, 0xff, sizeof row);
3146                memset(display, 0, sizeof display);
3147
3148                png_read_row(pp, row, display);
3149
3150                if (pRow1 != NULL)
3151                   deinterlace_row(pRow1, row, dp->pixel_size, dp->w, pass);
3152
3153                if (pRow2 != NULL)
3154                   deinterlace_row(pRow2, display, dp->pixel_size, dp->w, pass);
3155             }
3156          }
3157          else
3158             png_read_row(pp, pRow1, pRow2);
3159
3160          if (pRow1 != NULL)
3161             pRow1 += cbRow;
3162
3163          if (pRow2 != NULL)
3164             pRow2 += cbRow;
3165       }
3166    }
3167
3168    /* And finish the read operation (only really necessary if the caller wants
3169     * to find additional data in png_info from chunks after the last IDAT.)
3170     */
3171    png_read_end(pp, pi);
3172 }
3173
3174 static void
3175 standard_row_validate(standard_display *dp, png_structp pp, png_const_bytep row,
3176    png_const_bytep display, png_uint_32 y)
3177 {
3178    png_byte std[STANDARD_ROWMAX];
3179
3180    memset(std, 0xff, sizeof std);
3181    standard_row(pp, std, dp->id, y);
3182
3183    /* At the end both the 'row' and 'display' arrays should end up identical.
3184     * In earlier passes 'row' will be partially filled in, with only the pixels
3185     * that have been read so far, but 'display' will have those pixels
3186     * replicated to fill the unread pixels while reading an interlaced image.
3187     * The side effect inside the libpng sequential reader is that the 'row'
3188     * array retains the correct values for unwritten pixels within the row
3189     * bytes, while the 'display' array gets bits off the end of the image (in
3190     * the last byte) trashed.  Unfortunately in the progressive reader the
3191     * row bytes are always trashed, so we always do a pixel_cmp here even though
3192     * a memcmp of all cbRow bytes will succeed for the sequential reader.
3193     */
3194    if (row != NULL && pixel_cmp(std, row, dp->bit_width) != 0)
3195    {
3196       char msg[64];
3197       sprintf(msg, "PNG image row %d changed", y);
3198       png_error(pp, msg);
3199    }
3200
3201    /* In this case use pixel_cmp because we need to compare a partial
3202     * byte at the end of the row if the row is not an exact multiple
3203     * of 8 bits wide.
3204     */
3205    if (display != NULL && pixel_cmp(std, display, dp->bit_width) != 0)
3206    {
3207       char msg[64];
3208       sprintf(msg, "display row %d changed", y);
3209       png_error(pp, msg);
3210    }
3211 }
3212
3213 static void
3214 standard_image_validate(standard_display *dp, png_structp pp,
3215    png_const_bytep pImage, png_const_bytep pDisplay)
3216 {
3217    png_uint_32 y;
3218
3219    for (y=0; y<dp->h; ++y)
3220    {
3221       standard_row_validate(dp, pp, pImage, pDisplay, y);
3222
3223       if (pImage != NULL)
3224          pImage += dp->cbRow;
3225
3226       if (pDisplay != NULL)
3227          pDisplay += dp->cbRow;
3228    }
3229
3230    /* This avoids false positives if the validation code is never called! */
3231    dp->ps->validated = 1;
3232 }
3233
3234 static void
3235 standard_end(png_structp pp, png_infop pi)
3236 {
3237    standard_display *dp = png_get_progressive_ptr(pp);
3238
3239    UNUSED(pi)
3240
3241    /* Validate the image - progressive reading only produces one variant for
3242     * interlaced images.
3243     */
3244    standard_image_validate(dp, pp, dp->ps->image, NULL);
3245 }
3246
3247 /* A single test run checking the standard image to ensure it is not damaged. */
3248 static void
3249 standard_test(png_store* PNG_CONST psIn, png_uint_32 PNG_CONST id,
3250    int do_interlace)
3251 {
3252    standard_display d;
3253    context(psIn, fault);
3254
3255    /* Set up the display (stack frame) variables from the arguments to the
3256     * function and initialize the locals that are filled in later.
3257     */
3258    standard_display_init(&d, psIn, id, do_interlace);
3259
3260    /* Everything is protected by a Try/Catch.  The functions called also
3261     * typically have local Try/Catch blocks.
3262     */
3263    Try
3264    {
3265       png_structp pp;
3266       png_infop pi;
3267
3268       /* Get a png_struct for reading the image. This will throw an error if it
3269        * fails, so we don't need to check the result.
3270        */
3271       pp = set_store_for_read(d.ps, &pi, d.id,
3272          d.do_interlace ?  (d.ps->progressive ?
3273             "pngvalid progressive deinterlacer" :
3274             "pngvalid sequential deinterlacer") : (d.ps->progressive ?
3275                "progressive reader" : "sequential reader"));
3276
3277       /* Introduce the correct read function. */
3278       if (d.ps->progressive)
3279       {
3280          png_set_progressive_read_fn(pp, &d, standard_info, progressive_row,
3281             standard_end);
3282
3283          /* Now feed data into the reader until we reach the end: */
3284          store_progressive_read(d.ps, pp, pi);
3285       }
3286       else
3287       {
3288          /* Note that this takes the store, not the display. */
3289          png_set_read_fn(pp, d.ps, store_read);
3290
3291          /* Check the header values: */
3292          png_read_info(pp, pi);
3293
3294          /* The code tests both versions of the images that the sequential
3295           * reader can produce.
3296           */
3297          standard_info_imp(&d, pp, pi, 2 /*images*/);
3298
3299          /* Need the total bytes in the image below; we can't get to this point
3300           * unless the PNG file values have been checked against the expected
3301           * values.
3302           */
3303          {
3304             PNG_CONST png_bytep pImage = d.ps->image;
3305             PNG_CONST png_bytep pDisplay = pImage + d.cbRow * d.h;
3306
3307             sequential_row(&d, pp, pi, pImage, pDisplay);
3308
3309             /* After the last pass loop over the rows again to check that the
3310              * image is correct.
3311              */
3312             standard_image_validate(&d, pp, pImage, pDisplay);
3313          }
3314       }
3315
3316       /* Check for validation. */
3317       if (!d.ps->validated)
3318          png_error(pp, "image read failed silently");
3319
3320       /* Successful completion. */
3321    }
3322
3323    Catch(fault)
3324       d.ps = fault; /* make sure this hasn't been clobbered. */
3325
3326    /* In either case clean up the store. */
3327    store_read_reset(d.ps);
3328 }
3329
3330 static int
3331 test_standard(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type,
3332     int bdlo, int PNG_CONST bdhi)
3333 {
3334    for (; bdlo <= bdhi; ++bdlo)
3335    {
3336       int interlace_type;
3337
3338       for (interlace_type = PNG_INTERLACE_NONE;
3339            interlace_type < PNG_INTERLACE_LAST; ++interlace_type)
3340       {
3341          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
3342             interlace_type, 0, 0, 0), 0/*do_interlace*/);
3343
3344          if (fail(pm))
3345             return 0;
3346       }
3347    }
3348
3349    return 1; /* keep going */
3350 }
3351
3352 static void
3353 perform_standard_test(png_modifier *pm)
3354 {
3355    /* Test each colour type over the valid range of bit depths (expressed as
3356     * log2(bit_depth) in turn, stop as soon as any error is detected.
3357     */
3358    if (!test_standard(pm, 0, 0, READ_BDHI))
3359       return;
3360
3361    if (!test_standard(pm, 2, 3, READ_BDHI))
3362       return;
3363
3364    if (!test_standard(pm, 3, 0, 3))
3365       return;
3366
3367    if (!test_standard(pm, 4, 3, READ_BDHI))
3368       return;
3369
3370    if (!test_standard(pm, 6, 3, READ_BDHI))
3371       return;
3372 }
3373
3374
3375 /********************************** SIZE TESTS ********************************/
3376 static int
3377 test_size(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type,
3378     int bdlo, int PNG_CONST bdhi)
3379 {
3380    /* Run the tests on each combination.
3381     *
3382     * NOTE: on my 32 bit x86 each of the following blocks takes
3383     * a total of 3.5 seconds if done across every combo of bit depth
3384     * width and height.  This is a waste of time in practice, hence the
3385     * hinc and winc stuff:
3386     */
3387    static PNG_CONST png_byte hinc[] = {1, 3, 11, 1, 5};
3388    static PNG_CONST png_byte winc[] = {1, 9, 5, 7, 1};
3389    for (; bdlo <= bdhi; ++bdlo)
3390    {
3391       png_uint_32 h, w;
3392
3393       for (h=1; h<=16; h+=hinc[bdlo]) for (w=1; w<=16; w+=winc[bdlo])
3394       {
3395          /* First test all the 'size' images against the sequential
3396           * reader using libpng to deinterlace (where required.)  This
3397           * validates the write side of libpng.  There are four possibilities
3398           * to validate.
3399           */
3400          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
3401             PNG_INTERLACE_NONE, w, h, 0), 0/*do_interlace*/);
3402
3403          if (fail(pm))
3404             return 0;
3405
3406          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
3407             PNG_INTERLACE_NONE, w, h, 1), 0/*do_interlace*/);
3408
3409          if (fail(pm))
3410             return 0;
3411
3412          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
3413             PNG_INTERLACE_ADAM7, w, h, 0), 0/*do_interlace*/);
3414
3415          if (fail(pm))
3416             return 0;
3417
3418          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
3419             PNG_INTERLACE_ADAM7, w, h, 1), 0/*do_interlace*/);
3420
3421          if (fail(pm))
3422             return 0;
3423
3424          /* Now validate the interlaced read side - do_interlace true,
3425           * in the progressive case this does actually make a difference
3426           * to the code used in the non-interlaced case too.
3427           */
3428          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
3429             PNG_INTERLACE_NONE, w, h, 0), 1/*do_interlace*/);
3430
3431          if (fail(pm))
3432             return 0;
3433
3434          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
3435             PNG_INTERLACE_ADAM7, w, h, 0), 1/*do_interlace*/);
3436
3437          if (fail(pm))
3438             return 0;
3439       }
3440    }
3441
3442    return 1; /* keep going */
3443 }
3444
3445 static void
3446 perform_size_test(png_modifier *pm)
3447 {
3448    /* Test each colour type over the valid range of bit depths (expressed as
3449     * log2(bit_depth) in turn, stop as soon as any error is detected.
3450     */
3451    if (!test_size(pm, 0, 0, READ_BDHI))
3452       return;
3453
3454    if (!test_size(pm, 2, 3, READ_BDHI))
3455       return;
3456
3457    /* For the moment don't do the palette test - it's a waste of time when
3458     * compared to the greyscale test.
3459     */
3460 #if 0
3461    if (!test_size(pm, 3, 0, 3))
3462       return;
3463 #endif
3464
3465    if (!test_size(pm, 4, 3, READ_BDHI))
3466       return;
3467
3468    if (!test_size(pm, 6, 3, READ_BDHI))
3469       return;
3470 }
3471
3472
3473 /******************************* TRANSFORM TESTS ******************************/
3474 /* A set of tests to validate libpng image transforms.  The possibilities here
3475  * are legion because the transforms can be combined in a combinatorial
3476  * fashion.  To deal with this some measure of restraint is required, otherwise
3477  * the tests would take forever.
3478  */
3479 typedef struct image_pixel
3480 {
3481    /* A local (pngvalid) representation of a PNG pixel, in all its
3482     * various forms.
3483     */
3484    unsigned int red, green, blue, alpha; /* For non-palette images. */
3485    unsigned int palette_index;           /* For a palette image. */
3486    png_byte colour_type;                 /* As in the spec. */
3487    png_byte bit_depth;                   /* Defines bit size in row */
3488    png_byte sample_depth;                /* Scale of samples */
3489    int      have_tRNS;                   /* tRNS chunk may need processing */
3490
3491    /* For checking the code calculates double precision floating point values
3492     * along with an error value, accumulated from the transforms.  Because an
3493     * sBIT setting allows larger error bounds (indeed, by the spec, apparently
3494     * up to just less than +/-1 in the scaled value) the *lowest* sBIT for each
3495     * channel is stored.  This sBIT value is folded in to the stored error value
3496     * at the end of the application of the transforms to the pixel.
3497     */
3498    double   redf, greenf, bluef, alphaf;
3499    double   rede, greene, bluee, alphae;
3500    png_byte red_sBIT, green_sBIT, blue_sBIT, alpha_sBIT;
3501 } image_pixel;
3502
3503 /* Shared utility function, see below. */
3504 static void
3505 image_pixel_setf(image_pixel *this, unsigned int max)
3506 {
3507    this->redf = this->red / (double)max;
3508    this->greenf = this->green / (double)max;
3509    this->bluef = this->blue / (double)max;
3510    this->alphaf = this->alpha / (double)max;
3511
3512    if (this->red < max)
3513       this->rede = this->redf * DBL_EPSILON;
3514    else
3515       this->rede = 0;
3516    if (this->green < max)
3517       this->greene = this->greenf * DBL_EPSILON;
3518    else
3519       this->greene = 0;
3520    if (this->blue < max)
3521       this->bluee = this->bluef * DBL_EPSILON;
3522    else
3523       this->bluee = 0;
3524    if (this->alpha < max)
3525       this->alphae = this->alphaf * DBL_EPSILON;
3526    else
3527       this->alphae = 0;
3528 }
3529
3530 /* Initialize the structure for the next pixel - call this before doing any
3531  * transforms and call it for each pixel since all the fields may need to be
3532  * reset.
3533  */
3534 static void
3535 image_pixel_init(image_pixel *this, png_const_bytep row, png_byte colour_type,
3536     png_byte bit_depth, png_uint_32 x, standard_palette palette)
3537 {
3538    PNG_CONST png_byte sample_depth = (png_byte)(colour_type ==
3539       PNG_COLOR_TYPE_PALETTE ? 8 : bit_depth);
3540    PNG_CONST unsigned int max = (1U<<sample_depth)-1;
3541
3542    /* Initially just set everything to the same number and the alpha to opaque.
3543     * Note that this currently assumes a simple palette where entry x has colour
3544     * rgb(x,x,x)!
3545     */
3546    this->palette_index = this->red = this->green = this->blue =
3547       sample(row, colour_type, bit_depth, x, 0);
3548    this->alpha = max;
3549    this->red_sBIT = this->green_sBIT = this->blue_sBIT = this->alpha_sBIT =
3550       sample_depth;
3551
3552    /* Then override as appropriate: */
3553    if (colour_type == 3) /* palette */
3554    {
3555       /* This permits the caller to default to the sample value. */
3556       if (palette != 0)
3557       {
3558          PNG_CONST unsigned int i = this->palette_index;
3559
3560          this->red = palette[i].red;
3561          this->green = palette[i].green;
3562          this->blue = palette[i].blue;
3563          this->alpha = palette[i].alpha;
3564       }
3565    }
3566
3567    else /* not palette */
3568    {
3569       unsigned int i = 0;
3570
3571       if (colour_type & 2)
3572       {
3573          this->green = sample(row, colour_type, bit_depth, x, 1);
3574          this->blue = sample(row, colour_type, bit_depth, x, 2);
3575          i = 2;
3576       }
3577       if (colour_type & 4)
3578          this->alpha = sample(row, colour_type, bit_depth, x, ++i);
3579    }
3580
3581    /* Calculate the scaled values, these are simply the values divided by
3582     * 'max' and the error is initialized to the double precision epsilon value
3583     * from the header file.
3584     */
3585    image_pixel_setf(this, max);
3586
3587    /* Store the input information for use in the transforms - these will
3588     * modify the information.
3589     */
3590    this->colour_type = colour_type;
3591    this->bit_depth = bit_depth;
3592    this->sample_depth = sample_depth;
3593    this->have_tRNS = 0;
3594 }
3595
3596 /* Convert a palette image to an rgb image.  This necessarily converts the tRNS
3597  * chunk at the same time, because the tRNS will be in palette form.
3598  */
3599 static void
3600 image_pixel_convert_PLTE(image_pixel *this, const standard_display *display)
3601 {
3602    if (this->colour_type == PNG_COLOR_TYPE_PALETTE)
3603    {
3604       PNG_CONST unsigned int i = this->palette_index;
3605
3606       this->bit_depth = this->sample_depth;
3607       this->red = display->palette[i].red;
3608       this->green = display->palette[i].green;
3609       this->blue = display->palette[i].blue;
3610       this->red_sBIT = display->red_sBIT;
3611       this->green_sBIT = display->green_sBIT;
3612       this->blue_sBIT = display->blue_sBIT;
3613
3614       if (this->have_tRNS)
3615       {
3616          this->alpha = display->palette[i].alpha;
3617          this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
3618          this->have_tRNS = 0;
3619       }
3620       else
3621       {
3622          this->alpha = 255;
3623          this->colour_type = PNG_COLOR_TYPE_RGB;
3624       }
3625       this->alpha_sBIT = 8;
3626
3627       /* And regenerate the scaled values and all the errors, which are now set
3628        * back to the initial values.
3629        */
3630       image_pixel_setf(this, 255);
3631    }
3632 }
3633
3634 /* Add an alpha channel, this will glom in the tRNS information because tRNS is
3635  * not valid in an alpha image.  The bit depth will invariably be set to at
3636  * least 8.  Palette images will be converted to alpha (using the above API).
3637  */
3638 static void
3639 image_pixel_add_alpha(image_pixel *this, const standard_display *display)
3640 {
3641    if (this->colour_type == PNG_COLOR_TYPE_PALETTE)
3642       image_pixel_convert_PLTE(this, display);
3643
3644    if ((this->colour_type & PNG_COLOR_MASK_ALPHA) == 0)
3645    {
3646       if (this->colour_type == PNG_COLOR_TYPE_GRAY)
3647       {
3648          if (this->bit_depth < 8)
3649             this->bit_depth = 8;
3650
3651          if (this->have_tRNS)
3652          {
3653             this->have_tRNS = 0;
3654
3655             /* Check the input, original, channel value here against the
3656              * original tRNS gray chunk valie.
3657              */
3658             if (this->red == display->transparent.red)
3659                this->alphaf = 0;
3660             else
3661                this->alphaf = 1;
3662          }
3663          else
3664             this->alphaf = 1;
3665
3666          this->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA;
3667       }
3668
3669       else if (this->colour_type == PNG_COLOR_TYPE_RGB)
3670       {
3671          if (this->have_tRNS)
3672          {
3673             this->have_tRNS = 0;
3674
3675             /* Again, check the exact input values, not the current transformed
3676              * value!
3677              */
3678             if (this->red == display->transparent.red &&
3679                this->green == display->transparent.green &&
3680                this->blue == display->transparent.blue)
3681                this->alphaf = 0;
3682             else
3683                this->alphaf = 1;
3684
3685             this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
3686          }
3687       }
3688
3689       /* The error in the alpha is zero and the sBIT value comes from the
3690        * original sBIT data (actually it will always be the original bit depth).
3691        */
3692       this->alphae = 0;
3693       this->alpha_sBIT = display->alpha_sBIT;
3694    }
3695 }
3696
3697 struct transform_display;
3698 typedef struct image_transform
3699 {
3700    /* The name of this transform: a string. */
3701    PNG_CONST char *name;
3702
3703    /* Each transform can be disabled from the command line: */
3704    int enable;
3705
3706    /* The global list of transforms; read only. */
3707    struct image_transform *PNG_CONST list;
3708
3709    /* The global count of the number of times this transform has been set on an
3710     * image.
3711     */
3712    unsigned int global_use;
3713
3714    /* The local count of the number of times this transform has been set. */
3715    unsigned int local_use;
3716
3717    /* The next transform in the list, each transform must call its own next
3718     * transform after it has processed the pixel successfully.
3719     */
3720    PNG_CONST struct image_transform *next;
3721
3722    /* A single transform for the image, expressed as a series of function
3723     * callbacks and some space for values.
3724     *
3725     * First a callback to set the transform on the current png_read_struct:
3726     */
3727    void (*set)(PNG_CONST struct image_transform *this,
3728       struct transform_display *that, png_structp pp, png_infop pi);
3729
3730    /* Then a transform that takes an input pixel in one PNG format or another
3731     * and modifies it by a pngvalid implementation of the transform (thus
3732     * duplicating the libpng intent without, we hope, duplicating the bugs
3733     * in the libpng implementation!)  The png_structp is solely to allow error
3734     * reporting via png_error and png_warning.
3735     */
3736    void (*mod)(PNG_CONST struct image_transform *this, image_pixel *that,
3737       png_structp pp, PNG_CONST struct transform_display *display);
3738
3739    /* Add this transform to the list and return true if the transform is
3740     * meaningful for this colour type and bit depth - if false then the
3741     * transform should have no effect on the image so there's not a lot of
3742     * point running it.
3743     */
3744    int (*add)(struct image_transform *this,
3745       PNG_CONST struct image_transform **that, png_byte colour_type,
3746       png_byte bit_depth);
3747 } image_transform;
3748
3749 typedef struct transform_display
3750 {
3751    standard_display this;
3752
3753    /* Parameters */
3754    png_modifier*              pm;
3755    PNG_CONST image_transform* transform_list;
3756
3757    /* Local variables */
3758    png_byte output_colour_type;
3759    png_byte output_bit_depth;
3760 } transform_display;
3761
3762 /* Two functions to end the list: */
3763 static void
3764 image_transform_set_end(PNG_CONST image_transform *this,
3765    transform_display *that, png_structp pp, png_infop pi)
3766 {
3767    UNUSED(this)
3768    UNUSED(that)
3769    UNUSED(pp)
3770    UNUSED(pi)
3771 }
3772
3773 /* At the end of the list recalculate the output image pixel value from the
3774  * double precision values set up by the preceding 'mod' calls:
3775  */
3776 static unsigned int
3777 sample_scale(double sample_value, unsigned int scale)
3778 {
3779    sample_value = floor(sample_value * scale + .5);
3780
3781    /* Return NaN as 0: */
3782    if (!(sample_value > 0))
3783       sample_value = 0;
3784    else if (sample_value > scale)
3785       sample_value = scale;
3786
3787    return (unsigned int)sample_value;
3788 }
3789
3790 static void
3791 image_transform_mod_end(PNG_CONST image_transform *this, image_pixel *that,
3792     png_structp pp, PNG_CONST transform_display *display)
3793 {
3794    PNG_CONST unsigned int scale = (1U<<that->sample_depth)-1;
3795
3796    UNUSED(this)
3797    UNUSED(pp)
3798    UNUSED(display)
3799
3800    /* At the end recalculate the digitized red green and blue values according
3801     * to the current sample_depth of the pixel.
3802     *
3803     * The sample value is simply scaled to the maximum, checking for over
3804     * and underflow (which can both happen for some image transforms,
3805     * including simple size scaling, though libpng doesn't do that at present.
3806     */
3807    that->red = sample_scale(that->redf, scale);
3808
3809    /* The error value is increased, at the end, according to the lowest sBIT
3810     * value seen.  Common sense tells us that the intermediate integer
3811     * representations are no more accurate than +/- 0.5 in the integral values,
3812     * the sBIT allows the implementation to be worse than this.  In addition the
3813     * PNG specification actually permits any error within the range (-1..+1),
3814     * but that is ignored here.  Instead the final digitized value is compared,
3815     * below to the digitized value of the error limits - this has the net effect
3816     * of allowing (almost) +/-1 in the output value.  It's difficult to see how
3817     * any algorithm that digitizes intermediate results can be more accurate.
3818     */
3819    that->rede += 1./(2*((1U<<that->red_sBIT)-1));
3820
3821    if (that->colour_type & PNG_COLOR_MASK_COLOR)
3822    {
3823       that->green = sample_scale(that->greenf, scale);
3824       that->blue = sample_scale(that->bluef, scale);
3825       that->greene += 1./(2*((1U<<that->green_sBIT)-1));
3826       that->bluee += 1./(2*((1U<<that->blue_sBIT)-1));
3827    }
3828    else
3829    {
3830       that->blue = that->green = that->red;
3831       that->bluef = that->greenf = that->redf;
3832       that->bluee = that->greene = that->rede;
3833    }
3834
3835    if ((that->colour_type & PNG_COLOR_MASK_ALPHA) ||
3836       that->colour_type == PNG_COLOR_TYPE_PALETTE)
3837    {
3838       that->alpha = sample_scale(that->alphaf, scale);
3839       that->alphae += 1./(2*((1U<<that->alpha_sBIT)-1));
3840    }
3841    else
3842    {
3843       that->alpha = scale; /* opaque */
3844       that->alpha = 1;     /* Override this. */
3845       that->alphae = 0;    /* It's exact ;-) */
3846    }
3847 }
3848
3849 /* Static 'end' structure: */
3850 static image_transform image_transform_end =
3851 {
3852    "(end)", /* name */
3853    1, /* enable */
3854    0, /* list */
3855    0, /* global_use */
3856    0, /* local_use */
3857    0, /* next */
3858    image_transform_set_end,
3859    image_transform_mod_end,
3860    0 /* never called, I want it to crash if it is! */
3861 };
3862
3863 /* Reader callbacks and implementations, where they differ from the standard
3864  * ones.
3865  */
3866 static void
3867 transform_display_init(transform_display *dp, png_modifier *pm, png_uint_32 id,
3868     PNG_CONST image_transform *transform_list)
3869 {
3870    /* Standard fields */
3871    standard_display_init(&dp->this, &pm->this, id, 0/*do_interlace*/);
3872
3873    /* Parameter fields */
3874    dp->pm = pm;
3875    dp->transform_list = transform_list;
3876
3877    /* Local variable fields */
3878    dp->output_colour_type = 255; /* invalid */
3879    dp->output_bit_depth = 255;  /* invalid */
3880 }
3881
3882 static void
3883 transform_info_imp(transform_display *dp, png_structp pp, png_infop pi)
3884 {
3885    /* Reuse the standard stuff as appropriate. */
3886    standard_info_part1(&dp->this, pp, pi);
3887
3888    /* Now set the list of transforms. */
3889    dp->transform_list->set(dp->transform_list, dp, pp, pi);
3890
3891    /* Update the info structure for these transforms: */
3892    png_read_update_info(pp, pi);
3893
3894    /* And get the output information into the standard_display */
3895    standard_info_part2(&dp->this, pp, pi, 1/*images*/);
3896
3897    /* Plus the extra stuff we need for the transform tests: */
3898    dp->output_colour_type = png_get_color_type(pp, pi);
3899    dp->output_bit_depth = png_get_bit_depth(pp, pi);
3900
3901    /* Validate the combination of colour type and bit depth that we are getting
3902     * out of libpng; the semantics of something not in the PNG spec are, at
3903     * best, unclear.
3904     */
3905    switch (dp->output_colour_type)
3906    {
3907    case PNG_COLOR_TYPE_PALETTE:
3908       if (dp->output_bit_depth > 8) goto error;
3909       /*FALL THROUGH*/
3910    case PNG_COLOR_TYPE_GRAY:
3911       if (dp->output_bit_depth == 1 || dp->output_bit_depth == 2 ||
3912          dp->output_bit_depth == 4)
3913          break;
3914       /*FALL THROUGH*/
3915    default:
3916       if (dp->output_bit_depth == 8 || dp->output_bit_depth == 16)
3917          break;
3918       /*FALL THROUGH*/
3919    error:
3920       {
3921          char message[128];
3922          size_t pos;
3923
3924          pos = safecat(message, sizeof message, 0,
3925             "invalid final bit depth: colour type(");
3926          pos = safecatn(message, sizeof message, pos, dp->output_colour_type);
3927          pos = safecat(message, sizeof message, pos, ") with bit depth: ");
3928          pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);
3929
3930          png_error(pp, message);
3931       }
3932    }
3933
3934    /* Use a test pixel to check that the output agrees with what we expect -
3935     * this avoids running the whole test if the output is unexpected.
3936     */
3937    {
3938       image_pixel test_pixel;
3939
3940       memset(&test_pixel, 0, sizeof test_pixel);
3941       test_pixel.colour_type = dp->this.colour_type; /* input */
3942       test_pixel.bit_depth = dp->this.bit_depth;
3943       if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE)
3944          test_pixel.sample_depth = 8;
3945       else
3946          test_pixel.sample_depth = test_pixel.bit_depth;
3947       /* Don't need sBIT here */
3948       test_pixel.have_tRNS = dp->this.is_transparent;
3949
3950       dp->transform_list->mod(dp->transform_list, &test_pixel, pp, dp);
3951
3952       if (test_pixel.colour_type != dp->output_colour_type)
3953       {
3954          char message[128];
3955          size_t pos = safecat(message, sizeof message, 0, "colour type ");
3956
3957          pos = safecatn(message, sizeof message, pos, dp->output_colour_type);
3958          pos = safecat(message, sizeof message, pos, " expected ");
3959          pos = safecatn(message, sizeof message, pos, test_pixel.colour_type);
3960
3961          png_error(pp, message);
3962       }
3963
3964       if (test_pixel.bit_depth != dp->output_bit_depth)
3965       {
3966          char message[128];
3967          size_t pos = safecat(message, sizeof message, 0, "bit depth ");
3968
3969          pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);
3970          pos = safecat(message, sizeof message, pos, " expected ");
3971          pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth);
3972
3973          png_error(pp, message);
3974       }
3975
3976       /* If both bit depth and colour type are correct check the sample depth.
3977        * I believe these are both internal errors.
3978        */
3979       if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE)
3980       {
3981          if (test_pixel.sample_depth != 8) /* oops - internal error! */
3982             png_error(pp, "pngvalid: internal: palette sample depth not 8");
3983       }
3984       else if (test_pixel.sample_depth != dp->output_bit_depth)
3985       {
3986          char message[128];
3987          size_t pos = safecat(message, sizeof message, 0,
3988             "internal: sample depth ");
3989
3990          pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);
3991          pos = safecat(message, sizeof message, pos, " expected ");
3992          pos = safecatn(message, sizeof message, pos, test_pixel.sample_depth);
3993
3994          png_error(pp, message);
3995       }
3996    }
3997 }
3998
3999 static void
4000 transform_info(png_structp pp, png_infop pi)
4001 {
4002    transform_info_imp(png_get_progressive_ptr(pp), pp, pi);
4003 }
4004
4005 static void
4006 transform_range_check(png_structp pp, unsigned int r, unsigned int g,
4007    unsigned int b, unsigned int a, unsigned int in_digitized, double in,
4008    unsigned int out, png_byte sample_depth, double err, PNG_CONST char *name)
4009 {
4010    /* Compare the scaled, digitzed, values of our local calculation (in+-err)
4011     * with the digitized values libpng produced;  'sample_depth' is the actual
4012     * digitization depth of the libpng output colors (the bit depth except for
4013     * palette images where it is always 8.)
4014     */
4015    unsigned int max = (1U<<sample_depth)-1;
4016    double in_min = ceil((in-err)*max - .5);
4017    double in_max = floor((in+err)*max + .5);
4018    if (!(out >= in_min && out <= in_max))
4019    {
4020       char message[256];
4021       size_t pos;
4022
4023       pos = safecat(message, sizeof message, 0, name);
4024       pos = safecat(message, sizeof message, pos, " output value error: rgba(");
4025       pos = safecatn(message, sizeof message, pos, r);
4026       pos = safecat(message, sizeof message, pos, ",");
4027       pos = safecatn(message, sizeof message, pos, g);
4028       pos = safecat(message, sizeof message, pos, ",");
4029       pos = safecatn(message, sizeof message, pos, b);
4030       pos = safecat(message, sizeof message, pos, ",");
4031       pos = safecatn(message, sizeof message, pos, a);
4032       pos = safecat(message, sizeof message, pos, "): ");
4033       pos = safecatn(message, sizeof message, pos, out);
4034       pos = safecat(message, sizeof message, pos, " expected: ");
4035       pos = safecatn(message, sizeof message, pos, in_digitized);
4036       pos = safecat(message, sizeof message, pos, " (");
4037       pos = safecatd(message, sizeof message, pos, (in-err)*max, 3);
4038       pos = safecat(message, sizeof message, pos, "..");
4039       pos = safecatd(message, sizeof message, pos, (in+err)*max, 3);
4040       pos = safecat(message, sizeof message, pos, ")");
4041
4042       png_error(pp, message);
4043    }
4044 }
4045
4046 static void
4047 transform_image_validate(transform_display *dp, png_structp pp, png_infop pi,
4048     png_const_bytep pRow)
4049 {
4050    /* Constants for the loop below: */
4051    PNG_CONST png_byte in_ct = dp->this.colour_type;
4052    PNG_CONST png_byte in_bd = dp->this.bit_depth;
4053    PNG_CONST png_uint_32 w = dp->this.w;
4054    PNG_CONST png_uint_32 h = dp->this.h;
4055    PNG_CONST size_t cbRow = dp->this.cbRow;
4056    PNG_CONST png_byte out_ct = dp->output_colour_type;
4057    PNG_CONST png_byte out_bd = dp->output_bit_depth;
4058    PNG_CONST png_byte sample_depth = (png_byte)(out_ct ==
4059       PNG_COLOR_TYPE_PALETTE ? 8 : out_bd);
4060    PNG_CONST png_byte red_sBIT = dp->this.red_sBIT;
4061    PNG_CONST png_byte green_sBIT = dp->this.green_sBIT;
4062    PNG_CONST png_byte blue_sBIT = dp->this.blue_sBIT;
4063    PNG_CONST png_byte alpha_sBIT = dp->this.alpha_sBIT;
4064    PNG_CONST int have_tRNS = dp->this.is_transparent;
4065
4066    standard_palette out_palette;
4067    png_uint_32 y;
4068
4069    UNUSED(pi)
4070
4071    /* Read the palette corresponding to the output if the output colour type
4072     * indicates a palette, othewise set out_palette to garbage.
4073     */
4074    if (out_ct == PNG_COLOR_TYPE_PALETTE)
4075       (void)standard_palette_init(out_palette, pp, pi);
4076    else
4077       memset(out_palette, 0x5e, sizeof out_palette);
4078
4079    for (y=0; y<h; ++y, pRow += cbRow)
4080    {
4081       png_uint_32 x;
4082
4083       /* The original, standard, row pre-transforms. */
4084       png_byte std[STANDARD_ROWMAX];
4085
4086       transform_row(pp, std, in_ct, in_bd, y);
4087
4088       /* Go through each original pixel transforming it and comparing with what
4089        * libpng did to the same pixel.
4090        */
4091       for (x=0; x<w; ++x)
4092       {
4093          image_pixel in_pixel, out_pixel;
4094          unsigned int r, g, b, a;
4095
4096          /* Find out what we think the pixel should be: */
4097          image_pixel_init(&in_pixel, std, in_ct, in_bd, x, dp->this.palette);
4098
4099          in_pixel.red_sBIT = red_sBIT;
4100          in_pixel.green_sBIT = green_sBIT;
4101          in_pixel.blue_sBIT = blue_sBIT;
4102          in_pixel.alpha_sBIT = alpha_sBIT;
4103          in_pixel.have_tRNS = have_tRNS;
4104
4105          /* For error detection, below. */
4106          r = in_pixel.red;
4107          g = in_pixel.green;
4108          b = in_pixel.blue;
4109          a = in_pixel.alpha;
4110
4111          dp->transform_list->mod(dp->transform_list, &in_pixel, pp, dp);
4112
4113          /* Read the output pixel and compare it to what we got, we don't
4114           * use the error field here, so no need to update sBIT.
4115           */
4116          image_pixel_init(&out_pixel, pRow, out_ct, out_bd, x, out_palette);
4117
4118          /* We don't expect changes to the index here even if the bit depth is
4119           * changed.
4120           */
4121          if (in_ct == PNG_COLOR_TYPE_PALETTE &&
4122             out_ct == PNG_COLOR_TYPE_PALETTE)
4123          {
4124             if (in_pixel.palette_index != out_pixel.palette_index)
4125                png_error(pp, "unexpected transformed palette index");
4126          }
4127
4128          /* Check the colours for palette images too - in fact the palette could
4129           * be separately verified itself in most cases.
4130           */
4131          if (in_pixel.red != out_pixel.red)
4132             transform_range_check(pp, r, g, b, a, in_pixel.red, in_pixel.redf,
4133                out_pixel.red, sample_depth, in_pixel.rede, "red/gray");
4134
4135          if ((out_ct & PNG_COLOR_MASK_COLOR) != 0 &&
4136             in_pixel.green != out_pixel.green)
4137             transform_range_check(pp, r, g, b, a, in_pixel.green,
4138                in_pixel.greenf, out_pixel.green, sample_depth, in_pixel.greene,
4139                "green");
4140
4141          if ((out_ct & PNG_COLOR_MASK_COLOR) != 0 &&
4142             in_pixel.blue != out_pixel.blue)
4143             transform_range_check(pp, r, g, b, a, in_pixel.blue, in_pixel.bluef,
4144                out_pixel.blue, sample_depth, in_pixel.bluee, "blue");
4145
4146          if ((out_ct & PNG_COLOR_MASK_ALPHA) != 0 &&
4147             in_pixel.alpha != out_pixel.alpha)
4148             transform_range_check(pp, r, g, b, a, in_pixel.alpha,
4149                in_pixel.alphaf, out_pixel.alpha, sample_depth, in_pixel.alphae,
4150                "alpha");
4151       } /* pixel (x) loop */
4152    } /* row (y) loop */
4153
4154    /* Record that something was actually checked to avoid a false positive. */
4155    dp->this.ps->validated = 1;
4156 }
4157
4158 static void
4159 transform_end(png_structp pp, png_infop pi)
4160 {
4161    transform_display *dp = png_get_progressive_ptr(pp);
4162
4163    transform_image_validate(dp, pp, pi, dp->this.ps->image);
4164 }
4165
4166 /* A single test run. */
4167 static void
4168 transform_test(png_modifier *pmIn, PNG_CONST png_uint_32 idIn,
4169     PNG_CONST image_transform* transform_listIn, PNG_CONST char *name)
4170 {
4171    transform_display d;
4172    context(&pmIn->this, fault);
4173
4174    transform_display_init(&d, pmIn, idIn, transform_listIn);
4175
4176    Try
4177    {
4178       png_structp pp;
4179       png_infop pi;
4180
4181       /* Get a png_struct for writing the image. */
4182       pp = set_modifier_for_read(d.pm, &pi, d.this.id, name);
4183
4184 #     if 0
4185          /* Logging (debugging only) */
4186          {
4187             char buffer[256];
4188
4189             (void)store_message(&d.pm->this, pp, buffer, sizeof buffer, 0,
4190                "running test");
4191
4192             fprintf(stderr, "%s\n", buffer);
4193          }
4194 #     endif
4195
4196       /* Introduce the correct read function. */
4197       if (d.pm->this.progressive)
4198       {
4199          /* Share the row function with the standard implementation. */
4200          png_set_progressive_read_fn(pp, &d, transform_info, progressive_row,
4201             transform_end);
4202
4203          /* Now feed data into the reader until we reach the end: */
4204          modifier_progressive_read(d.pm, pp, pi);
4205       }
4206       else
4207       {
4208          /* modifier_read expects a png_modifier* */
4209          png_set_read_fn(pp, d.pm, modifier_read);
4210
4211          /* Check the header values: */
4212          png_read_info(pp, pi);
4213
4214          /* Process the 'info' requirements. Only one image is generated */
4215          transform_info_imp(&d, pp, pi);
4216
4217          sequential_row(&d.this, pp, pi, NULL, d.this.ps->image);
4218
4219          transform_image_validate(&d, pp, pi, d.this.ps->image);
4220       }
4221
4222       modifier_reset(d.pm);
4223    }
4224
4225    Catch(fault)
4226       modifier_reset((png_modifier*)fault);
4227 }
4228
4229 /* The transforms: */
4230 #define ITSTRUCT(name) image_transform_##name
4231 #define IT(name,prev)\
4232 static image_transform ITSTRUCT(name) =\
4233 {\
4234    #name,\
4235    1, /*enable*/\
4236    &ITSTRUCT(prev), /*list*/\
4237    0, /*global_use*/\
4238    0, /*local_use*/\
4239    0, /*next*/\
4240    image_transform_png_set_##name##_set,\
4241    image_transform_png_set_##name##_mod,\
4242    image_transform_png_set_##name##_add\
4243 }
4244
4245 /* To save code: */
4246 static int
4247 image_transform_default_add(image_transform *this,
4248     PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
4249 {
4250    UNUSED(colour_type)
4251    UNUSED(bit_depth)
4252
4253    this->next = *that;
4254    *that = this;
4255
4256    return 1;
4257 }
4258
4259 /* png_set_palette_to_rgb */
4260 static void
4261 image_transform_png_set_palette_to_rgb_set(PNG_CONST image_transform *this,
4262     transform_display *that, png_structp pp, png_infop pi)
4263 {
4264    png_set_palette_to_rgb(pp);
4265    this->next->set(this->next, that, pp, pi);
4266 }
4267
4268 static void
4269 image_transform_png_set_palette_to_rgb_mod(PNG_CONST image_transform *this,
4270     image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
4271 {
4272    if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
4273       image_pixel_convert_PLTE(that, &display->this);
4274
4275    this->next->mod(this->next, that, pp, display);
4276 }
4277
4278 static int
4279 image_transform_png_set_palette_to_rgb_add(image_transform *this,
4280     PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
4281 {
4282    UNUSED(bit_depth)
4283
4284    this->next = *that;
4285    *that = this;
4286
4287    return colour_type == PNG_COLOR_TYPE_PALETTE;
4288 }
4289
4290 IT(palette_to_rgb, end);
4291
4292
4293 /* png_set_tRNS_to_alpha */
4294 static void
4295 image_transform_png_set_tRNS_to_alpha_set(PNG_CONST image_transform *this,
4296    transform_display *that, png_structp pp, png_infop pi)
4297 {
4298    png_set_tRNS_to_alpha(pp);
4299    this->next->set(this->next, that, pp, pi);
4300 }
4301
4302 static void
4303 image_transform_png_set_tRNS_to_alpha_mod(PNG_CONST image_transform *this,
4304    image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
4305 {
4306    /* LIBPNG BUG: this always forces palette images to RGB. */
4307    if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
4308       image_pixel_convert_PLTE(that, &display->this);
4309
4310    /* This effectively does an 'expand' only if there is some transparency to
4311     * covert to an alpha channel.
4312     */
4313    if (that->have_tRNS)
4314       image_pixel_add_alpha(that, &display->this);
4315
4316    /* LIBPNG BUG: otherwise libpng still expands to 8 bits! */
4317    else
4318    {
4319       if (that->bit_depth < 8)
4320          that->bit_depth =8;
4321       if (that->sample_depth < 8)
4322          that->sample_depth = 8;
4323    }
4324
4325    this->next->mod(this->next, that, pp, display);
4326 }
4327
4328 static int
4329 image_transform_png_set_tRNS_to_alpha_add(image_transform *this,
4330     PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
4331 {
4332    UNUSED(bit_depth)
4333
4334    this->next = *that;
4335    *that = this;
4336
4337    /* We don't know yet whether there will be a tRNS chunk, but we know that
4338     * this transformation should do nothing if there already is an alpha
4339     * channel.
4340     */
4341    return (colour_type & PNG_COLOR_MASK_ALPHA) == 0;
4342 }
4343
4344 IT(tRNS_to_alpha,palette_to_rgb);
4345
4346 /* png_set_gray_to_rgb */
4347 static void
4348 image_transform_png_set_gray_to_rgb_set(PNG_CONST image_transform *this,
4349     transform_display *that, png_structp pp, png_infop pi)
4350 {
4351    png_set_gray_to_rgb(pp);
4352    this->next->set(this->next, that, pp, pi);
4353 }
4354
4355 static void
4356 image_transform_png_set_gray_to_rgb_mod(PNG_CONST image_transform *this,
4357     image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
4358 {
4359    /* NOTE: we can actually pend the tRNS processing at this point because we
4360     * can correctly recognize the original pixel value even though we have
4361     * mapped the one gray channel to the three RGB ones, but in fact libpng
4362     * doesn't do this, so we don't either.
4363     */
4364    if ((that->colour_type & PNG_COLOR_MASK_COLOR) == 0 && that->have_tRNS)
4365       image_pixel_add_alpha(that, &display->this);
4366
4367    /* Simply expand the bit depth and alter the colour type as required. */
4368    if (that->colour_type == PNG_COLOR_TYPE_GRAY)
4369    {
4370       /* RGB images have a bit depth at least equal to '8' */
4371       if (that->bit_depth < 8)
4372          that->sample_depth = that->bit_depth = 8;
4373
4374       /* And just changing the colour type works here because the green and blue
4375        * channels are being maintained in lock-step with the red/gray:
4376        */
4377       that->colour_type = PNG_COLOR_TYPE_RGB;
4378    }
4379
4380    else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
4381       that->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
4382
4383    this->next->mod(this->next, that, pp, display);
4384 }
4385
4386 static int
4387 image_transform_png_set_gray_to_rgb_add(image_transform *this,
4388     PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
4389 {
4390    UNUSED(bit_depth)
4391
4392    this->next = *that;
4393    *that = this;
4394
4395    return (colour_type & PNG_COLOR_MASK_COLOR) == 0;
4396 }
4397
4398 IT(gray_to_rgb,tRNS_to_alpha);
4399
4400 /* png_set_expand */
4401 static void
4402 image_transform_png_set_expand_set(PNG_CONST image_transform *this,
4403     transform_display *that, png_structp pp, png_infop pi)
4404 {
4405    png_set_expand(pp);
4406    this->next->set(this->next, that, pp, pi);
4407 }
4408
4409 static void
4410 image_transform_png_set_expand_mod(PNG_CONST image_transform *this,
4411     image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
4412 {
4413    /* The general expand case depends on what the colour type is: */
4414    if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
4415       image_pixel_convert_PLTE(that, &display->this);
4416    else if (that->bit_depth < 8) /* grayscale */
4417       that->sample_depth = that->bit_depth = 8;
4418
4419    if (that->have_tRNS)
4420       image_pixel_add_alpha(that, &display->this);
4421
4422    this->next->mod(this->next, that, pp, display);
4423 }
4424
4425 static int
4426 image_transform_png_set_expand_add(image_transform *this,
4427     PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
4428 {
4429    UNUSED(bit_depth)
4430
4431    this->next = *that;
4432    *that = this;
4433
4434    /* 'expand' should do nothing for RGBA or GA input - no tRNS and the bit
4435     * depth is at least 8 already.
4436     */
4437    return (colour_type & PNG_COLOR_MASK_ALPHA) == 0;
4438 }
4439
4440 IT(expand,gray_to_rgb);
4441
4442 /* png_set_expand_gray_1_2_4_to_8
4443  * LIBPNG BUG: this just does an 'expand'
4444  */
4445 static void
4446 image_transform_png_set_expand_gray_1_2_4_to_8_set(
4447     PNG_CONST image_transform *this, transform_display *that, png_structp pp,
4448     png_infop pi)
4449 {
4450    png_set_expand_gray_1_2_4_to_8(pp);
4451    this->next->set(this->next, that, pp, pi);
4452 }
4453
4454 static void
4455 image_transform_png_set_expand_gray_1_2_4_to_8_mod(
4456     PNG_CONST image_transform *this, image_pixel *that, png_structp pp,
4457     PNG_CONST transform_display *display)
4458 {
4459    image_transform_png_set_expand_mod(this, that, pp, display);
4460 }
4461
4462 static int
4463 image_transform_png_set_expand_gray_1_2_4_to_8_add(image_transform *this,
4464     PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
4465 {
4466    return image_transform_png_set_expand_add(this, that, colour_type,
4467       bit_depth);
4468 }
4469
4470 IT(expand_gray_1_2_4_to_8, expand);
4471 /* png_set_expand_16 */
4472 static void
4473 image_transform_png_set_expand_16_set(PNG_CONST image_transform *this,
4474     transform_display *that, png_structp pp, png_infop pi)
4475 {
4476    png_set_expand_16(pp);
4477    this->next->set(this->next, that, pp, pi);
4478 }
4479
4480 static void
4481 image_transform_png_set_expand_16_mod(PNG_CONST image_transform *this,
4482     image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
4483 {
4484    /* Expect expand_16 to expand everything to 16 bits as a result of also
4485     * causing 'expand' to happen.
4486     */
4487    if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
4488       image_pixel_convert_PLTE(that, &display->this);
4489
4490    if (that->have_tRNS)
4491       image_pixel_add_alpha(that, &display->this);
4492
4493    if (that->bit_depth < 16)
4494       that->sample_depth = that->bit_depth = 16;
4495
4496    this->next->mod(this->next, that, pp, display);
4497 }
4498
4499 static int
4500 image_transform_png_set_expand_16_add(image_transform *this,
4501     PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
4502 {
4503    UNUSED(colour_type)
4504
4505    this->next = *that;
4506    *that = this;
4507
4508    /* expand_16 does something unless the bit depth is already 16. */
4509    return bit_depth < 16;
4510 }
4511
4512 IT(expand_16, expand_gray_1_2_4_to_8);
4513
4514 /* png_set_strip_16 */
4515 static void
4516 image_transform_png_set_strip_16_set(PNG_CONST image_transform *this,
4517     transform_display *that, png_structp pp, png_infop pi)
4518 {
4519    png_set_strip_16(pp);
4520    this->next->set(this->next, that, pp, pi);
4521 }
4522
4523 static void
4524 image_transform_png_set_strip_16_mod(PNG_CONST image_transform *this,
4525     image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
4526 {
4527    if (that->bit_depth == 16)
4528    {
4529       that->sample_depth = that->bit_depth = 8;
4530       if (that->red_sBIT > 8) that->red_sBIT = 8;
4531       if (that->green_sBIT > 8) that->green_sBIT = 8;
4532       if (that->blue_sBIT > 8) that->blue_sBIT = 8;
4533       if (that->alpha_sBIT > 8) that->alpha_sBIT = 8;
4534
4535 #     ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
4536          /* The strip 16 algoirithm drops the low 8 bits rather than calculating
4537           * 1/257, so we need to adjust the permitted errors appropriately:
4538           */
4539          {
4540             PNG_CONST double d = (255-128.5)/65535;
4541             that->rede += d;
4542             that->greene += d;
4543             that->bluee += d;
4544             that->alphae += d;
4545          }
4546 #     endif
4547    }
4548
4549    this->next->mod(this->next, that, pp, display);
4550 }
4551
4552 static int
4553 image_transform_png_set_strip_16_add(image_transform *this,
4554     PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
4555 {
4556    UNUSED(colour_type)
4557
4558    this->next = *that;
4559    *that = this;
4560
4561    return bit_depth > 8;
4562 }
4563
4564 IT(strip_16, expand_16);
4565
4566 /* png_set_strip_alpha */
4567 static void
4568 image_transform_png_set_strip_alpha_set(PNG_CONST image_transform *this,
4569     transform_display *that, png_structp pp, png_infop pi)
4570 {
4571    png_set_strip_alpha(pp);
4572    this->next->set(this->next, that, pp, pi);
4573 }
4574
4575 static void
4576 image_transform_png_set_strip_alpha_mod(PNG_CONST image_transform *this,
4577     image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
4578 {
4579    if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
4580       that->colour_type = PNG_COLOR_TYPE_GRAY;
4581    else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
4582       that->colour_type = PNG_COLOR_TYPE_RGB;
4583
4584    that->have_tRNS = 0;
4585    that->alphaf = 1;
4586    that->alphae = 0;
4587
4588    this->next->mod(this->next, that, pp, display);
4589 }
4590
4591 static int
4592 image_transform_png_set_strip_alpha_add(image_transform *this,
4593     PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
4594 {
4595    UNUSED(bit_depth)
4596
4597    this->next = *that;
4598    *that = this;
4599
4600    return (colour_type & PNG_COLOR_MASK_ALPHA) != 0;
4601 }
4602
4603 IT(strip_alpha,strip_16);
4604
4605 /* png_set_rgb_to_gray(png_structp, int err_action, double red, double green)
4606  * png_set_rgb_to_gray_fixed(png_structp, int err_action, png_fixed_point red,
4607  *    png_fixed_point green)
4608  * png_get_rgb_to_gray_status
4609  *
4610  * At present the APIs are simply tested using the 16.16 fixed point conversion
4611  * values known to be used inside libpng:
4612  *
4613  *   red:    6968
4614  *   green: 23434
4615  *   blue:   2366
4616  *
4617  * NOTE: this currently ignores the gamma because no gamma is being set, the
4618  * tests on gamma need to happen in the gamma test set.
4619  */
4620 static void
4621 image_transform_png_set_rgb_to_gray_set(PNG_CONST image_transform *this,
4622     transform_display *that, png_structp pp, png_infop pi)
4623 {
4624    PNG_CONST int error_action = 1; /* no error, no defines in png.h */
4625
4626 #  ifdef PNG_FLOATING_POINT_SUPPORTED
4627       png_set_rgb_to_gray(pp, error_action, -1, -1);
4628 #  else
4629       png_set_rgb_to_gray_fixed(pp, error_action, -1, -1);
4630 #  endif
4631
4632    this->next->set(this->next, that, pp, pi);
4633 }
4634
4635 static void
4636 image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
4637     image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
4638 {
4639    if ((that->colour_type & PNG_COLOR_MASK_COLOR) != 0)
4640    {
4641       if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
4642          image_pixel_convert_PLTE(that, &display->this);
4643
4644       /* Image now has RGB channels... */
4645       that->bluef = that->greenf = that->redf = (that->redf * 6968 +
4646          that->greenf * 23434 + that->bluef * 2366) / 32768;
4647       that->bluee = that->greene = that->rede = (that->rede * 6968 +
4648          that->greene * 23434 + that->bluee * 2366) / 32768 *
4649          (1 + DBL_EPSILON * 6);
4650
4651       /* The sBIT is the minium of the three colour channel sBITs. */
4652       if (that->red_sBIT > that->green_sBIT)
4653          that->red_sBIT = that->green_sBIT;
4654       if (that->red_sBIT > that->blue_sBIT)
4655          that->red_sBIT = that->blue_sBIT;
4656       that->blue_sBIT = that->green_sBIT = that->red_sBIT;
4657
4658       /* And zap the colour bit in the type: */
4659       if (that->colour_type == PNG_COLOR_TYPE_RGB)
4660          that->colour_type = PNG_COLOR_TYPE_GRAY;
4661       else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
4662          that->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA;
4663    }
4664
4665    this->next->mod(this->next, that, pp, display);
4666 }
4667
4668 static int
4669 image_transform_png_set_rgb_to_gray_add(image_transform *this,
4670     PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
4671 {
4672    UNUSED(bit_depth)
4673
4674    this->next = *that;
4675    *that = this;
4676
4677    return (colour_type & PNG_COLOR_MASK_COLOR) != 0;
4678 }
4679
4680 IT(rgb_to_gray,strip_alpha);
4681
4682 /* png_set_background(png_structp, png_const_color_16p background_color,
4683  *    int background_gamma_code, int need_expand, double background_gamma)
4684  * png_set_background_fixed(png_structp, png_const_color_16p background_color,
4685  *    int background_gamma_code, int need_expand,
4686  *    png_fixed_point background_gamma)
4687  *
4688  * As with rgb_to_gray this ignores the gamma.
4689 */
4690 static void
4691 image_transform_png_set_background_set(PNG_CONST image_transform *this,
4692     transform_display *that, png_structp pp, png_infop pi)
4693 {
4694    png_color_16 back;
4695
4696    /* Since we don't know the output bit depth at this point we must use the
4697     * input values and ask libpng to expand the chunk as required.
4698     */
4699    back.index = 255; /* Should not be used */
4700    back.gray = back.blue = back.green = back.red =
4701       (png_uint_16)((1U << that->this.bit_depth) >> 1);
4702
4703 #  ifdef PNG_FLOATING_POINT_SUPPORTED
4704       png_set_background(pp, &back, PNG_BACKGROUND_GAMMA_FILE, 1, 0);
4705 #  else
4706       png_set_background_fixed(pp, &back, PNG_BACKGROUND_GAMMA_FILE, 1, 0);
4707 #  endif
4708
4709    this->next->set(this->next, that, pp, pi);
4710 }
4711
4712 static void
4713 image_transform_png_set_background_mod(PNG_CONST image_transform *this,
4714     image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
4715 {
4716    /* Check for tRNS first: */
4717    if (that->have_tRNS && that->colour_type != PNG_COLOR_TYPE_PALETTE)
4718       image_pixel_add_alpha(that, &display->this);
4719
4720    /* This is only necessary if the alpha value is less than 1. */
4721    if (that->alphaf < 1)
4722    {
4723       /* Repeat the calculation above and scale the result: */
4724       unsigned int tmp = (1U << display->this.bit_depth);
4725       double component = (tmp >> 1)/(double)(tmp-1);
4726
4727       /* Now we do the background calculation without any gamma correction. */
4728       if (that->alphaf <= 0)
4729       {
4730          that->bluef = that->greenf = that->redf = component;
4731          that->bluee = that->greene = that->rede = component * DBL_EPSILON;
4732          that->blue_sBIT = that->green_sBIT = that->red_sBIT = that->bit_depth;
4733       }
4734
4735       else
4736       {
4737          component *= 1-that->alphaf;
4738          that->redf = that->redf * that->alphaf + component;
4739          that->rede = that->rede * that->alphaf + that->redf * 3 * DBL_EPSILON;
4740          that->greenf = that->greenf * that->alphaf + component;
4741          that->greene = that->greene * that->alphaf + that->greenf * 3 *
4742             DBL_EPSILON;
4743          that->bluef = that->bluef * that->alphaf + component;
4744          that->bluee = that->bluee * that->alphaf + that->bluef * 3 *
4745             DBL_EPSILON;
4746       }
4747
4748       /* Remove the alpha type and set the alpha. */
4749       that->alphaf = 1;
4750       that->alphae = 0;
4751
4752       if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
4753          that->colour_type = PNG_COLOR_TYPE_RGB;
4754       else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
4755          that->colour_type = PNG_COLOR_TYPE_GRAY;
4756    }
4757
4758    this->next->mod(this->next, that, pp, display);
4759 }
4760
4761 #define image_transform_png_set_background_add image_transform_default_add
4762
4763 IT(background,rgb_to_gray);
4764
4765 static image_transform *PNG_CONST image_transform_first = &ITSTRUCT(background);
4766
4767 static void
4768 transform_enable(PNG_CONST char *name)
4769 {
4770    /* Everything starts out enabled, so if we see an 'enable' disabled
4771     * everything else the first time round.
4772     */
4773    static int all_disabled = 0;
4774    int found_it = 0;
4775    image_transform *list = image_transform_first;
4776
4777    while (list != &image_transform_end)
4778    {
4779       if (strcmp(list->name, name) == 0)
4780       {
4781          list->enable = 1;
4782          found_it = 1;
4783       }
4784       else if (!all_disabled)
4785          list->enable = 0;
4786
4787       list = list->list;
4788    }
4789
4790    all_disabled = 1;
4791
4792    if (!found_it)
4793    {
4794       fprintf(stderr, "pngvalid: --transform-enable=%s: unknown transform\n",
4795          name);
4796       exit(1);
4797    }
4798 }
4799
4800 static void
4801 transform_disable(PNG_CONST char *name)
4802 {
4803    image_transform *list = image_transform_first;
4804
4805    while (list != &image_transform_end)
4806    {
4807       if (strcmp(list->name, name) == 0)
4808       {
4809          list->enable = 0;
4810          return;
4811       }
4812
4813       list = list->list;
4814    }
4815
4816    fprintf(stderr, "pngvalid: --transform-disable=%s: unknown transform\n",
4817       name);
4818    exit(1);
4819 }
4820
4821 static void
4822 image_transform_reset_count(void)
4823 {
4824    image_transform *next = image_transform_first;
4825    int count = 0;
4826
4827    while (next != &image_transform_end)
4828    {
4829       next->local_use = 0;
4830       next->next = 0;
4831       next = next->list;
4832       ++count;
4833    }
4834
4835    /* This can only happen if we every have more than 32 transforms (excluding
4836     * the end) in the list.
4837     */
4838    if (count > 32) abort();
4839 }
4840
4841 static int
4842 image_transform_test_counter(png_uint_32 counter, unsigned int max)
4843 {
4844    /* Test the list to see if there is any point contining, given a current
4845     * counter and a 'max' value.
4846     */
4847    image_transform *next = image_transform_first;
4848
4849    while (next != &image_transform_end)
4850    {
4851       /* For max 0 or 1 continue until the counter overflows: */
4852       counter >>= 1;
4853
4854       /* Continue if any entry hasn't reacked the max. */
4855       if (max > 1 && next->local_use < max)
4856          return 1;
4857       next = next->list;
4858    }
4859
4860    return max <= 1 && counter == 0;
4861 }
4862
4863 static png_uint_32
4864 image_transform_add(PNG_CONST image_transform **this, unsigned int max,
4865    png_uint_32 counter, char *name, size_t sizeof_name, size_t *pos,
4866    png_byte colour_type, png_byte bit_depth)
4867 {
4868    for (;;) /* until we manage to add something */
4869    {
4870       png_uint_32 mask;
4871       image_transform *list;
4872
4873       /* Find the next counter value, if the counter is zero this is the start
4874        * of the list.  This routine always returns the current counter (not the
4875        * next) so it returns 0 at the end and expects 0 at the beginning.
4876        */
4877       if (counter == 0) /* first time */
4878       {
4879          image_transform_reset_count();
4880          if (max <= 1)
4881             counter = 1;
4882          else
4883             counter = random_32();
4884       }
4885       else /* advance the counter */
4886       {
4887          switch (max)
4888          {
4889             case 0:  ++counter; break;
4890             case 1:  counter <<= 1; break;
4891             default: counter = random_32(); break;
4892          }
4893       }
4894
4895       /* Now add all these items, if possible */
4896       *this = &image_transform_end;
4897       list = image_transform_first;
4898       mask = 1;
4899
4900       /* Go through the whole list adding anything that the counter selects: */
4901       while (list != &image_transform_end)
4902       {
4903          if ((counter & mask) != 0 && list->enable &&
4904              (max == 0 || list->local_use < max))
4905          {
4906             /* Candidate to add: */
4907             if (list->add(list, this, colour_type, bit_depth) || max == 0)
4908             {
4909                /* Added, so add to the name too. */
4910                *pos = safecat(name, sizeof_name, *pos, " +");
4911                *pos = safecat(name, sizeof_name, *pos, list->name);
4912             }
4913
4914             else
4915             {
4916                /* Not useful and max>0, so remvoe it from *this: */
4917                *this = list->next;
4918                list->next = 0;
4919
4920                /* And, since we know it isn't useful, stop it being added again
4921                 * in this run:
4922                 */
4923                list->local_use = max;
4924             }
4925          }
4926
4927          mask <<= 1;
4928          list = list->list;
4929       }
4930
4931       /* Now if anything was added we have something to do. */
4932       if (*this != &image_transform_end)
4933          return counter;
4934
4935       /* Nothing added, but was there anything in there to add? */
4936       if (!image_transform_test_counter(counter, max))
4937          return 0;
4938    }
4939 }
4940
4941 #ifdef THIS_IS_THE_PROFORMA
4942 static void
4943 image_transform_png_set_@_set(PNG_CONST image_transform *this,
4944     transform_display *that, png_structp pp, png_infop pi)
4945 {
4946    png_set_@(pp);
4947    this->next->set(this->next, that, pp, pi);
4948 }
4949
4950 static void
4951 image_transform_png_set_@_mod(PNG_CONST image_transform *this,
4952     image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
4953 {
4954    this->next->mod(this->next, that, pp, display);
4955 }
4956
4957 static int
4958 image_transform_png_set_@_add(image_transform *this,
4959     PNG_CONST image_transform **that, char *name, size_t sizeof_name,
4960     size_t *pos, png_byte colour_type, png_byte bit_depth)
4961 {
4962    this->next = *that;
4963    *that = this;
4964
4965    *pos = safecat(name, sizeof_name, *pos, " +@");
4966
4967    return 1;
4968 }
4969
4970 IT(@);
4971 #endif
4972
4973 /* png_set_quantize(png_structp, png_colorp palette, int num_palette,
4974  *    int maximum_colors, png_const_uint_16p histogram, int full_quantize)
4975  *
4976  * Very difficult to validate this!
4977  */
4978 /*NOTE: TBD NYI */
4979
4980 /* The data layout transforms are handled by swapping our own channel data,
4981  * necessarily these need to happen at the end of the transform list because the
4982  * semantic of the channels changes after these are executed.  Some of these,
4983  * like set_shift and set_packing, can't be done at present because they change
4984  * the layout of the data at the sub-sample level so sample() won't get the
4985  * right answer.
4986  */
4987 /* png_set_invert_alpha */
4988 /*NOTE: TBD NYI */
4989
4990 /* png_set_bgr */
4991 /*NOTE: TBD NYI */
4992
4993 /* png_set_swap_alpha */
4994 /*NOTE: TBD NYI */
4995
4996 /* png_set_swap */
4997 /*NOTE: TBD NYI */
4998
4999 /* png_set_filler, (png_structp png_ptr, png_uint_32 filler, int flags)); */
5000 /*NOTE: TBD NYI */
5001
5002 /* png_set_add_alpha, (png_structp png_ptr, png_uint_32 filler, int flags)); */
5003 /*NOTE: TBD NYI */
5004
5005 /* png_set_packing */
5006 /*NOTE: TBD NYI */
5007
5008 /* png_set_packswap */
5009 /*NOTE: TBD NYI */
5010
5011 /* png_set_invert_mono */
5012 /*NOTE: TBD NYI */
5013
5014 /* png_set_shift(png_structp, png_const_color_8p true_bits) */
5015 /*NOTE: TBD NYI */
5016
5017 static int
5018 test_transform(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type,
5019     int bdlo, int PNG_CONST bdhi, png_uint_32 max)
5020 {
5021    for (; bdlo <= bdhi; ++bdlo)
5022    {
5023       PNG_CONST png_byte bit_depth = DEPTH(bdlo);
5024       png_uint_32 counter = 0;
5025       size_t base_pos;
5026       char name[64];
5027
5028       base_pos = safecat(name, sizeof name, 0, "transform:");
5029
5030       for (;;)
5031       {
5032          size_t pos = base_pos;
5033          PNG_CONST image_transform *list = 0;
5034
5035          counter = image_transform_add(&list, max, counter, name, sizeof name,
5036             &pos, colour_type, bit_depth);
5037
5038          if (counter == 0)
5039             break;
5040
5041          /* The command line can change this to checking interlaced images. */
5042          transform_test(pm, FILEID(colour_type, bit_depth, pm->interlace_type,
5043             0, 0, 0), list, name);
5044
5045          if (fail(pm))
5046             return 0;
5047       }
5048    }
5049
5050    return 1; /* keep going */
5051 }
5052
5053 static void
5054 perform_transform_test(png_modifier *pm)
5055 {
5056    /* Test each colour type over the valid range of bit depths (expressed as
5057     * log2(bit_depth) in turn, stop as soon as any error is detected.
5058     */
5059    if (!test_transform(pm, 0, 0, READ_BDHI, 1))
5060       return;
5061
5062    if (!test_transform(pm, 2, 3, READ_BDHI, 1))
5063       return;
5064
5065    if (!test_transform(pm, 3, 0, 3, 1))
5066       return;
5067
5068    if (!test_transform(pm, 4, 3, READ_BDHI, 1))
5069       return;
5070
5071    if (!test_transform(pm, 6, 3, READ_BDHI, 1))
5072       return;
5073 }
5074
5075
5076 /********************************* GAMMA TESTS ********************************/
5077 /* Gamma test images. */
5078 typedef struct gamma_modification
5079 {
5080    png_modification this;
5081    png_fixed_point  gamma;
5082 } gamma_modification;
5083
5084 static int
5085 gamma_modify(png_modifier *pm, png_modification *me, int add)
5086 {
5087    UNUSED(add)
5088    /* This simply dumps the given gamma value into the buffer. */
5089    png_save_uint_32(pm->buffer, 4);
5090    png_save_uint_32(pm->buffer+4, CHUNK_gAMA);
5091    png_save_uint_32(pm->buffer+8, ((gamma_modification*)me)->gamma);
5092    return 1;
5093 }
5094
5095 static void
5096 gamma_modification_init(gamma_modification *me, png_modifier *pm, double gammad)
5097 {
5098    double g;
5099
5100    modification_init(&me->this);
5101    me->this.chunk = CHUNK_gAMA;
5102    me->this.modify_fn = gamma_modify;
5103    me->this.add = CHUNK_PLTE;
5104    g = floor(gammad * 100000 + .5);
5105    me->gamma = (png_fixed_point)g;
5106    me->this.next = pm->modifications;
5107    pm->modifications = &me->this;
5108 }
5109
5110 typedef struct srgb_modification
5111 {
5112    png_modification this;
5113    png_byte         intent;
5114 } srgb_modification;
5115
5116 static int
5117 srgb_modify(png_modifier *pm, png_modification *me, int add)
5118 {
5119    UNUSED(add)
5120    /* As above, ignore add and just make a new chunk */
5121    png_save_uint_32(pm->buffer, 1);
5122    png_save_uint_32(pm->buffer+4, CHUNK_sRGB);
5123    pm->buffer[8] = ((srgb_modification*)me)->intent;
5124    return 1;
5125 }
5126
5127 static void
5128 srgb_modification_init(srgb_modification *me, png_modifier *pm, png_byte intent)
5129 {
5130    modification_init(&me->this);
5131    me->this.chunk = CHUNK_sBIT;
5132
5133    if (intent <= 3) /* if valid, else *delete* sRGB chunks */
5134    {
5135       me->this.modify_fn = srgb_modify;
5136       me->this.add = CHUNK_PLTE;
5137       me->intent = intent;
5138    }
5139
5140    else
5141    {
5142       me->this.modify_fn = 0;
5143       me->this.add = 0;
5144       me->intent = 0;
5145    }
5146
5147    me->this.next = pm->modifications;
5148    pm->modifications = &me->this;
5149 }
5150
5151 typedef struct sbit_modification
5152 {
5153    png_modification this;
5154    png_byte         sbit;
5155 } sbit_modification;
5156
5157 static int
5158 sbit_modify(png_modifier *pm, png_modification *me, int add)
5159 {
5160    png_byte sbit = ((sbit_modification*)me)->sbit;
5161    if (pm->bit_depth > sbit)
5162    {
5163       int cb = 0;
5164       switch (pm->colour_type)
5165       {
5166          case 0:
5167             cb = 1;
5168             break;
5169
5170          case 2:
5171          case 3:
5172             cb = 3;
5173             break;
5174
5175          case 4:
5176             cb = 2;
5177             break;
5178
5179          case 6:
5180             cb = 4;
5181             break;
5182
5183          default:
5184             png_error(pm->this.pread,
5185                "unexpected colour type in sBIT modification");
5186       }
5187
5188       png_save_uint_32(pm->buffer, cb);
5189       png_save_uint_32(pm->buffer+4, CHUNK_sBIT);
5190
5191       while (cb > 0)
5192          (pm->buffer+8)[--cb] = sbit;
5193
5194       return 1;
5195    }
5196    else if (!add)
5197    {
5198       /* Remove the sBIT chunk */
5199       pm->buffer_count = pm->buffer_position = 0;
5200       return 1;
5201    }
5202    else
5203       return 0; /* do nothing */
5204 }
5205
5206 static void
5207 sbit_modification_init(sbit_modification *me, png_modifier *pm, png_byte sbit)
5208 {
5209    modification_init(&me->this);
5210    me->this.chunk = CHUNK_sBIT;
5211    me->this.modify_fn = sbit_modify;
5212    me->this.add = CHUNK_PLTE;
5213    me->sbit = sbit;
5214    me->this.next = pm->modifications;
5215    pm->modifications = &me->this;
5216 }
5217
5218 /* Reader callbacks and implementations, where they differ from the standard
5219  * ones.
5220  */
5221 typedef struct gamma_display
5222 {
5223    standard_display this;
5224
5225    /* Parameters */
5226    png_modifier*    pm;
5227    double           file_gamma;
5228    double           screen_gamma;
5229    png_byte         sbit;
5230    int              threshold_test;
5231    PNG_CONST char*  name;
5232    int              speed;
5233    int              use_input_precision;
5234    int              strip16;
5235
5236    /* Local variables */
5237    double       maxerrout;
5238    double       maxerrpc;
5239    double       maxerrabs;
5240 } gamma_display;
5241
5242 static void
5243 gamma_display_init(gamma_display *dp, png_modifier *pm, png_uint_32 id,
5244     double file_gamma, double screen_gamma, png_byte sbit, int threshold_test,
5245     int speed, int use_input_precision, int strip16)
5246 {
5247    /* Standard fields */
5248    standard_display_init(&dp->this, &pm->this, id, 0/*do_interlace*/);
5249
5250    /* Parameter fields */
5251    dp->pm = pm;
5252    dp->file_gamma = file_gamma;
5253    dp->screen_gamma = screen_gamma;
5254    dp->sbit = sbit;
5255    dp->threshold_test = threshold_test;
5256    dp->speed = speed;
5257    dp->use_input_precision = use_input_precision;
5258    dp->strip16 = strip16;
5259
5260    /* Local variable fields */
5261    dp->maxerrout = dp->maxerrpc = dp->maxerrabs = 0;
5262 }
5263
5264 static void
5265 gamma_info_imp(gamma_display *dp, png_structp pp, png_infop pi)
5266 {
5267    /* Reuse the standard stuff as appropriate. */
5268    standard_info_part1(&dp->this, pp, pi);
5269
5270    /* If requested strip 16 to 8 bits - this is handled automagically below
5271     * because the output bit depth is read from the library.  Note that there
5272     * are interactions with sBIT but, internally, libpng makes sbit at most
5273     * PNG_MAX_GAMMA_8 when doing the following.
5274     */
5275    if (dp->strip16)
5276 #     ifdef PNG_READ_16_TO_8_SUPPORTED
5277          png_set_strip_16(pp);
5278 #     else
5279          png_error(pp, "strip16 (16 to 8 bit conversion) not supported");
5280 #     endif
5281
5282    png_read_update_info(pp, pi);
5283
5284    /* Now we may get a different cbRow: */
5285    standard_info_part2(&dp->this, pp, pi, 1 /*images*/);
5286 }
5287
5288 static void
5289 gamma_info(png_structp pp, png_infop pi)
5290 {
5291    gamma_info_imp(png_get_progressive_ptr(pp), pp, pi);
5292 }
5293
5294 static void
5295 gamma_image_validate(gamma_display *dp, png_structp pp, png_infop pi,
5296     png_const_bytep pRow)
5297 {
5298    /* Get some constants derived from the input and output file formats: */
5299    PNG_CONST png_byte sbit = dp->sbit;
5300    PNG_CONST double file_gamma = dp->file_gamma;
5301    PNG_CONST double screen_gamma = dp->screen_gamma;
5302    PNG_CONST int use_input_precision = dp->use_input_precision;
5303    PNG_CONST int speed = dp->speed;
5304    PNG_CONST png_byte in_ct = dp->this.colour_type;
5305    PNG_CONST png_byte in_bd = dp->this.bit_depth;
5306    PNG_CONST png_uint_32 w = dp->this.w;
5307    PNG_CONST png_uint_32 h = dp->this.h;
5308    PNG_CONST size_t cbRow = dp->this.cbRow;
5309    PNG_CONST png_byte out_ct = png_get_color_type(pp, pi);
5310    PNG_CONST png_byte out_bd = png_get_bit_depth(pp, pi);
5311    PNG_CONST unsigned int outmax = (1U<<out_bd)-1;
5312    PNG_CONST double maxabs = abserr(dp->pm, out_bd);
5313    PNG_CONST double maxout = outerr(dp->pm, out_bd);
5314    PNG_CONST double maxpc = pcerr(dp->pm, out_bd);
5315
5316    /* There are three sources of error, firstly the quantization in the
5317     * file encoding, determined by sbit and/or the file depth, secondly
5318     * the output (screen) gamma and thirdly the output file encoding.
5319     *
5320     * Since this API receives the screen and file gamma in double
5321     * precision it is possible to calculate an exact answer given an input
5322     * pixel value.  Therefore we assume that the *input* value is exact -
5323     * sample/maxsample - calculate the corresponding gamma corrected
5324     * output to the limits of double precision arithmetic and compare with
5325     * what libpng returns.
5326     *
5327     * Since the library must quantize the output to 8 or 16 bits there is
5328     * a fundamental limit on the accuracy of the output of +/-.5 - this
5329     * quantization limit is included in addition to the other limits
5330     * specified by the paramaters to the API.  (Effectively, add .5
5331     * everywhere.)
5332     *
5333     * The behavior of the 'sbit' paramter is defined by section 12.5
5334     * (sample depth scaling) of the PNG spec.  That section forces the
5335     * decoder to assume that the PNG values have been scaled if sBIT is
5336     * present:
5337     *
5338     *     png-sample = floor( input-sample * (max-out/max-in) + .5);
5339     *
5340     * This means that only a subset of the possible PNG values should
5341     * appear in the input. However, the spec allows the encoder to use a
5342     * variety of approximations to the above and doesn't require any
5343     * restriction of the values produced.
5344     *
5345     * Nevertheless the spec requires that the upper 'sBIT' bits of the
5346     * value stored in a PNG file be the original sample bits.
5347     * Consequently the code below simply scales the top sbit bits by
5348     * (1<<sbit)-1 to obtain an original sample value.
5349     *
5350     * Because there is limited precision in the input it is arguable that
5351     * an acceptable result is any valid result from input-.5 to input+.5.
5352     * The basic tests below do not do this, however if
5353     * 'use_input_precision' is set a subsequent test is performed below.
5354     */
5355    PNG_CONST int processing = (fabs(screen_gamma*file_gamma-1) >=
5356       PNG_GAMMA_THRESHOLD && !dp->threshold_test && !speed && in_ct != 3) ||
5357       in_bd != out_bd;
5358
5359    PNG_CONST unsigned int samples_per_pixel = (out_ct & 2U) ? 3U : 1U;
5360
5361    PNG_CONST double gamma_correction = 1/(file_gamma*screen_gamma);/* Overall */
5362
5363    double maxerrout = 0, maxerrabs = 0, maxerrpc = 0;
5364    png_uint_32 y;
5365
5366    for (y=0; y<h; ++y, pRow += cbRow)
5367    {
5368       unsigned int s, x;
5369       png_byte std[STANDARD_ROWMAX];
5370
5371       transform_row(pp, std, in_ct, in_bd, y);
5372
5373       if (processing)
5374       {
5375          for (x=0; x<w; ++x) for (s=0; s<samples_per_pixel; ++s)
5376          {
5377             /* Input sample values: */
5378             PNG_CONST unsigned int
5379                id = sample(std, in_ct, in_bd, x, s);
5380
5381             PNG_CONST unsigned int
5382                od = sample(pRow, out_ct, out_bd, x, s);
5383
5384             PNG_CONST unsigned int
5385                isbit = id >> (in_bd-sbit);
5386
5387             double i, input_sample, encoded_sample, output;
5388             double encoded_error, error;
5389             double es_lo, es_hi;
5390
5391             /* First check on the 'perfect' result obtained from the
5392              * digitized input value, id, and compare this against the
5393              * actual digitized result, 'od'.  'i' is the input result
5394              * in the range 0..1:
5395              *
5396              * NOTE: sBIT should be taken into account here but isn't,
5397              * as described above.
5398              */
5399             i = isbit; i /= (1U<<sbit)-1;
5400
5401             /* Then get the gamma corrected version of 'i' and compare
5402              * to 'od', any error less than .5 is insignificant - just
5403              * quantization of the output value to the nearest digital
5404              * value (nevertheless the error is still recorded - it's
5405              * interesting ;-)
5406              */
5407             encoded_sample = pow(i, gamma_correction) * outmax;
5408             encoded_error = fabs(od-encoded_sample);
5409
5410             if (encoded_error > maxerrout)
5411                maxerrout = encoded_error;
5412
5413             if (encoded_error < .5+maxout)
5414                continue;
5415
5416             /* There may be an error, so calculate the actual sample
5417              * values - unencoded light intensity values.  Note that
5418              * in practice these are not unencoded because they
5419              * include a 'viewing correction' to decrease or
5420              * (normally) increase the perceptual contrast of the
5421              * image.  There's nothing we can do about this - we don't
5422              * know what it is - so assume the unencoded value is
5423              * perceptually linear.
5424              */
5425             input_sample = pow(i, 1/file_gamma); /* In range 0..1 */
5426             output = od;
5427             output /= outmax;
5428             output = pow(output, screen_gamma);
5429
5430             /* Now we have the numbers for real errors, both absolute
5431              * values as as a percentage of the correct value (output):
5432              */
5433             error = fabs(input_sample-output);
5434
5435             if (error > maxerrabs)
5436                maxerrabs = error;
5437
5438             /* The following is an attempt to ignore the tendency of
5439              * quantization to dominate the percentage errors for low
5440              * output sample values:
5441              */
5442             if (input_sample*maxpc > .5+maxabs)
5443             {
5444                double percentage_error = error/input_sample;
5445                if (percentage_error > maxerrpc) maxerrpc = percentage_error;
5446             }
5447
5448             /* Now calculate the digitization limits for
5449              * 'encoded_sample' using the 'max' values.  Note that
5450              * maxout is in the encoded space but maxpc and maxabs are
5451              * in linear light space.
5452              *
5453              * First find the maximum error in linear light space,
5454              * range 0..1:
5455              */
5456             {
5457                double tmp = input_sample * maxpc;
5458                if (tmp < maxabs) tmp = maxabs;
5459
5460                /* Low bound - the minimum of the three: */
5461                es_lo = encoded_sample - maxout;
5462
5463                if (es_lo > 0 && input_sample-tmp > 0)
5464                {
5465                   double low_value = outmax * pow(input_sample-tmp,
5466                      1/screen_gamma);
5467                   if (low_value < es_lo) es_lo = low_value;
5468                }
5469
5470                else
5471                   es_lo = 0;
5472
5473                es_hi = encoded_sample + maxout;
5474
5475                if (es_hi < outmax && input_sample+tmp < 1)
5476                {
5477                   double high_value = outmax * pow(input_sample+tmp,
5478                      1/screen_gamma);
5479                   if (high_value > es_hi) es_hi = high_value;
5480                }
5481
5482                else
5483                   es_hi = outmax;
5484             }
5485
5486             /* The primary test is that the final encoded value
5487              * returned by the library should be between the two limits
5488              * (inclusive) that were calculated above.  At this point
5489              * quantization of the output must be taken into account.
5490              */
5491             if (od+.5 < es_lo || od-.5 > es_hi)
5492             {
5493                /* There has been an error in processing. */
5494                double is_lo, is_hi;
5495
5496                if (use_input_precision)
5497                {
5498                   /* Ok, something is wrong - this actually happens in
5499                    * current libpng sbit processing.  Assume that the
5500                    * input value (id, adjusted for sbit) can be
5501                    * anywhere between value-.5 and value+.5 - quite a
5502                    * large range if sbit is low.
5503                    */
5504                   double tmp = (isbit - .5)/((1U<<sbit)-1);
5505
5506                   if (tmp > 0)
5507                   {
5508                      is_lo = outmax * pow(tmp, gamma_correction) - maxout;
5509                      if (is_lo < 0) is_lo = 0;
5510                   }
5511
5512                   else
5513                      is_lo = 0;
5514
5515                   tmp = (isbit + .5)/((1U<<sbit)-1);
5516
5517                   if (tmp < 1)
5518                   {
5519                      is_hi = outmax * pow(tmp, gamma_correction) + maxout;
5520                      if (is_hi > outmax) is_hi = outmax;
5521                   }
5522
5523                   else
5524                      is_hi = outmax;
5525
5526                   if (!(od+.5 < is_lo || od-.5 > is_hi))
5527                      continue;
5528                }
5529                else
5530                   is_lo = es_lo, is_hi = es_hi;
5531
5532                {
5533                   char msg[256];
5534
5535                   sprintf(msg,
5536                    "error: %.3f; %u{%u;%u} -> %u not %.2f (%.1f-%.1f)",
5537                      od-encoded_sample, id, sbit, isbit, od,
5538                      encoded_sample, is_lo, is_hi);
5539
5540                   png_warning(pp, msg);
5541                }
5542             }
5543          }
5544       }
5545
5546       else if (!speed && memcmp(std, pRow, cbRow) != 0)
5547       {
5548          char msg[64];
5549
5550          /* No transform is expected on the threshold tests. */
5551          sprintf(msg, "gamma: below threshold row %d changed", y);
5552
5553          png_error(pp, msg);
5554       }
5555    } /* row (y) loop */
5556
5557    dp->maxerrout = maxerrout;
5558    dp->maxerrabs = maxerrabs;
5559    dp->maxerrpc = maxerrpc;
5560    dp->this.ps->validated = 1;
5561 }
5562
5563 static void
5564 gamma_end(png_structp pp, png_infop pi)
5565 {
5566    gamma_display *dp = png_get_progressive_ptr(pp);
5567
5568    gamma_image_validate(dp, pp, pi, dp->this.ps->image);
5569 }
5570
5571 /* A single test run checking a gamma transformation.
5572  *
5573  * maxabs: maximum absolute error as a fraction
5574  * maxout: maximum output error in the output units
5575  * maxpc:  maximum percentage error (as a percentage)
5576  */
5577 static void
5578 gamma_test(png_modifier *pmIn, PNG_CONST png_byte colour_typeIn,
5579     PNG_CONST png_byte bit_depthIn, PNG_CONST int interlace_typeIn,
5580     PNG_CONST double file_gammaIn, PNG_CONST double screen_gammaIn,
5581     PNG_CONST png_byte sbitIn, PNG_CONST int threshold_testIn,
5582     PNG_CONST char *name, PNG_CONST int speedIn,
5583     PNG_CONST int use_input_precisionIn, PNG_CONST int strip16In)
5584 {
5585    gamma_display d;
5586    context(&pmIn->this, fault);
5587
5588    gamma_display_init(&d, pmIn, FILEID(colour_typeIn, bit_depthIn,
5589       interlace_typeIn, 0, 0, 0), file_gammaIn, screen_gammaIn, sbitIn,
5590       threshold_testIn, speedIn, use_input_precisionIn, strip16In);
5591
5592    Try
5593    {
5594       png_structp pp;
5595       png_infop pi;
5596       gamma_modification gamma_mod;
5597       srgb_modification srgb_mod;
5598       sbit_modification sbit_mod;
5599
5600       /* Make an appropriate modifier to set the PNG file gamma to the
5601        * given gamma value and the sBIT chunk to the given precision.
5602        */
5603       d.pm->modifications = NULL;
5604       gamma_modification_init(&gamma_mod, d.pm, d.file_gamma);
5605       srgb_modification_init(&srgb_mod, d.pm, 127 /*delete*/);
5606       sbit_modification_init(&sbit_mod, d.pm, d.sbit);
5607
5608       modification_reset(d.pm->modifications);
5609
5610       /* Get a png_struct for writing the image. */
5611       pp = set_modifier_for_read(d.pm, &pi, d.this.id, name);
5612
5613       /* Set up gamma processing. */
5614 #ifdef PNG_FLOATING_POINT_SUPPORTED
5615       png_set_gamma(pp, d.screen_gamma, d.file_gamma);
5616 #else
5617       {
5618          png_fixed_point s = floor(d.screen_gamma*100000+.5);
5619          png_fixed_point f = floor(d.file_gamma*100000+.5);
5620          png_set_gamma_fixed(pp, s, f);
5621       }
5622 #endif
5623
5624       /* Introduce the correct read function. */
5625       if (d.pm->this.progressive)
5626       {
5627          /* Share the row function with the standard implementation. */
5628          png_set_progressive_read_fn(pp, &d, gamma_info, progressive_row,
5629             gamma_end);
5630
5631          /* Now feed data into the reader until we reach the end: */
5632          modifier_progressive_read(d.pm, pp, pi);
5633       }
5634       else
5635       {
5636          /* modifier_read expects a png_modifier* */
5637          png_set_read_fn(pp, d.pm, modifier_read);
5638
5639          /* Check the header values: */
5640          png_read_info(pp, pi);
5641
5642          /* Process the 'info' requirements. Only one image is generated */
5643          gamma_info_imp(&d, pp, pi);
5644
5645          sequential_row(&d.this, pp, pi, NULL, d.this.ps->image);
5646
5647          gamma_image_validate(&d, pp, pi, d.this.ps->image);
5648       }
5649
5650       modifier_reset(d.pm);
5651
5652       if (d.pm->log && !d.threshold_test && !d.speed)
5653          fprintf(stderr, "%d bit %s %s: max error %f (%.2g, %2g%%)\n",
5654             d.this.bit_depth, colour_types[d.this.colour_type], d.name,
5655             d.maxerrout, d.maxerrabs, 100*d.maxerrpc);
5656
5657       /* Log the summary values too. */
5658       if (d.this.colour_type == 0 || d.this.colour_type == 4)
5659       {
5660          switch (d.this.bit_depth)
5661          {
5662          case 1:
5663             break;
5664
5665          case 2:
5666             if (d.maxerrout > d.pm->error_gray_2)
5667                d.pm->error_gray_2 = d.maxerrout;
5668
5669             break;
5670
5671          case 4:
5672             if (d.maxerrout > d.pm->error_gray_4)
5673                d.pm->error_gray_4 = d.maxerrout;
5674
5675             break;
5676
5677          case 8:
5678             if (d.maxerrout > d.pm->error_gray_8)
5679                d.pm->error_gray_8 = d.maxerrout;
5680
5681             break;
5682
5683          case 16:
5684             if (d.maxerrout > d.pm->error_gray_16)
5685                d.pm->error_gray_16 = d.maxerrout;
5686
5687             break;
5688
5689          default:
5690             png_error(pp, "bad bit depth (internal: 1)");
5691          }
5692       }
5693
5694       else if (d.this.colour_type == 2 || d.this.colour_type == 6)
5695       {
5696          switch (d.this.bit_depth)
5697          {
5698          case 8:
5699
5700             if (d.maxerrout > d.pm->error_color_8)
5701                d.pm->error_color_8 = d.maxerrout;
5702
5703             break;
5704
5705          case 16:
5706
5707             if (d.maxerrout > d.pm->error_color_16)
5708                d.pm->error_color_16 = d.maxerrout;
5709
5710             break;
5711
5712          default:
5713             png_error(pp, "bad bit depth (internal: 2)");
5714          }
5715       }
5716    }
5717
5718    Catch(fault)
5719       modifier_reset((png_modifier*)fault);
5720 }
5721
5722 static void gamma_threshold_test(png_modifier *pm, png_byte colour_type,
5723     png_byte bit_depth, int interlace_type, double file_gamma,
5724     double screen_gamma)
5725 {
5726    size_t pos = 0;
5727    char name[64];
5728    pos = safecat(name, sizeof name, pos, "threshold ");
5729    pos = safecatd(name, sizeof name, pos, file_gamma, 3);
5730    pos = safecat(name, sizeof name, pos, "/");
5731    pos = safecatd(name, sizeof name, pos, screen_gamma, 3);
5732
5733    (void)gamma_test(pm, colour_type, bit_depth, interlace_type, file_gamma,
5734       screen_gamma, bit_depth, 1, name, 0 /*speed*/, 0 /*no input precision*/,
5735       0 /*no strip16*/);
5736 }
5737
5738 static void
5739 perform_gamma_threshold_tests(png_modifier *pm)
5740 {
5741    png_byte colour_type = 0;
5742    png_byte bit_depth = 0;
5743
5744    while (next_format(&colour_type, &bit_depth))
5745    {
5746       double test_gamma = 1.0;
5747       while (test_gamma >= .4)
5748       {
5749          /* There's little point testing the interlacing vs non-interlacing,
5750           * but this can be set from the command line.
5751           */
5752          gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type,
5753             test_gamma, 1/test_gamma);
5754          test_gamma *= .95;
5755       }
5756
5757       /* And a special test for sRGB */
5758       gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type,
5759           .45455, 2.2);
5760
5761       if (fail(pm))
5762          return;
5763    }
5764 }
5765
5766 static void gamma_transform_test(png_modifier *pm,
5767    PNG_CONST png_byte colour_type, PNG_CONST png_byte bit_depth,
5768    PNG_CONST int interlace_type, PNG_CONST double file_gamma,
5769    PNG_CONST double screen_gamma, PNG_CONST png_byte sbit, PNG_CONST int speed,
5770    PNG_CONST int use_input_precision, PNG_CONST int strip16)
5771 {
5772    size_t pos = 0;
5773    char name[64];
5774
5775    if (sbit != bit_depth)
5776    {
5777       pos = safecat(name, sizeof name, pos, "sbit(");
5778       pos = safecatn(name, sizeof name, pos, sbit);
5779       pos = safecat(name, sizeof name, pos, ") ");
5780    }
5781
5782    else
5783       pos = safecat(name, sizeof name, pos, "gamma ");
5784
5785    if (strip16)
5786       pos = safecat(name, sizeof name, pos, "16to8 ");
5787
5788    pos = safecatd(name, sizeof name, pos, file_gamma, 3);
5789    pos = safecat(name, sizeof name, pos, "->");
5790    pos = safecatd(name, sizeof name, pos, screen_gamma, 3);
5791
5792    gamma_test(pm, colour_type, bit_depth, interlace_type, file_gamma,
5793       screen_gamma, sbit, 0, name, speed, use_input_precision, strip16);
5794 }
5795
5796 static void perform_gamma_transform_tests(png_modifier *pm, int speed)
5797 {
5798    png_byte colour_type = 0;
5799    png_byte bit_depth = 0;
5800
5801    /* Ignore palette images - the gamma correction happens on the palette entry,
5802     * haven't got the tests for this yet.
5803     */
5804    while (next_format(&colour_type, &bit_depth)) if (colour_type != 3)
5805    {
5806       unsigned int i, j;
5807
5808       for (i=0; i<pm->ngammas; ++i) for (j=0; j<pm->ngammas; ++j) if (i != j)
5809       {
5810          gamma_transform_test(pm, colour_type, bit_depth, pm->interlace_type,
5811             1/pm->gammas[i], pm->gammas[j], bit_depth, speed,
5812             pm->use_input_precision, 0 /*do not strip16*/);
5813
5814          if (fail(pm))
5815             return;
5816       }
5817    }
5818 }
5819
5820 static void perform_gamma_sbit_tests(png_modifier *pm, int speed)
5821 {
5822    png_byte sbit;
5823
5824    /* The only interesting cases are colour and grayscale, alpha is ignored here
5825     * for overall speed.  Only bit depths 8 and 16 are tested.
5826     */
5827    for (sbit=pm->sbitlow; sbit<(1<<READ_BDHI); ++sbit)
5828    {
5829       unsigned int i, j;
5830
5831       for (i=0; i<pm->ngammas; ++i)
5832       {
5833          for (j=0; j<pm->ngammas; ++j)
5834          {
5835             if (i != j)
5836             {
5837                if (sbit < 8)
5838                {
5839                   gamma_transform_test(pm, 0, 8, pm->interlace_type,
5840                       1/pm->gammas[i], pm->gammas[j], sbit, speed,
5841                       pm->use_input_precision_sbit, 0 /*strip16*/);
5842
5843                   if (fail(pm))
5844                      return;
5845
5846                   gamma_transform_test(pm, 2, 8, pm->interlace_type,
5847                       1/pm->gammas[i], pm->gammas[j], sbit, speed,
5848                       pm->use_input_precision_sbit, 0 /*strip16*/);
5849
5850                   if (fail(pm))
5851                      return;
5852                }
5853
5854 #ifdef DO_16BIT
5855                gamma_transform_test(pm, 0, 16, pm->interlace_type,
5856                    1/pm->gammas[i], pm->gammas[j], sbit, speed,
5857                    pm->use_input_precision_sbit, 0 /*strip16*/);
5858
5859                if (fail(pm))
5860                   return;
5861
5862                gamma_transform_test(pm, 2, 16, pm->interlace_type,
5863                    1/pm->gammas[i], pm->gammas[j], sbit, speed,
5864                    pm->use_input_precision_sbit, 0 /*strip16*/);
5865
5866                if (fail(pm))
5867                   return;
5868 #endif
5869             }
5870          }
5871       }
5872    }
5873 }
5874
5875 /* Note that this requires a 16 bit source image but produces 8 bit output, so
5876  * we only need the 16bit write support.
5877  */
5878 #ifdef PNG_READ_16_TO_8_SUPPORTED
5879 static void perform_gamma_strip16_tests(png_modifier *pm, int speed)
5880 {
5881 #  ifndef PNG_MAX_GAMMA_8
5882 #     define PNG_MAX_GAMMA_8 11
5883 #  endif
5884    /* Include the alpha cases here. Note that sbit matches the internal value
5885     * used by the library - otherwise we will get spurious errors from the
5886     * internal sbit style approximation.
5887     *
5888     * The threshold test is here because otherwise the 16 to 8 conversion will
5889     * proceed *without* gamma correction, and the tests above will fail (but not
5890     * by much) - this could be fixed, it only appears with the -g option.
5891     */
5892    unsigned int i, j;
5893    for (i=0; i<pm->ngammas; ++i)
5894    {
5895       for (j=0; j<pm->ngammas; ++j)
5896       {
5897          if (i != j &&
5898              fabs(pm->gammas[j]/pm->gammas[i]-1) >= PNG_GAMMA_THRESHOLD)
5899          {
5900             gamma_transform_test(pm, 0, 16, pm->interlace_type, 1/pm->gammas[i],
5901                 pm->gammas[j], PNG_MAX_GAMMA_8, speed,
5902                 pm->use_input_precision_16to8, 1 /*strip16*/);
5903
5904             if (fail(pm))
5905                return;
5906
5907             gamma_transform_test(pm, 2, 16, pm->interlace_type, 1/pm->gammas[i],
5908                 pm->gammas[j], PNG_MAX_GAMMA_8, speed,
5909                 pm->use_input_precision_16to8, 1 /*strip16*/);
5910
5911             if (fail(pm))
5912                return;
5913
5914             gamma_transform_test(pm, 4, 16, pm->interlace_type, 1/pm->gammas[i],
5915                 pm->gammas[j], PNG_MAX_GAMMA_8, speed,
5916                 pm->use_input_precision_16to8, 1 /*strip16*/);
5917
5918             if (fail(pm))
5919                return;
5920
5921             gamma_transform_test(pm, 6, 16, pm->interlace_type, 1/pm->gammas[i],
5922                 pm->gammas[j], PNG_MAX_GAMMA_8, speed,
5923                 pm->use_input_precision_16to8, 1 /*strip16*/);
5924
5925             if (fail(pm))
5926                return;
5927          }
5928       }
5929    }
5930 }
5931 #endif /* 16 to 8 bit conversion */
5932
5933 static void
5934 perform_gamma_test(png_modifier *pm, int speed, int summary)
5935 {
5936    /* First some arbitrary no-transform tests: */
5937    if (!speed && pm->test_gamma_threshold)
5938    {
5939       perform_gamma_threshold_tests(pm);
5940
5941       if (fail(pm))
5942          return;
5943    }
5944
5945    /* Now some real transforms. */
5946    if (pm->test_gamma_transform)
5947    {
5948       perform_gamma_transform_tests(pm, speed);
5949
5950       if (summary)
5951       {
5952          printf("Gamma correction error summary\n\n");
5953          printf("The printed value is the maximum error in the pixel values\n");
5954          printf("calculated by the libpng gamma correction code.  The error\n");
5955          printf("is calculated as the difference between the output pixel\n");
5956          printf("value (always an integer) and the ideal value from the\n");
5957          printf("libpng specification (typically not an integer).\n\n");
5958
5959          printf("Expect this value to be less than .5 for 8 bit formats,\n");
5960          printf("less than 1 for formats with fewer than 8 bits and a small\n");
5961          printf("number (typically less than 5) for the 16 bit formats.\n");
5962          printf("For performance reasons the value for 16 bit formats\n");
5963          printf("increases when the image file includes an sBIT chunk.\n\n");
5964
5965          printf("  2 bit gray:  %.5f\n", pm->error_gray_2);
5966          printf("  4 bit gray:  %.5f\n", pm->error_gray_4);
5967          printf("  8 bit gray:  %.5f\n", pm->error_gray_8);
5968          printf("  8 bit color: %.5f\n", pm->error_color_8);
5969 #ifdef DO_16BIT
5970          printf(" 16 bit gray:  %.5f\n", pm->error_gray_16);
5971          printf(" 16 bit color: %.5f\n", pm->error_color_16);
5972 #endif
5973       }
5974    }
5975
5976    /* The sbit tests produce much larger errors: */
5977    if (pm->test_gamma_sbit)
5978    {
5979       pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 =
5980       pm->error_gray_16 = pm->error_color_8 = pm->error_color_16 = 0;
5981       perform_gamma_sbit_tests(pm, speed);
5982
5983       if (summary)
5984       {
5985          printf("Gamma correction with sBIT:\n");
5986
5987          if (pm->sbitlow < 8U)
5988          {
5989             printf("  2 bit gray:  %.5f\n", pm->error_gray_2);
5990             printf("  4 bit gray:  %.5f\n", pm->error_gray_4);
5991             printf("  8 bit gray:  %.5f\n", pm->error_gray_8);
5992             printf("  8 bit color: %.5f\n", pm->error_color_8);
5993          }
5994
5995    #ifdef DO_16BIT
5996          printf(" 16 bit gray:  %.5f\n", pm->error_gray_16);
5997          printf(" 16 bit color: %.5f\n", pm->error_color_16);
5998    #endif
5999       }
6000    }
6001
6002 #ifdef PNG_READ_16_TO_8_SUPPORTED
6003    if (pm->test_gamma_strip16)
6004    {
6005       /* The 16 to 8 bit strip operations: */
6006       pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 =
6007       pm->error_gray_16 = pm->error_color_8 = pm->error_color_16 = 0;
6008       perform_gamma_strip16_tests(pm, speed);
6009
6010       if (summary)
6011       {
6012          printf("Gamma correction with 16 to 8 bit reduction:\n");
6013          printf(" 16 bit gray:  %.5f\n", pm->error_gray_16);
6014          printf(" 16 bit color: %.5f\n", pm->error_color_16);
6015       }
6016    }
6017 #endif
6018 }
6019
6020 /* INTERLACE MACRO VALIDATION */
6021 /* This is copied verbatim from the specification, it is simply the pass
6022  * number in which each pixel in each 8x8 tile appears.  The array must
6023  * be indexed adam7[y][x] and notice that the pass numbers are based at
6024  * 1, not 0 - the base libpng uses.
6025  */
6026 static PNG_CONST
6027 png_byte adam7[8][8] =
6028 {
6029    { 1,6,4,6,2,6,4,6 },
6030    { 7,7,7,7,7,7,7,7 },
6031    { 5,6,5,6,5,6,5,6 },
6032    { 7,7,7,7,7,7,7,7 },
6033    { 3,6,4,6,3,6,4,6 },
6034    { 7,7,7,7,7,7,7,7 },
6035    { 5,6,5,6,5,6,5,6 },
6036    { 7,7,7,7,7,7,7,7 }
6037 };
6038
6039 /* This routine validates all the interlace support macros in png.h for
6040  * a variety of valid PNG widths and heights.  It uses a number of similarly
6041  * named internal routines that feed off the above array.
6042  */
6043 static png_uint_32
6044 png_pass_start_row(int pass)
6045 {
6046    int x, y;
6047    ++pass;
6048    for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
6049       return y;
6050    return 0xf;
6051 }
6052
6053 static png_uint_32
6054 png_pass_start_col(int pass)
6055 {
6056    int x, y;
6057    ++pass;
6058    for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
6059       return x;
6060    return 0xf;
6061 }
6062
6063 static int
6064 png_pass_row_shift(int pass)
6065 {
6066    int x, y, base=(-1), inc=8;
6067    ++pass;
6068    for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
6069    {
6070       if (base == (-1))
6071          base = y;
6072       else if (base == y)
6073          {}
6074       else if (inc == y-base)
6075          base=y;
6076       else if (inc == 8)
6077          inc = y-base, base=y;
6078       else if (inc != y-base)
6079          return 0xff; /* error - more than one 'inc' value! */
6080    }
6081
6082    if (base == (-1)) return 0xfe; /* error - no row in pass! */
6083
6084    /* The shift is always 1, 2 or 3 - no pass has all the rows! */
6085    switch (inc)
6086    {
6087 case 2: return 1;
6088 case 4: return 2;
6089 case 8: return 3;
6090 default: break;
6091    }
6092
6093    /* error - unrecognized 'inc' */
6094    return (inc << 8) + 0xfd;
6095 }
6096
6097 static int
6098 png_pass_col_shift(int pass)
6099 {
6100    int x, y, base=(-1), inc=8;
6101    ++pass;
6102    for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
6103    {
6104       if (base == (-1))
6105          base = x;
6106       else if (base == x)
6107          {}
6108       else if (inc == x-base)
6109          base=x;
6110       else if (inc == 8)
6111          inc = x-base, base=x;
6112       else if (inc != x-base)
6113          return 0xff; /* error - more than one 'inc' value! */
6114    }
6115
6116    if (base == (-1)) return 0xfe; /* error - no row in pass! */
6117
6118    /* The shift is always 1, 2 or 3 - no pass has all the rows! */
6119    switch (inc)
6120    {
6121 case 1: return 0; /* pass 7 has all the columns */
6122 case 2: return 1;
6123 case 4: return 2;
6124 case 8: return 3;
6125 default: break;
6126    }
6127
6128    /* error - unrecognized 'inc' */
6129    return (inc << 8) + 0xfd;
6130 }
6131
6132 static png_uint_32
6133 png_row_from_pass_row(png_uint_32 yIn, int pass)
6134 {
6135    /* By examination of the array: */
6136    switch (pass)
6137    {
6138 case 0: return yIn * 8;
6139 case 1: return yIn * 8;
6140 case 2: return yIn * 8 + 4;
6141 case 3: return yIn * 4;
6142 case 4: return yIn * 4 + 2;
6143 case 5: return yIn * 2;
6144 case 6: return yIn * 2 + 1;
6145 default: break;
6146    }
6147
6148    return 0xff; /* bad pass number */
6149 }
6150
6151 static png_uint_32
6152 png_col_from_pass_col(png_uint_32 xIn, int pass)
6153 {
6154    /* By examination of the array: */
6155    switch (pass)
6156    {
6157 case 0: return xIn * 8;
6158 case 1: return xIn * 8 + 4;
6159 case 2: return xIn * 4;
6160 case 3: return xIn * 4 + 2;
6161 case 4: return xIn * 2;
6162 case 5: return xIn * 2 + 1;
6163 case 6: return xIn;
6164 default: break;
6165    }
6166
6167    return 0xff; /* bad pass number */
6168 }
6169
6170 static int
6171 png_row_in_interlace_pass(png_uint_32 y, int pass)
6172 {
6173    /* Is row 'y' in pass 'pass'? */
6174    int x;
6175    y &= 7;
6176    ++pass;
6177    for (x=0; x<8; ++x) if (adam7[y][x] == pass)
6178       return 1;
6179
6180    return 0;
6181 }
6182
6183 static int
6184 png_col_in_interlace_pass(png_uint_32 x, int pass)
6185 {
6186    /* Is column 'x' in pass 'pass'? */
6187    int y;
6188    x &= 7;
6189    ++pass;
6190    for (y=0; y<8; ++y) if (adam7[y][x] == pass)
6191       return 1;
6192
6193    return 0;
6194 }
6195
6196 static png_uint_32
6197 png_pass_rows(png_uint_32 height, int pass)
6198 {
6199    png_uint_32 tiles = height>>3;
6200    png_uint_32 rows = 0;
6201    unsigned int x, y;
6202
6203    height &= 7;
6204    ++pass;
6205    for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
6206    {
6207       rows += tiles;
6208       if (y < height) ++rows;
6209       break; /* i.e. break the 'x', column, loop. */
6210    }
6211
6212    return rows;
6213 }
6214
6215 static png_uint_32
6216 png_pass_cols(png_uint_32 width, int pass)
6217 {
6218    png_uint_32 tiles = width>>3;
6219    png_uint_32 cols = 0;
6220    unsigned int x, y;
6221
6222    width &= 7;
6223    ++pass;
6224    for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
6225    {
6226       cols += tiles;
6227       if (x < width) ++cols;
6228       break; /* i.e. break the 'y', row, loop. */
6229    }
6230
6231    return cols;
6232 }
6233
6234 static void
6235 perform_interlace_macro_validation(void)
6236 {
6237    /* The macros to validate, first those that depend only on pass:
6238     *
6239     * PNG_PASS_START_ROW(pass)
6240     * PNG_PASS_START_COL(pass)
6241     * PNG_PASS_ROW_SHIFT(pass)
6242     * PNG_PASS_COL_SHIFT(pass)
6243     */
6244    int pass;
6245
6246    for (pass=0; pass<7; ++pass)
6247    {
6248       png_uint_32 m, f, v;
6249
6250       m = PNG_PASS_START_ROW(pass);
6251       f = png_pass_start_row(pass);
6252       if (m != f)
6253       {
6254          fprintf(stderr, "PNG_PASS_START_ROW(%d) = %u != %x\n", pass, m, f);
6255          exit(1);
6256       }
6257
6258       m = PNG_PASS_START_COL(pass);
6259       f = png_pass_start_col(pass);
6260       if (m != f)
6261       {
6262          fprintf(stderr, "PNG_PASS_START_COL(%d) = %u != %x\n", pass, m, f);
6263          exit(1);
6264       }
6265
6266       m = PNG_PASS_ROW_SHIFT(pass);
6267       f = png_pass_row_shift(pass);
6268       if (m != f)
6269       {
6270          fprintf(stderr, "PNG_PASS_ROW_SHIFT(%d) = %u != %x\n", pass, m, f);
6271          exit(1);
6272       }
6273
6274       m = PNG_PASS_COL_SHIFT(pass);
6275       f = png_pass_col_shift(pass);
6276       if (m != f)
6277       {
6278          fprintf(stderr, "PNG_PASS_COL_SHIFT(%d) = %u != %x\n", pass, m, f);
6279          exit(1);
6280       }
6281
6282       /* Macros that depend on the image or sub-image height too:
6283        *
6284        * PNG_PASS_ROWS(height, pass)
6285        * PNG_PASS_COLS(width, pass)
6286        * PNG_ROW_FROM_PASS_ROW(yIn, pass)
6287        * PNG_COL_FROM_PASS_COL(xIn, pass)
6288        * PNG_ROW_IN_INTERLACE_PASS(y, pass)
6289        * PNG_COL_IN_INTERLACE_PASS(x, pass)
6290        */
6291       for (v=0;;)
6292       {
6293          /* First the base 0 stuff: */
6294          m = PNG_ROW_FROM_PASS_ROW(v, pass);
6295          f = png_row_from_pass_row(v, pass);
6296          if (m != f)
6297          {
6298             fprintf(stderr, "PNG_ROW_FROM_PASS_ROW(%u, %d) = %u != %x\n",
6299                v, pass, m, f);
6300             exit(1);
6301          }
6302
6303          m = PNG_COL_FROM_PASS_COL(v, pass);
6304          f = png_col_from_pass_col(v, pass);
6305          if (m != f)
6306          {
6307             fprintf(stderr, "PNG_COL_FROM_PASS_COL(%u, %d) = %u != %x\n",
6308                v, pass, m, f);
6309             exit(1);
6310          }
6311
6312          m = PNG_ROW_IN_INTERLACE_PASS(v, pass);
6313          f = png_row_in_interlace_pass(v, pass);
6314          if (m != f)
6315          {
6316             fprintf(stderr, "PNG_ROW_IN_INTERLACE_PASS(%u, %d) = %u != %x\n",
6317                v, pass, m, f);
6318             exit(1);
6319          }
6320
6321          m = PNG_COL_IN_INTERLACE_PASS(v, pass);
6322          f = png_col_in_interlace_pass(v, pass);
6323          if (m != f)
6324          {
6325             fprintf(stderr, "PNG_COL_IN_INTERLACE_PASS(%u, %d) = %u != %x\n",
6326                v, pass, m, f);
6327             exit(1);
6328          }
6329
6330          /* Then the base 1 stuff: */
6331          ++v;
6332          m = PNG_PASS_ROWS(v, pass);
6333          f = png_pass_rows(v, pass);
6334          if (m != f)
6335          {
6336             fprintf(stderr, "PNG_PASS_ROWS(%u, %d) = %u != %x\n",
6337                v, pass, m, f);
6338             exit(1);
6339          }
6340
6341          m = PNG_PASS_COLS(v, pass);
6342          f = png_pass_cols(v, pass);
6343          if (m != f)
6344          {
6345             fprintf(stderr, "PNG_PASS_COLS(%u, %d) = %u != %x\n",
6346                v, pass, m, f);
6347             exit(1);
6348          }
6349
6350          /* Move to the next v - the stepping algorithm starts skipping
6351           * values above 1024.
6352           */
6353          if (v > 1024)
6354          {
6355             if (v == PNG_UINT_31_MAX)
6356                break;
6357
6358             v = (v << 1) ^ v;
6359             if (v >= PNG_UINT_31_MAX)
6360                v = PNG_UINT_31_MAX-1;
6361          }
6362       }
6363    }
6364 }
6365
6366 /* main program */
6367 int main(int argc, PNG_CONST char **argv)
6368 {
6369    volatile int summary = 1;  /* Print the error summary at the end */
6370
6371    /* Create the given output file on success: */
6372    PNG_CONST char *volatile touch = NULL;
6373
6374    /* This is an array of standard gamma values (believe it or not I've seen
6375     * every one of these mentioned somewhere.)
6376     *
6377     * In the following list the most useful values are first!
6378     */
6379    static double
6380       gammas[]={2.2, 1.0, 2.2/1.45, 1.8, 1.5, 2.4, 2.5, 2.62, 2.9};
6381
6382    png_modifier pm;
6383    context(&pm.this, fault);
6384
6385    modifier_init(&pm);
6386
6387    /* Preallocate the image buffer, because we know how big it needs to be,
6388     * note that, for testing purposes, it is deliberately mis-aligned.
6389     */
6390    pm.this.image = malloc(2*TRANSFORM_IMAGEMAX+1);
6391
6392    if (pm.this.image != NULL)
6393    {
6394       /* Ignore OOM at this point - the 'ensure' routine above will allocate
6395        * the array appropriately.
6396        */
6397       ++(pm.this.image);
6398       pm.this.cb_image = 2*TRANSFORM_IMAGEMAX;
6399    }
6400
6401    /* Default to error on warning: */
6402    pm.this.treat_warnings_as_errors = 1;
6403
6404    /* Store the test gammas */
6405    pm.gammas = gammas;
6406    pm.ngammas = 0; /* default to off */
6407    pm.sbitlow = 8U; /* because libpng doesn't do sBIT below 8! */
6408    pm.use_input_precision_16to8 = 1U; /* Because of the way libpng does it */
6409
6410    /* Some default values (set the behavior for 'make check' here).
6411     * These values simply control the maximum error permitted in the gamma
6412     * transformations.  The practial limits for human perception are described
6413     * below (the setting for maxpc16), however for 8 bit encodings it isn't
6414     * possible to meet the accepted capabilities of human vision - i.e. 8 bit
6415     * images can never be good enough, regardless of encoding.
6416     */
6417    pm.maxout8 = .1;     /* Arithmetic error in *encoded* value */
6418    pm.maxabs8 = .00005; /* 1/20000 */
6419    pm.maxpc8 = .499;    /* I.e., .499% fractional error */
6420    pm.maxout16 = .499;  /* Error in *encoded* value */
6421    pm.maxabs16 = .00005;/* 1/20000 */
6422
6423    /* NOTE: this is a reasonable perceptual limit. We assume that humans can
6424     * perceive light level differences of 1% over a 100:1 range, so we need to
6425     * maintain 1 in 10000 accuracy (in linear light space), which is what the
6426     * following guarantees.  It also allows significantly higher errors at
6427     * higher 16 bit values, which is important for performance.  The actual
6428     * maximum 16 bit error is about +/-1.9 in the fixed point implementation but
6429     * this is only allowed for values >38149 by the following:
6430     */
6431    pm.maxpc16 = .005;   /* I.e., 1/200% - 1/20000 */
6432
6433    /* Now parse the command line options. */
6434    while (--argc >= 1)
6435    {
6436       if (strcmp(*++argv, "-v") == 0)
6437          pm.this.verbose = 1;
6438
6439       else if (strcmp(*argv, "-l") == 0)
6440          pm.log = 1;
6441
6442       else if (strcmp(*argv, "-q") == 0)
6443          summary = pm.this.verbose = pm.log = 0;
6444
6445       else if (strcmp(*argv, "-w") == 0)
6446          pm.this.treat_warnings_as_errors = 0;
6447
6448       else if (strcmp(*argv, "--speed") == 0)
6449          pm.this.speed = 1, pm.ngammas = (sizeof gammas)/(sizeof gammas[0]),
6450             pm.test_standard = 0;
6451
6452       else if (strcmp(*argv, "--size") == 0)
6453          pm.test_size = 1;
6454
6455       else if (strcmp(*argv, "--nosize") == 0)
6456          pm.test_size = 0;
6457
6458       else if (strcmp(*argv, "--standard") == 0)
6459          pm.test_standard = 1;
6460
6461       else if (strcmp(*argv, "--nostandard") == 0)
6462          pm.test_standard = 0;
6463
6464       else if (strcmp(*argv, "--transform") == 0)
6465          pm.test_transform = 1;
6466
6467       else if (strcmp(*argv, "--notransform") == 0)
6468          pm.test_transform = 0;
6469
6470       else if (strncmp(*argv, "--transform-disable=",
6471          sizeof "--transform-disable") == 0)
6472          {
6473          pm.test_transform = 1;
6474          transform_disable(*argv + sizeof "--transform-disable");
6475          }
6476
6477       else if (strncmp(*argv, "--transform-enable=",
6478          sizeof "--transform-enable") == 0)
6479          {
6480          pm.test_transform = 1;
6481          transform_enable(*argv + sizeof "--transform-enable");
6482          }
6483
6484       else if (strcmp(*argv, "--gamma") == 0)
6485          {
6486          /* Just do two gamma tests here (2.2 and linear) for speed: */
6487          pm.ngammas = 2U;
6488          pm.test_gamma_threshold = 1;
6489          pm.test_gamma_transform = 1;
6490          pm.test_gamma_sbit = 1;
6491          pm.test_gamma_strip16 = 1;
6492          }
6493
6494       else if (strcmp(*argv, "--nogamma") == 0)
6495          pm.ngammas = 0;
6496
6497       else if (strcmp(*argv, "--gamma-threshold") == 0)
6498          pm.ngammas = 2U, pm.test_gamma_threshold = 1;
6499
6500       else if (strcmp(*argv, "--nogamma-threshold") == 0)
6501          pm.test_gamma_threshold = 0;
6502
6503       else if (strcmp(*argv, "--gamma-transform") == 0)
6504          pm.ngammas = 2U, pm.test_gamma_transform = 1;
6505
6506       else if (strcmp(*argv, "--nogamma-transform") == 0)
6507          pm.test_gamma_transform = 0;
6508
6509       else if (strcmp(*argv, "--gamma-sbit") == 0)
6510          pm.ngammas = 2U, pm.test_gamma_sbit = 1;
6511
6512       else if (strcmp(*argv, "--nogamma-sbit") == 0)
6513          pm.test_gamma_sbit = 0;
6514
6515       else if (strcmp(*argv, "--gamma-16-to-8") == 0)
6516          pm.ngammas = 2U, pm.test_gamma_strip16 = 1;
6517
6518       else if (strcmp(*argv, "--nogamma-16-to-8") == 0)
6519          pm.test_gamma_strip16 = 0;
6520
6521       else if (strcmp(*argv, "--all-gammas") == 0)
6522          pm.ngammas = (sizeof gammas)/(sizeof gammas[0]);
6523
6524       else if (strcmp(*argv, "--progressive-read") == 0)
6525          pm.this.progressive = 1;
6526
6527       else if (strcmp(*argv, "--interlace") == 0)
6528          pm.interlace_type = PNG_INTERLACE_ADAM7;
6529
6530       else if (argc >= 1 && strcmp(*argv, "--sbitlow") == 0)
6531          --argc, pm.sbitlow = (png_byte)atoi(*++argv);
6532
6533       else if (argc >= 1 && strcmp(*argv, "--touch") == 0)
6534          --argc, touch = *++argv;
6535
6536       else if (argc >= 1 && strncmp(*argv, "--max", 4) == 0)
6537       {
6538          --argc;
6539
6540          if (strcmp(4+*argv, "abs8") == 0)
6541             pm.maxabs8 = atof(*++argv);
6542
6543          else if (strcmp(4+*argv, "abs16") == 0)
6544             pm.maxabs16 = atof(*++argv);
6545
6546          else if (strcmp(4+*argv, "out8") == 0)
6547             pm.maxout8 = atof(*++argv);
6548
6549          else if (strcmp(4+*argv, "out16") == 0)
6550             pm.maxout16 = atof(*++argv);
6551
6552          else if (strcmp(4+*argv, "pc8") == 0)
6553             pm.maxpc8 = atof(*++argv);
6554
6555          else if (strcmp(4+*argv, "pc16") == 0)
6556             pm.maxpc16 = atof(*++argv);
6557
6558          else
6559          {
6560             fprintf(stderr, "pngvalid: %s: unknown 'max' option\n", *argv);
6561             exit(1);
6562          }
6563       }
6564
6565       else
6566       {
6567          fprintf(stderr, "pngvalid: %s: unknown argument\n", *argv);
6568          exit(1);
6569       }
6570    }
6571
6572    /* If pngvalid is run with no arguments default to a reasonable set of the
6573     * tests.
6574     */
6575    if (pm.test_standard == 0 && pm.test_size == 0 && pm.test_transform == 0 &&
6576       pm.ngammas == 0)
6577    {
6578       pm.test_standard = 1;
6579       pm.test_size = 1;
6580       pm.test_transform = 1;
6581       pm.ngammas = 3U;
6582    }
6583
6584    if (pm.ngammas > 0 &&
6585       pm.test_gamma_threshold == 0 && pm.test_gamma_transform == 0 &&
6586       pm.test_gamma_sbit == 0 && pm.test_gamma_strip16 == 0)
6587    {
6588       pm.test_gamma_threshold = 1;
6589       pm.test_gamma_transform = 1;
6590       pm.test_gamma_sbit = 1;
6591       pm.test_gamma_strip16 = 1;
6592    }
6593
6594    else if (pm.ngammas == 0)
6595    {
6596       /* Nothing to test so turn everything off: */
6597       pm.test_gamma_threshold = 0;
6598       pm.test_gamma_transform = 0;
6599       pm.test_gamma_sbit = 0;
6600       pm.test_gamma_strip16 = 0;
6601    }
6602
6603    Try
6604    {
6605       /* Make useful base images */
6606       make_transform_images(&pm.this);
6607
6608       /* Perform the standard and gamma tests. */
6609       if (pm.test_standard)
6610       {
6611          perform_interlace_macro_validation();
6612          perform_standard_test(&pm);
6613          perform_error_test(&pm);
6614       }
6615
6616       /* Various oddly sized images: */
6617       if (pm.test_size)
6618       {
6619          make_size_images(&pm.this);
6620          perform_size_test(&pm);
6621       }
6622
6623       /* Combinatorial transforms: */
6624       if (pm.test_transform)
6625          perform_transform_test(&pm);
6626
6627       if (pm.ngammas > 0)
6628          perform_gamma_test(&pm, pm.this.speed != 0,
6629             summary && !pm.this.speed);
6630    }
6631
6632    Catch(fault)
6633    {
6634       fprintf(stderr, "pngvalid: test aborted (probably failed in cleanup)\n");
6635       if (!pm.this.verbose)
6636       {
6637          if (pm.this.error[0] != 0)
6638             fprintf(stderr, "pngvalid: first error: %s\n", pm.this.error);
6639
6640          fprintf(stderr, "pngvalid: run with -v to see what happened\n");
6641       }
6642       exit(1);
6643    }
6644
6645    if (summary && !pm.this.speed)
6646    {
6647       printf("Results using %s point arithmetic %s\n",
6648 #if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || PNG_LIBPNG_VER < 10500
6649          "floating",
6650 #else
6651          "fixed",
6652 #endif
6653          (pm.this.nerrors || (pm.this.treat_warnings_as_errors &&
6654             pm.this.nwarnings)) ? "(errors)" : (pm.this.nwarnings ?
6655                "(warnings)" : "(no errors or warnings)")
6656       );
6657       printf("Allocated memory statistics (in bytes):\n"
6658          "\tread  %lu maximum single, %lu peak, %lu total\n"
6659          "\twrite %lu maximum single, %lu peak, %lu total\n",
6660          (unsigned long)pm.this.read_memory_pool.max_max,
6661          (unsigned long)pm.this.read_memory_pool.max_limit,
6662          (unsigned long)pm.this.read_memory_pool.max_total,
6663          (unsigned long)pm.this.write_memory_pool.max_max,
6664          (unsigned long)pm.this.write_memory_pool.max_limit,
6665          (unsigned long)pm.this.write_memory_pool.max_total);
6666    }
6667
6668    /* Do this here to provoke memory corruption errors in memory not directly
6669     * allocated by libpng - not a complete test, but better than nothing.
6670     */
6671    store_delete(&pm.this);
6672
6673    /* Error exit if there are any errors, and maybe if there are any
6674     * warnings.
6675     */
6676    if (pm.this.nerrors || (pm.this.treat_warnings_as_errors &&
6677        pm.this.nwarnings))
6678    {
6679       if (!pm.this.verbose)
6680          fprintf(stderr, "pngvalid: %s\n", pm.this.error);
6681
6682       fprintf(stderr, "pngvalid: %d errors, %d warnings\n", pm.this.nerrors,
6683           pm.this.nwarnings);
6684
6685       exit(1);
6686    }
6687
6688    /* Success case. */
6689    if (touch != NULL)
6690    {
6691       FILE *fsuccess = fopen(touch, "wt");
6692
6693       if (fsuccess != NULL)
6694       {
6695          int error = 0;
6696          fprintf(fsuccess, "PNG validation succeeded\n");
6697          fflush(fsuccess);
6698          error = ferror(fsuccess);
6699
6700          if (fclose(fsuccess) || error)
6701          {
6702             fprintf(stderr, "%s: write failed\n", touch);
6703             exit(1);
6704          }
6705       }
6706    }
6707
6708    return 0;
6709 }