1 2 /* pngrutil.c - utilities to read a PNG file 3 * 4 * Last changed in libpng 1.2.19 August 18, 2007 5 * For conditions of distribution and use, see copyright notice in png.h 6 * Copyright (c) 1998-2007 Glenn Randers-Pehrson 7 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 9 * 10 * This file contains routines that are only called from within 11 * libpng itself during the course of reading an image. 12 */ 13 14 #define PNG_INTERNAL 15 #include "png.h" 16 17 #if defined(PNG_READ_SUPPORTED) 18 19 #if defined(_WIN32_WCE) && (_WIN32_WCE<0x500) 20 # define WIN32_WCE_OLD 21 #endif 22 23 #ifdef PNG_FLOATING_POINT_SUPPORTED 24 # if defined(WIN32_WCE_OLD) 25 /* strtod() function is not supported on WindowsCE */ 26 __inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr, char **endptr) 27 { 28 double result = 0; 29 int len; 30 wchar_t *str, *end; 31 32 len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0); 33 str = (wchar_t *)png_malloc(png_ptr, len * sizeof(wchar_t)); 34 if ( NULL != str ) 35 { 36 MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len); 37 result = wcstod(str, &end); 38 len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL); 39 *endptr = (char *)nptr + (png_strlen(nptr) - len + 1); 40 png_free(png_ptr, str); 41 } 42 return result; 43 } 44 # else 45 # define png_strtod(p,a,b) strtod(a,b) 46 # endif 47 #endif 48 49 png_uint_32 PNGAPI 50 png_get_uint_31(png_structp png_ptr, png_bytep buf) 51 { 52 png_uint_32 i = png_get_uint_32(buf); 53 if (i > PNG_UINT_31_MAX) 54 png_error(png_ptr, "PNG unsigned integer out of range."); 55 return (i); 56 } 57 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED 58 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ 59 png_uint_32 PNGAPI 60 png_get_uint_32(png_bytep buf) 61 { 62 png_uint_32 i = ((png_uint_32)(*buf) << 24) + 63 ((png_uint_32)(*(buf + 1)) << 16) + 64 ((png_uint_32)(*(buf + 2)) << 8) + 65 (png_uint_32)(*(buf + 3)); 66 67 return (i); 68 } 69 70 /* Grab a signed 32-bit integer from a buffer in big-endian format. The 71 * data is stored in the PNG file in two's complement format, and it is 72 * assumed that the machine format for signed integers is the same. */ 73 png_int_32 PNGAPI 74 png_get_int_32(png_bytep buf) 75 { 76 png_int_32 i = ((png_int_32)(*buf) << 24) + 77 ((png_int_32)(*(buf + 1)) << 16) + 78 ((png_int_32)(*(buf + 2)) << 8) + 79 (png_int_32)(*(buf + 3)); 80 81 return (i); 82 } 83 84 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ 85 png_uint_16 PNGAPI 86 png_get_uint_16(png_bytep buf) 87 { 88 png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) + 89 (png_uint_16)(*(buf + 1))); 90 91 return (i); 92 } 93 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */ 94 95 /* Read data, and (optionally) run it through the CRC. */ 96 void /* PRIVATE */ 97 png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length) 98 { 99 if(png_ptr == NULL) return; 100 png_read_data(png_ptr, buf, length); 101 png_calculate_crc(png_ptr, buf, length); 102 } 103 104 /* Optionally skip data and then check the CRC. Depending on whether we 105 are reading a ancillary or critical chunk, and how the program has set 106 things up, we may calculate the CRC on the data and print a message. 107 Returns '1' if there was a CRC error, '0' otherwise. */ 108 int /* PRIVATE */ 109 png_crc_finish(png_structp png_ptr, png_uint_32 skip) 110 { 111 png_size_t i; 112 png_size_t istop = png_ptr->zbuf_size; 113 114 for (i = (png_size_t)skip; i > istop; i -= istop) 115 { 116 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); 117 } 118 if (i) 119 { 120 png_crc_read(png_ptr, png_ptr->zbuf, i); 121 } 122 123 if (png_crc_error(png_ptr)) 124 { 125 if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */ 126 !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) || 127 (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */ 128 (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))) 129 { 130 png_chunk_warning(png_ptr, "CRC error"); 131 } 132 else 133 { 134 png_chunk_error(png_ptr, "CRC error"); 135 } 136 return (1); 137 } 138 139 return (0); 140 } 141 142 /* Compare the CRC stored in the PNG file with that calculated by libpng from 143 the data it has read thus far. */ 144 int /* PRIVATE */ 145 png_crc_error(png_structp png_ptr) 146 { 147 png_byte crc_bytes[4]; 148 png_uint_32 crc; 149 int need_crc = 1; 150 151 if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ 152 { 153 if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == 154 (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) 155 need_crc = 0; 156 } 157 else /* critical */ 158 { 159 if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) 160 need_crc = 0; 161 } 162 163 png_read_data(png_ptr, crc_bytes, 4); 164 165 if (need_crc) 166 { 167 crc = png_get_uint_32(crc_bytes); 168 return ((int)(crc != png_ptr->crc)); 169 } 170 else 171 return (0); 172 } 173 174 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \ 175 defined(PNG_READ_iCCP_SUPPORTED) 176 /* 177 * Decompress trailing data in a chunk. The assumption is that chunkdata 178 * points at an allocated area holding the contents of a chunk with a 179 * trailing compressed part. What we get back is an allocated area 180 * holding the original prefix part and an uncompressed version of the 181 * trailing part (the malloc area passed in is freed). 182 */ 183 png_charp /* PRIVATE */ 184 png_decompress_chunk(png_structp png_ptr, int comp_type, 185 png_charp chunkdata, png_size_t chunklength, 186 png_size_t prefix_size, png_size_t *newlength) 187 { 188 static PNG_CONST char msg[] = "Error decoding compressed text"; 189 png_charp text; 190 png_size_t text_size; 191 192 if (comp_type == PNG_COMPRESSION_TYPE_BASE) 193 { 194 int ret = Z_OK; 195 png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size); 196 png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size); 197 png_ptr->zstream.next_out = png_ptr->zbuf; 198 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 199 200 text_size = 0; 201 text = NULL; 202 203 while (png_ptr->zstream.avail_in) 204 { 205 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); 206 if (ret != Z_OK && ret != Z_STREAM_END) 207 { 208 if (png_ptr->zstream.msg != NULL) 209 png_warning(png_ptr, png_ptr->zstream.msg); 210 else 211 png_warning(png_ptr, msg); 212 inflateReset(&png_ptr->zstream); 213 png_ptr->zstream.avail_in = 0; 214 215 if (text == NULL) 216 { 217 text_size = prefix_size + png_sizeof(msg) + 1; 218 text = (png_charp)png_malloc_warn(png_ptr, text_size); 219 if (text == NULL) 220 { 221 png_free(png_ptr,chunkdata); 222 png_error(png_ptr,"Not enough memory to decompress chunk"); 223 } 224 png_memcpy(text, chunkdata, prefix_size); 225 } 226 227 text[text_size - 1] = 0x00; 228 229 /* Copy what we can of the error message into the text chunk */ 230 text_size = (png_size_t)(chunklength - (text - chunkdata) - 1); 231 text_size = png_sizeof(msg) > text_size ? text_size : 232 png_sizeof(msg); 233 png_memcpy(text + prefix_size, msg, text_size + 1); 234 break; 235 } 236 if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END) 237 { 238 if (text == NULL) 239 { 240 text_size = prefix_size + 241 png_ptr->zbuf_size - png_ptr->zstream.avail_out; 242 text = (png_charp)png_malloc_warn(png_ptr, text_size + 1); 243 if (text == NULL) 244 { 245 png_free(png_ptr,chunkdata); 246 png_error(png_ptr,"Not enough memory to decompress chunk."); 247 } 248 png_memcpy(text + prefix_size, png_ptr->zbuf, 249 text_size - prefix_size); 250 png_memcpy(text, chunkdata, prefix_size); 251 *(text + text_size) = 0x00; 252 } 253 else 254 { 255 png_charp tmp; 256 257 tmp = text; 258 text = (png_charp)png_malloc_warn(png_ptr, 259 (png_uint_32)(text_size + 260 png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1)); 261 if (text == NULL) 262 { 263 png_free(png_ptr, tmp); 264 png_free(png_ptr, chunkdata); 265 png_error(png_ptr,"Not enough memory to decompress chunk.."); 266 } 267 png_memcpy(text, tmp, text_size); 268 png_free(png_ptr, tmp); 269 png_memcpy(text + text_size, png_ptr->zbuf, 270 (png_ptr->zbuf_size - png_ptr->zstream.avail_out)); 271 text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; 272 *(text + text_size) = 0x00; 273 } 274 if (ret == Z_STREAM_END) 275 break; 276 else 277 { 278 png_ptr->zstream.next_out = png_ptr->zbuf; 279 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 280 } 281 } 282 } 283 if (ret != Z_STREAM_END) 284 { 285 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) 286 char umsg[52]; 287 288 if (ret == Z_BUF_ERROR) 289 png_snprintf(umsg, 52, 290 "Buffer error in compressed datastream in %s chunk", 291 png_ptr->chunk_name); 292 else if (ret == Z_DATA_ERROR) 293 png_snprintf(umsg, 52, 294 "Data error in compressed datastream in %s chunk", 295 png_ptr->chunk_name); 296 else 297 png_snprintf(umsg, 52, 298 "Incomplete compressed datastream in %s chunk", 299 png_ptr->chunk_name); 300 png_warning(png_ptr, umsg); 301 #else 302 png_warning(png_ptr, 303 "Incomplete compressed datastream in chunk other than IDAT"); 304 #endif 305 text_size=prefix_size; 306 if (text == NULL) 307 { 308 text = (png_charp)png_malloc_warn(png_ptr, text_size+1); 309 if (text == NULL) 310 { 311 png_free(png_ptr, chunkdata); 312 png_error(png_ptr,"Not enough memory for text."); 313 } 314 png_memcpy(text, chunkdata, prefix_size); 315 } 316 *(text + text_size) = 0x00; 317 } 318 319 inflateReset(&png_ptr->zstream); 320 png_ptr->zstream.avail_in = 0; 321 322 png_free(png_ptr, chunkdata); 323 chunkdata = text; 324 *newlength=text_size; 325 } 326 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */ 327 { 328 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) 329 char umsg[50]; 330 331 png_snprintf(umsg, 50, 332 "Unknown zTXt compression type %d", comp_type); 333 png_warning(png_ptr, umsg); 334 #else 335 png_warning(png_ptr, "Unknown zTXt compression type"); 336 #endif 337 338 *(chunkdata + prefix_size) = 0x00; 339 *newlength=prefix_size; 340 } 341 342 return chunkdata; 343 } 344 #endif 345 346 /* read and check the IDHR chunk */ 347 void /* PRIVATE */ 348 png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 349 { 350 png_byte buf[13]; 351 png_uint_32 width, height; 352 int bit_depth, color_type, compression_type, filter_type; 353 int interlace_type; 354 355 png_debug(1, "in png_handle_IHDR\n"); 356 357 if (png_ptr->mode & PNG_HAVE_IHDR) 358 png_error(png_ptr, "Out of place IHDR"); 359 360 /* check the length */ 361 if (length != 13) 362 png_error(png_ptr, "Invalid IHDR chunk"); 363 364 png_ptr->mode |= PNG_HAVE_IHDR; 365 366 png_crc_read(png_ptr, buf, 13); 367 png_crc_finish(png_ptr, 0); 368 369 width = png_get_uint_31(png_ptr, buf); 370 height = png_get_uint_31(png_ptr, buf + 4); 371 bit_depth = buf[8]; 372 color_type = buf[9]; 373 compression_type = buf[10]; 374 filter_type = buf[11]; 375 interlace_type = buf[12]; 376 377 /* set internal variables */ 378 png_ptr->width = width; 379 png_ptr->height = height; 380 png_ptr->bit_depth = (png_byte)bit_depth; 381 png_ptr->interlaced = (png_byte)interlace_type; 382 png_ptr->color_type = (png_byte)color_type; 383 #if defined(PNG_MNG_FEATURES_SUPPORTED) 384 png_ptr->filter_type = (png_byte)filter_type; 385 #endif 386 png_ptr->compression_type = (png_byte)compression_type; 387 388 /* find number of channels */ 389 switch (png_ptr->color_type) 390 { 391 case PNG_COLOR_TYPE_GRAY: 392 case PNG_COLOR_TYPE_PALETTE: 393 png_ptr->channels = 1; 394 break; 395 case PNG_COLOR_TYPE_RGB: 396 png_ptr->channels = 3; 397 break; 398 case PNG_COLOR_TYPE_GRAY_ALPHA: 399 png_ptr->channels = 2; 400 break; 401 case PNG_COLOR_TYPE_RGB_ALPHA: 402 png_ptr->channels = 4; 403 break; 404 } 405 406 /* set up other useful info */ 407 png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * 408 png_ptr->channels); 409 png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width); 410 png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth); 411 png_debug1(3,"channels = %d\n", png_ptr->channels); 412 png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes); 413 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, 414 color_type, interlace_type, compression_type, filter_type); 415 } 416 417 /* read and check the palette */ 418 void /* PRIVATE */ 419 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 420 { 421 png_color palette[PNG_MAX_PALETTE_LENGTH]; 422 int num, i; 423 #ifndef PNG_NO_POINTER_INDEXING 424 png_colorp pal_ptr; 425 #endif 426 427 png_debug(1, "in png_handle_PLTE\n"); 428 429 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 430 png_error(png_ptr, "Missing IHDR before PLTE"); 431 else if (png_ptr->mode & PNG_HAVE_IDAT) 432 { 433 png_warning(png_ptr, "Invalid PLTE after IDAT"); 434 png_crc_finish(png_ptr, length); 435 return; 436 } 437 else if (png_ptr->mode & PNG_HAVE_PLTE) 438 png_error(png_ptr, "Duplicate PLTE chunk"); 439 440 png_ptr->mode |= PNG_HAVE_PLTE; 441 442 if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) 443 { 444 png_warning(png_ptr, 445 "Ignoring PLTE chunk in grayscale PNG"); 446 png_crc_finish(png_ptr, length); 447 return; 448 } 449 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED) 450 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) 451 { 452 png_crc_finish(png_ptr, length); 453 return; 454 } 455 #endif 456 457 if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) 458 { 459 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) 460 { 461 png_warning(png_ptr, "Invalid palette chunk"); 462 png_crc_finish(png_ptr, length); 463 return; 464 } 465 else 466 { 467 png_error(png_ptr, "Invalid palette chunk"); 468 } 469 } 470 471 num = (int)length / 3; 472 473 #ifndef PNG_NO_POINTER_INDEXING 474 for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) 475 { 476 png_byte buf[3]; 477 478 png_crc_read(png_ptr, buf, 3); 479 pal_ptr->red = buf[0]; 480 pal_ptr->green = buf[1]; 481 pal_ptr->blue = buf[2]; 482 } 483 #else 484 for (i = 0; i < num; i++) 485 { 486 png_byte buf[3]; 487 488 png_crc_read(png_ptr, buf, 3); 489 /* don't depend upon png_color being any order */ 490 palette[i].red = buf[0]; 491 palette[i].green = buf[1]; 492 palette[i].blue = buf[2]; 493 } 494 #endif 495 496 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do 497 whatever the normal CRC configuration tells us. However, if we 498 have an RGB image, the PLTE can be considered ancillary, so 499 we will act as though it is. */ 500 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED) 501 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 502 #endif 503 { 504 png_crc_finish(png_ptr, 0); 505 } 506 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED) 507 else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ 508 { 509 /* If we don't want to use the data from an ancillary chunk, 510 we have two options: an error abort, or a warning and we 511 ignore the data in this chunk (which should be OK, since 512 it's considered ancillary for a RGB or RGBA image). */ 513 if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) 514 { 515 if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) 516 { 517 png_chunk_error(png_ptr, "CRC error"); 518 } 519 else 520 { 521 png_chunk_warning(png_ptr, "CRC error"); 522 return; 523 } 524 } 525 /* Otherwise, we (optionally) emit a warning and use the chunk. */ 526 else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) 527 { 528 png_chunk_warning(png_ptr, "CRC error"); 529 } 530 } 531 #endif 532 533 png_set_PLTE(png_ptr, info_ptr, palette, num); 534 535 #if defined(PNG_READ_tRNS_SUPPORTED) 536 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 537 { 538 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) 539 { 540 if (png_ptr->num_trans > (png_uint_16)num) 541 { 542 png_warning(png_ptr, "Truncating incorrect tRNS chunk length"); 543 png_ptr->num_trans = (png_uint_16)num; 544 } 545 if (info_ptr->num_trans > (png_uint_16)num) 546 { 547 png_warning(png_ptr, "Truncating incorrect info tRNS chunk length"); 548 info_ptr->num_trans = (png_uint_16)num; 549 } 550 } 551 } 552 #endif 553 554 } 555 556 void /* PRIVATE */ 557 png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 558 { 559 png_debug(1, "in png_handle_IEND\n"); 560 561 if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT)) 562 { 563 png_error(png_ptr, "No image in file"); 564 } 565 566 png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); 567 568 if (length != 0) 569 { 570 png_warning(png_ptr, "Incorrect IEND chunk length"); 571 } 572 png_crc_finish(png_ptr, length); 573 574 info_ptr =info_ptr; /* quiet compiler warnings about unused info_ptr */ 575 } 576 577 #if defined(PNG_READ_gAMA_SUPPORTED) 578 void /* PRIVATE */ 579 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 580 { 581 png_fixed_point igamma; 582 #ifdef PNG_FLOATING_POINT_SUPPORTED 583 float file_gamma; 584 #endif 585 png_byte buf[4]; 586 587 png_debug(1, "in png_handle_gAMA\n"); 588 589 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 590 png_error(png_ptr, "Missing IHDR before gAMA"); 591 else if (png_ptr->mode & PNG_HAVE_IDAT) 592 { 593 png_warning(png_ptr, "Invalid gAMA after IDAT"); 594 png_crc_finish(png_ptr, length); 595 return; 596 } 597 else if (png_ptr->mode & PNG_HAVE_PLTE) 598 /* Should be an error, but we can cope with it */ 599 png_warning(png_ptr, "Out of place gAMA chunk"); 600 601 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) 602 #if defined(PNG_READ_sRGB_SUPPORTED) 603 && !(info_ptr->valid & PNG_INFO_sRGB) 604 #endif 605 ) 606 { 607 png_warning(png_ptr, "Duplicate gAMA chunk"); 608 png_crc_finish(png_ptr, length); 609 return; 610 } 611 612 if (length != 4) 613 { 614 png_warning(png_ptr, "Incorrect gAMA chunk length"); 615 png_crc_finish(png_ptr, length); 616 return; 617 } 618 619 png_crc_read(png_ptr, buf, 4); 620 if (png_crc_finish(png_ptr, 0)) 621 return; 622 623 igamma = (png_fixed_point)png_get_uint_32(buf); 624 /* check for zero gamma */ 625 if (igamma == 0) 626 { 627 png_warning(png_ptr, 628 "Ignoring gAMA chunk with gamma=0"); 629 return; 630 } 631 632 #if defined(PNG_READ_sRGB_SUPPORTED) 633 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) 634 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) 635 { 636 png_warning(png_ptr, 637 "Ignoring incorrect gAMA value when sRGB is also present"); 638 #ifndef PNG_NO_CONSOLE_IO 639 fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma); 640 #endif 641 return; 642 } 643 #endif /* PNG_READ_sRGB_SUPPORTED */ 644 645 #ifdef PNG_FLOATING_POINT_SUPPORTED 646 file_gamma = (float)igamma / (float)100000.0; 647 # ifdef PNG_READ_GAMMA_SUPPORTED 648 png_ptr->gamma = file_gamma; 649 # endif 650 png_set_gAMA(png_ptr, info_ptr, file_gamma); 651 #endif 652 #ifdef PNG_FIXED_POINT_SUPPORTED 653 png_set_gAMA_fixed(png_ptr, info_ptr, igamma); 654 #endif 655 } 656 #endif 657 658 #if defined(PNG_READ_sBIT_SUPPORTED) 659 void /* PRIVATE */ 660 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 661 { 662 png_size_t truelen; 663 png_byte buf[4]; 664 665 png_debug(1, "in png_handle_sBIT\n"); 666 667 buf[0] = buf[1] = buf[2] = buf[3] = 0; 668 669 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 670 png_error(png_ptr, "Missing IHDR before sBIT"); 671 else if (png_ptr->mode & PNG_HAVE_IDAT) 672 { 673 png_warning(png_ptr, "Invalid sBIT after IDAT"); 674 png_crc_finish(png_ptr, length); 675 return; 676 } 677 else if (png_ptr->mode & PNG_HAVE_PLTE) 678 { 679 /* Should be an error, but we can cope with it */ 680 png_warning(png_ptr, "Out of place sBIT chunk"); 681 } 682 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) 683 { 684 png_warning(png_ptr, "Duplicate sBIT chunk"); 685 png_crc_finish(png_ptr, length); 686 return; 687 } 688 689 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 690 truelen = 3; 691 else 692 truelen = (png_size_t)png_ptr->channels; 693 694 if (length != truelen || length > 4) 695 { 696 png_warning(png_ptr, "Incorrect sBIT chunk length"); 697 png_crc_finish(png_ptr, length); 698 return; 699 } 700 701 png_crc_read(png_ptr, buf, truelen); 702 if (png_crc_finish(png_ptr, 0)) 703 return; 704 705 if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) 706 { 707 png_ptr->sig_bit.red = buf[0]; 708 png_ptr->sig_bit.green = buf[1]; 709 png_ptr->sig_bit.blue = buf[2]; 710 png_ptr->sig_bit.alpha = buf[3]; 711 } 712 else 713 { 714 png_ptr->sig_bit.gray = buf[0]; 715 png_ptr->sig_bit.red = buf[0]; 716 png_ptr->sig_bit.green = buf[0]; 717 png_ptr->sig_bit.blue = buf[0]; 718 png_ptr->sig_bit.alpha = buf[1]; 719 } 720 png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); 721 } 722 #endif 723 724 #if defined(PNG_READ_cHRM_SUPPORTED) 725 void /* PRIVATE */ 726 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 727 { 728 png_byte buf[4]; 729 #ifdef PNG_FLOATING_POINT_SUPPORTED 730 float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; 731 #endif 732 png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, 733 int_y_green, int_x_blue, int_y_blue; 734 735 png_uint_32 uint_x, uint_y; 736 737 png_debug(1, "in png_handle_cHRM\n"); 738 739 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 740 png_error(png_ptr, "Missing IHDR before cHRM"); 741 else if (png_ptr->mode & PNG_HAVE_IDAT) 742 { 743 png_warning(png_ptr, "Invalid cHRM after IDAT"); 744 png_crc_finish(png_ptr, length); 745 return; 746 } 747 else if (png_ptr->mode & PNG_HAVE_PLTE) 748 /* Should be an error, but we can cope with it */ 749 png_warning(png_ptr, "Missing PLTE before cHRM"); 750 751 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) 752 #if defined(PNG_READ_sRGB_SUPPORTED) 753 && !(info_ptr->valid & PNG_INFO_sRGB) 754 #endif 755 ) 756 { 757 png_warning(png_ptr, "Duplicate cHRM chunk"); 758 png_crc_finish(png_ptr, length); 759 return; 760 } 761 762 if (length != 32) 763 { 764 png_warning(png_ptr, "Incorrect cHRM chunk length"); 765 png_crc_finish(png_ptr, length); 766 return; 767 } 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 white point"); 779 png_crc_finish(png_ptr, 24); 780 return; 781 } 782 int_x_white = (png_fixed_point)uint_x; 783 int_y_white = (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 + uint_y > 100000L) 792 { 793 png_warning(png_ptr, "Invalid cHRM red point"); 794 png_crc_finish(png_ptr, 16); 795 return; 796 } 797 int_x_red = (png_fixed_point)uint_x; 798 int_y_red = (png_fixed_point)uint_y; 799 800 png_crc_read(png_ptr, buf, 4); 801 uint_x = png_get_uint_32(buf); 802 803 png_crc_read(png_ptr, buf, 4); 804 uint_y = png_get_uint_32(buf); 805 806 if (uint_x + uint_y > 100000L) 807 { 808 png_warning(png_ptr, "Invalid cHRM green point"); 809 png_crc_finish(png_ptr, 8); 810 return; 811 } 812 int_x_green = (png_fixed_point)uint_x; 813 int_y_green = (png_fixed_point)uint_y; 814 815 png_crc_read(png_ptr, buf, 4); 816 uint_x = png_get_uint_32(buf); 817 818 png_crc_read(png_ptr, buf, 4); 819 uint_y = png_get_uint_32(buf); 820 821 if (uint_x + uint_y > 100000L) 822 { 823 png_warning(png_ptr, "Invalid cHRM blue point"); 824 png_crc_finish(png_ptr, 0); 825 return; 826 } 827 int_x_blue = (png_fixed_point)uint_x; 828 int_y_blue = (png_fixed_point)uint_y; 829 830 #ifdef PNG_FLOATING_POINT_SUPPORTED 831 white_x = (float)int_x_white / (float)100000.0; 832 white_y = (float)int_y_white / (float)100000.0; 833 red_x = (float)int_x_red / (float)100000.0; 834 red_y = (float)int_y_red / (float)100000.0; 835 green_x = (float)int_x_green / (float)100000.0; 836 green_y = (float)int_y_green / (float)100000.0; 837 blue_x = (float)int_x_blue / (float)100000.0; 838 blue_y = (float)int_y_blue / (float)100000.0; 839 #endif 840 841 #if defined(PNG_READ_sRGB_SUPPORTED) 842 if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) 843 { 844 if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) || 845 PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) || 846 PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) || 847 PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) || 848 PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) || 849 PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) || 850 PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) || 851 PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000)) 852 { 853 png_warning(png_ptr, 854 "Ignoring incorrect cHRM value when sRGB is also present"); 855 #ifndef PNG_NO_CONSOLE_IO 856 #ifdef PNG_FLOATING_POINT_SUPPORTED 857 fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n", 858 white_x, white_y, red_x, red_y); 859 fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n", 860 green_x, green_y, blue_x, blue_y); 861 #else 862 fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n", 863 int_x_white, int_y_white, int_x_red, int_y_red); 864 fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n", 865 int_x_green, int_y_green, int_x_blue, int_y_blue); 866 #endif 867 #endif /* PNG_NO_CONSOLE_IO */ 868 } 869 png_crc_finish(png_ptr, 0); 870 return; 871 } 872 #endif /* PNG_READ_sRGB_SUPPORTED */ 873 874 #ifdef PNG_FLOATING_POINT_SUPPORTED 875 png_set_cHRM(png_ptr, info_ptr, 876 white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); 877 #endif 878 #ifdef PNG_FIXED_POINT_SUPPORTED 879 png_set_cHRM_fixed(png_ptr, info_ptr, 880 int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, 881 int_y_green, int_x_blue, int_y_blue); 882 #endif 883 if (png_crc_finish(png_ptr, 0)) 884 return; 885 } 886 #endif 887 888 #if defined(PNG_READ_sRGB_SUPPORTED) 889 void /* PRIVATE */ 890 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 891 { 892 int intent; 893 png_byte buf[1]; 894 895 png_debug(1, "in png_handle_sRGB\n"); 896 897 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 898 png_error(png_ptr, "Missing IHDR before sRGB"); 899 else if (png_ptr->mode & PNG_HAVE_IDAT) 900 { 901 png_warning(png_ptr, "Invalid sRGB after IDAT"); 902 png_crc_finish(png_ptr, length); 903 return; 904 } 905 else if (png_ptr->mode & PNG_HAVE_PLTE) 906 /* Should be an error, but we can cope with it */ 907 png_warning(png_ptr, "Out of place sRGB chunk"); 908 909 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) 910 { 911 png_warning(png_ptr, "Duplicate sRGB chunk"); 912 png_crc_finish(png_ptr, length); 913 return; 914 } 915 916 if (length != 1) 917 { 918 png_warning(png_ptr, "Incorrect sRGB chunk length"); 919 png_crc_finish(png_ptr, length); 920 return; 921 } 922 923 png_crc_read(png_ptr, buf, 1); 924 if (png_crc_finish(png_ptr, 0)) 925 return; 926 927 intent = buf[0]; 928 /* check for bad intent */ 929 if (intent >= PNG_sRGB_INTENT_LAST) 930 { 931 png_warning(png_ptr, "Unknown sRGB intent"); 932 return; 933 } 934 935 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) 936 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)) 937 { 938 png_fixed_point igamma; 939 #ifdef PNG_FIXED_POINT_SUPPORTED 940 igamma=info_ptr->int_gamma; 941 #else 942 # ifdef PNG_FLOATING_POINT_SUPPORTED 943 igamma=(png_fixed_point)(info_ptr->gamma * 100000.); 944 # endif 945 #endif 946 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) 947 { 948 png_warning(png_ptr, 949 "Ignoring incorrect gAMA value when sRGB is also present"); 950 #ifndef PNG_NO_CONSOLE_IO 951 # ifdef PNG_FIXED_POINT_SUPPORTED 952 fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma); 953 # else 954 # ifdef PNG_FLOATING_POINT_SUPPORTED 955 fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma); 956 # endif 957 # endif 958 #endif 959 } 960 } 961 #endif /* PNG_READ_gAMA_SUPPORTED */ 962 963 #ifdef PNG_READ_cHRM_SUPPORTED 964 #ifdef PNG_FIXED_POINT_SUPPORTED 965 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) 966 if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) || 967 PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) || 968 PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) || 969 PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) || 970 PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) || 971 PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) || 972 PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) || 973 PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000)) 974 { 975 png_warning(png_ptr, 976 "Ignoring incorrect cHRM value when sRGB is also present"); 977 } 978 #endif /* PNG_FIXED_POINT_SUPPORTED */ 979 #endif /* PNG_READ_cHRM_SUPPORTED */ 980 981 png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); 982 } 983 #endif /* PNG_READ_sRGB_SUPPORTED */ 984 985 #if defined(PNG_READ_iCCP_SUPPORTED) 986 void /* PRIVATE */ 987 png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 988 /* Note: this does not properly handle chunks that are > 64K under DOS */ 989 { 990 png_charp chunkdata; 991 png_byte compression_type; 992 png_bytep pC; 993 png_charp profile; 994 png_uint_32 skip = 0; 995 png_uint_32 profile_size, profile_length; 996 png_size_t slength, prefix_length, data_length; 997 998 png_debug(1, "in png_handle_iCCP\n"); 999 1000 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1001 png_error(png_ptr, "Missing IHDR before iCCP"); 1002 else if (png_ptr->mode & PNG_HAVE_IDAT) 1003 { 1004 png_warning(png_ptr, "Invalid iCCP after IDAT"); 1005 png_crc_finish(png_ptr, length); 1006 return; 1007 } 1008 else if (png_ptr->mode & PNG_HAVE_PLTE) 1009 /* Should be an error, but we can cope with it */ 1010 png_warning(png_ptr, "Out of place iCCP chunk"); 1011 1012 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)) 1013 { 1014 png_warning(png_ptr, "Duplicate iCCP chunk"); 1015 png_crc_finish(png_ptr, length); 1016 return; 1017 } 1018 1019 #ifdef PNG_MAX_MALLOC_64K 1020 if (length > (png_uint_32)65535L) 1021 { 1022 png_warning(png_ptr, "iCCP chunk too large to fit in memory"); 1023 skip = length - (png_uint_32)65535L; 1024 length = (png_uint_32)65535L; 1025 } 1026 #endif 1027 1028 chunkdata = (png_charp)png_malloc(png_ptr, length + 1); 1029 slength = (png_size_t)length; 1030 png_crc_read(png_ptr, (png_bytep)chunkdata, slength); 1031 1032 if (png_crc_finish(png_ptr, skip)) 1033 { 1034 png_free(png_ptr, chunkdata); 1035 return; 1036 } 1037 1038 chunkdata[slength] = 0x00; 1039 1040 for (profile = chunkdata; *profile; profile++) 1041 /* empty loop to find end of name */ ; 1042 1043 ++profile; 1044 1045 /* there should be at least one zero (the compression type byte) 1046 following the separator, and we should be on it */ 1047 if ( profile >= chunkdata + slength - 1) 1048 { 1049 png_free(png_ptr, chunkdata); 1050 png_warning(png_ptr, "Malformed iCCP chunk"); 1051 return; 1052 } 1053 1054 /* compression_type should always be zero */ 1055 compression_type = *profile++; 1056 if (compression_type) 1057 { 1058 png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk"); 1059 compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8 1060 wrote nonzero) */ 1061 } 1062 1063 prefix_length = profile - chunkdata; 1064 chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata, 1065 slength, prefix_length, &data_length); 1066 1067 profile_length = data_length - prefix_length; 1068 1069 if ( prefix_length > data_length || profile_length < 4) 1070 { 1071 png_free(png_ptr, chunkdata); 1072 png_warning(png_ptr, "Profile size field missing from iCCP chunk"); 1073 return; 1074 } 1075 1076 /* Check the profile_size recorded in the first 32 bits of the ICC profile */ 1077 pC = (png_bytep)(chunkdata+prefix_length); 1078 profile_size = ((*(pC ))<<24) | 1079 ((*(pC+1))<<16) | 1080 ((*(pC+2))<< 8) | 1081 ((*(pC+3)) ); 1082 1083 if(profile_size < profile_length) 1084 profile_length = profile_size; 1085 1086 if(profile_size > profile_length) 1087 { 1088 png_free(png_ptr, chunkdata); 1089 png_warning(png_ptr, "Ignoring truncated iCCP profile."); 1090 return; 1091 } 1092 1093 png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type, 1094 chunkdata + prefix_length, profile_length); 1095 png_free(png_ptr, chunkdata); 1096 } 1097 #endif /* PNG_READ_iCCP_SUPPORTED */ 1098 1099 #if defined(PNG_READ_sPLT_SUPPORTED) 1100 void /* PRIVATE */ 1101 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1102 /* Note: this does not properly handle chunks that are > 64K under DOS */ 1103 { 1104 png_bytep chunkdata; 1105 png_bytep entry_start; 1106 png_sPLT_t new_palette; 1107 #ifdef PNG_NO_POINTER_INDEXING 1108 png_sPLT_entryp pp; 1109 #endif 1110 int data_length, entry_size, i; 1111 png_uint_32 skip = 0; 1112 png_size_t slength; 1113 1114 png_debug(1, "in png_handle_sPLT\n"); 1115 1116 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1117 png_error(png_ptr, "Missing IHDR before sPLT"); 1118 else if (png_ptr->mode & PNG_HAVE_IDAT) 1119 { 1120 png_warning(png_ptr, "Invalid sPLT after IDAT"); 1121 png_crc_finish(png_ptr, length); 1122 return; 1123 } 1124 1125 #ifdef PNG_MAX_MALLOC_64K 1126 if (length > (png_uint_32)65535L) 1127 { 1128 png_warning(png_ptr, "sPLT chunk too large to fit in memory"); 1129 skip = length - (png_uint_32)65535L; 1130 length = (png_uint_32)65535L; 1131 } 1132 #endif 1133 1134 chunkdata = (png_bytep)png_malloc(png_ptr, length + 1); 1135 slength = (png_size_t)length; 1136 png_crc_read(png_ptr, (png_bytep)chunkdata, slength); 1137 1138 if (png_crc_finish(png_ptr, skip)) 1139 { 1140 png_free(png_ptr, chunkdata); 1141 return; 1142 } 1143 1144 chunkdata[slength] = 0x00; 1145 1146 for (entry_start = chunkdata; *entry_start; entry_start++) 1147 /* empty loop to find end of name */ ; 1148 ++entry_start; 1149 1150 /* a sample depth should follow the separator, and we should be on it */ 1151 if (entry_start > chunkdata + slength - 2) 1152 { 1153 png_free(png_ptr, chunkdata); 1154 png_warning(png_ptr, "malformed sPLT chunk"); 1155 return; 1156 } 1157 1158 new_palette.depth = *entry_start++; 1159 entry_size = (new_palette.depth == 8 ? 6 : 10); 1160 data_length = (slength - (entry_start - chunkdata)); 1161 1162 /* integrity-check the data length */ 1163 if (data_length % entry_size) 1164 { 1165 png_free(png_ptr, chunkdata); 1166 png_warning(png_ptr, "sPLT chunk has bad length"); 1167 return; 1168 } 1169 1170 new_palette.nentries = (png_int_32) ( data_length / entry_size); 1171 if ((png_uint_32) new_palette.nentries > (png_uint_32) (PNG_SIZE_MAX / 1172 png_sizeof(png_sPLT_entry))) 1173 { 1174 png_warning(png_ptr, "sPLT chunk too long"); 1175 return; 1176 } 1177 new_palette.entries = (png_sPLT_entryp)png_malloc_warn( 1178 png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry)); 1179 if (new_palette.entries == NULL) 1180 { 1181 png_warning(png_ptr, "sPLT chunk requires too much memory"); 1182 return; 1183 } 1184 1185 #ifndef PNG_NO_POINTER_INDEXING 1186 for (i = 0; i < new_palette.nentries; i++) 1187 { 1188 png_sPLT_entryp pp = new_palette.entries + i; 1189 1190 if (new_palette.depth == 8) 1191 { 1192 pp->red = *entry_start++; 1193 pp->green = *entry_start++; 1194 pp->blue = *entry_start++; 1195 pp->alpha = *entry_start++; 1196 } 1197 else 1198 { 1199 pp->red = png_get_uint_16(entry_start); entry_start += 2; 1200 pp->green = png_get_uint_16(entry_start); entry_start += 2; 1201 pp->blue = png_get_uint_16(entry_start); entry_start += 2; 1202 pp->alpha = png_get_uint_16(entry_start); entry_start += 2; 1203 } 1204 pp->frequency = png_get_uint_16(entry_start); entry_start += 2; 1205 } 1206 #else 1207 pp = new_palette.entries; 1208 for (i = 0; i < new_palette.nentries; i++) 1209 { 1210 1211 if (new_palette.depth == 8) 1212 { 1213 pp[i].red = *entry_start++; 1214 pp[i].green = *entry_start++; 1215 pp[i].blue = *entry_start++; 1216 pp[i].alpha = *entry_start++; 1217 } 1218 else 1219 { 1220 pp[i].red = png_get_uint_16(entry_start); entry_start += 2; 1221 pp[i].green = png_get_uint_16(entry_start); entry_start += 2; 1222 pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; 1223 pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; 1224 } 1225 pp->frequency = png_get_uint_16(entry_start); entry_start += 2; 1226 } 1227 #endif 1228 1229 /* discard all chunk data except the name and stash that */ 1230 new_palette.name = (png_charp)chunkdata; 1231 1232 png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); 1233 1234 png_free(png_ptr, chunkdata); 1235 png_free(png_ptr, new_palette.entries); 1236 } 1237 #endif /* PNG_READ_sPLT_SUPPORTED */ 1238 1239 #if defined(PNG_READ_tRNS_SUPPORTED) 1240 void /* PRIVATE */ 1241 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1242 { 1243 png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; 1244 int bit_mask; 1245 1246 png_debug(1, "in png_handle_tRNS\n"); 1247 1248 /* For non-indexed color, mask off any bits in the tRNS value that 1249 * exceed the bit depth. Some creators were writing extra bits there. 1250 * This is not needed for indexed color. */ 1251 bit_mask = (1 << png_ptr->bit_depth) - 1; 1252 1253 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1254 png_error(png_ptr, "Missing IHDR before tRNS"); 1255 else if (png_ptr->mode & PNG_HAVE_IDAT) 1256 { 1257 png_warning(png_ptr, "Invalid tRNS after IDAT"); 1258 png_crc_finish(png_ptr, length); 1259 return; 1260 } 1261 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) 1262 { 1263 png_warning(png_ptr, "Duplicate tRNS chunk"); 1264 png_crc_finish(png_ptr, length); 1265 return; 1266 } 1267 1268 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 1269 { 1270 png_byte buf[2]; 1271 1272 if (length != 2) 1273 { 1274 png_warning(png_ptr, "Incorrect tRNS chunk length"); 1275 png_crc_finish(png_ptr, length); 1276 return; 1277 } 1278 1279 png_crc_read(png_ptr, buf, 2); 1280 png_ptr->num_trans = 1; 1281 png_ptr->trans_values.gray = png_get_uint_16(buf) & bit_mask; 1282 } 1283 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 1284 { 1285 png_byte buf[6]; 1286 1287 if (length != 6) 1288 { 1289 png_warning(png_ptr, "Incorrect tRNS chunk length"); 1290 png_crc_finish(png_ptr, length); 1291 return; 1292 } 1293 png_crc_read(png_ptr, buf, (png_size_t)length); 1294 png_ptr->num_trans = 1; 1295 png_ptr->trans_values.red = png_get_uint_16(buf) & bit_mask; 1296 png_ptr->trans_values.green = png_get_uint_16(buf + 2) & bit_mask; 1297 png_ptr->trans_values.blue = png_get_uint_16(buf + 4) & bit_mask; 1298 } 1299 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1300 { 1301 if (!(png_ptr->mode & PNG_HAVE_PLTE)) 1302 { 1303 /* Should be an error, but we can cope with it. */ 1304 png_warning(png_ptr, "Missing PLTE before tRNS"); 1305 } 1306 if (length > (png_uint_32)png_ptr->num_palette || 1307 length > PNG_MAX_PALETTE_LENGTH) 1308 { 1309 png_warning(png_ptr, "Incorrect tRNS chunk length"); 1310 png_crc_finish(png_ptr, length); 1311 return; 1312 } 1313 if (length == 0) 1314 { 1315 png_warning(png_ptr, "Zero length tRNS chunk"); 1316 png_crc_finish(png_ptr, length); 1317 return; 1318 } 1319 png_crc_read(png_ptr, readbuf, (png_size_t)length); 1320 png_ptr->num_trans = (png_uint_16)length; 1321 } 1322 else 1323 { 1324 png_warning(png_ptr, "tRNS chunk not allowed with alpha channel"); 1325 png_crc_finish(png_ptr, length); 1326 return; 1327 } 1328 1329 if (png_crc_finish(png_ptr, 0)) 1330 { 1331 png_ptr->num_trans = 0; 1332 return; 1333 } 1334 1335 png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, 1336 &(png_ptr->trans_values)); 1337 } 1338 #endif 1339 1340 #if defined(PNG_READ_bKGD_SUPPORTED) 1341 void /* PRIVATE */ 1342 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1343 { 1344 png_size_t truelen; 1345 png_byte buf[6]; 1346 1347 png_debug(1, "in png_handle_bKGD\n"); 1348 1349 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1350 png_error(png_ptr, "Missing IHDR before bKGD"); 1351 else if (png_ptr->mode & PNG_HAVE_IDAT) 1352 { 1353 png_warning(png_ptr, "Invalid bKGD after IDAT"); 1354 png_crc_finish(png_ptr, length); 1355 return; 1356 } 1357 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 1358 !(png_ptr->mode & PNG_HAVE_PLTE)) 1359 { 1360 png_warning(png_ptr, "Missing PLTE before bKGD"); 1361 png_crc_finish(png_ptr, length); 1362 return; 1363 } 1364 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) 1365 { 1366 png_warning(png_ptr, "Duplicate bKGD chunk"); 1367 png_crc_finish(png_ptr, length); 1368 return; 1369 } 1370 1371 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1372 truelen = 1; 1373 else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) 1374 truelen = 6; 1375 else 1376 truelen = 2; 1377 1378 if (length != truelen) 1379 { 1380 png_warning(png_ptr, "Incorrect bKGD chunk length"); 1381 png_crc_finish(png_ptr, length); 1382 return; 1383 } 1384 1385 png_crc_read(png_ptr, buf, truelen); 1386 if (png_crc_finish(png_ptr, 0)) 1387 return; 1388 1389 /* We convert the index value into RGB components so that we can allow 1390 * arbitrary RGB values for background when we have transparency, and 1391 * so it is easy to determine the RGB values of the background color 1392 * from the info_ptr struct. */ 1393 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1394 { 1395 png_ptr->background.index = buf[0]; 1396 if(info_ptr->num_palette) 1397 { 1398 if(buf[0] > info_ptr->num_palette) 1399 { 1400 png_warning(png_ptr, "Incorrect bKGD chunk index value"); 1401 return; 1402 } 1403 png_ptr->background.red = 1404 (png_uint_16)png_ptr->palette[buf[0]].red; 1405 png_ptr->background.green = 1406 (png_uint_16)png_ptr->palette[buf[0]].green; 1407 png_ptr->background.blue = 1408 (png_uint_16)png_ptr->palette[buf[0]].blue; 1409 } 1410 } 1411 else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ 1412 { 1413 png_ptr->background.red = 1414 png_ptr->background.green = 1415 png_ptr->background.blue = 1416 png_ptr->background.gray = png_get_uint_16(buf); 1417 } 1418 else 1419 { 1420 png_ptr->background.red = png_get_uint_16(buf); 1421 png_ptr->background.green = png_get_uint_16(buf + 2); 1422 png_ptr->background.blue = png_get_uint_16(buf + 4); 1423 } 1424 1425 png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background)); 1426 } 1427 #endif 1428 1429 #if defined(PNG_READ_hIST_SUPPORTED) 1430 void /* PRIVATE */ 1431 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1432 { 1433 unsigned int num, i; 1434 png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; 1435 1436 png_debug(1, "in png_handle_hIST\n"); 1437 1438 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1439 png_error(png_ptr, "Missing IHDR before hIST"); 1440 else if (png_ptr->mode & PNG_HAVE_IDAT) 1441 { 1442 png_warning(png_ptr, "Invalid hIST after IDAT"); 1443 png_crc_finish(png_ptr, length); 1444 return; 1445 } 1446 else if (!(png_ptr->mode & PNG_HAVE_PLTE)) 1447 { 1448 png_warning(png_ptr, "Missing PLTE before hIST"); 1449 png_crc_finish(png_ptr, length); 1450 return; 1451 } 1452 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) 1453 { 1454 png_warning(png_ptr, "Duplicate hIST chunk"); 1455 png_crc_finish(png_ptr, length); 1456 return; 1457 } 1458 1459 num = length / 2 ; 1460 if (num != (unsigned int) png_ptr->num_palette || num > 1461 (unsigned int) PNG_MAX_PALETTE_LENGTH) 1462 { 1463 png_warning(png_ptr, "Incorrect hIST chunk length"); 1464 png_crc_finish(png_ptr, length); 1465 return; 1466 } 1467 1468 for (i = 0; i < num; i++) 1469 { 1470 png_byte buf[2]; 1471 1472 png_crc_read(png_ptr, buf, 2); 1473 readbuf[i] = png_get_uint_16(buf); 1474 } 1475 1476 if (png_crc_finish(png_ptr, 0)) 1477 return; 1478 1479 png_set_hIST(png_ptr, info_ptr, readbuf); 1480 } 1481 #endif 1482 1483 #if defined(PNG_READ_pHYs_SUPPORTED) 1484 void /* PRIVATE */ 1485 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1486 { 1487 png_byte buf[9]; 1488 png_uint_32 res_x, res_y; 1489 int unit_type; 1490 1491 png_debug(1, "in png_handle_pHYs\n"); 1492 1493 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1494 png_error(png_ptr, "Missing IHDR before pHYs"); 1495 else if (png_ptr->mode & PNG_HAVE_IDAT) 1496 { 1497 png_warning(png_ptr, "Invalid pHYs after IDAT"); 1498 png_crc_finish(png_ptr, length); 1499 return; 1500 } 1501 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) 1502 { 1503 png_warning(png_ptr, "Duplicate pHYs chunk"); 1504 png_crc_finish(png_ptr, length); 1505 return; 1506 } 1507 1508 if (length != 9) 1509 { 1510 png_warning(png_ptr, "Incorrect pHYs chunk length"); 1511 png_crc_finish(png_ptr, length); 1512 return; 1513 } 1514 1515 png_crc_read(png_ptr, buf, 9); 1516 if (png_crc_finish(png_ptr, 0)) 1517 return; 1518 1519 res_x = png_get_uint_32(buf); 1520 res_y = png_get_uint_32(buf + 4); 1521 unit_type = buf[8]; 1522 png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); 1523 } 1524 #endif 1525 1526 #if defined(PNG_READ_oFFs_SUPPORTED) 1527 void /* PRIVATE */ 1528 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1529 { 1530 png_byte buf[9]; 1531 png_int_32 offset_x, offset_y; 1532 int unit_type; 1533 1534 png_debug(1, "in png_handle_oFFs\n"); 1535 1536 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1537 png_error(png_ptr, "Missing IHDR before oFFs"); 1538 else if (png_ptr->mode & PNG_HAVE_IDAT) 1539 { 1540 png_warning(png_ptr, "Invalid oFFs after IDAT"); 1541 png_crc_finish(png_ptr, length); 1542 return; 1543 } 1544 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) 1545 { 1546 png_warning(png_ptr, "Duplicate oFFs chunk"); 1547 png_crc_finish(png_ptr, length); 1548 return; 1549 } 1550 1551 if (length != 9) 1552 { 1553 png_warning(png_ptr, "Incorrect oFFs chunk length"); 1554 png_crc_finish(png_ptr, length); 1555 return; 1556 } 1557 1558 png_crc_read(png_ptr, buf, 9); 1559 if (png_crc_finish(png_ptr, 0)) 1560 return; 1561 1562 offset_x = png_get_int_32(buf); 1563 offset_y = png_get_int_32(buf + 4); 1564 unit_type = buf[8]; 1565 png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); 1566 } 1567 #endif 1568 1569 #if defined(PNG_READ_pCAL_SUPPORTED) 1570 /* read the pCAL chunk (described in the PNG Extensions document) */ 1571 void /* PRIVATE */ 1572 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1573 { 1574 png_charp purpose; 1575 png_int_32 X0, X1; 1576 png_byte type, nparams; 1577 png_charp buf, units, endptr; 1578 png_charpp params; 1579 png_size_t slength; 1580 int i; 1581 1582 png_debug(1, "in png_handle_pCAL\n"); 1583 1584 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1585 png_error(png_ptr, "Missing IHDR before pCAL"); 1586 else if (png_ptr->mode & PNG_HAVE_IDAT) 1587 { 1588 png_warning(png_ptr, "Invalid pCAL after IDAT"); 1589 png_crc_finish(png_ptr, length); 1590 return; 1591 } 1592 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) 1593 { 1594 png_warning(png_ptr, "Duplicate pCAL chunk"); 1595 png_crc_finish(png_ptr, length); 1596 return; 1597 } 1598 1599 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n", 1600 length + 1); 1601 purpose = (png_charp)png_malloc_warn(png_ptr, length + 1); 1602 if (purpose == NULL) 1603 { 1604 png_warning(png_ptr, "No memory for pCAL purpose."); 1605 return; 1606 } 1607 slength = (png_size_t)length; 1608 png_crc_read(png_ptr, (png_bytep)purpose, slength); 1609 1610 if (png_crc_finish(png_ptr, 0)) 1611 { 1612 png_free(png_ptr, purpose); 1613 return; 1614 } 1615 1616 purpose[slength] = 0x00; /* null terminate the last string */ 1617 1618 png_debug(3, "Finding end of pCAL purpose string\n"); 1619 for (buf = purpose; *buf; buf++) 1620 /* empty loop */ ; 1621 1622 endptr = purpose + slength; 1623 1624 /* We need to have at least 12 bytes after the purpose string 1625 in order to get the parameter information. */ 1626 if (endptr <= buf + 12) 1627 { 1628 png_warning(png_ptr, "Invalid pCAL data"); 1629 png_free(png_ptr, purpose); 1630 return; 1631 } 1632 1633 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n"); 1634 X0 = png_get_int_32((png_bytep)buf+1); 1635 X1 = png_get_int_32((png_bytep)buf+5); 1636 type = buf[9]; 1637 nparams = buf[10]; 1638 units = buf + 11; 1639 1640 png_debug(3, "Checking pCAL equation type and number of parameters\n"); 1641 /* Check that we have the right number of parameters for known 1642 equation types. */ 1643 if ((type == PNG_EQUATION_LINEAR && nparams != 2) || 1644 (type == PNG_EQUATION_BASE_E && nparams != 3) || 1645 (type == PNG_EQUATION_ARBITRARY && nparams != 3) || 1646 (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) 1647 { 1648 png_warning(png_ptr, "Invalid pCAL parameters for equation type"); 1649 png_free(png_ptr, purpose); 1650 return; 1651 } 1652 else if (type >= PNG_EQUATION_LAST) 1653 { 1654 png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); 1655 } 1656 1657 for (buf = units; *buf; buf++) 1658 /* Empty loop to move past the units string. */ ; 1659 1660 png_debug(3, "Allocating pCAL parameters array\n"); 1661 params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams 1662 *png_sizeof(png_charp))) ; 1663 if (params == NULL) 1664 { 1665 png_free(png_ptr, purpose); 1666 png_warning(png_ptr, "No memory for pCAL params."); 1667 return; 1668 } 1669 1670 /* Get pointers to the start of each parameter string. */ 1671 for (i = 0; i < (int)nparams; i++) 1672 { 1673 buf++; /* Skip the null string terminator from previous parameter. */ 1674 1675 png_debug1(3, "Reading pCAL parameter %d\n", i); 1676 for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++) 1677 /* Empty loop to move past each parameter string */ ; 1678 1679 /* Make sure we haven't run out of data yet */ 1680 if (buf > endptr) 1681 { 1682 png_warning(png_ptr, "Invalid pCAL data"); 1683 png_free(png_ptr, purpose); 1684 png_free(png_ptr, params); 1685 return; 1686 } 1687 } 1688 1689 png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams, 1690 units, params); 1691 1692 png_free(png_ptr, purpose); 1693 png_free(png_ptr, params); 1694 } 1695 #endif 1696 1697 #if defined(PNG_READ_sCAL_SUPPORTED) 1698 /* read the sCAL chunk */ 1699 void /* PRIVATE */ 1700 png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1701 { 1702 png_charp buffer, ep; 1703 #ifdef PNG_FLOATING_POINT_SUPPORTED 1704 double width, height; 1705 png_charp vp; 1706 #else 1707 #ifdef PNG_FIXED_POINT_SUPPORTED 1708 png_charp swidth, sheight; 1709 #endif 1710 #endif 1711 png_size_t slength; 1712 1713 png_debug(1, "in png_handle_sCAL\n"); 1714 1715 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1716 png_error(png_ptr, "Missing IHDR before sCAL"); 1717 else if (png_ptr->mode & PNG_HAVE_IDAT) 1718 { 1719 png_warning(png_ptr, "Invalid sCAL after IDAT"); 1720 png_crc_finish(png_ptr, length); 1721 return; 1722 } 1723 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) 1724 { 1725 png_warning(png_ptr, "Duplicate sCAL chunk"); 1726 png_crc_finish(png_ptr, length); 1727 return; 1728 } 1729 1730 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n", 1731 length + 1); 1732 buffer = (png_charp)png_malloc_warn(png_ptr, length + 1); 1733 if (buffer == NULL) 1734 { 1735 png_warning(png_ptr, "Out of memory while processing sCAL chunk"); 1736 return; 1737 } 1738 slength = (png_size_t)length; 1739 png_crc_read(png_ptr, (png_bytep)buffer, slength); 1740 1741 if (png_crc_finish(png_ptr, 0)) 1742 { 1743 png_free(png_ptr, buffer); 1744 return; 1745 } 1746 1747 buffer[slength] = 0x00; /* null terminate the last string */ 1748 1749 ep = buffer + 1; /* skip unit byte */ 1750 1751 #ifdef PNG_FLOATING_POINT_SUPPORTED 1752 width = png_strtod(png_ptr, ep, &vp); 1753 if (*vp) 1754 { 1755 png_warning(png_ptr, "malformed width string in sCAL chunk"); 1756 return; 1757 } 1758 #else 1759 #ifdef PNG_FIXED_POINT_SUPPORTED 1760 swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); 1761 if (swidth == NULL) 1762 { 1763 png_warning(png_ptr, "Out of memory while processing sCAL chunk width"); 1764 return; 1765 } 1766 png_memcpy(swidth, ep, (png_size_t)png_strlen(ep)); 1767 #endif 1768 #endif 1769 1770 for (ep = buffer; *ep; ep++) 1771 /* empty loop */ ; 1772 ep++; 1773 1774 #ifdef PNG_FLOATING_POINT_SUPPORTED 1775 height = png_strtod(png_ptr, ep, &vp); 1776 if (*vp) 1777 { 1778 png_warning(png_ptr, "malformed height string in sCAL chunk"); 1779 return; 1780 } 1781 #else 1782 #ifdef PNG_FIXED_POINT_SUPPORTED 1783 sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); 1784 if (swidth == NULL) 1785 { 1786 png_warning(png_ptr, "Out of memory while processing sCAL chunk height"); 1787 return; 1788 } 1789 png_memcpy(sheight, ep, (png_size_t)png_strlen(ep)); 1790 #endif 1791 #endif 1792 1793 if (buffer + slength < ep 1794 #ifdef PNG_FLOATING_POINT_SUPPORTED 1795 || width <= 0. || height <= 0. 1796 #endif 1797 ) 1798 { 1799 png_warning(png_ptr, "Invalid sCAL data"); 1800 png_free(png_ptr, buffer); 1801 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1802 png_free(png_ptr, swidth); 1803 png_free(png_ptr, sheight); 1804 #endif 1805 return; 1806 } 1807 1808 1809 #ifdef PNG_FLOATING_POINT_SUPPORTED 1810 png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height); 1811 #else 1812 #ifdef PNG_FIXED_POINT_SUPPORTED 1813 png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight); 1814 #endif 1815 #endif 1816 1817 png_free(png_ptr, buffer); 1818 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1819 png_free(png_ptr, swidth); 1820 png_free(png_ptr, sheight); 1821 #endif 1822 } 1823 #endif 1824 1825 #if defined(PNG_READ_tIME_SUPPORTED) 1826 void /* PRIVATE */ 1827 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1828 { 1829 png_byte buf[7]; 1830 png_time mod_time; 1831 1832 png_debug(1, "in png_handle_tIME\n"); 1833 1834 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1835 png_error(png_ptr, "Out of place tIME chunk"); 1836 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) 1837 { 1838 png_warning(png_ptr, "Duplicate tIME chunk"); 1839 png_crc_finish(png_ptr, length); 1840 return; 1841 } 1842 1843 if (png_ptr->mode & PNG_HAVE_IDAT) 1844 png_ptr->mode |= PNG_AFTER_IDAT; 1845 1846 if (length != 7) 1847 { 1848 png_warning(png_ptr, "Incorrect tIME chunk length"); 1849 png_crc_finish(png_ptr, length); 1850 return; 1851 } 1852 1853 png_crc_read(png_ptr, buf, 7); 1854 if (png_crc_finish(png_ptr, 0)) 1855 return; 1856 1857 mod_time.second = buf[6]; 1858 mod_time.minute = buf[5]; 1859 mod_time.hour = buf[4]; 1860 mod_time.day = buf[3]; 1861 mod_time.month = buf[2]; 1862 mod_time.year = png_get_uint_16(buf); 1863 1864 png_set_tIME(png_ptr, info_ptr, &mod_time); 1865 } 1866 #endif 1867 1868 #if defined(PNG_READ_tEXt_SUPPORTED) 1869 /* Note: this does not properly handle chunks that are > 64K under DOS */ 1870 void /* PRIVATE */ 1871 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1872 { 1873 png_textp text_ptr; 1874 png_charp key; 1875 png_charp text; 1876 png_uint_32 skip = 0; 1877 png_size_t slength; 1878 int ret; 1879 1880 png_debug(1, "in png_handle_tEXt\n"); 1881 1882 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1883 png_error(png_ptr, "Missing IHDR before tEXt"); 1884 1885 if (png_ptr->mode & PNG_HAVE_IDAT) 1886 png_ptr->mode |= PNG_AFTER_IDAT; 1887 1888 #ifdef PNG_MAX_MALLOC_64K 1889 if (length > (png_uint_32)65535L) 1890 { 1891 png_warning(png_ptr, "tEXt chunk too large to fit in memory"); 1892 skip = length - (png_uint_32)65535L; 1893 length = (png_uint_32)65535L; 1894 } 1895 #endif 1896 1897 key = (png_charp)png_malloc_warn(png_ptr, length + 1); 1898 if (key == NULL) 1899 { 1900 png_warning(png_ptr, "No memory to process text chunk."); 1901 return; 1902 } 1903 slength = (png_size_t)length; 1904 png_crc_read(png_ptr, (png_bytep)key, slength); 1905 1906 if (png_crc_finish(png_ptr, skip)) 1907 { 1908 png_free(png_ptr, key); 1909 return; 1910 } 1911 1912 key[slength] = 0x00; 1913 1914 for (text = key; *text; text++) 1915 /* empty loop to find end of key */ ; 1916 1917 if (text != key + slength) 1918 text++; 1919 1920 text_ptr = (png_textp)png_malloc_warn(png_ptr, 1921 (png_uint_32)png_sizeof(png_text)); 1922 if (text_ptr == NULL) 1923 { 1924 png_warning(png_ptr, "Not enough memory to process text chunk."); 1925 png_free(png_ptr, key); 1926 return; 1927 } 1928 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; 1929 text_ptr->key = key; 1930 #ifdef PNG_iTXt_SUPPORTED 1931 text_ptr->lang = NULL; 1932 text_ptr->lang_key = NULL; 1933 text_ptr->itxt_length = 0; 1934 #endif 1935 text_ptr->text = text; 1936 text_ptr->text_length = png_strlen(text); 1937 1938 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 1939 1940 png_free(png_ptr, key); 1941 png_free(png_ptr, text_ptr); 1942 if (ret) 1943 png_warning(png_ptr, "Insufficient memory to process text chunk."); 1944 } 1945 #endif 1946 1947 #if defined(PNG_READ_zTXt_SUPPORTED) 1948 /* note: this does not correctly handle chunks that are > 64K under DOS */ 1949 void /* PRIVATE */ 1950 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1951 { 1952 png_textp text_ptr; 1953 png_charp chunkdata; 1954 png_charp text; 1955 int comp_type; 1956 int ret; 1957 png_size_t slength, prefix_len, data_len; 1958 1959 png_debug(1, "in png_handle_zTXt\n"); 1960 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1961 png_error(png_ptr, "Missing IHDR before zTXt"); 1962 1963 if (png_ptr->mode & PNG_HAVE_IDAT) 1964 png_ptr->mode |= PNG_AFTER_IDAT; 1965 1966 #ifdef PNG_MAX_MALLOC_64K 1967 /* We will no doubt have problems with chunks even half this size, but 1968 there is no hard and fast rule to tell us where to stop. */ 1969 if (length > (png_uint_32)65535L) 1970 { 1971 png_warning(png_ptr,"zTXt chunk too large to fit in memory"); 1972 png_crc_finish(png_ptr, length); 1973 return; 1974 } 1975 #endif 1976 1977 chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 1978 if (chunkdata == NULL) 1979 { 1980 png_warning(png_ptr,"Out of memory processing zTXt chunk."); 1981 return; 1982 } 1983 slength = (png_size_t)length; 1984 png_crc_read(png_ptr, (png_bytep)chunkdata, slength); 1985 if (png_crc_finish(png_ptr, 0)) 1986 { 1987 png_free(png_ptr, chunkdata); 1988 return; 1989 } 1990 1991 chunkdata[slength] = 0x00; 1992 1993 for (text = chunkdata; *text; text++) 1994 /* empty loop */ ; 1995 1996 /* zTXt must have some text after the chunkdataword */ 1997 if (text == chunkdata + slength - 1) 1998 { 1999 png_warning(png_ptr, "Truncated zTXt chunk"); 2000 png_free(png_ptr, chunkdata); 2001 return; 2002 } 2003 else 2004 { 2005 comp_type = *(++text); 2006 if (comp_type != PNG_TEXT_COMPRESSION_zTXt) 2007 { 2008 png_warning(png_ptr, "Unknown compression type in zTXt chunk"); 2009 comp_type = PNG_TEXT_COMPRESSION_zTXt; 2010 } 2011 text++; /* skip the compression_method byte */ 2012 } 2013 prefix_len = text - chunkdata; 2014 2015 chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata, 2016 (png_size_t)length, prefix_len, &data_len); 2017 2018 text_ptr = (png_textp)png_malloc_warn(png_ptr, 2019 (png_uint_32)png_sizeof(png_text)); 2020 if (text_ptr == NULL) 2021 { 2022 png_warning(png_ptr,"Not enough memory to process zTXt chunk."); 2023 png_free(png_ptr, chunkdata); 2024 return; 2025 } 2026 text_ptr->compression = comp_type; 2027 text_ptr->key = chunkdata; 2028 #ifdef PNG_iTXt_SUPPORTED 2029 text_ptr->lang = NULL; 2030 text_ptr->lang_key = NULL; 2031 text_ptr->itxt_length = 0; 2032 #endif 2033 text_ptr->text = chunkdata + prefix_len; 2034 text_ptr->text_length = data_len; 2035 2036 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 2037 2038 png_free(png_ptr, text_ptr); 2039 png_free(png_ptr, chunkdata); 2040 if (ret) 2041 png_error(png_ptr, "Insufficient memory to store zTXt chunk."); 2042 } 2043 #endif 2044 2045 #if defined(PNG_READ_iTXt_SUPPORTED) 2046 /* note: this does not correctly handle chunks that are > 64K under DOS */ 2047 void /* PRIVATE */ 2048 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 2049 { 2050 png_textp text_ptr; 2051 png_charp chunkdata; 2052 png_charp key, lang, text, lang_key; 2053 int comp_flag; 2054 int comp_type = 0; 2055 int ret; 2056 png_size_t slength, prefix_len, data_len; 2057 2058 png_debug(1, "in png_handle_iTXt\n"); 2059 2060 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 2061 png_error(png_ptr, "Missing IHDR before iTXt"); 2062 2063 if (png_ptr->mode & PNG_HAVE_IDAT) 2064 png_ptr->mode |= PNG_AFTER_IDAT; 2065 2066 #ifdef PNG_MAX_MALLOC_64K 2067 /* We will no doubt have problems with chunks even half this size, but 2068 there is no hard and fast rule to tell us where to stop. */ 2069 if (length > (png_uint_32)65535L) 2070 { 2071 png_warning(png_ptr,"iTXt chunk too large to fit in memory"); 2072 png_crc_finish(png_ptr, length); 2073 return; 2074 } 2075 #endif 2076 2077 chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 2078 if (chunkdata == NULL) 2079 { 2080 png_warning(png_ptr, "No memory to process iTXt chunk."); 2081 return; 2082 } 2083 slength = (png_size_t)length; 2084 png_crc_read(png_ptr, (png_bytep)chunkdata, slength); 2085 if (png_crc_finish(png_ptr, 0)) 2086 { 2087 png_free(png_ptr, chunkdata); 2088 return; 2089 } 2090 2091 chunkdata[slength] = 0x00; 2092 2093 for (lang = chunkdata; *lang; lang++) 2094 /* empty loop */ ; 2095 lang++; /* skip NUL separator */ 2096 2097 /* iTXt must have a language tag (possibly empty), two compression bytes, 2098 translated keyword (possibly empty), and possibly some text after the 2099 keyword */ 2100 2101 if (lang >= chunkdata + slength - 3) 2102 { 2103 png_warning(png_ptr, "Truncated iTXt chunk"); 2104 png_free(png_ptr, chunkdata); 2105 return; 2106 } 2107 else 2108 { 2109 comp_flag = *lang++; 2110 comp_type = *lang++; 2111 } 2112 2113 for (lang_key = lang; *lang_key; lang_key++) 2114 /* empty loop */ ; 2115 lang_key++; /* skip NUL separator */ 2116 2117 for (text = lang_key; *text; text++) 2118 /* empty loop */ ; 2119 text++; /* skip NUL separator */ 2120 if (text >= chunkdata + slength) 2121 { 2122 png_warning(png_ptr, "Malformed iTXt chunk"); 2123 png_free(png_ptr, chunkdata); 2124 return; 2125 } 2126 2127 prefix_len = text - chunkdata; 2128 2129 key=chunkdata; 2130 if (comp_flag) 2131 chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata, 2132 (size_t)length, prefix_len, &data_len); 2133 else 2134 data_len=png_strlen(chunkdata + prefix_len); 2135 text_ptr = (png_textp)png_malloc_warn(png_ptr, 2136 (png_uint_32)png_sizeof(png_text)); 2137 if (text_ptr == NULL) 2138 { 2139 png_warning(png_ptr,"Not enough memory to process iTXt chunk."); 2140 png_free(png_ptr, chunkdata); 2141 return; 2142 } 2143 text_ptr->compression = (int)comp_flag + 1; 2144 text_ptr->lang_key = chunkdata+(lang_key-key); 2145 text_ptr->lang = chunkdata+(lang-key); 2146 text_ptr->itxt_length = data_len; 2147 text_ptr->text_length = 0; 2148 text_ptr->key = chunkdata; 2149 text_ptr->text = chunkdata + prefix_len; 2150 2151 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 2152 2153 png_free(png_ptr, text_ptr); 2154 png_free(png_ptr, chunkdata); 2155 if (ret) 2156 png_error(png_ptr, "Insufficient memory to store iTXt chunk."); 2157 } 2158 #endif 2159 2160 /* This function is called when we haven't found a handler for a 2161 chunk. If there isn't a problem with the chunk itself (ie bad 2162 chunk name, CRC, or a critical chunk), the chunk is silently ignored 2163 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which 2164 case it will be saved away to be written out later. */ 2165 void /* PRIVATE */ 2166 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 2167 { 2168 png_uint_32 skip = 0; 2169 2170 png_debug(1, "in png_handle_unknown\n"); 2171 2172 if (png_ptr->mode & PNG_HAVE_IDAT) 2173 { 2174 #ifdef PNG_USE_LOCAL_ARRAYS 2175 PNG_CONST PNG_IDAT; 2176 #endif 2177 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */ 2178 png_ptr->mode |= PNG_AFTER_IDAT; 2179 } 2180 2181 png_check_chunk_name(png_ptr, png_ptr->chunk_name); 2182 2183 if (!(png_ptr->chunk_name[0] & 0x20)) 2184 { 2185 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) 2186 if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != 2187 PNG_HANDLE_CHUNK_ALWAYS 2188 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) 2189 && png_ptr->read_user_chunk_fn == NULL 2190 #endif 2191 ) 2192 #endif 2193 png_chunk_error(png_ptr, "unknown critical chunk"); 2194 } 2195 2196 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) 2197 if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) || 2198 (png_ptr->read_user_chunk_fn != NULL)) 2199 { 2200 #ifdef PNG_MAX_MALLOC_64K 2201 if (length > (png_uint_32)65535L) 2202 { 2203 png_warning(png_ptr, "unknown chunk too large to fit in memory"); 2204 skip = length - (png_uint_32)65535L; 2205 length = (png_uint_32)65535L; 2206 } 2207 #endif 2208 png_strncpy((png_charp)png_ptr->unknown_chunk.name, 2209 (png_charp)png_ptr->chunk_name, 2210 png_sizeof((png_charp)png_ptr->chunk_name)); 2211 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); 2212 png_ptr->unknown_chunk.size = (png_size_t)length; 2213 png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); 2214 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) 2215 if(png_ptr->read_user_chunk_fn != NULL) 2216 { 2217 /* callback to user unknown chunk handler */ 2218 int ret; 2219 ret = (*(png_ptr->read_user_chunk_fn)) 2220 (png_ptr, &png_ptr->unknown_chunk); 2221 if (ret < 0) 2222 png_chunk_error(png_ptr, "error in user chunk"); 2223 if (ret == 0) 2224 { 2225 if (!(png_ptr->chunk_name[0] & 0x20)) 2226 if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != 2227 PNG_HANDLE_CHUNK_ALWAYS) 2228 png_chunk_error(png_ptr, "unknown critical chunk"); 2229 png_set_unknown_chunks(png_ptr, info_ptr, 2230 &png_ptr->unknown_chunk, 1); 2231 } 2232 } 2233 #else 2234 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); 2235 #endif 2236 png_free(png_ptr, png_ptr->unknown_chunk.data); 2237 png_ptr->unknown_chunk.data = NULL; 2238 } 2239 else 2240 #endif 2241 skip = length; 2242 2243 png_crc_finish(png_ptr, skip); 2244 2245 #if !defined(PNG_READ_USER_CHUNKS_SUPPORTED) 2246 info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */ 2247 #endif 2248 } 2249 2250 /* This function is called to verify that a chunk name is valid. 2251 This function can't have the "critical chunk check" incorporated 2252 into it, since in the future we will need to be able to call user 2253 functions to handle unknown critical chunks after we check that 2254 the chunk name itself is valid. */ 2255 2256 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) 2257 2258 void /* PRIVATE */ 2259 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name) 2260 { 2261 png_debug(1, "in png_check_chunk_name\n"); 2262 if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) || 2263 isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3])) 2264 { 2265 png_chunk_error(png_ptr, "invalid chunk type"); 2266 } 2267 } 2268 2269 /* Combines the row recently read in with the existing pixels in the 2270 row. This routine takes care of alpha and transparency if requested. 2271 This routine also handles the two methods of progressive display 2272 of interlaced images, depending on the mask value. 2273 The mask value describes which pixels are to be combined with 2274 the row. The pattern always repeats every 8 pixels, so just 8 2275 bits are needed. A one indicates the pixel is to be combined, 2276 a zero indicates the pixel is to be skipped. This is in addition 2277 to any alpha or transparency value associated with the pixel. If 2278 you want all pixels to be combined, pass 0xff (255) in mask. */ 2279 2280 /* Optimized C version of utilities to read a PNG file 2281 * 2282 * Based on code contributed by Nirav Chhatrapati, Intel Corp., 1998. 2283 * Interface to libpng contributed by Gilles Vollant, 1999. 2284 * GNU C port by Greg Roelofs, 1999-2001. 2285 * 2286 */ 2287 2288 #if defined(PNG_OPTIMIZED_CODE_SUPPORTED) 2289 #if !defined(PNG_HAVE_MMX_COMBINE_ROW) 2290 2291 /*===========================================================================*/ 2292 /* */ 2293 /* P N G _ C O M B I N E _ R O W */ 2294 /* */ 2295 /*===========================================================================*/ 2296 2297 2298 #define BPP2 2 2299 #define BPP3 3 /* bytes per pixel (a.k.a. pixel_bytes) */ 2300 #define BPP4 4 2301 #define BPP6 6 /* (defined only to help avoid cut-and-paste errors) */ 2302 #define BPP8 8 2303 2304 /* Combines the row recently read in with the previous row. 2305 This routine takes care of alpha and transparency if requested. 2306 This routine also handles the two methods of progressive display 2307 of interlaced images, depending on the mask value. 2308 The mask value describes which pixels are to be combined with 2309 the row. The pattern always repeats every 8 pixels, so just 8 2310 bits are needed. A one indicates the pixel is to be combined; a 2311 zero indicates the pixel is to be skipped. This is in addition 2312 to any alpha or transparency value associated with the pixel. 2313 If you want all pixels to be combined, pass 0xff (255) in mask. */ 2314 2315 /* Use this routine for the x86 platform - it uses a faster MMX routine 2316 if the machine supports MMX. */ 2317 2318 void /* PRIVATE */ 2319 png_combine_row(png_structp png_ptr, png_bytep row, int mask) 2320 { 2321 2322 #if defined(PNG_USE_LOCAL_ARRAYS) 2323 static PNG_CONST int FARDATA png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 2324 static PNG_CONST int FARDATA png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 2325 static PNG_CONST int FARDATA png_pass_width[7] = {8, 4, 4, 2, 2, 1, 1}; 2326 #endif 2327 2328 png_debug(1, "in png_combine_row (pngrutil.c OPTIMIZED)\n"); 2329 2330 if (mask == 0xff) 2331 { 2332 png_debug(2,"mask == 0xff: doing single png_memcpy()\n"); 2333 png_memcpy(row, png_ptr->row_buf + 1, 2334 (png_size_t)PNG_ROWBYTES(png_ptr->row_info.pixel_depth,png_ptr->width)); 2335 } 2336 else /* (png_combine_row() is never called with mask == 0) */ 2337 { 2338 switch (png_ptr->row_info.pixel_depth) 2339 { 2340 /* most common case: combining 24-bit RGB */ 2341 case 24: /* png_ptr->row_info.pixel_depth */ 2342 { 2343 png_bytep srcptr; 2344 png_bytep dstptr; 2345 2346 { 2347 register png_uint_32 i; 2348 png_uint_32 initial_val = BPP3 * png_pass_start[png_ptr->pass]; 2349 /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ 2350 register int stride = BPP3 * png_pass_inc[png_ptr->pass]; 2351 /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ 2352 register int rep_bytes = BPP3 * png_pass_width[png_ptr->pass]; 2353 /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ 2354 png_uint_32 len = png_ptr->width &~7; /* reduce to mult of 8 */ 2355 int diff = (int) (png_ptr->width & 7); /* amount lost */ 2356 register png_uint_32 final_val = BPP3 * len; /* GRR bugfix */ 2357 2358 srcptr = png_ptr->row_buf + 1 + initial_val; 2359 dstptr = row + initial_val; 2360 2361 for (i = initial_val; i < final_val; i += stride) 2362 { 2363 png_memcpy(dstptr, srcptr, rep_bytes); 2364 srcptr += stride; 2365 dstptr += stride; 2366 } 2367 if (diff) /* number of leftover pixels: 3 for pngtest */ 2368 { 2369 final_val += diff*BPP3; 2370 for (; i < final_val; i += stride) 2371 { 2372 if (rep_bytes > (int)(final_val-i)) 2373 rep_bytes = (int)(final_val-i); 2374 png_memcpy(dstptr, srcptr, rep_bytes); 2375 srcptr += stride; 2376 dstptr += stride; 2377 } 2378 } 2379 } /* end of else (_mmx_supported) */ 2380 2381 break; 2382 } /* end 24 bpp */ 2383 2384 case 32: /* png_ptr->row_info.pixel_depth */ 2385 { 2386 png_bytep srcptr; 2387 png_bytep dstptr; 2388 2389 { 2390 register png_uint_32 i; 2391 png_uint_32 initial_val = BPP4 * png_pass_start[png_ptr->pass]; 2392 /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ 2393 register int stride = BPP4 * png_pass_inc[png_ptr->pass]; 2394 /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ 2395 register int rep_bytes = BPP4 * png_pass_width[png_ptr->pass]; 2396 /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ 2397 png_uint_32 len = png_ptr->width &~7; /* reduce to mult of 8 */ 2398 int diff = (int) (png_ptr->width & 7); /* amount lost */ 2399 register png_uint_32 final_val = BPP4 * len; /* GRR bugfix */ 2400 2401 srcptr = png_ptr->row_buf + 1 + initial_val; 2402 dstptr = row + initial_val; 2403 2404 for (i = initial_val; i < final_val; i += stride) 2405 { 2406 png_memcpy(dstptr, srcptr, rep_bytes); 2407 srcptr += stride; 2408 dstptr += stride; 2409 } 2410 if (diff) /* number of leftover pixels: 3 for pngtest */ 2411 { 2412 final_val += diff*BPP4; 2413 for (; i < final_val; i += stride) 2414 { 2415 if (rep_bytes > (int)(final_val-i)) 2416 rep_bytes = (int)(final_val-i); 2417 png_memcpy(dstptr, srcptr, rep_bytes); 2418 srcptr += stride; 2419 dstptr += stride; 2420 } 2421 } 2422 } 2423 2424 break; 2425 } /* end 32 bpp */ 2426 2427 case 8: /* png_ptr->row_info.pixel_depth */ 2428 { 2429 png_bytep srcptr; 2430 png_bytep dstptr; 2431 { 2432 register png_uint_32 i; 2433 png_uint_32 initial_val = png_pass_start[png_ptr->pass]; 2434 /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ 2435 register int stride = png_pass_inc[png_ptr->pass]; 2436 /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ 2437 register int rep_bytes = png_pass_width[png_ptr->pass]; 2438 /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ 2439 png_uint_32 len = png_ptr->width &~7; /* reduce to mult of 8 */ 2440 int diff = (int) (png_ptr->width & 7); /* amount lost */ 2441 register png_uint_32 final_val = len; /* GRR bugfix */ 2442 2443 srcptr = png_ptr->row_buf + 1 + initial_val; 2444 dstptr = row + initial_val; 2445 2446 for (i = initial_val; i < final_val; i += stride) 2447 { 2448 png_memcpy(dstptr, srcptr, rep_bytes); 2449 srcptr += stride; 2450 dstptr += stride; 2451 } 2452 if (diff) /* number of leftover pixels: 3 for pngtest */ 2453 { 2454 final_val += diff /* *BPP1 */ ; 2455 for (; i < final_val; i += stride) 2456 { 2457 if (rep_bytes > (int)(final_val-i)) 2458 rep_bytes = (int)(final_val-i); 2459 png_memcpy(dstptr, srcptr, rep_bytes); 2460 srcptr += stride; 2461 dstptr += stride; 2462 } 2463 } 2464 } 2465 2466 break; 2467 } /* end 8 bpp */ 2468 2469 case 1: /* png_ptr->row_info.pixel_depth */ 2470 { 2471 png_bytep sp; 2472 png_bytep dp; 2473 int s_inc, s_start, s_end; 2474 int m; 2475 int shift; 2476 png_uint_32 i; 2477 2478 sp = png_ptr->row_buf + 1; 2479 dp = row; 2480 m = 0x80; 2481 #if defined(PNG_READ_PACKSWAP_SUPPORTED) 2482 if (png_ptr->transformations & PNG_PACKSWAP) 2483 { 2484 s_start = 0; 2485 s_end = 7; 2486 s_inc = 1; 2487 } 2488 else 2489 #endif 2490 { 2491 s_start = 7; 2492 s_end = 0; 2493 s_inc = -1; 2494 } 2495 2496 shift = s_start; 2497 2498 for (i = 0; i < png_ptr->width; i++) 2499 { 2500 if (m & mask) 2501 { 2502 int value; 2503 2504 value = (*sp >> shift) & 0x1; 2505 *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); 2506 *dp |= (png_byte)(value << shift); 2507 } 2508 2509 if (shift == s_end) 2510 { 2511 shift = s_start; 2512 sp++; 2513 dp++; 2514 } 2515 else 2516 shift += s_inc; 2517 2518 if (m == 1) 2519 m = 0x80; 2520 else 2521 m >>= 1; 2522 } 2523 break; 2524 } /* end 1 bpp */ 2525 2526 case 2: /* png_ptr->row_info.pixel_depth */ 2527 { 2528 png_bytep sp; 2529 png_bytep dp; 2530 int s_start, s_end, s_inc; 2531 int m; 2532 int shift; 2533 png_uint_32 i; 2534 int value; 2535 2536 sp = png_ptr->row_buf + 1; 2537 dp = row; 2538 m = 0x80; 2539 #if defined(PNG_READ_PACKSWAP_SUPPORTED) 2540 if (png_ptr->transformations & PNG_PACKSWAP) 2541 { 2542 s_start = 0; 2543 s_end = 6; 2544 s_inc = 2; 2545 } 2546 else 2547 #endif 2548 { 2549 s_start = 6; 2550 s_end = 0; 2551 s_inc = -2; 2552 } 2553 2554 shift = s_start; 2555 2556 for (i = 0; i < png_ptr->width; i++) 2557 { 2558 if (m & mask) 2559 { 2560 value = (*sp >> shift) & 0x3; 2561 *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); 2562 *dp |= (png_byte)(value << shift); 2563 } 2564 2565 if (shift == s_end) 2566 { 2567 shift = s_start; 2568 sp++; 2569 dp++; 2570 } 2571 else 2572 shift += s_inc; 2573 if (m == 1) 2574 m = 0x80; 2575 else 2576 m >>= 1; 2577 } 2578 break; 2579 } /* end 2 bpp */ 2580 2581 case 4: /* png_ptr->row_info.pixel_depth */ 2582 { 2583 png_bytep sp; 2584 png_bytep dp; 2585 int s_start, s_end, s_inc; 2586 int m; 2587 int shift; 2588 png_uint_32 i; 2589 int value; 2590 2591 sp = png_ptr->row_buf + 1; 2592 dp = row; 2593 m = 0x80; 2594 #if defined(PNG_READ_PACKSWAP_SUPPORTED) 2595 if (png_ptr->transformations & PNG_PACKSWAP) 2596 { 2597 s_start = 0; 2598 s_end = 4; 2599 s_inc = 4; 2600 } 2601 else 2602 #endif 2603 { 2604 s_start = 4; 2605 s_end = 0; 2606 s_inc = -4; 2607 } 2608 shift = s_start; 2609 2610 for (i = 0; i < png_ptr->width; i++) 2611 { 2612 if (m & mask) 2613 { 2614 value = (*sp >> shift) & 0xf; 2615 *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); 2616 *dp |= (png_byte)(value << shift); 2617 } 2618 2619 if (shift == s_end) 2620 { 2621 shift = s_start; 2622 sp++; 2623 dp++; 2624 } 2625 else 2626 shift += s_inc; 2627 if (m == 1) 2628 m = 0x80; 2629 else 2630 m >>= 1; 2631 } 2632 break; 2633 } /* end 4 bpp */ 2634 2635 case 16: /* png_ptr->row_info.pixel_depth */ 2636 { 2637 png_bytep srcptr; 2638 png_bytep dstptr; 2639 2640 { 2641 register png_uint_32 i; 2642 png_uint_32 initial_val = BPP2 * png_pass_start[png_ptr->pass]; 2643 /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ 2644 register int stride = BPP2 * png_pass_inc[png_ptr->pass]; 2645 /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ 2646 register int rep_bytes = BPP2 * png_pass_width[png_ptr->pass]; 2647 /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ 2648 png_uint_32 len = png_ptr->width &~7; /* reduce to mult of 8 */ 2649 int diff = (int) (png_ptr->width & 7); /* amount lost */ 2650 register png_uint_32 final_val = BPP2 * len; /* GRR bugfix */ 2651 2652 srcptr = png_ptr->row_buf + 1 + initial_val; 2653 dstptr = row + initial_val; 2654 2655 for (i = initial_val; i < final_val; i += stride) 2656 { 2657 png_memcpy(dstptr, srcptr, rep_bytes); 2658 srcptr += stride; 2659 dstptr += stride; 2660 } 2661 if (diff) /* number of leftover pixels: 3 for pngtest */ 2662 { 2663 final_val += diff*BPP2; 2664 for (; i < final_val; i += stride) 2665 { 2666 if (rep_bytes > (int)(final_val-i)) 2667 rep_bytes = (int)(final_val-i); 2668 png_memcpy(dstptr, srcptr, rep_bytes); 2669 srcptr += stride; 2670 dstptr += stride; 2671 } 2672 } 2673 } /* end of else (_mmx_supported) */ 2674 2675 break; 2676 } /* end 16 bpp */ 2677 2678 2679 2680 case 48: /* png_ptr->row_info.pixel_depth */ 2681 { 2682 png_bytep srcptr; 2683 png_bytep dstptr; 2684 { 2685 register png_uint_32 i; 2686 png_uint_32 initial_val = BPP6 * png_pass_start[png_ptr->pass]; 2687 /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ 2688 register int stride = BPP6 * png_pass_inc[png_ptr->pass]; 2689 /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ 2690 register int rep_bytes = BPP6 * png_pass_width[png_ptr->pass]; 2691 /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ 2692 png_uint_32 len = png_ptr->width &~7; /* reduce to mult of 8 */ 2693 int diff = (int) (png_ptr->width & 7); /* amount lost */ 2694 register png_uint_32 final_val = BPP6 * len; /* GRR bugfix */ 2695 2696 srcptr = png_ptr->row_buf + 1 + initial_val; 2697 dstptr = row + initial_val; 2698 2699 for (i = initial_val; i < final_val; i += stride) 2700 { 2701 png_memcpy(dstptr, srcptr, rep_bytes); 2702 srcptr += stride; 2703 dstptr += stride; 2704 } 2705 if (diff) /* number of leftover pixels: 3 for pngtest */ 2706 { 2707 final_val += diff*BPP6; 2708 for (; i < final_val; i += stride) 2709 { 2710 if (rep_bytes > (int)(final_val-i)) 2711 rep_bytes = (int)(final_val-i); 2712 png_memcpy(dstptr, srcptr, rep_bytes); 2713 srcptr += stride; 2714 dstptr += stride; 2715 } 2716 } 2717 } 2718 break; 2719 } /* end 48 bpp */ 2720 2721 case 64: /* png_ptr->row_info.pixel_depth */ 2722 { 2723 png_bytep srcptr; 2724 png_bytep dstptr; 2725 register png_uint_32 i; 2726 png_uint_32 initial_val = BPP8 * png_pass_start[png_ptr->pass]; 2727 /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ 2728 register int stride = BPP8 * png_pass_inc[png_ptr->pass]; 2729 /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ 2730 register int rep_bytes = BPP8 * png_pass_width[png_ptr->pass]; 2731 /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ 2732 png_uint_32 len = png_ptr->width &~7; /* reduce to mult of 8 */ 2733 int diff = (int) (png_ptr->width & 7); /* amount lost */ 2734 register png_uint_32 final_val = BPP8 * len; /* GRR bugfix */ 2735 2736 srcptr = png_ptr->row_buf + 1 + initial_val; 2737 dstptr = row + initial_val; 2738 2739 for (i = initial_val; i < final_val; i += stride) 2740 { 2741 png_memcpy(dstptr, srcptr, rep_bytes); 2742 srcptr += stride; 2743 dstptr += stride; 2744 } 2745 if (diff) /* number of leftover pixels: 3 for pngtest */ 2746 { 2747 final_val += diff*BPP8; 2748 for (; i < final_val; i += stride) 2749 { 2750 if (rep_bytes > (int)(final_val-i)) 2751 rep_bytes = (int)(final_val-i); 2752 png_memcpy(dstptr, srcptr, rep_bytes); 2753 srcptr += stride; 2754 dstptr += stride; 2755 } 2756 } 2757 2758 break; 2759 } /* end 64 bpp */ 2760 2761 default: /* png_ptr->row_info.pixel_depth != 1,2,4,8,16,24,32,48,64 */ 2762 { 2763 /* this should never happen */ 2764 png_warning(png_ptr, "Invalid row_info.pixel_depth in pngrutil"); 2765 break; 2766 } 2767 } /* end switch (png_ptr->row_info.pixel_depth) */ 2768 2769 } /* end if (non-trivial mask) */ 2770 2771 } /* end png_combine_row() */ 2772 #endif /* PNG_HAVE_MMX_COMBINE_ROW */ 2773 2774 2775 2776 /*===========================================================================*/ 2777 /* */ 2778 /* P N G _ D O _ R E A D _ I N T E R L A C E */ 2779 /* */ 2780 /*===========================================================================*/ 2781 2782 #if defined(PNG_READ_INTERLACING_SUPPORTED) 2783 #if !defined(PNG_HAVE_MMX_READ_INTERLACE) 2784 2785 /* png_do_read_interlace() is called after any 16-bit to 8-bit conversion 2786 * has taken place. [GRR: what other steps come before and/or after?] 2787 */ 2788 2789 void /* PRIVATE */ 2790 png_do_read_interlace(png_structp png_ptr) 2791 { 2792 #if defined(PNG_USE_LOCAL_ARRAYS) 2793 static PNG_CONST int FARDATA png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 2794 #endif 2795 png_row_infop row_info = &(png_ptr->row_info); 2796 png_bytep row = png_ptr->row_buf + 1; 2797 int pass = png_ptr->pass; 2798 #if defined(PNG_READ_PACKSWAP_SUPPORTED) 2799 png_uint_32 transformations = png_ptr->transformations; 2800 #endif 2801 png_debug(1,"in png_do_read_interlace (pngrutil.c OPTIMIZED)\n"); 2802 2803 if (row != NULL && row_info != NULL) 2804 { 2805 png_uint_32 final_width; 2806 2807 final_width = row_info->width * png_pass_inc[pass]; 2808 2809 switch (row_info->pixel_depth) 2810 { 2811 case 1: 2812 { 2813 png_bytep sp, dp; 2814 int sshift, dshift; 2815 int s_start, s_end, s_inc; 2816 png_byte v; 2817 png_uint_32 i; 2818 int j; 2819 2820 sp = row + (png_size_t)((row_info->width - 1) >> 3); 2821 dp = row + (png_size_t)((final_width - 1) >> 3); 2822 #if defined(PNG_READ_PACKSWAP_SUPPORTED) 2823 if (transformations & PNG_PACKSWAP) 2824 { 2825 sshift = (int)((row_info->width + 7) & 7); 2826 dshift = (int)((final_width + 7) & 7); 2827 s_start = 7; 2828 s_end = 0; 2829 s_inc = -1; 2830 } 2831 else 2832 #endif 2833 { 2834 sshift = 7 - (int)((row_info->width + 7) & 7); 2835 dshift = 7 - (int)((final_width + 7) & 7); 2836 s_start = 0; 2837 s_end = 7; 2838 s_inc = 1; 2839 } 2840 2841 for (i = row_info->width; i; i--) 2842 { 2843 v = (png_byte)((*sp >> sshift) & 0x1); 2844 for (j = 0; j < png_pass_inc[pass]; j++) 2845 { 2846 *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); 2847 *dp |= (png_byte)(v << dshift); 2848 if (dshift == s_end) 2849 { 2850 dshift = s_start; 2851 dp--; 2852 } 2853 else 2854 dshift += s_inc; 2855 } 2856 if (sshift == s_end) 2857 { 2858 sshift = s_start; 2859 sp--; 2860 } 2861 else 2862 sshift += s_inc; 2863 } 2864 break; 2865 } 2866 2867 case 2: 2868 { 2869 png_bytep sp, dp; 2870 int sshift, dshift; 2871 int s_start, s_end, s_inc; 2872 png_uint_32 i; 2873 2874 sp = row + (png_size_t)((row_info->width - 1) >> 2); 2875 dp = row + (png_size_t)((final_width - 1) >> 2); 2876 #if defined(PNG_READ_PACKSWAP_SUPPORTED) 2877 if (transformations & PNG_PACKSWAP) 2878 { 2879 sshift = (png_size_t)(((row_info->width + 3) & 3) << 1); 2880 dshift = (png_size_t)(((final_width + 3) & 3) << 1); 2881 s_start = 6; 2882 s_end = 0; 2883 s_inc = -2; 2884 } 2885 else 2886 #endif 2887 { 2888 sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1); 2889 dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1); 2890 s_start = 0; 2891 s_end = 6; 2892 s_inc = 2; 2893 } 2894 2895 for (i = row_info->width; i; i--) 2896 { 2897 png_byte v; 2898 int j; 2899 2900 v = (png_byte)((*sp >> sshift) & 0x3); 2901 for (j = 0; j < png_pass_inc[pass]; j++) 2902 { 2903 *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); 2904 *dp |= (png_byte)(v << dshift); 2905 if (dshift == s_end) 2906 { 2907 dshift = s_start; 2908 dp--; 2909 } 2910 else 2911 dshift += s_inc; 2912 } 2913 if (sshift == s_end) 2914 { 2915 sshift = s_start; 2916 sp--; 2917 } 2918 else 2919 sshift += s_inc; 2920 } 2921 break; 2922 } 2923 2924 case 4: 2925 { 2926 png_bytep sp, dp; 2927 int sshift, dshift; 2928 int s_start, s_end, s_inc; 2929 png_uint_32 i; 2930 2931 sp = row + (png_size_t)((row_info->width - 1) >> 1); 2932 dp = row + (png_size_t)((final_width - 1) >> 1); 2933 #if defined(PNG_READ_PACKSWAP_SUPPORTED) 2934 if (transformations & PNG_PACKSWAP) 2935 { 2936 sshift = (png_size_t)(((row_info->width + 1) & 1) << 2); 2937 dshift = (png_size_t)(((final_width + 1) & 1) << 2); 2938 s_start = 4; 2939 s_end = 0; 2940 s_inc = -4; 2941 } 2942 else 2943 #endif 2944 { 2945 sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2); 2946 dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2); 2947 s_start = 0; 2948 s_end = 4; 2949 s_inc = 4; 2950 } 2951 2952 for (i = row_info->width; i; i--) 2953 { 2954 png_byte v; 2955 int j; 2956 2957 v = (png_byte)((*sp >> sshift) & 0xf); 2958 for (j = 0; j < png_pass_inc[pass]; j++) 2959 { 2960 *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); 2961 *dp |= (png_byte)(v << dshift); 2962 if (dshift == s_end) 2963 { 2964 dshift = s_start; 2965 dp--; 2966 } 2967 else 2968 dshift += s_inc; 2969 } 2970 if (sshift == s_end) 2971 { 2972 sshift = s_start; 2973 sp--; 2974 } 2975 else 2976 sshift += s_inc; 2977 } 2978 break; 2979 } 2980 2981 /*====================================================================*/ 2982 2983 default: /* 8-bit or larger (this is where the routine is modified) */ 2984 { 2985 png_bytep sptr, dp; 2986 png_uint_32 i; 2987 png_size_t pixel_bytes; 2988 int width = (int)row_info->width; 2989 2990 pixel_bytes = (row_info->pixel_depth >> 3); 2991 2992 /* point sptr at the last pixel in the pre-expanded row: */ 2993 sptr = row + (width - 1) * pixel_bytes; 2994 2995 /* point dp at the last pixel position in the expanded row: */ 2996 dp = row + (final_width - 1) * pixel_bytes; 2997 2998 /* MMX not supported: use modified C code - takes advantage 2999 * of inlining of png_memcpy for a constant */ 3000 /* GRR 19991007: does it? or should pixel_bytes in each 3001 * block be replaced with immediate value (e.g., 1)? */ 3002 /* GRR 19991017: replaced with constants in each case */ 3003 { 3004 if (pixel_bytes == 1) 3005 { 3006 for (i = width; i; i--) 3007 { 3008 int j; 3009 for (j = 0; j < png_pass_inc[pass]; j++) 3010 { 3011 *dp-- = *sptr; 3012 } 3013 --sptr; 3014 } 3015 } 3016 else if (pixel_bytes == 3) 3017 { 3018 for (i = width; i; i--) 3019 { 3020 png_byte v[8]; 3021 int j; 3022 png_memcpy(v, sptr, 3); 3023 for (j = 0; j < png_pass_inc[pass]; j++) 3024 { 3025 png_memcpy(dp, v, 3); 3026 dp -= 3; 3027 } 3028 sptr -= 3; 3029 } 3030 } 3031 else if (pixel_bytes == 2) 3032 { 3033 for (i = width; i; i--) 3034 { 3035 png_byte v[8]; 3036 int j; 3037 png_memcpy(v, sptr, 2); 3038 for (j = 0; j < png_pass_inc[pass]; j++) 3039 { 3040 png_memcpy(dp, v, 2); 3041 dp -= 2; 3042 } 3043 sptr -= 2; 3044 } 3045 } 3046 else if (pixel_bytes == 4) 3047 { 3048 for (i = width; i; i--) 3049 { 3050 png_byte v[8]; 3051 int j; 3052 png_memcpy(v, sptr, 4); 3053 for (j = 0; j < png_pass_inc[pass]; j++) 3054 { 3055 #if defined(PNG_DEBUG) && defined(PNG_1_0_X) 3056 if (dp < row || dp+3 > row+png_ptr->row_buf_size) 3057 { 3058 printf("dp out of bounds: row=%d, dp=%d, rp=%d\n", 3059 row, dp, row+png_ptr->row_buf_size); 3060 printf("row_buf=%d\n",png_ptr->row_buf_size); 3061 } 3062 #endif 3063 png_memcpy(dp, v, 4); 3064 dp -= 4; 3065 } 3066 sptr -= 4; 3067 } 3068 } 3069 else if (pixel_bytes == 6) 3070 { 3071 for (i = width; i; i--) 3072 { 3073 png_byte v[8]; 3074 int j; 3075 png_memcpy(v, sptr, 6); 3076 for (j = 0; j < png_pass_inc[pass]; j++) 3077 { 3078 png_memcpy(dp, v, 6); 3079 dp -= 6; 3080 } 3081 sptr -= 6; 3082 } 3083 } 3084 else if (pixel_bytes == 8) 3085 { 3086 for (i = width; i; i--) 3087 { 3088 png_byte v[8]; 3089 int j; 3090 png_memcpy(v, sptr, 8); 3091 for (j = 0; j < png_pass_inc[pass]; j++) 3092 { 3093 png_memcpy(dp, v, 8); 3094 dp -= 8; 3095 } 3096 sptr -= 8; 3097 } 3098 } 3099 else /* GRR: should never be reached */ 3100 { 3101 for (i = width; i; i--) 3102 { 3103 png_byte v[8]; 3104 int j; 3105 png_memcpy(v, sptr, pixel_bytes); 3106 for (j = 0; j < png_pass_inc[pass]; j++) 3107 { 3108 png_memcpy(dp, v, pixel_bytes); 3109 dp -= pixel_bytes; 3110 } 3111 sptr -= pixel_bytes; 3112 } 3113 } 3114 3115 } 3116 break; 3117 } 3118 } /* end switch (row_info->pixel_depth) */ 3119 3120 row_info->width = final_width; 3121 3122 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width); 3123 } 3124 3125 } /* end png_do_read_interlace() */ 3126 3127 #endif /* PNG_HAVE_MMX_READ_INTERLACE */ 3128 #endif /* PNG_READ_INTERLACING_SUPPORTED */ 3129 3130 3131 3132 #if !defined(PNG_HAVE_MMX_READ_FILTER_ROW) 3133 /*===========================================================================*/ 3134 /* */ 3135 /* P N G _ R E A D _ F I L T E R _ R O W */ 3136 /* */ 3137 /*===========================================================================*/ 3138 3139 3140 /* Optimized png_read_filter_row routines */ 3141 3142 void /* PRIVATE */ 3143 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep 3144 row, png_bytep prev_row, int filter) 3145 { 3146 #if defined(PNG_DEBUG) 3147 char filnm[10]; 3148 #endif 3149 3150 3151 #if defined(PNG_DEBUG) 3152 png_debug(1, "in png_read_filter_row (pngrutil.c OPTIMIZED)\n"); 3153 switch (filter) 3154 { 3155 case 0: 3156 png_snprintf(filnm, 10, "none"); 3157 break; 3158 3159 case 1: 3160 png_snprintf(filnm, 10, "sub-%s", 3161 "x86"); 3162 break; 3163 3164 case 2: 3165 png_snprintf(filnm, 10, "up-%s", 3166 "x86"); 3167 break; 3168 3169 case 3: 3170 png_snprintf(filnm, 10, "avg-%s", 3171 "x86"); 3172 break; 3173 3174 case 4: 3175 png_snprintf(filnm, 10, "Paeth-%s", 3176 "x86"); 3177 break; 3178 3179 default: 3180 png_snprintf(filnm, 10, "unknown"); 3181 break; 3182 } 3183 png_debug2(0, "row_number=%5ld, %10s, ", png_ptr->row_number, filnm); 3184 png_debug1(0, "row=0x%08lx, ", (unsigned long)row); 3185 png_debug2(0, "pixdepth=%2d, bytes=%d, ", (int)row_info->pixel_depth, 3186 (int)((row_info->pixel_depth + 7) >> 3)); 3187 png_debug1(0,"rowbytes=%8ld\n", row_info->rowbytes); 3188 #endif /* PNG_DEBUG */ 3189 3190 switch (filter) 3191 { 3192 case PNG_FILTER_VALUE_NONE: 3193 break; 3194 3195 case PNG_FILTER_VALUE_SUB: 3196 { 3197 png_uint_32 i; 3198 png_uint_32 istop = row_info->rowbytes; 3199 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 3200 png_bytep rp = row + bpp; 3201 png_bytep lp = row; 3202 3203 for (i = bpp; i < istop; i++) 3204 { 3205 *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); 3206 rp++; 3207 } 3208 } 3209 break; 3210 3211 case PNG_FILTER_VALUE_UP: 3212 { 3213 png_uint_32 i; 3214 png_uint_32 istop = row_info->rowbytes; 3215 png_bytep rp = row; 3216 png_bytep pp = prev_row; 3217 3218 for (i = 0; i < istop; ++i) 3219 { 3220 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); 3221 rp++; 3222 } 3223 } 3224 break; 3225 3226 case PNG_FILTER_VALUE_AVG: 3227 { 3228 png_uint_32 i; 3229 png_bytep rp = row; 3230 png_bytep pp = prev_row; 3231 png_bytep lp = row; 3232 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 3233 png_uint_32 istop = row_info->rowbytes - bpp; 3234 3235 for (i = 0; i < bpp; i++) 3236 { 3237 *rp = (png_byte)(((int)(*rp) + 3238 ((int)(*pp++) >> 1)) & 0xff); 3239 rp++; 3240 } 3241 3242 for (i = 0; i < istop; i++) 3243 { 3244 *rp = (png_byte)(((int)(*rp) + 3245 ((int)(*pp++ + *lp++) >> 1)) & 0xff); 3246 rp++; 3247 } 3248 } 3249 break; 3250 3251 case PNG_FILTER_VALUE_PAETH: 3252 { 3253 png_uint_32 i; 3254 png_bytep rp = row; 3255 png_bytep pp = prev_row; 3256 png_bytep lp = row; 3257 png_bytep cp = prev_row; 3258 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 3259 png_uint_32 istop = row_info->rowbytes - bpp; 3260 3261 for (i = 0; i < bpp; i++) 3262 { 3263 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); 3264 rp++; 3265 } 3266 3267 for (i = 0; i < istop; i++) /* use leftover rp,pp */ 3268 { 3269 int a, b, c, pa, pb, pc, p; 3270 3271 a = *lp++; 3272 b = *pp++; 3273 c = *cp++; 3274 3275 p = b - c; 3276 pc = a - c; 3277 3278 #if defined(PNG_USE_ABS) 3279 pa = abs(p); 3280 pb = abs(pc); 3281 pc = abs(p + pc); 3282 #else 3283 pa = p < 0 ? -p : p; 3284 pb = pc < 0 ? -pc : pc; 3285 pc = (p + pc) < 0 ? -(p + pc) : p + pc; 3286 #endif 3287 3288 /* 3289 if (pa <= pb && pa <= pc) 3290 p = a; 3291 else if (pb <= pc) 3292 p = b; 3293 else 3294 p = c; 3295 */ 3296 3297 p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c; 3298 3299 *rp = (png_byte)(((int)(*rp) + p) & 0xff); 3300 rp++; 3301 } 3302 } 3303 break; 3304 3305 default: 3306 png_warning(png_ptr, "Ignoring bad row-filter type"); 3307 *row=0; 3308 break; 3309 } 3310 } 3311 3312 #endif /* PNG_HAVE_MMX_READ_FILTER_ROW */ 3313 #endif /* PNG_OPTIMIZED_CODE_SUPPORTED */ 3314 3315 #if !defined(PNG_USE_PNGGCCRD) && !defined(PNG_USE_PNGVCRD) 3316 #if !defined(PNG_OPTIMIZED_CODE_SUPPORTED) 3317 /* Use the unoptimized original C code. This might be removed from a future 3318 * version of libpng if testing proves it to be worthless. */ 3319 void /* PRIVATE */ 3320 png_combine_row(png_structp png_ptr, png_bytep row, int mask) 3321 { 3322 png_debug(1,"in png_combine_row NOT OPTIMIZED\n"); 3323 if (mask == 0xff) 3324 { 3325 png_memcpy(row, png_ptr->row_buf + 1, 3326 PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)); 3327 } 3328 else 3329 { 3330 switch (png_ptr->row_info.pixel_depth) 3331 { 3332 case 1: 3333 { 3334 png_bytep sp = png_ptr->row_buf + 1; 3335 png_bytep dp = row; 3336 int s_inc, s_start, s_end; 3337 int m = 0x80; 3338 int shift; 3339 png_uint_32 i; 3340 png_uint_32 row_width = png_ptr->width; 3341 3342 #if defined(PNG_READ_PACKSWAP_SUPPORTED) 3343 if (png_ptr->transformations & PNG_PACKSWAP) 3344 { 3345 s_start = 0; 3346 s_end = 7; 3347 s_inc = 1; 3348 } 3349 else 3350 #endif 3351 { 3352 s_start = 7; 3353 s_end = 0; 3354 s_inc = -1; 3355 } 3356 3357 shift = s_start; 3358 3359 for (i = 0; i < row_width; i++) 3360 { 3361 if (m & mask) 3362 { 3363 int value; 3364 3365 value = (*sp >> shift) & 0x01; 3366 *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); 3367 *dp |= (png_byte)(value << shift); 3368 } 3369 3370 if (shift == s_end) 3371 { 3372 shift = s_start; 3373 sp++; 3374 dp++; 3375 } 3376 else 3377 shift += s_inc; 3378 3379 if (m == 1) 3380 m = 0x80; 3381 else 3382 m >>= 1; 3383 } 3384 break; 3385 } 3386 case 2: 3387 { 3388 png_bytep sp = png_ptr->row_buf + 1; 3389 png_bytep dp = row; 3390 int s_start, s_end, s_inc; 3391 int m = 0x80; 3392 int shift; 3393 png_uint_32 i; 3394 png_uint_32 row_width = png_ptr->width; 3395 int value; 3396 3397 #if defined(PNG_READ_PACKSWAP_SUPPORTED) 3398 if (png_ptr->transformations & PNG_PACKSWAP) 3399 { 3400 s_start = 0; 3401 s_end = 6; 3402 s_inc = 2; 3403 } 3404 else 3405 #endif 3406 { 3407 s_start = 6; 3408 s_end = 0; 3409 s_inc = -2; 3410 } 3411 3412 shift = s_start; 3413 3414 for (i = 0; i < row_width; i++) 3415 { 3416 if (m & mask) 3417 { 3418 value = (*sp >> shift) & 0x03; 3419 *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); 3420 *dp |= (png_byte)(value << shift); 3421 } 3422 3423 if (shift == s_end) 3424 { 3425 shift = s_start; 3426 sp++; 3427 dp++; 3428 } 3429 else 3430 shift += s_inc; 3431 if (m == 1) 3432 m = 0x80; 3433 else 3434 m >>= 1; 3435 } 3436 break; 3437 } 3438 case 4: 3439 { 3440 png_bytep sp = png_ptr->row_buf + 1; 3441 png_bytep dp = row; 3442 int s_start, s_end, s_inc; 3443 int m = 0x80; 3444 int shift; 3445 png_uint_32 i; 3446 png_uint_32 row_width = png_ptr->width; 3447 int value; 3448 3449 #if defined(PNG_READ_PACKSWAP_SUPPORTED) 3450 if (png_ptr->transformations & PNG_PACKSWAP) 3451 { 3452 s_start = 0; 3453 s_end = 4; 3454 s_inc = 4; 3455 } 3456 else 3457 #endif 3458 { 3459 s_start = 4; 3460 s_end = 0; 3461 s_inc = -4; 3462 } 3463 shift = s_start; 3464 3465 for (i = 0; i < row_width; i++) 3466 { 3467 if (m & mask) 3468 { 3469 value = (*sp >> shift) & 0xf; 3470 *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); 3471 *dp |= (png_byte)(value << shift); 3472 } 3473 3474 if (shift == s_end) 3475 { 3476 shift = s_start; 3477 sp++; 3478 dp++; 3479 } 3480 else 3481 shift += s_inc; 3482 if (m == 1) 3483 m = 0x80; 3484 else 3485 m >>= 1; 3486 } 3487 break; 3488 } 3489 default: 3490 { 3491 png_bytep sp = png_ptr->row_buf + 1; 3492 png_bytep dp = row; 3493 png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); 3494 png_uint_32 i; 3495 png_uint_32 row_width = png_ptr->width; 3496 png_byte m = 0x80; 3497 3498 3499 for (i = 0; i < row_width; i++) 3500 { 3501 if (m & mask) 3502 { 3503 png_memcpy(dp, sp, pixel_bytes); 3504 } 3505 3506 sp += pixel_bytes; 3507 dp += pixel_bytes; 3508 3509 if (m == 1) 3510 m = 0x80; 3511 else 3512 m >>= 1; 3513 } 3514 break; 3515 } 3516 } 3517 } 3518 } 3519 3520 #ifdef PNG_READ_INTERLACING_SUPPORTED 3521 /* OLD pre-1.0.9 interface: 3522 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, 3523 png_uint_32 transformations) 3524 */ 3525 void /* PRIVATE */ 3526 png_do_read_interlace(png_structp png_ptr) 3527 { 3528 png_row_infop row_info = &(png_ptr->row_info); 3529 png_bytep row = png_ptr->row_buf + 1; 3530 int pass = png_ptr->pass; 3531 png_uint_32 transformations = png_ptr->transformations; 3532 #ifdef PNG_USE_LOCAL_ARRAYS 3533 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 3534 /* offset to next interlace block */ 3535 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 3536 #endif 3537 3538 png_debug(1,"in png_do_read_interlace (pngrutil.c NOT OPTIMIZED)\n"); 3539 if (row != NULL && row_info != NULL) 3540 { 3541 png_uint_32 final_width; 3542 3543 final_width = row_info->width * png_pass_inc[pass]; 3544 3545 switch (row_info->pixel_depth) 3546 { 3547 case 1: 3548 { 3549 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3); 3550 png_bytep dp = row + (png_size_t)((final_width - 1) >> 3); 3551 int sshift, dshift; 3552 int s_start, s_end, s_inc; 3553 int jstop = png_pass_inc[pass]; 3554 png_byte v; 3555 png_uint_32 i; 3556 int j; 3557 3558 #if defined(PNG_READ_PACKSWAP_SUPPORTED) 3559 if (transformations & PNG_PACKSWAP) 3560 { 3561 sshift = (int)((row_info->width + 7) & 0x07); 3562 dshift = (int)((final_width + 7) & 0x07); 3563 s_start = 7; 3564 s_end = 0; 3565 s_inc = -1; 3566 } 3567 else 3568 #endif 3569 { 3570 sshift = 7 - (int)((row_info->width + 7) & 0x07); 3571 dshift = 7 - (int)((final_width + 7) & 0x07); 3572 s_start = 0; 3573 s_end = 7; 3574 s_inc = 1; 3575 } 3576 3577 for (i = 0; i < row_info->width; i++) 3578 { 3579 v = (png_byte)((*sp >> sshift) & 0x01); 3580 for (j = 0; j < jstop; j++) 3581 { 3582 *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); 3583 *dp |= (png_byte)(v << dshift); 3584 if (dshift == s_end) 3585 { 3586 dshift = s_start; 3587 dp--; 3588 } 3589 else 3590 dshift += s_inc; 3591 } 3592 if (sshift == s_end) 3593 { 3594 sshift = s_start; 3595 sp--; 3596 } 3597 else 3598 sshift += s_inc; 3599 } 3600 break; 3601 } 3602 case 2: 3603 { 3604 png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); 3605 png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2); 3606 int sshift, dshift; 3607 int s_start, s_end, s_inc; 3608 int jstop = png_pass_inc[pass]; 3609 png_uint_32 i; 3610 3611 #if defined(PNG_READ_PACKSWAP_SUPPORTED) 3612 if (transformations & PNG_PACKSWAP) 3613 { 3614 sshift = (int)(((row_info->width + 3) & 0x03) << 1); 3615 dshift = (int)(((final_width + 3) & 0x03) << 1); 3616 s_start = 6; 3617 s_end = 0; 3618 s_inc = -2; 3619 } 3620 else 3621 #endif 3622 { 3623 sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1); 3624 dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1); 3625 s_start = 0; 3626 s_end = 6; 3627 s_inc = 2; 3628 } 3629 3630 for (i = 0; i < row_info->width; i++) 3631 { 3632 png_byte v; 3633 int j; 3634 3635 v = (png_byte)((*sp >> sshift) & 0x03); 3636 for (j = 0; j < jstop; j++) 3637 { 3638 *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); 3639 *dp |= (png_byte)(v << dshift); 3640 if (dshift == s_end) 3641 { 3642 dshift = s_start; 3643 dp--; 3644 } 3645 else 3646 dshift += s_inc; 3647 } 3648 if (sshift == s_end) 3649 { 3650 sshift = s_start; 3651 sp--; 3652 } 3653 else 3654 sshift += s_inc; 3655 } 3656 break; 3657 } 3658 case 4: 3659 { 3660 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1); 3661 png_bytep dp = row + (png_size_t)((final_width - 1) >> 1); 3662 int sshift, dshift; 3663 int s_start, s_end, s_inc; 3664 png_uint_32 i; 3665 int jstop = png_pass_inc[pass]; 3666 3667 #if defined(PNG_READ_PACKSWAP_SUPPORTED) 3668 if (transformations & PNG_PACKSWAP) 3669 { 3670 sshift = (int)(((row_info->width + 1) & 0x01) << 2); 3671 dshift = (int)(((final_width + 1) & 0x01) << 2); 3672 s_start = 4; 3673 s_end = 0; 3674 s_inc = -4; 3675 } 3676 else 3677 #endif 3678 { 3679 sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2); 3680 dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2); 3681 s_start = 0; 3682 s_end = 4; 3683 s_inc = 4; 3684 } 3685 3686 for (i = 0; i < row_info->width; i++) 3687 { 3688 png_byte v = (png_byte)((*sp >> sshift) & 0xf); 3689 int j; 3690 3691 for (j = 0; j < jstop; j++) 3692 { 3693 *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); 3694 *dp |= (png_byte)(v << dshift); 3695 if (dshift == s_end) 3696 { 3697 dshift = s_start; 3698 dp--; 3699 } 3700 else 3701 dshift += s_inc; 3702 } 3703 if (sshift == s_end) 3704 { 3705 sshift = s_start; 3706 sp--; 3707 } 3708 else 3709 sshift += s_inc; 3710 } 3711 break; 3712 } 3713 default: 3714 { 3715 png_size_t pixel_bytes = (row_info->pixel_depth >> 3); 3716 png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes; 3717 png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes; 3718 3719 int jstop = png_pass_inc[pass]; 3720 png_uint_32 i; 3721 3722 for (i = 0; i < row_info->width; i++) 3723 { 3724 png_byte v[8]; 3725 int j; 3726 3727 png_memcpy(v, sp, pixel_bytes); 3728 for (j = 0; j < jstop; j++) 3729 { 3730 png_memcpy(dp, v, pixel_bytes); 3731 dp -= pixel_bytes; 3732 } 3733 sp -= pixel_bytes; 3734 } 3735 break; 3736 } 3737 } 3738 row_info->width = final_width; 3739 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width); 3740 } 3741 #if !defined(PNG_READ_PACKSWAP_SUPPORTED) 3742 transformations = transformations; /* silence compiler warning */ 3743 #endif 3744 } 3745 #endif /* PNG_READ_INTERLACING_SUPPORTED */ 3746 3747 void /* PRIVATE */ 3748 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, 3749 png_bytep prev_row, int filter) 3750 { 3751 png_debug(1, "in png_read_filter_row (NOT OPTIMIZED)\n"); 3752 png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter); 3753 switch (filter) 3754 { 3755 case PNG_FILTER_VALUE_NONE: 3756 break; 3757 case PNG_FILTER_VALUE_SUB: 3758 { 3759 png_uint_32 i; 3760 png_uint_32 istop = row_info->rowbytes; 3761 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 3762 png_bytep rp = row + bpp; 3763 png_bytep lp = row; 3764 3765 for (i = bpp; i < istop; i++) 3766 { 3767 *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); 3768 rp++; 3769 } 3770 break; 3771 } 3772 case PNG_FILTER_VALUE_UP: 3773 { 3774 png_uint_32 i; 3775 png_uint_32 istop = row_info->rowbytes; 3776 png_bytep rp = row; 3777 png_bytep pp = prev_row; 3778 3779 for (i = 0; i < istop; i++) 3780 { 3781 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); 3782 rp++; 3783 } 3784 break; 3785 } 3786 case PNG_FILTER_VALUE_AVG: 3787 { 3788 png_uint_32 i; 3789 png_bytep rp = row; 3790 png_bytep pp = prev_row; 3791 png_bytep lp = row; 3792 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 3793 png_uint_32 istop = row_info->rowbytes - bpp; 3794 3795 for (i = 0; i < bpp; i++) 3796 { 3797 *rp = (png_byte)(((int)(*rp) + 3798 ((int)(*pp++) / 2 )) & 0xff); 3799 rp++; 3800 } 3801 3802 for (i = 0; i < istop; i++) 3803 { 3804 *rp = (png_byte)(((int)(*rp) + 3805 (int)(*pp++ + *lp++) / 2 ) & 0xff); 3806 rp++; 3807 } 3808 break; 3809 } 3810 case PNG_FILTER_VALUE_PAETH: 3811 { 3812 png_uint_32 i; 3813 png_bytep rp = row; 3814 png_bytep pp = prev_row; 3815 png_bytep lp = row; 3816 png_bytep cp = prev_row; 3817 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 3818 png_uint_32 istop=row_info->rowbytes - bpp; 3819 3820 for (i = 0; i < bpp; i++) 3821 { 3822 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); 3823 rp++; 3824 } 3825 3826 for (i = 0; i < istop; i++) /* use leftover rp,pp */ 3827 { 3828 int a, b, c, pa, pb, pc, p; 3829 3830 a = *lp++; 3831 b = *pp++; 3832 c = *cp++; 3833 3834 p = b - c; 3835 pc = a - c; 3836 3837 #ifdef PNG_USE_ABS 3838 pa = abs(p); 3839 pb = abs(pc); 3840 pc = abs(p + pc); 3841 #else 3842 pa = p < 0 ? -p : p; 3843 pb = pc < 0 ? -pc : pc; 3844 pc = (p + pc) < 0 ? -(p + pc) : p + pc; 3845 #endif 3846 3847 /* 3848 if (pa <= pb && pa <= pc) 3849 p = a; 3850 else if (pb <= pc) 3851 p = b; 3852 else 3853 p = c; 3854 */ 3855 3856 p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; 3857 3858 *rp = (png_byte)(((int)(*rp) + p) & 0xff); 3859 rp++; 3860 } 3861 break; 3862 } 3863 default: 3864 png_warning(png_ptr, "Ignoring bad adaptive filter type"); 3865 *row=0; 3866 break; 3867 } 3868 } 3869 #endif /* !PNG_OPTIMIZED_CODE_SUPPORTED */ 3870 #endif /* !PNG_USE_PNGGCCRD && !PNG_USE_PNGVCRD */ 3871 3872 void /* PRIVATE */ 3873 png_read_finish_row(png_structp png_ptr) 3874 { 3875 #ifdef PNG_USE_LOCAL_ARRAYS 3876 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 3877 3878 /* start of interlace block */ 3879 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 3880 3881 /* offset to next interlace block */ 3882 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 3883 3884 /* start of interlace block in the y direction */ 3885 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 3886 3887 /* offset to next interlace block in the y direction */ 3888 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 3889 #endif 3890 3891 png_debug(1, "in png_read_finish_row\n"); 3892 png_ptr->row_number++; 3893 if (png_ptr->row_number < png_ptr->num_rows) 3894 return; 3895 3896 if (png_ptr->interlaced) 3897 { 3898 png_ptr->row_number = 0; 3899 png_memset_check(png_ptr, png_ptr->prev_row, 0, 3900 png_ptr->rowbytes + 1); 3901 do 3902 { 3903 png_ptr->pass++; 3904 if (png_ptr->pass >= 7) 3905 break; 3906 png_ptr->iwidth = (png_ptr->width + 3907 png_pass_inc[png_ptr->pass] - 1 - 3908 png_pass_start[png_ptr->pass]) / 3909 png_pass_inc[png_ptr->pass]; 3910 3911 png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, 3912 png_ptr->iwidth) + 1; 3913 3914 if (!(png_ptr->transformations & PNG_INTERLACE)) 3915 { 3916 png_ptr->num_rows = (png_ptr->height + 3917 png_pass_yinc[png_ptr->pass] - 1 - 3918 png_pass_ystart[png_ptr->pass]) / 3919 png_pass_yinc[png_ptr->pass]; 3920 if (!(png_ptr->num_rows)) 3921 continue; 3922 } 3923 else /* if (png_ptr->transformations & PNG_INTERLACE) */ 3924 break; 3925 } while (png_ptr->iwidth == 0); 3926 3927 if (png_ptr->pass < 7) 3928 return; 3929 } 3930 3931 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) 3932 { 3933 #ifdef PNG_USE_LOCAL_ARRAYS 3934 PNG_CONST PNG_IDAT; 3935 #endif 3936 char extra; 3937 int ret; 3938 3939 png_ptr->zstream.next_out = (Byte *)&extra; 3940 png_ptr->zstream.avail_out = (uInt)1; 3941 for(;;) 3942 { 3943 if (!(png_ptr->zstream.avail_in)) 3944 { 3945 while (!png_ptr->idat_size) 3946 { 3947 png_byte chunk_length[4]; 3948 3949 png_crc_finish(png_ptr, 0); 3950 3951 png_read_data(png_ptr, chunk_length, 4); 3952 png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length); 3953 png_reset_crc(png_ptr); 3954 png_crc_read(png_ptr, png_ptr->chunk_name, 4); 3955 if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) 3956 png_error(png_ptr, "Not enough image data"); 3957 3958 } 3959 png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; 3960 png_ptr->zstream.next_in = png_ptr->zbuf; 3961 if (png_ptr->zbuf_size > png_ptr->idat_size) 3962 png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; 3963 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in); 3964 png_ptr->idat_size -= png_ptr->zstream.avail_in; 3965 } 3966 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); 3967 if (ret == Z_STREAM_END) 3968 { 3969 if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in || 3970 png_ptr->idat_size) 3971 png_warning(png_ptr, "Extra compressed data"); 3972 png_ptr->mode |= PNG_AFTER_IDAT; 3973 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 3974 break; 3975 } 3976 if (ret != Z_OK) 3977 png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : 3978 "Decompression Error"); 3979 3980 if (!(png_ptr->zstream.avail_out)) 3981 { 3982 png_warning(png_ptr, "Extra compressed data."); 3983 png_ptr->mode |= PNG_AFTER_IDAT; 3984 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 3985 break; 3986 } 3987 3988 } 3989 png_ptr->zstream.avail_out = 0; 3990 } 3991 3992 if (png_ptr->idat_size || png_ptr->zstream.avail_in) 3993 png_warning(png_ptr, "Extra compression data"); 3994 3995 inflateReset(&png_ptr->zstream); 3996 3997 png_ptr->mode |= PNG_AFTER_IDAT; 3998 } 3999 4000 void /* PRIVATE */ 4001 png_read_start_row(png_structp png_ptr) 4002 { 4003 #ifdef PNG_USE_LOCAL_ARRAYS 4004 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 4005 4006 /* start of interlace block */ 4007 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 4008 4009 /* offset to next interlace block */ 4010 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 4011 4012 /* start of interlace block in the y direction */ 4013 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 4014 4015 /* offset to next interlace block in the y direction */ 4016 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 4017 #endif 4018 4019 int max_pixel_depth; 4020 png_uint_32 row_bytes; 4021 4022 png_debug(1, "in png_read_start_row\n"); 4023 png_ptr->zstream.avail_in = 0; 4024 png_init_read_transformations(png_ptr); 4025 if (png_ptr->interlaced) 4026 { 4027 if (!(png_ptr->transformations & PNG_INTERLACE)) 4028 png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - 4029 png_pass_ystart[0]) / png_pass_yinc[0]; 4030 else 4031 png_ptr->num_rows = png_ptr->height; 4032 4033 png_ptr->iwidth = (png_ptr->width + 4034 png_pass_inc[png_ptr->pass] - 1 - 4035 png_pass_start[png_ptr->pass]) / 4036 png_pass_inc[png_ptr->pass]; 4037 4038 row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1; 4039 4040 png_ptr->irowbytes = (png_size_t)row_bytes; 4041 if((png_uint_32)png_ptr->irowbytes != row_bytes) 4042 png_error(png_ptr, "Rowbytes overflow in png_read_start_row"); 4043 } 4044 else 4045 { 4046 png_ptr->num_rows = png_ptr->height; 4047 png_ptr->iwidth = png_ptr->width; 4048 png_ptr->irowbytes = png_ptr->rowbytes + 1; 4049 } 4050 max_pixel_depth = png_ptr->pixel_depth; 4051 4052 #if defined(PNG_READ_PACK_SUPPORTED) 4053 if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) 4054 max_pixel_depth = 8; 4055 #endif 4056 4057 #if defined(PNG_READ_EXPAND_SUPPORTED) 4058 if (png_ptr->transformations & PNG_EXPAND) 4059 { 4060 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 4061 { 4062 if (png_ptr->num_trans) 4063 max_pixel_depth = 32; 4064 else 4065 max_pixel_depth = 24; 4066 } 4067 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 4068 { 4069 if (max_pixel_depth < 8) 4070 max_pixel_depth = 8; 4071 if (png_ptr->num_trans) 4072 max_pixel_depth *= 2; 4073 } 4074 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 4075 { 4076 if (png_ptr->num_trans) 4077 { 4078 max_pixel_depth *= 4; 4079 max_pixel_depth /= 3; 4080 } 4081 } 4082 } 4083 #endif 4084 4085 #if defined(PNG_READ_FILLER_SUPPORTED) 4086 if (png_ptr->transformations & (PNG_FILLER)) 4087 { 4088 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 4089 max_pixel_depth = 32; 4090 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 4091 { 4092 if (max_pixel_depth <= 8) 4093 max_pixel_depth = 16; 4094 else 4095 max_pixel_depth = 32; 4096 } 4097 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 4098 { 4099 if (max_pixel_depth <= 32) 4100 max_pixel_depth = 32; 4101 else 4102 max_pixel_depth = 64; 4103 } 4104 } 4105 #endif 4106 4107 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) 4108 if (png_ptr->transformations & PNG_GRAY_TO_RGB) 4109 { 4110 if ( 4111 #if defined(PNG_READ_EXPAND_SUPPORTED) 4112 (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || 4113 #endif 4114 #if defined(PNG_READ_FILLER_SUPPORTED) 4115 (png_ptr->transformations & (PNG_FILLER)) || 4116 #endif 4117 png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 4118 { 4119 if (max_pixel_depth <= 16) 4120 max_pixel_depth = 32; 4121 else 4122 max_pixel_depth = 64; 4123 } 4124 else 4125 { 4126 if (max_pixel_depth <= 8) 4127 { 4128 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 4129 max_pixel_depth = 32; 4130 else 4131 max_pixel_depth = 24; 4132 } 4133 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 4134 max_pixel_depth = 64; 4135 else 4136 max_pixel_depth = 48; 4137 } 4138 } 4139 #endif 4140 4141 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ 4142 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) 4143 if(png_ptr->transformations & PNG_USER_TRANSFORM) 4144 { 4145 int user_pixel_depth=png_ptr->user_transform_depth* 4146 png_ptr->user_transform_channels; 4147 if(user_pixel_depth > max_pixel_depth) 4148 max_pixel_depth=user_pixel_depth; 4149 } 4150 #endif 4151 4152 /* align the width on the next larger 8 pixels. Mainly used 4153 for interlacing */ 4154 row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); 4155 /* calculate the maximum bytes needed, adding a byte and a pixel 4156 for safety's sake */ 4157 row_bytes = PNG_ROWBYTES(max_pixel_depth,row_bytes) + 4158 1 + ((max_pixel_depth + 7) >> 3); 4159 #ifdef PNG_MAX_MALLOC_64K 4160 if (row_bytes > (png_uint_32)65536L) 4161 png_error(png_ptr, "This image requires a row greater than 64KB"); 4162 #endif 4163 png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64); 4164 png_ptr->row_buf = png_ptr->big_row_buf+32; 4165 #if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD) && defined(PNG_1_0_X) 4166 png_ptr->row_buf_size = row_bytes; 4167 #endif 4168 4169 #ifdef PNG_MAX_MALLOC_64K 4170 if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L) 4171 png_error(png_ptr, "This image requires a row greater than 64KB"); 4172 #endif 4173 if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1)) 4174 png_error(png_ptr, "Row has too many bytes to allocate in memory."); 4175 png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)( 4176 png_ptr->rowbytes + 1)); 4177 4178 png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1); 4179 4180 png_debug1(3, "width = %lu,\n", png_ptr->width); 4181 png_debug1(3, "height = %lu,\n", png_ptr->height); 4182 png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth); 4183 png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows); 4184 png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes); 4185 png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes); 4186 4187 png_ptr->flags |= PNG_FLAG_ROW_INIT; 4188 } 4189 #endif /* PNG_READ_SUPPORTED */ 4190