Set the canvas of the bline used by the circle tool.
[synfig.git] / gtkmm-osx / trunk / libpng-1.2.5 / pngrutil.c
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. */
43 png_uint_32 /* PRIVATE */
44 png_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. */
58 png_int_32 /* PRIVATE */
59 png_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. */
71 png_uint_16 /* PRIVATE */
72 png_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. */
82 void /* PRIVATE */
83 png_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. */
93 int /* PRIVATE */
94 png_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. */
129 int /* PRIVATE */
130 png_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  */
168 png_charp /* PRIVATE */
169 png_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 */
327 void /* PRIVATE */
328 png_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 */
399 void /* PRIVATE */
400 png_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
537 void /* PRIVATE */
538 png_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)
559 void /* PRIVATE */
560 png_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)
640 void /* PRIVATE */
641 png_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)
706 void /* PRIVATE */
707 png_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)
874 void /* PRIVATE */
875 png_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)
971 void /* PRIVATE */
972 png_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)
1086 void /* PRIVATE */
1087 png_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)
1215 void /* PRIVATE */
1216 png_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)
1308 void /* PRIVATE */
1309 png_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)
1397 void /* PRIVATE */
1398 png_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)
1450 void /* PRIVATE */
1451 png_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)
1493 void /* PRIVATE */
1494 png_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) */
1537 void /* PRIVATE */
1538 png_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 */
1665 void /* PRIVATE */
1666 png_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)
1792 void /* PRIVATE */
1793 png_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 */
1836 void /* PRIVATE */
1837 png_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 */
1914 void /* PRIVATE */
1915 png_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 */
2010 void /* PRIVATE */
2011 png_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. */
2120 void /* PRIVATE */
2121 png_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
2208 void /* PRIVATE */
2209 png_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
2230 void /* PRIVATE */
2231 png_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:
2436 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2437    png_uint_32 transformations)
2438  */
2439 void /* PRIVATE */
2440 png_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
2664 void /* PRIVATE */
2665 png_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
2788 void /* PRIVATE */
2789 png_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
2915 void /* PRIVATE */
2916 png_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) && \
3057 defined(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 }