pngread.c 40.9 KB
Newer Older
G
Guy Schalnat 已提交
1

A
Andreas Dilger 已提交
2
/* pngread.c - read a PNG file
3
 *
4
 * Last changed in libpng 1.5.0 [April 29, 2010]
5
 * Copyright (c) 1998-2010 Glenn Randers-Pehrson
6 7
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8
 *
9
 * This code is released under the libpng license.
10
 * For conditions of distribution and use, see the disclaimer
11
 * and license in png.h
12
 *
13 14 15
 * This file contains routines that an application calls directly to
 * read a PNG file or stream.
 */
G
Guy Schalnat 已提交
16

17
#include "pngpriv.h"
18

19
#ifdef PNG_READ_SUPPORTED
20

A
Andreas Dilger 已提交
21
/* Create a PNG structure for reading, and allocate any memory needed. */
22
png_structp PNGAPI
23
png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
24
    png_error_ptr error_fn, png_error_ptr warn_fn)
G
Guy Schalnat 已提交
25
{
26 27 28

#ifdef PNG_USER_MEM_SUPPORTED
   return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
29
      warn_fn, NULL, NULL, NULL));
30 31
}

32 33 34
/* Alternate create PNG structure for reading, and allocate any memory
 * needed.
 */
35
png_structp PNGAPI
36
png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
37 38
    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
    png_malloc_ptr malloc_fn, png_free_ptr free_fn)
39 40 41
{
#endif /* PNG_USER_MEM_SUPPORTED */

42 43 44 45
#ifdef PNG_SETJMP_SUPPORTED
   volatile
#endif
   png_structp png_ptr;
46
   volatile int png_cleanup_needed = 0;
47 48

#ifdef PNG_SETJMP_SUPPORTED
A
Andreas Dilger 已提交
49
#ifdef USE_FAR_KEYWORD
50
   jmp_buf png_jmpbuf;
A
Andreas Dilger 已提交
51
#endif
52 53
#endif

54 55
   int i;

56
   png_debug(1, "in png_create_read_struct");
57

58
#ifdef PNG_USER_MEM_SUPPORTED
59
   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
60
      malloc_fn, mem_ptr);
61
#else
62
   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
63
#endif
64
   if (png_ptr == NULL)
65
      return (NULL);
66

67
   /* Added at libpng-1.2.6 */
68
#ifdef PNG_USER_LIMITS_SUPPORTED
69 70
   png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
   png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
71 72
#  ifdef PNG_USER_CHUNK_CACHE_MAX
   /* Added at libpng-1.2.43 and 1.4.0 */
73
   png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
74 75 76 77 78
#  endif
#  ifdef PNG_SET_USER_CHUNK_MALLOC_MAX
   /* Added at libpng-1.2.43 and 1.4.1 */
   png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
#  endif
79 80
#endif

81 82 83 84 85
#ifdef PNG_SETJMP_SUPPORTED
/* Applications that neglect to set up their own setjmp() and then
   encounter a png_error() will longjmp here.  Since the jmpbuf is
   then meaningless we abort instead of returning. */
#ifdef USE_FAR_KEYWORD
86
   if (setjmp(png_jmpbuf))
87
#else
88
   if (setjmp(png_jmpbuf(png_ptr))) /* Sets longjmp to match setjmp */
89
#endif
90
      PNG_ABORT();
91
#ifdef USE_FAR_KEYWORD
92
   png_memcpy(png_jmpbuf(png_ptr), png_jmpbuf, png_sizeof(jmp_buf));
93
#endif
94
#endif /* PNG_SETJMP_SUPPORTED */
95

96 97
#ifdef PNG_USER_MEM_SUPPORTED
   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
98
#endif
99

A
Andreas Dilger 已提交
100 101
   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);

102
   if (user_png_ver)
G
Guy Schalnat 已提交
103
   {
104 105 106 107 108 109 110 111
      i = 0;
      do
      {
         if (user_png_ver[i] != png_libpng_ver[i])
            png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
      } while (png_libpng_ver[i++]);
    }
    else
112
       png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
113

114

115 116 117 118 119 120 121 122 123 124 125
    if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
    {
       /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
       * we must recompile any applications that use any older library version.
       * For versions after libpng 1.0, we will be compatible, so we need
       * only check the first digit.
       */
      if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
          (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
          (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
      {
126
#ifdef PNG_CONSOLE_IO_SUPPORTED
127 128 129
         char msg[80];
         if (user_png_ver)
         {
130 131 132 133 134
            png_snprintf2(msg, 80,
                "Application built with libpng-%.20s"
                " but running with %.20s",
                user_png_ver,
                png_libpng_ver);
135
            png_warning(png_ptr, msg);
136
         }
137 138 139
#else
         png_warning(png_ptr,
             "Incompatible libpng version in application and library");
140 141
#endif
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
142
         png_ptr->flags = 0;
143
#endif
144

145 146
         png_cleanup_needed = 1;
      }
147 148
   }

149 150
   if (!png_cleanup_needed)
   {
151
   /* Initialize zbuf - compression buffer */
G
Guy Schalnat 已提交
152
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
153
   png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr,
154
       png_ptr->zbuf_size);
155
   if (png_ptr->zbuf == NULL)
156
      png_cleanup_needed = 1;
157
   }
A
Andreas Dilger 已提交
158 159 160
   png_ptr->zstream.zalloc = png_zalloc;
   png_ptr->zstream.zfree = png_zfree;
   png_ptr->zstream.opaque = (voidpf)png_ptr;
G
Guy Schalnat 已提交
161

162 163
   if (!png_cleanup_needed)
   {
164 165 166 167 168 169 170 171 172 173 174
      switch (inflateInit(&png_ptr->zstream))
      {
         case Z_OK: /* Do nothing */ break;
         case Z_MEM_ERROR:
         case Z_STREAM_ERROR: png_warning(png_ptr, "zlib memory error");
            png_cleanup_needed = 1; break;
         case Z_VERSION_ERROR: png_warning(png_ptr, "zlib version error");
            png_cleanup_needed = 1; break;
         default: png_warning(png_ptr, "Unknown zlib error");
            png_cleanup_needed = 1;
      }
175 176 177 178
   }

   if (png_cleanup_needed)
   {
179 180 181
      /* Clean up PNG structure and deallocate any memory. */
      png_free(png_ptr, png_ptr->zbuf);
      png_ptr->zbuf = NULL;
182
#ifdef PNG_USER_MEM_SUPPORTED
183
      png_destroy_struct_2((png_voidp)png_ptr,
184
          (png_free_ptr)free_fn, (png_voidp)mem_ptr);
185
#else
186
      png_destroy_struct((png_voidp)png_ptr);
187
#endif
188
      return (NULL);
G
Guy Schalnat 已提交
189 190
   }

A
Andreas Dilger 已提交
191 192
   png_ptr->zstream.next_out = png_ptr->zbuf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
G
Guy Schalnat 已提交
193

194
   png_set_read_fn(png_ptr, NULL, NULL);
G
Guy Schalnat 已提交
195

196

G
Guy Schalnat 已提交
197 198 199
   return (png_ptr);
}

200

201
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
202
/* Read the information before the actual image data.  This has been
203
 * changed in v0.90 to allow reading a file that already has the magic
A
Andreas Dilger 已提交
204
 * bytes read from the stream.  You can tell libpng how many bytes have
205
 * been read from the beginning of the stream (up to the maximum of 8)
A
Andreas Dilger 已提交
206 207 208 209
 * via png_set_sig_bytes(), and we will only check the remaining bytes
 * here.  The application can then have access to the signature bytes we
 * read if it is determined that this isn't a valid PNG file.
 */
