pngread.c 46.3 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.20 September 7, 2007
5
 * For conditions of distribution and use, see copyright notice in png.h
6
 * Copyright (c) 1998-2007 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 16

#define PNG_INTERNAL
#include "png.h"

17 18
#if defined(PNG_READ_SUPPORTED)

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

#ifdef PNG_USER_MEM_SUPPORTED
   return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
27
      warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
28 29 30
}

/* Alternate create PNG structure for reading, and allocate any memory needed. */
31
png_structp PNGAPI
32 33 34 35 36 37
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 已提交
38
   png_structp png_ptr;
39 40

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

46 47
   int i;

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

58 59 60 61 62 63
   /* 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

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

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

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

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

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

G
Guy Schalnat 已提交
132 133
   /* initialize zbuf - compression buffer */
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
134 135
   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
     (png_uint_32)png_ptr->zbuf_size);
A
Andreas Dilger 已提交
136 137 138
   png_ptr->zstream.zalloc = png_zalloc;
   png_ptr->zstream.zfree = png_zfree;
   png_ptr->zstream.opaque = (voidpf)png_ptr;
G
Guy Schalnat 已提交
139

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

152
   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
G
Guy Schalnat 已提交
153

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

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

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

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 已提交
232
{
233
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
234
   jmp_buf tmp_jmp;  /* to save current jump buffer */
235
#endif
G
Guy Schalnat 已提交
236

237
   int i=0;
238 239 240

   png_structp png_ptr=*ptr_ptr;

241 242
   if(png_ptr == NULL) return;

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

258
   png_debug(1, "in png_read_init_3\n");
259 260

#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
261
   /* save jump buffer and error functions */
262
   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
263
#endif
G
Guy Schalnat 已提交
264

265
   if(png_sizeof(png_struct) > png_struct_size)
266 267 268 269 270 271
     {
       png_destroy_struct(png_ptr);
       *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
       png_ptr = *ptr_ptr;
     }

G
Guy Schalnat 已提交
272
   /* reset all variables to 0 */
273
   png_memset(png_ptr, 0, png_sizeof (png_struct));
G
Guy Schalnat 已提交
274

275
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
276
   /* restore jump buffer */
277
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
278
#endif
G
Guy Schalnat 已提交
279

280 281 282 283 284 285
   /* 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 已提交
286
   /* initialize zbuf - compression buffer */
G
Guy Schalnat 已提交
287
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
288 289
   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
     (png_uint_32)png_ptr->zbuf_size);
A
Andreas Dilger 已提交
290 291 292
   png_ptr->zstream.zalloc = png_zalloc;
   png_ptr->zstream.zfree = png_zfree;
   png_ptr->zstream.opaque = (voidpf)png_ptr;
G
Guy Schalnat 已提交
293

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

306
   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
G
Guy Schalnat 已提交
307 308
}

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

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

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

A
Andreas Dilger 已提交
406
      png_read_data(png_ptr, chunk_length, 4);
407
      length = png_get_uint_31(png_ptr,chunk_length);
G
Guy Schalnat 已提交
408

A
Andreas Dilger 已提交
409 410 411
      png_reset_crc(png_ptr);
      png_crc_read(png_ptr, png_ptr->chunk_name, 4);

412
      png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name,
413
         length);
A
Andreas Dilger 已提交
414 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(png_ptr->chunk_name, png_IDAT, 4))
419 420 421
        if(png_ptr->mode & PNG_AFTER_IDAT)
          png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;

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

A
Andreas Dilger 已提交
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
{
A
Andreas Dilger 已提交
537
   png_debug(1, "in png_read_update_info\n");
538
   if(png_ptr == NULL) return;
G
Guy Schalnat 已提交
539
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
540
      png_read_start_row(png_ptr);
541 542 543
   else
      png_warning(png_ptr,
      "Ignoring extra png_read_update_info() call; row buffer not reallocated");
A
Andreas Dilger 已提交
544
   png_read_transform_info(png_ptr, info_ptr);
G
Guy Schalnat 已提交
545 546
}

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

