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