Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

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