pngread.c 46.4 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.19 July 18, 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
#if !defined(PNG_1_0_X)
59
#ifdef PNG_MMX_CODE_SUPPORTED
60 61
   png_init_mmx_flags(png_ptr);   /* 1.2.0 addition */
#endif
62
#endif /* PNG_1_0_X */
63

64 65 66 67 68 69
   /* 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

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

#ifdef PNG_USER_MEM_SUPPORTED
   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
94
#endif
95

A
Andreas Dilger 已提交
96 97
   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);

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

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

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

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

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

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

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

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

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

243
   int i=0;
244 245 246

   png_structp png_ptr=*ptr_ptr;

247 248
   if(png_ptr == NULL) return;

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

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

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

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

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

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

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

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

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

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

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

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

A
Andreas Dilger 已提交
412
      png_read_data(png_ptr, chunk_length, 4);
413
      length = png_get_uint_31(png_ptr,chunk_length);
G
Guy Schalnat 已提交
414

A
Andreas Dilger 已提交
415 416 417
      png_reset_crc(png_ptr);
      png_crc_read(png_ptr, png_ptr->chunk_name, 4);

418
      png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name,
419
         length);
A
Andreas Dilger 已提交
420 421 422 423

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

A
Andreas Dilger 已提交
428 429 430 431
      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);
432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
#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 已提交
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467
      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 已提交
468 469
#endif
#if defined(PNG_READ_cHRM_SUPPORTED)
A
Andreas Dilger 已提交
470 471
      else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
         png_handle_cHRM(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
472
#endif
A
Andreas Dilger 已提交
473 474 475
#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 已提交
476 477
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
A
Andreas Dilger 已提交
478 479
      else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
         png_handle_hIST(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
480
#endif
A
Andreas Dilger 已提交
481 482 483 484 485 486 487 488
#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
489 490 491 492
#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 已提交
493
#if defined(PNG_READ_pHYs_SUPPORTED)
A
Andreas Dilger 已提交
494 495
      else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
         png_handle_pHYs(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
496
#endif
A
Andreas Dilger 已提交
497 498 499 500
#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
501 502 503 504
#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
505 506 507 508 509 510 511 512
#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 已提交
513 514 515
#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 已提交
516 517
#endif
#if defined(PNG_READ_tIME_SUPPORTED)
A
Andreas Dilger 已提交
518 519
      else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
         png_handle_tIME(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
520
#endif
A
Andreas Dilger 已提交
521 522 523
#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 已提交
524 525
#endif
#if defined(PNG_READ_zTXt_SUPPORTED)
A
Andreas Dilger 已提交
526 527
      else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
         png_handle_zTXt(png_ptr, info_ptr, length);
528 529 530 531
#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 已提交
532
#endif
A
Andreas Dilger 已提交
533 534
      else
         png_handle_unknown(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
535 536
   }
}
537
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
538

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

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

569
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
570
void PNGAPI
G
Guy Schalnat 已提交
571
png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
G
Guy Schalnat 已提交
572
{
573
#ifdef PNG_USE_LOCAL_ARRAYS
574
   PNG_CONST PNG_IDAT;
575 576 577
   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};
578
#endif
G
Guy Schalnat 已提交
579
   int ret;
580
   if(png_ptr == NULL) return;
581
   png_debug2(1, "in png_read_row (row %lu, pass %d)\n",
A
Andreas Dilger 已提交
582
      png_ptr->row_number, png_ptr->pass);
G
Guy Schalnat 已提交
583
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
584
      png_read_start_row(png_ptr);
585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616
   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 已提交
617

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

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

A
Andreas Dilger 已提交
698 699
   png_ptr->zstream.next_out = png_ptr->row_buf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
G
Guy Schalnat 已提交
700 701
   do
   {
A
Andreas Dilger 已提交
702
      if (!(png_ptr->zstream.avail_in))
G
Guy Schalnat 已提交
703 704 705
      {
         while (!png_ptr->idat_size)
         {
A
Andreas Dilger 已提交
706
            png_byte chunk_length[4];
G
Guy Schalnat 已提交
707

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

A
Andreas Dilger 已提交
710
            png_read_data(png_ptr, chunk_length, 4);
711
            png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length);
712

A
Andreas Dilger 已提交
713 714 715 716
            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 已提交
717
         }
A
Andreas Dilger 已提交
718 719
         png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
         png_ptr->zstream.next_in = png_ptr->zbuf;
G
Guy Schalnat 已提交
720
         if (png_ptr->zbuf_size > png_ptr->idat_size)
A
Andreas Dilger 已提交
721
            png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
A
Andreas Dilger 已提交
722 723
         png_crc_read(png_ptr, png_ptr->zbuf,
            (png_size_t)png_ptr->zstream.avail_in);
A
Andreas Dilger 已提交
724
         png_ptr->idat_size -= png_ptr->zstream.avail_in;
G
Guy Schalnat 已提交
725
      }
A
Andreas Dilger 已提交
726
      ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
G
Guy Schalnat 已提交
727 728
      if (ret == Z_STREAM_END)
      {
A
Andreas Dilger 已提交
729
         if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
G
Guy Schalnat 已提交
730
            png_ptr->idat_size)
G
Guy Schalnat 已提交
731
            png_error(png_ptr, "Extra compressed data");
A
Andreas Dilger 已提交
732
         png_ptr->mode |= PNG_AFTER_IDAT;
G
Guy Schalnat 已提交
733
         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
G
Guy Schalnat 已提交
734
         break;
G
Guy Schalnat 已提交
735 736
      }
      if (ret != Z_OK)
A
Andreas Dilger 已提交
737
         png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
G
Guy Schalnat 已提交
738
                   "Decompression error");
A
Andreas Dilger 已提交
739 740

   } while (png_ptr->zstream.avail_out);
G
Guy Schalnat 已提交
741 742 743 744 745 746

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

750
   if(png_ptr->row_buf[0])
G
Guy Schalnat 已提交
751 752 753
   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 已提交
754

755
   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
756
      png_ptr->rowbytes + 1);
757

758 759 760 761 762 763 764 765
#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 已提交
766

767 768

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

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

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

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

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

830
void PNGAPI
G
Guy Schalnat 已提交
831
png_read_rows(png_structp png_ptr, png_bytepp row,
G
Guy Schalnat 已提交
832
   png_bytepp display_row, png_uint_32 num_rows)
G
Guy Schalnat 已提交
833
{
G
Guy Schalnat 已提交
834 835 836
   png_uint_32 i;
   png_bytepp rp;
   png_bytepp dp;
G
Guy Schalnat 已提交
837

A
Andreas Dilger 已提交
838
   png_debug(1, "in png_read_rows\n");
839
   if(png_ptr == NULL) return;
G
Guy Schalnat 已提交
840 841
   rp = row;
   dp = display_row;
842
   if (rp != NULL && dp != NULL)
843 844 845 846
      for (i = 0; i < num_rows; i++)
      {
         png_bytep rptr = *rp++;
         png_bytep dptr = *dp++;
847

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

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

A
Andreas Dilger 已提交
887
   png_debug(1, "in png_read_image\n");
888
   if(png_ptr == NULL) return;
889 890

#ifdef PNG_READ_INTERLACING_SUPPORTED
G
Guy Schalnat 已提交
891
   pass = png_set_interlace_handling(png_ptr);
892 893 894 895 896 897 898
#else
   if (png_ptr->interlaced)
      png_error(png_ptr,
        "Cannot read interlaced image -- interlace handler disabled.");
   pass = 1;
#endif

G
Guy Schalnat 已提交
899

900 901
   image_height=png_ptr->height;
   png_ptr->num_rows = image_height; /* Make sure this is set correctly */
