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

A
Andreas Dilger 已提交
2
/* pngread.c - read a PNG file
3
 *
4
 * libpng 1.2.6beta4 - July 28, 2004
5
 * For conditions of distribution and use, see copyright notice in png.h
6
 * Copyright (c) 1998-2004 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"

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

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

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

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

44 45
   int i;

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

56
#if !defined(PNG_1_0_X)
57 58 59
#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
   png_init_mmx_flags(png_ptr);   /* 1.2.0 addition */
#endif
60
#endif /* PNG_1_0_X */
61

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

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

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

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

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

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

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

148
   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
G
Guy Schalnat 已提交
149

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

A
Andreas Dilger 已提交
166
/* Initialize PNG structure for reading, and allocate any memory needed.
167
   This interface is deprecated in favour of the png_create_read_struct(),
A
Andreas Dilger 已提交
168
   and it will eventually disappear. */
169
#undef png_read_init
170
void PNGAPI
G
Guy Schalnat 已提交
171
png_read_init(png_structp png_ptr)
172 173
{
   /* We only come here via pre-1.0.7-compiled applications */
174
   png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
175 176
}

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

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 已提交
223
{
224
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
225
   jmp_buf tmp_jmp;  /* to save current jump buffer */
226
#endif
G
Guy Schalnat 已提交
227

228
   int i=0;
229 230 231

   png_structp png_ptr=*ptr_ptr;

232 233 234 235
   do
   {
     if(user_png_ver[i] != png_libpng_ver[i])
     {
236 237 238
#ifdef PNG_LEGACY_SUPPORTED
       png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
#else
239
       png_ptr->warning_fn=NULL;
240 241 242
       png_warning(png_ptr,
        "Application uses deprecated png_read_init() and should be recompiled.");
       break;
243
#endif
244 245 246
     }
   } while (png_libpng_ver[i++]);

247
   png_debug(1, "in png_read_init_3\n");
248 249

#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
250
   /* save jump buffer and error functions */
251
   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
252
#endif
G
Guy Schalnat 已提交
253

254
   if(png_sizeof(png_struct) > png_struct_size)
255 256 257 258 259 260
     {
       png_destroy_struct(png_ptr);
       *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
       png_ptr = *ptr_ptr;
     }

G
Guy Schalnat 已提交
261
   /* reset all variables to 0 */
262
   png_memset(png_ptr, 0, png_sizeof (png_struct));
G
Guy Schalnat 已提交
263

264
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
265
   /* restore jump buffer */
266
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
267
#endif
G
Guy Schalnat 已提交
268

G
Guy Schalnat 已提交
269
   /* initialize zbuf - compression buffer */
G
Guy Schalnat 已提交
270
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
271 272
   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
     (png_uint_32)png_ptr->zbuf_size);
A
Andreas Dilger 已提交
273 274 275
   png_ptr->zstream.zalloc = png_zalloc;
   png_ptr->zstream.zfree = png_zfree;
   png_ptr->zstream.opaque = (voidpf)png_ptr;
G
Guy Schalnat 已提交
276

A
Andreas Dilger 已提交
277
   switch (inflateInit(&png_ptr->zstream))
G
Guy Schalnat 已提交
278 279 280 281 282 283 284 285
   {
     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 已提交
286 287
   png_ptr->zstream.next_out = png_ptr->zbuf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
G
Guy Schalnat 已提交
288

289
   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
G
Guy Schalnat 已提交
290 291
}

292
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
293
/* Read the information before the actual image data.  This has been
294
 * changed in v0.90 to allow reading a file that already has the magic
A
Andreas Dilger 已提交
295
 * bytes read from the stream.  You can tell libpng how many bytes have
296
 * been read from the beginning of the stream (up to the maximum of 8)
A
Andreas Dilger 已提交
297 298 299 300
 * 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.
 */
