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

A
Andreas Dilger 已提交
2
/* pngread.c - read a PNG file
3
 *
4
 * libpng 1.2.2 - April 15, 2002
5
 * For conditions of distribution and use, see copyright notice in png.h
6
 * Copyright (c) 1998-2002 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 73 74 75 76 77
#ifdef PNG_USER_MEM_SUPPORTED
      png_destroy_struct_2((png_voidp)png_ptr, 
			   (png_free_ptr)free_fn,
			   (png_voidp)mem_ptr);
#else
      png_destroy_struct((png_voidp)png_ptr);
#endif
78
      return (NULL);
G
Guy Schalnat 已提交
79
   }
A
Andreas Dilger 已提交
80 81 82
#ifdef USE_FAR_KEYWORD
   png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
#endif
83
#endif
84 85 86

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

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

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

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

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

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

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

   return (png_ptr);
}

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

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

216
   int i=0;
217 218 219

   png_structp png_ptr=*ptr_ptr;

220 221 222 223
   do
   {
     if(user_png_ver[i] != png_libpng_ver[i])
     {
224 225 226
#ifdef PNG_LEGACY_SUPPORTED
       png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
#else
227
       png_ptr->warning_fn=NULL;
228 229 230
       png_warning(png_ptr,
        "Application uses deprecated png_read_init() and should be recompiled.");
       break;
231
#endif
232 233 234
     }
   } while (png_libpng_ver[i++]);

235
   png_debug(1, "in png_read_init_3\n");
236 237

#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
238
   /* save jump buffer and error functions */
G
Guy Schalnat 已提交
239
   png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
240
#endif
G
Guy Schalnat 已提交
241

242 243 244 245 246 247 248
   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 已提交
249
   /* reset all variables to 0 */
G
Guy Schalnat 已提交
250
   png_memset(png_ptr, 0, sizeof (png_struct));
G
Guy Schalnat 已提交
251

252
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
253
   /* restore jump buffer */
G
Guy Schalnat 已提交
254
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
255
#endif
G
Guy Schalnat 已提交
256

G
Guy Schalnat 已提交
257
   /* initialize zbuf - compression buffer */
G
Guy Schalnat 已提交
258
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
259 260
   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
     (png_uint_32)png_ptr->zbuf_size);
A
Andreas Dilger 已提交
261 262 263
   png_ptr->zstream.zalloc = png_zalloc;
   png_ptr->zstream.zfree = png_zfree;
   png_ptr->zstream.opaque = (voidpf)png_ptr;
G
Guy Schalnat 已提交
264

A
Andreas Dilger 已提交
265
   switch (inflateInit(&png_ptr->zstream))
G
Guy Schalnat 已提交
266 267 268 269 270 271 272 273
   {
     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 已提交
274 275
   png_ptr->zstream.next_out = png_ptr->zbuf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
G
Guy Schalnat 已提交
276

277
   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
G
Guy Schalnat 已提交
278 279
}

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

A
Andreas Dilger 已提交
299
      png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
A
Andreas Dilger 已提交
300 301 302 303 304 305 306 307 308 309
      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");
      }
310 311
      if (num_checked < 3)
         png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
G
Guy Schalnat 已提交
312
   }
G
Guy Schalnat 已提交
313

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

A
Andreas Dilger 已提交
376 377
      png_read_data(png_ptr, chunk_length, 4);
      length = png_get_uint_32(chunk_length);
G
Guy Schalnat 已提交
378

A
Andreas Dilger 已提交
379 380 381
      png_reset_crc(png_ptr);
      png_crc_read(png_ptr, png_ptr->chunk_name, 4);

382
      png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name,
383
         length);
A
Andreas Dilger 已提交
384

385 386 387
      if (length > PNG_MAX_UINT)
         png_error(png_ptr, "Invalid chunk length.");

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