210
void PNGAPI
A
Andreas Dilger 已提交
211
png_read_info(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
212
{
213 214
   png_debug(1, "in png_read_info");
 
215 216
   if (png_ptr == NULL || info_ptr == NULL)
      return;
217
 
A
Andreas Dilger 已提交
218 219
   /* If we haven't checked all of the PNG signature bytes, do so now. */
   if (png_ptr->sig_bytes < 8)
G
Guy Schalnat 已提交
220
   {
A
Andreas Dilger 已提交
221 222
      png_size_t num_checked = png_ptr->sig_bytes,
                 num_to_check = 8 - num_checked;
A
Andreas Dilger 已提交
223

224 225 226
#ifdef PNG_IO_STATE_SUPPORTED
      png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE;
#endif
227

A
Andreas Dilger 已提交
228
      png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
A
Andreas Dilger 已提交
229 230 231 232 233 234 235 236 237 238
      png_ptr->sig_bytes = 8;

      if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
      {
         if (num_checked < 4 &&
             png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
            png_error(png_ptr, "Not a PNG file");
         else
            png_error(png_ptr, "PNG file corrupted by ASCII conversion");
      }
239 240
      if (num_checked < 3)
         png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
G
Guy Schalnat 已提交
241
   }
G
Guy Schalnat 已提交
242

243
   for (;;)
G
Guy Schalnat 已提交
244
   {
245 246 247 248
      PNG_IHDR;
      PNG_IDAT;
      PNG_IEND;
      PNG_PLTE;
249
#ifdef PNG_READ_bKGD_SUPPORTED
250
      PNG_bKGD;
251
#endif
252
#ifdef PNG_READ_cHRM_SUPPORTED
253
      PNG_cHRM;
254
#endif
255
#ifdef PNG_READ_gAMA_SUPPORTED
256
      PNG_gAMA;
257
#endif
258
#ifdef PNG_READ_hIST_SUPPORTED
259
      PNG_hIST;
260
#endif
261
#ifdef PNG_READ_iCCP_SUPPORTED
262
      PNG_iCCP;
263
#endif
264
#ifdef PNG_READ_iTXt_SUPPORTED
265
      PNG_iTXt;
266
#endif
267
#ifdef PNG_READ_oFFs_SUPPORTED
268
      PNG_oFFs;
269
#endif
270
#ifdef PNG_READ_pCAL_SUPPORTED
271
      PNG_pCAL;
272
#endif
273
#ifdef PNG_READ_pHYs_SUPPORTED
274
      PNG_pHYs;
275
#endif
276
#ifdef PNG_READ_sBIT_SUPPORTED
277
      PNG_sBIT;
278
#endif
279
#ifdef PNG_READ_sCAL_SUPPORTED
280
      PNG_sCAL;
281
#endif
282
#ifdef PNG_READ_sPLT_SUPPORTED
283
      PNG_sPLT;
284
#endif
285
#ifdef PNG_READ_sRGB_SUPPORTED
286
      PNG_sRGB;
287
#endif
288
#ifdef PNG_READ_tEXt_SUPPORTED
289
      PNG_tEXt;
290
#endif
291
#ifdef PNG_READ_tIME_SUPPORTED
292
      PNG_tIME;
293
#endif
294
#ifdef PNG_READ_tRNS_SUPPORTED
295
      PNG_tRNS;
296
#endif
297
#ifdef PNG_READ_zTXt_SUPPORTED
298
      PNG_zTXt;
299
#endif
300
      png_uint_32 length = png_read_chunk_header(png_ptr);
301
      PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
A
Andreas Dilger 已提交
302 303 304 305

      /* This should be a binary subdivision search or a hash for
       * matching the chunk name rather than a linear search.
       */
306
      if (!png_memcmp(chunk_name, png_IDAT, 4))
307 308
         if (png_ptr->mode & PNG_AFTER_IDAT)
            png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
309

310
      if (!png_memcmp(chunk_name, png_IHDR, 4))
A
Andreas Dilger 已提交
311
         png_handle_IHDR(png_ptr, info_ptr, length);
312
      else if (!png_memcmp(chunk_name, png_IEND, 4))
A
Andreas Dilger 已提交
313
         png_handle_IEND(png_ptr, info_ptr, length);
314
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
315
      else if (png_handle_as_unknown(png_ptr, chunk_name))
316
      {
317
         if (!png_memcmp(chunk_name, png_IDAT, 4))
318 319
            png_ptr->mode |= PNG_HAVE_IDAT;
         png_handle_unknown(png_ptr, info_ptr, length);
320
         if (!png_memcmp(chunk_name, png_PLTE, 4))
321
            png_ptr->mode |= PNG_HAVE_PLTE;
322
         else if (!png_memcmp(chunk_name, png_IDAT, 4))
323 324 325 326
         {
            if (!(png_ptr->mode & PNG_HAVE_IHDR))
               png_error(png_ptr, "Missing IHDR before IDAT");
            else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
327
                !(png_ptr->mode & PNG_HAVE_PLTE))
328 329 330 331 332
               png_error(png_ptr, "Missing PLTE before IDAT");
            break;
         }
      }
#endif
333
      else if (!png_memcmp(chunk_name, png_PLTE, 4))
334
         png_handle_PLTE(png_ptr, info_ptr, length);
335
      else if (!png_memcmp(chunk_name, png_IDAT, 4))
A
Andreas Dilger 已提交
336 337 338 339
      {
         if (!(png_ptr->mode & PNG_HAVE_IHDR))
            png_error(png_ptr, "Missing IHDR before IDAT");
         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
340
             !(png_ptr->mode & PNG_HAVE_PLTE))
A
Andreas Dilger 已提交
341 342 343 344 345 346
            png_error(png_ptr, "Missing PLTE before IDAT");

         png_ptr->idat_size = length;
         png_ptr->mode |= PNG_HAVE_IDAT;
         break;
      }
347
#ifdef PNG_READ_bKGD_SUPPORTED
348
      else if (!png_memcmp(chunk_name, png_bKGD, 4))
A
Andreas Dilger 已提交
349
         png_handle_bKGD(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
350
#endif
351
#ifdef PNG_READ_cHRM_SUPPORTED
352
      else if (!png_memcmp(chunk_name, png_cHRM, 4))
A
Andreas Dilger 已提交
353
         png_handle_cHRM(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
354
#endif
355
#ifdef PNG_READ_gAMA_SUPPORTED
356
      else if (!png_memcmp(chunk_name, png_gAMA, 4))
A
Andreas Dilger 已提交
357
         png_handle_gAMA(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
358
#endif
359
#ifdef PNG_READ_hIST_SUPPORTED
360
      else if (!png_memcmp(chunk_name, png_hIST, 4))
A
Andreas Dilger 已提交
361
         png_handle_hIST(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
362
#endif
363
#ifdef PNG_READ_oFFs_SUPPORTED
364
      else if (!png_memcmp(chunk_name, png_oFFs, 4))
A
Andreas Dilger 已提交
365 366
         png_handle_oFFs(png_ptr, info_ptr, length);
#endif
367
#ifdef PNG_READ_pCAL_SUPPORTED
368
      else if (!png_memcmp(chunk_name, png_pCAL, 4))
A
Andreas Dilger 已提交
369 370
         png_handle_pCAL(png_ptr, info_ptr, length);
#endif
371
#ifdef PNG_READ_sCAL_SUPPORTED
372
      else if (!png_memcmp(chunk_name, png_sCAL, 4))
373 374
         png_handle_sCAL(png_ptr, info_ptr, length);
#endif
375
#ifdef PNG_READ_pHYs_SUPPORTED
376
      else if (!png_memcmp(chunk_name, png_pHYs, 4))
A
Andreas Dilger 已提交
377
         png_handle_pHYs(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
378
#endif
379
#ifdef PNG_READ_sBIT_SUPPORTED
380
      else if (!png_memcmp(chunk_name, png_sBIT, 4))
A
Andreas Dilger 已提交
381 382
         png_handle_sBIT(png_ptr, info_ptr, length);
#endif
383
#ifdef PNG_READ_sRGB_SUPPORTED
384
      else if (!png_memcmp(chunk_name, png_sRGB, 4))
385 386
         png_handle_sRGB(png_ptr, info_ptr, length);
#endif
387
#ifdef PNG_READ_iCCP_SUPPORTED
388
      else if (!png_memcmp(chunk_name, png_iCCP, 4))
389 390
         png_handle_iCCP(png_ptr, info_ptr, length);
#endif
391
#ifdef PNG_READ_sPLT_SUPPORTED
392
      else if (!png_memcmp(chunk_name, png_sPLT, 4))
393 394
         png_handle_sPLT(png_ptr, info_ptr, length);
#endif
395
#ifdef PNG_READ_tEXt_SUPPORTED
396
      else if (!png_memcmp(chunk_name, png_tEXt, 4))
A
Andreas Dilger 已提交
397
         png_handle_tEXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
398
#endif
399
#ifdef PNG_READ_tIME_SUPPORTED
400
      else if (!png_memcmp(chunk_name, png_tIME, 4))
A
Andreas Dilger 已提交
401
         png_handle_tIME(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
402
#endif
403
#ifdef PNG_READ_tRNS_SUPPORTED
404
      else if (!png_memcmp(chunk_name, png_tRNS, 4))
A
Andreas Dilger 已提交
405
         png_handle_tRNS(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
406
#endif
407
#ifdef PNG_READ_zTXt_SUPPORTED
408
      else if (!png_memcmp(chunk_name, png_zTXt, 4))
A
Andreas Dilger 已提交
409
         png_handle_zTXt(png_ptr, info_ptr, length);
410
#endif
411
#ifdef PNG_READ_iTXt_SUPPORTED
412
      else if (!png_memcmp(chunk_name, png_iTXt, 4))
413
         png_handle_iTXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
414
#endif
A
Andreas Dilger 已提交
415 416
      else
         png_handle_unknown(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
417 418
   }
}
419
#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
420

421
/* Optional call to update the users info_ptr structure */
422
void PNGAPI
A
Andreas Dilger 已提交
423
png_read_update_info(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
424
{
425
   png_debug(1, "in png_read_update_info");
426
 
427 428
   if (png_ptr == NULL)
      return;
G
Guy Schalnat 已提交
429
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
430
      png_read_start_row(png_ptr);
431 432
   else
      png_warning(png_ptr,
433 434
          "Ignoring extra png_read_update_info() call;"
          " row buffer not reallocated");
435

A
Andreas Dilger 已提交
436
   png_read_transform_info(png_ptr, info_ptr);
G
Guy Schalnat 已提交
437 438
}

439
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
440 441
/* Initialize palette, background, etc, after transformations
 * are set, but before any reading takes place.  This allows
442
 * the user to obtain a gamma-corrected palette, for example.
443 444
 * If the user doesn't call this, we will do it ourselves.
 */
445
void PNGAPI
G
Guy Schalnat 已提交
446
png_start_read_image(png_structp png_ptr)
G
Guy Schalnat 已提交
447
{
448
   png_debug(1, "in png_start_read_image");
449
 
450 451
   if (png_ptr == NULL)
      return;
G
Guy Schalnat 已提交
452
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
453
      png_read_start_row(png_ptr);
G
Guy Schalnat 已提交
454
}
455
#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
456

457
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
458
void PNGAPI
G
Guy Schalnat 已提交
459
png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
G
Guy Schalnat 已提交
460
{
461
   PNG_IDAT;
462
   PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
463
       0xff};
464
   PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
G
Guy Schalnat 已提交
465
   int ret;
466
 
467 468
   if (png_ptr == NULL)
      return;
469
 
470
   png_debug2(1, "in png_read_row (row %lu, pass %d)",
471
       (unsigned long) png_ptr->row_number, png_ptr->pass);
472

G
Guy Schalnat 已提交
473
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
474
      png_read_start_row(png_ptr);
475 476
   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
   {
477
   /* Check for transforms that have been set but were defined out */
478 479
#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
   if (png_ptr->transformations & PNG_INVERT_MONO)
480
      png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined");
481 482 483
#endif
#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
   if (png_ptr->transformations & PNG_FILLER)
484
      png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined");
485
#endif
486 487
#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
    !defined(PNG_READ_PACKSWAP_SUPPORTED)
488
   if (png_ptr->transformations & PNG_PACKSWAP)
489
      png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined");
490 491 492
#endif
#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
   if (png_ptr->transformations & PNG_PACK)
493
      png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined");
494 495 496
#endif
#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
   if (png_ptr->transformations & PNG_SHIFT)
497
      png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined");
498 499 500
#endif
#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
   if (png_ptr->transformations & PNG_BGR)
501
      png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined");
502 503 504
#endif
#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
   if (png_ptr->transformations & PNG_SWAP_BYTES)
505
      png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined");
506 507
#endif
   }
G
Guy Schalnat 已提交
508

509
#ifdef PNG_READ_INTERLACING_SUPPORTED
510
   /* If interlaced and we do not need a new row, combine row and return */
G
Guy Schalnat 已提交
511 512 513 514 515
   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
   {
      switch (png_ptr->pass)
      {
         case 0:
516
            if (png_ptr->row_number & 0x07)
G
Guy Schalnat 已提交
517
            {
A
Andreas Dilger 已提交
518
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
519 520
                  png_combine_row(png_ptr, dsp_row,
                     png_pass_dsp_mask[png_ptr->pass]);
G
Guy Schalnat 已提交
521
               png_read_finish_row(png_ptr);
G
Guy Schalnat 已提交
522 523 524 525
               return;
            }
            break;
         case 1:
526
            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
G
Guy Schalnat 已提交
527
            {
A
Andreas Dilger 已提交
528
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
529 530 531 532 533 534 535
                  png_combine_row(png_ptr, dsp_row,
                     png_pass_dsp_mask[png_ptr->pass]);
               png_read_finish_row(png_ptr);
               return;
            }
            break;
         case 2:
536
            if ((png_ptr->row_number & 0x07) != 4)
G
Guy Schalnat 已提交
537
            {
A
Andreas Dilger 已提交
538
               if (dsp_row != NULL && (png_ptr->row_number & 4))
G
Guy Schalnat 已提交
539
                  png_combine_row(png_ptr, dsp_row,
G
Guy Schalnat 已提交
540 541 542 543 544 545 546 547
                     png_pass_dsp_mask[png_ptr->pass]);
               png_read_finish_row(png_ptr);
               return;
            }
            break;
         case 3:
            if ((png_ptr->row_number & 3) || png_ptr->width < 3)
            {
A
Andreas Dilger 已提交
548
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
549 550 551 552 553 554 555 556
                  png_combine_row(png_ptr, dsp_row,
                     png_pass_dsp_mask[png_ptr->pass]);
               png_read_finish_row(png_ptr);
               return;
            }
            break;
         case 4:
            if ((png_ptr->row_number & 3) != 2)
G
Guy Schalnat 已提交
557
            {
A
Andreas Dilger 已提交
558
               if (dsp_row != NULL && (png_ptr->row_number & 2))
G
Guy Schalnat 已提交
559 560 561 562 563 564 565 566 567
                  png_combine_row(png_ptr, dsp_row,
                     png_pass_dsp_mask[png_ptr->pass]);
               png_read_finish_row(png_ptr);
               return;
            }
            break;
         case 5:
            if ((png_ptr->row_number & 1) || png_ptr->width < 2)
            {
A
Andreas Dilger 已提交
568
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
569 570 571 572 573 574
                  png_combine_row(png_ptr, dsp_row,
                     png_pass_dsp_mask[png_ptr->pass]);
               png_read_finish_row(png_ptr);
               return;
            }
            break;
G
Guy Schalnat 已提交
575
         case 6:
G
Guy Schalnat 已提交
576 577 578 579 580 581 582 583
            if (!(png_ptr->row_number & 1))
            {
               png_read_finish_row(png_ptr);
               return;
            }
            break;
      }
   }
G
Guy Schalnat 已提交
584
#endif
G
Guy Schalnat 已提交
585

G
Guy Schalnat 已提交
586 587
   if (!(png_ptr->mode & PNG_HAVE_IDAT))
      png_error(png_ptr, "Invalid attempt to read row data");
G
Guy Schalnat 已提交
588

A
Andreas Dilger 已提交
589
   png_ptr->zstream.next_out = png_ptr->row_buf;
590 591 592
   png_ptr->zstream.avail_out =
       (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
       png_ptr->iwidth) + 1);
G
Guy Schalnat 已提交
593 594
   do
   {
A
Andreas Dilger 已提交
595
      if (!(png_ptr->zstream.avail_in))
G
Guy Schalnat 已提交
596 597 598
      {
         while (!png_ptr->idat_size)
         {
A
Andreas Dilger 已提交
599
            png_crc_finish(png_ptr, 0);
G
Guy Schalnat 已提交
600

601
            png_ptr->idat_size = png_read_chunk_header(png_ptr);
A
Andreas Dilger 已提交
602 603
            if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
               png_error(png_ptr, "Not enough image data");
G
Guy Schalnat 已提交
604
         }
A
Andreas Dilger 已提交
605 606
         png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
         png_ptr->zstream.next_in = png_ptr->zbuf;
G
Guy Schalnat 已提交
607
         if (png_ptr->zbuf_size > png_ptr->idat_size)
A
Andreas Dilger 已提交
608
            png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
A
Andreas Dilger 已提交
609
         png_crc_read(png_ptr, png_ptr->zbuf,
610
             (png_size_t)png_ptr->zstream.avail_in);
A
Andreas Dilger 已提交
611
         png_ptr->idat_size -= png_ptr->zstream.avail_in;
G
Guy Schalnat 已提交
612
      }
A
Andreas Dilger 已提交
613
      ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
G
Guy Schalnat 已提交
614 615
      if (ret == Z_STREAM_END)
      {
A
Andreas Dilger 已提交
616
         if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
G
Guy Schalnat 已提交
617
            png_ptr->idat_size)
618
            png_benign_error(png_ptr, "Extra compressed data");
A
Andreas Dilger 已提交
619
         png_ptr->mode |= PNG_AFTER_IDAT;
G
Guy Schalnat 已提交
620
         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
G
Guy Schalnat 已提交
621
         break;
G
Guy Schalnat 已提交
622 623
      }
      if (ret != Z_OK)
A
Andreas Dilger 已提交
624
         png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
625
             "Decompression error");
A
Andreas Dilger 已提交
626 627

   } while (png_ptr->zstream.avail_out);
G
Guy Schalnat 已提交
628 629 630 631 632 633

   png_ptr->row_info.color_type = png_ptr->color_type;
   png_ptr->row_info.width = png_ptr->iwidth;
   png_ptr->row_info.channels = png_ptr->channels;
   png_ptr->row_info.bit_depth = png_ptr->bit_depth;
   png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
634 635
   png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
       png_ptr->row_info.width);
G
Guy Schalnat 已提交
636

637
   if (png_ptr->row_buf[0])
G
Guy Schalnat 已提交
638
   png_read_filter_row(png_ptr, &(png_ptr->row_info),
639 640
       png_ptr->row_buf + 1, png_ptr->prev_row + 1,
       (int)(png_ptr->row_buf[0]));
G
Guy Schalnat 已提交
641

642
   png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1);
643

644
#ifdef PNG_MNG_FEATURES_SUPPORTED
645
   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
646
       (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
647 648 649 650 651
   {
      /* Intrapixel differencing */
      png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
   }
#endif
G
Guy Schalnat 已提交
652

653

654
   if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
G
Guy Schalnat 已提交
655 656
      png_do_read_transformations(png_ptr);

657
#ifdef PNG_READ_INTERLACING_SUPPORTED
658
   /* Blow up interlaced rows to full size */
G
Guy Schalnat 已提交
659 660 661 662
   if (png_ptr->interlaced &&
      (png_ptr->transformations & PNG_INTERLACE))
   {
      if (png_ptr->pass < 6)
663
         /* Old interface (pre-1.0.9):
664 665 666
          * png_do_read_interlace(&(png_ptr->row_info),
          *    png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
          */
667
         png_do_read_interlace(png_ptr);
G
Guy Schalnat 已提交
668

A
Andreas Dilger 已提交
669
      if (dsp_row != NULL)
670
         png_combine_row(png_ptr, dsp_row, png_pass_dsp_mask[png_ptr->pass]);
A
Andreas Dilger 已提交
671
      if (row != NULL)
672
         png_combine_row(png_ptr, row, png_pass_mask[png_ptr->pass]);
G
Guy Schalnat 已提交
673 674
   }
   else
G
Guy Schalnat 已提交
675
#endif
G
Guy Schalnat 已提交
676
   {
A
Andreas Dilger 已提交
677
      if (row != NULL)
G
Guy Schalnat 已提交
678
         png_combine_row(png_ptr, row, 0xff);
A
Andreas Dilger 已提交
679
      if (dsp_row != NULL)
G
Guy Schalnat 已提交
680 681 682
         png_combine_row(png_ptr, dsp_row, 0xff);
   }
   png_read_finish_row(png_ptr);
683 684 685

   if (png_ptr->read_row_fn != NULL)
      (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
G
Guy Schalnat 已提交
686
}
687
#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
688

689
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
690
/* Read one or more rows of image data.  If the image is interlaced,
691 692
 * and png_set_interlace_handling() has been called, the rows need to
 * contain the contents of the rows from the previous pass.  If the
693
 * image has alpha or transparency, and png_handle_alpha()[*] has been
694 695
 * called, the rows contents must be initialized to the contents of the
 * screen.
696
 *
697 698 699 700 701 702 703 704 705 706 707 708 709
 * "row" holds the actual image, and pixels are placed in it
 * as they arrive.  If the image is displayed after each pass, it will
 * appear to "sparkle" in.  "display_row" can be used to display a
 * "chunky" progressive image, with finer detail added as it becomes
 * available.  If you do not want this "chunky" display, you may pass
 * NULL for display_row.  If you do not want the sparkle display, and
 * you have not called png_handle_alpha(), you may pass NULL for rows.
 * If you have called png_handle_alpha(), and the image has either an
 * alpha channel or a transparency chunk, you must provide a buffer for
 * rows.  In this case, you do not have to provide a display_row buffer
 * also, but you may.  If the image is not interlaced, or if you have
 * not called png_set_interlace_handling(), the display_row buffer will
 * be ignored, so pass NULL to it.
710
 *
711
 * [*] png_handle_alpha() does not exist yet, as of this version of libpng
712
 */
G
Guy Schalnat 已提交
713

714
void PNGAPI
G
Guy Schalnat 已提交
715
png_read_rows(png_structp png_ptr, png_bytepp row,
716
    png_bytepp display_row, png_uint_32 num_rows)
G
Guy Schalnat 已提交
717
{
G
Guy Schalnat 已提交
718 719 720
   png_uint_32 i;
   png_bytepp rp;
   png_bytepp dp;
G
Guy Schalnat 已提交
721

722
   png_debug(1, "in png_read_rows");
723
 
724 725
   if (png_ptr == NULL)
      return;
G
Guy Schalnat 已提交
726 727
   rp = row;
   dp = display_row;
728
   if (rp != NULL && dp != NULL)
729 730 731 732
      for (i = 0; i < num_rows; i++)
      {
         png_bytep rptr = *rp++;
         png_bytep dptr = *dp++;
733

734 735
         png_read_row(png_ptr, rptr, dptr);
      }
736
   else if (rp != NULL)
737 738
      for (i = 0; i < num_rows; i++)
      {
739
         png_bytep rptr = *rp;
740
         png_read_row(png_ptr, rptr, NULL);
741 742
         rp++;
      }
743
   else if (dp != NULL)
744 745 746
      for (i = 0; i < num_rows; i++)
      {
         png_bytep dptr = *dp;
747
         png_read_row(png_ptr, NULL, dptr);
748
         dp++;
749
      }
G
Guy Schalnat 已提交
750
}
751
#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
752

753
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
754
/* Read the entire image.  If the image has an alpha channel or a tRNS
755
 * chunk, and you have called png_handle_alpha()[*], you will need to
756 757 758 759 760 761 762
 * initialize the image to the current image that PNG will be overlaying.
 * We set the num_rows again here, in case it was incorrectly set in
 * png_read_start_row() by a call to png_read_update_info() or
 * png_start_read_image() if png_set_interlace_handling() wasn't called
 * prior to either of these functions like it should have been.  You can
 * only call this function once.  If you desire to have an image for
 * each pass of a interlaced image, use png_read_rows() instead.
763
 *
764
 * [*] png_handle_alpha() does not exist yet, as of this version of libpng
765
 */
766
void PNGAPI
G
Guy Schalnat 已提交
767
png_read_image(png_structp png_ptr, png_bytepp image)
G
Guy Schalnat 已提交
768
{
769
   png_uint_32 i, image_height;
G
Guy Schalnat 已提交
770
   int pass, j;
G
Guy Schalnat 已提交
771
   png_bytepp rp;
G
Guy Schalnat 已提交
772

773
   png_debug(1, "in png_read_image");
774
 
775 776
   if (png_ptr == NULL)
      return;
777 778

#ifdef PNG_READ_INTERLACING_SUPPORTED
G
Guy Schalnat 已提交
779
   pass = png_set_interlace_handling(png_ptr);
780 781 782
#else
   if (png_ptr->interlaced)
      png_error(png_ptr,
783
          "Cannot read interlaced image -- interlace handler disabled");
784 785 786
   pass = 1;
#endif

787

788 789
   image_height=png_ptr->height;
   png_ptr->num_rows = image_height; /* Make sure this is set correctly */
G
Guy Schalnat 已提交
790

G
Guy Schalnat 已提交
791 792 793
   for (j = 0; j < pass; j++)
   {
      rp = image;
794
      for (i = 0; i < image_height; i++)
G
Guy Schalnat 已提交
795
      {
796
         png_read_row(png_ptr, *rp, NULL);
G
Guy Schalnat 已提交
797 798 799 800
         rp++;
      }
   }
}
801
#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
802

803
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
804
/* Read the end of the PNG file.  Will not read past the end of the
805 806 807
 * file, will verify the end is accurate, and will read any comments
 * or time information at the end of the file, if info is not NULL.
 */
808
void PNGAPI
A
Andreas Dilger 已提交
809
png_read_end(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
810
{
811
   png_debug(1, "in png_read_end");
812
 
813 814
   if (png_ptr == NULL)
      return;
A
Andreas Dilger 已提交
815
   png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
G
Guy Schalnat 已提交
816 817 818

   do
   {
819 820 821 822
      PNG_IHDR;
      PNG_IDAT;
      PNG_IEND;
      PNG_PLTE;
823
#ifdef PNG_READ_bKGD_SUPPORTED
824
      PNG_bKGD;
825
#endif
826
#ifdef PNG_READ_cHRM_SUPPORTED
827
      PNG_cHRM;
828
#endif
829
#ifdef PNG_READ_gAMA_SUPPORTED
830
      PNG_gAMA;
831
#endif
832
#ifdef PNG_READ_hIST_SUPPORTED
833
      PNG_hIST;
834
#endif
835
#ifdef PNG_READ_iCCP_SUPPORTED
836
      PNG_iCCP;
837
#endif
838
#ifdef PNG_READ_iTXt_SUPPORTED
839
      PNG_iTXt;
840
#endif
841
#ifdef PNG_READ_oFFs_SUPPORTED
842
      PNG_oFFs;
843
#endif
844
#ifdef PNG_READ_pCAL_SUPPORTED
845
      PNG_pCAL;
846
#endif
847
#ifdef PNG_READ_pHYs_SUPPORTED
848
      PNG_pHYs;
849
#endif
850
#ifdef PNG_READ_sBIT_SUPPORTED
851
      PNG_sBIT;
852
#endif
853
#ifdef PNG_READ_sCAL_SUPPORTED
854
      PNG_sCAL;
855
#endif
856
#ifdef PNG_READ_sPLT_SUPPORTED
857
      PNG_sPLT;
858
#endif
859
#ifdef PNG_READ_sRGB_SUPPORTED
860
      PNG_sRGB;
861
#endif
862
#ifdef PNG_READ_tEXt_SUPPORTED
863
      PNG_tEXt;
864
#endif
865
#ifdef PNG_READ_tIME_SUPPORTED
866
      PNG_tIME;
867
#endif
868
#ifdef PNG_READ_tRNS_SUPPORTED
869
      PNG_tRNS;
870
#endif
871
#ifdef PNG_READ_zTXt_SUPPORTED
872
      PNG_zTXt;
873
#endif
874 875
      png_uint_32 length = png_read_chunk_header(png_ptr);
      PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
A
Andreas Dilger 已提交
876

877
      if (!png_memcmp(chunk_name, png_IHDR, 4))
A
Andreas Dilger 已提交
878
         png_handle_IHDR(png_ptr, info_ptr, length);
879
      else if (!png_memcmp(chunk_name, png_IEND, 4))
880 881
         png_handle_IEND(png_ptr, info_ptr, length);
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
882
      else if (png_handle_as_unknown(png_ptr, chunk_name))
883
      {
884
         if (!png_memcmp(chunk_name, png_IDAT, 4))
885
         {
886
            if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
887
               png_benign_error(png_ptr, "Too many IDATs found");
888 889
         }
         png_handle_unknown(png_ptr, info_ptr, length);
890
         if (!png_memcmp(chunk_name, png_PLTE, 4))
891 892 893
            png_ptr->mode |= PNG_HAVE_PLTE;
      }
#endif
894
      else if (!png_memcmp(chunk_name, png_IDAT, 4))
A
Andreas Dilger 已提交
895 896 897 898
      {
         /* Zero length IDATs are legal after the last IDAT has been
          * read, but not after other chunks have been read.
          */
899
         if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
900
            png_benign_error(png_ptr, "Too many IDATs found");
901
         png_crc_finish(png_ptr, length);
A
Andreas Dilger 已提交
902
      }
903
      else if (!png_memcmp(chunk_name, png_PLTE, 4))
A
Andreas Dilger 已提交
904
         png_handle_PLTE(png_ptr, info_ptr, length);
905
#ifdef PNG_READ_bKGD_SUPPORTED
906
      else if (!png_memcmp(chunk_name, png_bKGD, 4))
A
Andreas Dilger 已提交
907
         png_handle_bKGD(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
908
#endif
909
#ifdef PNG_READ_cHRM_SUPPORTED
910
      else if (!png_memcmp(chunk_name, png_cHRM, 4))
A
Andreas Dilger 已提交
911 912
         png_handle_cHRM(png_ptr, info_ptr, length);
#endif
913
#ifdef PNG_READ_gAMA_SUPPORTED
914
      else if (!png_memcmp(chunk_name, png_gAMA, 4))
A
Andreas Dilger 已提交
915 916
         png_handle_gAMA(png_ptr, info_ptr, length);
#endif
917
#ifdef PNG_READ_hIST_SUPPORTED
918
      else if (!png_memcmp(chunk_name, png_hIST, 4))
A
Andreas Dilger 已提交
919
         png_handle_hIST(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
920
#endif
921
#ifdef PNG_READ_oFFs_SUPPORTED
922
      else if (!png_memcmp(chunk_name, png_oFFs, 4))
A
Andreas Dilger 已提交
923
         png_handle_oFFs(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
924
#endif
925
#ifdef PNG_READ_pCAL_SUPPORTED
926
      else if (!png_memcmp(chunk_name, png_pCAL, 4))
A
Andreas Dilger 已提交
927 928
         png_handle_pCAL(png_ptr, info_ptr, length);
#endif
929
#ifdef PNG_READ_sCAL_SUPPORTED
930
      else if (!png_memcmp(chunk_name, png_sCAL, 4))
931 932
         png_handle_sCAL(png_ptr, info_ptr, length);
#endif
933
#ifdef PNG_READ_pHYs_SUPPORTED
934
      else if (!png_memcmp(chunk_name, png_pHYs, 4))
A
Andreas Dilger 已提交
935 936
         png_handle_pHYs(png_ptr, info_ptr, length);
#endif
937
#ifdef PNG_READ_sBIT_SUPPORTED
938
      else if (!png_memcmp(chunk_name, png_sBIT, 4))
A
Andreas Dilger 已提交
939
         png_handle_sBIT(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
940
#endif
941
#ifdef PNG_READ_sRGB_SUPPORTED
942
      else if (!png_memcmp(chunk_name, png_sRGB, 4))
943 944
         png_handle_sRGB(png_ptr, info_ptr, length);
#endif
945
#ifdef PNG_READ_iCCP_SUPPORTED
946
      else if (!png_memcmp(chunk_name, png_iCCP, 4))
947 948
         png_handle_iCCP(png_ptr, info_ptr, length);
#endif
949
#ifdef PNG_READ_sPLT_SUPPORTED
950
      else if (!png_memcmp(chunk_name, png_sPLT, 4))
951 952
         png_handle_sPLT(png_ptr, info_ptr, length);
#endif
953
#ifdef PNG_READ_tEXt_SUPPORTED
954
      else if (!png_memcmp(chunk_name, png_tEXt, 4))
A
Andreas Dilger 已提交
955
         png_handle_tEXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
956
#endif
957
#ifdef PNG_READ_tIME_SUPPORTED
958
      else if (!png_memcmp(chunk_name, png_tIME, 4))
A
Andreas Dilger 已提交
959 960
         png_handle_tIME(png_ptr, info_ptr, length);
#endif
961
#ifdef PNG_READ_tRNS_SUPPORTED
962
      else if (!png_memcmp(chunk_name, png_tRNS, 4))
A
Andreas Dilger 已提交
963 964
         png_handle_tRNS(png_ptr, info_ptr, length);
#endif
965
#ifdef PNG_READ_zTXt_SUPPORTED
966
      else if (!png_memcmp(chunk_name, png_zTXt, 4))
A
Andreas Dilger 已提交
967
         png_handle_zTXt(png_ptr, info_ptr, length);
968
#endif
969
#ifdef PNG_READ_iTXt_SUPPORTED
970
      else if (!png_memcmp(chunk_name, png_iTXt, 4))
971
         png_handle_iTXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
972
#endif
G
Guy Schalnat 已提交
973
      else
A
Andreas Dilger 已提交
974 975
         png_handle_unknown(png_ptr, info_ptr, length);
   } while (!(png_ptr->mode & PNG_HAVE_IEND));
G
Guy Schalnat 已提交
976
}
977
#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
978

979
/* Free all memory used by the read */
980
void PNGAPI
G
Guy Schalnat 已提交
981
png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
982
    png_infopp end_info_ptr_ptr)
G
Guy Schalnat 已提交
983 984
{
   png_structp png_ptr = NULL;
A
Andreas Dilger 已提交
985
   png_infop info_ptr = NULL, end_info_ptr = NULL;
986
#ifdef PNG_USER_MEM_SUPPORTED
987 988
   png_free_ptr free_fn = NULL;
   png_voidp mem_ptr = NULL;
989
#endif
G
Guy Schalnat 已提交
990

991
   png_debug(1, "in png_destroy_read_struct");
992
 
A
Andreas Dilger 已提交
993
   if (png_ptr_ptr != NULL)
G
Guy Schalnat 已提交
994
      png_ptr = *png_ptr_ptr;
995 996 997 998 999 1000 1001
   if (png_ptr == NULL)
      return;

#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
   mem_ptr = png_ptr->mem_ptr;
#endif
G
Guy Schalnat 已提交
1002

A
Andreas Dilger 已提交
1003
   if (info_ptr_ptr != NULL)
G
Guy Schalnat 已提交
1004 1005
      info_ptr = *info_ptr_ptr;

A
Andreas Dilger 已提交
1006
   if (end_info_ptr_ptr != NULL)
A
Andreas Dilger 已提交
1007
      end_info_ptr = *end_info_ptr_ptr;
G
Guy Schalnat 已提交
1008

A
Andreas Dilger 已提交
1009
   png_read_destroy(png_ptr, info_ptr, end_info_ptr);
G
Guy Schalnat 已提交
1010

A
Andreas Dilger 已提交
1011
   if (info_ptr != NULL)
G
Guy Schalnat 已提交
1012
   {
1013
#ifdef PNG_TEXT_SUPPORTED
1014
      png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
1015
#endif
1016 1017

#ifdef PNG_USER_MEM_SUPPORTED
1018 1019
      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
          (png_voidp)mem_ptr);
1020
#else
A
Andreas Dilger 已提交
1021
      png_destroy_struct((png_voidp)info_ptr);
1022
#endif
1023
      *info_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1024 1025
   }

A
Andreas Dilger 已提交
1026
   if (end_info_ptr != NULL)
G
Guy Schalnat 已提交
1027
   {
1028
#ifdef PNG_READ_TEXT_SUPPORTED
1029
      png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
1030
#endif
1031
#ifdef PNG_USER_MEM_SUPPORTED
1032
      png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
1033
          (png_voidp)mem_ptr);
1034
#else
A
Andreas Dilger 已提交
1035
      png_destroy_struct((png_voidp)end_info_ptr);
1036
#endif
1037
      *end_info_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1038 1039
   }

A
Andreas Dilger 已提交
1040
   if (png_ptr != NULL)
G
Guy Schalnat 已提交
1041
   {
1042
#ifdef PNG_USER_MEM_SUPPORTED
1043 1044
      png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
          (png_voidp)mem_ptr);
1045
#else
A
Andreas Dilger 已提交
1046
      png_destroy_struct((png_voidp)png_ptr);
1047
#endif
1048
      *png_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1049 1050 1051
   }
}

1052
/* Free all memory used by the read (old method) */
1053
void /* PRIVATE */
1054 1055
png_read_destroy(png_structp png_ptr, png_infop info_ptr,
    png_infop end_info_ptr)
G
Guy Schalnat 已提交
1056
{
1057
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
1058
   jmp_buf tmp_jmp;
1059
#endif
G
Guy Schalnat 已提交
1060 1061 1062
   png_error_ptr error_fn;
   png_error_ptr warning_fn;
   png_voidp error_ptr;
1063 1064 1065
#ifdef PNG_USER_MEM_SUPPORTED
   png_free_ptr free_fn;
#endif
G
Guy Schalnat 已提交
1066

1067
   png_debug(1, "in png_read_destroy");
1068
 
A
Andreas Dilger 已提交
1069
   if (info_ptr != NULL)
A
Andreas Dilger 已提交
1070
      png_info_destroy(png_ptr, info_ptr);
G
Guy Schalnat 已提交
1071

A
Andreas Dilger 已提交
1072
   if (end_info_ptr != NULL)
A
Andreas Dilger 已提交
1073
      png_info_destroy(png_ptr, end_info_ptr);
G
Guy Schalnat 已提交
1074

A
Andreas Dilger 已提交
1075
   png_free(png_ptr, png_ptr->zbuf);
1076
   png_free(png_ptr, png_ptr->big_row_buf);
A
Andreas Dilger 已提交
1077
   png_free(png_ptr, png_ptr->prev_row);
1078
   png_free(png_ptr, png_ptr->chunkdata);
1079
#ifdef PNG_READ_QUANTIZE_SUPPORTED
A
Andreas Dilger 已提交
1080
   png_free(png_ptr, png_ptr->palette_lookup);
1081
   png_free(png_ptr, png_ptr->quantize_index);
G
Guy Schalnat 已提交
1082
#endif
1083
#ifdef PNG_READ_GAMMA_SUPPORTED
A
Andreas Dilger 已提交
1084
   png_free(png_ptr, png_ptr->gamma_table);
G
Guy Schalnat 已提交
1085
#endif
1086
#ifdef PNG_READ_BACKGROUND_SUPPORTED
A
Andreas Dilger 已提交
1087 1088
   png_free(png_ptr, png_ptr->gamma_from_1);
   png_free(png_ptr, png_ptr->gamma_to_1);
G
Guy Schalnat 已提交
1089
#endif
1090
   if (png_ptr->free_me & PNG_FREE_PLTE)
1091
      png_zfree(png_ptr, png_ptr->palette);
1092
   png_ptr->free_me &= ~PNG_FREE_PLTE;
1093
#if defined(PNG_tRNS_SUPPORTED) || \
1094
    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
1095
   if (png_ptr->free_me & PNG_FREE_TRNS)
1096
      png_free(png_ptr, png_ptr->trans_alpha);
1097
   png_ptr->free_me &= ~PNG_FREE_TRNS;
1098
#endif
1099
#ifdef PNG_READ_hIST_SUPPORTED
1100
   if (png_ptr->free_me & PNG_FREE_HIST)
A
Andreas Dilger 已提交
1101
      png_free(png_ptr, png_ptr->hist);
1102
   png_ptr->free_me &= ~PNG_FREE_HIST;
G
Guy Schalnat 已提交
1103
#endif
1104
#ifdef PNG_READ_GAMMA_SUPPORTED
A
Andreas Dilger 已提交
1105
   if (png_ptr->gamma_16_table != NULL)
G
Guy Schalnat 已提交
1106
   {
1107 1108
      int i;
      int istop = (1 << (8 - png_ptr->gamma_shift));
1109
      for (i = 0; i < istop; i++)
G
Guy Schalnat 已提交
1110
      {
A
Andreas Dilger 已提交
1111
         png_free(png_ptr, png_ptr->gamma_16_table[i]);
G
Guy Schalnat 已提交
1112
      }
1113
   png_free(png_ptr, png_ptr->gamma_16_table);
G
Guy Schalnat 已提交
1114
   }
1115
#ifdef PNG_READ_BACKGROUND_SUPPORTED
A
Andreas Dilger 已提交
1116
   if (png_ptr->gamma_16_from_1 != NULL)
G
Guy Schalnat 已提交
1117
   {
1118 1119
      int i;
      int istop = (1 << (8 - png_ptr->gamma_shift));
1120
      for (i = 0; i < istop; i++)
G
Guy Schalnat 已提交
1121
      {
A
Andreas Dilger 已提交
1122
         png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
G
Guy Schalnat 已提交
1123
      }
A
Andreas Dilger 已提交
1124
   png_free(png_ptr, png_ptr->gamma_16_from_1);
1125
   }
A
Andreas Dilger 已提交
1126
   if (png_ptr->gamma_16_to_1 != NULL)
G
Guy Schalnat 已提交
1127
   {
1128 1129
      int i;
      int istop = (1 << (8 - png_ptr->gamma_shift));
1130
      for (i = 0; i < istop; i++)
G
Guy Schalnat 已提交
1131
      {
A
Andreas Dilger 已提交
1132
         png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
G
Guy Schalnat 已提交
1133
      }
A
Andreas Dilger 已提交
1134
   png_free(png_ptr, png_ptr->gamma_16_to_1);
1135
   }
G
Guy Schalnat 已提交
1136
#endif
1137
#endif
1138
#ifdef PNG_TIME_RFC1123_SUPPORTED
1139
   png_free(png_ptr, png_ptr->time_buffer);
1140
#endif
G
Guy Schalnat 已提交
1141

A
Andreas Dilger 已提交
1142
   inflateEnd(&png_ptr->zstream);
G
Guy Schalnat 已提交
1143
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
A
Andreas Dilger 已提交
1144
   png_free(png_ptr, png_ptr->save_buffer);
G
Guy Schalnat 已提交
1145
#endif
G
Guy Schalnat 已提交
1146

1147 1148 1149 1150 1151 1152
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
#ifdef PNG_TEXT_SUPPORTED
   png_free(png_ptr, png_ptr->current_text);
#endif /* PNG_TEXT_SUPPORTED */
#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */

G
Guy Schalnat 已提交
1153 1154 1155
   /* Save the important info out of the png_struct, in case it is
    * being used again.
    */
1156
#ifdef PNG_SETJMP_SUPPORTED
1157
   png_memcpy(tmp_jmp, png_ptr->png_jmpbuf, png_sizeof(jmp_buf));
1158
#endif
G
Guy Schalnat 已提交
1159 1160 1161 1162

   error_fn = png_ptr->error_fn;
   warning_fn = png_ptr->warning_fn;
   error_ptr = png_ptr->error_ptr;
1163 1164 1165
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
#endif
G
Guy Schalnat 已提交
1166

1167
   png_memset(png_ptr, 0, png_sizeof(png_struct));
G
Guy Schalnat 已提交
1168 1169 1170 1171

   png_ptr->error_fn = error_fn;
   png_ptr->warning_fn = warning_fn;
   png_ptr->error_ptr = error_ptr;
1172 1173 1174
#ifdef PNG_USER_MEM_SUPPORTED
   png_ptr->free_fn = free_fn;
#endif
G
Guy Schalnat 已提交
1175

1176
#ifdef PNG_SETJMP_SUPPORTED
1177
   png_memcpy(png_ptr->png_jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
1178 1179
#endif

G
Guy Schalnat 已提交
1180
}
1181

1182
void PNGAPI
1183 1184
png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
{
1185 1186
   if (png_ptr == NULL)
      return;
1187 1188
   png_ptr->read_row_fn = read_row_fn;
}
1189

1190

1191
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1192
#ifdef PNG_INFO_IMAGE_SUPPORTED
1193 1194
void PNGAPI
png_read_png(png_structp png_ptr, png_infop info_ptr,
1195 1196 1197 1198 1199
                           int transforms,
                           voidp params)
{
   int row;

1200 1201
   if (png_ptr == NULL)
      return;
1202

1203
   /* png_read_info() gives us all of the information from the
1204 1205 1206
    * PNG file before the first IDAT (image data chunk).
    */
   png_read_info(png_ptr, info_ptr);
1207 1208
   if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
      png_error(png_ptr, "Image is too high to process with png_read_png()");
1209 1210 1211

   /* -------------- image transformations start here ------------------- */

1212
#ifdef PNG_READ_16_TO_8_SUPPORTED
1213
   /* Tell libpng to strip 16 bit/color files down to 8 bits per color.
1214
    */
1215
   if (transforms & PNG_TRANSFORM_STRIP_16)
1216
      png_set_strip_16(png_ptr);
1217 1218
#endif

1219
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
1220 1221
   /* Strip alpha bytes from the input data without combining with
    * the background (not recommended).
1222 1223
    */
   if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
1224
      png_set_strip_alpha(png_ptr);
1225 1226
#endif

1227
#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
1228
   /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
1229 1230 1231
    * byte into separate bytes (useful for paletted and grayscale images).
    */
   if (transforms & PNG_TRANSFORM_PACKING)
1232
      png_set_packing(png_ptr);
1233 1234
#endif

1235
#ifdef PNG_READ_PACKSWAP_SUPPORTED
1236
   /* Change the order of packed pixels to least significant bit first
1237 1238
    * (not useful if you are using png_set_packing).
    */
1239
   if (transforms & PNG_TRANSFORM_PACKSWAP)
1240
      png_set_packswap(png_ptr);
1241 1242
#endif

1243
#ifdef PNG_READ_EXPAND_SUPPORTED
1244 1245 1246 1247 1248 1249
   /* Expand paletted colors into true RGB triplets
    * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
    * Expand paletted or RGB images with transparency to full alpha
    * channels so the data will be available as RGBA quartets.
    */
   if (transforms & PNG_TRANSFORM_EXPAND)
1250 1251 1252
      if ((png_ptr->bit_depth < 8) ||
          (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
          (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
1253
         png_set_expand(png_ptr);
1254 1255
#endif

1256
   /* We don't handle background color or gamma transformation or quantizing.
1257
    */
1258

1259
#ifdef PNG_READ_INVERT_SUPPORTED
1260
   /* Invert monochrome files to have 0 as white and 1 as black
1261
    */
1262
   if (transforms & PNG_TRANSFORM_INVERT_MONO)
1263
      png_set_invert_mono(png_ptr);
1264 1265
#endif

1266
#ifdef PNG_READ_SHIFT_SUPPORTED
1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280
   /* If you want to shift the pixel values from the range [0,255] or
    * [0,65535] to the original [0,7] or [0,31], or whatever range the
    * colors were originally in:
    */
   if ((transforms & PNG_TRANSFORM_SHIFT)
       && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
   {
      png_color_8p sig_bit;

      png_get_sBIT(png_ptr, info_ptr, &sig_bit);
      png_set_shift(png_ptr, sig_bit);
   }
#endif

1281
#ifdef PNG_READ_BGR_SUPPORTED
1282
   /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
1283
   if (transforms & PNG_TRANSFORM_BGR)
1284
      png_set_bgr(png_ptr);
1285 1286
#endif

1287
#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
1288
   /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
1289
   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
1290
      png_set_swap_alpha(png_ptr);
1291 1292
#endif

1293
#ifdef PNG_READ_SWAP_SUPPORTED
1294
   /* Swap bytes of 16 bit files to least significant byte first */
1295
   if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
1296
      png_set_swap(png_ptr);
1297 1298
#endif

1299
/* Added at libpng-1.2.41 */
1300
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
1301
   /* Invert the alpha channel from opacity to transparency */
1302
   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
1303
      png_set_invert_alpha(png_ptr);
1304 1305
#endif

1306
/* Added at libpng-1.2.41 */
1307
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1308
   /* Expand grayscale image to RGB */
1309
   if (transforms & PNG_TRANSFORM_GRAY_TO_RGB)
1310
      png_set_gray_to_rgb(png_ptr);
1311 1312
#endif

1313 1314 1315 1316
   /* We don't handle adding filler bytes */

   /* Optional call to gamma correct and add the background to the palette
    * and update info structure.  REQUIRED if you are expecting libpng to
1317
    * update the palette for you (i.e., you selected such a transform above).
1318 1319 1320 1321 1322
    */
   png_read_update_info(png_ptr, info_ptr);

   /* -------------- image transformations end here ------------------- */

1323
   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1324
   if (info_ptr->row_pointers == NULL)
1325
   {
1326
      png_uint_32 iptr;
1327

1328
      info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
1329
          info_ptr->height * png_sizeof(png_bytep));
1330 1331 1332
      for (iptr=0; iptr<info_ptr->height; iptr++)
         info_ptr->row_pointers[iptr] = NULL;

1333
      info_ptr->free_me |= PNG_FREE_ROWS;
1334

1335
      for (row = 0; row < (int)info_ptr->height; row++)
1336
         info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
1337
            png_get_rowbytes(png_ptr, info_ptr));
1338
   }
1339 1340 1341 1342

   png_read_image(png_ptr, info_ptr->row_pointers);
   info_ptr->valid |= PNG_INFO_IDAT;

1343
   /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
1344
   png_read_end(png_ptr, info_ptr);
1345

1346
   transforms = transforms; /* Quiet compiler warnings */
1347
   params = params;
1348

1349
}
1350
#endif /* PNG_INFO_IMAGE_SUPPORTED */
1351
#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
1352
#endif /* PNG_READ_SUPPORTED */