pngrutil.c 119.7 KB
Newer Older
1

A
Andreas Dilger 已提交
2
/* pngrutil.c - utilities to read a PNG file
3
 *
4
 * Last changed in libpng 1.5.10 [(PENDING RELEASE)]
5
 * Copyright (c) 1998-2012 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
 * This code is released under the libpng license.
10
 * For conditions of distribution and use, see the disclaimer
11
 * and license in png.h
12
 *
13
 * This file contains routines that are only called from within
14 15
 * libpng itself during the course of reading an image.
 */
G
Guy Schalnat 已提交
16

17
#include "pngpriv.h"
18

19 20 21 22
#ifdef PNG_READ_SUPPORTED

#define png_strtod(p,a,b) strtod(a,b)

23
png_uint_32 PNGAPI
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
png_get_uint_31(png_structp png_ptr, png_const_bytep buf)
{
   png_uint_32 uval = png_get_uint_32(buf);

   if (uval > PNG_UINT_31_MAX)
      png_error(png_ptr, "PNG unsigned integer out of range");

   return (uval);
}

#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED)
/* The following is a variation on the above for use with the fixed
 * point values used for gAMA and cHRM.  Instead of png_error it
 * issues a warning and returns (-1) - an invalid value because both
 * gAMA and cHRM use *unsigned* integers for fixed point values.
 */
#define PNG_FIXED_ERROR (-1)

static png_fixed_point /* PRIVATE */
png_get_fixed_point(png_structp png_ptr, png_const_bytep buf)
G
[devel]  
Glenn Randers-Pehrson 已提交
44
{
45 46 47 48 49 50 51 52 53 54
   png_uint_32 uval = png_get_uint_32(buf);

   if (uval <= PNG_UINT_31_MAX)
      return (png_fixed_point)uval; /* known to be in range */

   /* The caller can turn off the warning by passing NULL. */
   if (png_ptr != NULL)
      png_warning(png_ptr, "PNG fixed point integer out of range");

   return PNG_FIXED_ERROR;
G
[devel]  
Glenn Randers-Pehrson 已提交
55
}
56 57 58 59 60 61 62 63 64 65 66 67
#endif

#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
/* NOTE: the read macros will obscure these definitions, so that if
 * PNG_USE_READ_MACROS is set the library will not use them internally,
 * but the APIs will still be available externally.
 *
 * The parentheses around "PNGAPI function_name" in the following three
 * functions are necessary because they allow the macros to co-exist with
 * these (unused but exported) functions.
 */

68
/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
69 70
png_uint_32 (PNGAPI
png_get_uint_32)(png_const_bytep buf)
G
Guy Schalnat 已提交
71
{
72 73 74 75 76
   png_uint_32 uval =
       ((png_uint_32)(*(buf    )) << 24) +
       ((png_uint_32)(*(buf + 1)) << 16) +
       ((png_uint_32)(*(buf + 2)) <<  8) +
       ((png_uint_32)(*(buf + 3))      ) ;
G
Guy Schalnat 已提交
77

78
   return uval;
G
Guy Schalnat 已提交
79 80
}

81
/* Grab a signed 32-bit integer from a buffer in big-endian format.  The
82 83 84
 * data is stored in the PNG file in two's complement format and there
 * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore
 * the following code does a two's complement to native conversion.
85
 */
86 87
png_int_32 (PNGAPI
png_get_int_32)(png_const_bytep buf)
A
Andreas Dilger 已提交
88
{
89
   png_uint_32 uval = png_get_uint_32(buf);
90
   if ((uval & 0x80000000) == 0) /* non-negative */
91
      return uval;
A
Andreas Dilger 已提交
92

93
   uval = (uval ^ 0xffffffff) + 1;  /* 2's complement: -x = ~x+1 */
94
   return -(png_int_32)uval;
A
Andreas Dilger 已提交
95 96
}

97
/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
98 99
png_uint_16 (PNGAPI
png_get_uint_16)(png_const_bytep buf)
G
Guy Schalnat 已提交
100
{
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
   /* ANSI-C requires an int value to accomodate at least 16 bits so this
    * works and allows the compiler not to worry about possible narrowing
    * on 32 bit systems.  (Pre-ANSI systems did not make integers smaller
    * than 16 bits either.)
    */
   unsigned int val =
       ((unsigned int)(*buf) << 8) +
       ((unsigned int)(*(buf + 1)));

   return (png_uint_16)val;
}

#endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */

/* Read and check the PNG file signature */
void /* PRIVATE */
png_read_sig(png_structp png_ptr, png_infop info_ptr)
{
   png_size_t num_checked, num_to_check;

   /* Exit if the user application does not expect a signature. */
   if (png_ptr->sig_bytes >= 8)
      return;

   num_checked = png_ptr->sig_bytes;
   num_to_check = 8 - num_checked;
127

128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
#ifdef PNG_IO_STATE_SUPPORTED
   png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE;
#endif

   /* The signature must be serialized in a single I/O call. */
   png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
   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");
   }
   if (num_checked < 3)
      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
146 147
}

148 149 150 151 152 153 154 155 156 157 158 159 160
/* Read the chunk header (length + type name).
 * Put the type name into png_ptr->chunk_name, and return the length.
 */
png_uint_32 /* PRIVATE */
png_read_chunk_header(png_structp png_ptr)
{
   png_byte buf[8];
   png_uint_32 length;

#ifdef PNG_IO_STATE_SUPPORTED
   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
#endif

161 162 163
   /* Read the length and the chunk name.
    * This must be performed in a single I/O call.
    */
164 165 166
   png_read_data(png_ptr, buf, 8);
   length = png_get_uint_31(png_ptr, buf);

167
   /* Put the chunk name into png_ptr->chunk_name. */
168
   png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4);
169

170 171
   png_debug2(0, "Reading %lx chunk, length = %lu",
       (unsigned long)png_ptr->chunk_name, (unsigned long)length);
172

173
   /* Reset the crc and run it over the chunk name. */
174
   png_reset_crc(png_ptr);
175
   png_calculate_crc(png_ptr, buf + 4, 4);
176

177
   /* Check to see if chunk name is valid. */
178 179
   png_check_chunk_name(png_ptr, png_ptr->chunk_name);

180 181 182 183 184 185 186
#ifdef PNG_IO_STATE_SUPPORTED
   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
#endif

   return length;
}

187
/* Read data, and (optionally) run it through the CRC. */
188
void /* PRIVATE */
A
Andreas Dilger 已提交
189
png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
G
Guy Schalnat 已提交
190
{
191 192
   if (png_ptr == NULL)
      return;
193

G
Guy Schalnat 已提交
194
   png_read_data(png_ptr, buf, length);
A
Andreas Dilger 已提交
195
   png_calculate_crc(png_ptr, buf, length);
G
Guy Schalnat 已提交
196 197
}

A
Andreas Dilger 已提交
198
/* Optionally skip data and then check the CRC.  Depending on whether we
199 200 201 202
 * are reading a ancillary or critical chunk, and how the program has set
 * things up, we may calculate the CRC on the data and print a message.
 * Returns '1' if there was a CRC error, '0' otherwise.
 */
203
int /* PRIVATE */
A
Andreas Dilger 已提交
204
png_crc_finish(png_structp png_ptr, png_uint_32 skip)
G
Guy Schalnat 已提交
205
{
206 207
   png_size_t i;
   png_size_t istop = png_ptr->zbuf_size;
G
Guy Schalnat 已提交
208

209
   for (i = (png_size_t)skip; i > istop; i -= istop)
A
Andreas Dilger 已提交
210
   {
A
Andreas Dilger 已提交
211
      png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
G
Guy Schalnat 已提交
212
   }
213

214
   if (i)
G
Guy Schalnat 已提交
215
   {
216
      png_crc_read(png_ptr, png_ptr->zbuf, i);
A
Andreas Dilger 已提交
217 218
   }

A
Andreas Dilger 已提交
219
   if (png_crc_error(png_ptr))
A
Andreas Dilger 已提交
220
   {
221 222 223
      if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name) ?
          !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) :
          (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))
A
Andreas Dilger 已提交
224
      {
225
         png_chunk_warning(png_ptr, "CRC error");
A
Andreas Dilger 已提交
226
      }
227

A
Andreas Dilger 已提交
228 229
      else
      {
230 231
         png_chunk_benign_error(png_ptr, "CRC error");
         return (0);
A
Andreas Dilger 已提交
232
      }
233

234
      return (1);
G
Guy Schalnat 已提交
235
   }
A
Andreas Dilger 已提交
236

237
   return (0);
G
Guy Schalnat 已提交
238 239
}

240
/* Compare the CRC stored in the PNG file with that calculated by libpng from
241 242
 * the data it has read thus far.
 */
243
int /* PRIVATE */
A
Andreas Dilger 已提交
244 245 246 247
png_crc_error(png_structp png_ptr)
{
   png_byte crc_bytes[4];
   png_uint_32 crc;
A
Andreas Dilger 已提交
248
   int need_crc = 1;
A
Andreas Dilger 已提交
249

250
   if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name))
A
Andreas Dilger 已提交
251 252 253 254 255
   {
      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
         need_crc = 0;
   }
256

257
   else /* critical */
A
Andreas Dilger 已提交
258 259 260 261
   {
      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
         need_crc = 0;
   }
A
Andreas Dilger 已提交
262

263 264 265
#ifdef PNG_IO_STATE_SUPPORTED
   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
#endif
266

267
   /* The chunk CRC must be serialized in a single I/O call. */
A
Andreas Dilger 已提交
268
   png_read_data(png_ptr, crc_bytes, 4);
A
Andreas Dilger 已提交
269

A
Andreas Dilger 已提交
270 271 272
   if (need_crc)
   {
      crc = png_get_uint_32(crc_bytes);
273
      return ((int)(crc != png_ptr->crc));
A
Andreas Dilger 已提交
274
   }
275

A
Andreas Dilger 已提交
276
   else
277
      return (0);
A
Andreas Dilger 已提交
278 279
}

280
#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
281 282 283
static png_size_t
png_inflate(png_structp png_ptr, png_bytep data, png_size_t size,
    png_bytep output, png_size_t output_size)
284
{
285 286 287 288 289 290 291 292 293 294 295 296 297 298
   png_size_t count = 0;

   /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it can't
    * even necessarily handle 65536 bytes) because the type uInt is "16 bits or
    * more".  Consequently it is necessary to chunk the input to zlib.  This
    * code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the maximum value
    * that can be stored in a uInt.)  It is possible to set ZLIB_IO_MAX to a
    * lower value in pngpriv.h and this may sometimes have a performance
    * advantage, because it forces access of the input data to be separated from
    * at least some of the use by some period of time.
    */
   png_ptr->zstream.next_in = data;
   /* avail_in is set below from 'size' */
   png_ptr->zstream.avail_in = 0;
299

300
   while (1)
301
   {
302 303
      int ret, avail;

304
      /* The setting of 'avail_in' used to be outside the loop; by setting it
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
       * inside it is possible to chunk the input to zlib and simply rely on
       * zlib to advance the 'next_in' pointer.  This allows arbitrary amounts o
       * data to be passed through zlib at the unavoidable cost of requiring a
       * window save (memcpy of up to 32768 output bytes) every ZLIB_IO_MAX
       * input bytes.
       */
      if (png_ptr->zstream.avail_in == 0 && size > 0)
      {
         if (size <= ZLIB_IO_MAX)
         {
            /* The value is less than ZLIB_IO_MAX so the cast is safe: */
            png_ptr->zstream.avail_in = (uInt)size;
            size = 0;
         }

         else
         {
            png_ptr->zstream.avail_in = ZLIB_IO_MAX;
            size -= ZLIB_IO_MAX;
         }
      }
326

327 328 329
      /* Reset the output buffer each time round - we empty it
       * after every inflate call.
       */
330
      png_ptr->zstream.next_out = png_ptr->zbuf;
331
      png_ptr->zstream.avail_out = png_ptr->zbuf_size;
332

333 334
      ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
      avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out;
335

336 337 338 339
      /* First copy/count any new output - but only if we didn't
       * get an error code.
       */
      if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
340
      {
341 342 343
         png_size_t space = avail; /* > 0, see above */

         if (output != 0 && output_size > count)
344
         {
345 346 347 348 349 350
            png_size_t copy = output_size - count;

            if (space < copy)
               copy = space;

            png_memcpy(output + count, png_ptr->zbuf, copy);
351
         }
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
         count += space;
      }

      if (ret == Z_OK)
         continue;

      /* Termination conditions - always reset the zstream, it
       * must be left in inflateInit state.
       */
      png_ptr->zstream.avail_in = 0;
      inflateReset(&png_ptr->zstream);

      if (ret == Z_STREAM_END)
         return count; /* NOTE: may be zero. */

      /* Now handle the error codes - the API always returns 0
       * and the error message is dumped into the uncompressed
       * buffer if available.
       */
371
#     ifdef PNG_WARNINGS_SUPPORTED
372
      {
373 374
         png_const_charp msg;

375 376 377
         if (png_ptr->zstream.msg != 0)
            msg = png_ptr->zstream.msg;

378
         else switch (ret)
379
         {
380 381 382
            case Z_BUF_ERROR:
               msg = "Buffer error in compressed datastream";
               break;
383

384 385 386
            case Z_DATA_ERROR:
               msg = "Data error in compressed datastream";
               break;
387

388 389 390
            default:
               msg = "Incomplete compressed datastream";
               break;
391
         }
392

393
         png_chunk_warning(png_ptr, msg);
394
      }
395
#     endif
396

397 398 399 400
      /* 0 means an error - notice that this code simply ignores
       * zero length compressed chunks as a result.
       */
      return 0;
401 402 403
   }
}

404 405 406 407 408 409 410
/*
 * Decompress trailing data in a chunk.  The assumption is that chunkdata
 * points at an allocated area holding the contents of a chunk with a
 * trailing compressed part.  What we get back is an allocated area
 * holding the original prefix part and an uncompressed version of the
 * trailing part (the malloc area passed in is freed).
 */
411
void /* PRIVATE */
412
png_decompress_chunk(png_structp png_ptr, int comp_type,
413 414
    png_size_t chunklength,
    png_size_t prefix_size, png_size_t *newlength)
415
{
416 417
   /* The caller should guarantee this */
   if (prefix_size > chunklength)
418
   {
419 420 421
      /* The recovery is to delete the chunk. */
      png_warning(png_ptr, "invalid chunklength");
      prefix_size = 0; /* To delete everything */
422
   }
423

424
   else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
425
   {
426 427 428
      png_size_t expanded_size = png_inflate(png_ptr,
          (png_bytep)(png_ptr->chunkdata + prefix_size),
          chunklength - prefix_size,
429 430
          0,            /* output */
          0);           /* output size */
431

432 433 434
      /* Now check the limits on this chunk - if the limit fails the
       * compressed data will be removed, the prefix will remain.
       */
435 436
      if (prefix_size >= (~(png_size_t)0) - 1 ||
         expanded_size >= (~(png_size_t)0) - 1 - prefix_size
437
#ifdef PNG_USER_LIMITS_SUPPORTED
438
         || (png_ptr->user_chunk_malloc_max &&
439 440
          (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1))
#else
441
         || ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
442 443
          prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
#endif
444
         )
445
         png_warning(png_ptr, "Exceeded size limit while expanding chunk");
446

447 448 449 450 451 452
      /* If the size is zero either there was an error and a message
       * has already been output (warning) or the size really is zero
       * and we have nothing to do - the code will exit through the
       * error case below.
       */
      else if (expanded_size > 0)
453
      {
454 455
         /* Success (maybe) - really uncompress the chunk. */
         png_size_t new_size = 0;
456
         png_charp text = (png_charp)png_malloc_warn(png_ptr,
457
             prefix_size + expanded_size + 1);
458

459
         if (text != NULL)
460
         {
461 462 463 464 465 466
            png_memcpy(text, png_ptr->chunkdata, prefix_size);
            new_size = png_inflate(png_ptr,
                (png_bytep)(png_ptr->chunkdata + prefix_size),
                chunklength - prefix_size,
                (png_bytep)(text + prefix_size), expanded_size);
            text[prefix_size + expanded_size] = 0; /* just in case */
467

468 469 470 471 472 473
            if (new_size == expanded_size)
            {
               png_free(png_ptr, png_ptr->chunkdata);
               png_ptr->chunkdata = text;
               *newlength = prefix_size + expanded_size;
               return; /* The success return! */
474
            }
475

476 477
            png_warning(png_ptr, "png_inflate logic error");
            png_free(png_ptr, text);
478 479 480
         }

         else
481
            png_warning(png_ptr, "Not enough memory to decompress chunk");
482 483
      }
   }
484

485 486
   else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
   {
487 488
      PNG_WARNING_PARAMETERS(p)
      png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, comp_type);
489
      png_formatted_warning(png_ptr, p, "Unknown compression type @1");
490

491 492 493 494 495 496 497 498
      /* The recovery is to simply drop the data. */
   }

   /* Generic error return - leave the prefix, delete the compressed
    * data, reallocate the chunkdata to remove the potentially large
    * amount of compressed data.
    */
   {
499
      png_charp text = (png_charp)png_malloc_warn(png_ptr, prefix_size + 1);
500 501 502 503 504 505 506 507 508 509 510 511 512

      if (text != NULL)
      {
         if (prefix_size > 0)
            png_memcpy(text, png_ptr->chunkdata, prefix_size);

         png_free(png_ptr, png_ptr->chunkdata);
         png_ptr->chunkdata = text;

         /* This is an extra zero in the 'uncompressed' part. */
         *(png_ptr->chunkdata + prefix_size) = 0x00;
      }
      /* Ignore a malloc error here - it is safe. */
513
   }
514 515

   *newlength = prefix_size;
516
}
517
#endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */
A
Andreas Dilger 已提交
518

