source: trunk/third/libpng/pngrutil.c @ 18902

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