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