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

A
Andreas Dilger 已提交
2
/* pngread.c - read a PNG file
3
 *
4
 * Last changed in libpng 1.2.9 April 14, 2006
5
 * For conditions of distribution and use, see copyright notice in png.h
6
 * Copyright (c) 1998-2006 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 60 61
#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
   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 120 121 122 123
#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
        char msg[80];
        if (user_png_ver)
        {
          sprintf(msg, "Application was compiled with png.h from libpng-%.20s",
             user_png_ver);
          png_warning(png_ptr, msg);
        }
124
        sprintf(msg, "Application  is  running with png.c from libpng-%.20s",
125 126 127 128 129 130
           png_libpng_ver);
        png_warning(png_ptr, msg);
#endif
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
        png_ptr->flags=0;
#endif
131 132 133
        png_error(png_ptr,
           "Incompatible libpng version in application and library");
     }
134 135
   }

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

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

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

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

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

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

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

238
   int i=0;
239 240 241

   png_structp png_ptr=*ptr_ptr;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

410
      png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name,
411
         length);
A
Andreas Dilger 已提交
412 413 414 415

      /* This should be a binary subdivision search or a hash for
       * matching the chunk name rather than a linear search.
       */
A
Andreas Dilger 已提交
416 417 418 419
      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);
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
#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 已提交
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
      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 已提交
456 457
#endif
#if defined(PNG_READ_cHRM_SUPPORTED)
A
Andreas Dilger 已提交
458 459
      else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
         png_handle_cHRM(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
460
#endif
A
Andreas Dilger 已提交
461 462 463
#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 已提交
464 465
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
A
Andreas Dilger 已提交
466 467
      else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
         png_handle_hIST(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
468
#endif
A
Andreas Dilger 已提交
469 470 471 472 473 474 475 476
#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
477 478 479 480
#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 已提交
481
#if defined(PNG_READ_pHYs_SUPPORTED)
A
Andreas Dilger 已提交
482 483
      else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
         png_handle_pHYs(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
484
#endif
A
Andreas Dilger 已提交
485 486 487 488
#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
489 490 491 492
#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
493 494 495 496 497 498 499 500
#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 已提交
501 502 503
#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 已提交
504 505
#endif
#if defined(PNG_READ_tIME_SUPPORTED)
A
Andreas Dilger 已提交
506 507
      else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
         png_handle_tIME(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
508
#endif
A
Andreas Dilger 已提交
509 510 511
#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 已提交
512 513
#endif
#if defined(PNG_READ_zTXt_SUPPORTED)
A
Andreas Dilger 已提交
514 515
      else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
         png_handle_zTXt(png_ptr, info_ptr, length);
516 517 518 519
#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 已提交
520
#endif
A
Andreas Dilger 已提交
521 522
      else
         png_handle_unknown(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
523 524
   }
}
525
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
526

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

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

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

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

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

A
Andreas Dilger 已提交
682 683
   png_ptr->zstream.next_out = png_ptr->row_buf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
G
Guy Schalnat 已提交
684 685
   do
   {
A
Andreas Dilger 已提交
686
      if (!(png_ptr->zstream.avail_in))
G
Guy Schalnat 已提交
687 688 689
      {
         while (!png_ptr->idat_size)
         {
A
Andreas Dilger 已提交
690
            png_byte chunk_length[4];
G
Guy Schalnat 已提交
691

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

A
Andreas Dilger 已提交
694
            png_read_data(png_ptr, chunk_length, 4);
695
            png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length);
696

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

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

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

734
   if(png_ptr->row_buf[0])
G
Guy Schalnat 已提交
735 736 737
   png_read_filter_row(png_ptr, &(png_ptr->row_info),
      png_ptr->row_buf + 1, png_ptr->prev_row + 1,
      (int)(png_ptr->row_buf[0]));
G
Guy Schalnat 已提交
738

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

742 743 744 745 746 747 748 749
#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 已提交
750

751 752

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

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

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

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

789
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
790
/* Read one or more rows of image data.  If the image is interlaced,
791 792
 * and png_set_interlace_handling() has been called, the rows need to
 * contain the contents of the rows from the previous pass.  If the
793
 * image has alpha or transparency, and png_handle_alpha()[*] has been
794 795
 * called, the rows contents must be initialized to the contents of the
 * screen.
796
 *
797 798 799 800 801 802 803 804 805 806 807 808 809
 * "row" holds the actual image, and pixels are placed in it
 * as they arrive.  If the image is displayed after each pass, it will
 * appear to "sparkle" in.  "display_row" can be used to display a
 * "chunky" progressive image, with finer detail added as it becomes
 * available.  If you do not want this "chunky" display, you may pass
 * NULL for display_row.  If you do not want the sparkle display, and
 * you have not called png_handle_alpha(), you may pass NULL for rows.
 * If you have called png_handle_alpha(), and the image has either an
 * alpha channel or a transparency chunk, you must provide a buffer for
 * rows.  In this case, you do not have to provide a display_row buffer
 * also, but you may.  If the image is not interlaced, or if you have
 * not called png_set_interlace_handling(), the display_row buffer will
 * be ignored, so pass NULL to it.
810
 *
811
 * [*] png_handle_alpha() does not exist yet, as of this version of libpng
812
 */
G
Guy Schalnat 已提交
813

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

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

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

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

A
Andreas Dilger 已提交
870
   png_debug(1, "in png_read_image\n");
871 872

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

G
Guy Schalnat 已提交
881

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

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

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

A
Andreas Dilger 已提交
908 909
   png_debug(1, "in png_read_end\n");
   png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
G
Guy Schalnat 已提交
910 911 912

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

A
Andreas Dilger 已提交
971
      png_read_data(png_ptr, chunk_length, 4);
972
      length = png_get_uint_31(png_ptr,chunk_length);
G
Guy Schalnat 已提交
973

A
Andreas Dilger 已提交
974 975 976
      png_reset_crc(png_ptr);
      png_crc_read(png_ptr, png_ptr->chunk_name, 4);

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

A
Andreas Dilger 已提交
979 980
      if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
         png_handle_IHDR(png_ptr, info_ptr, length);
981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997
      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))
         {
            if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT)
               png_error(png_ptr, "Too many IDAT's found");
         }
         else
            png_ptr->mode |= PNG_AFTER_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;
      }
#endif
A
Andreas Dilger 已提交
998 999 1000 1001 1002 1003 1004
      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.
          */
         if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT)
            png_error(png_ptr, "Too many IDAT's found");
