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