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

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

#define PNG_INTERNAL
#include "png.h"
16 17
#if defined(PNG_READ_SUPPORTED)

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

#ifdef PNG_USER_MEM_SUPPORTED
   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. */
30
png_structp PNGAPI
31 32 33 34 35 36
png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
   png_malloc_ptr malloc_fn, png_free_ptr free_fn)
{
#endif /* PNG_USER_MEM_SUPPORTED */

37 38 39 40
#ifdef PNG_SETJMP_SUPPORTED
   volatile
#endif
   png_structp png_ptr;
41 42

#ifdef PNG_SETJMP_SUPPORTED
A
Andreas Dilger 已提交
43 44 45
#ifdef USE_FAR_KEYWORD
   jmp_buf jmpbuf;
#endif
46 47
#endif

48 49
   int i;

50
   png_debug(1, "in png_create_read_struct");
51
#ifdef PNG_USER_MEM_SUPPORTED
52 53
   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
      (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
54
#else
55
   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
56
#endif
57
   if (png_ptr == NULL)
58
      return (NULL);
59

60
   /* Added at libpng-1.2.6 */
61 62 63 64 65
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
   png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
   png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
#endif

66
#ifdef PNG_SETJMP_SUPPORTED
A
Andreas Dilger 已提交
67 68 69
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmpbuf))
#else
G
Guy Schalnat 已提交
70
   if (setjmp(png_ptr->jmpbuf))
A
Andreas Dilger 已提交
71
#endif
G
Guy Schalnat 已提交
72
   {
A
Andreas Dilger 已提交
73
      png_free(png_ptr, png_ptr->zbuf);
74
      png_ptr->zbuf = NULL;
75
#ifdef PNG_USER_MEM_SUPPORTED
76
      png_destroy_struct_2((png_voidp)png_ptr,
77
         (png_free_ptr)free_fn, (png_voidp)mem_ptr);
78 79 80
#else
      png_destroy_struct((png_voidp)png_ptr);
#endif
81
      return (NULL);
G
Guy Schalnat 已提交
82
   }
A
Andreas Dilger 已提交
83
#ifdef USE_FAR_KEYWORD
84
   png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
A
Andreas Dilger 已提交
85
#endif
86
#endif
87 88 89

#ifdef PNG_USER_MEM_SUPPORTED
   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
90
#endif
91

A
Andreas Dilger 已提交
92 93
   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);

94
   if (user_png_ver)
G
Guy Schalnat 已提交
95
   {
96
     i = 0;
97 98
     do
     {
99
       if (user_png_ver[i] != png_libpng_ver[i])
100 101 102 103
          png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
     } while (png_libpng_ver[i++]);
   }
   else
104
        png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
105
   
106

107
   if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
108
   {
109 110 111 112 113 114
     /* 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] ||
115
         (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
116 117
         (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
     {
118 119 120 121
#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
        char msg[80];
        if (user_png_ver)
        {
122 123
          png_snprintf(msg, 80,
             "Application was compiled with png.h from libpng-%.20s",
124 125 126
             user_png_ver);
          png_warning(png_ptr, msg);
        }
127 128
        png_snprintf(msg, 80,
             "Application  is  running with png.c from libpng-%.20s",
129 130 131 132
           png_libpng_ver);
        png_warning(png_ptr, msg);
#endif
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
133
        png_ptr->flags = 0;
134
#endif
135 136 137
        png_error(png_ptr,
           "Incompatible libpng version in application and library");
     }
138 139
   }

140
   /* Initialize zbuf - compression buffer */
G
Guy Schalnat 已提交
141
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
142 143
   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
     (png_uint_32)png_ptr->zbuf_size);
A
Andreas Dilger 已提交
144 145 146
   png_ptr->zstream.zalloc = png_zalloc;
   png_ptr->zstream.zfree = png_zfree;
   png_ptr->zstream.opaque = (voidpf)png_ptr;
G
Guy Schalnat 已提交
147

A
Andreas Dilger 已提交
148
   switch (inflateInit(&png_ptr->zstream))
G
Guy Schalnat 已提交
149 150 151 152 153 154 155 156
   {
     case Z_OK: /* Do nothing */ break;
     case Z_MEM_ERROR:
     case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
     case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break;
     default: png_error(png_ptr, "Unknown zlib error");
   }

A
Andreas Dilger 已提交
157 158
   png_ptr->zstream.next_out = png_ptr->zbuf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
G
Guy Schalnat 已提交
159

160
   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
G
Guy Schalnat 已提交
161

162 163 164 165 166 167 168
#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
   if (setjmp(jmpbuf))
      PNG_ABORT();
169
   png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
170 171 172 173 174
#else
   if (setjmp(png_ptr->jmpbuf))
      PNG_ABORT();
#endif
#endif
G
Guy Schalnat 已提交
175 176 177
   return (png_ptr);
}

178
#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
A
Andreas Dilger 已提交
179
/* Initialize PNG structure for reading, and allocate any memory needed.
180
   This interface is deprecated in favour of the png_create_read_struct(),
181
   and it will disappear as of libpng-1.3.0. */
182
#undef png_read_init
183
void PNGAPI
G
Guy Schalnat 已提交
184
png_read_init(png_structp png_ptr)
185 186
{
   /* We only come here via pre-1.0.7-compiled applications */
187
   png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
188 189
}

190
void PNGAPI
191 192
png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
   png_size_t png_struct_size, png_size_t png_info_size)
193 194
{
   /* We only come here via pre-1.0.12-compiled applications */
195
   if (png_ptr == NULL) return;
196
#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
197
   if (png_sizeof(png_struct) > png_struct_size ||
198
      png_sizeof(png_info) > png_info_size)
199 200
   {
      char msg[80];
201
      png_ptr->warning_fn = NULL;
202 203
      if (user_png_ver)
      {
204 205
        png_snprintf(msg, 80,
           "Application was compiled with png.h from libpng-%.20s",
206 207 208
           user_png_ver);
        png_warning(png_ptr, msg);
      }
209 210
      png_snprintf(msg, 80,
         "Application  is  running with png.c from libpng-%.20s",
211 212 213 214
         png_libpng_ver);
      png_warning(png_ptr, msg);
   }
#endif
215
   if (png_sizeof(png_struct) > png_struct_size)
216
     {
217
       png_ptr->error_fn = NULL;
218
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
219
       png_ptr->flags = 0;
220
#endif
221 222 223
       png_error(png_ptr,
       "The png struct allocated by the application for reading is too small.");
     }
224
   if (png_sizeof(png_info) > png_info_size)
225
     {
226
       png_ptr->error_fn = NULL;
227
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
228
       png_ptr->flags = 0;
229
#endif
230 231 232 233 234
       png_error(png_ptr,
         "The info struct allocated by application for reading is too small.");
     }
   png_read_init_3(&png_ptr, user_png_ver, png_struct_size);
}
235
#endif /* PNG_1_0_X || PNG_1_2_X */
236 237 238 239

void PNGAPI
png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
   png_size_t png_struct_size)