1005
         png_crc_finish(png_ptr, length);
A
Andreas Dilger 已提交
1006
      }
A
Andreas Dilger 已提交
1007 1008
      else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
         png_handle_PLTE(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
1009
#if defined(PNG_READ_bKGD_SUPPORTED)
A
Andreas Dilger 已提交
1010 1011
      else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
         png_handle_bKGD(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
1012 1013 1014 1015 1016 1017 1018 1019 1020 1021
#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 已提交
1022 1023
      else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
         png_handle_hIST(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
1024 1025
#endif
#if defined(PNG_READ_oFFs_SUPPORTED)
A
Andreas Dilger 已提交
1026 1027
      else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
         png_handle_oFFs(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
1028 1029 1030 1031 1032
#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
1033 1034 1035 1036
#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 已提交
1037 1038 1039 1040 1041 1042 1043
#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 已提交
1044
#endif
1045 1046 1047 1048
#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
1049 1050 1051 1052 1053 1054 1055 1056
#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 已提交
1057
#if defined(PNG_READ_tEXt_SUPPORTED)
A
Andreas Dilger 已提交
1058 1059
      else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
         png_handle_tEXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
1060
#endif
A
Andreas Dilger 已提交
1061 1062 1063 1064 1065 1066 1067 1068
#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 已提交
1069
#if defined(PNG_READ_zTXt_SUPPORTED)
A
Andreas Dilger 已提交
1070 1071
      else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
         png_handle_zTXt(png_ptr, info_ptr, length);
1072 1073 1074 1075
#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 已提交
1076
#endif
G
Guy Schalnat 已提交
1077
      else
A
Andreas Dilger 已提交
1078 1079
         png_handle_unknown(png_ptr, info_ptr, length);
   } while (!(png_ptr->mode & PNG_HAVE_IEND));
G
Guy Schalnat 已提交
1080
}
1081
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
1082 1083

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

A
Andreas Dilger 已提交
1095 1096
   png_debug(1, "in png_destroy_read_struct\n");
   if (png_ptr_ptr != NULL)
G
Guy Schalnat 已提交
1097 1098
      png_ptr = *png_ptr_ptr;

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

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

1105 1106
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
1107
   mem_ptr = png_ptr->mem_ptr;
1108 1109
#endif

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

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

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

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

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

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

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

A
Andreas Dilger 已提交
1171
   if (end_info_ptr != NULL)
A
Andreas Dilger 已提交
1172
      png_info_destroy(png_ptr, end_info_ptr);
G
Guy Schalnat 已提交
1173

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

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

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

   error_fn = png_ptr->error_fn;
   warning_fn = png_ptr->warning_fn;
   error_ptr = png_ptr->error_ptr;
1279 1280 1281
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
#endif
G
Guy Schalnat 已提交
1282

1283
   png_memset(png_ptr, 0, png_sizeof (png_struct));
G
Guy Schalnat 已提交
1284 1285 1286 1287

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

1292
#ifdef PNG_SETJMP_SUPPORTED
1293
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
1294 1295
#endif

G
Guy Schalnat 已提交
1296
}
1297

1298
void PNGAPI
1299 1300 1301 1302
png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
{
   png_ptr->read_row_fn = read_row_fn;
}
1303

1304 1305

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

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

1321
   /* png_read_info() gives us all of the information from the
1322 1323 1324
    * PNG file before the first IDAT (image data chunk).
    */
   png_read_info(png_ptr, info_ptr);
1325 1326
   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()");
1327 1328 1329 1330

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

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

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

1345
#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
1346
   /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
1347 1348 1349 1350 1351 1352 1353 1354
    * 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
1355 1356
    * (not useful if you are using png_set_packing).
    */
1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367
   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)
1368 1369 1370 1371
       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);
1372 1373
#endif

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

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

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

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

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

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

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

1453
   if(transforms == 0 || params == NULL)
1454 1455
      /* quiet compiler warnings */ return;

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