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

A
Andreas Dilger 已提交
2
/* pngread.c - read a PNG file
3
 *
4
 * Last changed in libpng 1.4.0 [April 1, 2009]
5
 * For conditions of distribution and use, see copyright notice in png.h
6
 * Copyright (c) 1998-2009 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

#include "png.h"
15
#if defined(PNG_READ_SUPPORTED)
16
#include "pngpriv.h"
17

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, NULL, NULL, 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 */

37 38 39 40
#ifdef PNG_SETJMP_SUPPORTED
   volatile
#endif
   png_structp png_ptr;
41 42

#ifdef PNG_SETJMP_SUPPORTED
A
Andreas Dilger 已提交
43 44 45
#ifdef USE_FAR_KEYWORD
   jmp_buf jmpbuf;
#endif
46 47
#endif

48 49
   int i;

50
   png_debug(1, "in png_create_read_struct");
51
#ifdef PNG_USER_MEM_SUPPORTED
52
   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
53
      malloc_fn, mem_ptr);
54
#else
55
   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
56
#endif
57
   if (png_ptr == NULL)
58
      return (NULL);
59

60 61 62 63 64 65
   /* 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

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

#ifdef PNG_USER_MEM_SUPPORTED
   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
90
#endif
91

A
Andreas Dilger 已提交
92 93
   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);

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

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

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

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

160
   png_set_read_fn(png_ptr, NULL, NULL);
G
Guy Schalnat 已提交
161

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

178 179 180 181

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 已提交
182
{
183
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
184
   jmp_buf tmp_jmp;  /* to save current jump buffer */
185
#endif
G
Guy Schalnat 已提交
186

187
   int i = 0;
188 189 190

   png_structp png_ptr=*ptr_ptr;

191
   if (png_ptr == NULL) return;
192

193 194
   do
   {
195
     if (user_png_ver[i] != png_libpng_ver[i])
196
     {
197 198 199
#ifdef PNG_LEGACY_SUPPORTED
       png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
#else
200
       png_ptr->warning_fn = NULL;
201
       png_warning(png_ptr,
202
        "Application uses deprecated png_read_init() and should be recompiled");
203
       break;
204
#endif
205 206 207
     }
   } while (png_libpng_ver[i++]);

208
   png_debug(1, "in png_read_init_3");
209 210

#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
211
   /* save jump buffer and error functions */
212
   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
213
#endif
G
Guy Schalnat 已提交
214

215
   if (png_sizeof(png_struct) > png_struct_size)
216 217 218 219 220
   {
      png_destroy_struct(png_ptr);
      *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
      png_ptr = *ptr_ptr;
   }
221

G
Guy Schalnat 已提交
222
   /* reset all variables to 0 */
223
   png_memset(png_ptr, 0, png_sizeof(png_struct));
G
Guy Schalnat 已提交
224

225
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
226
   /* restore jump buffer */
227
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
228
#endif
G
Guy Schalnat 已提交
229

230 231 232 233 234 235
   /* 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 已提交
236
   /* initialize zbuf - compression buffer */
G
Guy Schalnat 已提交
237
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
238 239
   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
     png_ptr->zbuf_size);
A
Andreas Dilger 已提交
240 241 242
   png_ptr->zstream.zalloc = png_zalloc;
   png_ptr->zstream.zfree = png_zfree;
   png_ptr->zstream.opaque = (voidpf)png_ptr;
G
Guy Schalnat 已提交
243

A
Andreas Dilger 已提交
244
   switch (inflateInit(&png_ptr->zstream))
G
Guy Schalnat 已提交
245 246 247 248 249 250 251 252
   {
     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 已提交
253 254
   png_ptr->zstream.next_out = png_ptr->zbuf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
G
Guy Schalnat 已提交
255

256
   png_set_read_fn(png_ptr, NULL, NULL);
G
Guy Schalnat 已提交
257 258
}

259
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
260
/* Read the information before the actual image data.  This has been
261
 * changed in v0.90 to allow reading a file that already has the magic
A
Andreas Dilger 已提交
262
 * bytes read from the stream.  You can tell libpng how many bytes have
263
 * been read from the beginning of the stream (up to the maximum of 8)
A
Andreas Dilger 已提交
264 265 266 267
 * 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.
 */
