2 /* pngtest.c - a simple test program to test libpng
4 * Last changed in libpng 1.2.6 - August 15, 2004
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2004 Glenn Randers-Pehrson
7 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
10 * This program reads in a PNG image, writes it out again, and then
11 * compares the two files. If the files are identical, this shows that
12 * the basic chunk handling, filtering, and (de)compression code is working
13 * properly. It does not currently test all of the transforms, although
16 * The program will report "FAIL" in certain legitimate cases:
17 * 1) when the compression level or filter selection method is changed.
18 * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192.
19 * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks
20 * exist in the input file.
21 * 4) others not listed here...
22 * In these cases, it is best to check with another tool such as "pngcheck"
23 * to see what the differences between the two files are.
25 * If a filename is given on the command-line, then this file is used
26 * for the input, rather than the default "pngtest.png". This allows
27 * testing a wide variety of files easily. You can also test a number
28 * of files at once by typing "pngtest -m file1.png file2.png ..."
33 #if defined(_WIN32_WCE)
35 __error__ (f
|w
)printf functions are
not supported on old WindowsCE
.;
39 # define READFILE(file, data, length, check) \
40 if (ReadFile(file, data, length, &check,NULL)) check = 0
41 # define WRITEFILE(file, data, length, check)) \
42 if (WriteFile(file, data, length, &check, NULL)) check = 0
43 # define FCLOSE(file) CloseHandle(file)
47 # define READFILE(file, data, length, check) \
48 check=(png_size_t)fread(data,(png_size_t)1,length,file)
49 # define WRITEFILE(file, data, length, check) \
50 check=(png_size_t)fwrite(data,(png_size_t)1, length, file)
51 # define FCLOSE(file) fclose(file)
54 #if defined(PNG_NO_STDIO)
55 # if defined(_WIN32_WCE)
56 typedef HANDLE png_FILE_p
;
58 typedef FILE * png_FILE_p
;
62 /* Makes pngtest verbose so we can find problems (needs to be before png.h) */
68 # define SINGLE_ROWBUF_ALLOC /* makes buffer overruns easier to nail */
72 #define PNGTEST_TIMING
75 #ifdef PNG_NO_FLOATING_POINT_SUPPORTED
80 static float t_start
, t_stop
, t_decode
, t_encode
, t_misc
;
84 #if defined(PNG_TIME_RFC1123_SUPPORTED)
85 static int tIME_chunk_present
=0;
86 static char tIME_string
[30] = "no tIME chunk present in file";
89 static int verbose
= 0;
91 int test_one_file
PNGARG((PNG_CONST
char *inname
, PNG_CONST
char *outname
));
97 /* defined so I can write to a file on gui/windowing platforms */
98 /* #define STDERR stderr */
99 #define STDERR stdout /* for DOS */
101 /* example of using row callbacks to make a simple progress meter */
102 static int status_pass
=1;
103 static int status_dots_requested
=0;
104 static int status_dots
=1;
106 /* In case a system header (e.g., on AIX) defined jmpbuf */
111 /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
113 # define png_jmpbuf(png_ptr) png_ptr->jmpbuf
120 read_row_callback(png_structp png_ptr
, png_uint_32 row_number
, int pass
);
125 read_row_callback(png_structp png_ptr
, png_uint_32 row_number
, int pass
)
127 if(png_ptr
== NULL
|| row_number
> PNG_UINT_31_MAX
) return;
128 if(status_pass
!= pass
)
130 fprintf(stdout
,"\n Pass %d: ",pass
);
137 fprintf(stdout
, "\n ");
140 fprintf(stdout
, "r");
147 write_row_callback(png_structp png_ptr
, png_uint_32 row_number
, int pass
);
152 write_row_callback(png_structp png_ptr
, png_uint_32 row_number
, int pass
)
154 if(png_ptr
== NULL
|| row_number
> PNG_UINT_31_MAX
|| pass
> 7) return;
155 fprintf(stdout
, "w");
159 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
160 /* Example of using user transform callback (we don't transform anything,
161 but merely examine the row filters. We set this to 256 rather than
162 5 in case illegal filter values are present.) */
163 static png_uint_32 filters_used
[256];
168 count_filters(png_structp png_ptr
, png_row_infop row_info
, png_bytep data
);
173 count_filters(png_structp png_ptr
, png_row_infop row_info
, png_bytep data
)
175 if(png_ptr
!= NULL
&& row_info
!= NULL
)
176 ++filters_used
[*(data
-1)];
180 #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
181 /* example of using user transform callback (we don't transform anything,
182 but merely count the zero samples) */
184 static png_uint_32 zero_samples
;
190 count_zero_samples(png_structp png_ptr
, png_row_infop row_info
, png_bytep data
);
195 count_zero_samples(png_structp png_ptr
, png_row_infop row_info
, png_bytep data
)
198 if(png_ptr
== NULL
)return;
200 /* contents of row_info:
201 * png_uint_32 width width of row
202 * png_uint_32 rowbytes number of bytes in row
203 * png_byte color_type color type of pixels
204 * png_byte bit_depth bit depth of samples
205 * png_byte channels number of channels (1-4)
206 * png_byte pixel_depth bits per pixel (depth*channels)
210 /* counts the number of zero samples (or zero pixels if color_type is 3 */
212 if(row_info
->color_type
== 0 || row_info
->color_type
== 3)
215 png_uint_32 n
, nstop
;
216 for (n
=0, nstop
=row_info
->width
; n
<nstop
; n
++)
218 if(row_info
->bit_depth
== 1)
220 if(((*dp
<< pos
++ ) & 0x80) == 0) zero_samples
++;
227 if(row_info
->bit_depth
== 2)
229 if(((*dp
<< (pos
+=2)) & 0xc0) == 0) zero_samples
++;
236 if(row_info
->bit_depth
== 4)
238 if(((*dp
<< (pos
+=4)) & 0xf0) == 0) zero_samples
++;
245 if(row_info
->bit_depth
== 8)
246 if(*dp
++ == 0) zero_samples
++;
247 if(row_info
->bit_depth
== 16)
249 if((*dp
| *(dp
+1)) == 0) zero_samples
++;
254 else /* other color types */
256 png_uint_32 n
, nstop
;
258 int color_channels
= row_info
->channels
;
259 if(row_info
->color_type
> 3)color_channels
--;
261 for (n
=0, nstop
=row_info
->width
; n
<nstop
; n
++)
263 for (channel
= 0; channel
< color_channels
; channel
++)
265 if(row_info
->bit_depth
== 8)
266 if(*dp
++ == 0) zero_samples
++;
267 if(row_info
->bit_depth
== 16)
269 if((*dp
| *(dp
+1)) == 0) zero_samples
++;
273 if(row_info
->color_type
> 3)
276 if(row_info
->bit_depth
== 16)dp
++;
281 #endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
283 static int wrote_question
= 0;
285 #if defined(PNG_NO_STDIO)
286 /* START of code to validate stdio-free compilation */
287 /* These copies of the default read/write functions come from pngrio.c and */
288 /* pngwio.c. They allow "don't include stdio" testing of the library. */
289 /* This is the function that does the actual reading of data. If you are
290 not reading from a standard C stream, you should create a replacement
291 read_data function and use it at run time with png_set_read_fn(), rather
292 than changing the library. */
294 #ifndef USE_FAR_KEYWORD
296 pngtest_read_data(png_structp png_ptr
, png_bytep data
, png_size_t length
)
300 /* fread() returns 0 on error, so it is OK to store this in a png_size_t
301 * instead of an int, which is what fread() actually returns.
303 READFILE((png_FILE_p
)png_ptr
->io_ptr
, data
, length
, check
);
307 png_error(png_ptr
, "Read Error!");
311 /* this is the model-independent version. Since the standard I/O library
312 can't handle far buffers in the medium and small models, we have to copy
316 #define NEAR_BUF_SIZE 1024
317 #define MIN(a,b) (a <= b ? a : b)
320 pngtest_read_data(png_structp png_ptr
, png_bytep data
, png_size_t length
)
326 /* Check if data really is near. If so, use usual code. */
327 n_data
= (png_byte
*)CVT_PTR_NOCHECK(data
);
328 io_ptr
= (png_FILE_p
)CVT_PTR(png_ptr
->io_ptr
);
329 if ((png_bytep
)n_data
== data
)
331 READFILE(io_ptr
, n_data
, length
, check
);
335 png_byte buf
[NEAR_BUF_SIZE
];
336 png_size_t read
, remaining
, err
;
341 read
= MIN(NEAR_BUF_SIZE
, remaining
);
342 READFILE(io_ptr
, buf
, 1, err
);
343 png_memcpy(data
, buf
, read
); /* copy far buffer to near buffer */
351 while (remaining
!= 0);
355 png_error(png_ptr
, "read Error");
358 #endif /* USE_FAR_KEYWORD */
360 #if defined(PNG_WRITE_FLUSH_SUPPORTED)
362 pngtest_flush(png_structp png_ptr
)
364 #if !defined(_WIN32_WCE)
366 io_ptr
= (png_FILE_p
)CVT_PTR((png_ptr
->io_ptr
));
373 /* This is the function that does the actual writing of data. If you are
374 not writing to a standard C stream, you should create a replacement
375 write_data function and use it at run time with png_set_write_fn(), rather
376 than changing the library. */
377 #ifndef USE_FAR_KEYWORD
379 pngtest_write_data(png_structp png_ptr
, png_bytep data
, png_size_t length
)
383 WRITEFILE((png_FILE_p
)png_ptr
->io_ptr
, data
, length
, check
);
386 png_error(png_ptr
, "Write Error");
390 /* this is the model-independent version. Since the standard I/O library
391 can't handle far buffers in the medium and small models, we have to copy
395 #define NEAR_BUF_SIZE 1024
396 #define MIN(a,b) (a <= b ? a : b)
399 pngtest_write_data(png_structp png_ptr
, png_bytep data
, png_size_t length
)
402 png_byte
*near_data
; /* Needs to be "png_byte *" instead of "png_bytep" */
405 /* Check if data really is near. If so, use usual code. */
406 near_data
= (png_byte
*)CVT_PTR_NOCHECK(data
);
407 io_ptr
= (png_FILE_p
)CVT_PTR(png_ptr
->io_ptr
);
408 if ((png_bytep
)near_data
== data
)
410 WRITEFILE(io_ptr
, near_data
, length
, check
);
414 png_byte buf
[NEAR_BUF_SIZE
];
415 png_size_t written
, remaining
, err
;
420 written
= MIN(NEAR_BUF_SIZE
, remaining
);
421 png_memcpy(buf
, data
, written
); /* copy far buffer to near buffer */
422 WRITEFILE(io_ptr
, buf
, written
, err
);
428 remaining
-= written
;
430 while (remaining
!= 0);
434 png_error(png_ptr
, "Write Error");
437 #endif /* USE_FAR_KEYWORD */
438 #endif /* PNG_NO_STDIO */
439 /* END of code to validate stdio-free compilation */
441 /* This function is called when there is a warning, but the library thinks
442 * it can continue anyway. Replacement functions don't have to do anything
443 * here if you don't want to. In the default configuration, png_ptr is
444 * not used, but it is passed in case it may be useful.
447 pngtest_warning(png_structp png_ptr
, png_const_charp message
)
449 PNG_CONST
char *name
= "UNKNOWN (ERROR!)";
450 if (png_ptr
!= NULL
&& png_ptr
->error_ptr
!= NULL
)
451 name
= png_ptr
->error_ptr
;
452 fprintf(STDERR
, "%s: libpng warning: %s\n", name
, message
);
455 /* This is the default error handling function. Note that replacements for
456 * this function MUST NOT RETURN, or the program will likely crash. This
457 * function is used by default, or if the program supplies NULL for the
458 * error function pointer in png_set_error_fn().
461 pngtest_error(png_structp png_ptr
, png_const_charp message
)
463 pngtest_warning(png_ptr
, message
);
464 /* We can return because png_error calls the default handler, which is
465 * actually OK in this case. */
468 /* START of code to validate memory allocation and deallocation */
469 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
471 /* Allocate memory. For reasonable files, size should never exceed
472 64K. However, zlib may allocate more then 64K if you don't tell
473 it not to. See zconf.h and png.h for more information. zlib does
474 need to allocate exactly 64K, so whatever you call here must
475 have the ability to do that.
477 This piece of code can be compiled to validate max 64K allocations
478 by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. */
479 typedef struct memory_information
483 struct memory_information FAR
*next
;
484 } memory_information
;
485 typedef memory_information FAR
*memory_infop
;
487 static memory_infop pinformation
= NULL
;
488 static int current_allocation
= 0;
489 static int maximum_allocation
= 0;
490 static int total_allocation
= 0;
491 static int num_allocations
= 0;
493 png_voidp png_debug_malloc
PNGARG((png_structp png_ptr
, png_uint_32 size
));
494 void png_debug_free
PNGARG((png_structp png_ptr
, png_voidp ptr
));
497 png_debug_malloc(png_structp png_ptr
, png_uint_32 size
)
500 /* png_malloc has already tested for NULL; png_create_struct calls
501 png_debug_malloc directly, with png_ptr == NULL which is OK */
506 /* This calls the library allocator twice, once to get the requested
507 buffer and once to get a new free list entry. */
509 /* Disable malloc_fn and free_fn */
511 png_set_mem_fn(png_ptr
, NULL
, NULL
, NULL
);
512 pinfo
= (memory_infop
)png_malloc(png_ptr
,
513 (png_uint_32
)png_sizeof (*pinfo
));
515 current_allocation
+= size
;
516 total_allocation
+= size
;
518 if (current_allocation
> maximum_allocation
)
519 maximum_allocation
= current_allocation
;
520 pinfo
->pointer
= (png_voidp
)png_malloc(png_ptr
, size
);
521 /* Restore malloc_fn and free_fn */
522 png_set_mem_fn(png_ptr
, png_voidp_NULL
, (png_malloc_ptr
)png_debug_malloc
,
523 (png_free_ptr
)png_debug_free
);
524 if (size
!= 0 && pinfo
->pointer
== NULL
)
526 current_allocation
-= size
;
527 total_allocation
-= size
;
529 "out of memory in pngtest->png_debug_malloc.");
531 pinfo
->next
= pinformation
;
532 pinformation
= pinfo
;
533 /* Make sure the caller isn't assuming zeroed memory. */
534 png_memset(pinfo
->pointer
, 0xdd, pinfo
->size
);
536 printf("png_malloc %lu bytes at %x\n",(unsigned long)size
,
538 return (png_voidp
)(pinfo
->pointer
);
542 /* Free a pointer. It is removed from the list at the same time. */
544 png_debug_free(png_structp png_ptr
, png_voidp ptr
)
547 fprintf(STDERR
, "NULL pointer to png_debug_free.\n");
550 #if 0 /* This happens all the time. */
551 fprintf(STDERR
, "WARNING: freeing NULL pointer\n");
556 /* Unlink the element from the list. */
558 memory_infop FAR
*ppinfo
= &pinformation
;
561 memory_infop pinfo
= *ppinfo
;
562 if (pinfo
->pointer
== ptr
)
564 *ppinfo
= pinfo
->next
;
565 current_allocation
-= pinfo
->size
;
566 if (current_allocation
< 0)
567 fprintf(STDERR
, "Duplicate free of memory\n");
568 /* We must free the list element too, but first kill
569 the memory that is to be freed. */
570 png_memset(ptr
, 0x55, pinfo
->size
);
571 png_free_default(png_ptr
, pinfo
);
575 if (pinfo
->next
== NULL
)
577 fprintf(STDERR
, "Pointer %x not found\n", (unsigned int)ptr
);
580 ppinfo
= &pinfo
->next
;
584 /* Finally free the data. */
586 printf("Freeing %x\n",ptr
);
587 png_free_default(png_ptr
, ptr
);
590 #endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */
591 /* END of code to test memory allocation/deallocation */
595 test_one_file(PNG_CONST
char *inname
, PNG_CONST
char *outname
)
597 static png_FILE_p fpin
;
598 static png_FILE_p fpout
; /* "static" prevents setjmp corruption */
599 png_structp read_ptr
;
600 png_infop read_info_ptr
, end_info_ptr
;
601 #ifdef PNG_WRITE_SUPPORTED
602 png_structp write_ptr
;
603 png_infop write_info_ptr
;
604 png_infop write_end_info_ptr
;
606 png_structp write_ptr
= NULL
;
607 png_infop write_info_ptr
= NULL
;
608 png_infop write_end_info_ptr
= NULL
;
612 png_uint_32 width
, height
;
614 int bit_depth
, color_type
;
615 #ifdef PNG_SETJMP_SUPPORTED
616 #ifdef USE_FAR_KEYWORD
621 #if defined(_WIN32_WCE)
622 TCHAR path
[MAX_PATH
];
624 char inbuf
[256], outbuf
[256];
628 #if defined(_WIN32_WCE)
629 MultiByteToWideChar(CP_ACP
, 0, inname
, -1, path
, MAX_PATH
);
630 if ((fpin
= CreateFile(path
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, NULL
)) == INVALID_HANDLE_VALUE
)
632 if ((fpin
= fopen(inname
, "rb")) == NULL
)
635 fprintf(STDERR
, "Could not find input file %s\n", inname
);
639 #if defined(_WIN32_WCE)
640 MultiByteToWideChar(CP_ACP
, 0, outname
, -1, path
, MAX_PATH
);
641 if ((fpout
= CreateFile(path
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
)) == INVALID_HANDLE_VALUE
)
643 if ((fpout
= fopen(outname
, "wb")) == NULL
)
646 fprintf(STDERR
, "Could not open output file %s\n", outname
);
651 png_debug(0, "Allocating read and write structures\n");
652 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
653 read_ptr
= png_create_read_struct_2(PNG_LIBPNG_VER_STRING
, png_voidp_NULL
,
654 png_error_ptr_NULL
, png_error_ptr_NULL
, png_voidp_NULL
,
655 (png_malloc_ptr
)png_debug_malloc
, (png_free_ptr
)png_debug_free
);
657 read_ptr
= png_create_read_struct(PNG_LIBPNG_VER_STRING
, png_voidp_NULL
,
658 png_error_ptr_NULL
, png_error_ptr_NULL
);
660 png_set_error_fn(read_ptr
, (png_voidp
)inname
, pngtest_error
,
662 #ifdef PNG_WRITE_SUPPORTED
663 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
664 write_ptr
= png_create_write_struct_2(PNG_LIBPNG_VER_STRING
, png_voidp_NULL
,
665 png_error_ptr_NULL
, png_error_ptr_NULL
, png_voidp_NULL
,
666 (png_malloc_ptr
)png_debug_malloc
, (png_free_ptr
)png_debug_free
);
668 write_ptr
= png_create_write_struct(PNG_LIBPNG_VER_STRING
, png_voidp_NULL
,
669 png_error_ptr_NULL
, png_error_ptr_NULL
);
671 png_set_error_fn(write_ptr
, (png_voidp
)inname
, pngtest_error
,
674 png_debug(0, "Allocating read_info, write_info and end_info structures\n");
675 read_info_ptr
= png_create_info_struct(read_ptr
);
676 end_info_ptr
= png_create_info_struct(read_ptr
);
677 #ifdef PNG_WRITE_SUPPORTED
678 write_info_ptr
= png_create_info_struct(write_ptr
);
679 write_end_info_ptr
= png_create_info_struct(write_ptr
);
682 #ifdef PNG_SETJMP_SUPPORTED
683 png_debug(0, "Setting jmpbuf for read struct\n");
684 #ifdef USE_FAR_KEYWORD
687 if (setjmp(png_jmpbuf(read_ptr
)))
690 fprintf(STDERR
, "%s -> %s: libpng read error\n", inname
, outname
);
692 png_free(read_ptr
, row_buf
);
693 png_destroy_read_struct(&read_ptr
, &read_info_ptr
, &end_info_ptr
);
694 #ifdef PNG_WRITE_SUPPORTED
695 png_destroy_info_struct(write_ptr
, &write_end_info_ptr
);
696 png_destroy_write_struct(&write_ptr
, &write_info_ptr
);
702 #ifdef USE_FAR_KEYWORD
703 png_memcpy(png_jmpbuf(read_ptr
),jmpbuf
,png_sizeof(jmp_buf));
706 #ifdef PNG_WRITE_SUPPORTED
707 png_debug(0, "Setting jmpbuf for write struct\n");
708 #ifdef USE_FAR_KEYWORD
711 if (setjmp(png_jmpbuf(write_ptr
)))
714 fprintf(STDERR
, "%s -> %s: libpng write error\n", inname
, outname
);
715 png_destroy_read_struct(&read_ptr
, &read_info_ptr
, &end_info_ptr
);
716 png_destroy_info_struct(write_ptr
, &write_end_info_ptr
);
717 #ifdef PNG_WRITE_SUPPORTED
718 png_destroy_write_struct(&write_ptr
, &write_info_ptr
);
724 #ifdef USE_FAR_KEYWORD
725 png_memcpy(png_jmpbuf(write_ptr
),jmpbuf
,png_sizeof(jmp_buf));
730 png_debug(0, "Initializing input and output streams\n");
731 #if !defined(PNG_NO_STDIO)
732 png_init_io(read_ptr
, fpin
);
733 # ifdef PNG_WRITE_SUPPORTED
734 png_init_io(write_ptr
, fpout
);
737 png_set_read_fn(read_ptr
, (png_voidp
)fpin
, pngtest_read_data
);
738 # ifdef PNG_WRITE_SUPPORTED
739 png_set_write_fn(write_ptr
, (png_voidp
)fpout
, pngtest_write_data
,
740 # if defined(PNG_WRITE_FLUSH_SUPPORTED)
747 if(status_dots_requested
== 1)
749 #ifdef PNG_WRITE_SUPPORTED
750 png_set_write_status_fn(write_ptr
, write_row_callback
);
752 png_set_read_status_fn(read_ptr
, read_row_callback
);
756 #ifdef PNG_WRITE_SUPPORTED
757 png_set_write_status_fn(write_ptr
, png_write_status_ptr_NULL
);
759 png_set_read_status_fn(read_ptr
, png_read_status_ptr_NULL
);
762 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
767 png_set_read_user_transform_fn(read_ptr
, count_filters
);
770 #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
772 png_set_write_user_transform_fn(write_ptr
, count_zero_samples
);
775 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
776 # ifndef PNG_HANDLE_CHUNK_ALWAYS
777 # define PNG_HANDLE_CHUNK_ALWAYS 3
779 png_set_keep_unknown_chunks(read_ptr
, PNG_HANDLE_CHUNK_ALWAYS
,
782 #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
783 # ifndef PNG_HANDLE_CHUNK_IF_SAFE
784 # define PNG_HANDLE_CHUNK_IF_SAFE 2
786 png_set_keep_unknown_chunks(write_ptr
, PNG_HANDLE_CHUNK_IF_SAFE
,
790 png_debug(0, "Reading info struct\n");
791 png_read_info(read_ptr
, read_info_ptr
);
793 png_debug(0, "Transferring info struct\n");
795 int interlace_type
, compression_type
, filter_type
;
797 if (png_get_IHDR(read_ptr
, read_info_ptr
, &width
, &height
, &bit_depth
,
798 &color_type
, &interlace_type
, &compression_type
, &filter_type
))
800 png_set_IHDR(write_ptr
, write_info_ptr
, width
, height
, bit_depth
,
801 #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
802 color_type
, interlace_type
, compression_type
, filter_type
);
804 color_type
, PNG_INTERLACE_NONE
, compression_type
, filter_type
);
808 #if defined(PNG_FIXED_POINT_SUPPORTED)
809 #if defined(PNG_cHRM_SUPPORTED)
811 png_fixed_point white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
,
813 if (png_get_cHRM_fixed(read_ptr
, read_info_ptr
, &white_x
, &white_y
, &red_x
,
814 &red_y
, &green_x
, &green_y
, &blue_x
, &blue_y
))
816 png_set_cHRM_fixed(write_ptr
, write_info_ptr
, white_x
, white_y
, red_x
,
817 red_y
, green_x
, green_y
, blue_x
, blue_y
);
821 #if defined(PNG_gAMA_SUPPORTED)
823 png_fixed_point gamma
;
825 if (png_get_gAMA_fixed(read_ptr
, read_info_ptr
, &gamma
))
827 png_set_gAMA_fixed(write_ptr
, write_info_ptr
, gamma
);
831 #else /* Use floating point versions */
832 #if defined(PNG_FLOATING_POINT_SUPPORTED)
833 #if defined(PNG_cHRM_SUPPORTED)
835 double white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
,
837 if (png_get_cHRM(read_ptr
, read_info_ptr
, &white_x
, &white_y
, &red_x
,
838 &red_y
, &green_x
, &green_y
, &blue_x
, &blue_y
))
840 png_set_cHRM(write_ptr
, write_info_ptr
, white_x
, white_y
, red_x
,
841 red_y
, green_x
, green_y
, blue_x
, blue_y
);
845 #if defined(PNG_gAMA_SUPPORTED)
849 if (png_get_gAMA(read_ptr
, read_info_ptr
, &gamma
))
851 png_set_gAMA(write_ptr
, write_info_ptr
, gamma
);
855 #endif /* floating point */
856 #endif /* fixed point */
857 #if defined(PNG_iCCP_SUPPORTED)
862 int compression_type
;
864 if (png_get_iCCP(read_ptr
, read_info_ptr
, &name
, &compression_type
,
867 png_set_iCCP(write_ptr
, write_info_ptr
, name
, compression_type
,
872 #if defined(PNG_sRGB_SUPPORTED)
876 if (png_get_sRGB(read_ptr
, read_info_ptr
, &intent
))
878 png_set_sRGB(write_ptr
, write_info_ptr
, intent
);
886 if (png_get_PLTE(read_ptr
, read_info_ptr
, &palette
, &num_palette
))
888 png_set_PLTE(write_ptr
, write_info_ptr
, palette
, num_palette
);
891 #if defined(PNG_bKGD_SUPPORTED)
893 png_color_16p background
;
895 if (png_get_bKGD(read_ptr
, read_info_ptr
, &background
))
897 png_set_bKGD(write_ptr
, write_info_ptr
, background
);
901 #if defined(PNG_hIST_SUPPORTED)
905 if (png_get_hIST(read_ptr
, read_info_ptr
, &hist
))
907 png_set_hIST(write_ptr
, write_info_ptr
, hist
);
911 #if defined(PNG_oFFs_SUPPORTED)
913 png_int_32 offset_x
, offset_y
;
916 if (png_get_oFFs(read_ptr
, read_info_ptr
,&offset_x
,&offset_y
,&unit_type
))
918 png_set_oFFs(write_ptr
, write_info_ptr
, offset_x
, offset_y
, unit_type
);
922 #if defined(PNG_pCAL_SUPPORTED)
924 png_charp purpose
, units
;
929 if (png_get_pCAL(read_ptr
, read_info_ptr
, &purpose
, &X0
, &X1
, &type
,
930 &nparams
, &units
, ¶ms
))
932 png_set_pCAL(write_ptr
, write_info_ptr
, purpose
, X0
, X1
, type
,
933 nparams
, units
, params
);
937 #if defined(PNG_pHYs_SUPPORTED)
939 png_uint_32 res_x
, res_y
;
942 if (png_get_pHYs(read_ptr
, read_info_ptr
, &res_x
, &res_y
, &unit_type
))
944 png_set_pHYs(write_ptr
, write_info_ptr
, res_x
, res_y
, unit_type
);
948 #if defined(PNG_sBIT_SUPPORTED)
950 png_color_8p sig_bit
;
952 if (png_get_sBIT(read_ptr
, read_info_ptr
, &sig_bit
))
954 png_set_sBIT(write_ptr
, write_info_ptr
, sig_bit
);
958 #if defined(PNG_sCAL_SUPPORTED)
959 #ifdef PNG_FLOATING_POINT_SUPPORTED
962 double scal_width
, scal_height
;
964 if (png_get_sCAL(read_ptr
, read_info_ptr
, &unit
, &scal_width
,
967 png_set_sCAL(write_ptr
, write_info_ptr
, unit
, scal_width
, scal_height
);
971 #ifdef PNG_FIXED_POINT_SUPPORTED
974 png_charp scal_width
, scal_height
;
976 if (png_get_sCAL_s(read_ptr
, read_info_ptr
, &unit
, &scal_width
,
979 png_set_sCAL_s(write_ptr
, write_info_ptr
, unit
, scal_width
, scal_height
);
985 #if defined(PNG_TEXT_SUPPORTED)
990 if (png_get_text(read_ptr
, read_info_ptr
, &text_ptr
, &num_text
) > 0)
992 png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text
);
993 png_set_text(write_ptr
, write_info_ptr
, text_ptr
, num_text
);
997 #if defined(PNG_tIME_SUPPORTED)
1001 if (png_get_tIME(read_ptr
, read_info_ptr
, &mod_time
))
1003 png_set_tIME(write_ptr
, write_info_ptr
, mod_time
);
1004 #if defined(PNG_TIME_RFC1123_SUPPORTED)
1005 /* we have to use png_strncpy instead of "=" because the string
1006 pointed to by png_convert_to_rfc1123() gets free'ed before
1008 png_strncpy(tIME_string
,png_convert_to_rfc1123(read_ptr
,
1010 tIME_chunk_present
++;
1011 #endif /* PNG_TIME_RFC1123_SUPPORTED */
1015 #if defined(PNG_tRNS_SUPPORTED)
1019 png_color_16p trans_values
;
1021 if (png_get_tRNS(read_ptr
, read_info_ptr
, &trans
, &num_trans
,
1024 png_set_tRNS(write_ptr
, write_info_ptr
, trans
, num_trans
,
1029 #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1031 png_unknown_chunkp unknowns
;
1032 int num_unknowns
= (int)png_get_unknown_chunks(read_ptr
, read_info_ptr
,
1037 png_set_unknown_chunks(write_ptr
, write_info_ptr
, unknowns
,
1039 /* copy the locations from the read_info_ptr. The automatically
1040 generated locations in write_info_ptr are wrong because we
1041 haven't written anything yet */
1042 for (i
= 0; i
< (png_size_t
)num_unknowns
; i
++)
1043 png_set_unknown_chunk_location(write_ptr
, write_info_ptr
, i
,
1044 unknowns
[i
].location
);
1049 #ifdef PNG_WRITE_SUPPORTED
1050 png_debug(0, "\nWriting info struct\n");
1052 /* If we wanted, we could write info in two steps:
1053 png_write_info_before_PLTE(write_ptr, write_info_ptr);
1055 png_write_info(write_ptr
, write_info_ptr
);
1058 #ifdef SINGLE_ROWBUF_ALLOC
1059 png_debug(0, "\nAllocating row buffer...");
1060 row_buf
= (png_bytep
)png_malloc(read_ptr
,
1061 png_get_rowbytes(read_ptr
, read_info_ptr
));
1062 png_debug1(0, "0x%08lx\n\n", (unsigned long)row_buf
);
1063 #endif /* SINGLE_ROWBUF_ALLOC */
1064 png_debug(0, "Writing row data\n");
1066 #if defined(PNG_READ_INTERLACING_SUPPORTED) || \
1067 defined(PNG_WRITE_INTERLACING_SUPPORTED)
1068 num_pass
= png_set_interlace_handling(read_ptr
);
1069 # ifdef PNG_WRITE_SUPPORTED
1070 png_set_interlace_handling(write_ptr
);
1076 #ifdef PNGTEST_TIMING
1077 t_stop
= (float)clock();
1078 t_misc
+= (t_stop
- t_start
);
1081 for (pass
= 0; pass
< num_pass
; pass
++)
1083 png_debug1(0, "Writing row data for pass %d\n",pass
);
1084 for (y
= 0; y
< height
; y
++)
1086 #ifndef SINGLE_ROWBUF_ALLOC
1087 png_debug2(0, "\nAllocating row buffer (pass %d, y = %ld)...", pass
,y
);
1088 row_buf
= (png_bytep
)png_malloc(read_ptr
,
1089 png_get_rowbytes(read_ptr
, read_info_ptr
));
1090 png_debug2(0, "0x%08lx (%ld bytes)\n", (unsigned long)row_buf
,
1091 png_get_rowbytes(read_ptr
, read_info_ptr
));
1092 #endif /* !SINGLE_ROWBUF_ALLOC */
1093 png_read_rows(read_ptr
, (png_bytepp
)&row_buf
, png_bytepp_NULL
, 1);
1095 #ifdef PNG_WRITE_SUPPORTED
1096 #ifdef PNGTEST_TIMING
1097 t_stop
= (float)clock();
1098 t_decode
+= (t_stop
- t_start
);
1101 png_write_rows(write_ptr
, (png_bytepp
)&row_buf
, 1);
1102 #ifdef PNGTEST_TIMING
1103 t_stop
= (float)clock();
1104 t_encode
+= (t_stop
- t_start
);
1107 #endif /* PNG_WRITE_SUPPORTED */
1109 #ifndef SINGLE_ROWBUF_ALLOC
1110 png_debug2(0, "Freeing row buffer (pass %d, y = %ld)\n\n", pass
, y
);
1111 png_free(read_ptr
, row_buf
);
1112 #endif /* !SINGLE_ROWBUF_ALLOC */
1116 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
1117 png_free_data(read_ptr
, read_info_ptr
, PNG_FREE_UNKN
, -1);
1119 #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1120 png_free_data(write_ptr
, write_info_ptr
, PNG_FREE_UNKN
, -1);
1123 png_debug(0, "Reading and writing end_info data\n");
1125 png_read_end(read_ptr
, end_info_ptr
);
1126 #if defined(PNG_TEXT_SUPPORTED)
1131 if (png_get_text(read_ptr
, end_info_ptr
, &text_ptr
, &num_text
) > 0)
1133 png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text
);
1134 png_set_text(write_ptr
, write_end_info_ptr
, text_ptr
, num_text
);
1138 #if defined(PNG_tIME_SUPPORTED)
1142 if (png_get_tIME(read_ptr
, end_info_ptr
, &mod_time
))
1144 png_set_tIME(write_ptr
, write_end_info_ptr
, mod_time
);
1145 #if defined(PNG_TIME_RFC1123_SUPPORTED)
1146 /* we have to use png_strncpy instead of "=" because the string
1147 pointed to by png_convert_to_rfc1123() gets free'ed before
1149 png_strncpy(tIME_string
,png_convert_to_rfc1123(read_ptr
,
1151 tIME_chunk_present
++;
1152 #endif /* PNG_TIME_RFC1123_SUPPORTED */
1156 #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1158 png_unknown_chunkp unknowns
;
1160 num_unknowns
= (int)png_get_unknown_chunks(read_ptr
, end_info_ptr
,
1165 png_set_unknown_chunks(write_ptr
, write_end_info_ptr
, unknowns
,
1167 /* copy the locations from the read_info_ptr. The automatically
1168 generated locations in write_end_info_ptr are wrong because we
1169 haven't written the end_info yet */
1170 for (i
= 0; i
< (png_size_t
)num_unknowns
; i
++)
1171 png_set_unknown_chunk_location(write_ptr
, write_end_info_ptr
, i
,
1172 unknowns
[i
].location
);
1176 #ifdef PNG_WRITE_SUPPORTED
1177 png_write_end(write_ptr
, write_end_info_ptr
);
1180 #ifdef PNG_EASY_ACCESS_SUPPORTED
1183 png_uint_32 iwidth
, iheight
;
1184 iwidth
= png_get_image_width(write_ptr
, write_info_ptr
);
1185 iheight
= png_get_image_height(write_ptr
, write_info_ptr
);
1186 fprintf(STDERR
, "Image width = %lu, height = %lu\n",
1187 (unsigned long)iwidth
, (unsigned long)iheight
);
1191 png_debug(0, "Destroying data structs\n");
1192 #ifdef SINGLE_ROWBUF_ALLOC
1193 png_debug(1, "destroying row_buf for read_ptr\n");
1194 png_free(read_ptr
, row_buf
);
1196 #endif /* SINGLE_ROWBUF_ALLOC */
1197 png_debug(1, "destroying read_ptr, read_info_ptr, end_info_ptr\n");
1198 png_destroy_read_struct(&read_ptr
, &read_info_ptr
, &end_info_ptr
);
1199 #ifdef PNG_WRITE_SUPPORTED
1200 png_debug(1, "destroying write_end_info_ptr\n");
1201 png_destroy_info_struct(write_ptr
, &write_end_info_ptr
);
1202 png_debug(1, "destroying write_ptr, write_info_ptr\n");
1203 png_destroy_write_struct(&write_ptr
, &write_info_ptr
);
1205 png_debug(0, "Destruction complete.\n");
1210 png_debug(0, "Opening files for comparison\n");
1211 #if defined(_WIN32_WCE)
1212 MultiByteToWideChar(CP_ACP
, 0, inname
, -1, path
, MAX_PATH
);
1213 if ((fpin
= CreateFile(path
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, NULL
)) == INVALID_HANDLE_VALUE
)
1215 if ((fpin
= fopen(inname
, "rb")) == NULL
)
1218 fprintf(STDERR
, "Could not find file %s\n", inname
);
1222 #if defined(_WIN32_WCE)
1223 MultiByteToWideChar(CP_ACP
, 0, outname
, -1, path
, MAX_PATH
);
1224 if ((fpout
= CreateFile(path
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, NULL
)) == INVALID_HANDLE_VALUE
)
1226 if ((fpout
= fopen(outname
, "rb")) == NULL
)
1229 fprintf(STDERR
, "Could not find file %s\n", outname
);
1236 png_size_t num_in
, num_out
;
1238 READFILE(fpin
, inbuf
, 1, num_in
);
1239 READFILE(fpout
, outbuf
, 1, num_out
);
1241 if (num_in
!= num_out
)
1243 fprintf(STDERR
, "\nFiles %s and %s are of a different size\n",
1245 if(wrote_question
== 0)
1248 " Was %s written with the same maximum IDAT chunk size (%d bytes),",
1249 inname
,PNG_ZBUF_SIZE
);
1251 "\n filtering heuristic (libpng default), compression");
1253 " level (zlib default),\n and zlib version (%s)?\n\n",
1265 if (png_memcmp(inbuf
, outbuf
, num_in
))
1267 fprintf(STDERR
, "\nFiles %s and %s are different\n", inname
, outname
);
1268 if(wrote_question
== 0)
1271 " Was %s written with the same maximum IDAT chunk size (%d bytes),",
1272 inname
,PNG_ZBUF_SIZE
);
1274 "\n filtering heuristic (libpng default), compression");
1276 " level (zlib default),\n and zlib version (%s)?\n\n",
1292 /* input and output filenames */
1294 static PNG_CONST
char *inname
= "pngtest/png";
1295 static PNG_CONST
char *outname
= "pngout/png";
1297 static PNG_CONST
char *inname
= "pngtest.png";
1298 static PNG_CONST
char *outname
= "pngout.png";
1302 main(int argc
, char *argv
[])
1307 fprintf(STDERR
, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING
);
1308 fprintf(STDERR
, " with zlib version %s\n", ZLIB_VERSION
);
1309 fprintf(STDERR
,"%s",png_get_copyright(NULL
));
1310 /* Show the version of libpng used in building the library */
1311 fprintf(STDERR
," library (%lu):%s",
1312 (unsigned long)png_access_version_number(),
1313 png_get_header_version(NULL
));
1314 /* Show the version of libpng used in building the application */
1315 fprintf(STDERR
," pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER
,
1316 PNG_HEADER_VERSION_STRING
);
1317 fprintf(STDERR
," png_sizeof(png_struct)=%ld, png_sizeof(png_info)=%ld\n",
1318 (long)png_sizeof(png_struct
), (long)png_sizeof(png_info
));
1320 /* Do some consistency checking on the memory allocation settings, I'm
1321 not sure this matters, but it is nice to know, the first of these
1322 tests should be impossible because of the way the macros are set
1324 #if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
1325 fprintf(STDERR
, " NOTE: Zlib compiled for max 64k, libpng not\n");
1327 /* I think the following can happen. */
1328 #if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
1329 fprintf(STDERR
, " NOTE: libpng compiled for max 64k, zlib not\n");
1332 if (strcmp(png_libpng_ver
, PNG_LIBPNG_VER_STRING
))
1335 "Warning: versions are different between png.h and png.c\n");
1336 fprintf(STDERR
, " png.h version: %s\n", PNG_LIBPNG_VER_STRING
);
1337 fprintf(STDERR
, " png.c version: %s\n\n", png_libpng_ver
);
1343 if (strcmp(argv
[1], "-m") == 0)
1346 status_dots_requested
= 0;
1348 else if (strcmp(argv
[1], "-mv") == 0 ||
1349 strcmp(argv
[1], "-vm") == 0 )
1353 status_dots_requested
= 1;
1355 else if (strcmp(argv
[1], "-v") == 0)
1358 status_dots_requested
= 1;
1364 status_dots_requested
= 0;
1368 if (!multiple
&& argc
== 3+verbose
)
1369 outname
= argv
[2+verbose
];
1371 if ((!multiple
&& argc
> 3+verbose
) || (multiple
&& argc
< 2))
1374 "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
1377 " reads/writes one PNG file (without -m) or multiple files (-m)\n");
1379 " with -m %s is used as a temporary file\n", outname
);
1386 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1387 int allocation_now
= current_allocation
;
1389 for (i
=2; i
<argc
; ++i
)
1391 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1395 fprintf(STDERR
, "Testing %s:",argv
[i
]);
1396 kerror
= test_one_file(argv
[i
], outname
);
1399 #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
1400 fprintf(STDERR
, "\n PASS (%lu zero samples)\n",
1401 (unsigned long)zero_samples
);
1403 fprintf(STDERR
, " PASS\n");
1405 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1406 for (k
=0; k
<256; k
++)
1408 fprintf(STDERR
, " Filter %d was used %lu times\n",
1409 k
,(unsigned long)filters_used
[k
]);
1411 #if defined(PNG_TIME_RFC1123_SUPPORTED)
1412 if(tIME_chunk_present
!= 0)
1413 fprintf(STDERR
, " tIME = %s\n",tIME_string
);
1414 tIME_chunk_present
= 0;
1415 #endif /* PNG_TIME_RFC1123_SUPPORTED */
1419 fprintf(STDERR
, " FAIL\n");
1422 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1423 if (allocation_now
!= current_allocation
)
1424 fprintf(STDERR
, "MEMORY ERROR: %d bytes lost\n",
1425 current_allocation
-allocation_now
);
1426 if (current_allocation
!= 0)
1428 memory_infop pinfo
= pinformation
;
1430 fprintf(STDERR
, "MEMORY ERROR: %d bytes still allocated\n",
1431 current_allocation
);
1432 while (pinfo
!= NULL
)
1434 fprintf(STDERR
, " %lu bytes at %x\n", (unsigned long)pinfo
->size
,
1435 (unsigned int) pinfo
->pointer
);
1436 pinfo
= pinfo
->next
;
1441 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1442 fprintf(STDERR
, " Current memory allocation: %10d bytes\n",
1443 current_allocation
);
1444 fprintf(STDERR
, " Maximum memory allocation: %10d bytes\n",
1445 maximum_allocation
);
1446 fprintf(STDERR
, " Total memory allocation: %10d bytes\n",
1448 fprintf(STDERR
, " Number of allocations: %10d\n",
1458 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1459 int allocation_now
= current_allocation
;
1461 if (i
== 1) status_dots_requested
= 1;
1462 else if(verbose
== 0)status_dots_requested
= 0;
1463 if (i
== 0 || verbose
== 1 || ierror
!= 0)
1464 fprintf(STDERR
, "Testing %s:",inname
);
1465 kerror
= test_one_file(inname
, outname
);
1468 if(verbose
== 1 || i
== 2)
1470 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1473 #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
1474 fprintf(STDERR
, "\n PASS (%lu zero samples)\n",
1475 (unsigned long)zero_samples
);
1477 fprintf(STDERR
, " PASS\n");
1479 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1480 for (k
=0; k
<256; k
++)
1482 fprintf(STDERR
, " Filter %d was used %lu times\n",
1483 k
,(unsigned long)filters_used
[k
]);
1485 #if defined(PNG_TIME_RFC1123_SUPPORTED)
1486 if(tIME_chunk_present
!= 0)
1487 fprintf(STDERR
, " tIME = %s\n",tIME_string
);
1488 #endif /* PNG_TIME_RFC1123_SUPPORTED */
1493 if(verbose
== 0 && i
!= 2)
1494 fprintf(STDERR
, "Testing %s:",inname
);
1495 fprintf(STDERR
, " FAIL\n");
1498 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1499 if (allocation_now
!= current_allocation
)
1500 fprintf(STDERR
, "MEMORY ERROR: %d bytes lost\n",
1501 current_allocation
-allocation_now
);
1502 if (current_allocation
!= 0)
1504 memory_infop pinfo
= pinformation
;
1506 fprintf(STDERR
, "MEMORY ERROR: %d bytes still allocated\n",
1507 current_allocation
);
1508 while (pinfo
!= NULL
)
1510 fprintf(STDERR
," %lu bytes at %x\n",
1511 (unsigned long)pinfo
->size
, (unsigned int)pinfo
->pointer
);
1512 pinfo
= pinfo
->next
;
1517 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1518 fprintf(STDERR
, " Current memory allocation: %10d bytes\n",
1519 current_allocation
);
1520 fprintf(STDERR
, " Maximum memory allocation: %10d bytes\n",
1521 maximum_allocation
);
1522 fprintf(STDERR
, " Total memory allocation: %10d bytes\n",
1524 fprintf(STDERR
, " Number of allocations: %10d\n",
1529 #ifdef PNGTEST_TIMING
1530 t_stop
= (float)clock();
1531 t_misc
+= (t_stop
- t_start
);
1533 fprintf(STDERR
," CPU time used = %.3f seconds",
1534 (t_misc
+t_decode
+t_encode
)/(float)CLOCKS_PER_SEC
);
1535 fprintf(STDERR
," (decoding %.3f,\n",
1536 t_decode
/(float)CLOCKS_PER_SEC
);
1537 fprintf(STDERR
," encoding %.3f ,",
1538 t_encode
/(float)CLOCKS_PER_SEC
);
1539 fprintf(STDERR
," other %.3f seconds)\n\n",
1540 t_misc
/(float)CLOCKS_PER_SEC
);
1544 fprintf(STDERR
, "libpng passes test\n");
1546 fprintf(STDERR
, "libpng FAILS test\n");
1547 return (int)(ierror
!= 0);
1550 /* Generate a compiler error if there is an old png.h in the search path. */
1551 typedef version_1_2_20 your_png_h_is_not_version_1_2_20
;