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