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