xref: /plan9/sys/src/cmd/gs/libpng/pngread.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
17dd7cddfSDavid du Colombier 
27dd7cddfSDavid du Colombier /* pngread.c - read a PNG file
37dd7cddfSDavid du Colombier  *
4*593dc095SDavid du Colombier  * libpng 1.2.8 - December 3, 2004
57dd7cddfSDavid du Colombier  * For conditions of distribution and use, see copyright notice in png.h
6*593dc095SDavid du Colombier  * Copyright (c) 1998-2004 Glenn Randers-Pehrson
7*593dc095SDavid du Colombier  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8*593dc095SDavid du Colombier  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
97dd7cddfSDavid du Colombier  *
107dd7cddfSDavid du Colombier  * This file contains routines that an application calls directly to
117dd7cddfSDavid du Colombier  * read a PNG file or stream.
127dd7cddfSDavid du Colombier  */
137dd7cddfSDavid du Colombier 
147dd7cddfSDavid du Colombier #define PNG_INTERNAL
157dd7cddfSDavid du Colombier #include "png.h"
167dd7cddfSDavid du Colombier 
177dd7cddfSDavid du Colombier /* Create a PNG structure for reading, and allocate any memory needed. */
18*593dc095SDavid du Colombier png_structp PNGAPI
png_create_read_struct(png_const_charp user_png_ver,png_voidp error_ptr,png_error_ptr error_fn,png_error_ptr warn_fn)197dd7cddfSDavid du Colombier png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
207dd7cddfSDavid du Colombier    png_error_ptr error_fn, png_error_ptr warn_fn)
217dd7cddfSDavid du Colombier {
22*593dc095SDavid du Colombier 
23*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
24*593dc095SDavid du Colombier    return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
25*593dc095SDavid du Colombier       warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
26*593dc095SDavid du Colombier }
27*593dc095SDavid du Colombier 
28*593dc095SDavid du Colombier /* Alternate create PNG structure for reading, and allocate any memory needed. */
29*593dc095SDavid du Colombier png_structp PNGAPI
png_create_read_struct_2(png_const_charp user_png_ver,png_voidp error_ptr,png_error_ptr error_fn,png_error_ptr warn_fn,png_voidp mem_ptr,png_malloc_ptr malloc_fn,png_free_ptr free_fn)30*593dc095SDavid du Colombier png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
31*593dc095SDavid du Colombier    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
32*593dc095SDavid du Colombier    png_malloc_ptr malloc_fn, png_free_ptr free_fn)
33*593dc095SDavid du Colombier {
34*593dc095SDavid du Colombier #endif /* PNG_USER_MEM_SUPPORTED */
35*593dc095SDavid du Colombier 
367dd7cddfSDavid du Colombier    png_structp png_ptr;
37*593dc095SDavid du Colombier 
38*593dc095SDavid du Colombier #ifdef PNG_SETJMP_SUPPORTED
397dd7cddfSDavid du Colombier #ifdef USE_FAR_KEYWORD
407dd7cddfSDavid du Colombier    jmp_buf jmpbuf;
417dd7cddfSDavid du Colombier #endif
42*593dc095SDavid du Colombier #endif
43*593dc095SDavid du Colombier 
44*593dc095SDavid du Colombier    int i;
45*593dc095SDavid du Colombier 
467dd7cddfSDavid du Colombier    png_debug(1, "in png_create_read_struct\n");
47*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
48*593dc095SDavid du Colombier    png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
49*593dc095SDavid du Colombier       (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
50*593dc095SDavid du Colombier #else
51*593dc095SDavid du Colombier    png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
52*593dc095SDavid du Colombier #endif
53*593dc095SDavid du Colombier    if (png_ptr == NULL)
54*593dc095SDavid du Colombier       return (NULL);
55*593dc095SDavid du Colombier 
56*593dc095SDavid du Colombier #if !defined(PNG_1_0_X)
57*593dc095SDavid du Colombier #ifdef PNG_ASSEMBLER_CODE_SUPPORTED
58*593dc095SDavid du Colombier    png_init_mmx_flags(png_ptr);   /* 1.2.0 addition */
59*593dc095SDavid du Colombier #endif
60*593dc095SDavid du Colombier #endif /* PNG_1_0_X */
61*593dc095SDavid du Colombier 
62*593dc095SDavid du Colombier    /* added at libpng-1.2.6 */
63*593dc095SDavid du Colombier #ifdef PNG_SET_USER_LIMITS_SUPPORTED
64*593dc095SDavid du Colombier    png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
65*593dc095SDavid du Colombier    png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
66*593dc095SDavid du Colombier #endif
67*593dc095SDavid du Colombier 
68*593dc095SDavid du Colombier #ifdef PNG_SETJMP_SUPPORTED
697dd7cddfSDavid du Colombier #ifdef USE_FAR_KEYWORD
707dd7cddfSDavid du Colombier    if (setjmp(jmpbuf))
717dd7cddfSDavid du Colombier #else
727dd7cddfSDavid du Colombier    if (setjmp(png_ptr->jmpbuf))
737dd7cddfSDavid du Colombier #endif
747dd7cddfSDavid du Colombier    {
757dd7cddfSDavid du Colombier       png_free(png_ptr, png_ptr->zbuf);
76*593dc095SDavid du Colombier       png_ptr->zbuf=NULL;
77*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
78*593dc095SDavid du Colombier       png_destroy_struct_2((png_voidp)png_ptr,
79*593dc095SDavid du Colombier          (png_free_ptr)free_fn, (png_voidp)mem_ptr);
80*593dc095SDavid du Colombier #else
81*593dc095SDavid du Colombier       png_destroy_struct((png_voidp)png_ptr);
82*593dc095SDavid du Colombier #endif
83*593dc095SDavid du Colombier       return (NULL);
847dd7cddfSDavid du Colombier    }
857dd7cddfSDavid du Colombier #ifdef USE_FAR_KEYWORD
86*593dc095SDavid du Colombier    png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
877dd7cddfSDavid du Colombier #endif
88*593dc095SDavid du Colombier #endif
89*593dc095SDavid du Colombier 
90*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
91*593dc095SDavid du Colombier    png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
92*593dc095SDavid du Colombier #endif
93*593dc095SDavid du Colombier 
947dd7cddfSDavid du Colombier    png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
957dd7cddfSDavid du Colombier 
96*593dc095SDavid du Colombier    i=0;
97*593dc095SDavid du Colombier    do
98*593dc095SDavid du Colombier    {
99*593dc095SDavid du Colombier      if(user_png_ver[i] != png_libpng_ver[i])
100*593dc095SDavid du Colombier         png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
101*593dc095SDavid du Colombier    } while (png_libpng_ver[i++]);
102*593dc095SDavid du Colombier 
103*593dc095SDavid du Colombier    if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
104*593dc095SDavid du Colombier    {
1057dd7cddfSDavid du Colombier      /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
1067dd7cddfSDavid du Colombier       * we must recompile any applications that use any older library version.
1077dd7cddfSDavid du Colombier       * For versions after libpng 1.0, we will be compatible, so we need
1087dd7cddfSDavid du Colombier       * only check the first digit.
1097dd7cddfSDavid du Colombier       */
1107dd7cddfSDavid du Colombier      if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
111*593dc095SDavid du Colombier          (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
1127dd7cddfSDavid du Colombier          (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
1137dd7cddfSDavid du Colombier      {
114*593dc095SDavid du Colombier #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
115*593dc095SDavid du Colombier         char msg[80];
116*593dc095SDavid du Colombier         if (user_png_ver)
117*593dc095SDavid du Colombier         {
118*593dc095SDavid du Colombier           sprintf(msg, "Application was compiled with png.h from libpng-%.20s",
119*593dc095SDavid du Colombier              user_png_ver);
120*593dc095SDavid du Colombier           png_warning(png_ptr, msg);
121*593dc095SDavid du Colombier         }
122*593dc095SDavid du Colombier         sprintf(msg, "Application  is  running with png.c from libpng-%.20s",
123*593dc095SDavid du Colombier            png_libpng_ver);
124*593dc095SDavid du Colombier         png_warning(png_ptr, msg);
125*593dc095SDavid du Colombier #endif
126*593dc095SDavid du Colombier #ifdef PNG_ERROR_NUMBERS_SUPPORTED
127*593dc095SDavid du Colombier         png_ptr->flags=0;
128*593dc095SDavid du Colombier #endif
1297dd7cddfSDavid du Colombier         png_error(png_ptr,
1307dd7cddfSDavid du Colombier            "Incompatible libpng version in application and library");
1317dd7cddfSDavid du Colombier      }
132*593dc095SDavid du Colombier    }
1337dd7cddfSDavid du Colombier 
1347dd7cddfSDavid du Colombier    /* initialize zbuf - compression buffer */
1357dd7cddfSDavid du Colombier    png_ptr->zbuf_size = PNG_ZBUF_SIZE;
1367dd7cddfSDavid du Colombier    png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
1377dd7cddfSDavid du Colombier      (png_uint_32)png_ptr->zbuf_size);
1387dd7cddfSDavid du Colombier    png_ptr->zstream.zalloc = png_zalloc;
1397dd7cddfSDavid du Colombier    png_ptr->zstream.zfree = png_zfree;
1407dd7cddfSDavid du Colombier    png_ptr->zstream.opaque = (voidpf)png_ptr;
1417dd7cddfSDavid du Colombier 
1427dd7cddfSDavid du Colombier    switch (inflateInit(&png_ptr->zstream))
1437dd7cddfSDavid du Colombier    {
1447dd7cddfSDavid du Colombier      case Z_OK: /* Do nothing */ break;
1457dd7cddfSDavid du Colombier      case Z_MEM_ERROR:
1467dd7cddfSDavid du Colombier      case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
1477dd7cddfSDavid du Colombier      case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break;
1487dd7cddfSDavid du Colombier      default: png_error(png_ptr, "Unknown zlib error");
1497dd7cddfSDavid du Colombier    }
1507dd7cddfSDavid du Colombier 
1517dd7cddfSDavid du Colombier    png_ptr->zstream.next_out = png_ptr->zbuf;
1527dd7cddfSDavid du Colombier    png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1537dd7cddfSDavid du Colombier 
154*593dc095SDavid du Colombier    png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
1557dd7cddfSDavid du Colombier 
156*593dc095SDavid du Colombier #ifdef PNG_SETJMP_SUPPORTED
157*593dc095SDavid du Colombier /* Applications that neglect to set up their own setjmp() and then encounter
158*593dc095SDavid du Colombier    a png_error() will longjmp here.  Since the jmpbuf is then meaningless we
159*593dc095SDavid du Colombier    abort instead of returning. */
160*593dc095SDavid du Colombier #ifdef USE_FAR_KEYWORD
161*593dc095SDavid du Colombier    if (setjmp(jmpbuf))
162*593dc095SDavid du Colombier       PNG_ABORT();
163*593dc095SDavid du Colombier    png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
164*593dc095SDavid du Colombier #else
165*593dc095SDavid du Colombier    if (setjmp(png_ptr->jmpbuf))
166*593dc095SDavid du Colombier       PNG_ABORT();
167*593dc095SDavid du Colombier #endif
168*593dc095SDavid du Colombier #endif
1697dd7cddfSDavid du Colombier    return (png_ptr);
1707dd7cddfSDavid du Colombier }
1717dd7cddfSDavid du Colombier 
1727dd7cddfSDavid du Colombier /* Initialize PNG structure for reading, and allocate any memory needed.
173*593dc095SDavid du Colombier    This interface is deprecated in favour of the png_create_read_struct(),
1747dd7cddfSDavid du Colombier    and it will eventually disappear. */
175*593dc095SDavid du Colombier #if defined(PNG_1_0_X) || defined (PNG_1_2_X)
176*593dc095SDavid du Colombier #undef png_read_init
177*593dc095SDavid du Colombier void PNGAPI
png_read_init(png_structp png_ptr)1787dd7cddfSDavid du Colombier png_read_init(png_structp png_ptr)
1797dd7cddfSDavid du Colombier {
180*593dc095SDavid du Colombier    /* We only come here via pre-1.0.7-compiled applications */
181*593dc095SDavid du Colombier    png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
182*593dc095SDavid du Colombier }
183*593dc095SDavid du Colombier #endif
1847dd7cddfSDavid du Colombier 
185*593dc095SDavid du Colombier void PNGAPI
png_read_init_2(png_structp png_ptr,png_const_charp user_png_ver,png_size_t png_struct_size,png_size_t png_info_size)186*593dc095SDavid du Colombier png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
187*593dc095SDavid du Colombier    png_size_t png_struct_size, png_size_t png_info_size)
188*593dc095SDavid du Colombier {
189*593dc095SDavid du Colombier    /* We only come here via pre-1.0.12-compiled applications */
190*593dc095SDavid du Colombier #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
191*593dc095SDavid du Colombier    if(png_sizeof(png_struct) > png_struct_size ||
192*593dc095SDavid du Colombier       png_sizeof(png_info) > png_info_size)
193*593dc095SDavid du Colombier    {
194*593dc095SDavid du Colombier       char msg[80];
195*593dc095SDavid du Colombier       png_ptr->warning_fn=NULL;
196*593dc095SDavid du Colombier       if (user_png_ver)
197*593dc095SDavid du Colombier       {
198*593dc095SDavid du Colombier         sprintf(msg, "Application was compiled with png.h from libpng-%.20s",
199*593dc095SDavid du Colombier            user_png_ver);
200*593dc095SDavid du Colombier         png_warning(png_ptr, msg);
201*593dc095SDavid du Colombier       }
202*593dc095SDavid du Colombier       sprintf(msg, "Application  is  running with png.c from libpng-%.20s",
203*593dc095SDavid du Colombier          png_libpng_ver);
204*593dc095SDavid du Colombier       png_warning(png_ptr, msg);
205*593dc095SDavid du Colombier    }
206*593dc095SDavid du Colombier #endif
207*593dc095SDavid du Colombier    if(png_sizeof(png_struct) > png_struct_size)
208*593dc095SDavid du Colombier      {
209*593dc095SDavid du Colombier        png_ptr->error_fn=NULL;
210*593dc095SDavid du Colombier #ifdef PNG_ERROR_NUMBERS_SUPPORTED
211*593dc095SDavid du Colombier        png_ptr->flags=0;
212*593dc095SDavid du Colombier #endif
213*593dc095SDavid du Colombier        png_error(png_ptr,
214*593dc095SDavid du Colombier        "The png struct allocated by the application for reading is too small.");
215*593dc095SDavid du Colombier      }
216*593dc095SDavid du Colombier    if(png_sizeof(png_info) > png_info_size)
217*593dc095SDavid du Colombier      {
218*593dc095SDavid du Colombier        png_ptr->error_fn=NULL;
219*593dc095SDavid du Colombier #ifdef PNG_ERROR_NUMBERS_SUPPORTED
220*593dc095SDavid du Colombier        png_ptr->flags=0;
221*593dc095SDavid du Colombier #endif
222*593dc095SDavid du Colombier        png_error(png_ptr,
223*593dc095SDavid du Colombier          "The info struct allocated by application for reading is too small.");
224*593dc095SDavid du Colombier      }
225*593dc095SDavid du Colombier    png_read_init_3(&png_ptr, user_png_ver, png_struct_size);
226*593dc095SDavid du Colombier }
227*593dc095SDavid du Colombier 
228*593dc095SDavid du Colombier void PNGAPI
png_read_init_3(png_structpp ptr_ptr,png_const_charp user_png_ver,png_size_t png_struct_size)229*593dc095SDavid du Colombier png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
230*593dc095SDavid du Colombier    png_size_t png_struct_size)
231*593dc095SDavid du Colombier {
232*593dc095SDavid du Colombier #ifdef PNG_SETJMP_SUPPORTED
233*593dc095SDavid du Colombier    jmp_buf tmp_jmp;  /* to save current jump buffer */
234*593dc095SDavid du Colombier #endif
235*593dc095SDavid du Colombier 
236*593dc095SDavid du Colombier    int i=0;
237*593dc095SDavid du Colombier 
238*593dc095SDavid du Colombier    png_structp png_ptr=*ptr_ptr;
239*593dc095SDavid du Colombier 
240*593dc095SDavid du Colombier    do
241*593dc095SDavid du Colombier    {
242*593dc095SDavid du Colombier      if(user_png_ver[i] != png_libpng_ver[i])
243*593dc095SDavid du Colombier      {
244*593dc095SDavid du Colombier #ifdef PNG_LEGACY_SUPPORTED
245*593dc095SDavid du Colombier        png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
246*593dc095SDavid du Colombier #else
247*593dc095SDavid du Colombier        png_ptr->warning_fn=NULL;
248*593dc095SDavid du Colombier        png_warning(png_ptr,
249*593dc095SDavid du Colombier         "Application uses deprecated png_read_init() and should be recompiled.");
250*593dc095SDavid du Colombier        break;
251*593dc095SDavid du Colombier #endif
252*593dc095SDavid du Colombier      }
253*593dc095SDavid du Colombier    } while (png_libpng_ver[i++]);
254*593dc095SDavid du Colombier 
255*593dc095SDavid du Colombier    png_debug(1, "in png_read_init_3\n");
256*593dc095SDavid du Colombier 
257*593dc095SDavid du Colombier #ifdef PNG_SETJMP_SUPPORTED
2587dd7cddfSDavid du Colombier    /* save jump buffer and error functions */
259*593dc095SDavid du Colombier    png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
260*593dc095SDavid du Colombier #endif
261*593dc095SDavid du Colombier 
262*593dc095SDavid du Colombier    if(png_sizeof(png_struct) > png_struct_size)
263*593dc095SDavid du Colombier      {
264*593dc095SDavid du Colombier        png_destroy_struct(png_ptr);
265*593dc095SDavid du Colombier        *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
266*593dc095SDavid du Colombier        png_ptr = *ptr_ptr;
267*593dc095SDavid du Colombier      }
2687dd7cddfSDavid du Colombier 
2697dd7cddfSDavid du Colombier    /* reset all variables to 0 */
270*593dc095SDavid du Colombier    png_memset(png_ptr, 0, png_sizeof (png_struct));
2717dd7cddfSDavid du Colombier 
272*593dc095SDavid du Colombier #ifdef PNG_SETJMP_SUPPORTED
2737dd7cddfSDavid du Colombier    /* restore jump buffer */
274*593dc095SDavid du Colombier    png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
275*593dc095SDavid du Colombier #endif
276*593dc095SDavid du Colombier 
277*593dc095SDavid du Colombier    /* added at libpng-1.2.6 */
278*593dc095SDavid du Colombier #ifdef PNG_SET_USER_LIMITS_SUPPORTED
279*593dc095SDavid du Colombier    png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
280*593dc095SDavid du Colombier    png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
281*593dc095SDavid du Colombier #endif
2827dd7cddfSDavid du Colombier 
2837dd7cddfSDavid du Colombier    /* initialize zbuf - compression buffer */
2847dd7cddfSDavid du Colombier    png_ptr->zbuf_size = PNG_ZBUF_SIZE;
2857dd7cddfSDavid du Colombier    png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
2867dd7cddfSDavid du Colombier      (png_uint_32)png_ptr->zbuf_size);
2877dd7cddfSDavid du Colombier    png_ptr->zstream.zalloc = png_zalloc;
2887dd7cddfSDavid du Colombier    png_ptr->zstream.zfree = png_zfree;
2897dd7cddfSDavid du Colombier    png_ptr->zstream.opaque = (voidpf)png_ptr;
2907dd7cddfSDavid du Colombier 
2917dd7cddfSDavid du Colombier    switch (inflateInit(&png_ptr->zstream))
2927dd7cddfSDavid du Colombier    {
2937dd7cddfSDavid du Colombier      case Z_OK: /* Do nothing */ break;
2947dd7cddfSDavid du Colombier      case Z_MEM_ERROR:
2957dd7cddfSDavid du Colombier      case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory"); break;
2967dd7cddfSDavid du Colombier      case Z_VERSION_ERROR: png_error(png_ptr, "zlib version"); break;
2977dd7cddfSDavid du Colombier      default: png_error(png_ptr, "Unknown zlib error");
2987dd7cddfSDavid du Colombier    }
2997dd7cddfSDavid du Colombier 
3007dd7cddfSDavid du Colombier    png_ptr->zstream.next_out = png_ptr->zbuf;
3017dd7cddfSDavid du Colombier    png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
3027dd7cddfSDavid du Colombier 
303*593dc095SDavid du Colombier    png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
3047dd7cddfSDavid du Colombier }
3057dd7cddfSDavid du Colombier 
306*593dc095SDavid du Colombier #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
3077dd7cddfSDavid du Colombier /* Read the information before the actual image data.  This has been
308*593dc095SDavid du Colombier  * changed in v0.90 to allow reading a file that already has the magic
3097dd7cddfSDavid du Colombier  * bytes read from the stream.  You can tell libpng how many bytes have
310*593dc095SDavid du Colombier  * been read from the beginning of the stream (up to the maximum of 8)
3117dd7cddfSDavid du Colombier  * via png_set_sig_bytes(), and we will only check the remaining bytes
3127dd7cddfSDavid du Colombier  * here.  The application can then have access to the signature bytes we
3137dd7cddfSDavid du Colombier  * read if it is determined that this isn't a valid PNG file.
3147dd7cddfSDavid du Colombier  */
315*593dc095SDavid du Colombier void PNGAPI
png_read_info(png_structp png_ptr,png_infop info_ptr)3167dd7cddfSDavid du Colombier png_read_info(png_structp png_ptr, png_infop info_ptr)
3177dd7cddfSDavid du Colombier {
3187dd7cddfSDavid du Colombier    png_debug(1, "in png_read_info\n");
3197dd7cddfSDavid du Colombier    /* If we haven't checked all of the PNG signature bytes, do so now. */
3207dd7cddfSDavid du Colombier    if (png_ptr->sig_bytes < 8)
3217dd7cddfSDavid du Colombier    {
3227dd7cddfSDavid du Colombier       png_size_t num_checked = png_ptr->sig_bytes,
3237dd7cddfSDavid du Colombier                  num_to_check = 8 - num_checked;
3247dd7cddfSDavid du Colombier 
3257dd7cddfSDavid du Colombier       png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
3267dd7cddfSDavid du Colombier       png_ptr->sig_bytes = 8;
3277dd7cddfSDavid du Colombier 
3287dd7cddfSDavid du Colombier       if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
3297dd7cddfSDavid du Colombier       {
3307dd7cddfSDavid du Colombier          if (num_checked < 4 &&
3317dd7cddfSDavid du Colombier              png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
3327dd7cddfSDavid du Colombier             png_error(png_ptr, "Not a PNG file");
3337dd7cddfSDavid du Colombier          else
3347dd7cddfSDavid du Colombier             png_error(png_ptr, "PNG file corrupted by ASCII conversion");
3357dd7cddfSDavid du Colombier       }
336*593dc095SDavid du Colombier       if (num_checked < 3)
337*593dc095SDavid du Colombier          png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
3387dd7cddfSDavid du Colombier    }
3397dd7cddfSDavid du Colombier 
340*593dc095SDavid du Colombier    for(;;)
3417dd7cddfSDavid du Colombier    {
342*593dc095SDavid du Colombier #ifdef PNG_USE_LOCAL_ARRAYS
343*593dc095SDavid du Colombier       PNG_IHDR;
344*593dc095SDavid du Colombier       PNG_IDAT;
345*593dc095SDavid du Colombier       PNG_IEND;
346*593dc095SDavid du Colombier       PNG_PLTE;
347*593dc095SDavid du Colombier #if defined(PNG_READ_bKGD_SUPPORTED)
348*593dc095SDavid du Colombier       PNG_bKGD;
349*593dc095SDavid du Colombier #endif
350*593dc095SDavid du Colombier #if defined(PNG_READ_cHRM_SUPPORTED)
351*593dc095SDavid du Colombier       PNG_cHRM;
352*593dc095SDavid du Colombier #endif
353*593dc095SDavid du Colombier #if defined(PNG_READ_gAMA_SUPPORTED)
354*593dc095SDavid du Colombier       PNG_gAMA;
355*593dc095SDavid du Colombier #endif
356*593dc095SDavid du Colombier #if defined(PNG_READ_hIST_SUPPORTED)
357*593dc095SDavid du Colombier       PNG_hIST;
358*593dc095SDavid du Colombier #endif
359*593dc095SDavid du Colombier #if defined(PNG_READ_iCCP_SUPPORTED)
360*593dc095SDavid du Colombier       PNG_iCCP;
361*593dc095SDavid du Colombier #endif
362*593dc095SDavid du Colombier #if defined(PNG_READ_iTXt_SUPPORTED)
363*593dc095SDavid du Colombier       PNG_iTXt;
364*593dc095SDavid du Colombier #endif
365*593dc095SDavid du Colombier #if defined(PNG_READ_oFFs_SUPPORTED)
366*593dc095SDavid du Colombier       PNG_oFFs;
367*593dc095SDavid du Colombier #endif
368*593dc095SDavid du Colombier #if defined(PNG_READ_pCAL_SUPPORTED)
369*593dc095SDavid du Colombier       PNG_pCAL;
370*593dc095SDavid du Colombier #endif
371*593dc095SDavid du Colombier #if defined(PNG_READ_pHYs_SUPPORTED)
372*593dc095SDavid du Colombier       PNG_pHYs;
373*593dc095SDavid du Colombier #endif
374*593dc095SDavid du Colombier #if defined(PNG_READ_sBIT_SUPPORTED)
375*593dc095SDavid du Colombier       PNG_sBIT;
376*593dc095SDavid du Colombier #endif
377*593dc095SDavid du Colombier #if defined(PNG_READ_sCAL_SUPPORTED)
378*593dc095SDavid du Colombier       PNG_sCAL;
379*593dc095SDavid du Colombier #endif
380*593dc095SDavid du Colombier #if defined(PNG_READ_sPLT_SUPPORTED)
381*593dc095SDavid du Colombier       PNG_sPLT;
382*593dc095SDavid du Colombier #endif
383*593dc095SDavid du Colombier #if defined(PNG_READ_sRGB_SUPPORTED)
384*593dc095SDavid du Colombier       PNG_sRGB;
385*593dc095SDavid du Colombier #endif
386*593dc095SDavid du Colombier #if defined(PNG_READ_tEXt_SUPPORTED)
387*593dc095SDavid du Colombier       PNG_tEXt;
388*593dc095SDavid du Colombier #endif
389*593dc095SDavid du Colombier #if defined(PNG_READ_tIME_SUPPORTED)
390*593dc095SDavid du Colombier       PNG_tIME;
391*593dc095SDavid du Colombier #endif
392*593dc095SDavid du Colombier #if defined(PNG_READ_tRNS_SUPPORTED)
393*593dc095SDavid du Colombier       PNG_tRNS;
394*593dc095SDavid du Colombier #endif
395*593dc095SDavid du Colombier #if defined(PNG_READ_zTXt_SUPPORTED)
396*593dc095SDavid du Colombier       PNG_zTXt;
397*593dc095SDavid du Colombier #endif
398*593dc095SDavid du Colombier #endif /* PNG_USE_LOCAL_ARRAYS */
3997dd7cddfSDavid du Colombier       png_byte chunk_length[4];
4007dd7cddfSDavid du Colombier       png_uint_32 length;
4017dd7cddfSDavid du Colombier 
4027dd7cddfSDavid du Colombier       png_read_data(png_ptr, chunk_length, 4);
403*593dc095SDavid du Colombier       length = png_get_uint_31(png_ptr,chunk_length);
4047dd7cddfSDavid du Colombier 
4057dd7cddfSDavid du Colombier       png_reset_crc(png_ptr);
4067dd7cddfSDavid du Colombier       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
4077dd7cddfSDavid du Colombier 
408*593dc095SDavid du Colombier       png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name,
409*593dc095SDavid du Colombier          length);
4107dd7cddfSDavid du Colombier 
4117dd7cddfSDavid du Colombier       /* This should be a binary subdivision search or a hash for
4127dd7cddfSDavid du Colombier        * matching the chunk name rather than a linear search.
4137dd7cddfSDavid du Colombier        */
4147dd7cddfSDavid du Colombier       if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
4157dd7cddfSDavid du Colombier          png_handle_IHDR(png_ptr, info_ptr, length);
4167dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
4177dd7cddfSDavid du Colombier          png_handle_IEND(png_ptr, info_ptr, length);
418*593dc095SDavid du Colombier #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
419*593dc095SDavid du Colombier       else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
420*593dc095SDavid du Colombier       {
421*593dc095SDavid du Colombier          if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
422*593dc095SDavid du Colombier             png_ptr->mode |= PNG_HAVE_IDAT;
423*593dc095SDavid du Colombier          png_handle_unknown(png_ptr, info_ptr, length);
424*593dc095SDavid du Colombier          if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
425*593dc095SDavid du Colombier             png_ptr->mode |= PNG_HAVE_PLTE;
426*593dc095SDavid du Colombier          else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
427*593dc095SDavid du Colombier          {
428*593dc095SDavid du Colombier             if (!(png_ptr->mode & PNG_HAVE_IHDR))
429*593dc095SDavid du Colombier                png_error(png_ptr, "Missing IHDR before IDAT");
430*593dc095SDavid du Colombier             else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
431*593dc095SDavid du Colombier                      !(png_ptr->mode & PNG_HAVE_PLTE))
432*593dc095SDavid du Colombier                png_error(png_ptr, "Missing PLTE before IDAT");
433*593dc095SDavid du Colombier             break;
434*593dc095SDavid du Colombier          }
435*593dc095SDavid du Colombier       }
436*593dc095SDavid du Colombier #endif
437*593dc095SDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
438*593dc095SDavid du Colombier          png_handle_PLTE(png_ptr, info_ptr, length);
4397dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
4407dd7cddfSDavid du Colombier       {
4417dd7cddfSDavid du Colombier          if (!(png_ptr->mode & PNG_HAVE_IHDR))
4427dd7cddfSDavid du Colombier             png_error(png_ptr, "Missing IHDR before IDAT");
4437dd7cddfSDavid du Colombier          else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
4447dd7cddfSDavid du Colombier                   !(png_ptr->mode & PNG_HAVE_PLTE))
4457dd7cddfSDavid du Colombier             png_error(png_ptr, "Missing PLTE before IDAT");
4467dd7cddfSDavid du Colombier 
4477dd7cddfSDavid du Colombier          png_ptr->idat_size = length;
4487dd7cddfSDavid du Colombier          png_ptr->mode |= PNG_HAVE_IDAT;
4497dd7cddfSDavid du Colombier          break;
4507dd7cddfSDavid du Colombier       }
4517dd7cddfSDavid du Colombier #if defined(PNG_READ_bKGD_SUPPORTED)
4527dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
4537dd7cddfSDavid du Colombier          png_handle_bKGD(png_ptr, info_ptr, length);
4547dd7cddfSDavid du Colombier #endif
4557dd7cddfSDavid du Colombier #if defined(PNG_READ_cHRM_SUPPORTED)
4567dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
4577dd7cddfSDavid du Colombier          png_handle_cHRM(png_ptr, info_ptr, length);
4587dd7cddfSDavid du Colombier #endif
4597dd7cddfSDavid du Colombier #if defined(PNG_READ_gAMA_SUPPORTED)
4607dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
4617dd7cddfSDavid du Colombier          png_handle_gAMA(png_ptr, info_ptr, length);
4627dd7cddfSDavid du Colombier #endif
4637dd7cddfSDavid du Colombier #if defined(PNG_READ_hIST_SUPPORTED)
4647dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
4657dd7cddfSDavid du Colombier          png_handle_hIST(png_ptr, info_ptr, length);
4667dd7cddfSDavid du Colombier #endif
4677dd7cddfSDavid du Colombier #if defined(PNG_READ_oFFs_SUPPORTED)
4687dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
4697dd7cddfSDavid du Colombier          png_handle_oFFs(png_ptr, info_ptr, length);
4707dd7cddfSDavid du Colombier #endif
4717dd7cddfSDavid du Colombier #if defined(PNG_READ_pCAL_SUPPORTED)
4727dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
4737dd7cddfSDavid du Colombier          png_handle_pCAL(png_ptr, info_ptr, length);
4747dd7cddfSDavid du Colombier #endif
475*593dc095SDavid du Colombier #if defined(PNG_READ_sCAL_SUPPORTED)
476*593dc095SDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
477*593dc095SDavid du Colombier          png_handle_sCAL(png_ptr, info_ptr, length);
478*593dc095SDavid du Colombier #endif
4797dd7cddfSDavid du Colombier #if defined(PNG_READ_pHYs_SUPPORTED)
4807dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
4817dd7cddfSDavid du Colombier          png_handle_pHYs(png_ptr, info_ptr, length);
4827dd7cddfSDavid du Colombier #endif
4837dd7cddfSDavid du Colombier #if defined(PNG_READ_sBIT_SUPPORTED)
4847dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
4857dd7cddfSDavid du Colombier          png_handle_sBIT(png_ptr, info_ptr, length);
4867dd7cddfSDavid du Colombier #endif
4877dd7cddfSDavid du Colombier #if defined(PNG_READ_sRGB_SUPPORTED)
4887dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
4897dd7cddfSDavid du Colombier          png_handle_sRGB(png_ptr, info_ptr, length);
4907dd7cddfSDavid du Colombier #endif
491*593dc095SDavid du Colombier #if defined(PNG_READ_iCCP_SUPPORTED)
492*593dc095SDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
493*593dc095SDavid du Colombier          png_handle_iCCP(png_ptr, info_ptr, length);
494*593dc095SDavid du Colombier #endif
495*593dc095SDavid du Colombier #if defined(PNG_READ_sPLT_SUPPORTED)
496*593dc095SDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
497*593dc095SDavid du Colombier          png_handle_sPLT(png_ptr, info_ptr, length);
498*593dc095SDavid du Colombier #endif
4997dd7cddfSDavid du Colombier #if defined(PNG_READ_tEXt_SUPPORTED)
5007dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
5017dd7cddfSDavid du Colombier          png_handle_tEXt(png_ptr, info_ptr, length);
5027dd7cddfSDavid du Colombier #endif
5037dd7cddfSDavid du Colombier #if defined(PNG_READ_tIME_SUPPORTED)
5047dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
5057dd7cddfSDavid du Colombier          png_handle_tIME(png_ptr, info_ptr, length);
5067dd7cddfSDavid du Colombier #endif
5077dd7cddfSDavid du Colombier #if defined(PNG_READ_tRNS_SUPPORTED)
5087dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
5097dd7cddfSDavid du Colombier          png_handle_tRNS(png_ptr, info_ptr, length);
5107dd7cddfSDavid du Colombier #endif
5117dd7cddfSDavid du Colombier #if defined(PNG_READ_zTXt_SUPPORTED)
5127dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
5137dd7cddfSDavid du Colombier          png_handle_zTXt(png_ptr, info_ptr, length);
5147dd7cddfSDavid du Colombier #endif
515*593dc095SDavid du Colombier #if defined(PNG_READ_iTXt_SUPPORTED)
516*593dc095SDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
517*593dc095SDavid du Colombier          png_handle_iTXt(png_ptr, info_ptr, length);
518*593dc095SDavid du Colombier #endif
5197dd7cddfSDavid du Colombier       else
5207dd7cddfSDavid du Colombier          png_handle_unknown(png_ptr, info_ptr, length);
5217dd7cddfSDavid du Colombier    }
5227dd7cddfSDavid du Colombier }
523*593dc095SDavid du Colombier #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
5247dd7cddfSDavid du Colombier 
5257dd7cddfSDavid du Colombier /* optional call to update the users info_ptr structure */
526*593dc095SDavid du Colombier void PNGAPI
png_read_update_info(png_structp png_ptr,png_infop info_ptr)5277dd7cddfSDavid du Colombier png_read_update_info(png_structp png_ptr, png_infop info_ptr)
5287dd7cddfSDavid du Colombier {
5297dd7cddfSDavid du Colombier    png_debug(1, "in png_read_update_info\n");
5307dd7cddfSDavid du Colombier    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
5317dd7cddfSDavid du Colombier       png_read_start_row(png_ptr);
532*593dc095SDavid du Colombier    else
533*593dc095SDavid du Colombier       png_warning(png_ptr,
534*593dc095SDavid du Colombier       "Ignoring extra png_read_update_info() call; row buffer not reallocated");
5357dd7cddfSDavid du Colombier    png_read_transform_info(png_ptr, info_ptr);
5367dd7cddfSDavid du Colombier }
5377dd7cddfSDavid du Colombier 
538*593dc095SDavid du Colombier #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
5397dd7cddfSDavid du Colombier /* Initialize palette, background, etc, after transformations
5407dd7cddfSDavid du Colombier  * are set, but before any reading takes place.  This allows
541*593dc095SDavid du Colombier  * the user to obtain a gamma-corrected palette, for example.
5427dd7cddfSDavid du Colombier  * If the user doesn't call this, we will do it ourselves.
5437dd7cddfSDavid du Colombier  */
544*593dc095SDavid du Colombier void PNGAPI
png_start_read_image(png_structp png_ptr)5457dd7cddfSDavid du Colombier png_start_read_image(png_structp png_ptr)
5467dd7cddfSDavid du Colombier {
5477dd7cddfSDavid du Colombier    png_debug(1, "in png_start_read_image\n");
5487dd7cddfSDavid du Colombier    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
5497dd7cddfSDavid du Colombier       png_read_start_row(png_ptr);
5507dd7cddfSDavid du Colombier }
551*593dc095SDavid du Colombier #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
5527dd7cddfSDavid du Colombier 
553*593dc095SDavid du Colombier #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
554*593dc095SDavid du Colombier void PNGAPI
png_read_row(png_structp png_ptr,png_bytep row,png_bytep dsp_row)5557dd7cddfSDavid du Colombier png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
5567dd7cddfSDavid du Colombier {
557*593dc095SDavid du Colombier #ifdef PNG_USE_LOCAL_ARRAYS
558*593dc095SDavid du Colombier    PNG_IDAT;
559*593dc095SDavid du Colombier    const int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
560*593dc095SDavid du Colombier    const int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
561*593dc095SDavid du Colombier #endif
5627dd7cddfSDavid du Colombier    int ret;
563*593dc095SDavid du Colombier    png_debug2(1, "in png_read_row (row %lu, pass %d)\n",
5647dd7cddfSDavid du Colombier       png_ptr->row_number, png_ptr->pass);
5657dd7cddfSDavid du Colombier    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
5667dd7cddfSDavid du Colombier       png_read_start_row(png_ptr);
567*593dc095SDavid du Colombier    if (png_ptr->row_number == 0 && png_ptr->pass == 0)
568*593dc095SDavid du Colombier    {
569*593dc095SDavid du Colombier    /* check for transforms that have been set but were defined out */
570*593dc095SDavid du Colombier #if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
571*593dc095SDavid du Colombier    if (png_ptr->transformations & PNG_INVERT_MONO)
572*593dc095SDavid du Colombier       png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined.");
573*593dc095SDavid du Colombier #endif
574*593dc095SDavid du Colombier #if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
575*593dc095SDavid du Colombier    if (png_ptr->transformations & PNG_FILLER)
576*593dc095SDavid du Colombier       png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined.");
577*593dc095SDavid du Colombier #endif
578*593dc095SDavid du Colombier #if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED)
579*593dc095SDavid du Colombier    if (png_ptr->transformations & PNG_PACKSWAP)
580*593dc095SDavid du Colombier       png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined.");
581*593dc095SDavid du Colombier #endif
582*593dc095SDavid du Colombier #if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
583*593dc095SDavid du Colombier    if (png_ptr->transformations & PNG_PACK)
584*593dc095SDavid du Colombier       png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined.");
585*593dc095SDavid du Colombier #endif
586*593dc095SDavid du Colombier #if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
587*593dc095SDavid du Colombier    if (png_ptr->transformations & PNG_SHIFT)
588*593dc095SDavid du Colombier       png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined.");
589*593dc095SDavid du Colombier #endif
590*593dc095SDavid du Colombier #if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
591*593dc095SDavid du Colombier    if (png_ptr->transformations & PNG_BGR)
592*593dc095SDavid du Colombier       png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined.");
593*593dc095SDavid du Colombier #endif
594*593dc095SDavid du Colombier #if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
595*593dc095SDavid du Colombier    if (png_ptr->transformations & PNG_SWAP_BYTES)
596*593dc095SDavid du Colombier       png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined.");
597*593dc095SDavid du Colombier #endif
598*593dc095SDavid du Colombier    }
5997dd7cddfSDavid du Colombier 
6007dd7cddfSDavid du Colombier #if defined(PNG_READ_INTERLACING_SUPPORTED)
6017dd7cddfSDavid du Colombier    /* if interlaced and we do not need a new row, combine row and return */
6027dd7cddfSDavid du Colombier    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
6037dd7cddfSDavid du Colombier    {
6047dd7cddfSDavid du Colombier       switch (png_ptr->pass)
6057dd7cddfSDavid du Colombier       {
6067dd7cddfSDavid du Colombier          case 0:
607*593dc095SDavid du Colombier             if (png_ptr->row_number & 0x07)
6087dd7cddfSDavid du Colombier             {
6097dd7cddfSDavid du Colombier                if (dsp_row != NULL)
6107dd7cddfSDavid du Colombier                   png_combine_row(png_ptr, dsp_row,
6117dd7cddfSDavid du Colombier                      png_pass_dsp_mask[png_ptr->pass]);
6127dd7cddfSDavid du Colombier                png_read_finish_row(png_ptr);
6137dd7cddfSDavid du Colombier                return;
6147dd7cddfSDavid du Colombier             }
6157dd7cddfSDavid du Colombier             break;
6167dd7cddfSDavid du Colombier          case 1:
617*593dc095SDavid du Colombier             if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
6187dd7cddfSDavid du Colombier             {
6197dd7cddfSDavid du Colombier                if (dsp_row != NULL)
6207dd7cddfSDavid du Colombier                   png_combine_row(png_ptr, dsp_row,
6217dd7cddfSDavid du Colombier                      png_pass_dsp_mask[png_ptr->pass]);
6227dd7cddfSDavid du Colombier                png_read_finish_row(png_ptr);
6237dd7cddfSDavid du Colombier                return;
6247dd7cddfSDavid du Colombier             }
6257dd7cddfSDavid du Colombier             break;
6267dd7cddfSDavid du Colombier          case 2:
627*593dc095SDavid du Colombier             if ((png_ptr->row_number & 0x07) != 4)
6287dd7cddfSDavid du Colombier             {
6297dd7cddfSDavid du Colombier                if (dsp_row != NULL && (png_ptr->row_number & 4))
6307dd7cddfSDavid du Colombier                   png_combine_row(png_ptr, dsp_row,
6317dd7cddfSDavid du Colombier                      png_pass_dsp_mask[png_ptr->pass]);
6327dd7cddfSDavid du Colombier                png_read_finish_row(png_ptr);
6337dd7cddfSDavid du Colombier                return;
6347dd7cddfSDavid du Colombier             }
6357dd7cddfSDavid du Colombier             break;
6367dd7cddfSDavid du Colombier          case 3:
6377dd7cddfSDavid du Colombier             if ((png_ptr->row_number & 3) || png_ptr->width < 3)
6387dd7cddfSDavid du Colombier             {
6397dd7cddfSDavid du Colombier                if (dsp_row != NULL)
6407dd7cddfSDavid du Colombier                   png_combine_row(png_ptr, dsp_row,
6417dd7cddfSDavid du Colombier                      png_pass_dsp_mask[png_ptr->pass]);
6427dd7cddfSDavid du Colombier                png_read_finish_row(png_ptr);
6437dd7cddfSDavid du Colombier                return;
6447dd7cddfSDavid du Colombier             }
6457dd7cddfSDavid du Colombier             break;
6467dd7cddfSDavid du Colombier          case 4:
6477dd7cddfSDavid du Colombier             if ((png_ptr->row_number & 3) != 2)
6487dd7cddfSDavid du Colombier             {
6497dd7cddfSDavid du Colombier                if (dsp_row != NULL && (png_ptr->row_number & 2))
6507dd7cddfSDavid du Colombier                   png_combine_row(png_ptr, dsp_row,
6517dd7cddfSDavid du Colombier                      png_pass_dsp_mask[png_ptr->pass]);
6527dd7cddfSDavid du Colombier                png_read_finish_row(png_ptr);
6537dd7cddfSDavid du Colombier                return;
6547dd7cddfSDavid du Colombier             }
6557dd7cddfSDavid du Colombier             break;
6567dd7cddfSDavid du Colombier          case 5:
6577dd7cddfSDavid du Colombier             if ((png_ptr->row_number & 1) || png_ptr->width < 2)
6587dd7cddfSDavid du Colombier             {
6597dd7cddfSDavid du Colombier                if (dsp_row != NULL)
6607dd7cddfSDavid du Colombier                   png_combine_row(png_ptr, dsp_row,
6617dd7cddfSDavid du Colombier                      png_pass_dsp_mask[png_ptr->pass]);
6627dd7cddfSDavid du Colombier                png_read_finish_row(png_ptr);
6637dd7cddfSDavid du Colombier                return;
6647dd7cddfSDavid du Colombier             }
6657dd7cddfSDavid du Colombier             break;
6667dd7cddfSDavid du Colombier          case 6:
6677dd7cddfSDavid du Colombier             if (!(png_ptr->row_number & 1))
6687dd7cddfSDavid du Colombier             {
6697dd7cddfSDavid du Colombier                png_read_finish_row(png_ptr);
6707dd7cddfSDavid du Colombier                return;
6717dd7cddfSDavid du Colombier             }
6727dd7cddfSDavid du Colombier             break;
6737dd7cddfSDavid du Colombier       }
6747dd7cddfSDavid du Colombier    }
6757dd7cddfSDavid du Colombier #endif
6767dd7cddfSDavid du Colombier 
6777dd7cddfSDavid du Colombier    if (!(png_ptr->mode & PNG_HAVE_IDAT))
6787dd7cddfSDavid du Colombier       png_error(png_ptr, "Invalid attempt to read row data");
6797dd7cddfSDavid du Colombier 
6807dd7cddfSDavid du Colombier    png_ptr->zstream.next_out = png_ptr->row_buf;
6817dd7cddfSDavid du Colombier    png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
6827dd7cddfSDavid du Colombier    do
6837dd7cddfSDavid du Colombier    {
6847dd7cddfSDavid du Colombier       if (!(png_ptr->zstream.avail_in))
6857dd7cddfSDavid du Colombier       {
6867dd7cddfSDavid du Colombier          while (!png_ptr->idat_size)
6877dd7cddfSDavid du Colombier          {
6887dd7cddfSDavid du Colombier             png_byte chunk_length[4];
6897dd7cddfSDavid du Colombier 
6907dd7cddfSDavid du Colombier             png_crc_finish(png_ptr, 0);
6917dd7cddfSDavid du Colombier 
6927dd7cddfSDavid du Colombier             png_read_data(png_ptr, chunk_length, 4);
693*593dc095SDavid du Colombier             png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length);
6947dd7cddfSDavid du Colombier 
6957dd7cddfSDavid du Colombier             png_reset_crc(png_ptr);
6967dd7cddfSDavid du Colombier             png_crc_read(png_ptr, png_ptr->chunk_name, 4);
6977dd7cddfSDavid du Colombier             if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
6987dd7cddfSDavid du Colombier                png_error(png_ptr, "Not enough image data");
6997dd7cddfSDavid du Colombier          }
7007dd7cddfSDavid du Colombier          png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
7017dd7cddfSDavid du Colombier          png_ptr->zstream.next_in = png_ptr->zbuf;
7027dd7cddfSDavid du Colombier          if (png_ptr->zbuf_size > png_ptr->idat_size)
7037dd7cddfSDavid du Colombier             png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
7047dd7cddfSDavid du Colombier          png_crc_read(png_ptr, png_ptr->zbuf,
7057dd7cddfSDavid du Colombier             (png_size_t)png_ptr->zstream.avail_in);
7067dd7cddfSDavid du Colombier          png_ptr->idat_size -= png_ptr->zstream.avail_in;
7077dd7cddfSDavid du Colombier       }
7087dd7cddfSDavid du Colombier       ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
7097dd7cddfSDavid du Colombier       if (ret == Z_STREAM_END)
7107dd7cddfSDavid du Colombier       {
7117dd7cddfSDavid du Colombier          if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
7127dd7cddfSDavid du Colombier             png_ptr->idat_size)
7137dd7cddfSDavid du Colombier             png_error(png_ptr, "Extra compressed data");
7147dd7cddfSDavid du Colombier          png_ptr->mode |= PNG_AFTER_IDAT;
7157dd7cddfSDavid du Colombier          png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
7167dd7cddfSDavid du Colombier          break;
7177dd7cddfSDavid du Colombier       }
7187dd7cddfSDavid du Colombier       if (ret != Z_OK)
7197dd7cddfSDavid du Colombier          png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
7207dd7cddfSDavid du Colombier                    "Decompression error");
7217dd7cddfSDavid du Colombier 
7227dd7cddfSDavid du Colombier    } while (png_ptr->zstream.avail_out);
7237dd7cddfSDavid du Colombier 
7247dd7cddfSDavid du Colombier    png_ptr->row_info.color_type = png_ptr->color_type;
7257dd7cddfSDavid du Colombier    png_ptr->row_info.width = png_ptr->iwidth;
7267dd7cddfSDavid du Colombier    png_ptr->row_info.channels = png_ptr->channels;
7277dd7cddfSDavid du Colombier    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
7287dd7cddfSDavid du Colombier    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
729*593dc095SDavid du Colombier    png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
730*593dc095SDavid du Colombier        png_ptr->row_info.width);
7317dd7cddfSDavid du Colombier 
732*593dc095SDavid du Colombier    if(png_ptr->row_buf[0])
7337dd7cddfSDavid du Colombier    png_read_filter_row(png_ptr, &(png_ptr->row_info),
7347dd7cddfSDavid du Colombier       png_ptr->row_buf + 1, png_ptr->prev_row + 1,
7357dd7cddfSDavid du Colombier       (int)(png_ptr->row_buf[0]));
7367dd7cddfSDavid du Colombier 
737*593dc095SDavid du Colombier    png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
738*593dc095SDavid du Colombier       png_ptr->rowbytes + 1);
7397dd7cddfSDavid du Colombier 
740*593dc095SDavid du Colombier #if defined(PNG_MNG_FEATURES_SUPPORTED)
741*593dc095SDavid du Colombier    if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
742*593dc095SDavid du Colombier       (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
743*593dc095SDavid du Colombier    {
744*593dc095SDavid du Colombier       /* Intrapixel differencing */
745*593dc095SDavid du Colombier       png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
746*593dc095SDavid du Colombier    }
747*593dc095SDavid du Colombier #endif
748*593dc095SDavid du Colombier 
749*593dc095SDavid du Colombier 
750*593dc095SDavid du Colombier    if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
7517dd7cddfSDavid du Colombier       png_do_read_transformations(png_ptr);
7527dd7cddfSDavid du Colombier 
7537dd7cddfSDavid du Colombier #if defined(PNG_READ_INTERLACING_SUPPORTED)
7547dd7cddfSDavid du Colombier    /* blow up interlaced rows to full size */
7557dd7cddfSDavid du Colombier    if (png_ptr->interlaced &&
7567dd7cddfSDavid du Colombier       (png_ptr->transformations & PNG_INTERLACE))
7577dd7cddfSDavid du Colombier    {
7587dd7cddfSDavid du Colombier       if (png_ptr->pass < 6)
759*593dc095SDavid du Colombier /*       old interface (pre-1.0.9):
7607dd7cddfSDavid du Colombier          png_do_read_interlace(&(png_ptr->row_info),
7617dd7cddfSDavid du Colombier             png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
762*593dc095SDavid du Colombier  */
763*593dc095SDavid du Colombier          png_do_read_interlace(png_ptr);
7647dd7cddfSDavid du Colombier 
7657dd7cddfSDavid du Colombier       if (dsp_row != NULL)
7667dd7cddfSDavid du Colombier          png_combine_row(png_ptr, dsp_row,
7677dd7cddfSDavid du Colombier             png_pass_dsp_mask[png_ptr->pass]);
7687dd7cddfSDavid du Colombier       if (row != NULL)
7697dd7cddfSDavid du Colombier          png_combine_row(png_ptr, row,
7707dd7cddfSDavid du Colombier             png_pass_mask[png_ptr->pass]);
7717dd7cddfSDavid du Colombier    }
7727dd7cddfSDavid du Colombier    else
7737dd7cddfSDavid du Colombier #endif
7747dd7cddfSDavid du Colombier    {
7757dd7cddfSDavid du Colombier       if (row != NULL)
7767dd7cddfSDavid du Colombier          png_combine_row(png_ptr, row, 0xff);
7777dd7cddfSDavid du Colombier       if (dsp_row != NULL)
7787dd7cddfSDavid du Colombier          png_combine_row(png_ptr, dsp_row, 0xff);
7797dd7cddfSDavid du Colombier    }
7807dd7cddfSDavid du Colombier    png_read_finish_row(png_ptr);
7817dd7cddfSDavid du Colombier 
782*593dc095SDavid du Colombier    if (png_ptr->read_row_fn != NULL)
783*593dc095SDavid du Colombier       (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
784*593dc095SDavid du Colombier }
785*593dc095SDavid du Colombier #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
786*593dc095SDavid du Colombier 
787*593dc095SDavid du Colombier #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
7887dd7cddfSDavid du Colombier /* Read one or more rows of image data.  If the image is interlaced,
7897dd7cddfSDavid du Colombier  * and png_set_interlace_handling() has been called, the rows need to
7907dd7cddfSDavid du Colombier  * contain the contents of the rows from the previous pass.  If the
791*593dc095SDavid du Colombier  * image has alpha or transparency, and png_handle_alpha()[*] has been
7927dd7cddfSDavid du Colombier  * called, the rows contents must be initialized to the contents of the
7937dd7cddfSDavid du Colombier  * screen.
7947dd7cddfSDavid du Colombier  *
7957dd7cddfSDavid du Colombier  * "row" holds the actual image, and pixels are placed in it
7967dd7cddfSDavid du Colombier  * as they arrive.  If the image is displayed after each pass, it will
7977dd7cddfSDavid du Colombier  * appear to "sparkle" in.  "display_row" can be used to display a
7987dd7cddfSDavid du Colombier  * "chunky" progressive image, with finer detail added as it becomes
7997dd7cddfSDavid du Colombier  * available.  If you do not want this "chunky" display, you may pass
8007dd7cddfSDavid du Colombier  * NULL for display_row.  If you do not want the sparkle display, and
8017dd7cddfSDavid du Colombier  * you have not called png_handle_alpha(), you may pass NULL for rows.
8027dd7cddfSDavid du Colombier  * If you have called png_handle_alpha(), and the image has either an
8037dd7cddfSDavid du Colombier  * alpha channel or a transparency chunk, you must provide a buffer for
8047dd7cddfSDavid du Colombier  * rows.  In this case, you do not have to provide a display_row buffer
8057dd7cddfSDavid du Colombier  * also, but you may.  If the image is not interlaced, or if you have
8067dd7cddfSDavid du Colombier  * not called png_set_interlace_handling(), the display_row buffer will
8077dd7cddfSDavid du Colombier  * be ignored, so pass NULL to it.
808*593dc095SDavid du Colombier  *
809*593dc095SDavid du Colombier  * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.8
8107dd7cddfSDavid du Colombier  */
8117dd7cddfSDavid du Colombier 
812*593dc095SDavid du Colombier void PNGAPI
png_read_rows(png_structp png_ptr,png_bytepp row,png_bytepp display_row,png_uint_32 num_rows)8137dd7cddfSDavid du Colombier png_read_rows(png_structp png_ptr, png_bytepp row,
8147dd7cddfSDavid du Colombier    png_bytepp display_row, png_uint_32 num_rows)
8157dd7cddfSDavid du Colombier {
8167dd7cddfSDavid du Colombier    png_uint_32 i;
8177dd7cddfSDavid du Colombier    png_bytepp rp;
8187dd7cddfSDavid du Colombier    png_bytepp dp;
8197dd7cddfSDavid du Colombier 
8207dd7cddfSDavid du Colombier    png_debug(1, "in png_read_rows\n");
8217dd7cddfSDavid du Colombier    rp = row;
8227dd7cddfSDavid du Colombier    dp = display_row;
823*593dc095SDavid du Colombier    if (rp != NULL && dp != NULL)
8247dd7cddfSDavid du Colombier       for (i = 0; i < num_rows; i++)
8257dd7cddfSDavid du Colombier       {
826*593dc095SDavid du Colombier          png_bytep rptr = *rp++;
827*593dc095SDavid du Colombier          png_bytep dptr = *dp++;
8287dd7cddfSDavid du Colombier 
8297dd7cddfSDavid du Colombier          png_read_row(png_ptr, rptr, dptr);
830*593dc095SDavid du Colombier       }
831*593dc095SDavid du Colombier    else if(rp != NULL)
832*593dc095SDavid du Colombier       for (i = 0; i < num_rows; i++)
833*593dc095SDavid du Colombier       {
834*593dc095SDavid du Colombier          png_bytep rptr = *rp;
835*593dc095SDavid du Colombier          png_read_row(png_ptr, rptr, png_bytep_NULL);
8367dd7cddfSDavid du Colombier          rp++;
837*593dc095SDavid du Colombier       }
838*593dc095SDavid du Colombier    else if(dp != NULL)
839*593dc095SDavid du Colombier       for (i = 0; i < num_rows; i++)
840*593dc095SDavid du Colombier       {
841*593dc095SDavid du Colombier          png_bytep dptr = *dp;
842*593dc095SDavid du Colombier          png_read_row(png_ptr, png_bytep_NULL, dptr);
8437dd7cddfSDavid du Colombier          dp++;
8447dd7cddfSDavid du Colombier       }
8457dd7cddfSDavid du Colombier }
846*593dc095SDavid du Colombier #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
8477dd7cddfSDavid du Colombier 
848*593dc095SDavid du Colombier #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
8497dd7cddfSDavid du Colombier /* Read the entire image.  If the image has an alpha channel or a tRNS
850*593dc095SDavid du Colombier  * chunk, and you have called png_handle_alpha()[*], you will need to
8517dd7cddfSDavid du Colombier  * initialize the image to the current image that PNG will be overlaying.
8527dd7cddfSDavid du Colombier  * We set the num_rows again here, in case it was incorrectly set in
8537dd7cddfSDavid du Colombier  * png_read_start_row() by a call to png_read_update_info() or
8547dd7cddfSDavid du Colombier  * png_start_read_image() if png_set_interlace_handling() wasn't called
8557dd7cddfSDavid du Colombier  * prior to either of these functions like it should have been.  You can
8567dd7cddfSDavid du Colombier  * only call this function once.  If you desire to have an image for
8577dd7cddfSDavid du Colombier  * each pass of a interlaced image, use png_read_rows() instead.
858*593dc095SDavid du Colombier  *
859*593dc095SDavid du Colombier  * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.8
8607dd7cddfSDavid du Colombier  */
861*593dc095SDavid du Colombier void PNGAPI
png_read_image(png_structp png_ptr,png_bytepp image)8627dd7cddfSDavid du Colombier png_read_image(png_structp png_ptr, png_bytepp image)
8637dd7cddfSDavid du Colombier {
864*593dc095SDavid du Colombier    png_uint_32 i,image_height;
8657dd7cddfSDavid du Colombier    int pass, j;
8667dd7cddfSDavid du Colombier    png_bytepp rp;
8677dd7cddfSDavid du Colombier 
8687dd7cddfSDavid du Colombier    png_debug(1, "in png_read_image\n");
8697dd7cddfSDavid du Colombier 
870*593dc095SDavid du Colombier #ifdef PNG_READ_INTERLACING_SUPPORTED
871*593dc095SDavid du Colombier    pass = png_set_interlace_handling(png_ptr);
872*593dc095SDavid du Colombier #else
873*593dc095SDavid du Colombier    if (png_ptr->interlaced)
874*593dc095SDavid du Colombier       png_error(png_ptr,
875*593dc095SDavid du Colombier         "Cannot read interlaced image -- interlace handler disabled.");
876*593dc095SDavid du Colombier    pass = 1;
877*593dc095SDavid du Colombier #endif
878*593dc095SDavid du Colombier 
879*593dc095SDavid du Colombier 
880*593dc095SDavid du Colombier    image_height=png_ptr->height;
881*593dc095SDavid du Colombier    png_ptr->num_rows = image_height; /* Make sure this is set correctly */
8827dd7cddfSDavid du Colombier 
8837dd7cddfSDavid du Colombier    for (j = 0; j < pass; j++)
8847dd7cddfSDavid du Colombier    {
8857dd7cddfSDavid du Colombier       rp = image;
886*593dc095SDavid du Colombier       for (i = 0; i < image_height; i++)
8877dd7cddfSDavid du Colombier       {
888*593dc095SDavid du Colombier          png_read_row(png_ptr, *rp, png_bytep_NULL);
8897dd7cddfSDavid du Colombier          rp++;
8907dd7cddfSDavid du Colombier       }
8917dd7cddfSDavid du Colombier    }
8927dd7cddfSDavid du Colombier }
893*593dc095SDavid du Colombier #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
8947dd7cddfSDavid du Colombier 
895*593dc095SDavid du Colombier #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
8967dd7cddfSDavid du Colombier /* Read the end of the PNG file.  Will not read past the end of the
8977dd7cddfSDavid du Colombier  * file, will verify the end is accurate, and will read any comments
8987dd7cddfSDavid du Colombier  * or time information at the end of the file, if info is not NULL.
8997dd7cddfSDavid du Colombier  */
900*593dc095SDavid du Colombier void PNGAPI
png_read_end(png_structp png_ptr,png_infop info_ptr)9017dd7cddfSDavid du Colombier png_read_end(png_structp png_ptr, png_infop info_ptr)
9027dd7cddfSDavid du Colombier {
9037dd7cddfSDavid du Colombier    png_byte chunk_length[4];
9047dd7cddfSDavid du Colombier    png_uint_32 length;
9057dd7cddfSDavid du Colombier 
9067dd7cddfSDavid du Colombier    png_debug(1, "in png_read_end\n");
9077dd7cddfSDavid du Colombier    png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
9087dd7cddfSDavid du Colombier 
9097dd7cddfSDavid du Colombier    do
9107dd7cddfSDavid du Colombier    {
911*593dc095SDavid du Colombier #ifdef PNG_USE_LOCAL_ARRAYS
912*593dc095SDavid du Colombier       PNG_IHDR;
913*593dc095SDavid du Colombier       PNG_IDAT;
914*593dc095SDavid du Colombier       PNG_IEND;
915*593dc095SDavid du Colombier       PNG_PLTE;
916*593dc095SDavid du Colombier #if defined(PNG_READ_bKGD_SUPPORTED)
917*593dc095SDavid du Colombier       PNG_bKGD;
918*593dc095SDavid du Colombier #endif
919*593dc095SDavid du Colombier #if defined(PNG_READ_cHRM_SUPPORTED)
920*593dc095SDavid du Colombier       PNG_cHRM;
921*593dc095SDavid du Colombier #endif
922*593dc095SDavid du Colombier #if defined(PNG_READ_gAMA_SUPPORTED)
923*593dc095SDavid du Colombier       PNG_gAMA;
924*593dc095SDavid du Colombier #endif
925*593dc095SDavid du Colombier #if defined(PNG_READ_hIST_SUPPORTED)
926*593dc095SDavid du Colombier       PNG_hIST;
927*593dc095SDavid du Colombier #endif
928*593dc095SDavid du Colombier #if defined(PNG_READ_iCCP_SUPPORTED)
929*593dc095SDavid du Colombier       PNG_iCCP;
930*593dc095SDavid du Colombier #endif
931*593dc095SDavid du Colombier #if defined(PNG_READ_iTXt_SUPPORTED)
932*593dc095SDavid du Colombier       PNG_iTXt;
933*593dc095SDavid du Colombier #endif
934*593dc095SDavid du Colombier #if defined(PNG_READ_oFFs_SUPPORTED)
935*593dc095SDavid du Colombier       PNG_oFFs;
936*593dc095SDavid du Colombier #endif
937*593dc095SDavid du Colombier #if defined(PNG_READ_pCAL_SUPPORTED)
938*593dc095SDavid du Colombier       PNG_pCAL;
939*593dc095SDavid du Colombier #endif
940*593dc095SDavid du Colombier #if defined(PNG_READ_pHYs_SUPPORTED)
941*593dc095SDavid du Colombier       PNG_pHYs;
942*593dc095SDavid du Colombier #endif
943*593dc095SDavid du Colombier #if defined(PNG_READ_sBIT_SUPPORTED)
944*593dc095SDavid du Colombier       PNG_sBIT;
945*593dc095SDavid du Colombier #endif
946*593dc095SDavid du Colombier #if defined(PNG_READ_sCAL_SUPPORTED)
947*593dc095SDavid du Colombier       PNG_sCAL;
948*593dc095SDavid du Colombier #endif
949*593dc095SDavid du Colombier #if defined(PNG_READ_sPLT_SUPPORTED)
950*593dc095SDavid du Colombier       PNG_sPLT;
951*593dc095SDavid du Colombier #endif
952*593dc095SDavid du Colombier #if defined(PNG_READ_sRGB_SUPPORTED)
953*593dc095SDavid du Colombier       PNG_sRGB;
954*593dc095SDavid du Colombier #endif
955*593dc095SDavid du Colombier #if defined(PNG_READ_tEXt_SUPPORTED)
956*593dc095SDavid du Colombier       PNG_tEXt;
957*593dc095SDavid du Colombier #endif
958*593dc095SDavid du Colombier #if defined(PNG_READ_tIME_SUPPORTED)
959*593dc095SDavid du Colombier       PNG_tIME;
960*593dc095SDavid du Colombier #endif
961*593dc095SDavid du Colombier #if defined(PNG_READ_tRNS_SUPPORTED)
962*593dc095SDavid du Colombier       PNG_tRNS;
963*593dc095SDavid du Colombier #endif
964*593dc095SDavid du Colombier #if defined(PNG_READ_zTXt_SUPPORTED)
965*593dc095SDavid du Colombier       PNG_zTXt;
966*593dc095SDavid du Colombier #endif
967*593dc095SDavid du Colombier #endif /* PNG_USE_LOCAL_ARRAYS */
968*593dc095SDavid du Colombier 
9697dd7cddfSDavid du Colombier       png_read_data(png_ptr, chunk_length, 4);
970*593dc095SDavid du Colombier       length = png_get_uint_31(png_ptr,chunk_length);
9717dd7cddfSDavid du Colombier 
9727dd7cddfSDavid du Colombier       png_reset_crc(png_ptr);
9737dd7cddfSDavid du Colombier       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
9747dd7cddfSDavid du Colombier 
9757dd7cddfSDavid du Colombier       png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name);
9767dd7cddfSDavid du Colombier 
9777dd7cddfSDavid du Colombier       if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
9787dd7cddfSDavid du Colombier          png_handle_IHDR(png_ptr, info_ptr, length);
979*593dc095SDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
980*593dc095SDavid du Colombier          png_handle_IEND(png_ptr, info_ptr, length);
981*593dc095SDavid du Colombier #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
982*593dc095SDavid du Colombier       else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
983*593dc095SDavid du Colombier       {
984*593dc095SDavid du Colombier          if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
985*593dc095SDavid du Colombier          {
986*593dc095SDavid du Colombier             if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT)
987*593dc095SDavid du Colombier                png_error(png_ptr, "Too many IDAT's found");
988*593dc095SDavid du Colombier          }
989*593dc095SDavid du Colombier          else
990*593dc095SDavid du Colombier             png_ptr->mode |= PNG_AFTER_IDAT;
991*593dc095SDavid du Colombier          png_handle_unknown(png_ptr, info_ptr, length);
992*593dc095SDavid du Colombier          if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
993*593dc095SDavid du Colombier             png_ptr->mode |= PNG_HAVE_PLTE;
994*593dc095SDavid du Colombier       }
995*593dc095SDavid du Colombier #endif
9967dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
9977dd7cddfSDavid du Colombier       {
9987dd7cddfSDavid du Colombier          /* Zero length IDATs are legal after the last IDAT has been
9997dd7cddfSDavid du Colombier           * read, but not after other chunks have been read.
10007dd7cddfSDavid du Colombier           */
10017dd7cddfSDavid du Colombier          if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT)
10027dd7cddfSDavid du Colombier             png_error(png_ptr, "Too many IDAT's found");
1003*593dc095SDavid du Colombier          png_crc_finish(png_ptr, length);
10047dd7cddfSDavid du Colombier       }
10057dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
10067dd7cddfSDavid du Colombier          png_handle_PLTE(png_ptr, info_ptr, length);
10077dd7cddfSDavid du Colombier #if defined(PNG_READ_bKGD_SUPPORTED)
10087dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
10097dd7cddfSDavid du Colombier          png_handle_bKGD(png_ptr, info_ptr, length);
10107dd7cddfSDavid du Colombier #endif
10117dd7cddfSDavid du Colombier #if defined(PNG_READ_cHRM_SUPPORTED)
10127dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
10137dd7cddfSDavid du Colombier          png_handle_cHRM(png_ptr, info_ptr, length);
10147dd7cddfSDavid du Colombier #endif
10157dd7cddfSDavid du Colombier #if defined(PNG_READ_gAMA_SUPPORTED)
10167dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
10177dd7cddfSDavid du Colombier          png_handle_gAMA(png_ptr, info_ptr, length);
10187dd7cddfSDavid du Colombier #endif
10197dd7cddfSDavid du Colombier #if defined(PNG_READ_hIST_SUPPORTED)
10207dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
10217dd7cddfSDavid du Colombier          png_handle_hIST(png_ptr, info_ptr, length);
10227dd7cddfSDavid du Colombier #endif
10237dd7cddfSDavid du Colombier #if defined(PNG_READ_oFFs_SUPPORTED)
10247dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
10257dd7cddfSDavid du Colombier          png_handle_oFFs(png_ptr, info_ptr, length);
10267dd7cddfSDavid du Colombier #endif
10277dd7cddfSDavid du Colombier #if defined(PNG_READ_pCAL_SUPPORTED)
10287dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
10297dd7cddfSDavid du Colombier          png_handle_pCAL(png_ptr, info_ptr, length);
10307dd7cddfSDavid du Colombier #endif
1031*593dc095SDavid du Colombier #if defined(PNG_READ_sCAL_SUPPORTED)
1032*593dc095SDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
1033*593dc095SDavid du Colombier          png_handle_sCAL(png_ptr, info_ptr, length);
1034*593dc095SDavid du Colombier #endif
10357dd7cddfSDavid du Colombier #if defined(PNG_READ_pHYs_SUPPORTED)
10367dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
10377dd7cddfSDavid du Colombier          png_handle_pHYs(png_ptr, info_ptr, length);
10387dd7cddfSDavid du Colombier #endif
10397dd7cddfSDavid du Colombier #if defined(PNG_READ_sBIT_SUPPORTED)
10407dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
10417dd7cddfSDavid du Colombier          png_handle_sBIT(png_ptr, info_ptr, length);
10427dd7cddfSDavid du Colombier #endif
10437dd7cddfSDavid du Colombier #if defined(PNG_READ_sRGB_SUPPORTED)
10447dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
10457dd7cddfSDavid du Colombier          png_handle_sRGB(png_ptr, info_ptr, length);
10467dd7cddfSDavid du Colombier #endif
1047*593dc095SDavid du Colombier #if defined(PNG_READ_iCCP_SUPPORTED)
1048*593dc095SDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
1049*593dc095SDavid du Colombier          png_handle_iCCP(png_ptr, info_ptr, length);
1050*593dc095SDavid du Colombier #endif
1051*593dc095SDavid du Colombier #if defined(PNG_READ_sPLT_SUPPORTED)
1052*593dc095SDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
1053*593dc095SDavid du Colombier          png_handle_sPLT(png_ptr, info_ptr, length);
1054*593dc095SDavid du Colombier #endif
10557dd7cddfSDavid du Colombier #if defined(PNG_READ_tEXt_SUPPORTED)
10567dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
10577dd7cddfSDavid du Colombier          png_handle_tEXt(png_ptr, info_ptr, length);
10587dd7cddfSDavid du Colombier #endif
10597dd7cddfSDavid du Colombier #if defined(PNG_READ_tIME_SUPPORTED)
10607dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
10617dd7cddfSDavid du Colombier          png_handle_tIME(png_ptr, info_ptr, length);
10627dd7cddfSDavid du Colombier #endif
10637dd7cddfSDavid du Colombier #if defined(PNG_READ_tRNS_SUPPORTED)
10647dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
10657dd7cddfSDavid du Colombier          png_handle_tRNS(png_ptr, info_ptr, length);
10667dd7cddfSDavid du Colombier #endif
10677dd7cddfSDavid du Colombier #if defined(PNG_READ_zTXt_SUPPORTED)
10687dd7cddfSDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
10697dd7cddfSDavid du Colombier          png_handle_zTXt(png_ptr, info_ptr, length);
10707dd7cddfSDavid du Colombier #endif
1071*593dc095SDavid du Colombier #if defined(PNG_READ_iTXt_SUPPORTED)
1072*593dc095SDavid du Colombier       else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
1073*593dc095SDavid du Colombier          png_handle_iTXt(png_ptr, info_ptr, length);
1074*593dc095SDavid du Colombier #endif
10757dd7cddfSDavid du Colombier       else
10767dd7cddfSDavid du Colombier          png_handle_unknown(png_ptr, info_ptr, length);
10777dd7cddfSDavid du Colombier    } while (!(png_ptr->mode & PNG_HAVE_IEND));
10787dd7cddfSDavid du Colombier }
1079*593dc095SDavid du Colombier #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
10807dd7cddfSDavid du Colombier 
10817dd7cddfSDavid du Colombier /* free all memory used by the read */
1082*593dc095SDavid du Colombier void PNGAPI
png_destroy_read_struct(png_structpp png_ptr_ptr,png_infopp info_ptr_ptr,png_infopp end_info_ptr_ptr)10837dd7cddfSDavid du Colombier png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
10847dd7cddfSDavid du Colombier    png_infopp end_info_ptr_ptr)
10857dd7cddfSDavid du Colombier {
10867dd7cddfSDavid du Colombier    png_structp png_ptr = NULL;
10877dd7cddfSDavid du Colombier    png_infop info_ptr = NULL, end_info_ptr = NULL;
1088*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
1089*593dc095SDavid du Colombier    png_free_ptr free_fn;
1090*593dc095SDavid du Colombier    png_voidp mem_ptr;
1091*593dc095SDavid du Colombier #endif
10927dd7cddfSDavid du Colombier 
10937dd7cddfSDavid du Colombier    png_debug(1, "in png_destroy_read_struct\n");
10947dd7cddfSDavid du Colombier    if (png_ptr_ptr != NULL)
10957dd7cddfSDavid du Colombier       png_ptr = *png_ptr_ptr;
10967dd7cddfSDavid du Colombier 
10977dd7cddfSDavid du Colombier    if (info_ptr_ptr != NULL)
10987dd7cddfSDavid du Colombier       info_ptr = *info_ptr_ptr;
10997dd7cddfSDavid du Colombier 
11007dd7cddfSDavid du Colombier    if (end_info_ptr_ptr != NULL)
11017dd7cddfSDavid du Colombier       end_info_ptr = *end_info_ptr_ptr;
11027dd7cddfSDavid du Colombier 
1103*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
1104*593dc095SDavid du Colombier    free_fn = png_ptr->free_fn;
1105*593dc095SDavid du Colombier    mem_ptr = png_ptr->mem_ptr;
1106*593dc095SDavid du Colombier #endif
1107*593dc095SDavid du Colombier 
11087dd7cddfSDavid du Colombier    png_read_destroy(png_ptr, info_ptr, end_info_ptr);
11097dd7cddfSDavid du Colombier 
11107dd7cddfSDavid du Colombier    if (info_ptr != NULL)
11117dd7cddfSDavid du Colombier    {
1112*593dc095SDavid du Colombier #if defined(PNG_TEXT_SUPPORTED)
1113*593dc095SDavid du Colombier       png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
11147dd7cddfSDavid du Colombier #endif
1115*593dc095SDavid du Colombier 
1116*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
1117*593dc095SDavid du Colombier       png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
1118*593dc095SDavid du Colombier           (png_voidp)mem_ptr);
1119*593dc095SDavid du Colombier #else
11207dd7cddfSDavid du Colombier       png_destroy_struct((png_voidp)info_ptr);
1121*593dc095SDavid du Colombier #endif
1122*593dc095SDavid du Colombier       *info_ptr_ptr = NULL;
11237dd7cddfSDavid du Colombier    }
11247dd7cddfSDavid du Colombier 
11257dd7cddfSDavid du Colombier    if (end_info_ptr != NULL)
11267dd7cddfSDavid du Colombier    {
1127*593dc095SDavid du Colombier #if defined(PNG_READ_TEXT_SUPPORTED)
1128*593dc095SDavid du Colombier       png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
11297dd7cddfSDavid du Colombier #endif
1130*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
1131*593dc095SDavid du Colombier       png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
1132*593dc095SDavid du Colombier          (png_voidp)mem_ptr);
1133*593dc095SDavid du Colombier #else
11347dd7cddfSDavid du Colombier       png_destroy_struct((png_voidp)end_info_ptr);
1135*593dc095SDavid du Colombier #endif
1136*593dc095SDavid du Colombier       *end_info_ptr_ptr = NULL;
11377dd7cddfSDavid du Colombier    }
11387dd7cddfSDavid du Colombier 
11397dd7cddfSDavid du Colombier    if (png_ptr != NULL)
11407dd7cddfSDavid du Colombier    {
1141*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
1142*593dc095SDavid du Colombier       png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
1143*593dc095SDavid du Colombier           (png_voidp)mem_ptr);
1144*593dc095SDavid du Colombier #else
11457dd7cddfSDavid du Colombier       png_destroy_struct((png_voidp)png_ptr);
1146*593dc095SDavid du Colombier #endif
1147*593dc095SDavid du Colombier       *png_ptr_ptr = NULL;
11487dd7cddfSDavid du Colombier    }
11497dd7cddfSDavid du Colombier }
11507dd7cddfSDavid du Colombier 
11517dd7cddfSDavid du Colombier /* free all memory used by the read (old method) */
1152*593dc095SDavid du Colombier void /* PRIVATE */
png_read_destroy(png_structp png_ptr,png_infop info_ptr,png_infop end_info_ptr)11537dd7cddfSDavid du Colombier png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
11547dd7cddfSDavid du Colombier {
1155*593dc095SDavid du Colombier #ifdef PNG_SETJMP_SUPPORTED
11567dd7cddfSDavid du Colombier    jmp_buf tmp_jmp;
1157*593dc095SDavid du Colombier #endif
11587dd7cddfSDavid du Colombier    png_error_ptr error_fn;
11597dd7cddfSDavid du Colombier    png_error_ptr warning_fn;
11607dd7cddfSDavid du Colombier    png_voidp error_ptr;
1161*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
1162*593dc095SDavid du Colombier    png_free_ptr free_fn;
1163*593dc095SDavid du Colombier #endif
11647dd7cddfSDavid du Colombier 
11657dd7cddfSDavid du Colombier    png_debug(1, "in png_read_destroy\n");
11667dd7cddfSDavid du Colombier    if (info_ptr != NULL)
11677dd7cddfSDavid du Colombier       png_info_destroy(png_ptr, info_ptr);
11687dd7cddfSDavid du Colombier 
11697dd7cddfSDavid du Colombier    if (end_info_ptr != NULL)
11707dd7cddfSDavid du Colombier       png_info_destroy(png_ptr, end_info_ptr);
11717dd7cddfSDavid du Colombier 
11727dd7cddfSDavid du Colombier    png_free(png_ptr, png_ptr->zbuf);
1173*593dc095SDavid du Colombier    png_free(png_ptr, png_ptr->big_row_buf);
11747dd7cddfSDavid du Colombier    png_free(png_ptr, png_ptr->prev_row);
11757dd7cddfSDavid du Colombier #if defined(PNG_READ_DITHER_SUPPORTED)
11767dd7cddfSDavid du Colombier    png_free(png_ptr, png_ptr->palette_lookup);
11777dd7cddfSDavid du Colombier    png_free(png_ptr, png_ptr->dither_index);
11787dd7cddfSDavid du Colombier #endif
11797dd7cddfSDavid du Colombier #if defined(PNG_READ_GAMMA_SUPPORTED)
11807dd7cddfSDavid du Colombier    png_free(png_ptr, png_ptr->gamma_table);
11817dd7cddfSDavid du Colombier #endif
11827dd7cddfSDavid du Colombier #if defined(PNG_READ_BACKGROUND_SUPPORTED)
11837dd7cddfSDavid du Colombier    png_free(png_ptr, png_ptr->gamma_from_1);
11847dd7cddfSDavid du Colombier    png_free(png_ptr, png_ptr->gamma_to_1);
11857dd7cddfSDavid du Colombier #endif
1186*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
1187*593dc095SDavid du Colombier    if (png_ptr->free_me & PNG_FREE_PLTE)
11887dd7cddfSDavid du Colombier       png_zfree(png_ptr, png_ptr->palette);
1189*593dc095SDavid du Colombier    png_ptr->free_me &= ~PNG_FREE_PLTE;
1190*593dc095SDavid du Colombier #else
1191*593dc095SDavid du Colombier    if (png_ptr->flags & PNG_FLAG_FREE_PLTE)
1192*593dc095SDavid du Colombier       png_zfree(png_ptr, png_ptr->palette);
1193*593dc095SDavid du Colombier    png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
1194*593dc095SDavid du Colombier #endif
1195*593dc095SDavid du Colombier #if defined(PNG_tRNS_SUPPORTED) || \
1196*593dc095SDavid du Colombier     defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
1197*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
1198*593dc095SDavid du Colombier    if (png_ptr->free_me & PNG_FREE_TRNS)
11997dd7cddfSDavid du Colombier       png_free(png_ptr, png_ptr->trans);
1200*593dc095SDavid du Colombier    png_ptr->free_me &= ~PNG_FREE_TRNS;
1201*593dc095SDavid du Colombier #else
1202*593dc095SDavid du Colombier    if (png_ptr->flags & PNG_FLAG_FREE_TRNS)
1203*593dc095SDavid du Colombier       png_free(png_ptr, png_ptr->trans);
1204*593dc095SDavid du Colombier    png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
1205*593dc095SDavid du Colombier #endif
12067dd7cddfSDavid du Colombier #endif
12077dd7cddfSDavid du Colombier #if defined(PNG_READ_hIST_SUPPORTED)
1208*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
1209*593dc095SDavid du Colombier    if (png_ptr->free_me & PNG_FREE_HIST)
1210*593dc095SDavid du Colombier       png_free(png_ptr, png_ptr->hist);
1211*593dc095SDavid du Colombier    png_ptr->free_me &= ~PNG_FREE_HIST;
1212*593dc095SDavid du Colombier #else
12137dd7cddfSDavid du Colombier    if (png_ptr->flags & PNG_FLAG_FREE_HIST)
12147dd7cddfSDavid du Colombier       png_free(png_ptr, png_ptr->hist);
1215*593dc095SDavid du Colombier    png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
1216*593dc095SDavid du Colombier #endif
12177dd7cddfSDavid du Colombier #endif
12187dd7cddfSDavid du Colombier #if defined(PNG_READ_GAMMA_SUPPORTED)
12197dd7cddfSDavid du Colombier    if (png_ptr->gamma_16_table != NULL)
12207dd7cddfSDavid du Colombier    {
12217dd7cddfSDavid du Colombier       int i;
1222*593dc095SDavid du Colombier       int istop = (1 << (8 - png_ptr->gamma_shift));
1223*593dc095SDavid du Colombier       for (i = 0; i < istop; i++)
12247dd7cddfSDavid du Colombier       {
12257dd7cddfSDavid du Colombier          png_free(png_ptr, png_ptr->gamma_16_table[i]);
12267dd7cddfSDavid du Colombier       }
12277dd7cddfSDavid du Colombier    png_free(png_ptr, png_ptr->gamma_16_table);
1228*593dc095SDavid du Colombier    }
1229*593dc095SDavid du Colombier #if defined(PNG_READ_BACKGROUND_SUPPORTED)
12307dd7cddfSDavid du Colombier    if (png_ptr->gamma_16_from_1 != NULL)
12317dd7cddfSDavid du Colombier    {
12327dd7cddfSDavid du Colombier       int i;
1233*593dc095SDavid du Colombier       int istop = (1 << (8 - png_ptr->gamma_shift));
1234*593dc095SDavid du Colombier       for (i = 0; i < istop; i++)
12357dd7cddfSDavid du Colombier       {
12367dd7cddfSDavid du Colombier          png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
12377dd7cddfSDavid du Colombier       }
12387dd7cddfSDavid du Colombier    png_free(png_ptr, png_ptr->gamma_16_from_1);
1239*593dc095SDavid du Colombier    }
12407dd7cddfSDavid du Colombier    if (png_ptr->gamma_16_to_1 != NULL)
12417dd7cddfSDavid du Colombier    {
12427dd7cddfSDavid du Colombier       int i;
1243*593dc095SDavid du Colombier       int istop = (1 << (8 - png_ptr->gamma_shift));
1244*593dc095SDavid du Colombier       for (i = 0; i < istop; i++)
12457dd7cddfSDavid du Colombier       {
12467dd7cddfSDavid du Colombier          png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
12477dd7cddfSDavid du Colombier       }
12487dd7cddfSDavid du Colombier    png_free(png_ptr, png_ptr->gamma_16_to_1);
1249*593dc095SDavid du Colombier    }
1250*593dc095SDavid du Colombier #endif
1251*593dc095SDavid du Colombier #endif
1252*593dc095SDavid du Colombier #if defined(PNG_TIME_RFC1123_SUPPORTED)
1253*593dc095SDavid du Colombier    png_free(png_ptr, png_ptr->time_buffer);
12547dd7cddfSDavid du Colombier #endif
12557dd7cddfSDavid du Colombier 
12567dd7cddfSDavid du Colombier    inflateEnd(&png_ptr->zstream);
12577dd7cddfSDavid du Colombier #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
12587dd7cddfSDavid du Colombier    png_free(png_ptr, png_ptr->save_buffer);
12597dd7cddfSDavid du Colombier #endif
12607dd7cddfSDavid du Colombier 
1261*593dc095SDavid du Colombier #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
1262*593dc095SDavid du Colombier #ifdef PNG_TEXT_SUPPORTED
1263*593dc095SDavid du Colombier    png_free(png_ptr, png_ptr->current_text);
1264*593dc095SDavid du Colombier #endif /* PNG_TEXT_SUPPORTED */
1265*593dc095SDavid du Colombier #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
1266*593dc095SDavid du Colombier 
12677dd7cddfSDavid du Colombier    /* Save the important info out of the png_struct, in case it is
12687dd7cddfSDavid du Colombier     * being used again.
12697dd7cddfSDavid du Colombier     */
1270*593dc095SDavid du Colombier #ifdef PNG_SETJMP_SUPPORTED
1271*593dc095SDavid du Colombier    png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
1272*593dc095SDavid du Colombier #endif
12737dd7cddfSDavid du Colombier 
12747dd7cddfSDavid du Colombier    error_fn = png_ptr->error_fn;
12757dd7cddfSDavid du Colombier    warning_fn = png_ptr->warning_fn;
12767dd7cddfSDavid du Colombier    error_ptr = png_ptr->error_ptr;
1277*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
1278*593dc095SDavid du Colombier    free_fn = png_ptr->free_fn;
1279*593dc095SDavid du Colombier #endif
12807dd7cddfSDavid du Colombier 
1281*593dc095SDavid du Colombier    png_memset(png_ptr, 0, png_sizeof (png_struct));
12827dd7cddfSDavid du Colombier 
12837dd7cddfSDavid du Colombier    png_ptr->error_fn = error_fn;
12847dd7cddfSDavid du Colombier    png_ptr->warning_fn = warning_fn;
12857dd7cddfSDavid du Colombier    png_ptr->error_ptr = error_ptr;
1286*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
1287*593dc095SDavid du Colombier    png_ptr->free_fn = free_fn;
1288*593dc095SDavid du Colombier #endif
12897dd7cddfSDavid du Colombier 
1290*593dc095SDavid du Colombier #ifdef PNG_SETJMP_SUPPORTED
1291*593dc095SDavid du Colombier    png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
1292*593dc095SDavid du Colombier #endif
1293*593dc095SDavid du Colombier 
12947dd7cddfSDavid du Colombier }
1295*593dc095SDavid du Colombier 
1296*593dc095SDavid du Colombier void PNGAPI
png_set_read_status_fn(png_structp png_ptr,png_read_status_ptr read_row_fn)1297*593dc095SDavid du Colombier png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
1298*593dc095SDavid du Colombier {
1299*593dc095SDavid du Colombier    png_ptr->read_row_fn = read_row_fn;
1300*593dc095SDavid du Colombier }
1301*593dc095SDavid du Colombier 
1302*593dc095SDavid du Colombier 
1303*593dc095SDavid du Colombier #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
1304*593dc095SDavid du Colombier #if defined(PNG_INFO_IMAGE_SUPPORTED)
1305*593dc095SDavid du Colombier void PNGAPI
png_read_png(png_structp png_ptr,png_infop info_ptr,int transforms,voidp params)1306*593dc095SDavid du Colombier png_read_png(png_structp png_ptr, png_infop info_ptr,
1307*593dc095SDavid du Colombier                            int transforms,
1308*593dc095SDavid du Colombier                            voidp params)
1309*593dc095SDavid du Colombier {
1310*593dc095SDavid du Colombier    int row;
1311*593dc095SDavid du Colombier 
1312*593dc095SDavid du Colombier #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1313*593dc095SDavid du Colombier    /* invert the alpha channel from opacity to transparency
1314*593dc095SDavid du Colombier     */
1315*593dc095SDavid du Colombier    if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
1316*593dc095SDavid du Colombier        png_set_invert_alpha(png_ptr);
1317*593dc095SDavid du Colombier #endif
1318*593dc095SDavid du Colombier 
1319*593dc095SDavid du Colombier    /* png_read_info() gives us all of the information from the
1320*593dc095SDavid du Colombier     * PNG file before the first IDAT (image data chunk).
1321*593dc095SDavid du Colombier     */
1322*593dc095SDavid du Colombier    png_read_info(png_ptr, info_ptr);
1323*593dc095SDavid du Colombier    if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
1324*593dc095SDavid du Colombier       png_error(png_ptr,"Image is too high to process with png_read_png()");
1325*593dc095SDavid du Colombier 
1326*593dc095SDavid du Colombier    /* -------------- image transformations start here ------------------- */
1327*593dc095SDavid du Colombier 
1328*593dc095SDavid du Colombier #if defined(PNG_READ_16_TO_8_SUPPORTED)
1329*593dc095SDavid du Colombier    /* tell libpng to strip 16 bit/color files down to 8 bits per color
1330*593dc095SDavid du Colombier     */
1331*593dc095SDavid du Colombier    if (transforms & PNG_TRANSFORM_STRIP_16)
1332*593dc095SDavid du Colombier        png_set_strip_16(png_ptr);
1333*593dc095SDavid du Colombier #endif
1334*593dc095SDavid du Colombier 
1335*593dc095SDavid du Colombier #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1336*593dc095SDavid du Colombier    /* Strip alpha bytes from the input data without combining with
1337*593dc095SDavid du Colombier     * the background (not recommended).
1338*593dc095SDavid du Colombier     */
1339*593dc095SDavid du Colombier    if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
1340*593dc095SDavid du Colombier        png_set_strip_alpha(png_ptr);
1341*593dc095SDavid du Colombier #endif
1342*593dc095SDavid du Colombier 
1343*593dc095SDavid du Colombier #if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
1344*593dc095SDavid du Colombier    /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
1345*593dc095SDavid du Colombier     * byte into separate bytes (useful for paletted and grayscale images).
1346*593dc095SDavid du Colombier     */
1347*593dc095SDavid du Colombier    if (transforms & PNG_TRANSFORM_PACKING)
1348*593dc095SDavid du Colombier        png_set_packing(png_ptr);
1349*593dc095SDavid du Colombier #endif
1350*593dc095SDavid du Colombier 
1351*593dc095SDavid du Colombier #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1352*593dc095SDavid du Colombier    /* Change the order of packed pixels to least significant bit first
1353*593dc095SDavid du Colombier     * (not useful if you are using png_set_packing).
1354*593dc095SDavid du Colombier     */
1355*593dc095SDavid du Colombier    if (transforms & PNG_TRANSFORM_PACKSWAP)
1356*593dc095SDavid du Colombier        png_set_packswap(png_ptr);
1357*593dc095SDavid du Colombier #endif
1358*593dc095SDavid du Colombier 
1359*593dc095SDavid du Colombier #if defined(PNG_READ_EXPAND_SUPPORTED)
1360*593dc095SDavid du Colombier    /* Expand paletted colors into true RGB triplets
1361*593dc095SDavid du Colombier     * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
1362*593dc095SDavid du Colombier     * Expand paletted or RGB images with transparency to full alpha
1363*593dc095SDavid du Colombier     * channels so the data will be available as RGBA quartets.
1364*593dc095SDavid du Colombier     */
1365*593dc095SDavid du Colombier    if (transforms & PNG_TRANSFORM_EXPAND)
1366*593dc095SDavid du Colombier        if ((png_ptr->bit_depth < 8) ||
1367*593dc095SDavid du Colombier            (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
1368*593dc095SDavid du Colombier            (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
1369*593dc095SDavid du Colombier          png_set_expand(png_ptr);
1370*593dc095SDavid du Colombier #endif
1371*593dc095SDavid du Colombier 
1372*593dc095SDavid du Colombier    /* We don't handle background color or gamma transformation or dithering.
1373*593dc095SDavid du Colombier     */
1374*593dc095SDavid du Colombier 
1375*593dc095SDavid du Colombier #if defined(PNG_READ_INVERT_SUPPORTED)
1376*593dc095SDavid du Colombier    /* invert monochrome files to have 0 as white and 1 as black
1377*593dc095SDavid du Colombier     */
1378*593dc095SDavid du Colombier    if (transforms & PNG_TRANSFORM_INVERT_MONO)
1379*593dc095SDavid du Colombier        png_set_invert_mono(png_ptr);
1380*593dc095SDavid du Colombier #endif
1381*593dc095SDavid du Colombier 
1382*593dc095SDavid du Colombier #if defined(PNG_READ_SHIFT_SUPPORTED)
1383*593dc095SDavid du Colombier    /* If you want to shift the pixel values from the range [0,255] or
1384*593dc095SDavid du Colombier     * [0,65535] to the original [0,7] or [0,31], or whatever range the
1385*593dc095SDavid du Colombier     * colors were originally in:
1386*593dc095SDavid du Colombier     */
1387*593dc095SDavid du Colombier    if ((transforms & PNG_TRANSFORM_SHIFT)
1388*593dc095SDavid du Colombier        && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
1389*593dc095SDavid du Colombier    {
1390*593dc095SDavid du Colombier       png_color_8p sig_bit;
1391*593dc095SDavid du Colombier 
1392*593dc095SDavid du Colombier       png_get_sBIT(png_ptr, info_ptr, &sig_bit);
1393*593dc095SDavid du Colombier       png_set_shift(png_ptr, sig_bit);
1394*593dc095SDavid du Colombier    }
1395*593dc095SDavid du Colombier #endif
1396*593dc095SDavid du Colombier 
1397*593dc095SDavid du Colombier #if defined(PNG_READ_BGR_SUPPORTED)
1398*593dc095SDavid du Colombier    /* flip the RGB pixels to BGR (or RGBA to BGRA)
1399*593dc095SDavid du Colombier     */
1400*593dc095SDavid du Colombier    if (transforms & PNG_TRANSFORM_BGR)
1401*593dc095SDavid du Colombier        png_set_bgr(png_ptr);
1402*593dc095SDavid du Colombier #endif
1403*593dc095SDavid du Colombier 
1404*593dc095SDavid du Colombier #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1405*593dc095SDavid du Colombier    /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
1406*593dc095SDavid du Colombier     */
1407*593dc095SDavid du Colombier    if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
1408*593dc095SDavid du Colombier        png_set_swap_alpha(png_ptr);
1409*593dc095SDavid du Colombier #endif
1410*593dc095SDavid du Colombier 
1411*593dc095SDavid du Colombier #if defined(PNG_READ_SWAP_SUPPORTED)
1412*593dc095SDavid du Colombier    /* swap bytes of 16 bit files to least significant byte first
1413*593dc095SDavid du Colombier     */
1414*593dc095SDavid du Colombier    if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
1415*593dc095SDavid du Colombier        png_set_swap(png_ptr);
1416*593dc095SDavid du Colombier #endif
1417*593dc095SDavid du Colombier 
1418*593dc095SDavid du Colombier    /* We don't handle adding filler bytes */
1419*593dc095SDavid du Colombier 
1420*593dc095SDavid du Colombier    /* Optional call to gamma correct and add the background to the palette
1421*593dc095SDavid du Colombier     * and update info structure.  REQUIRED if you are expecting libpng to
1422*593dc095SDavid du Colombier     * update the palette for you (i.e., you selected such a transform above).
1423*593dc095SDavid du Colombier     */
1424*593dc095SDavid du Colombier    png_read_update_info(png_ptr, info_ptr);
1425*593dc095SDavid du Colombier 
1426*593dc095SDavid du Colombier    /* -------------- image transformations end here ------------------- */
1427*593dc095SDavid du Colombier 
1428*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
1429*593dc095SDavid du Colombier    png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1430*593dc095SDavid du Colombier #endif
1431*593dc095SDavid du Colombier    if(info_ptr->row_pointers == NULL)
1432*593dc095SDavid du Colombier    {
1433*593dc095SDavid du Colombier       info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
1434*593dc095SDavid du Colombier          info_ptr->height * png_sizeof(png_bytep));
1435*593dc095SDavid du Colombier #ifdef PNG_FREE_ME_SUPPORTED
1436*593dc095SDavid du Colombier       info_ptr->free_me |= PNG_FREE_ROWS;
1437*593dc095SDavid du Colombier #endif
1438*593dc095SDavid du Colombier       for (row = 0; row < (int)info_ptr->height; row++)
1439*593dc095SDavid du Colombier       {
1440*593dc095SDavid du Colombier          info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
1441*593dc095SDavid du Colombier             png_get_rowbytes(png_ptr, info_ptr));
1442*593dc095SDavid du Colombier       }
1443*593dc095SDavid du Colombier    }
1444*593dc095SDavid du Colombier 
1445*593dc095SDavid du Colombier    png_read_image(png_ptr, info_ptr->row_pointers);
1446*593dc095SDavid du Colombier    info_ptr->valid |= PNG_INFO_IDAT;
1447*593dc095SDavid du Colombier 
1448*593dc095SDavid du Colombier    /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
1449*593dc095SDavid du Colombier    png_read_end(png_ptr, info_ptr);
1450*593dc095SDavid du Colombier 
1451*593dc095SDavid du Colombier    if(transforms == 0 || params == NULL)
1452*593dc095SDavid du Colombier       /* quiet compiler warnings */ return;
1453*593dc095SDavid du Colombier 
1454*593dc095SDavid du Colombier }
1455*593dc095SDavid du Colombier #endif
1456*593dc095SDavid du Colombier #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
1457