301
void PNGAPI
A
Andreas Dilger 已提交
302
png_read_info(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
303
{
A
Andreas Dilger 已提交
304
   png_debug(1, "in png_read_info\n");
A
Andreas Dilger 已提交
305 306
   /* If we haven't checked all of the PNG signature bytes, do so now. */
   if (png_ptr->sig_bytes < 8)
G
Guy Schalnat 已提交
307
   {
A
Andreas Dilger 已提交
308 309
      png_size_t num_checked = png_ptr->sig_bytes,
                 num_to_check = 8 - num_checked;
A
Andreas Dilger 已提交
310

A
Andreas Dilger 已提交
311
      png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
A
Andreas Dilger 已提交
312 313 314 315 316 317 318 319 320 321
      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");
      }
322 323
      if (num_checked < 3)
         png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
G
Guy Schalnat 已提交
324
   }
G
Guy Schalnat 已提交
325

326
   for(;;)
G
Guy Schalnat 已提交
327
   {
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
#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
345 346 347 348 349 350
#if defined(PNG_READ_iCCP_SUPPORTED)
      PNG_iCCP;
#endif
#if defined(PNG_READ_iTXt_SUPPORTED)
      PNG_iTXt;
#endif
351 352 353 354 355 356 357 358 359 360 361 362
#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
363
#if defined(PNG_READ_sCAL_SUPPORTED)
364 365 366 367 368
      PNG_sCAL;
#endif
#if defined(PNG_READ_sPLT_SUPPORTED)
      PNG_sPLT;
#endif
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
#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
#endif /* PNG_GLOBAL_ARRAYS */
A
Andreas Dilger 已提交
385 386
      png_byte chunk_length[4];
      png_uint_32 length;
G
Guy Schalnat 已提交
387

A
Andreas Dilger 已提交
388
      png_read_data(png_ptr, chunk_length, 4);
389
      length = png_get_uint_31(png_ptr,chunk_length);
G
Guy Schalnat 已提交
390

A
Andreas Dilger 已提交
391 392 393
      png_reset_crc(png_ptr);
      png_crc_read(png_ptr, png_ptr->chunk_name, 4);

394
      png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name,
395
         length);
A
Andreas Dilger 已提交
396 397 398 399

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

A
Andreas Dilger 已提交
511
/* optional call to update the users info_ptr structure */
512
void PNGAPI
A
Andreas Dilger 已提交
513
png_read_update_info(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
514
{
A
Andreas Dilger 已提交
515
   png_debug(1, "in png_read_update_info\n");
G
Guy Schalnat 已提交
516
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
517
      png_read_start_row(png_ptr);
518 519 520
   else
      png_warning(png_ptr,
      "Ignoring extra png_read_update_info() call; row buffer not reallocated");
A
Andreas Dilger 已提交
521
   png_read_transform_info(png_ptr, info_ptr);
G
Guy Schalnat 已提交
522 523
}

524
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
525 526
/* Initialize palette, background, etc, after transformations
 * are set, but before any reading takes place.  This allows
527
 * the user to obtain a gamma-corrected palette, for example.
528 529
 * If the user doesn't call this, we will do it ourselves.
 */
530
void PNGAPI
G
Guy Schalnat 已提交
531
png_start_read_image(png_structp png_ptr)
G
Guy Schalnat 已提交
532
{
A
Andreas Dilger 已提交
533
   png_debug(1, "in png_start_read_image\n");
G
Guy Schalnat 已提交
534
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
535
      png_read_start_row(png_ptr);
G
Guy Schalnat 已提交
536
}
537
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
538

539
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
540
void PNGAPI
G
Guy Schalnat 已提交
541
png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
G
Guy Schalnat 已提交
542
{
543 544
#ifdef PNG_USE_LOCAL_ARRAYS
   PNG_IDAT;
545 546
   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};
547
#endif
G
Guy Schalnat 已提交
548
   int ret;
549
   png_debug2(1, "in png_read_row (row %lu, pass %d)\n",
A
Andreas Dilger 已提交
550
      png_ptr->row_number, png_ptr->pass);
G
Guy Schalnat 已提交
551
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
552
      png_read_start_row(png_ptr);
553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584
   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 已提交
585

G
Guy Schalnat 已提交
586
#if defined(PNG_READ_INTERLACING_SUPPORTED)
G
Guy Schalnat 已提交
587 588 589 590 591 592
   /* 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:
593
            if (png_ptr->row_number & 0x07)
G
Guy Schalnat 已提交
594
            {
A
Andreas Dilger 已提交
595
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
596 597
                  png_combine_row(png_ptr, dsp_row,
                     png_pass_dsp_mask[png_ptr->pass]);
G
Guy Schalnat 已提交
598
               png_read_finish_row(png_ptr);
G
Guy Schalnat 已提交
599 600 601 602
               return;
            }
            break;
         case 1:
603
            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
G
Guy Schalnat 已提交
604
            {
A
Andreas Dilger 已提交
605
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
606 607 608 609 610 611 612
                  png_combine_row(png_ptr, dsp_row,
                     png_pass_dsp_mask[png_ptr->pass]);
               png_read_finish_row(png_ptr);
               return;
            }
            break;
         case 2:
613
            if ((png_ptr->row_number & 0x07) != 4)
G
Guy Schalnat 已提交
614
            {
A
Andreas Dilger 已提交
615
               if (dsp_row != NULL && (png_ptr->row_number & 4))
G
Guy Schalnat 已提交
616
                  png_combine_row(png_ptr, dsp_row,
G
Guy Schalnat 已提交
617 618 619 620 621 622 623 624
                     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 已提交
625
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
626 627 628 629 630 631 632 633
                  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 已提交
634
            {
A
Andreas Dilger 已提交
635
               if (dsp_row != NULL && (png_ptr->row_number & 2))
G
Guy Schalnat 已提交
636 637 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 5:
            if ((png_ptr->row_number & 1) || png_ptr->width < 2)
            {
A
Andreas Dilger 已提交
645
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
646 647 648 649 650 651
                  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 已提交
652
         case 6:
G
Guy Schalnat 已提交
653 654 655 656 657 658 659 660
            if (!(png_ptr->row_number & 1))
            {
               png_read_finish_row(png_ptr);
               return;
            }
            break;
      }
   }
G
Guy Schalnat 已提交
661
#endif
G
Guy Schalnat 已提交
662

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

A
Andreas Dilger 已提交
666 667
   png_ptr->zstream.next_out = png_ptr->row_buf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
G
Guy Schalnat 已提交
668 669
   do
   {
A
Andreas Dilger 已提交
670
      if (!(png_ptr->zstream.avail_in))
G
Guy Schalnat 已提交
671 672 673
      {
         while (!png_ptr->idat_size)
         {
A
Andreas Dilger 已提交
674
            png_byte chunk_length[4];
G
Guy Schalnat 已提交
675

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

A
Andreas Dilger 已提交
678
            png_read_data(png_ptr, chunk_length, 4);
679
            png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length);
680

A
Andreas Dilger 已提交
681 682 683 684
            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 已提交
685
         }
A
Andreas Dilger 已提交
686 687
         png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
         png_ptr->zstream.next_in = png_ptr->zbuf;
G
Guy Schalnat 已提交
688
         if (png_ptr->zbuf_size > png_ptr->idat_size)
A
Andreas Dilger 已提交
689
            png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
A
Andreas Dilger 已提交
690 691
         png_crc_read(png_ptr, png_ptr->zbuf,
            (png_size_t)png_ptr->zstream.avail_in);
A
Andreas Dilger 已提交
692
         png_ptr->idat_size -= png_ptr->zstream.avail_in;
G
Guy Schalnat 已提交
693
      }
A
Andreas Dilger 已提交
694
      ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
G
Guy Schalnat 已提交
695 696
      if (ret == Z_STREAM_END)
      {
A
Andreas Dilger 已提交
697
         if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
G
Guy Schalnat 已提交
698
            png_ptr->idat_size)
G
Guy Schalnat 已提交
699
            png_error(png_ptr, "Extra compressed data");
A
Andreas Dilger 已提交
700
         png_ptr->mode |= PNG_AFTER_IDAT;
G
Guy Schalnat 已提交
701
         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
G
Guy Schalnat 已提交
702
         break;
G
Guy Schalnat 已提交
703 704
      }
      if (ret != Z_OK)
A
Andreas Dilger 已提交
705
         png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
G
Guy Schalnat 已提交
706
                   "Decompression error");
A
Andreas Dilger 已提交
707 708

   } while (png_ptr->zstream.avail_out);
G
Guy Schalnat 已提交
709 710 711 712 713 714

   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;
715 716
   png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
      (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
G
Guy Schalnat 已提交
717

718
   if(png_ptr->row_buf[0])
G
Guy Schalnat 已提交
719 720 721
   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 已提交
722

723
   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
724
      png_ptr->rowbytes + 1);
725 726 727 728 729 730 731 732 733
   
#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 已提交
734 735 736 737

   if (png_ptr->transformations)
      png_do_read_transformations(png_ptr);

G
Guy Schalnat 已提交
738
#if defined(PNG_READ_INTERLACING_SUPPORTED)
G
Guy Schalnat 已提交
739 740 741 742 743
   /* blow up interlaced rows to full size */
   if (png_ptr->interlaced &&
      (png_ptr->transformations & PNG_INTERLACE))
   {
      if (png_ptr->pass < 6)
744
/*       old interface (pre-1.0.9):
G
Guy Schalnat 已提交
745
         png_do_read_interlace(&(png_ptr->row_info),
A
Andreas Dilger 已提交
746
            png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
747 748
 */
         png_do_read_interlace(png_ptr);
G
Guy Schalnat 已提交
749

A
Andreas Dilger 已提交
750
      if (dsp_row != NULL)
G
Guy Schalnat 已提交
751 752
         png_combine_row(png_ptr, dsp_row,
            png_pass_dsp_mask[png_ptr->pass]);
A
Andreas Dilger 已提交
753
      if (row != NULL)
G
Guy Schalnat 已提交
754 755 756 757
         png_combine_row(png_ptr, row,
            png_pass_mask[png_ptr->pass]);
   }
   else
G
Guy Schalnat 已提交
758
#endif
G
Guy Schalnat 已提交
759
   {
A
Andreas Dilger 已提交
760
      if (row != NULL)
G
Guy Schalnat 已提交
761
         png_combine_row(png_ptr, row, 0xff);
A
Andreas Dilger 已提交
762
      if (dsp_row != NULL)
G
Guy Schalnat 已提交
763 764 765
         png_combine_row(png_ptr, dsp_row, 0xff);
   }
   png_read_finish_row(png_ptr);
766 767 768

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

772
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
773
/* Read one or more rows of image data.  If the image is interlaced,
774 775
 * and png_set_interlace_handling() has been called, the rows need to
 * contain the contents of the rows from the previous pass.  If the
776
 * image has alpha or transparency, and png_handle_alpha()[*] has been
777 778
 * called, the rows contents must be initialized to the contents of the
 * screen.
779
 *
780 781 782 783 784 785 786 787 788 789 790 791 792
 * "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.
793
 *
794
 * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.6beta4
795
 */
G
Guy Schalnat 已提交
796

797
void PNGAPI
G
Guy Schalnat 已提交
798
png_read_rows(png_structp png_ptr, png_bytepp row,
G
Guy Schalnat 已提交
799
   png_bytepp display_row, png_uint_32 num_rows)
G
Guy Schalnat 已提交
800
{
G
Guy Schalnat 已提交
801 802 803
   png_uint_32 i;
   png_bytepp rp;
   png_bytepp dp;
G
Guy Schalnat 已提交
804

A
Andreas Dilger 已提交
805
   png_debug(1, "in png_read_rows\n");
G
Guy Schalnat 已提交
806 807
   rp = row;
   dp = display_row;
808
   if (rp != NULL && dp != NULL)
809 810 811 812
      for (i = 0; i < num_rows; i++)
      {
         png_bytep rptr = *rp++;
         png_bytep dptr = *dp++;
813

814 815
         png_read_row(png_ptr, rptr, dptr);
      }
816
   else if(rp != NULL)
817 818
      for (i = 0; i < num_rows; i++)
      {
819
         png_bytep rptr = *rp;
820
         png_read_row(png_ptr, rptr, png_bytep_NULL);
821 822 823 824 825 826
         rp++;
      }
   else if(dp != NULL)
      for (i = 0; i < num_rows; i++)
      {
         png_bytep dptr = *dp;
827
         png_read_row(png_ptr, png_bytep_NULL, dptr);
828
         dp++;
829
      }
G
Guy Schalnat 已提交
830
}
831
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
832

833
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
834
/* Read the entire image.  If the image has an alpha channel or a tRNS
835
 * chunk, and you have called png_handle_alpha()[*], you will need to
836 837 838 839 840 841 842
 * 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.
843
 *
844
 * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.6beta4
845
 */
846
void PNGAPI
G
Guy Schalnat 已提交
847
png_read_image(png_structp png_ptr, png_bytepp image)
G
Guy Schalnat 已提交
848
{
849
   png_uint_32 i,image_height;
G
Guy Schalnat 已提交
850
   int pass, j;
G
Guy Schalnat 已提交
851
   png_bytepp rp;
G
Guy Schalnat 已提交
852

A
Andreas Dilger 已提交
853
   png_debug(1, "in png_read_image\n");
854 855

#ifdef PNG_READ_INTERLACING_SUPPORTED
G
Guy Schalnat 已提交
856
   pass = png_set_interlace_handling(png_ptr);
857 858 859 860 861 862 863
#else
   if (png_ptr->interlaced)
      png_error(png_ptr,
        "Cannot read interlaced image -- interlace handler disabled.");
   pass = 1;
#endif

G
Guy Schalnat 已提交
864

865 866
   image_height=png_ptr->height;
   png_ptr->num_rows = image_height; /* Make sure this is set correctly */
G
Guy Schalnat 已提交
867

G
Guy Schalnat 已提交
868 869 870
   for (j = 0; j < pass; j++)
   {
      rp = image;
871
      for (i = 0; i < image_height; i++)
G
Guy Schalnat 已提交
872
      {
873
         png_read_row(png_ptr, *rp, png_bytep_NULL);
G
Guy Schalnat 已提交
874 875 876 877
         rp++;
      }
   }
}
878
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
879

880
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
881
/* Read the end of the PNG file.  Will not read past the end of the
882 883 884
 * 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.
 */
885
void PNGAPI
A
Andreas Dilger 已提交
886
png_read_end(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
887
{
A
Andreas Dilger 已提交
888
   png_byte chunk_length[4];
G
Guy Schalnat 已提交
889 890
   png_uint_32 length;

A
Andreas Dilger 已提交
891 892
   png_debug(1, "in png_read_end\n");
   png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
G
Guy Schalnat 已提交
893 894 895

   do
   {
896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912
#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
913 914 915 916 917 918
#if defined(PNG_READ_iCCP_SUPPORTED)
      PNG_iCCP;
#endif
#if defined(PNG_READ_iTXt_SUPPORTED)
      PNG_iTXt;
#endif
919 920 921 922 923 924 925 926 927 928 929 930
#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
931
#if defined(PNG_READ_sCAL_SUPPORTED)
932 933 934 935 936
      PNG_sCAL;
#endif
#if defined(PNG_READ_sPLT_SUPPORTED)
      PNG_sPLT;
#endif
937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953
#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
#endif /* PNG_GLOBAL_ARRAYS */

A
Andreas Dilger 已提交
954
      png_read_data(png_ptr, chunk_length, 4);
955
      length = png_get_uint_31(png_ptr,chunk_length);
G
Guy Schalnat 已提交
956

A
Andreas Dilger 已提交
957 958 959
      png_reset_crc(png_ptr);
      png_crc_read(png_ptr, png_ptr->chunk_name, 4);

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

A
Andreas Dilger 已提交
962 963
      if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
         png_handle_IHDR(png_ptr, info_ptr, length);
964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980
      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 已提交
981 982 983 984 985 986 987
      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");
988
         png_crc_finish(png_ptr, length);
A
Andreas Dilger 已提交
989
      }
A
Andreas Dilger 已提交
990 991
      else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
         png_handle_PLTE(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
992
#if defined(PNG_READ_bKGD_SUPPORTED)
A
Andreas Dilger 已提交
993 994
      else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
         png_handle_bKGD(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
995 996 997 998 999 1000 1001 1002 1003 1004
#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 已提交
1005 1006
      else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
         png_handle_hIST(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
1007 1008
#endif
#if defined(PNG_READ_oFFs_SUPPORTED)
A
Andreas Dilger 已提交
1009 1010
      else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
         png_handle_oFFs(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
1011 1012 1013 1014 1015
#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
1016 1017 1018 1019
#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 已提交
1020 1021 1022 1023 1024 1025 1026
#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 已提交
1027
#endif
1028 1029 1030 1031
#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
1032 1033 1034 1035 1036 1037 1038 1039
#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 已提交
1040
#if defined(PNG_READ_tEXt_SUPPORTED)
A
Andreas Dilger 已提交
1041 1042
      else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
         png_handle_tEXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
1043
#endif
A
Andreas Dilger 已提交
1044 1045 1046 1047 1048 1049 1050 1051
#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 已提交
1052
#if defined(PNG_READ_zTXt_SUPPORTED)
A
Andreas Dilger 已提交
1053 1054
      else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
         png_handle_zTXt(png_ptr, info_ptr, length);
1055 1056 1057 1058
#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 已提交
1059
#endif
G
Guy Schalnat 已提交
1060
      else
A
Andreas Dilger 已提交
1061 1062
         png_handle_unknown(png_ptr, info_ptr, length);
   } while (!(png_ptr->mode & PNG_HAVE_IEND));
G
Guy Schalnat 已提交
1063
}
1064
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
1065 1066

/* free all memory used by the read */
1067
void PNGAPI
G
Guy Schalnat 已提交
1068
png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
A
Andreas Dilger 已提交
1069
   png_infopp end_info_ptr_ptr)
G
Guy Schalnat 已提交
1070 1071
{
   png_structp png_ptr = NULL;
A
Andreas Dilger 已提交
1072
   png_infop info_ptr = NULL, end_info_ptr = NULL;
1073 1074
#ifdef PNG_USER_MEM_SUPPORTED
   png_free_ptr free_fn = NULL;
1075
   png_voidp mem_ptr = NULL;
1076
#endif
G
Guy Schalnat 已提交
1077

A
Andreas Dilger 已提交
1078 1079
   png_debug(1, "in png_destroy_read_struct\n");
   if (png_ptr_ptr != NULL)
G
Guy Schalnat 已提交
1080 1081
      png_ptr = *png_ptr_ptr;

A
Andreas Dilger 已提交
1082
   if (info_ptr_ptr != NULL)
G
Guy Schalnat 已提交
1083 1084
      info_ptr = *info_ptr_ptr;

A
Andreas Dilger 已提交
1085
   if (end_info_ptr_ptr != NULL)
A
Andreas Dilger 已提交
1086
      end_info_ptr = *end_info_ptr_ptr;
G
Guy Schalnat 已提交
1087

1088 1089
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
1090
   mem_ptr = png_ptr->mem_ptr;
1091 1092
#endif

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

A
Andreas Dilger 已提交
1095
   if (info_ptr != NULL)
G
Guy Schalnat 已提交
1096
   {
1097
#if defined(PNG_TEXT_SUPPORTED)
1098
      png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
1099
#endif
1100 1101

#ifdef PNG_USER_MEM_SUPPORTED
1102 1103
      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
          (png_voidp)mem_ptr);
1104
#else
A
Andreas Dilger 已提交
1105
      png_destroy_struct((png_voidp)info_ptr);
1106
#endif
1107
      *info_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1108 1109
   }

A
Andreas Dilger 已提交
1110
   if (end_info_ptr != NULL)
G
Guy Schalnat 已提交
1111
   {
1112
#if defined(PNG_READ_TEXT_SUPPORTED)
1113
      png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
1114
#endif
1115
#ifdef PNG_USER_MEM_SUPPORTED
1116 1117
      png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
         (png_voidp)mem_ptr);
1118
#else
A
Andreas Dilger 已提交
1119
      png_destroy_struct((png_voidp)end_info_ptr);
1120
#endif
1121
      *end_info_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1122 1123
   }

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

A
Andreas Dilger 已提交
1136
/* free all memory used by the read (old method) */
1137
void /* PRIVATE */
A
Andreas Dilger 已提交
1138
png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
G
Guy Schalnat 已提交
1139
{
1140
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
1141
   jmp_buf tmp_jmp;
1142
#endif
G
Guy Schalnat 已提交
1143 1144 1145
   png_error_ptr error_fn;
   png_error_ptr warning_fn;
   png_voidp error_ptr;
1146 1147 1148
#ifdef PNG_USER_MEM_SUPPORTED
   png_free_ptr free_fn;
#endif
G
Guy Schalnat 已提交
1149

A
Andreas Dilger 已提交
1150 1151
   png_debug(1, "in png_read_destroy\n");
   if (info_ptr != NULL)
A
Andreas Dilger 已提交
1152
      png_info_destroy(png_ptr, info_ptr);
G
Guy Schalnat 已提交
1153

A
Andreas Dilger 已提交
1154
   if (end_info_ptr != NULL)
A
Andreas Dilger 已提交
1155
      png_info_destroy(png_ptr, end_info_ptr);
G
Guy Schalnat 已提交
1156

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

A
Andreas Dilger 已提交
1241
   inflateEnd(&png_ptr->zstream);
G
Guy Schalnat 已提交
1242
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
A
Andreas Dilger 已提交
1243
   png_free(png_ptr, png_ptr->save_buffer);
G
Guy Schalnat 已提交
1244
#endif
G
Guy Schalnat 已提交
1245

1246 1247 1248 1249 1250 1251
#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 已提交
1252 1253 1254
   /* Save the important info out of the png_struct, in case it is
    * being used again.
    */
1255
#ifdef PNG_SETJMP_SUPPORTED
1256
   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
1257
#endif
G
Guy Schalnat 已提交
1258 1259 1260 1261

   error_fn = png_ptr->error_fn;
   warning_fn = png_ptr->warning_fn;
   error_ptr = png_ptr->error_ptr;
1262 1263 1264
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
#endif
G
Guy Schalnat 已提交
1265

1266
   png_memset(png_ptr, 0, png_sizeof (png_struct));
G
Guy Schalnat 已提交
1267 1268 1269 1270

   png_ptr->error_fn = error_fn;
   png_ptr->warning_fn = warning_fn;
   png_ptr->error_ptr = error_ptr;
1271 1272 1273
#ifdef PNG_USER_MEM_SUPPORTED
   png_ptr->free_fn = free_fn;
#endif
G
Guy Schalnat 已提交
1274

1275
#ifdef PNG_SETJMP_SUPPORTED
1276
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
1277 1278
#endif

G
Guy Schalnat 已提交
1279
}
1280

1281
void PNGAPI
1282 1283 1284 1285
png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
{
   png_ptr->read_row_fn = read_row_fn;
}
1286

1287 1288

#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
1289
#if defined(PNG_INFO_IMAGE_SUPPORTED)
1290 1291
void PNGAPI
png_read_png(png_structp png_ptr, png_infop info_ptr,
1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323
                           int transforms,
                           voidp params)
{
   int row;

#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
   /* invert the alpha channel from opacity to transparency */
   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
       png_set_invert_alpha(png_ptr);
#endif

   /* The call to png_read_info() gives us all of the information from the
    * PNG file before the first IDAT (image data chunk).
    */
   png_read_info(png_ptr, info_ptr);

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

#if defined(PNG_READ_16_TO_8_SUPPORTED)
   /* tell libpng to strip 16 bit/color files down to 8 bits/color */
   if (transforms & PNG_TRANSFORM_STRIP_16)
       png_set_strip_16(png_ptr);
#endif

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

1324
#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345
   /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
    * 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
    * (not useful if you are using png_set_packing). */
   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)
1346 1347 1348 1349
       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);
1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396
#endif

   /* We don't handle background color or gamma transformation or dithering. */

#if defined(PNG_READ_INVERT_SUPPORTED)
   /* invert monochrome files to have 0 as white and 1 as black */
   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)
   /* flip the RGB pixels to BGR (or RGBA to BGRA) */
   if (transforms & PNG_TRANSFORM_BGR)
       png_set_bgr(png_ptr);
#endif

#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
   /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
       png_set_swap_alpha(png_ptr);
#endif

#if defined(PNG_READ_SWAP_SUPPORTED)
   /* swap bytes of 16 bit files to least significant byte first */
   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
1397
    * update the palette for you (i.e., you selected such a transform above).
1398 1399 1400 1401 1402
    */
   png_read_update_info(png_ptr, info_ptr);

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

1403
#ifdef PNG_FREE_ME_SUPPORTED
1404
   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1405
#endif
1406 1407 1408
   if(info_ptr->row_pointers == NULL)
   {
      info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
1409
         info_ptr->height * png_sizeof(png_bytep));
1410
#ifdef PNG_FREE_ME_SUPPORTED
1411
      info_ptr->free_me |= PNG_FREE_ROWS;
1412 1413
#endif
      for (row = 0; row < (int)info_ptr->height; row++)
1414 1415
      {
         info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
1416
            png_get_rowbytes(png_ptr, info_ptr));
1417
      }
1418
   }
1419 1420 1421 1422 1423 1424

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

1426
   if(transforms == 0 || params == NULL)
1427 1428
      /* quiet compiler warnings */ return;

1429 1430
}
#endif
1431
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */