VirtualBox

source: vbox/trunk/src/libs/libpng-1.6.45/pngtest.c@ 107935

Last change on this file since 107935 was 107813, checked in by vboxsync, 3 weeks ago

libpng-1.6.45: Applied and adjusted our libpng changes to 1.6.45. bugref:8515

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette