2 /* pngtest.c - a simple test program to test libpng
4 * Last changed in libpng 1.2.32 [September 18, 2008]
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2008 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 #define PNG_tIME_STRING_LENGTH 29
86 static int tIME_chunk_present
= 0;
87 static char tIME_string
[PNG_tIME_STRING_LENGTH
] = "tIME chunk is not present";
90 static int verbose
= 0;
92 int test_one_file
PNGARG((PNG_CONST
char *inname
, PNG_CONST
char *outname
));
98 /* defined so I can write to a file on gui/windowing platforms */
99 /* #define STDERR stderr */
100 #define STDERR stdout /* for DOS */
102 /* In case a system header (e.g., on AIX) defined jmpbuf */
107 /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
109 # define png_jmpbuf(png_ptr) png_ptr->jmpbuf
112 /* example of using row callbacks to make a simple progress meter */
113 static int status_pass
= 1;
114 static int status_dots_requested
= 0;
115 static int status_dots
= 1;
121 read_row_callback(png_structp png_ptr
, png_uint_32 row_number
, int pass
);
126 read_row_callback(png_structp png_ptr
, png_uint_32 row_number
, int pass
)
128 if (png_ptr
== NULL
|| row_number
> PNG_UINT_31_MAX
) return;
129 if (status_pass
!= pass
)
131 fprintf(stdout
, "\n Pass %d: ", pass
);
136 if (status_dots
== 0)
138 fprintf(stdout
, "\n ");
141 fprintf(stdout
, "r");
148 write_row_callback(png_structp png_ptr
, png_uint_32 row_number
, int pass
);
153 write_row_callback(png_structp png_ptr
, png_uint_32 row_number
, int pass
)
155 if (png_ptr
== NULL
|| row_number
> PNG_UINT_31_MAX
|| pass
> 7) return;
156 fprintf(stdout
, "w");
160 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
161 /* Example of using user transform callback (we don't transform anything,
162 but merely examine the row filters. We set this to 256 rather than
163 5 in case illegal filter values are present.) */
164 static png_uint_32 filters_used
[256];
169 count_filters(png_structp png_ptr
, png_row_infop row_info
, png_bytep data
);
174 count_filters(png_structp png_ptr
, png_row_infop row_info
, png_bytep data
)
176 if (png_ptr
!= NULL
&& row_info
!= NULL
)
177 ++filters_used
[*(data
- 1)];
181 #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
182 /* example of using user transform callback (we don't transform anything,
183 but merely count the zero samples) */
185 static png_uint_32 zero_samples
;
191 count_zero_samples(png_structp png_ptr
, png_row_infop row_info
, png_bytep data
);
196 count_zero_samples(png_structp png_ptr
, png_row_infop row_info
, png_bytep data
)
199 if (png_ptr
== NULL
)return;
201 /* contents of row_info:
202 * png_uint_32 width width of row
203 * png_uint_32 rowbytes number of bytes in row
204 * png_byte color_type color type of pixels
205 * png_byte bit_depth bit depth of samples
206 * png_byte channels number of channels (1-4)
207 * png_byte pixel_depth bits per pixel (depth*channels)
211 /* counts the number of zero samples (or zero pixels if color_type is 3 */
213 if (row_info
->color_type
== 0 || row_info
->color_type
== 3)
216 png_uint_32 n
, nstop
;
217 for (n
= 0, nstop
=row_info
->width
; n
<nstop
; n
++)
219 if (row_info
->bit_depth
== 1)
221 if (((*dp
<< pos
++ ) & 0x80) == 0) zero_samples
++;
228 if (row_info
->bit_depth
== 2)
230 if (((*dp
<< (pos
+=2)) & 0xc0) == 0) zero_samples
++;
237 if (row_info
->bit_depth
== 4)
239 if (((*dp
<< (pos
+=4)) & 0xf0) == 0) zero_samples
++;
246 if (row_info
->bit_depth
== 8)
247 if (*dp
++ == 0) zero_samples
++;
248 if (row_info
->bit_depth
== 16)
250 if ((*dp
| *(dp
+1)) == 0) zero_samples
++;
255 else /* other color types */
257 png_uint_32 n
, nstop
;
259 int color_channels
= row_info
->channels
;
260 if (row_info
->color_type
> 3)color_channels
--;
262 for (n
= 0, nstop
=row_info
->width
; n
<nstop
; n
++)
264 for (channel
= 0; channel
< color_channels
; channel
++)
266 if (row_info
->bit_depth
== 8)
267 if (*dp
++ == 0) zero_samples
++;
268 if (row_info
->bit_depth
== 16)
270 if ((*dp
| *(dp
+1)) == 0) zero_samples
++;
274 if (row_info
->color_type
> 3)
277 if (row_info
->bit_depth
== 16)dp
++;
282 #endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
284 static int wrote_question
= 0;
286 #if defined(PNG_NO_STDIO)
287 /* START of code to validate stdio-free compilation */
288 /* These copies of the default read/write functions come from pngrio.c and */
289 /* pngwio.c. They allow "don't include stdio" testing of the library. */
290 /* This is the function that does the actual reading of data. If you are
291 not reading from a standard C stream, you should create a replacement
292 read_data function and use it at run time with png_set_read_fn(), rather
293 than changing the library. */
295 #ifndef USE_FAR_KEYWORD
297 pngtest_read_data(png_structp png_ptr
, png_bytep data
, png_size_t length
)
301 /* fread() returns 0 on error, so it is OK to store this in a png_size_t
302 * instead of an int, which is what fread() actually returns.
304 READFILE((png_FILE_p
)png_ptr
->io_ptr
, data
, length
, check
);
308 png_error(png_ptr
, "Read Error!");
312 /* this is the model-independent version. Since the standard I/O library
313 can't handle far buffers in the medium and small models, we have to copy
317 #define NEAR_BUF_SIZE 1024
318 #define MIN(a,b) (a <= b ? a : b)
321 pngtest_read_data(png_structp png_ptr
, png_bytep data
, png_size_t length
)
327 /* Check if data really is near. If so, use usual code. */
328 n_data
= (png_byte
*)CVT_PTR_NOCHECK(data
);
329 io_ptr
= (png_FILE_p
)CVT_PTR(png_ptr
->io_ptr
);
330 if ((png_bytep
)n_data
== data
)
332 READFILE(io_ptr
, n_data
, length
, check
);
336 png_byte buf
[NEAR_BUF_SIZE
];
337 png_size_t read
, remaining
, err
;
342 read
= MIN(NEAR_BUF_SIZE
, remaining
);
343 READFILE(io_ptr
, buf
, 1, err
);
344 png_memcpy(data
, buf
, read
); /* copy far buffer to near buffer */
352 while (remaining
!= 0);
356 png_error(png_ptr
, "read Error");
359 #endif /* USE_FAR_KEYWORD */
361 #if defined(PNG_WRITE_FLUSH_SUPPORTED)
363 pngtest_flush(png_structp png_ptr
)
365 #if !defined(_WIN32_WCE)
367 io_ptr
= (png_FILE_p
)CVT_PTR((png_ptr
->io_ptr
));
374 /* This is the function that does the actual writing of data. If you are
375 not writing to a standard C stream, you should create a replacement
376 write_data function and use it at run time with png_set_write_fn(), rather
377 than changing the library. */
378 #ifndef USE_FAR_KEYWORD
380 pngtest_write_data(png_structp png_ptr
, png_bytep data
, png_size_t length
)
384 WRITEFILE((png_FILE_p
)png_ptr
->io_ptr
, data
, length
, check
);
387 png_error(png_ptr
, "Write Error");
391 /* this is the model-independent version. Since the standard I/O library
392 can't handle far buffers in the medium and small models, we have to copy
396 #define NEAR_BUF_SIZE 1024
397 #define MIN(a,b) (a <= b ? a : b)
400 pngtest_write_data(png_structp png_ptr
, png_bytep data
, png_size_t length
)
403 png_byte
*near_data
; /* Needs to be "png_byte *" instead of "png_bytep" */
406 /* Check if data really is near. If so, use usual code. */
407 near_data
= (png_byte
*)CVT_PTR_NOCHECK(data
);
408 io_ptr
= (png_FILE_p
)CVT_PTR(png_ptr
->io_ptr
);
409 if ((png_bytep
)near_data
== data
)
411 WRITEFILE(io_ptr
, near_data
, length
, check
);
415 png_byte buf
[NEAR_BUF_SIZE
];
416 png_size_t written
, remaining
, err
;
421 written
= MIN(NEAR_BUF_SIZE
, remaining
);
422 png_memcpy(buf
, data
, written
); /* copy far buffer to near buffer */
423 WRITEFILE(io_ptr
, buf
, written
, err
);
429 remaining
-= written
;
431 while (remaining
!= 0);
435 png_error(png_ptr
, "Write Error");
438 #endif /* USE_FAR_KEYWORD */
440 /* This function is called when there is a warning, but the library thinks
441 * it can continue anyway. Replacement functions don't have to do anything
442 * here if you don't want to. In the default configuration, png_ptr is
443 * not used, but it is passed in case it may be useful.
446 pngtest_warning(png_structp png_ptr
, png_const_charp message
)
448 PNG_CONST
char *name
= "UNKNOWN (ERROR!)";
449 if (png_ptr
!= NULL
&& png_ptr
->error_ptr
!= NULL
)
450 name
= png_ptr
->error_ptr
;
451 fprintf(STDERR
, "%s: libpng warning: %s\n", name
, message
);
454 /* This is the default error handling function. Note that replacements for
455 * this function MUST NOT RETURN, or the program will likely crash. This
456 * function is used by default, or if the program supplies NULL for the
457 * error function pointer in png_set_error_fn().
460 pngtest_error(png_structp png_ptr
, png_const_charp message
)
462 pngtest_warning(png_ptr
, message
);
463 /* We can return because png_error calls the default handler, which is
464 * actually OK in this case. */
466 #endif /* PNG_NO_STDIO */
467 /* END of code to validate stdio-free compilation */
469 /* START of code to validate memory allocation and deallocation */
470 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
472 /* Allocate memory. For reasonable files, size should never exceed
473 64K. However, zlib may allocate more then 64K if you don't tell
474 it not to. See zconf.h and png.h for more information. zlib does
475 need to allocate exactly 64K, so whatever you call here must
476 have the ability to do that.
478 This piece of code can be compiled to validate max 64K allocations
479 by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. */
480 typedef struct memory_information
484 struct memory_information FAR
*next
;
485 } memory_information
;
486 typedef memory_information FAR
*memory_infop
;
488 static memory_infop pinformation
= NULL
;
489 static int current_allocation
= 0;
490 static int maximum_allocation
= 0;
491 static int total_allocation
= 0;
492 static int num_allocations
= 0;
494 png_voidp png_debug_malloc
PNGARG((png_structp png_ptr
, png_uint_32 size
));
495 void png_debug_free
PNGARG((png_structp png_ptr
, png_voidp ptr
));
498 png_debug_malloc(png_structp png_ptr
, png_uint_32 size
)
501 /* png_malloc has already tested for NULL; png_create_struct calls
502 png_debug_malloc directly, with png_ptr == NULL which is OK */
507 /* This calls the library allocator twice, once to get the requested
508 buffer and once to get a new free list entry. */
510 /* Disable malloc_fn and free_fn */
512 png_set_mem_fn(png_ptr
, NULL
, NULL
, NULL
);
513 pinfo
= (memory_infop
)png_malloc(png_ptr
,
514 (png_uint_32
)png_sizeof(*pinfo
));
516 current_allocation
+= size
;
517 total_allocation
+= size
;
519 if (current_allocation
> maximum_allocation
)
520 maximum_allocation
= current_allocation
;
521 pinfo
->pointer
= (png_voidp
)png_malloc(png_ptr
, size
);
522 /* Restore malloc_fn and free_fn */
523 png_set_mem_fn(png_ptr
,
524 png_voidp_NULL
, (png_malloc_ptr
)png_debug_malloc
,
525 (png_free_ptr
)png_debug_free
);
526 if (size
!= 0 && pinfo
->pointer
== NULL
)
528 current_allocation
-= size
;
529 total_allocation
-= size
;
531 "out of memory in pngtest->png_debug_malloc.");
533 pinfo
->next
= pinformation
;
534 pinformation
= pinfo
;
535 /* Make sure the caller isn't assuming zeroed memory. */
536 png_memset(pinfo
->pointer
, 0xdd, pinfo
->size
);
538 printf("png_malloc %lu bytes at %x\n", (unsigned long)size
,
540 return (png_voidp
)(pinfo
->pointer
);
544 /* Free a pointer. It is removed from the list at the same time. */
546 png_debug_free(png_structp png_ptr
, png_voidp ptr
)
549 fprintf(STDERR
, "NULL pointer to png_debug_free.\n");
552 #if 0 /* This happens all the time. */
553 fprintf(STDERR
, "WARNING: freeing NULL pointer\n");
558 /* Unlink the element from the list. */
560 memory_infop FAR
*ppinfo
= &pinformation
;
563 memory_infop pinfo
= *ppinfo
;
564 if (pinfo
->pointer
== ptr
)
566 *ppinfo
= pinfo
->next
;
567 current_allocation
-= pinfo
->size
;
568 if (current_allocation
< 0)
569 fprintf(STDERR
, "Duplicate free of memory\n");
570 /* We must free the list element too, but first kill
571 the memory that is to be freed. */
572 png_memset(ptr
, 0x55, pinfo
->size
);
573 png_free_default(png_ptr
, pinfo
);
577 if (pinfo
->next
== NULL
)
579 fprintf(STDERR
, "Pointer %x not found\n", (unsigned int)ptr
);
582 ppinfo
= &pinfo
->next
;
586 /* Finally free the data. */
588 printf("Freeing %x\n", ptr
);
589 png_free_default(png_ptr
, ptr
);
592 #endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */
593 /* END of code to test memory allocation/deallocation */
596 /* Demonstration of user chunk support of the sTER and vpAg chunks */
597 #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
599 /* (sTER is a public chunk not yet understood by libpng. vpAg is a private
600 chunk used in ImageMagick to store "virtual page" size). */
602 static png_uint_32 user_chunk_data
[4];
610 static int read_user_chunk_callback(png_struct
*png_ptr
,
611 png_unknown_chunkp chunk
)
616 /* Return one of the following: */
617 /* return (-n); chunk had an error */
618 /* return (0); did not recognize */
619 /* return (n); success */
621 /* The unknown chunk structure contains the chunk data:
626 * Note that libpng has already taken care of the CRC handling.
629 if (chunk
->name
[0] == 115 && chunk
->name
[1] == 84 && /* s T */
630 chunk
->name
[2] == 69 && chunk
->name
[3] == 82) /* E R */
632 /* Found sTER chunk */
633 if (chunk
->size
!= 1)
634 return (-1); /* Error return */
635 if (chunk
->data
[0] != 0 && chunk
->data
[0] != 1)
636 return (-1); /* Invalid mode */
637 user_chunk_data
=(png_uint_32
*) png_get_user_chunk_ptr(png_ptr
);
638 user_chunk_data
[0]=chunk
->data
[0]+1;
641 if (chunk
->name
[0] != 118 || chunk
->name
[1] != 112 || /* v p */
642 chunk
->name
[2] != 65 || chunk
->name
[3] != 103) /* A g */
643 return (0); /* Did not recognize */
645 /* Found ImageMagick vpAg chunk */
647 if (chunk
->size
!= 9)
648 return (-1); /* Error return */
650 user_chunk_data
=(png_uint_32
*) png_get_user_chunk_ptr(png_ptr
);
652 user_chunk_data
[1]=png_get_uint_31(png_ptr
, chunk
->data
);
653 user_chunk_data
[2]=png_get_uint_31(png_ptr
, chunk
->data
+ 4);
654 user_chunk_data
[3]=(png_uint_32
)chunk
->data
[8];
660 /* END of code to demonstrate user chunk support */
664 test_one_file(PNG_CONST
char *inname
, PNG_CONST
char *outname
)
666 static png_FILE_p fpin
;
667 static png_FILE_p fpout
; /* "static" prevents setjmp corruption */
668 png_structp read_ptr
;
669 png_infop read_info_ptr
, end_info_ptr
;
670 #ifdef PNG_WRITE_SUPPORTED
671 png_structp write_ptr
;
672 png_infop write_info_ptr
;
673 png_infop write_end_info_ptr
;
675 png_structp write_ptr
= NULL
;
676 png_infop write_info_ptr
= NULL
;
677 png_infop write_end_info_ptr
= NULL
;
681 png_uint_32 width
, height
;
683 int bit_depth
, color_type
;
684 #ifdef PNG_SETJMP_SUPPORTED
685 #ifdef USE_FAR_KEYWORD
690 #if defined(_WIN32_WCE)
691 TCHAR path
[MAX_PATH
];
693 char inbuf
[256], outbuf
[256];
697 #if defined(_WIN32_WCE)
698 MultiByteToWideChar(CP_ACP
, 0, inname
, -1, path
, MAX_PATH
);
699 if ((fpin
= CreateFile(path
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, NULL
)) == INVALID_HANDLE_VALUE
)
701 if ((fpin
= fopen(inname
, "rb")) == NULL
)
704 fprintf(STDERR
, "Could not find input file %s\n", inname
);
708 #if defined(_WIN32_WCE)
709 MultiByteToWideChar(CP_ACP
, 0, outname
, -1, path
, MAX_PATH
);
710 if ((fpout
= CreateFile(path
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
)) == INVALID_HANDLE_VALUE
)
712 if ((fpout
= fopen(outname
, "wb")) == NULL
)
715 fprintf(STDERR
, "Could not open output file %s\n", outname
);
720 png_debug(0, "Allocating read and write structures");
721 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
723 png_create_read_struct_2(PNG_LIBPNG_VER_STRING
, png_voidp_NULL
,
724 png_error_ptr_NULL
, png_error_ptr_NULL
, png_voidp_NULL
,
725 (png_malloc_ptr
)png_debug_malloc
, (png_free_ptr
)png_debug_free
);
728 png_create_read_struct(PNG_LIBPNG_VER_STRING
, png_voidp_NULL
,
729 png_error_ptr_NULL
, png_error_ptr_NULL
);
731 #if defined(PNG_NO_STDIO)
732 png_set_error_fn(read_ptr
, (png_voidp
)inname
, pngtest_error
,
736 #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
737 user_chunk_data
[0] = 0;
738 user_chunk_data
[1] = 0;
739 user_chunk_data
[2] = 0;
740 user_chunk_data
[3] = 0;
741 png_set_read_user_chunk_fn(read_ptr
, user_chunk_data
,
742 read_user_chunk_callback
);
745 #ifdef PNG_WRITE_SUPPORTED
746 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
748 png_create_write_struct_2(PNG_LIBPNG_VER_STRING
, png_voidp_NULL
,
749 png_error_ptr_NULL
, png_error_ptr_NULL
, png_voidp_NULL
,
750 (png_malloc_ptr
)png_debug_malloc
, (png_free_ptr
)png_debug_free
);
753 png_create_write_struct(PNG_LIBPNG_VER_STRING
, png_voidp_NULL
,
754 png_error_ptr_NULL
, png_error_ptr_NULL
);
756 #if defined(PNG_NO_STDIO)
757 png_set_error_fn(write_ptr
, (png_voidp
)inname
, pngtest_error
,
761 png_debug(0, "Allocating read_info, write_info and end_info structures");
762 read_info_ptr
= png_create_info_struct(read_ptr
);
763 end_info_ptr
= png_create_info_struct(read_ptr
);
764 #ifdef PNG_WRITE_SUPPORTED
765 write_info_ptr
= png_create_info_struct(write_ptr
);
766 write_end_info_ptr
= png_create_info_struct(write_ptr
);
769 #ifdef PNG_SETJMP_SUPPORTED
770 png_debug(0, "Setting jmpbuf for read struct");
771 #ifdef USE_FAR_KEYWORD
774 if (setjmp(png_jmpbuf(read_ptr
)))
777 fprintf(STDERR
, "%s -> %s: libpng read error\n", inname
, outname
);
778 png_free(read_ptr
, row_buf
);
780 png_destroy_read_struct(&read_ptr
, &read_info_ptr
, &end_info_ptr
);
781 #ifdef PNG_WRITE_SUPPORTED
782 png_destroy_info_struct(write_ptr
, &write_end_info_ptr
);
783 png_destroy_write_struct(&write_ptr
, &write_info_ptr
);
789 #ifdef USE_FAR_KEYWORD
790 png_memcpy(png_jmpbuf(read_ptr
), jmpbuf
, png_sizeof(jmp_buf));
793 #ifdef PNG_WRITE_SUPPORTED
794 png_debug(0, "Setting jmpbuf for write struct");
795 #ifdef USE_FAR_KEYWORD
798 if (setjmp(png_jmpbuf(write_ptr
)))
801 fprintf(STDERR
, "%s -> %s: libpng write error\n", inname
, outname
);
802 png_destroy_read_struct(&read_ptr
, &read_info_ptr
, &end_info_ptr
);
803 png_destroy_info_struct(write_ptr
, &write_end_info_ptr
);
804 #ifdef PNG_WRITE_SUPPORTED
805 png_destroy_write_struct(&write_ptr
, &write_info_ptr
);
811 #ifdef USE_FAR_KEYWORD
812 png_memcpy(png_jmpbuf(write_ptr
), jmpbuf
, png_sizeof(jmp_buf));
817 png_debug(0, "Initializing input and output streams");
818 #if !defined(PNG_NO_STDIO)
819 png_init_io(read_ptr
, fpin
);
820 # ifdef PNG_WRITE_SUPPORTED
821 png_init_io(write_ptr
, fpout
);
824 png_set_read_fn(read_ptr
, (png_voidp
)fpin
, pngtest_read_data
);
825 # ifdef PNG_WRITE_SUPPORTED
826 png_set_write_fn(write_ptr
, (png_voidp
)fpout
, pngtest_write_data
,
827 # if defined(PNG_WRITE_FLUSH_SUPPORTED)
834 if (status_dots_requested
== 1)
836 #ifdef PNG_WRITE_SUPPORTED
837 png_set_write_status_fn(write_ptr
, write_row_callback
);
839 png_set_read_status_fn(read_ptr
, read_row_callback
);
843 #ifdef PNG_WRITE_SUPPORTED
844 png_set_write_status_fn(write_ptr
, png_write_status_ptr_NULL
);
846 png_set_read_status_fn(read_ptr
, png_read_status_ptr_NULL
);
849 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
852 for (i
= 0; i
<256; i
++)
854 png_set_read_user_transform_fn(read_ptr
, count_filters
);
857 #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
859 png_set_write_user_transform_fn(write_ptr
, count_zero_samples
);
862 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
863 # ifndef PNG_HANDLE_CHUNK_ALWAYS
864 # define PNG_HANDLE_CHUNK_ALWAYS 3
866 png_set_keep_unknown_chunks(read_ptr
, PNG_HANDLE_CHUNK_ALWAYS
,
869 #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
870 # ifndef PNG_HANDLE_CHUNK_IF_SAFE
871 # define PNG_HANDLE_CHUNK_IF_SAFE 2
873 png_set_keep_unknown_chunks(write_ptr
, PNG_HANDLE_CHUNK_IF_SAFE
,
877 png_debug(0, "Reading info struct");
878 png_read_info(read_ptr
, read_info_ptr
);
880 png_debug(0, "Transferring info struct");
882 int interlace_type
, compression_type
, filter_type
;
884 if (png_get_IHDR(read_ptr
, read_info_ptr
, &width
, &height
, &bit_depth
,
885 &color_type
, &interlace_type
, &compression_type
, &filter_type
))
887 png_set_IHDR(write_ptr
, write_info_ptr
, width
, height
, bit_depth
,
888 #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
889 color_type
, interlace_type
, compression_type
, filter_type
);
891 color_type
, PNG_INTERLACE_NONE
, compression_type
, filter_type
);
895 #if defined(PNG_FIXED_POINT_SUPPORTED)
896 #if defined(PNG_cHRM_SUPPORTED)
898 png_fixed_point white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
,
900 if (png_get_cHRM_fixed(read_ptr
, read_info_ptr
, &white_x
, &white_y
, &red_x
,
901 &red_y
, &green_x
, &green_y
, &blue_x
, &blue_y
))
903 png_set_cHRM_fixed(write_ptr
, write_info_ptr
, white_x
, white_y
, red_x
,
904 red_y
, green_x
, green_y
, blue_x
, blue_y
);
908 #if defined(PNG_gAMA_SUPPORTED)
910 png_fixed_point gamma
;
912 if (png_get_gAMA_fixed(read_ptr
, read_info_ptr
, &gamma
))
914 png_set_gAMA_fixed(write_ptr
, write_info_ptr
, gamma
);
918 #else /* Use floating point versions */
919 #if defined(PNG_FLOATING_POINT_SUPPORTED)
920 #if defined(PNG_cHRM_SUPPORTED)
922 double white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
,
924 if (png_get_cHRM(read_ptr
, read_info_ptr
, &white_x
, &white_y
, &red_x
,
925 &red_y
, &green_x
, &green_y
, &blue_x
, &blue_y
))
927 png_set_cHRM(write_ptr
, write_info_ptr
, white_x
, white_y
, red_x
,
928 red_y
, green_x
, green_y
, blue_x
, blue_y
);
932 #if defined(PNG_gAMA_SUPPORTED)
936 if (png_get_gAMA(read_ptr
, read_info_ptr
, &gamma
))
938 png_set_gAMA(write_ptr
, write_info_ptr
, gamma
);
942 #endif /* floating point */
943 #endif /* fixed point */
944 #if defined(PNG_iCCP_SUPPORTED)
949 int compression_type
;
951 if (png_get_iCCP(read_ptr
, read_info_ptr
, &name
, &compression_type
,
954 png_set_iCCP(write_ptr
, write_info_ptr
, name
, compression_type
,
959 #if defined(PNG_sRGB_SUPPORTED)
963 if (png_get_sRGB(read_ptr
, read_info_ptr
, &intent
))
965 png_set_sRGB(write_ptr
, write_info_ptr
, intent
);
973 if (png_get_PLTE(read_ptr
, read_info_ptr
, &palette
, &num_palette
))
975 png_set_PLTE(write_ptr
, write_info_ptr
, palette
, num_palette
);
978 #if defined(PNG_bKGD_SUPPORTED)
980 png_color_16p background
;
982 if (png_get_bKGD(read_ptr
, read_info_ptr
, &background
))
984 png_set_bKGD(write_ptr
, write_info_ptr
, background
);
988 #if defined(PNG_hIST_SUPPORTED)
992 if (png_get_hIST(read_ptr
, read_info_ptr
, &hist
))
994 png_set_hIST(write_ptr
, write_info_ptr
, hist
);
998 #if defined(PNG_oFFs_SUPPORTED)
1000 png_int_32 offset_x
, offset_y
;
1003 if (png_get_oFFs(read_ptr
, read_info_ptr
, &offset_x
, &offset_y
,
1006 png_set_oFFs(write_ptr
, write_info_ptr
, offset_x
, offset_y
, unit_type
);
1010 #if defined(PNG_pCAL_SUPPORTED)
1012 png_charp purpose
, units
;
1017 if (png_get_pCAL(read_ptr
, read_info_ptr
, &purpose
, &X0
, &X1
, &type
,
1018 &nparams
, &units
, ¶ms
))
1020 png_set_pCAL(write_ptr
, write_info_ptr
, purpose
, X0
, X1
, type
,
1021 nparams
, units
, params
);
1025 #if defined(PNG_pHYs_SUPPORTED)
1027 png_uint_32 res_x
, res_y
;
1030 if (png_get_pHYs(read_ptr
, read_info_ptr
, &res_x
, &res_y
, &unit_type
))
1032 png_set_pHYs(write_ptr
, write_info_ptr
, res_x
, res_y
, unit_type
);
1036 #if defined(PNG_sBIT_SUPPORTED)
1038 png_color_8p sig_bit
;
1040 if (png_get_sBIT(read_ptr
, read_info_ptr
, &sig_bit
))
1042 png_set_sBIT(write_ptr
, write_info_ptr
, sig_bit
);
1046 #if defined(PNG_sCAL_SUPPORTED)
1047 #ifdef PNG_FLOATING_POINT_SUPPORTED
1050 double scal_width
, scal_height
;
1052 if (png_get_sCAL(read_ptr
, read_info_ptr
, &unit
, &scal_width
,
1055 png_set_sCAL(write_ptr
, write_info_ptr
, unit
, scal_width
, scal_height
);
1059 #ifdef PNG_FIXED_POINT_SUPPORTED
1062 png_charp scal_width
, scal_height
;
1064 if (png_get_sCAL_s(read_ptr
, read_info_ptr
, &unit
, &scal_width
,
1067 png_set_sCAL_s(write_ptr
, write_info_ptr
, unit
, scal_width
, scal_height
);
1073 #if defined(PNG_TEXT_SUPPORTED)
1078 if (png_get_text(read_ptr
, read_info_ptr
, &text_ptr
, &num_text
) > 0)
1080 png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks", num_text
);
1081 png_set_text(write_ptr
, write_info_ptr
, text_ptr
, num_text
);
1085 #if defined(PNG_tIME_SUPPORTED)
1089 if (png_get_tIME(read_ptr
, read_info_ptr
, &mod_time
))
1091 png_set_tIME(write_ptr
, write_info_ptr
, mod_time
);
1092 #if defined(PNG_TIME_RFC1123_SUPPORTED)
1093 /* we have to use png_memcpy instead of "=" because the string
1094 pointed to by png_convert_to_rfc1123() gets free'ed before
1096 png_memcpy(tIME_string
,
1097 png_convert_to_rfc1123(read_ptr
, mod_time
),
1098 png_sizeof(tIME_string
));
1099 tIME_string
[png_sizeof(tIME_string
) - 1] = '\0';
1100 tIME_chunk_present
++;
1101 #endif /* PNG_TIME_RFC1123_SUPPORTED */
1105 #if defined(PNG_tRNS_SUPPORTED)
1109 png_color_16p trans_values
;
1111 if (png_get_tRNS(read_ptr
, read_info_ptr
, &trans
, &num_trans
,
1114 int sample_max
= (1 << read_info_ptr
->bit_depth
);
1115 /* libpng doesn't reject a tRNS chunk with out-of-range samples */
1116 if (!((read_info_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
&&
1117 (int)trans_values
->gray
> sample_max
) ||
1118 (read_info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
&&
1119 ((int)trans_values
->red
> sample_max
||
1120 (int)trans_values
->green
> sample_max
||
1121 (int)trans_values
->blue
> sample_max
))))
1122 png_set_tRNS(write_ptr
, write_info_ptr
, trans
, num_trans
,
1127 #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1129 png_unknown_chunkp unknowns
;
1130 int num_unknowns
= (int)png_get_unknown_chunks(read_ptr
, read_info_ptr
,
1135 png_set_unknown_chunks(write_ptr
, write_info_ptr
, unknowns
,
1137 /* copy the locations from the read_info_ptr. The automatically
1138 generated locations in write_info_ptr are wrong because we
1139 haven't written anything yet */
1140 for (i
= 0; i
< (png_size_t
)num_unknowns
; i
++)
1141 png_set_unknown_chunk_location(write_ptr
, write_info_ptr
, i
,
1142 unknowns
[i
].location
);
1147 #ifdef PNG_WRITE_SUPPORTED
1148 png_debug(0, "Writing info struct");
1150 /* If we wanted, we could write info in two steps:
1151 png_write_info_before_PLTE(write_ptr, write_info_ptr);
1153 png_write_info(write_ptr
, write_info_ptr
);
1155 #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
1156 if (user_chunk_data
[0] != 0)
1158 png_byte png_sTER
[5] = {115, 84, 69, 82, '\0'};
1164 fprintf(STDERR
, "stereo mode = %lu\n",
1165 (unsigned long)(user_chunk_data
[0] - 1));
1166 ster_chunk_data
[0]=(unsigned char)(user_chunk_data
[0] - 1);
1167 png_write_chunk(write_ptr
, png_sTER
, ster_chunk_data
, 1);
1169 if (user_chunk_data
[1] != 0 || user_chunk_data
[2] != 0)
1171 png_byte png_vpAg
[5] = {118, 112, 65, 103, '\0'};
1177 fprintf(STDERR
, "vpAg = %lu x %lu, units=%lu\n",
1178 (unsigned long)user_chunk_data
[1],
1179 (unsigned long)user_chunk_data
[2],
1180 (unsigned long)user_chunk_data
[3]);
1181 png_save_uint_32(vpag_chunk_data
, user_chunk_data
[1]);
1182 png_save_uint_32(vpag_chunk_data
+ 4, user_chunk_data
[2]);
1183 vpag_chunk_data
[8] = (unsigned char)(user_chunk_data
[3] & 0xff);
1184 png_write_chunk(write_ptr
, png_vpAg
, vpag_chunk_data
, 9);
1190 #ifdef SINGLE_ROWBUF_ALLOC
1191 png_debug(0, "Allocating row buffer...");
1192 row_buf
= (png_bytep
)png_malloc(read_ptr
,
1193 png_get_rowbytes(read_ptr
, read_info_ptr
));
1194 png_debug1(0, "0x%08lx", (unsigned long)row_buf
);
1195 #endif /* SINGLE_ROWBUF_ALLOC */
1196 png_debug(0, "Writing row data");
1198 #if defined(PNG_READ_INTERLACING_SUPPORTED) || \
1199 defined(PNG_WRITE_INTERLACING_SUPPORTED)
1200 num_pass
= png_set_interlace_handling(read_ptr
);
1201 # ifdef PNG_WRITE_SUPPORTED
1202 png_set_interlace_handling(write_ptr
);
1208 #ifdef PNGTEST_TIMING
1209 t_stop
= (float)clock();
1210 t_misc
+= (t_stop
- t_start
);
1213 for (pass
= 0; pass
< num_pass
; pass
++)
1215 png_debug1(0, "Writing row data for pass %d", pass
);
1216 for (y
= 0; y
< height
; y
++)
1218 #ifndef SINGLE_ROWBUF_ALLOC
1219 png_debug2(0, "\nAllocating row buffer (pass %d, y = %ld)...", pass
, y
);
1220 row_buf
= (png_bytep
)png_malloc(read_ptr
,
1221 png_get_rowbytes(read_ptr
, read_info_ptr
));
1222 png_debug2(0, "0x%08lx (%ld bytes)", (unsigned long)row_buf
,
1223 png_get_rowbytes(read_ptr
, read_info_ptr
));
1224 #endif /* !SINGLE_ROWBUF_ALLOC */
1225 png_read_rows(read_ptr
, (png_bytepp
)&row_buf
, png_bytepp_NULL
, 1);
1227 #ifdef PNG_WRITE_SUPPORTED
1228 #ifdef PNGTEST_TIMING
1229 t_stop
= (float)clock();
1230 t_decode
+= (t_stop
- t_start
);
1233 png_write_rows(write_ptr
, (png_bytepp
)&row_buf
, 1);
1234 #ifdef PNGTEST_TIMING
1235 t_stop
= (float)clock();
1236 t_encode
+= (t_stop
- t_start
);
1239 #endif /* PNG_WRITE_SUPPORTED */
1241 #ifndef SINGLE_ROWBUF_ALLOC
1242 png_debug2(0, "Freeing row buffer (pass %d, y = %ld)", pass
, y
);
1243 png_free(read_ptr
, row_buf
);
1245 #endif /* !SINGLE_ROWBUF_ALLOC */
1249 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
1250 png_free_data(read_ptr
, read_info_ptr
, PNG_FREE_UNKN
, -1);
1252 #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1253 png_free_data(write_ptr
, write_info_ptr
, PNG_FREE_UNKN
, -1);
1256 png_debug(0, "Reading and writing end_info data");
1258 png_read_end(read_ptr
, end_info_ptr
);
1259 #if defined(PNG_TEXT_SUPPORTED)
1264 if (png_get_text(read_ptr
, end_info_ptr
, &text_ptr
, &num_text
) > 0)
1266 png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks", num_text
);
1267 png_set_text(write_ptr
, write_end_info_ptr
, text_ptr
, num_text
);
1271 #if defined(PNG_tIME_SUPPORTED)
1275 if (png_get_tIME(read_ptr
, end_info_ptr
, &mod_time
))
1277 png_set_tIME(write_ptr
, write_end_info_ptr
, mod_time
);
1278 #if defined(PNG_TIME_RFC1123_SUPPORTED)
1279 /* we have to use png_memcpy instead of "=" because the string
1280 pointed to by png_convert_to_rfc1123() gets free'ed before
1282 png_memcpy(tIME_string
,
1283 png_convert_to_rfc1123(read_ptr
, mod_time
),
1284 png_sizeof(tIME_string
));
1285 tIME_string
[png_sizeof(tIME_string
) - 1] = '\0';
1286 tIME_chunk_present
++;
1287 #endif /* PNG_TIME_RFC1123_SUPPORTED */
1291 #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1293 png_unknown_chunkp unknowns
;
1295 num_unknowns
= (int)png_get_unknown_chunks(read_ptr
, end_info_ptr
,
1300 png_set_unknown_chunks(write_ptr
, write_end_info_ptr
, unknowns
,
1302 /* copy the locations from the read_info_ptr. The automatically
1303 generated locations in write_end_info_ptr are wrong because we
1304 haven't written the end_info yet */
1305 for (i
= 0; i
< (png_size_t
)num_unknowns
; i
++)
1306 png_set_unknown_chunk_location(write_ptr
, write_end_info_ptr
, i
,
1307 unknowns
[i
].location
);
1311 #ifdef PNG_WRITE_SUPPORTED
1312 png_write_end(write_ptr
, write_end_info_ptr
);
1315 #ifdef PNG_EASY_ACCESS_SUPPORTED
1318 png_uint_32 iwidth
, iheight
;
1319 iwidth
= png_get_image_width(write_ptr
, write_info_ptr
);
1320 iheight
= png_get_image_height(write_ptr
, write_info_ptr
);
1321 fprintf(STDERR
, "Image width = %lu, height = %lu\n",
1322 (unsigned long)iwidth
, (unsigned long)iheight
);
1326 png_debug(0, "Destroying data structs");
1327 #ifdef SINGLE_ROWBUF_ALLOC
1328 png_debug(1, "destroying row_buf for read_ptr");
1329 png_free(read_ptr
, row_buf
);
1331 #endif /* SINGLE_ROWBUF_ALLOC */
1332 png_debug(1, "destroying read_ptr, read_info_ptr, end_info_ptr");
1333 png_destroy_read_struct(&read_ptr
, &read_info_ptr
, &end_info_ptr
);
1334 #ifdef PNG_WRITE_SUPPORTED
1335 png_debug(1, "destroying write_end_info_ptr");
1336 png_destroy_info_struct(write_ptr
, &write_end_info_ptr
);
1337 png_debug(1, "destroying write_ptr, write_info_ptr");
1338 png_destroy_write_struct(&write_ptr
, &write_info_ptr
);
1340 png_debug(0, "Destruction complete.");
1345 png_debug(0, "Opening files for comparison");
1346 #if defined(_WIN32_WCE)
1347 MultiByteToWideChar(CP_ACP
, 0, inname
, -1, path
, MAX_PATH
);
1348 if ((fpin
= CreateFile(path
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, NULL
)) == INVALID_HANDLE_VALUE
)
1350 if ((fpin
= fopen(inname
, "rb")) == NULL
)
1353 fprintf(STDERR
, "Could not find file %s\n", inname
);
1357 #if defined(_WIN32_WCE)
1358 MultiByteToWideChar(CP_ACP
, 0, outname
, -1, path
, MAX_PATH
);
1359 if ((fpout
= CreateFile(path
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, NULL
)) == INVALID_HANDLE_VALUE
)
1361 if ((fpout
= fopen(outname
, "rb")) == NULL
)
1364 fprintf(STDERR
, "Could not find file %s\n", outname
);
1371 png_size_t num_in
, num_out
;
1373 READFILE(fpin
, inbuf
, 1, num_in
);
1374 READFILE(fpout
, outbuf
, 1, num_out
);
1376 if (num_in
!= num_out
)
1378 fprintf(STDERR
, "\nFiles %s and %s are of a different size\n",
1380 if (wrote_question
== 0)
1383 " Was %s written with the same maximum IDAT chunk size (%d bytes),",
1384 inname
, PNG_ZBUF_SIZE
);
1386 "\n filtering heuristic (libpng default), compression");
1388 " level (zlib default),\n and zlib version (%s)?\n\n",
1400 if (png_memcmp(inbuf
, outbuf
, num_in
))
1402 fprintf(STDERR
, "\nFiles %s and %s are different\n", inname
, outname
);
1403 if (wrote_question
== 0)
1406 " Was %s written with the same maximum IDAT chunk size (%d bytes),",
1407 inname
, PNG_ZBUF_SIZE
);
1409 "\n filtering heuristic (libpng default), compression");
1411 " level (zlib default),\n and zlib version (%s)?\n\n",
1427 /* input and output filenames */
1429 static PNG_CONST
char *inname
= "pngtest/png";
1430 static PNG_CONST
char *outname
= "pngout/png";
1432 static PNG_CONST
char *inname
= "pngtest.png";
1433 static PNG_CONST
char *outname
= "pngout.png";
1437 main(int argc
, char *argv
[])
1442 fprintf(STDERR
, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING
);
1443 fprintf(STDERR
, " with zlib version %s\n", ZLIB_VERSION
);
1444 fprintf(STDERR
, "%s", png_get_copyright(NULL
));
1445 /* Show the version of libpng used in building the library */
1446 fprintf(STDERR
, " library (%lu):%s",
1447 (unsigned long)png_access_version_number(),
1448 png_get_header_version(NULL
));
1449 /* Show the version of libpng used in building the application */
1450 fprintf(STDERR
, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER
,
1451 PNG_HEADER_VERSION_STRING
);
1452 fprintf(STDERR
, " sizeof(png_struct)=%ld, sizeof(png_info)=%ld\n",
1453 (long)png_sizeof(png_struct
), (long)png_sizeof(png_info
));
1455 /* Do some consistency checking on the memory allocation settings, I'm
1456 not sure this matters, but it is nice to know, the first of these
1457 tests should be impossible because of the way the macros are set
1459 #if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
1460 fprintf(STDERR
, " NOTE: Zlib compiled for max 64k, libpng not\n");
1462 /* I think the following can happen. */
1463 #if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
1464 fprintf(STDERR
, " NOTE: libpng compiled for max 64k, zlib not\n");
1467 if (strcmp(png_libpng_ver
, PNG_LIBPNG_VER_STRING
))
1470 "Warning: versions are different between png.h and png.c\n");
1471 fprintf(STDERR
, " png.h version: %s\n", PNG_LIBPNG_VER_STRING
);
1472 fprintf(STDERR
, " png.c version: %s\n\n", png_libpng_ver
);
1478 if (strcmp(argv
[1], "-m") == 0)
1481 status_dots_requested
= 0;
1483 else if (strcmp(argv
[1], "-mv") == 0 ||
1484 strcmp(argv
[1], "-vm") == 0 )
1488 status_dots_requested
= 1;
1490 else if (strcmp(argv
[1], "-v") == 0)
1493 status_dots_requested
= 1;
1499 status_dots_requested
= 0;
1503 if (!multiple
&& argc
== 3 + verbose
)
1504 outname
= argv
[2 + verbose
];
1506 if ((!multiple
&& argc
> 3 + verbose
) || (multiple
&& argc
< 2))
1509 "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
1512 " reads/writes one PNG file (without -m) or multiple files (-m)\n");
1514 " with -m %s is used as a temporary file\n", outname
);
1521 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1522 int allocation_now
= current_allocation
;
1524 for (i
=2; i
<argc
; ++i
)
1526 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1530 fprintf(STDERR
, "Testing %s:", argv
[i
]);
1531 kerror
= test_one_file(argv
[i
], outname
);
1534 #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
1535 fprintf(STDERR
, "\n PASS (%lu zero samples)\n",
1536 (unsigned long)zero_samples
);
1538 fprintf(STDERR
, " PASS\n");
1540 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1541 for (k
= 0; k
<256; k
++)
1542 if (filters_used
[k
])
1543 fprintf(STDERR
, " Filter %d was used %lu times\n",
1544 k
, (unsigned long)filters_used
[k
]);
1546 #if defined(PNG_TIME_RFC1123_SUPPORTED)
1547 if (tIME_chunk_present
!= 0)
1548 fprintf(STDERR
, " tIME = %s\n", tIME_string
);
1549 tIME_chunk_present
= 0;
1550 #endif /* PNG_TIME_RFC1123_SUPPORTED */
1554 fprintf(STDERR
, " FAIL\n");
1557 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1558 if (allocation_now
!= current_allocation
)
1559 fprintf(STDERR
, "MEMORY ERROR: %d bytes lost\n",
1560 current_allocation
- allocation_now
);
1561 if (current_allocation
!= 0)
1563 memory_infop pinfo
= pinformation
;
1565 fprintf(STDERR
, "MEMORY ERROR: %d bytes still allocated\n",
1566 current_allocation
);
1567 while (pinfo
!= NULL
)
1569 fprintf(STDERR
, " %lu bytes at %x\n",
1570 (unsigned long)pinfo
->size
,
1571 (unsigned int) pinfo
->pointer
);
1572 pinfo
= pinfo
->next
;
1577 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1578 fprintf(STDERR
, " Current memory allocation: %10d bytes\n",
1579 current_allocation
);
1580 fprintf(STDERR
, " Maximum memory allocation: %10d bytes\n",
1581 maximum_allocation
);
1582 fprintf(STDERR
, " Total memory allocation: %10d bytes\n",
1584 fprintf(STDERR
, " Number of allocations: %10d\n",
1591 for (i
= 0; i
<3; ++i
)
1594 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1595 int allocation_now
= current_allocation
;
1597 if (i
== 1) status_dots_requested
= 1;
1598 else if (verbose
== 0)status_dots_requested
= 0;
1599 if (i
== 0 || verbose
== 1 || ierror
!= 0)
1600 fprintf(STDERR
, "Testing %s:", inname
);
1601 kerror
= test_one_file(inname
, outname
);
1604 if (verbose
== 1 || i
== 2)
1606 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1609 #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
1610 fprintf(STDERR
, "\n PASS (%lu zero samples)\n",
1611 (unsigned long)zero_samples
);
1613 fprintf(STDERR
, " PASS\n");
1615 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1616 for (k
= 0; k
<256; k
++)
1617 if (filters_used
[k
])
1618 fprintf(STDERR
, " Filter %d was used %lu times\n",
1620 (unsigned long)filters_used
[k
]);
1622 #if defined(PNG_TIME_RFC1123_SUPPORTED)
1623 if (tIME_chunk_present
!= 0)
1624 fprintf(STDERR
, " tIME = %s\n", tIME_string
);
1625 #endif /* PNG_TIME_RFC1123_SUPPORTED */
1630 if (verbose
== 0 && i
!= 2)
1631 fprintf(STDERR
, "Testing %s:", inname
);
1632 fprintf(STDERR
, " FAIL\n");
1635 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1636 if (allocation_now
!= current_allocation
)
1637 fprintf(STDERR
, "MEMORY ERROR: %d bytes lost\n",
1638 current_allocation
- allocation_now
);
1639 if (current_allocation
!= 0)
1641 memory_infop pinfo
= pinformation
;
1643 fprintf(STDERR
, "MEMORY ERROR: %d bytes still allocated\n",
1644 current_allocation
);
1645 while (pinfo
!= NULL
)
1647 fprintf(STDERR
, " %lu bytes at %x\n",
1648 (unsigned long)pinfo
->size
, (unsigned int)pinfo
->pointer
);
1649 pinfo
= pinfo
->next
;
1654 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1655 fprintf(STDERR
, " Current memory allocation: %10d bytes\n",
1656 current_allocation
);
1657 fprintf(STDERR
, " Maximum memory allocation: %10d bytes\n",
1658 maximum_allocation
);
1659 fprintf(STDERR
, " Total memory allocation: %10d bytes\n",
1661 fprintf(STDERR
, " Number of allocations: %10d\n",
1666 #ifdef PNGTEST_TIMING
1667 t_stop
= (float)clock();
1668 t_misc
+= (t_stop
- t_start
);
1670 fprintf(STDERR
, " CPU time used = %.3f seconds",
1671 (t_misc
+t_decode
+t_encode
)/(float)CLOCKS_PER_SEC
);
1672 fprintf(STDERR
, " (decoding %.3f,\n",
1673 t_decode
/(float)CLOCKS_PER_SEC
);
1674 fprintf(STDERR
, " encoding %.3f ,",
1675 t_encode
/(float)CLOCKS_PER_SEC
);
1676 fprintf(STDERR
, " other %.3f seconds)\n\n",
1677 t_misc
/(float)CLOCKS_PER_SEC
);
1681 fprintf(STDERR
, "libpng passes test\n");
1683 fprintf(STDERR
, "libpng FAILS test\n");
1684 return (int)(ierror
!= 0);
1687 /* Generate a compiler error if there is an old png.h in the search path. */
1688 typedef version_1_2_34 your_png_h_is_not_version_1_2_34
;