/src/Image_LibPNG154/png.c
C | 2422 lines | 1542 code | 352 blank | 528 comment | 378 complexity | 43b4081a11a10f668ae3eec92d1918f0 MD5 | raw file
Possible License(s): AGPL-3.0, LGPL-2.1, LGPL-3.0, GPL-2.0
Large files files are truncated, but you can click here to view the full file
1 2/* png.c - location for general purpose libpng functions 3 * 4 * Last changed in libpng 1.5.4 [July 7, 2011] 5 * Copyright (c) 1998-2011 Glenn Randers-Pehrson 6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 8 * 9 * This code is released under the libpng license. 10 * For conditions of distribution and use, see the disclaimer 11 * and license in png.h 12 */ 13 14#include "pngpriv.h" 15 16/* Generate a compiler error if there is an old png.h in the search path. */ 17typedef png_libpng_version_1_5_4 Your_png_h_is_not_version_1_5_4; 18 19/* Tells libpng that we have already handled the first "num_bytes" bytes 20 * of the PNG file signature. If the PNG data is embedded into another 21 * stream we can set num_bytes = 8 so that libpng will not attempt to read 22 * or write any of the magic bytes before it starts on the IHDR. 23 */ 24 25#ifdef PNG_READ_SUPPORTED 26void PNGAPI 27png_set_sig_bytes(png_structp png_ptr, int num_bytes) 28{ 29 png_debug(1, "in png_set_sig_bytes"); 30 31 if (png_ptr == NULL) 32 return; 33 34 if (num_bytes > 8) 35 png_error(png_ptr, "Too many bytes for PNG signature"); 36 37 png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes); 38} 39 40/* Checks whether the supplied bytes match the PNG signature. We allow 41 * checking less than the full 8-byte signature so that those apps that 42 * already read the first few bytes of a file to determine the file type 43 * can simply check the remaining bytes for extra assurance. Returns 44 * an integer less than, equal to, or greater than zero if sig is found, 45 * respectively, to be less than, to match, or be greater than the correct 46 * PNG signature (this is the same behaviour as strcmp, memcmp, etc). 47 */ 48int PNGAPI 49png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check) 50{ 51 png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; 52 53 if (num_to_check > 8) 54 num_to_check = 8; 55 56 else if (num_to_check < 1) 57 return (-1); 58 59 if (start > 7) 60 return (-1); 61 62 if (start + num_to_check > 8) 63 num_to_check = 8 - start; 64 65 return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check))); 66} 67 68#endif /* PNG_READ_SUPPORTED */ 69 70#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) 71/* Function to allocate memory for zlib */ 72PNG_FUNCTION(voidpf /* PRIVATE */, 73png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED) 74{ 75 png_voidp ptr; 76 png_structp p=(png_structp)png_ptr; 77 png_uint_32 save_flags=p->flags; 78 png_alloc_size_t num_bytes; 79 80 if (png_ptr == NULL) 81 return (NULL); 82 83 if (items > PNG_UINT_32_MAX/size) 84 { 85 png_warning (p, "Potential overflow in png_zalloc()"); 86 return (NULL); 87 } 88 num_bytes = (png_alloc_size_t)items * size; 89 90 p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; 91 ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes); 92 p->flags=save_flags; 93 94 return ((voidpf)ptr); 95} 96 97/* Function to free memory for zlib */ 98void /* PRIVATE */ 99png_zfree(voidpf png_ptr, voidpf ptr) 100{ 101 png_free((png_structp)png_ptr, (png_voidp)ptr); 102} 103 104/* Reset the CRC variable to 32 bits of 1's. Care must be taken 105 * in case CRC is > 32 bits to leave the top bits 0. 106 */ 107void /* PRIVATE */ 108png_reset_crc(png_structp png_ptr) 109{ 110 png_ptr->crc = crc32(0, Z_NULL, 0); 111} 112 113/* Calculate the CRC over a section of data. We can only pass as 114 * much data to this routine as the largest single buffer size. We 115 * also check that this data will actually be used before going to the 116 * trouble of calculating it. 117 */ 118void /* PRIVATE */ 119png_calculate_crc(png_structp png_ptr, png_const_bytep ptr, png_size_t length) 120{ 121 int need_crc = 1; 122 123 if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ 124 { 125 if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == 126 (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) 127 need_crc = 0; 128 } 129 130 else /* critical */ 131 { 132 if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) 133 need_crc = 0; 134 } 135 136 if (need_crc) 137 png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length); 138} 139 140/* Check a user supplied version number, called from both read and write 141 * functions that create a png_struct 142 */ 143int 144png_user_version_check(png_structp png_ptr, png_const_charp user_png_ver) 145{ 146 if (user_png_ver) 147 { 148 int i = 0; 149 150 do 151 { 152 if (user_png_ver[i] != png_libpng_ver[i]) 153 png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; 154 } while (png_libpng_ver[i++]); 155 } 156 157 else 158 png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; 159 160 if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) 161 { 162 /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so 163 * we must recompile any applications that use any older library version. 164 * For versions after libpng 1.0, we will be compatible, so we need 165 * only check the first digit. 166 */ 167 if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] || 168 (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) || 169 (user_png_ver[0] == '0' && user_png_ver[2] < '9')) 170 { 171#ifdef PNG_WARNINGS_SUPPORTED 172 size_t pos = 0; 173 char m[128]; 174 175 pos = png_safecat(m, sizeof m, pos, "Application built with libpng-"); 176 pos = png_safecat(m, sizeof m, pos, user_png_ver); 177 pos = png_safecat(m, sizeof m, pos, " but running with "); 178 pos = png_safecat(m, sizeof m, pos, png_libpng_ver); 179 180 png_warning(png_ptr, m); 181#endif 182 183#ifdef PNG_ERROR_NUMBERS_SUPPORTED 184 png_ptr->flags = 0; 185#endif 186 187 return 0; 188 } 189 } 190 191 /* Success return. */ 192 return 1; 193} 194 195/* Allocate the memory for an info_struct for the application. We don't 196 * really need the png_ptr, but it could potentially be useful in the 197 * future. This should be used in favour of malloc(png_sizeof(png_info)) 198 * and png_info_init() so that applications that want to use a shared 199 * libpng don't have to be recompiled if png_info changes size. 200 */ 201PNG_FUNCTION(png_infop,PNGAPI 202png_create_info_struct,(png_structp png_ptr),PNG_ALLOCATED) 203{ 204 png_infop info_ptr; 205 206 png_debug(1, "in png_create_info_struct"); 207 208 if (png_ptr == NULL) 209 return (NULL); 210 211#ifdef PNG_USER_MEM_SUPPORTED 212 info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO, 213 png_ptr->malloc_fn, png_ptr->mem_ptr); 214#else 215 info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); 216#endif 217 if (info_ptr != NULL) 218 png_info_init_3(&info_ptr, png_sizeof(png_info)); 219 220 return (info_ptr); 221} 222 223/* This function frees the memory associated with a single info struct. 224 * Normally, one would use either png_destroy_read_struct() or 225 * png_destroy_write_struct() to free an info struct, but this may be 226 * useful for some applications. 227 */ 228void PNGAPI 229png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr) 230{ 231 png_infop info_ptr = NULL; 232 233 png_debug(1, "in png_destroy_info_struct"); 234 235 if (png_ptr == NULL) 236 return; 237 238 if (info_ptr_ptr != NULL) 239 info_ptr = *info_ptr_ptr; 240 241 if (info_ptr != NULL) 242 { 243 png_info_destroy(png_ptr, info_ptr); 244 245#ifdef PNG_USER_MEM_SUPPORTED 246 png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn, 247 png_ptr->mem_ptr); 248#else 249 png_destroy_struct((png_voidp)info_ptr); 250#endif 251 *info_ptr_ptr = NULL; 252 } 253} 254 255/* Initialize the info structure. This is now an internal function (0.89) 256 * and applications using it are urged to use png_create_info_struct() 257 * instead. 258 */ 259 260void PNGAPI 261png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size) 262{ 263 png_infop info_ptr = *ptr_ptr; 264 265 png_debug(1, "in png_info_init_3"); 266 267 if (info_ptr == NULL) 268 return; 269 270 if (png_sizeof(png_info) > png_info_struct_size) 271 { 272 png_destroy_struct(info_ptr); 273 info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); 274 *ptr_ptr = info_ptr; 275 } 276 277 /* Set everything to 0 */ 278 png_memset(info_ptr, 0, png_sizeof(png_info)); 279} 280 281void PNGAPI 282png_data_freer(png_structp png_ptr, png_infop info_ptr, 283 int freer, png_uint_32 mask) 284{ 285 png_debug(1, "in png_data_freer"); 286 287 if (png_ptr == NULL || info_ptr == NULL) 288 return; 289 290 if (freer == PNG_DESTROY_WILL_FREE_DATA) 291 info_ptr->free_me |= mask; 292 293 else if (freer == PNG_USER_WILL_FREE_DATA) 294 info_ptr->free_me &= ~mask; 295 296 else 297 png_warning(png_ptr, 298 "Unknown freer parameter in png_data_freer"); 299} 300 301void PNGAPI 302png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask, 303 int num) 304{ 305 png_debug(1, "in png_free_data"); 306 307 if (png_ptr == NULL || info_ptr == NULL) 308 return; 309 310#ifdef PNG_TEXT_SUPPORTED 311 /* Free text item num or (if num == -1) all text items */ 312 if ((mask & PNG_FREE_TEXT) & info_ptr->free_me) 313 { 314 if (num != -1) 315 { 316 if (info_ptr->text && info_ptr->text[num].key) 317 { 318 png_free(png_ptr, info_ptr->text[num].key); 319 info_ptr->text[num].key = NULL; 320 } 321 } 322 323 else 324 { 325 int i; 326 for (i = 0; i < info_ptr->num_text; i++) 327 png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i); 328 png_free(png_ptr, info_ptr->text); 329 info_ptr->text = NULL; 330 info_ptr->num_text=0; 331 } 332 } 333#endif 334 335#ifdef PNG_tRNS_SUPPORTED 336 /* Free any tRNS entry */ 337 if ((mask & PNG_FREE_TRNS) & info_ptr->free_me) 338 { 339 png_free(png_ptr, info_ptr->trans_alpha); 340 info_ptr->trans_alpha = NULL; 341 info_ptr->valid &= ~PNG_INFO_tRNS; 342 } 343#endif 344 345#ifdef PNG_sCAL_SUPPORTED 346 /* Free any sCAL entry */ 347 if ((mask & PNG_FREE_SCAL) & info_ptr->free_me) 348 { 349 png_free(png_ptr, info_ptr->scal_s_width); 350 png_free(png_ptr, info_ptr->scal_s_height); 351 info_ptr->scal_s_width = NULL; 352 info_ptr->scal_s_height = NULL; 353 info_ptr->valid &= ~PNG_INFO_sCAL; 354 } 355#endif 356 357#ifdef PNG_pCAL_SUPPORTED 358 /* Free any pCAL entry */ 359 if ((mask & PNG_FREE_PCAL) & info_ptr->free_me) 360 { 361 png_free(png_ptr, info_ptr->pcal_purpose); 362 png_free(png_ptr, info_ptr->pcal_units); 363 info_ptr->pcal_purpose = NULL; 364 info_ptr->pcal_units = NULL; 365 if (info_ptr->pcal_params != NULL) 366 { 367 int i; 368 for (i = 0; i < (int)info_ptr->pcal_nparams; i++) 369 { 370 png_free(png_ptr, info_ptr->pcal_params[i]); 371 info_ptr->pcal_params[i] = NULL; 372 } 373 png_free(png_ptr, info_ptr->pcal_params); 374 info_ptr->pcal_params = NULL; 375 } 376 info_ptr->valid &= ~PNG_INFO_pCAL; 377 } 378#endif 379 380#ifdef PNG_iCCP_SUPPORTED 381 /* Free any iCCP entry */ 382 if ((mask & PNG_FREE_ICCP) & info_ptr->free_me) 383 { 384 png_free(png_ptr, info_ptr->iccp_name); 385 png_free(png_ptr, info_ptr->iccp_profile); 386 info_ptr->iccp_name = NULL; 387 info_ptr->iccp_profile = NULL; 388 info_ptr->valid &= ~PNG_INFO_iCCP; 389 } 390#endif 391 392#ifdef PNG_sPLT_SUPPORTED 393 /* Free a given sPLT entry, or (if num == -1) all sPLT entries */ 394 if ((mask & PNG_FREE_SPLT) & info_ptr->free_me) 395 { 396 if (num != -1) 397 { 398 if (info_ptr->splt_palettes) 399 { 400 png_free(png_ptr, info_ptr->splt_palettes[num].name); 401 png_free(png_ptr, info_ptr->splt_palettes[num].entries); 402 info_ptr->splt_palettes[num].name = NULL; 403 info_ptr->splt_palettes[num].entries = NULL; 404 } 405 } 406 407 else 408 { 409 if (info_ptr->splt_palettes_num) 410 { 411 int i; 412 for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) 413 png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i); 414 415 png_free(png_ptr, info_ptr->splt_palettes); 416 info_ptr->splt_palettes = NULL; 417 info_ptr->splt_palettes_num = 0; 418 } 419 info_ptr->valid &= ~PNG_INFO_sPLT; 420 } 421 } 422#endif 423 424#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED 425 if (png_ptr->unknown_chunk.data) 426 { 427 png_free(png_ptr, png_ptr->unknown_chunk.data); 428 png_ptr->unknown_chunk.data = NULL; 429 } 430 431 if ((mask & PNG_FREE_UNKN) & info_ptr->free_me) 432 { 433 if (num != -1) 434 { 435 if (info_ptr->unknown_chunks) 436 { 437 png_free(png_ptr, info_ptr->unknown_chunks[num].data); 438 info_ptr->unknown_chunks[num].data = NULL; 439 } 440 } 441 442 else 443 { 444 int i; 445 446 if (info_ptr->unknown_chunks_num) 447 { 448 for (i = 0; i < info_ptr->unknown_chunks_num; i++) 449 png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i); 450 451 png_free(png_ptr, info_ptr->unknown_chunks); 452 info_ptr->unknown_chunks = NULL; 453 info_ptr->unknown_chunks_num = 0; 454 } 455 } 456 } 457#endif 458 459#ifdef PNG_hIST_SUPPORTED 460 /* Free any hIST entry */ 461 if ((mask & PNG_FREE_HIST) & info_ptr->free_me) 462 { 463 png_free(png_ptr, info_ptr->hist); 464 info_ptr->hist = NULL; 465 info_ptr->valid &= ~PNG_INFO_hIST; 466 } 467#endif 468 469 /* Free any PLTE entry that was internally allocated */ 470 if ((mask & PNG_FREE_PLTE) & info_ptr->free_me) 471 { 472 png_zfree(png_ptr, info_ptr->palette); 473 info_ptr->palette = NULL; 474 info_ptr->valid &= ~PNG_INFO_PLTE; 475 info_ptr->num_palette = 0; 476 } 477 478#ifdef PNG_INFO_IMAGE_SUPPORTED 479 /* Free any image bits attached to the info structure */ 480 if ((mask & PNG_FREE_ROWS) & info_ptr->free_me) 481 { 482 if (info_ptr->row_pointers) 483 { 484 int row; 485 for (row = 0; row < (int)info_ptr->height; row++) 486 { 487 png_free(png_ptr, info_ptr->row_pointers[row]); 488 info_ptr->row_pointers[row] = NULL; 489 } 490 png_free(png_ptr, info_ptr->row_pointers); 491 info_ptr->row_pointers = NULL; 492 } 493 info_ptr->valid &= ~PNG_INFO_IDAT; 494 } 495#endif 496 497 if (num != -1) 498 mask &= ~PNG_FREE_MUL; 499 500 info_ptr->free_me &= ~mask; 501} 502 503/* This is an internal routine to free any memory that the info struct is 504 * pointing to before re-using it or freeing the struct itself. Recall 505 * that png_free() checks for NULL pointers for us. 506 */ 507void /* PRIVATE */ 508png_info_destroy(png_structp png_ptr, png_infop info_ptr) 509{ 510 png_debug(1, "in png_info_destroy"); 511 512 png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); 513 514#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 515 if (png_ptr->num_chunk_list) 516 { 517 png_free(png_ptr, png_ptr->chunk_list); 518 png_ptr->chunk_list = NULL; 519 png_ptr->num_chunk_list = 0; 520 } 521#endif 522 523 png_info_init_3(&info_ptr, png_sizeof(png_info)); 524} 525#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ 526 527/* This function returns a pointer to the io_ptr associated with the user 528 * functions. The application should free any memory associated with this 529 * pointer before png_write_destroy() or png_read_destroy() are called. 530 */ 531png_voidp PNGAPI 532png_get_io_ptr(png_structp png_ptr) 533{ 534 if (png_ptr == NULL) 535 return (NULL); 536 537 return (png_ptr->io_ptr); 538} 539 540#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) 541# ifdef PNG_STDIO_SUPPORTED 542/* Initialize the default input/output functions for the PNG file. If you 543 * use your own read or write routines, you can call either png_set_read_fn() 544 * or png_set_write_fn() instead of png_init_io(). If you have defined 545 * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't 546 * necessarily available. 547 */ 548void PNGAPI 549png_init_io(png_structp png_ptr, png_FILE_p fp) 550{ 551 png_debug(1, "in png_init_io"); 552 553 if (png_ptr == NULL) 554 return; 555 556 png_ptr->io_ptr = (png_voidp)fp; 557} 558# endif 559 560# ifdef PNG_TIME_RFC1123_SUPPORTED 561/* Convert the supplied time into an RFC 1123 string suitable for use in 562 * a "Creation Time" or other text-based time string. 563 */ 564png_const_charp PNGAPI 565png_convert_to_rfc1123(png_structp png_ptr, png_const_timep ptime) 566{ 567 static PNG_CONST char short_months[12][4] = 568 {"Jan", "Feb", "Mar", "Apr", "May", "Jun", 569 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; 570 571 if (png_ptr == NULL) 572 return (NULL); 573 574 { 575 size_t pos = 0; 576 char number_buf[5]; /* enough for a four digit year */ 577 578# define APPEND_STRING(string)\ 579 pos = png_safecat(png_ptr->time_buffer, sizeof png_ptr->time_buffer,\ 580 pos, (string)) 581# define APPEND_NUMBER(format, value)\ 582 APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value))) 583# define APPEND(ch)\ 584 if (pos < (sizeof png_ptr->time_buffer)-1)\ 585 png_ptr->time_buffer[pos++] = (ch) 586 587 APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day % 32); 588 APPEND(' '); 589 APPEND_STRING(short_months[(ptime->month - 1) % 12]); 590 APPEND(' '); 591 APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year); 592 APPEND(' '); 593 APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour % 24); 594 APPEND(':'); 595 APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute % 60); 596 APPEND(':'); 597 APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second % 61); 598 APPEND_STRING(" +0000"); /* This reliably terminates the buffer */ 599 600# undef APPEND 601# undef APPEND_NUMBER 602# undef APPEND_STRING 603 } 604 605 return png_ptr->time_buffer; 606} 607# endif /* PNG_TIME_RFC1123_SUPPORTED */ 608 609#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ 610 611png_const_charp PNGAPI 612png_get_copyright(png_const_structp png_ptr) 613{ 614 PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ 615#ifdef PNG_STRING_COPYRIGHT 616 return PNG_STRING_COPYRIGHT 617#else 618# ifdef __STDC__ 619 return PNG_STRING_NEWLINE \ 620 "libpng version 1.5.4 - July 7, 2011" PNG_STRING_NEWLINE \ 621 "Copyright (c) 1998-2011 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ 622 "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ 623 "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ 624 PNG_STRING_NEWLINE; 625# else 626 return "libpng version 1.5.4 - July 7, 2011\ 627 Copyright (c) 1998-2011 Glenn Randers-Pehrson\ 628 Copyright (c) 1996-1997 Andreas Dilger\ 629 Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; 630# endif 631#endif 632} 633 634/* The following return the library version as a short string in the 635 * format 1.0.0 through 99.99.99zz. To get the version of *.h files 636 * used with your application, print out PNG_LIBPNG_VER_STRING, which 637 * is defined in png.h. 638 * Note: now there is no difference between png_get_libpng_ver() and 639 * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard, 640 * it is guaranteed that png.c uses the correct version of png.h. 641 */ 642png_const_charp PNGAPI 643png_get_libpng_ver(png_const_structp png_ptr) 644{ 645 /* Version of *.c files used when building libpng */ 646 return png_get_header_ver(png_ptr); 647} 648 649png_const_charp PNGAPI 650png_get_header_ver(png_const_structp png_ptr) 651{ 652 /* Version of *.h files used when building libpng */ 653 PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ 654 return PNG_LIBPNG_VER_STRING; 655} 656 657png_const_charp PNGAPI 658png_get_header_version(png_const_structp png_ptr) 659{ 660 /* Returns longer string containing both version and date */ 661 PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ 662#ifdef __STDC__ 663 return PNG_HEADER_VERSION_STRING 664# ifndef PNG_READ_SUPPORTED 665 " (NO READ SUPPORT)" 666# endif 667 PNG_STRING_NEWLINE; 668#else 669 return PNG_HEADER_VERSION_STRING; 670#endif 671} 672 673#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) 674# ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 675int PNGAPI 676png_handle_as_unknown(png_structp png_ptr, png_const_bytep chunk_name) 677{ 678 /* Check chunk_name and return "keep" value if it's on the list, else 0 */ 679 int i; 680 png_bytep p; 681 if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0) 682 return 0; 683 684 p = png_ptr->chunk_list + png_ptr->num_chunk_list*5 - 5; 685 for (i = png_ptr->num_chunk_list; i; i--, p -= 5) 686 if (!png_memcmp(chunk_name, p, 4)) 687 return ((int)*(p + 4)); 688 return 0; 689} 690# endif 691#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ 692 693#ifdef PNG_READ_SUPPORTED 694/* This function, added to libpng-1.0.6g, is untested. */ 695int PNGAPI 696png_reset_zstream(png_structp png_ptr) 697{ 698 if (png_ptr == NULL) 699 return Z_STREAM_ERROR; 700 701 return (inflateReset(&png_ptr->zstream)); 702} 703#endif /* PNG_READ_SUPPORTED */ 704 705/* This function was added to libpng-1.0.7 */ 706png_uint_32 PNGAPI 707png_access_version_number(void) 708{ 709 /* Version of *.c files used when building libpng */ 710 return((png_uint_32)PNG_LIBPNG_VER); 711} 712 713 714 715#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) 716# ifdef PNG_SIZE_T 717/* Added at libpng version 1.2.6 */ 718 PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size)); 719png_size_t PNGAPI 720png_convert_size(size_t size) 721{ 722 if (size > (png_size_t)-1) 723 PNG_ABORT(); /* We haven't got access to png_ptr, so no png_error() */ 724 725 return ((png_size_t)size); 726} 727# endif /* PNG_SIZE_T */ 728 729/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */ 730# ifdef PNG_CHECK_cHRM_SUPPORTED 731 732int /* PRIVATE */ 733png_check_cHRM_fixed(png_structp png_ptr, 734 png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, 735 png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, 736 png_fixed_point blue_x, png_fixed_point blue_y) 737{ 738 int ret = 1; 739 unsigned long xy_hi,xy_lo,yx_hi,yx_lo; 740 741 png_debug(1, "in function png_check_cHRM_fixed"); 742 743 if (png_ptr == NULL) 744 return 0; 745 746 /* (x,y,z) values are first limited to 0..100000 (PNG_FP_1), the white 747 * y must also be greater than 0. To test for the upper limit calculate 748 * (PNG_FP_1-y) - x must be <= to this for z to be >= 0 (and the expression 749 * cannot overflow.) At this point we know x and y are >= 0 and (x+y) is 750 * <= PNG_FP_1. The previous test on PNG_MAX_UINT_31 is removed because it 751 * pointless (and it produces compiler warnings!) 752 */ 753 if (white_x < 0 || white_y <= 0 || 754 red_x < 0 || red_y < 0 || 755 green_x < 0 || green_y < 0 || 756 blue_x < 0 || blue_y < 0) 757 { 758 png_warning(png_ptr, 759 "Ignoring attempt to set negative chromaticity value"); 760 ret = 0; 761 } 762 /* And (x+y) must be <= PNG_FP_1 (so z is >= 0) */ 763 if (white_x > PNG_FP_1 - white_y) 764 { 765 png_warning(png_ptr, "Invalid cHRM white point"); 766 ret = 0; 767 } 768 769 if (red_x > PNG_FP_1 - red_y) 770 { 771 png_warning(png_ptr, "Invalid cHRM red point"); 772 ret = 0; 773 } 774 775 if (green_x > PNG_FP_1 - green_y) 776 { 777 png_warning(png_ptr, "Invalid cHRM green point"); 778 ret = 0; 779 } 780 781 if (blue_x > PNG_FP_1 - blue_y) 782 { 783 png_warning(png_ptr, "Invalid cHRM blue point"); 784 ret = 0; 785 } 786 787 png_64bit_product(green_x - red_x, blue_y - red_y, &xy_hi, &xy_lo); 788 png_64bit_product(green_y - red_y, blue_x - red_x, &yx_hi, &yx_lo); 789 790 if (xy_hi == yx_hi && xy_lo == yx_lo) 791 { 792 png_warning(png_ptr, 793 "Ignoring attempt to set cHRM RGB triangle with zero area"); 794 ret = 0; 795 } 796 797 return ret; 798} 799# endif /* PNG_CHECK_cHRM_SUPPORTED */ 800 801void /* PRIVATE */ 802png_check_IHDR(png_structp png_ptr, 803 png_uint_32 width, png_uint_32 height, int bit_depth, 804 int color_type, int interlace_type, int compression_type, 805 int filter_type) 806{ 807 int error = 0; 808 809 /* Check for width and height valid values */ 810 if (width == 0) 811 { 812 png_warning(png_ptr, "Image width is zero in IHDR"); 813 error = 1; 814 } 815 816 if (height == 0) 817 { 818 png_warning(png_ptr, "Image height is zero in IHDR"); 819 error = 1; 820 } 821 822# ifdef PNG_SET_USER_LIMITS_SUPPORTED 823 if (width > png_ptr->user_width_max) 824 825# else 826 if (width > PNG_USER_WIDTH_MAX) 827# endif 828 { 829 png_warning(png_ptr, "Image width exceeds user limit in IHDR"); 830 error = 1; 831 } 832 833# ifdef PNG_SET_USER_LIMITS_SUPPORTED 834 if (height > png_ptr->user_height_max) 835# else 836 if (height > PNG_USER_HEIGHT_MAX) 837# endif 838 { 839 png_warning(png_ptr, "Image height exceeds user limit in IHDR"); 840 error = 1; 841 } 842 843 if (width > PNG_UINT_31_MAX) 844 { 845 png_warning(png_ptr, "Invalid image width in IHDR"); 846 error = 1; 847 } 848 849 if (height > PNG_UINT_31_MAX) 850 { 851 png_warning(png_ptr, "Invalid image height in IHDR"); 852 error = 1; 853 } 854 855 if (width > (PNG_UINT_32_MAX 856 >> 3) /* 8-byte RGBA pixels */ 857 - 48 /* bigrowbuf hack */ 858 - 1 /* filter byte */ 859 - 7*8 /* rounding of width to multiple of 8 pixels */ 860 - 8) /* extra max_pixel_depth pad */ 861 png_warning(png_ptr, "Width is too large for libpng to process pixels"); 862 863 /* Check other values */ 864 if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && 865 bit_depth != 8 && bit_depth != 16) 866 { 867 png_warning(png_ptr, "Invalid bit depth in IHDR"); 868 error = 1; 869 } 870 871 if (color_type < 0 || color_type == 1 || 872 color_type == 5 || color_type > 6) 873 { 874 png_warning(png_ptr, "Invalid color type in IHDR"); 875 error = 1; 876 } 877 878 if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) || 879 ((color_type == PNG_COLOR_TYPE_RGB || 880 color_type == PNG_COLOR_TYPE_GRAY_ALPHA || 881 color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8)) 882 { 883 png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR"); 884 error = 1; 885 } 886 887 if (interlace_type >= PNG_INTERLACE_LAST) 888 { 889 png_warning(png_ptr, "Unknown interlace method in IHDR"); 890 error = 1; 891 } 892 893 if (compression_type != PNG_COMPRESSION_TYPE_BASE) 894 { 895 png_warning(png_ptr, "Unknown compression method in IHDR"); 896 error = 1; 897 } 898 899# ifdef PNG_MNG_FEATURES_SUPPORTED 900 /* Accept filter_method 64 (intrapixel differencing) only if 901 * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and 902 * 2. Libpng did not read a PNG signature (this filter_method is only 903 * used in PNG datastreams that are embedded in MNG datastreams) and 904 * 3. The application called png_permit_mng_features with a mask that 905 * included PNG_FLAG_MNG_FILTER_64 and 906 * 4. The filter_method is 64 and 907 * 5. The color_type is RGB or RGBA 908 */ 909 if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) && 910 png_ptr->mng_features_permitted) 911 png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); 912 913 if (filter_type != PNG_FILTER_TYPE_BASE) 914 { 915 if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && 916 (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && 917 ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && 918 (color_type == PNG_COLOR_TYPE_RGB || 919 color_type == PNG_COLOR_TYPE_RGB_ALPHA))) 920 { 921 png_warning(png_ptr, "Unknown filter method in IHDR"); 922 error = 1; 923 } 924 925 if (png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) 926 { 927 png_warning(png_ptr, "Invalid filter method in IHDR"); 928 error = 1; 929 } 930 } 931 932# else 933 if (filter_type != PNG_FILTER_TYPE_BASE) 934 { 935 png_warning(png_ptr, "Unknown filter method in IHDR"); 936 error = 1; 937 } 938# endif 939 940 if (error == 1) 941 png_error(png_ptr, "Invalid IHDR data"); 942} 943 944#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) 945/* ASCII to fp functions */ 946/* Check an ASCII formated floating point value, see the more detailed 947 * comments in pngpriv.h 948 */ 949/* The following is used internally to preserve the sticky flags */ 950#define png_fp_add(state, flags) ((state) |= (flags)) 951#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY)) 952 953int /* PRIVATE */ 954png_check_fp_number(png_const_charp string, png_size_t size, int *statep, 955 png_size_tp whereami) 956{ 957 int state = *statep; 958 png_size_t i = *whereami; 959 960 while (i < size) 961 { 962 int type; 963 /* First find the type of the next character */ 964 switch (string[i]) 965 { 966 case 43: type = PNG_FP_SAW_SIGN; break; 967 case 45: type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break; 968 case 46: type = PNG_FP_SAW_DOT; break; 969 case 48: type = PNG_FP_SAW_DIGIT; break; 970 case 49: case 50: case 51: case 52: 971 case 53: case 54: case 55: case 56: 972 case 57: type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break; 973 case 69: 974 case 101: type = PNG_FP_SAW_E; break; 975 default: goto PNG_FP_End; 976 } 977 978 /* Now deal with this type according to the current 979 * state, the type is arranged to not overlap the 980 * bits of the PNG_FP_STATE. 981 */ 982 switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY)) 983 { 984 case PNG_FP_INTEGER + PNG_FP_SAW_SIGN: 985 if (state & PNG_FP_SAW_ANY) 986 goto PNG_FP_End; /* not a part of the number */ 987 988 png_fp_add(state, type); 989 break; 990 991 case PNG_FP_INTEGER + PNG_FP_SAW_DOT: 992 /* Ok as trailer, ok as lead of fraction. */ 993 if (state & PNG_FP_SAW_DOT) /* two dots */ 994 goto PNG_FP_End; 995 996 else if (state & PNG_FP_SAW_DIGIT) /* trailing dot? */ 997 png_fp_add(state, type); 998 999 else 1000 png_fp_set(state, PNG_FP_FRACTION | type); 1001 1002 break; 1003 1004 case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT: 1005 if (state & PNG_FP_SAW_DOT) /* delayed fraction */ 1006 png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); 1007 1008 png_fp_add(state, type | PNG_FP_WAS_VALID); 1009 1010 break; 1011 1012 case PNG_FP_INTEGER + PNG_FP_SAW_E: 1013 if ((state & PNG_FP_SAW_DIGIT) == 0) 1014 goto PNG_FP_End; 1015 1016 png_fp_set(state, PNG_FP_EXPONENT); 1017 1018 break; 1019 1020 /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN: 1021 goto PNG_FP_End; ** no sign in fraction */ 1022 1023 /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT: 1024 goto PNG_FP_End; ** Because SAW_DOT is always set */ 1025 1026 case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT: 1027 png_fp_add(state, type | PNG_FP_WAS_VALID); 1028 break; 1029 1030 case PNG_FP_FRACTION + PNG_FP_SAW_E: 1031 /* This is correct because the trailing '.' on an 1032 * integer is handled above - so we can only get here 1033 * with the sequence ".E" (with no preceding digits). 1034 */ 1035 if ((state & PNG_FP_SAW_DIGIT) == 0) 1036 goto PNG_FP_End; 1037 1038 png_fp_set(state, PNG_FP_EXPONENT); 1039 1040 break; 1041 1042 case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN: 1043 if (state & PNG_FP_SAW_ANY) 1044 goto PNG_FP_End; /* not a part of the number */ 1045 1046 png_fp_add(state, PNG_FP_SAW_SIGN); 1047 1048 break; 1049 1050 /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT: 1051 goto PNG_FP_End; */ 1052 1053 case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT: 1054 png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID); 1055 1056 break; 1057 1058 /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E: 1059 goto PNG_FP_End; */ 1060 1061 default: goto PNG_FP_End; /* I.e. break 2 */ 1062 } 1063 1064 /* The character seems ok, continue. */ 1065 ++i; 1066 } 1067 1068PNG_FP_End: 1069 /* Here at the end, update the state and return the correct 1070 * return code. 1071 */ 1072 *statep = state; 1073 *whereami = i; 1074 1075 return (state & PNG_FP_SAW_DIGIT) != 0; 1076} 1077 1078 1079/* The same but for a complete string. */ 1080int 1081png_check_fp_string(png_const_charp string, png_size_t size) 1082{ 1083 int state=0; 1084 png_size_t char_index=0; 1085 1086 if (png_check_fp_number(string, size, &state, &char_index) && 1087 (char_index == size || string[char_index] == 0)) 1088 return state /* must be non-zero - see above */; 1089 1090 return 0; /* i.e. fail */ 1091} 1092#endif /* pCAL or sCAL */ 1093 1094#ifdef PNG_READ_sCAL_SUPPORTED 1095# ifdef PNG_FLOATING_POINT_SUPPORTED 1096/* Utility used below - a simple accurate power of ten from an integral 1097 * exponent. 1098 */ 1099static double 1100png_pow10(int power) 1101{ 1102 int recip = 0; 1103 double d = 1; 1104 1105 /* Handle negative exponent with a reciprocal at the end because 1106 * 10 is exact whereas .1 is inexact in base 2 1107 */ 1108 if (power < 0) 1109 { 1110 if (power < DBL_MIN_10_EXP) return 0; 1111 recip = 1, power = -power; 1112 } 1113 1114 if (power > 0) 1115 { 1116 /* Decompose power bitwise. */ 1117 double mult = 10; 1118 do 1119 { 1120 if (power & 1) d *= mult; 1121 mult *= mult; 1122 power >>= 1; 1123 } 1124 while (power > 0); 1125 1126 if (recip) d = 1/d; 1127 } 1128 /* else power is 0 and d is 1 */ 1129 1130 return d; 1131} 1132 1133/* Function to format a floating point value in ASCII with a given 1134 * precision. 1135 */ 1136void /* PRIVATE */ 1137png_ascii_from_fp(png_structp png_ptr, png_charp ascii, png_size_t size, 1138 double fp, unsigned int precision) 1139{ 1140 /* We use standard functions from math.h, but not printf because 1141 * that would require stdio. The caller must supply a buffer of 1142 * sufficient size or we will png_error. The tests on size and 1143 * the space in ascii[] consumed are indicated below. 1144 */ 1145 if (precision < 1) 1146 precision = DBL_DIG; 1147 1148 /* Enforce the limit of the implementation precision too. */ 1149 if (precision > DBL_DIG+1) 1150 precision = DBL_DIG+1; 1151 1152 /* Basic sanity checks */ 1153 if (size >= precision+5) /* See the requirements below. */ 1154 { 1155 if (fp < 0) 1156 { 1157 fp = -fp; 1158 *ascii++ = 45; /* '-' PLUS 1 TOTAL 1 */ 1159 --size; 1160 } 1161 1162 if (fp >= DBL_MIN && fp <= DBL_MAX) 1163 { 1164 int exp_b10; /* A base 10 exponent */ 1165 double base; /* 10^exp_b10 */ 1166 1167 /* First extract a base 10 exponent of the number, 1168 * the calculation below rounds down when converting 1169 * from base 2 to base 10 (multiply by log10(2) - 1170 * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to 1171 * be increased. Note that the arithmetic shift 1172 * performs a floor() unlike C arithmetic - using a 1173 * C multiply would break the following for negative 1174 * exponents. 1175 */ 1176 (void)frexp(fp, &exp_b10); /* exponent to base 2 */ 1177 1178 exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */ 1179 1180 /* Avoid underflow here. */ 1181 base = png_pow10(exp_b10); /* May underflow */ 1182 1183 while (base < DBL_MIN || base < fp) 1184 { 1185 /* And this may overflow. */ 1186 double test = png_pow10(exp_b10+1); 1187 1188 if (test <= DBL_MAX) 1189 ++exp_b10, base = test; 1190 1191 else 1192 break; 1193 } 1194 1195 /* Normalize fp and correct exp_b10, after this fp is in the 1196 * range [.1,1) and exp_b10 is both the exponent and the digit 1197 * *before* which the decimal point should be inserted 1198 * (starting with 0 for the first digit). Note that this 1199 * works even if 10^exp_b10 is out of range because of the 1200 * test on DBL_MAX above. 1201 */ 1202 fp /= base; 1203 while (fp >= 1) fp /= 10, ++exp_b10; 1204 1205 /* Because of the code above fp may, at this point, be 1206 * less than .1, this is ok because the code below can 1207 * handle the leading zeros this generates, so no attempt 1208 * is made to correct that here. 1209 */ 1210 1211 { 1212 int czero, clead, cdigits; 1213 char exponent[10]; 1214 1215 /* Allow up to two leading zeros - this will not lengthen 1216 * the number compared to using E-n. 1217 */ 1218 if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */ 1219 { 1220 czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */ 1221 exp_b10 = 0; /* Dot added below before first output. */ 1222 } 1223 else 1224 czero = 0; /* No zeros to add */ 1225 1226 /* Generate the digit list, stripping trailing zeros and 1227 * inserting a '.' before a digit if the exponent is 0. 1228 */ 1229 clead = czero; /* Count of leading zeros */ 1230 cdigits = 0; /* Count of digits in list. */ 1231 1232 do 1233 { 1234 double d; 1235 1236 fp *= 10; 1237 /* Use modf here, not floor and subtract, so that 1238 * the separation is done in one step. At the end 1239 * of the loop don't break the number into parts so 1240 * that the final digit is rounded. 1241 */ 1242 if (cdigits+czero-clead+1 < (int)precision) 1243 fp = modf(fp, &d); 1244 1245 else 1246 { 1247 d = floor(fp + .5); 1248 1249 if (d > 9) 1250 { 1251 /* Rounding up to 10, handle that here. */ 1252 if (czero > 0) 1253 { 1254 --czero, d = 1; 1255 if (cdigits == 0) --clead; 1256 } 1257 else 1258 { 1259 while (cdigits > 0 && d > 9) 1260 { 1261 int ch = *--ascii; 1262 1263 if (exp_b10 != (-1)) 1264 ++exp_b10; 1265 1266 else if (ch == 46) 1267 { 1268 ch = *--ascii, ++size; 1269 /* Advance exp_b10 to '1', so that the 1270 * decimal point happens after the 1271 * previous digit. 1272 */ 1273 exp_b10 = 1; 1274 } 1275 1276 --cdigits; 1277 d = ch - 47; /* I.e. 1+(ch-48) */ 1278 } 1279 1280 /* Did we reach the beginning? If so adjust the 1281 * exponent but take into account the leading 1282 * decimal point. 1283 */ 1284 if (d > 9) /* cdigits == 0 */ 1285 { 1286 if (exp_b10 == (-1)) 1287 { 1288 /* Leading decimal point (plus zeros?), if 1289 * we lose the decimal point here it must 1290 * be reentered below. 1291 */ 1292 int ch = *--ascii; 1293 1294 if (ch == 46) 1295 ++size, exp_b10 = 1; 1296 1297 /* Else lost a leading zero, so 'exp_b10' is 1298 * still ok at (-1) 1299 */ 1300 } 1301 else 1302 ++exp_b10; 1303 1304 /* In all cases we output a '1' */ 1305 d = 1; 1306 } 1307 } 1308 } 1309 fp = 0; /* Guarantees termination below. */ 1310 } 1311 1312 if (d == 0) 1313 { 1314 ++czero; 1315 if (cdigits == 0) ++clead; 1316 } 1317 else 1318 { 1319 /* Included embedded zeros in the digit count. */ 1320 cdigits += czero - clead; 1321 clead = 0; 1322 1323 while (czero > 0) 1324 { 1325 /* exp_b10 == (-1) means we just output the decimal 1326 * place - after the DP don't adjust 'exp_b10' any 1327 * more! 1328 */ 1329 if (exp_b10 != (-1)) 1330 { 1331 if (exp_b10 == 0) *ascii++ = 46, --size; 1332 /* PLUS 1: TOTAL 4 */ 1333 --exp_b10; 1334 } 1335 *ascii++ = 48, --czero; 1336 } 1337 1338 if (exp_b10 != (-1)) 1339 { 1340 if (exp_b10 == 0) *ascii++ = 46, --size; /* counted 1341 above */ 1342 --exp_b10; 1343 } 1344 *ascii++ = (char)(48 + (int)d), ++cdigits; 1345 } 1346 } 1347 while (cdigits+czero-clead < (int)precision && fp > DBL_MIN); 1348 1349 /* The total output count (max) is now 4+precision */ 1350 1351 /* Check for an exponent, if we don't need one we are 1352 * done and just need to terminate the string. At 1353 * this point exp_b10==(-1) is effectively if flag - it got 1354 * to '-1' because of the decrement after outputing 1355 * the decimal point above (the exponent required is 1356 * *not* -1!) 1357 */ 1358 if (exp_b10 >= (-1) && exp_b10 <= 2) 1359 { 1360 /* The following only happens if we didn't output the 1361 * leading zeros above for negative exponent, so this 1362 * doest add to the digit requirement. Note that the 1363 * two zeros here can only be output if the two leading 1364 * zeros were *not* output, so this doesn't increase 1365 * the output count. 1366 */ 1367 while (--exp_b10 >= 0) *ascii++ = 48; 1368 1369 *ascii = 0; 1370 1371 /* Total buffer requirement (including the '\0') is 1372 * 5+precision - see check at the start. 1373 */ 1374 return; 1375 } 1376 1377 /* Here if an exponent is required, adjust size for 1378 * the digits we output but did not count. The total 1379 * digit output here so far is at most 1+precision - no 1380 * decimal point and no leading or trailing zeros have 1381 * been output. 1382 */ 1383 size -= cdigits; 1384 1385 *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision */ 1386 if (exp_b10 < 0) 1387 { 1388 *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */ 1389 exp_b10 = -exp_b10; 1390 } 1391 1392 cdigits = 0; 1393 1394 while (exp_b10 > 0) 1395 { 1396 exponent[cdigits++] = (char)(48 + exp_b10 % 10); 1397 exp_b10 /= 10; 1398 } 1399 1400 /* Need another size check here for the exponent digits, so 1401 * this need not be considered above. 1402 */ 1403 if ((int)size > cdigits) 1404 { 1405 while (cdigits > 0) *ascii++ = exponent[--cdigits]; 1406 1407 *ascii = 0; 1408 1409 return; 1410 } 1411 } 1412 } 1413 else if (!(fp >= DBL_MIN)) 1414 { 1415 *ascii++ = 48; /* '0' */ 1416 *ascii = 0; 1417 return; 1418 } 1419 else 1420 { 1421 *ascii++ = 105; /* 'i' */ 1422 *ascii++ = 110; /* 'n' */ 1423 *ascii++ = 102; /* 'f' */ 1424 *ascii = 0; 1425 return; 1426 } 1427 } 1428 1429 /* Here on buffer too small. */ 1430 png_error(png_ptr, "ASCII conversion buffer too small"); 1431} 1432 1433# endif /* FLOATING_POINT */ 1434 1435# ifdef PNG_FIXED_POINT_SUPPORTED 1436/* Function to format a fixed point value in ASCII. 1437 */ 1438void /* PRIVATE */ 1439png_ascii_from_fixed(png_structp png_ptr, png_charp ascii, png_size_t size, 1440 png_fixed_point fp) 1441{ 1442 /* Require space for 10 decimal digits, a decimal point, a minus sign and a 1443 * trailing \0, 13 characters: 1444 */ 1445 if (size > 12) 1446 { 1447 png_uint_32 num; 1448 1449 /* Avoid overflow here on the minimum integer. */ 1450 if (fp < 0) 1451 *ascii++ = 45, --size, num = -fp; 1452 else 1453 num = fp; 1454 1455 if (num <= 0x80000000U) /* else overflowed */ 1456 { 1457 unsigned int ndigits = 0, first = 16 /* flag value */; 1458 char digits[10]; 1459 1460 while (num) 1461 { 1462 /* Split the low digit off num: */ 1463 unsigned int tmp = num/10; 1464 num -= tmp*10; 1465 digits[ndigits++] = (char)(48 + num); 1466 /* Record the first non-zero digit, note that this is a number 1467 * starting at 1, it's not actually the array index. 1468 */ 1469 if (first == 16 && num > 0) 1470 first = ndigits; 1471 num = tmp; 1472 } 1473 1474 if (ndigits > 0) 1475 { 1476 while (ndigits > 5) *ascii++ = digits[--ndigits]; 1477 /* The remaining digits are fractional digits, ndigits is '5' or 1478 * smaller at this point. It is certainly not zero. Check for a 1479 * non-zero fractional digit: 1480 */ 1481 if (first <= 5) 1482 { 1483 unsigned int i; 1484 *ascii++ = 46; /* decimal point */ 1485 /* ndigits may be <5 for small numbers, output leading zeros 1486 * then ndigits digits to first: 1487 */ 1488 i = 5; 1489 while (ndigits < i) *ascii++ = 48, --i; 1490 while (ndigits >= first) *ascii++ = digits[--ndigits]; 1491 /* Don't output the trailing zeros! */ 1492 } 1493 } 1494 else 1495 *ascii++ = 48; 1496 1497 /* And null terminate the string: */ 1498 *ascii = 0; 1499 return; 1500 } 1501 } 1502 1503 /* Here on buffer too small. */ 1504 png_error(png_ptr, "ASCII conversion buffer too small"); 1505} 1506# endif /* FIXED_POINT */ 1507#endif /* READ_SCAL */ 1508 1509#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ 1510 !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) 1511png_fixed_point 1512png_fixed(png_structp png_ptr, double fp, png_const_charp text) 1513{ 1514 double r = floor(100000 * fp + .5); 1515 1516 if (r > 2147483647. || r < -2147483648.) 1517 png_fixed_error(png_ptr, text); 1518 1519 return (png_fixed_point)r; 1520} 1521#endif 1522 1523#if defined(PNG_READ_GAMMA_SUPPORTED) || \ 1524 defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG__READ_pHYs_SUPPORTED) 1525/* muldiv functions */ 1526/* This API takes signed arguments and rounds the result to the nearest 1527 * integer (or, for a fixed point number - the standard argument - to 1528 * the nearest .00001). Overflow and divide by zero are signalled in 1529 * the result, a boolean - true on success, false on overflow. 1530 */ 1531int 1532png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, 1533 png_int_32 divisor) 1534{ 1535 /* Return a * times / divisor, rounded. */ 1536 if (divisor != 0) 1537 { 1538 if (a == 0 || times == 0) 1539 { 1540 *res = 0; 1541 return 1; 1542 } 1543 else 1544 { 1545#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 1546 double r = a; 1547 r *= times; 1548 r /= divisor; 1549 r = floor(r+.5); 1550 1551 /* A png_fixed_point is a 32-bit integer. */ 1552 if (r <= 2147483647. && r >= -2147483648.) 1553 { 1554 *res = (png_fixed_point)r; 1555 return 1; 1556 } 1557#else 1558 int negative = 0; 1559 png_uint_32 A, T, D; 1560 png_uint_32 s16, s32, s00; 1561 1562 if (a < 0) 1563 negative = 1, A = -a; 1564 else 1565 A = a; 1566 1567 if (times < 0) 1568 negative = !negative, T = -times; 1569 else 1570 T = times; 1571 1572 if (divisor < 0) 1573 negative = !negative, D = -divisor; 1574 else 1575 D = divisor; 1576 1577 /* Following can't overflow because the arguments only 1578 * have 31 bits each, however the result may be 32 bits. 1579 */ 1580 s16 = (A >> 16) * (T & 0xffff) + 1581 (A & 0xffff) * (T >> 16); 1582 /* Can't overflow because the a*times bit is only 30 1583 * bits at most. 1584 */ 1585 s32 = (A >> 16) * (T >> 16) + (s16 >> 16); 1586 s00 = (A & 0xffff) * (T & 0xffff); 1587 1588 s16 = (s16 & 0xffff) << 16; 1589 s00 += s16; 1590 1591 if (s00 < s16) 1592 ++s32; /* carry */ 1593 1594 if (s32 < D) /* else overflow */ 1595 { 1596 /* s32.s00 is now the 64-bit product, do a standard 1597 * division, we know that s32 < D, so the maximum 1598 * required shift is 31. 1599 */ 1600 int bitshift = 32; 1601 png_fixed_point result = 0; /* NOTE: signed */ 1602 1603 while (--bitshift >= 0) 1604 { 1605 png_uint_32 d32, d00; 1606 1607 if (bitshift > 0) 1608 d32 = D >> (32-bitshift), d00 = D << bitshift; 1609 1610 else 1611 d32 = 0, d00 = D; 1612 1613 if (s32 > d32) 1614 { 1615 if (s00 < d00) --s32; /* carry */ 1616 s32 -= d32, s00 -= d00, result += 1<<bitshift; 1617 } 1618 1619 else 1620 if (s32 == d32 && s00 >= d00) 1621 s32 = 0, s00 -= d00, result += 1<<bitshift; 1622 } 1623 1624 /* Handle the rounding. */ 1625 if (s00 >= (D >> 1)) 1626 ++result; 1627 1628 if (negative) 1629 result = -result; 1630 1631 /* Check for overflow. */ 1632 if ((negative && result <= 0) || (!negative && result >= 0)) 1633 { 1634 *res = result; 1635 return 1; 1636 } 1637 } 1638#endif 1639 } 1640 } 1641 1642 return 0; 1643} 1644#endif /* READ_GAMMA || INCH_CONVERSIONS */ 1645 1646#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) 1647/* The following is for when the caller doesn't much care about the 1648 * result. 1649 */ 1650png_fixed_point 1651png_muldiv_warn(png_structp png_ptr, png_fixed_point a, png_int_32 times, 1652 png_int_32 divisor) 1653{ 1654 png_fixed_point result; 1655 1656 if (png_muldiv(&result, a, times, divisor)) 1657 return result; 1658 1659 png_warning(png_ptr, "fixed point overflow ignored"); 1660 return 0; 1661} 1662#endif 1663 1664#ifdef PNG_READ_GAMMA_SUPPORTED /* more fixed point functions for gammma */ 1665/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ 1666png_fixed_point 1667png_reciprocal(png_fixed_point a) 1668{ 1669#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 1670 double r = floor(1E10/a+.5); 1671 1672 if (r <= 2147483647. && r >= -2147483648.) 1673 return (png_fixed_point)r; 1674#else 1675 png_fixed_point res; 1676 1677 if (png_muldiv(&res, 100000, 100000, a)) 1678 return res; 1679#endif 1680 1681 return 0; /* error/overflow */ 1682} 1683 1684/* A local convenience routine. */ 1685static png_fixed_point 1686png_product2(png_fixed_point a, png_fixed_point b) 1687{ 1688 /* The required result is 1/a * 1/b; the following preserves accuracy. */ 1689#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 1690 double r = a * 1E-5; 1691 r *= b; 1692 r = floor(r+.5); 1693 1694 if (r <= 2147483647. && r >= -2147483648.) 1695 return (png_fixed_point)r; 1696#else 1697 png_fixed_point res; 1698 1699 if (png_muldiv(&res, a, b, 100000)) 1700 return res; 1701#endif 1702 1703 return 0; /* overflow */ 1704} 1705 1706/* The inverse of the above. */ 1707png_fixed_point 1708png_reciprocal2(png_fixed_point a, png_fixed_point b) 1709{ 1710 /* The required result is 1/a * 1…
Large files files are truncated, but you can click here to view the full file