A
Andreas Dilger 已提交
501
/* optional call to update the users info_ptr structure */
502
void PNGAPI
A
Andreas Dilger 已提交
503
png_read_update_info(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
504
{
A
Andreas Dilger 已提交
505 506
   png_debug(1, "in png_read_update_info\n");
   /* save jump buffer and error functions */
G
Guy Schalnat 已提交
507
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
508
      png_read_start_row(png_ptr);
509 510 511
   else
      png_warning(png_ptr,
      "Ignoring extra png_read_update_info() call; row buffer not reallocated");
A
Andreas Dilger 已提交
512
   png_read_transform_info(png_ptr, info_ptr);
G
Guy Schalnat 已提交
513 514
}

515 516
/* Initialize palette, background, etc, after transformations
 * are set, but before any reading takes place.  This allows
517
 * the user to obtain a gamma-corrected palette, for example.
518 519
 * If the user doesn't call this, we will do it ourselves.
 */
520
void PNGAPI
G
Guy Schalnat 已提交
521
png_start_read_image(png_structp png_ptr)
G
Guy Schalnat 已提交
522
{
A
Andreas Dilger 已提交
523 524
   png_debug(1, "in png_start_read_image\n");
   /* save jump buffer and error functions */
G
Guy Schalnat 已提交
525
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
526
      png_read_start_row(png_ptr);
G
Guy Schalnat 已提交
527 528
}

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

G
Guy Schalnat 已提交
576
#if defined(PNG_READ_INTERLACING_SUPPORTED)
G
Guy Schalnat 已提交
577 578 579 580 581 582
   /* 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:
583
            if (png_ptr->row_number & 0x07)
G
Guy Schalnat 已提交
584
            {
A
Andreas Dilger 已提交
585
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
586 587
                  png_combine_row(png_ptr, dsp_row,
                     png_pass_dsp_mask[png_ptr->pass]);
G
Guy Schalnat 已提交
588
               png_read_finish_row(png_ptr);
G
Guy Schalnat 已提交
589 590 591 592
               return;
            }
            break;
         case 1:
593
            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
G
Guy Schalnat 已提交
594
            {
A
Andreas Dilger 已提交
595
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
596 597 598 599 600 601 602
                  png_combine_row(png_ptr, dsp_row,
                     png_pass_dsp_mask[png_ptr->pass]);
               png_read_finish_row(png_ptr);
               return;
            }
            break;
         case 2:
603
            if ((png_ptr->row_number & 0x07) != 4)
G
Guy Schalnat 已提交
604
            {
A
Andreas Dilger 已提交
605
               if (dsp_row != NULL && (png_ptr->row_number & 4))
G
Guy Schalnat 已提交
606
                  png_combine_row(png_ptr, dsp_row,
G
Guy Schalnat 已提交
607 608 609 610 611 612 613 614
                     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 已提交
615
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
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 4:
            if ((png_ptr->row_number & 3) != 2)
G
Guy Schalnat 已提交
624
            {
A
Andreas Dilger 已提交
625
               if (dsp_row != NULL && (png_ptr->row_number & 2))
G
Guy Schalnat 已提交
626 627 628 629 630 631 632 633 634
                  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 已提交
635
               if (dsp_row != NULL)
G
Guy Schalnat 已提交
636 637 638 639 640 641
                  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 已提交
642
         case 6:
G
Guy Schalnat 已提交
643 644 645 646 647 648 649 650
            if (!(png_ptr->row_number & 1))
            {
               png_read_finish_row(png_ptr);
               return;
            }
            break;
      }
   }
G
Guy Schalnat 已提交
651
#endif
G
Guy Schalnat 已提交
652

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

A
Andreas Dilger 已提交
656 657
   png_ptr->zstream.next_out = png_ptr->row_buf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
G
Guy Schalnat 已提交
658 659
   do
   {
A
Andreas Dilger 已提交
660
      if (!(png_ptr->zstream.avail_in))
G
Guy Schalnat 已提交
661 662 663
      {
         while (!png_ptr->idat_size)
         {
A
Andreas Dilger 已提交
664
            png_byte chunk_length[4];
G
Guy Schalnat 已提交
665

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

A
Andreas Dilger 已提交
668 669
            png_read_data(png_ptr, chunk_length, 4);
            png_ptr->idat_size = png_get_uint_32(chunk_length);
G
Guy Schalnat 已提交
670

671 672 673
            if (png_ptr->idat_size > PNG_MAX_UINT)
              png_error(png_ptr, "Invalid chunk length.");

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

   } while (png_ptr->zstream.avail_out);
G
Guy Schalnat 已提交
702 703 704 705 706 707

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

711
   if(png_ptr->row_buf[0])
G
Guy Schalnat 已提交
712 713 714
   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 已提交
715

716
   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
717
      png_ptr->rowbytes + 1);
718 719 720 721 722 723 724 725 726
   
#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 已提交
727 728 729 730

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

G
Guy Schalnat 已提交
731
#if defined(PNG_READ_INTERLACING_SUPPORTED)
G
Guy Schalnat 已提交
732 733 734 735 736
   /* blow up interlaced rows to full size */
   if (png_ptr->interlaced &&
      (png_ptr->transformations & PNG_INTERLACE))
   {
      if (png_ptr->pass < 6)
737
/*       old interface (pre-1.0.9):
G
Guy Schalnat 已提交
738
         png_do_read_interlace(&(png_ptr->row_info),
A
Andreas Dilger 已提交
739
            png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
740 741
 */
         png_do_read_interlace(png_ptr);
G
Guy Schalnat 已提交
742

A
Andreas Dilger 已提交
743
      if (dsp_row != NULL)
G
Guy Schalnat 已提交
744 745
         png_combine_row(png_ptr, dsp_row,
            png_pass_dsp_mask[png_ptr->pass]);
A
Andreas Dilger 已提交
746
      if (row != NULL)
G
Guy Schalnat 已提交
747 748 749 750
         png_combine_row(png_ptr, row,
            png_pass_mask[png_ptr->pass]);
   }
   else
G
Guy Schalnat 已提交
751
#endif
G
Guy Schalnat 已提交
752
   {
A
Andreas Dilger 已提交
753
      if (row != NULL)
G
Guy Schalnat 已提交
754
         png_combine_row(png_ptr, row, 0xff);
A
Andreas Dilger 已提交
755
      if (dsp_row != NULL)
G
Guy Schalnat 已提交
756 757 758
         png_combine_row(png_ptr, dsp_row, 0xff);
   }
   png_read_finish_row(png_ptr);
759 760 761

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

A
Andreas Dilger 已提交
764
/* Read one or more rows of image data.  If the image is interlaced,
765 766
 * and png_set_interlace_handling() has been called, the rows need to
 * contain the contents of the rows from the previous pass.  If the
767
 * image has alpha or transparency, and png_handle_alpha()[*] has been
768 769
 * called, the rows contents must be initialized to the contents of the
 * screen.
770
 *
771 772 773 774 775 776 777 778 779 780 781 782 783
 * "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.
784
 *
785
 * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.2
786
 */
G
Guy Schalnat 已提交
787

788
void PNGAPI
G
Guy Schalnat 已提交
789
png_read_rows(png_structp png_ptr, png_bytepp row,
G
Guy Schalnat 已提交
790
   png_bytepp display_row, png_uint_32 num_rows)
G
Guy Schalnat 已提交
791
{
G
Guy Schalnat 已提交
792 793 794
   png_uint_32 i;
   png_bytepp rp;
   png_bytepp dp;
G
Guy Schalnat 已提交
795

A
Andreas Dilger 已提交
796 797
   png_debug(1, "in png_read_rows\n");
   /* save jump buffer and error functions */
G
Guy Schalnat 已提交
798 799
   rp = row;
   dp = display_row;
800
   if (rp != NULL && dp != NULL)
801 802 803 804
      for (i = 0; i < num_rows; i++)
      {
         png_bytep rptr = *rp++;
         png_bytep dptr = *dp++;
805

806 807
         png_read_row(png_ptr, rptr, dptr);
      }
808
   else if(rp != NULL)
809 810
      for (i = 0; i < num_rows; i++)
      {
811
         png_bytep rptr = *rp;
812
         png_read_row(png_ptr, rptr, png_bytep_NULL);
813 814 815 816 817 818
         rp++;
      }
   else if(dp != NULL)
      for (i = 0; i < num_rows; i++)
      {
         png_bytep dptr = *dp;
819
         png_read_row(png_ptr, png_bytep_NULL, dptr);
820
         dp++;
821
      }
G
Guy Schalnat 已提交
822 823
}

A
Andreas Dilger 已提交
824
/* Read the entire image.  If the image has an alpha channel or a tRNS
825
 * chunk, and you have called png_handle_alpha()[*], you will need to
826 827 828 829 830 831 832
 * 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.
833
 *
834
 * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.2
835
 */
836
void PNGAPI
G
Guy Schalnat 已提交
837
png_read_image(png_structp png_ptr, png_bytepp image)
G
Guy Schalnat 已提交
838
{
839
   png_uint_32 i,image_height;
G
Guy Schalnat 已提交
840
   int pass, j;
G
Guy Schalnat 已提交
841
   png_bytepp rp;
G
Guy Schalnat 已提交
842

A
Andreas Dilger 已提交
843 844
   png_debug(1, "in png_read_image\n");
   /* save jump buffer and error functions */
845 846

#ifdef PNG_READ_INTERLACING_SUPPORTED
G
Guy Schalnat 已提交
847
   pass = png_set_interlace_handling(png_ptr);
848 849 850 851 852 853 854
#else
   if (png_ptr->interlaced)
      png_error(png_ptr,
        "Cannot read interlaced image -- interlace handler disabled.");
   pass = 1;
#endif

G
Guy Schalnat 已提交
855

856 857
   image_height=png_ptr->height;
   png_ptr->num_rows = image_height; /* Make sure this is set correctly */
G
Guy Schalnat 已提交
858

G
Guy Schalnat 已提交
859 860 861
   for (j = 0; j < pass; j++)
   {
      rp = image;
862
      for (i = 0; i < image_height; i++)
G
Guy Schalnat 已提交
863
      {
864
         png_read_row(png_ptr, *rp, png_bytep_NULL);
G
Guy Schalnat 已提交
865 866 867 868 869
         rp++;
      }
   }
}

A
Andreas Dilger 已提交
870
/* Read the end of the PNG file.  Will not read past the end of the
871 872 873
 * 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.
 */
874
void PNGAPI
A
Andreas Dilger 已提交
875
png_read_end(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
876
{
A
Andreas Dilger 已提交
877
   png_byte chunk_length[4];
G
Guy Schalnat 已提交
878 879
   png_uint_32 length;

A
Andreas Dilger 已提交
880 881 882
   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 已提交
883 884 885

   do
   {
886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902
#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
903 904 905 906 907 908
#if defined(PNG_READ_iCCP_SUPPORTED)
      PNG_iCCP;
#endif
#if defined(PNG_READ_iTXt_SUPPORTED)
      PNG_iTXt;
#endif
909 910 911 912 913 914 915 916 917 918 919 920
#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
921
#if defined(PNG_READ_sCAL_SUPPORTED)
922 923 924 925 926
      PNG_sCAL;
#endif
#if defined(PNG_READ_sPLT_SUPPORTED)
      PNG_sPLT;
#endif
927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943
#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 已提交
944 945
      png_read_data(png_ptr, chunk_length, 4);
      length = png_get_uint_32(chunk_length);
G
Guy Schalnat 已提交
946

A
Andreas Dilger 已提交
947 948 949
      png_reset_crc(png_ptr);
      png_crc_read(png_ptr, png_ptr->chunk_name, 4);

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

952 953 954
      if (length > PNG_MAX_UINT)
         png_error(png_ptr, "Invalid chunk length.");

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

/* free all memory used by the read */
1059
void PNGAPI
G
Guy Schalnat 已提交
1060
png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
A
Andreas Dilger 已提交
1061
   png_infopp end_info_ptr_ptr)
G
Guy Schalnat 已提交
1062 1063
{
   png_structp png_ptr = NULL;
A
Andreas Dilger 已提交
1064
   png_infop info_ptr = NULL, end_info_ptr = NULL;
1065 1066
#ifdef PNG_USER_MEM_SUPPORTED
   png_free_ptr free_fn = NULL;
1067
   png_voidp mem_ptr = NULL;
1068
#endif
G
Guy Schalnat 已提交
1069

A
Andreas Dilger 已提交
1070 1071 1072
   png_debug(1, "in png_destroy_read_struct\n");
   /* save jump buffer and error functions */
   if (png_ptr_ptr != NULL)
G
Guy Schalnat 已提交
1073 1074
      png_ptr = *png_ptr_ptr;

A
Andreas Dilger 已提交
1075
   if (info_ptr_ptr != NULL)
G
Guy Schalnat 已提交
1076 1077
      info_ptr = *info_ptr_ptr;

A
Andreas Dilger 已提交
1078
   if (end_info_ptr_ptr != NULL)
A
Andreas Dilger 已提交
1079
      end_info_ptr = *end_info_ptr_ptr;
G
Guy Schalnat 已提交
1080

1081 1082
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
1083
   mem_ptr = png_ptr->mem_ptr;
1084 1085
#endif

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

A
Andreas Dilger 已提交
1088
   if (info_ptr != NULL)
G
Guy Schalnat 已提交
1089
   {
1090
#if defined(PNG_TEXT_SUPPORTED)
1091
      png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
1092
#endif
1093 1094

#ifdef PNG_USER_MEM_SUPPORTED
1095 1096
      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
          (png_voidp)mem_ptr);
1097
#else
A
Andreas Dilger 已提交
1098
      png_destroy_struct((png_voidp)info_ptr);
1099
#endif
1100
      *info_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1101 1102
   }

A
Andreas Dilger 已提交
1103
   if (end_info_ptr != NULL)
G
Guy Schalnat 已提交
1104
   {
1105
#if defined(PNG_READ_TEXT_SUPPORTED)
1106
      png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
1107
#endif
1108
#ifdef PNG_USER_MEM_SUPPORTED
1109 1110
      png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
         (png_voidp)mem_ptr);
1111
#else
A
Andreas Dilger 已提交
1112
      png_destroy_struct((png_voidp)end_info_ptr);
1113
#endif
1114
      *end_info_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1115 1116
   }

A
Andreas Dilger 已提交
1117
   if (png_ptr != NULL)
G
Guy Schalnat 已提交
1118
   {
1119
#ifdef PNG_USER_MEM_SUPPORTED
1120 1121
      png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
          (png_voidp)mem_ptr);
1122
#else
A
Andreas Dilger 已提交
1123
      png_destroy_struct((png_voidp)png_ptr);
1124
#endif
1125
      *png_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1126 1127 1128
   }
}