563
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
564
void PNGAPI
G
Guy Schalnat 已提交
565
png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
G
Guy Schalnat 已提交
566
{
567
#ifdef PNG_USE_LOCAL_ARRAYS
568
   PNG_CONST PNG_IDAT;
569 570 571
   PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
     0xff};
   PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
572
#endif
G
Guy Schalnat 已提交
573
   int ret;
574
   if(png_ptr == NULL) return;
575
   png_debug2(1, "in png_read_row (row %lu, pass %d)\n",
A
Andreas Dilger 已提交
576
      png_ptr->row_number, png_ptr->pass);
G
Guy Schalnat 已提交
577
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
578
      png_read_start_row(png_ptr);
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 607 608 609 610
   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 已提交
611

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

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

A
Andreas Dilger 已提交
692 693
   png_ptr->zstream.next_out = png_ptr->row_buf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
G
Guy Schalnat 已提交
694 695
   do
   {
A
Andreas Dilger 已提交
696
      if (!(png_ptr->zstream.avail_in))
G
Guy Schalnat 已提交
697 698 699
      {
         while (!png_ptr->idat_size)
         {
A
Andreas Dilger 已提交
700
            png_byte chunk_length[4];
G
Guy Schalnat 已提交
701

A
Andreas Dilger 已提交
702
            png_crc_finish(png_ptr, 0);
G
Guy Schalnat 已提交
703

A
Andreas Dilger 已提交
704
            png_read_data(png_ptr, chunk_length, 4);
705
            png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length);
706

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

   } while (png_ptr->zstream.avail_out);
G
Guy Schalnat 已提交
735 736 737 738 739 740

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

744
   if(png_ptr->row_buf[0])
G
Guy Schalnat 已提交
745 746 747
   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 已提交
748

749
   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
750
      png_ptr->rowbytes + 1);
751

752 753 754 755 756 757 758 759
#if defined(PNG_MNG_FEATURES_SUPPORTED)
   if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
      (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 已提交
760

761 762

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

G
Guy Schalnat 已提交
765
#if defined(PNG_READ_INTERLACING_SUPPORTED)
G
Guy Schalnat 已提交
766 767 768 769 770
   /* blow up interlaced rows to full size */
   if (png_ptr->interlaced &&
      (png_ptr->transformations & PNG_INTERLACE))
   {
      if (png_ptr->pass < 6)
771
/*       old interface (pre-1.0.9):
G
Guy Schalnat 已提交
772
         png_do_read_interlace(&(png_ptr->row_info),
A
Andreas Dilger 已提交
773
            png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
774 775
 */
         png_do_read_interlace(png_ptr);
G
Guy Schalnat 已提交
776

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

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

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

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

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

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

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

A
Andreas Dilger 已提交
881
   png_debug(1, "in png_read_image\n");
882
   if(png_ptr == NULL) return;
883 884

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

G
Guy Schalnat 已提交
893

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

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

909
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
910
/* Read the end of the PNG file.  Will not read past the end of the
911 912 913
 * 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.
 */
914
void PNGAPI
A
Andreas Dilger 已提交
915
png_read_end(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
916
{
A
Andreas Dilger 已提交
917
   png_byte chunk_length[4];
G
Guy Schalnat 已提交
918 919
   png_uint_32 length;

A
Andreas Dilger 已提交
920
   png_debug(1, "in png_read_end\n");
921
   if(png_ptr == NULL) return;
A
Andreas Dilger 已提交
922
   png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
G
Guy Schalnat 已提交
923 924 925

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

A
Andreas Dilger 已提交
984
      png_read_data(png_ptr, chunk_length, 4);
985
      length = png_get_uint_31(png_ptr,chunk_length);
G
Guy Schalnat 已提交
986

A
Andreas Dilger 已提交
987 988 989
      png_reset_crc(png_ptr);
      png_crc_read(png_ptr, png_ptr->chunk_name, 4);

A
Andreas Dilger 已提交
990 991
      png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name);

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

/* free all memory used by the read */
1095
void PNGAPI
G
Guy Schalnat 已提交
1096
png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
A
Andreas Dilger 已提交
1097
   png_infopp end_info_ptr_ptr)
G
Guy Schalnat 已提交
1098 1099
{
   png_structp png_ptr = NULL;
A
Andreas Dilger 已提交
1100
   png_infop info_ptr = NULL, end_info_ptr = NULL;
1101
#ifdef PNG_USER_MEM_SUPPORTED
1102 1103
   png_free_ptr free_fn;
   png_voidp mem_ptr;
1104
#endif
G
Guy Schalnat 已提交
1105

A
Andreas Dilger 已提交
1106 1107
   png_debug(1, "in png_destroy_read_struct\n");
   if (png_ptr_ptr != NULL)
G
Guy Schalnat 已提交
1108 1109
      png_ptr = *png_ptr_ptr;

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

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

1116 1117
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
1118
   mem_ptr = png_ptr->mem_ptr;
1119 1120
#endif

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

A
Andreas Dilger 已提交
1123
   if (info_ptr != NULL)
G
Guy Schalnat 已提交
1124
   {
1125
#if defined(PNG_TEXT_SUPPORTED)
1126
      png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
1127
#endif
1128 1129

#ifdef PNG_USER_MEM_SUPPORTED
1130 1131
      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
          (png_voidp)mem_ptr);
1132
#else
A
Andreas Dilger 已提交
1133
      png_destroy_struct((png_voidp)info_ptr);
1134
#endif
1135
      *info_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1136 1137
   }

A
Andreas Dilger 已提交
1138
   if (end_info_ptr != NULL)
G
Guy Schalnat 已提交
1139
   {
1140
#if defined(PNG_READ_TEXT_SUPPORTED)
1141
      png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
1142
#endif
1143
#ifdef PNG_USER_MEM_SUPPORTED
1144 1145
      png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
         (png_voidp)mem_ptr);
1146
#else
A
Andreas Dilger 已提交
1147
      png_destroy_struct((png_voidp)end_info_ptr);
1148
#endif
1149
      *end_info_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1150 1151
   }

A
Andreas Dilger 已提交
1152
   if (png_ptr != NULL)
G
Guy Schalnat 已提交
1153
   {
1154
#ifdef PNG_USER_MEM_SUPPORTED
1155 1156
      png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
          (png_voidp)mem_ptr);
1157
#else
A
Andreas Dilger 已提交
1158
      png_destroy_struct((png_voidp)png_ptr);
1159
#endif
1160
      *png_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1161 1162 1163
   }
}

