]> git.cworth.org Git - apitrace/blob - libpng/pngrutil.c
Use the process ID as process name when /proc/self/exe can't be read.
[apitrace] / libpng / pngrutil.c
1
2 /* pngrutil.c - utilities to read a PNG file
3  *
4  * Last changed in libpng 1.4.4 [August 26, 2010]
5  * Copyright (c) 1998-2010 Glenn Randers-Pehrson
6  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8  *
9  * This code is released under the libpng license.
10  * For conditions of distribution and use, see the disclaimer
11  * and license in png.h
12  *
13  * This file contains routines that are only called from within
14  * libpng itself during the course of reading an image.
15  */
16
17 #define PNG_NO_PEDANTIC_WARNINGS
18 #include "png.h"
19 #ifdef PNG_READ_SUPPORTED
20 #include "pngpriv.h"
21
22 #    define png_strtod(p,a,b) strtod(a,b)
23 png_uint_32 PNGAPI
24 png_get_uint_31(png_structp png_ptr, png_bytep buf)
25 {
26    png_uint_32 i = png_get_uint_32(buf);
27    if (i > PNG_UINT_31_MAX)
28      png_error(png_ptr, "PNG unsigned integer out of range");
29    return (i);
30 }
31 #ifndef PNG_USE_READ_MACROS
32 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
33 png_uint_32 (PNGAPI
34 png_get_uint_32)(png_bytep buf)
35 {
36    png_uint_32 i =
37        ((png_uint_32)(*(buf    )) << 24) +
38        ((png_uint_32)(*(buf + 1)) << 16) +
39        ((png_uint_32)(*(buf + 2)) <<  8) +
40        ((png_uint_32)(*(buf + 3))      ) ;
41
42    return (i);
43 }
44
45 /* Grab a signed 32-bit integer from a buffer in big-endian format.  The
46  * data is stored in the PNG file in two's complement format and there
47  * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore
48  * the following code does a two's complement to native conversion.
49  */
50 png_int_32 (PNGAPI
51 png_get_int_32)(png_bytep buf)
52 {
53    png_uint_32 u = png_get_uint_32(buf);
54    if ((u & 0x80000000) == 0) /* non-negative */
55       return u;
56
57    u = (u ^ 0xffffffff) + 1;  /* 2's complement: -x = ~x+1 */
58    return -(png_int_32)u;
59 }
60
61 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
62 png_uint_16 (PNGAPI
63 png_get_uint_16)(png_bytep buf)
64 {
65    png_uint_16 i =
66        ((png_uint_32)(*buf) << 8) +
67        ((png_uint_32)(*(buf + 1)));
68
69    return (i);
70 }
71 #endif /* PNG_USE_READ_MACROS */
72
73 /* Read the chunk header (length + type name).
74  * Put the type name into png_ptr->chunk_name, and return the length.
75  */
76 png_uint_32 /* PRIVATE */
77 png_read_chunk_header(png_structp png_ptr)
78 {
79    png_byte buf[8];
80    png_uint_32 length;
81
82 #ifdef PNG_IO_STATE_SUPPORTED
83    /* Inform the I/O callback that the chunk header is being read.
84     * PNG_IO_CHUNK_HDR requires a single I/O call.
85     */
86    png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
87 #endif
88
89    /* Read the length and the chunk name */
90    png_read_data(png_ptr, buf, 8);
91    length = png_get_uint_31(png_ptr, buf);
92
93    /* Put the chunk name into png_ptr->chunk_name */
94    png_memcpy(png_ptr->chunk_name, buf + 4, 4);
95
96    png_debug2(0, "Reading %s chunk, length = %lu",
97       png_ptr->chunk_name, length);
98
99    /* Reset the crc and run it over the chunk name */
100    png_reset_crc(png_ptr);
101    png_calculate_crc(png_ptr, png_ptr->chunk_name, 4);
102
103    /* Check to see if chunk name is valid */
104    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
105
106 #ifdef PNG_IO_STATE_SUPPORTED
107    /* Inform the I/O callback that chunk data will (possibly) be read.
108     * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls.
109     */
110    png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
111 #endif
112
113    return length;
114 }
115
116 /* Read data, and (optionally) run it through the CRC. */
117 void /* PRIVATE */
118 png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
119 {
120    if (png_ptr == NULL)
121       return;
122    png_read_data(png_ptr, buf, length);
123    png_calculate_crc(png_ptr, buf, length);
124 }
125
126 /* Optionally skip data and then check the CRC.  Depending on whether we
127  * are reading a ancillary or critical chunk, and how the program has set
128  * things up, we may calculate the CRC on the data and print a message.
129  * Returns '1' if there was a CRC error, '0' otherwise.
130  */
131 int /* PRIVATE */
132 png_crc_finish(png_structp png_ptr, png_uint_32 skip)
133 {
134    png_size_t i;
135    png_size_t istop = png_ptr->zbuf_size;
136
137    for (i = (png_size_t)skip; i > istop; i -= istop)
138    {
139       png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
140    }
141    if (i)
142    {
143       png_crc_read(png_ptr, png_ptr->zbuf, i);
144    }
145
146    if (png_crc_error(png_ptr))
147    {
148       if (((png_ptr->chunk_name[0] & 0x20) &&                /* Ancillary */
149           !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
150           (!(png_ptr->chunk_name[0] & 0x20) &&             /* Critical  */
151           (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
152       {
153          png_chunk_warning(png_ptr, "CRC error");
154       }
155       else
156       {
157          png_chunk_benign_error(png_ptr, "CRC error");
158          return (0);
159       }
160       return (1);
161    }
162
163    return (0);
164 }
165
166 /* Compare the CRC stored in the PNG file with that calculated by libpng from
167  * the data it has read thus far.
168  */
169 int /* PRIVATE */
170 png_crc_error(png_structp png_ptr)
171 {
172    png_byte crc_bytes[4];
173    png_uint_32 crc;
174    int need_crc = 1;
175
176    if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
177    {
178       if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
179           (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
180          need_crc = 0;
181    }
182    else                                                    /* critical */
183    {
184       if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
185          need_crc = 0;
186    }
187
188 #ifdef PNG_IO_STATE_SUPPORTED
189    /* Inform the I/O callback that the chunk CRC is being read */
190    /* PNG_IO_CHUNK_CRC requires the I/O to be done at once */
191    png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
192 #endif
193
194    png_read_data(png_ptr, crc_bytes, 4);
195
196    if (need_crc)
197    {
198       crc = png_get_uint_32(crc_bytes);
199       return ((int)(crc != png_ptr->crc));
200    }
201    else
202       return (0);
203 }
204
205 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
206     defined(PNG_READ_iCCP_SUPPORTED)
207 static png_size_t
208 png_inflate(png_structp png_ptr, const png_byte *data, png_size_t size,
209         png_bytep output, png_size_t output_size)
210 {
211    png_size_t count = 0;
212
213    png_ptr->zstream.next_in = (png_bytep)data; /* const_cast: VALID */
214    png_ptr->zstream.avail_in = size;
215
216    while (1)
217    {
218       int ret, avail;
219
220       /* Reset the output buffer each time round - we empty it
221        * after every inflate call.
222        */
223       png_ptr->zstream.next_out = png_ptr->zbuf;
224       png_ptr->zstream.avail_out = png_ptr->zbuf_size;
225
226       ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
227       avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out;
228
229       /* First copy/count any new output - but only if we didn't
230        * get an error code.
231        */
232       if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
233       {
234          if (output != 0 && output_size > count)
235          {
236             int copy = output_size - count;
237             if (avail < copy) copy = avail;
238             png_memcpy(output + count, png_ptr->zbuf, copy);
239          }
240          count += avail;
241       }
242
243       if (ret == Z_OK)
244          continue;
245
246       /* Termination conditions - always reset the zstream, it
247        * must be left in inflateInit state.
248        */
249       png_ptr->zstream.avail_in = 0;
250       inflateReset(&png_ptr->zstream);
251
252       if (ret == Z_STREAM_END)
253          return count; /* NOTE: may be zero. */
254
255       /* Now handle the error codes - the API always returns 0
256        * and the error message is dumped into the uncompressed
257        * buffer if available.
258        */
259       {
260          PNG_CONST char *msg;
261          if (png_ptr->zstream.msg != 0)
262             msg = png_ptr->zstream.msg;
263          else
264          {
265 #ifdef PNG_STDIO_SUPPORTED
266             char umsg[52];
267
268             switch (ret)
269             {
270                case Z_BUF_ERROR:
271                   msg = "Buffer error in compressed datastream in %s chunk";
272                   break;
273                case Z_DATA_ERROR:
274                   msg = "Data error in compressed datastream in %s chunk";
275                   break;
276                default:
277                   msg = "Incomplete compressed datastream in %s chunk";
278                   break;
279             }
280
281             png_snprintf(umsg, sizeof umsg, msg, png_ptr->chunk_name);
282             msg = umsg;
283 #else
284             msg = "Damaged compressed datastream in chunk other than IDAT";
285 #endif
286          }
287
288          png_warning(png_ptr, msg);
289       }
290
291       /* 0 means an error - notice that this code simple ignores
292        * zero length compressed chunks as a result.
293        */
294       return 0;
295    }
296 }
297
298 /*
299  * Decompress trailing data in a chunk.  The assumption is that chunkdata
300  * points at an allocated area holding the contents of a chunk with a
301  * trailing compressed part.  What we get back is an allocated area
302  * holding the original prefix part and an uncompressed version of the
303  * trailing part (the malloc area passed in is freed).
304  */
305 void /* PRIVATE */
306 png_decompress_chunk(png_structp png_ptr, int comp_type,
307     png_size_t chunklength,
308     png_size_t prefix_size, png_size_t *newlength)
309 {
310    /* The caller should guarantee this */
311    if (prefix_size > chunklength)
312    {
313       /* The recovery is to delete the chunk. */
314       png_warning(png_ptr, "invalid chunklength");
315       prefix_size = 0; /* To delete everything */
316    }
317
318    else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
319    {
320       png_size_t expanded_size = png_inflate(png_ptr,
321                 (png_bytep)(png_ptr->chunkdata + prefix_size),
322                 chunklength - prefix_size,
323                 0/*output*/, 0/*output size*/);
324
325       /* Now check the limits on this chunk - if the limit fails the
326        * compressed data will be removed, the prefix will remain.
327        */
328 #ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
329       if (png_ptr->user_chunk_malloc_max &&
330           (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1))
331 #else
332 #  ifdef PNG_USER_CHUNK_MALLOC_MAX
333       if ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
334           prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
335 #  endif
336 #endif
337          png_warning(png_ptr, "Exceeded size limit while expanding chunk");
338
339       /* If the size is zero either there was an error and a message
340        * has already been output (warning) or the size really is zero
341        * and we have nothing to do - the code will exit through the
342        * error case below.
343        */
344 #if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \
345     defined(PNG_USER_CHUNK_MALLOC_MAX)
346       else
347 #endif
348       if (expanded_size > 0)
349       {
350          /* Success (maybe) - really uncompress the chunk. */
351          png_size_t new_size = 0;
352          png_charp text = png_malloc_warn(png_ptr,
353                         prefix_size + expanded_size + 1);
354
355          if (text != NULL)
356          {
357             png_memcpy(text, png_ptr->chunkdata, prefix_size);
358             new_size = png_inflate(png_ptr,
359                 (png_bytep)(png_ptr->chunkdata + prefix_size),
360                 chunklength - prefix_size,
361                 (png_bytep)(text + prefix_size), expanded_size);
362             text[prefix_size + expanded_size] = 0; /* just in case */
363
364             if (new_size == expanded_size)
365             {
366                png_free(png_ptr, png_ptr->chunkdata);
367                png_ptr->chunkdata = text;
368                *newlength = prefix_size + expanded_size;
369                return; /* The success return! */
370             }
371
372             png_warning(png_ptr, "png_inflate logic error");
373             png_free(png_ptr, text);
374          }
375          else
376           png_warning(png_ptr, "Not enough memory to decompress chunk");
377       }
378    }
379
380    else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
381    {
382 #ifdef PNG_STDIO_SUPPORTED
383       char umsg[50];
384
385       png_snprintf(umsg, sizeof umsg, "Unknown zTXt compression type %d",
386           comp_type);
387       png_warning(png_ptr, umsg);
388 #else
389       png_warning(png_ptr, "Unknown zTXt compression type");
390 #endif
391
392       /* The recovery is to simply drop the data. */
393    }
394
395    /* Generic error return - leave the prefix, delete the compressed
396     * data, reallocate the chunkdata to remove the potentially large
397     * amount of compressed data.
398     */
399    {
400       png_charp text = png_malloc_warn(png_ptr, prefix_size + 1);
401       if (text != NULL)
402       {
403          if (prefix_size > 0)
404             png_memcpy(text, png_ptr->chunkdata, prefix_size);
405          png_free(png_ptr, png_ptr->chunkdata);
406          png_ptr->chunkdata = text;
407
408          /* This is an extra zero in the 'uncompressed' part. */
409          *(png_ptr->chunkdata + prefix_size) = 0x00;
410       }
411       /* Ignore a malloc error here - it is safe. */
412    }
413
414    *newlength = prefix_size;
415 }
416 #endif
417
418 /* Read and check the IDHR chunk */
419 void /* PRIVATE */
420 png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
421 {
422    png_byte buf[13];
423    png_uint_32 width, height;
424    int bit_depth, color_type, compression_type, filter_type;
425    int interlace_type;
426
427    png_debug(1, "in png_handle_IHDR");
428
429    if (png_ptr->mode & PNG_HAVE_IHDR)
430       png_error(png_ptr, "Out of place IHDR");
431
432    /* Check the length */
433    if (length != 13)
434       png_error(png_ptr, "Invalid IHDR chunk");
435
436    png_ptr->mode |= PNG_HAVE_IHDR;
437
438    png_crc_read(png_ptr, buf, 13);
439    png_crc_finish(png_ptr, 0);
440
441    width = png_get_uint_31(png_ptr, buf);
442    height = png_get_uint_31(png_ptr, buf + 4);
443    bit_depth = buf[8];
444    color_type = buf[9];
445    compression_type = buf[10];
446    filter_type = buf[11];
447    interlace_type = buf[12];
448
449    /* Set internal variables */
450    png_ptr->width = width;
451    png_ptr->height = height;
452    png_ptr->bit_depth = (png_byte)bit_depth;
453    png_ptr->interlaced = (png_byte)interlace_type;
454    png_ptr->color_type = (png_byte)color_type;
455 #ifdef PNG_MNG_FEATURES_SUPPORTED
456    png_ptr->filter_type = (png_byte)filter_type;
457 #endif
458    png_ptr->compression_type = (png_byte)compression_type;
459
460    /* Find number of channels */
461    switch (png_ptr->color_type)
462    {
463       case PNG_COLOR_TYPE_GRAY:
464       case PNG_COLOR_TYPE_PALETTE:
465          png_ptr->channels = 1;
466          break;
467
468       case PNG_COLOR_TYPE_RGB:
469          png_ptr->channels = 3;
470          break;
471
472       case PNG_COLOR_TYPE_GRAY_ALPHA:
473          png_ptr->channels = 2;
474          break;
475
476       case PNG_COLOR_TYPE_RGB_ALPHA:
477          png_ptr->channels = 4;
478          break;
479    }
480
481    /* Set up other useful info */
482    png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
483    png_ptr->channels);
484    png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
485    png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
486    png_debug1(3, "channels = %d", png_ptr->channels);
487    png_debug1(3, "rowbytes = %lu", png_ptr->rowbytes);
488    png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
489       color_type, interlace_type, compression_type, filter_type);
490 }
491
492 /* Read and check the palette */
493 void /* PRIVATE */
494 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
495 {
496    png_color palette[PNG_MAX_PALETTE_LENGTH];
497    int num, i;
498 #ifdef PNG_POINTER_INDEXING_SUPPORTED
499    png_colorp pal_ptr;
500 #endif
501
502    png_debug(1, "in png_handle_PLTE");
503
504    if (!(png_ptr->mode & PNG_HAVE_IHDR))
505       png_error(png_ptr, "Missing IHDR before PLTE");
506
507    else if (png_ptr->mode & PNG_HAVE_IDAT)
508    {
509       png_warning(png_ptr, "Invalid PLTE after IDAT");
510       png_crc_finish(png_ptr, length);
511       return;
512    }
513
514    else if (png_ptr->mode & PNG_HAVE_PLTE)
515       png_error(png_ptr, "Duplicate PLTE chunk");
516
517    png_ptr->mode |= PNG_HAVE_PLTE;
518
519    if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
520    {
521       png_warning(png_ptr,
522         "Ignoring PLTE chunk in grayscale PNG");
523       png_crc_finish(png_ptr, length);
524       return;
525    }
526 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
527    if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
528    {
529       png_crc_finish(png_ptr, length);
530       return;
531    }
532 #endif
533
534    if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
535    {
536       if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
537       {
538          png_warning(png_ptr, "Invalid palette chunk");
539          png_crc_finish(png_ptr, length);
540          return;
541       }
542
543       else
544       {
545          png_error(png_ptr, "Invalid palette chunk");
546       }
547    }
548
549    num = (int)length / 3;
550
551 #ifdef PNG_POINTER_INDEXING_SUPPORTED
552    for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
553    {
554       png_byte buf[3];
555
556       png_crc_read(png_ptr, buf, 3);
557       pal_ptr->red = buf[0];
558       pal_ptr->green = buf[1];
559       pal_ptr->blue = buf[2];
560    }
561 #else
562    for (i = 0; i < num; i++)
563    {
564       png_byte buf[3];
565
566       png_crc_read(png_ptr, buf, 3);
567       /* Don't depend upon png_color being any order */
568       palette[i].red = buf[0];
569       palette[i].green = buf[1];
570       palette[i].blue = buf[2];
571    }
572 #endif
573
574    /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
575     * whatever the normal CRC configuration tells us.  However, if we
576     * have an RGB image, the PLTE can be considered ancillary, so
577     * we will act as though it is.
578     */
579 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
580    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
581 #endif
582    {
583       png_crc_finish(png_ptr, 0);
584    }
585 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
586    else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
587    {
588       /* If we don't want to use the data from an ancillary chunk,
589          we have two options: an error abort, or a warning and we
590          ignore the data in this chunk (which should be OK, since
591          it's considered ancillary for a RGB or RGBA image). */
592       if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
593       {
594          if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
595          {
596             png_chunk_benign_error(png_ptr, "CRC error");
597          }
598          else
599          {
600             png_chunk_warning(png_ptr, "CRC error");
601             return;
602          }
603       }
604       /* Otherwise, we (optionally) emit a warning and use the chunk. */
605       else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
606       {
607          png_chunk_warning(png_ptr, "CRC error");
608       }
609    }
610 #endif
611
612    png_set_PLTE(png_ptr, info_ptr, palette, num);
613
614 #ifdef PNG_READ_tRNS_SUPPORTED
615    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
616    {
617       if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
618       {
619          if (png_ptr->num_trans > (png_uint_16)num)
620          {
621             png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
622             png_ptr->num_trans = (png_uint_16)num;
623          }
624          if (info_ptr->num_trans > (png_uint_16)num)
625          {
626             png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
627             info_ptr->num_trans = (png_uint_16)num;
628          }
629       }
630    }
631 #endif
632
633 }
634
635 void /* PRIVATE */
636 png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
637 {
638    png_debug(1, "in png_handle_IEND");
639
640    if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
641    {
642       png_error(png_ptr, "No image in file");
643    }
644
645    png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
646
647    if (length != 0)
648    {
649       png_warning(png_ptr, "Incorrect IEND chunk length");
650    }
651    png_crc_finish(png_ptr, length);
652
653    info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
654 }
655
656 #ifdef PNG_READ_gAMA_SUPPORTED
657 void /* PRIVATE */
658 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
659 {
660    png_fixed_point igamma;
661 #ifdef PNG_FLOATING_POINT_SUPPORTED
662    float file_gamma;
663 #endif
664    png_byte buf[4];
665
666    png_debug(1, "in png_handle_gAMA");
667
668    if (!(png_ptr->mode & PNG_HAVE_IHDR))
669       png_error(png_ptr, "Missing IHDR before gAMA");
670    else if (png_ptr->mode & PNG_HAVE_IDAT)
671    {
672       png_warning(png_ptr, "Invalid gAMA after IDAT");
673       png_crc_finish(png_ptr, length);
674       return;
675    }
676    else if (png_ptr->mode & PNG_HAVE_PLTE)
677       /* Should be an error, but we can cope with it */
678       png_warning(png_ptr, "Out of place gAMA chunk");
679
680    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
681 #ifdef PNG_READ_sRGB_SUPPORTED
682       && !(info_ptr->valid & PNG_INFO_sRGB)
683 #endif
684       )
685    {
686       png_warning(png_ptr, "Duplicate gAMA chunk");
687       png_crc_finish(png_ptr, length);
688       return;
689    }
690
691    if (length != 4)
692    {
693       png_warning(png_ptr, "Incorrect gAMA chunk length");
694       png_crc_finish(png_ptr, length);
695       return;
696    }
697
698    png_crc_read(png_ptr, buf, 4);
699    if (png_crc_finish(png_ptr, 0))
700       return;
701
702    igamma = (png_fixed_point)png_get_uint_32(buf);
703    /* Check for zero gamma */
704    if (igamma == 0)
705       {
706          png_warning(png_ptr,
707            "Ignoring gAMA chunk with gamma=0");
708          return;
709       }
710
711 #ifdef PNG_READ_sRGB_SUPPORTED
712    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
713       if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
714       {
715          png_warning(png_ptr,
716            "Ignoring incorrect gAMA value when sRGB is also present");
717 #ifdef PNG_CONSOLE_IO_SUPPORTED
718          fprintf(stderr, "gamma = (%d/100000)", (int)igamma);
719 #endif
720          return;
721       }
722 #endif /* PNG_READ_sRGB_SUPPORTED */
723
724 #ifdef PNG_FLOATING_POINT_SUPPORTED
725    file_gamma = (float)igamma / (float)100000.0;
726 #  ifdef PNG_READ_GAMMA_SUPPORTED
727      png_ptr->gamma = file_gamma;
728 #  endif
729      png_set_gAMA(png_ptr, info_ptr, file_gamma);
730 #endif
731 #ifdef PNG_FIXED_POINT_SUPPORTED
732    png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
733 #endif
734 }
735 #endif
736
737 #ifdef PNG_READ_sBIT_SUPPORTED
738 void /* PRIVATE */
739 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
740 {
741    png_size_t truelen;
742    png_byte buf[4];
743
744    png_debug(1, "in png_handle_sBIT");
745
746    buf[0] = buf[1] = buf[2] = buf[3] = 0;
747
748    if (!(png_ptr->mode & PNG_HAVE_IHDR))
749       png_error(png_ptr, "Missing IHDR before sBIT");
750    else if (png_ptr->mode & PNG_HAVE_IDAT)
751    {
752       png_warning(png_ptr, "Invalid sBIT after IDAT");
753       png_crc_finish(png_ptr, length);
754       return;
755    }
756    else if (png_ptr->mode & PNG_HAVE_PLTE)
757    {
758       /* Should be an error, but we can cope with it */
759       png_warning(png_ptr, "Out of place sBIT chunk");
760    }
761    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
762    {
763       png_warning(png_ptr, "Duplicate sBIT chunk");
764       png_crc_finish(png_ptr, length);
765       return;
766    }
767
768    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
769       truelen = 3;
770    else
771       truelen = (png_size_t)png_ptr->channels;
772
773    if (length != truelen || length > 4)
774    {
775       png_warning(png_ptr, "Incorrect sBIT chunk length");
776       png_crc_finish(png_ptr, length);
777       return;
778    }
779
780    png_crc_read(png_ptr, buf, truelen);
781    if (png_crc_finish(png_ptr, 0))
782       return;
783
784    if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
785    {
786       png_ptr->sig_bit.red = buf[0];
787       png_ptr->sig_bit.green = buf[1];
788       png_ptr->sig_bit.blue = buf[2];
789       png_ptr->sig_bit.alpha = buf[3];
790    }
791    else
792    {
793       png_ptr->sig_bit.gray = buf[0];
794       png_ptr->sig_bit.red = buf[0];
795       png_ptr->sig_bit.green = buf[0];
796       png_ptr->sig_bit.blue = buf[0];
797       png_ptr->sig_bit.alpha = buf[1];
798    }
799    png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
800 }
801 #endif
802
803 #ifdef PNG_READ_cHRM_SUPPORTED
804 void /* PRIVATE */
805 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
806 {
807    png_byte buf[32];
808 #ifdef PNG_FLOATING_POINT_SUPPORTED
809    float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
810 #endif
811    png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
812       int_y_green, int_x_blue, int_y_blue;
813
814    png_uint_32 uint_x, uint_y;
815
816    png_debug(1, "in png_handle_cHRM");
817
818    if (!(png_ptr->mode & PNG_HAVE_IHDR))
819       png_error(png_ptr, "Missing IHDR before cHRM");
820    else if (png_ptr->mode & PNG_HAVE_IDAT)
821    {
822       png_warning(png_ptr, "Invalid cHRM after IDAT");
823       png_crc_finish(png_ptr, length);
824       return;
825    }
826    else if (png_ptr->mode & PNG_HAVE_PLTE)
827       /* Should be an error, but we can cope with it */
828       png_warning(png_ptr, "Missing PLTE before cHRM");
829
830    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
831 #ifdef PNG_READ_sRGB_SUPPORTED
832       && !(info_ptr->valid & PNG_INFO_sRGB)
833 #endif
834       )
835    {
836       png_warning(png_ptr, "Duplicate cHRM chunk");
837       png_crc_finish(png_ptr, length);
838       return;
839    }
840
841    if (length != 32)
842    {
843       png_warning(png_ptr, "Incorrect cHRM chunk length");
844       png_crc_finish(png_ptr, length);
845       return;
846    }
847
848    png_crc_read(png_ptr, buf, 32);
849    if (png_crc_finish(png_ptr, 0))
850       return;
851
852    uint_x = png_get_uint_32(buf);
853    uint_y = png_get_uint_32(buf + 4);
854    int_x_white = (png_fixed_point)uint_x;
855    int_y_white = (png_fixed_point)uint_y;
856
857    uint_x = png_get_uint_32(buf + 8);
858    uint_y = png_get_uint_32(buf + 12);
859    int_x_red = (png_fixed_point)uint_x;
860    int_y_red = (png_fixed_point)uint_y;
861
862    uint_x = png_get_uint_32(buf + 16);
863    uint_y = png_get_uint_32(buf + 20);
864    int_x_green = (png_fixed_point)uint_x;
865    int_y_green = (png_fixed_point)uint_y;
866
867    uint_x = png_get_uint_32(buf + 24);
868    uint_y = png_get_uint_32(buf + 28);
869    int_x_blue = (png_fixed_point)uint_x;
870    int_y_blue = (png_fixed_point)uint_y;
871
872 #ifdef PNG_FLOATING_POINT_SUPPORTED
873    white_x = (float)int_x_white / (float)100000.0;
874    white_y = (float)int_y_white / (float)100000.0;
875    red_x   = (float)int_x_red   / (float)100000.0;
876    red_y   = (float)int_y_red   / (float)100000.0;
877    green_x = (float)int_x_green / (float)100000.0;
878    green_y = (float)int_y_green / (float)100000.0;
879    blue_x  = (float)int_x_blue  / (float)100000.0;
880    blue_y  = (float)int_y_blue  / (float)100000.0;
881 #endif
882
883 #ifdef PNG_READ_sRGB_SUPPORTED
884    if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
885       {
886       if (PNG_OUT_OF_RANGE(int_x_white, 31270,  1000) ||
887           PNG_OUT_OF_RANGE(int_y_white, 32900,  1000) ||
888           PNG_OUT_OF_RANGE(int_x_red,   64000L, 1000) ||
889           PNG_OUT_OF_RANGE(int_y_red,   33000,  1000) ||
890           PNG_OUT_OF_RANGE(int_x_green, 30000,  1000) ||
891           PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
892           PNG_OUT_OF_RANGE(int_x_blue,  15000,  1000) ||
893           PNG_OUT_OF_RANGE(int_y_blue,   6000,  1000))
894          {
895             png_warning(png_ptr,
896               "Ignoring incorrect cHRM value when sRGB is also present");
897 #ifdef PNG_CONSOLE_IO_SUPPORTED
898 #ifdef PNG_FLOATING_POINT_SUPPORTED
899             fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n",
900                white_x, white_y, red_x, red_y);
901             fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n",
902                green_x, green_y, blue_x, blue_y);
903 #else
904             fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
905                (long)int_x_white, (long)int_y_white,
906                (long)int_x_red, (long)int_y_red);
907             fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
908                (long)int_x_green, (long)int_y_green,
909                (long)int_x_blue, (long)int_y_blue);
910 #endif
911 #endif /* PNG_CONSOLE_IO_SUPPORTED */
912          }
913          return;
914       }
915 #endif /* PNG_READ_sRGB_SUPPORTED */
916
917 #ifdef PNG_FLOATING_POINT_SUPPORTED
918    png_set_cHRM(png_ptr, info_ptr,
919       white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
920 #endif
921 #ifdef PNG_FIXED_POINT_SUPPORTED
922    png_set_cHRM_fixed(png_ptr, info_ptr,
923       int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
924       int_y_green, int_x_blue, int_y_blue);
925 #endif
926 }
927 #endif
928
929 #ifdef PNG_READ_sRGB_SUPPORTED
930 void /* PRIVATE */
931 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
932 {
933    int intent;
934    png_byte buf[1];
935
936    png_debug(1, "in png_handle_sRGB");
937
938    if (!(png_ptr->mode & PNG_HAVE_IHDR))
939       png_error(png_ptr, "Missing IHDR before sRGB");
940    else if (png_ptr->mode & PNG_HAVE_IDAT)
941    {
942       png_warning(png_ptr, "Invalid sRGB after IDAT");
943       png_crc_finish(png_ptr, length);
944       return;
945    }
946    else if (png_ptr->mode & PNG_HAVE_PLTE)
947       /* Should be an error, but we can cope with it */
948       png_warning(png_ptr, "Out of place sRGB chunk");
949
950    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
951    {
952       png_warning(png_ptr, "Duplicate sRGB chunk");
953       png_crc_finish(png_ptr, length);
954       return;
955    }
956
957    if (length != 1)
958    {
959       png_warning(png_ptr, "Incorrect sRGB chunk length");
960       png_crc_finish(png_ptr, length);
961       return;
962    }
963
964    png_crc_read(png_ptr, buf, 1);
965    if (png_crc_finish(png_ptr, 0))
966       return;
967
968    intent = buf[0];
969    /* Check for bad intent */
970    if (intent >= PNG_sRGB_INTENT_LAST)
971    {
972       png_warning(png_ptr, "Unknown sRGB intent");
973       return;
974    }
975
976 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
977    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
978    {
979    png_fixed_point igamma;
980 #ifdef PNG_FIXED_POINT_SUPPORTED
981       igamma=info_ptr->int_gamma;
982 #else
983 #  ifdef PNG_FLOATING_POINT_SUPPORTED
984       igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
985 #  endif
986 #endif
987       if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
988       {
989          png_warning(png_ptr,
990            "Ignoring incorrect gAMA value when sRGB is also present");
991 #ifdef PNG_CONSOLE_IO_SUPPORTED
992 #  ifdef PNG_FIXED_POINT_SUPPORTED
993          fprintf(stderr, "incorrect gamma=(%d/100000)\n",
994             (int)png_ptr->int_gamma);
995 #  else
996 #    ifdef PNG_FLOATING_POINT_SUPPORTED
997          fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma);
998 #    endif
999 #  endif
1000 #endif
1001       }
1002    }
1003 #endif /* PNG_READ_gAMA_SUPPORTED */
1004
1005 #ifdef PNG_READ_cHRM_SUPPORTED
1006 #ifdef PNG_FIXED_POINT_SUPPORTED
1007    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
1008       if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270,  1000) ||
1009           PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900,  1000) ||
1010           PNG_OUT_OF_RANGE(info_ptr->int_x_red,   64000L, 1000) ||
1011           PNG_OUT_OF_RANGE(info_ptr->int_y_red,   33000,  1000) ||
1012           PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000,  1000) ||
1013           PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
1014           PNG_OUT_OF_RANGE(info_ptr->int_x_blue,  15000,  1000) ||
1015           PNG_OUT_OF_RANGE(info_ptr->int_y_blue,   6000,  1000))
1016          {
1017             png_warning(png_ptr,
1018               "Ignoring incorrect cHRM value when sRGB is also present");
1019          }
1020 #endif /* PNG_FIXED_POINT_SUPPORTED */
1021 #endif /* PNG_READ_cHRM_SUPPORTED */
1022
1023    png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
1024 }
1025 #endif /* PNG_READ_sRGB_SUPPORTED */
1026
1027 #ifdef PNG_READ_iCCP_SUPPORTED
1028 void /* PRIVATE */
1029 png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1030 /* Note: this does not properly handle chunks that are > 64K under DOS */
1031 {
1032    png_byte compression_type;
1033    png_bytep pC;
1034    png_charp profile;
1035    png_uint_32 skip = 0;
1036    png_uint_32 profile_size, profile_length;
1037    png_size_t slength, prefix_length, data_length;
1038
1039    png_debug(1, "in png_handle_iCCP");
1040
1041    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1042       png_error(png_ptr, "Missing IHDR before iCCP");
1043    else if (png_ptr->mode & PNG_HAVE_IDAT)
1044    {
1045       png_warning(png_ptr, "Invalid iCCP after IDAT");
1046       png_crc_finish(png_ptr, length);
1047       return;
1048    }
1049    else if (png_ptr->mode & PNG_HAVE_PLTE)
1050       /* Should be an error, but we can cope with it */
1051       png_warning(png_ptr, "Out of place iCCP chunk");
1052
1053    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
1054    {
1055       png_warning(png_ptr, "Duplicate iCCP chunk");
1056       png_crc_finish(png_ptr, length);
1057       return;
1058    }
1059
1060 #ifdef PNG_MAX_MALLOC_64K
1061    if (length > (png_uint_32)65535L)
1062    {
1063       png_warning(png_ptr, "iCCP chunk too large to fit in memory");
1064       skip = length - (png_uint_32)65535L;
1065       length = (png_uint_32)65535L;
1066    }
1067 #endif
1068
1069    png_free(png_ptr, png_ptr->chunkdata);
1070    png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1071    slength = (png_size_t)length;
1072    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1073
1074    if (png_crc_finish(png_ptr, skip))
1075    {
1076       png_free(png_ptr, png_ptr->chunkdata);
1077       png_ptr->chunkdata = NULL;
1078       return;
1079    }
1080
1081    png_ptr->chunkdata[slength] = 0x00;
1082
1083    for (profile = png_ptr->chunkdata; *profile; profile++)
1084       /* Empty loop to find end of name */ ;
1085
1086    ++profile;
1087
1088    /* There should be at least one zero (the compression type byte)
1089     * following the separator, and we should be on it
1090     */
1091    if ( profile >= png_ptr->chunkdata + slength - 1)
1092    {
1093       png_free(png_ptr, png_ptr->chunkdata);
1094       png_ptr->chunkdata = NULL;
1095       png_warning(png_ptr, "Malformed iCCP chunk");
1096       return;
1097    }
1098
1099    /* Compression_type should always be zero */
1100    compression_type = *profile++;
1101    if (compression_type)
1102    {
1103       png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
1104       compression_type = 0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
1105                                  wrote nonzero) */
1106    }
1107
1108    prefix_length = profile - png_ptr->chunkdata;
1109    png_decompress_chunk(png_ptr, compression_type,
1110      slength, prefix_length, &data_length);
1111
1112    profile_length = data_length - prefix_length;
1113
1114    if ( prefix_length > data_length || profile_length < 4)
1115    {
1116       png_free(png_ptr, png_ptr->chunkdata);
1117       png_ptr->chunkdata = NULL;
1118       png_warning(png_ptr, "Profile size field missing from iCCP chunk");
1119       return;
1120    }
1121
1122    /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1123    pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
1124    profile_size = ((*(pC    ))<<24) |
1125                   ((*(pC + 1))<<16) |
1126                   ((*(pC + 2))<< 8) |
1127                   ((*(pC + 3))    );
1128
1129    if (profile_size < profile_length)
1130       profile_length = profile_size;
1131
1132    if (profile_size > profile_length)
1133    {
1134 #ifdef PNG_STDIO_SUPPORTED
1135          char umsg[50];
1136 #endif
1137       png_free(png_ptr, png_ptr->chunkdata);
1138       png_ptr->chunkdata = NULL;
1139       png_warning(png_ptr, "Ignoring truncated iCCP profile");
1140 #ifdef PNG_STDIO_SUPPORTED
1141
1142       png_snprintf(umsg, 50, "declared profile size = %lu",
1143           (unsigned long)profile_size);
1144       png_warning(png_ptr, umsg);
1145       png_snprintf(umsg, 50, "actual profile length = %lu",
1146           (unsigned long)profile_length);
1147       png_warning(png_ptr, umsg);
1148 #endif
1149       return;
1150    }
1151
1152    png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
1153      compression_type, png_ptr->chunkdata + prefix_length, profile_length);
1154    png_free(png_ptr, png_ptr->chunkdata);
1155    png_ptr->chunkdata = NULL;
1156 }
1157 #endif /* PNG_READ_iCCP_SUPPORTED */
1158
1159 #ifdef PNG_READ_sPLT_SUPPORTED
1160 void /* PRIVATE */
1161 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1162 /* Note: this does not properly handle chunks that are > 64K under DOS */
1163 {
1164    png_bytep entry_start;
1165    png_sPLT_t new_palette;
1166 #ifdef PNG_POINTER_INDEXING_SUPPORTED
1167    png_sPLT_entryp pp;
1168 #endif
1169    int data_length, entry_size, i;
1170    png_uint_32 skip = 0;
1171    png_size_t slength;
1172
1173    png_debug(1, "in png_handle_sPLT");
1174
1175 #ifdef PNG_USER_LIMITS_SUPPORTED
1176
1177    if (png_ptr->user_chunk_cache_max != 0)
1178    {
1179       if (png_ptr->user_chunk_cache_max == 1)
1180       {
1181          png_crc_finish(png_ptr, length);
1182          return;
1183       }
1184       if (--png_ptr->user_chunk_cache_max == 1)
1185       {
1186          png_warning(png_ptr, "No space in chunk cache for sPLT");
1187          png_crc_finish(png_ptr, length);
1188          return;
1189       }
1190    }
1191 #endif
1192
1193    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1194       png_error(png_ptr, "Missing IHDR before sPLT");
1195    else if (png_ptr->mode & PNG_HAVE_IDAT)
1196    {
1197       png_warning(png_ptr, "Invalid sPLT after IDAT");
1198       png_crc_finish(png_ptr, length);
1199       return;
1200    }
1201
1202 #ifdef PNG_MAX_MALLOC_64K
1203    if (length > (png_uint_32)65535L)
1204    {
1205       png_warning(png_ptr, "sPLT chunk too large to fit in memory");
1206       skip = length - (png_uint_32)65535L;
1207       length = (png_uint_32)65535L;
1208    }
1209 #endif
1210
1211    png_free(png_ptr, png_ptr->chunkdata);
1212    png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1213    slength = (png_size_t)length;
1214    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1215
1216    if (png_crc_finish(png_ptr, skip))
1217    {
1218       png_free(png_ptr, png_ptr->chunkdata);
1219       png_ptr->chunkdata = NULL;
1220       return;
1221    }
1222
1223    png_ptr->chunkdata[slength] = 0x00;
1224
1225    for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
1226        entry_start++)
1227       /* Empty loop to find end of name */ ;
1228    ++entry_start;
1229
1230    /* A sample depth should follow the separator, and we should be on it  */
1231    if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
1232    {
1233       png_free(png_ptr, png_ptr->chunkdata);
1234       png_ptr->chunkdata = NULL;
1235       png_warning(png_ptr, "malformed sPLT chunk");
1236       return;
1237    }
1238
1239    new_palette.depth = *entry_start++;
1240    entry_size = (new_palette.depth == 8 ? 6 : 10);
1241    data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata));
1242
1243    /* Integrity-check the data length */
1244    if (data_length % entry_size)
1245    {
1246       png_free(png_ptr, png_ptr->chunkdata);
1247       png_ptr->chunkdata = NULL;
1248       png_warning(png_ptr, "sPLT chunk has bad length");
1249       return;
1250    }
1251
1252    new_palette.nentries = (png_int_32) ( data_length / entry_size);
1253    if ((png_uint_32) new_palette.nentries >
1254        (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry)))
1255    {
1256        png_warning(png_ptr, "sPLT chunk too long");
1257        return;
1258    }
1259    new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
1260        png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
1261    if (new_palette.entries == NULL)
1262    {
1263        png_warning(png_ptr, "sPLT chunk requires too much memory");
1264        return;
1265    }
1266
1267 #ifdef PNG_POINTER_INDEXING_SUPPORTED
1268    for (i = 0; i < new_palette.nentries; i++)
1269    {
1270       pp = new_palette.entries + i;
1271
1272       if (new_palette.depth == 8)
1273       {
1274           pp->red = *entry_start++;
1275           pp->green = *entry_start++;
1276           pp->blue = *entry_start++;
1277           pp->alpha = *entry_start++;
1278       }
1279       else
1280       {
1281           pp->red   = png_get_uint_16(entry_start); entry_start += 2;
1282           pp->green = png_get_uint_16(entry_start); entry_start += 2;
1283           pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
1284           pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1285       }
1286       pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1287    }
1288 #else
1289    pp = new_palette.entries;
1290    for (i = 0; i < new_palette.nentries; i++)
1291    {
1292
1293       if (new_palette.depth == 8)
1294       {
1295           pp[i].red   = *entry_start++;
1296           pp[i].green = *entry_start++;
1297           pp[i].blue  = *entry_start++;
1298           pp[i].alpha = *entry_start++;
1299       }
1300       else
1301       {
1302           pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
1303           pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
1304           pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
1305           pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
1306       }
1307       pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1308    }
1309 #endif
1310
1311    /* Discard all chunk data except the name and stash that */
1312    new_palette.name = png_ptr->chunkdata;
1313
1314    png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1315
1316    png_free(png_ptr, png_ptr->chunkdata);
1317    png_ptr->chunkdata = NULL;
1318    png_free(png_ptr, new_palette.entries);
1319 }
1320 #endif /* PNG_READ_sPLT_SUPPORTED */
1321
1322 #ifdef PNG_READ_tRNS_SUPPORTED
1323 void /* PRIVATE */
1324 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1325 {
1326    png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1327
1328    png_debug(1, "in png_handle_tRNS");
1329
1330    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1331       png_error(png_ptr, "Missing IHDR before tRNS");
1332    else if (png_ptr->mode & PNG_HAVE_IDAT)
1333    {
1334       png_warning(png_ptr, "Invalid tRNS after IDAT");
1335       png_crc_finish(png_ptr, length);
1336       return;
1337    }
1338    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
1339    {
1340       png_warning(png_ptr, "Duplicate tRNS chunk");
1341       png_crc_finish(png_ptr, length);
1342       return;
1343    }
1344
1345    if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1346    {
1347       png_byte buf[2];
1348
1349       if (length != 2)
1350       {
1351          png_warning(png_ptr, "Incorrect tRNS chunk length");
1352          png_crc_finish(png_ptr, length);
1353          return;
1354       }
1355
1356       png_crc_read(png_ptr, buf, 2);
1357       png_ptr->num_trans = 1;
1358       png_ptr->trans_color.gray = png_get_uint_16(buf);
1359    }
1360    else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
1361    {
1362       png_byte buf[6];
1363
1364       if (length != 6)
1365       {
1366          png_warning(png_ptr, "Incorrect tRNS chunk length");
1367          png_crc_finish(png_ptr, length);
1368          return;
1369       }
1370       png_crc_read(png_ptr, buf, (png_size_t)length);
1371       png_ptr->num_trans = 1;
1372       png_ptr->trans_color.red = png_get_uint_16(buf);
1373       png_ptr->trans_color.green = png_get_uint_16(buf + 2);
1374       png_ptr->trans_color.blue = png_get_uint_16(buf + 4);
1375    }
1376    else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1377    {
1378       if (!(png_ptr->mode & PNG_HAVE_PLTE))
1379       {
1380          /* Should be an error, but we can cope with it. */
1381          png_warning(png_ptr, "Missing PLTE before tRNS");
1382       }
1383       if (length > (png_uint_32)png_ptr->num_palette ||
1384           length > PNG_MAX_PALETTE_LENGTH)
1385       {
1386          png_warning(png_ptr, "Incorrect tRNS chunk length");
1387          png_crc_finish(png_ptr, length);
1388          return;
1389       }
1390       if (length == 0)
1391       {
1392          png_warning(png_ptr, "Zero length tRNS chunk");
1393          png_crc_finish(png_ptr, length);
1394          return;
1395       }
1396       png_crc_read(png_ptr, readbuf, (png_size_t)length);
1397       png_ptr->num_trans = (png_uint_16)length;
1398    }
1399    else
1400    {
1401       png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
1402       png_crc_finish(png_ptr, length);
1403       return;
1404    }
1405
1406    if (png_crc_finish(png_ptr, 0))
1407    {
1408       png_ptr->num_trans = 0;
1409       return;
1410    }
1411
1412    png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1413       &(png_ptr->trans_color));
1414 }
1415 #endif
1416
1417 #ifdef PNG_READ_bKGD_SUPPORTED
1418 void /* PRIVATE */
1419 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1420 {
1421    png_size_t truelen;
1422    png_byte buf[6];
1423
1424    png_debug(1, "in png_handle_bKGD");
1425
1426    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1427       png_error(png_ptr, "Missing IHDR before bKGD");
1428    else if (png_ptr->mode & PNG_HAVE_IDAT)
1429    {
1430       png_warning(png_ptr, "Invalid bKGD after IDAT");
1431       png_crc_finish(png_ptr, length);
1432       return;
1433    }
1434    else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
1435             !(png_ptr->mode & PNG_HAVE_PLTE))
1436    {
1437       png_warning(png_ptr, "Missing PLTE before bKGD");
1438       png_crc_finish(png_ptr, length);
1439       return;
1440    }
1441    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
1442    {
1443       png_warning(png_ptr, "Duplicate bKGD chunk");
1444       png_crc_finish(png_ptr, length);
1445       return;
1446    }
1447
1448    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1449       truelen = 1;
1450    else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
1451       truelen = 6;
1452    else
1453       truelen = 2;
1454
1455    if (length != truelen)
1456    {
1457       png_warning(png_ptr, "Incorrect bKGD chunk length");
1458       png_crc_finish(png_ptr, length);
1459       return;
1460    }
1461
1462    png_crc_read(png_ptr, buf, truelen);
1463    if (png_crc_finish(png_ptr, 0))
1464       return;
1465
1466    /* We convert the index value into RGB components so that we can allow
1467     * arbitrary RGB values for background when we have transparency, and
1468     * so it is easy to determine the RGB values of the background color
1469     * from the info_ptr struct. */
1470    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1471    {
1472       png_ptr->background.index = buf[0];
1473       if (info_ptr && info_ptr->num_palette)
1474       {
1475           if (buf[0] >= info_ptr->num_palette)
1476           {
1477              png_warning(png_ptr, "Incorrect bKGD chunk index value");
1478              return;
1479           }
1480           png_ptr->background.red =
1481              (png_uint_16)png_ptr->palette[buf[0]].red;
1482           png_ptr->background.green =
1483              (png_uint_16)png_ptr->palette[buf[0]].green;
1484           png_ptr->background.blue =
1485              (png_uint_16)png_ptr->palette[buf[0]].blue;
1486       }
1487    }
1488    else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
1489    {
1490       png_ptr->background.red =
1491       png_ptr->background.green =
1492       png_ptr->background.blue =
1493       png_ptr->background.gray = png_get_uint_16(buf);
1494    }
1495    else
1496    {
1497       png_ptr->background.red = png_get_uint_16(buf);
1498       png_ptr->background.green = png_get_uint_16(buf + 2);
1499       png_ptr->background.blue = png_get_uint_16(buf + 4);
1500    }
1501
1502    png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
1503 }
1504 #endif
1505
1506 #ifdef PNG_READ_hIST_SUPPORTED
1507 void /* PRIVATE */
1508 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1509 {
1510    unsigned int num, i;
1511    png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
1512
1513    png_debug(1, "in png_handle_hIST");
1514
1515    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1516       png_error(png_ptr, "Missing IHDR before hIST");
1517    else if (png_ptr->mode & PNG_HAVE_IDAT)
1518    {
1519       png_warning(png_ptr, "Invalid hIST after IDAT");
1520       png_crc_finish(png_ptr, length);
1521       return;
1522    }
1523    else if (!(png_ptr->mode & PNG_HAVE_PLTE))
1524    {
1525       png_warning(png_ptr, "Missing PLTE before hIST");
1526       png_crc_finish(png_ptr, length);
1527       return;
1528    }
1529    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
1530    {
1531       png_warning(png_ptr, "Duplicate hIST chunk");
1532       png_crc_finish(png_ptr, length);
1533       return;
1534    }
1535
1536    num = length / 2 ;
1537    if (num != (unsigned int) png_ptr->num_palette || num >
1538       (unsigned int) PNG_MAX_PALETTE_LENGTH)
1539    {
1540       png_warning(png_ptr, "Incorrect hIST chunk length");
1541       png_crc_finish(png_ptr, length);
1542       return;
1543    }
1544
1545    for (i = 0; i < num; i++)
1546    {
1547       png_byte buf[2];
1548
1549       png_crc_read(png_ptr, buf, 2);
1550       readbuf[i] = png_get_uint_16(buf);
1551    }
1552
1553    if (png_crc_finish(png_ptr, 0))
1554       return;
1555
1556    png_set_hIST(png_ptr, info_ptr, readbuf);
1557 }
1558 #endif
1559
1560 #ifdef PNG_READ_pHYs_SUPPORTED
1561 void /* PRIVATE */
1562 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1563 {
1564    png_byte buf[9];
1565    png_uint_32 res_x, res_y;
1566    int unit_type;
1567
1568    png_debug(1, "in png_handle_pHYs");
1569
1570    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1571       png_error(png_ptr, "Missing IHDR before pHYs");
1572    else if (png_ptr->mode & PNG_HAVE_IDAT)
1573    {
1574       png_warning(png_ptr, "Invalid pHYs after IDAT");
1575       png_crc_finish(png_ptr, length);
1576       return;
1577    }
1578    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
1579    {
1580       png_warning(png_ptr, "Duplicate pHYs chunk");
1581       png_crc_finish(png_ptr, length);
1582       return;
1583    }
1584
1585    if (length != 9)
1586    {
1587       png_warning(png_ptr, "Incorrect pHYs chunk length");
1588       png_crc_finish(png_ptr, length);
1589       return;
1590    }
1591
1592    png_crc_read(png_ptr, buf, 9);
1593    if (png_crc_finish(png_ptr, 0))
1594       return;
1595
1596    res_x = png_get_uint_32(buf);
1597    res_y = png_get_uint_32(buf + 4);
1598    unit_type = buf[8];
1599    png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
1600 }
1601 #endif
1602
1603 #ifdef PNG_READ_oFFs_SUPPORTED
1604 void /* PRIVATE */
1605 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1606 {
1607    png_byte buf[9];
1608    png_int_32 offset_x, offset_y;
1609    int unit_type;
1610
1611    png_debug(1, "in png_handle_oFFs");
1612
1613    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1614       png_error(png_ptr, "Missing IHDR before oFFs");
1615    else if (png_ptr->mode & PNG_HAVE_IDAT)
1616    {
1617       png_warning(png_ptr, "Invalid oFFs after IDAT");
1618       png_crc_finish(png_ptr, length);
1619       return;
1620    }
1621    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
1622    {
1623       png_warning(png_ptr, "Duplicate oFFs chunk");
1624       png_crc_finish(png_ptr, length);
1625       return;
1626    }
1627
1628    if (length != 9)
1629    {
1630       png_warning(png_ptr, "Incorrect oFFs chunk length");
1631       png_crc_finish(png_ptr, length);
1632       return;
1633    }
1634
1635    png_crc_read(png_ptr, buf, 9);
1636    if (png_crc_finish(png_ptr, 0))
1637       return;
1638
1639    offset_x = png_get_int_32(buf);
1640    offset_y = png_get_int_32(buf + 4);
1641    unit_type = buf[8];
1642    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
1643 }
1644 #endif
1645
1646 #ifdef PNG_READ_pCAL_SUPPORTED
1647 /* Read the pCAL chunk (described in the PNG Extensions document) */
1648 void /* PRIVATE */
1649 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1650 {
1651    png_int_32 X0, X1;
1652    png_byte type, nparams;
1653    png_charp buf, units, endptr;
1654    png_charpp params;
1655    png_size_t slength;
1656    int i;
1657
1658    png_debug(1, "in png_handle_pCAL");
1659
1660    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1661       png_error(png_ptr, "Missing IHDR before pCAL");
1662    else if (png_ptr->mode & PNG_HAVE_IDAT)
1663    {
1664       png_warning(png_ptr, "Invalid pCAL after IDAT");
1665       png_crc_finish(png_ptr, length);
1666       return;
1667    }
1668    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
1669    {
1670       png_warning(png_ptr, "Duplicate pCAL chunk");
1671       png_crc_finish(png_ptr, length);
1672       return;
1673    }
1674
1675    png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
1676       length + 1);
1677    png_free(png_ptr, png_ptr->chunkdata);
1678    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1679    if (png_ptr->chunkdata == NULL)
1680      {
1681        png_warning(png_ptr, "No memory for pCAL purpose");
1682        return;
1683      }
1684    slength = (png_size_t)length;
1685    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1686
1687    if (png_crc_finish(png_ptr, 0))
1688    {
1689       png_free(png_ptr, png_ptr->chunkdata);
1690       png_ptr->chunkdata = NULL;
1691       return;
1692    }
1693
1694    png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
1695
1696    png_debug(3, "Finding end of pCAL purpose string");
1697    for (buf = png_ptr->chunkdata; *buf; buf++)
1698       /* Empty loop */ ;
1699
1700    endptr = png_ptr->chunkdata + slength;
1701
1702    /* We need to have at least 12 bytes after the purpose string
1703       in order to get the parameter information. */
1704    if (endptr <= buf + 12)
1705    {
1706       png_warning(png_ptr, "Invalid pCAL data");
1707       png_free(png_ptr, png_ptr->chunkdata);
1708       png_ptr->chunkdata = NULL;
1709       return;
1710    }
1711
1712    png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
1713    X0 = png_get_int_32((png_bytep)buf+1);
1714    X1 = png_get_int_32((png_bytep)buf+5);
1715    type = buf[9];
1716    nparams = buf[10];
1717    units = buf + 11;
1718
1719    png_debug(3, "Checking pCAL equation type and number of parameters");
1720    /* Check that we have the right number of parameters for known
1721       equation types. */
1722    if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
1723        (type == PNG_EQUATION_BASE_E && nparams != 3) ||
1724        (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
1725        (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
1726    {
1727       png_warning(png_ptr, "Invalid pCAL parameters for equation type");
1728       png_free(png_ptr, png_ptr->chunkdata);
1729       png_ptr->chunkdata = NULL;
1730       return;
1731    }
1732    else if (type >= PNG_EQUATION_LAST)
1733    {
1734       png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1735    }
1736
1737    for (buf = units; *buf; buf++)
1738       /* Empty loop to move past the units string. */ ;
1739
1740    png_debug(3, "Allocating pCAL parameters array");
1741    params = (png_charpp)png_malloc_warn(png_ptr,
1742       (png_size_t)(nparams * png_sizeof(png_charp)));
1743    if (params == NULL)
1744      {
1745        png_free(png_ptr, png_ptr->chunkdata);
1746        png_ptr->chunkdata = NULL;
1747        png_warning(png_ptr, "No memory for pCAL params");
1748        return;
1749      }
1750
1751    /* Get pointers to the start of each parameter string. */
1752    for (i = 0; i < (int)nparams; i++)
1753    {
1754       buf++; /* Skip the null string terminator from previous parameter. */
1755
1756       png_debug1(3, "Reading pCAL parameter %d", i);
1757       for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
1758          /* Empty loop to move past each parameter string */ ;
1759
1760       /* Make sure we haven't run out of data yet */
1761       if (buf > endptr)
1762       {
1763          png_warning(png_ptr, "Invalid pCAL data");
1764          png_free(png_ptr, png_ptr->chunkdata);
1765          png_ptr->chunkdata = NULL;
1766          png_free(png_ptr, params);
1767          return;
1768       }
1769    }
1770
1771    png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
1772       units, params);
1773
1774    png_free(png_ptr, png_ptr->chunkdata);
1775    png_ptr->chunkdata = NULL;
1776    png_free(png_ptr, params);
1777 }
1778 #endif
1779
1780 #ifdef PNG_READ_sCAL_SUPPORTED
1781 /* Read the sCAL chunk */
1782 void /* PRIVATE */
1783 png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1784 {
1785    png_charp ep;
1786 #ifdef PNG_FLOATING_POINT_SUPPORTED
1787    double width, height;
1788    png_charp vp;
1789 #else
1790 #ifdef PNG_FIXED_POINT_SUPPORTED
1791    png_charp swidth, sheight;
1792 #endif
1793 #endif
1794    png_size_t slength;
1795
1796    png_debug(1, "in png_handle_sCAL");
1797
1798    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1799       png_error(png_ptr, "Missing IHDR before sCAL");
1800    else if (png_ptr->mode & PNG_HAVE_IDAT)
1801    {
1802       png_warning(png_ptr, "Invalid sCAL after IDAT");
1803       png_crc_finish(png_ptr, length);
1804       return;
1805    }
1806    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
1807    {
1808       png_warning(png_ptr, "Duplicate sCAL chunk");
1809       png_crc_finish(png_ptr, length);
1810       return;
1811    }
1812
1813    png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
1814       length + 1);
1815    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1816    if (png_ptr->chunkdata == NULL)
1817    {
1818       png_warning(png_ptr, "Out of memory while processing sCAL chunk");
1819       png_crc_finish(png_ptr, length);
1820       return;
1821    }
1822    slength = (png_size_t)length;
1823    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1824
1825    if (png_crc_finish(png_ptr, 0))
1826    {
1827       png_free(png_ptr, png_ptr->chunkdata);
1828       png_ptr->chunkdata = NULL;
1829       return;
1830    }
1831
1832    png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
1833
1834    ep = png_ptr->chunkdata + 1;        /* Skip unit byte */
1835
1836 #ifdef PNG_FLOATING_POINT_SUPPORTED
1837    width = png_strtod(png_ptr, ep, &vp);
1838    if (*vp)
1839    {
1840       png_warning(png_ptr, "malformed width string in sCAL chunk");
1841       png_free(png_ptr, png_ptr->chunkdata);
1842       png_ptr->chunkdata = NULL;
1843       return;
1844    }
1845 #else
1846 #ifdef PNG_FIXED_POINT_SUPPORTED
1847    swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1848    if (swidth == NULL)
1849    {
1850       png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
1851       png_free(png_ptr, png_ptr->chunkdata);
1852       png_ptr->chunkdata = NULL;
1853       return;
1854    }
1855    png_memcpy(swidth, ep, png_strlen(ep));
1856 #endif
1857 #endif
1858
1859    for (ep = png_ptr->chunkdata; *ep; ep++)
1860       /* Empty loop */ ;
1861    ep++;
1862
1863    if (png_ptr->chunkdata + slength < ep)
1864    {
1865       png_warning(png_ptr, "Truncated sCAL chunk");
1866 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1867       png_free(png_ptr, swidth);
1868 #endif
1869       png_free(png_ptr, png_ptr->chunkdata);
1870       png_ptr->chunkdata = NULL;
1871       return;
1872    }
1873
1874 #ifdef PNG_FLOATING_POINT_SUPPORTED
1875    height = png_strtod(png_ptr, ep, &vp);
1876    if (*vp)
1877    {
1878       png_warning(png_ptr, "malformed height string in sCAL chunk");
1879       png_free(png_ptr, png_ptr->chunkdata);
1880       png_ptr->chunkdata = NULL;
1881       return;
1882    }
1883 #else
1884 #ifdef PNG_FIXED_POINT_SUPPORTED
1885    sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1886    if (sheight == NULL)
1887    {
1888       png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
1889       png_free(png_ptr, png_ptr->chunkdata);
1890       png_ptr->chunkdata = NULL;
1891       png_free(png_ptr, swidth);
1892       return;
1893    }
1894    png_memcpy(sheight, ep, png_strlen(ep));
1895 #endif
1896 #endif
1897
1898    if (png_ptr->chunkdata + slength < ep
1899 #ifdef PNG_FLOATING_POINT_SUPPORTED
1900       || width <= 0. || height <= 0.
1901 #endif
1902       )
1903    {
1904       png_warning(png_ptr, "Invalid sCAL data");
1905       png_free(png_ptr, png_ptr->chunkdata);
1906       png_ptr->chunkdata = NULL;
1907 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1908       png_free(png_ptr, swidth);
1909       png_free(png_ptr, sheight);
1910 #endif
1911       return;
1912    }
1913
1914
1915 #ifdef PNG_FLOATING_POINT_SUPPORTED
1916    png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height);
1917 #else
1918 #ifdef PNG_FIXED_POINT_SUPPORTED
1919    png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight);
1920 #endif
1921 #endif
1922
1923    png_free(png_ptr, png_ptr->chunkdata);
1924    png_ptr->chunkdata = NULL;
1925 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1926    png_free(png_ptr, swidth);
1927    png_free(png_ptr, sheight);
1928 #endif
1929 }
1930 #endif
1931
1932 #ifdef PNG_READ_tIME_SUPPORTED
1933 void /* PRIVATE */
1934 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1935 {
1936    png_byte buf[7];
1937    png_time mod_time;
1938
1939    png_debug(1, "in png_handle_tIME");
1940
1941    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1942       png_error(png_ptr, "Out of place tIME chunk");
1943    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
1944    {
1945       png_warning(png_ptr, "Duplicate tIME chunk");
1946       png_crc_finish(png_ptr, length);
1947       return;
1948    }
1949
1950    if (png_ptr->mode & PNG_HAVE_IDAT)
1951       png_ptr->mode |= PNG_AFTER_IDAT;
1952
1953    if (length != 7)
1954    {
1955       png_warning(png_ptr, "Incorrect tIME chunk length");
1956       png_crc_finish(png_ptr, length);
1957       return;
1958    }
1959
1960    png_crc_read(png_ptr, buf, 7);
1961    if (png_crc_finish(png_ptr, 0))
1962       return;
1963
1964    mod_time.second = buf[6];
1965    mod_time.minute = buf[5];
1966    mod_time.hour = buf[4];
1967    mod_time.day = buf[3];
1968    mod_time.month = buf[2];
1969    mod_time.year = png_get_uint_16(buf);
1970
1971    png_set_tIME(png_ptr, info_ptr, &mod_time);
1972 }
1973 #endif
1974
1975 #ifdef PNG_READ_tEXt_SUPPORTED
1976 /* Note: this does not properly handle chunks that are > 64K under DOS */
1977 void /* PRIVATE */
1978 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1979 {
1980    png_textp text_ptr;
1981    png_charp key;
1982    png_charp text;
1983    png_uint_32 skip = 0;
1984    png_size_t slength;
1985    int ret;
1986
1987    png_debug(1, "in png_handle_tEXt");
1988
1989 #ifdef PNG_USER_LIMITS_SUPPORTED
1990    if (png_ptr->user_chunk_cache_max != 0)
1991    {
1992       if (png_ptr->user_chunk_cache_max == 1)
1993       {
1994          png_crc_finish(png_ptr, length);
1995          return;
1996       }
1997       if (--png_ptr->user_chunk_cache_max == 1)
1998       {
1999          png_warning(png_ptr, "No space in chunk cache for tEXt");
2000          png_crc_finish(png_ptr, length);
2001          return;
2002       }
2003    }
2004 #endif
2005
2006    if (!(png_ptr->mode & PNG_HAVE_IHDR))
2007       png_error(png_ptr, "Missing IHDR before tEXt");
2008
2009    if (png_ptr->mode & PNG_HAVE_IDAT)
2010       png_ptr->mode |= PNG_AFTER_IDAT;
2011
2012 #ifdef PNG_MAX_MALLOC_64K
2013    if (length > (png_uint_32)65535L)
2014    {
2015       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
2016       skip = length - (png_uint_32)65535L;
2017       length = (png_uint_32)65535L;
2018    }
2019 #endif
2020
2021    png_free(png_ptr, png_ptr->chunkdata);
2022
2023    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2024    if (png_ptr->chunkdata == NULL)
2025    {
2026      png_warning(png_ptr, "No memory to process text chunk");
2027      return;
2028    }
2029    slength = (png_size_t)length;
2030    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2031
2032    if (png_crc_finish(png_ptr, skip))
2033    {
2034       png_free(png_ptr, png_ptr->chunkdata);
2035       png_ptr->chunkdata = NULL;
2036       return;
2037    }
2038
2039    key = png_ptr->chunkdata;
2040
2041    key[slength] = 0x00;
2042
2043    for (text = key; *text; text++)
2044       /* Empty loop to find end of key */ ;
2045
2046    if (text != key + slength)
2047       text++;
2048
2049    text_ptr = (png_textp)png_malloc_warn(png_ptr,
2050       png_sizeof(png_text));
2051    if (text_ptr == NULL)
2052    {
2053      png_warning(png_ptr, "Not enough memory to process text chunk");
2054      png_free(png_ptr, png_ptr->chunkdata);
2055      png_ptr->chunkdata = NULL;
2056      return;
2057    }
2058    text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
2059    text_ptr->key = key;
2060 #ifdef PNG_iTXt_SUPPORTED
2061    text_ptr->lang = NULL;
2062    text_ptr->lang_key = NULL;
2063    text_ptr->itxt_length = 0;
2064 #endif
2065    text_ptr->text = text;
2066    text_ptr->text_length = png_strlen(text);
2067
2068    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2069
2070    png_free(png_ptr, png_ptr->chunkdata);
2071    png_ptr->chunkdata = NULL;
2072    png_free(png_ptr, text_ptr);
2073    if (ret)
2074      png_warning(png_ptr, "Insufficient memory to process text chunk");
2075 }
2076 #endif
2077
2078 #ifdef PNG_READ_zTXt_SUPPORTED
2079 /* Note: this does not correctly handle chunks that are > 64K under DOS */
2080 void /* PRIVATE */
2081 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2082 {
2083    png_textp text_ptr;
2084    png_charp text;
2085    int comp_type;
2086    int ret;
2087    png_size_t slength, prefix_len, data_len;
2088
2089    png_debug(1, "in png_handle_zTXt");
2090
2091 #ifdef PNG_USER_LIMITS_SUPPORTED
2092    if (png_ptr->user_chunk_cache_max != 0)
2093    {
2094       if (png_ptr->user_chunk_cache_max == 1)
2095       {
2096          png_crc_finish(png_ptr, length);
2097          return;
2098       }
2099       if (--png_ptr->user_chunk_cache_max == 1)
2100       {
2101          png_warning(png_ptr, "No space in chunk cache for zTXt");
2102          png_crc_finish(png_ptr, length);
2103          return;
2104       }
2105    }
2106 #endif
2107
2108    if (!(png_ptr->mode & PNG_HAVE_IHDR))
2109       png_error(png_ptr, "Missing IHDR before zTXt");
2110
2111    if (png_ptr->mode & PNG_HAVE_IDAT)
2112       png_ptr->mode |= PNG_AFTER_IDAT;
2113
2114 #ifdef PNG_MAX_MALLOC_64K
2115    /* We will no doubt have problems with chunks even half this size, but
2116       there is no hard and fast rule to tell us where to stop. */
2117    if (length > (png_uint_32)65535L)
2118    {
2119      png_warning(png_ptr, "zTXt chunk too large to fit in memory");
2120      png_crc_finish(png_ptr, length);
2121      return;
2122    }
2123 #endif
2124
2125    png_free(png_ptr, png_ptr->chunkdata);
2126    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2127    if (png_ptr->chunkdata == NULL)
2128    {
2129      png_warning(png_ptr, "Out of memory processing zTXt chunk");
2130      return;
2131    }
2132    slength = (png_size_t)length;
2133    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2134    if (png_crc_finish(png_ptr, 0))
2135    {
2136       png_free(png_ptr, png_ptr->chunkdata);
2137       png_ptr->chunkdata = NULL;
2138       return;
2139    }
2140
2141    png_ptr->chunkdata[slength] = 0x00;
2142
2143    for (text = png_ptr->chunkdata; *text; text++)
2144       /* Empty loop */ ;
2145
2146    /* zTXt must have some text after the chunkdataword */
2147    if (text >= png_ptr->chunkdata + slength - 2)
2148    {
2149       png_warning(png_ptr, "Truncated zTXt chunk");
2150       png_free(png_ptr, png_ptr->chunkdata);
2151       png_ptr->chunkdata = NULL;
2152       return;
2153    }
2154    else
2155    {
2156        comp_type = *(++text);
2157        if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
2158        {
2159           png_warning(png_ptr, "Unknown compression type in zTXt chunk");
2160           comp_type = PNG_TEXT_COMPRESSION_zTXt;
2161        }
2162        text++;        /* Skip the compression_method byte */
2163    }
2164    prefix_len = text - png_ptr->chunkdata;
2165
2166    png_decompress_chunk(png_ptr, comp_type,
2167      (png_size_t)length, prefix_len, &data_len);
2168
2169    text_ptr = (png_textp)png_malloc_warn(png_ptr,
2170       png_sizeof(png_text));
2171    if (text_ptr == NULL)
2172    {
2173      png_warning(png_ptr, "Not enough memory to process zTXt chunk");
2174      png_free(png_ptr, png_ptr->chunkdata);
2175      png_ptr->chunkdata = NULL;
2176      return;
2177    }
2178    text_ptr->compression = comp_type;
2179    text_ptr->key = png_ptr->chunkdata;
2180 #ifdef PNG_iTXt_SUPPORTED
2181    text_ptr->lang = NULL;
2182    text_ptr->lang_key = NULL;
2183    text_ptr->itxt_length = 0;
2184 #endif
2185    text_ptr->text = png_ptr->chunkdata + prefix_len;
2186    text_ptr->text_length = data_len;
2187
2188    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2189
2190    png_free(png_ptr, text_ptr);
2191    png_free(png_ptr, png_ptr->chunkdata);
2192    png_ptr->chunkdata = NULL;
2193    if (ret)
2194      png_error(png_ptr, "Insufficient memory to store zTXt chunk");
2195 }
2196 #endif
2197
2198 #ifdef PNG_READ_iTXt_SUPPORTED
2199 /* Note: this does not correctly handle chunks that are > 64K under DOS */
2200 void /* PRIVATE */
2201 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2202 {
2203    png_textp text_ptr;
2204    png_charp key, lang, text, lang_key;
2205    int comp_flag;
2206    int comp_type = 0;
2207    int ret;
2208    png_size_t slength, prefix_len, data_len;
2209
2210    png_debug(1, "in png_handle_iTXt");
2211
2212 #ifdef PNG_USER_LIMITS_SUPPORTED
2213    if (png_ptr->user_chunk_cache_max != 0)
2214    {
2215       if (png_ptr->user_chunk_cache_max == 1)
2216       {
2217          png_crc_finish(png_ptr, length);
2218          return;
2219       }
2220       if (--png_ptr->user_chunk_cache_max == 1)
2221       {
2222          png_warning(png_ptr, "No space in chunk cache for iTXt");
2223          png_crc_finish(png_ptr, length);
2224          return;
2225       }
2226    }
2227 #endif
2228
2229    if (!(png_ptr->mode & PNG_HAVE_IHDR))
2230       png_error(png_ptr, "Missing IHDR before iTXt");
2231
2232    if (png_ptr->mode & PNG_HAVE_IDAT)
2233       png_ptr->mode |= PNG_AFTER_IDAT;
2234
2235 #ifdef PNG_MAX_MALLOC_64K
2236    /* We will no doubt have problems with chunks even half this size, but
2237       there is no hard and fast rule to tell us where to stop. */
2238    if (length > (png_uint_32)65535L)
2239    {
2240      png_warning(png_ptr, "iTXt chunk too large to fit in memory");
2241      png_crc_finish(png_ptr, length);
2242      return;
2243    }
2244 #endif
2245
2246    png_free(png_ptr, png_ptr->chunkdata);
2247    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2248    if (png_ptr->chunkdata == NULL)
2249    {
2250      png_warning(png_ptr, "No memory to process iTXt chunk");
2251      return;
2252    }
2253    slength = (png_size_t)length;
2254    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2255    if (png_crc_finish(png_ptr, 0))
2256    {
2257       png_free(png_ptr, png_ptr->chunkdata);
2258       png_ptr->chunkdata = NULL;
2259       return;
2260    }
2261
2262    png_ptr->chunkdata[slength] = 0x00;
2263
2264    for (lang = png_ptr->chunkdata; *lang; lang++)
2265       /* Empty loop */ ;
2266    lang++;        /* Skip NUL separator */
2267
2268    /* iTXt must have a language tag (possibly empty), two compression bytes,
2269     * translated keyword (possibly empty), and possibly some text after the
2270     * keyword
2271     */
2272
2273    if (lang >= png_ptr->chunkdata + slength - 3)
2274    {
2275       png_warning(png_ptr, "Truncated iTXt chunk");
2276       png_free(png_ptr, png_ptr->chunkdata);
2277       png_ptr->chunkdata = NULL;
2278       return;
2279    }
2280    else
2281    {
2282        comp_flag = *lang++;
2283        comp_type = *lang++;
2284    }
2285
2286    for (lang_key = lang; *lang_key; lang_key++)
2287       /* Empty loop */ ;
2288    lang_key++;        /* Skip NUL separator */
2289
2290    if (lang_key >= png_ptr->chunkdata + slength)
2291    {
2292       png_warning(png_ptr, "Truncated iTXt chunk");
2293       png_free(png_ptr, png_ptr->chunkdata);
2294       png_ptr->chunkdata = NULL;
2295       return;
2296    }
2297
2298    for (text = lang_key; *text; text++)
2299       /* Empty loop */ ;
2300    text++;        /* Skip NUL separator */
2301    if (text >= png_ptr->chunkdata + slength)
2302    {
2303       png_warning(png_ptr, "Malformed iTXt chunk");
2304       png_free(png_ptr, png_ptr->chunkdata);
2305       png_ptr->chunkdata = NULL;
2306       return;
2307    }
2308
2309    prefix_len = text - png_ptr->chunkdata;
2310
2311    key=png_ptr->chunkdata;
2312    if (comp_flag)
2313        png_decompress_chunk(png_ptr, comp_type,
2314          (size_t)length, prefix_len, &data_len);
2315    else
2316        data_len = png_strlen(png_ptr->chunkdata + prefix_len);
2317    text_ptr = (png_textp)png_malloc_warn(png_ptr,
2318       png_sizeof(png_text));
2319    if (text_ptr == NULL)
2320    {
2321      png_warning(png_ptr, "Not enough memory to process iTXt chunk");
2322      png_free(png_ptr, png_ptr->chunkdata);
2323      png_ptr->chunkdata = NULL;
2324      return;
2325    }
2326    text_ptr->compression = (int)comp_flag + 1;
2327    text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
2328    text_ptr->lang = png_ptr->chunkdata + (lang - key);
2329    text_ptr->itxt_length = data_len;
2330    text_ptr->text_length = 0;
2331    text_ptr->key = png_ptr->chunkdata;
2332    text_ptr->text = png_ptr->chunkdata + prefix_len;
2333
2334    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2335
2336    png_free(png_ptr, text_ptr);
2337    png_free(png_ptr, png_ptr->chunkdata);
2338    png_ptr->chunkdata = NULL;
2339    if (ret)
2340      png_error(png_ptr, "Insufficient memory to store iTXt chunk");
2341 }
2342 #endif
2343
2344 /* This function is called when we haven't found a handler for a
2345    chunk.  If there isn't a problem with the chunk itself (ie bad
2346    chunk name, CRC, or a critical chunk), the chunk is silently ignored
2347    -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2348    case it will be saved away to be written out later. */
2349 void /* PRIVATE */
2350 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2351 {
2352    png_uint_32 skip = 0;
2353
2354    png_debug(1, "in png_handle_unknown");
2355
2356 #ifdef PNG_USER_LIMITS_SUPPORTED
2357    if (png_ptr->user_chunk_cache_max != 0)
2358    {
2359       if (png_ptr->user_chunk_cache_max == 1)
2360       {
2361          png_crc_finish(png_ptr, length);
2362          return;
2363       }
2364       if (--png_ptr->user_chunk_cache_max == 1)
2365       {
2366          png_warning(png_ptr, "No space in chunk cache for unknown chunk");
2367          png_crc_finish(png_ptr, length);
2368          return;
2369       }
2370    }
2371 #endif
2372
2373    if (png_ptr->mode & PNG_HAVE_IDAT)
2374    {
2375       PNG_IDAT;
2376       if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))  /* Not an IDAT */
2377          png_ptr->mode |= PNG_AFTER_IDAT;
2378    }
2379
2380    if (!(png_ptr->chunk_name[0] & 0x20))
2381    {
2382 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2383       if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2384            PNG_HANDLE_CHUNK_ALWAYS
2385 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2386            && png_ptr->read_user_chunk_fn == NULL
2387 #endif
2388         )
2389 #endif
2390           png_chunk_error(png_ptr, "unknown critical chunk");
2391    }
2392
2393 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
2394    if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
2395 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2396        || (png_ptr->read_user_chunk_fn != NULL)
2397 #endif
2398         )
2399    {
2400 #ifdef PNG_MAX_MALLOC_64K
2401        if (length > (png_uint_32)65535L)
2402        {
2403            png_warning(png_ptr, "unknown chunk too large to fit in memory");
2404            skip = length - (png_uint_32)65535L;
2405            length = (png_uint_32)65535L;
2406        }
2407 #endif
2408        png_memcpy((png_charp)png_ptr->unknown_chunk.name,
2409                   (png_charp)png_ptr->chunk_name,
2410                   png_sizeof(png_ptr->unknown_chunk.name));
2411        png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1]
2412            = '\0';
2413        png_ptr->unknown_chunk.size = (png_size_t)length;
2414        if (length == 0)
2415          png_ptr->unknown_chunk.data = NULL;
2416        else
2417        {
2418          png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
2419          png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
2420        }
2421 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2422        if (png_ptr->read_user_chunk_fn != NULL)
2423        {
2424           /* Callback to user unknown chunk handler */
2425           int ret;
2426           ret = (*(png_ptr->read_user_chunk_fn))
2427             (png_ptr, &png_ptr->unknown_chunk);
2428           if (ret < 0)
2429              png_chunk_error(png_ptr, "error in user chunk");
2430           if (ret == 0)
2431           {
2432              if (!(png_ptr->chunk_name[0] & 0x20))
2433 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2434                 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2435                      PNG_HANDLE_CHUNK_ALWAYS)
2436 #endif
2437                    png_chunk_error(png_ptr, "unknown critical chunk");
2438              png_set_unknown_chunks(png_ptr, info_ptr,
2439                &png_ptr->unknown_chunk, 1);
2440           }
2441        }
2442        else
2443 #endif
2444        png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
2445        png_free(png_ptr, png_ptr->unknown_chunk.data);
2446        png_ptr->unknown_chunk.data = NULL;
2447    }
2448    else
2449 #endif
2450       skip = length;
2451
2452    png_crc_finish(png_ptr, skip);
2453
2454 #ifndef PNG_READ_USER_CHUNKS_SUPPORTED
2455    info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
2456 #endif
2457 }
2458
2459 /* This function is called to verify that a chunk name is valid.
2460    This function can't have the "critical chunk check" incorporated
2461    into it, since in the future we will need to be able to call user
2462    functions to handle unknown critical chunks after we check that
2463    the chunk name itself is valid. */
2464
2465 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
2466
2467 void /* PRIVATE */
2468 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
2469 {
2470    png_debug(1, "in png_check_chunk_name");
2471    if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
2472        isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
2473    {
2474       png_chunk_error(png_ptr, "invalid chunk type");
2475    }
2476 }
2477
2478 /* Combines the row recently read in with the existing pixels in the
2479    row.  This routine takes care of alpha and transparency if requested.
2480    This routine also handles the two methods of progressive display
2481    of interlaced images, depending on the mask value.
2482    The mask value describes which pixels are to be combined with
2483    the row.  The pattern always repeats every 8 pixels, so just 8
2484    bits are needed.  A one indicates the pixel is to be combined,
2485    a zero indicates the pixel is to be skipped.  This is in addition
2486    to any alpha or transparency value associated with the pixel.  If
2487    you want all pixels to be combined, pass 0xff (255) in mask.  */
2488
2489 void /* PRIVATE */
2490 png_combine_row(png_structp png_ptr, png_bytep row, int mask)
2491 {
2492    png_debug(1, "in png_combine_row");
2493    if (mask == 0xff)
2494    {
2495       png_memcpy(row, png_ptr->row_buf + 1,
2496          PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
2497    }
2498    else
2499    {
2500       switch (png_ptr->row_info.pixel_depth)
2501       {
2502          case 1:
2503          {
2504             png_bytep sp = png_ptr->row_buf + 1;
2505             png_bytep dp = row;
2506             int s_inc, s_start, s_end;
2507             int m = 0x80;
2508             int shift;
2509             png_uint_32 i;
2510             png_uint_32 row_width = png_ptr->width;
2511
2512 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2513             if (png_ptr->transformations & PNG_PACKSWAP)
2514             {
2515                 s_start = 0;
2516                 s_end = 7;
2517                 s_inc = 1;
2518             }
2519             else
2520 #endif
2521             {
2522                 s_start = 7;
2523                 s_end = 0;
2524                 s_inc = -1;
2525             }
2526
2527             shift = s_start;
2528
2529             for (i = 0; i < row_width; i++)
2530             {
2531                if (m & mask)
2532                {
2533                   int value;
2534
2535                   value = (*sp >> shift) & 0x01;
2536                   *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
2537                   *dp |= (png_byte)(value << shift);
2538                }
2539
2540                if (shift == s_end)
2541                {
2542                   shift = s_start;
2543                   sp++;
2544                   dp++;
2545                }
2546                else
2547                   shift += s_inc;
2548
2549                if (m == 1)
2550                   m = 0x80;
2551                else
2552                   m >>= 1;
2553             }
2554             break;
2555          }
2556          case 2:
2557          {
2558             png_bytep sp = png_ptr->row_buf + 1;
2559             png_bytep dp = row;
2560             int s_start, s_end, s_inc;
2561             int m = 0x80;
2562             int shift;
2563             png_uint_32 i;
2564             png_uint_32 row_width = png_ptr->width;
2565             int value;
2566
2567 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2568             if (png_ptr->transformations & PNG_PACKSWAP)
2569             {
2570                s_start = 0;
2571                s_end = 6;
2572                s_inc = 2;
2573             }
2574             else
2575 #endif
2576             {
2577                s_start = 6;
2578                s_end = 0;
2579                s_inc = -2;
2580             }
2581
2582             shift = s_start;
2583
2584             for (i = 0; i < row_width; i++)
2585             {
2586                if (m & mask)
2587                {
2588                   value = (*sp >> shift) & 0x03;
2589                   *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2590                   *dp |= (png_byte)(value << shift);
2591                }
2592
2593                if (shift == s_end)
2594                {
2595                   shift = s_start;
2596                   sp++;
2597                   dp++;
2598                }
2599                else
2600                   shift += s_inc;
2601                if (m == 1)
2602                   m = 0x80;
2603                else
2604                   m >>= 1;
2605             }
2606             break;
2607          }
2608          case 4:
2609          {
2610             png_bytep sp = png_ptr->row_buf + 1;
2611             png_bytep dp = row;
2612             int s_start, s_end, s_inc;
2613             int m = 0x80;
2614             int shift;
2615             png_uint_32 i;
2616             png_uint_32 row_width = png_ptr->width;
2617             int value;
2618
2619 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2620             if (png_ptr->transformations & PNG_PACKSWAP)
2621             {
2622                s_start = 0;
2623                s_end = 4;
2624                s_inc = 4;
2625             }
2626             else
2627 #endif
2628             {
2629                s_start = 4;
2630                s_end = 0;
2631                s_inc = -4;
2632             }
2633             shift = s_start;
2634
2635             for (i = 0; i < row_width; i++)
2636             {
2637                if (m & mask)
2638                {
2639                   value = (*sp >> shift) & 0xf;
2640                   *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2641                   *dp |= (png_byte)(value << shift);
2642                }
2643
2644                if (shift == s_end)
2645                {
2646                   shift = s_start;
2647                   sp++;
2648                   dp++;
2649                }
2650                else
2651                   shift += s_inc;
2652                if (m == 1)
2653                   m = 0x80;
2654                else
2655                   m >>= 1;
2656             }
2657             break;
2658          }
2659          default:
2660          {
2661             png_bytep sp = png_ptr->row_buf + 1;
2662             png_bytep dp = row;
2663             png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
2664             png_uint_32 i;
2665             png_uint_32 row_width = png_ptr->width;
2666             png_byte m = 0x80;
2667
2668
2669             for (i = 0; i < row_width; i++)
2670             {
2671                if (m & mask)
2672                {
2673                   png_memcpy(dp, sp, pixel_bytes);
2674                }
2675
2676                sp += pixel_bytes;
2677                dp += pixel_bytes;
2678
2679                if (m == 1)
2680                   m = 0x80;
2681                else
2682                   m >>= 1;
2683             }
2684             break;
2685          }
2686       }
2687    }
2688 }
2689
2690 #ifdef PNG_READ_INTERLACING_SUPPORTED
2691 /* OLD pre-1.0.9 interface:
2692 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2693    png_uint_32 transformations)
2694  */
2695 void /* PRIVATE */
2696 png_do_read_interlace(png_structp png_ptr)
2697 {
2698    png_row_infop row_info = &(png_ptr->row_info);
2699    png_bytep row = png_ptr->row_buf + 1;
2700    int pass = png_ptr->pass;
2701    png_uint_32 transformations = png_ptr->transformations;
2702    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2703    /* Offset to next interlace block */
2704    PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2705
2706    png_debug(1, "in png_do_read_interlace");
2707    if (row != NULL && row_info != NULL)
2708    {
2709       png_uint_32 final_width;
2710
2711       final_width = row_info->width * png_pass_inc[pass];
2712
2713       switch (row_info->pixel_depth)
2714       {
2715          case 1:
2716          {
2717             png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
2718             png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
2719             int sshift, dshift;
2720             int s_start, s_end, s_inc;
2721             int jstop = png_pass_inc[pass];
2722             png_byte v;
2723             png_uint_32 i;
2724             int j;
2725
2726 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2727             if (transformations & PNG_PACKSWAP)
2728             {
2729                 sshift = (int)((row_info->width + 7) & 0x07);
2730                 dshift = (int)((final_width + 7) & 0x07);
2731                 s_start = 7;
2732                 s_end = 0;
2733                 s_inc = -1;
2734             }
2735             else
2736 #endif
2737             {
2738                 sshift = 7 - (int)((row_info->width + 7) & 0x07);
2739                 dshift = 7 - (int)((final_width + 7) & 0x07);
2740                 s_start = 0;
2741                 s_end = 7;
2742                 s_inc = 1;
2743             }
2744
2745             for (i = 0; i < row_info->width; i++)
2746             {
2747                v = (png_byte)((*sp >> sshift) & 0x01);
2748                for (j = 0; j < jstop; j++)
2749                {
2750                   *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
2751                   *dp |= (png_byte)(v << dshift);
2752                   if (dshift == s_end)
2753                   {
2754                      dshift = s_start;
2755                      dp--;
2756                   }
2757                   else
2758                      dshift += s_inc;
2759                }
2760                if (sshift == s_end)
2761                {
2762                   sshift = s_start;
2763                   sp--;
2764                }
2765                else
2766                   sshift += s_inc;
2767             }
2768             break;
2769          }
2770          case 2:
2771          {
2772             png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
2773             png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
2774             int sshift, dshift;
2775             int s_start, s_end, s_inc;
2776             int jstop = png_pass_inc[pass];
2777             png_uint_32 i;
2778
2779 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2780             if (transformations & PNG_PACKSWAP)
2781             {
2782                sshift = (int)(((row_info->width + 3) & 0x03) << 1);
2783                dshift = (int)(((final_width + 3) & 0x03) << 1);
2784                s_start = 6;
2785                s_end = 0;
2786                s_inc = -2;
2787             }
2788             else
2789 #endif
2790             {
2791                sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
2792                dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
2793                s_start = 0;
2794                s_end = 6;
2795                s_inc = 2;
2796             }
2797
2798             for (i = 0; i < row_info->width; i++)
2799             {
2800                png_byte v;
2801                int j;
2802
2803                v = (png_byte)((*sp >> sshift) & 0x03);
2804                for (j = 0; j < jstop; j++)
2805                {
2806                   *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
2807                   *dp |= (png_byte)(v << dshift);
2808                   if (dshift == s_end)
2809                   {
2810                      dshift = s_start;
2811                      dp--;
2812                   }
2813                   else
2814                      dshift += s_inc;
2815                }
2816                if (sshift == s_end)
2817                {
2818                   sshift = s_start;
2819                   sp--;
2820                }
2821                else
2822                   sshift += s_inc;
2823             }
2824             break;
2825          }
2826          case 4:
2827          {
2828             png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
2829             png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
2830             int sshift, dshift;
2831             int s_start, s_end, s_inc;
2832             png_uint_32 i;
2833             int jstop = png_pass_inc[pass];
2834
2835 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2836             if (transformations & PNG_PACKSWAP)
2837             {
2838                sshift = (int)(((row_info->width + 1) & 0x01) << 2);
2839                dshift = (int)(((final_width + 1) & 0x01) << 2);
2840                s_start = 4;
2841                s_end = 0;
2842                s_inc = -4;
2843             }
2844             else
2845 #endif
2846             {
2847                sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
2848                dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
2849                s_start = 0;
2850                s_end = 4;
2851                s_inc = 4;
2852             }
2853
2854             for (i = 0; i < row_info->width; i++)
2855             {
2856                png_byte v = (png_byte)((*sp >> sshift) & 0xf);
2857                int j;
2858
2859                for (j = 0; j < jstop; j++)
2860                {
2861                   *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
2862                   *dp |= (png_byte)(v << dshift);
2863                   if (dshift == s_end)
2864                   {
2865                      dshift = s_start;
2866                      dp--;
2867                   }
2868                   else
2869                      dshift += s_inc;
2870                }
2871                if (sshift == s_end)
2872                {
2873                   sshift = s_start;
2874                   sp--;
2875                }
2876                else
2877                   sshift += s_inc;
2878             }
2879             break;
2880          }
2881          default:
2882          {
2883             png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
2884             png_bytep sp = row + (png_size_t)(row_info->width - 1)
2885                 * pixel_bytes;
2886             png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
2887
2888             int jstop = png_pass_inc[pass];
2889             png_uint_32 i;
2890
2891             for (i = 0; i < row_info->width; i++)
2892             {
2893                png_byte v[8];
2894                int j;
2895
2896                png_memcpy(v, sp, pixel_bytes);
2897                for (j = 0; j < jstop; j++)
2898                {
2899                   png_memcpy(dp, v, pixel_bytes);
2900                   dp -= pixel_bytes;
2901                }
2902                sp -= pixel_bytes;
2903             }
2904             break;
2905          }
2906       }
2907       row_info->width = final_width;
2908       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
2909    }
2910 #ifndef PNG_READ_PACKSWAP_SUPPORTED
2911    transformations = transformations; /* Silence compiler warning */
2912 #endif
2913 }
2914 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2915
2916 void /* PRIVATE */
2917 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
2918    png_bytep prev_row, int filter)
2919 {
2920    png_debug(1, "in png_read_filter_row");
2921    png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter);
2922    switch (filter)
2923    {
2924       case PNG_FILTER_VALUE_NONE:
2925          break;
2926       case PNG_FILTER_VALUE_SUB:
2927       {
2928          png_uint_32 i;
2929          png_uint_32 istop = row_info->rowbytes;
2930          png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2931          png_bytep rp = row + bpp;
2932          png_bytep lp = row;
2933
2934          for (i = bpp; i < istop; i++)
2935          {
2936             *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
2937             rp++;
2938          }
2939          break;
2940       }
2941       case PNG_FILTER_VALUE_UP:
2942       {
2943          png_uint_32 i;
2944          png_uint_32 istop = row_info->rowbytes;
2945          png_bytep rp = row;
2946          png_bytep pp = prev_row;
2947
2948          for (i = 0; i < istop; i++)
2949          {
2950             *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2951             rp++;
2952          }
2953          break;
2954       }
2955       case PNG_FILTER_VALUE_AVG:
2956       {
2957          png_uint_32 i;
2958          png_bytep rp = row;
2959          png_bytep pp = prev_row;
2960          png_bytep lp = row;
2961          png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2962          png_uint_32 istop = row_info->rowbytes - bpp;
2963
2964          for (i = 0; i < bpp; i++)
2965          {
2966             *rp = (png_byte)(((int)(*rp) +
2967                ((int)(*pp++) / 2 )) & 0xff);
2968             rp++;
2969          }
2970
2971          for (i = 0; i < istop; i++)
2972          {
2973             *rp = (png_byte)(((int)(*rp) +
2974                (int)(*pp++ + *lp++) / 2 ) & 0xff);
2975             rp++;
2976          }
2977          break;
2978       }
2979       case PNG_FILTER_VALUE_PAETH:
2980       {
2981          png_uint_32 i;
2982          png_bytep rp = row;
2983          png_bytep pp = prev_row;
2984          png_bytep lp = row;
2985          png_bytep cp = prev_row;
2986          png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2987          png_uint_32 istop=row_info->rowbytes - bpp;
2988
2989          for (i = 0; i < bpp; i++)
2990          {
2991             *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2992             rp++;
2993          }
2994
2995          for (i = 0; i < istop; i++)   /* Use leftover rp,pp */
2996          {
2997             int a, b, c, pa, pb, pc, p;
2998
2999             a = *lp++;
3000             b = *pp++;
3001             c = *cp++;
3002
3003             p = b - c;
3004             pc = a - c;
3005
3006 #ifdef PNG_USE_ABS
3007             pa = abs(p);
3008             pb = abs(pc);
3009             pc = abs(p + pc);
3010 #else
3011             pa = p < 0 ? -p : p;
3012             pb = pc < 0 ? -pc : pc;
3013             pc = (p + pc) < 0 ? -(p + pc) : p + pc;
3014 #endif
3015
3016             /*
3017                if (pa <= pb && pa <= pc)
3018                   p = a;
3019                else if (pb <= pc)
3020                   p = b;
3021                else
3022                   p = c;
3023              */
3024
3025             p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
3026
3027             *rp = (png_byte)(((int)(*rp) + p) & 0xff);
3028             rp++;
3029          }
3030          break;
3031       }
3032       default:
3033          png_warning(png_ptr, "Ignoring bad adaptive filter type");
3034          *row = 0;
3035          break;
3036    }
3037 }
3038
3039 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
3040 void /* PRIVATE */
3041 png_read_finish_row(png_structp png_ptr)
3042 {
3043 #ifdef PNG_READ_INTERLACING_SUPPORTED
3044    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3045
3046    /* Start of interlace block */
3047    PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3048
3049    /* Offset to next interlace block */
3050    PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3051
3052    /* Start of interlace block in the y direction */
3053    PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3054
3055    /* Offset to next interlace block in the y direction */
3056    PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3057 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3058
3059    png_debug(1, "in png_read_finish_row");
3060    png_ptr->row_number++;
3061    if (png_ptr->row_number < png_ptr->num_rows)
3062       return;
3063
3064 #ifdef PNG_READ_INTERLACING_SUPPORTED
3065    if (png_ptr->interlaced)
3066    {
3067       png_ptr->row_number = 0;
3068       png_memset(png_ptr->prev_row, 0,
3069          png_ptr->rowbytes + 1);
3070       do
3071       {
3072          png_ptr->pass++;
3073          if (png_ptr->pass >= 7)
3074             break;
3075          png_ptr->iwidth = (png_ptr->width +
3076             png_pass_inc[png_ptr->pass] - 1 -
3077             png_pass_start[png_ptr->pass]) /
3078             png_pass_inc[png_ptr->pass];
3079
3080          if (!(png_ptr->transformations & PNG_INTERLACE))
3081          {
3082             png_ptr->num_rows = (png_ptr->height +
3083                png_pass_yinc[png_ptr->pass] - 1 -
3084                png_pass_ystart[png_ptr->pass]) /
3085                png_pass_yinc[png_ptr->pass];
3086             if (!(png_ptr->num_rows))
3087                continue;
3088          }
3089          else  /* if (png_ptr->transformations & PNG_INTERLACE) */
3090             break;
3091       } while (png_ptr->iwidth == 0);
3092
3093       if (png_ptr->pass < 7)
3094          return;
3095    }
3096 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3097
3098    if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
3099    {
3100       PNG_IDAT;
3101       char extra;
3102       int ret;
3103
3104       png_ptr->zstream.next_out = (Byte *)&extra;
3105       png_ptr->zstream.avail_out = (uInt)1;
3106       for (;;)
3107       {
3108          if (!(png_ptr->zstream.avail_in))
3109          {
3110             while (!png_ptr->idat_size)
3111             {
3112                png_byte chunk_length[4];
3113
3114                png_crc_finish(png_ptr, 0);
3115
3116                png_read_data(png_ptr, chunk_length, 4);
3117                png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
3118                png_reset_crc(png_ptr);
3119                png_crc_read(png_ptr, png_ptr->chunk_name, 4);
3120                if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
3121                   png_error(png_ptr, "Not enough image data");
3122
3123             }
3124             png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
3125             png_ptr->zstream.next_in = png_ptr->zbuf;
3126             if (png_ptr->zbuf_size > png_ptr->idat_size)
3127                png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
3128             png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
3129             png_ptr->idat_size -= png_ptr->zstream.avail_in;
3130          }
3131          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
3132          if (ret == Z_STREAM_END)
3133          {
3134             if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
3135                png_ptr->idat_size)
3136                png_warning(png_ptr, "Extra compressed data");
3137             png_ptr->mode |= PNG_AFTER_IDAT;
3138             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
3139             break;
3140          }
3141          if (ret != Z_OK)
3142             png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
3143                       "Decompression Error");
3144
3145          if (!(png_ptr->zstream.avail_out))
3146          {
3147             png_warning(png_ptr, "Extra compressed data");
3148             png_ptr->mode |= PNG_AFTER_IDAT;
3149             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
3150             break;
3151          }
3152
3153       }
3154       png_ptr->zstream.avail_out = 0;
3155    }
3156
3157    if (png_ptr->idat_size || png_ptr->zstream.avail_in)
3158       png_warning(png_ptr, "Extra compression data");
3159
3160    inflateReset(&png_ptr->zstream);
3161
3162    png_ptr->mode |= PNG_AFTER_IDAT;
3163 }
3164 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
3165
3166 void /* PRIVATE */
3167 png_read_start_row(png_structp png_ptr)
3168 {
3169 #ifdef PNG_READ_INTERLACING_SUPPORTED
3170    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3171
3172    /* Start of interlace block */
3173    PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3174
3175    /* Offset to next interlace block */
3176    PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3177
3178    /* Start of interlace block in the y direction */
3179    PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3180
3181    /* Offset to next interlace block in the y direction */
3182    PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3183 #endif
3184
3185    int max_pixel_depth;
3186    png_size_t row_bytes;
3187
3188    png_debug(1, "in png_read_start_row");
3189    png_ptr->zstream.avail_in = 0;
3190    png_init_read_transformations(png_ptr);
3191 #ifdef PNG_READ_INTERLACING_SUPPORTED
3192    if (png_ptr->interlaced)
3193    {
3194       if (!(png_ptr->transformations & PNG_INTERLACE))
3195          png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
3196             png_pass_ystart[0]) / png_pass_yinc[0];
3197       else
3198          png_ptr->num_rows = png_ptr->height;
3199
3200       png_ptr->iwidth = (png_ptr->width +
3201          png_pass_inc[png_ptr->pass] - 1 -
3202          png_pass_start[png_ptr->pass]) /
3203          png_pass_inc[png_ptr->pass];
3204    }
3205    else
3206 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3207    {
3208       png_ptr->num_rows = png_ptr->height;
3209       png_ptr->iwidth = png_ptr->width;
3210    }
3211    max_pixel_depth = png_ptr->pixel_depth;
3212
3213 #ifdef PNG_READ_PACK_SUPPORTED
3214    if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
3215       max_pixel_depth = 8;
3216 #endif
3217
3218 #ifdef PNG_READ_EXPAND_SUPPORTED
3219    if (png_ptr->transformations & PNG_EXPAND)
3220    {
3221       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3222       {
3223          if (png_ptr->num_trans)
3224             max_pixel_depth = 32;
3225          else
3226             max_pixel_depth = 24;
3227       }
3228       else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3229       {
3230          if (max_pixel_depth < 8)
3231             max_pixel_depth = 8;
3232          if (png_ptr->num_trans)
3233             max_pixel_depth *= 2;
3234       }
3235       else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3236       {
3237          if (png_ptr->num_trans)
3238          {
3239             max_pixel_depth *= 4;
3240             max_pixel_depth /= 3;
3241          }
3242       }
3243    }
3244 #endif
3245
3246 #ifdef PNG_READ_FILLER_SUPPORTED
3247    if (png_ptr->transformations & (PNG_FILLER))
3248    {
3249       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3250          max_pixel_depth = 32;
3251       else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3252       {
3253          if (max_pixel_depth <= 8)
3254             max_pixel_depth = 16;
3255          else
3256             max_pixel_depth = 32;
3257       }
3258       else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3259       {
3260          if (max_pixel_depth <= 32)
3261             max_pixel_depth = 32;
3262          else
3263             max_pixel_depth = 64;
3264       }
3265    }
3266 #endif
3267
3268 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
3269    if (png_ptr->transformations & PNG_GRAY_TO_RGB)
3270    {
3271       if (
3272 #ifdef PNG_READ_EXPAND_SUPPORTED
3273         (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
3274 #endif
3275 #ifdef PNG_READ_FILLER_SUPPORTED
3276         (png_ptr->transformations & (PNG_FILLER)) ||
3277 #endif
3278         png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3279       {
3280          if (max_pixel_depth <= 16)
3281             max_pixel_depth = 32;
3282          else
3283             max_pixel_depth = 64;
3284       }
3285       else
3286       {
3287          if (max_pixel_depth <= 8)
3288            {
3289              if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3290                max_pixel_depth = 32;
3291              else
3292                max_pixel_depth = 24;
3293            }
3294          else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3295             max_pixel_depth = 64;
3296          else
3297             max_pixel_depth = 48;
3298       }
3299    }
3300 #endif
3301
3302 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3303 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3304    if (png_ptr->transformations & PNG_USER_TRANSFORM)
3305      {
3306        int user_pixel_depth = png_ptr->user_transform_depth*
3307          png_ptr->user_transform_channels;
3308        if (user_pixel_depth > max_pixel_depth)
3309          max_pixel_depth=user_pixel_depth;
3310      }
3311 #endif
3312
3313    /* Align the width on the next larger 8 pixels.  Mainly used
3314     * for interlacing
3315     */
3316    row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
3317    /* Calculate the maximum bytes needed, adding a byte and a pixel
3318     * for safety's sake
3319     */
3320    row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
3321       1 + ((max_pixel_depth + 7) >> 3);
3322 #ifdef PNG_MAX_MALLOC_64K
3323    if (row_bytes > (png_uint_32)65536L)
3324       png_error(png_ptr, "This image requires a row greater than 64KB");
3325 #endif
3326
3327    if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
3328    {
3329      png_free(png_ptr, png_ptr->big_row_buf);
3330      if (png_ptr->interlaced)
3331         png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
3332             row_bytes + 48);
3333      else
3334         png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr,
3335             row_bytes + 48);
3336      png_ptr->old_big_row_buf_size = row_bytes + 48;
3337
3338 #ifdef PNG_ALIGNED_MEMORY_SUPPORTED
3339      /* Use 16-byte aligned memory for row_buf with at least 16 bytes
3340       * of padding before and after row_buf.
3341       */
3342      png_ptr->row_buf = png_ptr->big_row_buf + 32
3343          - (((png_alloc_size_t)&(png_ptr->big_row_buf[0]) + 15) % 16);
3344      png_ptr->old_big_row_buf_size = row_bytes + 48;
3345 #else
3346      /* Use 32 bytes of padding before and 16 bytes after row_buf. */
3347      png_ptr->row_buf = png_ptr->big_row_buf + 32;
3348 #endif
3349      png_ptr->old_big_row_buf_size = row_bytes + 48;
3350    }
3351
3352 #ifdef PNG_MAX_MALLOC_64K
3353    if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
3354       png_error(png_ptr, "This image requires a row greater than 64KB");
3355 #endif
3356    if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1))
3357       png_error(png_ptr, "Row has too many bytes to allocate in memory");
3358
3359    if (png_ptr->rowbytes + 1 > png_ptr->old_prev_row_size)
3360    {
3361       png_free(png_ptr, png_ptr->prev_row);
3362       png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
3363         png_ptr->rowbytes + 1));
3364       png_ptr->old_prev_row_size = png_ptr->rowbytes + 1;
3365    }
3366
3367    png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
3368
3369    png_debug1(3, "width = %lu,", png_ptr->width);
3370    png_debug1(3, "height = %lu,", png_ptr->height);
3371    png_debug1(3, "iwidth = %lu,", png_ptr->iwidth);
3372    png_debug1(3, "num_rows = %lu,", png_ptr->num_rows);
3373    png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes);
3374    png_debug1(3, "irowbytes = %lu",
3375        PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
3376
3377    png_ptr->flags |= PNG_FLAG_ROW_INIT;
3378 }
3379 #endif /* PNG_READ_SUPPORTED */