G
Guy Schalnat 已提交
240
{
241
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
242
   jmp_buf tmp_jmp;  /* to save current jump buffer */
243
#endif
G
Guy Schalnat 已提交
244

245
   int i = 0;
246 247 248

   png_structp png_ptr=*ptr_ptr;

249
   if (png_ptr == NULL) return;
250

251 252
   do
   {
253
     if (user_png_ver[i] != png_libpng_ver[i])
254
     {
255 256 257
#ifdef PNG_LEGACY_SUPPORTED
       png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
#else
258
       png_ptr->warning_fn = NULL;
259 260 261
       png_warning(png_ptr,
        "Application uses deprecated png_read_init() and should be recompiled.");
       break;
262
#endif
263 264 265
     }
   } while (png_libpng_ver[i++]);

266
   png_debug(1, "in png_read_init_3");
267 268

#ifdef PNG_SETJMP_SUPPORTED
269
   /* Save jump buffer and error functions */
270
   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
271
#endif
G
Guy Schalnat 已提交
272

273 274 275 276 277 278
   if (png_sizeof(png_struct) > png_struct_size)
   {
      png_destroy_struct(png_ptr);
      *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
      png_ptr = *ptr_ptr;
   }
279

280
   /* Reset all variables to 0 */
281
   png_memset(png_ptr, 0, png_sizeof(png_struct));
G
Guy Schalnat 已提交
282

283
#ifdef PNG_SETJMP_SUPPORTED
284
   /* Restore jump buffer */
285
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
286
#endif
G
Guy Schalnat 已提交
287

288
   /* Added at libpng-1.2.6 */
289 290 291 292 293
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
   png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
   png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
#endif

294
   /* Initialize zbuf - compression buffer */
G
Guy Schalnat 已提交
295
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
296 297
   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
     (png_uint_32)png_ptr->zbuf_size);
A
Andreas Dilger 已提交
298 299 300
   png_ptr->zstream.zalloc = png_zalloc;
   png_ptr->zstream.zfree = png_zfree;
   png_ptr->zstream.opaque = (voidpf)png_ptr;
G
Guy Schalnat 已提交
301

A
Andreas Dilger 已提交
302
   switch (inflateInit(&png_ptr->zstream))
G
Guy Schalnat 已提交
303 304 305 306 307 308 309 310
   {
     case Z_OK: /* Do nothing */ break;
     case Z_MEM_ERROR:
     case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory"); break;
     case Z_VERSION_ERROR: png_error(png_ptr, "zlib version"); break;
     default: png_error(png_ptr, "Unknown zlib error");
   }

A
Andreas Dilger 已提交
311 312
   png_ptr->zstream.next_out = png_ptr->zbuf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
G
Guy Schalnat 已提交
313

314
   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
G
Guy Schalnat 已提交
315 316
}

317
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
318
/* Read the information before the actual image data.  This has been
319
 * changed in v0.90 to allow reading a file that already has the magic
A
Andreas Dilger 已提交
320
 * bytes read from the stream.  You can tell libpng how many bytes have
321
 * been read from the beginning of the stream (up to the maximum of 8)
A
Andreas Dilger 已提交
322 323 324 325
 * 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.
 */
326
void PNGAPI
A
Andreas Dilger 已提交
327
png_read_info(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
328
{
329 330
   if (png_ptr == NULL || info_ptr == NULL)
      return;
331
   png_debug(1, "in png_read_info");
A
Andreas Dilger 已提交
332 333
   /* If we haven't checked all of the PNG signature bytes, do so now. */
   if (png_ptr->sig_bytes < 8)
G
Guy Schalnat 已提交
334
   {
A
Andreas Dilger 已提交
335 336
      png_size_t num_checked = png_ptr->sig_bytes,
                 num_to_check = 8 - num_checked;
A
Andreas Dilger 已提交
337

A
Andreas Dilger 已提交
338
      png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
A
Andreas Dilger 已提交
339 340 341 342 343 344 345 346 347 348
      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");
      }
349 350
      if (num_checked < 3)
         png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
G
Guy Schalnat 已提交
351
   }
G
Guy Schalnat 已提交
352

353
   for (;;)
G
Guy Schalnat 已提交
354
   {
355
#ifdef PNG_USE_LOCAL_ARRAYS
356 357 358 359
      PNG_CONST PNG_IHDR;
      PNG_CONST PNG_IDAT;
      PNG_CONST PNG_IEND;
      PNG_CONST PNG_PLTE;
360
#if defined(PNG_READ_bKGD_SUPPORTED)
361
      PNG_CONST PNG_bKGD;
362 363
#endif
#if defined(PNG_READ_cHRM_SUPPORTED)
364
      PNG_CONST PNG_cHRM;
365 366
#endif
#if defined(PNG_READ_gAMA_SUPPORTED)
367
      PNG_CONST PNG_gAMA;
368 369
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
370
      PNG_CONST PNG_hIST;
371
#endif
372
#if defined(PNG_READ_iCCP_SUPPORTED)
373
      PNG_CONST PNG_iCCP;
374 375
#endif
#if defined(PNG_READ_iTXt_SUPPORTED)
376
      PNG_CONST PNG_iTXt;
377
#endif
378
#if defined(PNG_READ_oFFs_SUPPORTED)
379
      PNG_CONST PNG_oFFs;
380 381
#endif
#if defined(PNG_READ_pCAL_SUPPORTED)
382
      PNG_CONST PNG_pCAL;
383 384
#endif
#if defined(PNG_READ_pHYs_SUPPORTED)
385
      PNG_CONST PNG_pHYs;
386 387
#endif
#if defined(PNG_READ_sBIT_SUPPORTED)
388
      PNG_CONST PNG_sBIT;
389
#endif
390
#if defined(PNG_READ_sCAL_SUPPORTED)
391
      PNG_CONST PNG_sCAL;
392 393
#endif
#if defined(PNG_READ_sPLT_SUPPORTED)
394
      PNG_CONST PNG_sPLT;
395
#endif
396
#if defined(PNG_READ_sRGB_SUPPORTED)
397
      PNG_CONST PNG_sRGB;
398 399
#endif
#if defined(PNG_READ_tEXt_SUPPORTED)
400
      PNG_CONST PNG_tEXt;
401 402
#endif
#if defined(PNG_READ_tIME_SUPPORTED)
403
      PNG_CONST PNG_tIME;
404 405
#endif
#if defined(PNG_READ_tRNS_SUPPORTED)
406
      PNG_CONST PNG_tRNS;
407 408
#endif
#if defined(PNG_READ_zTXt_SUPPORTED)
409
      PNG_CONST PNG_zTXt;
410
#endif
411
#endif /* PNG_USE_LOCAL_ARRAYS */
412
      png_uint_32 length = png_read_chunk_header(png_ptr);
413
      PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
A
Andreas Dilger 已提交
414

A
Andreas Dilger 已提交
415 416 417
      /* This should be a binary subdivision search or a hash for
       * matching the chunk name rather than a linear search.
       */
418
      if (!png_memcmp(chunk_name, png_IDAT, 4))
419
        if (png_ptr->mode & PNG_AFTER_IDAT)
420 421
          png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;

422
      if (!png_memcmp(chunk_name, png_IHDR, 4))
A
Andreas Dilger 已提交
423
         png_handle_IHDR(png_ptr, info_ptr, length);
424
      else if (!png_memcmp(chunk_name, png_IEND, 4))
A
Andreas Dilger 已提交
425
         png_handle_IEND(png_ptr, info_ptr, length);
426
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
427
      else if (png_handle_as_unknown(png_ptr, chunk_name))
428
      {
429
         if (!png_memcmp(chunk_name, png_IDAT, 4))
430 431
            png_ptr->mode |= PNG_HAVE_IDAT;
         png_handle_unknown(png_ptr, info_ptr, length);
432
         if (!png_memcmp(chunk_name, png_PLTE, 4))
433
            png_ptr->mode |= PNG_HAVE_PLTE;
434
         else if (!png_memcmp(chunk_name, png_IDAT, 4))
435 436 437 438 439 440 441 442 443 444
         {
            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 &&
                     !(png_ptr->mode & PNG_HAVE_PLTE))
               png_error(png_ptr, "Missing PLTE before IDAT");
            break;
         }
      }
#endif
445
      else if (!png_memcmp(chunk_name, png_PLTE, 4))
446
         png_handle_PLTE(png_ptr, info_ptr, length);
447
      else if (!png_memcmp(chunk_name, png_IDAT, 4))
A
Andreas Dilger 已提交
448 449 450 451 452 453 454 455 456 457 458 459
      {
         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 &&
                  !(png_ptr->mode & PNG_HAVE_PLTE))
            png_error(png_ptr, "Missing PLTE before IDAT");

         png_ptr->idat_size = length;
         png_ptr->mode |= PNG_HAVE_IDAT;
         break;
      }
