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