519
/* Read and check the IDHR chunk */
520
void /* PRIVATE */
A
Andreas Dilger 已提交
521
png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
G
Guy Schalnat 已提交
522 523 524 525 526 527
{
   png_byte buf[13];
   png_uint_32 width, height;
   int bit_depth, color_type, compression_type, filter_type;
   int interlace_type;

528
   png_debug(1, "in png_handle_IHDR");
A
Andreas Dilger 已提交
529

530
   if (png_ptr->mode & PNG_HAVE_IHDR)
G
Guy Schalnat 已提交
531 532
      png_error(png_ptr, "Out of place IHDR");

533
   /* Check the length */
G
Guy Schalnat 已提交
534
   if (length != 13)
G
Guy Schalnat 已提交
535
      png_error(png_ptr, "Invalid IHDR chunk");
G
Guy Schalnat 已提交
536

A
Andreas Dilger 已提交
537 538
   png_ptr->mode |= PNG_HAVE_IHDR;

G
Guy Schalnat 已提交
539
   png_crc_read(png_ptr, buf, 13);
A
Andreas Dilger 已提交
540
   png_crc_finish(png_ptr, 0);
G
Guy Schalnat 已提交
541

542 543
   width = png_get_uint_31(png_ptr, buf);
   height = png_get_uint_31(png_ptr, buf + 4);
G
Guy Schalnat 已提交
544 545 546 547 548 549
   bit_depth = buf[8];
   color_type = buf[9];
   compression_type = buf[10];
   filter_type = buf[11];
   interlace_type = buf[12];

550
   /* Set internal variables */
G
Guy Schalnat 已提交
551 552
   png_ptr->width = width;
   png_ptr->height = height;
G
Guy Schalnat 已提交
553 554 555
   png_ptr->bit_depth = (png_byte)bit_depth;
   png_ptr->interlaced = (png_byte)interlace_type;
   png_ptr->color_type = (png_byte)color_type;
556
#ifdef PNG_MNG_FEATURES_SUPPORTED
557
   png_ptr->filter_type = (png_byte)filter_type;
558
#endif
559
   png_ptr->compression_type = (png_byte)compression_type;
G
Guy Schalnat 已提交
560

561
   /* Find number of channels */
G
Guy Schalnat 已提交
562 563
   switch (png_ptr->color_type)
   {
564
      default: /* invalid, png_set_IHDR calls png_error */
A
Andreas Dilger 已提交
565 566
      case PNG_COLOR_TYPE_GRAY:
      case PNG_COLOR_TYPE_PALETTE:
G
Guy Schalnat 已提交
567 568
         png_ptr->channels = 1;
         break;
569

A
Andreas Dilger 已提交
570
      case PNG_COLOR_TYPE_RGB:
G
Guy Schalnat 已提交
571 572
         png_ptr->channels = 3;
         break;
573

A
Andreas Dilger 已提交
574
      case PNG_COLOR_TYPE_GRAY_ALPHA:
G
Guy Schalnat 已提交
575 576
         png_ptr->channels = 2;
         break;
577

A
Andreas Dilger 已提交
578
      case PNG_COLOR_TYPE_RGB_ALPHA:
G
Guy Schalnat 已提交
579 580 581
         png_ptr->channels = 4;
         break;
   }
A
Andreas Dilger 已提交
582

583
   /* Set up other useful info */
G
Guy Schalnat 已提交
584
   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
585
   png_ptr->channels);
586
   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
587 588
   png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
   png_debug1(3, "channels = %d", png_ptr->channels);
589
   png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes);
A
Andreas Dilger 已提交
590
   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
591
       color_type, interlace_type, compression_type, filter_type);
G
Guy Schalnat 已提交
592 593
}

594
/* Read and check the palette */
595
void /* PRIVATE */
A
Andreas Dilger 已提交
596
png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
G
Guy Schalnat 已提交
597
{
598
   png_color palette[PNG_MAX_PALETTE_LENGTH];
A
Andreas Dilger 已提交
599
   int num, i;
600
#ifdef PNG_POINTER_INDEXING_SUPPORTED
601 602
   png_colorp pal_ptr;
#endif
G
Guy Schalnat 已提交
603

604
   png_debug(1, "in png_handle_PLTE");
A
Andreas Dilger 已提交
605

G
Guy Schalnat 已提交
606 607
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before PLTE");
608

A
Andreas Dilger 已提交
609 610 611 612 613 614
   else if (png_ptr->mode & PNG_HAVE_IDAT)
   {
      png_warning(png_ptr, "Invalid PLTE after IDAT");
      png_crc_finish(png_ptr, length);
      return;
   }
615

G
Guy Schalnat 已提交
616
   else if (png_ptr->mode & PNG_HAVE_PLTE)
A
Andreas Dilger 已提交
617 618 619
      png_error(png_ptr, "Duplicate PLTE chunk");

   png_ptr->mode |= PNG_HAVE_PLTE;
G
Guy Schalnat 已提交
620

621 622 623
   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
   {
      png_warning(png_ptr,
624
          "Ignoring PLTE chunk in grayscale PNG");
625 626 627
      png_crc_finish(png_ptr, length);
      return;
   }
628

629
#ifndef PNG_READ_OPT_PLTE_SUPPORTED
G
Guy Schalnat 已提交
630 631
   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
   {
A
Andreas Dilger 已提交
632
      png_crc_finish(png_ptr, length);
G
Guy Schalnat 已提交
633 634 635 636
      return;
   }
#endif

637
   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
G
Guy Schalnat 已提交
638 639 640 641
   {
      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
      {
         png_warning(png_ptr, "Invalid palette chunk");
A
Andreas Dilger 已提交
642
         png_crc_finish(png_ptr, length);
G
Guy Schalnat 已提交
643 644
         return;
      }
645

G
Guy Schalnat 已提交
646 647 648 649 650
      else
      {
         png_error(png_ptr, "Invalid palette chunk");
      }
   }
G
Guy Schalnat 已提交
651 652

   num = (int)length / 3;
653

654
#ifdef PNG_POINTER_INDEXING_SUPPORTED
655 656 657 658 659 660 661 662 663 664
   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
   {
      png_byte buf[3];

      png_crc_read(png_ptr, buf, 3);
      pal_ptr->red = buf[0];
      pal_ptr->green = buf[1];
      pal_ptr->blue = buf[2];
   }
#else
G
Guy Schalnat 已提交
665
   for (i = 0; i < num; i++)
G
Guy Schalnat 已提交
666 667 668 669
   {
      png_byte buf[3];

      png_crc_read(png_ptr, buf, 3);
670
      /* Don't depend upon png_color being any order */
G
Guy Schalnat 已提交
671 672 673 674
      palette[i].red = buf[0];
      palette[i].green = buf[1];
      palette[i].blue = buf[2];
   }
675
#endif
A
Andreas Dilger 已提交
676

677
   /* If we actually need the PLTE chunk (ie for a paletted image), we do
678 679 680 681
    * whatever the normal CRC configuration tells us.  However, if we
    * have an RGB image, the PLTE can be considered ancillary, so
    * we will act as though it is.
    */
682
#ifndef PNG_READ_OPT_PLTE_SUPPORTED
A
Andreas Dilger 已提交
683
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
684
#endif
A
Andreas Dilger 已提交
685
   {
A
Andreas Dilger 已提交
686
      png_crc_finish(png_ptr, 0);
A
Andreas Dilger 已提交
687
   }
688

689
#ifndef PNG_READ_OPT_PLTE_SUPPORTED
A
Andreas Dilger 已提交
690 691 692
   else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
   {
      /* If we don't want to use the data from an ancillary chunk,
693 694 695 696
       * we have two options: an error abort, or a warning and we
       * ignore the data in this chunk (which should be OK, since
       * it's considered ancillary for a RGB or RGBA image).
       */
A
Andreas Dilger 已提交
697 698 699 700
      if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
      {
         if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
         {
701
            png_chunk_benign_error(png_ptr, "CRC error");
A
Andreas Dilger 已提交
702
         }
703

A
Andreas Dilger 已提交
704 705
         else
         {
706
            png_chunk_warning(png_ptr, "CRC error");
A
Andreas Dilger 已提交
707 708 709
            return;
         }
      }
710

A
Andreas Dilger 已提交
711
      /* Otherwise, we (optionally) emit a warning and use the chunk. */
A
Andreas Dilger 已提交
712 713
      else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
      {
714
         png_chunk_warning(png_ptr, "CRC error");
A
Andreas Dilger 已提交
715 716
      }
   }
717
#endif
718

A
Andreas Dilger 已提交
719
   png_set_PLTE(png_ptr, info_ptr, palette, num);
720

721
#ifdef PNG_READ_tRNS_SUPPORTED
722 723
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   {
724
      if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
725
      {
726
         if (png_ptr->num_trans > (png_uint_16)num)
727 728
         {
            png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
729 730
            png_ptr->num_trans = (png_uint_16)num;
         }
731

732 733 734 735
         if (info_ptr->num_trans > (png_uint_16)num)
         {
            png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
            info_ptr->num_trans = (png_uint_16)num;
736 737 738 739 740
         }
      }
   }
#endif

A
Andreas Dilger 已提交
741
}
G
Guy Schalnat 已提交
742

743
void /* PRIVATE */
A
Andreas Dilger 已提交
744 745
png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
746
   png_debug(1, "in png_handle_IEND");
A
Andreas Dilger 已提交
747

A
Andreas Dilger 已提交
748 749 750 751 752
   if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
   {
      png_error(png_ptr, "No image in file");
   }

753
   png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
A
Andreas Dilger 已提交
754 755 756 757 758

   if (length != 0)
   {
      png_warning(png_ptr, "Incorrect IEND chunk length");
   }
759

A
Andreas Dilger 已提交
760
   png_crc_finish(png_ptr, length);
761

762
   PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */
G
Guy Schalnat 已提交
763 764
}

765
#ifdef PNG_READ_gAMA_SUPPORTED
766
void /* PRIVATE */
A
Andreas Dilger 已提交
767
png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
G
Guy Schalnat 已提交
768
{
769
   png_fixed_point igamma;
G
Guy Schalnat 已提交
770 771
   png_byte buf[4];

772
   png_debug(1, "in png_handle_gAMA");
A
Andreas Dilger 已提交
773

G
Guy Schalnat 已提交
774 775
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before gAMA");
776

A
Andreas Dilger 已提交
777 778 779 780 781 782
   else if (png_ptr->mode & PNG_HAVE_IDAT)
   {
      png_warning(png_ptr, "Invalid gAMA after IDAT");
      png_crc_finish(png_ptr, length);
      return;
   }
783

G
Guy Schalnat 已提交
784 785 786
   else if (png_ptr->mode & PNG_HAVE_PLTE)
      /* Should be an error, but we can cope with it */
      png_warning(png_ptr, "Out of place gAMA chunk");
787

788
   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
789
#ifdef PNG_READ_sRGB_SUPPORTED
790
       && !(info_ptr->valid & PNG_INFO_sRGB)
791
#endif
792
       )
A
Andreas Dilger 已提交
793 794 795 796 797
   {
      png_warning(png_ptr, "Duplicate gAMA chunk");
      png_crc_finish(png_ptr, length);
      return;
   }
G
Guy Schalnat 已提交
798

G
Guy Schalnat 已提交
799 800
   if (length != 4)
   {
G
Guy Schalnat 已提交
801
      png_warning(png_ptr, "Incorrect gAMA chunk length");
A
Andreas Dilger 已提交
802
      png_crc_finish(png_ptr, length);
G
Guy Schalnat 已提交
803 804 805 806
      return;
   }

   png_crc_read(png_ptr, buf, 4);
807

A
Andreas Dilger 已提交
808 809 810
   if (png_crc_finish(png_ptr, 0))
      return;

811
   igamma = png_get_fixed_point(NULL, buf);
G
Guy Schalnat 已提交
812

813 814 815 816 817 818 819 820 821 822
   /* Check for zero gamma or an error. */
   if (igamma <= 0)
   {
      png_warning(png_ptr,
          "Ignoring gAMA chunk with out of range gamma");

      return;
   }

#  ifdef PNG_READ_sRGB_SUPPORTED
823
   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
824
   {
825
      if (PNG_OUT_OF_RANGE(igamma, 45500, 500))
826
      {
827 828 829 830
         PNG_WARNING_PARAMETERS(p)
         png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, igamma);
         png_formatted_warning(png_ptr, p,
             "Ignoring incorrect gAMA value @1 when sRGB is also present");
831 832
         return;
      }
833 834
   }
#  endif /* PNG_READ_sRGB_SUPPORTED */
835

836
#  ifdef PNG_READ_GAMMA_SUPPORTED
837 838
   /* Gamma correction on read is supported. */
   png_ptr->gamma = igamma;
839
#  endif
840
   /* And set the 'info' structure members. */
841
   png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
G
Guy Schalnat 已提交
842
}
G
Guy Schalnat 已提交
843
#endif
G
Guy Schalnat 已提交
844

845
#ifdef PNG_READ_sBIT_SUPPORTED
846
void /* PRIVATE */
A
Andreas Dilger 已提交
847
png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
G
Guy Schalnat 已提交
848
{
A
Andreas Dilger 已提交
849
   png_size_t truelen;
G
Guy Schalnat 已提交
850
   png_byte buf[4];
G
Guy Schalnat 已提交
851

852
   png_debug(1, "in png_handle_sBIT");
A
Andreas Dilger 已提交
853

G
Guy Schalnat 已提交
854
   buf[0] = buf[1] = buf[2] = buf[3] = 0;
G
Guy Schalnat 已提交
855

G
Guy Schalnat 已提交
856 857
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before sBIT");
858

A
Andreas Dilger 已提交
859 860 861 862 863 864
   else if (png_ptr->mode & PNG_HAVE_IDAT)
   {
      png_warning(png_ptr, "Invalid sBIT after IDAT");
      png_crc_finish(png_ptr, length);
      return;
   }
865

G
Guy Schalnat 已提交
866
   else if (png_ptr->mode & PNG_HAVE_PLTE)
867
   {
G
Guy Schalnat 已提交
868 869
      /* Should be an error, but we can cope with it */
      png_warning(png_ptr, "Out of place sBIT chunk");
870
   }
871

872
   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
A
Andreas Dilger 已提交
873 874 875 876 877
   {
      png_warning(png_ptr, "Duplicate sBIT chunk");
      png_crc_finish(png_ptr, length);
      return;
   }
G
Guy Schalnat 已提交
878

G
Guy Schalnat 已提交
879
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
A
Andreas Dilger 已提交
880
      truelen = 3;
881

G
Guy Schalnat 已提交
882
   else
A
Andreas Dilger 已提交
883
      truelen = (png_size_t)png_ptr->channels;
G
Guy Schalnat 已提交
884

885
   if (length != truelen || length > 4)
G
Guy Schalnat 已提交
886
   {
G
Guy Schalnat 已提交
887
      png_warning(png_ptr, "Incorrect sBIT chunk length");
A
Andreas Dilger 已提交
888
      png_crc_finish(png_ptr, length);
G
Guy Schalnat 已提交
889
      return;
G
Guy Schalnat 已提交
890 891
   }

A
Andreas Dilger 已提交
892
   png_crc_read(png_ptr, buf, truelen);
893

A
Andreas Dilger 已提交
894 895 896
   if (png_crc_finish(png_ptr, 0))
      return;

G
Guy Schalnat 已提交
897 898
   if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
   {
G
Guy Schalnat 已提交
899 900 901 902
      png_ptr->sig_bit.red = buf[0];
      png_ptr->sig_bit.green = buf[1];
      png_ptr->sig_bit.blue = buf[2];
      png_ptr->sig_bit.alpha = buf[3];
G
Guy Schalnat 已提交
903
   }
904

G
Guy Schalnat 已提交
905 906
   else
   {
G
Guy Schalnat 已提交
907
      png_ptr->sig_bit.gray = buf[0];
908 909 910
      png_ptr->sig_bit.red = buf[0];
      png_ptr->sig_bit.green = buf[0];
      png_ptr->sig_bit.blue = buf[0];
G
Guy Schalnat 已提交
911
      png_ptr->sig_bit.alpha = buf[1];
G
Guy Schalnat 已提交
912
   }
913

A
Andreas Dilger 已提交
914
   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
G
Guy Schalnat 已提交
915
}
G
Guy Schalnat 已提交
916
#endif
G
Guy Schalnat 已提交
917

918
#ifdef PNG_READ_cHRM_SUPPORTED
919
void /* PRIVATE */
A
Andreas Dilger 已提交
920
png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
G
Guy Schalnat 已提交
921
{
922
   png_byte buf[32];
923 924
   png_fixed_point x_white, y_white, x_red, y_red, x_green, y_green, x_blue,
      y_blue;
925

926
   png_debug(1, "in png_handle_cHRM");
A
Andreas Dilger 已提交
927

G
Guy Schalnat 已提交
928
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
929
      png_error(png_ptr, "Missing IHDR before cHRM");
930

A
Andreas Dilger 已提交
931 932 933 934 935 936
   else if (png_ptr->mode & PNG_HAVE_IDAT)
   {
      png_warning(png_ptr, "Invalid cHRM after IDAT");
      png_crc_finish(png_ptr, length);
      return;
   }
937

G
Guy Schalnat 已提交
938 939
   else if (png_ptr->mode & PNG_HAVE_PLTE)
      /* Should be an error, but we can cope with it */
940
      png_warning(png_ptr, "Out of place cHRM chunk");
941

942
   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
943 944 945
#  ifdef PNG_READ_sRGB_SUPPORTED
       && !(info_ptr->valid & PNG_INFO_sRGB)
#  endif
946
      )
A
Andreas Dilger 已提交
947 948 949 950 951
   {
      png_warning(png_ptr, "Duplicate cHRM chunk");
      png_crc_finish(png_ptr, length);
      return;
   }
G
Guy Schalnat 已提交
952

G
Guy Schalnat 已提交
953 954
   if (length != 32)
   {
G
Guy Schalnat 已提交
955
      png_warning(png_ptr, "Incorrect cHRM chunk length");
A
Andreas Dilger 已提交
956
      png_crc_finish(png_ptr, length);
G
Guy Schalnat 已提交
957
      return;
G
Guy Schalnat 已提交
958 959
   }

960
   png_crc_read(png_ptr, buf, 32);
961

962 963
   if (png_crc_finish(png_ptr, 0))
      return;
A
Andreas Dilger 已提交
964

965 966 967 968 969 970 971 972
   x_white = png_get_fixed_point(NULL, buf);
   y_white = png_get_fixed_point(NULL, buf + 4);
   x_red   = png_get_fixed_point(NULL, buf + 8);
   y_red   = png_get_fixed_point(NULL, buf + 12);
   x_green = png_get_fixed_point(NULL, buf + 16);
   y_green = png_get_fixed_point(NULL, buf + 20);
   x_blue  = png_get_fixed_point(NULL, buf + 24);
   y_blue  = png_get_fixed_point(NULL, buf + 28);
973

974 975 976 977 978 979 980 981 982 983 984 985
   if (x_white == PNG_FIXED_ERROR ||
       y_white == PNG_FIXED_ERROR ||
       x_red   == PNG_FIXED_ERROR ||
       y_red   == PNG_FIXED_ERROR ||
       x_green == PNG_FIXED_ERROR ||
       y_green == PNG_FIXED_ERROR ||
       x_blue  == PNG_FIXED_ERROR ||
       y_blue  == PNG_FIXED_ERROR)
   {
      png_warning(png_ptr, "Ignoring cHRM chunk with negative chromaticities");
      return;
   }
G
Guy Schalnat 已提交
986

987
#ifdef PNG_READ_sRGB_SUPPORTED
988
   if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
989 990 991
   {
      if (PNG_OUT_OF_RANGE(x_white, 31270,  1000) ||
          PNG_OUT_OF_RANGE(y_white, 32900,  1000) ||
992
          PNG_OUT_OF_RANGE(x_red,   64000,  1000) ||
993 994
          PNG_OUT_OF_RANGE(y_red,   33000,  1000) ||
          PNG_OUT_OF_RANGE(x_green, 30000,  1000) ||
995
          PNG_OUT_OF_RANGE(y_green, 60000,  1000) ||
996 997
          PNG_OUT_OF_RANGE(x_blue,  15000,  1000) ||
          PNG_OUT_OF_RANGE(y_blue,   6000,  1000))
998
      {
999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
         PNG_WARNING_PARAMETERS(p)

         png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, x_white);
         png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_fixed, y_white);
         png_warning_parameter_signed(p, 3, PNG_NUMBER_FORMAT_fixed, x_red);
         png_warning_parameter_signed(p, 4, PNG_NUMBER_FORMAT_fixed, y_red);
         png_warning_parameter_signed(p, 5, PNG_NUMBER_FORMAT_fixed, x_green);
         png_warning_parameter_signed(p, 6, PNG_NUMBER_FORMAT_fixed, y_green);
         png_warning_parameter_signed(p, 7, PNG_NUMBER_FORMAT_fixed, x_blue);
         png_warning_parameter_signed(p, 8, PNG_NUMBER_FORMAT_fixed, y_blue);

         png_formatted_warning(png_ptr, p,
             "Ignoring incorrect cHRM white(@1,@2) r(@3,@4)g(@5,@6)b(@7,@8) "
             "when sRGB is also present");