A
Andreas Dilger 已提交
1129
/* free all memory used by the read (old method) */
1130
void /* PRIVATE */
A
Andreas Dilger 已提交
1131
png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
G
Guy Schalnat 已提交
1132
{
1133
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
1134
   jmp_buf tmp_jmp;
1135
#endif
G
Guy Schalnat 已提交
1136 1137 1138
   png_error_ptr error_fn;
   png_error_ptr warning_fn;
   png_voidp error_ptr;
1139 1140 1141
#ifdef PNG_USER_MEM_SUPPORTED
   png_free_ptr free_fn;
#endif
G
Guy Schalnat 已提交
1142

A
Andreas Dilger 已提交
1143 1144 1145
   png_debug(1, "in png_read_destroy\n");
   /* save jump buffer and error functions */
   if (info_ptr != NULL)
A
Andreas Dilger 已提交
1146
      png_info_destroy(png_ptr, info_ptr);
G
Guy Schalnat 已提交
1147

A
Andreas Dilger 已提交
1148
   if (end_info_ptr != NULL)
A
Andreas Dilger 已提交
1149
      png_info_destroy(png_ptr, end_info_ptr);
G
Guy Schalnat 已提交
1150

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

A
Andreas Dilger 已提交
1235
   inflateEnd(&png_ptr->zstream);
G
Guy Schalnat 已提交
1236
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
A
Andreas Dilger 已提交
1237
   png_free(png_ptr, png_ptr->save_buffer);
G
Guy Schalnat 已提交
1238
#endif
G
Guy Schalnat 已提交
1239 1240 1241 1242

   /* Save the important info out of the png_struct, in case it is
    * being used again.
    */
1243
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
1244
   png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
1245
#endif
G
Guy Schalnat 已提交
1246 1247 1248 1249

   error_fn = png_ptr->error_fn;
   warning_fn = png_ptr->warning_fn;
   error_ptr = png_ptr->error_ptr;
1250 1251 1252
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
#endif
G
Guy Schalnat 已提交
1253

G
Guy Schalnat 已提交
1254
   png_memset(png_ptr, 0, sizeof (png_struct));
G
Guy Schalnat 已提交
1255 1256 1257 1258

   png_ptr->error_fn = error_fn;
   png_ptr->warning_fn = warning_fn;
   png_ptr->error_ptr = error_ptr;
1259 1260 1261
#ifdef PNG_USER_MEM_SUPPORTED
   png_ptr->free_fn = free_fn;
#endif
G
Guy Schalnat 已提交
1262

1263
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
1264
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
1265 1266
#endif

G
Guy Schalnat 已提交
1267
}
1268

