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