/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/png/pngrutil.c
ViewVC logotype

Annotation of /trunk/3rdparty/wxWidgets/src/png/pngrutil.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.22