G
Guy Schalnat 已提交
902

G
Guy Schalnat 已提交
903 904 905
   for (j = 0; j < pass; j++)
   {
      rp = image;
906
      for (i = 0; i < image_height; i++)
G
Guy Schalnat 已提交
907
      {
908
         png_read_row(png_ptr, *rp, png_bytep_NULL);
G
Guy Schalnat 已提交
909 910 911 912
         rp++;
      }
   }
}
913
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
914

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

A
Andreas Dilger 已提交
926
   png_debug(1, "in png_read_end\n");
927
   if(png_ptr == NULL) return;
A
Andreas Dilger 已提交
928
   png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
G
Guy Schalnat 已提交
929 930 931

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

A
Andreas Dilger 已提交
990
      png_read_data(png_ptr, chunk_length, 4);
991
      length = png_get_uint_31(png_ptr,chunk_length);
G
Guy Schalnat 已提交
992

A
Andreas Dilger 已提交
993 994 995
      png_reset_crc(png_ptr);
      png_crc_read(png_ptr, png_ptr->chunk_name, 4);

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

A
Andreas Dilger 已提交
998 999
      if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
         png_handle_IHDR(png_ptr, info_ptr, length);
1000 1001 1002 1003 1004 1005 1006
      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))
         {
1007
            if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
1008 1009 1010 1011 1012 1013 1014
               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 已提交
1015 1016 1017 1018 1019
      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.
          */
1020
         if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
A
Andreas Dilger 已提交
1021
            png_error(png_ptr, "Too many IDAT's found");
1022
         png_crc_finish(png_ptr, length);
A
Andreas Dilger 已提交
1023
      }
