1
2/* pngread.c - read a PNG file
3 *
4 * Last changed in libpng 1.2.44 [June 26, 2010]
5 * Copyright (c) 1998-2010 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 an application calls directly to
14 * read a PNG file or stream.
15 */
16
17#define PNG_INTERNAL
18#define PNG_NO_PEDANTIC_WARNINGS
19#include "png.h"
20#ifdef PNG_READ_SUPPORTED
21
22
23/* Create a PNG structure for reading, and allocate any memory needed. */
24png_structp PNGAPI
25png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
26   png_error_ptr error_fn, png_error_ptr warn_fn)
27{
28
29#ifdef PNG_USER_MEM_SUPPORTED
30   return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
31      warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
32}
33
34/* Alternate create PNG structure for reading, and allocate any memory
35 * needed.
36 */
37png_structp PNGAPI
38png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
39   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
40   png_malloc_ptr malloc_fn, png_free_ptr free_fn)
41{
42#endif /* PNG_USER_MEM_SUPPORTED */
43
44#ifdef PNG_SETJMP_SUPPORTED
45   volatile
46#endif
47   png_structp png_ptr;
48
49#ifdef PNG_SETJMP_SUPPORTED
50#ifdef USE_FAR_KEYWORD
51   jmp_buf jmpbuf;
52#endif
53#endif
54
55   int i;
56
57   png_debug(1, "in png_create_read_struct");
58
59#ifdef PNG_USER_MEM_SUPPORTED
60   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
61      (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
62#else
63   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
64#endif
65   if (png_ptr == NULL)
66      return (NULL);
67
68   /* Added at libpng-1.2.6 */
69#ifdef PNG_USER_LIMITS_SUPPORTED
70   png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
71   png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
72#  ifdef PNG_USER_CHUNK_CACHE_MAX
73   /* Added at libpng-1.2.43 and 1.4.0 */
74   png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
75#  endif
76#  ifdef PNG_SET_USER_CHUNK_MALLOC_MAX
77   /* Added at libpng-1.2.43 and 1.4.1 */
78   png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
79#  endif
80#endif
81
82#ifdef PNG_SETJMP_SUPPORTED
83#ifdef USE_FAR_KEYWORD
84   if (setjmp(jmpbuf))
85#else
86   if (setjmp(png_ptr->jmpbuf))
87#endif
88   {
89      png_free(png_ptr, png_ptr->zbuf);
90      png_ptr->zbuf = NULL;
91#ifdef PNG_USER_MEM_SUPPORTED
92      png_destroy_struct_2((png_voidp)png_ptr,
93         (png_free_ptr)free_fn, (png_voidp)mem_ptr);
94#else
95      png_destroy_struct((png_voidp)png_ptr);
96#endif
97      return (NULL);
98   }
99#ifdef USE_FAR_KEYWORD
100   png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
101#endif
102#endif /* PNG_SETJMP_SUPPORTED */
103
104#ifdef PNG_USER_MEM_SUPPORTED
105   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
106#endif
107
108   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
109
110   if (user_png_ver)
111   {
112      i = 0;
113      do
114      {
115         if (user_png_ver[i] != png_libpng_ver[i])
116            png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
117      } while (png_libpng_ver[i++]);
118    }
119    else
120         png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
121
122
123    if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
124    {
125       /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
126       * we must recompile any applications that use any older library version.
127       * For versions after libpng 1.0, we will be compatible, so we need
128       * only check the first digit.
129       */
130      if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
131          (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
132          (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
133      {
134#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
135         char msg[80];
136         if (user_png_ver)
137         {
138           png_snprintf(msg, 80,
139              "Application was compiled with png.h from libpng-%.20s",
140              user_png_ver);
141           png_warning(png_ptr, msg);
142         }
143         png_snprintf(msg, 80,
144             "Application  is  running with png.c from libpng-%.20s",
145             png_libpng_ver);
146         png_warning(png_ptr, msg);
147#endif
148#ifdef PNG_ERROR_NUMBERS_SUPPORTED
149         png_ptr->flags = 0;
150#endif
151         png_error(png_ptr,
152            "Incompatible libpng version in application and library");
153      }
154   }
155
156   /* Initialize zbuf - compression buffer */
157   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
158   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
159     (png_uint_32)png_ptr->zbuf_size);
160   png_ptr->zstream.zalloc = png_zalloc;
161   png_ptr->zstream.zfree = png_zfree;
162   png_ptr->zstream.opaque = (voidpf)png_ptr;
163
164      switch (inflateInit(&png_ptr->zstream))
165      {
166         case Z_OK: /* Do nothing */ break;
167         case Z_MEM_ERROR:
168         case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error");
169            break;
170         case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error");
171            break;
172         default: png_error(png_ptr, "Unknown zlib error");
173      }
174
175
176   png_ptr->zstream.next_out = png_ptr->zbuf;
177   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
178
179   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
180
181#ifdef PNG_SETJMP_SUPPORTED
182/* Applications that neglect to set up their own setjmp() and then
183   encounter a png_error() will longjmp here.  Since the jmpbuf is
184   then meaningless we abort instead of returning. */
185#ifdef USE_FAR_KEYWORD
186   if (setjmp(jmpbuf))
187       PNG_ABORT();
188   png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
189#else
190   if (setjmp(png_ptr->jmpbuf))
191       PNG_ABORT();
192#endif
193#endif /* PNG_SETJMP_SUPPORTED */
194
195#ifdef PNG_INDEX_SUPPORTED
196   png_ptr->index = NULL;
197#endif
198
199   return (png_ptr);
200}
201
202#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
203/* Initialize PNG structure for reading, and allocate any memory needed.
204 * This interface is deprecated in favour of the png_create_read_struct(),
205 * and it will disappear as of libpng-1.3.0.
206 */
207#undef png_read_init
208void PNGAPI
209png_read_init(png_structp png_ptr)
210{
211   /* We only come here via pre-1.0.7-compiled applications */
212   png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
213}
214
215void PNGAPI
216png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
217   png_size_t png_struct_size, png_size_t png_info_size)
218{
219   /* We only come here via pre-1.0.12-compiled applications */
220   if (png_ptr == NULL)
221      return;
222#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
223   if (png_sizeof(png_struct) > png_struct_size ||
224      png_sizeof(png_info) > png_info_size)
225   {
226      char msg[80];
227      png_ptr->warning_fn = NULL;
228      if (user_png_ver)
229      {
230        png_snprintf(msg, 80,
231           "Application was compiled with png.h from libpng-%.20s",
232           user_png_ver);
233        png_warning(png_ptr, msg);
234      }
235      png_snprintf(msg, 80,
236         "Application  is  running with png.c from libpng-%.20s",
237         png_libpng_ver);
238      png_warning(png_ptr, msg);
239   }
240#endif
241   if (png_sizeof(png_struct) > png_struct_size)
242   {
243      png_ptr->error_fn = NULL;
244#ifdef PNG_ERROR_NUMBERS_SUPPORTED
245      png_ptr->flags = 0;
246#endif
247      png_error(png_ptr,
248      "The png struct allocated by the application for reading is"
249      " too small.");
250   }
251   if (png_sizeof(png_info) > png_info_size)
252   {
253      png_ptr->error_fn = NULL;
254#ifdef PNG_ERROR_NUMBERS_SUPPORTED
255      png_ptr->flags = 0;
256#endif
257      png_error(png_ptr,
258        "The info struct allocated by application for reading is"
259        " too small.");
260   }
261   png_read_init_3(&png_ptr, user_png_ver, png_struct_size);
262}
263#endif /* PNG_1_0_X || PNG_1_2_X */
264
265void PNGAPI
266png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
267   png_size_t png_struct_size)
268{
269#ifdef PNG_SETJMP_SUPPORTED
270   jmp_buf tmp_jmp;  /* to save current jump buffer */
271#endif
272
273   int i = 0;
274
275   png_structp png_ptr=*ptr_ptr;
276
277   if (png_ptr == NULL)
278      return;
279
280   do
281   {
282      if (user_png_ver[i] != png_libpng_ver[i])
283      {
284#ifdef PNG_LEGACY_SUPPORTED
285        png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
286#else
287        png_ptr->warning_fn = NULL;
288        png_warning(png_ptr,
289         "Application uses deprecated png_read_init() and should be"
290         " recompiled.");
291        break;
292#endif
293      }
294   } while (png_libpng_ver[i++]);
295
296   png_debug(1, "in png_read_init_3");
297
298#ifdef PNG_SETJMP_SUPPORTED
299   /* Save jump buffer and error functions */
300   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
301#endif
302
303   if (png_sizeof(png_struct) > png_struct_size)
304   {
305      png_destroy_struct(png_ptr);
306      *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
307      png_ptr = *ptr_ptr;
308   }
309
310   /* Reset all variables to 0 */
311   png_memset(png_ptr, 0, png_sizeof(png_struct));
312
313#ifdef PNG_SETJMP_SUPPORTED
314   /* Restore jump buffer */
315   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
316#endif
317
318   /* Added at libpng-1.2.6 */
319#ifdef PNG_SET_USER_LIMITS_SUPPORTED
320   png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
321   png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
322#endif
323
324   /* Initialize zbuf - compression buffer */
325   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
326   png_ptr->zstream.zalloc = png_zalloc;
327   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
328     (png_uint_32)png_ptr->zbuf_size);
329   png_ptr->zstream.zalloc = png_zalloc;
330   png_ptr->zstream.zfree = png_zfree;
331   png_ptr->zstream.opaque = (voidpf)png_ptr;
332
333   switch (inflateInit(&png_ptr->zstream))
334   {
335      case Z_OK: /* Do nothing */ break;
336      case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
337      case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error");
338          break;
339      default: png_error(png_ptr, "Unknown zlib error");
340   }
341
342   png_ptr->zstream.next_out = png_ptr->zbuf;
343   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
344
345   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
346}
347
348#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
349/* Read the information before the actual image data.  This has been
350 * changed in v0.90 to allow reading a file that already has the magic
351 * bytes read from the stream.  You can tell libpng how many bytes have
352 * been read from the beginning of the stream (up to the maximum of 8)
353 * via png_set_sig_bytes(), and we will only check the remaining bytes
354 * here.  The application can then have access to the signature bytes we
355 * read if it is determined that this isn't a valid PNG file.
356 */
357void PNGAPI
358png_read_info(png_structp png_ptr, png_infop info_ptr)
359{
360   png_debug(1, "in png_read_info");
361
362   if (png_ptr == NULL || info_ptr == NULL)
363      return;
364
365   /* If we haven't checked all of the PNG signature bytes, do so now. */
366   if (png_ptr->sig_bytes < 8)
367   {
368      png_size_t num_checked = png_ptr->sig_bytes,
369                 num_to_check = 8 - num_checked;
370
371      png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
372      png_ptr->sig_bytes = 8;
373
374      if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
375      {
376         if (num_checked < 4 &&
377             png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
378            png_error(png_ptr, "Not a PNG file");
379         else
380            png_error(png_ptr, "PNG file corrupted by ASCII conversion");
381      }
382      if (num_checked < 3)
383         png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
384   }
385
386   for (;;)
387   {
388#ifdef PNG_USE_LOCAL_ARRAYS
389      PNG_CONST PNG_IHDR;
390      PNG_CONST PNG_IDAT;
391      PNG_CONST PNG_IEND;
392      PNG_CONST PNG_PLTE;
393#ifdef PNG_READ_bKGD_SUPPORTED
394      PNG_CONST PNG_bKGD;
395#endif
396#ifdef PNG_READ_cHRM_SUPPORTED
397      PNG_CONST PNG_cHRM;
398#endif
399#ifdef PNG_READ_gAMA_SUPPORTED
400      PNG_CONST PNG_gAMA;
401#endif
402#ifdef PNG_READ_hIST_SUPPORTED
403      PNG_CONST PNG_hIST;
404#endif
405#ifdef PNG_READ_iCCP_SUPPORTED
406      PNG_CONST PNG_iCCP;
407#endif
408#ifdef PNG_READ_iTXt_SUPPORTED
409      PNG_CONST PNG_iTXt;
410#endif
411#ifdef PNG_READ_oFFs_SUPPORTED
412      PNG_CONST PNG_oFFs;
413#endif
414#ifdef PNG_READ_pCAL_SUPPORTED
415      PNG_CONST PNG_pCAL;
416#endif
417#ifdef PNG_READ_pHYs_SUPPORTED
418      PNG_CONST PNG_pHYs;
419#endif
420#ifdef PNG_READ_sBIT_SUPPORTED
421      PNG_CONST PNG_sBIT;
422#endif
423#ifdef PNG_READ_sCAL_SUPPORTED
424      PNG_CONST PNG_sCAL;
425#endif
426#ifdef PNG_READ_sPLT_SUPPORTED
427      PNG_CONST PNG_sPLT;
428#endif
429#ifdef PNG_READ_sRGB_SUPPORTED
430      PNG_CONST PNG_sRGB;
431#endif
432#ifdef PNG_READ_tEXt_SUPPORTED
433      PNG_CONST PNG_tEXt;
434#endif
435#ifdef PNG_READ_tIME_SUPPORTED
436      PNG_CONST PNG_tIME;
437#endif
438#ifdef PNG_READ_tRNS_SUPPORTED
439      PNG_CONST PNG_tRNS;
440#endif
441#ifdef PNG_READ_zTXt_SUPPORTED
442      PNG_CONST PNG_zTXt;
443#endif
444#endif /* PNG_USE_LOCAL_ARRAYS */
445      png_uint_32 length = png_read_chunk_header(png_ptr);
446      PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
447
448      /* This should be a binary subdivision search or a hash for
449       * matching the chunk name rather than a linear search.
450       */
451      if (!png_memcmp(chunk_name, png_IDAT, 4))
452        if (png_ptr->mode & PNG_AFTER_IDAT)
453          png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
454
455      if (!png_memcmp(chunk_name, png_IHDR, 4))
456         png_handle_IHDR(png_ptr, info_ptr, length);
457      else if (!png_memcmp(chunk_name, png_IEND, 4))
458         png_handle_IEND(png_ptr, info_ptr, length);
459#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
460      else if (png_handle_as_unknown(png_ptr, chunk_name))
461      {
462         if (!png_memcmp(chunk_name, png_IDAT, 4))
463            png_ptr->mode |= PNG_HAVE_IDAT;
464         png_handle_unknown(png_ptr, info_ptr, length);
465         if (!png_memcmp(chunk_name, png_PLTE, 4))
466            png_ptr->mode |= PNG_HAVE_PLTE;
467         else if (!png_memcmp(chunk_name, png_IDAT, 4))
468         {
469            if (!(png_ptr->mode & PNG_HAVE_IHDR))
470               png_error(png_ptr, "Missing IHDR before IDAT");
471            else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
472                     !(png_ptr->mode & PNG_HAVE_PLTE))
473               png_error(png_ptr, "Missing PLTE before IDAT");
474            break;
475         }
476      }
477#endif
478      else if (!png_memcmp(chunk_name, png_PLTE, 4))
479         png_handle_PLTE(png_ptr, info_ptr, length);
480      else if (!png_memcmp(chunk_name, png_IDAT, 4))
481      {
482         if (!(png_ptr->mode & PNG_HAVE_IHDR))
483            png_error(png_ptr, "Missing IHDR before IDAT");
484         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
485                  !(png_ptr->mode & PNG_HAVE_PLTE))
486            png_error(png_ptr, "Missing PLTE before IDAT");
487
488         png_ptr->idat_size = length;
489         png_ptr->mode |= PNG_HAVE_IDAT;
490         break;
491      }
492#ifdef PNG_READ_bKGD_SUPPORTED
493      else if (!png_memcmp(chunk_name, png_bKGD, 4))
494         png_handle_bKGD(png_ptr, info_ptr, length);
495#endif
496#ifdef PNG_READ_cHRM_SUPPORTED
497      else if (!png_memcmp(chunk_name, png_cHRM, 4))
498         png_handle_cHRM(png_ptr, info_ptr, length);
499#endif
500#ifdef PNG_READ_gAMA_SUPPORTED
501      else if (!png_memcmp(chunk_name, png_gAMA, 4))
502         png_handle_gAMA(png_ptr, info_ptr, length);
503#endif
504#ifdef PNG_READ_hIST_SUPPORTED
505      else if (!png_memcmp(chunk_name, png_hIST, 4))
506         png_handle_hIST(png_ptr, info_ptr, length);
507#endif
508#ifdef PNG_READ_oFFs_SUPPORTED
509      else if (!png_memcmp(chunk_name, png_oFFs, 4))
510         png_handle_oFFs(png_ptr, info_ptr, length);
511#endif
512#ifdef PNG_READ_pCAL_SUPPORTED
513      else if (!png_memcmp(chunk_name, png_pCAL, 4))
514         png_handle_pCAL(png_ptr, info_ptr, length);
515#endif
516#ifdef PNG_READ_sCAL_SUPPORTED
517      else if (!png_memcmp(chunk_name, png_sCAL, 4))
518         png_handle_sCAL(png_ptr, info_ptr, length);
519#endif
520#ifdef PNG_READ_pHYs_SUPPORTED
521      else if (!png_memcmp(chunk_name, png_pHYs, 4))
522         png_handle_pHYs(png_ptr, info_ptr, length);
523#endif
524#ifdef PNG_READ_sBIT_SUPPORTED
525      else if (!png_memcmp(chunk_name, png_sBIT, 4))
526         png_handle_sBIT(png_ptr, info_ptr, length);
527#endif
528#ifdef PNG_READ_sRGB_SUPPORTED
529      else if (!png_memcmp(chunk_name, png_sRGB, 4))
530         png_handle_sRGB(png_ptr, info_ptr, length);
531#endif
532#ifdef PNG_READ_iCCP_SUPPORTED
533      else if (!png_memcmp(chunk_name, png_iCCP, 4))
534         png_handle_iCCP(png_ptr, info_ptr, length);
535#endif
536#ifdef PNG_READ_sPLT_SUPPORTED
537      else if (!png_memcmp(chunk_name, png_sPLT, 4))
538         png_handle_sPLT(png_ptr, info_ptr, length);
539#endif
540#ifdef PNG_READ_tEXt_SUPPORTED
541      else if (!png_memcmp(chunk_name, png_tEXt, 4))
542         png_handle_tEXt(png_ptr, info_ptr, length);
543#endif
544#ifdef PNG_READ_tIME_SUPPORTED
545      else if (!png_memcmp(chunk_name, png_tIME, 4))
546         png_handle_tIME(png_ptr, info_ptr, length);
547#endif
548#ifdef PNG_READ_tRNS_SUPPORTED
549      else if (!png_memcmp(chunk_name, png_tRNS, 4))
550         png_handle_tRNS(png_ptr, info_ptr, length);
551#endif
552#ifdef PNG_READ_zTXt_SUPPORTED
553      else if (!png_memcmp(chunk_name, png_zTXt, 4))
554         png_handle_zTXt(png_ptr, info_ptr, length);
555#endif
556#ifdef PNG_READ_iTXt_SUPPORTED
557      else if (!png_memcmp(chunk_name, png_iTXt, 4))
558         png_handle_iTXt(png_ptr, info_ptr, length);
559#endif
560      else
561         png_handle_unknown(png_ptr, info_ptr, length);
562   }
563}
564#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
565
566/* Optional call to update the users info_ptr structure */
567void PNGAPI
568png_read_update_info(png_structp png_ptr, png_infop info_ptr)
569{
570   png_debug(1, "in png_read_update_info");
571
572   if (png_ptr == NULL)
573      return;
574#ifdef PNG_INDEX_SUPPORTED
575   if (png_ptr->index) {
576      png_read_start_row(png_ptr);
577   }
578#endif
579   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
580      png_read_start_row(png_ptr);
581   else
582      png_warning(png_ptr,
583      "Ignoring extra png_read_update_info() call; row buffer not reallocated");
584
585   png_read_transform_info(png_ptr, info_ptr);
586}
587
588#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
589/* Initialize palette, background, etc, after transformations
590 * are set, but before any reading takes place.  This allows
591 * the user to obtain a gamma-corrected palette, for example.
592 * If the user doesn't call this, we will do it ourselves.
593 */
594void PNGAPI
595png_start_read_image(png_structp png_ptr)
596{
597   png_debug(1, "in png_start_read_image");
598
599   if (png_ptr == NULL)
600      return;
601   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
602      png_read_start_row(png_ptr);
603}
604#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
605
606#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
607void PNGAPI
608png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
609{
610   PNG_CONST PNG_IDAT;
611   PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
612      0xff};
613   PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
614   int ret;
615
616   if (png_ptr == NULL)
617      return;
618
619   png_debug2(1, "in png_read_row (row %lu, pass %d)",
620      png_ptr->row_number, png_ptr->pass);
621
622   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
623      png_read_start_row(png_ptr);
624   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
625   {
626   /* Check for transforms that have been set but were defined out */
627#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
628   if (png_ptr->transformations & PNG_INVERT_MONO)
629      png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined.");
630#endif
631#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
632   if (png_ptr->transformations & PNG_FILLER)
633      png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined.");
634#endif
635#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
636    !defined(PNG_READ_PACKSWAP_SUPPORTED)
637   if (png_ptr->transformations & PNG_PACKSWAP)
638      png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined.");
639#endif
640#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
641   if (png_ptr->transformations & PNG_PACK)
642      png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined.");
643#endif
644#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
645   if (png_ptr->transformations & PNG_SHIFT)
646      png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined.");
647#endif
648#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
649   if (png_ptr->transformations & PNG_BGR)
650      png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined.");
651#endif
652#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
653   if (png_ptr->transformations & PNG_SWAP_BYTES)
654      png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined.");
655#endif
656   }
657
658#ifdef PNG_READ_INTERLACING_SUPPORTED
659   /* If interlaced and we do not need a new row, combine row and return */
660   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
661   {
662      switch (png_ptr->pass)
663      {
664         case 0:
665            if (png_ptr->row_number & 0x07)
666            {
667               if (dsp_row != NULL)
668                  png_combine_row(png_ptr, dsp_row,
669                     png_pass_dsp_mask[png_ptr->pass]);
670               png_read_finish_row(png_ptr);
671               return;
672            }
673            break;
674         case 1:
675            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
676            {
677               if (dsp_row != NULL)
678                  png_combine_row(png_ptr, dsp_row,
679                     png_pass_dsp_mask[png_ptr->pass]);
680               png_read_finish_row(png_ptr);
681               return;
682            }
683            break;
684         case 2:
685            if ((png_ptr->row_number & 0x07) != 4)
686            {
687               if (dsp_row != NULL && (png_ptr->row_number & 4))
688                  png_combine_row(png_ptr, dsp_row,
689                     png_pass_dsp_mask[png_ptr->pass]);
690               png_read_finish_row(png_ptr);
691               return;
692            }
693            break;
694         case 3:
695            if ((png_ptr->row_number & 3) || png_ptr->width < 3)
696            {
697               if (dsp_row != NULL)
698                  png_combine_row(png_ptr, dsp_row,
699                     png_pass_dsp_mask[png_ptr->pass]);
700               png_read_finish_row(png_ptr);
701               return;
702            }
703            break;
704         case 4:
705            if ((png_ptr->row_number & 3) != 2)
706            {
707               if (dsp_row != NULL && (png_ptr->row_number & 2))
708                  png_combine_row(png_ptr, dsp_row,
709                     png_pass_dsp_mask[png_ptr->pass]);
710               png_read_finish_row(png_ptr);
711               return;
712            }
713            break;
714         case 5:
715            if ((png_ptr->row_number & 1) || png_ptr->width < 2)
716            {
717               if (dsp_row != NULL)
718                  png_combine_row(png_ptr, dsp_row,
719                     png_pass_dsp_mask[png_ptr->pass]);
720               png_read_finish_row(png_ptr);
721               return;
722            }
723            break;
724         case 6:
725            if (!(png_ptr->row_number & 1))
726            {
727               png_read_finish_row(png_ptr);
728               return;
729            }
730            break;
731      }
732   }
733#endif
734
735   if (!(png_ptr->mode & PNG_HAVE_IDAT))
736      png_error(png_ptr, "Invalid attempt to read row data");
737
738   png_ptr->zstream.next_out = png_ptr->row_buf;
739   png_ptr->zstream.avail_out =
740       (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
741       png_ptr->iwidth) + 1);
742   do
743   {
744      if (!(png_ptr->zstream.avail_in))
745      {
746         while (!png_ptr->idat_size)
747         {
748#ifdef PNG_INDEX_SUPPORTED
749            if (png_ptr->index) {
750               png_opt_crc_finish(png_ptr, 0, 0);
751               png_ptr->index->stream_idat_position = png_ptr->total_data_read;
752            } else
753#endif
754               png_crc_finish(png_ptr, 0);
755
756
757            png_ptr->idat_size = png_read_chunk_header(png_ptr);
758            if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
759               png_error(png_ptr, "Not enough image data");
760         }
761         png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
762         png_ptr->zstream.next_in = png_ptr->zbuf;
763         if (png_ptr->zbuf_size > png_ptr->idat_size)
764            png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
765         png_crc_read(png_ptr, png_ptr->zbuf,
766            (png_size_t)png_ptr->zstream.avail_in);
767         png_ptr->idat_size -= png_ptr->zstream.avail_in;
768      }
769      ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
770      if (ret == Z_STREAM_END)
771      {
772         if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
773            png_ptr->idat_size)
774            png_error(png_ptr, "Extra compressed data");
775         png_ptr->mode |= PNG_AFTER_IDAT;
776         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
777         break;
778      }
779      if (ret != Z_OK) {
780#ifdef PNG_INDEX_SUPPORTED
781         if (png_ptr->index) {
782            if (png_ptr->row_number != png_ptr->height - 1) {
783               png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
784                     "Decompression error");
785            }
786         } else
787#endif
788            png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
789                  "Decompression error");
790      }
791   } while (png_ptr->zstream.avail_out);
792
793   png_ptr->row_info.color_type = png_ptr->color_type;
794   png_ptr->row_info.width = png_ptr->iwidth;
795   png_ptr->row_info.channels = png_ptr->channels;
796   png_ptr->row_info.bit_depth = png_ptr->bit_depth;
797   png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
798   png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
799       png_ptr->row_info.width);
800
801   if (png_ptr->row_buf[0])
802   png_read_filter_row(png_ptr, &(png_ptr->row_info),
803      png_ptr->row_buf + 1, png_ptr->prev_row + 1,
804      (int)(png_ptr->row_buf[0]));
805
806   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
807      png_ptr->rowbytes + 1);
808
809#ifdef PNG_MNG_FEATURES_SUPPORTED
810   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
811      (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
812   {
813      /* Intrapixel differencing */
814      png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
815   }
816#endif
817
818
819   if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
820      png_do_read_transformations(png_ptr);
821
822#ifdef PNG_READ_INTERLACING_SUPPORTED
823   /* Blow up interlaced rows to full size */
824   if (png_ptr->interlaced &&
825      (png_ptr->transformations & PNG_INTERLACE))
826   {
827      if (png_ptr->pass < 6)
828         /* Old interface (pre-1.0.9):
829          * png_do_read_interlace(&(png_ptr->row_info),
830          *    png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
831          */
832         png_do_read_interlace(png_ptr);
833
834      if (dsp_row != NULL)
835         png_combine_row(png_ptr, dsp_row,
836            png_pass_dsp_mask[png_ptr->pass]);
837      if (row != NULL)
838         png_combine_row(png_ptr, row,
839            png_pass_mask[png_ptr->pass]);
840   }
841   else
842#endif
843   {
844      if (row != NULL)
845         png_combine_row(png_ptr, row, 0xff);
846      if (dsp_row != NULL)
847         png_combine_row(png_ptr, dsp_row, 0xff);
848   }
849   png_read_finish_row(png_ptr);
850
851   if (png_ptr->read_row_fn != NULL)
852      (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
853}
854#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
855
856#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
857/* Read one or more rows of image data.  If the image is interlaced,
858 * and png_set_interlace_handling() has been called, the rows need to
859 * contain the contents of the rows from the previous pass.  If the
860 * image has alpha or transparency, and png_handle_alpha()[*] has been
861 * called, the rows contents must be initialized to the contents of the
862 * screen.
863 *
864 * "row" holds the actual image, and pixels are placed in it
865 * as they arrive.  If the image is displayed after each pass, it will
866 * appear to "sparkle" in.  "display_row" can be used to display a
867 * "chunky" progressive image, with finer detail added as it becomes
868 * available.  If you do not want this "chunky" display, you may pass
869 * NULL for display_row.  If you do not want the sparkle display, and
870 * you have not called png_handle_alpha(), you may pass NULL for rows.
871 * If you have called png_handle_alpha(), and the image has either an
872 * alpha channel or a transparency chunk, you must provide a buffer for
873 * rows.  In this case, you do not have to provide a display_row buffer
874 * also, but you may.  If the image is not interlaced, or if you have
875 * not called png_set_interlace_handling(), the display_row buffer will
876 * be ignored, so pass NULL to it.
877 *
878 * [*] png_handle_alpha() does not exist yet, as of this version of libpng
879 */
880
881void PNGAPI
882png_read_rows(png_structp png_ptr, png_bytepp row,
883   png_bytepp display_row, png_uint_32 num_rows)
884{
885   png_uint_32 i;
886   png_bytepp rp;
887   png_bytepp dp;
888
889   png_debug(1, "in png_read_rows");
890
891   if (png_ptr == NULL)
892      return;
893   rp = row;
894   dp = display_row;
895   if (rp != NULL && dp != NULL)
896      for (i = 0; i < num_rows; i++)
897      {
898         png_bytep rptr = *rp++;
899         png_bytep dptr = *dp++;
900
901         png_read_row(png_ptr, rptr, dptr);
902      }
903   else if (rp != NULL)
904      for (i = 0; i < num_rows; i++)
905      {
906         png_bytep rptr = *rp;
907         png_read_row(png_ptr, rptr, png_bytep_NULL);
908         rp++;
909      }
910   else if (dp != NULL)
911      for (i = 0; i < num_rows; i++)
912      {
913         png_bytep dptr = *dp;
914         png_read_row(png_ptr, png_bytep_NULL, dptr);
915         dp++;
916      }
917}
918#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
919
920#ifdef PNG_INDEX_SUPPORTED
921#define IDAT_HEADER_SIZE 8
922
923/* Set the png read position to a new position based on idat_position and
924 * offset.
925 */
926void
927png_set_read_offset(png_structp png_ptr,
928      png_uint_32 idat_position, png_uint_32 bytes_left)
929{
930   png_seek_data(png_ptr, idat_position);
931   png_ptr->idat_size = png_read_chunk_header(png_ptr);
932
933   // We need to add back IDAT_HEADER_SIZE because in zlib's perspective,
934   // IDAT_HEADER in PNG is already stripped out.
935   png_seek_data(png_ptr, idat_position + IDAT_HEADER_SIZE + png_ptr->idat_size - bytes_left);
936   png_ptr->idat_size = bytes_left;
937}
938
939/* Configure png decoder to decode the pass starting from *row.
940 * The requested row may be adjusted to align with an indexing row.
941 * The actual row for the decoder to start its decoding will be returned in
942 * *row.
943 */
944void PNGAPI
945png_configure_decoder(png_structp png_ptr, int *row, int pass)
946{
947   png_indexp index = png_ptr->index;
948   int n = *row / index->step[pass];
949   png_line_indexp line_index = index->pass_line_index[pass][n];
950
951   // Adjust row to an indexing row.
952   *row = n * index->step[pass];
953   png_ptr->row_number = *row;
954
955#ifdef PNG_READ_INTERLACING_SUPPORTED
956   if (png_ptr->interlaced)
957      png_set_interlaced_pass(png_ptr, pass);
958#endif
959
960   long row_byte_length =
961      PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1;
962
963   inflateEnd(&png_ptr->zstream);
964   inflateCopy(&png_ptr->zstream, line_index->z_state);
965
966   // Set the png read position to line_index.
967   png_set_read_offset(png_ptr, line_index->stream_idat_position,
968         line_index->bytes_left_in_idat);
969   png_memcpy_check(png_ptr,
970         png_ptr->prev_row, line_index->prev_row, row_byte_length);
971   png_ptr->zstream.avail_in = 0;
972}
973
974/* Build the line index and store the index in png_ptr->index.
975 */
976void PNGAPI
977png_build_index(png_structp png_ptr)
978{
979   // number of rows in a 8x8 block for each interlaced pass.
980   int number_rows_in_pass[7] = {1, 1, 1, 2, 2, 4, 4};
981
982   int ret;
983   png_uint_32 i, j;
984   png_bytep rp;
985   int p, pass_number = 1;
986
987#ifdef PNG_READ_INTERLACING_SUPPORTED
988   pass_number = png_set_interlace_handling(png_ptr);
989#endif
990
991   if (png_ptr == NULL)
992      return;
993
994   png_read_start_row(png_ptr);
995
996#ifdef PNG_READ_INTERLACING_SUPPORTED
997   if (!png_ptr->interlaced)
998#endif
999   {
1000      number_rows_in_pass[0] = 8;
1001   }
1002
1003   rp = png_malloc(png_ptr, png_ptr->rowbytes);
1004
1005   png_indexp index = png_malloc(png_ptr, sizeof(png_index));
1006   png_ptr->index = index;
1007
1008   index->stream_idat_position = png_ptr->total_data_read - IDAT_HEADER_SIZE;
1009
1010   // Set the default size of index in each pass to 0,
1011   // so that we can free index correctly in png_destroy_read_struct.
1012   for (p = 0; p < 7; p++)
1013      index->size[p] = 0;
1014
1015   for (p = 0; p < pass_number; p++)
1016   {
1017      // We adjust the index step in each pass to make sure each pass
1018      // has roughly the same size of index.
1019      // This way, we won't consume to much memory in recording index.
1020      index->step[p] = INDEX_SAMPLE_SIZE * (8 / number_rows_in_pass[p]);
1021      index->size[p] =
1022         (png_ptr->height + index->step[p] - 1) / index->step[p];
1023      index->pass_line_index[p] =
1024         png_malloc(png_ptr, index->size[p] * sizeof(png_line_indexp));
1025
1026      // Get the row_byte_length seen by the filter. This value may be
1027      // different from the row_byte_length of a bitmap in the case of
1028      // color palette mode.
1029      int row_byte_length =
1030         PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1;
1031
1032      // Now, we record index for each indexing row.
1033      for (i = 0; i < index->size[p]; i++)
1034      {
1035         png_line_indexp line_index = png_malloc(png_ptr, sizeof(png_line_index));
1036         index->pass_line_index[p][i] = line_index;
1037
1038         line_index->z_state = png_malloc(png_ptr, sizeof(z_stream));
1039         inflateCopy(line_index->z_state, &png_ptr->zstream);
1040         line_index->prev_row = png_malloc(png_ptr, row_byte_length);
1041         png_memcpy_check(png_ptr,
1042               line_index->prev_row, png_ptr->prev_row, row_byte_length);
1043         line_index->stream_idat_position = index->stream_idat_position;
1044         line_index->bytes_left_in_idat = png_ptr->idat_size + png_ptr->zstream.avail_in;
1045
1046         // Skip the "step" number of rows to the next indexing row.
1047         for (j = 0; j < index->step[p] &&
1048               i * index->step[p] + j < png_ptr->height; j++)
1049         {
1050            png_read_row(png_ptr, rp, png_bytep_NULL);
1051         }
1052      }
1053   }
1054   png_free(png_ptr, rp);
1055}
1056#endif
1057
1058#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1059/* Read the entire image.  If the image has an alpha channel or a tRNS
1060 * chunk, and you have called png_handle_alpha()[*], you will need to
1061 * initialize the image to the current image that PNG will be overlaying.
1062 * We set the num_rows again here, in case it was incorrectly set in
1063 * png_read_start_row() by a call to png_read_update_info() or
1064 * png_start_read_image() if png_set_interlace_handling() wasn't called
1065 * prior to either of these functions like it should have been.  You can
1066 * only call this function once.  If you desire to have an image for
1067 * each pass of a interlaced image, use png_read_rows() instead.
1068 *
1069 * [*] png_handle_alpha() does not exist yet, as of this version of libpng
1070 */
1071void PNGAPI
1072png_read_image(png_structp png_ptr, png_bytepp image)
1073{
1074   png_uint_32 i, image_height;
1075   int pass, j;
1076   png_bytepp rp;
1077
1078   png_debug(1, "in png_read_image");
1079
1080   if (png_ptr == NULL)
1081      return;
1082
1083#ifdef PNG_READ_INTERLACING_SUPPORTED
1084   pass = png_set_interlace_handling(png_ptr);
1085#else
1086   if (png_ptr->interlaced)
1087      png_error(png_ptr,
1088        "Cannot read interlaced image -- interlace handler disabled.");
1089   pass = 1;
1090#endif
1091
1092
1093   image_height=png_ptr->height;
1094   png_ptr->num_rows = image_height; /* Make sure this is set correctly */
1095
1096   for (j = 0; j < pass; j++)
1097   {
1098      rp = image;
1099      for (i = 0; i < image_height; i++)
1100      {
1101         png_read_row(png_ptr, *rp, png_bytep_NULL);
1102         rp++;
1103      }
1104   }
1105}
1106#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
1107
1108#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1109/* Read the end of the PNG file.  Will not read past the end of the
1110 * file, will verify the end is accurate, and will read any comments
1111 * or time information at the end of the file, if info is not NULL.
1112 */
1113void PNGAPI
1114png_read_end(png_structp png_ptr, png_infop info_ptr)
1115{
1116   png_debug(1, "in png_read_end");
1117
1118   if (png_ptr == NULL)
1119      return;
1120   png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
1121
1122   do
1123   {
1124#ifdef PNG_USE_LOCAL_ARRAYS
1125      PNG_CONST PNG_IHDR;
1126      PNG_CONST PNG_IDAT;
1127      PNG_CONST PNG_IEND;
1128      PNG_CONST PNG_PLTE;
1129#ifdef PNG_READ_bKGD_SUPPORTED
1130      PNG_CONST PNG_bKGD;
1131#endif
1132#ifdef PNG_READ_cHRM_SUPPORTED
1133      PNG_CONST PNG_cHRM;
1134#endif
1135#ifdef PNG_READ_gAMA_SUPPORTED
1136      PNG_CONST PNG_gAMA;
1137#endif
1138#ifdef PNG_READ_hIST_SUPPORTED
1139      PNG_CONST PNG_hIST;
1140#endif
1141#ifdef PNG_READ_iCCP_SUPPORTED
1142      PNG_CONST PNG_iCCP;
1143#endif
1144#ifdef PNG_READ_iTXt_SUPPORTED
1145      PNG_CONST PNG_iTXt;
1146#endif
1147#ifdef PNG_READ_oFFs_SUPPORTED
1148      PNG_CONST PNG_oFFs;
1149#endif
1150#ifdef PNG_READ_pCAL_SUPPORTED
1151      PNG_CONST PNG_pCAL;
1152#endif
1153#ifdef PNG_READ_pHYs_SUPPORTED
1154      PNG_CONST PNG_pHYs;
1155#endif
1156#ifdef PNG_READ_sBIT_SUPPORTED
1157      PNG_CONST PNG_sBIT;
1158#endif
1159#ifdef PNG_READ_sCAL_SUPPORTED
1160      PNG_CONST PNG_sCAL;
1161#endif
1162#ifdef PNG_READ_sPLT_SUPPORTED
1163      PNG_CONST PNG_sPLT;
1164#endif
1165#ifdef PNG_READ_sRGB_SUPPORTED
1166      PNG_CONST PNG_sRGB;
1167#endif
1168#ifdef PNG_READ_tEXt_SUPPORTED
1169      PNG_CONST PNG_tEXt;
1170#endif
1171#ifdef PNG_READ_tIME_SUPPORTED
1172      PNG_CONST PNG_tIME;
1173#endif
1174#ifdef PNG_READ_tRNS_SUPPORTED
1175      PNG_CONST PNG_tRNS;
1176#endif
1177#ifdef PNG_READ_zTXt_SUPPORTED
1178      PNG_CONST PNG_zTXt;
1179#endif
1180#endif /* PNG_USE_LOCAL_ARRAYS */
1181      png_uint_32 length = png_read_chunk_header(png_ptr);
1182      PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
1183
1184      if (!png_memcmp(chunk_name, png_IHDR, 4))
1185         png_handle_IHDR(png_ptr, info_ptr, length);
1186      else if (!png_memcmp(chunk_name, png_IEND, 4))
1187         png_handle_IEND(png_ptr, info_ptr, length);
1188#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
1189      else if (png_handle_as_unknown(png_ptr, chunk_name))
1190      {
1191         if (!png_memcmp(chunk_name, png_IDAT, 4))
1192         {
1193            if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
1194               png_error(png_ptr, "Too many IDAT's found");
1195         }
1196         png_handle_unknown(png_ptr, info_ptr, length);
1197         if (!png_memcmp(chunk_name, png_PLTE, 4))
1198            png_ptr->mode |= PNG_HAVE_PLTE;
1199      }
1200#endif
1201      else if (!png_memcmp(chunk_name, png_IDAT, 4))
1202      {
1203         /* Zero length IDATs are legal after the last IDAT has been
1204          * read, but not after other chunks have been read.
1205          */
1206         if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
1207            png_error(png_ptr, "Too many IDAT's found");
1208         png_crc_finish(png_ptr, length);
1209      }
1210      else if (!png_memcmp(chunk_name, png_PLTE, 4))
1211         png_handle_PLTE(png_ptr, info_ptr, length);
1212#ifdef PNG_READ_bKGD_SUPPORTED
1213      else if (!png_memcmp(chunk_name, png_bKGD, 4))
1214         png_handle_bKGD(png_ptr, info_ptr, length);
1215#endif
1216#ifdef PNG_READ_cHRM_SUPPORTED
1217      else if (!png_memcmp(chunk_name, png_cHRM, 4))
1218         png_handle_cHRM(png_ptr, info_ptr, length);
1219#endif
1220#ifdef PNG_READ_gAMA_SUPPORTED
1221      else if (!png_memcmp(chunk_name, png_gAMA, 4))
1222         png_handle_gAMA(png_ptr, info_ptr, length);
1223#endif
1224#ifdef PNG_READ_hIST_SUPPORTED
1225      else if (!png_memcmp(chunk_name, png_hIST, 4))
1226         png_handle_hIST(png_ptr, info_ptr, length);
1227#endif
1228#ifdef PNG_READ_oFFs_SUPPORTED
1229      else if (!png_memcmp(chunk_name, png_oFFs, 4))
1230         png_handle_oFFs(png_ptr, info_ptr, length);
1231#endif
1232#ifdef PNG_READ_pCAL_SUPPORTED
1233      else if (!png_memcmp(chunk_name, png_pCAL, 4))
1234         png_handle_pCAL(png_ptr, info_ptr, length);
1235#endif
1236#ifdef PNG_READ_sCAL_SUPPORTED
1237      else if (!png_memcmp(chunk_name, png_sCAL, 4))
1238         png_handle_sCAL(png_ptr, info_ptr, length);
1239#endif
1240#ifdef PNG_READ_pHYs_SUPPORTED
1241      else if (!png_memcmp(chunk_name, png_pHYs, 4))
1242         png_handle_pHYs(png_ptr, info_ptr, length);
1243#endif
1244#ifdef PNG_READ_sBIT_SUPPORTED
1245      else if (!png_memcmp(chunk_name, png_sBIT, 4))
1246         png_handle_sBIT(png_ptr, info_ptr, length);
1247#endif
1248#ifdef PNG_READ_sRGB_SUPPORTED
1249      else if (!png_memcmp(chunk_name, png_sRGB, 4))
1250         png_handle_sRGB(png_ptr, info_ptr, length);
1251#endif
1252#ifdef PNG_READ_iCCP_SUPPORTED
1253      else if (!png_memcmp(chunk_name, png_iCCP, 4))
1254         png_handle_iCCP(png_ptr, info_ptr, length);
1255#endif
1256#ifdef PNG_READ_sPLT_SUPPORTED
1257      else if (!png_memcmp(chunk_name, png_sPLT, 4))
1258         png_handle_sPLT(png_ptr, info_ptr, length);
1259#endif
1260#ifdef PNG_READ_tEXt_SUPPORTED
1261      else if (!png_memcmp(chunk_name, png_tEXt, 4))
1262         png_handle_tEXt(png_ptr, info_ptr, length);
1263#endif
1264#ifdef PNG_READ_tIME_SUPPORTED
1265      else if (!png_memcmp(chunk_name, png_tIME, 4))
1266         png_handle_tIME(png_ptr, info_ptr, length);
1267#endif
1268#ifdef PNG_READ_tRNS_SUPPORTED
1269      else if (!png_memcmp(chunk_name, png_tRNS, 4))
1270         png_handle_tRNS(png_ptr, info_ptr, length);
1271#endif
1272#ifdef PNG_READ_zTXt_SUPPORTED
1273      else if (!png_memcmp(chunk_name, png_zTXt, 4))
1274         png_handle_zTXt(png_ptr, info_ptr, length);
1275#endif
1276#ifdef PNG_READ_iTXt_SUPPORTED
1277      else if (!png_memcmp(chunk_name, png_iTXt, 4))
1278         png_handle_iTXt(png_ptr, info_ptr, length);
1279#endif
1280      else
1281         png_handle_unknown(png_ptr, info_ptr, length);
1282   } while (!(png_ptr->mode & PNG_HAVE_IEND));
1283}
1284#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
1285
1286/* Free all memory used by the read */
1287void PNGAPI
1288png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
1289   png_infopp end_info_ptr_ptr)
1290{
1291   png_structp png_ptr = NULL;
1292   png_infop info_ptr = NULL, end_info_ptr = NULL;
1293#ifdef PNG_USER_MEM_SUPPORTED
1294   png_free_ptr free_fn = NULL;
1295   png_voidp mem_ptr = NULL;
1296#endif
1297
1298   png_debug(1, "in png_destroy_read_struct");
1299
1300   if (png_ptr_ptr != NULL)
1301      png_ptr = *png_ptr_ptr;
1302   if (png_ptr == NULL)
1303      return;
1304
1305#ifdef PNG_USER_MEM_SUPPORTED
1306   free_fn = png_ptr->free_fn;
1307   mem_ptr = png_ptr->mem_ptr;
1308#endif
1309
1310   if (info_ptr_ptr != NULL)
1311      info_ptr = *info_ptr_ptr;
1312
1313   if (end_info_ptr_ptr != NULL)
1314      end_info_ptr = *end_info_ptr_ptr;
1315
1316   png_read_destroy(png_ptr, info_ptr, end_info_ptr);
1317
1318   if (info_ptr != NULL)
1319   {
1320#ifdef PNG_TEXT_SUPPORTED
1321      png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
1322#endif
1323
1324#ifdef PNG_USER_MEM_SUPPORTED
1325      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
1326          (png_voidp)mem_ptr);
1327#else
1328      png_destroy_struct((png_voidp)info_ptr);
1329#endif
1330      *info_ptr_ptr = NULL;
1331   }
1332
1333   if (end_info_ptr != NULL)
1334   {
1335#ifdef PNG_READ_TEXT_SUPPORTED
1336      png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
1337#endif
1338#ifdef PNG_USER_MEM_SUPPORTED
1339      png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
1340         (png_voidp)mem_ptr);
1341#else
1342      png_destroy_struct((png_voidp)end_info_ptr);
1343#endif
1344      *end_info_ptr_ptr = NULL;
1345   }
1346
1347   if (png_ptr != NULL)
1348   {
1349#ifdef PNG_INDEX_SUPPORTED
1350      if (png_ptr->index) {
1351         unsigned int i, p;
1352         png_indexp index = png_ptr->index;
1353         for (p = 0; p < 7; p++) {
1354            for (i = 0; i < index->size[p]; i++) {
1355               inflateEnd(index->pass_line_index[p][i]->z_state);
1356               png_free(png_ptr, index->pass_line_index[p][i]->z_state);
1357               png_free(png_ptr, index->pass_line_index[p][i]->prev_row);
1358               png_free(png_ptr, index->pass_line_index[p][i]);
1359            }
1360            if (index->size[p] != 0) {
1361               png_free(png_ptr, index->pass_line_index[p]);
1362            }
1363         }
1364         png_free(png_ptr, index);
1365      }
1366#endif
1367#ifdef PNG_USER_MEM_SUPPORTED
1368      png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
1369          (png_voidp)mem_ptr);
1370#else
1371      png_destroy_struct((png_voidp)png_ptr);
1372#endif
1373      *png_ptr_ptr = NULL;
1374   }
1375}
1376
1377/* Free all memory used by the read (old method) */
1378void /* PRIVATE */
1379png_read_destroy(png_structp png_ptr, png_infop info_ptr,
1380    png_infop end_info_ptr)
1381{
1382#ifdef PNG_SETJMP_SUPPORTED
1383   jmp_buf tmp_jmp;
1384#endif
1385   png_error_ptr error_fn;
1386   png_error_ptr warning_fn;
1387   png_voidp error_ptr;
1388#ifdef PNG_USER_MEM_SUPPORTED
1389   png_free_ptr free_fn;
1390#endif
1391
1392   png_debug(1, "in png_read_destroy");
1393
1394   if (info_ptr != NULL)
1395      png_info_destroy(png_ptr, info_ptr);
1396
1397   if (end_info_ptr != NULL)
1398      png_info_destroy(png_ptr, end_info_ptr);
1399
1400   png_free(png_ptr, png_ptr->zbuf);
1401   png_free(png_ptr, png_ptr->big_row_buf);
1402   png_free(png_ptr, png_ptr->prev_row);
1403   png_free(png_ptr, png_ptr->chunkdata);
1404#ifdef PNG_READ_DITHER_SUPPORTED
1405   png_free(png_ptr, png_ptr->palette_lookup);
1406   png_free(png_ptr, png_ptr->dither_index);
1407#endif
1408#ifdef PNG_READ_GAMMA_SUPPORTED
1409   png_free(png_ptr, png_ptr->gamma_table);
1410#endif
1411#ifdef PNG_READ_BACKGROUND_SUPPORTED
1412   png_free(png_ptr, png_ptr->gamma_from_1);
1413   png_free(png_ptr, png_ptr->gamma_to_1);
1414#endif
1415#ifdef PNG_FREE_ME_SUPPORTED
1416   if (png_ptr->free_me & PNG_FREE_PLTE)
1417      png_zfree(png_ptr, png_ptr->palette);
1418   png_ptr->free_me &= ~PNG_FREE_PLTE;
1419#else
1420   if (png_ptr->flags & PNG_FLAG_FREE_PLTE)
1421      png_zfree(png_ptr, png_ptr->palette);
1422   png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
1423#endif
1424#if defined(PNG_tRNS_SUPPORTED) || \
1425    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
1426#ifdef PNG_FREE_ME_SUPPORTED
1427   if (png_ptr->free_me & PNG_FREE_TRNS)
1428      png_free(png_ptr, png_ptr->trans);
1429   png_ptr->free_me &= ~PNG_FREE_TRNS;
1430#else
1431   if (png_ptr->flags & PNG_FLAG_FREE_TRNS)
1432      png_free(png_ptr, png_ptr->trans);
1433   png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
1434#endif
1435#endif
1436#ifdef PNG_READ_hIST_SUPPORTED
1437#ifdef PNG_FREE_ME_SUPPORTED
1438   if (png_ptr->free_me & PNG_FREE_HIST)
1439      png_free(png_ptr, png_ptr->hist);
1440   png_ptr->free_me &= ~PNG_FREE_HIST;
1441#else
1442   if (png_ptr->flags & PNG_FLAG_FREE_HIST)
1443      png_free(png_ptr, png_ptr->hist);
1444   png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
1445#endif
1446#endif
1447#ifdef PNG_READ_GAMMA_SUPPORTED
1448   if (png_ptr->gamma_16_table != NULL)
1449   {
1450      int i;
1451      int istop = (1 << (8 - png_ptr->gamma_shift));
1452      for (i = 0; i < istop; i++)
1453      {
1454         png_free(png_ptr, png_ptr->gamma_16_table[i]);
1455      }
1456   png_free(png_ptr, png_ptr->gamma_16_table);
1457   }
1458#ifdef PNG_READ_BACKGROUND_SUPPORTED
1459   if (png_ptr->gamma_16_from_1 != NULL)
1460   {
1461      int i;
1462      int istop = (1 << (8 - png_ptr->gamma_shift));
1463      for (i = 0; i < istop; i++)
1464      {
1465         png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
1466      }
1467   png_free(png_ptr, png_ptr->gamma_16_from_1);
1468   }
1469   if (png_ptr->gamma_16_to_1 != NULL)
1470   {
1471      int i;
1472      int istop = (1 << (8 - png_ptr->gamma_shift));
1473      for (i = 0; i < istop; i++)
1474      {
1475         png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
1476      }
1477   png_free(png_ptr, png_ptr->gamma_16_to_1);
1478   }
1479#endif
1480#endif
1481#ifdef PNG_TIME_RFC1123_SUPPORTED
1482   png_free(png_ptr, png_ptr->time_buffer);
1483#endif
1484
1485   inflateEnd(&png_ptr->zstream);
1486#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
1487   png_free(png_ptr, png_ptr->save_buffer);
1488#endif
1489
1490#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
1491#ifdef PNG_TEXT_SUPPORTED
1492   png_free(png_ptr, png_ptr->current_text);
1493#endif /* PNG_TEXT_SUPPORTED */
1494#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
1495
1496   /* Save the important info out of the png_struct, in case it is
1497    * being used again.
1498    */
1499#ifdef PNG_SETJMP_SUPPORTED
1500   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
1501#endif
1502
1503   error_fn = png_ptr->error_fn;
1504   warning_fn = png_ptr->warning_fn;
1505   error_ptr = png_ptr->error_ptr;
1506#ifdef PNG_USER_MEM_SUPPORTED
1507   free_fn = png_ptr->free_fn;
1508#endif
1509
1510   png_memset(png_ptr, 0, png_sizeof(png_struct));
1511
1512   png_ptr->error_fn = error_fn;
1513   png_ptr->warning_fn = warning_fn;
1514   png_ptr->error_ptr = error_ptr;
1515#ifdef PNG_USER_MEM_SUPPORTED
1516   png_ptr->free_fn = free_fn;
1517#endif
1518
1519#ifdef PNG_SETJMP_SUPPORTED
1520   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
1521#endif
1522
1523}
1524
1525void PNGAPI
1526png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
1527{
1528   if (png_ptr == NULL)
1529      return;
1530   png_ptr->read_row_fn = read_row_fn;
1531}
1532
1533
1534#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1535#ifdef PNG_INFO_IMAGE_SUPPORTED
1536void PNGAPI
1537png_read_png(png_structp png_ptr, png_infop info_ptr,
1538                           int transforms,
1539                           voidp params)
1540{
1541   int row;
1542
1543   if (png_ptr == NULL)
1544      return;
1545#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
1546   /* Invert the alpha channel from opacity to transparency
1547    */
1548   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
1549       png_set_invert_alpha(png_ptr);
1550#endif
1551
1552   /* png_read_info() gives us all of the information from the
1553    * PNG file before the first IDAT (image data chunk).
1554    */
1555   png_read_info(png_ptr, info_ptr);
1556   if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
1557      png_error(png_ptr, "Image is too high to process with png_read_png()");
1558
1559   /* -------------- image transformations start here ------------------- */
1560
1561#ifdef PNG_READ_16_TO_8_SUPPORTED
1562   /* Tell libpng to strip 16 bit/color files down to 8 bits per color.
1563    */
1564   if (transforms & PNG_TRANSFORM_STRIP_16)
1565      png_set_strip_16(png_ptr);
1566#endif
1567
1568#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
1569   /* Strip alpha bytes from the input data without combining with
1570    * the background (not recommended).
1571    */
1572   if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
1573      png_set_strip_alpha(png_ptr);
1574#endif
1575
1576#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
1577   /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
1578    * byte into separate bytes (useful for paletted and grayscale images).
1579    */
1580   if (transforms & PNG_TRANSFORM_PACKING)
1581      png_set_packing(png_ptr);
1582#endif
1583
1584#ifdef PNG_READ_PACKSWAP_SUPPORTED
1585   /* Change the order of packed pixels to least significant bit first
1586    * (not useful if you are using png_set_packing).
1587    */
1588   if (transforms & PNG_TRANSFORM_PACKSWAP)
1589      png_set_packswap(png_ptr);
1590#endif
1591
1592#ifdef PNG_READ_EXPAND_SUPPORTED
1593   /* Expand paletted colors into true RGB triplets
1594    * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
1595    * Expand paletted or RGB images with transparency to full alpha
1596    * channels so the data will be available as RGBA quartets.
1597    */
1598   if (transforms & PNG_TRANSFORM_EXPAND)
1599      if ((png_ptr->bit_depth < 8) ||
1600          (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
1601          (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
1602         png_set_expand(png_ptr);
1603#endif
1604
1605   /* We don't handle background color or gamma transformation or dithering.
1606    */
1607
1608#ifdef PNG_READ_INVERT_SUPPORTED
1609   /* Invert monochrome files to have 0 as white and 1 as black
1610    */
1611   if (transforms & PNG_TRANSFORM_INVERT_MONO)
1612      png_set_invert_mono(png_ptr);
1613#endif
1614
1615#ifdef PNG_READ_SHIFT_SUPPORTED
1616   /* If you want to shift the pixel values from the range [0,255] or
1617    * [0,65535] to the original [0,7] or [0,31], or whatever range the
1618    * colors were originally in:
1619    */
1620   if ((transforms & PNG_TRANSFORM_SHIFT)
1621       && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
1622   {
1623      png_color_8p sig_bit;
1624
1625      png_get_sBIT(png_ptr, info_ptr, &sig_bit);
1626      png_set_shift(png_ptr, sig_bit);
1627   }
1628#endif
1629
1630#ifdef PNG_READ_BGR_SUPPORTED
1631   /* Flip the RGB pixels to BGR (or RGBA to BGRA)
1632    */
1633   if (transforms & PNG_TRANSFORM_BGR)
1634      png_set_bgr(png_ptr);
1635#endif
1636
1637#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
1638   /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
1639    */
1640   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
1641       png_set_swap_alpha(png_ptr);
1642#endif
1643
1644#ifdef PNG_READ_SWAP_SUPPORTED
1645   /* Swap bytes of 16 bit files to least significant byte first
1646    */
1647   if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
1648      png_set_swap(png_ptr);
1649#endif
1650
1651/* Added at libpng-1.2.41 */
1652#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
1653   /* Invert the alpha channel from opacity to transparency
1654    */
1655   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
1656       png_set_invert_alpha(png_ptr);
1657#endif
1658
1659/* Added at libpng-1.2.41 */
1660#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1661   /* Expand grayscale image to RGB
1662    */
1663   if (transforms & PNG_TRANSFORM_GRAY_TO_RGB)
1664       png_set_gray_to_rgb(png_ptr);
1665#endif
1666
1667   /* We don't handle adding filler bytes */
1668
1669   /* Optional call to gamma correct and add the background to the palette
1670    * and update info structure.  REQUIRED if you are expecting libpng to
1671    * update the palette for you (i.e., you selected such a transform above).
1672    */
1673   png_read_update_info(png_ptr, info_ptr);
1674
1675   /* -------------- image transformations end here ------------------- */
1676
1677#ifdef PNG_FREE_ME_SUPPORTED
1678   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1679#endif
1680   if (info_ptr->row_pointers == NULL)
1681   {
1682      info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
1683         info_ptr->height * png_sizeof(png_bytep));
1684      png_memset(info_ptr->row_pointers, 0, info_ptr->height
1685         * png_sizeof(png_bytep));
1686
1687#ifdef PNG_FREE_ME_SUPPORTED
1688      info_ptr->free_me |= PNG_FREE_ROWS;
1689#endif
1690
1691      for (row = 0; row < (int)info_ptr->height; row++)
1692         info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
1693            png_get_rowbytes(png_ptr, info_ptr));
1694   }
1695
1696   png_read_image(png_ptr, info_ptr->row_pointers);
1697   info_ptr->valid |= PNG_INFO_IDAT;
1698
1699   /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
1700   png_read_end(png_ptr, info_ptr);
1701
1702   transforms = transforms; /* Quiet compiler warnings */
1703   params = params;
1704
1705}
1706#endif /* PNG_INFO_IMAGE_SUPPORTED */
1707#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
1708#endif /* PNG_READ_SUPPORTED */
1709