source: bootcd/isolinux/syslinux-6.03/com32/lib/libpng/pngrutil.c @ dd1be7c

Last change on this file since dd1be7c was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

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