A
Andreas Dilger 已提交
1024 1025
      else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
         png_handle_PLTE(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
1026
#if defined(PNG_READ_bKGD_SUPPORTED)
A
Andreas Dilger 已提交
1027 1028
      else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
         png_handle_bKGD(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038
#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 已提交
1039 1040
      else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
         png_handle_hIST(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
1041 1042
#endif
#if defined(PNG_READ_oFFs_SUPPORTED)
A
Andreas Dilger 已提交
1043 1044
      else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
         png_handle_oFFs(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
1045 1046 1047 1048 1049
#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
1050 1051 1052 1053
#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 已提交
1054 1055 1056 1057 1058 1059 1060
#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 已提交
1061
#endif
1062 1063 1064 1065
#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
1066 1067 1068 1069 1070 1071 1072 1073
#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 已提交
1074
#if defined(PNG_READ_tEXt_SUPPORTED)
A
Andreas Dilger 已提交
1075 1076
      else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
         png_handle_tEXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
1077
#endif
A
Andreas Dilger 已提交
1078 1079 1080 1081 1082 1083 1084 1085
#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 已提交
1086
#if defined(PNG_READ_zTXt_SUPPORTED)
A
Andreas Dilger 已提交
1087 1088
      else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
         png_handle_zTXt(png_ptr, info_ptr, length);
1089 1090 1091 1092
#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 已提交
1093
#endif
G
Guy Schalnat 已提交
1094
      else
A
Andreas Dilger 已提交
1095 1096
         png_handle_unknown(png_ptr, info_ptr, length);
   } while (!(png_ptr->mode & PNG_HAVE_IEND));
G
Guy Schalnat 已提交
1097
}
1098
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
1099 1100

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

A
Andreas Dilger 已提交
1112 1113
   png_debug(1, "in png_destroy_read_struct\n");
   if (png_ptr_ptr != NULL)
G
Guy Schalnat 已提交
1114 1115
      png_ptr = *png_ptr_ptr;

A
Andreas Dilger 已提交
1116
   if (info_ptr_ptr != NULL)
G
Guy Schalnat 已提交
1117 1118
      info_ptr = *info_ptr_ptr;

A
Andreas Dilger 已提交
1119
   if (end_info_ptr_ptr != NULL)
A
Andreas Dilger 已提交
1120
      end_info_ptr = *end_info_ptr_ptr;
G
Guy Schalnat 已提交
1121

1122 1123
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
1124
   mem_ptr = png_ptr->mem_ptr;
1125 1126
#endif

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

A
Andreas Dilger 已提交
1129
   if (info_ptr != NULL)
G
Guy Schalnat 已提交
1130
   {
1131
#if defined(PNG_TEXT_SUPPORTED)
1132
      png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
1133
#endif
1134 1135

#ifdef PNG_USER_MEM_SUPPORTED
1136 1137
      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
          (png_voidp)mem_ptr);
1138
#else
A
Andreas Dilger 已提交
1139
      png_destroy_struct((png_voidp)info_ptr);
1140
#endif
1141
      *info_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1142 1143
   }

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

A
Andreas Dilger 已提交
1158
   if (png_ptr != NULL)
G
Guy Schalnat 已提交
1159
   {
1160
#ifdef PNG_USER_MEM_SUPPORTED
1161 1162
      png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
          (png_voidp)mem_ptr);
1163
#else
A
Andreas Dilger 已提交
1164
      png_destroy_struct((png_voidp)png_ptr);
1165
#endif
1166
      *png_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1167 1168 1169
   }
}

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