1269
void PNGAPI
1270 1271 1272 1273
png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
{
   png_ptr->read_row_fn = read_row_fn;
}
1274 1275

#if defined(PNG_INFO_IMAGE_SUPPORTED)
1276 1277
void PNGAPI
png_read_png(png_structp png_ptr, png_infop info_ptr,
1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309
                           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

1310
#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331
   /* 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)
1332 1333 1334 1335
       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);
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 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382
#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
1383
    * update the palette for you (i.e., you selected such a transform above).
1384 1385 1386 1387 1388
    */
   png_read_update_info(png_ptr, info_ptr);

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

1389
#ifdef PNG_FREE_ME_SUPPORTED
1390
   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1391
#endif
1392 1393 1394
   if(info_ptr->row_pointers == NULL)
   {
      info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
1395
         info_ptr->height * sizeof(png_bytep));
1396
#ifdef PNG_FREE_ME_SUPPORTED
1397
      info_ptr->free_me |= PNG_FREE_ROWS;
1398 1399
#endif
      for (row = 0; row < (int)info_ptr->height; row++)
1400 1401
      {
         info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
1402
            png_get_rowbytes(png_ptr, info_ptr));
1403
      }
1404
   }
1405 1406 1407 1408 1409 1410

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

1412
   if(transforms == 0 || params == NULL)
1413 1414
      /* quiet compiler warnings */ return;

1415 1416
}
#endif