#if defined(PNG_READ_bKGD_SUPPORTED)
460
      else if (!png_memcmp(chunk_name, png_bKGD, 4))
A
Andreas Dilger 已提交
461
         png_handle_bKGD(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
462 463
#endif
#if defined(PNG_READ_cHRM_SUPPORTED)
464
      else if (!png_memcmp(chunk_name, png_cHRM, 4))
A
Andreas Dilger 已提交
465
         png_handle_cHRM(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
466
#endif
A
Andreas Dilger 已提交
467
#if defined(PNG_READ_gAMA_SUPPORTED)
468
      else if (!png_memcmp(chunk_name, png_gAMA, 4))
A
Andreas Dilger 已提交
469
         png_handle_gAMA(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
470 471
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
472
      else if (!png_memcmp(chunk_name, png_hIST, 4))
A
Andreas Dilger 已提交
473
         png_handle_hIST(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
474
#endif
A
Andreas Dilger 已提交
475
#if defined(PNG_READ_oFFs_SUPPORTED)
476
      else if (!png_memcmp(chunk_name, png_oFFs, 4))
A
Andreas Dilger 已提交
477 478 479
         png_handle_oFFs(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_pCAL_SUPPORTED)
480
      else if (!png_memcmp(chunk_name, png_pCAL, 4))
A
Andreas Dilger 已提交
481 482
         png_handle_pCAL(png_ptr, info_ptr, length);
#endif
483
#if defined(PNG_READ_sCAL_SUPPORTED)
484
      else if (!png_memcmp(chunk_name, png_sCAL, 4))
485 486
         png_handle_sCAL(png_ptr, info_ptr, length);
#endif
G
Guy Schalnat 已提交
487
#if defined(PNG_READ_pHYs_SUPPORTED)
488
      else if (!png_memcmp(chunk_name, png_pHYs, 4))
A
Andreas Dilger 已提交
489
         png_handle_pHYs(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
490
#endif
A
Andreas Dilger 已提交
491
#if defined(PNG_READ_sBIT_SUPPORTED)
492
      else if (!png_memcmp(chunk_name, png_sBIT, 4))
A
Andreas Dilger 已提交
493 494
         png_handle_sBIT(png_ptr, info_ptr, length);
#endif
495
#if defined(PNG_READ_sRGB_SUPPORTED)
496
      else if (!png_memcmp(chunk_name, png_sRGB, 4))
497 498
         png_handle_sRGB(png_ptr, info_ptr, length);
#endif
499
#if defined(PNG_READ_iCCP_SUPPORTED)
500
      else if (!png_memcmp(chunk_name, png_iCCP, 4))
501 502 503
         png_handle_iCCP(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_sPLT_SUPPORTED)
504
      else if (!png_memcmp(chunk_name, png_sPLT, 4))
505 506
         png_handle_sPLT(png_ptr, info_ptr, length);
#endif
A
Andreas Dilger 已提交
507
#if defined(PNG_READ_tEXt_SUPPORTED)
508
      else if (!png_memcmp(chunk_name, png_tEXt, 4))
A
Andreas Dilger 已提交
509
         png_handle_tEXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
510 511
#endif
#if defined(PNG_READ_tIME_SUPPORTED)
512
      else if (!png_memcmp(chunk_name, png_tIME, 4))
A
Andreas Dilger 已提交
513
         png_handle_tIME(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
514
#endif
A
Andreas Dilger 已提交
515
#if defined(PNG_READ_tRNS_SUPPORTED)
516
      else if (!png_memcmp(chunk_name, png_tRNS, 4))
A
Andreas Dilger 已提交
517
         png_handle_tRNS(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
518 519
#endif
#if defined(PNG_READ_zTXt_SUPPORTED)
520
      else if (!png_memcmp(chunk_name, png_zTXt, 4))
A
Andreas Dilger 已提交
521
         png_handle_zTXt(png_ptr, info_ptr, length);
522 523
#endif
#if defined(PNG_READ_iTXt_SUPPORTED)
524
      else if (!png_memcmp(chunk_name, png_iTXt, 4))
525
         png_handle_iTXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
526
#endif
A
Andreas Dilger 已提交
527 528
      else
         png_handle_unknown(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
529 530
   }
}
531
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
532

533
/* Optional call to update the users info_ptr structure */
534
void PNGAPI
A
Andreas Dilger 已提交
535
png_read_update_info(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
536
{
537
   png_debug(1, "in png_read_update_info");
538 539
   if (png_ptr == NULL)
      return;
G
Guy Schalnat 已提交
540
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
541
      png_read_start_row(png_ptr);
542 543 544
   else
      png_warning(png_ptr,
      "Ignoring extra png_read_update_info() call; row buffer not reallocated");
A
Andreas Dilger 已提交
545
   png_read_transform_info(png_ptr, info_ptr);
G
Guy Schalnat 已提交
546 547
}

548
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
549 550
/* Initialize palette, background, etc, after transformations
 * are set, but before any reading takes place.  This allows
551
 * the user to obtain a gamma-corrected palette, for example.
552 553
 * If the user doesn't call this, we will do it ourselves.
 */
554
void PNGAPI
G
Guy Schalnat 已提交
555
png_start_read_image(png_structp png_ptr)
G
Guy Schalnat 已提交
556
{
557
   png_debug(1, "in png_start_read_image");
558 559
   if (png_ptr == NULL)
      return;
G
Guy Schalnat 已提交
560
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
561
      png_read_start_row(png_ptr);
G
Guy Schalnat 已提交
562
}
563
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
564

565
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
566
void PNGAPI
G
Guy Schalnat 已提交
567
png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
G
Guy Schalnat 已提交
568
{
569
#ifdef PNG_USE_LOCAL_ARRAYS
570
   PNG_CONST PNG_IDAT;
571
   PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
572
      0xff};
573
   PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
574
#endif
G
Guy Schalnat 已提交
575
   int ret;
576 577
   if (png_ptr == NULL)
      return;
578
   png_debug2(1, "in png_read_row (row %lu, pass %d)",
A
Andreas Dilger 已提交
579
      png_ptr->row_number, png_ptr->pass);
G
Guy Schalnat 已提交
580
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
581
      png_read_start_row(png_ptr);
582 583
   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
   {
584
   /* Check for transforms that have been set but were defined out */
585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613
#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
   if (png_ptr->transformations & PNG_INVERT_MONO)
      png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
   if (png_ptr->transformations & PNG_FILLER)
      png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED)
   if (png_ptr->transformations & PNG_PACKSWAP)
      png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
   if (png_ptr->transformations & PNG_PACK)
      png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
   if (png_ptr->transformations & PNG_SHIFT)
      png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
   if (png_ptr->transformations & PNG_BGR)
      png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
   if (png_ptr->transformations & PNG_SWAP_BYTES)
      png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined.");
#endif
   }
G
Guy Schalnat 已提交
614

G
Guy Schalnat 已提交
615
#if defined(PNG_READ_INTERLACING_SUPPORTED)
616
   /* If interlaced and we do not need a new row, combine row and return */
G
Guy Schalnat 已提交
617 618 619 620 621
   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
   {
      switch (png_ptr->pass)
      {
         case 0:
622
            if (png_ptr->row_number & 0x07)
G
Guy Schalnat 已提交
623
            {
A
Andreas Dilger 已提交
624
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
625 626
                  png_combine_row(png_ptr, dsp_row,
                     png_pass_dsp_mask[png_ptr->pass]);
G
Guy Schalnat 已提交
627
               png_read_finish_row(png_ptr);
G
Guy Schalnat 已提交
628 629 630 631
               return;
            }
            break;
         case 1:
632
            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
G
Guy Schalnat 已提交
633
            {
A
Andreas Dilger 已提交
634
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
635 636 637 638 639 640 641
                  png_combine_row(png_ptr, dsp_row,
                     png_pass_dsp_mask[png_ptr->pass]);
               png_read_finish_row(png_ptr);
               return;
            }
            break;
         case 2:
642
            if ((png_ptr->row_number & 0x07) != 4)
G
Guy Schalnat 已提交
643
            {
A
Andreas Dilger 已提交
644
               if (dsp_row != NULL && (png_ptr->row_number & 4))
G
Guy Schalnat 已提交
645
                  png_combine_row(png_ptr, dsp_row,
G
Guy Schalnat 已提交
646 647 648 649 650 651 652 653
                     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 已提交
654
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
655 656 657 658 659 660 661 662
                  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 已提交
663
            {
A
Andreas Dilger 已提交
664
               if (dsp_row != NULL && (png_ptr->row_number & 2))
G
Guy Schalnat 已提交
665 666 667 668 669 670 671 672 673
                  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 已提交
674
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
675 676 677 678 679 680
                  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 已提交
681
         case 6:
G
Guy Schalnat 已提交
682 683 684 685 686 687 688 689
            if (!(png_ptr->row_number & 1))
            {
               png_read_finish_row(png_ptr);
               return;
            }
            break;
      }
   }
G
Guy Schalnat 已提交
690
#endif
G
Guy Schalnat 已提交
691

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

A
Andreas Dilger 已提交
695 696
   png_ptr->zstream.next_out = png_ptr->row_buf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
G
Guy Schalnat 已提交
697 698
   do
   {
A
Andreas Dilger 已提交
699
      if (!(png_ptr->zstream.avail_in))
G
Guy Schalnat 已提交
700 701 702
      {
         while (!png_ptr->idat_size)
         {
A
Andreas Dilger 已提交
703
            png_crc_finish(png_ptr, 0);
G
Guy Schalnat 已提交
704

705
            png_ptr->idat_size = png_read_chunk_header(png_ptr);
A
Andreas Dilger 已提交
706 707
            if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
               png_error(png_ptr, "Not enough image data");
G
Guy Schalnat 已提交
708
         }
A
Andreas Dilger 已提交
709 710
         png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
         png_ptr->zstream.next_in = png_ptr->zbuf;
G
Guy Schalnat 已提交
711
         if (png_ptr->zbuf_size > png_ptr->idat_size)
A
Andreas Dilger 已提交
712
            png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
A
Andreas Dilger 已提交
713 714
         png_crc_read(png_ptr, png_ptr->zbuf,
            (png_size_t)png_ptr->zstream.avail_in);
A
Andreas Dilger 已提交
715
         png_ptr->idat_size -= png_ptr->zstream.avail_in;
G
Guy Schalnat 已提交
716
      }
A
Andreas Dilger 已提交
717
      ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
G
Guy Schalnat 已提交
718 719
      if (ret == Z_STREAM_END)
      {
A
Andreas Dilger 已提交
720
         if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
G
Guy Schalnat 已提交
721
            png_ptr->idat_size)
G
Guy Schalnat 已提交
722
            png_error(png_ptr, "Extra compressed data");
A
Andreas Dilger 已提交
723
         png_ptr->mode |= PNG_AFTER_IDAT;
G
Guy Schalnat 已提交
724
         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
G
Guy Schalnat 已提交
725
         break;
G
Guy Schalnat 已提交
726 727
      }
      if (ret != Z_OK)
A
Andreas Dilger 已提交
728
         png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
G
Guy Schalnat 已提交
729
                   "Decompression error");
A
Andreas Dilger 已提交
730 731

   } while (png_ptr->zstream.avail_out);
G
Guy Schalnat 已提交
732 733 734 735 736 737

   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;
738 739
   png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
       png_ptr->row_info.width);
G
Guy Schalnat 已提交
740

741
   if (png_ptr->row_buf[0])
G
Guy Schalnat 已提交
742 743 744
   png_read_filter_row(png_ptr, &(png_ptr->row_info),
      png_ptr->row_buf + 1, png_ptr->prev_row + 1,
      (int)(png_ptr->row_buf[0]));
G
Guy Schalnat 已提交
745

746
   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
747
      png_ptr->rowbytes + 1);
748

749
#if defined(PNG_MNG_FEATURES_SUPPORTED)
750
   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
751 752 753 754 755 756
      (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
   {
      /* Intrapixel differencing */
      png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
   }
#endif
G
Guy Schalnat 已提交
757

758 759

   if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
G
Guy Schalnat 已提交
760 761
      png_do_read_transformations(png_ptr);

G
Guy Schalnat 已提交
762
#if defined(PNG_READ_INTERLACING_SUPPORTED)
763
   /* Blow up interlaced rows to full size */
G
Guy Schalnat 已提交
764 765 766 767
   if (png_ptr->interlaced &&
      (png_ptr->transformations & PNG_INTERLACE))
   {
      if (png_ptr->pass < 6)
768 769 770 771
         /* Old interface (pre-1.0.9):
          * png_do_read_interlace(&(png_ptr->row_info),
          *    png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
          */
772
         png_do_read_interlace(png_ptr);
G
Guy Schalnat 已提交
773

A
Andreas Dilger 已提交
774
      if (dsp_row != NULL)
G
Guy Schalnat 已提交
775 776
         png_combine_row(png_ptr, dsp_row,
            png_pass_dsp_mask[png_ptr->pass]);
A
Andreas Dilger 已提交
777
      if (row != NULL)
G
Guy Schalnat 已提交
778 779 780 781
         png_combine_row(png_ptr, row,
            png_pass_mask[png_ptr->pass]);
   }
   else
G
Guy Schalnat 已提交
782
#endif
G
Guy Schalnat 已提交
783
   {
A
Andreas Dilger 已提交
784
      if (row != NULL)
G
Guy Schalnat 已提交
785
         png_combine_row(png_ptr, row, 0xff);
A
Andreas Dilger 已提交
786
      if (dsp_row != NULL)
G
Guy Schalnat 已提交
787 788 789
         png_combine_row(png_ptr, dsp_row, 0xff);
   }
   png_read_finish_row(png_ptr);
790 791 792

   if (png_ptr->read_row_fn != NULL)
      (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
G
Guy Schalnat 已提交
793
}
794
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
795

796
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
797
/* Read one or more rows of image data.  If the image is interlaced,
798 799
 * and png_set_interlace_handling() has been called, the rows need to
 * contain the contents of the rows from the previous pass.  If the
800
 * image has alpha or transparency, and png_handle_alpha()[*] has been
801 802
 * called, the rows contents must be initialized to the contents of the
 * screen.
803
 *
804 805 806 807 808 809 810 811 812 813 814 815 816
 * "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.
817
 *
818
 * [*] png_handle_alpha() does not exist yet, as of this version of libpng
819
 */
G
Guy Schalnat 已提交
820

821
void PNGAPI
G
Guy Schalnat 已提交
822
png_read_rows(png_structp png_ptr, png_bytepp row,
G
Guy Schalnat 已提交
823
   png_bytepp display_row, png_uint_32 num_rows)
G
Guy Schalnat 已提交
824
{
G
Guy Schalnat 已提交
825 826 827
   png_uint_32 i;
   png_bytepp rp;
   png_bytepp dp;
G
Guy Schalnat 已提交
828

829
   png_debug(1, "in png_read_rows");
830 831
   if (png_ptr == NULL)
      return;
G
Guy Schalnat 已提交
832 833
   rp = row;
   dp = display_row;
834
   if (rp != NULL && dp != NULL)
835 836 837 838
      for (i = 0; i < num_rows; i++)
      {
         png_bytep rptr = *rp++;
         png_bytep dptr = *dp++;
839

840 841
         png_read_row(png_ptr, rptr, dptr);
      }
842
   else if (rp != NULL)
843 844
      for (i = 0; i < num_rows; i++)
      {
845
         png_bytep rptr = *rp;
846
         png_read_row(png_ptr, rptr, png_bytep_NULL);
847 848
         rp++;
      }
849
   else if (dp != NULL)
850 851 852
      for (i = 0; i < num_rows; i++)
      {
         png_bytep dptr = *dp;
853
         png_read_row(png_ptr, png_bytep_NULL, dptr);
854
         dp++;
855
      }
G
Guy Schalnat 已提交
856
}
857
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
858

859
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
860
/* Read the entire image.  If the image has an alpha channel or a tRNS
861
 * chunk, and you have called png_handle_alpha()[*], you will need to
862 863 864 865 866 867 868
 * 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.
869
 *
870
 * [*] png_handle_alpha() does not exist yet, as of this version of libpng
871
 */
872
void PNGAPI
G
Guy Schalnat 已提交
873
png_read_image(png_structp png_ptr, png_bytepp image)
G
Guy Schalnat 已提交
874
{
875
   png_uint_32 i, image_height;
G
Guy Schalnat 已提交
876
   int pass, j;
G
Guy Schalnat 已提交
877
   png_bytepp rp;
G
Guy Schalnat 已提交
878

879
   png_debug(1, "in png_read_image");
880 881
   if (png_ptr == NULL)
      return;
882 883

#ifdef PNG_READ_INTERLACING_SUPPORTED
G
Guy Schalnat 已提交
884
   pass = png_set_interlace_handling(png_ptr);
885 886 887 888 889 890 891
#else
   if (png_ptr->interlaced)
      png_error(png_ptr,
        "Cannot read interlaced image -- interlace handler disabled.");
   pass = 1;
#endif

G
Guy Schalnat 已提交
892

893 894
   image_height=png_ptr->height;
   png_ptr->num_rows = image_height; /* Make sure this is set correctly */
G
Guy Schalnat 已提交
895

G
Guy Schalnat 已提交
896 897 898
   for (j = 0; j < pass; j++)
   {
      rp = image;
899
      for (i = 0; i < image_height; i++)
G
Guy Schalnat 已提交
900
      {
901
         png_read_row(png_ptr, *rp, png_bytep_NULL);
G
Guy Schalnat 已提交
902 903 904 905
         rp++;
      }
   }
}
906
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
907

908
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
909
/* Read the end of the PNG file.  Will not read past the end of the
910 911 912
 * 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.
 */
913
void PNGAPI
A
Andreas Dilger 已提交
914
png_read_end(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
915
{
916
   png_debug(1, "in png_read_end");
917 918
   if (png_ptr == NULL)
      return;
A
Andreas Dilger 已提交
919
   png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
G
Guy Schalnat 已提交
920 921 922

   do
   {
923
#ifdef PNG_USE_LOCAL_ARRAYS
924 925 926 927
      PNG_CONST PNG_IHDR;
      PNG_CONST PNG_IDAT;
      PNG_CONST PNG_IEND;
      PNG_CONST PNG_PLTE;
928
#if defined(PNG_READ_bKGD_SUPPORTED)
929
      PNG_CONST PNG_bKGD;
930 931
#endif
#if defined(PNG_READ_cHRM_SUPPORTED)
932
      PNG_CONST PNG_cHRM;
933 934
#endif
#if defined(PNG_READ_gAMA_SUPPORTED)
935
      PNG_CONST PNG_gAMA;
936 937
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
938
      PNG_CONST PNG_hIST;
939
#endif
940
#if defined(PNG_READ_iCCP_SUPPORTED)
941
      PNG_CONST PNG_iCCP;
942 943
#endif
#if defined(PNG_READ_iTXt_SUPPORTED)
944
      PNG_CONST PNG_iTXt;
945
#endif
946
#if defined(PNG_READ_oFFs_SUPPORTED)
947
      PNG_CONST PNG_oFFs;
948 949
#endif
#if defined(PNG_READ_pCAL_SUPPORTED)
950
      PNG_CONST PNG_pCAL;
951 952
#endif
#if defined(PNG_READ_pHYs_SUPPORTED)
953
      PNG_CONST PNG_pHYs;
954 955
#endif
#if defined(PNG_READ_sBIT_SUPPORTED)
956
      PNG_CONST PNG_sBIT;
957
#endif
958
#if defined(PNG_READ_sCAL_SUPPORTED)
959
      PNG_CONST PNG_sCAL;
960 961
#endif
#if defined(PNG_READ_sPLT_SUPPORTED)
962
      PNG_CONST PNG_sPLT;
963
#endif
964
#if defined(PNG_READ_sRGB_SUPPORTED)
965
      PNG_CONST PNG_sRGB;
966 967
#endif
#if defined(PNG_READ_tEXt_SUPPORTED)
968
      PNG_CONST PNG_tEXt;
969 970
#endif
#if defined(PNG_READ_tIME_SUPPORTED)
971
      PNG_CONST PNG_tIME;
972 973
#endif
#if defined(PNG_READ_tRNS_SUPPORTED)
974
      PNG_CONST PNG_tRNS;
975 976
#endif
#if defined(PNG_READ_zTXt_SUPPORTED)
977
      PNG_CONST PNG_zTXt;
978
#endif
979
#endif /* PNG_USE_LOCAL_ARRAYS */
980 981
      png_uint_32 length = png_read_chunk_header(png_ptr);
      PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
A
Andreas Dilger 已提交
982

983
      if (!png_memcmp(chunk_name, png_IHDR, 4))
A
Andreas Dilger 已提交
984
         png_handle_IHDR(png_ptr, info_ptr, length);
985
      else if (!png_memcmp(chunk_name, png_IEND, 4))
986 987
         png_handle_IEND(png_ptr, info_ptr, length);
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
988
      else if (png_handle_as_unknown(png_ptr, chunk_name))
989
      {
990
         if (!png_memcmp(chunk_name, png_IDAT, 4))
991
         {
992
            if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
993 994 995
               png_error(png_ptr, "Too many IDAT's found");
         }
         png_handle_unknown(png_ptr, info_ptr, length);
996
         if (!png_memcmp(chunk_name, png_PLTE, 4))
997 998 999
            png_ptr->mode |= PNG_HAVE_PLTE;
      }
#endif
1000
      else if (!png_memcmp(chunk_name, png_IDAT, 4))
A
Andreas Dilger 已提交
1001 1002 1003 1004
      {
         /* Zero length IDATs are legal after the last IDAT has been
          * read, but not after other chunks have been read.
          */
1005
         if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
A
Andreas Dilger 已提交
1006
            png_error(png_ptr, "Too many IDAT's found");
1007
         png_crc_finish(png_ptr, length);
A
Andreas Dilger 已提交
1008
      }
1009
      else if (!png_memcmp(chunk_name, png_PLTE, 4))
A
Andreas Dilger 已提交
1010
         png_handle_PLTE(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
1011
#if defined(PNG_READ_bKGD_SUPPORTED)
1012
      else if (!png_memcmp(chunk_name, png_bKGD, 4))
A
Andreas Dilger 已提交
1013
         png_handle_bKGD(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
1014 1015
#endif
#if defined(PNG_READ_cHRM_SUPPORTED)
1016
      else if (!png_memcmp(chunk_name, png_cHRM, 4))
A
Andreas Dilger 已提交
1017 1018 1019
         png_handle_cHRM(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_gAMA_SUPPORTED)
1020
      else if (!png_memcmp(chunk_name, png_gAMA, 4))
A
Andreas Dilger 已提交
1021 1022 1023
         png_handle_gAMA(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
1024
      else if (!png_memcmp(chunk_name, png_hIST, 4))
A
Andreas Dilger 已提交
1025
         png_handle_hIST(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
1026 1027
#endif
#if defined(PNG_READ_oFFs_SUPPORTED)
1028
      else if (!png_memcmp(chunk_name, png_oFFs, 4))
A
Andreas Dilger 已提交
1029
         png_handle_oFFs(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
1030 1031
#endif
#if defined(PNG_READ_pCAL_SUPPORTED)
1032
      else if (!png_memcmp(chunk_name, png_pCAL, 4))
A
Andreas Dilger 已提交
1033 1034
         png_handle_pCAL(png_ptr, info_ptr, length);
#endif
1035
#if defined(PNG_READ_sCAL_SUPPORTED)
1036
      else if (!png_memcmp(chunk_name, png_sCAL, 4))
1037 1038
         png_handle_sCAL(png_ptr, info_ptr, length);
#endif
A
Andreas Dilger 已提交
1039
#if defined(PNG_READ_pHYs_SUPPORTED)
1040
      else if (!png_memcmp(chunk_name, png_pHYs, 4))
A
Andreas Dilger 已提交
1041 1042 1043
         png_handle_pHYs(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_sBIT_SUPPORTED)
1044
      else if (!png_memcmp(chunk_name, png_sBIT, 4))
A
Andreas Dilger 已提交
1045
         png_handle_sBIT(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
1046
#endif
1047
#if defined(PNG_READ_sRGB_SUPPORTED)
1048
      else if (!png_memcmp(chunk_name, png_sRGB, 4))
1049 1050
         png_handle_sRGB(png_ptr, info_ptr, length);
#endif
1051
#if defined(PNG_READ_iCCP_SUPPORTED)
1052
      else if (!png_memcmp(chunk_name, png_iCCP, 4))
1053 1054 1055
         png_handle_iCCP(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_sPLT_SUPPORTED)
1056
      else if (!png_memcmp(chunk_name, png_sPLT, 4))
1057 1058
         png_handle_sPLT(png_ptr, info_ptr, length);
#endif
G
Guy Schalnat 已提交
1059
#if defined(PNG_READ_tEXt_SUPPORTED)
1060
      else if (!png_memcmp(chunk_name, png_tEXt, 4))
A
Andreas Dilger 已提交
1061
         png_handle_tEXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
1062
#endif
A
Andreas Dilger 已提交
1063
#if defined(PNG_READ_tIME_SUPPORTED)
1064
      else if (!png_memcmp(chunk_name, png_tIME, 4))
A
Andreas Dilger 已提交
1065 1066 1067
         png_handle_tIME(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_tRNS_SUPPORTED)
1068
      else if (!png_memcmp(chunk_name, png_tRNS, 4))
A
Andreas Dilger 已提交
1069 1070
         png_handle_tRNS(png_ptr, info_ptr, length);
#endif
G
Guy Schalnat 已提交
1071
#if defined(PNG_READ_zTXt_SUPPORTED)
1072
      else if (!png_memcmp(chunk_name, png_zTXt, 4))
A
Andreas Dilger 已提交
1073
         png_handle_zTXt(png_ptr, info_ptr, length);
1074 1075
#endif
#if defined(PNG_READ_iTXt_SUPPORTED)
1076
      else if (!png_memcmp(chunk_name, png_iTXt, 4))
1077
         png_handle_iTXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
1078
#endif
G
Guy Schalnat 已提交
1079
      else
A
Andreas Dilger 已提交
1080 1081
         png_handle_unknown(png_ptr, info_ptr, length);
   } while (!(png_ptr->mode & PNG_HAVE_IEND));
G
Guy Schalnat 已提交
1082
}
1083
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
1084

1085
/* Free all memory used by the read */
1086
void PNGAPI
G
Guy Schalnat 已提交
1087
png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
A
Andreas Dilger 已提交
1088
   png_infopp end_info_ptr_ptr)
G
Guy Schalnat 已提交
1089 1090
{
   png_structp png_ptr = NULL;
A
Andreas Dilger 已提交
1091
   png_infop info_ptr = NULL, end_info_ptr = NULL;
1092
#ifdef PNG_USER_MEM_SUPPORTED
1093 1094
   png_free_ptr free_fn = NULL;
   png_voidp mem_ptr = NULL;
1095
#endif
G
Guy Schalnat 已提交
1096

1097
   png_debug(1, "in png_destroy_read_struct");
A
Andreas Dilger 已提交
1098
   if (png_ptr_ptr != NULL)
G
Guy Schalnat 已提交
1099
      png_ptr = *png_ptr_ptr;
1100
   if (png_ptr == NULL)
1101
      return;
G
Guy Schalnat 已提交
1102

1103 1104 1105 1106 1107
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
   mem_ptr = png_ptr->mem_ptr;
#endif

A
Andreas Dilger 已提交
1108
   if (info_ptr_ptr != NULL)
G
Guy Schalnat 已提交
1109 1110
      info_ptr = *info_ptr_ptr;

A
Andreas Dilger 已提交
1111
   if (end_info_ptr_ptr != NULL)
A
Andreas Dilger 已提交
1112
      end_info_ptr = *end_info_ptr_ptr;
G
Guy Schalnat 已提交
1113

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

A
Andreas Dilger 已提交
1116
   if (info_ptr != NULL)
G
Guy Schalnat 已提交
1117
   {
1118
#if defined(PNG_TEXT_SUPPORTED)
1119
      png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
1120
#endif
1121 1122

#ifdef PNG_USER_MEM_SUPPORTED
1123 1124
      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
          (png_voidp)mem_ptr);
1125
#else
A
Andreas Dilger 已提交
1126
      png_destroy_struct((png_voidp)info_ptr);
1127
#endif
1128
      *info_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1129 1130
   }

A
Andreas Dilger 已提交
1131
   if (end_info_ptr != NULL)
G
Guy Schalnat 已提交
1132
   {
1133
#if defined(PNG_READ_TEXT_SUPPORTED)
1134
      png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
1135
#endif
1136
#ifdef PNG_USER_MEM_SUPPORTED
1137 1138
      png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
         (png_voidp)mem_ptr);
1139
#else
A
Andreas Dilger 已提交
1140
      png_destroy_struct((png_voidp)end_info_ptr);
1141
#endif
1142
      *end_info_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1143 1144
   }

1145 1146
   if (png_ptr != NULL)
   {
1147
#ifdef PNG_USER_MEM_SUPPORTED
1148 1149
      png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
          (png_voidp)mem_ptr);
1150
#else
1151
      png_destroy_struct((png_voidp)png_ptr);
1152
#endif
1153 1154
      *png_ptr_ptr = NULL;
   }
G
Guy Schalnat 已提交
1155 1156
}

1157
/* Free all memory used by the read (old method) */
1158
void /* PRIVATE */
A
Andreas Dilger 已提交
1159
png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
G
Guy Schalnat 已提交
1160
{
1161
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
1162
   jmp_buf tmp_jmp;
1163
#endif
G
Guy Schalnat 已提交
1164 1165 1166
   png_error_ptr error_fn;
   png_error_ptr warning_fn;
   png_voidp error_ptr;
1167 1168 1169
#ifdef PNG_USER_MEM_SUPPORTED
   png_free_ptr free_fn;
#endif
G
Guy Schalnat 已提交
1170

1171
   png_debug(1, "in png_read_destroy");
A
Andreas Dilger 已提交
1172
   if (info_ptr != NULL)
A
Andreas Dilger 已提交
1173
      png_info_destroy(png_ptr, info_ptr);
G
Guy Schalnat 已提交
1174

A
Andreas Dilger 已提交
1175
   if (end_info_ptr != NULL)
A
Andreas Dilger 已提交
1176
      png_info_destroy(png_ptr, end_info_ptr);
G
Guy Schalnat 已提交
1177

A
Andreas Dilger 已提交
1178
   png_free(png_ptr, png_ptr->zbuf);
1179
   png_free(png_ptr, png_ptr->big_row_buf);
A
Andreas Dilger 已提交
1180
   png_free(png_ptr, png_ptr->prev_row);
1181
   png_free(png_ptr, png_ptr->chunkdata);
G
Guy Schalnat 已提交
1182
#if defined(PNG_READ_DITHER_SUPPORTED)
A
Andreas Dilger 已提交
1183 1184
   png_free(png_ptr, png_ptr->palette_lookup);
   png_free(png_ptr, png_ptr->dither_index);
G
Guy Schalnat 已提交
1185 1186
#endif
#if defined(PNG_READ_GAMMA_SUPPORTED)
A
Andreas Dilger 已提交
1187
   png_free(png_ptr, png_ptr->gamma_table);
G
Guy Schalnat 已提交
1188 1189
#endif
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
A
Andreas Dilger 已提交
1190 1191
   png_free(png_ptr, png_ptr->gamma_from_1);
   png_free(png_ptr, png_ptr->gamma_to_1);
G
Guy Schalnat 已提交
1192
#endif
1193
#ifdef PNG_FREE_ME_SUPPORTED
1194
   if (png_ptr->free_me & PNG_FREE_PLTE)
1195
      png_zfree(png_ptr, png_ptr->palette);
1196
   png_ptr->free_me &= ~PNG_FREE_PLTE;
1197 1198 1199 1200 1201
#else
   if (png_ptr->flags & PNG_FLAG_FREE_PLTE)
      png_zfree(png_ptr, png_ptr->palette);
   png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
#endif
1202
#if defined(PNG_tRNS_SUPPORTED) || \
1203
    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
1204
#ifdef PNG_FREE_ME_SUPPORTED
1205
   if (png_ptr->free_me & PNG_FREE_TRNS)
A
Andreas Dilger 已提交
1206
      png_free(png_ptr, png_ptr->trans);
1207
   png_ptr->free_me &= ~PNG_FREE_TRNS;
1208 1209 1210 1211 1212
#else
   if (png_ptr->flags & PNG_FLAG_FREE_TRNS)
      png_free(png_ptr, png_ptr->trans);
   png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
#endif
1213
#endif
G
Guy Schalnat 已提交
1214
#if defined(PNG_READ_hIST_SUPPORTED)
1215
#ifdef PNG_FREE_ME_SUPPORTED
1216
   if (png_ptr->free_me & PNG_FREE_HIST)
A
Andreas Dilger 已提交
1217
      png_free(png_ptr, png_ptr->hist);
1218
   png_ptr->free_me &= ~PNG_FREE_HIST;
1219 1220 1221 1222 1223
#else
   if (png_ptr->flags & PNG_FLAG_FREE_HIST)
      png_free(png_ptr, png_ptr->hist);
   png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
#endif
G
Guy Schalnat 已提交
1224 1225
#endif
#if defined(PNG_READ_GAMMA_SUPPORTED)
A
Andreas Dilger 已提交
1226
   if (png_ptr->gamma_16_table != NULL)
G
Guy Schalnat 已提交
1227
   {
1228 1229
      int i;
      int istop = (1 << (8 - png_ptr->gamma_shift));
1230
      for (i = 0; i < istop; i++)
G
Guy Schalnat 已提交
1231
      {
A
Andreas Dilger 已提交
1232
         png_free(png_ptr, png_ptr->gamma_16_table[i]);
G
Guy Schalnat 已提交
1233
      }
1234
   png_free(png_ptr, png_ptr->gamma_16_table);
G
Guy Schalnat 已提交
1235
   }
G
Guy Schalnat 已提交
1236
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
A
Andreas Dilger 已提交
1237
   if (png_ptr->gamma_16_from_1 != NULL)
G
Guy Schalnat 已提交
1238
   {
1239 1240
      int i;
      int istop = (1 << (8 - png_ptr->gamma_shift));
1241
      for (i = 0; i < istop; i++)
G
Guy Schalnat 已提交
1242
      {
A
Andreas Dilger 已提交
1243
         png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
G
Guy Schalnat 已提交
1244
      }
A
Andreas Dilger 已提交
1245
   png_free(png_ptr, png_ptr->gamma_16_from_1);
1246
   }
A
Andreas Dilger 已提交
1247
   if (png_ptr->gamma_16_to_1 != NULL)
G
Guy Schalnat 已提交
1248
   {
1249 1250
      int i;
      int istop = (1 << (8 - png_ptr->gamma_shift));
1251
      for (i = 0; i < istop; i++)
G
Guy Schalnat 已提交
1252
      {
A
Andreas Dilger 已提交
1253
         png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
G
Guy Schalnat 已提交
1254
      }
A
Andreas Dilger 已提交
1255
   png_free(png_ptr, png_ptr->gamma_16_to_1);
1256
   }
G
Guy Schalnat 已提交
1257
#endif
1258 1259 1260
#endif
#if defined(PNG_TIME_RFC1123_SUPPORTED)
   png_free(png_ptr, png_ptr->time_buffer);
1261
#endif
G
Guy Schalnat 已提交
1262

A
Andreas Dilger 已提交
1263
   inflateEnd(&png_ptr->zstream);
G
Guy Schalnat 已提交
1264
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
A
Andreas Dilger 已提交
1265
   png_free(png_ptr, png_ptr->save_buffer);
G
Guy Schalnat 已提交
1266
#endif
G
Guy Schalnat 已提交
1267

1268 1269 1270 1271 1272 1273
#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 已提交
1274 1275 1276
   /* Save the important info out of the png_struct, in case it is
    * being used again.
    */
1277
#ifdef PNG_SETJMP_SUPPORTED
1278
   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
1279
#endif
G
Guy Schalnat 已提交
1280 1281 1282 1283

   error_fn = png_ptr->error_fn;
   warning_fn = png_ptr->warning_fn;
   error_ptr = png_ptr->error_ptr;
1284 1285 1286
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
#endif
G
Guy Schalnat 已提交
1287

1288
   png_memset(png_ptr, 0, png_sizeof(png_struct));
G
Guy Schalnat 已提交
1289 1290 1291 1292

   png_ptr->error_fn = error_fn;
   png_ptr->warning_fn = warning_fn;
   png_ptr->error_ptr = error_ptr;
1293 1294 1295
#ifdef PNG_USER_MEM_SUPPORTED
   png_ptr->free_fn = free_fn;
#endif
G
Guy Schalnat 已提交
1296

1297
#ifdef PNG_SETJMP_SUPPORTED
1298
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
1299 1300
#endif

G
Guy Schalnat 已提交
1301
}
1302

1303
void PNGAPI
1304 1305
png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
{
1306 1307
   if (png_ptr == NULL)
      return;
1308 1309
   png_ptr->read_row_fn = read_row_fn;
}
1310

1311 1312

#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
1313
#if defined(PNG_INFO_IMAGE_SUPPORTED)
1314 1315
void PNGAPI
png_read_png(png_structp png_ptr, png_infop info_ptr,
1316 1317 1318 1319 1320
                           int transforms,
                           voidp params)
{
   int row;

1321 1322
   if (png_ptr == NULL)
      return;
1323
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1324
   /* Invert the alpha channel from opacity to transparency
1325
    */
1326 1327 1328 1329
   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
       png_set_invert_alpha(png_ptr);
#endif

1330
   /* png_read_info() gives us all of the information from the
1331 1332 1333
    * PNG file before the first IDAT (image data chunk).
    */
   png_read_info(png_ptr, info_ptr);
1334
   if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
1335
      png_error(png_ptr, "Image is too high to process with png_read_png()");
1336 1337 1338 1339

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

#if defined(PNG_READ_16_TO_8_SUPPORTED)
1340
   /* Tell libpng to strip 16 bit/color files down to 8 bits per color.
1341
    */
1342
   if (transforms & PNG_TRANSFORM_STRIP_16)
1343
      png_set_strip_16(png_ptr);
1344 1345 1346
#endif

#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1347 1348
   /* Strip alpha bytes from the input data without combining with
    * the background (not recommended).
1349 1350
    */
   if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
1351
      png_set_strip_alpha(png_ptr);
1352 1353
#endif

1354
#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
1355
   /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
1356 1357 1358
    * byte into separate bytes (useful for paletted and grayscale images).
    */
   if (transforms & PNG_TRANSFORM_PACKING)
1359
      png_set_packing(png_ptr);
1360 1361 1362 1363
#endif

#if defined(PNG_READ_PACKSWAP_SUPPORTED)
   /* Change the order of packed pixels to least significant bit first
1364 1365
    * (not useful if you are using png_set_packing).
    */
1366
   if (transforms & PNG_TRANSFORM_PACKSWAP)
1367
      png_set_packswap(png_ptr);
1368 1369 1370 1371 1372 1373 1374 1375 1376
#endif

#if defined(PNG_READ_EXPAND_SUPPORTED)
   /* 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)
1377 1378 1379
      if ((png_ptr->bit_depth < 8) ||
          (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
          (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
1380
         png_set_expand(png_ptr);
1381 1382
#endif

1383 1384
   /* We don't handle background color or gamma transformation or dithering.
    */
1385 1386

#if defined(PNG_READ_INVERT_SUPPORTED)
1387
   /* Invert monochrome files to have 0 as white and 1 as black
1388
    */
1389
   if (transforms & PNG_TRANSFORM_INVERT_MONO)
1390
      png_set_invert_mono(png_ptr);
1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408
#endif

#if defined(PNG_READ_SHIFT_SUPPORTED)
   /* 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

#if defined(PNG_READ_BGR_SUPPORTED)
1409
   /* Flip the RGB pixels to BGR (or RGBA to BGRA)
1410
    */
1411
   if (transforms & PNG_TRANSFORM_BGR)
1412
      png_set_bgr(png_ptr);
1413 1414 1415
#endif

#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1416
   /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
1417
    */
1418 1419 1420 1421 1422
   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
       png_set_swap_alpha(png_ptr);
#endif

#if defined(PNG_READ_SWAP_SUPPORTED)
1423
   /* Swap bytes of 16 bit files to least significant byte first
1424
    */
1425
   if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
1426
      png_set_swap(png_ptr);
1427 1428 1429 1430 1431 1432
#endif

   /* 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
1433
    * update the palette for you (i.e., you selected such a transform above).
1434 1435 1436 1437 1438
    */
   png_read_update_info(png_ptr, info_ptr);

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

1439
#ifdef PNG_FREE_ME_SUPPORTED
1440
   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1441
#endif
1442
   if (info_ptr->row_pointers == NULL)
1443 1444
   {
      info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
1445
         info_ptr->height * png_sizeof(png_bytep));
1446 1447
      png_memset(info_ptr->row_pointers, 0, info_ptr->height
         * png_sizeof(png_bytep));
1448
#ifdef PNG_FREE_ME_SUPPORTED
1449
      info_ptr->free_me |= PNG_FREE_ROWS;
1450
#endif
1451
      for (row = 0; row < (int)info_ptr->height; row++)
1452
         info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
1453
            png_get_rowbytes(png_ptr, info_ptr));
1454
   }
1455 1456 1457 1458

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

1459
   /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
1460
   png_read_end(png_ptr, info_ptr);
1461

1462
   transforms = transforms; /* Quiet compiler warnings */
1463
   params = params;
1464

1465
}
1466
#endif /* PNG_INFO_IMAGE_SUPPORTED */
1467
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
1468
#endif /* PNG_READ_SUPPORTED */