268
void PNGAPI
A
Andreas Dilger 已提交
269
png_read_info(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
270
{
271
   if (png_ptr == NULL || info_ptr == NULL) return;
272
   png_debug(1, "in png_read_info");
A
Andreas Dilger 已提交
273 274
   /* If we haven't checked all of the PNG signature bytes, do so now. */
   if (png_ptr->sig_bytes < 8)
G
Guy Schalnat 已提交
275
   {
A
Andreas Dilger 已提交
276 277
      png_size_t num_checked = png_ptr->sig_bytes,
                 num_to_check = 8 - num_checked;
A
Andreas Dilger 已提交
278

279 280 281
#ifdef PNG_IO_STATE_SUPPORTED
      png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE;
#endif
282

A
Andreas Dilger 已提交
283
      png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
A
Andreas Dilger 已提交
284 285 286 287 288 289 290 291 292 293
      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");
      }
294 295
      if (num_checked < 3)
         png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
G
Guy Schalnat 已提交
296
   }
G
Guy Schalnat 已提交
297

298
   for (;;)
G
Guy Schalnat 已提交
299
   {
300
#ifdef PNG_USE_LOCAL_ARRAYS
301 302 303 304
      PNG_CONST PNG_IHDR;
      PNG_CONST PNG_IDAT;
      PNG_CONST PNG_IEND;
      PNG_CONST PNG_PLTE;
305
#if defined(PNG_READ_bKGD_SUPPORTED)
306
      PNG_CONST PNG_bKGD;
307 308
#endif
#if defined(PNG_READ_cHRM_SUPPORTED)
309
      PNG_CONST PNG_cHRM;
310 311
#endif
#if defined(PNG_READ_gAMA_SUPPORTED)
312
      PNG_CONST PNG_gAMA;
313 314
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
315
      PNG_CONST PNG_hIST;
316
#endif
317
#if defined(PNG_READ_iCCP_SUPPORTED)
318
      PNG_CONST PNG_iCCP;
319 320
#endif
#if defined(PNG_READ_iTXt_SUPPORTED)
321
      PNG_CONST PNG_iTXt;
322
#endif
323
#if defined(PNG_READ_oFFs_SUPPORTED)
324
      PNG_CONST PNG_oFFs;
325 326
#endif
#if defined(PNG_READ_pCAL_SUPPORTED)
327
      PNG_CONST PNG_pCAL;
328 329
#endif
#if defined(PNG_READ_pHYs_SUPPORTED)
330
      PNG_CONST PNG_pHYs;
331 332
#endif
#if defined(PNG_READ_sBIT_SUPPORTED)
333
      PNG_CONST PNG_sBIT;
334
#endif
335
#if defined(PNG_READ_sCAL_SUPPORTED)
336
      PNG_CONST PNG_sCAL;
337 338
#endif
#if defined(PNG_READ_sPLT_SUPPORTED)
339
      PNG_CONST PNG_sPLT;
340
#endif
341
#if defined(PNG_READ_sRGB_SUPPORTED)
342
      PNG_CONST PNG_sRGB;
343 344
#endif
#if defined(PNG_READ_tEXt_SUPPORTED)
345
      PNG_CONST PNG_tEXt;
346 347
#endif
#if defined(PNG_READ_tIME_SUPPORTED)
348
      PNG_CONST PNG_tIME;
349 350
#endif
#if defined(PNG_READ_tRNS_SUPPORTED)
351
      PNG_CONST PNG_tRNS;
352 353
#endif
#if defined(PNG_READ_zTXt_SUPPORTED)
354
      PNG_CONST PNG_zTXt;
355
#endif
356
#endif /* PNG_USE_LOCAL_ARRAYS */
357
      png_uint_32 length = png_read_chunk_header(png_ptr);
358
      PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
A
Andreas Dilger 已提交
359 360 361 362

      /* This should be a binary subdivision search or a hash for
       * matching the chunk name rather than a linear search.
       */
363 364
      if (!png_memcmp(chunk_name, png_IDAT, 4))
        if (png_ptr->mode & PNG_AFTER_IDAT)
365 366
          png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;

367
      if (!png_memcmp(chunk_name, png_IHDR, 4))
A
Andreas Dilger 已提交
368
         png_handle_IHDR(png_ptr, info_ptr, length);
369
      else if (!png_memcmp(chunk_name, png_IEND, 4))
A
Andreas Dilger 已提交
370
         png_handle_IEND(png_ptr, info_ptr, length);
371
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
372
      else if (png_handle_as_unknown(png_ptr, chunk_name))
373
      {
374
         if (!png_memcmp(chunk_name, png_IDAT, 4))
375 376
            png_ptr->mode |= PNG_HAVE_IDAT;
         png_handle_unknown(png_ptr, info_ptr, length);
377
         if (!png_memcmp(chunk_name, png_PLTE, 4))
378
            png_ptr->mode |= PNG_HAVE_PLTE;
379
         else if (!png_memcmp(chunk_name, png_IDAT, 4))
380 381 382 383 384 385 386 387 388 389
         {
            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
390
      else if (!png_memcmp(chunk_name, png_PLTE, 4))
391
         png_handle_PLTE(png_ptr, info_ptr, length);
392
      else if (!png_memcmp(chunk_name, png_IDAT, 4))
A
Andreas Dilger 已提交
393 394 395 396 397 398 399 400 401 402 403 404
      {
         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)
405
      else if (!png_memcmp(chunk_name, png_bKGD, 4))
A
Andreas Dilger 已提交
406
         png_handle_bKGD(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
407 408
#endif
#if defined(PNG_READ_cHRM_SUPPORTED)
409
      else if (!png_memcmp(chunk_name, png_cHRM, 4))
A
Andreas Dilger 已提交
410
         png_handle_cHRM(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
411
#endif
A
Andreas Dilger 已提交
412
#if defined(PNG_READ_gAMA_SUPPORTED)
413
      else if (!png_memcmp(chunk_name, png_gAMA, 4))
A
Andreas Dilger 已提交
414
         png_handle_gAMA(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
415 416
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
417
      else if (!png_memcmp(chunk_name, png_hIST, 4))
A
Andreas Dilger 已提交
418
         png_handle_hIST(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
419
#endif
A
Andreas Dilger 已提交
420
#if defined(PNG_READ_oFFs_SUPPORTED)
421
      else if (!png_memcmp(chunk_name, png_oFFs, 4))
A
Andreas Dilger 已提交
422 423 424
         png_handle_oFFs(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_pCAL_SUPPORTED)
425
      else if (!png_memcmp(chunk_name, png_pCAL, 4))
A
Andreas Dilger 已提交
426 427
         png_handle_pCAL(png_ptr, info_ptr, length);
#endif
428
#if defined(PNG_READ_sCAL_SUPPORTED)
429
      else if (!png_memcmp(chunk_name, png_sCAL, 4))
430 431
         png_handle_sCAL(png_ptr, info_ptr, length);
#endif
G
Guy Schalnat 已提交
432
#if defined(PNG_READ_pHYs_SUPPORTED)
433
      else if (!png_memcmp(chunk_name, png_pHYs, 4))
A
Andreas Dilger 已提交
434
         png_handle_pHYs(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
435
#endif
A
Andreas Dilger 已提交
436
#if defined(PNG_READ_sBIT_SUPPORTED)
437
      else if (!png_memcmp(chunk_name, png_sBIT, 4))
A
Andreas Dilger 已提交
438 439
         png_handle_sBIT(png_ptr, info_ptr, length);
#endif
440
#if defined(PNG_READ_sRGB_SUPPORTED)
441
      else if (!png_memcmp(chunk_name, png_sRGB, 4))
442 443
         png_handle_sRGB(png_ptr, info_ptr, length);
#endif
444
#if defined(PNG_READ_iCCP_SUPPORTED)
445
      else if (!png_memcmp(chunk_name, png_iCCP, 4))
446 447 448
         png_handle_iCCP(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_sPLT_SUPPORTED)
449
      else if (!png_memcmp(chunk_name, png_sPLT, 4))
450 451
         png_handle_sPLT(png_ptr, info_ptr, length);
#endif
A
Andreas Dilger 已提交
452
#if defined(PNG_READ_tEXt_SUPPORTED)
453
      else if (!png_memcmp(chunk_name, png_tEXt, 4))
A
Andreas Dilger 已提交
454
         png_handle_tEXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
455 456
#endif
#if defined(PNG_READ_tIME_SUPPORTED)
457
      else if (!png_memcmp(chunk_name, png_tIME, 4))
A
Andreas Dilger 已提交
458
         png_handle_tIME(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
459
#endif
A
Andreas Dilger 已提交
460
#if defined(PNG_READ_tRNS_SUPPORTED)
461
      else if (!png_memcmp(chunk_name, png_tRNS, 4))
A
Andreas Dilger 已提交
462
         png_handle_tRNS(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
463 464
#endif
#if defined(PNG_READ_zTXt_SUPPORTED)
465
      else if (!png_memcmp(chunk_name, png_zTXt, 4))
A
Andreas Dilger 已提交
466
         png_handle_zTXt(png_ptr, info_ptr, length);
467 468
#endif
#if defined(PNG_READ_iTXt_SUPPORTED)
469
      else if (!png_memcmp(chunk_name, png_iTXt, 4))
470
         png_handle_iTXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
471
#endif
A
Andreas Dilger 已提交
472 473
      else
         png_handle_unknown(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
474 475
   }
}
476
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
477

A
Andreas Dilger 已提交
478
/* optional call to update the users info_ptr structure */
479
void PNGAPI
A
Andreas Dilger 已提交
480
png_read_update_info(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
481
{
482
   png_debug(1, "in png_read_update_info");
483
   if (png_ptr == NULL) return;
G
Guy Schalnat 已提交
484
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
485
      png_read_start_row(png_ptr);
486 487 488
   else
      png_warning(png_ptr,
      "Ignoring extra png_read_update_info() call; row buffer not reallocated");
A
Andreas Dilger 已提交
489
   png_read_transform_info(png_ptr, info_ptr);
G
Guy Schalnat 已提交
490 491
}

492
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
493 494
/* Initialize palette, background, etc, after transformations
 * are set, but before any reading takes place.  This allows
495
 * the user to obtain a gamma-corrected palette, for example.
496 497
 * If the user doesn't call this, we will do it ourselves.
 */
498
void PNGAPI
G
Guy Schalnat 已提交
499
png_start_read_image(png_structp png_ptr)
G
Guy Schalnat 已提交
500
{
501
   png_debug(1, "in png_start_read_image");
502
   if (png_ptr == NULL) return;
G
Guy Schalnat 已提交
503
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
504
      png_read_start_row(png_ptr);
G
Guy Schalnat 已提交
505
}
506
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
507

508
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
509
void PNGAPI
G
Guy Schalnat 已提交
510
png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
G
Guy Schalnat 已提交
511
{
512
#ifdef PNG_USE_LOCAL_ARRAYS
513 514 515 516
   PNG_CONST PNG_IDAT;
   PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
      0xff};
   PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
517
#endif
G
Guy Schalnat 已提交
518
   int ret;
519
   if (png_ptr == NULL) return;
520
   png_debug2(1, "in png_read_row (row %lu, pass %d)",
521
      (unsigned long) png_ptr->row_number, png_ptr->pass);
G
Guy Schalnat 已提交
522
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
G
Guy Schalnat 已提交
523
      png_read_start_row(png_ptr);
524 525 526 527 528
   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)
529
      png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined");
530 531 532
#endif
#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
   if (png_ptr->transformations & PNG_FILLER)
533
      png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined");
534 535 536
#endif
#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED)
   if (png_ptr->transformations & PNG_PACKSWAP)
537
      png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined");
538 539 540
#endif
#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
   if (png_ptr->transformations & PNG_PACK)
541
      png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined");
542 543 544
#endif
#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
   if (png_ptr->transformations & PNG_SHIFT)
545
      png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined");
546 547 548
#endif
#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
   if (png_ptr->transformations & PNG_BGR)
549
      png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined");
550 551 552
#endif
#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
   if (png_ptr->transformations & PNG_SWAP_BYTES)
553
      png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined");
554 555
#endif
   }
G
Guy Schalnat 已提交
556

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

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

A
Andreas Dilger 已提交
637 638
   png_ptr->zstream.next_out = png_ptr->row_buf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
G
Guy Schalnat 已提交
639 640
   do
   {
A
Andreas Dilger 已提交
641
      if (!(png_ptr->zstream.avail_in))
G
Guy Schalnat 已提交
642 643 644
      {
         while (!png_ptr->idat_size)
         {
A
Andreas Dilger 已提交
645
            png_crc_finish(png_ptr, 0);
G
Guy Schalnat 已提交
646

647
            png_ptr->idat_size = png_read_chunk_header(png_ptr);
A
Andreas Dilger 已提交
648 649
            if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
               png_error(png_ptr, "Not enough image data");
G
Guy Schalnat 已提交
650
         }
A
Andreas Dilger 已提交
651 652
         png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
         png_ptr->zstream.next_in = png_ptr->zbuf;
G
Guy Schalnat 已提交
653
         if (png_ptr->zbuf_size > png_ptr->idat_size)
A
Andreas Dilger 已提交
654
            png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
A
Andreas Dilger 已提交
655 656
         png_crc_read(png_ptr, png_ptr->zbuf,
            (png_size_t)png_ptr->zstream.avail_in);
A
Andreas Dilger 已提交
657
         png_ptr->idat_size -= png_ptr->zstream.avail_in;
G
Guy Schalnat 已提交
658
      }
A
Andreas Dilger 已提交
659
      ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
G
Guy Schalnat 已提交
660 661
      if (ret == Z_STREAM_END)
      {
A
Andreas Dilger 已提交
662
         if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
G
Guy Schalnat 已提交
663
            png_ptr->idat_size)
664
            png_benign_error(png_ptr, "Extra compressed data");
A
Andreas Dilger 已提交
665
         png_ptr->mode |= PNG_AFTER_IDAT;
G
Guy Schalnat 已提交
666
         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
G
Guy Schalnat 已提交
667
         break;
G
Guy Schalnat 已提交
668 669
      }
      if (ret != Z_OK)
A
Andreas Dilger 已提交
670
         png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
G
Guy Schalnat 已提交
671
                   "Decompression error");
A
Andreas Dilger 已提交
672 673

   } while (png_ptr->zstream.avail_out);
G
Guy Schalnat 已提交
674 675 676 677 678 679

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

683
   if (png_ptr->row_buf[0])
G
Guy Schalnat 已提交
684 685 686
   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 已提交
687

688
   png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1);
689

690
#if defined(PNG_MNG_FEATURES_SUPPORTED)
691
   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
692 693 694 695 696 697
      (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 已提交
698

699

700
   if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
G
Guy Schalnat 已提交
701 702
      png_do_read_transformations(png_ptr);

G
Guy Schalnat 已提交
703
#if defined(PNG_READ_INTERLACING_SUPPORTED)
G
Guy Schalnat 已提交
704 705 706 707 708
   /* blow up interlaced rows to full size */
   if (png_ptr->interlaced &&
      (png_ptr->transformations & PNG_INTERLACE))
   {
      if (png_ptr->pass < 6)
709
/*       old interface (pre-1.0.9):
G
Guy Schalnat 已提交
710
         png_do_read_interlace(&(png_ptr->row_info),
A
Andreas Dilger 已提交
711
            png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
712 713
 */
         png_do_read_interlace(png_ptr);
G
Guy Schalnat 已提交
714

A
Andreas Dilger 已提交
715
      if (dsp_row != NULL)
G
Guy Schalnat 已提交
716 717
         png_combine_row(png_ptr, dsp_row,
            png_pass_dsp_mask[png_ptr->pass]);
A
Andreas Dilger 已提交
718
      if (row != NULL)
G
Guy Schalnat 已提交
719 720 721 722
         png_combine_row(png_ptr, row,
            png_pass_mask[png_ptr->pass]);
   }
   else
G
Guy Schalnat 已提交
723
#endif
G
Guy Schalnat 已提交
724
   {
A
Andreas Dilger 已提交
725
      if (row != NULL)
G
Guy Schalnat 已提交
726
         png_combine_row(png_ptr, row, 0xff);
A
Andreas Dilger 已提交
727
      if (dsp_row != NULL)
G
Guy Schalnat 已提交
728 729 730
         png_combine_row(png_ptr, dsp_row, 0xff);
   }
   png_read_finish_row(png_ptr);
731 732 733

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

737
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
738
/* Read one or more rows of image data.  If the image is interlaced,
739 740
 * and png_set_interlace_handling() has been called, the rows need to
 * contain the contents of the rows from the previous pass.  If the
741
 * image has alpha or transparency, and png_handle_alpha()[*] has been
742 743
 * called, the rows contents must be initialized to the contents of the
 * screen.
744
 *
745 746 747 748 749 750 751 752 753 754 755 756 757
 * "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.
758
 *
759
 * [*] png_handle_alpha() does not exist yet, as of this version of libpng
760
 */
G
Guy Schalnat 已提交
761

762
void PNGAPI
G
Guy Schalnat 已提交
763
png_read_rows(png_structp png_ptr, png_bytepp row,
G
Guy Schalnat 已提交
764
   png_bytepp display_row, png_uint_32 num_rows)
G
Guy Schalnat 已提交
765
{
G
Guy Schalnat 已提交
766 767 768
   png_uint_32 i;
   png_bytepp rp;
   png_bytepp dp;
G
Guy Schalnat 已提交
769

770
   png_debug(1, "in png_read_rows");
771
   if (png_ptr == NULL) return;
G
Guy Schalnat 已提交
772 773
   rp = row;
   dp = display_row;
774
   if (rp != NULL && dp != NULL)
775 776 777 778
      for (i = 0; i < num_rows; i++)
      {
         png_bytep rptr = *rp++;
         png_bytep dptr = *dp++;
779

780 781
         png_read_row(png_ptr, rptr, dptr);
      }
782
   else if (rp != NULL)
783 784
      for (i = 0; i < num_rows; i++)
      {
785
         png_bytep rptr = *rp;
786
         png_read_row(png_ptr, rptr, NULL);
787 788
         rp++;
      }
789
   else if (dp != NULL)
790 791 792
      for (i = 0; i < num_rows; i++)
      {
         png_bytep dptr = *dp;
793
         png_read_row(png_ptr, NULL, dptr);
794
         dp++;
795
      }
G
Guy Schalnat 已提交
796
}
797
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
798

799
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
800
/* Read the entire image.  If the image has an alpha channel or a tRNS
801
 * chunk, and you have called png_handle_alpha()[*], you will need to
802 803 804 805 806 807 808
 * 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.
809
 *
810
 * [*] png_handle_alpha() does not exist yet, as of this version of libpng
811
 */
812
void PNGAPI
G
Guy Schalnat 已提交
813
png_read_image(png_structp png_ptr, png_bytepp image)
G
Guy Schalnat 已提交
814
{
815
   png_uint_32 i, image_height;
G
Guy Schalnat 已提交
816
   int pass, j;
G
Guy Schalnat 已提交
817
   png_bytepp rp;
G
Guy Schalnat 已提交
818

819
   png_debug(1, "in png_read_image");
820
   if (png_ptr == NULL) return;
821 822

#ifdef PNG_READ_INTERLACING_SUPPORTED
G
Guy Schalnat 已提交
823
   pass = png_set_interlace_handling(png_ptr);
824 825 826
#else
   if (png_ptr->interlaced)
      png_error(png_ptr,
827
        "Cannot read interlaced image -- interlace handler disabled");
828 829 830
   pass = 1;
#endif

831

832 833
   image_height=png_ptr->height;
   png_ptr->num_rows = image_height; /* Make sure this is set correctly */
G
Guy Schalnat 已提交
834

G
Guy Schalnat 已提交
835 836 837
   for (j = 0; j < pass; j++)
   {
      rp = image;
838
      for (i = 0; i < image_height; i++)
G
Guy Schalnat 已提交
839
      {
840
         png_read_row(png_ptr, *rp, NULL);
G
Guy Schalnat 已提交
841 842 843 844
         rp++;
      }
   }
}
845
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
846

847
#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
A
Andreas Dilger 已提交
848
/* Read the end of the PNG file.  Will not read past the end of the
849 850 851
 * 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.
 */
852
void PNGAPI
A
Andreas Dilger 已提交
853
png_read_end(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
854
{
855
   png_debug(1, "in png_read_end");
856
   if (png_ptr == NULL) return;
A
Andreas Dilger 已提交
857
   png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
G
Guy Schalnat 已提交
858 859 860

   do
   {
861
#ifdef PNG_USE_LOCAL_ARRAYS
862 863 864 865
      PNG_CONST PNG_IHDR;
      PNG_CONST PNG_IDAT;
      PNG_CONST PNG_IEND;
      PNG_CONST PNG_PLTE;
866
#if defined(PNG_READ_bKGD_SUPPORTED)
867
      PNG_CONST PNG_bKGD;
868 869
#endif
#if defined(PNG_READ_cHRM_SUPPORTED)
870
      PNG_CONST PNG_cHRM;
871 872
#endif
#if defined(PNG_READ_gAMA_SUPPORTED)
873
      PNG_CONST PNG_gAMA;
874 875
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
876
      PNG_CONST PNG_hIST;
877
#endif
878
#if defined(PNG_READ_iCCP_SUPPORTED)
879
      PNG_CONST PNG_iCCP;
880 881
#endif
#if defined(PNG_READ_iTXt_SUPPORTED)
882
      PNG_CONST PNG_iTXt;
883
#endif
884
#if defined(PNG_READ_oFFs_SUPPORTED)
885
      PNG_CONST PNG_oFFs;
886 887
#endif
#if defined(PNG_READ_pCAL_SUPPORTED)
888
      PNG_CONST PNG_pCAL;
889 890
#endif
#if defined(PNG_READ_pHYs_SUPPORTED)
891
      PNG_CONST PNG_pHYs;
892 893
#endif
#if defined(PNG_READ_sBIT_SUPPORTED)
894
      PNG_CONST PNG_sBIT;
895
#endif
896
#if defined(PNG_READ_sCAL_SUPPORTED)
897
      PNG_CONST PNG_sCAL;
898 899
#endif
#if defined(PNG_READ_sPLT_SUPPORTED)
900
      PNG_CONST PNG_sPLT;
901
#endif
902
#if defined(PNG_READ_sRGB_SUPPORTED)
903
      PNG_CONST PNG_sRGB;
904 905
#endif
#if defined(PNG_READ_tEXt_SUPPORTED)
906
      PNG_CONST PNG_tEXt;
907 908
#endif
#if defined(PNG_READ_tIME_SUPPORTED)
909
      PNG_CONST PNG_tIME;
910 911
#endif
#if defined(PNG_READ_tRNS_SUPPORTED)
912
      PNG_CONST PNG_tRNS;
913 914
#endif
#if defined(PNG_READ_zTXt_SUPPORTED)
915
      PNG_CONST PNG_zTXt;
916
#endif
917
#endif /* PNG_USE_LOCAL_ARRAYS */
918 919
      png_uint_32 length = png_read_chunk_header(png_ptr);
      PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
A
Andreas Dilger 已提交
920

921
      if (!png_memcmp(chunk_name, png_IHDR, 4))
A
Andreas Dilger 已提交
922
         png_handle_IHDR(png_ptr, info_ptr, length);
923
      else if (!png_memcmp(chunk_name, png_IEND, 4))
924 925
         png_handle_IEND(png_ptr, info_ptr, length);
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
926
      else if (png_handle_as_unknown(png_ptr, chunk_name))
927
      {
928
         if (!png_memcmp(chunk_name, png_IDAT, 4))
929
         {
930
            if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
931
               png_benign_error(png_ptr, "Too many IDATs found");
932 933
         }
         png_handle_unknown(png_ptr, info_ptr, length);
934
         if (!png_memcmp(chunk_name, png_PLTE, 4))
935 936 937
            png_ptr->mode |= PNG_HAVE_PLTE;
      }
#endif
938
      else if (!png_memcmp(chunk_name, png_IDAT, 4))
A
Andreas Dilger 已提交
939 940 941 942
      {
         /* Zero length IDATs are legal after the last IDAT has been
          * read, but not after other chunks have been read.
          */
943
         if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
944
            png_benign_error(png_ptr, "Too many IDATs found");
945
         png_crc_finish(png_ptr, length);
A
Andreas Dilger 已提交
946
      }
947
      else if (!png_memcmp(chunk_name, png_PLTE, 4))
A
Andreas Dilger 已提交
948
         png_handle_PLTE(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
949
#if defined(PNG_READ_bKGD_SUPPORTED)
950
      else if (!png_memcmp(chunk_name, png_bKGD, 4))
A
Andreas Dilger 已提交
951
         png_handle_bKGD(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
952 953
#endif
#if defined(PNG_READ_cHRM_SUPPORTED)
954
      else if (!png_memcmp(chunk_name, png_cHRM, 4))
A
Andreas Dilger 已提交
955 956 957
         png_handle_cHRM(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_gAMA_SUPPORTED)
958
      else if (!png_memcmp(chunk_name, png_gAMA, 4))
A
Andreas Dilger 已提交
959 960 961
         png_handle_gAMA(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
962
      else if (!png_memcmp(chunk_name, png_hIST, 4))
A
Andreas Dilger 已提交
963
         png_handle_hIST(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
964 965
#endif
#if defined(PNG_READ_oFFs_SUPPORTED)
966
      else if (!png_memcmp(chunk_name, png_oFFs, 4))
A
Andreas Dilger 已提交
967
         png_handle_oFFs(png_ptr, info_ptr, length);
A
Andreas Dilger 已提交
968 969
#endif
#if defined(PNG_READ_pCAL_SUPPORTED)
970
      else if (!png_memcmp(chunk_name, png_pCAL, 4))
A
Andreas Dilger 已提交
971 972
         png_handle_pCAL(png_ptr, info_ptr, length);
#endif
973
#if defined(PNG_READ_sCAL_SUPPORTED)
974
      else if (!png_memcmp(chunk_name, png_sCAL, 4))
975 976
         png_handle_sCAL(png_ptr, info_ptr, length);
#endif
A
Andreas Dilger 已提交
977
#if defined(PNG_READ_pHYs_SUPPORTED)
978
      else if (!png_memcmp(chunk_name, png_pHYs, 4))
A
Andreas Dilger 已提交
979 980 981
         png_handle_pHYs(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_sBIT_SUPPORTED)
982
      else if (!png_memcmp(chunk_name, png_sBIT, 4))
A
Andreas Dilger 已提交
983
         png_handle_sBIT(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
984
#endif
985
#if defined(PNG_READ_sRGB_SUPPORTED)
986
      else if (!png_memcmp(chunk_name, png_sRGB, 4))
987 988
         png_handle_sRGB(png_ptr, info_ptr, length);
#endif
989
#if defined(PNG_READ_iCCP_SUPPORTED)
990
      else if (!png_memcmp(chunk_name, png_iCCP, 4))
991 992 993
         png_handle_iCCP(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_sPLT_SUPPORTED)
994
      else if (!png_memcmp(chunk_name, png_sPLT, 4))
995 996
         png_handle_sPLT(png_ptr, info_ptr, length);
#endif
G
Guy Schalnat 已提交
997
#if defined(PNG_READ_tEXt_SUPPORTED)
998
      else if (!png_memcmp(chunk_name, png_tEXt, 4))
A
Andreas Dilger 已提交
999
         png_handle_tEXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
1000
#endif
A
Andreas Dilger 已提交
1001
#if defined(PNG_READ_tIME_SUPPORTED)
1002
      else if (!png_memcmp(chunk_name, png_tIME, 4))
A
Andreas Dilger 已提交
1003 1004 1005
         png_handle_tIME(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_tRNS_SUPPORTED)
1006
      else if (!png_memcmp(chunk_name, png_tRNS, 4))
A
Andreas Dilger 已提交
1007 1008
         png_handle_tRNS(png_ptr, info_ptr, length);
#endif
G
Guy Schalnat 已提交
1009
#if defined(PNG_READ_zTXt_SUPPORTED)
1010
      else if (!png_memcmp(chunk_name, png_zTXt, 4))
A
Andreas Dilger 已提交
1011
         png_handle_zTXt(png_ptr, info_ptr, length);
1012 1013
#endif
#if defined(PNG_READ_iTXt_SUPPORTED)
1014
      else if (!png_memcmp(chunk_name, png_iTXt, 4))
1015
         png_handle_iTXt(png_ptr, info_ptr, length);
G
Guy Schalnat 已提交
1016
#endif
G
Guy Schalnat 已提交
1017
      else
A
Andreas Dilger 已提交
1018 1019
         png_handle_unknown(png_ptr, info_ptr, length);
   } while (!(png_ptr->mode & PNG_HAVE_IEND));
G
Guy Schalnat 已提交
1020
}
1021
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
1022 1023

/* free all memory used by the read */
1024
void PNGAPI
G
Guy Schalnat 已提交
1025
png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
A
Andreas Dilger 已提交
1026
   png_infopp end_info_ptr_ptr)
G
Guy Schalnat 已提交
1027 1028
{
   png_structp png_ptr = NULL;
A
Andreas Dilger 已提交
1029
   png_infop info_ptr = NULL, end_info_ptr = NULL;
1030
#ifdef PNG_USER_MEM_SUPPORTED
1031 1032
   png_free_ptr free_fn = NULL;
   png_voidp mem_ptr = NULL;
1033
#endif
G
Guy Schalnat 已提交
1034

1035
   png_debug(1, "in png_destroy_read_struct");
A
Andreas Dilger 已提交
1036
   if (png_ptr_ptr != NULL)
G
Guy Schalnat 已提交
1037
      png_ptr = *png_ptr_ptr;
1038 1039 1040 1041 1042 1043 1044
   if (png_ptr == NULL)
      return;

#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
   mem_ptr = png_ptr->mem_ptr;
#endif
G
Guy Schalnat 已提交
1045

A
Andreas Dilger 已提交
1046
   if (info_ptr_ptr != NULL)
G
Guy Schalnat 已提交
1047 1048
      info_ptr = *info_ptr_ptr;

A
Andreas Dilger 已提交
1049
   if (end_info_ptr_ptr != NULL)
A
Andreas Dilger 已提交
1050
      end_info_ptr = *end_info_ptr_ptr;
G
Guy Schalnat 已提交
1051

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

A
Andreas Dilger 已提交
1054
   if (info_ptr != NULL)
G
Guy Schalnat 已提交
1055
   {
1056
#if defined(PNG_TEXT_SUPPORTED)
1057
      png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
1058
#endif
1059 1060

#ifdef PNG_USER_MEM_SUPPORTED
1061 1062
      png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
          (png_voidp)mem_ptr);
1063
#else
A
Andreas Dilger 已提交
1064
      png_destroy_struct((png_voidp)info_ptr);
1065
#endif
1066
      *info_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1067 1068
   }

A
Andreas Dilger 已提交
1069
   if (end_info_ptr != NULL)
G
Guy Schalnat 已提交
1070
   {
1071
#if defined(PNG_READ_TEXT_SUPPORTED)
1072
      png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
1073
#endif
1074
#ifdef PNG_USER_MEM_SUPPORTED
1075 1076
      png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
         (png_voidp)mem_ptr);
1077
#else
A
Andreas Dilger 已提交
1078
      png_destroy_struct((png_voidp)end_info_ptr);
1079
#endif
1080
      *end_info_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1081 1082
   }

A
Andreas Dilger 已提交
1083
   if (png_ptr != NULL)
G
Guy Schalnat 已提交
1084
   {
1085
#ifdef PNG_USER_MEM_SUPPORTED
1086 1087
      png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
          (png_voidp)mem_ptr);
1088
#else
A
Andreas Dilger 已提交
1089
      png_destroy_struct((png_voidp)png_ptr);
1090
#endif
1091
      *png_ptr_ptr = NULL;
G
Guy Schalnat 已提交
1092 1093 1094
   }
}

A
Andreas Dilger 已提交
1095
/* free all memory used by the read (old method) */
1096
void /* PRIVATE */
A
Andreas Dilger 已提交
1097
png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
G
Guy Schalnat 已提交
1098
{
1099
#ifdef PNG_SETJMP_SUPPORTED
G
Guy Schalnat 已提交
1100
   jmp_buf tmp_jmp;
1101
#endif
G
Guy Schalnat 已提交
1102 1103 1104
   png_error_ptr error_fn;
   png_error_ptr warning_fn;
   png_voidp error_ptr;
1105 1106 1107
#ifdef PNG_USER_MEM_SUPPORTED
   png_free_ptr free_fn;
#endif
G
Guy Schalnat 已提交
1108

1109
   png_debug(1, "in png_read_destroy");
A
Andreas Dilger 已提交
1110
   if (info_ptr != NULL)
A
Andreas Dilger 已提交
1111
      png_info_destroy(png_ptr, info_ptr);
G
Guy Schalnat 已提交
1112

A
Andreas Dilger 已提交
1113
   if (end_info_ptr != NULL)
A
Andreas Dilger 已提交
1114
      png_info_destroy(png_ptr, end_info_ptr);
G
Guy Schalnat 已提交
1115

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

A
Andreas Dilger 已提交
1201
   inflateEnd(&png_ptr->zstream);
G
Guy Schalnat 已提交
1202
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
A
Andreas Dilger 已提交
1203
   png_free(png_ptr, png_ptr->save_buffer);
G
Guy Schalnat 已提交
1204
#endif
G
Guy Schalnat 已提交
1205

1206 1207 1208 1209 1210 1211
#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 已提交
1212 1213 1214
   /* Save the important info out of the png_struct, in case it is
    * being used again.
    */
1215
#ifdef PNG_SETJMP_SUPPORTED
1216
   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
1217
#endif
G
Guy Schalnat 已提交
1218 1219 1220 1221

   error_fn = png_ptr->error_fn;
   warning_fn = png_ptr->warning_fn;
   error_ptr = png_ptr->error_ptr;
1222 1223 1224
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
#endif
G
Guy Schalnat 已提交
1225

1226
   png_memset(png_ptr, 0, png_sizeof(png_struct));
G
Guy Schalnat 已提交
1227 1228 1229 1230

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

1235
#ifdef PNG_SETJMP_SUPPORTED
1236
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
1237 1238
#endif

G
Guy Schalnat 已提交
1239
}
1240

1241
void PNGAPI
1242 1243
png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
{
1244
   if (png_ptr == NULL) return;
1245 1246
   png_ptr->read_row_fn = read_row_fn;
}
1247

1248 1249

#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
1250
#if defined(PNG_INFO_IMAGE_SUPPORTED)
1251 1252
void PNGAPI
png_read_png(png_structp png_ptr, png_infop info_ptr,
1253 1254 1255 1256 1257
                           int transforms,
                           voidp params)
{
   int row;

1258
   if (png_ptr == NULL) return;
1259
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1260 1261
   /* invert the alpha channel from opacity to transparency
    */
1262 1263 1264 1265
   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
       png_set_invert_alpha(png_ptr);
#endif

1266
   /* png_read_info() gives us all of the information from the
1267 1268 1269
    * PNG file before the first IDAT (image data chunk).
    */
   png_read_info(png_ptr, info_ptr);
1270 1271
   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()");
1272 1273 1274 1275

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

#if defined(PNG_READ_16_TO_8_SUPPORTED)
1276 1277
   /* tell libpng to strip 16 bit/color files down to 8 bits per color
    */
1278 1279 1280 1281 1282
   if (transforms & PNG_TRANSFORM_STRIP_16)
       png_set_strip_16(png_ptr);
#endif

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

1290
#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
1291
   /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
1292 1293 1294 1295 1296 1297 1298 1299
    * 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
1300 1301
    * (not useful if you are using png_set_packing).
    */
1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312
   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)
1313 1314 1315 1316
       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);
1317 1318
#endif

1319 1320
   /* We don't handle background color or gamma transformation or dithering.
    */
1321 1322

#if defined(PNG_READ_INVERT_SUPPORTED)
1323 1324
   /* invert monochrome files to have 0 as white and 1 as black
    */
1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344
   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)
1345 1346
   /* flip the RGB pixels to BGR (or RGBA to BGRA)
    */
1347 1348 1349 1350 1351
   if (transforms & PNG_TRANSFORM_BGR)
       png_set_bgr(png_ptr);
#endif

#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1352 1353
   /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
    */
1354 1355 1356 1357 1358
   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
       png_set_swap_alpha(png_ptr);
#endif

#if defined(PNG_READ_SWAP_SUPPORTED)
1359 1360
   /* swap bytes of 16 bit files to least significant byte first
    */
1361 1362 1363 1364 1365 1366 1367 1368
   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
1369
    * update the palette for you (i.e., you selected such a transform above).
1370 1371 1372 1373 1374
    */
   png_read_update_info(png_ptr, info_ptr);

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

1375
#ifdef PNG_FREE_ME_SUPPORTED
1376
   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1377
#endif
1378
   if (info_ptr->row_pointers == NULL)
1379
   {
1380
#ifdef PNG_CALLOC_SUPPORTED
1381
      info_ptr->row_pointers = (png_bytepp)png_calloc(png_ptr,
1382
         info_ptr->height * png_sizeof(png_bytep));
1383 1384 1385
#else
      info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
         info_ptr->height * png_sizeof(png_bytep));
1386 1387
      png_memset(info_ptr->row_pointers, 0, info_ptr->height
         * png_sizeof(png_bytep));
1388
#endif
1389
#ifdef PNG_FREE_ME_SUPPORTED
1390
      info_ptr->free_me |= PNG_FREE_ROWS;
1391 1392
#endif
      for (row = 0; row < (int)info_ptr->height; row++)
1393
         info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
1394
            png_get_rowbytes(png_ptr, info_ptr));
1395
   }
1396 1397 1398 1399 1400 1401

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

1403 1404
   transforms = transforms; /* quiet compiler warnings */
   params = params;
1405

1406
}
1407
#endif /* PNG_INFO_IMAGE_SUPPORTED */
1408
#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
1409
#endif /* PNG_READ_SUPPORTED */