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