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

Revision 18166, 87.9 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18165, which included commits to RCS files with non-trunk default branches.
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
1053   profile_length = data_length - prefix_length;
1054
1055   if ( prefix_length > data_length || profile_length < 4)
1056   {
1057      png_free(png_ptr, chunkdata);
1058      png_warning(png_ptr, "Profile size field missing from iCCP chunk");
1059      return;
1060   }
1061
1062   /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1063   pC = (png_bytep)(chunkdata+prefix_length);
1064   profile_size = ((*(pC  ))<<24) |
1065                  ((*(pC+1))<<16) |
1066                  ((*(pC+2))<< 8) |
1067                  ((*(pC+3))    );
1068
1069   if(profile_size < profile_length)
1070      profile_length = profile_size;
1071
1072   if(profile_size > profile_length)
1073   {
1074      png_free(png_ptr, chunkdata);
1075      png_warning(png_ptr, "Ignoring truncated iCCP profile.\n");
1076      return;
1077   }
1078
1079   png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
1080                chunkdata + prefix_length, profile_length);
1081   png_free(png_ptr, chunkdata);
1082}
1083#endif /* PNG_READ_iCCP_SUPPORTED */
1084
1085#if defined(PNG_READ_sPLT_SUPPORTED)
1086void /* PRIVATE */
1087png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1088/* Note: this does not properly handle chunks that are > 64K under DOS */
1089{
1090   png_bytep chunkdata;
1091   png_bytep entry_start;
1092   png_sPLT_t new_palette;
1093#ifdef PNG_NO_POINTER_INDEXING
1094   png_sPLT_entryp pp;
1095#endif
1096   int data_length, entry_size, i;
1097   png_uint_32 skip = 0;
1098   png_size_t slength;
1099
1100   png_debug(1, "in png_handle_sPLT\n");
1101
1102   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1103      png_error(png_ptr, "Missing IHDR before sPLT");
1104   else if (png_ptr->mode & PNG_HAVE_IDAT)
1105   {
1106      png_warning(png_ptr, "Invalid sPLT after IDAT");
1107      png_crc_finish(png_ptr, length);
1108      return;
1109   }
1110
1111#ifdef PNG_MAX_MALLOC_64K
1112   if (length > (png_uint_32)65535L)
1113   {
1114      png_warning(png_ptr, "sPLT chunk too large to fit in memory");
1115      skip = length - (png_uint_32)65535L;
1116      length = (png_uint_32)65535L;
1117   }
1118#endif
1119
1120   chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
1121   slength = (png_size_t)length;
1122   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
1123
1124   if (png_crc_finish(png_ptr, skip))
1125   {
1126      png_free(png_ptr, chunkdata);
1127      return;
1128   }
1129
1130   chunkdata[slength] = 0x00;
1131
1132   for (entry_start = chunkdata; *entry_start; entry_start++)
1133      /* empty loop to find end of name */ ;
1134   ++entry_start;
1135
1136   /* a sample depth should follow the separator, and we should be on it  */
1137   if (entry_start > chunkdata + slength)
1138   {
1139      png_free(png_ptr, chunkdata);
1140      png_warning(png_ptr, "malformed sPLT chunk");
1141      return;
1142   }
1143
1144   new_palette.depth = *entry_start++;
1145   entry_size = (new_palette.depth == 8 ? 6 : 10);
1146   data_length = (slength - (entry_start - chunkdata));
1147
1148   /* integrity-check the data length */
1149   if (data_length % entry_size)
1150   {
1151      png_free(png_ptr, chunkdata);
1152      png_warning(png_ptr, "sPLT chunk has bad length");
1153      return;
1154   }
1155
1156   new_palette.nentries = data_length / entry_size;
1157   new_palette.entries = (png_sPLT_entryp)png_malloc(
1158       png_ptr, new_palette.nentries * sizeof(png_sPLT_entry));
1159
1160#ifndef PNG_NO_POINTER_INDEXING
1161   for (i = 0; i < new_palette.nentries; i++)
1162   {
1163      png_sPLT_entryp pp = new_palette.entries + i;
1164
1165      if (new_palette.depth == 8)
1166      {
1167          pp->red = *entry_start++;
1168          pp->green = *entry_start++;
1169          pp->blue = *entry_start++;
1170          pp->alpha = *entry_start++;
1171      }
1172      else
1173      {
1174          pp->red   = png_get_uint_16(entry_start); entry_start += 2;
1175          pp->green = png_get_uint_16(entry_start); entry_start += 2;
1176          pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
1177          pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1178      }
1179      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1180   }
1181#else
1182   pp = new_palette.entries;
1183   for (i = 0; i < new_palette.nentries; i++)
1184   {
1185
1186      if (new_palette.depth == 8)
1187      {
1188          pp[i].red   = *entry_start++;
1189          pp[i].green = *entry_start++;
1190          pp[i].blue  = *entry_start++;
1191          pp[i].alpha = *entry_start++;
1192      }
1193      else
1194      {
1195          pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
1196          pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
1197          pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
1198          pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
1199      }
1200      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1201   }
1202#endif
1203
1204   /* discard all chunk data except the name and stash that */
1205   new_palette.name = (png_charp)chunkdata;
1206
1207   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1208
1209   png_free(png_ptr, chunkdata);
1210   png_free(png_ptr, new_palette.entries);
1211}
1212#endif /* PNG_READ_sPLT_SUPPORTED */
1213
1214#if defined(PNG_READ_tRNS_SUPPORTED)
1215void /* PRIVATE */
1216png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1217{
1218   png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1219
1220   png_debug(1, "in png_handle_tRNS\n");
1221
1222   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1223      png_error(png_ptr, "Missing IHDR before tRNS");
1224   else if (png_ptr->mode & PNG_HAVE_IDAT)
1225   {
1226      png_warning(png_ptr, "Invalid tRNS after IDAT");
1227      png_crc_finish(png_ptr, length);
1228      return;
1229   }
1230   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
1231   {
1232      png_warning(png_ptr, "Duplicate tRNS chunk");
1233      png_crc_finish(png_ptr, length);
1234      return;
1235   }
1236
1237   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1238   {
1239      if (!(png_ptr->mode & PNG_HAVE_PLTE))
1240      {
1241         /* Should be an error, but we can cope with it */
1242         png_warning(png_ptr, "Missing PLTE before tRNS");
1243      }
1244      else if (length > (png_uint_32)png_ptr->num_palette)
1245      {
1246         png_warning(png_ptr, "Incorrect tRNS chunk length");
1247         png_crc_finish(png_ptr, length);
1248         return;
1249      }
1250      if (length == 0)
1251      {
1252         png_warning(png_ptr, "Zero length tRNS chunk");
1253         png_crc_finish(png_ptr, length);
1254         return;
1255      }
1256
1257      png_crc_read(png_ptr, readbuf, (png_size_t)length);
1258      png_ptr->num_trans = (png_uint_16)length;
1259   }
1260   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
1261   {
1262      png_byte buf[6];
1263
1264      if (length != 6)
1265      {
1266         png_warning(png_ptr, "Incorrect tRNS chunk length");
1267         png_crc_finish(png_ptr, length);
1268         return;
1269      }
1270
1271      png_crc_read(png_ptr, buf, (png_size_t)length);
1272      png_ptr->num_trans = 1;
1273      png_ptr->trans_values.red = png_get_uint_16(buf);
1274      png_ptr->trans_values.green = png_get_uint_16(buf + 2);
1275      png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
1276   }
1277   else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1278   {
1279      png_byte buf[6];
1280
1281      if (length != 2)
1282      {
1283         png_warning(png_ptr, "Incorrect tRNS chunk length");
1284         png_crc_finish(png_ptr, length);
1285         return;
1286      }
1287
1288      png_crc_read(png_ptr, buf, 2);
1289      png_ptr->num_trans = 1;
1290      png_ptr->trans_values.gray = png_get_uint_16(buf);
1291   }
1292   else
1293   {
1294      png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
1295      png_crc_finish(png_ptr, length);
1296      return;
1297   }
1298
1299   if (png_crc_finish(png_ptr, 0))
1300      return;
1301
1302   png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1303      &(png_ptr->trans_values));
1304}
1305#endif
1306
1307#if defined(PNG_READ_bKGD_SUPPORTED)
1308void /* PRIVATE */
1309png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1310{
1311   png_size_t truelen;
1312   png_byte buf[6];
1313
1314   png_debug(1, "in png_handle_bKGD\n");
1315
1316   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1317      png_error(png_ptr, "Missing IHDR before bKGD");
1318   else if (png_ptr->mode & PNG_HAVE_IDAT)
1319   {
1320      png_warning(png_ptr, "Invalid bKGD after IDAT");
1321      png_crc_finish(png_ptr, length);
1322      return;
1323   }
1324   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
1325            !(png_ptr->mode & PNG_HAVE_PLTE))
1326   {
1327      png_warning(png_ptr, "Missing PLTE before bKGD");
1328      png_crc_finish(png_ptr, length);
1329      return;
1330   }
1331   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
1332   {
1333      png_warning(png_ptr, "Duplicate bKGD chunk");
1334      png_crc_finish(png_ptr, length);
1335      return;
1336   }
1337
1338   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1339      truelen = 1;
1340   else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
1341      truelen = 6;
1342   else
1343      truelen = 2;
1344
1345   if (length != truelen)
1346   {
1347      png_warning(png_ptr, "Incorrect bKGD chunk length");
1348      png_crc_finish(png_ptr, length);
1349      return;
1350   }
1351
1352   png_crc_read(png_ptr, buf, truelen);
1353   if (png_crc_finish(png_ptr, 0))
1354      return;
1355
1356   /* We convert the index value into RGB components so that we can allow
1357    * arbitrary RGB values for background when we have transparency, and
1358    * so it is easy to determine the RGB values of the background color
1359    * from the info_ptr struct. */
1360   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1361   {
1362      png_ptr->background.index = buf[0];
1363      if(info_ptr->num_palette)
1364      {
1365          if(buf[0] > info_ptr->num_palette)
1366          {
1367             png_warning(png_ptr, "Incorrect bKGD chunk index value");
1368             return;
1369          }
1370          png_ptr->background.red =
1371             (png_uint_16)png_ptr->palette[buf[0]].red;
1372          png_ptr->background.green =
1373             (png_uint_16)png_ptr->palette[buf[0]].green;
1374          png_ptr->background.blue =
1375             (png_uint_16)png_ptr->palette[buf[0]].blue;
1376      }
1377   }
1378   else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
1379   {
1380      png_ptr->background.red =
1381      png_ptr->background.green =
1382      png_ptr->background.blue =
1383      png_ptr->background.gray = png_get_uint_16(buf);
1384   }
1385   else
1386   {
1387      png_ptr->background.red = png_get_uint_16(buf);
1388      png_ptr->background.green = png_get_uint_16(buf + 2);
1389      png_ptr->background.blue = png_get_uint_16(buf + 4);
1390   }
1391
1392   png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
1393}
1394#endif
1395
1396#if defined(PNG_READ_hIST_SUPPORTED)
1397void /* PRIVATE */
1398png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1399{
1400   int num, i;
1401   png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
1402
1403   png_debug(1, "in png_handle_hIST\n");
1404
1405   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1406      png_error(png_ptr, "Missing IHDR before hIST");
1407   else if (png_ptr->mode & PNG_HAVE_IDAT)
1408   {
1409      png_warning(png_ptr, "Invalid hIST after IDAT");
1410      png_crc_finish(png_ptr, length);
1411      return;
1412   }
1413   else if (!(png_ptr->mode & PNG_HAVE_PLTE))
1414   {
1415      png_warning(png_ptr, "Missing PLTE before hIST");
1416      png_crc_finish(png_ptr, length);
1417      return;
1418   }
1419   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
1420   {
1421      png_warning(png_ptr, "Duplicate hIST chunk");
1422      png_crc_finish(png_ptr, length);
1423      return;
1424   }
1425
1426   num = (int)length / 2 ;
1427   if (num != png_ptr->num_palette)
1428   {
1429      png_warning(png_ptr, "Incorrect hIST chunk length");
1430      png_crc_finish(png_ptr, length);
1431      return;
1432   }
1433
1434   for (i = 0; i < num; i++)
1435   {
1436      png_byte buf[2];
1437
1438      png_crc_read(png_ptr, buf, 2);
1439      readbuf[i] = png_get_uint_16(buf);
1440   }
1441
1442   if (png_crc_finish(png_ptr, 0))
1443      return;
1444
1445   png_set_hIST(png_ptr, info_ptr, readbuf);
1446}
1447#endif
1448
1449#if defined(PNG_READ_pHYs_SUPPORTED)
1450void /* PRIVATE */
1451png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1452{
1453   png_byte buf[9];
1454   png_uint_32 res_x, res_y;
1455   int unit_type;
1456
1457   png_debug(1, "in png_handle_pHYs\n");
1458
1459   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1460      png_error(png_ptr, "Missing IHDR before pHYs");
1461   else if (png_ptr->mode & PNG_HAVE_IDAT)
1462   {
1463      png_warning(png_ptr, "Invalid pHYs after IDAT");
1464      png_crc_finish(png_ptr, length);
1465      return;
1466   }
1467   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
1468   {
1469      png_warning(png_ptr, "Duplicate pHYs chunk");
1470      png_crc_finish(png_ptr, length);
1471      return;
1472   }
1473
1474   if (length != 9)
1475   {
1476      png_warning(png_ptr, "Incorrect pHYs chunk length");
1477      png_crc_finish(png_ptr, length);
1478      return;
1479   }
1480
1481   png_crc_read(png_ptr, buf, 9);
1482   if (png_crc_finish(png_ptr, 0))
1483      return;
1484
1485   res_x = png_get_uint_32(buf);
1486   res_y = png_get_uint_32(buf + 4);
1487   unit_type = buf[8];
1488   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
1489}
1490#endif
1491
1492#if defined(PNG_READ_oFFs_SUPPORTED)
1493void /* PRIVATE */
1494png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1495{
1496   png_byte buf[9];
1497   png_int_32 offset_x, offset_y;
1498   int unit_type;
1499
1500   png_debug(1, "in png_handle_oFFs\n");
1501
1502   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1503      png_error(png_ptr, "Missing IHDR before oFFs");
1504   else if (png_ptr->mode & PNG_HAVE_IDAT)
1505   {
1506      png_warning(png_ptr, "Invalid oFFs after IDAT");
1507      png_crc_finish(png_ptr, length);
1508      return;
1509   }
1510   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
1511   {
1512      png_warning(png_ptr, "Duplicate oFFs chunk");
1513      png_crc_finish(png_ptr, length);
1514      return;
1515   }
1516
1517   if (length != 9)
1518   {
1519      png_warning(png_ptr, "Incorrect oFFs chunk length");
1520      png_crc_finish(png_ptr, length);
1521      return;
1522   }
1523
1524   png_crc_read(png_ptr, buf, 9);
1525   if (png_crc_finish(png_ptr, 0))
1526      return;
1527
1528   offset_x = png_get_int_32(buf);
1529   offset_y = png_get_int_32(buf + 4);
1530   unit_type = buf[8];
1531   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
1532}
1533#endif
1534
1535#if defined(PNG_READ_pCAL_SUPPORTED)
1536/* read the pCAL chunk (described in the PNG Extensions document) */
1537void /* PRIVATE */
1538png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1539{
1540   png_charp purpose;
1541   png_int_32 X0, X1;
1542   png_byte type, nparams;
1543   png_charp buf, units, endptr;
1544   png_charpp params;
1545   png_size_t slength;
1546   int i;
1547
1548   png_debug(1, "in png_handle_pCAL\n");
1549
1550   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1551      png_error(png_ptr, "Missing IHDR before pCAL");
1552   else if (png_ptr->mode & PNG_HAVE_IDAT)
1553   {
1554      png_warning(png_ptr, "Invalid pCAL after IDAT");
1555      png_crc_finish(png_ptr, length);
1556      return;
1557   }
1558   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
1559   {
1560      png_warning(png_ptr, "Duplicate pCAL chunk");
1561      png_crc_finish(png_ptr, length);
1562      return;
1563   }
1564
1565   png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
1566      length + 1);
1567   purpose = (png_charp)png_malloc_warn(png_ptr, length + 1);
1568   if (purpose == NULL)
1569     {
1570       png_warning(png_ptr, "No memory for pCAL purpose.");
1571       return;
1572     }
1573   slength = (png_size_t)length;
1574   png_crc_read(png_ptr, (png_bytep)purpose, slength);
1575
1576   if (png_crc_finish(png_ptr, 0))
1577   {
1578      png_free(png_ptr, purpose);
1579      return;
1580   }
1581
1582   purpose[slength] = 0x00; /* null terminate the last string */
1583
1584   png_debug(3, "Finding end of pCAL purpose string\n");
1585   for (buf = purpose; *buf; buf++)
1586      /* empty loop */ ;
1587
1588   endptr = purpose + slength;
1589
1590   /* We need to have at least 12 bytes after the purpose string
1591      in order to get the parameter information. */
1592   if (endptr <= buf + 12)
1593   {
1594      png_warning(png_ptr, "Invalid pCAL data");
1595      png_free(png_ptr, purpose);
1596      return;
1597   }
1598
1599   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
1600   X0 = png_get_int_32((png_bytep)buf+1);
1601   X1 = png_get_int_32((png_bytep)buf+5);
1602   type = buf[9];
1603   nparams = buf[10];
1604   units = buf + 11;
1605
1606   png_debug(3, "Checking pCAL equation type and number of parameters\n");
1607   /* Check that we have the right number of parameters for known
1608      equation types. */
1609   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
1610       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
1611       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
1612       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
1613   {
1614      png_warning(png_ptr, "Invalid pCAL parameters for equation type");
1615      png_free(png_ptr, purpose);
1616      return;
1617   }
1618   else if (type >= PNG_EQUATION_LAST)
1619   {
1620      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1621   }
1622
1623   for (buf = units; *buf; buf++)
1624      /* Empty loop to move past the units string. */ ;
1625
1626   png_debug(3, "Allocating pCAL parameters array\n");
1627   params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams
1628      *sizeof(png_charp))) ;
1629   if (params == NULL)
1630     {
1631       png_free(png_ptr, purpose);
1632       png_warning(png_ptr, "No memory for pCAL params.");
1633       return;
1634     }
1635
1636   /* Get pointers to the start of each parameter string. */
1637   for (i = 0; i < (int)nparams; i++)
1638   {
1639      buf++; /* Skip the null string terminator from previous parameter. */
1640
1641      png_debug1(3, "Reading pCAL parameter %d\n", i);
1642      for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++)
1643         /* Empty loop to move past each parameter string */ ;
1644
1645      /* Make sure we haven't run out of data yet */
1646      if (buf > endptr)
1647      {
1648         png_warning(png_ptr, "Invalid pCAL data");
1649         png_free(png_ptr, purpose);
1650         png_free(png_ptr, params);
1651         return;
1652      }
1653   }
1654
1655   png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
1656      units, params);
1657
1658   png_free(png_ptr, purpose);
1659   png_free(png_ptr, params);
1660}
1661#endif
1662
1663#if defined(PNG_READ_sCAL_SUPPORTED)
1664/* read the sCAL chunk */
1665void /* PRIVATE */
1666png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1667{
1668   png_charp buffer, ep;
1669#ifdef PNG_FLOATING_POINT_SUPPORTED
1670   double width, height;
1671   png_charp vp;
1672#else
1673#ifdef PNG_FIXED_POINT_SUPPORTED
1674   png_charp swidth, sheight;
1675#endif
1676#endif
1677   png_size_t slength;
1678
1679   png_debug(1, "in png_handle_sCAL\n");
1680
1681   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1682      png_error(png_ptr, "Missing IHDR before sCAL");
1683   else if (png_ptr->mode & PNG_HAVE_IDAT)
1684   {
1685      png_warning(png_ptr, "Invalid sCAL after IDAT");
1686      png_crc_finish(png_ptr, length);
1687      return;
1688   }
1689   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
1690   {
1691      png_warning(png_ptr, "Duplicate sCAL chunk");
1692      png_crc_finish(png_ptr, length);
1693      return;
1694   }
1695
1696   png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
1697      length + 1);
1698   buffer = (png_charp)png_malloc_warn(png_ptr, length + 1);
1699   if (buffer == NULL)
1700     {
1701       png_warning(png_ptr, "Out of memory while processing sCAL chunk");
1702       return;
1703     }
1704   slength = (png_size_t)length;
1705   png_crc_read(png_ptr, (png_bytep)buffer, slength);
1706
1707   if (png_crc_finish(png_ptr, 0))
1708   {
1709      png_free(png_ptr, buffer);
1710      return;
1711   }
1712
1713   buffer[slength] = 0x00; /* null terminate the last string */
1714
1715   ep = buffer + 1;        /* skip unit byte */
1716
1717#ifdef PNG_FLOATING_POINT_SUPPORTED
1718   width = strtod(ep, &vp);
1719   if (*vp)
1720   {
1721       png_warning(png_ptr, "malformed width string in sCAL chunk");
1722       return;
1723   }
1724#else
1725#ifdef PNG_FIXED_POINT_SUPPORTED
1726   swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1727   if (swidth == NULL)
1728     {
1729       png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
1730       return;
1731     }
1732   png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
1733#endif
1734#endif
1735
1736   for (ep = buffer; *ep; ep++)
1737      /* empty loop */ ;
1738   ep++;
1739
1740#ifdef PNG_FLOATING_POINT_SUPPORTED
1741   height = strtod(ep, &vp);
1742   if (*vp)
1743   {
1744       png_warning(png_ptr, "malformed height string in sCAL chunk");
1745       return;
1746   }
1747#else
1748#ifdef PNG_FIXED_POINT_SUPPORTED
1749   sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1750   if (swidth == NULL)
1751     {
1752       png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
1753       return;
1754     }
1755   png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
1756#endif
1757#endif
1758
1759   if (buffer + slength < ep
1760#ifdef PNG_FLOATING_POINT_SUPPORTED
1761      || width <= 0. || height <= 0.
1762#endif
1763      )
1764   {
1765      png_warning(png_ptr, "Invalid sCAL data");
1766      png_free(png_ptr, buffer);
1767#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1768      png_free(png_ptr, swidth);
1769      png_free(png_ptr, sheight);
1770#endif
1771      return;
1772   }
1773
1774
1775#ifdef PNG_FLOATING_POINT_SUPPORTED
1776   png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
1777#else
1778#ifdef PNG_FIXED_POINT_SUPPORTED
1779   png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
1780#endif
1781#endif
1782
1783   png_free(png_ptr, buffer);
1784#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1785   png_free(png_ptr, swidth);
1786   png_free(png_ptr, sheight);
1787#endif
1788}
1789#endif
1790
1791#if defined(PNG_READ_tIME_SUPPORTED)
1792void /* PRIVATE */
1793png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1794{
1795   png_byte buf[7];
1796   png_time mod_time;
1797
1798   png_debug(1, "in png_handle_tIME\n");
1799
1800   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1801      png_error(png_ptr, "Out of place tIME chunk");
1802   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
1803   {
1804      png_warning(png_ptr, "Duplicate tIME chunk");
1805      png_crc_finish(png_ptr, length);
1806      return;
1807   }
1808
1809   if (png_ptr->mode & PNG_HAVE_IDAT)
1810      png_ptr->mode |= PNG_AFTER_IDAT;
1811
1812   if (length != 7)
1813   {
1814      png_warning(png_ptr, "Incorrect tIME chunk length");
1815      png_crc_finish(png_ptr, length);
1816      return;
1817   }
1818
1819   png_crc_read(png_ptr, buf, 7);
1820   if (png_crc_finish(png_ptr, 0))
1821      return;
1822
1823   mod_time.second = buf[6];
1824   mod_time.minute = buf[5];
1825   mod_time.hour = buf[4];
1826   mod_time.day = buf[3];
1827   mod_time.month = buf[2];
1828   mod_time.year = png_get_uint_16(buf);
1829
1830   png_set_tIME(png_ptr, info_ptr, &mod_time);
1831}
1832#endif
1833
1834#if defined(PNG_READ_tEXt_SUPPORTED)
1835/* Note: this does not properly handle chunks that are > 64K under DOS */
1836void /* PRIVATE */
1837png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1838{
1839   png_textp text_ptr;
1840   png_charp key;
1841   png_charp text;
1842   png_uint_32 skip = 0;
1843   png_size_t slength;
1844   int ret;
1845
1846   png_debug(1, "in png_handle_tEXt\n");
1847
1848   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1849      png_error(png_ptr, "Missing IHDR before tEXt");
1850
1851   if (png_ptr->mode & PNG_HAVE_IDAT)
1852      png_ptr->mode |= PNG_AFTER_IDAT;
1853
1854#ifdef PNG_MAX_MALLOC_64K
1855   if (length > (png_uint_32)65535L)
1856   {
1857      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
1858      skip = length - (png_uint_32)65535L;
1859      length = (png_uint_32)65535L;
1860   }
1861#endif
1862
1863   key = (png_charp)png_malloc_warn(png_ptr, length + 1);
1864   if (key == NULL)
1865   {
1866     png_warning(png_ptr, "No memory to process text chunk.");
1867     return;
1868   }
1869   slength = (png_size_t)length;
1870   png_crc_read(png_ptr, (png_bytep)key, slength);
1871
1872   if (png_crc_finish(png_ptr, skip))
1873   {
1874      png_free(png_ptr, key);
1875      return;
1876   }
1877
1878   key[slength] = 0x00;
1879
1880   for (text = key; *text; text++)
1881      /* empty loop to find end of key */ ;
1882
1883   if (text != key + slength)
1884      text++;
1885
1886   text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text));
1887   if (text_ptr == NULL)
1888   {
1889     png_warning(png_ptr, "Not enough memory to process text chunk.");
1890     png_free(png_ptr, key);
1891     return;
1892   }
1893   text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
1894   text_ptr->key = key;
1895#ifdef PNG_iTXt_SUPPORTED
1896   text_ptr->lang = NULL;
1897   text_ptr->lang_key = NULL;
1898   text_ptr->itxt_length = 0;
1899#endif
1900   text_ptr->text = text;
1901   text_ptr->text_length = png_strlen(text);
1902
1903   ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1904
1905   png_free(png_ptr, key);
1906   png_free(png_ptr, text_ptr);
1907   if (ret)
1908     png_warning(png_ptr, "Insufficient memory to process text chunk.");
1909}
1910#endif
1911
1912#if defined(PNG_READ_zTXt_SUPPORTED)
1913/* note: this does not correctly handle chunks that are > 64K under DOS */
1914void /* PRIVATE */
1915png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1916{
1917   png_textp text_ptr;
1918   png_charp chunkdata;
1919   png_charp text;
1920   int comp_type;
1921   int ret;
1922   png_size_t slength, prefix_len, data_len;
1923
1924   png_debug(1, "in png_handle_zTXt\n");
1925   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1926      png_error(png_ptr, "Missing IHDR before zTXt");
1927
1928   if (png_ptr->mode & PNG_HAVE_IDAT)
1929      png_ptr->mode |= PNG_AFTER_IDAT;
1930
1931#ifdef PNG_MAX_MALLOC_64K
1932   /* We will no doubt have problems with chunks even half this size, but
1933      there is no hard and fast rule to tell us where to stop. */
1934   if (length > (png_uint_32)65535L)
1935   {
1936     png_warning(png_ptr,"zTXt chunk too large to fit in memory");
1937     png_crc_finish(png_ptr, length);
1938     return;
1939   }
1940#endif
1941
1942   chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1943   if (chunkdata == NULL)
1944   {
1945     png_warning(png_ptr,"Out of memory processing zTXt chunk.");
1946     return;
1947   }
1948   slength = (png_size_t)length;
1949   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
1950   if (png_crc_finish(png_ptr, 0))
1951   {
1952      png_free(png_ptr, chunkdata);
1953      return;
1954   }
1955
1956   chunkdata[slength] = 0x00;
1957
1958   for (text = chunkdata; *text; text++)
1959      /* empty loop */ ;
1960
1961   /* zTXt must have some text after the chunkdataword */
1962   if (text == chunkdata + slength)
1963   {
1964      comp_type = PNG_TEXT_COMPRESSION_NONE;
1965      png_warning(png_ptr, "Zero length zTXt chunk");
1966   }
1967   else
1968   {
1969       comp_type = *(++text);
1970       if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
1971       {
1972          png_warning(png_ptr, "Unknown compression type in zTXt chunk");
1973          comp_type = PNG_TEXT_COMPRESSION_zTXt;
1974       }
1975       text++;        /* skip the compression_method byte */
1976   }
1977   prefix_len = text - chunkdata;
1978
1979   chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
1980                                    (png_size_t)length, prefix_len, &data_len);
1981
1982   text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text));
1983   if (text_ptr == NULL)
1984   {
1985     png_warning(png_ptr,"Not enough memory to process zTXt chunk.");
1986     png_free(png_ptr, chunkdata);
1987     return;
1988   }
1989   text_ptr->compression = comp_type;
1990   text_ptr->key = chunkdata;
1991#ifdef PNG_iTXt_SUPPORTED
1992   text_ptr->lang = NULL;
1993   text_ptr->lang_key = NULL;
1994   text_ptr->itxt_length = 0;
1995#endif
1996   text_ptr->text = chunkdata + prefix_len;
1997   text_ptr->text_length = data_len;
1998
1999   ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2000
2001   png_free(png_ptr, text_ptr);
2002   png_free(png_ptr, chunkdata);
2003   if (ret)
2004     png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
2005}
2006#endif
2007
2008#if defined(PNG_READ_iTXt_SUPPORTED)
2009/* note: this does not correctly handle chunks that are > 64K under DOS */
2010void /* PRIVATE */
2011png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2012{
2013   png_textp text_ptr;
2014   png_charp chunkdata;
2015   png_charp key, lang, text, lang_key;
2016   int comp_flag;
2017   int comp_type = 0;
2018   int ret;
2019   png_size_t slength, prefix_len, data_len;
2020
2021   png_debug(1, "in png_handle_iTXt\n");
2022
2023   if (!(png_ptr->mode & PNG_HAVE_IHDR))
2024      png_error(png_ptr, "Missing IHDR before iTXt");
2025
2026   if (png_ptr->mode & PNG_HAVE_IDAT)
2027      png_ptr->mode |= PNG_AFTER_IDAT;
2028
2029#ifdef PNG_MAX_MALLOC_64K
2030   /* We will no doubt have problems with chunks even half this size, but
2031      there is no hard and fast rule to tell us where to stop. */
2032   if (length > (png_uint_32)65535L)
2033   {
2034     png_warning(png_ptr,"iTXt chunk too large to fit in memory");
2035     png_crc_finish(png_ptr, length);
2036     return;
2037   }
2038#endif
2039
2040   chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2041   if (chunkdata == NULL)
2042   {
2043     png_warning(png_ptr, "No memory to process iTXt chunk.");
2044     return;
2045   }
2046   slength = (png_size_t)length;
2047   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
2048   if (png_crc_finish(png_ptr, 0))
2049   {
2050      png_free(png_ptr, chunkdata);
2051      return;
2052   }
2053
2054   chunkdata[slength] = 0x00;
2055
2056   for (lang = chunkdata; *lang; lang++)
2057      /* empty loop */ ;
2058   lang++;        /* skip NUL separator */
2059
2060   /* iTXt must have a language tag (possibly empty), two compression bytes,
2061      translated keyword (possibly empty), and possibly some text after the
2062      keyword */
2063
2064   if (lang >= chunkdata + slength)
2065   {
2066      comp_flag = PNG_TEXT_COMPRESSION_NONE;
2067      png_warning(png_ptr, "Zero length iTXt chunk");
2068   }
2069   else
2070   {
2071       comp_flag = *lang++;
2072       comp_type = *lang++;
2073   }
2074
2075   for (lang_key = lang; *lang_key; lang_key++)
2076      /* empty loop */ ;
2077   lang_key++;        /* skip NUL separator */
2078
2079   for (text = lang_key; *text; text++)
2080      /* empty loop */ ;
2081   text++;        /* skip NUL separator */
2082
2083   prefix_len = text - chunkdata;
2084
2085   key=chunkdata;
2086   if (comp_flag)
2087       chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
2088          (size_t)length, prefix_len, &data_len);
2089   else
2090       data_len=png_strlen(chunkdata + prefix_len);
2091   text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text));
2092   if (text_ptr == NULL)
2093   {
2094     png_warning(png_ptr,"Not enough memory to process iTXt chunk.");
2095     png_free(png_ptr, chunkdata);
2096     return;
2097   }
2098   text_ptr->compression = (int)comp_flag + 1;
2099   text_ptr->lang_key = chunkdata+(lang_key-key);
2100   text_ptr->lang = chunkdata+(lang-key);
2101   text_ptr->itxt_length = data_len;
2102   text_ptr->text_length = 0;
2103   text_ptr->key = chunkdata;
2104   text_ptr->text = chunkdata + prefix_len;
2105
2106   ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2107
2108   png_free(png_ptr, text_ptr);
2109   png_free(png_ptr, chunkdata);
2110   if (ret)
2111     png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
2112}
2113#endif
2114
2115/* This function is called when we haven't found a handler for a
2116   chunk.  If there isn't a problem with the chunk itself (ie bad
2117   chunk name, CRC, or a critical chunk), the chunk is silently ignored
2118   -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2119   case it will be saved away to be written out later. */
2120void /* PRIVATE */
2121png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2122{
2123   png_uint_32 skip = 0;
2124
2125   png_debug(1, "in png_handle_unknown\n");
2126
2127   if (png_ptr->mode & PNG_HAVE_IDAT)
2128   {
2129#ifdef PNG_USE_LOCAL_ARRAYS
2130      PNG_IDAT;
2131#endif
2132      if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))  /* not an IDAT */
2133         png_ptr->mode |= PNG_AFTER_IDAT;
2134   }
2135
2136   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
2137
2138   if (!(png_ptr->chunk_name[0] & 0x20))
2139   {
2140#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2141      if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2142           HANDLE_CHUNK_ALWAYS
2143#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2144           && png_ptr->read_user_chunk_fn == NULL
2145#endif
2146        )
2147#endif
2148          png_chunk_error(png_ptr, "unknown critical chunk");
2149   }
2150
2151#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2152   if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
2153   {
2154       png_unknown_chunk chunk;
2155
2156#ifdef PNG_MAX_MALLOC_64K
2157       if (length > (png_uint_32)65535L)
2158       {
2159           png_warning(png_ptr, "unknown chunk too large to fit in memory");
2160           skip = length - (png_uint_32)65535L;
2161           length = (png_uint_32)65535L;
2162       }
2163#endif
2164       png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name);
2165       chunk.data = (png_bytep)png_malloc(png_ptr, length);
2166       chunk.size = (png_size_t)length;
2167       png_crc_read(png_ptr, (png_bytep)chunk.data, length);
2168#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2169       if(png_ptr->read_user_chunk_fn != NULL)
2170       {
2171          /* callback to user unknown chunk handler */
2172          if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0)
2173          {
2174             if (!(png_ptr->chunk_name[0] & 0x20))
2175                if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2176                     HANDLE_CHUNK_ALWAYS)
2177                 {
2178                   png_free(png_ptr, chunk.data);
2179                   png_chunk_error(png_ptr, "unknown critical chunk");
2180                 }
2181             png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
2182          }
2183       }
2184       else
2185#endif
2186          png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
2187       png_free(png_ptr, chunk.data);
2188   }
2189   else
2190#endif
2191      skip = length;
2192
2193   png_crc_finish(png_ptr, skip);
2194
2195#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2196   info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
2197#endif
2198}
2199
2200/* This function is called to verify that a chunk name is valid.
2201   This function can't have the "critical chunk check" incorporated
2202   into it, since in the future we will need to be able to call user
2203   functions to handle unknown critical chunks after we check that
2204   the chunk name itself is valid. */
2205
2206#define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
2207
2208void /* PRIVATE */
2209png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
2210{
2211   png_debug(1, "in png_check_chunk_name\n");
2212   if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
2213       isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
2214   {
2215      png_chunk_error(png_ptr, "invalid chunk type");
2216   }
2217}
2218
2219/* Combines the row recently read in with the existing pixels in the
2220   row.  This routine takes care of alpha and transparency if requested.
2221   This routine also handles the two methods of progressive display
2222   of interlaced images, depending on the mask value.
2223   The mask value describes which pixels are to be combined with
2224   the row.  The pattern always repeats every 8 pixels, so just 8
2225   bits are needed.  A one indicates the pixel is to be combined,
2226   a zero indicates the pixel is to be skipped.  This is in addition
2227   to any alpha or transparency value associated with the pixel.  If
2228   you want all pixels to be combined, pass 0xff (255) in mask.  */
2229#ifndef PNG_HAVE_ASSEMBLER_COMBINE_ROW
2230void /* PRIVATE */
2231png_combine_row(png_structp png_ptr, png_bytep row, int mask)
2232{
2233   png_debug(1,"in png_combine_row\n");
2234   if (mask == 0xff)
2235   {
2236      png_memcpy(row, png_ptr->row_buf + 1,
2237         (png_size_t)((png_ptr->width *
2238         png_ptr->row_info.pixel_depth + 7) >> 3));
2239   }
2240   else
2241   {
2242      switch (png_ptr->row_info.pixel_depth)
2243      {
2244         case 1:
2245         {
2246            png_bytep sp = png_ptr->row_buf + 1;
2247            png_bytep dp = row;
2248            int s_inc, s_start, s_end;
2249            int m = 0x80;
2250            int shift;
2251            png_uint_32 i;
2252            png_uint_32 row_width = png_ptr->width;
2253
2254#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2255            if (png_ptr->transformations & PNG_PACKSWAP)
2256            {
2257                s_start = 0;
2258                s_end = 7;
2259                s_inc = 1;
2260            }
2261            else
2262#endif
2263            {
2264                s_start = 7;
2265                s_end = 0;
2266                s_inc = -1;
2267            }
2268
2269            shift = s_start;
2270
2271            for (i = 0; i < row_width; i++)
2272            {
2273               if (m & mask)
2274               {
2275                  int value;
2276
2277                  value = (*sp >> shift) & 0x01;
2278                  *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
2279                  *dp |= (png_byte)(value << shift);
2280               }
2281
2282               if (shift == s_end)
2283               {
2284                  shift = s_start;
2285                  sp++;
2286                  dp++;
2287               }
2288               else
2289                  shift += s_inc;
2290
2291               if (m == 1)
2292                  m = 0x80;
2293               else
2294                  m >>= 1;
2295            }
2296            break;
2297         }
2298         case 2:
2299         {
2300            png_bytep sp = png_ptr->row_buf + 1;
2301            png_bytep dp = row;
2302            int s_start, s_end, s_inc;
2303            int m = 0x80;
2304            int shift;
2305            png_uint_32 i;
2306            png_uint_32 row_width = png_ptr->width;
2307            int value;
2308
2309#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2310            if (png_ptr->transformations & PNG_PACKSWAP)
2311            {
2312               s_start = 0;
2313               s_end = 6;
2314               s_inc = 2;
2315            }
2316            else
2317#endif
2318            {
2319               s_start = 6;
2320               s_end = 0;
2321               s_inc = -2;
2322            }
2323
2324            shift = s_start;
2325
2326            for (i = 0; i < row_width; i++)
2327            {
2328               if (m & mask)
2329               {
2330                  value = (*sp >> shift) & 0x03;
2331                  *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2332                  *dp |= (png_byte)(value << shift);
2333               }
2334
2335               if (shift == s_end)
2336               {
2337                  shift = s_start;
2338                  sp++;
2339                  dp++;
2340               }
2341               else
2342                  shift += s_inc;
2343               if (m == 1)
2344                  m = 0x80;
2345               else
2346                  m >>= 1;
2347            }
2348            break;
2349         }
2350         case 4:
2351         {
2352            png_bytep sp = png_ptr->row_buf + 1;
2353            png_bytep dp = row;
2354            int s_start, s_end, s_inc;
2355            int m = 0x80;
2356            int shift;
2357            png_uint_32 i;
2358            png_uint_32 row_width = png_ptr->width;
2359            int value;
2360
2361#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2362            if (png_ptr->transformations & PNG_PACKSWAP)
2363            {
2364               s_start = 0;
2365               s_end = 4;
2366               s_inc = 4;
2367            }
2368            else
2369#endif
2370            {
2371               s_start = 4;
2372               s_end = 0;
2373               s_inc = -4;
2374            }
2375            shift = s_start;
2376
2377            for (i = 0; i < row_width; i++)
2378            {
2379               if (m & mask)
2380               {
2381                  value = (*sp >> shift) & 0xf;
2382                  *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2383                  *dp |= (png_byte)(value << shift);
2384               }
2385
2386               if (shift == s_end)
2387               {
2388                  shift = s_start;
2389                  sp++;
2390                  dp++;
2391               }
2392               else
2393                  shift += s_inc;
2394               if (m == 1)
2395                  m = 0x80;
2396               else
2397                  m >>= 1;
2398            }
2399            break;
2400         }
2401         default:
2402         {
2403            png_bytep sp = png_ptr->row_buf + 1;
2404            png_bytep dp = row;
2405            png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
2406            png_uint_32 i;
2407            png_uint_32 row_width = png_ptr->width;
2408            png_byte m = 0x80;
2409
2410
2411            for (i = 0; i < row_width; i++)
2412            {
2413               if (m & mask)
2414               {
2415                  png_memcpy(dp, sp, pixel_bytes);
2416               }
2417
2418               sp += pixel_bytes;
2419               dp += pixel_bytes;
2420
2421               if (m == 1)
2422                  m = 0x80;
2423               else
2424                  m >>= 1;
2425            }
2426            break;
2427         }
2428      }
2429   }
2430}
2431#endif /* !PNG_HAVE_ASSEMBLER_COMBINE_ROW */
2432
2433#ifdef PNG_READ_INTERLACING_SUPPORTED
2434#ifndef PNG_HAVE_ASSEMBLER_READ_INTERLACE   /* else in pngvcrd.c, pnggccrd.c */
2435/* OLD pre-1.0.9 interface:
2436void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2437   png_uint_32 transformations)
2438 */
2439void /* PRIVATE */
2440png_do_read_interlace(png_structp png_ptr)
2441{
2442   png_row_infop row_info = &(png_ptr->row_info);
2443   png_bytep row = png_ptr->row_buf + 1;
2444   int pass = png_ptr->pass;
2445   png_uint_32 transformations = png_ptr->transformations;
2446#ifdef PNG_USE_LOCAL_ARRAYS
2447   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2448   /* offset to next interlace block */
2449   const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2450#endif
2451
2452   png_debug(1,"in png_do_read_interlace (stock C version)\n");
2453   if (row != NULL && row_info != NULL)
2454   {
2455      png_uint_32 final_width;
2456
2457      final_width = row_info->width * png_pass_inc[pass];
2458
2459      switch (row_info->pixel_depth)
2460      {
2461         case 1:
2462         {
2463            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
2464            png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
2465            int sshift, dshift;
2466            int s_start, s_end, s_inc;
2467            int jstop = png_pass_inc[pass];
2468            png_byte v;
2469            png_uint_32 i;
2470            int j;
2471
2472#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2473            if (transformations & PNG_PACKSWAP)
2474            {
2475                sshift = (int)((row_info->width + 7) & 0x07);
2476                dshift = (int)((final_width + 7) & 0x07);
2477                s_start = 7;
2478                s_end = 0;
2479                s_inc = -1;
2480            }
2481            else
2482#endif
2483            {
2484                sshift = 7 - (int)((row_info->width + 7) & 0x07);
2485                dshift = 7 - (int)((final_width + 7) & 0x07);
2486                s_start = 0;
2487                s_end = 7;
2488                s_inc = 1;
2489            }
2490
2491            for (i = 0; i < row_info->width; i++)
2492            {
2493               v = (png_byte)((*sp >> sshift) & 0x01);
2494               for (j = 0; j < jstop; j++)
2495               {
2496                  *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
2497                  *dp |= (png_byte)(v << dshift);
2498                  if (dshift == s_end)
2499                  {
2500                     dshift = s_start;
2501                     dp--;
2502                  }
2503                  else
2504                     dshift += s_inc;
2505               }
2506               if (sshift == s_end)
2507               {
2508                  sshift = s_start;
2509                  sp--;
2510               }
2511               else
2512                  sshift += s_inc;
2513            }
2514            break;
2515         }
2516         case 2:
2517         {
2518            png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
2519            png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
2520            int sshift, dshift;
2521            int s_start, s_end, s_inc;
2522            int jstop = png_pass_inc[pass];
2523            png_uint_32 i;
2524
2525#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2526            if (transformations & PNG_PACKSWAP)
2527            {
2528               sshift = (int)(((row_info->width + 3) & 0x03) << 1);
2529               dshift = (int)(((final_width + 3) & 0x03) << 1);
2530               s_start = 6;
2531               s_end = 0;
2532               s_inc = -2;
2533            }
2534            else
2535#endif
2536            {
2537               sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
2538               dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
2539               s_start = 0;
2540               s_end = 6;
2541               s_inc = 2;
2542            }
2543
2544            for (i = 0; i < row_info->width; i++)
2545            {
2546               png_byte v;
2547               int j;
2548
2549               v = (png_byte)((*sp >> sshift) & 0x03);
2550               for (j = 0; j < jstop; j++)
2551               {
2552                  *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
2553                  *dp |= (png_byte)(v << dshift);
2554                  if (dshift == s_end)
2555                  {
2556                     dshift = s_start;
2557                     dp--;
2558                  }
2559                  else
2560                     dshift += s_inc;
2561               }
2562               if (sshift == s_end)
2563               {
2564                  sshift = s_start;
2565                  sp--;
2566               }
2567               else
2568                  sshift += s_inc;
2569            }
2570            break;
2571         }
2572         case 4:
2573         {
2574            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
2575            png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
2576            int sshift, dshift;
2577            int s_start, s_end, s_inc;
2578            png_uint_32 i;
2579            int jstop = png_pass_inc[pass];
2580
2581#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2582            if (transformations & PNG_PACKSWAP)
2583            {
2584               sshift = (int)(((row_info->width + 1) & 0x01) << 2);
2585               dshift = (int)(((final_width + 1) & 0x01) << 2);
2586               s_start = 4;
2587               s_end = 0;
2588               s_inc = -4;
2589            }
2590            else
2591#endif
2592            {
2593               sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
2594               dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
2595               s_start = 0;
2596               s_end = 4;
2597               s_inc = 4;
2598            }
2599
2600            for (i = 0; i < row_info->width; i++)
2601            {
2602               png_byte v = (png_byte)((*sp >> sshift) & 0xf);
2603               int j;
2604
2605               for (j = 0; j < jstop; j++)
2606               {
2607                  *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
2608                  *dp |= (png_byte)(v << dshift);
2609                  if (dshift == s_end)
2610                  {
2611                     dshift = s_start;
2612                     dp--;
2613                  }
2614                  else
2615                     dshift += s_inc;
2616               }
2617               if (sshift == s_end)
2618               {
2619                  sshift = s_start;
2620                  sp--;
2621               }
2622               else
2623                  sshift += s_inc;
2624            }
2625            break;
2626         }
2627         default:
2628         {
2629            png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
2630            png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
2631            png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
2632
2633            int jstop = png_pass_inc[pass];
2634            png_uint_32 i;
2635
2636            for (i = 0; i < row_info->width; i++)
2637            {
2638               png_byte v[8];
2639               int j;
2640
2641               png_memcpy(v, sp, pixel_bytes);
2642               for (j = 0; j < jstop; j++)
2643               {
2644                  png_memcpy(dp, v, pixel_bytes);
2645                  dp -= pixel_bytes;
2646               }
2647               sp -= pixel_bytes;
2648            }
2649            break;
2650         }
2651      }
2652      row_info->width = final_width;
2653      row_info->rowbytes = ((final_width *
2654         (png_uint_32)row_info->pixel_depth + 7) >> 3);
2655   }
2656#if !defined(PNG_READ_PACKSWAP_SUPPORTED)
2657   transformations = transformations; /* silence compiler warning */
2658#endif
2659}
2660#endif /* !PNG_HAVE_ASSEMBLER_READ_INTERLACE */
2661#endif /* PNG_READ_INTERLACING_SUPPORTED */
2662
2663#ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
2664void /* PRIVATE */
2665png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
2666   png_bytep prev_row, int filter)
2667{
2668   png_debug(1, "in png_read_filter_row\n");
2669   png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
2670   switch (filter)
2671   {
2672      case PNG_FILTER_VALUE_NONE:
2673         break;
2674      case PNG_FILTER_VALUE_SUB:
2675      {
2676         png_uint_32 i;
2677         png_uint_32 istop = row_info->rowbytes;
2678         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2679         png_bytep rp = row + bpp;
2680         png_bytep lp = row;
2681
2682         for (i = bpp; i < istop; i++)
2683         {
2684            *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
2685            rp++;
2686         }
2687         break;
2688      }
2689      case PNG_FILTER_VALUE_UP:
2690      {
2691         png_uint_32 i;
2692         png_uint_32 istop = row_info->rowbytes;
2693         png_bytep rp = row;
2694         png_bytep pp = prev_row;
2695
2696         for (i = 0; i < istop; i++)
2697         {
2698            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2699            rp++;
2700         }
2701         break;
2702      }
2703      case PNG_FILTER_VALUE_AVG:
2704      {
2705         png_uint_32 i;
2706         png_bytep rp = row;
2707         png_bytep pp = prev_row;
2708         png_bytep lp = row;
2709         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2710         png_uint_32 istop = row_info->rowbytes - bpp;
2711
2712         for (i = 0; i < bpp; i++)
2713         {
2714            *rp = (png_byte)(((int)(*rp) +
2715               ((int)(*pp++) / 2 )) & 0xff);
2716            rp++;
2717         }
2718
2719         for (i = 0; i < istop; i++)
2720         {
2721            *rp = (png_byte)(((int)(*rp) +
2722               (int)(*pp++ + *lp++) / 2 ) & 0xff);
2723            rp++;
2724         }
2725         break;
2726      }
2727      case PNG_FILTER_VALUE_PAETH:
2728      {
2729         png_uint_32 i;
2730         png_bytep rp = row;
2731         png_bytep pp = prev_row;
2732         png_bytep lp = row;
2733         png_bytep cp = prev_row;
2734         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2735         png_uint_32 istop=row_info->rowbytes - bpp;
2736
2737         for (i = 0; i < bpp; i++)
2738         {
2739            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2740            rp++;
2741         }
2742
2743         for (i = 0; i < istop; i++)   /* use leftover rp,pp */
2744         {
2745            int a, b, c, pa, pb, pc, p;
2746
2747            a = *lp++;
2748            b = *pp++;
2749            c = *cp++;
2750
2751            p = b - c;
2752            pc = a - c;
2753
2754#ifdef PNG_USE_ABS
2755            pa = abs(p);
2756            pb = abs(pc);
2757            pc = abs(p + pc);
2758#else
2759            pa = p < 0 ? -p : p;
2760            pb = pc < 0 ? -pc : pc;
2761            pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2762#endif
2763
2764            /*
2765               if (pa <= pb && pa <= pc)
2766                  p = a;
2767               else if (pb <= pc)
2768                  p = b;
2769               else
2770                  p = c;
2771             */
2772
2773            p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
2774
2775            *rp = (png_byte)(((int)(*rp) + p) & 0xff);
2776            rp++;
2777         }
2778         break;
2779      }
2780      default:
2781         png_warning(png_ptr, "Ignoring bad adaptive filter type");
2782         *row=0;
2783         break;
2784   }
2785}
2786#endif /* !PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */
2787
2788void /* PRIVATE */
2789png_read_finish_row(png_structp png_ptr)
2790{
2791#ifdef PNG_USE_LOCAL_ARRAYS
2792   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2793
2794   /* start of interlace block */
2795   const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2796
2797   /* offset to next interlace block */
2798   const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2799
2800   /* start of interlace block in the y direction */
2801   const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
2802
2803   /* offset to next interlace block in the y direction */
2804   const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
2805#endif
2806
2807   png_debug(1, "in png_read_finish_row\n");
2808   png_ptr->row_number++;
2809   if (png_ptr->row_number < png_ptr->num_rows)
2810      return;
2811
2812   if (png_ptr->interlaced)
2813   {
2814      png_ptr->row_number = 0;
2815      png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
2816      do
2817      {
2818         png_ptr->pass++;
2819         if (png_ptr->pass >= 7)
2820            break;
2821         png_ptr->iwidth = (png_ptr->width +
2822            png_pass_inc[png_ptr->pass] - 1 -
2823            png_pass_start[png_ptr->pass]) /
2824            png_pass_inc[png_ptr->pass];
2825            png_ptr->irowbytes = ((png_ptr->iwidth *
2826               (png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
2827
2828         if (!(png_ptr->transformations & PNG_INTERLACE))
2829         {
2830            png_ptr->num_rows = (png_ptr->height +
2831               png_pass_yinc[png_ptr->pass] - 1 -
2832               png_pass_ystart[png_ptr->pass]) /
2833               png_pass_yinc[png_ptr->pass];
2834            if (!(png_ptr->num_rows))
2835               continue;
2836         }
2837         else  /* if (png_ptr->transformations & PNG_INTERLACE) */
2838            break;
2839      } while (png_ptr->iwidth == 0);
2840
2841      if (png_ptr->pass < 7)
2842         return;
2843   }
2844
2845   if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
2846   {
2847#ifdef PNG_USE_LOCAL_ARRAYS
2848      PNG_IDAT;
2849#endif
2850      char extra;
2851      int ret;
2852
2853      png_ptr->zstream.next_out = (Byte *)&extra;
2854      png_ptr->zstream.avail_out = (uInt)1;
2855      for(;;)
2856      {
2857         if (!(png_ptr->zstream.avail_in))
2858         {
2859            while (!png_ptr->idat_size)
2860            {
2861               png_byte chunk_length[4];
2862
2863               png_crc_finish(png_ptr, 0);
2864
2865               png_read_data(png_ptr, chunk_length, 4);
2866               png_ptr->idat_size = png_get_uint_32(chunk_length);
2867
2868               png_reset_crc(png_ptr);
2869               png_crc_read(png_ptr, png_ptr->chunk_name, 4);
2870               if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
2871                  png_error(png_ptr, "Not enough image data");
2872
2873            }
2874            png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
2875            png_ptr->zstream.next_in = png_ptr->zbuf;
2876            if (png_ptr->zbuf_size > png_ptr->idat_size)
2877               png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
2878            png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
2879            png_ptr->idat_size -= png_ptr->zstream.avail_in;
2880         }
2881         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
2882         if (ret == Z_STREAM_END)
2883         {
2884            if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
2885               png_ptr->idat_size)
2886               png_warning(png_ptr, "Extra compressed data");
2887            png_ptr->mode |= PNG_AFTER_IDAT;
2888            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
2889            break;
2890         }
2891         if (ret != Z_OK)
2892            png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
2893                      "Decompression Error");
2894
2895         if (!(png_ptr->zstream.avail_out))
2896         {
2897            png_warning(png_ptr, "Extra compressed data.");
2898            png_ptr->mode |= PNG_AFTER_IDAT;
2899            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
2900            break;
2901         }
2902
2903      }
2904      png_ptr->zstream.avail_out = 0;
2905   }
2906
2907   if (png_ptr->idat_size || png_ptr->zstream.avail_in)
2908      png_warning(png_ptr, "Extra compression data");
2909
2910   inflateReset(&png_ptr->zstream);
2911
2912   png_ptr->mode |= PNG_AFTER_IDAT;
2913}
2914
2915void /* PRIVATE */
2916png_read_start_row(png_structp png_ptr)
2917{
2918#ifdef PNG_USE_LOCAL_ARRAYS
2919   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2920
2921   /* start of interlace block */
2922   const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2923
2924   /* offset to next interlace block */
2925   const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2926
2927   /* start of interlace block in the y direction */
2928   const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
2929
2930   /* offset to next interlace block in the y direction */
2931   const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
2932#endif
2933
2934   int max_pixel_depth;
2935   png_uint_32 row_bytes;
2936
2937   png_debug(1, "in png_read_start_row\n");
2938   png_ptr->zstream.avail_in = 0;
2939   png_init_read_transformations(png_ptr);
2940   if (png_ptr->interlaced)
2941   {
2942      if (!(png_ptr->transformations & PNG_INTERLACE))
2943         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
2944            png_pass_ystart[0]) / png_pass_yinc[0];
2945      else
2946         png_ptr->num_rows = png_ptr->height;
2947
2948      png_ptr->iwidth = (png_ptr->width +
2949         png_pass_inc[png_ptr->pass] - 1 -
2950         png_pass_start[png_ptr->pass]) /
2951         png_pass_inc[png_ptr->pass];
2952
2953         row_bytes = ((png_ptr->iwidth *
2954            (png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
2955         png_ptr->irowbytes = (png_size_t)row_bytes;
2956         if((png_uint_32)png_ptr->irowbytes != row_bytes)
2957            png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
2958   }
2959   else
2960   {
2961      png_ptr->num_rows = png_ptr->height;
2962      png_ptr->iwidth = png_ptr->width;
2963      png_ptr->irowbytes = png_ptr->rowbytes + 1;
2964   }
2965   max_pixel_depth = png_ptr->pixel_depth;
2966
2967#if defined(PNG_READ_PACK_SUPPORTED)
2968   if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
2969      max_pixel_depth = 8;
2970#endif
2971
2972#if defined(PNG_READ_EXPAND_SUPPORTED)
2973   if (png_ptr->transformations & PNG_EXPAND)
2974   {
2975      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2976      {
2977         if (png_ptr->num_trans)
2978            max_pixel_depth = 32;
2979         else
2980            max_pixel_depth = 24;
2981      }
2982      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
2983      {
2984         if (max_pixel_depth < 8)
2985            max_pixel_depth = 8;
2986         if (png_ptr->num_trans)
2987            max_pixel_depth *= 2;
2988      }
2989      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
2990      {
2991         if (png_ptr->num_trans)
2992         {
2993            max_pixel_depth *= 4;
2994            max_pixel_depth /= 3;
2995         }
2996      }
2997   }
2998#endif
2999
3000#if defined(PNG_READ_FILLER_SUPPORTED)
3001   if (png_ptr->transformations & (PNG_FILLER))
3002   {
3003      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3004         max_pixel_depth = 32;
3005      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3006      {
3007         if (max_pixel_depth <= 8)
3008            max_pixel_depth = 16;
3009         else
3010            max_pixel_depth = 32;
3011      }
3012      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3013      {
3014         if (max_pixel_depth <= 32)
3015            max_pixel_depth = 32;
3016         else
3017            max_pixel_depth = 64;
3018      }
3019   }
3020#endif
3021
3022#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
3023   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
3024   {
3025      if (
3026#if defined(PNG_READ_EXPAND_SUPPORTED)
3027        (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
3028#endif
3029#if defined(PNG_READ_FILLER_SUPPORTED)
3030        (png_ptr->transformations & (PNG_FILLER)) ||
3031#endif
3032        png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3033      {
3034         if (max_pixel_depth <= 16)
3035            max_pixel_depth = 32;
3036         else
3037            max_pixel_depth = 64;
3038      }
3039      else
3040      {
3041         if (max_pixel_depth <= 8)
3042           {
3043             if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3044               max_pixel_depth = 32;
3045             else
3046               max_pixel_depth = 24;
3047           }
3048         else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3049            max_pixel_depth = 64;
3050         else
3051            max_pixel_depth = 48;
3052      }
3053   }
3054#endif
3055
3056#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3057defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3058   if(png_ptr->transformations & PNG_USER_TRANSFORM)
3059     {
3060       int user_pixel_depth=png_ptr->user_transform_depth*
3061         png_ptr->user_transform_channels;
3062       if(user_pixel_depth > max_pixel_depth)
3063         max_pixel_depth=user_pixel_depth;
3064     }
3065#endif
3066
3067   /* align the width on the next larger 8 pixels.  Mainly used
3068      for interlacing */
3069   row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
3070   /* calculate the maximum bytes needed, adding a byte and a pixel
3071      for safety's sake */
3072   row_bytes = ((row_bytes * (png_uint_32)max_pixel_depth + 7) >> 3) +
3073      1 + ((max_pixel_depth + 7) >> 3);
3074#ifdef PNG_MAX_MALLOC_64K
3075   if (row_bytes > (png_uint_32)65536L)
3076      png_error(png_ptr, "This image requires a row greater than 64KB");
3077#endif
3078   png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
3079   png_ptr->row_buf = png_ptr->big_row_buf+32;
3080#if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD)
3081   png_ptr->row_buf_size = row_bytes;
3082#endif
3083
3084#ifdef PNG_MAX_MALLOC_64K
3085   if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
3086      png_error(png_ptr, "This image requires a row greater than 64KB");
3087#endif
3088   png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
3089      png_ptr->rowbytes + 1));
3090
3091   png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
3092
3093   png_debug1(3, "width = %lu,\n", png_ptr->width);
3094   png_debug1(3, "height = %lu,\n", png_ptr->height);
3095   png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
3096   png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
3097   png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
3098   png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
3099
3100   png_ptr->flags |= PNG_FLAG_ROW_INIT;
3101}
Note: See TracBrowser for help on using the repository browser.