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