1013
      }
1014 1015
      return;
   }
1016 1017
#endif /* PNG_READ_sRGB_SUPPORTED */

1018 1019
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
   /* Store the _white values as default coefficients for the rgb to gray
1020 1021
    * operation if it is supported.  Check if the transform is already set to
    * avoid destroying the transform values.
1022
    */
1023
   if (!png_ptr->rgb_to_gray_coefficients_set)
1024
   {
1025 1026
      /* png_set_background has not been called and we haven't seen an sRGB
       * chunk yet.  Find the XYZ of the three end points.
1027
       */
1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040
      png_XYZ XYZ;
      png_xy xy;

      xy.redx = x_red;
      xy.redy = y_red;
      xy.greenx = x_green;
      xy.greeny = y_green;
      xy.bluex = x_blue;
      xy.bluey = y_blue;
      xy.whitex = x_white;
      xy.whitey = y_white;

      if (png_XYZ_from_xy_checked(png_ptr, &XYZ, xy))
1041
      {
1042 1043 1044
         /* The success case, because XYZ_from_xy normalises to a reference
          * white Y of 1.0 we just need to scale the numbers.  This should
          * always work just fine. It is an internal error if this overflows.
1045
          */
1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093
         {
            png_fixed_point r, g, b;
            if (png_muldiv(&r, XYZ.redY, 32768, PNG_FP_1) &&
               r >= 0 && r <= 32768 &&
               png_muldiv(&g, XYZ.greenY, 32768, PNG_FP_1) &&
               g >= 0 && g <= 32768 &&
               png_muldiv(&b, XYZ.blueY, 32768, PNG_FP_1) &&
               b >= 0 && b <= 32768 &&
               r+g+b <= 32769)
            {
               /* We allow 0 coefficients here.  r+g+b may be 32769 if two or
                * all of the coefficients were rounded up.  Handle this by
                * reducing the *largest* coefficient by 1; this matches the
                * approach used for the default coefficients in pngrtran.c
                */
               int add = 0;

               if (r+g+b > 32768)
                  add = -1;
               else if (r+g+b < 32768)
                  add = 1;

               if (add != 0)
               {
                  if (g >= r && g >= b)
                     g += add;
                  else if (r >= g && r >= b)
                     r += add;
                  else
                     b += add;
               }

               /* Check for an internal error. */
               if (r+g+b != 32768)
                  png_error(png_ptr,
                     "internal error handling cHRM coefficients");

               png_ptr->rgb_to_gray_red_coeff   = (png_uint_16)r;
               png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
            }

            /* This is a png_error at present even though it could be ignored -
             * it should never happen, but it is important that if it does, the
             * bug is fixed.
             */
            else
               png_error(png_ptr, "internal error handling cHRM->XYZ");
         }
1094 1095 1096 1097
      }
   }
#endif

1098 1099
   png_set_cHRM_fixed(png_ptr, info_ptr, x_white, y_white, x_red, y_red,
      x_green, y_green, x_blue, y_blue);
G
Guy Schalnat 已提交
1100
}
G
Guy Schalnat 已提交
1101
#endif
G
Guy Schalnat 已提交
1102

1103
#ifdef PNG_READ_sRGB_SUPPORTED
1104
void /* PRIVATE */
1105 1106
png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
1107
   int intent;
1108 1109
   png_byte buf[1];

1110
   png_debug(1, "in png_handle_sRGB");
1111 1112 1113

   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before sRGB");
1114

1115 1116 1117 1118 1119 1120
   else if (png_ptr->mode & PNG_HAVE_IDAT)
   {
      png_warning(png_ptr, "Invalid sRGB after IDAT");
      png_crc_finish(png_ptr, length);
      return;
   }
1121

1122 1123 1124
   else if (png_ptr->mode & PNG_HAVE_PLTE)
      /* Should be an error, but we can cope with it */
      png_warning(png_ptr, "Out of place sRGB chunk");
1125

1126
   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140
   {
      png_warning(png_ptr, "Duplicate sRGB chunk");
      png_crc_finish(png_ptr, length);
      return;
   }

   if (length != 1)
   {
      png_warning(png_ptr, "Incorrect sRGB chunk length");
      png_crc_finish(png_ptr, length);
      return;
   }

   png_crc_read(png_ptr, buf, 1);
1141

1142 1143 1144 1145
   if (png_crc_finish(png_ptr, 0))
      return;

   intent = buf[0];
1146

1147
   /* Check for bad intent */
1148
   if (intent >= PNG_sRGB_INTENT_LAST)
1149 1150 1151 1152 1153
   {
      png_warning(png_ptr, "Unknown sRGB intent");
      return;
   }

1154
#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
1155
   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
1156
   {
1157
      if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500, 500))
1158
      {
1159 1160 1161 1162 1163 1164 1165
         PNG_WARNING_PARAMETERS(p)

         png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed,
            info_ptr->gamma);

         png_formatted_warning(png_ptr, p,
             "Ignoring incorrect gAMA value @1 when sRGB is also present");
1166
      }
1167
   }
1168 1169 1170
#endif /* PNG_READ_gAMA_SUPPORTED */

#ifdef PNG_READ_cHRM_SUPPORTED
1171
   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
1172 1173
      if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270,  1000) ||
          PNG_OUT_OF_RANGE(info_ptr->y_white, 32900,  1000) ||
1174
          PNG_OUT_OF_RANGE(info_ptr->x_red,   64000,  1000) ||
1175 1176
          PNG_OUT_OF_RANGE(info_ptr->y_red,   33000,  1000) ||
          PNG_OUT_OF_RANGE(info_ptr->x_green, 30000,  1000) ||
1177
          PNG_OUT_OF_RANGE(info_ptr->y_green, 60000,  1000) ||
1178 1179 1180 1181 1182 1183
          PNG_OUT_OF_RANGE(info_ptr->x_blue,  15000,  1000) ||
          PNG_OUT_OF_RANGE(info_ptr->y_blue,   6000,  1000))
      {
         png_warning(png_ptr,
             "Ignoring incorrect cHRM value when sRGB is also present");
      }
1184
#endif /* PNG_READ_cHRM_SUPPORTED */
1185

1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226
   /* This is recorded for use when handling the cHRM chunk above.  An sRGB
    * chunk unconditionally overwrites the coefficients for grayscale conversion
    * too.
    */
   png_ptr->is_sRGB = 1;

#  ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
      /* Don't overwrite user supplied values: */
      if (!png_ptr->rgb_to_gray_coefficients_set)
      {
         /* These numbers come from the sRGB specification (or, since one has to
          * pay much money to get a copy, the wikipedia sRGB page) the
          * chromaticity values quoted have been inverted to get the reverse
          * transformation from RGB to XYZ and the 'Y' coefficients scaled by
          * 32768 (then rounded).
          *
          * sRGB and ITU Rec-709 both truncate the values for the D65 white
          * point to four digits and, even though it actually stores five
          * digits, the PNG spec gives the truncated value.
          *
          * This means that when the chromaticities are converted back to XYZ
          * end points we end up with (6968,23435,2366), which, as described in
          * pngrtran.c, would overflow.  If the five digit precision and up is
          * used we get, instead:
          *
          *    6968*R + 23435*G + 2365*B
          *
          * (Notice that this rounds the blue coefficient down, rather than the
          * choice used in pngrtran.c which is to round the green one down.)
          */
         png_ptr->rgb_to_gray_red_coeff   =  6968; /* 0.212639005871510 */
         png_ptr->rgb_to_gray_green_coeff = 23434; /* 0.715168678767756 */
         /* png_ptr->rgb_to_gray_blue_coeff  =  2366; 0.072192315360734	*/

         /* The following keeps the cHRM chunk from destroying the
          * coefficients again in the event that it follows the sRGB chunk.
          */
         png_ptr->rgb_to_gray_coefficients_set = 1;
      }
#  endif

1227
   png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
1228
}
1229 1230
#endif /* PNG_READ_sRGB_SUPPORTED */

1231
#ifdef PNG_READ_iCCP_SUPPORTED
1232
void /* PRIVATE */
1233 1234 1235 1236
png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
/* Note: this does not properly handle chunks that are > 64K under DOS */
{
   png_byte compression_type;
1237
   png_bytep pC;
1238 1239
   png_charp profile;
   png_uint_32 skip = 0;
1240 1241
   png_uint_32 profile_size;
   png_alloc_size_t profile_length;
1242
   png_size_t slength, prefix_length, data_length;
1243

1244
   png_debug(1, "in png_handle_iCCP");
1245 1246 1247

   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before iCCP");
1248

1249 1250 1251 1252 1253 1254
   else if (png_ptr->mode & PNG_HAVE_IDAT)
   {
      png_warning(png_ptr, "Invalid iCCP after IDAT");
      png_crc_finish(png_ptr, length);
      return;
   }
1255

1256 1257 1258 1259
   else if (png_ptr->mode & PNG_HAVE_PLTE)
      /* Should be an error, but we can cope with it */
      png_warning(png_ptr, "Out of place iCCP chunk");

1260
   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275
   {
      png_warning(png_ptr, "Duplicate iCCP chunk");
      png_crc_finish(png_ptr, length);
      return;
   }

#ifdef PNG_MAX_MALLOC_64K
   if (length > (png_uint_32)65535L)
   {
      png_warning(png_ptr, "iCCP chunk too large to fit in memory");
      skip = length - (png_uint_32)65535L;
      length = (png_uint_32)65535L;
   }
#endif

1276 1277
   png_free(png_ptr, png_ptr->chunkdata);
   png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1278
   slength = length;
1279
   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1280 1281 1282

   if (png_crc_finish(png_ptr, skip))
   {
1283 1284
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
1285 1286 1287
      return;
   }

1288
   png_ptr->chunkdata[slength] = 0x00;
1289

1290
   for (profile = png_ptr->chunkdata; *profile; profile++)
1291
      /* Empty loop to find end of name */ ;
1292

1293 1294
   ++profile;

1295 1296 1297
   /* There should be at least one zero (the compression type byte)
    * following the separator, and we should be on it
    */
1298
   if (profile >= png_ptr->chunkdata + slength - 1)
1299
   {
1300 1301
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
1302
      png_warning(png_ptr, "Malformed iCCP chunk");
1303
      return;
1304 1305
   }

1306
   /* Compression_type should always be zero */
1307
   compression_type = *profile++;
1308

1309 1310 1311
   if (compression_type)
   {
      png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
1312
      compression_type = 0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
1313 1314
                                 wrote nonzero) */
   }
1315

1316
   prefix_length = profile - png_ptr->chunkdata;
1317
   png_decompress_chunk(png_ptr, compression_type,
1318
       slength, prefix_length, &data_length);
1319

1320
   profile_length = data_length - prefix_length;
1321

1322
   if (prefix_length > data_length || profile_length < 4)
1323
   {
1324 1325
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
1326 1327 1328 1329
      png_warning(png_ptr, "Profile size field missing from iCCP chunk");
      return;
   }

1330
   /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1331
   pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
1332 1333 1334 1335
   profile_size = ((*(pC    )) << 24) |
                  ((*(pC + 1)) << 16) |
                  ((*(pC + 2)) <<  8) |
                  ((*(pC + 3))      );
1336

1337 1338 1339
   /* NOTE: the following guarantees that 'profile_length' fits into 32 bits,
    * because profile_size is a 32 bit value.
    */
1340
   if (profile_size < profile_length)
1341 1342
      profile_length = profile_size;

1343
   /* And the following guarantees that profile_size == profile_length. */
1344
   if (profile_size > profile_length)
1345
   {
1346 1347
      PNG_WARNING_PARAMETERS(p)

1348 1349
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
1350 1351 1352 1353 1354

      png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_u, profile_size);
      png_warning_parameter_unsigned(p, 2, PNG_NUMBER_FORMAT_u, profile_length);
      png_formatted_warning(png_ptr, p,
         "Ignoring iCCP chunk with declared size = @1 and actual length = @2");
1355 1356 1357
      return;
   }

1358
   png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
1359 1360
       compression_type, (png_bytep)png_ptr->chunkdata + prefix_length,
       profile_size);
1361 1362
   png_free(png_ptr, png_ptr->chunkdata);
   png_ptr->chunkdata = NULL;
1363 1364 1365
}
#endif /* PNG_READ_iCCP_SUPPORTED */

1366
#ifdef PNG_READ_sPLT_SUPPORTED
1367
void /* PRIVATE */
1368 1369 1370 1371
png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
/* Note: this does not properly handle chunks that are > 64K under DOS */
{
   png_bytep entry_start;
1372
   png_sPLT_t new_palette;
1373
   png_sPLT_entryp pp;
1374 1375
   png_uint_32 data_length;
   int entry_size, i;
1376 1377
   png_uint_32 skip = 0;
   png_size_t slength;
1378 1379
   png_uint_32 dl;
   png_size_t max_dl;
1380

1381
   png_debug(1, "in png_handle_sPLT");
1382

1383
#ifdef PNG_USER_LIMITS_SUPPORTED
1384

1385 1386 1387 1388 1389 1390 1391
   if (png_ptr->user_chunk_cache_max != 0)
   {
      if (png_ptr->user_chunk_cache_max == 1)
      {
         png_crc_finish(png_ptr, length);
         return;
      }
1392

1393 1394 1395 1396 1397 1398 1399 1400 1401
      if (--png_ptr->user_chunk_cache_max == 1)
      {
         png_warning(png_ptr, "No space in chunk cache for sPLT");
         png_crc_finish(png_ptr, length);
         return;
      }
   }
#endif

1402 1403
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before sPLT");
1404

1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420
   else if (png_ptr->mode & PNG_HAVE_IDAT)
   {
      png_warning(png_ptr, "Invalid sPLT after IDAT");
      png_crc_finish(png_ptr, length);
      return;
   }

#ifdef PNG_MAX_MALLOC_64K
   if (length > (png_uint_32)65535L)
   {
      png_warning(png_ptr, "sPLT chunk too large to fit in memory");
      skip = length - (png_uint_32)65535L;
      length = (png_uint_32)65535L;
   }
#endif

1421 1422
   png_free(png_ptr, png_ptr->chunkdata);
   png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1423 1424 1425 1426 1427

   /* WARNING: this may break if size_t is less than 32 bits; it is assumed
    * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a
    * potential breakage point if the types in pngconf.h aren't exactly right.
    */
1428
   slength = length;
1429
   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1430 1431 1432

   if (png_crc_finish(png_ptr, skip))
   {
1433 1434
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
1435 1436 1437
      return;
   }

1438
   png_ptr->chunkdata[slength] = 0x00;
1439

1440 1441
   for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
       entry_start++)
1442
      /* Empty loop to find end of name */ ;
1443

1444 1445
   ++entry_start;

1446
   /* A sample depth should follow the separator, and we should be on it  */
1447
   if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
1448
   {
1449 1450
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
1451 1452
      png_warning(png_ptr, "malformed sPLT chunk");
      return;
1453 1454 1455
   }

   new_palette.depth = *entry_start++;
1456
   entry_size = (new_palette.depth == 8 ? 6 : 10);
1457 1458 1459 1460 1461 1462
   /* This must fit in a png_uint_32 because it is derived from the original
    * chunk data length (and use 'length', not 'slength' here for clarity -
    * they are guaranteed to be the same, see the tests above.)
    */
   data_length = length - (png_uint_32)(entry_start -
      (png_bytep)png_ptr->chunkdata);
1463

1464
   /* Integrity-check the data length */
1465 1466
   if (data_length % entry_size)
   {
1467 1468
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
1469 1470
      png_warning(png_ptr, "sPLT chunk has bad length");
      return;
1471 1472
   }

1473 1474 1475 1476
   dl = (png_int_32)(data_length / entry_size);
   max_dl = PNG_SIZE_MAX / png_sizeof(png_sPLT_entry);

   if (dl > max_dl)
1477 1478 1479 1480
   {
       png_warning(png_ptr, "sPLT chunk too long");
       return;
   }
1481 1482 1483

   new_palette.nentries = (png_int_32)(data_length / entry_size);

1484
   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
1485
       png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
1486

1487 1488 1489 1490 1491
   if (new_palette.entries == NULL)
   {
       png_warning(png_ptr, "sPLT chunk requires too much memory");
       return;
   }
1492

1493
#ifdef PNG_POINTER_INDEXING_SUPPORTED
1494 1495
   for (i = 0; i < new_palette.nentries; i++)
   {
1496
      pp = new_palette.entries + i;
1497 1498 1499

      if (new_palette.depth == 8)
      {
1500 1501 1502 1503
         pp->red = *entry_start++;
         pp->green = *entry_start++;
         pp->blue = *entry_start++;
         pp->alpha = *entry_start++;
1504
      }
1505

1506 1507
      else
      {
1508 1509 1510 1511
         pp->red   = png_get_uint_16(entry_start); entry_start += 2;
         pp->green = png_get_uint_16(entry_start); entry_start += 2;
         pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
         pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1512
      }
1513

1514 1515
      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
   }
1516 1517
#else
   pp = new_palette.entries;
1518

1519 1520 1521 1522 1523
   for (i = 0; i < new_palette.nentries; i++)
   {

      if (new_palette.depth == 8)
      {
1524 1525 1526 1527
         pp[i].red   = *entry_start++;
         pp[i].green = *entry_start++;
         pp[i].blue  = *entry_start++;
         pp[i].alpha = *entry_start++;
1528
      }
1529

1530 1531
      else
      {
1532 1533 1534 1535
         pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
         pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
         pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
         pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
1536
      }
1537

1538
      pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2;
1539 1540
   }
#endif
1541

1542
   /* Discard all chunk data except the name and stash that */
1543
   new_palette.name = png_ptr->chunkdata;
1544

1545
   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1546

1547 1548
   png_free(png_ptr, png_ptr->chunkdata);
   png_ptr->chunkdata = NULL;
1549 1550 1551 1552
   png_free(png_ptr, new_palette.entries);
}
#endif /* PNG_READ_sPLT_SUPPORTED */

1553
#ifdef PNG_READ_tRNS_SUPPORTED
1554
void /* PRIVATE */
A
Andreas Dilger 已提交
1555
png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
G
Guy Schalnat 已提交
1556
{
1557
   png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1558

1559
   png_debug(1, "in png_handle_tRNS");
A
Andreas Dilger 已提交
1560

G
Guy Schalnat 已提交
1561 1562
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before tRNS");
1563

A
Andreas Dilger 已提交
1564 1565 1566 1567 1568 1569
   else if (png_ptr->mode & PNG_HAVE_IDAT)
   {
      png_warning(png_ptr, "Invalid tRNS after IDAT");
      png_crc_finish(png_ptr, length);
      return;
   }
1570

1571
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
A
Andreas Dilger 已提交
1572
   {
1573
      png_warning(png_ptr, "Duplicate tRNS chunk");
A
Andreas Dilger 已提交
1574 1575 1576
      png_crc_finish(png_ptr, length);
      return;
   }
G
Guy Schalnat 已提交
1577

1578
   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
G
Guy Schalnat 已提交
1579
   {
1580 1581 1582
      png_byte buf[2];

      if (length != 2)
G
Guy Schalnat 已提交
1583
      {
G
Guy Schalnat 已提交
1584
         png_warning(png_ptr, "Incorrect tRNS chunk length");
A
Andreas Dilger 已提交
1585
         png_crc_finish(png_ptr, length);
G
Guy Schalnat 已提交
1586 1587 1588
         return;
      }

1589 1590
      png_crc_read(png_ptr, buf, 2);
      png_ptr->num_trans = 1;
1591
      png_ptr->trans_color.gray = png_get_uint_16(buf);
G
Guy Schalnat 已提交
1592
   }
1593

G
Guy Schalnat 已提交
1594 1595 1596 1597 1598 1599
   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
   {
      png_byte buf[6];

      if (length != 6)
      {
G
Guy Schalnat 已提交
1600
         png_warning(png_ptr, "Incorrect tRNS chunk length");
A
Andreas Dilger 已提交
1601
         png_crc_finish(png_ptr, length);
G
Guy Schalnat 已提交
1602 1603
         return;
      }
1604

A
Andreas Dilger 已提交
1605
      png_crc_read(png_ptr, buf, (png_size_t)length);
1606
      png_ptr->num_trans = 1;
1607 1608 1609
      png_ptr->trans_color.red = png_get_uint_16(buf);
      png_ptr->trans_color.green = png_get_uint_16(buf + 2);
      png_ptr->trans_color.blue = png_get_uint_16(buf + 4);
G
Guy Schalnat 已提交
1610
   }
1611

1612
   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
G
Guy Schalnat 已提交
1613
   {
1614 1615 1616 1617 1618
      if (!(png_ptr->mode & PNG_HAVE_PLTE))
      {
         /* Should be an error, but we can cope with it. */
         png_warning(png_ptr, "Missing PLTE before tRNS");
      }
1619

1620 1621
      if (length > (png_uint_32)png_ptr->num_palette ||
          length > PNG_MAX_PALETTE_LENGTH)
G
Guy Schalnat 已提交
1622
      {
G
Guy Schalnat 已提交
1623
         png_warning(png_ptr, "Incorrect tRNS chunk length");
A
Andreas Dilger 已提交
1624
         png_crc_finish(png_ptr, length);
G
Guy Schalnat 已提交
1625 1626
         return;
      }
1627

1628 1629 1630 1631 1632 1633
      if (length == 0)
      {
         png_warning(png_ptr, "Zero length tRNS chunk");
         png_crc_finish(png_ptr, length);
         return;
      }
1634

1635 1636
      png_crc_read(png_ptr, readbuf, (png_size_t)length);
      png_ptr->num_trans = (png_uint_16)length;
G
Guy Schalnat 已提交
1637
   }
1638

G
Guy Schalnat 已提交
1639
   else
G
Guy Schalnat 已提交
1640 1641
   {
      png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
A
Andreas Dilger 已提交
1642
      png_crc_finish(png_ptr, length);
G
Guy Schalnat 已提交
1643 1644
      return;
   }
G
Guy Schalnat 已提交
1645

A
Andreas Dilger 已提交
1646
   if (png_crc_finish(png_ptr, 0))
1647 1648
   {
      png_ptr->num_trans = 0;
A
Andreas Dilger 已提交
1649
      return;
1650
   }
A
Andreas Dilger 已提交
1651

1652
   png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1653
       &(png_ptr->trans_color));
G
Guy Schalnat 已提交
1654
}
G
Guy Schalnat 已提交
1655
#endif
G
Guy Schalnat 已提交
1656

1657
#ifdef PNG_READ_bKGD_SUPPORTED
1658
void /* PRIVATE */
A
Andreas Dilger 已提交
1659
png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
G
Guy Schalnat 已提交
1660
{
A
Andreas Dilger 已提交
1661
   png_size_t truelen;
G
Guy Schalnat 已提交
1662
   png_byte buf[6];
1663
   png_color_16 background;
G
Guy Schalnat 已提交
1664

1665
   png_debug(1, "in png_handle_bKGD");
A
Andreas Dilger 已提交
1666

G
Guy Schalnat 已提交
1667 1668
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before bKGD");
1669

A
Andreas Dilger 已提交
1670 1671 1672 1673 1674 1675
   else if (png_ptr->mode & PNG_HAVE_IDAT)
   {
      png_warning(png_ptr, "Invalid bKGD after IDAT");
      png_crc_finish(png_ptr, length);
      return;
   }
1676

G
Guy Schalnat 已提交
1677
   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
1678
       !(png_ptr->mode & PNG_HAVE_PLTE))
G
Guy Schalnat 已提交
1679 1680
   {
      png_warning(png_ptr, "Missing PLTE before bKGD");
A
Andreas Dilger 已提交
1681 1682 1683
      png_crc_finish(png_ptr, length);
      return;
   }
1684

1685
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
A
Andreas Dilger 已提交
1686 1687 1688
   {
      png_warning(png_ptr, "Duplicate bKGD chunk");
      png_crc_finish(png_ptr, length);
G
Guy Schalnat 已提交
1689 1690 1691
      return;
   }

G
Guy Schalnat 已提交
1692 1693
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
      truelen = 1;
1694

G
Guy Schalnat 已提交
1695 1696
   else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
      truelen = 6;
1697

G
Guy Schalnat 已提交
1698 1699 1700
   else
      truelen = 2;

A
Andreas Dilger 已提交
1701
   if (length != truelen)
G
Guy Schalnat 已提交
1702
   {
G
Guy Schalnat 已提交
1703
      png_warning(png_ptr, "Incorrect bKGD chunk length");
A
Andreas Dilger 已提交
1704
      png_crc_finish(png_ptr, length);
G
Guy Schalnat 已提交
1705 1706 1707
      return;
   }

A
Andreas Dilger 已提交
1708
   png_crc_read(png_ptr, buf, truelen);
1709

A
Andreas Dilger 已提交
1710 1711 1712
   if (png_crc_finish(png_ptr, 0))
      return;

G
Guy Schalnat 已提交
1713 1714 1715
   /* We convert the index value into RGB components so that we can allow
    * arbitrary RGB values for background when we have transparency, and
    * so it is easy to determine the RGB values of the background color
1716 1717
    * from the info_ptr struct.
    */
G
Guy Schalnat 已提交
1718
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
G
Guy Schalnat 已提交
1719
   {
1720
      background.index = buf[0];
1721

1722
      if (info_ptr && info_ptr->num_palette)
1723
      {
1724 1725 1726 1727 1728 1729
         if (buf[0] >= info_ptr->num_palette)
         {
            png_warning(png_ptr, "Incorrect bKGD chunk index value");
            return;
         }

1730 1731 1732 1733
         background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
         background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
         background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
      }
1734

1735 1736
      else
         background.red = background.green = background.blue = 0;
1737

1738
      background.gray = 0;
G
Guy Schalnat 已提交
1739
   }
1740

A
Andreas Dilger 已提交
1741
   else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
G
Guy Schalnat 已提交
1742
   {
1743 1744 1745 1746 1747
      background.index = 0;
      background.red =
      background.green =
      background.blue =
      background.gray = png_get_uint_16(buf);
G
Guy Schalnat 已提交
1748
   }
1749

G
Guy Schalnat 已提交
1750 1751
   else
   {
1752 1753 1754 1755 1756
      background.index = 0;
      background.red = png_get_uint_16(buf);
      background.green = png_get_uint_16(buf + 2);
      background.blue = png_get_uint_16(buf + 4);
      background.gray = 0;
G
Guy Schalnat 已提交
1757 1758
   }

1759
   png_set_bKGD(png_ptr, info_ptr, &background);
G
Guy Schalnat 已提交
1760
}
G
Guy Schalnat 已提交
1761
#endif
G
Guy Schalnat 已提交
1762

1763
#ifdef PNG_READ_hIST_SUPPORTED
1764
void /* PRIVATE */
A
Andreas Dilger 已提交
1765
png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
G
Guy Schalnat 已提交
1766
{
1767
   unsigned int num, i;
1768
   png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
G
Guy Schalnat 已提交
1769

1770
   png_debug(1, "in png_handle_hIST");
A
Andreas Dilger 已提交
1771

G
Guy Schalnat 已提交
1772 1773
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before hIST");
1774

A
Andreas Dilger 已提交
1775 1776 1777 1778 1779 1780
   else if (png_ptr->mode & PNG_HAVE_IDAT)
   {
      png_warning(png_ptr, "Invalid hIST after IDAT");
      png_crc_finish(png_ptr, length);
      return;
   }
1781

G
Guy Schalnat 已提交
1782 1783 1784
   else if (!(png_ptr->mode & PNG_HAVE_PLTE))
   {
      png_warning(png_ptr, "Missing PLTE before hIST");
A
Andreas Dilger 已提交
1785 1786 1787
      png_crc_finish(png_ptr, length);
      return;
   }
1788

1789
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
A
Andreas Dilger 已提交
1790 1791 1792
   {
      png_warning(png_ptr, "Duplicate hIST chunk");
      png_crc_finish(png_ptr, length);
G
Guy Schalnat 已提交
1793 1794 1795
      return;
   }

1796 1797
   if (length > 2*PNG_MAX_PALETTE_LENGTH ||
       length != (unsigned int) (2*png_ptr->num_palette))
G
Guy Schalnat 已提交
1798 1799
   {
      png_warning(png_ptr, "Incorrect hIST chunk length");
A
Andreas Dilger 已提交
1800
      png_crc_finish(png_ptr, length);
G
Guy Schalnat 已提交
1801 1802
      return;
   }
G
Guy Schalnat 已提交
1803

1804 1805
   num = length / 2 ;

G
Guy Schalnat 已提交
1806
   for (i = 0; i < num; i++)
G
Guy Schalnat 已提交
1807 1808 1809 1810
   {
      png_byte buf[2];

      png_crc_read(png_ptr, buf, 2);
1811
      readbuf[i] = png_get_uint_16(buf);
G
Guy Schalnat 已提交
1812
   }
A
Andreas Dilger 已提交
1813 1814 1815 1816

   if (png_crc_finish(png_ptr, 0))
      return;

1817
   png_set_hIST(png_ptr, info_ptr, readbuf);
G
Guy Schalnat 已提交
1818
}
G
Guy Schalnat 已提交
1819
#endif
G
Guy Schalnat 已提交
1820

1821
#ifdef PNG_READ_pHYs_SUPPORTED
1822
void /* PRIVATE */
A
Andreas Dilger 已提交
1823
png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
G
Guy Schalnat 已提交
1824 1825 1826 1827 1828
{
   png_byte buf[9];
   png_uint_32 res_x, res_y;
   int unit_type;

1829
   png_debug(1, "in png_handle_pHYs");
A
Andreas Dilger 已提交
1830

G
Guy Schalnat 已提交
1831
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1832
      png_error(png_ptr, "Missing IHDR before pHYs");
1833

A
Andreas Dilger 已提交
1834 1835
   else if (png_ptr->mode & PNG_HAVE_IDAT)
   {
1836
      png_warning(png_ptr, "Invalid pHYs after IDAT");
A
Andreas Dilger 已提交
1837 1838 1839
      png_crc_finish(png_ptr, length);
      return;
   }
1840

1841
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
A
Andreas Dilger 已提交
1842
   {
1843
      png_warning(png_ptr, "Duplicate pHYs chunk");
A
Andreas Dilger 已提交
1844 1845 1846
      png_crc_finish(png_ptr, length);
      return;
   }
G
Guy Schalnat 已提交
1847

G
Guy Schalnat 已提交
1848 1849
   if (length != 9)
   {
G
Guy Schalnat 已提交
1850
      png_warning(png_ptr, "Incorrect pHYs chunk length");
A
Andreas Dilger 已提交
1851
      png_crc_finish(png_ptr, length);
G
Guy Schalnat 已提交
1852
      return;
G
Guy Schalnat 已提交
1853
   }
G
Guy Schalnat 已提交
1854 1855

   png_crc_read(png_ptr, buf, 9);
1856

A
Andreas Dilger 已提交
1857 1858
   if (png_crc_finish(png_ptr, 0))
      return;
G
Guy Schalnat 已提交
1859 1860 1861 1862

   res_x = png_get_uint_32(buf);
   res_y = png_get_uint_32(buf + 4);
   unit_type = buf[8];
A
Andreas Dilger 已提交
1863
   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
G
Guy Schalnat 已提交
1864
}
G
Guy Schalnat 已提交
1865
#endif
G
Guy Schalnat 已提交
1866

1867
#ifdef PNG_READ_oFFs_SUPPORTED
1868
void /* PRIVATE */
A
Andreas Dilger 已提交
1869
png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
G
Guy Schalnat 已提交
1870 1871
{
   png_byte buf[9];
1872
   png_int_32 offset_x, offset_y;
G
Guy Schalnat 已提交
1873 1874
   int unit_type;

1875
   png_debug(1, "in png_handle_oFFs");
A
Andreas Dilger 已提交
1876

G
Guy Schalnat 已提交
1877 1878
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before oFFs");
1879

A
Andreas Dilger 已提交
1880 1881 1882 1883 1884 1885
   else if (png_ptr->mode & PNG_HAVE_IDAT)
   {
      png_warning(png_ptr, "Invalid oFFs after IDAT");
      png_crc_finish(png_ptr, length);
      return;
   }
1886

1887
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
A
Andreas Dilger 已提交
1888 1889 1890 1891 1892
   {
      png_warning(png_ptr, "Duplicate oFFs chunk");
      png_crc_finish(png_ptr, length);
      return;
   }
G
Guy Schalnat 已提交
1893

G
Guy Schalnat 已提交
1894 1895
   if (length != 9)
   {
G
Guy Schalnat 已提交
1896
      png_warning(png_ptr, "Incorrect oFFs chunk length");
A
Andreas Dilger 已提交
1897
      png_crc_finish(png_ptr, length);
G
Guy Schalnat 已提交
1898 1899 1900
      return;
   }

G
Guy Schalnat 已提交
1901
   png_crc_read(png_ptr, buf, 9);
1902

A
Andreas Dilger 已提交
1903 1904
   if (png_crc_finish(png_ptr, 0))
      return;
G
Guy Schalnat 已提交
1905

1906 1907
   offset_x = png_get_int_32(buf);
   offset_y = png_get_int_32(buf + 4);
G
Guy Schalnat 已提交
1908
   unit_type = buf[8];
A
Andreas Dilger 已提交
1909 1910 1911 1912
   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
}
#endif

1913
#ifdef PNG_READ_pCAL_SUPPORTED
1914
/* Read the pCAL chunk (described in the PNG Extensions document) */
1915
void /* PRIVATE */
A
Andreas Dilger 已提交
1916 1917 1918 1919 1920 1921
png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
   png_int_32 X0, X1;
   png_byte type, nparams;
   png_charp buf, units, endptr;
   png_charpp params;
1922
   png_size_t slength;
A
Andreas Dilger 已提交
1923 1924
   int i;

1925
   png_debug(1, "in png_handle_pCAL");
A
Andreas Dilger 已提交
1926 1927 1928

   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before pCAL");
1929

A
Andreas Dilger 已提交
1930 1931 1932 1933 1934 1935
   else if (png_ptr->mode & PNG_HAVE_IDAT)
   {
      png_warning(png_ptr, "Invalid pCAL after IDAT");
      png_crc_finish(png_ptr, length);
      return;
   }
1936

1937
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
A
Andreas Dilger 已提交
1938 1939 1940 1941 1942 1943
   {
      png_warning(png_ptr, "Duplicate pCAL chunk");
      png_crc_finish(png_ptr, length);
      return;
   }

1944 1945
   png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)",
       length + 1);
1946 1947
   png_free(png_ptr, png_ptr->chunkdata);
   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1948

1949
   if (png_ptr->chunkdata == NULL)
1950 1951 1952 1953 1954
   {
      png_warning(png_ptr, "No memory for pCAL purpose");
      return;
   }

1955
   slength = length;
1956
   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
A
Andreas Dilger 已提交
1957 1958 1959

   if (png_crc_finish(png_ptr, 0))
   {
1960 1961
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
A
Andreas Dilger 已提交
1962 1963 1964
      return;
   }

1965
   png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
A
Andreas Dilger 已提交
1966

1967
   png_debug(3, "Finding end of pCAL purpose string");
1968
   for (buf = png_ptr->chunkdata; *buf; buf++)
1969
      /* Empty loop */ ;
A
Andreas Dilger 已提交
1970

1971
   endptr = png_ptr->chunkdata + slength;
A
Andreas Dilger 已提交
1972 1973

   /* We need to have at least 12 bytes after the purpose string
1974 1975
    * in order to get the parameter information.
    */
A
Andreas Dilger 已提交
1976 1977 1978
   if (endptr <= buf + 12)
   {
      png_warning(png_ptr, "Invalid pCAL data");
1979 1980
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
A
Andreas Dilger 已提交
1981 1982 1983
      return;
   }

1984
   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
A
Andreas Dilger 已提交
1985 1986 1987 1988 1989 1990
   X0 = png_get_int_32((png_bytep)buf+1);
   X1 = png_get_int_32((png_bytep)buf+5);
   type = buf[9];
   nparams = buf[10];
   units = buf + 11;

1991
   png_debug(3, "Checking pCAL equation type and number of parameters");
A
Andreas Dilger 已提交
1992
   /* Check that we have the right number of parameters for known
1993 1994
    * equation types.
    */
A
Andreas Dilger 已提交
1995 1996 1997 1998 1999 2000
   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
   {
      png_warning(png_ptr, "Invalid pCAL parameters for equation type");
2001 2002
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
A
Andreas Dilger 已提交
2003 2004
      return;
   }
2005

A
Andreas Dilger 已提交
2006 2007 2008 2009 2010
   else if (type >= PNG_EQUATION_LAST)
   {
      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
   }

2011
   for (buf = units; *buf; buf++)
2012
      /* Empty loop to move past the units string. */ ;
A
Andreas Dilger 已提交
2013

2014
   png_debug(3, "Allocating pCAL parameters array");
2015

2016
   params = (png_charpp)png_malloc_warn(png_ptr,
2017 2018
       (png_size_t)(nparams * png_sizeof(png_charp)));

2019
   if (params == NULL)
2020 2021 2022 2023 2024 2025
   {
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
      png_warning(png_ptr, "No memory for pCAL params");
      return;
   }
A
Andreas Dilger 已提交
2026 2027

   /* Get pointers to the start of each parameter string. */
2028
   for (i = 0; i < (int)nparams; i++)
