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

A
Andreas Dilger 已提交
2
/* pngread.c - read a PNG file
3
 *
4
 * libpng 1.2.2beta1 - February 22, 2002
5
 * For conditions of distribution and use, see copyright notice in png.h
6
 * Copyright (c) 1998-2001 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 57 58 59
#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
   png_init_mmx_flags(png_ptr);   /* 1.2.0 addition */
#endif

60
#ifdef PNG_SETJMP_SUPPORTED
A
Andreas Dilger 已提交
61 62 63
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmpbuf))
#else
G
Guy Schalnat 已提交
64
   if (setjmp(png_ptr->jmpbuf))
A
Andreas Dilger 已提交
65
#endif
G
Guy Schalnat 已提交
66
   {
A
Andreas Dilger 已提交
67
      png_free(png_ptr, png_ptr->zbuf);
68
      png_ptr->zbuf=NULL;
G
Guy Schalnat 已提交
69
      png_destroy_struct(png_ptr);
70
      return (NULL);
G
Guy Schalnat 已提交
71
   }
A
Andreas Dilger 已提交
72 73 74
#ifdef USE_FAR_KEYWORD
   png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
#endif
75
#endif
76 77 78

#ifdef PNG_USER_MEM_SUPPORTED
   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
79
#endif
80

A
Andreas Dilger 已提交
81 82
   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);

83 84
   i=0;
   do
G
Guy Schalnat 已提交
85
   {
86 87 88
     if(user_png_ver[i] != png_libpng_ver[i])
        png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
   } while (png_libpng_ver[i++]);
89

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

G
Guy Schalnat 已提交
121 122
   /* initialize zbuf - compression buffer */
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
123 124
   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
     (png_uint_32)png_ptr->zbuf_size);
A
Andreas Dilger 已提交
125 126 127
   png_ptr->zstream.zalloc = png_zalloc;
   png_ptr->zstream.zfree = png_zfree;
   png_ptr->zstream.opaque = (voidpf)png_ptr;
G
Guy Schalnat 已提交
128

A
Andreas Dilger 已提交
129
   switch (inflateInit(&png_ptr->zstream))
G
Guy Schalnat 已提交
130 131 132 133 134 135 136 137
   {
     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 已提交
138 139
   png_ptr->zstream.next_out = png_ptr->zbuf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
G
Guy Schalnat 已提交
140

141
   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
G
Guy Schalnat 已提交
142 143 144 145

   return (png_ptr);
}

A
Andreas Dilger 已提交
146
/* Initialize PNG structure for reading, and allocate any memory needed.
147
   This interface is deprecated in favour of the png_create_read_struct(),
A
Andreas Dilger 已提交
148
   and it will eventually disappear. */
149
#undef png_read_init
150
void PNGAPI
G
Guy Schalnat 已提交
151
png_read_init(png_structp png_ptr)
152 153
{
   /* We only come here via pre-1.0.7-compiled applications */
154
   png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
155 156
}