A
Andreas Dilger 已提交
1184 1185
   png_debug(1, "in png_read_destroy\n");
   if (info_ptr != NULL)
A
Andreas Dilger 已提交
1186
      png_info_destroy(png_ptr, info_ptr);
G
Guy Schalnat 已提交
1187

A
Andreas Dilger 已提交
1188
   if (end_info_ptr != NULL)
A
Andreas Dilger 已提交
1189
      png_info_destroy(png_ptr, end_info_ptr);
G
Guy Schalnat 已提交
1190

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

A
Andreas Dilger 已提交
1275
   inflateEnd(&png_ptr->zstream);
G
Guy Schalnat 已提交
1276
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
A
Andreas Dilger 已提交
1277
   png_free(png_ptr, png_ptr->save_buffer);
G
Guy Schalnat 已提交
1278
#endif
G
Guy Schalnat 已提交
1279

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

   error_fn = png_ptr->error_fn;
   warning_fn = png_ptr->warning_fn;
   error_ptr = png_ptr->error_ptr;
1296 1297 1298
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
#endif
G
Guy Schalnat 已提交
1299

1300
   png_memset(png_ptr, 0, png_sizeof (png_struct));
G
Guy Schalnat 已提交
1301 1302 1303 1304

   png_ptr->error_fn = error_fn;
   png_ptr->warning_fn = warning_fn;
   png_ptr->error_ptr = error_ptr;
1305 1306 1307
#ifdef PNG_USER_MEM_SUPPORTED
   png_ptr->free_fn = free_fn;
#endif
G
Guy Schalnat 已提交
1308

1309
#ifdef PNG_SETJMP_SUPPORTED
1310
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
1311 1312
#endif

G
Guy Schalnat 已提交
1313
}
1314

1315
void PNGAPI
1316 1317
png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
{
1318
   if(png_ptr == NULL) return;
1319 1320
   png_ptr->read_row_fn = read_row_fn;
}
1321

1322 1323

#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
1324
#if defined(PNG_INFO_IMAGE_SUPPORTED)
1325 1326
void PNGAPI
png_read_png(png_structp png_ptr, png_infop info_ptr,
1327 1328 1329 1330 1331
                           int transforms,
                           voidp params)
{
   int row;

1332
   if(png_ptr == NULL) return;
1333
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1334 1335
   /* invert the alpha channel from opacity to transparency
    */
1336 1337 1338 1339
   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
       png_set_invert_alpha(png_ptr);
#endif

1340
   /* png_read_info() gives us all of the information from the
1341 1342 1343
    * PNG file before the first IDAT (image data chunk).
    */
   png_read_info(png_ptr, info_ptr);
1344 1345
   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()");
1346 1347 1348 1349

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

#if defined(PNG_READ_16_TO_8_SUPPORTED)
1350 1351
   /* tell libpng to strip 16 bit/color files down to 8 bits per color
    */
1352 1353 1354 1355 1356
   if (transforms & PNG_TRANSFORM_STRIP_16)
       png_set_strip_16(png_ptr);
#endif

#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1357 1358
   /* Strip alpha bytes from the input data without combining with
    * the background (not recommended).
1359 1360 1361 1362 1363
    */
   if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
       png_set_strip_alpha(png_ptr);
#endif

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

1393 1394
   /* We don't handle background color or gamma transformation or dithering.
    */
1395 1396

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

#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1426 1427
   /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
    */
1428 1429 1430 1431 1432
   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
       png_set_swap_alpha(png_ptr);
#endif

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

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

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

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

1472 1473
   transforms = transforms; /* quiet compiler warnings */
   params = params;
1474

1475
}
1476
#endif /* PNG_INFO_IMAGE_SUPPORTED */
1477
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
1478
#endif /* PNG_READ_SUPPORTED */