A
Andreas Dilger 已提交
2029 2030 2031
   {
      buf++; /* Skip the null string terminator from previous parameter. */

2032
      png_debug1(3, "Reading pCAL parameter %d", i);
2033

2034
      for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
2035
         /* Empty loop to move past each parameter string */ ;
A
Andreas Dilger 已提交
2036 2037 2038 2039 2040

      /* Make sure we haven't run out of data yet */
      if (buf > endptr)
      {
         png_warning(png_ptr, "Invalid pCAL data");
2041 2042
         png_free(png_ptr, png_ptr->chunkdata);
         png_ptr->chunkdata = NULL;
A
Andreas Dilger 已提交
2043 2044 2045 2046 2047
         png_free(png_ptr, params);
         return;
      }
   }

2048
   png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
A
Andreas Dilger 已提交
2049 2050
      units, params);

2051 2052
   png_free(png_ptr, png_ptr->chunkdata);
   png_ptr->chunkdata = NULL;
A
Andreas Dilger 已提交
2053
   png_free(png_ptr, params);
G
Guy Schalnat 已提交
2054
}
G
Guy Schalnat 已提交
2055
#endif
G
Guy Schalnat 已提交
2056

2057
#ifdef PNG_READ_sCAL_SUPPORTED
2058
/* Read the sCAL chunk */
2059
void /* PRIVATE */
2060 2061
png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
2062
   png_size_t slength, i;
2063
   int state;
2064

2065
   png_debug(1, "in png_handle_sCAL");
2066 2067 2068

   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before sCAL");
2069

2070 2071 2072 2073 2074 2075
   else if (png_ptr->mode & PNG_HAVE_IDAT)
   {
      png_warning(png_ptr, "Invalid sCAL after IDAT");
      png_crc_finish(png_ptr, length);
      return;
   }
2076

2077
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
2078 2079 2080 2081 2082 2083
   {
      png_warning(png_ptr, "Duplicate sCAL chunk");
      png_crc_finish(png_ptr, length);
      return;
   }

2084 2085 2086 2087 2088 2089 2090 2091
   /* Need unit type, width, \0, height: minimum 4 bytes */
   else if (length < 4)
   {
      png_warning(png_ptr, "sCAL chunk too short");
      png_crc_finish(png_ptr, length);
      return;
   }

2092
   png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
2093
      length + 1);
2094

2095
   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2096

2097
   if (png_ptr->chunkdata == NULL)
2098 2099
   {
      png_warning(png_ptr, "Out of memory while processing sCAL chunk");
2100
      png_crc_finish(png_ptr, length);
2101 2102
      return;
   }
2103

2104
   slength = length;
2105
   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2106
   png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
2107

G
[devel]  
Glenn Randers-Pehrson 已提交
2108
   if (png_crc_finish(png_ptr, 0))
2109
   {
2110 2111
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
2112
      return;
2113
   }
2114

2115 2116
   /* Validate the unit. */
   if (png_ptr->chunkdata[0] != 1 && png_ptr->chunkdata[0] != 2)
2117
   {
2118
      png_warning(png_ptr, "Invalid sCAL ignored: invalid unit");
2119 2120
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
2121 2122
      return;
   }
2123

2124 2125 2126
   /* Validate the ASCII numbers, need two ASCII numbers separated by
    * a '\0' and they need to fit exactly in the chunk data.
    */
2127
   i = 1;
2128
   state = 0;
2129

2130
   if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) ||
2131
       i >= slength || png_ptr->chunkdata[i++] != 0)
2132 2133
      png_warning(png_ptr, "Invalid sCAL chunk ignored: bad width format");

2134 2135 2136
   else if (!PNG_FP_IS_POSITIVE(state))
      png_warning(png_ptr, "Invalid sCAL chunk ignored: non-positive width");

2137
   else
2138
   {
2139
      png_size_t heighti = i;
2140

2141
      state = 0;
2142
      if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) ||
2143
          i != slength)
2144
         png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format");
2145

2146 2147 2148 2149
      else if (!PNG_FP_IS_POSITIVE(state))
         png_warning(png_ptr,
            "Invalid sCAL chunk ignored: non-positive height");

2150 2151 2152 2153 2154
      else
         /* This is the (only) success case. */
         png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0],
            png_ptr->chunkdata+1, png_ptr->chunkdata+heighti);
   }
2155

2156
   /* Clean up - just free the temporarily allocated buffer. */
2157 2158
   png_free(png_ptr, png_ptr->chunkdata);
   png_ptr->chunkdata = NULL;
2159 2160 2161
}
#endif

2162
#ifdef PNG_READ_tIME_SUPPORTED
2163
void /* PRIVATE */
A
Andreas Dilger 已提交
2164
png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
G
Guy Schalnat 已提交
2165 2166 2167 2168
{
   png_byte buf[7];
   png_time mod_time;

2169
   png_debug(1, "in png_handle_tIME");
A
Andreas Dilger 已提交
2170

G
Guy Schalnat 已提交
2171
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
A
Andreas Dilger 已提交
2172
      png_error(png_ptr, "Out of place tIME chunk");
2173

2174
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
A
Andreas Dilger 已提交
2175 2176 2177 2178 2179 2180 2181 2182
   {
      png_warning(png_ptr, "Duplicate tIME chunk");
      png_crc_finish(png_ptr, length);
      return;
   }

   if (png_ptr->mode & PNG_HAVE_IDAT)
      png_ptr->mode |= PNG_AFTER_IDAT;
G
Guy Schalnat 已提交
2183

G
Guy Schalnat 已提交
2184 2185
   if (length != 7)
   {
G
Guy Schalnat 已提交
2186
      png_warning(png_ptr, "Incorrect tIME chunk length");
A
Andreas Dilger 已提交
2187
      png_crc_finish(png_ptr, length);
G
Guy Schalnat 已提交
2188 2189 2190 2191
      return;
   }

   png_crc_read(png_ptr, buf, 7);
2192

A
Andreas Dilger 已提交
2193 2194
   if (png_crc_finish(png_ptr, 0))
      return;
G
Guy Schalnat 已提交
2195 2196 2197 2198 2199 2200

   mod_time.second = buf[6];
   mod_time.minute = buf[5];
   mod_time.hour = buf[4];
   mod_time.day = buf[3];
   mod_time.month = buf[2];
G
Guy Schalnat 已提交
2201
   mod_time.year = png_get_uint_16(buf);
G
Guy Schalnat 已提交
2202

A
Andreas Dilger 已提交
2203
   png_set_tIME(png_ptr, info_ptr, &mod_time);
G
Guy Schalnat 已提交
2204
}
G
Guy Schalnat 已提交
2205
#endif
G
Guy Schalnat 已提交
2206

2207
#ifdef PNG_READ_tEXt_SUPPORTED
A
Andreas Dilger 已提交
2208
/* Note: this does not properly handle chunks that are > 64K under DOS */
2209
void /* PRIVATE */
A
Andreas Dilger 已提交
2210
png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
G
Guy Schalnat 已提交
2211
{
A
Andreas Dilger 已提交
2212
   png_textp text_ptr;
G
Guy Schalnat 已提交
2213
   png_charp key;
G
Guy Schalnat 已提交
2214
   png_charp text;
A
Andreas Dilger 已提交
2215
   png_uint_32 skip = 0;
2216
   png_size_t slength;
2217
   int ret;
A
Andreas Dilger 已提交
2218

2219
   png_debug(1, "in png_handle_tEXt");
G
Guy Schalnat 已提交
2220

2221
#ifdef PNG_USER_LIMITS_SUPPORTED
2222 2223 2224 2225 2226 2227 2228
   if (png_ptr->user_chunk_cache_max != 0)
   {
      if (png_ptr->user_chunk_cache_max == 1)
      {
         png_crc_finish(png_ptr, length);
         return;
      }
2229

2230 2231 2232 2233 2234 2235 2236 2237 2238
      if (--png_ptr->user_chunk_cache_max == 1)
      {
         png_warning(png_ptr, "No space in chunk cache for tEXt");
         png_crc_finish(png_ptr, length);
         return;
      }
   }
#endif

G
Guy Schalnat 已提交
2239 2240 2241
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before tEXt");

A
Andreas Dilger 已提交
2242 2243 2244
   if (png_ptr->mode & PNG_HAVE_IDAT)
      png_ptr->mode |= PNG_AFTER_IDAT;

A
Andreas Dilger 已提交
2245
#ifdef PNG_MAX_MALLOC_64K
2246
   if (length > (png_uint_32)65535L)
A
Andreas Dilger 已提交
2247 2248
   {
      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
2249 2250
      skip = length - (png_uint_32)65535L;
      length = (png_uint_32)65535L;
A
Andreas Dilger 已提交
2251 2252 2253
   }
#endif

2254 2255 2256
   png_free(png_ptr, png_ptr->chunkdata);

   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2257

2258
   if (png_ptr->chunkdata == NULL)
2259
   {
2260
     png_warning(png_ptr, "No memory to process text chunk");
2261 2262
     return;
   }
2263

2264
   slength = length;
2265
   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
A
Andreas Dilger 已提交
2266 2267

   if (png_crc_finish(png_ptr, skip))
A
Andreas Dilger 已提交
2268
   {
2269 2270
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
A
Andreas Dilger 已提交
2271 2272 2273
      return;
   }

2274 2275
   key = png_ptr->chunkdata;

2276
   key[slength] = 0x00;
G
Guy Schalnat 已提交
2277 2278

   for (text = key; *text; text++)
2279
      /* Empty loop to find end of key */ ;
G
Guy Schalnat 已提交
2280

2281
   if (text != key + slength)
G
Guy Schalnat 已提交
2282 2283
      text++;

2284
   text_ptr = (png_textp)png_malloc_warn(png_ptr,
2285 2286
       png_sizeof(png_text));

2287 2288
   if (text_ptr == NULL)
   {
2289 2290 2291 2292
      png_warning(png_ptr, "Not enough memory to process text chunk");
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
      return;
2293
   }
2294

A
Andreas Dilger 已提交
2295 2296
   text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
   text_ptr->key = key;
2297 2298
   text_ptr->lang = NULL;
   text_ptr->lang_key = NULL;
2299
   text_ptr->itxt_length = 0;
A
Andreas Dilger 已提交
2300
   text_ptr->text = text;
2301
   text_ptr->text_length = png_strlen(text);
A
Andreas Dilger 已提交
2302

2303
   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
A
Andreas Dilger 已提交
2304

2305 2306
   png_free(png_ptr, png_ptr->chunkdata);
   png_ptr->chunkdata = NULL;
2307
   png_free(png_ptr, text_ptr);
2308

2309
   if (ret)
2310
      png_warning(png_ptr, "Insufficient memory to process text chunk");
G
Guy Schalnat 已提交
2311
}
G
Guy Schalnat 已提交
2312
#endif
G
Guy Schalnat 已提交
2313

2314
#ifdef PNG_READ_zTXt_SUPPORTED
2315
/* Note: this does not correctly handle chunks that are > 64K under DOS */
2316
void /* PRIVATE */
A
Andreas Dilger 已提交
2317
png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
G
Guy Schalnat 已提交
2318
{
A
Andreas Dilger 已提交
2319
   png_textp text_ptr;
G
Guy Schalnat 已提交
2320
   png_charp text;
2321
   int comp_type;
2322
   int ret;
2323
   png_size_t slength, prefix_len, data_len;
A
Andreas Dilger 已提交
2324

2325
   png_debug(1, "in png_handle_zTXt");
2326

2327
#ifdef PNG_USER_LIMITS_SUPPORTED
2328 2329 2330 2331 2332 2333 2334
   if (png_ptr->user_chunk_cache_max != 0)
   {
      if (png_ptr->user_chunk_cache_max == 1)
      {
         png_crc_finish(png_ptr, length);
         return;
      }
2335

2336 2337 2338 2339 2340 2341 2342 2343 2344
      if (--png_ptr->user_chunk_cache_max == 1)
      {
         png_warning(png_ptr, "No space in chunk cache for zTXt");
         png_crc_finish(png_ptr, length);
         return;
      }
   }
#endif

G
Guy Schalnat 已提交
2345 2346 2347
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before zTXt");

A
Andreas Dilger 已提交
2348 2349 2350
   if (png_ptr->mode & PNG_HAVE_IDAT)
      png_ptr->mode |= PNG_AFTER_IDAT;

A
Andreas Dilger 已提交
2351 2352
#ifdef PNG_MAX_MALLOC_64K
   /* We will no doubt have problems with chunks even half this size, but
2353 2354
    * there is no hard and fast rule to tell us where to stop.
    */
2355
   if (length > (png_uint_32)65535L)
A
Andreas Dilger 已提交
2356
   {
2357 2358 2359
      png_warning(png_ptr, "zTXt chunk too large to fit in memory");
      png_crc_finish(png_ptr, length);
      return;
A
Andreas Dilger 已提交
2360 2361 2362
   }
#endif

2363
   png_free(png_ptr, png_ptr->chunkdata);
2364
   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2365

2366
   if (png_ptr->chunkdata == NULL)
2367
   {
2368 2369
      png_warning(png_ptr, "Out of memory processing zTXt chunk");
      return;
2370
   }
2371

2372
   slength = length;
2373
   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2374

A
Andreas Dilger 已提交
2375 2376
   if (png_crc_finish(png_ptr, 0))
   {
2377 2378
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
A
Andreas Dilger 已提交
2379 2380 2381
      return;
   }

2382
   png_ptr->chunkdata[slength] = 0x00;
G
Guy Schalnat 已提交
2383

2384
   for (text = png_ptr->chunkdata; *text; text++)
2385
      /* Empty loop */ ;
G
Guy Schalnat 已提交
2386

2387
   /* zTXt must have some text after the chunkdataword */
2388
   if (text >= png_ptr->chunkdata + slength - 2)
G
Guy Schalnat 已提交
2389
   {
2390
      png_warning(png_ptr, "Truncated zTXt chunk");
2391 2392
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
2393
      return;
G
Guy Schalnat 已提交
2394
   }
2395

2396
   else
G
Guy Schalnat 已提交
2397
   {
2398
       comp_type = *(++text);
2399

2400 2401 2402 2403 2404
       if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
       {
          png_warning(png_ptr, "Unknown compression type in zTXt chunk");
          comp_type = PNG_TEXT_COMPRESSION_zTXt;
       }
2405

2406
       text++;        /* Skip the compression_method byte */
2407
   }
2408

2409
   prefix_len = text - png_ptr->chunkdata;
G
Guy Schalnat 已提交
2410

2411
   png_decompress_chunk(png_ptr, comp_type,
2412
       (png_size_t)length, prefix_len, &data_len);
G
Guy Schalnat 已提交
2413

2414
   text_ptr = (png_textp)png_malloc_warn(png_ptr,
2415 2416
       png_sizeof(png_text));

2417 2418
   if (text_ptr == NULL)
   {
2419 2420 2421 2422
      png_warning(png_ptr, "Not enough memory to process zTXt chunk");
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
      return;
2423
   }
2424

2425
   text_ptr->compression = comp_type;
2426
   text_ptr->key = png_ptr->chunkdata;
2427 2428 2429
   text_ptr->lang = NULL;
   text_ptr->lang_key = NULL;
   text_ptr->itxt_length = 0;
2430
   text_ptr->text = png_ptr->chunkdata + prefix_len;
2431
   text_ptr->text_length = data_len;
G
Guy Schalnat 已提交
2432

2433
   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
G
Guy Schalnat 已提交
2434

2435
   png_free(png_ptr, text_ptr);
2436 2437
   png_free(png_ptr, png_ptr->chunkdata);
   png_ptr->chunkdata = NULL;
2438

2439
   if (ret)
2440
      png_error(png_ptr, "Insufficient memory to store zTXt chunk");
2441 2442
}
#endif
G
Guy Schalnat 已提交
2443

2444
#ifdef PNG_READ_iTXt_SUPPORTED
2445
/* Note: this does not correctly handle chunks that are > 64K under DOS */
2446
void /* PRIVATE */
2447 2448 2449
png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
   png_textp text_ptr;
2450
   png_charp key, lang, text, lang_key;
2451
   int comp_flag;
2452
   int comp_type = 0;
2453
   int ret;
2454
   png_size_t slength, prefix_len, data_len;
G
Guy Schalnat 已提交
2455

2456
   png_debug(1, "in png_handle_iTXt");
G
Guy Schalnat 已提交
2457

2458
#ifdef PNG_USER_LIMITS_SUPPORTED
2459 2460 2461 2462 2463 2464 2465
   if (png_ptr->user_chunk_cache_max != 0)
   {
      if (png_ptr->user_chunk_cache_max == 1)
      {
         png_crc_finish(png_ptr, length);
         return;
      }
2466

2467 2468 2469 2470 2471 2472 2473 2474 2475
      if (--png_ptr->user_chunk_cache_max == 1)
      {
         png_warning(png_ptr, "No space in chunk cache for iTXt");
         png_crc_finish(png_ptr, length);
         return;
      }
   }
#endif

2476 2477
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
      png_error(png_ptr, "Missing IHDR before iTXt");
G
Guy Schalnat 已提交
2478

2479 2480
   if (png_ptr->mode & PNG_HAVE_IDAT)
      png_ptr->mode |= PNG_AFTER_IDAT;
G
Guy Schalnat 已提交
2481

2482 2483
#ifdef PNG_MAX_MALLOC_64K
   /* We will no doubt have problems with chunks even half this size, but
2484 2485
    * there is no hard and fast rule to tell us where to stop.
    */
2486 2487
   if (length > (png_uint_32)65535L)
   {
2488 2489 2490
      png_warning(png_ptr, "iTXt chunk too large to fit in memory");
      png_crc_finish(png_ptr, length);
      return;
G
Guy Schalnat 已提交
2491
   }
2492 2493
#endif

2494 2495
   png_free(png_ptr, png_ptr->chunkdata);
   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2496

2497
   if (png_ptr->chunkdata == NULL)
2498
   {
2499 2500
      png_warning(png_ptr, "No memory to process iTXt chunk");
      return;
2501
   }
2502

2503
   slength = length;
2504
   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2505

2506
   if (png_crc_finish(png_ptr, 0))
A
Andreas Dilger 已提交
2507
   {
2508 2509
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
2510 2511
      return;
   }
A
Andreas Dilger 已提交
2512

2513
   png_ptr->chunkdata[slength] = 0x00;
A
Andreas Dilger 已提交
2514

2515
   for (lang = png_ptr->chunkdata; *lang; lang++)
2516
      /* Empty loop */ ;
2517

2518
   lang++;        /* Skip NUL separator */
2519

2520
   /* iTXt must have a language tag (possibly empty), two compression bytes,
2521 2522 2523
    * translated keyword (possibly empty), and possibly some text after the
    * keyword
    */
2524

2525
   if (lang >= png_ptr->chunkdata + slength - 3)
2526
   {
2527
      png_warning(png_ptr, "Truncated iTXt chunk");
2528 2529
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
2530
      return;
A
Andreas Dilger 已提交
2531
   }
2532

2533 2534
   else
   {
2535 2536
      comp_flag = *lang++;
      comp_type = *lang++;
2537 2538
   }

2539
   if (comp_type || (comp_flag && comp_flag != PNG_TEXT_COMPRESSION_zTXt))
2540
   {
2541
      png_warning(png_ptr, "Unknown iTXt compression type or method");
2542 2543 2544 2545 2546
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
      return;
   }

