1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* pngtest.c - a simple test program to test libpng 26 * 27 * This file is available under and governed by the GNU General Public 28 * License version 2 only, as published by the Free Software Foundation. 29 * However, the following notice accompanied the original version of this 30 * file and, per its terms, should not be removed: 31 * 32 * Last changed in libpng 1.5.25 [December 3, 2015] 33 * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson 34 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 35 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 36 * 37 * This code is released under the libpng license. 38 * For conditions of distribution and use, see the disclaimer 39 * and license in png.h 40 * 41 * This program reads in a PNG image, writes it out again, and then 42 * compares the two files. If the files are identical, this shows that 43 * the basic chunk handling, filtering, and (de)compression code is working 44 * properly. It does not currently test all of the transforms, although 45 * it probably should. 46 * 47 * The program will report "FAIL" in certain legitimate cases: 48 * 1) when the compression level or filter selection method is changed. 49 * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192. 50 * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks 51 * exist in the input file. 52 * 4) others not listed here... 53 * In these cases, it is best to check with another tool such as "pngcheck" 54 * to see what the differences between the two files are. 55 * 56 * If a filename is given on the command-line, then this file is used 57 * for the input, rather than the default "pngtest.png". This allows 58 * testing a wide variety of files easily. You can also test a number 59 * of files at once by typing "pngtest -m file1.png file2.png ..." 60 */ 61 62 #define _POSIX_SOURCE 1 63 64 #include <stdio.h> 65 #include <stdlib.h> 66 #include <string.h> 67 68 /* Defined so I can write to a file on gui/windowing platforms */ 69 /* #define STDERR stderr */ 70 #define STDERR stdout /* For DOS */ 71 72 #include "png.h" 73 74 /* 1.6.1 added support for the configure test harness, which uses 77 to indicate 75 * a skipped test, in earlier versions we need to succeed on a skipped test, so: 76 */ 77 #if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H) 78 # define SKIP 77 79 #else 80 # define SKIP 0 81 #endif 82 83 /* Known chunks that exist in pngtest.png must be supported or pngtest will fail 84 * simply as a result of re-ordering them. This may be fixed in 1.7 85 * 86 * pngtest allocates a single row buffer for each row and overwrites it, 87 * therefore if the write side doesn't support the writing of interlaced images 88 * nothing can be done for an interlaced image (and the code below will fail 89 * horribly trying to write extra data after writing garbage). 90 */ 91 #if defined PNG_READ_SUPPORTED && /* else nothing can be done */\ 92 defined PNG_READ_bKGD_SUPPORTED &&\ 93 defined PNG_READ_cHRM_SUPPORTED &&\ 94 defined PNG_READ_gAMA_SUPPORTED &&\ 95 defined PNG_READ_oFFs_SUPPORTED &&\ 96 defined PNG_READ_pCAL_SUPPORTED &&\ 97 defined PNG_READ_pHYs_SUPPORTED &&\ 98 defined PNG_READ_sBIT_SUPPORTED &&\ 99 defined PNG_READ_sCAL_SUPPORTED &&\ 100 defined PNG_READ_sRGB_SUPPORTED &&\ 101 defined PNG_READ_sPLT_SUPPORTED &&\ 102 defined PNG_READ_tEXt_SUPPORTED &&\ 103 defined PNG_READ_tIME_SUPPORTED &&\ 104 defined PNG_READ_zTXt_SUPPORTED &&\ 105 (defined PNG_WRITE_INTERLACING_SUPPORTED || PNG_LIBPNG_VER >= 10700) 106 107 #ifdef PNG_ZLIB_HEADER 108 # include PNG_ZLIB_HEADER /* defined by pnglibconf.h from 1.7 */ 109 #else 110 # include "zlib.h" 111 #endif 112 113 /* Copied from pngpriv.h but only used in error messages below. */ 114 #ifndef PNG_ZBUF_SIZE 115 # define PNG_ZBUF_SIZE 8192 116 #endif 117 #define FCLOSE(file) fclose(file) 118 119 #ifndef PNG_STDIO_SUPPORTED 120 typedef FILE * png_FILE_p; 121 #endif 122 123 /* Makes pngtest verbose so we can find problems. */ 124 #ifndef PNG_DEBUG 125 # define PNG_DEBUG 0 126 #endif 127 128 #if PNG_DEBUG > 1 129 # define pngtest_debug(m) ((void)fprintf(stderr, m "\n")) 130 # define pngtest_debug1(m,p1) ((void)fprintf(stderr, m "\n", p1)) 131 # define pngtest_debug2(m,p1,p2) ((void)fprintf(stderr, m "\n", p1, p2)) 132 #else 133 # define pngtest_debug(m) ((void)0) 134 # define pngtest_debug1(m,p1) ((void)0) 135 # define pngtest_debug2(m,p1,p2) ((void)0) 136 #endif 137 138 #if !PNG_DEBUG 139 # define SINGLE_ROWBUF_ALLOC /* Makes buffer overruns easier to nail */ 140 #endif 141 142 #ifndef PNG_UNUSED 143 # define PNG_UNUSED(param) (void)param; 144 #endif 145 146 /* Turn on CPU timing 147 #define PNGTEST_TIMING 148 */ 149 150 #ifndef PNG_FLOATING_POINT_SUPPORTED 151 #undef PNGTEST_TIMING 152 #endif 153 154 #ifdef PNGTEST_TIMING 155 static float t_start, t_stop, t_decode, t_encode, t_misc; 156 #include <time.h> 157 #endif 158 159 #ifdef PNG_TIME_RFC1123_SUPPORTED 160 #define PNG_tIME_STRING_LENGTH 29 161 static int tIME_chunk_present = 0; 162 static char tIME_string[PNG_tIME_STRING_LENGTH] = "tIME chunk is not present"; 163 164 #if PNG_LIBPNG_VER < 10619 165 #define png_convert_to_rfc1123_buffer(ts, t) tIME_to_str(read_ptr, ts, t) 166 167 static int 168 tIME_to_str(png_structp png_ptr, png_charp ts, png_const_timep t) 169 { 170 png_const_charp str = png_convert_to_rfc1123(png_ptr, t); 171 172 if (str == NULL) 173 return 0; 174 175 strcpy(ts, str); 176 return 1; 177 } 178 #endif /* older libpng */ 179 #endif 180 181 static int verbose = 0; 182 static int strict = 0; 183 static int relaxed = 0; 184 static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */ 185 static int error_count = 0; /* count calls to png_error */ 186 static int warning_count = 0; /* count calls to png_warning */ 187 188 /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ 189 #ifndef png_jmpbuf 190 # define png_jmpbuf(png_ptr) png_ptr->jmpbuf 191 #endif 192 193 /* Defines for unknown chunk handling if required. */ 194 #ifndef PNG_HANDLE_CHUNK_ALWAYS 195 # define PNG_HANDLE_CHUNK_ALWAYS 3 196 #endif 197 #ifndef PNG_HANDLE_CHUNK_IF_SAFE 198 # define PNG_HANDLE_CHUNK_IF_SAFE 2 199 #endif 200 201 /* Utility to save typing/errors, the argument must be a name */ 202 #define MEMZERO(var) ((void)memset(&var, 0, sizeof var)) 203 204 /* Example of using row callbacks to make a simple progress meter */ 205 static int status_pass = 1; 206 static int status_dots_requested = 0; 207 static int status_dots = 1; 208 209 static void PNGCBAPI 210 read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) 211 { 212 if (png_ptr == NULL || row_number > PNG_UINT_31_MAX) 213 return; 214 215 if (status_pass != pass) 216 { 217 fprintf(stdout, "\n Pass %d: ", pass); 218 status_pass = pass; 219 status_dots = 31; 220 } 221 222 status_dots--; 223 224 if (status_dots == 0) 225 { 226 fprintf(stdout, "\n "); 227 status_dots=30; 228 } 229 230 fprintf(stdout, "r"); 231 } 232 233 #ifdef PNG_WRITE_SUPPORTED 234 static void PNGCBAPI 235 write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) 236 { 237 if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) 238 return; 239 240 fprintf(stdout, "w"); 241 } 242 #endif 243 244 245 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED 246 /* Example of using a user transform callback (doesn't do anything at present). 247 */ 248 static void PNGCBAPI 249 read_user_callback(png_structp png_ptr, png_row_infop row_info, png_bytep data) 250 { 251 PNG_UNUSED(png_ptr) 252 PNG_UNUSED(row_info) 253 PNG_UNUSED(data) 254 } 255 #endif 256 257 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED 258 /* Example of using user transform callback (we don't transform anything, 259 * but merely count the zero samples) 260 */ 261 262 static png_uint_32 zero_samples; 263 264 static void PNGCBAPI 265 count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) 266 { 267 png_bytep dp = data; 268 if (png_ptr == NULL) 269 return; 270 271 /* Contents of row_info: 272 * png_uint_32 width width of row 273 * png_uint_32 rowbytes number of bytes in row 274 * png_byte color_type color type of pixels 275 * png_byte bit_depth bit depth of samples 276 * png_byte channels number of channels (1-4) 277 * png_byte pixel_depth bits per pixel (depth*channels) 278 */ 279 280 /* Counts the number of zero samples (or zero pixels if color_type is 3 */ 281 282 if (row_info->color_type == 0 || row_info->color_type == 3) 283 { 284 int pos = 0; 285 png_uint_32 n, nstop; 286 287 for (n = 0, nstop=row_info->width; n<nstop; n++) 288 { 289 if (row_info->bit_depth == 1) 290 { 291 if (((*dp << pos++ ) & 0x80) == 0) 292 zero_samples++; 293 294 if (pos == 8) 295 { 296 pos = 0; 297 dp++; 298 } 299 } 300 301 if (row_info->bit_depth == 2) 302 { 303 if (((*dp << (pos+=2)) & 0xc0) == 0) 304 zero_samples++; 305 306 if (pos == 8) 307 { 308 pos = 0; 309 dp++; 310 } 311 } 312 313 if (row_info->bit_depth == 4) 314 { 315 if (((*dp << (pos+=4)) & 0xf0) == 0) 316 zero_samples++; 317 318 if (pos == 8) 319 { 320 pos = 0; 321 dp++; 322 } 323 } 324 325 if (row_info->bit_depth == 8) 326 if (*dp++ == 0) 327 zero_samples++; 328 329 if (row_info->bit_depth == 16) 330 { 331 if ((*dp | *(dp+1)) == 0) 332 zero_samples++; 333 dp+=2; 334 } 335 } 336 } 337 else /* Other color types */ 338 { 339 png_uint_32 n, nstop; 340 int channel; 341 int color_channels = row_info->channels; 342 if (row_info->color_type > 3) 343 color_channels--; 344 345 for (n = 0, nstop=row_info->width; n<nstop; n++) 346 { 347 for (channel = 0; channel < color_channels; channel++) 348 { 349 if (row_info->bit_depth == 8) 350 if (*dp++ == 0) 351 zero_samples++; 352 353 if (row_info->bit_depth == 16) 354 { 355 if ((*dp | *(dp+1)) == 0) 356 zero_samples++; 357 358 dp+=2; 359 } 360 } 361 if (row_info->color_type > 3) 362 { 363 dp++; 364 if (row_info->bit_depth == 16) 365 dp++; 366 } 367 } 368 } 369 } 370 #endif /* WRITE_USER_TRANSFORM */ 371 372 #ifndef PNG_STDIO_SUPPORTED 373 /* START of code to validate stdio-free compilation */ 374 /* These copies of the default read/write functions come from pngrio.c and 375 * pngwio.c. They allow "don't include stdio" testing of the library. 376 * This is the function that does the actual reading of data. If you are 377 * not reading from a standard C stream, you should create a replacement 378 * read_data function and use it at run time with png_set_read_fn(), rather 379 * than changing the library. 380 */ 381 382 #ifdef PNG_IO_STATE_SUPPORTED 383 void 384 pngtest_check_io_state(png_structp png_ptr, png_size_t data_length, 385 png_uint_32 io_op); 386 void 387 pngtest_check_io_state(png_structp png_ptr, png_size_t data_length, 388 png_uint_32 io_op) 389 { 390 png_uint_32 io_state = png_get_io_state(png_ptr); 391 int err = 0; 392 393 /* Check if the current operation (reading / writing) is as expected. */ 394 if ((io_state & PNG_IO_MASK_OP) != io_op) 395 png_error(png_ptr, "Incorrect operation in I/O state"); 396 397 /* Check if the buffer size specific to the current location 398 * (file signature / header / data / crc) is as expected. 399 */ 400 switch (io_state & PNG_IO_MASK_LOC) 401 { 402 case PNG_IO_SIGNATURE: 403 if (data_length > 8) 404 err = 1; 405 break; 406 case PNG_IO_CHUNK_HDR: 407 if (data_length != 8) 408 err = 1; 409 break; 410 case PNG_IO_CHUNK_DATA: 411 break; /* no restrictions here */ 412 case PNG_IO_CHUNK_CRC: 413 if (data_length != 4) 414 err = 1; 415 break; 416 default: 417 err = 1; /* uninitialized */ 418 } 419 if (err != 0) 420 png_error(png_ptr, "Bad I/O state or buffer size"); 421 } 422 #endif 423 424 static void PNGCBAPI 425 pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) 426 { 427 png_size_t check = 0; 428 png_voidp io_ptr; 429 430 /* fread() returns 0 on error, so it is OK to store this in a png_size_t 431 * instead of an int, which is what fread() actually returns. 432 */ 433 io_ptr = png_get_io_ptr(png_ptr); 434 if (io_ptr != NULL) 435 { 436 check = fread(data, 1, length, (png_FILE_p)io_ptr); 437 } 438 439 if (check != length) 440 { 441 png_error(png_ptr, "Read Error"); 442 } 443 444 #ifdef PNG_IO_STATE_SUPPORTED 445 pngtest_check_io_state(png_ptr, length, PNG_IO_READING); 446 #endif 447 } 448 449 #ifdef PNG_WRITE_FLUSH_SUPPORTED 450 static void PNGCBAPI 451 pngtest_flush(png_structp png_ptr) 452 { 453 /* Do nothing; fflush() is said to be just a waste of energy. */ 454 PNG_UNUSED(png_ptr) /* Stifle compiler warning */ 455 } 456 #endif 457 458 /* This is the function that does the actual writing of data. If you are 459 * not writing to a standard C stream, you should create a replacement 460 * write_data function and use it at run time with png_set_write_fn(), rather 461 * than changing the library. 462 */ 463 static void PNGCBAPI 464 pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) 465 { 466 png_size_t check; 467 468 check = fwrite(data, 1, length, (png_FILE_p)png_get_io_ptr(png_ptr)); 469 470 if (check != length) 471 { 472 png_error(png_ptr, "Write Error"); 473 } 474 475 #ifdef PNG_IO_STATE_SUPPORTED 476 pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING); 477 #endif 478 } 479 #endif /* !STDIO */ 480 481 /* This function is called when there is a warning, but the library thinks 482 * it can continue anyway. Replacement functions don't have to do anything 483 * here if you don't want to. In the default configuration, png_ptr is 484 * not used, but it is passed in case it may be useful. 485 */ 486 typedef struct 487 { 488 PNG_CONST char *file_name; 489 } pngtest_error_parameters; 490 491 static void PNGCBAPI 492 pngtest_warning(png_structp png_ptr, png_const_charp message) 493 { 494 PNG_CONST char *name = "UNKNOWN (ERROR!)"; 495 pngtest_error_parameters *test = 496 (pngtest_error_parameters*)png_get_error_ptr(png_ptr); 497 498 ++warning_count; 499 500 if (test != NULL && test->file_name != NULL) 501 name = test->file_name; 502 503 fprintf(STDERR, "%s: libpng warning: %s\n", name, message); 504 } 505 506 /* This is the default error handling function. Note that replacements for 507 * this function MUST NOT RETURN, or the program will likely crash. This 508 * function is used by default, or if the program supplies NULL for the 509 * error function pointer in png_set_error_fn(). 510 */ 511 static void PNGCBAPI 512 pngtest_error(png_structp png_ptr, png_const_charp message) 513 { 514 ++error_count; 515 516 pngtest_warning(png_ptr, message); 517 /* We can return because png_error calls the default handler, which is 518 * actually OK in this case. 519 */ 520 } 521 522 /* END of code to validate stdio-free compilation */ 523 524 /* START of code to validate memory allocation and deallocation */ 525 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG 526 527 /* Allocate memory. For reasonable files, size should never exceed 528 * 64K. However, zlib may allocate more than 64K if you don't tell 529 * it not to. See zconf.h and png.h for more information. zlib does 530 * need to allocate exactly 64K, so whatever you call here must 531 * have the ability to do that. 532 * 533 * This piece of code can be compiled to validate max 64K allocations 534 * by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. 535 */ 536 typedef struct memory_information 537 { 538 png_alloc_size_t size; 539 png_voidp pointer; 540 struct memory_information *next; 541 } memory_information; 542 typedef memory_information *memory_infop; 543 544 static memory_infop pinformation = NULL; 545 static int current_allocation = 0; 546 static int maximum_allocation = 0; 547 static int total_allocation = 0; 548 static int num_allocations = 0; 549 550 png_voidp PNGCBAPI png_debug_malloc PNGARG((png_structp png_ptr, 551 png_alloc_size_t size)); 552 void PNGCBAPI png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr)); 553 554 png_voidp 555 PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size) 556 { 557 558 /* png_malloc has already tested for NULL; png_create_struct calls 559 * png_debug_malloc directly, with png_ptr == NULL which is OK 560 */ 561 562 if (size == 0) 563 return (NULL); 564 565 /* This calls the library allocator twice, once to get the requested 566 buffer and once to get a new free list entry. */ 567 { 568 /* Disable malloc_fn and free_fn */ 569 memory_infop pinfo; 570 png_set_mem_fn(png_ptr, NULL, NULL, NULL); 571 pinfo = (memory_infop)png_malloc(png_ptr, 572 (sizeof *pinfo)); 573 pinfo->size = size; 574 current_allocation += size; 575 total_allocation += size; 576 num_allocations ++; 577 578 if (current_allocation > maximum_allocation) 579 maximum_allocation = current_allocation; 580 581 pinfo->pointer = png_malloc(png_ptr, size); 582 /* Restore malloc_fn and free_fn */ 583 584 png_set_mem_fn(png_ptr, 585 NULL, png_debug_malloc, png_debug_free); 586 587 if (size != 0 && pinfo->pointer == NULL) 588 { 589 current_allocation -= size; 590 total_allocation -= size; 591 png_error(png_ptr, 592 "out of memory in pngtest->png_debug_malloc"); 593 } 594 595 pinfo->next = pinformation; 596 pinformation = pinfo; 597 /* Make sure the caller isn't assuming zeroed memory. */ 598 memset(pinfo->pointer, 0xdd, pinfo->size); 599 600 if (verbose != 0) 601 printf("png_malloc %lu bytes at %p\n", (unsigned long)size, 602 pinfo->pointer); 603 604 return (png_voidp)(pinfo->pointer); 605 } 606 } 607 608 /* Free a pointer. It is removed from the list at the same time. */ 609 void PNGCBAPI 610 png_debug_free(png_structp png_ptr, png_voidp ptr) 611 { 612 if (png_ptr == NULL) 613 fprintf(STDERR, "NULL pointer to png_debug_free.\n"); 614 615 if (ptr == 0) 616 { 617 #if 0 /* This happens all the time. */ 618 fprintf(STDERR, "WARNING: freeing NULL pointer\n"); 619 #endif 620 return; 621 } 622 623 /* Unlink the element from the list. */ 624 if (pinformation != NULL) 625 { 626 memory_infop *ppinfo = &pinformation; 627 628 for (;;) 629 { 630 memory_infop pinfo = *ppinfo; 631 632 if (pinfo->pointer == ptr) 633 { 634 *ppinfo = pinfo->next; 635 current_allocation -= pinfo->size; 636 if (current_allocation < 0) 637 fprintf(STDERR, "Duplicate free of memory\n"); 638 /* We must free the list element too, but first kill 639 the memory that is to be freed. */ 640 memset(ptr, 0x55, pinfo->size); 641 free(pinfo); 642 pinfo = NULL; 643 break; 644 } 645 646 if (pinfo->next == NULL) 647 { 648 fprintf(STDERR, "Pointer %p not found\n", ptr); 649 break; 650 } 651 652 ppinfo = &pinfo->next; 653 } 654 } 655 656 /* Finally free the data. */ 657 if (verbose != 0) 658 printf("Freeing %p\n", ptr); 659 660 if (ptr != NULL) 661 free(ptr); 662 ptr = NULL; 663 } 664 #endif /* USER_MEM && DEBUG */ 665 /* END of code to test memory allocation/deallocation */ 666 667 668 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED 669 /* Demonstration of user chunk support of the sTER and vpAg chunks */ 670 671 /* (sTER is a public chunk not yet known by libpng. vpAg is a private 672 chunk used in ImageMagick to store "virtual page" size). */ 673 674 static struct user_chunk_data 675 { 676 png_const_infop info_ptr; 677 png_uint_32 vpAg_width, vpAg_height; 678 png_byte vpAg_units; 679 png_byte sTER_mode; 680 int location[2]; 681 } 682 user_chunk_data; 683 684 /* Used for location and order; zero means nothing. */ 685 #define have_sTER 0x01 686 #define have_vpAg 0x02 687 #define before_PLTE 0x10 688 #define before_IDAT 0x20 689 #define after_IDAT 0x40 690 691 static void 692 init_callback_info(png_const_infop info_ptr) 693 { 694 MEMZERO(user_chunk_data); 695 user_chunk_data.info_ptr = info_ptr; 696 } 697 698 static int 699 set_location(png_structp png_ptr, struct user_chunk_data *data, int what) 700 { 701 int location; 702 703 if ((data->location[0] & what) != 0 || (data->location[1] & what) != 0) 704 return 0; /* already have one of these */ 705 706 /* Find where we are (the code below zeroes info_ptr to indicate that the 707 * chunks before the first IDAT have been read.) 708 */ 709 if (data->info_ptr == NULL) /* after IDAT */ 710 location = what | after_IDAT; 711 712 else if (png_get_valid(png_ptr, data->info_ptr, PNG_INFO_PLTE) != 0) 713 location = what | before_IDAT; 714 715 else 716 location = what | before_PLTE; 717 718 if (data->location[0] == 0) 719 data->location[0] = location; 720 721 else 722 data->location[1] = location; 723 724 return 1; /* handled */ 725 } 726 727 static int PNGCBAPI 728 read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk) 729 { 730 struct user_chunk_data *my_user_chunk_data = 731 (struct user_chunk_data*)png_get_user_chunk_ptr(png_ptr); 732 733 if (my_user_chunk_data == NULL) 734 png_error(png_ptr, "lost user chunk pointer"); 735 736 /* Return one of the following: 737 * return (-n); chunk had an error 738 * return (0); did not recognize 739 * return (n); success 740 * 741 * The unknown chunk structure contains the chunk data: 742 * png_byte name[5]; 743 * png_byte *data; 744 * png_size_t size; 745 * 746 * Note that libpng has already taken care of the CRC handling. 747 */ 748 749 if (chunk->name[0] == 115 && chunk->name[1] == 84 && /* s T */ 750 chunk->name[2] == 69 && chunk->name[3] == 82) /* E R */ 751 { 752 /* Found sTER chunk */ 753 if (chunk->size != 1) 754 return (-1); /* Error return */ 755 756 if (chunk->data[0] != 0 && chunk->data[0] != 1) 757 return (-1); /* Invalid mode */ 758 759 if (set_location(png_ptr, my_user_chunk_data, have_sTER) != 0) 760 { 761 my_user_chunk_data->sTER_mode=chunk->data[0]; 762 return (1); 763 } 764 765 else 766 return (0); /* duplicate sTER - give it to libpng */ 767 } 768 769 if (chunk->name[0] != 118 || chunk->name[1] != 112 || /* v p */ 770 chunk->name[2] != 65 || chunk->name[3] != 103) /* A g */ 771 return (0); /* Did not recognize */ 772 773 /* Found ImageMagick vpAg chunk */ 774 775 if (chunk->size != 9) 776 return (-1); /* Error return */ 777 778 if (set_location(png_ptr, my_user_chunk_data, have_vpAg) == 0) 779 return (0); /* duplicate vpAg */ 780 781 my_user_chunk_data->vpAg_width = png_get_uint_31(png_ptr, chunk->data); 782 my_user_chunk_data->vpAg_height = png_get_uint_31(png_ptr, chunk->data + 4); 783 my_user_chunk_data->vpAg_units = chunk->data[8]; 784 785 return (1); 786 } 787 788 #ifdef PNG_WRITE_SUPPORTED 789 static void 790 write_sTER_chunk(png_structp write_ptr) 791 { 792 png_byte sTER[5] = {115, 84, 69, 82, '\0'}; 793 794 if (verbose != 0) 795 fprintf(STDERR, "\n stereo mode = %d\n", user_chunk_data.sTER_mode); 796 797 png_write_chunk(write_ptr, sTER, &user_chunk_data.sTER_mode, 1); 798 } 799 800 static void 801 write_vpAg_chunk(png_structp write_ptr) 802 { 803 png_byte vpAg[5] = {118, 112, 65, 103, '\0'}; 804 805 png_byte vpag_chunk_data[9]; 806 807 if (verbose != 0) 808 fprintf(STDERR, " vpAg = %lu x %lu, units = %d\n", 809 (unsigned long)user_chunk_data.vpAg_width, 810 (unsigned long)user_chunk_data.vpAg_height, 811 user_chunk_data.vpAg_units); 812 813 png_save_uint_32(vpag_chunk_data, user_chunk_data.vpAg_width); 814 png_save_uint_32(vpag_chunk_data + 4, user_chunk_data.vpAg_height); 815 vpag_chunk_data[8] = user_chunk_data.vpAg_units; 816 png_write_chunk(write_ptr, vpAg, vpag_chunk_data, 9); 817 } 818 819 static void 820 write_chunks(png_structp write_ptr, int location) 821 { 822 int i; 823 824 /* Notice that this preserves the original chunk order, however chunks 825 * intercepted by the callback will be written *after* chunks passed to 826 * libpng. This will actually reverse a pair of sTER chunks or a pair of 827 * vpAg chunks, resulting in an error later. This is not worth worrying 828 * about - the chunks should not be duplicated! 829 */ 830 for (i=0; i<2; ++i) 831 { 832 if (user_chunk_data.location[i] == (location | have_sTER)) 833 write_sTER_chunk(write_ptr); 834 835 else if (user_chunk_data.location[i] == (location | have_vpAg)) 836 write_vpAg_chunk(write_ptr); 837 } 838 } 839 #endif /* WRITE */ 840 #else /* !READ_USER_CHUNKS */ 841 # define write_chunks(pp,loc) ((void)0) 842 #endif 843 /* END of code to demonstrate user chunk support */ 844 845 /* START of code to check that libpng has the required text support; this only 846 * checks for the write support because if read support is missing the chunk 847 * will simply not be reported back to pngtest. 848 */ 849 #ifdef PNG_TEXT_SUPPORTED 850 static void 851 pngtest_check_text_support(png_structp png_ptr, png_textp text_ptr, 852 int num_text) 853 { 854 while (num_text > 0) 855 { 856 switch (text_ptr[--num_text].compression) 857 { 858 case PNG_TEXT_COMPRESSION_NONE: 859 break; 860 861 case PNG_TEXT_COMPRESSION_zTXt: 862 # ifndef PNG_WRITE_zTXt_SUPPORTED 863 ++unsupported_chunks; 864 /* In libpng 1.7 this now does an app-error, so stop it: */ 865 text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE; 866 # endif 867 break; 868 869 case PNG_ITXT_COMPRESSION_NONE: 870 case PNG_ITXT_COMPRESSION_zTXt: 871 # ifndef PNG_WRITE_iTXt_SUPPORTED 872 ++unsupported_chunks; 873 text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE; 874 # endif 875 break; 876 877 default: 878 /* This is an error */ 879 png_error(png_ptr, "invalid text chunk compression field"); 880 break; 881 } 882 } 883 } 884 #endif 885 /* END of code to check that libpng has the required text support */ 886 887 /* Test one file */ 888 static int 889 test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) 890 { 891 static png_FILE_p fpin; 892 static png_FILE_p fpout; /* "static" prevents setjmp corruption */ 893 pngtest_error_parameters error_parameters; 894 png_structp read_ptr; 895 png_infop read_info_ptr, end_info_ptr; 896 #ifdef PNG_WRITE_SUPPORTED 897 png_structp write_ptr; 898 png_infop write_info_ptr; 899 png_infop write_end_info_ptr; 900 #ifdef PNG_WRITE_FILTER_SUPPORTED 901 int interlace_preserved = 1; 902 #endif /* WRITE_FILTER */ 903 #else /* !WRITE */ 904 png_structp write_ptr = NULL; 905 png_infop write_info_ptr = NULL; 906 png_infop write_end_info_ptr = NULL; 907 #endif /* !WRITE */ 908 png_bytep row_buf; 909 png_uint_32 y; 910 png_uint_32 width, height; 911 volatile int num_passes; 912 int pass; 913 int bit_depth, color_type; 914 915 row_buf = NULL; 916 error_parameters.file_name = inname; 917 918 if ((fpin = fopen(inname, "rb")) == NULL) 919 { 920 fprintf(STDERR, "Could not find input file %s\n", inname); 921 return (1); 922 } 923 924 if ((fpout = fopen(outname, "wb")) == NULL) 925 { 926 fprintf(STDERR, "Could not open output file %s\n", outname); 927 FCLOSE(fpin); 928 return (1); 929 } 930 931 pngtest_debug("Allocating read and write structures"); 932 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG 933 read_ptr = 934 png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL, 935 NULL, NULL, NULL, png_debug_malloc, png_debug_free); 936 #else 937 read_ptr = 938 png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 939 #endif 940 png_set_error_fn(read_ptr, &error_parameters, pngtest_error, 941 pngtest_warning); 942 943 #ifdef PNG_WRITE_SUPPORTED 944 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG 945 write_ptr = 946 png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL, 947 NULL, NULL, NULL, png_debug_malloc, png_debug_free); 948 #else 949 write_ptr = 950 png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 951 #endif 952 png_set_error_fn(write_ptr, &error_parameters, pngtest_error, 953 pngtest_warning); 954 #endif 955 pngtest_debug("Allocating read_info, write_info and end_info structures"); 956 read_info_ptr = png_create_info_struct(read_ptr); 957 end_info_ptr = png_create_info_struct(read_ptr); 958 #ifdef PNG_WRITE_SUPPORTED 959 write_info_ptr = png_create_info_struct(write_ptr); 960 write_end_info_ptr = png_create_info_struct(write_ptr); 961 #endif 962 963 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED 964 init_callback_info(read_info_ptr); 965 png_set_read_user_chunk_fn(read_ptr, &user_chunk_data, 966 read_user_chunk_callback); 967 #endif 968 969 #ifdef PNG_SETJMP_SUPPORTED 970 pngtest_debug("Setting jmpbuf for read struct"); 971 if (setjmp(png_jmpbuf(read_ptr))) 972 { 973 fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname); 974 png_free(read_ptr, row_buf); 975 row_buf = NULL; 976 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); 977 #ifdef PNG_WRITE_SUPPORTED 978 png_destroy_info_struct(write_ptr, &write_end_info_ptr); 979 png_destroy_write_struct(&write_ptr, &write_info_ptr); 980 #endif 981 FCLOSE(fpin); 982 FCLOSE(fpout); 983 return (1); 984 } 985 986 #ifdef PNG_WRITE_SUPPORTED 987 pngtest_debug("Setting jmpbuf for write struct"); 988 989 if (setjmp(png_jmpbuf(write_ptr))) 990 { 991 fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname); 992 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); 993 png_destroy_info_struct(write_ptr, &write_end_info_ptr); 994 #ifdef PNG_WRITE_SUPPORTED 995 png_destroy_write_struct(&write_ptr, &write_info_ptr); 996 #endif 997 FCLOSE(fpin); 998 FCLOSE(fpout); 999 return (1); 1000 } 1001 #endif 1002 #endif 1003 1004 if (strict != 0) 1005 { 1006 /* Treat png_benign_error() as errors on read */ 1007 png_set_benign_errors(read_ptr, 0); 1008 1009 #ifdef PNG_WRITE_SUPPORTED 1010 /* Treat them as errors on write */ 1011 png_set_benign_errors(write_ptr, 0); 1012 #endif 1013 1014 /* if strict is not set, then app warnings and errors are treated as 1015 * warnings in release builds, but not in unstable builds; this can be 1016 * changed with '--relaxed'. 1017 */ 1018 } 1019 1020 else if (relaxed != 0) 1021 { 1022 /* Allow application (pngtest) errors and warnings to pass */ 1023 png_set_benign_errors(read_ptr, 1); 1024 1025 #ifdef PNG_WRITE_SUPPORTED 1026 png_set_benign_errors(write_ptr, 1); 1027 #endif 1028 } 1029 1030 pngtest_debug("Initializing input and output streams"); 1031 #ifdef PNG_STDIO_SUPPORTED 1032 png_init_io(read_ptr, fpin); 1033 # ifdef PNG_WRITE_SUPPORTED 1034 png_init_io(write_ptr, fpout); 1035 # endif 1036 #else 1037 png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data); 1038 # ifdef PNG_WRITE_SUPPORTED 1039 png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data, 1040 # ifdef PNG_WRITE_FLUSH_SUPPORTED 1041 pngtest_flush); 1042 # else 1043 NULL); 1044 # endif 1045 # endif 1046 #endif 1047 1048 if (status_dots_requested == 1) 1049 { 1050 #ifdef PNG_WRITE_SUPPORTED 1051 png_set_write_status_fn(write_ptr, write_row_callback); 1052 #endif 1053 png_set_read_status_fn(read_ptr, read_row_callback); 1054 } 1055 1056 else 1057 { 1058 #ifdef PNG_WRITE_SUPPORTED 1059 png_set_write_status_fn(write_ptr, NULL); 1060 #endif 1061 png_set_read_status_fn(read_ptr, NULL); 1062 } 1063 1064 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED 1065 png_set_read_user_transform_fn(read_ptr, read_user_callback); 1066 #endif 1067 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED 1068 zero_samples = 0; 1069 png_set_write_user_transform_fn(write_ptr, count_zero_samples); 1070 #endif 1071 1072 #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED 1073 /* Preserve all the unknown chunks, if possible. If this is disabled then, 1074 * even if the png_{get,set}_unknown_chunks stuff is enabled, we can't use 1075 * libpng to *save* the unknown chunks on read (because we can't switch the 1076 * save option on!) 1077 * 1078 * Notice that if SET_UNKNOWN_CHUNKS is *not* supported read will discard all 1079 * unknown chunks and write will write them all. 1080 */ 1081 #ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED 1082 png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS, 1083 NULL, 0); 1084 #endif 1085 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED 1086 png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS, 1087 NULL, 0); 1088 #endif 1089 #endif 1090 1091 pngtest_debug("Reading info struct"); 1092 png_read_info(read_ptr, read_info_ptr); 1093 1094 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED 1095 /* This is a bit of a hack; there is no obvious way in the callback function 1096 * to determine that the chunks before the first IDAT have been read, so 1097 * remove the info_ptr (which is only used to determine position relative to 1098 * PLTE) here to indicate that we are after the IDAT. 1099 */ 1100 user_chunk_data.info_ptr = NULL; 1101 #endif 1102 1103 pngtest_debug("Transferring info struct"); 1104 { 1105 int interlace_type, compression_type, filter_type; 1106 1107 if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth, 1108 &color_type, &interlace_type, &compression_type, &filter_type) != 0) 1109 { 1110 png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth, 1111 color_type, interlace_type, compression_type, filter_type); 1112 /* num_passes may not be available below if interlace support is not 1113 * provided by libpng for both read and write. 1114 */ 1115 switch (interlace_type) 1116 { 1117 case PNG_INTERLACE_NONE: 1118 num_passes = 1; 1119 break; 1120 1121 case PNG_INTERLACE_ADAM7: 1122 num_passes = 7; 1123 break; 1124 1125 default: 1126 png_error(read_ptr, "invalid interlace type"); 1127 /*NOT REACHED*/ 1128 } 1129 } 1130 1131 else 1132 png_error(read_ptr, "png_get_IHDR failed"); 1133 } 1134 #ifdef PNG_FIXED_POINT_SUPPORTED 1135 #ifdef PNG_cHRM_SUPPORTED 1136 { 1137 png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x, 1138 blue_y; 1139 1140 if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, 1141 &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) 1142 { 1143 png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x, 1144 red_y, green_x, green_y, blue_x, blue_y); 1145 } 1146 } 1147 #endif 1148 #ifdef PNG_gAMA_SUPPORTED 1149 { 1150 png_fixed_point gamma; 1151 1152 if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma) != 0) 1153 png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma); 1154 } 1155 #endif 1156 #else /* Use floating point versions */ 1157 #ifdef PNG_FLOATING_POINT_SUPPORTED 1158 #ifdef PNG_cHRM_SUPPORTED 1159 { 1160 double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, 1161 blue_y; 1162 1163 if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x, 1164 &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) 1165 { 1166 png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x, 1167 red_y, green_x, green_y, blue_x, blue_y); 1168 } 1169 } 1170 #endif 1171 #ifdef PNG_gAMA_SUPPORTED 1172 { 1173 double gamma; 1174 1175 if (png_get_gAMA(read_ptr, read_info_ptr, &gamma) != 0) 1176 png_set_gAMA(write_ptr, write_info_ptr, gamma); 1177 } 1178 #endif 1179 #endif /* Floating point */ 1180 #endif /* Fixed point */ 1181 #ifdef PNG_iCCP_SUPPORTED 1182 { 1183 png_charp name; 1184 png_bytep profile; 1185 png_uint_32 proflen; 1186 int compression_type; 1187 1188 if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type, 1189 &profile, &proflen) != 0) 1190 { 1191 png_set_iCCP(write_ptr, write_info_ptr, name, compression_type, 1192 profile, proflen); 1193 } 1194 } 1195 #endif 1196 #ifdef PNG_sRGB_SUPPORTED 1197 { 1198 int intent; 1199 1200 if (png_get_sRGB(read_ptr, read_info_ptr, &intent) != 0) 1201 png_set_sRGB(write_ptr, write_info_ptr, intent); 1202 } 1203 #endif 1204 { 1205 png_colorp palette; 1206 int num_palette; 1207 1208 if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette) != 0) 1209 png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette); 1210 } 1211 #ifdef PNG_bKGD_SUPPORTED 1212 { 1213 png_color_16p background; 1214 1215 if (png_get_bKGD(read_ptr, read_info_ptr, &background) != 0) 1216 { 1217 png_set_bKGD(write_ptr, write_info_ptr, background); 1218 } 1219 } 1220 #endif 1221 #ifdef PNG_hIST_SUPPORTED 1222 { 1223 png_uint_16p hist; 1224 1225 if (png_get_hIST(read_ptr, read_info_ptr, &hist) != 0) 1226 png_set_hIST(write_ptr, write_info_ptr, hist); 1227 } 1228 #endif 1229 #ifdef PNG_oFFs_SUPPORTED 1230 { 1231 png_int_32 offset_x, offset_y; 1232 int unit_type; 1233 1234 if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y, 1235 &unit_type) != 0) 1236 { 1237 png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type); 1238 } 1239 } 1240 #endif 1241 #ifdef PNG_pCAL_SUPPORTED 1242 { 1243 png_charp purpose, units; 1244 png_charpp params; 1245 png_int_32 X0, X1; 1246 int type, nparams; 1247 1248 if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type, 1249 &nparams, &units, ¶ms) != 0) 1250 { 1251 png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type, 1252 nparams, units, params); 1253 } 1254 } 1255 #endif 1256 #ifdef PNG_pHYs_SUPPORTED 1257 { 1258 png_uint_32 res_x, res_y; 1259 int unit_type; 1260 1261 if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, 1262 &unit_type) != 0) 1263 png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type); 1264 } 1265 #endif 1266 #ifdef PNG_sBIT_SUPPORTED 1267 { 1268 png_color_8p sig_bit; 1269 1270 if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit) != 0) 1271 png_set_sBIT(write_ptr, write_info_ptr, sig_bit); 1272 } 1273 #endif 1274 #ifdef PNG_sCAL_SUPPORTED 1275 #if defined(PNG_FLOATING_POINT_SUPPORTED) && \ 1276 defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) 1277 { 1278 int unit; 1279 double scal_width, scal_height; 1280 1281 if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width, 1282 &scal_height) != 0) 1283 { 1284 png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height); 1285 } 1286 } 1287 #else 1288 #ifdef PNG_FIXED_POINT_SUPPORTED 1289 { 1290 int unit; 1291 png_charp scal_width, scal_height; 1292 1293 if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width, 1294 &scal_height) != 0) 1295 { 1296 png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, 1297 scal_height); 1298 } 1299 } 1300 #endif 1301 #endif 1302 #endif 1303 1304 #ifdef PNG_sPLT_SUPPORTED 1305 { 1306 png_sPLT_tp entries; 1307 1308 int num_entries = (int) png_get_sPLT(read_ptr, read_info_ptr, &entries); 1309 if (num_entries) 1310 { 1311 png_set_sPLT(write_ptr, write_info_ptr, entries, num_entries); 1312 } 1313 } 1314 #endif 1315 1316 #ifdef PNG_TEXT_SUPPORTED 1317 { 1318 png_textp text_ptr; 1319 int num_text; 1320 1321 if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0) 1322 { 1323 pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); 1324 1325 pngtest_check_text_support(read_ptr, text_ptr, num_text); 1326 1327 if (verbose != 0) 1328 { 1329 int i; 1330 1331 printf("\n"); 1332 for (i=0; i<num_text; i++) 1333 { 1334 printf(" Text compression[%d]=%d\n", 1335 i, text_ptr[i].compression); 1336 } 1337 } 1338 1339 png_set_text(write_ptr, write_info_ptr, text_ptr, num_text); 1340 } 1341 } 1342 #endif 1343 #ifdef PNG_tIME_SUPPORTED 1344 { 1345 png_timep mod_time; 1346 1347 if (png_get_tIME(read_ptr, read_info_ptr, &mod_time) != 0) 1348 { 1349 png_set_tIME(write_ptr, write_info_ptr, mod_time); 1350 #ifdef PNG_TIME_RFC1123_SUPPORTED 1351 if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0) 1352 tIME_string[(sizeof tIME_string) - 1] = '\0'; 1353 1354 else 1355 { 1356 strncpy(tIME_string, "*** invalid time ***", (sizeof tIME_string)); 1357 tIME_string[(sizeof tIME_string) - 1] = '\0'; 1358 } 1359 1360 tIME_chunk_present++; 1361 #endif /* TIME_RFC1123 */ 1362 } 1363 } 1364 #endif 1365 #ifdef PNG_tRNS_SUPPORTED 1366 { 1367 png_bytep trans_alpha; 1368 int num_trans; 1369 png_color_16p trans_color; 1370 1371 if (png_get_tRNS(read_ptr, read_info_ptr, &trans_alpha, &num_trans, 1372 &trans_color) != 0) 1373 { 1374 int sample_max = (1 << bit_depth); 1375 /* libpng doesn't reject a tRNS chunk with out-of-range samples */ 1376 if (!((color_type == PNG_COLOR_TYPE_GRAY && 1377 (int)trans_color->gray > sample_max) || 1378 (color_type == PNG_COLOR_TYPE_RGB && 1379 ((int)trans_color->red > sample_max || 1380 (int)trans_color->green > sample_max || 1381 (int)trans_color->blue > sample_max)))) 1382 png_set_tRNS(write_ptr, write_info_ptr, trans_alpha, num_trans, 1383 trans_color); 1384 } 1385 } 1386 #endif 1387 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED 1388 { 1389 png_unknown_chunkp unknowns; 1390 int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr, 1391 &unknowns); 1392 1393 if (num_unknowns != 0) 1394 { 1395 png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns, 1396 num_unknowns); 1397 #if PNG_LIBPNG_VER < 10600 1398 /* Copy the locations from the read_info_ptr. The automatically 1399 * generated locations in write_end_info_ptr are wrong prior to 1.6.0 1400 * because they are reset from the write pointer (removed in 1.6.0). 1401 */ 1402 { 1403 int i; 1404 for (i = 0; i < num_unknowns; i++) 1405 png_set_unknown_chunk_location(write_ptr, write_info_ptr, i, 1406 unknowns[i].location); 1407 } 1408 #endif 1409 } 1410 } 1411 #endif 1412 1413 #ifdef PNG_WRITE_SUPPORTED 1414 pngtest_debug("Writing info struct"); 1415 1416 /* Write the info in two steps so that if we write the 'unknown' chunks here 1417 * they go to the correct place. 1418 */ 1419 png_write_info_before_PLTE(write_ptr, write_info_ptr); 1420 1421 write_chunks(write_ptr, before_PLTE); /* before PLTE */ 1422 1423 png_write_info(write_ptr, write_info_ptr); 1424 1425 write_chunks(write_ptr, before_IDAT); /* after PLTE */ 1426 #endif 1427 1428 #ifdef SINGLE_ROWBUF_ALLOC 1429 pngtest_debug("Allocating row buffer..."); 1430 row_buf = (png_bytep)png_malloc(read_ptr, 1431 png_get_rowbytes(read_ptr, read_info_ptr)); 1432 1433 pngtest_debug1("\t0x%08lx", (unsigned long)row_buf); 1434 #endif /* SINGLE_ROWBUF_ALLOC */ 1435 pngtest_debug("Writing row data"); 1436 1437 #if defined(PNG_READ_INTERLACING_SUPPORTED) &&\ 1438 defined(PNG_WRITE_INTERLACING_SUPPORTED) 1439 /* Both must be defined for libpng to be able to handle the interlace, 1440 * otherwise it gets handled below by simply reading and writing the passes 1441 * directly. 1442 */ 1443 if (png_set_interlace_handling(read_ptr) != num_passes) 1444 png_error(write_ptr, 1445 "png_set_interlace_handling(read): wrong pass count "); 1446 if (png_set_interlace_handling(write_ptr) != num_passes) 1447 png_error(write_ptr, 1448 "png_set_interlace_handling(write): wrong pass count "); 1449 #else /* png_set_interlace_handling not called on either read or write */ 1450 # define calc_pass_height 1451 #endif /* not using libpng interlace handling */ 1452 1453 #ifdef PNGTEST_TIMING 1454 t_stop = (float)clock(); 1455 t_misc += (t_stop - t_start); 1456 t_start = t_stop; 1457 #endif 1458 for (pass = 0; pass < num_passes; pass++) 1459 { 1460 # ifdef calc_pass_height 1461 png_uint_32 pass_height; 1462 1463 if (num_passes == 7) /* interlaced */ 1464 { 1465 if (PNG_PASS_COLS(width, pass) > 0) 1466 pass_height = PNG_PASS_ROWS(height, pass); 1467 1468 else 1469 pass_height = 0; 1470 } 1471 1472 else /* not interlaced */ 1473 pass_height = height; 1474 # else 1475 # define pass_height height 1476 # endif 1477 1478 pngtest_debug1("Writing row data for pass %d", pass); 1479 for (y = 0; y < pass_height; y++) 1480 { 1481 #ifndef SINGLE_ROWBUF_ALLOC 1482 pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y); 1483 1484 row_buf = (png_bytep)png_malloc(read_ptr, 1485 png_get_rowbytes(read_ptr, read_info_ptr)); 1486 1487 pngtest_debug2("\t0x%08lx (%lu bytes)", (unsigned long)row_buf, 1488 (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr)); 1489 1490 #endif /* !SINGLE_ROWBUF_ALLOC */ 1491 png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1); 1492 1493 #ifdef PNG_WRITE_SUPPORTED 1494 #ifdef PNGTEST_TIMING 1495 t_stop = (float)clock(); 1496 t_decode += (t_stop - t_start); 1497 t_start = t_stop; 1498 #endif 1499 png_write_rows(write_ptr, (png_bytepp)&row_buf, 1); 1500 #ifdef PNGTEST_TIMING 1501 t_stop = (float)clock(); 1502 t_encode += (t_stop - t_start); 1503 t_start = t_stop; 1504 #endif 1505 #endif /* WRITE */ 1506 1507 #ifndef SINGLE_ROWBUF_ALLOC 1508 pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y); 1509 png_free(read_ptr, row_buf); 1510 row_buf = NULL; 1511 #endif /* !SINGLE_ROWBUF_ALLOC */ 1512 } 1513 } 1514 1515 #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED 1516 # ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED 1517 png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1); 1518 # endif 1519 # ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED 1520 png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1); 1521 # endif 1522 #endif 1523 1524 pngtest_debug("Reading and writing end_info data"); 1525 1526 png_read_end(read_ptr, end_info_ptr); 1527 #ifdef PNG_TEXT_SUPPORTED 1528 { 1529 png_textp text_ptr; 1530 int num_text; 1531 1532 if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0) 1533 { 1534 pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); 1535 1536 pngtest_check_text_support(read_ptr, text_ptr, num_text); 1537 1538 if (verbose != 0) 1539 { 1540 int i; 1541 1542 printf("\n"); 1543 for (i=0; i<num_text; i++) 1544 { 1545 printf(" Text compression[%d]=%d\n", 1546 i, text_ptr[i].compression); 1547 } 1548 } 1549 1550 png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text); 1551 } 1552 } 1553 #endif 1554 #ifdef PNG_tIME_SUPPORTED 1555 { 1556 png_timep mod_time; 1557 1558 if (png_get_tIME(read_ptr, end_info_ptr, &mod_time) != 0) 1559 { 1560 png_set_tIME(write_ptr, write_end_info_ptr, mod_time); 1561 #ifdef PNG_TIME_RFC1123_SUPPORTED 1562 if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0) 1563 tIME_string[(sizeof tIME_string) - 1] = '\0'; 1564 1565 else 1566 { 1567 strncpy(tIME_string, "*** invalid time ***", sizeof tIME_string); 1568 tIME_string[(sizeof tIME_string)-1] = '\0'; 1569 } 1570 1571 tIME_chunk_present++; 1572 #endif /* TIME_RFC1123 */ 1573 } 1574 } 1575 #endif 1576 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED 1577 { 1578 png_unknown_chunkp unknowns; 1579 int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr, 1580 &unknowns); 1581 1582 if (num_unknowns != 0) 1583 { 1584 png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns, 1585 num_unknowns); 1586 #if PNG_LIBPNG_VER < 10600 1587 /* Copy the locations from the read_info_ptr. The automatically 1588 * generated locations in write_end_info_ptr are wrong prior to 1.6.0 1589 * because they are reset from the write pointer (removed in 1.6.0). 1590 */ 1591 { 1592 int i; 1593 for (i = 0; i < num_unknowns; i++) 1594 png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i, 1595 unknowns[i].location); 1596 } 1597 #endif 1598 } 1599 } 1600 #endif 1601 1602 #ifdef PNG_WRITE_SUPPORTED 1603 #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED 1604 /* Normally one would use Z_DEFAULT_STRATEGY for text compression. 1605 * This is here just to make pngtest replicate the results from libpng 1606 * versions prior to 1.5.4, and to test this new API. 1607 */ 1608 png_set_text_compression_strategy(write_ptr, Z_FILTERED); 1609 #endif 1610 1611 /* When the unknown vpAg/sTER chunks are written by pngtest the only way to 1612 * do it is to write them *before* calling png_write_end. When unknown 1613 * chunks are written by libpng, however, they are written just before IEND. 1614 * There seems to be no way round this, however vpAg/sTER are not expected 1615 * after IDAT. 1616 */ 1617 write_chunks(write_ptr, after_IDAT); 1618 1619 png_write_end(write_ptr, write_end_info_ptr); 1620 #endif 1621 1622 #ifdef PNG_EASY_ACCESS_SUPPORTED 1623 if (verbose != 0) 1624 { 1625 png_uint_32 iwidth, iheight; 1626 iwidth = png_get_image_width(write_ptr, write_info_ptr); 1627 iheight = png_get_image_height(write_ptr, write_info_ptr); 1628 fprintf(STDERR, "\n Image width = %lu, height = %lu\n", 1629 (unsigned long)iwidth, (unsigned long)iheight); 1630 } 1631 #endif 1632 1633 pngtest_debug("Destroying data structs"); 1634 #ifdef SINGLE_ROWBUF_ALLOC 1635 pngtest_debug("destroying row_buf for read_ptr"); 1636 png_free(read_ptr, row_buf); 1637 row_buf = NULL; 1638 #endif /* SINGLE_ROWBUF_ALLOC */ 1639 pngtest_debug("destroying read_ptr, read_info_ptr, end_info_ptr"); 1640 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); 1641 #ifdef PNG_WRITE_SUPPORTED 1642 pngtest_debug("destroying write_end_info_ptr"); 1643 png_destroy_info_struct(write_ptr, &write_end_info_ptr); 1644 pngtest_debug("destroying write_ptr, write_info_ptr"); 1645 png_destroy_write_struct(&write_ptr, &write_info_ptr); 1646 #endif 1647 pngtest_debug("Destruction complete."); 1648 1649 FCLOSE(fpin); 1650 FCLOSE(fpout); 1651 1652 /* Summarize any warnings or errors and in 'strict' mode fail the test. 1653 * Unsupported chunks can result in warnings, in that case ignore the strict 1654 * setting, otherwise fail the test on warnings as well as errors. 1655 */ 1656 if (error_count > 0) 1657 { 1658 /* We don't really expect to get here because of the setjmp handling 1659 * above, but this is safe. 1660 */ 1661 fprintf(STDERR, "\n %s: %d libpng errors found (%d warnings)", 1662 inname, error_count, warning_count); 1663 1664 if (strict != 0) 1665 return (1); 1666 } 1667 1668 # ifdef PNG_WRITE_SUPPORTED 1669 /* If there is no write support nothing was written! */ 1670 else if (unsupported_chunks > 0) 1671 { 1672 fprintf(STDERR, "\n %s: unsupported chunks (%d)%s", 1673 inname, unsupported_chunks, strict ? ": IGNORED --strict!" : ""); 1674 } 1675 # endif 1676 1677 else if (warning_count > 0) 1678 { 1679 fprintf(STDERR, "\n %s: %d libpng warnings found", 1680 inname, warning_count); 1681 1682 if (strict != 0) 1683 return (1); 1684 } 1685 1686 pngtest_debug("Opening files for comparison"); 1687 if ((fpin = fopen(inname, "rb")) == NULL) 1688 { 1689 fprintf(STDERR, "Could not find file %s\n", inname); 1690 return (1); 1691 } 1692 1693 if ((fpout = fopen(outname, "rb")) == NULL) 1694 { 1695 fprintf(STDERR, "Could not find file %s\n", outname); 1696 FCLOSE(fpin); 1697 return (1); 1698 } 1699 1700 #if defined (PNG_WRITE_SUPPORTED) /* else nothing was written */ &&\ 1701 defined (PNG_WRITE_FILTER_SUPPORTED) 1702 if (interlace_preserved != 0) /* else the files will be changed */ 1703 { 1704 for (;;) 1705 { 1706 static int wrote_question = 0; 1707 png_size_t num_in, num_out; 1708 char inbuf[256], outbuf[256]; 1709 1710 num_in = fread(inbuf, 1, sizeof inbuf, fpin); 1711 num_out = fread(outbuf, 1, sizeof outbuf, fpout); 1712 1713 if (num_in != num_out) 1714 { 1715 fprintf(STDERR, "\nFiles %s and %s are of a different size\n", 1716 inname, outname); 1717 1718 if (wrote_question == 0 && unsupported_chunks == 0) 1719 { 1720 fprintf(STDERR, 1721 " Was %s written with the same maximum IDAT chunk size (%d bytes),", 1722 inname, PNG_ZBUF_SIZE); 1723 fprintf(STDERR, 1724 "\n filtering heuristic (libpng default), compression"); 1725 fprintf(STDERR, 1726 " level (zlib default),\n and zlib version (%s)?\n\n", 1727 ZLIB_VERSION); 1728 wrote_question = 1; 1729 } 1730 1731 FCLOSE(fpin); 1732 FCLOSE(fpout); 1733 1734 if (strict != 0 && unsupported_chunks == 0) 1735 return (1); 1736 1737 else 1738 return (0); 1739 } 1740 1741 if (num_in == 0) 1742 break; 1743 1744 if (memcmp(inbuf, outbuf, num_in)) 1745 { 1746 fprintf(STDERR, "\nFiles %s and %s are different\n", inname, 1747 outname); 1748 1749 if (wrote_question == 0 && unsupported_chunks == 0) 1750 { 1751 fprintf(STDERR, 1752 " Was %s written with the same maximum IDAT chunk size (%d bytes),", 1753 inname, PNG_ZBUF_SIZE); 1754 fprintf(STDERR, 1755 "\n filtering heuristic (libpng default), compression"); 1756 fprintf(STDERR, 1757 " level (zlib default),\n and zlib version (%s)?\n\n", 1758 ZLIB_VERSION); 1759 wrote_question = 1; 1760 } 1761 1762 FCLOSE(fpin); 1763 FCLOSE(fpout); 1764 1765 /* NOTE: the unsupported_chunks escape is permitted here because 1766 * unsupported text chunk compression will result in the compression 1767 * mode being changed (to NONE) yet, in the test case, the result 1768 * can be exactly the same size! 1769 */ 1770 if (strict != 0 && unsupported_chunks == 0) 1771 return (1); 1772 1773 else 1774 return (0); 1775 } 1776 } 1777 } 1778 #endif /* WRITE && WRITE_FILTER */ 1779 1780 FCLOSE(fpin); 1781 FCLOSE(fpout); 1782 1783 return (0); 1784 } 1785 1786 /* Input and output filenames */ 1787 #ifdef RISCOS 1788 static PNG_CONST char *inname = "pngtest/png"; 1789 static PNG_CONST char *outname = "pngout/png"; 1790 #else 1791 static PNG_CONST char *inname = "pngtest.png"; 1792 static PNG_CONST char *outname = "pngout.png"; 1793 #endif 1794 1795 int 1796 main(int argc, char *argv[]) 1797 { 1798 int multiple = 0; 1799 int ierror = 0; 1800 1801 png_structp dummy_ptr; 1802 1803 fprintf(STDERR, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING); 1804 fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION); 1805 fprintf(STDERR, "%s", png_get_copyright(NULL)); 1806 /* Show the version of libpng used in building the library */ 1807 fprintf(STDERR, " library (%lu):%s", 1808 (unsigned long)png_access_version_number(), 1809 png_get_header_version(NULL)); 1810 1811 /* Show the version of libpng used in building the application */ 1812 fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER, 1813 PNG_HEADER_VERSION_STRING); 1814 1815 /* Do some consistency checking on the memory allocation settings, I'm 1816 * not sure this matters, but it is nice to know, the first of these 1817 * tests should be impossible because of the way the macros are set 1818 * in pngconf.h 1819 */ 1820 #if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) 1821 fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n"); 1822 #endif 1823 /* I think the following can happen. */ 1824 #if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K) 1825 fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n"); 1826 #endif 1827 1828 if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING)) 1829 { 1830 fprintf(STDERR, 1831 "Warning: versions are different between png.h and png.c\n"); 1832 fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING); 1833 fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver); 1834 ++ierror; 1835 } 1836 1837 if (argc > 1) 1838 { 1839 if (strcmp(argv[1], "-m") == 0) 1840 { 1841 multiple = 1; 1842 status_dots_requested = 0; 1843 } 1844 1845 else if (strcmp(argv[1], "-mv") == 0 || 1846 strcmp(argv[1], "-vm") == 0 ) 1847 { 1848 multiple = 1; 1849 verbose = 1; 1850 status_dots_requested = 1; 1851 } 1852 1853 else if (strcmp(argv[1], "-v") == 0) 1854 { 1855 verbose = 1; 1856 status_dots_requested = 1; 1857 inname = argv[2]; 1858 } 1859 1860 else if (strcmp(argv[1], "--strict") == 0) 1861 { 1862 status_dots_requested = 0; 1863 verbose = 1; 1864 inname = argv[2]; 1865 strict++; 1866 relaxed = 0; 1867 } 1868 1869 else if (strcmp(argv[1], "--relaxed") == 0) 1870 { 1871 status_dots_requested = 0; 1872 verbose = 1; 1873 inname = argv[2]; 1874 strict = 0; 1875 relaxed++; 1876 } 1877 1878 else 1879 { 1880 inname = argv[1]; 1881 status_dots_requested = 0; 1882 } 1883 } 1884 1885 if (multiple == 0 && argc == 3 + verbose) 1886 outname = argv[2 + verbose]; 1887 1888 if ((multiple == 0 && argc > 3 + verbose) || 1889 (multiple != 0 && argc < 2)) 1890 { 1891 fprintf(STDERR, 1892 "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n", 1893 argv[0], argv[0]); 1894 fprintf(STDERR, 1895 " reads/writes one PNG file (without -m) or multiple files (-m)\n"); 1896 fprintf(STDERR, 1897 " with -m %s is used as a temporary file\n", outname); 1898 exit(1); 1899 } 1900 1901 if (multiple != 0) 1902 { 1903 int i; 1904 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG 1905 int allocation_now = current_allocation; 1906 #endif 1907 for (i=2; i<argc; ++i) 1908 { 1909 int kerror; 1910 fprintf(STDERR, "\n Testing %s:", argv[i]); 1911 #if PNG_DEBUG > 0 1912 fprintf(STDERR, "\n"); 1913 #endif 1914 kerror = test_one_file(argv[i], outname); 1915 if (kerror == 0) 1916 { 1917 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED 1918 fprintf(STDERR, "\n PASS (%lu zero samples)\n", 1919 (unsigned long)zero_samples); 1920 #else 1921 fprintf(STDERR, " PASS\n"); 1922 #endif 1923 #ifdef PNG_TIME_RFC1123_SUPPORTED 1924 if (tIME_chunk_present != 0) 1925 fprintf(STDERR, " tIME = %s\n", tIME_string); 1926 1927 tIME_chunk_present = 0; 1928 #endif /* TIME_RFC1123 */ 1929 } 1930 1931 else 1932 { 1933 fprintf(STDERR, " FAIL\n"); 1934 ierror += kerror; 1935 } 1936 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG 1937 if (allocation_now != current_allocation) 1938 fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", 1939 current_allocation - allocation_now); 1940 1941 if (current_allocation != 0) 1942 { 1943 memory_infop pinfo = pinformation; 1944 1945 fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n", 1946 current_allocation); 1947 1948 while (pinfo != NULL) 1949 { 1950 fprintf(STDERR, " %lu bytes at %p\n", 1951 (unsigned long)pinfo->size, 1952 pinfo->pointer); 1953 pinfo = pinfo->next; 1954 } 1955 } 1956 #endif 1957 } 1958 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG 1959 fprintf(STDERR, " Current memory allocation: %10d bytes\n", 1960 current_allocation); 1961 fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", 1962 maximum_allocation); 1963 fprintf(STDERR, " Total memory allocation: %10d bytes\n", 1964 total_allocation); 1965 fprintf(STDERR, " Number of allocations: %10d\n", 1966 num_allocations); 1967 #endif 1968 } 1969 1970 else 1971 { 1972 int i; 1973 for (i = 0; i<3; ++i) 1974 { 1975 int kerror; 1976 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG 1977 int allocation_now = current_allocation; 1978 #endif 1979 if (i == 1) 1980 status_dots_requested = 1; 1981 1982 else if (verbose == 0) 1983 status_dots_requested = 0; 1984 1985 if (i == 0 || verbose == 1 || ierror != 0) 1986 { 1987 fprintf(STDERR, "\n Testing %s:", inname); 1988 #if PNG_DEBUG > 0 1989 fprintf(STDERR, "\n"); 1990 #endif 1991 } 1992 1993 kerror = test_one_file(inname, outname); 1994 1995 if (kerror == 0) 1996 { 1997 if (verbose == 1 || i == 2) 1998 { 1999 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED 2000 fprintf(STDERR, "\n PASS (%lu zero samples)\n", 2001 (unsigned long)zero_samples); 2002 #else 2003 fprintf(STDERR, " PASS\n"); 2004 #endif 2005 #ifdef PNG_TIME_RFC1123_SUPPORTED 2006 if (tIME_chunk_present != 0) 2007 fprintf(STDERR, " tIME = %s\n", tIME_string); 2008 #endif /* TIME_RFC1123 */ 2009 } 2010 } 2011 2012 else 2013 { 2014 if (verbose == 0 && i != 2) 2015 { 2016 fprintf(STDERR, "\n Testing %s:", inname); 2017 #if PNG_DEBUG > 0 2018 fprintf(STDERR, "\n"); 2019 #endif 2020 } 2021 2022 fprintf(STDERR, " FAIL\n"); 2023 ierror += kerror; 2024 } 2025 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG 2026 if (allocation_now != current_allocation) 2027 fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", 2028 current_allocation - allocation_now); 2029 2030 if (current_allocation != 0) 2031 { 2032 memory_infop pinfo = pinformation; 2033 2034 fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n", 2035 current_allocation); 2036 2037 while (pinfo != NULL) 2038 { 2039 fprintf(STDERR, " %lu bytes at %p\n", 2040 (unsigned long)pinfo->size, pinfo->pointer); 2041 pinfo = pinfo->next; 2042 } 2043 } 2044 #endif 2045 } 2046 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG 2047 fprintf(STDERR, " Current memory allocation: %10d bytes\n", 2048 current_allocation); 2049 fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", 2050 maximum_allocation); 2051 fprintf(STDERR, " Total memory allocation: %10d bytes\n", 2052 total_allocation); 2053 fprintf(STDERR, " Number of allocations: %10d\n", 2054 num_allocations); 2055 #endif 2056 } 2057 2058 #ifdef PNGTEST_TIMING 2059 t_stop = (float)clock(); 2060 t_misc += (t_stop - t_start); 2061 t_start = t_stop; 2062 fprintf(STDERR, " CPU time used = %.3f seconds", 2063 (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC); 2064 fprintf(STDERR, " (decoding %.3f,\n", 2065 t_decode/(float)CLOCKS_PER_SEC); 2066 fprintf(STDERR, " encoding %.3f ,", 2067 t_encode/(float)CLOCKS_PER_SEC); 2068 fprintf(STDERR, " other %.3f seconds)\n\n", 2069 t_misc/(float)CLOCKS_PER_SEC); 2070 #endif 2071 2072 if (ierror == 0) 2073 fprintf(STDERR, " libpng passes test\n"); 2074 2075 else 2076 fprintf(STDERR, " libpng FAILS test\n"); 2077 2078 dummy_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 2079 fprintf(STDERR, " Default limits:\n"); 2080 fprintf(STDERR, " width_max = %lu\n", 2081 (unsigned long) png_get_user_width_max(dummy_ptr)); 2082 fprintf(STDERR, " height_max = %lu\n", 2083 (unsigned long) png_get_user_height_max(dummy_ptr)); 2084 if (png_get_chunk_cache_max(dummy_ptr) == 0) 2085 fprintf(STDERR, " cache_max = unlimited\n"); 2086 else 2087 fprintf(STDERR, " cache_max = %lu\n", 2088 (unsigned long) png_get_chunk_cache_max(dummy_ptr)); 2089 if (png_get_chunk_malloc_max(dummy_ptr) == 0) 2090 fprintf(STDERR, " malloc_max = unlimited\n"); 2091 else 2092 fprintf(STDERR, " malloc_max = %lu\n", 2093 (unsigned long) png_get_chunk_malloc_max(dummy_ptr)); 2094 png_destroy_read_struct(&dummy_ptr, NULL, NULL); 2095 2096 return (int)(ierror != 0); 2097 } 2098 #else 2099 int 2100 main(void) 2101 { 2102 fprintf(STDERR, 2103 " test ignored because libpng was not built with read support\n"); 2104 /* And skip this test */ 2105 return SKIP; 2106 } 2107 #endif 2108 2109 /* Generate a compiler error if there is an old png.h in the search path. */ 2110 typedef png_libpng_version_1_6_23 Your_png_h_is_not_version_1_6_23;