1 2/* pngrutil.c - utilities to read a PNG file 3 * 4 * Last changed in libpng 1.2.45 [July 7, 2011] 5 * Copyright (c) 1998-2011 Glenn Randers-Pehrson 6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 7 * (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 * libpng itself during the course of reading an image. 15 */ 16 17#define PNG_INTERNAL 18#define PNG_NO_PEDANTIC_WARNINGS 19#include "png.h" 20#ifdef PNG_READ_SUPPORTED 21 22#if defined(_WIN32_WCE) && (_WIN32_WCE<0x500) 23# define WIN32_WCE_OLD 24#endif 25 26#ifdef PNG_FLOATING_POINT_SUPPORTED 27# ifdef WIN32_WCE_OLD 28/* The strtod() function is not supported on WindowsCE */ 29__inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr, 30 char **endptr) 31{ 32 double result = 0; 33 int len; 34 wchar_t *str, *end; 35 36 len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0); 37 str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t)); 38 if ( NULL != str ) 39 { 40 MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len); 41 result = wcstod(str, &end); 42 len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL); 43 *endptr = (char *)nptr + (png_strlen(nptr) - len + 1); 44 png_free(png_ptr, str); 45 } 46 return result; 47} 48# else 49# define png_strtod(p,a,b) strtod(a,b) 50# endif 51#endif 52 53png_uint_32 PNGAPI 54png_get_uint_31(png_structp png_ptr, png_bytep buf) 55{ 56#ifdef PNG_READ_BIG_ENDIAN_SUPPORTED 57 png_uint_32 i = png_get_uint_32(buf); 58#else 59 /* Avoid an extra function call by inlining the result. */ 60 png_uint_32 i = ((png_uint_32)(*buf) << 24) + 61 ((png_uint_32)(*(buf + 1)) << 16) + 62 ((png_uint_32)(*(buf + 2)) << 8) + 63 (png_uint_32)(*(buf + 3)); 64#endif 65 if (i > PNG_UINT_31_MAX) 66 png_error(png_ptr, "PNG unsigned integer out of range."); 67 return (i); 68} 69#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED 70/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ 71png_uint_32 PNGAPI 72png_get_uint_32(png_bytep buf) 73{ 74 png_uint_32 i = ((png_uint_32)(*buf) << 24) + 75 ((png_uint_32)(*(buf + 1)) << 16) + 76 ((png_uint_32)(*(buf + 2)) << 8) + 77 (png_uint_32)(*(buf + 3)); 78 79 return (i); 80} 81 82/* Grab a signed 32-bit integer from a buffer in big-endian format. The 83 * data is stored in the PNG file in two's complement format, and it is 84 * assumed that the machine format for signed integers is the same. 85 */ 86png_int_32 PNGAPI 87png_get_int_32(png_bytep buf) 88{ 89 png_int_32 i = ((png_int_32)(*buf) << 24) + 90 ((png_int_32)(*(buf + 1)) << 16) + 91 ((png_int_32)(*(buf + 2)) << 8) + 92 (png_int_32)(*(buf + 3)); 93 94 return (i); 95} 96 97/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ 98png_uint_16 PNGAPI 99png_get_uint_16(png_bytep buf) 100{ 101 png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) + 102 (png_uint_16)(*(buf + 1))); 103 104 return (i); 105} 106#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */ 107 108/* Read the chunk header (length + type name). 109 * Put the type name into png_ptr->chunk_name, and return the length. 110 */ 111png_uint_32 /* PRIVATE */ 112png_read_chunk_header(png_structp png_ptr) 113{ 114 png_byte buf[8]; 115 png_uint_32 length; 116 117 /* Read the length and the chunk name */ 118 png_read_data(png_ptr, buf, 8); 119 length = png_get_uint_31(png_ptr, buf); 120 121 /* Put the chunk name into png_ptr->chunk_name */ 122 png_memcpy(png_ptr->chunk_name, buf + 4, 4); 123 124 png_debug2(0, "Reading %s chunk, length = %lu", 125 png_ptr->chunk_name, length); 126 127 /* Reset the crc and run it over the chunk name */ 128 png_reset_crc(png_ptr); 129 png_calculate_crc(png_ptr, png_ptr->chunk_name, 4); 130 131 /* Check to see if chunk name is valid */ 132 png_check_chunk_name(png_ptr, png_ptr->chunk_name); 133 134 return length; 135} 136 137/* Read data, and (optionally) run it through the CRC. */ 138void /* PRIVATE */ 139png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length) 140{ 141 if (png_ptr == NULL) 142 return; 143 png_read_data(png_ptr, buf, length); 144 png_calculate_crc(png_ptr, buf, length); 145} 146 147/* Optionally skip data and then check the CRC. Depending on whether we 148 * are reading a ancillary or critical chunk, and how the program has set 149 * things up, we may calculate the CRC on the data and print a message. 150 * Returns '1' if there was a CRC error, '0' otherwise. 151 */ 152int /* PRIVATE */ 153png_crc_finish(png_structp png_ptr, png_uint_32 skip) 154{ 155 png_size_t i; 156 png_size_t istop = png_ptr->zbuf_size; 157 158 for (i = (png_size_t)skip; i > istop; i -= istop) 159 { 160 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); 161 } 162 if (i) 163 { 164 png_crc_read(png_ptr, png_ptr->zbuf, i); 165 } 166 167 if (png_crc_error(png_ptr)) 168 { 169 if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */ 170 !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) || 171 (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */ 172 (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))) 173 { 174 png_chunk_warning(png_ptr, "CRC error"); 175 } 176 else 177 { 178 png_chunk_error(png_ptr, "CRC error"); 179 } 180 return (1); 181 } 182 183 return (0); 184} 185 186/* Compare the CRC stored in the PNG file with that calculated by libpng from 187 * the data it has read thus far. 188 */ 189int /* PRIVATE */ 190png_crc_error(png_structp png_ptr) 191{ 192 png_byte crc_bytes[4]; 193 png_uint_32 crc; 194 int need_crc = 1; 195 196 if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ 197 { 198 if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == 199 (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) 200 need_crc = 0; 201 } 202 else /* critical */ 203 { 204 if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) 205 need_crc = 0; 206 } 207 208 png_read_data(png_ptr, crc_bytes, 4); 209 210 if (need_crc) 211 { 212 crc = png_get_uint_32(crc_bytes); 213 return ((int)(crc != png_ptr->crc)); 214 } 215 else 216 return (0); 217} 218 219#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \ 220 defined(PNG_READ_iCCP_SUPPORTED) 221static png_size_t 222png_inflate(png_structp png_ptr, const png_byte *data, png_size_t size, 223 png_bytep output, png_size_t output_size) 224{ 225 png_size_t count = 0; 226 227 png_ptr->zstream.next_in = (png_bytep)data; /* const_cast: VALID */ 228 png_ptr->zstream.avail_in = size; 229 230 while (1) 231 { 232 int ret, avail; 233 234 /* Reset the output buffer each time round - we empty it 235 * after every inflate call. 236 */ 237 png_ptr->zstream.next_out = png_ptr->zbuf; 238 png_ptr->zstream.avail_out = png_ptr->zbuf_size; 239 240 ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); 241 avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out; 242 243 /* First copy/count any new output - but only if we didn't 244 * get an error code. 245 */ 246 if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0) 247 { 248 if (output != 0 && output_size > count) 249 { 250 png_size_t copy = output_size - count; 251 if ((png_size_t) avail < copy) copy = (png_size_t) avail; 252 png_memcpy(output + count, png_ptr->zbuf, copy); 253 } 254 count += avail; 255 } 256 257 if (ret == Z_OK) 258 continue; 259 260 /* Termination conditions - always reset the zstream, it 261 * must be left in inflateInit state. 262 */ 263 png_ptr->zstream.avail_in = 0; 264 inflateReset(&png_ptr->zstream); 265 266 if (ret == Z_STREAM_END) 267 return count; /* NOTE: may be zero. */ 268 269 /* Now handle the error codes - the API always returns 0 270 * and the error message is dumped into the uncompressed 271 * buffer if available. 272 */ 273 { 274 PNG_CONST char *msg; 275 if (png_ptr->zstream.msg != 0) 276 msg = png_ptr->zstream.msg; 277 else 278 { 279#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE) 280 char umsg[52]; 281 282 switch (ret) 283 { 284 case Z_BUF_ERROR: 285 msg = "Buffer error in compressed datastream in %s chunk"; 286 break; 287 case Z_DATA_ERROR: 288 msg = "Data error in compressed datastream in %s chunk"; 289 break; 290 default: 291 msg = "Incomplete compressed datastream in %s chunk"; 292 break; 293 } 294 295 png_snprintf(umsg, sizeof umsg, msg, png_ptr->chunk_name); 296 msg = umsg; 297#else 298 msg = "Damaged compressed datastream in chunk other than IDAT"; 299#endif 300 } 301 302 png_warning(png_ptr, msg); 303 } 304 305 /* 0 means an error - notice that this code simple ignores 306 * zero length compressed chunks as a result. 307 */ 308 return 0; 309 } 310} 311 312/* 313 * Decompress trailing data in a chunk. The assumption is that chunkdata 314 * points at an allocated area holding the contents of a chunk with a 315 * trailing compressed part. What we get back is an allocated area 316 * holding the original prefix part and an uncompressed version of the 317 * trailing part (the malloc area passed in is freed). 318 */ 319void /* PRIVATE */ 320png_decompress_chunk(png_structp png_ptr, int comp_type, 321 png_size_t chunklength, 322 png_size_t prefix_size, png_size_t *newlength) 323{ 324 /* The caller should guarantee this */ 325 if (prefix_size > chunklength) 326 { 327 /* The recovery is to delete the chunk. */ 328 png_warning(png_ptr, "invalid chunklength"); 329 prefix_size = 0; /* To delete everything */ 330 } 331 332 else if (comp_type == PNG_COMPRESSION_TYPE_BASE) 333 { 334 png_size_t expanded_size = png_inflate(png_ptr, 335 (png_bytep)(png_ptr->chunkdata + prefix_size), 336 chunklength - prefix_size, 337 0/*output*/, 0/*output size*/); 338 339 /* Now check the limits on this chunk - if the limit fails the 340 * compressed data will be removed, the prefix will remain. 341 */ 342#ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED 343 if (png_ptr->user_chunk_malloc_max && 344 (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1)) 345#else 346# ifdef PNG_USER_CHUNK_MALLOC_MAX 347 if ((PNG_USER_CHUNK_MALLOC_MAX > 0) && 348 prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1) 349# endif 350#endif 351 png_warning(png_ptr, "Exceeded size limit while expanding chunk"); 352 353 /* If the size is zero either there was an error and a message 354 * has already been output (warning) or the size really is zero 355 * and we have nothing to do - the code will exit through the 356 * error case below. 357 */ 358#if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \ 359 defined(PNG_USER_CHUNK_MALLOC_MAX) 360 else 361#endif 362 if (expanded_size > 0) 363 { 364 /* Success (maybe) - really uncompress the chunk. */ 365 png_size_t new_size = 0; 366 png_charp text = NULL; 367 /* Need to check for both truncation (64-bit platforms) and integer 368 * overflow. 369 */ 370 if (prefix_size + expanded_size > prefix_size && 371 prefix_size + expanded_size < 0xffffffffU) 372 { 373 text = png_malloc_warn(png_ptr, prefix_size + expanded_size + 1); 374 } 375 376 if (text != NULL) 377 { 378 png_memcpy(text, png_ptr->chunkdata, prefix_size); 379 new_size = png_inflate(png_ptr, 380 (png_bytep)(png_ptr->chunkdata + prefix_size), 381 chunklength - prefix_size, 382 (png_bytep)(text + prefix_size), expanded_size); 383 text[prefix_size + expanded_size] = 0; /* just in case */ 384 385 if (new_size == expanded_size) 386 { 387 png_free(png_ptr, png_ptr->chunkdata); 388 png_ptr->chunkdata = text; 389 *newlength = prefix_size + expanded_size; 390 return; /* The success return! */ 391 } 392 393 png_warning(png_ptr, "png_inflate logic error"); 394 png_free(png_ptr, text); 395 } 396 else 397 png_warning(png_ptr, "Not enough memory to decompress chunk."); 398 } 399 } 400 401 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */ 402 { 403#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE) 404 char umsg[50]; 405 406 png_snprintf(umsg, sizeof umsg, "Unknown zTXt compression type %d", 407 comp_type); 408 png_warning(png_ptr, umsg); 409#else 410 png_warning(png_ptr, "Unknown zTXt compression type"); 411#endif 412 413 /* The recovery is to simply drop the data. */ 414 } 415 416 /* Generic error return - leave the prefix, delete the compressed 417 * data, reallocate the chunkdata to remove the potentially large 418 * amount of compressed data. 419 */ 420 { 421 png_charp text = png_malloc_warn(png_ptr, prefix_size + 1); 422 if (text != NULL) 423 { 424 if (prefix_size > 0) 425 png_memcpy(text, png_ptr->chunkdata, prefix_size); 426 png_free(png_ptr, png_ptr->chunkdata); 427 png_ptr->chunkdata = text; 428 429 /* This is an extra zero in the 'uncompressed' part. */ 430 *(png_ptr->chunkdata + prefix_size) = 0x00; 431 } 432 /* Ignore a malloc error here - it is safe. */ 433 } 434 435 *newlength = prefix_size; 436} 437#endif 438 439/* Read and check the IDHR chunk */ 440void /* PRIVATE */ 441png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 442{ 443 png_byte buf[13]; 444 png_uint_32 width, height; 445 int bit_depth, color_type, compression_type, filter_type; 446 int interlace_type; 447 448 png_debug(1, "in png_handle_IHDR"); 449 450 if (png_ptr->mode & PNG_HAVE_IHDR) 451 png_error(png_ptr, "Out of place IHDR"); 452 453 /* Check the length */ 454 if (length != 13) 455 png_error(png_ptr, "Invalid IHDR chunk"); 456 457 png_ptr->mode |= PNG_HAVE_IHDR; 458 459 png_crc_read(png_ptr, buf, 13); 460 png_crc_finish(png_ptr, 0); 461 462 width = png_get_uint_31(png_ptr, buf); 463 height = png_get_uint_31(png_ptr, buf + 4); 464 bit_depth = buf[8]; 465 color_type = buf[9]; 466 compression_type = buf[10]; 467 filter_type = buf[11]; 468 interlace_type = buf[12]; 469 470 /* Set internal variables */ 471 png_ptr->width = width; 472 png_ptr->height = height; 473 png_ptr->bit_depth = (png_byte)bit_depth; 474 png_ptr->interlaced = (png_byte)interlace_type; 475 png_ptr->color_type = (png_byte)color_type; 476#ifdef PNG_MNG_FEATURES_SUPPORTED 477 png_ptr->filter_type = (png_byte)filter_type; 478#endif 479 png_ptr->compression_type = (png_byte)compression_type; 480 481 /* Find number of channels */ 482 switch (png_ptr->color_type) 483 { 484 case PNG_COLOR_TYPE_GRAY: 485 case PNG_COLOR_TYPE_PALETTE: 486 png_ptr->channels = 1; 487 break; 488 489 case PNG_COLOR_TYPE_RGB: 490 png_ptr->channels = 3; 491 break; 492 493 case PNG_COLOR_TYPE_GRAY_ALPHA: 494 png_ptr->channels = 2; 495 break; 496 497 case PNG_COLOR_TYPE_RGB_ALPHA: 498 png_ptr->channels = 4; 499 break; 500 } 501 502 /* Set up other useful info */ 503 png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * 504 png_ptr->channels); 505 png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width); 506 png_debug1(3, "bit_depth = %d", png_ptr->bit_depth); 507 png_debug1(3, "channels = %d", png_ptr->channels); 508 png_debug1(3, "rowbytes = %lu", png_ptr->rowbytes); 509 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, 510 color_type, interlace_type, compression_type, filter_type); 511} 512 513/* Read and check the palette */ 514void /* PRIVATE */ 515png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 516{ 517 png_color palette[PNG_MAX_PALETTE_LENGTH]; 518 int num, i; 519#ifdef PNG_POINTER_INDEXING_SUPPORTED 520 png_colorp pal_ptr; 521#endif 522 523 png_debug(1, "in png_handle_PLTE"); 524 525 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 526 png_error(png_ptr, "Missing IHDR before PLTE"); 527 528 else if (png_ptr->mode & PNG_HAVE_IDAT) 529 { 530 png_warning(png_ptr, "Invalid PLTE after IDAT"); 531 png_crc_finish(png_ptr, length); 532 return; 533 } 534 535 else if (png_ptr->mode & PNG_HAVE_PLTE) 536 png_error(png_ptr, "Duplicate PLTE chunk"); 537 538 png_ptr->mode |= PNG_HAVE_PLTE; 539 540 if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) 541 { 542 png_warning(png_ptr, 543 "Ignoring PLTE chunk in grayscale PNG"); 544 png_crc_finish(png_ptr, length); 545 return; 546 } 547#ifndef PNG_READ_OPT_PLTE_SUPPORTED 548 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) 549 { 550 png_crc_finish(png_ptr, length); 551 return; 552 } 553#endif 554 555 if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) 556 { 557 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) 558 { 559 png_warning(png_ptr, "Invalid palette chunk"); 560 png_crc_finish(png_ptr, length); 561 return; 562 } 563 564 else 565 { 566 png_error(png_ptr, "Invalid palette chunk"); 567 } 568 } 569 570 num = (int)length / 3; 571 572#ifdef PNG_POINTER_INDEXING_SUPPORTED 573 for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) 574 { 575 png_byte buf[3]; 576 577 png_crc_read(png_ptr, buf, 3); 578 pal_ptr->red = buf[0]; 579 pal_ptr->green = buf[1]; 580 pal_ptr->blue = buf[2]; 581 } 582#else 583 for (i = 0; i < num; i++) 584 { 585 png_byte buf[3]; 586 587 png_crc_read(png_ptr, buf, 3); 588 /* Don't depend upon png_color being any order */ 589 palette[i].red = buf[0]; 590 palette[i].green = buf[1]; 591 palette[i].blue = buf[2]; 592 } 593#endif 594 595 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do 596 * whatever the normal CRC configuration tells us. However, if we 597 * have an RGB image, the PLTE can be considered ancillary, so 598 * we will act as though it is. 599 */ 600#ifndef PNG_READ_OPT_PLTE_SUPPORTED 601 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 602#endif 603 { 604 png_crc_finish(png_ptr, 0); 605 } 606#ifndef PNG_READ_OPT_PLTE_SUPPORTED 607 else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ 608 { 609 /* If we don't want to use the data from an ancillary chunk, 610 we have two options: an error abort, or a warning and we 611 ignore the data in this chunk (which should be OK, since 612 it's considered ancillary for a RGB or RGBA image). */ 613 if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) 614 { 615 if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) 616 { 617 png_chunk_error(png_ptr, "CRC error"); 618 } 619 else 620 { 621 png_chunk_warning(png_ptr, "CRC error"); 622 return; 623 } 624 } 625 /* Otherwise, we (optionally) emit a warning and use the chunk. */ 626 else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) 627 { 628 png_chunk_warning(png_ptr, "CRC error"); 629 } 630 } 631#endif 632 633 png_set_PLTE(png_ptr, info_ptr, palette, num); 634 635#ifdef PNG_READ_tRNS_SUPPORTED 636 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 637 { 638 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) 639 { 640 if (png_ptr->num_trans > (png_uint_16)num) 641 { 642 png_warning(png_ptr, "Truncating incorrect tRNS chunk length"); 643 png_ptr->num_trans = (png_uint_16)num; 644 } 645 if (info_ptr->num_trans > (png_uint_16)num) 646 { 647 png_warning(png_ptr, "Truncating incorrect info tRNS chunk length"); 648 info_ptr->num_trans = (png_uint_16)num; 649 } 650 } 651 } 652#endif 653 654} 655 656void /* PRIVATE */ 657png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 658{ 659 png_debug(1, "in png_handle_IEND"); 660 661 if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT)) 662 { 663 png_error(png_ptr, "No image in file"); 664 } 665 666 png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); 667 668 if (length != 0) 669 { 670 png_warning(png_ptr, "Incorrect IEND chunk length"); 671 } 672 png_crc_finish(png_ptr, length); 673 674 info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */ 675} 676 677#ifdef PNG_READ_gAMA_SUPPORTED 678void /* PRIVATE */ 679png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 680{ 681 png_fixed_point igamma; 682#ifdef PNG_FLOATING_POINT_SUPPORTED 683 float file_gamma; 684#endif 685 png_byte buf[4]; 686 687 png_debug(1, "in png_handle_gAMA"); 688 689 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 690 png_error(png_ptr, "Missing IHDR before gAMA"); 691 else if (png_ptr->mode & PNG_HAVE_IDAT) 692 { 693 png_warning(png_ptr, "Invalid gAMA after IDAT"); 694 png_crc_finish(png_ptr, length); 695 return; 696 } 697 else if (png_ptr->mode & PNG_HAVE_PLTE) 698 /* Should be an error, but we can cope with it */ 699 png_warning(png_ptr, "Out of place gAMA chunk"); 700 701 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) 702#ifdef PNG_READ_sRGB_SUPPORTED 703 && !(info_ptr->valid & PNG_INFO_sRGB) 704#endif 705 ) 706 { 707 png_warning(png_ptr, "Duplicate gAMA chunk"); 708 png_crc_finish(png_ptr, length); 709 return; 710 } 711 712 if (length != 4) 713 { 714 png_warning(png_ptr, "Incorrect gAMA chunk length"); 715 png_crc_finish(png_ptr, length); 716 return; 717 } 718 719 png_crc_read(png_ptr, buf, 4); 720 if (png_crc_finish(png_ptr, 0)) 721 return; 722 723 igamma = (png_fixed_point)png_get_uint_32(buf); 724 /* Check for zero gamma */ 725 if (igamma == 0) 726 { 727 png_warning(png_ptr, 728 "Ignoring gAMA chunk with gamma=0"); 729 return; 730 } 731 732#ifdef PNG_READ_sRGB_SUPPORTED 733 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) 734 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) 735 { 736 png_warning(png_ptr, 737 "Ignoring incorrect gAMA value when sRGB is also present"); 738#ifdef PNG_CONSOLE_IO_SUPPORTED 739 fprintf(stderr, "gamma = (%d/100000)", (int)igamma); 740#endif 741 return; 742 } 743#endif /* PNG_READ_sRGB_SUPPORTED */ 744 745#ifdef PNG_FLOATING_POINT_SUPPORTED 746 file_gamma = (float)igamma / (float)100000.0; 747# ifdef PNG_READ_GAMMA_SUPPORTED 748 png_ptr->gamma = file_gamma; 749# endif 750 png_set_gAMA(png_ptr, info_ptr, file_gamma); 751#endif 752#ifdef PNG_FIXED_POINT_SUPPORTED 753 png_set_gAMA_fixed(png_ptr, info_ptr, igamma); 754#endif 755} 756#endif 757 758#ifdef PNG_READ_sBIT_SUPPORTED 759void /* PRIVATE */ 760png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 761{ 762 png_size_t truelen; 763 png_byte buf[4]; 764 765 png_debug(1, "in png_handle_sBIT"); 766 767 buf[0] = buf[1] = buf[2] = buf[3] = 0; 768 769 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 770 png_error(png_ptr, "Missing IHDR before sBIT"); 771 else if (png_ptr->mode & PNG_HAVE_IDAT) 772 { 773 png_warning(png_ptr, "Invalid sBIT after IDAT"); 774 png_crc_finish(png_ptr, length); 775 return; 776 } 777 else if (png_ptr->mode & PNG_HAVE_PLTE) 778 { 779 /* Should be an error, but we can cope with it */ 780 png_warning(png_ptr, "Out of place sBIT chunk"); 781 } 782 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) 783 { 784 png_warning(png_ptr, "Duplicate sBIT chunk"); 785 png_crc_finish(png_ptr, length); 786 return; 787 } 788 789 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 790 truelen = 3; 791 else 792 truelen = (png_size_t)png_ptr->channels; 793 794 if (length != truelen || length > 4) 795 { 796 png_warning(png_ptr, "Incorrect sBIT chunk length"); 797 png_crc_finish(png_ptr, length); 798 return; 799 } 800 801 png_crc_read(png_ptr, buf, truelen); 802 if (png_crc_finish(png_ptr, 0)) 803 return; 804 805 if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) 806 { 807 png_ptr->sig_bit.red = buf[0]; 808 png_ptr->sig_bit.green = buf[1]; 809 png_ptr->sig_bit.blue = buf[2]; 810 png_ptr->sig_bit.alpha = buf[3]; 811 } 812 else 813 { 814 png_ptr->sig_bit.gray = buf[0]; 815 png_ptr->sig_bit.red = buf[0]; 816 png_ptr->sig_bit.green = buf[0]; 817 png_ptr->sig_bit.blue = buf[0]; 818 png_ptr->sig_bit.alpha = buf[1]; 819 } 820 png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); 821} 822#endif 823 824#ifdef PNG_READ_cHRM_SUPPORTED 825void /* PRIVATE */ 826png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 827{ 828 png_byte buf[32]; 829#ifdef PNG_FLOATING_POINT_SUPPORTED 830 float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; 831#endif 832 png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, 833 int_y_green, int_x_blue, int_y_blue; 834 835 png_uint_32 uint_x, uint_y; 836 837 png_debug(1, "in png_handle_cHRM"); 838 839 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 840 png_error(png_ptr, "Missing IHDR before cHRM"); 841 else if (png_ptr->mode & PNG_HAVE_IDAT) 842 { 843 png_warning(png_ptr, "Invalid cHRM after IDAT"); 844 png_crc_finish(png_ptr, length); 845 return; 846 } 847 else if (png_ptr->mode & PNG_HAVE_PLTE) 848 /* Should be an error, but we can cope with it */ 849 png_warning(png_ptr, "Missing PLTE before cHRM"); 850 851 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) 852#ifdef PNG_READ_sRGB_SUPPORTED 853 && !(info_ptr->valid & PNG_INFO_sRGB) 854#endif 855 ) 856 { 857 png_warning(png_ptr, "Duplicate cHRM chunk"); 858 png_crc_finish(png_ptr, length); 859 return; 860 } 861 862 if (length != 32) 863 { 864 png_warning(png_ptr, "Incorrect cHRM chunk length"); 865 png_crc_finish(png_ptr, length); 866 return; 867 } 868 869 png_crc_read(png_ptr, buf, 32); 870 if (png_crc_finish(png_ptr, 0)) 871 return; 872 873 uint_x = png_get_uint_32(buf); 874 uint_y = png_get_uint_32(buf + 4); 875 int_x_white = (png_fixed_point)uint_x; 876 int_y_white = (png_fixed_point)uint_y; 877 878 uint_x = png_get_uint_32(buf + 8); 879 uint_y = png_get_uint_32(buf + 12); 880 int_x_red = (png_fixed_point)uint_x; 881 int_y_red = (png_fixed_point)uint_y; 882 883 uint_x = png_get_uint_32(buf + 16); 884 uint_y = png_get_uint_32(buf + 20); 885 int_x_green = (png_fixed_point)uint_x; 886 int_y_green = (png_fixed_point)uint_y; 887 888 uint_x = png_get_uint_32(buf + 24); 889 uint_y = png_get_uint_32(buf + 28); 890 int_x_blue = (png_fixed_point)uint_x; 891 int_y_blue = (png_fixed_point)uint_y; 892 893#ifdef PNG_FLOATING_POINT_SUPPORTED 894 white_x = (float)int_x_white / (float)100000.0; 895 white_y = (float)int_y_white / (float)100000.0; 896 red_x = (float)int_x_red / (float)100000.0; 897 red_y = (float)int_y_red / (float)100000.0; 898 green_x = (float)int_x_green / (float)100000.0; 899 green_y = (float)int_y_green / (float)100000.0; 900 blue_x = (float)int_x_blue / (float)100000.0; 901 blue_y = (float)int_y_blue / (float)100000.0; 902#endif 903 904#ifdef PNG_READ_sRGB_SUPPORTED 905 if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) 906 { 907 if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) || 908 PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) || 909 PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) || 910 PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) || 911 PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) || 912 PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) || 913 PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) || 914 PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000)) 915 { 916 png_warning(png_ptr, 917 "Ignoring incorrect cHRM value when sRGB is also present"); 918#ifdef PNG_CONSOLE_IO_SUPPORTED 919#ifdef PNG_FLOATING_POINT_SUPPORTED 920 fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n", 921 white_x, white_y, red_x, red_y); 922 fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n", 923 green_x, green_y, blue_x, blue_y); 924#else 925 fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n", 926 (long)int_x_white, (long)int_y_white, 927 (long)int_x_red, (long)int_y_red); 928 fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n", 929 (long)int_x_green, (long)int_y_green, 930 (long)int_x_blue, (long)int_y_blue); 931#endif 932#endif /* PNG_CONSOLE_IO_SUPPORTED */ 933 } 934 return; 935 } 936#endif /* PNG_READ_sRGB_SUPPORTED */ 937 938#ifdef PNG_FLOATING_POINT_SUPPORTED 939 png_set_cHRM(png_ptr, info_ptr, 940 white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); 941#endif 942#ifdef PNG_FIXED_POINT_SUPPORTED 943 png_set_cHRM_fixed(png_ptr, info_ptr, 944 int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, 945 int_y_green, int_x_blue, int_y_blue); 946#endif 947} 948#endif 949 950#ifdef PNG_READ_sRGB_SUPPORTED 951void /* PRIVATE */ 952png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 953{ 954 int intent; 955 png_byte buf[1]; 956 957 png_debug(1, "in png_handle_sRGB"); 958 959 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 960 png_error(png_ptr, "Missing IHDR before sRGB"); 961 else if (png_ptr->mode & PNG_HAVE_IDAT) 962 { 963 png_warning(png_ptr, "Invalid sRGB after IDAT"); 964 png_crc_finish(png_ptr, length); 965 return; 966 } 967 else if (png_ptr->mode & PNG_HAVE_PLTE) 968 /* Should be an error, but we can cope with it */ 969 png_warning(png_ptr, "Out of place sRGB chunk"); 970 971 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) 972 { 973 png_warning(png_ptr, "Duplicate sRGB chunk"); 974 png_crc_finish(png_ptr, length); 975 return; 976 } 977 978 if (length != 1) 979 { 980 png_warning(png_ptr, "Incorrect sRGB chunk length"); 981 png_crc_finish(png_ptr, length); 982 return; 983 } 984 985 png_crc_read(png_ptr, buf, 1); 986 if (png_crc_finish(png_ptr, 0)) 987 return; 988 989 intent = buf[0]; 990 /* Check for bad intent */ 991 if (intent >= PNG_sRGB_INTENT_LAST) 992 { 993 png_warning(png_ptr, "Unknown sRGB intent"); 994 return; 995 } 996 997#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) 998 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)) 999 { 1000 png_fixed_point igamma; 1001#ifdef PNG_FIXED_POINT_SUPPORTED 1002 igamma=info_ptr->int_gamma; 1003#else 1004# ifdef PNG_FLOATING_POINT_SUPPORTED 1005 igamma=(png_fixed_point)(info_ptr->gamma * 100000.); 1006# endif 1007#endif 1008 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) 1009 { 1010 png_warning(png_ptr, 1011 "Ignoring incorrect gAMA value when sRGB is also present"); 1012#ifdef PNG_CONSOLE_IO_SUPPORTED 1013# ifdef PNG_FIXED_POINT_SUPPORTED 1014 fprintf(stderr, "incorrect gamma=(%d/100000)\n", 1015 (int)png_ptr->int_gamma); 1016# else 1017# ifdef PNG_FLOATING_POINT_SUPPORTED 1018 fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma); 1019# endif 1020# endif 1021#endif 1022 } 1023 } 1024#endif /* PNG_READ_gAMA_SUPPORTED */ 1025 1026#ifdef PNG_READ_cHRM_SUPPORTED 1027#ifdef PNG_FIXED_POINT_SUPPORTED 1028 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) 1029 if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) || 1030 PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) || 1031 PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) || 1032 PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) || 1033 PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) || 1034 PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) || 1035 PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) || 1036 PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000)) 1037 { 1038 png_warning(png_ptr, 1039 "Ignoring incorrect cHRM value when sRGB is also present"); 1040 } 1041#endif /* PNG_FIXED_POINT_SUPPORTED */ 1042#endif /* PNG_READ_cHRM_SUPPORTED */ 1043 1044 png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); 1045} 1046#endif /* PNG_READ_sRGB_SUPPORTED */ 1047 1048#ifdef PNG_READ_iCCP_SUPPORTED 1049void /* PRIVATE */ 1050png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1051/* Note: this does not properly handle chunks that are > 64K under DOS */ 1052{ 1053 png_byte compression_type; 1054 png_bytep pC; 1055 png_charp profile; 1056 png_uint_32 skip = 0; 1057 png_uint_32 profile_size, profile_length; 1058 png_size_t slength, prefix_length, data_length; 1059 1060 png_debug(1, "in png_handle_iCCP"); 1061 1062 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1063 png_error(png_ptr, "Missing IHDR before iCCP"); 1064 else if (png_ptr->mode & PNG_HAVE_IDAT) 1065 { 1066 png_warning(png_ptr, "Invalid iCCP after IDAT"); 1067 png_crc_finish(png_ptr, length); 1068 return; 1069 } 1070 else if (png_ptr->mode & PNG_HAVE_PLTE) 1071 /* Should be an error, but we can cope with it */ 1072 png_warning(png_ptr, "Out of place iCCP chunk"); 1073 1074 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)) 1075 { 1076 png_warning(png_ptr, "Duplicate iCCP chunk"); 1077 png_crc_finish(png_ptr, length); 1078 return; 1079 } 1080 1081#ifdef PNG_MAX_MALLOC_64K 1082 if (length > (png_uint_32)65535L) 1083 { 1084 png_warning(png_ptr, "iCCP chunk too large to fit in memory"); 1085 skip = length - (png_uint_32)65535L; 1086 length = (png_uint_32)65535L; 1087 } 1088#endif 1089 1090 png_free(png_ptr, png_ptr->chunkdata); 1091 png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); 1092 slength = (png_size_t)length; 1093 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1094 1095 if (png_crc_finish(png_ptr, skip)) 1096 { 1097 png_free(png_ptr, png_ptr->chunkdata); 1098 png_ptr->chunkdata = NULL; 1099 return; 1100 } 1101 1102 png_ptr->chunkdata[slength] = 0x00; 1103 1104 for (profile = png_ptr->chunkdata; *profile; profile++) 1105 /* Empty loop to find end of name */ ; 1106 1107 ++profile; 1108 1109 /* There should be at least one zero (the compression type byte) 1110 * following the separator, and we should be on it 1111 */ 1112 if ( profile >= png_ptr->chunkdata + slength - 1) 1113 { 1114 png_free(png_ptr, png_ptr->chunkdata); 1115 png_ptr->chunkdata = NULL; 1116 png_warning(png_ptr, "Malformed iCCP chunk"); 1117 return; 1118 } 1119 1120 /* Compression_type should always be zero */ 1121 compression_type = *profile++; 1122 if (compression_type) 1123 { 1124 png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk"); 1125 compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8 1126 wrote nonzero) */ 1127 } 1128 1129 prefix_length = profile - png_ptr->chunkdata; 1130 png_decompress_chunk(png_ptr, compression_type, 1131 slength, prefix_length, &data_length); 1132 1133 profile_length = data_length - prefix_length; 1134 1135 if ( prefix_length > data_length || profile_length < 4) 1136 { 1137 png_free(png_ptr, png_ptr->chunkdata); 1138 png_ptr->chunkdata = NULL; 1139 png_warning(png_ptr, "Profile size field missing from iCCP chunk"); 1140 return; 1141 } 1142 1143 /* Check the profile_size recorded in the first 32 bits of the ICC profile */ 1144 pC = (png_bytep)(png_ptr->chunkdata + prefix_length); 1145 profile_size = ((*(pC ))<<24) | 1146 ((*(pC + 1))<<16) | 1147 ((*(pC + 2))<< 8) | 1148 ((*(pC + 3)) ); 1149 1150 if (profile_size < profile_length) 1151 profile_length = profile_size; 1152 1153 if (profile_size > profile_length) 1154 { 1155 png_free(png_ptr, png_ptr->chunkdata); 1156 png_ptr->chunkdata = NULL; 1157 png_warning(png_ptr, "Ignoring truncated iCCP profile."); 1158 return; 1159 } 1160 1161 png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata, 1162 compression_type, png_ptr->chunkdata + prefix_length, profile_length); 1163 png_free(png_ptr, png_ptr->chunkdata); 1164 png_ptr->chunkdata = NULL; 1165} 1166#endif /* PNG_READ_iCCP_SUPPORTED */ 1167 1168#ifdef PNG_READ_sPLT_SUPPORTED 1169void /* PRIVATE */ 1170png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1171/* Note: this does not properly handle chunks that are > 64K under DOS */ 1172{ 1173 png_bytep entry_start; 1174 png_sPLT_t new_palette; 1175#ifdef PNG_POINTER_INDEXING_SUPPORTED 1176 png_sPLT_entryp pp; 1177#endif 1178 int data_length, entry_size, i; 1179 png_uint_32 skip = 0; 1180 png_size_t slength; 1181 1182 png_debug(1, "in png_handle_sPLT"); 1183 1184#ifdef PNG_USER_LIMITS_SUPPORTED 1185 1186 if (png_ptr->user_chunk_cache_max != 0) 1187 { 1188 if (png_ptr->user_chunk_cache_max == 1) 1189 { 1190 png_crc_finish(png_ptr, length); 1191 return; 1192 } 1193 if (--png_ptr->user_chunk_cache_max == 1) 1194 { 1195 png_warning(png_ptr, "No space in chunk cache for sPLT"); 1196 png_crc_finish(png_ptr, length); 1197 return; 1198 } 1199 } 1200#endif 1201 1202 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1203 png_error(png_ptr, "Missing IHDR before sPLT"); 1204 else if (png_ptr->mode & PNG_HAVE_IDAT) 1205 { 1206 png_warning(png_ptr, "Invalid sPLT after IDAT"); 1207 png_crc_finish(png_ptr, length); 1208 return; 1209 } 1210 1211#ifdef PNG_MAX_MALLOC_64K 1212 if (length > (png_uint_32)65535L) 1213 { 1214 png_warning(png_ptr, "sPLT chunk too large to fit in memory"); 1215 skip = length - (png_uint_32)65535L; 1216 length = (png_uint_32)65535L; 1217 } 1218#endif 1219 1220 png_free(png_ptr, png_ptr->chunkdata); 1221 png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); 1222 slength = (png_size_t)length; 1223 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1224 1225 if (png_crc_finish(png_ptr, skip)) 1226 { 1227 png_free(png_ptr, png_ptr->chunkdata); 1228 png_ptr->chunkdata = NULL; 1229 return; 1230 } 1231 1232 png_ptr->chunkdata[slength] = 0x00; 1233 1234 for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start; 1235 entry_start++) 1236 /* Empty loop to find end of name */ ; 1237 ++entry_start; 1238 1239 /* A sample depth should follow the separator, and we should be on it */ 1240 if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2) 1241 { 1242 png_free(png_ptr, png_ptr->chunkdata); 1243 png_ptr->chunkdata = NULL; 1244 png_warning(png_ptr, "malformed sPLT chunk"); 1245 return; 1246 } 1247 1248 new_palette.depth = *entry_start++; 1249 entry_size = (new_palette.depth == 8 ? 6 : 10); 1250 data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata)); 1251 1252 /* Integrity-check the data length */ 1253 if (data_length % entry_size) 1254 { 1255 png_free(png_ptr, png_ptr->chunkdata); 1256 png_ptr->chunkdata = NULL; 1257 png_warning(png_ptr, "sPLT chunk has bad length"); 1258 return; 1259 } 1260 1261 new_palette.nentries = (png_int_32) ( data_length / entry_size); 1262 if ((png_uint_32) new_palette.nentries > 1263 (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry))) 1264 { 1265 png_warning(png_ptr, "sPLT chunk too long"); 1266 return; 1267 } 1268 new_palette.entries = (png_sPLT_entryp)png_malloc_warn( 1269 png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry)); 1270 if (new_palette.entries == NULL) 1271 { 1272 png_warning(png_ptr, "sPLT chunk requires too much memory"); 1273 return; 1274 } 1275 1276#ifdef PNG_POINTER_INDEXING_SUPPORTED 1277 for (i = 0; i < new_palette.nentries; i++) 1278 { 1279 pp = new_palette.entries + i; 1280 1281 if (new_palette.depth == 8) 1282 { 1283 pp->red = *entry_start++; 1284 pp->green = *entry_start++; 1285 pp->blue = *entry_start++; 1286 pp->alpha = *entry_start++; 1287 } 1288 else 1289 { 1290 pp->red = png_get_uint_16(entry_start); entry_start += 2; 1291 pp->green = png_get_uint_16(entry_start); entry_start += 2; 1292 pp->blue = png_get_uint_16(entry_start); entry_start += 2; 1293 pp->alpha = png_get_uint_16(entry_start); entry_start += 2; 1294 } 1295 pp->frequency = png_get_uint_16(entry_start); entry_start += 2; 1296 } 1297#else 1298 pp = new_palette.entries; 1299 for (i = 0; i < new_palette.nentries; i++) 1300 { 1301 1302 if (new_palette.depth == 8) 1303 { 1304 pp[i].red = *entry_start++; 1305 pp[i].green = *entry_start++; 1306 pp[i].blue = *entry_start++; 1307 pp[i].alpha = *entry_start++; 1308 } 1309 else 1310 { 1311 pp[i].red = png_get_uint_16(entry_start); entry_start += 2; 1312 pp[i].green = png_get_uint_16(entry_start); entry_start += 2; 1313 pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; 1314 pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; 1315 } 1316 pp->frequency = png_get_uint_16(entry_start); entry_start += 2; 1317 } 1318#endif 1319 1320 /* Discard all chunk data except the name and stash that */ 1321 new_palette.name = png_ptr->chunkdata; 1322 1323 png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); 1324 1325 png_free(png_ptr, png_ptr->chunkdata); 1326 png_ptr->chunkdata = NULL; 1327 png_free(png_ptr, new_palette.entries); 1328} 1329#endif /* PNG_READ_sPLT_SUPPORTED */ 1330 1331#ifdef PNG_READ_tRNS_SUPPORTED 1332void /* PRIVATE */ 1333png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1334{ 1335 png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; 1336 1337 png_debug(1, "in png_handle_tRNS"); 1338 1339 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1340 png_error(png_ptr, "Missing IHDR before tRNS"); 1341 else if (png_ptr->mode & PNG_HAVE_IDAT) 1342 { 1343 png_warning(png_ptr, "Invalid tRNS after IDAT"); 1344 png_crc_finish(png_ptr, length); 1345 return; 1346 } 1347 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) 1348 { 1349 png_warning(png_ptr, "Duplicate tRNS chunk"); 1350 png_crc_finish(png_ptr, length); 1351 return; 1352 } 1353 1354 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 1355 { 1356 png_byte buf[2]; 1357 1358 if (length != 2) 1359 { 1360 png_warning(png_ptr, "Incorrect tRNS chunk length"); 1361 png_crc_finish(png_ptr, length); 1362 return; 1363 } 1364 1365 png_crc_read(png_ptr, buf, 2); 1366 png_ptr->num_trans = 1; 1367 png_ptr->trans_values.gray = png_get_uint_16(buf); 1368 } 1369 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 1370 { 1371 png_byte buf[6]; 1372 1373 if (length != 6) 1374 { 1375 png_warning(png_ptr, "Incorrect tRNS chunk length"); 1376 png_crc_finish(png_ptr, length); 1377 return; 1378 } 1379 png_crc_read(png_ptr, buf, (png_size_t)length); 1380 png_ptr->num_trans = 1; 1381 png_ptr->trans_values.red = png_get_uint_16(buf); 1382 png_ptr->trans_values.green = png_get_uint_16(buf + 2); 1383 png_ptr->trans_values.blue = png_get_uint_16(buf + 4); 1384 } 1385 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1386 { 1387 if (!(png_ptr->mode & PNG_HAVE_PLTE)) 1388 { 1389 /* Should be an error, but we can cope with it. */ 1390 png_warning(png_ptr, "Missing PLTE before tRNS"); 1391 } 1392 if (length > (png_uint_32)png_ptr->num_palette || 1393 length > PNG_MAX_PALETTE_LENGTH) 1394 { 1395 png_warning(png_ptr, "Incorrect tRNS chunk length"); 1396 png_crc_finish(png_ptr, length); 1397 return; 1398 } 1399 if (length == 0) 1400 { 1401 png_warning(png_ptr, "Zero length tRNS chunk"); 1402 png_crc_finish(png_ptr, length); 1403 return; 1404 } 1405 png_crc_read(png_ptr, readbuf, (png_size_t)length); 1406 png_ptr->num_trans = (png_uint_16)length; 1407 } 1408 else 1409 { 1410 png_warning(png_ptr, "tRNS chunk not allowed with alpha channel"); 1411 png_crc_finish(png_ptr, length); 1412 return; 1413 } 1414 1415 if (png_crc_finish(png_ptr, 0)) 1416 { 1417 png_ptr->num_trans = 0; 1418 return; 1419 } 1420 1421 png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, 1422 &(png_ptr->trans_values)); 1423} 1424#endif 1425 1426#ifdef PNG_READ_bKGD_SUPPORTED 1427void /* PRIVATE */ 1428png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1429{ 1430 png_size_t truelen; 1431 png_byte buf[6]; 1432 1433 png_debug(1, "in png_handle_bKGD"); 1434 1435 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1436 png_error(png_ptr, "Missing IHDR before bKGD"); 1437 else if (png_ptr->mode & PNG_HAVE_IDAT) 1438 { 1439 png_warning(png_ptr, "Invalid bKGD after IDAT"); 1440 png_crc_finish(png_ptr, length); 1441 return; 1442 } 1443 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 1444 !(png_ptr->mode & PNG_HAVE_PLTE)) 1445 { 1446 png_warning(png_ptr, "Missing PLTE before bKGD"); 1447 png_crc_finish(png_ptr, length); 1448 return; 1449 } 1450 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) 1451 { 1452 png_warning(png_ptr, "Duplicate bKGD chunk"); 1453 png_crc_finish(png_ptr, length); 1454 return; 1455 } 1456 1457 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1458 truelen = 1; 1459 else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) 1460 truelen = 6; 1461 else 1462 truelen = 2; 1463 1464 if (length != truelen) 1465 { 1466 png_warning(png_ptr, "Incorrect bKGD chunk length"); 1467 png_crc_finish(png_ptr, length); 1468 return; 1469 } 1470 1471 png_crc_read(png_ptr, buf, truelen); 1472 if (png_crc_finish(png_ptr, 0)) 1473 return; 1474 1475 /* We convert the index value into RGB components so that we can allow 1476 * arbitrary RGB values for background when we have transparency, and 1477 * so it is easy to determine the RGB values of the background color 1478 * from the info_ptr struct. */ 1479 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1480 { 1481 png_ptr->background.index = buf[0]; 1482 if (info_ptr && info_ptr->num_palette) 1483 { 1484 if (buf[0] >= info_ptr->num_palette) 1485 { 1486 png_warning(png_ptr, "Incorrect bKGD chunk index value"); 1487 return; 1488 } 1489 png_ptr->background.red = 1490 (png_uint_16)png_ptr->palette[buf[0]].red; 1491 png_ptr->background.green = 1492 (png_uint_16)png_ptr->palette[buf[0]].green; 1493 png_ptr->background.blue = 1494 (png_uint_16)png_ptr->palette[buf[0]].blue; 1495 } 1496 } 1497 else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ 1498 { 1499 png_ptr->background.red = 1500 png_ptr->background.green = 1501 png_ptr->background.blue = 1502 png_ptr->background.gray = png_get_uint_16(buf); 1503 } 1504 else 1505 { 1506 png_ptr->background.red = png_get_uint_16(buf); 1507 png_ptr->background.green = png_get_uint_16(buf + 2); 1508 png_ptr->background.blue = png_get_uint_16(buf + 4); 1509 } 1510 1511 png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background)); 1512} 1513#endif 1514 1515#ifdef PNG_READ_hIST_SUPPORTED 1516void /* PRIVATE */ 1517png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1518{ 1519 unsigned int num, i; 1520 png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; 1521 1522 png_debug(1, "in png_handle_hIST"); 1523 1524 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1525 png_error(png_ptr, "Missing IHDR before hIST"); 1526 else if (png_ptr->mode & PNG_HAVE_IDAT) 1527 { 1528 png_warning(png_ptr, "Invalid hIST after IDAT"); 1529 png_crc_finish(png_ptr, length); 1530 return; 1531 } 1532 else if (!(png_ptr->mode & PNG_HAVE_PLTE)) 1533 { 1534 png_warning(png_ptr, "Missing PLTE before hIST"); 1535 png_crc_finish(png_ptr, length); 1536 return; 1537 } 1538 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) 1539 { 1540 png_warning(png_ptr, "Duplicate hIST chunk"); 1541 png_crc_finish(png_ptr, length); 1542 return; 1543 } 1544 1545 num = length / 2 ; 1546 if (num != (unsigned int) png_ptr->num_palette || num > 1547 (unsigned int) PNG_MAX_PALETTE_LENGTH) 1548 { 1549 png_warning(png_ptr, "Incorrect hIST chunk length"); 1550 png_crc_finish(png_ptr, length); 1551 return; 1552 } 1553 1554 for (i = 0; i < num; i++) 1555 { 1556 png_byte buf[2]; 1557 1558 png_crc_read(png_ptr, buf, 2); 1559 readbuf[i] = png_get_uint_16(buf); 1560 } 1561 1562 if (png_crc_finish(png_ptr, 0)) 1563 return; 1564 1565 png_set_hIST(png_ptr, info_ptr, readbuf); 1566} 1567#endif 1568 1569#ifdef PNG_READ_pHYs_SUPPORTED 1570void /* PRIVATE */ 1571png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1572{ 1573 png_byte buf[9]; 1574 png_uint_32 res_x, res_y; 1575 int unit_type; 1576 1577 png_debug(1, "in png_handle_pHYs"); 1578 1579 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1580 png_error(png_ptr, "Missing IHDR before pHYs"); 1581 else if (png_ptr->mode & PNG_HAVE_IDAT) 1582 { 1583 png_warning(png_ptr, "Invalid pHYs after IDAT"); 1584 png_crc_finish(png_ptr, length); 1585 return; 1586 } 1587 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) 1588 { 1589 png_warning(png_ptr, "Duplicate pHYs chunk"); 1590 png_crc_finish(png_ptr, length); 1591 return; 1592 } 1593 1594 if (length != 9) 1595 { 1596 png_warning(png_ptr, "Incorrect pHYs chunk length"); 1597 png_crc_finish(png_ptr, length); 1598 return; 1599 } 1600 1601 png_crc_read(png_ptr, buf, 9); 1602 if (png_crc_finish(png_ptr, 0)) 1603 return; 1604 1605 res_x = png_get_uint_32(buf); 1606 res_y = png_get_uint_32(buf + 4); 1607 unit_type = buf[8]; 1608 png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); 1609} 1610#endif 1611 1612#ifdef PNG_READ_oFFs_SUPPORTED 1613void /* PRIVATE */ 1614png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1615{ 1616 png_byte buf[9]; 1617 png_int_32 offset_x, offset_y; 1618 int unit_type; 1619 1620 png_debug(1, "in png_handle_oFFs"); 1621 1622 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1623 png_error(png_ptr, "Missing IHDR before oFFs"); 1624 else if (png_ptr->mode & PNG_HAVE_IDAT) 1625 { 1626 png_warning(png_ptr, "Invalid oFFs after IDAT"); 1627 png_crc_finish(png_ptr, length); 1628 return; 1629 } 1630 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) 1631 { 1632 png_warning(png_ptr, "Duplicate oFFs chunk"); 1633 png_crc_finish(png_ptr, length); 1634 return; 1635 } 1636 1637 if (length != 9) 1638 { 1639 png_warning(png_ptr, "Incorrect oFFs chunk length"); 1640 png_crc_finish(png_ptr, length); 1641 return; 1642 } 1643 1644 png_crc_read(png_ptr, buf, 9); 1645 if (png_crc_finish(png_ptr, 0)) 1646 return; 1647 1648 offset_x = png_get_int_32(buf); 1649 offset_y = png_get_int_32(buf + 4); 1650 unit_type = buf[8]; 1651 png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); 1652} 1653#endif 1654 1655#ifdef PNG_READ_pCAL_SUPPORTED 1656/* Read the pCAL chunk (described in the PNG Extensions document) */ 1657void /* PRIVATE */ 1658png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1659{ 1660 png_int_32 X0, X1; 1661 png_byte type, nparams; 1662 png_charp buf, units, endptr; 1663 png_charpp params; 1664 png_size_t slength; 1665 int i; 1666 1667 png_debug(1, "in png_handle_pCAL"); 1668 1669 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1670 png_error(png_ptr, "Missing IHDR before pCAL"); 1671 else if (png_ptr->mode & PNG_HAVE_IDAT) 1672 { 1673 png_warning(png_ptr, "Invalid pCAL after IDAT"); 1674 png_crc_finish(png_ptr, length); 1675 return; 1676 } 1677 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) 1678 { 1679 png_warning(png_ptr, "Duplicate pCAL chunk"); 1680 png_crc_finish(png_ptr, length); 1681 return; 1682 } 1683 1684 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)", 1685 length + 1); 1686 png_free(png_ptr, png_ptr->chunkdata); 1687 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 1688 if (png_ptr->chunkdata == NULL) 1689 { 1690 png_warning(png_ptr, "No memory for pCAL purpose."); 1691 return; 1692 } 1693 slength = (png_size_t)length; 1694 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1695 1696 if (png_crc_finish(png_ptr, 0)) 1697 { 1698 png_free(png_ptr, png_ptr->chunkdata); 1699 png_ptr->chunkdata = NULL; 1700 return; 1701 } 1702 1703 png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ 1704 1705 png_debug(3, "Finding end of pCAL purpose string"); 1706 for (buf = png_ptr->chunkdata; *buf; buf++) 1707 /* Empty loop */ ; 1708 1709 endptr = png_ptr->chunkdata + slength; 1710 1711 /* We need to have at least 12 bytes after the purpose string 1712 in order to get the parameter information. */ 1713 if (endptr <= buf + 12) 1714 { 1715 png_warning(png_ptr, "Invalid pCAL data"); 1716 png_free(png_ptr, png_ptr->chunkdata); 1717 png_ptr->chunkdata = NULL; 1718 return; 1719 } 1720 1721 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units"); 1722 X0 = png_get_int_32((png_bytep)buf+1); 1723 X1 = png_get_int_32((png_bytep)buf+5); 1724 type = buf[9]; 1725 nparams = buf[10]; 1726 units = buf + 11; 1727 1728 png_debug(3, "Checking pCAL equation type and number of parameters"); 1729 /* Check that we have the right number of parameters for known 1730 equation types. */ 1731 if ((type == PNG_EQUATION_LINEAR && nparams != 2) || 1732 (type == PNG_EQUATION_BASE_E && nparams != 3) || 1733 (type == PNG_EQUATION_ARBITRARY && nparams != 3) || 1734 (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) 1735 { 1736 png_warning(png_ptr, "Invalid pCAL parameters for equation type"); 1737 png_free(png_ptr, png_ptr->chunkdata); 1738 png_ptr->chunkdata = NULL; 1739 return; 1740 } 1741 else if (type >= PNG_EQUATION_LAST) 1742 { 1743 png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); 1744 } 1745 1746 for (buf = units; *buf; buf++) 1747 /* Empty loop to move past the units string. */ ; 1748 1749 png_debug(3, "Allocating pCAL parameters array"); 1750 params = (png_charpp)png_malloc_warn(png_ptr, 1751 (png_uint_32)(nparams * png_sizeof(png_charp))) ; 1752 if (params == NULL) 1753 { 1754 png_free(png_ptr, png_ptr->chunkdata); 1755 png_ptr->chunkdata = NULL; 1756 png_warning(png_ptr, "No memory for pCAL params."); 1757 return; 1758 } 1759 1760 /* Get pointers to the start of each parameter string. */ 1761 for (i = 0; i < (int)nparams; i++) 1762 { 1763 buf++; /* Skip the null string terminator from previous parameter. */ 1764 1765 png_debug1(3, "Reading pCAL parameter %d", i); 1766 for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++) 1767 /* Empty loop to move past each parameter string */ ; 1768 1769 /* Make sure we haven't run out of data yet */ 1770 if (buf > endptr) 1771 { 1772 png_warning(png_ptr, "Invalid pCAL data"); 1773 png_free(png_ptr, png_ptr->chunkdata); 1774 png_ptr->chunkdata = NULL; 1775 png_free(png_ptr, params); 1776 return; 1777 } 1778 } 1779 1780 png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams, 1781 units, params); 1782 1783 png_free(png_ptr, png_ptr->chunkdata); 1784 png_ptr->chunkdata = NULL; 1785 png_free(png_ptr, params); 1786} 1787#endif 1788 1789#ifdef PNG_READ_sCAL_SUPPORTED 1790/* Read the sCAL chunk */ 1791void /* PRIVATE */ 1792png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1793{ 1794 png_charp ep; 1795#ifdef PNG_FLOATING_POINT_SUPPORTED 1796 double width, height; 1797 png_charp vp; 1798#else 1799#ifdef PNG_FIXED_POINT_SUPPORTED 1800 png_charp swidth, sheight; 1801#endif 1802#endif 1803 png_size_t slength; 1804 1805 png_debug(1, "in png_handle_sCAL"); 1806 1807 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1808 png_error(png_ptr, "Missing IHDR before sCAL"); 1809 else if (png_ptr->mode & PNG_HAVE_IDAT) 1810 { 1811 png_warning(png_ptr, "Invalid sCAL after IDAT"); 1812 png_crc_finish(png_ptr, length); 1813 return; 1814 } 1815 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) 1816 { 1817 png_warning(png_ptr, "Duplicate sCAL chunk"); 1818 png_crc_finish(png_ptr, length); 1819 return; 1820 } 1821 1822 /* Need unit type, width, \0, height: minimum 4 bytes */ 1823 else if (length < 4) 1824 { 1825 png_warning(png_ptr, "sCAL chunk too short"); 1826 png_crc_finish(png_ptr, length); 1827 return; 1828 } 1829 1830 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)", 1831 length + 1); 1832 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 1833 if (png_ptr->chunkdata == NULL) 1834 { 1835 png_warning(png_ptr, "Out of memory while processing sCAL chunk"); 1836 png_crc_finish(png_ptr, length); 1837 return; 1838 } 1839 slength = (png_size_t)length; 1840 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1841 1842 if (png_crc_finish(png_ptr, 0)) 1843 { 1844 png_free(png_ptr, png_ptr->chunkdata); 1845 png_ptr->chunkdata = NULL; 1846 return; 1847 } 1848 1849 png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ 1850 1851 ep = png_ptr->chunkdata + 1; /* Skip unit byte */ 1852 1853#ifdef PNG_FLOATING_POINT_SUPPORTED 1854 width = png_strtod(png_ptr, ep, &vp); 1855 if (*vp) 1856 { 1857 png_warning(png_ptr, "malformed width string in sCAL chunk"); 1858 png_free(png_ptr, png_ptr->chunkdata); 1859 png_ptr->chunkdata = NULL; 1860 return; 1861 } 1862#else 1863#ifdef PNG_FIXED_POINT_SUPPORTED 1864 swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); 1865 if (swidth == NULL) 1866 { 1867 png_warning(png_ptr, "Out of memory while processing sCAL chunk width"); 1868 png_free(png_ptr, png_ptr->chunkdata); 1869 png_ptr->chunkdata = NULL; 1870 return; 1871 } 1872 png_memcpy(swidth, ep, (png_size_t)png_strlen(ep)); 1873#endif 1874#endif 1875 1876 for (ep = png_ptr->chunkdata; *ep; ep++) 1877 /* Empty loop */ ; 1878 ep++; 1879 1880 if (png_ptr->chunkdata + slength < ep) 1881 { 1882 png_warning(png_ptr, "Truncated sCAL chunk"); 1883#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1884 png_free(png_ptr, swidth); 1885#endif 1886 png_free(png_ptr, png_ptr->chunkdata); 1887 png_ptr->chunkdata = NULL; 1888 return; 1889 } 1890 1891#ifdef PNG_FLOATING_POINT_SUPPORTED 1892 height = png_strtod(png_ptr, ep, &vp); 1893 if (*vp) 1894 { 1895 png_warning(png_ptr, "malformed height string in sCAL chunk"); 1896 png_free(png_ptr, png_ptr->chunkdata); 1897 png_ptr->chunkdata = NULL; 1898#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1899 png_free(png_ptr, swidth); 1900#endif 1901 return; 1902 } 1903#else 1904#ifdef PNG_FIXED_POINT_SUPPORTED 1905 sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); 1906 if (sheight == NULL) 1907 { 1908 png_warning(png_ptr, "Out of memory while processing sCAL chunk height"); 1909 png_free(png_ptr, png_ptr->chunkdata); 1910 png_ptr->chunkdata = NULL; 1911#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1912 png_free(png_ptr, swidth); 1913#endif 1914 return; 1915 } 1916 png_memcpy(sheight, ep, (png_size_t)png_strlen(ep)); 1917#endif 1918#endif 1919 1920 if (png_ptr->chunkdata + slength < ep 1921#ifdef PNG_FLOATING_POINT_SUPPORTED 1922 || width <= 0. || height <= 0. 1923#endif 1924 ) 1925 { 1926 png_warning(png_ptr, "Invalid sCAL data"); 1927 png_free(png_ptr, png_ptr->chunkdata); 1928 png_ptr->chunkdata = NULL; 1929#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1930 png_free(png_ptr, swidth); 1931 png_free(png_ptr, sheight); 1932#endif 1933 return; 1934 } 1935 1936 1937#ifdef PNG_FLOATING_POINT_SUPPORTED 1938 png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height); 1939#else 1940#ifdef PNG_FIXED_POINT_SUPPORTED 1941 png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight); 1942#endif 1943#endif 1944 1945 png_free(png_ptr, png_ptr->chunkdata); 1946 png_ptr->chunkdata = NULL; 1947#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1948 png_free(png_ptr, swidth); 1949 png_free(png_ptr, sheight); 1950#endif 1951} 1952#endif 1953 1954#ifdef PNG_READ_tIME_SUPPORTED 1955void /* PRIVATE */ 1956png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1957{ 1958 png_byte buf[7]; 1959 png_time mod_time; 1960 1961 png_debug(1, "in png_handle_tIME"); 1962 1963 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1964 png_error(png_ptr, "Out of place tIME chunk"); 1965 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) 1966 { 1967 png_warning(png_ptr, "Duplicate tIME chunk"); 1968 png_crc_finish(png_ptr, length); 1969 return; 1970 } 1971 1972 if (png_ptr->mode & PNG_HAVE_IDAT) 1973 png_ptr->mode |= PNG_AFTER_IDAT; 1974 1975 if (length != 7) 1976 { 1977 png_warning(png_ptr, "Incorrect tIME chunk length"); 1978 png_crc_finish(png_ptr, length); 1979 return; 1980 } 1981 1982 png_crc_read(png_ptr, buf, 7); 1983 if (png_crc_finish(png_ptr, 0)) 1984 return; 1985 1986 mod_time.second = buf[6]; 1987 mod_time.minute = buf[5]; 1988 mod_time.hour = buf[4]; 1989 mod_time.day = buf[3]; 1990 mod_time.month = buf[2]; 1991 mod_time.year = png_get_uint_16(buf); 1992 1993 png_set_tIME(png_ptr, info_ptr, &mod_time); 1994} 1995#endif 1996 1997#ifdef PNG_READ_tEXt_SUPPORTED 1998/* Note: this does not properly handle chunks that are > 64K under DOS */ 1999void /* PRIVATE */ 2000png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 2001{ 2002 png_textp text_ptr; 2003 png_charp key; 2004 png_charp text; 2005 png_uint_32 skip = 0; 2006 png_size_t slength; 2007 int ret; 2008 2009 png_debug(1, "in png_handle_tEXt"); 2010 2011#ifdef PNG_USER_LIMITS_SUPPORTED 2012 if (png_ptr->user_chunk_cache_max != 0) 2013 { 2014 if (png_ptr->user_chunk_cache_max == 1) 2015 { 2016 png_crc_finish(png_ptr, length); 2017 return; 2018 } 2019 if (--png_ptr->user_chunk_cache_max == 1) 2020 { 2021 png_warning(png_ptr, "No space in chunk cache for tEXt"); 2022 png_crc_finish(png_ptr, length); 2023 return; 2024 } 2025 } 2026#endif 2027 2028 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 2029 png_error(png_ptr, "Missing IHDR before tEXt"); 2030 2031 if (png_ptr->mode & PNG_HAVE_IDAT) 2032 png_ptr->mode |= PNG_AFTER_IDAT; 2033 2034#ifdef PNG_MAX_MALLOC_64K 2035 if (length > (png_uint_32)65535L) 2036 { 2037 png_warning(png_ptr, "tEXt chunk too large to fit in memory"); 2038 skip = length - (png_uint_32)65535L; 2039 length = (png_uint_32)65535L; 2040 } 2041#endif 2042 2043 png_free(png_ptr, png_ptr->chunkdata); 2044 2045 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 2046 if (png_ptr->chunkdata == NULL) 2047 { 2048 png_warning(png_ptr, "No memory to process text chunk."); 2049 return; 2050 } 2051 slength = (png_size_t)length; 2052 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 2053 2054 if (png_crc_finish(png_ptr, skip)) 2055 { 2056 png_free(png_ptr, png_ptr->chunkdata); 2057 png_ptr->chunkdata = NULL; 2058 return; 2059 } 2060 2061 key = png_ptr->chunkdata; 2062 2063 key[slength] = 0x00; 2064 2065 for (text = key; *text; text++) 2066 /* Empty loop to find end of key */ ; 2067 2068 if (text != key + slength) 2069 text++; 2070 2071 text_ptr = (png_textp)png_malloc_warn(png_ptr, 2072 (png_uint_32)png_sizeof(png_text)); 2073 if (text_ptr == NULL) 2074 { 2075 png_warning(png_ptr, "Not enough memory to process text chunk."); 2076 png_free(png_ptr, png_ptr->chunkdata); 2077 png_ptr->chunkdata = NULL; 2078 return; 2079 } 2080 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; 2081 text_ptr->key = key; 2082#ifdef PNG_iTXt_SUPPORTED 2083 text_ptr->lang = NULL; 2084 text_ptr->lang_key = NULL; 2085 text_ptr->itxt_length = 0; 2086#endif 2087 text_ptr->text = text; 2088 text_ptr->text_length = png_strlen(text); 2089 2090 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 2091 2092 png_free(png_ptr, png_ptr->chunkdata); 2093 png_ptr->chunkdata = NULL; 2094 png_free(png_ptr, text_ptr); 2095 if (ret) 2096 png_warning(png_ptr, "Insufficient memory to process text chunk."); 2097} 2098#endif 2099 2100#ifdef PNG_READ_zTXt_SUPPORTED 2101/* Note: this does not correctly handle chunks that are > 64K under DOS */ 2102void /* PRIVATE */ 2103png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 2104{ 2105 png_textp text_ptr; 2106 png_charp text; 2107 int comp_type; 2108 int ret; 2109 png_size_t slength, prefix_len, data_len; 2110 2111 png_debug(1, "in png_handle_zTXt"); 2112 2113#ifdef PNG_USER_LIMITS_SUPPORTED 2114 if (png_ptr->user_chunk_cache_max != 0) 2115 { 2116 if (png_ptr->user_chunk_cache_max == 1) 2117 { 2118 png_crc_finish(png_ptr, length); 2119 return; 2120 } 2121 if (--png_ptr->user_chunk_cache_max == 1) 2122 { 2123 png_warning(png_ptr, "No space in chunk cache for zTXt"); 2124 png_crc_finish(png_ptr, length); 2125 return; 2126 } 2127 } 2128#endif 2129 2130 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 2131 png_error(png_ptr, "Missing IHDR before zTXt"); 2132 2133 if (png_ptr->mode & PNG_HAVE_IDAT) 2134 png_ptr->mode |= PNG_AFTER_IDAT; 2135 2136#ifdef PNG_MAX_MALLOC_64K 2137 /* We will no doubt have problems with chunks even half this size, but 2138 there is no hard and fast rule to tell us where to stop. */ 2139 if (length > (png_uint_32)65535L) 2140 { 2141 png_warning(png_ptr, "zTXt chunk too large to fit in memory"); 2142 png_crc_finish(png_ptr, length); 2143 return; 2144 } 2145#endif 2146 2147 png_free(png_ptr, png_ptr->chunkdata); 2148 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 2149 if (png_ptr->chunkdata == NULL) 2150 { 2151 png_warning(png_ptr, "Out of memory processing zTXt chunk."); 2152 return; 2153 } 2154 slength = (png_size_t)length; 2155 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 2156 if (png_crc_finish(png_ptr, 0)) 2157 { 2158 png_free(png_ptr, png_ptr->chunkdata); 2159 png_ptr->chunkdata = NULL; 2160 return; 2161 } 2162 2163 png_ptr->chunkdata[slength] = 0x00; 2164 2165 for (text = png_ptr->chunkdata; *text; text++) 2166 /* Empty loop */ ; 2167 2168 /* zTXt must have some text after the chunkdataword */ 2169 if (text >= png_ptr->chunkdata + slength - 2) 2170 { 2171 png_warning(png_ptr, "Truncated zTXt chunk"); 2172 png_free(png_ptr, png_ptr->chunkdata); 2173 png_ptr->chunkdata = NULL; 2174 return; 2175 } 2176 else 2177 { 2178 comp_type = *(++text); 2179 if (comp_type != PNG_TEXT_COMPRESSION_zTXt) 2180 { 2181 png_warning(png_ptr, "Unknown compression type in zTXt chunk"); 2182 comp_type = PNG_TEXT_COMPRESSION_zTXt; 2183 } 2184 text++; /* Skip the compression_method byte */ 2185 } 2186 prefix_len = text - png_ptr->chunkdata; 2187 2188 png_decompress_chunk(png_ptr, comp_type, 2189 (png_size_t)length, prefix_len, &data_len); 2190 2191 text_ptr = (png_textp)png_malloc_warn(png_ptr, 2192 (png_uint_32)png_sizeof(png_text)); 2193 if (text_ptr == NULL) 2194 { 2195 png_warning(png_ptr, "Not enough memory to process zTXt chunk."); 2196 png_free(png_ptr, png_ptr->chunkdata); 2197 png_ptr->chunkdata = NULL; 2198 return; 2199 } 2200 text_ptr->compression = comp_type; 2201 text_ptr->key = png_ptr->chunkdata; 2202#ifdef PNG_iTXt_SUPPORTED 2203 text_ptr->lang = NULL; 2204 text_ptr->lang_key = NULL; 2205 text_ptr->itxt_length = 0; 2206#endif 2207 text_ptr->text = png_ptr->chunkdata + prefix_len; 2208 text_ptr->text_length = data_len; 2209 2210 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 2211 2212 png_free(png_ptr, text_ptr); 2213 png_free(png_ptr, png_ptr->chunkdata); 2214 png_ptr->chunkdata = NULL; 2215 if (ret) 2216 png_error(png_ptr, "Insufficient memory to store zTXt chunk."); 2217} 2218#endif 2219 2220#ifdef PNG_READ_iTXt_SUPPORTED 2221/* Note: this does not correctly handle chunks that are > 64K under DOS */ 2222void /* PRIVATE */ 2223png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 2224{ 2225 png_textp text_ptr; 2226 png_charp key, lang, text, lang_key; 2227 int comp_flag; 2228 int comp_type = 0; 2229 int ret; 2230 png_size_t slength, prefix_len, data_len; 2231 2232 png_debug(1, "in png_handle_iTXt"); 2233 2234#ifdef PNG_USER_LIMITS_SUPPORTED 2235 if (png_ptr->user_chunk_cache_max != 0) 2236 { 2237 if (png_ptr->user_chunk_cache_max == 1) 2238 { 2239 png_crc_finish(png_ptr, length); 2240 return; 2241 } 2242 if (--png_ptr->user_chunk_cache_max == 1) 2243 { 2244 png_warning(png_ptr, "No space in chunk cache for iTXt"); 2245 png_crc_finish(png_ptr, length); 2246 return; 2247 } 2248 } 2249#endif 2250 2251 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 2252 png_error(png_ptr, "Missing IHDR before iTXt"); 2253 2254 if (png_ptr->mode & PNG_HAVE_IDAT) 2255 png_ptr->mode |= PNG_AFTER_IDAT; 2256 2257#ifdef PNG_MAX_MALLOC_64K 2258 /* We will no doubt have problems with chunks even half this size, but 2259 there is no hard and fast rule to tell us where to stop. */ 2260 if (length > (png_uint_32)65535L) 2261 { 2262 png_warning(png_ptr, "iTXt chunk too large to fit in memory"); 2263 png_crc_finish(png_ptr, length); 2264 return; 2265 } 2266#endif 2267 2268 png_free(png_ptr, png_ptr->chunkdata); 2269 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 2270 if (png_ptr->chunkdata == NULL) 2271 { 2272 png_warning(png_ptr, "No memory to process iTXt chunk."); 2273 return; 2274 } 2275 slength = (png_size_t)length; 2276 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 2277 if (png_crc_finish(png_ptr, 0)) 2278 { 2279 png_free(png_ptr, png_ptr->chunkdata); 2280 png_ptr->chunkdata = NULL; 2281 return; 2282 } 2283 2284 png_ptr->chunkdata[slength] = 0x00; 2285 2286 for (lang = png_ptr->chunkdata; *lang; lang++) 2287 /* Empty loop */ ; 2288 lang++; /* Skip NUL separator */ 2289 2290 /* iTXt must have a language tag (possibly empty), two compression bytes, 2291 * translated keyword (possibly empty), and possibly some text after the 2292 * keyword 2293 */ 2294 2295 if (lang >= png_ptr->chunkdata + slength - 3) 2296 { 2297 png_warning(png_ptr, "Truncated iTXt chunk"); 2298 png_free(png_ptr, png_ptr->chunkdata); 2299 png_ptr->chunkdata = NULL; 2300 return; 2301 } 2302 else 2303 { 2304 comp_flag = *lang++; 2305 comp_type = *lang++; 2306 } 2307 2308 for (lang_key = lang; *lang_key; lang_key++) 2309 /* Empty loop */ ; 2310 lang_key++; /* Skip NUL separator */ 2311 2312 if (lang_key >= png_ptr->chunkdata + slength) 2313 { 2314 png_warning(png_ptr, "Truncated iTXt chunk"); 2315 png_free(png_ptr, png_ptr->chunkdata); 2316 png_ptr->chunkdata = NULL; 2317 return; 2318 } 2319 2320 for (text = lang_key; *text; text++) 2321 /* Empty loop */ ; 2322 text++; /* Skip NUL separator */ 2323 if (text >= png_ptr->chunkdata + slength) 2324 { 2325 png_warning(png_ptr, "Malformed iTXt chunk"); 2326 png_free(png_ptr, png_ptr->chunkdata); 2327 png_ptr->chunkdata = NULL; 2328 return; 2329 } 2330 2331 prefix_len = text - png_ptr->chunkdata; 2332 2333 key=png_ptr->chunkdata; 2334 if (comp_flag) 2335 png_decompress_chunk(png_ptr, comp_type, 2336 (size_t)length, prefix_len, &data_len); 2337 else 2338 data_len = png_strlen(png_ptr->chunkdata + prefix_len); 2339 text_ptr = (png_textp)png_malloc_warn(png_ptr, 2340 (png_uint_32)png_sizeof(png_text)); 2341 if (text_ptr == NULL) 2342 { 2343 png_warning(png_ptr, "Not enough memory to process iTXt chunk."); 2344 png_free(png_ptr, png_ptr->chunkdata); 2345 png_ptr->chunkdata = NULL; 2346 return; 2347 } 2348 text_ptr->compression = (int)comp_flag + 1; 2349 text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key); 2350 text_ptr->lang = png_ptr->chunkdata + (lang - key); 2351 text_ptr->itxt_length = data_len; 2352 text_ptr->text_length = 0; 2353 text_ptr->key = png_ptr->chunkdata; 2354 text_ptr->text = png_ptr->chunkdata + prefix_len; 2355 2356 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 2357 2358 png_free(png_ptr, text_ptr); 2359 png_free(png_ptr, png_ptr->chunkdata); 2360 png_ptr->chunkdata = NULL; 2361 if (ret) 2362 png_error(png_ptr, "Insufficient memory to store iTXt chunk."); 2363} 2364#endif 2365 2366/* This function is called when we haven't found a handler for a 2367 chunk. If there isn't a problem with the chunk itself (ie bad 2368 chunk name, CRC, or a critical chunk), the chunk is silently ignored 2369 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which 2370 case it will be saved away to be written out later. */ 2371void /* PRIVATE */ 2372png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 2373{ 2374 png_uint_32 skip = 0; 2375 2376 png_debug(1, "in png_handle_unknown"); 2377 2378#ifdef PNG_USER_LIMITS_SUPPORTED 2379 if (png_ptr->user_chunk_cache_max != 0) 2380 { 2381 if (png_ptr->user_chunk_cache_max == 1) 2382 { 2383 png_crc_finish(png_ptr, length); 2384 return; 2385 } 2386 if (--png_ptr->user_chunk_cache_max == 1) 2387 { 2388 png_warning(png_ptr, "No space in chunk cache for unknown chunk"); 2389 png_crc_finish(png_ptr, length); 2390 return; 2391 } 2392 } 2393#endif 2394 2395 if (png_ptr->mode & PNG_HAVE_IDAT) 2396 { 2397#ifdef PNG_USE_LOCAL_ARRAYS 2398 PNG_CONST PNG_IDAT; 2399#endif 2400 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */ 2401 png_ptr->mode |= PNG_AFTER_IDAT; 2402 } 2403 2404 if (!(png_ptr->chunk_name[0] & 0x20)) 2405 { 2406#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 2407 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != 2408 PNG_HANDLE_CHUNK_ALWAYS 2409#ifdef PNG_READ_USER_CHUNKS_SUPPORTED 2410 && png_ptr->read_user_chunk_fn == NULL 2411#endif 2412 ) 2413#endif 2414 png_chunk_error(png_ptr, "unknown critical chunk"); 2415 } 2416 2417#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED 2418 if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) 2419#ifdef PNG_READ_USER_CHUNKS_SUPPORTED 2420 || (png_ptr->read_user_chunk_fn != NULL) 2421#endif 2422 ) 2423 { 2424#ifdef PNG_MAX_MALLOC_64K 2425 if (length > (png_uint_32)65535L) 2426 { 2427 png_warning(png_ptr, "unknown chunk too large to fit in memory"); 2428 skip = length - (png_uint_32)65535L; 2429 length = (png_uint_32)65535L; 2430 } 2431#endif 2432 png_memcpy((png_charp)png_ptr->unknown_chunk.name, 2433 (png_charp)png_ptr->chunk_name, 2434 png_sizeof(png_ptr->unknown_chunk.name)); 2435 png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1] 2436 = '\0'; 2437 png_ptr->unknown_chunk.size = (png_size_t)length; 2438 if (length == 0) 2439 png_ptr->unknown_chunk.data = NULL; 2440 else 2441 { 2442 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); 2443 png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); 2444 } 2445#ifdef PNG_READ_USER_CHUNKS_SUPPORTED 2446 if (png_ptr->read_user_chunk_fn != NULL) 2447 { 2448 /* Callback to user unknown chunk handler */ 2449 int ret; 2450 ret = (*(png_ptr->read_user_chunk_fn)) 2451 (png_ptr, &png_ptr->unknown_chunk); 2452 if (ret < 0) 2453 png_chunk_error(png_ptr, "error in user chunk"); 2454 if (ret == 0) 2455 { 2456 if (!(png_ptr->chunk_name[0] & 0x20)) 2457#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 2458 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != 2459 PNG_HANDLE_CHUNK_ALWAYS) 2460#endif 2461 png_chunk_error(png_ptr, "unknown critical chunk"); 2462 png_set_unknown_chunks(png_ptr, info_ptr, 2463 &png_ptr->unknown_chunk, 1); 2464 } 2465 } 2466 else 2467#endif 2468 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); 2469 png_free(png_ptr, png_ptr->unknown_chunk.data); 2470 png_ptr->unknown_chunk.data = NULL; 2471 } 2472 else 2473#endif 2474 skip = length; 2475 2476 png_crc_finish(png_ptr, skip); 2477 2478#ifndef PNG_READ_USER_CHUNKS_SUPPORTED 2479 info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */ 2480#endif 2481} 2482 2483/* This function is called to verify that a chunk name is valid. 2484 This function can't have the "critical chunk check" incorporated 2485 into it, since in the future we will need to be able to call user 2486 functions to handle unknown critical chunks after we check that 2487 the chunk name itself is valid. */ 2488 2489#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) 2490 2491void /* PRIVATE */ 2492png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name) 2493{ 2494 png_debug(1, "in png_check_chunk_name"); 2495 if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) || 2496 isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3])) 2497 { 2498 png_chunk_error(png_ptr, "invalid chunk type"); 2499 } 2500} 2501 2502/* Combines the row recently read in with the existing pixels in the 2503 row. This routine takes care of alpha and transparency if requested. 2504 This routine also handles the two methods of progressive display 2505 of interlaced images, depending on the mask value. 2506 The mask value describes which pixels are to be combined with 2507 the row. The pattern always repeats every 8 pixels, so just 8 2508 bits are needed. A one indicates the pixel is to be combined, 2509 a zero indicates the pixel is to be skipped. This is in addition 2510 to any alpha or transparency value associated with the pixel. If 2511 you want all pixels to be combined, pass 0xff (255) in mask. */ 2512 2513void /* PRIVATE */ 2514png_combine_row(png_structp png_ptr, png_bytep row, int mask) 2515{ 2516 png_debug(1, "in png_combine_row"); 2517 if (mask == 0xff) 2518 { 2519 png_memcpy(row, png_ptr->row_buf + 1, 2520 PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)); 2521 } 2522 else 2523 { 2524 switch (png_ptr->row_info.pixel_depth) 2525 { 2526 case 1: 2527 { 2528 png_bytep sp = png_ptr->row_buf + 1; 2529 png_bytep dp = row; 2530 int s_inc, s_start, s_end; 2531 int m = 0x80; 2532 int shift; 2533 png_uint_32 i; 2534 png_uint_32 row_width = png_ptr->width; 2535 2536#ifdef PNG_READ_PACKSWAP_SUPPORTED 2537 if (png_ptr->transformations & PNG_PACKSWAP) 2538 { 2539 s_start = 0; 2540 s_end = 7; 2541 s_inc = 1; 2542 } 2543 else 2544#endif 2545 { 2546 s_start = 7; 2547 s_end = 0; 2548 s_inc = -1; 2549 } 2550 2551 shift = s_start; 2552 2553 for (i = 0; i < row_width; i++) 2554 { 2555 if (m & mask) 2556 { 2557 int value; 2558 2559 value = (*sp >> shift) & 0x01; 2560 *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); 2561 *dp |= (png_byte)(value << shift); 2562 } 2563 2564 if (shift == s_end) 2565 { 2566 shift = s_start; 2567 sp++; 2568 dp++; 2569 } 2570 else 2571 shift += s_inc; 2572 2573 if (m == 1) 2574 m = 0x80; 2575 else 2576 m >>= 1; 2577 } 2578 break; 2579 } 2580 case 2: 2581 { 2582 png_bytep sp = png_ptr->row_buf + 1; 2583 png_bytep dp = row; 2584 int s_start, s_end, s_inc; 2585 int m = 0x80; 2586 int shift; 2587 png_uint_32 i; 2588 png_uint_32 row_width = png_ptr->width; 2589 int value; 2590 2591#ifdef PNG_READ_PACKSWAP_SUPPORTED 2592 if (png_ptr->transformations & PNG_PACKSWAP) 2593 { 2594 s_start = 0; 2595 s_end = 6; 2596 s_inc = 2; 2597 } 2598 else 2599#endif 2600 { 2601 s_start = 6; 2602 s_end = 0; 2603 s_inc = -2; 2604 } 2605 2606 shift = s_start; 2607 2608 for (i = 0; i < row_width; i++) 2609 { 2610 if (m & mask) 2611 { 2612 value = (*sp >> shift) & 0x03; 2613 *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); 2614 *dp |= (png_byte)(value << shift); 2615 } 2616 2617 if (shift == s_end) 2618 { 2619 shift = s_start; 2620 sp++; 2621 dp++; 2622 } 2623 else 2624 shift += s_inc; 2625 if (m == 1) 2626 m = 0x80; 2627 else 2628 m >>= 1; 2629 } 2630 break; 2631 } 2632 case 4: 2633 { 2634 png_bytep sp = png_ptr->row_buf + 1; 2635 png_bytep dp = row; 2636 int s_start, s_end, s_inc; 2637 int m = 0x80; 2638 int shift; 2639 png_uint_32 i; 2640 png_uint_32 row_width = png_ptr->width; 2641 int value; 2642 2643#ifdef PNG_READ_PACKSWAP_SUPPORTED 2644 if (png_ptr->transformations & PNG_PACKSWAP) 2645 { 2646 s_start = 0; 2647 s_end = 4; 2648 s_inc = 4; 2649 } 2650 else 2651#endif 2652 { 2653 s_start = 4; 2654 s_end = 0; 2655 s_inc = -4; 2656 } 2657 shift = s_start; 2658 2659 for (i = 0; i < row_width; i++) 2660 { 2661 if (m & mask) 2662 { 2663 value = (*sp >> shift) & 0xf; 2664 *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); 2665 *dp |= (png_byte)(value << shift); 2666 } 2667 2668 if (shift == s_end) 2669 { 2670 shift = s_start; 2671 sp++; 2672 dp++; 2673 } 2674 else 2675 shift += s_inc; 2676 if (m == 1) 2677 m = 0x80; 2678 else 2679 m >>= 1; 2680 } 2681 break; 2682 } 2683 default: 2684 { 2685 png_bytep sp = png_ptr->row_buf + 1; 2686 png_bytep dp = row; 2687 png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); 2688 png_uint_32 i; 2689 png_uint_32 row_width = png_ptr->width; 2690 png_byte m = 0x80; 2691 2692 2693 for (i = 0; i < row_width; i++) 2694 { 2695 if (m & mask) 2696 { 2697 png_memcpy(dp, sp, pixel_bytes); 2698 } 2699 2700 sp += pixel_bytes; 2701 dp += pixel_bytes; 2702 2703 if (m == 1) 2704 m = 0x80; 2705 else 2706 m >>= 1; 2707 } 2708 break; 2709 } 2710 } 2711 } 2712} 2713 2714#ifdef PNG_READ_INTERLACING_SUPPORTED 2715/* OLD pre-1.0.9 interface: 2716void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, 2717 png_uint_32 transformations) 2718 */ 2719void /* PRIVATE */ 2720png_do_read_interlace(png_structp png_ptr) 2721{ 2722 png_row_infop row_info = &(png_ptr->row_info); 2723 png_bytep row = png_ptr->row_buf + 1; 2724 int pass = png_ptr->pass; 2725 png_uint_32 transformations = png_ptr->transformations; 2726 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 2727 /* Offset to next interlace block */ 2728 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 2729 2730 png_debug(1, "in png_do_read_interlace"); 2731 if (row != NULL && row_info != NULL) 2732 { 2733 png_uint_32 final_width; 2734 2735 final_width = row_info->width * png_pass_inc[pass]; 2736 2737 switch (row_info->pixel_depth) 2738 { 2739 case 1: 2740 { 2741 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3); 2742 png_bytep dp = row + (png_size_t)((final_width - 1) >> 3); 2743 int sshift, dshift; 2744 int s_start, s_end, s_inc; 2745 int jstop = png_pass_inc[pass]; 2746 png_byte v; 2747 png_uint_32 i; 2748 int j; 2749 2750#ifdef PNG_READ_PACKSWAP_SUPPORTED 2751 if (transformations & PNG_PACKSWAP) 2752 { 2753 sshift = (int)((row_info->width + 7) & 0x07); 2754 dshift = (int)((final_width + 7) & 0x07); 2755 s_start = 7; 2756 s_end = 0; 2757 s_inc = -1; 2758 } 2759 else 2760#endif 2761 { 2762 sshift = 7 - (int)((row_info->width + 7) & 0x07); 2763 dshift = 7 - (int)((final_width + 7) & 0x07); 2764 s_start = 0; 2765 s_end = 7; 2766 s_inc = 1; 2767 } 2768 2769 for (i = 0; i < row_info->width; i++) 2770 { 2771 v = (png_byte)((*sp >> sshift) & 0x01); 2772 for (j = 0; j < jstop; j++) 2773 { 2774 *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); 2775 *dp |= (png_byte)(v << dshift); 2776 if (dshift == s_end) 2777 { 2778 dshift = s_start; 2779 dp--; 2780 } 2781 else 2782 dshift += s_inc; 2783 } 2784 if (sshift == s_end) 2785 { 2786 sshift = s_start; 2787 sp--; 2788 } 2789 else 2790 sshift += s_inc; 2791 } 2792 break; 2793 } 2794 case 2: 2795 { 2796 png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); 2797 png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2); 2798 int sshift, dshift; 2799 int s_start, s_end, s_inc; 2800 int jstop = png_pass_inc[pass]; 2801 png_uint_32 i; 2802 2803#ifdef PNG_READ_PACKSWAP_SUPPORTED 2804 if (transformations & PNG_PACKSWAP) 2805 { 2806 sshift = (int)(((row_info->width + 3) & 0x03) << 1); 2807 dshift = (int)(((final_width + 3) & 0x03) << 1); 2808 s_start = 6; 2809 s_end = 0; 2810 s_inc = -2; 2811 } 2812 else 2813#endif 2814 { 2815 sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1); 2816 dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1); 2817 s_start = 0; 2818 s_end = 6; 2819 s_inc = 2; 2820 } 2821 2822 for (i = 0; i < row_info->width; i++) 2823 { 2824 png_byte v; 2825 int j; 2826 2827 v = (png_byte)((*sp >> sshift) & 0x03); 2828 for (j = 0; j < jstop; j++) 2829 { 2830 *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); 2831 *dp |= (png_byte)(v << dshift); 2832 if (dshift == s_end) 2833 { 2834 dshift = s_start; 2835 dp--; 2836 } 2837 else 2838 dshift += s_inc; 2839 } 2840 if (sshift == s_end) 2841 { 2842 sshift = s_start; 2843 sp--; 2844 } 2845 else 2846 sshift += s_inc; 2847 } 2848 break; 2849 } 2850 case 4: 2851 { 2852 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1); 2853 png_bytep dp = row + (png_size_t)((final_width - 1) >> 1); 2854 int sshift, dshift; 2855 int s_start, s_end, s_inc; 2856 png_uint_32 i; 2857 int jstop = png_pass_inc[pass]; 2858 2859#ifdef PNG_READ_PACKSWAP_SUPPORTED 2860 if (transformations & PNG_PACKSWAP) 2861 { 2862 sshift = (int)(((row_info->width + 1) & 0x01) << 2); 2863 dshift = (int)(((final_width + 1) & 0x01) << 2); 2864 s_start = 4; 2865 s_end = 0; 2866 s_inc = -4; 2867 } 2868 else 2869#endif 2870 { 2871 sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2); 2872 dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2); 2873 s_start = 0; 2874 s_end = 4; 2875 s_inc = 4; 2876 } 2877 2878 for (i = 0; i < row_info->width; i++) 2879 { 2880 png_byte v = (png_byte)((*sp >> sshift) & 0xf); 2881 int j; 2882 2883 for (j = 0; j < jstop; j++) 2884 { 2885 *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); 2886 *dp |= (png_byte)(v << dshift); 2887 if (dshift == s_end) 2888 { 2889 dshift = s_start; 2890 dp--; 2891 } 2892 else 2893 dshift += s_inc; 2894 } 2895 if (sshift == s_end) 2896 { 2897 sshift = s_start; 2898 sp--; 2899 } 2900 else 2901 sshift += s_inc; 2902 } 2903 break; 2904 } 2905 default: 2906 { 2907 png_size_t pixel_bytes = (row_info->pixel_depth >> 3); 2908 png_bytep sp = row + (png_size_t)(row_info->width - 1) 2909 * pixel_bytes; 2910 png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes; 2911 2912 int jstop = png_pass_inc[pass]; 2913 png_uint_32 i; 2914 2915 for (i = 0; i < row_info->width; i++) 2916 { 2917 png_byte v[8]; 2918 int j; 2919 2920 png_memcpy(v, sp, pixel_bytes); 2921 for (j = 0; j < jstop; j++) 2922 { 2923 png_memcpy(dp, v, pixel_bytes); 2924 dp -= pixel_bytes; 2925 } 2926 sp -= pixel_bytes; 2927 } 2928 break; 2929 } 2930 } 2931 row_info->width = final_width; 2932 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); 2933 } 2934#ifndef PNG_READ_PACKSWAP_SUPPORTED 2935 transformations = transformations; /* Silence compiler warning */ 2936#endif 2937} 2938#endif /* PNG_READ_INTERLACING_SUPPORTED */ 2939 2940void /* PRIVATE */ 2941png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, 2942 png_bytep prev_row, int filter) 2943{ 2944 png_debug(1, "in png_read_filter_row"); 2945 png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter); 2946 switch (filter) 2947 { 2948 case PNG_FILTER_VALUE_NONE: 2949 break; 2950 case PNG_FILTER_VALUE_SUB: 2951 { 2952 png_uint_32 i; 2953 png_uint_32 istop = row_info->rowbytes; 2954 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 2955 png_bytep rp = row + bpp; 2956 png_bytep lp = row; 2957 2958 for (i = bpp; i < istop; i++) 2959 { 2960 *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); 2961 rp++; 2962 } 2963 break; 2964 } 2965 case PNG_FILTER_VALUE_UP: 2966 { 2967 png_uint_32 i; 2968 png_uint_32 istop = row_info->rowbytes; 2969 png_bytep rp = row; 2970 png_bytep pp = prev_row; 2971 2972 for (i = 0; i < istop; i++) 2973 { 2974 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); 2975 rp++; 2976 } 2977 break; 2978 } 2979 case PNG_FILTER_VALUE_AVG: 2980 { 2981 png_uint_32 i; 2982 png_bytep rp = row; 2983 png_bytep pp = prev_row; 2984 png_bytep lp = row; 2985 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 2986 png_uint_32 istop = row_info->rowbytes - bpp; 2987 2988 for (i = 0; i < bpp; i++) 2989 { 2990 *rp = (png_byte)(((int)(*rp) + 2991 ((int)(*pp++) / 2 )) & 0xff); 2992 rp++; 2993 } 2994 2995 for (i = 0; i < istop; i++) 2996 { 2997 *rp = (png_byte)(((int)(*rp) + 2998 (int)(*pp++ + *lp++) / 2 ) & 0xff); 2999 rp++; 3000 } 3001 break; 3002 } 3003 case PNG_FILTER_VALUE_PAETH: 3004 { 3005 png_uint_32 i; 3006 png_bytep rp = row; 3007 png_bytep pp = prev_row; 3008 png_bytep lp = row; 3009 png_bytep cp = prev_row; 3010 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 3011 png_uint_32 istop=row_info->rowbytes - bpp; 3012 3013 for (i = 0; i < bpp; i++) 3014 { 3015 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); 3016 rp++; 3017 } 3018 3019 for (i = 0; i < istop; i++) /* Use leftover rp,pp */ 3020 { 3021 int a, b, c, pa, pb, pc, p; 3022 3023 a = *lp++; 3024 b = *pp++; 3025 c = *cp++; 3026 3027 p = b - c; 3028 pc = a - c; 3029 3030#ifdef PNG_USE_ABS 3031 pa = abs(p); 3032 pb = abs(pc); 3033 pc = abs(p + pc); 3034#else 3035 pa = p < 0 ? -p : p; 3036 pb = pc < 0 ? -pc : pc; 3037 pc = (p + pc) < 0 ? -(p + pc) : p + pc; 3038#endif 3039 3040 /* 3041 if (pa <= pb && pa <= pc) 3042 p = a; 3043 else if (pb <= pc) 3044 p = b; 3045 else 3046 p = c; 3047 */ 3048 3049 p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c; 3050 3051 *rp = (png_byte)(((int)(*rp) + p) & 0xff); 3052 rp++; 3053 } 3054 break; 3055 } 3056 default: 3057 png_warning(png_ptr, "Ignoring bad adaptive filter type"); 3058 *row = 0; 3059 break; 3060 } 3061} 3062 3063#ifdef PNG_SEQUENTIAL_READ_SUPPORTED 3064void /* PRIVATE */ 3065png_read_finish_row(png_structp png_ptr) 3066{ 3067#ifdef PNG_READ_INTERLACING_SUPPORTED 3068 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 3069 3070 /* Start of interlace block */ 3071 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 3072 3073 /* Offset to next interlace block */ 3074 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 3075 3076 /* Start of interlace block in the y direction */ 3077 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 3078 3079 /* Offset to next interlace block in the y direction */ 3080 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 3081#endif /* PNG_READ_INTERLACING_SUPPORTED */ 3082 3083 png_debug(1, "in png_read_finish_row"); 3084 png_ptr->row_number++; 3085 if (png_ptr->row_number < png_ptr->num_rows) 3086 return; 3087 3088#ifdef PNG_READ_INTERLACING_SUPPORTED 3089 if (png_ptr->interlaced) 3090 { 3091 png_ptr->row_number = 0; 3092 png_memset_check(png_ptr, png_ptr->prev_row, 0, 3093 png_ptr->rowbytes + 1); 3094 do 3095 { 3096 png_ptr->pass++; 3097 if (png_ptr->pass >= 7) 3098 break; 3099 png_ptr->iwidth = (png_ptr->width + 3100 png_pass_inc[png_ptr->pass] - 1 - 3101 png_pass_start[png_ptr->pass]) / 3102 png_pass_inc[png_ptr->pass]; 3103 3104 if (!(png_ptr->transformations & PNG_INTERLACE)) 3105 { 3106 png_ptr->num_rows = (png_ptr->height + 3107 png_pass_yinc[png_ptr->pass] - 1 - 3108 png_pass_ystart[png_ptr->pass]) / 3109 png_pass_yinc[png_ptr->pass]; 3110 if (!(png_ptr->num_rows)) 3111 continue; 3112 } 3113 else /* if (png_ptr->transformations & PNG_INTERLACE) */ 3114 break; 3115 } while (png_ptr->iwidth == 0); 3116 3117 if (png_ptr->pass < 7) 3118 return; 3119 } 3120#endif /* PNG_READ_INTERLACING_SUPPORTED */ 3121 3122 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) 3123 { 3124#ifdef PNG_USE_LOCAL_ARRAYS 3125 PNG_CONST PNG_IDAT; 3126#endif 3127 char extra; 3128 int ret; 3129 3130 png_ptr->zstream.next_out = (Byte *)&extra; 3131 png_ptr->zstream.avail_out = (uInt)1; 3132 for (;;) 3133 { 3134 if (!(png_ptr->zstream.avail_in)) 3135 { 3136 while (!png_ptr->idat_size) 3137 { 3138 png_byte chunk_length[4]; 3139 3140 png_crc_finish(png_ptr, 0); 3141 3142 png_read_data(png_ptr, chunk_length, 4); 3143 png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length); 3144 png_reset_crc(png_ptr); 3145 png_crc_read(png_ptr, png_ptr->chunk_name, 4); 3146 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 3147 png_error(png_ptr, "Not enough image data"); 3148 3149 } 3150 png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; 3151 png_ptr->zstream.next_in = png_ptr->zbuf; 3152 if (png_ptr->zbuf_size > png_ptr->idat_size) 3153 png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; 3154 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in); 3155 png_ptr->idat_size -= png_ptr->zstream.avail_in; 3156 } 3157 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); 3158 if (ret == Z_STREAM_END) 3159 { 3160 if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in || 3161 png_ptr->idat_size) 3162 png_warning(png_ptr, "Extra compressed data."); 3163 png_ptr->mode |= PNG_AFTER_IDAT; 3164 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 3165 break; 3166 } 3167 if (ret != Z_OK) 3168 png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : 3169 "Decompression Error"); 3170 3171 if (!(png_ptr->zstream.avail_out)) 3172 { 3173 png_warning(png_ptr, "Extra compressed data."); 3174 png_ptr->mode |= PNG_AFTER_IDAT; 3175 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 3176 break; 3177 } 3178 3179 } 3180 png_ptr->zstream.avail_out = 0; 3181 } 3182 3183 if (png_ptr->idat_size || png_ptr->zstream.avail_in) 3184 png_warning(png_ptr, "Extra compression data."); 3185 3186 inflateReset(&png_ptr->zstream); 3187 3188 png_ptr->mode |= PNG_AFTER_IDAT; 3189} 3190#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 3191 3192void /* PRIVATE */ 3193png_read_start_row(png_structp png_ptr) 3194{ 3195#ifdef PNG_READ_INTERLACING_SUPPORTED 3196 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 3197 3198 /* Start of interlace block */ 3199 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 3200 3201 /* Offset to next interlace block */ 3202 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 3203 3204 /* Start of interlace block in the y direction */ 3205 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 3206 3207 /* Offset to next interlace block in the y direction */ 3208 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 3209#endif 3210 3211 int max_pixel_depth; 3212 png_size_t row_bytes; 3213 3214 png_debug(1, "in png_read_start_row"); 3215 png_ptr->zstream.avail_in = 0; 3216 png_init_read_transformations(png_ptr); 3217#ifdef PNG_READ_INTERLACING_SUPPORTED 3218 if (png_ptr->interlaced) 3219 { 3220 if (!(png_ptr->transformations & PNG_INTERLACE)) 3221 png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - 3222 png_pass_ystart[0]) / png_pass_yinc[0]; 3223 else 3224 png_ptr->num_rows = png_ptr->height; 3225 3226 png_ptr->iwidth = (png_ptr->width + 3227 png_pass_inc[png_ptr->pass] - 1 - 3228 png_pass_start[png_ptr->pass]) / 3229 png_pass_inc[png_ptr->pass]; 3230 } 3231 else 3232#endif /* PNG_READ_INTERLACING_SUPPORTED */ 3233 { 3234 png_ptr->num_rows = png_ptr->height; 3235 png_ptr->iwidth = png_ptr->width; 3236 } 3237 max_pixel_depth = png_ptr->pixel_depth; 3238 3239#ifdef PNG_READ_PACK_SUPPORTED 3240 if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) 3241 max_pixel_depth = 8; 3242#endif 3243 3244#ifdef PNG_READ_EXPAND_SUPPORTED 3245 if (png_ptr->transformations & PNG_EXPAND) 3246 { 3247 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 3248 { 3249 if (png_ptr->num_trans) 3250 max_pixel_depth = 32; 3251 else 3252 max_pixel_depth = 24; 3253 } 3254 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 3255 { 3256 if (max_pixel_depth < 8) 3257 max_pixel_depth = 8; 3258 if (png_ptr->num_trans) 3259 max_pixel_depth *= 2; 3260 } 3261 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 3262 { 3263 if (png_ptr->num_trans) 3264 { 3265 max_pixel_depth *= 4; 3266 max_pixel_depth /= 3; 3267 } 3268 } 3269 } 3270#endif 3271 3272#ifdef PNG_READ_FILLER_SUPPORTED 3273 if (png_ptr->transformations & (PNG_FILLER)) 3274 { 3275 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 3276 max_pixel_depth = 32; 3277 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 3278 { 3279 if (max_pixel_depth <= 8) 3280 max_pixel_depth = 16; 3281 else 3282 max_pixel_depth = 32; 3283 } 3284 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 3285 { 3286 if (max_pixel_depth <= 32) 3287 max_pixel_depth = 32; 3288 else 3289 max_pixel_depth = 64; 3290 } 3291 } 3292#endif 3293 3294#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 3295 if (png_ptr->transformations & PNG_GRAY_TO_RGB) 3296 { 3297 if ( 3298#ifdef PNG_READ_EXPAND_SUPPORTED 3299 (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || 3300#endif 3301#ifdef PNG_READ_FILLER_SUPPORTED 3302 (png_ptr->transformations & (PNG_FILLER)) || 3303#endif 3304 png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 3305 { 3306 if (max_pixel_depth <= 16) 3307 max_pixel_depth = 32; 3308 else 3309 max_pixel_depth = 64; 3310 } 3311 else 3312 { 3313 if (max_pixel_depth <= 8) 3314 { 3315 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 3316 max_pixel_depth = 32; 3317 else 3318 max_pixel_depth = 24; 3319 } 3320 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 3321 max_pixel_depth = 64; 3322 else 3323 max_pixel_depth = 48; 3324 } 3325 } 3326#endif 3327 3328#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ 3329defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) 3330 if (png_ptr->transformations & PNG_USER_TRANSFORM) 3331 { 3332 int user_pixel_depth = png_ptr->user_transform_depth* 3333 png_ptr->user_transform_channels; 3334 if (user_pixel_depth > max_pixel_depth) 3335 max_pixel_depth=user_pixel_depth; 3336 } 3337#endif 3338 3339 /* Align the width on the next larger 8 pixels. Mainly used 3340 * for interlacing 3341 */ 3342 row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); 3343 /* Calculate the maximum bytes needed, adding a byte and a pixel 3344 * for safety's sake 3345 */ 3346 row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) + 3347 1 + ((max_pixel_depth + 7) >> 3); 3348#ifdef PNG_MAX_MALLOC_64K 3349 if (row_bytes > (png_uint_32)65536L) 3350 png_error(png_ptr, "This image requires a row greater than 64KB"); 3351#endif 3352 3353 if (row_bytes + 64 > png_ptr->old_big_row_buf_size) 3354 { 3355 png_free(png_ptr, png_ptr->big_row_buf); 3356 if (png_ptr->interlaced) 3357 png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, 3358 row_bytes + 64); 3359 else 3360 png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, 3361 row_bytes + 64); 3362 png_ptr->old_big_row_buf_size = row_bytes + 64; 3363 3364 /* Use 32 bytes of padding before and after row_buf. */ 3365 png_ptr->row_buf = png_ptr->big_row_buf + 32; 3366 png_ptr->old_big_row_buf_size = row_bytes + 64; 3367 } 3368 3369#ifdef PNG_MAX_MALLOC_64K 3370 if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L) 3371 png_error(png_ptr, "This image requires a row greater than 64KB"); 3372#endif 3373 if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1)) 3374 png_error(png_ptr, "Row has too many bytes to allocate in memory."); 3375 3376 if (row_bytes + 1 > png_ptr->old_prev_row_size) 3377 { 3378 png_free(png_ptr, png_ptr->prev_row); 3379 png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)( 3380 row_bytes + 1)); 3381 png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1); 3382 png_ptr->old_prev_row_size = row_bytes + 1; 3383 } 3384 3385 png_ptr->rowbytes = row_bytes; 3386 3387 png_debug1(3, "width = %lu,", png_ptr->width); 3388 png_debug1(3, "height = %lu,", png_ptr->height); 3389 png_debug1(3, "iwidth = %lu,", png_ptr->iwidth); 3390 png_debug1(3, "num_rows = %lu,", png_ptr->num_rows); 3391 png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes); 3392 png_debug1(3, "irowbytes = %lu", 3393 PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); 3394 3395 png_ptr->flags |= PNG_FLAG_ROW_INIT; 3396} 3397#endif /* PNG_READ_SUPPORTED */ 3398