2547
   for (lang_key = lang; *lang_key; lang_key++)
2548
      /* Empty loop */ ;
2549

2550
   lang_key++;        /* Skip NUL separator */
2551

2552
   if (lang_key >= png_ptr->chunkdata + slength)
2553 2554
   {
      png_warning(png_ptr, "Truncated iTXt chunk");
2555 2556
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
2557 2558 2559
      return;
   }

2560
   for (text = lang_key; *text; text++)
2561
      /* Empty loop */ ;
2562

2563
   text++;        /* Skip NUL separator */
2564

2565
   if (text >= png_ptr->chunkdata + slength)
2566 2567
   {
      png_warning(png_ptr, "Malformed iTXt chunk");
2568 2569
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
2570 2571
      return;
   }
2572

2573
   prefix_len = text - png_ptr->chunkdata;
2574

2575
   key=png_ptr->chunkdata;
2576

2577
   if (comp_flag)
2578 2579 2580
      png_decompress_chunk(png_ptr, comp_type,
          (size_t)length, prefix_len, &data_len);

2581
   else
2582 2583
      data_len = png_strlen(png_ptr->chunkdata + prefix_len);

2584
   text_ptr = (png_textp)png_malloc_warn(png_ptr,
2585 2586
       png_sizeof(png_text));

2587 2588
   if (text_ptr == NULL)
   {
2589 2590 2591 2592
      png_warning(png_ptr, "Not enough memory to process iTXt chunk");
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
      return;
2593
   }
2594

2595
   text_ptr->compression = (int)comp_flag + 1;
2596 2597
   text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
   text_ptr->lang = png_ptr->chunkdata + (lang - key);
2598 2599
   text_ptr->itxt_length = data_len;
   text_ptr->text_length = 0;
2600 2601
   text_ptr->key = png_ptr->chunkdata;
   text_ptr->text = png_ptr->chunkdata + prefix_len;
G
Guy Schalnat 已提交
2602

2603
   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
A
Andreas Dilger 已提交
2604

2605
   png_free(png_ptr, text_ptr);
2606 2607
   png_free(png_ptr, png_ptr->chunkdata);
   png_ptr->chunkdata = NULL;
2608

2609
   if (ret)
2610
      png_error(png_ptr, "Insufficient memory to store iTXt chunk");
2611 2612 2613
}
#endif

A
Andreas Dilger 已提交
2614
/* This function is called when we haven't found a handler for a
2615 2616 2617 2618 2619
 * chunk.  If there isn't a problem with the chunk itself (ie bad
 * chunk name, CRC, or a critical chunk), the chunk is silently ignored
 * -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
 * case it will be saved away to be written out later.
 */
2620
void /* PRIVATE */
A
Andreas Dilger 已提交
2621 2622
png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
2623 2624
   png_uint_32 skip = 0;

2625
   png_debug(1, "in png_handle_unknown");
A
Andreas Dilger 已提交
2626

2627
#ifdef PNG_USER_LIMITS_SUPPORTED
2628 2629 2630 2631 2632 2633 2634
   if (png_ptr->user_chunk_cache_max != 0)
   {
      if (png_ptr->user_chunk_cache_max == 1)
      {
         png_crc_finish(png_ptr, length);
         return;
      }
2635

2636 2637 2638 2639 2640 2641 2642 2643 2644
      if (--png_ptr->user_chunk_cache_max == 1)
      {
         png_warning(png_ptr, "No space in chunk cache for unknown chunk");
         png_crc_finish(png_ptr, length);
         return;
      }
   }
#endif

2645
   if (png_ptr->mode & PNG_HAVE_IDAT)
2646
   {
2647
      if (png_ptr->chunk_name != png_IDAT)
2648 2649
         png_ptr->mode |= PNG_AFTER_IDAT;
   }
2650

2651
   if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
A
Andreas Dilger 已提交
2652
   {
2653
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2654
      if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) !=
2655
          PNG_HANDLE_CHUNK_ALWAYS
2656
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2657
          && png_ptr->read_user_chunk_fn == NULL
2658
#endif
2659
          )
2660
#endif
2661
         png_chunk_error(png_ptr, "unknown critical chunk");
A
Andreas Dilger 已提交
2662 2663
   }

2664
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
2665
   if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
2666
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2667 2668
       || (png_ptr->read_user_chunk_fn != NULL)
#endif
2669
       )
2670 2671
   {
#ifdef PNG_MAX_MALLOC_64K
2672
      if (length > 65535)
2673 2674
      {
         png_warning(png_ptr, "unknown chunk too large to fit in memory");
2675 2676
         skip = length - 65535;
         length = 65535;
2677
      }
2678
#endif
2679

2680 2681 2682 2683 2684 2685
      /* TODO: this code is very close to the unknown handling in pngpread.c,
       * maybe it can be put into a common utility routine?
       * png_struct::unknown_chunk is just used as a temporary variable, along
       * with the data into which the chunk is read.  These can be eliminated.
       */
      PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
2686 2687 2688
      png_ptr->unknown_chunk.size = (png_size_t)length;

      if (length == 0)
2689
         png_ptr->unknown_chunk.data = NULL;
2690 2691 2692

      else
      {
2693
         png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
2694
         png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length);
2695 2696
      }

2697
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710
      if (png_ptr->read_user_chunk_fn != NULL)
      {
         /* Callback to user unknown chunk handler */
         int ret;

         ret = (*(png_ptr->read_user_chunk_fn))
             (png_ptr, &png_ptr->unknown_chunk);

         if (ret < 0)
            png_chunk_error(png_ptr, "error in user chunk");

         if (ret == 0)
         {
2711
            if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
2712
            {
2713
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2714
               if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) !=
2715
                   PNG_HANDLE_CHUNK_ALWAYS)
2716
#endif
2717 2718 2719 2720 2721 2722 2723 2724 2725
                  png_chunk_error(png_ptr, "unknown critical chunk");
            }

            png_set_unknown_chunks(png_ptr, info_ptr,
                &png_ptr->unknown_chunk, 1);
         }
      }

      else
2726
#endif
2727 2728 2729 2730
         png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);

      png_free(png_ptr, png_ptr->unknown_chunk.data);
      png_ptr->unknown_chunk.data = NULL;
2731
   }
2732

2733 2734
   else
#endif
2735
      skip = length;
2736

2737
   png_crc_finish(png_ptr, skip);
2738

2739
#ifndef PNG_READ_USER_CHUNKS_SUPPORTED
2740
   PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */
2741
#endif
A
Andreas Dilger 已提交
2742 2743 2744
}

/* This function is called to verify that a chunk name is valid.
2745 2746 2747 2748 2749
 * This function can't have the "critical chunk check" incorporated
 * into it, since in the future we will need to be able to call user
 * functions to handle unknown critical chunks after we check that
 * the chunk name itself is valid.
 */
A
Andreas Dilger 已提交
2750

2751 2752 2753 2754
/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is:
 *
 * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
 */
A
Andreas Dilger 已提交
2755

2756
void /* PRIVATE */
2757
png_check_chunk_name(png_structp png_ptr, png_uint_32 chunk_name)
A
Andreas Dilger 已提交
2758
{
2759 2760
   int i;

2761
   png_debug(1, "in png_check_chunk_name");
2762 2763

   for (i=1; i<=4; ++i)
A
Andreas Dilger 已提交
2764
   {
2765 2766 2767 2768 2769 2770
      int c = chunk_name & 0xff;

      if (c < 65 || c > 122 || (c > 90 && c < 97))
         png_chunk_error(png_ptr, "invalid chunk type");

      chunk_name >>= 8;
A
Andreas Dilger 已提交
2771 2772 2773
   }
}

2774 2775 2776 2777 2778 2779
/* Combines the row recently read in with the existing pixels in the row.  This
 * routine takes care of alpha and transparency if requested.  This routine also
 * handles the two methods of progressive display of interlaced images,
 * depending on the 'display' value; if 'display' is true then the whole row
 * (dp) is filled from the start by replicating the available pixels.  If
 * 'display' is false only those pixels present in the pass are filled in.
2780
 */
2781
void /* PRIVATE */
2782
png_combine_row(png_structp png_ptr, png_bytep dp, int display)
G
Guy Schalnat 已提交
2783
{
2784 2785
   unsigned int pixel_depth = png_ptr->transformed_pixel_depth;
   png_const_bytep sp = png_ptr->row_buf + 1;
2786
   png_uint_32 row_width = png_ptr->width;
2787
   unsigned int pass = png_ptr->pass;
2788 2789 2790
   png_bytep end_ptr = 0;
   png_byte end_byte = 0;
   unsigned int end_mask;
2791

2792
   png_debug(1, "in png_combine_row");
2793

2794 2795 2796 2797 2798 2799 2800 2801
   /* Added in 1.5.6: it should not be possible to enter this routine until at
    * least one row has been read from the PNG data and transformed.
    */
   if (pixel_depth == 0)
      png_error(png_ptr, "internal row logic error");

   /* Added in 1.5.4: the pixel depth should match the information returned by
    * any call to png_read_update_info at this point.  Do not continue if we got
2802 2803 2804
    * this wrong.
    */
   if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes !=
2805
          PNG_ROWBYTES(pixel_depth, row_width))
2806 2807
      png_error(png_ptr, "internal row size calculation error");

2808 2809 2810
   /* Don't expect this to ever happen: */
   if (row_width == 0)
      png_error(png_ptr, "internal row width error");
2811

2812 2813 2814 2815 2816 2817 2818
   /* Preserve the last byte in cases where only part of it will be overwritten,
    * the multiply below may overflow, we don't care because ANSI-C guarantees
    * we get the low bits.
    */
   end_mask = (pixel_depth * row_width) & 7;
   if (end_mask != 0)
   {
2819
      /* end_ptr == NULL is a flag to say do nothing */
2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831
      end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1;
      end_byte = *end_ptr;
#     ifdef PNG_READ_PACKSWAP_SUPPORTED
         if (png_ptr->transformations & PNG_PACKSWAP) /* little-endian byte */
            end_mask = 0xff << end_mask;

         else /* big-endian byte */
#     endif
         end_mask = 0xff >> end_mask;
      /* end_mask is now the bits to *keep* from the destination row */
   }

2832 2833 2834 2835 2836
   /* For non-interlaced images this reduces to a png_memcpy(). A png_memcpy()
    * will also happen if interlacing isn't supported or if the application
    * does not call png_set_interlace_handling().  In the latter cases the
    * caller just gets a sequence of the unexpanded rows from each interlace
    * pass.
2837 2838 2839
    */
#ifdef PNG_READ_INTERLACING_SUPPORTED
   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE) &&
2840 2841 2842
      pass < 6 && (display == 0 ||
      /* The following copies everything for 'display' on passes 0, 2 and 4. */
      (display == 1 && (pass & 1) != 0)))
G
Guy Schalnat 已提交
2843
   {
2844 2845
      /* Narrow images may have no bits in a pass; the caller should handle
       * this, but this test is cheap:
2846
       */
2847 2848
      if (row_width <= PNG_PASS_START_COL(pass))
         return;
2849

2850
      if (pixel_depth < 8)
G
Guy Schalnat 已提交
2851
      {
2852
         /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit
2853
          * into 32 bits, then a single loop over the bytes using the four byte
2854
          * values in the 32-bit mask can be used.  For the 'display' option the
2855 2856 2857 2858 2859 2860
          * expanded mask may also not require any masking within a byte.  To
          * make this work the PACKSWAP option must be taken into account - it
          * simply requires the pixels to be reversed in each byte.
          *
          * The 'regular' case requires a mask for each of the first 6 passes,
          * the 'display' case does a copy for the even passes in the range
2861
          * 0..6.  This has already been handled in the test above.
2862 2863 2864 2865 2866 2867 2868
          *
          * The masks are arranged as four bytes with the first byte to use in
          * the lowest bits (little-endian) regardless of the order (PACKSWAP or
          * not) of the pixels in each byte.
          *
          * NOTE: the whole of this logic depends on the caller of this function
          * only calling it on rows appropriate to the pass.  This function only
2869
          * understands the 'x' logic; the 'y' logic is handled by the caller.
2870 2871 2872
          *
          * The following defines allow generation of compile time constant bit
          * masks for each pixel depth and each possibility of swapped or not
2873 2874 2875 2876 2877
          * swapped bytes.  Pass 'p' is in the range 0..6; 'x', a pixel index,
          * is in the range 0..7; and the result is 1 if the pixel is to be
          * copied in the pass, 0 if not.  'S' is for the sparkle method, 'B'
          * for the block method.
          *
2878
          * With some compilers a compile time expression of the general form:
2879
          *
2880 2881 2882
          *    (shift >= 32) ? (a >> (shift-32)) : (b >> shift)
          *
          * Produces warnings with values of 'shift' in the range 33 to 63
2883
          * because the right hand side of the ?: expression is evaluated by
2884 2885 2886
          * the compiler even though it isn't used.  Microsoft Visual C (various
          * versions) and the Intel C compiler are known to do this.  To avoid
          * this the following macros are used in 1.5.6.  This is a temporary
2887
          * solution to avoid destabilizing the code during the release process.
2888
          */
2889
#        if PNG_USE_COMPILE_TIME_MASKS
2890 2891
#           define PNG_LSR(x,s) ((x)>>((s) & 0x1f))
#           define PNG_LSL(x,s) ((x)<<((s) & 0x1f))
2892
#        else
2893 2894
#           define PNG_LSR(x,s) ((x)>>(s))
#           define PNG_LSL(x,s) ((x)<<(s))
2895
#        endif
2896 2897 2898 2899
#        define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\
           PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1)
#        define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\
           PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1)
2900 2901 2902 2903 2904 2905 2906

         /* Return a mask for pass 'p' pixel 'x' at depth 'd'.  The mask is
          * little endian - the first pixel is at bit 0 - however the extra
          * parameter 's' can be set to cause the mask position to be swapped
          * within each byte, to match the PNG format.  This is done by XOR of
          * the shift with 7, 6 or 4 for bit depths 1, 2 and 4.
          */
2907 2908
#        define PIXEL_MASK(p,x,d,s) \
            (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0))))
2909 2910 2911 2912 2913 2914

         /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask.
          */
#        define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
#        define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)

2915 2916 2917
         /* Combine 8 of these to get the full mask.  For the 1-bpp and 2-bpp
          * cases the result needs replicating, for the 4-bpp case the above
          * generates a full 32 bits.
2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931
          */
#        define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1)))

#        define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\
            S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\
            S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d)

#        define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\
            B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\
            B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d)

#if PNG_USE_COMPILE_TIME_MASKS
         /* Utility macros to construct all the masks for a depth/swap
          * combination.  The 's' parameter says whether the format is PNG
2932
          * (big endian bytes) or not.  Only the three odd-numbered passes are
2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944
          * required for the display/block algorithm.
          */
#        define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\
            S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) }

#        define B_MASKS(d,s) { B_MASK(1,d,s), S_MASK(3,d,s), S_MASK(5,d,s) }

#        define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2))

         /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and
          * then pass:
          */
2945 2946
         static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] =
         {
2947 2948 2949 2950 2951 2952 2953 2954 2955
            /* Little-endian byte masks for PACKSWAP */
            { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) },
            /* Normal (big-endian byte) masks - PNG format */
            { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) }
         };

         /* display_mask has only three entries for the odd passes, so index by
          * pass>>1.
          */
2956 2957
         static PNG_CONST png_uint_32 display_mask[2][3][3] =
         {
2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992
            /* Little-endian byte masks for PACKSWAP */
            { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) },
            /* Normal (big-endian byte) masks - PNG format */
            { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) }
         };

#        define MASK(pass,depth,display,png)\
            ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\
               row_mask[png][DEPTH_INDEX(depth)][pass])

#else /* !PNG_USE_COMPILE_TIME_MASKS */
         /* This is the runtime alternative: it seems unlikely that this will
          * ever be either smaller or faster than the compile time approach.
          */
#        define MASK(pass,depth,display,png)\
            ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png))
#endif /* !PNG_USE_COMPILE_TIME_MASKS */

         /* Use the appropriate mask to copy the required bits.  In some cases
          * the byte mask will be 0 or 0xff, optimize these cases.  row_width is
          * the number of pixels, but the code copies bytes, so it is necessary
          * to special case the end.
          */
         png_uint_32 pixels_per_byte = 8 / pixel_depth;
         png_uint_32 mask;

#        ifdef PNG_READ_PACKSWAP_SUPPORTED
            if (png_ptr->transformations & PNG_PACKSWAP)
               mask = MASK(pass, pixel_depth, display, 0);

            else
#        endif
            mask = MASK(pass, pixel_depth, display, 1);

         for (;;)
G
Guy Schalnat 已提交
2993
         {
2994
            png_uint_32 m;
G
Guy Schalnat 已提交
2995

2996
            /* It doesn't matter in the following if png_uint_32 has more than
2997
             * 32 bits because the high bits always match those in m<<24; it is,
2998 2999 3000 3001 3002
             * however, essential to use OR here, not +, because of this.
             */
            m = mask;
            mask = (m >> 8) | (m << 24); /* rotate right to good compilers */
            m &= 0xff;
3003

3004
            if (m != 0) /* something to copy */
A
Andreas Dilger 已提交
3005
            {
3006 3007 3008 3009
               if (m != 0xff)
                  *dp = (png_byte)((*dp & ~m) | (*sp & m));
               else
                  *dp = *sp;
A
Andreas Dilger 已提交
3010
            }
3011

3012
            /* NOTE: this may overwrite the last byte with garbage if the image
3013
             * is not an exact number of bytes wide; libpng has always done
3014 3015 3016
             * this.
             */
            if (row_width <= pixels_per_byte)
3017
               break; /* May need to restore part of the last byte */
3018

3019 3020 3021 3022 3023
            row_width -= pixels_per_byte;
            ++dp;
            ++sp;
         }
      }
3024

