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