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