3025 3026 3027
      else /* pixel_depth >= 8 */
      {
         unsigned int bytes_to_copy, bytes_to_jump;
3028

3029 3030 3031
         /* Validate the depth - it must be a multiple of 8 */
         if (pixel_depth & 7)
            png_error(png_ptr, "invalid user transform pixel depth");
3032

3033 3034
         pixel_depth >>= 3; /* now in bytes */
         row_width *= pixel_depth;
3035

3036 3037 3038 3039
         /* Regardless of pass number the Adam 7 interlace always results in a
          * fixed number of pixels to copy then to skip.  There may be a
          * different number of pixels to skip at the start though.
          */
G
Guy Schalnat 已提交
3040
         {
3041
            unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth;
3042

3043 3044 3045 3046
            row_width -= offset;
            dp += offset;
            sp += offset;
         }
3047

3048 3049 3050 3051 3052 3053
         /* Work out the bytes to copy. */
         if (display)
         {
            /* When doing the 'block' algorithm the pixel in the pass gets
             * replicated to adjacent pixels.  This is why the even (0,2,4,6)
             * passes are skipped above - the entire expanded row is copied.
3054
             */
3055
            bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth;
3056

3057 3058 3059 3060
            /* But don't allow this number to exceed the actual row width. */
            if (bytes_to_copy > row_width)
               bytes_to_copy = row_width;
         }
3061

3062 3063
         else /* normal row; Adam7 only ever gives us one pixel to copy. */
            bytes_to_copy = pixel_depth;
3064

3065 3066
         /* In Adam7 there is a constant offset between where the pixels go. */
         bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth;
3067

3068
         /* And simply copy these bytes.  Some optimization is possible here,
3069
          * depending on the value of 'bytes_to_copy'.  Special case the low
3070
          * byte counts, which we know to be frequent.
3071 3072 3073 3074
          *
          * Notice that these cases all 'return' rather than 'break' - this
          * avoids an unnecessary test on whether to restore the last byte
          * below.
3075 3076 3077 3078 3079
          */
         switch (bytes_to_copy)
         {
            case 1:
               for (;;)
3080
               {
3081
                  *dp = *sp;
G
Guy Schalnat 已提交
3082

3083 3084
                  if (row_width <= bytes_to_jump)
                     return;
3085

3086 3087 3088
                  dp += bytes_to_jump;
                  sp += bytes_to_jump;
                  row_width -= bytes_to_jump;
3089
               }
3090

3091
            case 2:
3092
               /* There is a possibility of a partial copy at the end here; this
3093 3094
                * slows the code down somewhat.
                */
3095
               do
3096
               {
3097
                  dp[0] = sp[0], dp[1] = sp[1];
3098

3099 3100
                  if (row_width <= bytes_to_jump)
                     return;
3101

3102 3103 3104
                  sp += bytes_to_jump;
                  dp += bytes_to_jump;
                  row_width -= bytes_to_jump;
3105
               }
3106
               while (row_width > 1);
3107

3108 3109 3110
               /* And there can only be one byte left at this point: */
               *dp = *sp;
               return;
3111

3112 3113 3114 3115 3116
            case 3:
               /* This can only be the RGB case, so each copy is exactly one
                * pixel and it is not necessary to check for a partial copy.
                */
               for(;;)
3117
               {
3118
                  dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2];
3119

3120 3121
                  if (row_width <= bytes_to_jump)
                     return;
3122

3123 3124 3125
                  sp += bytes_to_jump;
                  dp += bytes_to_jump;
                  row_width -= bytes_to_jump;
3126 3127
               }

3128 3129
            default:
#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE
3130 3131
               /* Check for double byte alignment and, if possible, use a
                * 16-bit copy.  Don't attempt this for narrow images - ones that
3132
                * are less than an interlace panel wide.  Don't attempt it for
3133
                * wide bytes_to_copy either - use the png_memcpy there.
3134
                */
3135
               if (bytes_to_copy < 16 /*else use png_memcpy*/ &&
3136 3137 3138 3139
                  png_isaligned(dp, png_uint_16) &&
                  png_isaligned(sp, png_uint_16) &&
                  bytes_to_copy % sizeof (png_uint_16) == 0 &&
                  bytes_to_jump % sizeof (png_uint_16) == 0)
3140
               {
3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174
                  /* Everything is aligned for png_uint_16 copies, but try for
                   * png_uint_32 first.
                   */
                  if (png_isaligned(dp, png_uint_32) &&
                     png_isaligned(sp, png_uint_32) &&
                     bytes_to_copy % sizeof (png_uint_32) == 0 &&
                     bytes_to_jump % sizeof (png_uint_32) == 0)
                  {
                     png_uint_32p dp32 = (png_uint_32p)dp;
                     png_const_uint_32p sp32 = (png_const_uint_32p)sp;
                     unsigned int skip = (bytes_to_jump-bytes_to_copy) /
                        sizeof (png_uint_32);

                     do
                     {
                        size_t c = bytes_to_copy;
                        do
                        {
                           *dp32++ = *sp32++;
                           c -= sizeof (png_uint_32);
                        }
                        while (c > 0);

                        if (row_width <= bytes_to_jump)
                           return;

                        dp32 += skip;
                        sp32 += skip;
                        row_width -= bytes_to_jump;
                     }
                     while (bytes_to_copy <= row_width);

                     /* Get to here when the row_width truncates the final copy.
                      * There will be 1-3 bytes left to copy, so don't try the
3175
                      * 16-bit loop below.
3176 3177 3178 3179 3180 3181 3182 3183 3184
                      */
                     dp = (png_bytep)dp32;
                     sp = (png_const_bytep)sp32;
                     do
                        *dp++ = *sp++;
                     while (--row_width > 0);
                     return;
                  }

3185
                  /* Else do it in 16-bit quantities, but only if the size is
3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213
                   * not too large.
                   */
                  else
                  {
                     png_uint_16p dp16 = (png_uint_16p)dp;
                     png_const_uint_16p sp16 = (png_const_uint_16p)sp;
                     unsigned int skip = (bytes_to_jump-bytes_to_copy) /
                        sizeof (png_uint_16);

                     do
                     {
                        size_t c = bytes_to_copy;
                        do
                        {
                           *dp16++ = *sp16++;
                           c -= sizeof (png_uint_16);
                        }
                        while (c > 0);

                        if (row_width <= bytes_to_jump)
                           return;

                        dp16 += skip;
                        sp16 += skip;
                        row_width -= bytes_to_jump;
                     }
                     while (bytes_to_copy <= row_width);

3214
                     /* End of row - 1 byte left, bytes_to_copy > row_width: */
3215 3216 3217 3218 3219 3220 3221 3222 3223
                     dp = (png_bytep)dp16;
                     sp = (png_const_bytep)sp16;
                     do
                        *dp++ = *sp++;
                     while (--row_width > 0);
                     return;
                  }
               }
#endif /* PNG_ALIGN_ code */
3224

3225
               /* The true default - use a png_memcpy: */
3226 3227 3228
               for (;;)
               {
                  png_memcpy(dp, sp, bytes_to_copy);
3229

3230 3231
                  if (row_width <= bytes_to_jump)
                     return;
3232

3233 3234 3235 3236 3237
                  sp += bytes_to_jump;
                  dp += bytes_to_jump;
                  row_width -= bytes_to_jump;
                  if (bytes_to_copy > row_width)
                     bytes_to_copy = row_width;
3238
               }
G
Guy Schalnat 已提交
3239
         }
3240 3241

         /* NOT REACHED*/
3242
      } /* pixel_depth >= 8 */
3243

3244
      /* Here if pixel_depth < 8 to check 'end_ptr' below. */
G
Guy Schalnat 已提交
3245
   }
3246
   else
3247 3248
#endif

3249
   /* If here then the switch above wasn't used so just png_memcpy the whole row
3250 3251
    * from the temporary row buffer (notice that this overwrites the end of the
    * destination row if it is a partial byte.)
3252 3253
    */
   png_memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width));
3254 3255 3256 3257

   /* Restore the overwritten bits from the last byte if necessary. */
   if (end_ptr != NULL)
      *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask));
G
Guy Schalnat 已提交
3258 3259
}

3260
#ifdef PNG_READ_INTERLACING_SUPPORTED
3261
void /* PRIVATE */
3262 3263
png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
   png_uint_32 transformations /* Because these may affect the byte layout */)
G
Guy Schalnat 已提交
3264
{
3265 3266
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
   /* Offset to next interlace block */
3267
   static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3268

3269
   png_debug(1, "in png_do_read_interlace");
3270
   if (row != NULL && row_info != NULL)
G
Guy Schalnat 已提交
3271
   {
3272 3273 3274
      png_uint_32 final_width;

      final_width = row_info->width * png_pass_inc[pass];
G
Guy Schalnat 已提交
3275 3276 3277 3278 3279

      switch (row_info->pixel_depth)
      {
         case 1:
         {
3280 3281
            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
            png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
3282 3283 3284 3285
            int sshift, dshift;
            int s_start, s_end, s_inc;
            int jstop = png_pass_inc[pass];
            png_byte v;
G
Guy Schalnat 已提交
3286
            png_uint_32 i;
3287
            int j;
G
Guy Schalnat 已提交
3288

3289
#ifdef PNG_READ_PACKSWAP_SUPPORTED
A
Andreas Dilger 已提交
3290 3291
            if (transformations & PNG_PACKSWAP)
            {
3292 3293 3294 3295 3296
                sshift = (int)((row_info->width + 7) & 0x07);
                dshift = (int)((final_width + 7) & 0x07);
                s_start = 7;
                s_end = 0;
                s_inc = -1;
A
Andreas Dilger 已提交
3297
            }
3298

3299
            else
A
Andreas Dilger 已提交
3300
#endif
G
Guy Schalnat 已提交
3301
            {
3302 3303 3304 3305 3306 3307
                sshift = 7 - (int)((row_info->width + 7) & 0x07);
                dshift = 7 - (int)((final_width + 7) & 0x07);
                s_start = 0;
                s_end = 7;
                s_inc = 1;
            }
3308

3309 3310 3311 3312
            for (i = 0; i < row_info->width; i++)
            {
               v = (png_byte)((*sp >> sshift) & 0x01);
               for (j = 0; j < jstop; j++)
G
Guy Schalnat 已提交
3313
               {
3314 3315
                  *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
                  *dp |= (png_byte)(v << dshift);
3316

3317 3318 3319 3320 3321
                  if (dshift == s_end)
                  {
                     dshift = s_start;
                     dp--;
                  }
3322

3323 3324
                  else
                     dshift += s_inc;
G
Guy Schalnat 已提交
3325
               }
3326

3327
               if (sshift == s_end)
G
Guy Schalnat 已提交
3328
               {
3329
                  sshift = s_start;
G
Guy Schalnat 已提交
3330 3331
                  sp--;
               }
3332

3333 3334
               else
                  sshift += s_inc;
G
Guy Schalnat 已提交
3335 3336 3337
            }
            break;
         }
3338

G
Guy Schalnat 已提交
3339 3340
         case 2:
         {
3341 3342 3343 3344 3345
            png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
            png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
            int sshift, dshift;
            int s_start, s_end, s_inc;
            int jstop = png_pass_inc[pass];
A
Andreas Dilger 已提交
3346
            png_uint_32 i;
G
Guy Schalnat 已提交
3347

3348
#ifdef PNG_READ_PACKSWAP_SUPPORTED
A
Andreas Dilger 已提交
3349 3350
            if (transformations & PNG_PACKSWAP)
            {
3351 3352 3353 3354 3355
               sshift = (int)(((row_info->width + 3) & 0x03) << 1);
               dshift = (int)(((final_width + 3) & 0x03) << 1);
               s_start = 6;
               s_end = 0;
               s_inc = -2;
A
Andreas Dilger 已提交
3356
            }
3357

3358
            else
A
Andreas Dilger 已提交
3359
#endif
3360 3361 3362 3363 3364 3365 3366
            {
               sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
               dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
               s_start = 0;
               s_end = 6;
               s_inc = 2;
            }
A
Andreas Dilger 已提交
3367

3368
            for (i = 0; i < row_info->width; i++)
G
Guy Schalnat 已提交
3369
            {
3370 3371
               png_byte v;
               int j;
A
Andreas Dilger 已提交
3372

3373 3374
               v = (png_byte)((*sp >> sshift) & 0x03);
               for (j = 0; j < jstop; j++)
G
Guy Schalnat 已提交
3375
               {
3376 3377
                  *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
                  *dp |= (png_byte)(v << dshift);
3378

3379 3380 3381 3382 3383
                  if (dshift == s_end)
                  {
                     dshift = s_start;
                     dp--;
                  }
3384

3385 3386
                  else
                     dshift += s_inc;
G
Guy Schalnat 已提交
3387
               }
3388

3389
               if (sshift == s_end)
G
Guy Schalnat 已提交
3390
               {
3391
                  sshift = s_start;
G
Guy Schalnat 已提交
3392 3393
                  sp--;
               }
3394

3395 3396
               else
                  sshift += s_inc;
G
Guy Schalnat 已提交
3397 3398 3399
            }
            break;
         }
3400

G
Guy Schalnat 已提交
3401 3402
         case 4:
         {
3403 3404
            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
            png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
3405 3406
            int sshift, dshift;
            int s_start, s_end, s_inc;
G
Guy Schalnat 已提交
3407
            png_uint_32 i;
3408
            int jstop = png_pass_inc[pass];
G
Guy Schalnat 已提交
3409

3410
#ifdef PNG_READ_PACKSWAP_SUPPORTED
A
Andreas Dilger 已提交
3411 3412
            if (transformations & PNG_PACKSWAP)
            {
3413 3414 3415 3416 3417
               sshift = (int)(((row_info->width + 1) & 0x01) << 2);
               dshift = (int)(((final_width + 1) & 0x01) << 2);
               s_start = 4;
               s_end = 0;
               s_inc = -4;
A
Andreas Dilger 已提交
3418
            }
3419

3420
            else
A
Andreas Dilger 已提交
3421 3422
#endif
            {
3423 3424 3425 3426 3427 3428
               sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
               dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
               s_start = 0;
               s_end = 4;
               s_inc = 4;
            }
A
Andreas Dilger 已提交
3429

3430 3431
            for (i = 0; i < row_info->width; i++)
            {
3432
               png_byte v = (png_byte)((*sp >> sshift) & 0x0f);
3433
               int j;
A
Andreas Dilger 已提交
3434

3435
               for (j = 0; j < jstop; j++)
G
Guy Schalnat 已提交
3436
               {
3437 3438
                  *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
                  *dp |= (png_byte)(v << dshift);
3439

3440 3441 3442 3443 3444
                  if (dshift == s_end)
                  {
                     dshift = s_start;
                     dp--;
                  }
3445

3446 3447
                  else
                     dshift += s_inc;
G
Guy Schalnat 已提交
3448
               }
3449

3450
               if (sshift == s_end)
G
Guy Schalnat 已提交
3451
               {
3452
                  sshift = s_start;
G
Guy Schalnat 已提交
3453 3454
                  sp--;
               }
3455

3456 3457
               else
                  sshift += s_inc;
G
Guy Schalnat 已提交
3458 3459 3460
            }
            break;
         }
3461

G
Guy Schalnat 已提交
3462 3463
         default:
         {
3464
            png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
3465

3466 3467
            png_bytep sp = row + (png_size_t)(row_info->width - 1)
                * pixel_bytes;
3468

3469 3470 3471
            png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;

            int jstop = png_pass_inc[pass];
A
Andreas Dilger 已提交
3472
            png_uint_32 i;
G
Guy Schalnat 已提交
3473

3474
            for (i = 0; i < row_info->width; i++)
G
Guy Schalnat 已提交
3475
            {
3476 3477 3478 3479
               png_byte v[8];
               int j;

               png_memcpy(v, sp, pixel_bytes);
3480

3481 3482 3483 3484 3485
               for (j = 0; j < jstop; j++)
               {
                  png_memcpy(dp, v, pixel_bytes);
                  dp -= pixel_bytes;
               }
3486

3487
               sp -= pixel_bytes;
G
Guy Schalnat 已提交
3488 3489 3490 3491
            }
            break;
         }
      }
3492

G
Guy Schalnat 已提交
3493
      row_info->width = final_width;
3494
      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
G
Guy Schalnat 已提交
3495
   }
3496
#ifndef PNG_READ_PACKSWAP_SUPPORTED
3497
   PNG_UNUSED(transformations)  /* Silence compiler warning */
3498
#endif
G
Guy Schalnat 已提交
3499
}
3500
#endif /* PNG_READ_INTERLACING_SUPPORTED */
G
Guy Schalnat 已提交
3501

3502 3503 3504
static void
png_read_filter_row_sub(png_row_infop row_info, png_bytep row,
   png_const_bytep prev_row)
3505
{
3506 3507 3508 3509 3510 3511 3512 3513
   png_size_t i;
   png_size_t istop = row_info->rowbytes;
   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
   png_bytep rp = row + bpp;

   PNG_UNUSED(prev_row)

   for (i = bpp; i < istop; i++)
3514
   {
3515
      *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
3516 3517 3518
      rp++;
   }
}
3519

3520 3521 3522 3523 3524 3525 3526 3527
static void
png_read_filter_row_up(png_row_infop row_info, png_bytep row,
   png_const_bytep prev_row)
{
   png_size_t i;
   png_size_t istop = row_info->rowbytes;
   png_bytep rp = row;
   png_const_bytep pp = prev_row;
3528

3529 3530 3531 3532 3533 3534
   for (i = 0; i < istop; i++)
   {
      *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
      rp++;
   }
}
3535

3536 3537 3538 3539 3540 3541 3542 3543 3544
static void
png_read_filter_row_avg(png_row_infop row_info, png_bytep row,
   png_const_bytep prev_row)
{
   png_size_t i;
   png_bytep rp = row;
   png_const_bytep pp = prev_row;
   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
   png_size_t istop = row_info->rowbytes - bpp;
3545

3546 3547 3548 3549
   for (i = 0; i < bpp; i++)
   {
      *rp = (png_byte)(((int)(*rp) +
         ((int)(*pp++) / 2 )) & 0xff);
3550

3551 3552
      rp++;
   }
3553

3554 3555 3556
   for (i = 0; i < istop; i++)
   {
      *rp = (png_byte)(((int)(*rp) +
3557
         (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
3558

3559 3560 3561 3562 3563
      rp++;
   }
}

static void
3564
png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
3565 3566
   png_const_bytep prev_row)
{
3567 3568
   png_bytep rp_end = row + row_info->rowbytes;
   int a, c;
3569

3570 3571 3572 3573
   /* First pixel/byte */
   c = *prev_row++;
   a = *row + c;
   *row++ = (png_byte)a;
3574

3575 3576
   /* Remainder */
   while (row < rp_end)
3577
   {
3578
      int b, pa, pb, pc, p;
3579

3580 3581
      a &= 0xff; /* From previous iteration or start */
      b = *prev_row++;
3582 3583 3584

      p = b - c;
      pc = a - c;
3585

3586 3587 3588 3589 3590 3591 3592 3593 3594
#     ifdef PNG_USE_ABS
         pa = abs(p);
         pb = abs(pc);
         pc = abs(p + pc);
#     else
         pa = p < 0 ? -p : p;
         pb = pc < 0 ? -pc : pc;
         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
#     endif
3595

3596 3597 3598 3599 3600
      /* Find the best predictor, the least of pa, pb, pc favoring the earlier
       * ones in the case of a tie.
       */
      if (pb < pa) pa = pb, a = b;
      if (pc < pa) a = c;
3601

3602 3603 3604 3605 3606 3607 3608 3609
      /* Calculate the current pixel in a, and move the previous row pixel to c
       * for the next time round the loop
       */
      c = b;
      a += *row;
      *row++ = (png_byte)a;
   }
}
3610

3611 3612 3613 3614 3615 3616
static void
png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
   png_const_bytep prev_row)
{
   int bpp = (row_info->pixel_depth + 7) >> 3;
   png_bytep rp_end = row + bpp;
3617

3618 3619 3620 3621 3622 3623 3624 3625
   /* Process the first pixel in the row completely (this is the same as 'up'
    * because there is only one candidate predictor for the first row).
    */
   while (row < rp_end)
   {
      int a = *row + *prev_row++;
      *row++ = (png_byte)a;
   }
3626

3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656
   /* Remainder */
   rp_end += row_info->rowbytes - bpp;

   while (row < rp_end)
   {
      int a, b, c, pa, pb, pc, p;

      c = *(prev_row - bpp);
      a = *(row - bpp);
      b = *prev_row++;

      p = b - c;
      pc = a - c;

#     ifdef PNG_USE_ABS
         pa = abs(p);
         pb = abs(pc);
         pc = abs(p + pc);
#     else
         pa = p < 0 ? -p : p;
         pb = pc < 0 ? -pc : pc;
         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
#     endif

      if (pb < pa) pa = pb, a = b;
      if (pc < pa) a = c;

      c = b;
      a += *row;
      *row++ = (png_byte)a;
3657 3658
   }
}
G
Guy Schalnat 已提交
3659

3660
#ifdef PNG_ARM_NEON
3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691

#ifdef __linux__
#include <stdio.h>
#include <elf.h>
#include <asm/hwcap.h>

static int png_have_hwcap(unsigned cap)
{
   FILE *f = fopen("/proc/self/auxv", "r");
   Elf32_auxv_t aux;
   int have_cap = 0;

   if (!f)
      return 0;

   while (fread(&aux, sizeof(aux), 1, f) > 0)
   {
      if (aux.a_type == AT_HWCAP &&
          aux.a_un.a_val & cap)
      {
         have_cap = 1;
         break;
      }
   }

   fclose(f);

   return have_cap;
}
#endif /* __linux__ */

3692
static void
3693
png_init_filter_functions_neon(png_structp pp, unsigned int bpp)
3694
{
3695 3696 3697 3698 3699
#ifdef __linux__
   if (!png_have_hwcap(HWCAP_NEON))
      return;
#endif

3700 3701
   pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon;

3702 3703
   if (bpp == 3)
   {
3704 3705
      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon;
      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon;
3706 3707 3708 3709 3710 3711
      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = 
         png_read_filter_row_paeth3_neon;
   }

   else if (bpp == 4)
   {
3712 3713
      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon;
      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon;
3714 3715
      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
          png_read_filter_row_paeth4_neon;
3716 3717
   }
}
3718
#endif /* PNG_ARM_NEON */
3719 3720 3721 3722

static void
png_init_filter_functions(png_structp pp)
{
3723 3724
   unsigned int bpp = (pp->pixel_depth + 7) >> 3;

3725 3726 3727
   pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub;
   pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up;
   pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg;
3728 3729 3730 3731 3732 3733
   if (bpp == 1)
      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
         png_read_filter_row_paeth_1byte_pixel;
   else
      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
         png_read_filter_row_paeth_multibyte_pixel;
3734 3735

#ifdef PNG_ARM_NEON
3736
   png_init_filter_functions_neon(pp, bpp);
3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749
#endif
}

void /* PRIVATE */
png_read_filter_row(png_structp pp, png_row_infop row_info, png_bytep row,
   png_const_bytep prev_row, int filter)
{
   if (pp->read_filter[0] == NULL)
      png_init_filter_functions(pp);
   if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST)
      pp->read_filter[filter-1](row_info, row, prev_row);
}

