2 /* pngtest.c - a simple test program to test libpng
4 * Last changed in libpng 1.5.0 [January 6, 2011]
5 * Copyright (c) 1998-2011 Glenn Randers-Pehrson
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
9 * This code is released under the libpng license.
10 * For conditions of distribution and use, see the disclaimer
11 * and license in png.h
13 * This program reads in a PNG image, writes it out again, and then
14 * compares the two files. If the files are identical, this shows that
15 * the basic chunk handling, filtering, and (de)compression code is working
16 * properly. It does not currently test all of the transforms, although
19 * The program will report "FAIL" in certain legitimate cases:
20 * 1) when the compression level or filter selection method is changed.
21 * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192.
22 * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks
23 * exist in the input file.
24 * 4) others not listed here...
25 * In these cases, it is best to check with another tool such as "pngcheck"
26 * to see what the differences between the two files are.
28 * If a filename is given on the command-line, then this file is used
29 * for the input, rather than the default "pngtest.png". This allows
30 * testing a wide variety of files easily. You can also test a number
31 * of files at once by typing "pngtest -m file1.png file2.png ..."
36 /* Copied from pngpriv.h but only used in error messages below. */
38 # define PNG_ZBUF_SIZE 8192
43 # define FCLOSE(file) fclose(file)
45 #ifndef PNG_STDIO_SUPPORTED
46 typedef FILE * png_FILE_p
;
49 /* Makes pngtest verbose so we can find problems. */
55 # define pngtest_debug(m) ((void)fprintf(stderr, m "\n"))
56 # define pngtest_debug1(m,p1) ((void)fprintf(stderr, m "\n", p1))
57 # define pngtest_debug2(m,p1,p2) ((void)fprintf(stderr, m "\n", p1, p2))
59 # define pngtest_debug(m) ((void)0)
60 # define pngtest_debug1(m,p1) ((void)0)
61 # define pngtest_debug2(m,p1,p2) ((void)0)
65 # define SINGLE_ROWBUF_ALLOC /* Makes buffer overruns easier to nail */
68 /* The code uses memcmp and memcpy on large objects (typically row pointers) so
69 * it is necessary to do soemthing special on certain architectures, note that
70 * the actual support for this was effectively removed in 1.4, so only the
71 * memory remains in this program:
73 #define CVT_PTR(ptr) (ptr)
74 #define CVT_PTR_NOCHECK(ptr) (ptr)
75 #define png_memcmp memcmp
76 #define png_memcpy memcpy
77 #define png_memset memset
80 #define PNGTEST_TIMING
83 #ifndef PNG_FLOATING_POINT_SUPPORTED
88 static float t_start
, t_stop
, t_decode
, t_encode
, t_misc
;
92 #ifdef PNG_TIME_RFC1123_SUPPORTED
93 #define PNG_tIME_STRING_LENGTH 29
94 static int tIME_chunk_present
= 0;
95 static char tIME_string
[PNG_tIME_STRING_LENGTH
] = "tIME chunk is not present";
98 static int verbose
= 0;
100 int test_one_file
PNGARG((PNG_CONST
char *inname
, PNG_CONST
char *outname
));
106 /* Defined so I can write to a file on gui/windowing platforms */
107 /* #define STDERR stderr */
108 #define STDERR stdout /* For DOS */
110 /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
112 # define png_jmpbuf(png_ptr) png_ptr->jmpbuf
115 /* Example of using row callbacks to make a simple progress meter */
116 static int status_pass
= 1;
117 static int status_dots_requested
= 0;
118 static int status_dots
= 1;
121 read_row_callback(png_structp png_ptr
, png_uint_32 row_number
, int pass
);
123 read_row_callback(png_structp png_ptr
, png_uint_32 row_number
, int pass
)
125 if (png_ptr
== NULL
|| row_number
> PNG_UINT_31_MAX
)
128 if (status_pass
!= pass
)
130 fprintf(stdout
, "\n Pass %d: ", pass
);
137 if (status_dots
== 0)
139 fprintf(stdout
, "\n ");
143 fprintf(stdout
, "r");
147 write_row_callback(png_structp png_ptr
, png_uint_32 row_number
, int pass
);
149 write_row_callback(png_structp png_ptr
, png_uint_32 row_number
, int pass
)
151 if (png_ptr
== NULL
|| row_number
> PNG_UINT_31_MAX
|| pass
> 7)
154 fprintf(stdout
, "w");
158 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
159 /* Example of using user transform callback (we don't transform anything,
160 * but merely examine the row filters. We set this to 256 rather than
161 * 5 in case illegal filter values are present.)
163 static png_uint_32 filters_used
[256];
165 count_filters(png_structp png_ptr
, png_row_infop row_info
, png_bytep data
);
167 count_filters(png_structp png_ptr
, png_row_infop row_info
, png_bytep data
)
169 if (png_ptr
!= NULL
&& row_info
!= NULL
)
170 ++filters_used
[*(data
- 1)];
174 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
175 /* Example of using user transform callback (we don't transform anything,
176 * but merely count the zero samples)
179 static png_uint_32 zero_samples
;
182 count_zero_samples(png_structp png_ptr
, png_row_infop row_info
, png_bytep data
);
184 count_zero_samples(png_structp png_ptr
, png_row_infop row_info
, png_bytep data
)
190 /* Contents of row_info:
191 * png_uint_32 width width of row
192 * png_uint_32 rowbytes number of bytes in row
193 * png_byte color_type color type of pixels
194 * png_byte bit_depth bit depth of samples
195 * png_byte channels number of channels (1-4)
196 * png_byte pixel_depth bits per pixel (depth*channels)
199 /* Counts the number of zero samples (or zero pixels if color_type is 3 */
201 if (row_info
->color_type
== 0 || row_info
->color_type
== 3)
204 png_uint_32 n
, nstop
;
206 for (n
= 0, nstop
=row_info
->width
; n
<nstop
; n
++)
208 if (row_info
->bit_depth
== 1)
210 if (((*dp
<< pos
++ ) & 0x80) == 0)
220 if (row_info
->bit_depth
== 2)
222 if (((*dp
<< (pos
+=2)) & 0xc0) == 0)
232 if (row_info
->bit_depth
== 4)
234 if (((*dp
<< (pos
+=4)) & 0xf0) == 0)
244 if (row_info
->bit_depth
== 8)
248 if (row_info
->bit_depth
== 16)
250 if ((*dp
| *(dp
+1)) == 0)
256 else /* Other color types */
258 png_uint_32 n
, nstop
;
260 int color_channels
= row_info
->channels
;
261 if (row_info
->color_type
> 3)color_channels
--;
263 for (n
= 0, nstop
=row_info
->width
; n
<nstop
; n
++)
265 for (channel
= 0; channel
< color_channels
; channel
++)
267 if (row_info
->bit_depth
== 8)
271 if (row_info
->bit_depth
== 16)
273 if ((*dp
| *(dp
+1)) == 0)
279 if (row_info
->color_type
> 3)
282 if (row_info
->bit_depth
== 16)
288 #endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
290 static int wrote_question
= 0;
292 #ifndef PNG_STDIO_SUPPORTED
293 /* START of code to validate stdio-free compilation */
294 /* These copies of the default read/write functions come from pngrio.c and
295 * pngwio.c. They allow "don't include stdio" testing of the library.
296 * This is the function that does the actual reading of data. If you are
297 * not reading from a standard C stream, you should create a replacement
298 * read_data function and use it at run time with png_set_read_fn(), rather
299 * than changing the library.
302 #ifdef PNG_IO_STATE_SUPPORTED
304 pngtest_check_io_state(png_structp png_ptr
, png_size_t data_length
,
307 pngtest_check_io_state(png_structp png_ptr
, png_size_t data_length
,
310 png_uint_32 io_state
= png_get_io_state(png_ptr
);
313 /* Check if the current operation (reading / writing) is as expected. */
314 if ((io_state
& PNG_IO_MASK_OP
) != io_op
)
315 png_error(png_ptr
, "Incorrect operation in I/O state");
317 /* Check if the buffer size specific to the current location
318 * (file signature / header / data / crc) is as expected.
320 switch (io_state
& PNG_IO_MASK_LOC
)
322 case PNG_IO_SIGNATURE
:
326 case PNG_IO_CHUNK_HDR
:
327 if (data_length
!= 8)
330 case PNG_IO_CHUNK_DATA
:
331 break; /* no restrictions here */
332 case PNG_IO_CHUNK_CRC
:
333 if (data_length
!= 4)
337 err
= 1; /* uninitialized */
340 png_error(png_ptr
, "Bad I/O state or buffer size");
344 #ifndef USE_FAR_KEYWORD
346 pngtest_read_data(png_structp png_ptr
, png_bytep data
, png_size_t length
)
348 png_size_t check
= 0;
351 /* fread() returns 0 on error, so it is OK to store this in a png_size_t
352 * instead of an int, which is what fread() actually returns.
354 io_ptr
= png_get_io_ptr(png_ptr
);
357 check
= fread(data
, 1, length
, (png_FILE_p
)io_ptr
);
362 png_error(png_ptr
, "Read Error");
365 #ifdef PNG_IO_STATE_SUPPORTED
366 pngtest_check_io_state(png_ptr
, length
, PNG_IO_READING
);
370 /* This is the model-independent version. Since the standard I/O library
371 can't handle far buffers in the medium and small models, we have to copy
375 #define NEAR_BUF_SIZE 1024
376 #define MIN(a,b) (a <= b ? a : b)
379 pngtest_read_data(png_structp png_ptr
, png_bytep data
, png_size_t length
)
385 /* Check if data really is near. If so, use usual code. */
386 n_data
= (png_byte
*)CVT_PTR_NOCHECK(data
);
387 io_ptr
= (png_FILE_p
)CVT_PTR(png_get_io_ptr(png_ptr
));
388 if ((png_bytep
)n_data
== data
)
390 check
= fread(n_data
, 1, length
, io_ptr
);
394 png_byte buf
[NEAR_BUF_SIZE
];
395 png_size_t read
, remaining
, err
;
401 read
= MIN(NEAR_BUF_SIZE
, remaining
);
402 err
= fread(buf
, 1, 1, io_ptr
);
403 png_memcpy(data
, buf
, read
); /* Copy far buffer to near buffer */
411 while (remaining
!= 0);
415 png_error(png_ptr
, "Read Error");
417 #ifdef PNG_IO_STATE_SUPPORTED
418 pngtest_check_io_state(png_ptr
, length
, PNG_IO_READING
);
421 #endif /* USE_FAR_KEYWORD */
423 #ifdef PNG_WRITE_FLUSH_SUPPORTED
425 pngtest_flush(png_structp png_ptr
)
427 /* Do nothing; fflush() is said to be just a waste of energy. */
428 PNG_UNUSED(png_ptr
) /* Stifle compiler warning */
432 /* This is the function that does the actual writing of data. If you are
433 * not writing to a standard C stream, you should create a replacement
434 * write_data function and use it at run time with png_set_write_fn(), rather
435 * than changing the library.
437 #ifndef USE_FAR_KEYWORD
439 pngtest_write_data(png_structp png_ptr
, png_bytep data
, png_size_t length
)
443 check
= fwrite(data
, 1, length
, (png_FILE_p
)png_get_io_ptr(png_ptr
));
447 png_error(png_ptr
, "Write Error");
450 #ifdef PNG_IO_STATE_SUPPORTED
451 pngtest_check_io_state(png_ptr
, length
, PNG_IO_WRITING
);
455 /* This is the model-independent version. Since the standard I/O library
456 can't handle far buffers in the medium and small models, we have to copy
460 #define NEAR_BUF_SIZE 1024
461 #define MIN(a,b) (a <= b ? a : b)
464 pngtest_write_data(png_structp png_ptr
, png_bytep data
, png_size_t length
)
467 png_byte
*near_data
; /* Needs to be "png_byte *" instead of "png_bytep" */
470 /* Check if data really is near. If so, use usual code. */
471 near_data
= (png_byte
*)CVT_PTR_NOCHECK(data
);
472 io_ptr
= (png_FILE_p
)CVT_PTR(png_get_io_ptr(png_ptr
));
474 if ((png_bytep
)near_data
== data
)
476 check
= fwrite(near_data
, 1, length
, io_ptr
);
481 png_byte buf
[NEAR_BUF_SIZE
];
482 png_size_t written
, remaining
, err
;
488 written
= MIN(NEAR_BUF_SIZE
, remaining
);
489 png_memcpy(buf
, data
, written
); /* Copy far buffer to near buffer */
490 err
= fwrite(buf
, 1, written
, io_ptr
);
496 remaining
-= written
;
498 while (remaining
!= 0);
503 png_error(png_ptr
, "Write Error");
506 #ifdef PNG_IO_STATE_SUPPORTED
507 pngtest_check_io_state(png_ptr
, length
, PNG_IO_WRITING
);
510 #endif /* USE_FAR_KEYWORD */
512 /* This function is called when there is a warning, but the library thinks
513 * it can continue anyway. Replacement functions don't have to do anything
514 * here if you don't want to. In the default configuration, png_ptr is
515 * not used, but it is passed in case it may be useful.
518 pngtest_warning(png_structp png_ptr
, png_const_charp message
)
520 PNG_CONST
char *name
= "UNKNOWN (ERROR!)";
522 test
= png_get_error_ptr(png_ptr
);
525 fprintf(STDERR
, "%s: libpng warning: %s\n", name
, message
);
528 fprintf(STDERR
, "%s: libpng warning: %s\n", test
, message
);
531 /* This is the default error handling function. Note that replacements for
532 * this function MUST NOT RETURN, or the program will likely crash. This
533 * function is used by default, or if the program supplies NULL for the
534 * error function pointer in png_set_error_fn().
537 pngtest_error(png_structp png_ptr
, png_const_charp message
)
539 pngtest_warning(png_ptr
, message
);
540 /* We can return because png_error calls the default handler, which is
541 * actually OK in this case.
544 #endif /* !PNG_STDIO_SUPPORTED */
545 /* END of code to validate stdio-free compilation */
547 /* START of code to validate memory allocation and deallocation */
548 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
550 /* Allocate memory. For reasonable files, size should never exceed
551 * 64K. However, zlib may allocate more then 64K if you don't tell
552 * it not to. See zconf.h and png.h for more information. zlib does
553 * need to allocate exactly 64K, so whatever you call here must
554 * have the ability to do that.
556 * This piece of code can be compiled to validate max 64K allocations
557 * by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K.
559 typedef struct memory_information
561 png_alloc_size_t size
;
563 struct memory_information FAR
*next
;
564 } memory_information
;
565 typedef memory_information FAR
*memory_infop
;
567 static memory_infop pinformation
= NULL
;
568 static int current_allocation
= 0;
569 static int maximum_allocation
= 0;
570 static int total_allocation
= 0;
571 static int num_allocations
= 0;
573 png_voidp PNGCBAPI png_debug_malloc
PNGARG((png_structp png_ptr
,
574 png_alloc_size_t size
));
575 void PNGCBAPI png_debug_free
PNGARG((png_structp png_ptr
, png_voidp ptr
));
578 PNGCBAPI
png_debug_malloc(png_structp png_ptr
, png_alloc_size_t size
)
581 /* png_malloc has already tested for NULL; png_create_struct calls
582 * png_debug_malloc directly, with png_ptr == NULL which is OK
588 /* This calls the library allocator twice, once to get the requested
589 buffer and once to get a new free list entry. */
591 /* Disable malloc_fn and free_fn */
593 png_set_mem_fn(png_ptr
, NULL
, NULL
, NULL
);
594 pinfo
= (memory_infop
)png_malloc(png_ptr
,
597 current_allocation
+= size
;
598 total_allocation
+= size
;
601 if (current_allocation
> maximum_allocation
)
602 maximum_allocation
= current_allocation
;
604 pinfo
->pointer
= png_malloc(png_ptr
, size
);
605 /* Restore malloc_fn and free_fn */
607 png_set_mem_fn(png_ptr
,
608 NULL
, png_debug_malloc
, png_debug_free
);
610 if (size
!= 0 && pinfo
->pointer
== NULL
)
612 current_allocation
-= size
;
613 total_allocation
-= size
;
615 "out of memory in pngtest->png_debug_malloc");
618 pinfo
->next
= pinformation
;
619 pinformation
= pinfo
;
620 /* Make sure the caller isn't assuming zeroed memory. */
621 png_memset(pinfo
->pointer
, 0xdd, pinfo
->size
);
624 printf("png_malloc %lu bytes at %p\n", (unsigned long)size
,
627 return (png_voidp
)(pinfo
->pointer
);
631 /* Free a pointer. It is removed from the list at the same time. */
633 png_debug_free(png_structp png_ptr
, png_voidp ptr
)
636 fprintf(STDERR
, "NULL pointer to png_debug_free.\n");
640 #if 0 /* This happens all the time. */
641 fprintf(STDERR
, "WARNING: freeing NULL pointer\n");
646 /* Unlink the element from the list. */
648 memory_infop FAR
*ppinfo
= &pinformation
;
652 memory_infop pinfo
= *ppinfo
;
654 if (pinfo
->pointer
== ptr
)
656 *ppinfo
= pinfo
->next
;
657 current_allocation
-= pinfo
->size
;
658 if (current_allocation
< 0)
659 fprintf(STDERR
, "Duplicate free of memory\n");
660 /* We must free the list element too, but first kill
661 the memory that is to be freed. */
662 png_memset(ptr
, 0x55, pinfo
->size
);
663 png_free_default(png_ptr
, pinfo
);
668 if (pinfo
->next
== NULL
)
670 fprintf(STDERR
, "Pointer %x not found\n", (unsigned int)ptr
);
674 ppinfo
= &pinfo
->next
;
678 /* Finally free the data. */
680 printf("Freeing %p\n", ptr
);
682 png_free_default(png_ptr
, ptr
);
685 #endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */
686 /* END of code to test memory allocation/deallocation */
689 /* Demonstration of user chunk support of the sTER and vpAg chunks */
690 #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
692 /* (sTER is a public chunk not yet known by libpng. vpAg is a private
693 chunk used in ImageMagick to store "virtual page" size). */
695 static png_uint_32 user_chunk_data
[4];
703 static int PNGCBAPI
read_user_chunk_callback(png_struct
*png_ptr
,
704 png_unknown_chunkp chunk
)
709 /* Return one of the following:
710 * return (-n); chunk had an error
711 * return (0); did not recognize
712 * return (n); success
714 * The unknown chunk structure contains the chunk data:
719 * Note that libpng has already taken care of the CRC handling.
722 if (chunk
->name
[0] == 115 && chunk
->name
[1] == 84 && /* s T */
723 chunk
->name
[2] == 69 && chunk
->name
[3] == 82) /* E R */
725 /* Found sTER chunk */
726 if (chunk
->size
!= 1)
727 return (-1); /* Error return */
729 if (chunk
->data
[0] != 0 && chunk
->data
[0] != 1)
730 return (-1); /* Invalid mode */
732 my_user_chunk_data
=(png_uint_32
*) png_get_user_chunk_ptr(png_ptr
);
733 my_user_chunk_data
[0]=chunk
->data
[0]+1;
737 if (chunk
->name
[0] != 118 || chunk
->name
[1] != 112 || /* v p */
738 chunk
->name
[2] != 65 || chunk
->name
[3] != 103) /* A g */
739 return (0); /* Did not recognize */
741 /* Found ImageMagick vpAg chunk */
743 if (chunk
->size
!= 9)
744 return (-1); /* Error return */
746 my_user_chunk_data
=(png_uint_32
*) png_get_user_chunk_ptr(png_ptr
);
748 my_user_chunk_data
[1]=png_get_uint_31(png_ptr
, chunk
->data
);
749 my_user_chunk_data
[2]=png_get_uint_31(png_ptr
, chunk
->data
+ 4);
750 my_user_chunk_data
[3]=(png_uint_32
)chunk
->data
[8];
756 /* END of code to demonstrate user chunk support */
760 test_one_file(PNG_CONST
char *inname
, PNG_CONST
char *outname
)
762 static png_FILE_p fpin
;
763 static png_FILE_p fpout
; /* "static" prevents setjmp corruption */
764 png_structp read_ptr
;
765 png_infop read_info_ptr
, end_info_ptr
;
766 #ifdef PNG_WRITE_SUPPORTED
767 png_structp write_ptr
;
768 png_infop write_info_ptr
;
769 png_infop write_end_info_ptr
;
771 png_structp write_ptr
= NULL
;
772 png_infop write_info_ptr
= NULL
;
773 png_infop write_end_info_ptr
= NULL
;
777 png_uint_32 width
, height
;
779 int bit_depth
, color_type
;
780 #ifdef PNG_SETJMP_SUPPORTED
781 #ifdef USE_FAR_KEYWORD
786 char inbuf
[256], outbuf
[256];
790 if ((fpin
= fopen(inname
, "rb")) == NULL
)
792 fprintf(STDERR
, "Could not find input file %s\n", inname
);
796 if ((fpout
= fopen(outname
, "wb")) == NULL
)
798 fprintf(STDERR
, "Could not open output file %s\n", outname
);
803 pngtest_debug("Allocating read and write structures");
804 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
806 png_create_read_struct_2(PNG_LIBPNG_VER_STRING
, NULL
,
807 NULL
, NULL
, NULL
, png_debug_malloc
, png_debug_free
);
810 png_create_read_struct(PNG_LIBPNG_VER_STRING
, NULL
, NULL
, NULL
);
812 #ifndef PNG_STDIO_SUPPORTED
813 png_set_error_fn(read_ptr
, (png_voidp
)inname
, pngtest_error
,
817 #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
818 user_chunk_data
[0] = 0;
819 user_chunk_data
[1] = 0;
820 user_chunk_data
[2] = 0;
821 user_chunk_data
[3] = 0;
822 png_set_read_user_chunk_fn(read_ptr
, user_chunk_data
,
823 read_user_chunk_callback
);
826 #ifdef PNG_WRITE_SUPPORTED
827 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
829 png_create_write_struct_2(PNG_LIBPNG_VER_STRING
, NULL
,
830 NULL
, NULL
, NULL
, png_debug_malloc
, png_debug_free
);
833 png_create_write_struct(PNG_LIBPNG_VER_STRING
, NULL
, NULL
, NULL
);
835 #ifndef PNG_STDIO_SUPPORTED
836 png_set_error_fn(write_ptr
, (png_voidp
)inname
, pngtest_error
,
840 pngtest_debug("Allocating read_info, write_info and end_info structures");
841 read_info_ptr
= png_create_info_struct(read_ptr
);
842 end_info_ptr
= png_create_info_struct(read_ptr
);
843 #ifdef PNG_WRITE_SUPPORTED
844 write_info_ptr
= png_create_info_struct(write_ptr
);
845 write_end_info_ptr
= png_create_info_struct(write_ptr
);
848 #ifdef PNG_SETJMP_SUPPORTED
849 pngtest_debug("Setting jmpbuf for read struct");
850 #ifdef USE_FAR_KEYWORD
851 if (setjmp(png_jmpbuf
))
853 if (setjmp(png_jmpbuf(read_ptr
)))
856 fprintf(STDERR
, "%s -> %s: libpng read error\n", inname
, outname
);
857 png_free(read_ptr
, row_buf
);
859 png_destroy_read_struct(&read_ptr
, &read_info_ptr
, &end_info_ptr
);
860 #ifdef PNG_WRITE_SUPPORTED
861 png_destroy_info_struct(write_ptr
, &write_end_info_ptr
);
862 png_destroy_write_struct(&write_ptr
, &write_info_ptr
);
868 #ifdef USE_FAR_KEYWORD
869 png_memcpy(png_jmpbuf(read_ptr
), png_jmpbuf
, png_sizeof(jmp_buf));
872 #ifdef PNG_WRITE_SUPPORTED
873 pngtest_debug("Setting jmpbuf for write struct");
874 #ifdef USE_FAR_KEYWORD
876 if (setjmp(png_jmpbuf
))
878 if (setjmp(png_jmpbuf(write_ptr
)))
881 fprintf(STDERR
, "%s -> %s: libpng write error\n", inname
, outname
);
882 png_destroy_read_struct(&read_ptr
, &read_info_ptr
, &end_info_ptr
);
883 png_destroy_info_struct(write_ptr
, &write_end_info_ptr
);
884 #ifdef PNG_WRITE_SUPPORTED
885 png_destroy_write_struct(&write_ptr
, &write_info_ptr
);
892 #ifdef USE_FAR_KEYWORD
893 png_memcpy(png_jmpbuf(write_ptr
), png_jmpbuf
, png_sizeof(jmp_buf));
898 pngtest_debug("Initializing input and output streams");
899 #ifdef PNG_STDIO_SUPPORTED
900 png_init_io(read_ptr
, fpin
);
901 # ifdef PNG_WRITE_SUPPORTED
902 png_init_io(write_ptr
, fpout
);
905 png_set_read_fn(read_ptr
, (png_voidp
)fpin
, pngtest_read_data
);
906 # ifdef PNG_WRITE_SUPPORTED
907 png_set_write_fn(write_ptr
, (png_voidp
)fpout
, pngtest_write_data
,
908 # ifdef PNG_WRITE_FLUSH_SUPPORTED
916 if (status_dots_requested
== 1)
918 #ifdef PNG_WRITE_SUPPORTED
919 png_set_write_status_fn(write_ptr
, write_row_callback
);
921 png_set_read_status_fn(read_ptr
, read_row_callback
);
926 #ifdef PNG_WRITE_SUPPORTED
927 png_set_write_status_fn(write_ptr
, NULL
);
929 png_set_read_status_fn(read_ptr
, NULL
);
932 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
936 for (i
= 0; i
<256; i
++)
939 png_set_read_user_transform_fn(read_ptr
, count_filters
);
942 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
944 png_set_write_user_transform_fn(write_ptr
, count_zero_samples
);
947 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
948 # ifndef PNG_HANDLE_CHUNK_ALWAYS
949 # define PNG_HANDLE_CHUNK_ALWAYS 3
951 png_set_keep_unknown_chunks(read_ptr
, PNG_HANDLE_CHUNK_ALWAYS
,
954 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
955 # ifndef PNG_HANDLE_CHUNK_IF_SAFE
956 # define PNG_HANDLE_CHUNK_IF_SAFE 2
958 png_set_keep_unknown_chunks(write_ptr
, PNG_HANDLE_CHUNK_IF_SAFE
,
962 pngtest_debug("Reading info struct");
963 png_read_info(read_ptr
, read_info_ptr
);
965 pngtest_debug("Transferring info struct");
967 int interlace_type
, compression_type
, filter_type
;
969 if (png_get_IHDR(read_ptr
, read_info_ptr
, &width
, &height
, &bit_depth
,
970 &color_type
, &interlace_type
, &compression_type
, &filter_type
))
972 png_set_IHDR(write_ptr
, write_info_ptr
, width
, height
, bit_depth
,
973 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
974 color_type
, interlace_type
, compression_type
, filter_type
);
976 color_type
, PNG_INTERLACE_NONE
, compression_type
, filter_type
);
980 #ifdef PNG_FIXED_POINT_SUPPORTED
981 #ifdef PNG_cHRM_SUPPORTED
983 png_fixed_point white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
,
986 if (png_get_cHRM_fixed(read_ptr
, read_info_ptr
, &white_x
, &white_y
,
987 &red_x
, &red_y
, &green_x
, &green_y
, &blue_x
, &blue_y
))
989 png_set_cHRM_fixed(write_ptr
, write_info_ptr
, white_x
, white_y
, red_x
,
990 red_y
, green_x
, green_y
, blue_x
, blue_y
);
994 #ifdef PNG_gAMA_SUPPORTED
996 png_fixed_point gamma
;
998 if (png_get_gAMA_fixed(read_ptr
, read_info_ptr
, &gamma
))
999 png_set_gAMA_fixed(write_ptr
, write_info_ptr
, gamma
);
1002 #else /* Use floating point versions */
1003 #ifdef PNG_FLOATING_POINT_SUPPORTED
1004 #ifdef PNG_cHRM_SUPPORTED
1006 double white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
,
1009 if (png_get_cHRM(read_ptr
, read_info_ptr
, &white_x
, &white_y
, &red_x
,
1010 &red_y
, &green_x
, &green_y
, &blue_x
, &blue_y
))
1012 png_set_cHRM(write_ptr
, write_info_ptr
, white_x
, white_y
, red_x
,
1013 red_y
, green_x
, green_y
, blue_x
, blue_y
);
1017 #ifdef PNG_gAMA_SUPPORTED
1021 if (png_get_gAMA(read_ptr
, read_info_ptr
, &gamma
))
1022 png_set_gAMA(write_ptr
, write_info_ptr
, gamma
);
1025 #endif /* Floating point */
1026 #endif /* Fixed point */
1027 #ifdef PNG_iCCP_SUPPORTED
1031 png_uint_32 proflen
;
1032 int compression_type
;
1034 if (png_get_iCCP(read_ptr
, read_info_ptr
, &name
, &compression_type
,
1035 &profile
, &proflen
))
1037 png_set_iCCP(write_ptr
, write_info_ptr
, name
, compression_type
,
1042 #ifdef PNG_sRGB_SUPPORTED
1046 if (png_get_sRGB(read_ptr
, read_info_ptr
, &intent
))
1047 png_set_sRGB(write_ptr
, write_info_ptr
, intent
);
1054 if (png_get_PLTE(read_ptr
, read_info_ptr
, &palette
, &num_palette
))
1055 png_set_PLTE(write_ptr
, write_info_ptr
, palette
, num_palette
);
1057 #ifdef PNG_bKGD_SUPPORTED
1059 png_color_16p background
;
1061 if (png_get_bKGD(read_ptr
, read_info_ptr
, &background
))
1063 png_set_bKGD(write_ptr
, write_info_ptr
, background
);
1067 #ifdef PNG_hIST_SUPPORTED
1071 if (png_get_hIST(read_ptr
, read_info_ptr
, &hist
))
1072 png_set_hIST(write_ptr
, write_info_ptr
, hist
);
1075 #ifdef PNG_oFFs_SUPPORTED
1077 png_int_32 offset_x
, offset_y
;
1080 if (png_get_oFFs(read_ptr
, read_info_ptr
, &offset_x
, &offset_y
,
1083 png_set_oFFs(write_ptr
, write_info_ptr
, offset_x
, offset_y
, unit_type
);
1087 #ifdef PNG_pCAL_SUPPORTED
1089 png_charp purpose
, units
;
1094 if (png_get_pCAL(read_ptr
, read_info_ptr
, &purpose
, &X0
, &X1
, &type
,
1095 &nparams
, &units
, ¶ms
))
1097 png_set_pCAL(write_ptr
, write_info_ptr
, purpose
, X0
, X1
, type
,
1098 nparams
, units
, params
);
1102 #ifdef PNG_pHYs_SUPPORTED
1104 png_uint_32 res_x
, res_y
;
1107 if (png_get_pHYs(read_ptr
, read_info_ptr
, &res_x
, &res_y
, &unit_type
))
1108 png_set_pHYs(write_ptr
, write_info_ptr
, res_x
, res_y
, unit_type
);
1111 #ifdef PNG_sBIT_SUPPORTED
1113 png_color_8p sig_bit
;
1115 if (png_get_sBIT(read_ptr
, read_info_ptr
, &sig_bit
))
1116 png_set_sBIT(write_ptr
, write_info_ptr
, sig_bit
);
1119 #ifdef PNG_sCAL_SUPPORTED
1120 #ifdef PNG_FLOATING_POINT_SUPPORTED
1123 double scal_width
, scal_height
;
1125 if (png_get_sCAL(read_ptr
, read_info_ptr
, &unit
, &scal_width
,
1128 png_set_sCAL(write_ptr
, write_info_ptr
, unit
, scal_width
, scal_height
);
1132 #ifdef PNG_FIXED_POINT_SUPPORTED
1135 png_charp scal_width
, scal_height
;
1137 if (png_get_sCAL_s(read_ptr
, read_info_ptr
, &unit
, &scal_width
,
1140 png_set_sCAL_s(write_ptr
, write_info_ptr
, unit
, scal_width
,
1147 #ifdef PNG_TEXT_SUPPORTED
1152 if (png_get_text(read_ptr
, read_info_ptr
, &text_ptr
, &num_text
) > 0)
1154 pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text
);
1155 png_set_text(write_ptr
, write_info_ptr
, text_ptr
, num_text
);
1159 #ifdef PNG_tIME_SUPPORTED
1163 if (png_get_tIME(read_ptr
, read_info_ptr
, &mod_time
))
1165 png_set_tIME(write_ptr
, write_info_ptr
, mod_time
);
1166 #ifdef PNG_TIME_RFC1123_SUPPORTED
1167 /* We have to use png_memcpy instead of "=" because the string
1168 * pointed to by png_convert_to_rfc1123() gets free'ed before
1171 png_memcpy(tIME_string
,
1172 png_convert_to_rfc1123(read_ptr
, mod_time
),
1173 png_sizeof(tIME_string
));
1175 tIME_string
[png_sizeof(tIME_string
) - 1] = '\0';
1176 tIME_chunk_present
++;
1177 #endif /* PNG_TIME_RFC1123_SUPPORTED */
1181 #ifdef PNG_tRNS_SUPPORTED
1183 png_bytep trans_alpha
;
1185 png_color_16p trans_color
;
1187 if (png_get_tRNS(read_ptr
, read_info_ptr
, &trans_alpha
, &num_trans
,
1190 int sample_max
= (1 << bit_depth
);
1191 /* libpng doesn't reject a tRNS chunk with out-of-range samples */
1192 if (!((color_type
== PNG_COLOR_TYPE_GRAY
&&
1193 (int)trans_color
->gray
> sample_max
) ||
1194 (color_type
== PNG_COLOR_TYPE_RGB
&&
1195 ((int)trans_color
->red
> sample_max
||
1196 (int)trans_color
->green
> sample_max
||
1197 (int)trans_color
->blue
> sample_max
))))
1198 png_set_tRNS(write_ptr
, write_info_ptr
, trans_alpha
, num_trans
,
1203 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
1205 png_unknown_chunkp unknowns
;
1206 int num_unknowns
= png_get_unknown_chunks(read_ptr
, read_info_ptr
,
1212 png_set_unknown_chunks(write_ptr
, write_info_ptr
, unknowns
,
1214 /* Copy the locations from the read_info_ptr. The automatically
1215 * generated locations in write_info_ptr are wrong because we
1216 * haven't written anything yet.
1218 for (i
= 0; i
< num_unknowns
; i
++)
1219 png_set_unknown_chunk_location(write_ptr
, write_info_ptr
, i
,
1220 unknowns
[i
].location
);
1225 #ifdef PNG_WRITE_SUPPORTED
1226 pngtest_debug("Writing info struct");
1228 /* If we wanted, we could write info in two steps:
1229 * png_write_info_before_PLTE(write_ptr, write_info_ptr);
1231 png_write_info(write_ptr
, write_info_ptr
);
1233 #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
1234 if (user_chunk_data
[0] != 0)
1236 png_byte png_sTER
[5] = {115, 84, 69, 82, '\0'};
1242 fprintf(STDERR
, "\n stereo mode = %lu\n",
1243 (unsigned long)(user_chunk_data
[0] - 1));
1245 ster_chunk_data
[0]=(unsigned char)(user_chunk_data
[0] - 1);
1246 png_write_chunk(write_ptr
, png_sTER
, ster_chunk_data
, 1);
1249 if (user_chunk_data
[1] != 0 || user_chunk_data
[2] != 0)
1251 png_byte png_vpAg
[5] = {118, 112, 65, 103, '\0'};
1257 fprintf(STDERR
, " vpAg = %lu x %lu, units = %lu\n",
1258 (unsigned long)user_chunk_data
[1],
1259 (unsigned long)user_chunk_data
[2],
1260 (unsigned long)user_chunk_data
[3]);
1262 png_save_uint_32(vpag_chunk_data
, user_chunk_data
[1]);
1263 png_save_uint_32(vpag_chunk_data
+ 4, user_chunk_data
[2]);
1264 vpag_chunk_data
[8] = (unsigned char)(user_chunk_data
[3] & 0xff);
1265 png_write_chunk(write_ptr
, png_vpAg
, vpag_chunk_data
, 9);
1271 #ifdef SINGLE_ROWBUF_ALLOC
1272 pngtest_debug("Allocating row buffer...");
1273 row_buf
= (png_bytep
)png_malloc(read_ptr
,
1274 png_get_rowbytes(read_ptr
, read_info_ptr
));
1276 pngtest_debug1("\t0x%08lx", (unsigned long)row_buf
);
1277 #endif /* SINGLE_ROWBUF_ALLOC */
1278 pngtest_debug("Writing row data");
1280 #if defined(PNG_READ_INTERLACING_SUPPORTED) || \
1281 defined(PNG_WRITE_INTERLACING_SUPPORTED)
1282 num_pass
= png_set_interlace_handling(read_ptr
);
1283 # ifdef PNG_WRITE_SUPPORTED
1284 png_set_interlace_handling(write_ptr
);
1290 #ifdef PNGTEST_TIMING
1291 t_stop
= (float)clock();
1292 t_misc
+= (t_stop
- t_start
);
1295 for (pass
= 0; pass
< num_pass
; pass
++)
1297 pngtest_debug1("Writing row data for pass %d", pass
);
1298 for (y
= 0; y
< height
; y
++)
1300 #ifndef SINGLE_ROWBUF_ALLOC
1301 pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass
, y
);
1302 row_buf
= (png_bytep
)png_malloc(read_ptr
,
1303 png_get_rowbytes(read_ptr
, read_info_ptr
));
1305 pngtest_debug2("\t0x%08lx (%u bytes)", (unsigned long)row_buf
,
1306 png_get_rowbytes(read_ptr
, read_info_ptr
));
1308 #endif /* !SINGLE_ROWBUF_ALLOC */
1309 png_read_rows(read_ptr
, (png_bytepp
)&row_buf
, NULL
, 1);
1311 #ifdef PNG_WRITE_SUPPORTED
1312 #ifdef PNGTEST_TIMING
1313 t_stop
= (float)clock();
1314 t_decode
+= (t_stop
- t_start
);
1317 png_write_rows(write_ptr
, (png_bytepp
)&row_buf
, 1);
1318 #ifdef PNGTEST_TIMING
1319 t_stop
= (float)clock();
1320 t_encode
+= (t_stop
- t_start
);
1323 #endif /* PNG_WRITE_SUPPORTED */
1325 #ifndef SINGLE_ROWBUF_ALLOC
1326 pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass
, y
);
1327 png_free(read_ptr
, row_buf
);
1329 #endif /* !SINGLE_ROWBUF_ALLOC */
1333 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
1334 png_free_data(read_ptr
, read_info_ptr
, PNG_FREE_UNKN
, -1);
1336 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
1337 png_free_data(write_ptr
, write_info_ptr
, PNG_FREE_UNKN
, -1);
1340 pngtest_debug("Reading and writing end_info data");
1342 png_read_end(read_ptr
, end_info_ptr
);
1343 #ifdef PNG_TEXT_SUPPORTED
1348 if (png_get_text(read_ptr
, end_info_ptr
, &text_ptr
, &num_text
) > 0)
1350 pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text
);
1351 png_set_text(write_ptr
, write_end_info_ptr
, text_ptr
, num_text
);
1355 #ifdef PNG_tIME_SUPPORTED
1359 if (png_get_tIME(read_ptr
, end_info_ptr
, &mod_time
))
1361 png_set_tIME(write_ptr
, write_end_info_ptr
, mod_time
);
1362 #ifdef PNG_TIME_RFC1123_SUPPORTED
1363 /* We have to use png_memcpy instead of "=" because the string
1364 pointed to by png_convert_to_rfc1123() gets free'ed before
1366 png_memcpy(tIME_string
,
1367 png_convert_to_rfc1123(read_ptr
, mod_time
),
1368 png_sizeof(tIME_string
));
1370 tIME_string
[png_sizeof(tIME_string
) - 1] = '\0';
1371 tIME_chunk_present
++;
1372 #endif /* PNG_TIME_RFC1123_SUPPORTED */
1376 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
1378 png_unknown_chunkp unknowns
;
1379 int num_unknowns
= png_get_unknown_chunks(read_ptr
, end_info_ptr
,
1385 png_set_unknown_chunks(write_ptr
, write_end_info_ptr
, unknowns
,
1387 /* Copy the locations from the read_info_ptr. The automatically
1388 * generated locations in write_end_info_ptr are wrong because we
1389 * haven't written the end_info yet.
1391 for (i
= 0; i
< num_unknowns
; i
++)
1392 png_set_unknown_chunk_location(write_ptr
, write_end_info_ptr
, i
,
1393 unknowns
[i
].location
);
1397 #ifdef PNG_WRITE_SUPPORTED
1398 png_write_end(write_ptr
, write_end_info_ptr
);
1401 #ifdef PNG_EASY_ACCESS_SUPPORTED
1404 png_uint_32 iwidth
, iheight
;
1405 iwidth
= png_get_image_width(write_ptr
, write_info_ptr
);
1406 iheight
= png_get_image_height(write_ptr
, write_info_ptr
);
1407 fprintf(STDERR
, "\n Image width = %lu, height = %lu\n",
1408 (unsigned long)iwidth
, (unsigned long)iheight
);
1412 pngtest_debug("Destroying data structs");
1413 #ifdef SINGLE_ROWBUF_ALLOC
1414 pngtest_debug("destroying row_buf for read_ptr");
1415 png_free(read_ptr
, row_buf
);
1417 #endif /* SINGLE_ROWBUF_ALLOC */
1418 pngtest_debug("destroying read_ptr, read_info_ptr, end_info_ptr");
1419 png_destroy_read_struct(&read_ptr
, &read_info_ptr
, &end_info_ptr
);
1420 #ifdef PNG_WRITE_SUPPORTED
1421 pngtest_debug("destroying write_end_info_ptr");
1422 png_destroy_info_struct(write_ptr
, &write_end_info_ptr
);
1423 pngtest_debug("destroying write_ptr, write_info_ptr");
1424 png_destroy_write_struct(&write_ptr
, &write_info_ptr
);
1426 pngtest_debug("Destruction complete.");
1431 pngtest_debug("Opening files for comparison");
1432 if ((fpin
= fopen(inname
, "rb")) == NULL
)
1434 fprintf(STDERR
, "Could not find file %s\n", inname
);
1438 if ((fpout
= fopen(outname
, "rb")) == NULL
)
1440 fprintf(STDERR
, "Could not find file %s\n", outname
);
1447 png_size_t num_in
, num_out
;
1449 num_in
= fread(inbuf
, 1, 1, fpin
);
1450 num_out
= fread(outbuf
, 1, 1, fpout
);
1452 if (num_in
!= num_out
)
1454 fprintf(STDERR
, "\nFiles %s and %s are of a different size\n",
1457 if (wrote_question
== 0)
1460 " Was %s written with the same maximum IDAT chunk size (%d bytes),",
1461 inname
, PNG_ZBUF_SIZE
);
1463 "\n filtering heuristic (libpng default), compression");
1465 " level (zlib default),\n and zlib version (%s)?\n\n",
1478 if (png_memcmp(inbuf
, outbuf
, num_in
))
1480 fprintf(STDERR
, "\nFiles %s and %s are different\n", inname
, outname
);
1482 if (wrote_question
== 0)
1485 " Was %s written with the same maximum IDAT chunk size (%d bytes),",
1486 inname
, PNG_ZBUF_SIZE
);
1488 "\n filtering heuristic (libpng default), compression");
1490 " level (zlib default),\n and zlib version (%s)?\n\n",
1507 /* Input and output filenames */
1509 static PNG_CONST
char *inname
= "pngtest/png";
1510 static PNG_CONST
char *outname
= "pngout/png";
1512 static PNG_CONST
char *inname
= "pngtest.png";
1513 static PNG_CONST
char *outname
= "pngout.png";
1517 main(int argc
, char *argv
[])
1522 fprintf(STDERR
, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING
);
1523 fprintf(STDERR
, " with zlib version %s\n", ZLIB_VERSION
);
1524 fprintf(STDERR
, "%s", png_get_copyright(NULL
));
1525 /* Show the version of libpng used in building the library */
1526 fprintf(STDERR
, " library (%lu):%s",
1527 (unsigned long)png_access_version_number(),
1528 png_get_header_version(NULL
));
1530 /* Show the version of libpng used in building the application */
1531 fprintf(STDERR
, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER
,
1532 PNG_HEADER_VERSION_STRING
);
1534 /* Do some consistency checking on the memory allocation settings, I'm
1535 * not sure this matters, but it is nice to know, the first of these
1536 * tests should be impossible because of the way the macros are set
1539 #if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
1540 fprintf(STDERR
, " NOTE: Zlib compiled for max 64k, libpng not\n");
1542 /* I think the following can happen. */
1543 #if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
1544 fprintf(STDERR
, " NOTE: libpng compiled for max 64k, zlib not\n");
1547 if (strcmp(png_libpng_ver
, PNG_LIBPNG_VER_STRING
))
1550 "Warning: versions are different between png.h and png.c\n");
1551 fprintf(STDERR
, " png.h version: %s\n", PNG_LIBPNG_VER_STRING
);
1552 fprintf(STDERR
, " png.c version: %s\n\n", png_libpng_ver
);
1558 if (strcmp(argv
[1], "-m") == 0)
1561 status_dots_requested
= 0;
1564 else if (strcmp(argv
[1], "-mv") == 0 ||
1565 strcmp(argv
[1], "-vm") == 0 )
1569 status_dots_requested
= 1;
1572 else if (strcmp(argv
[1], "-v") == 0)
1575 status_dots_requested
= 1;
1582 status_dots_requested
= 0;
1586 if (!multiple
&& argc
== 3 + verbose
)
1587 outname
= argv
[2 + verbose
];
1589 if ((!multiple
&& argc
> 3 + verbose
) || (multiple
&& argc
< 2))
1592 "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
1595 " reads/writes one PNG file (without -m) or multiple files (-m)\n");
1597 " with -m %s is used as a temporary file\n", outname
);
1604 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1605 int allocation_now
= current_allocation
;
1607 for (i
=2; i
<argc
; ++i
)
1610 fprintf(STDERR
, "\n Testing %s:", argv
[i
]);
1611 kerror
= test_one_file(argv
[i
], outname
);
1614 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
1617 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
1618 fprintf(STDERR
, "\n PASS (%lu zero samples)\n",
1619 (unsigned long)zero_samples
);
1621 fprintf(STDERR
, " PASS\n");
1623 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
1624 for (k
= 0; k
<256; k
++)
1625 if (filters_used
[k
])
1626 fprintf(STDERR
, " Filter %d was used %lu times\n",
1627 k
, (unsigned long)filters_used
[k
]);
1629 #ifdef PNG_TIME_RFC1123_SUPPORTED
1630 if (tIME_chunk_present
!= 0)
1631 fprintf(STDERR
, " tIME = %s\n", tIME_string
);
1633 tIME_chunk_present
= 0;
1634 #endif /* PNG_TIME_RFC1123_SUPPORTED */
1639 fprintf(STDERR
, " FAIL\n");
1642 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1643 if (allocation_now
!= current_allocation
)
1644 fprintf(STDERR
, "MEMORY ERROR: %d bytes lost\n",
1645 current_allocation
- allocation_now
);
1647 if (current_allocation
!= 0)
1649 memory_infop pinfo
= pinformation
;
1651 fprintf(STDERR
, "MEMORY ERROR: %d bytes still allocated\n",
1652 current_allocation
);
1654 while (pinfo
!= NULL
)
1656 fprintf(STDERR
, " %lu bytes at %x\n",
1657 (unsigned long)pinfo
->size
,
1658 (unsigned int)pinfo
->pointer
);
1659 pinfo
= pinfo
->next
;
1664 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1665 fprintf(STDERR
, " Current memory allocation: %10d bytes\n",
1666 current_allocation
);
1667 fprintf(STDERR
, " Maximum memory allocation: %10d bytes\n",
1668 maximum_allocation
);
1669 fprintf(STDERR
, " Total memory allocation: %10d bytes\n",
1671 fprintf(STDERR
, " Number of allocations: %10d\n",
1679 for (i
= 0; i
<3; ++i
)
1682 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1683 int allocation_now
= current_allocation
;
1686 status_dots_requested
= 1;
1688 else if (verbose
== 0)
1689 status_dots_requested
= 0;
1691 if (i
== 0 || verbose
== 1 || ierror
!= 0)
1692 fprintf(STDERR
, "\n Testing %s:", inname
);
1694 kerror
= test_one_file(inname
, outname
);
1698 if (verbose
== 1 || i
== 2)
1700 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
1703 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
1704 fprintf(STDERR
, "\n PASS (%lu zero samples)\n",
1705 (unsigned long)zero_samples
);
1707 fprintf(STDERR
, " PASS\n");
1709 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
1710 for (k
= 0; k
<256; k
++)
1711 if (filters_used
[k
])
1712 fprintf(STDERR
, " Filter %d was used %lu times\n",
1713 k
, (unsigned long)filters_used
[k
]);
1715 #ifdef PNG_TIME_RFC1123_SUPPORTED
1716 if (tIME_chunk_present
!= 0)
1717 fprintf(STDERR
, " tIME = %s\n", tIME_string
);
1718 #endif /* PNG_TIME_RFC1123_SUPPORTED */
1724 if (verbose
== 0 && i
!= 2)
1725 fprintf(STDERR
, "\n Testing %s:", inname
);
1727 fprintf(STDERR
, " FAIL\n");
1730 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1731 if (allocation_now
!= current_allocation
)
1732 fprintf(STDERR
, "MEMORY ERROR: %d bytes lost\n",
1733 current_allocation
- allocation_now
);
1735 if (current_allocation
!= 0)
1737 memory_infop pinfo
= pinformation
;
1739 fprintf(STDERR
, "MEMORY ERROR: %d bytes still allocated\n",
1740 current_allocation
);
1742 while (pinfo
!= NULL
)
1744 fprintf(STDERR
, " %lu bytes at %x\n",
1745 (unsigned long)pinfo
->size
, (unsigned int)pinfo
->pointer
);
1746 pinfo
= pinfo
->next
;
1751 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1752 fprintf(STDERR
, " Current memory allocation: %10d bytes\n",
1753 current_allocation
);
1754 fprintf(STDERR
, " Maximum memory allocation: %10d bytes\n",
1755 maximum_allocation
);
1756 fprintf(STDERR
, " Total memory allocation: %10d bytes\n",
1758 fprintf(STDERR
, " Number of allocations: %10d\n",
1763 #ifdef PNGTEST_TIMING
1764 t_stop
= (float)clock();
1765 t_misc
+= (t_stop
- t_start
);
1767 fprintf(STDERR
, " CPU time used = %.3f seconds",
1768 (t_misc
+t_decode
+t_encode
)/(float)CLOCKS_PER_SEC
);
1769 fprintf(STDERR
, " (decoding %.3f,\n",
1770 t_decode
/(float)CLOCKS_PER_SEC
);
1771 fprintf(STDERR
, " encoding %.3f ,",
1772 t_encode
/(float)CLOCKS_PER_SEC
);
1773 fprintf(STDERR
, " other %.3f seconds)\n\n",
1774 t_misc
/(float)CLOCKS_PER_SEC
);
1778 fprintf(STDERR
, " libpng passes test\n");
1781 fprintf(STDERR
, " libpng FAILS test\n");
1783 return (int)(ierror
!= 0);
1786 /* Generate a compiler error if there is an old png.h in the search path. */
1787 typedef png_libpng_version_1_5_2 Your_png_h_is_not_version_1_5_2
;