157
#undef png_read_init_2
158
void PNGAPI
159 160
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)
161 162
{
   /* We only come here via pre-1.0.12-compiled applications */
163 164 165 166
#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
   if(sizeof(png_struct) > png_struct_size || sizeof(png_info) > png_info_size)
   {
      char msg[80];
167
      png_ptr->warning_fn=NULL;
168 169 170 171 172 173
      if (user_png_ver)
      {
        sprintf(msg, "Application was compiled with png.h from libpng-%.20s",
           user_png_ver);
        png_warning(png_ptr, msg);
      }
174
      sprintf(msg, "Application  is  running with png.c from libpng-%.20s",
175 176 177 178
         png_libpng_ver);
      png_warning(png_ptr, msg);
   }
#endif
179 180
   if(sizeof(png_struct) > png_struct_size)
     {
181
       png_ptr->error_fn=NULL;
182 183 184
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
       png_ptr->flags=0;
#endif
185 186 187 188 189
       png_error(png_ptr,
       "The png struct allocated by the application for reading is too small.");
     }
   if(sizeof(png_info) > png_info_size)
     {
190
       png_ptr->error_fn=NULL;
191 192 193
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
       png_ptr->flags=0;
#endif
194 195 196 197 198 199 200 201 202
       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 已提交
203
{
204
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
205
   jmp_buf tmp_jmp;  /* to save current jump buffer */
206
#endif
G
Guy Schalnat 已提交
207

208
   int i=0;
209 210 211

   png_structp png_ptr=*ptr_ptr;

212 213 214 215
   do
   {
     if(user_png_ver[i] != png_libpng_ver[i])
     {
216 217 218
#ifdef PNG_LEGACY_SUPPORTED
       png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
#else
219
       png_ptr->warning_fn=NULL;
220 221 222
       png_warning(png_ptr,
        "Application uses deprecated png_read_init() and should be recompiled.");
       break;
223
#endif
224 225 226
     }
   } while (png_libpng_ver[i++]);

227
   png_debug(1, "in png_read_init_3\n");
228 229

#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
230
   /* save jump buffer and error functions */
G
Guy Schalnat 已提交
231
   png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
232
#endif
G
Guy Schalnat 已提交
233

234 235 236 237 238 239 240
   if(sizeof(png_struct) > png_struct_size)
     {
       png_destroy_struct(png_ptr);
       *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
       png_ptr = *ptr_ptr;
     }

G
Guy Schalnat 已提交
241
   /* reset all variables to 0 */
G
Guy Schalnat 已提交
242
   png_memset(png_ptr, 0, sizeof (png_struct));
G
Guy Schalnat 已提交
243

244
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
245
   /* restore jump buffer */
G
Guy Schalnat 已提交
246
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
247
#endif
G
Guy Schalnat 已提交
248

G
Guy Schalnat 已提交
249
   /* initialize zbuf - compression buffer */
G
Guy Schalnat 已提交
250
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
251 252
   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
     (png_uint_32)png_ptr->zbuf_size);
A
Andreas Dilger 已提交
253 254 255
   png_ptr->zstream.zalloc = png_zalloc;
   png_ptr->zstream.zfree = png_zfree;
   png_ptr->zstream.opaque = (voidpf)png_ptr;
G
Guy Schalnat 已提交
256

A
Andreas Dilger 已提交
257
   switch (inflateInit(&png_ptr->zstream))
G
Guy Schalnat 已提交
258 259 260 261 262 263 264 265
   {
     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 已提交
266 267
   png_ptr->zstream.next_out = png_ptr->zbuf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
G
Guy Schalnat 已提交
268

269
   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
G
Guy Schalnat 已提交
270 271
}

A
Andreas Dilger 已提交
272
/* Read the information before the actual image data.  This has been
273
 * changed in v0.90 to allow reading a file that already has the magic
A
Andreas Dilger 已提交
274
 * bytes read from the stream.  You can tell libpng how many bytes have
275
 * been read from the beginning of the stream (up to the maximum of 8)
A
Andreas Dilger 已提交
276 277 278 279
 * 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.
 */
280
void PNGAPI
A
Andreas Dilger 已提交
281
png_read_info(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
282
{
A
Andreas Dilger 已提交
283 284
   png_debug(1, "in png_read_info\n");
   /* save jump buffer and error functions */
A
Andreas Dilger 已提交
285 286
   /* If we haven't checked all of the PNG signature bytes, do so now. */
   if (png_ptr->sig_bytes < 8)
G
Guy Schalnat 已提交
287
   {
A
Andreas Dilger 已提交
288 289
      png_size_t num_checked = png_ptr->sig_bytes,
                 num_to_check = 8 - num_checked;
A
Andreas Dilger 已提交
290

A
Andreas Dilger 已提交
291
      png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
A
Andreas Dilger 已提交
292 293 294 295 296 297 298 299 300 301
      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");
      }
302 303
      if (num_checked < 3)
         png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
G
Guy Schalnat 已提交
304
   }
G
Guy Schalnat 已提交
305

306
   for(;;)
G
Guy Schalnat 已提交
307
   {
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
#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
325 326 327 328 329 330
#if defined(PNG_READ_iCCP_SUPPORTED)
      PNG_iCCP;
#endif
#if defined(PNG_READ_iTXt_SUPPORTED)
      PNG_iTXt;
#endif
331 332 333 334 335 336 337 338 339 340 341 342
#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
343
#if defined(PNG_READ_sCAL_SUPPORTED)
344 345 346 347 348
      PNG_sCAL;
#endif
#if defined(PNG_READ_sPLT_SUPPORTED)
      PNG_sPLT;
#endif
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
#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 已提交
365 366
      png_byte chunk_length[4];
      png_uint_32 length;
G
Guy Schalnat 已提交
367

A
Andreas Dilger 已提交
368 369
      png_read_data(png_ptr, chunk_length, 4);
      length = png_get_uint_32(chunk_length);
G
Guy Schalnat 已提交
370

A
Andreas Dilger 已提交
371 372 373
      png_reset_crc(png_ptr);
      png_crc_read(png_ptr, png_ptr->chunk_name, 4);

374
      png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name,
375
         length);
A
Andreas Dilger 已提交
376 377 378 379

      /* This should be a binary subdivision search or a hash for
       * matching the chunk name rather than a linear search.
       */
A
Andreas Dilger 已提交
380 381 382 383
      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);
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404
#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 已提交
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
      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 已提交
420 421
#endif
#if defined(PNG_READ_cHRM_SUPPORTED)
A
Andreas Dilger 已提交
422 423
      else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
         png_handle_cHRM(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
424
#endif
A
Andreas Dilger 已提交
425 426 427
#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 已提交
428 429
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
A
Andreas Dilger 已提交
430 431
      else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
         png_handle_hIST(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
432
#endif
A
Andreas Dilger 已提交
433 434 435 436 437 438 439 440
#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
441 442 443 444
#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 已提交
445
#if defined(PNG_READ_pHYs_SUPPORTED)
A
Andreas Dilger 已提交
446 447
      else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
         png_handle_pHYs(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
448
#endif
A
Andreas Dilger 已提交
449 450 451 452
#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
453 454 455 456
#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
457 458 459 460 461 462 463 464
#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 已提交
465 466 467
#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 已提交
468 469
#endif
#if defined(PNG_READ_tIME_SUPPORTED)
A
Andreas Dilger 已提交
470 471
      else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
         png_handle_tIME(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
472
#endif
A
Andreas Dilger 已提交
473 474 475
#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 已提交
476 477
#endif
#if defined(PNG_READ_zTXt_SUPPORTED)
A
Andreas Dilger 已提交
478 479
      else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
         png_handle_zTXt(png_ptr, info_ptr, length);
480 481 482 483
#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 已提交
484
#endif
A
Andreas Dilger 已提交
485 486
      else
         png_handle_unknown(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
487 488 489
   }
}

A
Andreas Dilger 已提交
490
/* optional call to update the users info_ptr structure */
491
void PNGAPI
A
Andreas Dilger 已提交
492
png_read_update_info(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
493
{
A
Andreas Dilger 已提交
494 495
   png_debug(1, "in png_read_update_info\n");
   /* save jump buffer and error functions */
G
Guy Schalnat 已提交
496
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
497
      png_read_start_row(png_ptr);
498 499 500
   else
      png_warning(png_ptr,
      "Ignoring extra png_read_update_info() call; row buffer not reallocated");
A
Andreas Dilger 已提交
501
   png_read_transform_info(png_ptr, info_ptr);
G
Guy Schalnat 已提交
502 503
}

504 505
/* Initialize palette, background, etc, after transformations
 * are set, but before any reading takes place.  This allows
506
 * the user to obtain a gamma-corrected palette, for example.
507 508
 * If the user doesn't call this, we will do it ourselves.
 */
509
void PNGAPI
G
Guy Schalnat 已提交
510
png_start_read_image(png_structp png_ptr)
G
Guy Schalnat 已提交
511
{
A
Andreas Dilger 已提交
512 513
   png_debug(1, "in png_start_read_image\n");
   /* save jump buffer and error functions */
G
Guy Schalnat 已提交
514
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
515
      png_read_start_row(png_ptr);
G
Guy Schalnat 已提交
516 517
}

518
void PNGAPI
G
Guy Schalnat 已提交
519
png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
G
Guy Schalnat 已提交
520
{
521 522
#ifdef PNG_USE_LOCAL_ARRAYS
   PNG_IDAT;
523 524
   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};
525
#endif
G
Guy Schalnat 已提交
526
   int ret;
527
   png_debug2(1, "in png_read_row (row %lu, pass %d)\n",
A
Andreas Dilger 已提交
528 529
      png_ptr->row_number, png_ptr->pass);
   /* save jump buffer and error functions */
G
Guy Schalnat 已提交
530
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
531
      png_read_start_row(png_ptr);
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
   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 已提交
564

G
Guy Schalnat 已提交
565
#if defined(PNG_READ_INTERLACING_SUPPORTED)
G
Guy Schalnat 已提交
566 567 568 569 570 571
   /* 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:
572
            if (png_ptr->row_number & 0x07)
G
Guy Schalnat 已提交
573
            {
A
Andreas Dilger 已提交
574
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
575 576
                  png_combine_row(png_ptr, dsp_row,
                     png_pass_dsp_mask[png_ptr->pass]);
G
Guy Schalnat 已提交
577
               png_read_finish_row(png_ptr);
G
Guy Schalnat 已提交
578 579 580 581
               return;
            }
            break;
         case 1:
582
            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
G
Guy Schalnat 已提交
583
            {
A
Andreas Dilger 已提交
584
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
585 586 587 588 589 590 591
                  png_combine_row(png_ptr, dsp_row,
                     png_pass_dsp_mask[png_ptr->pass]);
               png_read_finish_row(png_ptr);
               return;
            }
            break;
         case 2:
592
            if ((png_ptr->row_number & 0x07) != 4)
G
Guy Schalnat 已提交
593
            {
A
Andreas Dilger 已提交
594
               if (dsp_row != NULL && (png_ptr->row_number & 4))
G
Guy Schalnat 已提交
595
                  png_combine_row(png_ptr, dsp_row,
G
Guy Schalnat 已提交
596 597 598 599 600 601 602 603
                     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 已提交
604
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
605 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 4:
            if ((png_ptr->row_number & 3) != 2)
G
Guy Schalnat 已提交
613
            {
A
Andreas Dilger 已提交
614
               if (dsp_row != NULL && (png_ptr->row_number & 2))
G
Guy Schalnat 已提交
615 616 617 618 619 620 621 622 623
                  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 已提交
624
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
625 626 627 628 629 630
                  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 已提交
631
         case 6:
G
Guy Schalnat 已提交
632 633 634 635 636 637 638 639
            if (!(png_ptr->row_number & 1))
            {
               png_read_finish_row(png_ptr);
               return;
            }
            break;
      }
   }
G
Guy Schalnat 已提交
640
#endif
G
Guy Schalnat 已提交
641

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

A
Andreas Dilger 已提交
645 646
   png_ptr->zstream.next_out = png_ptr->row_buf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
G
Guy Schalnat 已提交
647 648
   do
   {
A
Andreas Dilger 已提交
649
      if (!(png_ptr->zstream.avail_in))
G
Guy Schalnat 已提交
650 651 652
      {
         while (!png_ptr->idat_size)
         {
A
Andreas Dilger 已提交
653
            png_byte chunk_length[4];
G
Guy Schalnat 已提交
654

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

A
Andreas Dilger 已提交
657 658
            png_read_data(png_ptr, chunk_length, 4);
            png_ptr->idat_size = png_get_uint_32(chunk_length);
G
Guy Schalnat 已提交
659

A
Andreas Dilger 已提交
660 661 662 663
            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 已提交
664
         }
A
Andreas Dilger 已提交
665 666
         png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
         png_ptr->zstream.next_in = png_ptr->zbuf;
G
Guy Schalnat 已提交
667
         if (png_ptr->zbuf_size > png_ptr->idat_size)
A
Andreas Dilger 已提交
668
            png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
A
Andreas Dilger 已提交
669 670
         png_crc_read(png_ptr, png_ptr->zbuf,
            (png_size_t)png_ptr->zstream.avail_in);
A
Andreas Dilger 已提交
671
         png_ptr->idat_size -= png_ptr->zstream.avail_in;
G
Guy Schalnat 已提交
672
      }
A
Andreas Dilger 已提交
673
      ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
G
Guy Schalnat 已提交
674 675
      if (ret == Z_STREAM_END)
      {
A
Andreas Dilger 已提交
676
         if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
G
Guy Schalnat 已提交
677
            png_ptr->idat_size)
G
Guy Schalnat 已提交
678
            png_error(png_ptr, "Extra compressed data");
A
Andreas Dilger 已提交
679
         png_ptr->mode |= PNG_AFTER_IDAT;
G
Guy Schalnat 已提交
680
         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
G
Guy Schalnat 已提交
681
         break;
G
Guy Schalnat 已提交
682 683
      }
      if (ret != Z_OK)
A
Andreas Dilger 已提交
684
         png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
G
Guy Schalnat 已提交
685
                   "Decompression error");
A
Andreas Dilger 已提交
686 687

   } while (png_ptr->zstream.avail_out);
G
Guy Schalnat 已提交
688 689 690 691 692 693

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

697
   if(png_ptr->row_buf[0])
G
Guy Schalnat 已提交
698 699 700
   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 已提交
701

702
   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
703
      png_ptr->rowbytes + 1);
704 705 706 707 708 709 710 711 712
   
#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 已提交
713 714 715 716

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

G
Guy Schalnat 已提交
717
#if defined(PNG_READ_INTERLACING_SUPPORTED)
G
Guy Schalnat 已提交
718 719 720 721 722
   /* blow up interlaced rows to full size */
   if (png_ptr->interlaced &&
      (png_ptr->transformations & PNG_INTERLACE))
   {
      if (png_ptr->pass < 6)
723
/*       old interface (pre-1.0.9):
G
Guy Schalnat 已提交
724
         png_do_read_interlace(&(png_ptr->row_info),
A
Andreas Dilger 已提交
725
            png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
726 727
 */
         png_do_read_interlace(png_ptr);
G
Guy Schalnat 已提交
728

A
Andreas Dilger 已提交
729
      if (dsp_row != NULL)
G
Guy Schalnat 已提交
730 731
         png_combine_row(png_ptr, dsp_row,
            png_pass_dsp_mask[png_ptr->pass]);
A
Andreas Dilger 已提交
732
      if (row != NULL)
G
Guy Schalnat 已提交
733 734 735 736
         png_combine_row(png_ptr, row,
            png_pass_mask[png_ptr->pass]);
   }
   else
G
Guy Schalnat 已提交
737
#endif
G
Guy Schalnat 已提交
738
   {
A
Andreas Dilger 已提交
739
      if (row != NULL)
G
Guy Schalnat 已提交
740
         png_combine_row(png_ptr, row, 0xff);
A
Andreas Dilger 已提交
741
      if (dsp_row != NULL)
G
Guy Schalnat 已提交
742 743 744
         png_combine_row(png_ptr, dsp_row, 0xff);
   }
   png_read_finish_row(png_ptr);
745 746 747

   if (png_ptr->read_row_fn != NULL)
      (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
G
Guy Schalnat 已提交
748 749
}

A
Andreas Dilger 已提交
750
/* Read one or more rows of image data.  If the image is interlaced,
751 752
 * and png_set_interlace_handling() has been called, the rows need to
 * contain the contents of the rows from the previous pass.  If the
753
 * image has alpha or transparency, and png_handle_alpha()[*] has been
754 755
 * called, the rows contents must be initialized to the contents of the
 * screen.
756
 *
757 758 759 760 761 762 763 764 765 766 767 768 769
 * "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.
770
 *
771
 * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.2beta1
772
 */
G
Guy Schalnat 已提交
773

774
void PNGAPI
G
Guy Schalnat 已提交
775
png_read_rows(png_structp png_ptr, png_bytepp row,
G
Guy Schalnat 已提交
776
   png_bytepp display_row, png_uint_32 num_rows)
G
Guy Schalnat 已提交
777
{
G
Guy Schalnat 已提交
778 779 780
   png_uint_32 i;
   png_bytepp rp;
   png_bytepp dp;
G
Guy Schalnat 已提交
781

A
Andreas Dilger 已提交
782 783
   png_debug(1, "in png_read_rows\n");
   /* save jump buffer and error functions */
G
Guy Schalnat 已提交
784 785
   rp = row;
   dp = display_row;
786
   if (rp != NULL && dp != NULL)
787 788 789 790
      for (i = 0; i < num_rows; i++)
      {
         png_bytep rptr = *rp++;
         png_bytep dptr = *dp++;
791

792 793
         png_read_row(png_ptr, rptr, dptr);
      }
794
   else if(rp != NULL)
795 796
      for (i = 0; i < num_rows; i++)
      {
797
         png_bytep rptr = *rp;
798
         png_read_row(png_ptr, rptr, png_bytep_NULL);
799 800 801 802 803 804
         rp++;
      }
   else if(dp != NULL)
      for (i = 0; i < num_rows; i++)
      {
         png_bytep dptr = *dp;
805
         png_read_row(png_ptr, png_bytep_NULL, dptr);
806
         dp++;
807
      }
G
Guy Schalnat 已提交
808 809
}

A
Andreas Dilger 已提交
810
/* Read the entire image.  If the image has an alpha channel or a tRNS
811
 * chunk, and you have called png_handle_alpha()[*], you will need to
812 813 814 815 816 817 818
 * 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.
819
 *
820
 * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.2beta1
821
 */
822
void PNGAPI
G
Guy Schalnat 已提交
823
png_read_image(png_structp png_ptr, png_bytepp image)
G
Guy Schalnat 已提交
824
{
825
   png_uint_32 i,image_height;
G
Guy Schalnat 已提交
826
   int pass, j;
G
Guy Schalnat 已提交
827
   png_bytepp rp;
G
Guy Schalnat 已提交
828

A
Andreas Dilger 已提交
829 830
   png_debug(1, "in png_read_image\n");
   /* save jump buffer and error functions */
831 832

#ifdef PNG_READ_INTERLACING_SUPPORTED
G
Guy Schalnat 已提交
833
   pass = png_set_interlace_handling(png_ptr);
834 835 836 837 838 839 840
#else
   if (png_ptr->interlaced)
      png_error(png_ptr,
        "Cannot read interlaced image -- interlace handler disabled.");
   pass = 1;
#endif

G
Guy Schalnat 已提交
841

842 843
   image_height=png_ptr->height;
   png_ptr->num_rows = image_height; /* Make sure this is set correctly */
G
Guy Schalnat 已提交
844

G
Guy Schalnat 已提交
845 846 847
   for (j = 0; j < pass; j++)
   {
      rp = image;
848
      for (i = 0; i < image_height; i++)
G
Guy Schalnat 已提交
849
      {
850
         png_read_row(png_ptr, *rp, png_bytep_NULL);
G
Guy Schalnat 已提交
851 852 853 854 855
         rp++;
      }
   }
}

A
Andreas Dilger 已提交
856
/* Read the end of the PNG file.  Will not read past the end of the
857 858 859
 * 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.
 */
860
void PNGAPI
A
Andreas Dilger 已提交
861
png_read_end(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
862
{
A
Andreas Dilger 已提交
863
   png_byte chunk_length[4];
G
Guy Schalnat 已提交
864 865
   png_uint_32 length;

A
Andreas Dilger 已提交
866 867 868
   png_debug(1, "in png_read_end\n");
   /* save jump buffer and error functions */
   png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
G
Guy Schalnat 已提交
869 870 871

   do
   {
872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888
#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
889 890 891 892 893 894
#if defined(PNG_READ_iCCP_SUPPORTED)
      PNG_iCCP;
#endif
#if defined(PNG_READ_iTXt_SUPPORTED)
      PNG_iTXt;
#endif
895 896 897 898 899 900 901 902 903 904 905 906
#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
907
#if defined(PNG_READ_sCAL_SUPPORTED)
908 909 910 911 912
      PNG_sCAL;
#endif
#if defined(PNG_READ_sPLT_SUPPORTED)
      PNG_sPLT;
#endif
913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929
#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 已提交
930 931
      png_read_data(png_ptr, chunk_length, 4);
      length = png_get_uint_32(chunk_length);
G
Guy Schalnat 已提交
932

A
Andreas Dilger 已提交
933 934 935
      png_reset_crc(png_ptr);
      png_crc_read(png_ptr, png_ptr->chunk_name, 4);

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

A
Andreas Dilger 已提交
938 939
      if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
         png_handle_IHDR(png_ptr, info_ptr, length);
940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956
      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 已提交
957 958 959 960 961 962 963
      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");
964
         png_crc_finish(png_ptr, length);
A
Andreas Dilger 已提交
965
      }
A
Andreas Dilger 已提交
966 967
      else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
         png_handle_PLTE(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
968
#if defined(PNG_READ_bKGD_SUPPORTED)
A
Andreas Dilger 已提交
969 970
      else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
         png_handle_bKGD(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
971 972 973 974 975 976 977 978 979 980
#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 已提交
981 982
      else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
         png_handle_hIST(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
983 984
#endif
#if defined(PNG_READ_oFFs_SUPPORTED)
A
Andreas Dilger 已提交
985 986
      else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
         png_handle_oFFs(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
987 988 989 990 991
#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
992 993 994 995
#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 已提交
996 997 998 999 1000 1001 1002
#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 已提交
1003
#endif
1004 1005 1006 1007
#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
1008 1009 1010 1011 1012 1013 1014 1015
#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 已提交
1016
#if defined(PNG_READ_tEXt_SUPPORTED)
A
Andreas Dilger 已提交
1017 1018
      else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
         png_handle_tEXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
1019
#endif
A
Andreas Dilger 已提交
1020 1021 1022 1023 1024 1025 1026 1027
#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 已提交
1028
#if defined(PNG_READ_zTXt_SUPPORTED)
A
Andreas Dilger 已提交
1029 1030
      else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
         png_handle_zTXt(png_ptr, info_ptr, length);
1031 1032 1033 1034
#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 已提交
1035
#endif
G
Guy Schalnat 已提交
1036
      else
A
Andreas Dilger 已提交
1037 1038
         png_handle_unknown(png_ptr, info_ptr, length);
   } while (!(png_ptr->mode & PNG_HAVE_IEND));
G
Guy Schalnat 已提交
1039 1040 1041
}

/* free all memory used by the read */
1042
void PNGAPI
G
Guy Schalnat 已提交
1043
png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
A
Andreas Dilger 已提交
1044
   png_infopp end_info_ptr_ptr)
G
Guy Schalnat 已提交
1045 1046
{
   png_structp png_ptr = NULL;
A
Andreas Dilger 已提交
1047
   png_infop info_ptr = NULL, end_info_ptr = NULL;
1048 1049
#ifdef PNG_USER_MEM_SUPPORTED
   png_free_ptr free_fn = NULL;
1050
   png_voidp mem_ptr = NULL;
1051
#endif
G
Guy Schalnat 已提交
1052

A
Andreas Dilger 已提交
1053 1054 1055
   png_debug(1, "in png_destroy_read_struct\n");
   /* save jump buffer and error functions */
   if (png_ptr_ptr != NULL)
G
Guy Schalnat 已提交
1056 1057
      png_ptr = *png_ptr_ptr;

A
Andreas Dilger 已提交
1058
   if (info_ptr_ptr != NULL)
G
Guy Schalnat 已提交
1059 1060
      info_ptr = *info_ptr_ptr;

A
Andreas Dilger 已提交
1061
   if (end_info_ptr_ptr != NULL)
A
Andreas Dilger 已提交
1062
      end_info_ptr = *end_info_ptr_ptr;
G
Guy Schalnat 已提交
1063

1064 1065
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
1066
   mem_ptr = png_ptr->mem_ptr;
1067 1068
#endif

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

A
Andreas Dilger 已提交
1071
   if (info_ptr != NULL)
G
Guy Schalnat 已提交
1072
   {
1073
#if defined(PNG_TEXT_SUPPORTED)
1074
      png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
1075
#endif
1076 1077

#ifdef PNG_USER_MEM_SUPPORTED
1078 1079
      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
          (png_voidp)mem_ptr);
1080
#else
A
Andreas Dilger 已提交
1081
      png_destroy_struct((png_voidp)info_ptr);
1082
#endif
1083
      *info_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1084 1085
   }

A
Andreas Dilger 已提交
1086
   if (end_info_ptr != NULL)
G
Guy Schalnat 已提交
1087
   {
1088
#if defined(PNG_READ_TEXT_SUPPORTED)
1089
      png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
1090
#endif
1091
#ifdef PNG_USER_MEM_SUPPORTED
1092 1093
      png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
         (png_voidp)mem_ptr);
1094
#else
A
Andreas Dilger 已提交
1095
      png_destroy_struct((png_voidp)end_info_ptr);
1096
#endif
1097
      *end_info_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1098 1099
   }

A
Andreas Dilger 已提交
1100
   if (png_ptr != NULL)
G
Guy Schalnat 已提交
1101
   {
1102
#ifdef PNG_USER_MEM_SUPPORTED
1103 1104
      png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
          (png_voidp)mem_ptr);
1105
#else
A
Andreas Dilger 已提交
1106
      png_destroy_struct((png_voidp)png_ptr);
1107
#endif
1108
      *png_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1109 1110 1111
   }
}

A
Andreas Dilger 已提交
1112
/* free all memory used by the read (old method) */
1113
void /* PRIVATE */
A
Andreas Dilger 已提交
1114
png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
G
Guy Schalnat 已提交
1115
{
1116
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
1117
   jmp_buf tmp_jmp;
1118
#endif
G
Guy Schalnat 已提交
1119 1120 1121
   png_error_ptr error_fn;
   png_error_ptr warning_fn;
   png_voidp error_ptr;
1122 1123 1124
#ifdef PNG_USER_MEM_SUPPORTED
   png_free_ptr free_fn;
#endif
G
Guy Schalnat 已提交
1125

A
Andreas Dilger 已提交
1126 1127 1128
   png_debug(1, "in png_read_destroy\n");
   /* save jump buffer and error functions */
   if (info_ptr != NULL)
A
Andreas Dilger 已提交
1129
      png_info_destroy(png_ptr, info_ptr);
G
Guy Schalnat 已提交
1130

A
Andreas Dilger 已提交
1131
   if (end_info_ptr != NULL)
A
Andreas Dilger 已提交
1132
      png_info_destroy(png_ptr, end_info_ptr);
G
Guy Schalnat 已提交
1133

A
Andreas Dilger 已提交
1134
   png_free(png_ptr, png_ptr->zbuf);
1135
   png_free(png_ptr, png_ptr->big_row_buf);
A
Andreas Dilger 已提交
1136
   png_free(png_ptr, png_ptr->prev_row);
G
Guy Schalnat 已提交
1137
#if defined(PNG_READ_DITHER_SUPPORTED)
A
Andreas Dilger 已提交
1138 1139
   png_free(png_ptr, png_ptr->palette_lookup);
   png_free(png_ptr, png_ptr->dither_index);
G
Guy Schalnat 已提交
1140 1141
#endif
#if defined(PNG_READ_GAMMA_SUPPORTED)
A
Andreas Dilger 已提交
1142
   png_free(png_ptr, png_ptr->gamma_table);
G
Guy Schalnat 已提交
1143 1144
#endif
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
A
Andreas Dilger 已提交
1145 1146
   png_free(png_ptr, png_ptr->gamma_from_1);
   png_free(png_ptr, png_ptr->gamma_to_1);
G
Guy Schalnat 已提交
1147
#endif
1148
#ifdef PNG_FREE_ME_SUPPORTED
1149
   if (png_ptr->free_me & PNG_FREE_PLTE)
1150
      png_zfree(png_ptr, png_ptr->palette);
1151
   png_ptr->free_me &= ~PNG_FREE_PLTE;
1152 1153 1154 1155 1156
#else
   if (png_ptr->flags & PNG_FLAG_FREE_PLTE)
      png_zfree(png_ptr, png_ptr->palette);
   png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
#endif
1157
#if defined(PNG_tRNS_SUPPORTED) || \
1158
    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
1159
#ifdef PNG_FREE_ME_SUPPORTED
1160
   if (png_ptr->free_me & PNG_FREE_TRNS)
A
Andreas Dilger 已提交
1161
      png_free(png_ptr, png_ptr->trans);
1162
   png_ptr->free_me &= ~PNG_FREE_TRNS;
1163 1164 1165 1166 1167
#else
   if (png_ptr->flags & PNG_FLAG_FREE_TRNS)
      png_free(png_ptr, png_ptr->trans);
   png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
#endif
1168
#endif
G
Guy Schalnat 已提交
1169
#if defined(PNG_READ_hIST_SUPPORTED)
1170
#ifdef PNG_FREE_ME_SUPPORTED
1171
   if (png_ptr->free_me & PNG_FREE_HIST)
A
Andreas Dilger 已提交
1172
      png_free(png_ptr, png_ptr->hist);
1173
   png_ptr->free_me &= ~PNG_FREE_HIST;
1174 1175 1176 1177 1178
#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 已提交
1179 1180
#endif
#if defined(PNG_READ_GAMMA_SUPPORTED)
A
Andreas Dilger 已提交
1181
   if (png_ptr->gamma_16_table != NULL)
G
Guy Schalnat 已提交
1182
   {
1183 1184
      int i;
      int istop = (1 << (8 - png_ptr->gamma_shift));
1185
      for (i = 0; i < istop; i++)
G
Guy Schalnat 已提交
1186
      {
A
Andreas Dilger 已提交
1187
         png_free(png_ptr, png_ptr->gamma_16_table[i]);
G
Guy Schalnat 已提交
1188
      }
1189
   png_free(png_ptr, png_ptr->gamma_16_table);
G
Guy Schalnat 已提交
1190
   }
G
Guy Schalnat 已提交
1191
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
A
Andreas Dilger 已提交
1192
   if (png_ptr->gamma_16_from_1 != NULL)
G
Guy Schalnat 已提交
1193
   {
1194 1195
      int i;
      int istop = (1 << (8 - png_ptr->gamma_shift));
1196
      for (i = 0; i < istop; i++)
G
Guy Schalnat 已提交
1197
      {
A
Andreas Dilger 已提交
1198
         png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
G
Guy Schalnat 已提交
1199
      }
A
Andreas Dilger 已提交
1200
   png_free(png_ptr, png_ptr->gamma_16_from_1);
1201
   }
A
Andreas Dilger 已提交
1202
   if (png_ptr->gamma_16_to_1 != NULL)
G
Guy Schalnat 已提交
1203
   {
1204 1205
      int i;
      int istop = (1 << (8 - png_ptr->gamma_shift));
1206
      for (i = 0; i < istop; i++)
G
Guy Schalnat 已提交
1207
      {
A
Andreas Dilger 已提交
1208
         png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
G
Guy Schalnat 已提交
1209
      }
A
Andreas Dilger 已提交
1210
   png_free(png_ptr, png_ptr->gamma_16_to_1);
1211
   }
G
Guy Schalnat 已提交
1212
#endif
1213 1214 1215
#endif
#if defined(PNG_TIME_RFC1123_SUPPORTED)
   png_free(png_ptr, png_ptr->time_buffer);
1216
#endif
G
Guy Schalnat 已提交
1217

A
Andreas Dilger 已提交
1218
   inflateEnd(&png_ptr->zstream);
G
Guy Schalnat 已提交
1219
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
A
Andreas Dilger 已提交
1220
   png_free(png_ptr, png_ptr->save_buffer);
G
Guy Schalnat 已提交
1221
#endif
G
Guy Schalnat 已提交
1222 1223 1224 1225

   /* Save the important info out of the png_struct, in case it is
    * being used again.
    */
1226
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
1227
   png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
1228
#endif
G
Guy Schalnat 已提交
1229 1230 1231 1232

   error_fn = png_ptr->error_fn;
   warning_fn = png_ptr->warning_fn;
   error_ptr = png_ptr->error_ptr;
1233 1234 1235
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
#endif
G
Guy Schalnat 已提交
1236

G
Guy Schalnat 已提交
1237
   png_memset(png_ptr, 0, sizeof (png_struct));
G
Guy Schalnat 已提交
1238 1239 1240 1241

   png_ptr->error_fn = error_fn;
   png_ptr->warning_fn = warning_fn;
   png_ptr->error_ptr = error_ptr;
1242 1243 1244
#ifdef PNG_USER_MEM_SUPPORTED
   png_ptr->free_fn = free_fn;
#endif
G
Guy Schalnat 已提交
1245

1246
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
1247
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
1248 1249
#endif

G
Guy Schalnat 已提交
1250
}
1251

1252
void PNGAPI
1253 1254 1255 1256
png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
{
   png_ptr->read_row_fn = read_row_fn;
}
1257 1258

#if defined(PNG_INFO_IMAGE_SUPPORTED)
1259 1260
void PNGAPI
png_read_png(png_structp png_ptr, png_infop info_ptr,
1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292
                           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

1293
#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314
   /* 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)
1315 1316 1317 1318
       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);
1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365
#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
1366
    * update the palette for you (i.e., you selected such a transform above).
1367 1368 1369 1370 1371
    */
   png_read_update_info(png_ptr, info_ptr);

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

1372
#ifdef PNG_FREE_ME_SUPPORTED
1373
   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1374
#endif
1375 1376 1377
   if(info_ptr->row_pointers == NULL)
   {
      info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
1378
         info_ptr->height * sizeof(png_bytep));
1379
#ifdef PNG_FREE_ME_SUPPORTED
1380
      info_ptr->free_me |= PNG_FREE_ROWS;
1381 1382
#endif
      for (row = 0; row < (int)info_ptr->height; row++)
1383 1384
      {
         info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
1385
            png_get_rowbytes(png_ptr, info_ptr));
1386
      }
1387
   }
1388 1389 1390 1391 1392 1393

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

1395
   if(transforms == 0 || params == NULL)
1396 1397
      /* quiet compiler warnings */ return;

1398 1399
}
#endif