3750
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
3751
void /* PRIVATE */
G
Guy Schalnat 已提交
3752
png_read_finish_row(png_structp png_ptr)
G
Guy Schalnat 已提交
3753
{
3754
#ifdef PNG_READ_INTERLACING_SUPPORTED
3755
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3756

3757
   /* Start of interlace block */
3758
   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3759

3760
   /* Offset to next interlace block */
3761
   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3762

3763
   /* Start of interlace block in the y direction */
3764
   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3765

3766
   /* Offset to next interlace block in the y direction */
3767
   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3768
#endif /* PNG_READ_INTERLACING_SUPPORTED */
3769

3770
   png_debug(1, "in png_read_finish_row");
G
Guy Schalnat 已提交
3771 3772 3773 3774
   png_ptr->row_number++;
   if (png_ptr->row_number < png_ptr->num_rows)
      return;

3775
#ifdef PNG_READ_INTERLACING_SUPPORTED
G
Guy Schalnat 已提交
3776 3777 3778
   if (png_ptr->interlaced)
   {
      png_ptr->row_number = 0;
3779

3780 3781 3782
      /* TO DO: don't do this if prev_row isn't needed (requires
       * read-ahead of the next row's filter byte.
       */
3783 3784
      png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);

G
Guy Schalnat 已提交
3785 3786 3787
      do
      {
         png_ptr->pass++;
3788

G
Guy Schalnat 已提交
3789 3790
         if (png_ptr->pass >= 7)
            break;
3791

G
Guy Schalnat 已提交
3792 3793 3794 3795
         png_ptr->iwidth = (png_ptr->width +
            png_pass_inc[png_ptr->pass] - 1 -
            png_pass_start[png_ptr->pass]) /
            png_pass_inc[png_ptr->pass];
3796

G
Guy Schalnat 已提交
3797 3798 3799
         if (!(png_ptr->transformations & PNG_INTERLACE))
         {
            png_ptr->num_rows = (png_ptr->height +
3800 3801 3802
                png_pass_yinc[png_ptr->pass] - 1 -
                png_pass_ystart[png_ptr->pass]) /
                png_pass_yinc[png_ptr->pass];
G
Guy Schalnat 已提交
3803
         }
3804

3805
         else  /* if (png_ptr->transformations & PNG_INTERLACE) */
3806 3807 3808
            break; /* libpng deinterlacing sees every row */

      } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0);
G
Guy Schalnat 已提交
3809 3810 3811 3812

      if (png_ptr->pass < 7)
         return;
   }
3813
#endif /* PNG_READ_INTERLACING_SUPPORTED */
G
Guy Schalnat 已提交
3814

G
Guy Schalnat 已提交
3815
   if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
G
Guy Schalnat 已提交
3816 3817 3818 3819
   {
      char extra;
      int ret;

A
Andreas Dilger 已提交
3820 3821
      png_ptr->zstream.next_out = (Byte *)&extra;
      png_ptr->zstream.avail_out = (uInt)1;
3822

3823
      for (;;)
G
Guy Schalnat 已提交
3824
      {
A
Andreas Dilger 已提交
3825
         if (!(png_ptr->zstream.avail_in))
G
Guy Schalnat 已提交
3826 3827 3828
         {
            while (!png_ptr->idat_size)
            {
A
Andreas Dilger 已提交
3829
               png_crc_finish(png_ptr, 0);
3830
               png_ptr->idat_size = png_read_chunk_header(png_ptr);
3831
               if (png_ptr->chunk_name != png_IDAT)
G
Guy Schalnat 已提交
3832
                  png_error(png_ptr, "Not enough image data");
3833
            }
3834

A
Andreas Dilger 已提交
3835 3836
            png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
            png_ptr->zstream.next_in = png_ptr->zbuf;
3837

G
Guy Schalnat 已提交
3838
            if (png_ptr->zbuf_size > png_ptr->idat_size)
A
Andreas Dilger 已提交
3839
               png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
3840

A
Andreas Dilger 已提交
3841 3842
            png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
            png_ptr->idat_size -= png_ptr->zstream.avail_in;
G
Guy Schalnat 已提交
3843
         }
3844

A
Andreas Dilger 已提交
3845
         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
3846

G
Guy Schalnat 已提交
3847 3848
         if (ret == Z_STREAM_END)
         {
A
Andreas Dilger 已提交
3849
            if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
3850
                png_ptr->idat_size)
3851
               png_warning(png_ptr, "Extra compressed data");
3852

A
Andreas Dilger 已提交
3853 3854
            png_ptr->mode |= PNG_AFTER_IDAT;
            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
G
Guy Schalnat 已提交
3855 3856
            break;
         }
3857

G
Guy Schalnat 已提交
3858
         if (ret != Z_OK)
3859
            png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
3860
                "Decompression Error");
G
Guy Schalnat 已提交
3861

A
Andreas Dilger 已提交
3862
         if (!(png_ptr->zstream.avail_out))
3863
         {
3864
            png_warning(png_ptr, "Extra compressed data");
3865 3866 3867 3868
            png_ptr->mode |= PNG_AFTER_IDAT;
            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
            break;
         }
G
Guy Schalnat 已提交
3869

3870
      }
A
Andreas Dilger 已提交
3871
      png_ptr->zstream.avail_out = 0;
G
Guy Schalnat 已提交
3872 3873
   }

A
Andreas Dilger 已提交
3874
   if (png_ptr->idat_size || png_ptr->zstream.avail_in)
3875
      png_warning(png_ptr, "Extra compression data");
G
Guy Schalnat 已提交
3876

A
Andreas Dilger 已提交
3877
   inflateReset(&png_ptr->zstream);
G
Guy Schalnat 已提交
3878

A
Andreas Dilger 已提交
3879
   png_ptr->mode |= PNG_AFTER_IDAT;
G
Guy Schalnat 已提交
3880
}
3881
#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
G
Guy Schalnat 已提交
3882

3883
void /* PRIVATE */
G
Guy Schalnat 已提交
3884
png_read_start_row(png_structp png_ptr)
G
Guy Schalnat 已提交
3885
{
3886
#ifdef PNG_READ_INTERLACING_SUPPORTED
3887
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3888

3889
   /* Start of interlace block */
3890
   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3891

3892
   /* Offset to next interlace block */
3893
   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3894

3895
   /* Start of interlace block in the y direction */
3896
   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3897

3898
   /* Offset to next interlace block in the y direction */
3899
   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3900
#endif
3901

G
Guy Schalnat 已提交
3902
   int max_pixel_depth;
3903
   png_size_t row_bytes;
G
Guy Schalnat 已提交
3904

3905
   png_debug(1, "in png_read_start_row");
A
Andreas Dilger 已提交
3906
   png_ptr->zstream.avail_in = 0;
3907
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
G
Guy Schalnat 已提交
3908
   png_init_read_transformations(png_ptr);
3909
#endif
3910
#ifdef PNG_READ_INTERLACING_SUPPORTED
G
Guy Schalnat 已提交
3911 3912 3913 3914
   if (png_ptr->interlaced)
   {
      if (!(png_ptr->transformations & PNG_INTERLACE))
         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
3915 3916
             png_pass_ystart[0]) / png_pass_yinc[0];

G
Guy Schalnat 已提交
3917 3918 3919 3920
      else
         png_ptr->num_rows = png_ptr->height;

      png_ptr->iwidth = (png_ptr->width +
3921 3922 3923
          png_pass_inc[png_ptr->pass] - 1 -
          png_pass_start[png_ptr->pass]) /
          png_pass_inc[png_ptr->pass];
G
Guy Schalnat 已提交
3924
   }
3925

G
Guy Schalnat 已提交
3926
   else
3927
#endif /* PNG_READ_INTERLACING_SUPPORTED */
G
Guy Schalnat 已提交
3928 3929 3930 3931
   {
      png_ptr->num_rows = png_ptr->height;
      png_ptr->iwidth = png_ptr->width;
   }
3932

G
Guy Schalnat 已提交
3933 3934
   max_pixel_depth = png_ptr->pixel_depth;

3935 3936 3937 3938 3939 3940 3941 3942 3943 3944
   /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpliar set of
    * calculations to calculate the final pixel depth, then
    * png_do_read_transforms actually does the transforms.  This means that the
    * code which effectively calculates this value is actually repeated in three
    * separate places.  They must all match.  Innocent changes to the order of
    * transformations can and will break libpng in a way that causes memory
    * overwrites.
    *
    * TODO: fix this.
    */
3945
#ifdef PNG_READ_PACK_SUPPORTED
G
Guy Schalnat 已提交
3946 3947
   if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
      max_pixel_depth = 8;
G
Guy Schalnat 已提交
3948
#endif
G
Guy Schalnat 已提交
3949

3950
#ifdef PNG_READ_EXPAND_SUPPORTED
G
Guy Schalnat 已提交
3951
   if (png_ptr->transformations & PNG_EXPAND)
G
Guy Schalnat 已提交
3952 3953 3954 3955 3956
   {
      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
      {
         if (png_ptr->num_trans)
            max_pixel_depth = 32;
3957

G
Guy Schalnat 已提交
3958 3959 3960
         else
            max_pixel_depth = 24;
      }
3961

G
Guy Schalnat 已提交
3962 3963 3964 3965
      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
      {
         if (max_pixel_depth < 8)
            max_pixel_depth = 8;
3966

G
Guy Schalnat 已提交
3967 3968 3969
         if (png_ptr->num_trans)
            max_pixel_depth *= 2;
      }
3970

G
Guy Schalnat 已提交
3971 3972 3973 3974 3975 3976 3977 3978 3979
      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
      {
         if (png_ptr->num_trans)
         {
            max_pixel_depth *= 4;
            max_pixel_depth /= 3;
         }
      }
   }
G
Guy Schalnat 已提交
3980
#endif
G
Guy Schalnat 已提交
3981

3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999
#ifdef PNG_READ_EXPAND_16_SUPPORTED
   if (png_ptr->transformations & PNG_EXPAND_16)
   {
#     ifdef PNG_READ_EXPAND_SUPPORTED
         /* In fact it is an error if it isn't supported, but checking is
          * the safe way.
          */
         if (png_ptr->transformations & PNG_EXPAND)
         {
            if (png_ptr->bit_depth < 16)
               max_pixel_depth *= 2;
         }
         else
#     endif
         png_ptr->transformations &= ~PNG_EXPAND_16;
   }
#endif

4000
#ifdef PNG_READ_FILLER_SUPPORTED
G
Guy Schalnat 已提交
4001
   if (png_ptr->transformations & (PNG_FILLER))
G
Guy Schalnat 已提交
4002
   {
4003
      if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
4004 4005 4006
      {
         if (max_pixel_depth <= 8)
            max_pixel_depth = 16;
4007

4008 4009 4010
         else
            max_pixel_depth = 32;
      }
4011

4012 4013
      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB ||
         png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
4014 4015 4016
      {
         if (max_pixel_depth <= 32)
            max_pixel_depth = 32;
4017

4018 4019 4020
         else
            max_pixel_depth = 64;
      }
G
Guy Schalnat 已提交
4021
   }
G
Guy Schalnat 已提交
4022
#endif
G
Guy Schalnat 已提交
4023

4024
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
G
Guy Schalnat 已提交
4025 4026
   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
   {
4027
      if (
4028
#ifdef PNG_READ_EXPAND_SUPPORTED
4029
          (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
4030
#endif
4031
#ifdef PNG_READ_FILLER_SUPPORTED
4032
          (png_ptr->transformations & (PNG_FILLER)) ||
4033
#endif
4034
          png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
G
Guy Schalnat 已提交
4035 4036 4037
      {
         if (max_pixel_depth <= 16)
            max_pixel_depth = 32;
4038

4039
         else
G
Guy Schalnat 已提交
4040 4041
            max_pixel_depth = 64;
      }
4042

G
Guy Schalnat 已提交
4043 4044 4045
      else
      {
         if (max_pixel_depth <= 8)
4046 4047
         {
            if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
4048
               max_pixel_depth = 32;
4049 4050

            else
4051
               max_pixel_depth = 24;
4052 4053
         }

4054 4055
         else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
            max_pixel_depth = 64;
4056

4057
         else
G
Guy Schalnat 已提交
4058 4059 4060
            max_pixel_depth = 48;
      }
   }
G
Guy Schalnat 已提交
4061
#endif
G
Guy Schalnat 已提交
4062

4063 4064
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
4065
   if (png_ptr->transformations & PNG_USER_TRANSFORM)
4066
   {
4067
      int user_pixel_depth = png_ptr->user_transform_depth *
4068
         png_ptr->user_transform_channels;
4069 4070

      if (user_pixel_depth > max_pixel_depth)
4071
         max_pixel_depth = user_pixel_depth;
4072
   }
4073 4074
#endif

4075 4076 4077 4078 4079 4080
   /* This value is stored in png_struct and double checked in the row read
    * code.
    */
   png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth;
   png_ptr->transformed_pixel_depth = 0; /* calculated on demand */

4081 4082 4083
   /* Align the width on the next larger 8 pixels.  Mainly used
    * for interlacing
    */
4084
   row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
4085 4086 4087
   /* Calculate the maximum bytes needed, adding a byte and a pixel
    * for safety's sake
    */
4088
   row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
4089 4090
       1 + ((max_pixel_depth + 7) >> 3);

G
Guy Schalnat 已提交
4091
#ifdef PNG_MAX_MALLOC_64K
4092
   if (row_bytes > (png_uint_32)65536L)
G
Guy Schalnat 已提交
4093
      png_error(png_ptr, "This image requires a row greater than 64KB");
G
Guy Schalnat 已提交
4094
#endif
4095

4096
   if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
4097 4098
   {
     png_free(png_ptr, png_ptr->big_row_buf);
4099
     png_free(png_ptr, png_ptr->big_prev_row);
4100

4101
     if (png_ptr->interlaced)
4102 4103
        png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
            row_bytes + 48);
4104

4105
     else
4106
        png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
4107

4108
     png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
4109 4110 4111

#ifdef PNG_ALIGNED_MEMORY_SUPPORTED
     /* Use 16-byte aligned memory for row_buf with at least 16 bytes
4112
      * of padding before and after row_buf; treat prev_row similarly.
4113 4114
      * NOTE: the alignment is to the start of the pixels, one beyond the start
      * of the buffer, because of the filter byte.  Prior to libpng 1.5.6 this
4115 4116
      * was incorrect; the filter byte was aligned, which had the exact
      * opposite effect of that intended.
4117
      */
4118 4119
     {
        png_bytep temp = png_ptr->big_row_buf + 32;
4120
        int extra = (int)((temp - (png_bytep)0) & 0x0f);
4121
        png_ptr->row_buf = temp - extra - 1/*filter byte*/;
4122 4123

        temp = png_ptr->big_prev_row + 32;
4124
        extra = (int)((temp - (png_bytep)0) & 0x0f);
4125
        png_ptr->prev_row = temp - extra - 1/*filter byte*/;
4126
     }
4127

4128
#else
4129 4130
     /* Use 31 bytes of padding before and 17 bytes after row_buf. */
     png_ptr->row_buf = png_ptr->big_row_buf + 31;
4131
     png_ptr->prev_row = png_ptr->big_prev_row + 31;
4132 4133
#endif
     png_ptr->old_big_row_buf_size = row_bytes + 48;
4134
   }
G
Guy Schalnat 已提交
4135 4136

#ifdef PNG_MAX_MALLOC_64K
4137
   if (png_ptr->rowbytes > 65535)
G
Guy Schalnat 已提交
4138
      png_error(png_ptr, "This image requires a row greater than 64KB");
4139

G
Guy Schalnat 已提交
4140
#endif
4141
   if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1))
4142
      png_error(png_ptr, "Row has too many bytes to allocate in memory");
4143

4144
   png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
G
Guy Schalnat 已提交
4145

4146 4147 4148 4149
   png_debug1(3, "width = %u,", png_ptr->width);
   png_debug1(3, "height = %u,", png_ptr->height);
   png_debug1(3, "iwidth = %u,", png_ptr->iwidth);
   png_debug1(3, "num_rows = %u,", png_ptr->num_rows);
4150 4151 4152
   png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes);
   png_debug1(3, "irowbytes = %lu",
       (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
G
Guy Schalnat 已提交
4153

G
Guy Schalnat 已提交
4154
   png_ptr->flags |= PNG_FLAG_ROW_INIT;
G
Guy Schalnat 已提交
4155
}
4156
#endif /* PNG_READ_SUPPORTED */