A
Andreas Dilger 已提交
1164
/* free all memory used by the read (old method) */
1165
void /* PRIVATE */
A
Andreas Dilger 已提交
1166
png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
G
Guy Schalnat 已提交
1167
{
1168
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
1169
   jmp_buf tmp_jmp;
1170
#endif
G
Guy Schalnat 已提交
1171 1172 1173
   png_error_ptr error_fn;
   png_error_ptr warning_fn;
   png_voidp error_ptr;
1174 1175 1176
#ifdef PNG_USER_MEM_SUPPORTED
   png_free_ptr free_fn;
#endif
G
Guy Schalnat 已提交
1177

A
Andreas Dilger 已提交
1178 1179
   png_debug(1, "in png_read_destroy\n");
   if (info_ptr != NULL)
A
Andreas Dilger 已提交
1180
      png_info_destroy(png_ptr, info_ptr);
G
Guy Schalnat 已提交
1181

A
Andreas Dilger 已提交
1182
   if (end_info_ptr != NULL)
A
Andreas Dilger 已提交
1183
      png_info_destroy(png_ptr, end_info_ptr);
G
Guy Schalnat 已提交
1184

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

A
Andreas Dilger 已提交
1269
   inflateEnd(&png_ptr->zstream);
G
Guy Schalnat 已提交
1270
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
A
Andreas Dilger 已提交
1271
   png_free(png_ptr, png_ptr->save_buffer);
G
Guy Schalnat 已提交
1272
#endif
G
Guy Schalnat 已提交
1273

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

   error_fn = png_ptr->error_fn;
   warning_fn = png_ptr->warning_fn;
   error_ptr = png_ptr->error_ptr;
1290 1291 1292
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
#endif
G
Guy Schalnat 已提交
1293

1294
   png_memset(png_ptr, 0, png_sizeof (png_struct));
G
Guy Schalnat 已提交
1295 1296 1297 1298

   png_ptr->error_fn = error_fn;
   png_ptr->warning_fn = warning_fn;
   png_ptr->error_ptr = error_ptr;
1299 1300 1301
#ifdef PNG_USER_MEM_SUPPORTED
   png_ptr->free_fn = free_fn;
#endif
G
Guy Schalnat 已提交
1302

1303
#ifdef PNG_SETJMP_SUPPORTED
1304
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
1305 1306
#endif

G
Guy Schalnat 已提交
1307
}
1308

1309
void PNGAPI
1310 1311
png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
{
1312
   if(png_ptr == NULL) return;
1313 1314
   png_ptr->read_row_fn = read_row_fn;
}
1315

1316 1317

#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
1318
#if defined(PNG_INFO_IMAGE_SUPPORTED)
1319 1320
void PNGAPI
png_read_png(png_structp png_ptr, png_infop info_ptr,
1321 1322 1323 1324 1325
                           int transforms,
                           voidp params)
{
   int row;

1326
   if(png_ptr == NULL) return;
1327
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1328 1329
   /* invert the alpha channel from opacity to transparency
    */
1330 1331 1332 1333
   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
       png_set_invert_alpha(png_ptr);
#endif

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

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

#if defined(PNG_READ_16_TO_8_SUPPORTED)
1344 1345
   /* tell libpng to strip 16 bit/color files down to 8 bits per color
    */
1346 1347 1348 1349 1350
   if (transforms & PNG_TRANSFORM_STRIP_16)
       png_set_strip_16(png_ptr);
#endif

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

1358
#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
1359
   /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
1360 1361 1362 1363 1364 1365 1366 1367
    * 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
1368 1369
    * (not useful if you are using png_set_packing).
    */
1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380
   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)
1381 1382 1383 1384
       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);
1385 1386
#endif

1387 1388
   /* We don't handle background color or gamma transformation or dithering.
    */
1389 1390

#if defined(PNG_READ_INVERT_SUPPORTED)
1391 1392
   /* invert monochrome files to have 0 as white and 1 as black
    */
1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412
   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)
1413 1414
   /* flip the RGB pixels to BGR (or RGBA to BGRA)
    */
1415 1416 1417 1418 1419
   if (transforms & PNG_TRANSFORM_BGR)
       png_set_bgr(png_ptr);
#endif

#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1420 1421
   /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
    */
1422 1423 1424 1425 1426
   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
       png_set_swap_alpha(png_ptr);
#endif

#if defined(PNG_READ_SWAP_SUPPORTED)
1427 1428
   /* swap bytes of 16 bit files to least significant byte first
    */
1429 1430 1431 1432 1433 1434 1435 1436
   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
1437
    * update the palette for you (i.e., you selected such a transform above).
1438 1439 1440 1441 1442
    */
   png_read_update_info(png_ptr, info_ptr);

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

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

   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);
1465

1466 1467
   transforms = transforms; /* quiet compiler warnings */
   params = params;
1468

1469
}
1470
#endif /* PNG_INFO_IMAGE_SUPPORTED */
1471
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
1472
#endif /* PNG_READ_SUPPORTED */