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

A
Andreas Dilger 已提交
2
/* pngread.c - read a PNG file
3 4
 *
 * For conditions of distribution and use, see copyright notice in png.h
5
 * Copyright (c) 1998-2006 Glenn Randers-Pehrson
6 7
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8 9 10 11
 *
 * This file contains routines that an application calls directly to
 * read a PNG file or stream.
 */
G
Guy Schalnat 已提交
12 13 14 15

#define PNG_INTERNAL
#include "png.h"

16 17
#if defined(PNG_READ_SUPPORTED)

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

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

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

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

45 46
   int i;

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

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

63 64 65 66 67 68
   /* added at libpng-1.2.6 */
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
   png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
   png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
#endif

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

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

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

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

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

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

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

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

157 158 159 160 161 162 163
#ifdef PNG_SETJMP_SUPPORTED
/* Applications that neglect to set up their own setjmp() and then encounter
   a png_error() will longjmp here.  Since the jmpbuf is then meaningless we
   abort instead of returning. */
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmpbuf))
      PNG_ABORT();
164
   png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
165 166 167 168 169
#else
   if (setjmp(png_ptr->jmpbuf))
      PNG_ABORT();
#endif
#endif
G
Guy Schalnat 已提交
170 171 172
   return (png_ptr);
}

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

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

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

237
   int i=0;
238 239 240

   png_structp png_ptr=*ptr_ptr;

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

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

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

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

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

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

278 279 280 281 282 283
   /* added at libpng-1.2.6 */
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
   png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
   png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
#endif

G
Guy Schalnat 已提交
284
   /* initialize zbuf - compression buffer */
G
Guy Schalnat 已提交
285
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
286 287
   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
     (png_uint_32)png_ptr->zbuf_size);
A
Andreas Dilger 已提交
288 289 290
   png_ptr->zstream.zalloc = png_zalloc;
   png_ptr->zstream.zfree = png_zfree;
   png_ptr->zstream.opaque = (voidpf)png_ptr;
G
Guy Schalnat 已提交
291

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

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

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

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

341
   for(;;)
G
Guy Schalnat 已提交
342
   {
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
#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
360 361 362 363 364 365
#if defined(PNG_READ_iCCP_SUPPORTED)
      PNG_iCCP;
#endif
#if defined(PNG_READ_iTXt_SUPPORTED)
      PNG_iTXt;
#endif
366 367 368 369 370 371 372 373 374 375 376 377
#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
378
#if defined(PNG_READ_sCAL_SUPPORTED)
379 380 381 382 383
      PNG_sCAL;
#endif
#if defined(PNG_READ_sPLT_SUPPORTED)
      PNG_sPLT;
#endif
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
#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
399
#endif /* PNG_USE_LOCAL_ARRAYS */
A
Andreas Dilger 已提交
400 401
      png_byte chunk_length[4];
      png_uint_32 length;
G
Guy Schalnat 已提交
402

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

733
   if(png_ptr->row_buf[0])
G
Guy Schalnat 已提交
734 735 736
   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 已提交
737

738
   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
739
      png_ptr->rowbytes + 1);
740 741 742 743 744 745 746 747 748
   
#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 已提交
749

750 751

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

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

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

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

788
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
789
/* Read one or more rows of image data.  If the image is interlaced,
790 791
 * and png_set_interlace_handling() has been called, the rows need to
 * contain the contents of the rows from the previous pass.  If the
792
 * image has alpha or transparency, and png_handle_alpha()[*] has been
793 794
 * called, the rows contents must be initialized to the contents of the
 * screen.
795
 *
796 797 798 799 800 801 802 803 804 805 806 807 808
 * "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.
809
 *
810
 * [*] png_handle_alpha() does not exist yet, as of this version of libpng
811
 */
G
Guy Schalnat 已提交
812

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

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

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

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

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

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

G
Guy Schalnat 已提交
880

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

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

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

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

   do
   {
912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928
#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
929 930 931 932 933 934
#if defined(PNG_READ_iCCP_SUPPORTED)
      PNG_iCCP;
#endif
#if defined(PNG_READ_iTXt_SUPPORTED)
      PNG_iTXt;
#endif
935 936 937 938 939 940 941 942 943 944 945 946
#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
947
#if defined(PNG_READ_sCAL_SUPPORTED)
948 949 950 951 952
      PNG_sCAL;
#endif
#if defined(PNG_READ_sPLT_SUPPORTED)
      PNG_sPLT;
#endif
953 954 955 956 957 958 959 960 961 962 963 964 965 966 967
#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
968
#endif /* PNG_USE_LOCAL_ARRAYS */
969

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1262 1263 1264 1265 1266 1267
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
#ifdef PNG_TEXT_SUPPORTED
   png_free(png_ptr, png_ptr->current_text);
#endif /* PNG_TEXT_SUPPORTED */
#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */

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

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

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

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

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

G
Guy Schalnat 已提交
1295
}
1296

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

1303 1304

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

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

1320
   /* png_read_info() gives us all of the information from the
1321 1322 1323
    * PNG file before the first IDAT (image data chunk).
    */
   png_read_info(png_ptr, info_ptr);
1324 1325
   if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
      png_error(png_ptr,"Image is too high to process with png_read_png()");
1326 1327 1328 1329

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

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

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

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

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

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

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

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

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

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

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

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

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