You need to sign in or sign up before continuing.
pngread.c 45.5 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.30 [July 17, 2008]
5
 * For conditions of distribution and use, see copyright notice in png.h
6
 * Copyright (c) 1998-2008 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 */

G
Guy Schalnat 已提交
37
   png_structp png_ptr;
38 39

#ifdef PNG_SETJMP_SUPPORTED
A
Andreas Dilger 已提交
40 41 42
#ifdef USE_FAR_KEYWORD
   jmp_buf jmpbuf;
#endif
43 44
#endif

45 46
   int i;

A
Andreas Dilger 已提交
47
   png_debug(1, "in png_create_read_struct\n");
48
#ifdef PNG_USER_MEM_SUPPORTED
49 50
   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
      (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
51
#else
52
   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
53
#endif
54
   if (png_ptr == NULL)
55
      return (NULL);
56

57 58 59 60 61 62
   /* added at libpng-1.2.6 */
#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

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

#ifdef PNG_USER_MEM_SUPPORTED
   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
87
#endif
88

A
Andreas Dilger 已提交
89 90
   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);

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

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

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

A
Andreas Dilger 已提交
145
   switch (inflateInit(&png_ptr->zstream))
G
Guy Schalnat 已提交
146 147 148 149 150 151 152 153
   {
     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 已提交
154 155
   png_ptr->zstream.next_out = png_ptr->zbuf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
G
Guy Schalnat 已提交
156

157
   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
G
Guy Schalnat 已提交
158

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

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

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

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 已提交
237
{
238
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
239
   jmp_buf tmp_jmp;  /* to save current jump buffer */
240
#endif
G
Guy Schalnat 已提交
241

242
   int i=0;
243 244 245

   png_structp png_ptr=*ptr_ptr;

246
   if (png_ptr == NULL) return;
247

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

263
   png_debug(1, "in png_read_init_3\n");
264 265

#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
266
   /* save jump buffer and error functions */
267
   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
268
#endif
G
Guy Schalnat 已提交
269

270 271 272 273 274 275
   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;
   }
276

G
Guy Schalnat 已提交
277
   /* reset all variables to 0 */
278
   png_memset(png_ptr, 0, png_sizeof(png_struct));
G
Guy Schalnat 已提交
279

280
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
281
   /* restore jump buffer */
282
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
283
#endif
G
Guy Schalnat 已提交
284

285 286 287 288 289 290
   /* added at libpng-1.2.6 */
#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

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

A
Andreas Dilger 已提交
299
   switch (inflateInit(&png_ptr->zstream))
G
Guy Schalnat 已提交
300 301 302 303 304 305 306 307
   {
     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 已提交
308 309
   png_ptr->zstream.next_out = png_ptr->zbuf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
G
Guy Schalnat 已提交
310

311
   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
G
Guy Schalnat 已提交
312 313
}

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

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

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

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

418
      if (!png_memcmp(chunk_name, png_IHDR, 4))
A
Andreas Dilger 已提交
419
         png_handle_IHDR(png_ptr, info_ptr, length);
420
      else if (!png_memcmp(chunk_name, png_IEND, 4))
A
Andreas Dilger 已提交
421
         png_handle_IEND(png_ptr, info_ptr, length);
422
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
423
      else if (png_handle_as_unknown(png_ptr, chunk_name))
424
      {
425
         if (!png_memcmp(chunk_name, png_IDAT, 4))
426 427
            png_ptr->mode |= PNG_HAVE_IDAT;
         png_handle_unknown(png_ptr, info_ptr, length);
428
         if (!png_memcmp(chunk_name, png_PLTE, 4))
429
            png_ptr->mode |= PNG_HAVE_PLTE;
430
         else if (!png_memcmp(chunk_name, png_IDAT, 4))
431 432 433 434 435 436 437 438 439 440
         {
            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
441
      else if (!png_memcmp(chunk_name, png_PLTE, 4))
442
         png_handle_PLTE(png_ptr, info_ptr, length);
443
      else if (!png_memcmp(chunk_name, png_IDAT, 4))
A
Andreas Dilger 已提交
444 445 446 447 448 449 450 451 452 453 454 455
      {
         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)
456
      else if (!png_memcmp(chunk_name, png_bKGD, 4))
A
Andreas Dilger 已提交
457
         png_handle_bKGD(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
458 459
#endif
#if defined(PNG_READ_cHRM_SUPPORTED)
460
      else if (!png_memcmp(chunk_name, png_cHRM, 4))
A
Andreas Dilger 已提交
461
         png_handle_cHRM(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
462
#endif
A
Andreas Dilger 已提交
463
#if defined(PNG_READ_gAMA_SUPPORTED)
464
      else if (!png_memcmp(chunk_name, png_gAMA, 4))
A
Andreas Dilger 已提交
465
         png_handle_gAMA(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
466 467
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
468
      else if (!png_memcmp(chunk_name, png_hIST, 4))
A
Andreas Dilger 已提交
469
         png_handle_hIST(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
470
#endif
A
Andreas Dilger 已提交
471
#if defined(PNG_READ_oFFs_SUPPORTED)
472
      else if (!png_memcmp(chunk_name, png_oFFs, 4))
A
Andreas Dilger 已提交
473 474 475
         png_handle_oFFs(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_pCAL_SUPPORTED)
476
      else if (!png_memcmp(chunk_name, png_pCAL, 4))
A
Andreas Dilger 已提交
477 478
         png_handle_pCAL(png_ptr, info_ptr, length);
#endif
479
#if defined(PNG_READ_sCAL_SUPPORTED)
480
      else if (!png_memcmp(chunk_name, png_sCAL, 4))
481 482
         png_handle_sCAL(png_ptr, info_ptr, length);
#endif
G
Guy Schalnat 已提交
483
#if defined(PNG_READ_pHYs_SUPPORTED)
484
      else if (!png_memcmp(chunk_name, png_pHYs, 4))
A
Andreas Dilger 已提交
485
         png_handle_pHYs(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
486
#endif
A
Andreas Dilger 已提交
487
#if defined(PNG_READ_sBIT_SUPPORTED)
488
      else if (!png_memcmp(chunk_name, png_sBIT, 4))
A
Andreas Dilger 已提交
489 490
         png_handle_sBIT(png_ptr, info_ptr, length);
#endif
491
#if defined(PNG_READ_sRGB_SUPPORTED)
492
      else if (!png_memcmp(chunk_name, png_sRGB, 4))
493 494
         png_handle_sRGB(png_ptr, info_ptr, length);
#endif
495
#if defined(PNG_READ_iCCP_SUPPORTED)
496
      else if (!png_memcmp(chunk_name, png_iCCP, 4))
497 498 499
         png_handle_iCCP(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_sPLT_SUPPORTED)
500
      else if (!png_memcmp(chunk_name, png_sPLT, 4))
501 502
         png_handle_sPLT(png_ptr, info_ptr, length);
#endif
A
Andreas Dilger 已提交
503
#if defined(PNG_READ_tEXt_SUPPORTED)
504
      else if (!png_memcmp(chunk_name, png_tEXt, 4))
A
Andreas Dilger 已提交
505
         png_handle_tEXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
506 507
#endif
#if defined(PNG_READ_tIME_SUPPORTED)
508
      else if (!png_memcmp(chunk_name, png_tIME, 4))
A
Andreas Dilger 已提交
509
         png_handle_tIME(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
510
#endif
A
Andreas Dilger 已提交
511
#if defined(PNG_READ_tRNS_SUPPORTED)
512
      else if (!png_memcmp(chunk_name, png_tRNS, 4))
A
Andreas Dilger 已提交
513
         png_handle_tRNS(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
514 515
#endif
#if defined(PNG_READ_zTXt_SUPPORTED)
516
      else if (!png_memcmp(chunk_name, png_zTXt, 4))
A
Andreas Dilger 已提交
517
         png_handle_zTXt(png_ptr, info_ptr, length);
518 519
#endif
#if defined(PNG_READ_iTXt_SUPPORTED)
520
      else if (!png_memcmp(chunk_name, png_iTXt, 4))
521
         png_handle_iTXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
522
#endif
A
Andreas Dilger 已提交
523 524
      else
         png_handle_unknown(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
525 526
   }
}
527
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
528

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

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

559
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
560
void PNGAPI
G
Guy Schalnat 已提交
561
png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
G
Guy Schalnat 已提交
562
{
563
#ifdef PNG_USE_LOCAL_ARRAYS
564
   PNG_CONST PNG_IDAT;
565
   PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
566
      0xff};
567
   PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
568
#endif
G
Guy Schalnat 已提交
569
   int ret;
570
   if (png_ptr == NULL) return;
571
   png_debug2(1, "in png_read_row (row %lu, pass %d)\n",
A
Andreas Dilger 已提交
572
      png_ptr->row_number, png_ptr->pass);
G
Guy Schalnat 已提交
573
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
574
      png_read_start_row(png_ptr);
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606
   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
   {
   /* check for transforms that have been set but were defined out */
#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 已提交
607

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

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

A
Andreas Dilger 已提交
688 689
   png_ptr->zstream.next_out = png_ptr->row_buf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
G
Guy Schalnat 已提交
690 691
   do
   {
A
Andreas Dilger 已提交
692
      if (!(png_ptr->zstream.avail_in))
G
Guy Schalnat 已提交
693 694 695
      {
         while (!png_ptr->idat_size)
         {
A
Andreas Dilger 已提交
696
            png_crc_finish(png_ptr, 0);
G
Guy Schalnat 已提交
697

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

   } while (png_ptr->zstream.avail_out);
G
Guy Schalnat 已提交
725 726 727 728 729 730

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

734
   if (png_ptr->row_buf[0])
G
Guy Schalnat 已提交
735 736 737
   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 已提交
738

739
   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
740
      png_ptr->rowbytes + 1);
741

742
#if defined(PNG_MNG_FEATURES_SUPPORTED)
743
   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
744 745 746 747 748 749
      (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 已提交
750

751 752

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

G
Guy Schalnat 已提交
755
#if defined(PNG_READ_INTERLACING_SUPPORTED)
G
Guy Schalnat 已提交
756 757 758 759 760
   /* blow up interlaced rows to full size */
   if (png_ptr->interlaced &&
      (png_ptr->transformations & PNG_INTERLACE))
   {
      if (png_ptr->pass < 6)
761
/*       old interface (pre-1.0.9):
G
Guy Schalnat 已提交
762
         png_do_read_interlace(&(png_ptr->row_info),
A
Andreas Dilger 已提交
763
            png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
764 765
 */
         png_do_read_interlace(png_ptr);
G
Guy Schalnat 已提交
766

A
Andreas Dilger 已提交
767
      if (dsp_row != NULL)
G
Guy Schalnat 已提交
768 769
         png_combine_row(png_ptr, dsp_row,
            png_pass_dsp_mask[png_ptr->pass]);
A
Andreas Dilger 已提交
770
      if (row != NULL)
G
Guy Schalnat 已提交
771 772 773 774
         png_combine_row(png_ptr, row,
            png_pass_mask[png_ptr->pass]);
   }
   else
G
Guy Schalnat 已提交
775
#endif
G
Guy Schalnat 已提交
776
   {
A
Andreas Dilger 已提交
777
      if (row != NULL)
G
Guy Schalnat 已提交
778
         png_combine_row(png_ptr, row, 0xff);
A
Andreas Dilger 已提交
779
      if (dsp_row != NULL)
G
Guy Schalnat 已提交
780 781 782
         png_combine_row(png_ptr, dsp_row, 0xff);
   }
   png_read_finish_row(png_ptr);
783 784 785

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

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

814
void PNGAPI
G
Guy Schalnat 已提交
815
png_read_rows(png_structp png_ptr, png_bytepp row,
G
Guy Schalnat 已提交
816
   png_bytepp display_row, png_uint_32 num_rows)
G
Guy Schalnat 已提交
817
{
G
Guy Schalnat 已提交
818 819 820
   png_uint_32 i;
   png_bytepp rp;
   png_bytepp dp;
G
Guy Schalnat 已提交
821

A
Andreas Dilger 已提交
822
   png_debug(1, "in png_read_rows\n");
823
   if (png_ptr == NULL) return;
G
Guy Schalnat 已提交
824 825
   rp = row;
   dp = display_row;
826
   if (rp != NULL && dp != NULL)
827 828 829 830
      for (i = 0; i < num_rows; i++)
      {
         png_bytep rptr = *rp++;
         png_bytep dptr = *dp++;
831

832 833
         png_read_row(png_ptr, rptr, dptr);
      }
834
   else if (rp != NULL)
835 836
      for (i = 0; i < num_rows; i++)
      {
837
         png_bytep rptr = *rp;
838
         png_read_row(png_ptr, rptr, png_bytep_NULL);
839 840
         rp++;
      }
841
   else if (dp != NULL)
842 843 844
      for (i = 0; i < num_rows; i++)
      {
         png_bytep dptr = *dp;
845
         png_read_row(png_ptr, png_bytep_NULL, dptr);
846
         dp++;
847
      }
G
Guy Schalnat 已提交
848
}
849
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
850

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

A
Andreas Dilger 已提交
871
   png_debug(1, "in png_read_image\n");
872
   if (png_ptr == NULL) return;
873 874

#ifdef PNG_READ_INTERLACING_SUPPORTED
G
Guy Schalnat 已提交
875
   pass = png_set_interlace_handling(png_ptr);
876 877 878 879 880 881 882
#else
   if (png_ptr->interlaced)
      png_error(png_ptr,
        "Cannot read interlaced image -- interlace handler disabled.");
   pass = 1;
#endif

G
Guy Schalnat 已提交
883

884 885
   image_height=png_ptr->height;
   png_ptr->num_rows = image_height; /* Make sure this is set correctly */
G
Guy Schalnat 已提交
886

G
Guy Schalnat 已提交
887 888 889
   for (j = 0; j < pass; j++)
   {
      rp = image;
890
      for (i = 0; i < image_height; i++)
G
Guy Schalnat 已提交
891
      {
892
         png_read_row(png_ptr, *rp, png_bytep_NULL);
G
Guy Schalnat 已提交
893 894 895 896
         rp++;
      }
   }
}
897
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
898

899
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
900
/* Read the end of the PNG file.  Will not read past the end of the
901 902 903
 * 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.
 */
904
void PNGAPI
A
Andreas Dilger 已提交
905
png_read_end(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
906
{
907
   png_bytep chunk_name;
G
Guy Schalnat 已提交
908 909
   png_uint_32 length;

A
Andreas Dilger 已提交
910
   png_debug(1, "in png_read_end\n");
911
   if (png_ptr == NULL) return;
A
Andreas Dilger 已提交
912
   png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
G
Guy Schalnat 已提交
913 914 915

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

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

/* free all memory used by the read */
1079
void PNGAPI
G
Guy Schalnat 已提交
1080
png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
A
Andreas Dilger 已提交
1081
   png_infopp end_info_ptr_ptr)
G
Guy Schalnat 已提交
1082 1083
{
   png_structp png_ptr = NULL;
A
Andreas Dilger 已提交
1084
   png_infop info_ptr = NULL, end_info_ptr = NULL;
1085
#ifdef PNG_USER_MEM_SUPPORTED
1086 1087
   png_free_ptr free_fn = NULL;
   png_voidp mem_ptr = NULL;
1088
#endif
G
Guy Schalnat 已提交
1089

A
Andreas Dilger 已提交
1090 1091
   png_debug(1, "in png_destroy_read_struct\n");
   if (png_ptr_ptr != NULL)
G
Guy Schalnat 已提交
1092
      png_ptr = *png_ptr_ptr;
1093
   if (png_ptr == NULL)
1094
      return;
G
Guy Schalnat 已提交
1095

1096 1097 1098 1099 1100
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
   mem_ptr = png_ptr->mem_ptr;
#endif

A
Andreas Dilger 已提交
1101
   if (info_ptr_ptr != NULL)
G
Guy Schalnat 已提交
1102 1103
      info_ptr = *info_ptr_ptr;

A
Andreas Dilger 已提交
1104
   if (end_info_ptr_ptr != NULL)
A
Andreas Dilger 已提交
1105
      end_info_ptr = *end_info_ptr_ptr;
G
Guy Schalnat 已提交
1106

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

A
Andreas Dilger 已提交
1109
   if (info_ptr != NULL)
G
Guy Schalnat 已提交
1110
   {
1111
#if defined(PNG_TEXT_SUPPORTED)
1112
      png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
1113
#endif
1114 1115

#ifdef PNG_USER_MEM_SUPPORTED
1116 1117
      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
          (png_voidp)mem_ptr);
1118
#else
A
Andreas Dilger 已提交
1119
      png_destroy_struct((png_voidp)info_ptr);
1120
#endif
1121
      *info_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1122 1123
   }

A
Andreas Dilger 已提交
1124
   if (end_info_ptr != NULL)
G
Guy Schalnat 已提交
1125
   {
1126
#if defined(PNG_READ_TEXT_SUPPORTED)
1127
      png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
1128
#endif
1129
#ifdef PNG_USER_MEM_SUPPORTED
1130 1131
      png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
         (png_voidp)mem_ptr);
1132
#else
A
Andreas Dilger 已提交
1133
      png_destroy_struct((png_voidp)end_info_ptr);
1134
#endif
1135
      *end_info_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1136 1137
   }

1138 1139
   if (png_ptr != NULL)
   {
1140
#ifdef PNG_USER_MEM_SUPPORTED
1141 1142
      png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
          (png_voidp)mem_ptr);
1143
#else
1144
      png_destroy_struct((png_voidp)png_ptr);
1145
#endif
1146 1147
      *png_ptr_ptr = NULL;
   }
G
Guy Schalnat 已提交
1148 1149
}

A
Andreas Dilger 已提交
1150
/* free all memory used by the read (old method) */
1151
void /* PRIVATE */
A
Andreas Dilger 已提交
1152
png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
G
Guy Schalnat 已提交
1153
{
1154
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
1155
   jmp_buf tmp_jmp;
1156
#endif
G
Guy Schalnat 已提交
1157 1158 1159
   png_error_ptr error_fn;
   png_error_ptr warning_fn;
   png_voidp error_ptr;
1160 1161 1162
#ifdef PNG_USER_MEM_SUPPORTED
   png_free_ptr free_fn;
#endif
G
Guy Schalnat 已提交
1163

A
Andreas Dilger 已提交
1164 1165
   png_debug(1, "in png_read_destroy\n");
   if (info_ptr != NULL)
A
Andreas Dilger 已提交
1166
      png_info_destroy(png_ptr, info_ptr);
G
Guy Schalnat 已提交
1167

A
Andreas Dilger 已提交
1168
   if (end_info_ptr != NULL)
A
Andreas Dilger 已提交
1169
      png_info_destroy(png_ptr, end_info_ptr);
G
Guy Schalnat 已提交
1170

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

A
Andreas Dilger 已提交
1255
   inflateEnd(&png_ptr->zstream);
G
Guy Schalnat 已提交
1256
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
A
Andreas Dilger 已提交
1257
   png_free(png_ptr, png_ptr->save_buffer);
G
Guy Schalnat 已提交
1258
#endif
G
Guy Schalnat 已提交
1259

1260 1261 1262 1263 1264 1265
#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 已提交
1266 1267 1268
   /* Save the important info out of the png_struct, in case it is
    * being used again.
    */
1269
#ifdef PNG_SETJMP_SUPPORTED
1270
   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
1271
#endif
G
Guy Schalnat 已提交
1272 1273 1274 1275

   error_fn = png_ptr->error_fn;
   warning_fn = png_ptr->warning_fn;
   error_ptr = png_ptr->error_ptr;
1276 1277 1278
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
#endif
G
Guy Schalnat 已提交
1279

1280
   png_memset(png_ptr, 0, png_sizeof(png_struct));
G
Guy Schalnat 已提交
1281 1282 1283 1284

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

1289
#ifdef PNG_SETJMP_SUPPORTED
1290
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
1291 1292
#endif

G
Guy Schalnat 已提交
1293
}
1294

1295
void PNGAPI
1296 1297
png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
{
1298
   if (png_ptr == NULL) return;
1299 1300
   png_ptr->read_row_fn = read_row_fn;
}
1301

1302 1303

#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
1304
#if defined(PNG_INFO_IMAGE_SUPPORTED)
1305 1306
void PNGAPI
png_read_png(png_structp png_ptr, png_infop info_ptr,
1307 1308 1309 1310 1311
                           int transforms,
                           voidp params)
{
   int row;

1312
   if (png_ptr == NULL) return;
1313
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1314 1315
   /* invert the alpha channel from opacity to transparency
    */
1316 1317 1318 1319
   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
       png_set_invert_alpha(png_ptr);
#endif

1320
   /* png_read_info() gives us all of the information from the
1321 1322 1323
    * PNG file before the first IDAT (image data chunk).
    */
   png_read_info(png_ptr, info_ptr);
1324
   if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
1325
      png_error(png_ptr, "Image is too high to process with png_read_png()");
1326 1327 1328 1329

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

#if defined(PNG_READ_16_TO_8_SUPPORTED)
1330 1331
   /* tell libpng to strip 16 bit/color files down to 8 bits per color
    */
1332 1333 1334 1335 1336
   if (transforms & PNG_TRANSFORM_STRIP_16)
       png_set_strip_16(png_ptr);
#endif

#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1337 1338
   /* Strip alpha bytes from the input data without combining with
    * the background (not recommended).
1339 1340 1341 1342 1343
    */
   if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
       png_set_strip_alpha(png_ptr);
#endif

1344
#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
1345
   /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
1346 1347 1348 1349 1350 1351 1352 1353
    * byte into separate bytes (useful for paletted and grayscale images).
    */
   if (transforms & PNG_TRANSFORM_PACKING)
       png_set_packing(png_ptr);
#endif

#if defined(PNG_READ_PACKSWAP_SUPPORTED)
   /* Change the order of packed pixels to least significant bit first
1354 1355
    * (not useful if you are using png_set_packing).
    */
1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366
   if (transforms & PNG_TRANSFORM_PACKSWAP)
       png_set_packswap(png_ptr);
#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)
1367 1368 1369 1370
       if ((png_ptr->bit_depth < 8) ||
           (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
           (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
         png_set_expand(png_ptr);
1371 1372
#endif

1373 1374
   /* We don't handle background color or gamma transformation or dithering.
    */
1375 1376

#if defined(PNG_READ_INVERT_SUPPORTED)
1377 1378
   /* invert monochrome files to have 0 as white and 1 as black
    */
1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398
   if (transforms & PNG_TRANSFORM_INVERT_MONO)
       png_set_invert_mono(png_ptr);
#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)
1399 1400
   /* flip the RGB pixels to BGR (or RGBA to BGRA)
    */
1401 1402 1403 1404 1405
   if (transforms & PNG_TRANSFORM_BGR)
       png_set_bgr(png_ptr);
#endif

#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1406 1407
   /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
    */
1408 1409 1410 1411 1412
   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
       png_set_swap_alpha(png_ptr);
#endif

#if defined(PNG_READ_SWAP_SUPPORTED)
1413 1414
   /* swap bytes of 16 bit files to least significant byte first
    */
1415 1416 1417 1418 1419 1420 1421 1422
   if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
       png_set_swap(png_ptr);
#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
1423
    * update the palette for you (i.e., you selected such a transform above).
1424 1425 1426 1427 1428
    */
   png_read_update_info(png_ptr, info_ptr);

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

1429
#ifdef PNG_FREE_ME_SUPPORTED
1430
   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1431
#endif
1432
   if (info_ptr->row_pointers == NULL)
1433 1434
   {
      info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
1435
         info_ptr->height * png_sizeof(png_bytep));
1436
#ifdef PNG_FREE_ME_SUPPORTED
1437
      info_ptr->free_me |= PNG_FREE_ROWS;
1438 1439
#endif
      for (row = 0; row < (int)info_ptr->height; row++)
1440 1441
      {
         info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
1442
            png_get_rowbytes(png_ptr, info_ptr));
1443
      }
1444
   }
1445 1446 1447 1448 1449 1450

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

   /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
   png_read_end(png_ptr, info_ptr);
1451

1452 1453
   transforms = transforms; /* quiet compiler warnings */
   params = params;
1454

1455
}
1456
#endif /* PNG_INFO_IMAGE_SUPPORTED */
1457
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
1458
#endif /* PNG_READ_SUPPORTED */