blob: f5e098fb7b6b224d5e1202634a78a8d0e2a59e24 [file] [log] [blame]
The Android Open Source Project893912b2009-03-03 19:30:05 -08001
2/* pngtest.c - a simple test program to test libpng
3 *
The Android Open Source Project4215dd12009-03-09 11:52:12 -07004 * Last changed in libpng 1.2.32 [September 18, 2008]
The Android Open Source Project893912b2009-03-03 19:30:05 -08005 * 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.)
9 *
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
14 * it probably should.
15 *
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.
24 *
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 ..."
29 */
30
31#include "png.h"
32
33#if defined(_WIN32_WCE)
34# if _WIN32_WCE < 211
35 __error__ (f|w)printf functions are not supported on old WindowsCE.;
36# endif
37# include <windows.h>
38# include <stdlib.h>
39# define READFILE(file, data, length, check) \
The Android Open Source Project4215dd12009-03-09 11:52:12 -070040 if (ReadFile(file, data, length, &check, NULL)) check = 0
The Android Open Source Project893912b2009-03-03 19:30:05 -080041# define WRITEFILE(file, data, length, check)) \
42 if (WriteFile(file, data, length, &check, NULL)) check = 0
43# define FCLOSE(file) CloseHandle(file)
44#else
45# include <stdio.h>
46# include <stdlib.h>
47# define READFILE(file, data, length, check) \
The Android Open Source Project4215dd12009-03-09 11:52:12 -070048 check=(png_size_t)fread(data, (png_size_t)1, length, file)
The Android Open Source Project893912b2009-03-03 19:30:05 -080049# define WRITEFILE(file, data, length, check) \
The Android Open Source Project4215dd12009-03-09 11:52:12 -070050 check=(png_size_t)fwrite(data, (png_size_t)1, length, file)
The Android Open Source Project893912b2009-03-03 19:30:05 -080051# define FCLOSE(file) fclose(file)
52#endif
53
54#if defined(PNG_NO_STDIO)
55# if defined(_WIN32_WCE)
56 typedef HANDLE png_FILE_p;
57# else
58 typedef FILE * png_FILE_p;
59# endif
60#endif
61
62/* Makes pngtest verbose so we can find problems (needs to be before png.h) */
63#ifndef PNG_DEBUG
64# define PNG_DEBUG 0
65#endif
66
67#if !PNG_DEBUG
68# define SINGLE_ROWBUF_ALLOC /* makes buffer overruns easier to nail */
69#endif
70
71/* Turn on CPU timing
72#define PNGTEST_TIMING
73*/
74
75#ifdef PNG_NO_FLOATING_POINT_SUPPORTED
76#undef PNGTEST_TIMING
77#endif
78
79#ifdef PNGTEST_TIMING
80static float t_start, t_stop, t_decode, t_encode, t_misc;
81#include <time.h>
82#endif
83
84#if defined(PNG_TIME_RFC1123_SUPPORTED)
The Android Open Source Project4215dd12009-03-09 11:52:12 -070085#define PNG_tIME_STRING_LENGTH 29
86static int tIME_chunk_present = 0;
87static char tIME_string[PNG_tIME_STRING_LENGTH] = "tIME chunk is not present";
The Android Open Source Project893912b2009-03-03 19:30:05 -080088#endif
89
90static int verbose = 0;
91
92int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname));
93
94#ifdef __TURBOC__
95#include <mem.h>
96#endif
97
98/* defined so I can write to a file on gui/windowing platforms */
99/* #define STDERR stderr */
100#define STDERR stdout /* for DOS */
101
The Android Open Source Project893912b2009-03-03 19:30:05 -0800102/* In case a system header (e.g., on AIX) defined jmpbuf */
103#ifdef jmpbuf
104# undef jmpbuf
105#endif
106
107/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
108#ifndef png_jmpbuf
109# define png_jmpbuf(png_ptr) png_ptr->jmpbuf
110#endif
111
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700112/* example of using row callbacks to make a simple progress meter */
113static int status_pass = 1;
114static int status_dots_requested = 0;
115static int status_dots = 1;
116
The Android Open Source Project893912b2009-03-03 19:30:05 -0800117void
118#ifdef PNG_1_0_X
119PNGAPI
120#endif
121read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
122void
123#ifdef PNG_1_0_X
124PNGAPI
125#endif
126read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
127{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700128 if (png_ptr == NULL || row_number > PNG_UINT_31_MAX) return;
129 if (status_pass != pass)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800130 {
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700131 fprintf(stdout, "\n Pass %d: ", pass);
The Android Open Source Project893912b2009-03-03 19:30:05 -0800132 status_pass = pass;
133 status_dots = 31;
134 }
135 status_dots--;
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700136 if (status_dots == 0)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800137 {
138 fprintf(stdout, "\n ");
139 status_dots=30;
140 }
141 fprintf(stdout, "r");
142}
143
144void
145#ifdef PNG_1_0_X
146PNGAPI
147#endif
148write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
149void
150#ifdef PNG_1_0_X
151PNGAPI
152#endif
153write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
154{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700155 if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) return;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800156 fprintf(stdout, "w");
157}
158
159
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.) */
164static png_uint_32 filters_used[256];
165void
166#ifdef PNG_1_0_X
167PNGAPI
168#endif
169count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data);
170void
171#ifdef PNG_1_0_X
172PNGAPI
173#endif
174count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data)
175{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700176 if (png_ptr != NULL && row_info != NULL)
177 ++filters_used[*(data - 1)];
The Android Open Source Project893912b2009-03-03 19:30:05 -0800178}
179#endif
180
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) */
184
185static png_uint_32 zero_samples;
186
187void
188#ifdef PNG_1_0_X
189PNGAPI
190#endif
191count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data);
192void
193#ifdef PNG_1_0_X
194PNGAPI
195#endif
196count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
197{
198 png_bytep dp = data;
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700199 if (png_ptr == NULL)return;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800200
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)
208 */
209
210
211 /* counts the number of zero samples (or zero pixels if color_type is 3 */
212
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700213 if (row_info->color_type == 0 || row_info->color_type == 3)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800214 {
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700215 int pos = 0;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800216 png_uint_32 n, nstop;
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700217 for (n = 0, nstop=row_info->width; n<nstop; n++)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800218 {
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700219 if (row_info->bit_depth == 1)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800220 {
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700221 if (((*dp << pos++ ) & 0x80) == 0) zero_samples++;
222 if (pos == 8)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800223 {
224 pos = 0;
225 dp++;
226 }
227 }
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700228 if (row_info->bit_depth == 2)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800229 {
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700230 if (((*dp << (pos+=2)) & 0xc0) == 0) zero_samples++;
231 if (pos == 8)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800232 {
233 pos = 0;
234 dp++;
235 }
236 }
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700237 if (row_info->bit_depth == 4)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800238 {
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700239 if (((*dp << (pos+=4)) & 0xf0) == 0) zero_samples++;
240 if (pos == 8)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800241 {
242 pos = 0;
243 dp++;
244 }
245 }
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700246 if (row_info->bit_depth == 8)
247 if (*dp++ == 0) zero_samples++;
248 if (row_info->bit_depth == 16)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800249 {
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700250 if ((*dp | *(dp+1)) == 0) zero_samples++;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800251 dp+=2;
252 }
253 }
254 }
255 else /* other color types */
256 {
257 png_uint_32 n, nstop;
258 int channel;
259 int color_channels = row_info->channels;
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700260 if (row_info->color_type > 3)color_channels--;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800261
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700262 for (n = 0, nstop=row_info->width; n<nstop; n++)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800263 {
264 for (channel = 0; channel < color_channels; channel++)
265 {
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700266 if (row_info->bit_depth == 8)
267 if (*dp++ == 0) zero_samples++;
268 if (row_info->bit_depth == 16)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800269 {
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700270 if ((*dp | *(dp+1)) == 0) zero_samples++;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800271 dp+=2;
272 }
273 }
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700274 if (row_info->color_type > 3)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800275 {
276 dp++;
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700277 if (row_info->bit_depth == 16)dp++;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800278 }
279 }
280 }
281}
282#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
283
284static int wrote_question = 0;
285
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. */
294
295#ifndef USE_FAR_KEYWORD
296static void
297pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
298{
299 png_size_t check;
300
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.
303 */
304 READFILE((png_FILE_p)png_ptr->io_ptr, data, length, check);
305
306 if (check != length)
307 {
308 png_error(png_ptr, "Read Error!");
309 }
310}
311#else
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
314 the data.
315*/
316
317#define NEAR_BUF_SIZE 1024
318#define MIN(a,b) (a <= b ? a : b)
319
320static void
321pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
322{
323 int check;
324 png_byte *n_data;
325 png_FILE_p io_ptr;
326
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)
331 {
332 READFILE(io_ptr, n_data, length, check);
333 }
334 else
335 {
336 png_byte buf[NEAR_BUF_SIZE];
337 png_size_t read, remaining, err;
338 check = 0;
339 remaining = length;
340 do
341 {
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 */
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700345 if (err != read)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800346 break;
347 else
348 check += err;
349 data += read;
350 remaining -= read;
351 }
352 while (remaining != 0);
353 }
354 if (check != length)
355 {
356 png_error(png_ptr, "read Error");
357 }
358}
359#endif /* USE_FAR_KEYWORD */
360
361#if defined(PNG_WRITE_FLUSH_SUPPORTED)
362static void
363pngtest_flush(png_structp png_ptr)
364{
365#if !defined(_WIN32_WCE)
366 png_FILE_p io_ptr;
367 io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
368 if (io_ptr != NULL)
369 fflush(io_ptr);
370#endif
371}
372#endif
373
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
379static void
380pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
381{
382 png_uint_32 check;
383
384 WRITEFILE((png_FILE_p)png_ptr->io_ptr, data, length, check);
385 if (check != length)
386 {
387 png_error(png_ptr, "Write Error");
388 }
389}
390#else
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
393 the data.
394*/
395
396#define NEAR_BUF_SIZE 1024
397#define MIN(a,b) (a <= b ? a : b)
398
399static void
400pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
401{
402 png_uint_32 check;
403 png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
404 png_FILE_p io_ptr;
405
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)
410 {
411 WRITEFILE(io_ptr, near_data, length, check);
412 }
413 else
414 {
415 png_byte buf[NEAR_BUF_SIZE];
416 png_size_t written, remaining, err;
417 check = 0;
418 remaining = length;
419 do
420 {
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);
424 if (err != written)
425 break;
426 else
427 check += err;
428 data += written;
429 remaining -= written;
430 }
431 while (remaining != 0);
432 }
433 if (check != length)
434 {
435 png_error(png_ptr, "Write Error");
436 }
437}
438#endif /* USE_FAR_KEYWORD */
The Android Open Source Project893912b2009-03-03 19:30:05 -0800439
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.
444 */
445static void
446pngtest_warning(png_structp png_ptr, png_const_charp message)
447{
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);
452}
453
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().
458 */
459static void
460pngtest_error(png_structp png_ptr, png_const_charp message)
461{
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. */
465}
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700466#endif /* PNG_NO_STDIO */
467/* END of code to validate stdio-free compilation */
The Android Open Source Project893912b2009-03-03 19:30:05 -0800468
469/* START of code to validate memory allocation and deallocation */
470#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
471
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.
477
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. */
480typedef struct memory_information
481{
482 png_uint_32 size;
483 png_voidp pointer;
484 struct memory_information FAR *next;
485} memory_information;
486typedef memory_information FAR *memory_infop;
487
488static memory_infop pinformation = NULL;
489static int current_allocation = 0;
490static int maximum_allocation = 0;
491static int total_allocation = 0;
492static int num_allocations = 0;
493
494png_voidp png_debug_malloc PNGARG((png_structp png_ptr, png_uint_32 size));
495void png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr));
496
497png_voidp
498png_debug_malloc(png_structp png_ptr, png_uint_32 size)
499{
500
501 /* png_malloc has already tested for NULL; png_create_struct calls
502 png_debug_malloc directly, with png_ptr == NULL which is OK */
503
504 if (size == 0)
505 return (NULL);
506
507 /* This calls the library allocator twice, once to get the requested
508 buffer and once to get a new free list entry. */
509 {
510 /* Disable malloc_fn and free_fn */
511 memory_infop pinfo;
512 png_set_mem_fn(png_ptr, NULL, NULL, NULL);
513 pinfo = (memory_infop)png_malloc(png_ptr,
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700514 (png_uint_32)png_sizeof(*pinfo));
The Android Open Source Project893912b2009-03-03 19:30:05 -0800515 pinfo->size = size;
516 current_allocation += size;
517 total_allocation += size;
518 num_allocations ++;
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 */
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700523 png_set_mem_fn(png_ptr,
524 png_voidp_NULL, (png_malloc_ptr)png_debug_malloc,
525 (png_free_ptr)png_debug_free);
The Android Open Source Project893912b2009-03-03 19:30:05 -0800526 if (size != 0 && pinfo->pointer == NULL)
527 {
528 current_allocation -= size;
529 total_allocation -= size;
530 png_error(png_ptr,
531 "out of memory in pngtest->png_debug_malloc.");
532 }
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);
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700537 if (verbose)
538 printf("png_malloc %lu bytes at %x\n", (unsigned long)size,
539 pinfo->pointer);
The Android Open Source Project893912b2009-03-03 19:30:05 -0800540 return (png_voidp)(pinfo->pointer);
541 }
542}
543
544/* Free a pointer. It is removed from the list at the same time. */
545void
546png_debug_free(png_structp png_ptr, png_voidp ptr)
547{
548 if (png_ptr == NULL)
549 fprintf(STDERR, "NULL pointer to png_debug_free.\n");
550 if (ptr == 0)
551 {
552#if 0 /* This happens all the time. */
553 fprintf(STDERR, "WARNING: freeing NULL pointer\n");
554#endif
555 return;
556 }
557
558 /* Unlink the element from the list. */
559 {
560 memory_infop FAR *ppinfo = &pinformation;
561 for (;;)
562 {
563 memory_infop pinfo = *ppinfo;
564 if (pinfo->pointer == ptr)
565 {
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);
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700574 pinfo = NULL;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800575 break;
576 }
577 if (pinfo->next == NULL)
578 {
579 fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr);
580 break;
581 }
582 ppinfo = &pinfo->next;
583 }
584 }
585
586 /* Finally free the data. */
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700587 if (verbose)
588 printf("Freeing %x\n", ptr);
The Android Open Source Project893912b2009-03-03 19:30:05 -0800589 png_free_default(png_ptr, ptr);
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700590 ptr = NULL;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800591}
592#endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */
593/* END of code to test memory allocation/deallocation */
594
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700595
596/* Demonstration of user chunk support of the sTER and vpAg chunks */
597#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
598
599/* (sTER is a public chunk not yet understood by libpng. vpAg is a private
600chunk used in ImageMagick to store "virtual page" size). */
601
602static png_uint_32 user_chunk_data[4];
603
604 /* 0: sTER mode + 1
605 * 1: vpAg width
606 * 2: vpAg height
607 * 3: vpAg units
608 */
609
610static int read_user_chunk_callback(png_struct *png_ptr,
611 png_unknown_chunkp chunk)
612{
613 png_uint_32
614 *user_chunk_data;
615
616 /* Return one of the following: */
617 /* return (-n); chunk had an error */
618 /* return (0); did not recognize */
619 /* return (n); success */
620
621 /* The unknown chunk structure contains the chunk data:
622 * png_byte name[5];
623 * png_byte *data;
624 * png_size_t size;
625 *
626 * Note that libpng has already taken care of the CRC handling.
627 */
628
629 if (chunk->name[0] == 115 && chunk->name[1] == 84 && /* s T */
630 chunk->name[2] == 69 && chunk->name[3] == 82) /* E R */
631 {
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;
639 return (1);
640 }
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 */
644
645 /* Found ImageMagick vpAg chunk */
646
647 if (chunk->size != 9)
648 return (-1); /* Error return */
649
650 user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr);
651
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];
655
656 return (1);
657
658}
659#endif
660/* END of code to demonstrate user chunk support */
661
The Android Open Source Project893912b2009-03-03 19:30:05 -0800662/* Test one file */
663int
664test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
665{
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;
674#else
675 png_structp write_ptr = NULL;
676 png_infop write_info_ptr = NULL;
677 png_infop write_end_info_ptr = NULL;
678#endif
679 png_bytep row_buf;
680 png_uint_32 y;
681 png_uint_32 width, height;
682 int num_pass, pass;
683 int bit_depth, color_type;
684#ifdef PNG_SETJMP_SUPPORTED
685#ifdef USE_FAR_KEYWORD
686 jmp_buf jmpbuf;
687#endif
688#endif
689
690#if defined(_WIN32_WCE)
691 TCHAR path[MAX_PATH];
692#endif
693 char inbuf[256], outbuf[256];
694
695 row_buf = NULL;
696
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)
700#else
701 if ((fpin = fopen(inname, "rb")) == NULL)
702#endif
703 {
704 fprintf(STDERR, "Could not find input file %s\n", inname);
705 return (1);
706 }
707
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)
711#else
712 if ((fpout = fopen(outname, "wb")) == NULL)
713#endif
714 {
715 fprintf(STDERR, "Could not open output file %s\n", outname);
716 FCLOSE(fpin);
717 return (1);
718 }
719
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700720 png_debug(0, "Allocating read and write structures");
The Android Open Source Project893912b2009-03-03 19:30:05 -0800721#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700722 read_ptr =
723 png_create_read_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
The Android Open Source Project893912b2009-03-03 19:30:05 -0800724 png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
725 (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
726#else
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700727 read_ptr =
728 png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
The Android Open Source Project893912b2009-03-03 19:30:05 -0800729 png_error_ptr_NULL, png_error_ptr_NULL);
730#endif
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700731#if defined(PNG_NO_STDIO)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800732 png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error,
733 pngtest_warning);
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700734#endif
735
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);
743
744#endif
The Android Open Source Project893912b2009-03-03 19:30:05 -0800745#ifdef PNG_WRITE_SUPPORTED
746#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700747 write_ptr =
748 png_create_write_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
The Android Open Source Project893912b2009-03-03 19:30:05 -0800749 png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
750 (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
751#else
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700752 write_ptr =
753 png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
The Android Open Source Project893912b2009-03-03 19:30:05 -0800754 png_error_ptr_NULL, png_error_ptr_NULL);
755#endif
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700756#if defined(PNG_NO_STDIO)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800757 png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error,
758 pngtest_warning);
759#endif
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700760#endif
761 png_debug(0, "Allocating read_info, write_info and end_info structures");
The Android Open Source Project893912b2009-03-03 19:30:05 -0800762 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);
767#endif
768
769#ifdef PNG_SETJMP_SUPPORTED
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700770 png_debug(0, "Setting jmpbuf for read struct");
The Android Open Source Project893912b2009-03-03 19:30:05 -0800771#ifdef USE_FAR_KEYWORD
772 if (setjmp(jmpbuf))
773#else
774 if (setjmp(png_jmpbuf(read_ptr)))
775#endif
776 {
777 fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
778 png_free(read_ptr, row_buf);
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700779 row_buf = NULL;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800780 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);
784#endif
785 FCLOSE(fpin);
786 FCLOSE(fpout);
787 return (1);
788 }
789#ifdef USE_FAR_KEYWORD
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700790 png_memcpy(png_jmpbuf(read_ptr), jmpbuf, png_sizeof(jmp_buf));
The Android Open Source Project893912b2009-03-03 19:30:05 -0800791#endif
792
793#ifdef PNG_WRITE_SUPPORTED
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700794 png_debug(0, "Setting jmpbuf for write struct");
The Android Open Source Project893912b2009-03-03 19:30:05 -0800795#ifdef USE_FAR_KEYWORD
796 if (setjmp(jmpbuf))
797#else
798 if (setjmp(png_jmpbuf(write_ptr)))
799#endif
800 {
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);
806#endif
807 FCLOSE(fpin);
808 FCLOSE(fpout);
809 return (1);
810 }
811#ifdef USE_FAR_KEYWORD
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700812 png_memcpy(png_jmpbuf(write_ptr), jmpbuf, png_sizeof(jmp_buf));
The Android Open Source Project893912b2009-03-03 19:30:05 -0800813#endif
814#endif
815#endif
816
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700817 png_debug(0, "Initializing input and output streams");
The Android Open Source Project893912b2009-03-03 19:30:05 -0800818#if !defined(PNG_NO_STDIO)
819 png_init_io(read_ptr, fpin);
820# ifdef PNG_WRITE_SUPPORTED
821 png_init_io(write_ptr, fpout);
822# endif
823#else
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)
828 pngtest_flush);
829# else
830 NULL);
831# endif
832# endif
833#endif
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700834 if (status_dots_requested == 1)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800835 {
836#ifdef PNG_WRITE_SUPPORTED
837 png_set_write_status_fn(write_ptr, write_row_callback);
838#endif
839 png_set_read_status_fn(read_ptr, read_row_callback);
840 }
841 else
842 {
843#ifdef PNG_WRITE_SUPPORTED
844 png_set_write_status_fn(write_ptr, png_write_status_ptr_NULL);
845#endif
846 png_set_read_status_fn(read_ptr, png_read_status_ptr_NULL);
847 }
848
849#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
850 {
851 int i;
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700852 for (i = 0; i<256; i++)
853 filters_used[i] = 0;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800854 png_set_read_user_transform_fn(read_ptr, count_filters);
855 }
856#endif
857#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700858 zero_samples = 0;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800859 png_set_write_user_transform_fn(write_ptr, count_zero_samples);
860#endif
861
862#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
863# ifndef PNG_HANDLE_CHUNK_ALWAYS
864# define PNG_HANDLE_CHUNK_ALWAYS 3
865# endif
866 png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS,
867 png_bytep_NULL, 0);
868#endif
869#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
870# ifndef PNG_HANDLE_CHUNK_IF_SAFE
871# define PNG_HANDLE_CHUNK_IF_SAFE 2
872# endif
873 png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE,
874 png_bytep_NULL, 0);
875#endif
876
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700877 png_debug(0, "Reading info struct");
The Android Open Source Project893912b2009-03-03 19:30:05 -0800878 png_read_info(read_ptr, read_info_ptr);
879
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700880 png_debug(0, "Transferring info struct");
The Android Open Source Project893912b2009-03-03 19:30:05 -0800881 {
882 int interlace_type, compression_type, filter_type;
883
884 if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
885 &color_type, &interlace_type, &compression_type, &filter_type))
886 {
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);
890#else
891 color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
892#endif
893 }
894 }
895#if defined(PNG_FIXED_POINT_SUPPORTED)
896#if defined(PNG_cHRM_SUPPORTED)
897 {
898 png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
899 blue_y;
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))
902 {
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);
905 }
906 }
907#endif
908#if defined(PNG_gAMA_SUPPORTED)
909 {
910 png_fixed_point gamma;
911
912 if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma))
913 {
914 png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma);
915 }
916 }
917#endif
918#else /* Use floating point versions */
919#if defined(PNG_FLOATING_POINT_SUPPORTED)
920#if defined(PNG_cHRM_SUPPORTED)
921 {
922 double white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
923 blue_y;
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))
926 {
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);
929 }
930 }
931#endif
932#if defined(PNG_gAMA_SUPPORTED)
933 {
934 double gamma;
935
936 if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
937 {
938 png_set_gAMA(write_ptr, write_info_ptr, gamma);
939 }
940 }
941#endif
942#endif /* floating point */
943#endif /* fixed point */
944#if defined(PNG_iCCP_SUPPORTED)
945 {
946 png_charp name;
947 png_charp profile;
948 png_uint_32 proflen;
949 int compression_type;
950
951 if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,
952 &profile, &proflen))
953 {
954 png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,
955 profile, proflen);
956 }
957 }
958#endif
959#if defined(PNG_sRGB_SUPPORTED)
960 {
961 int intent;
962
963 if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
964 {
965 png_set_sRGB(write_ptr, write_info_ptr, intent);
966 }
967 }
968#endif
969 {
970 png_colorp palette;
971 int num_palette;
972
973 if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
974 {
975 png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
976 }
977 }
978#if defined(PNG_bKGD_SUPPORTED)
979 {
980 png_color_16p background;
981
982 if (png_get_bKGD(read_ptr, read_info_ptr, &background))
983 {
984 png_set_bKGD(write_ptr, write_info_ptr, background);
985 }
986 }
987#endif
988#if defined(PNG_hIST_SUPPORTED)
989 {
990 png_uint_16p hist;
991
992 if (png_get_hIST(read_ptr, read_info_ptr, &hist))
993 {
994 png_set_hIST(write_ptr, write_info_ptr, hist);
995 }
996 }
997#endif
998#if defined(PNG_oFFs_SUPPORTED)
999 {
1000 png_int_32 offset_x, offset_y;
1001 int unit_type;
1002
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001003 if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y,
1004 &unit_type))
The Android Open Source Project893912b2009-03-03 19:30:05 -08001005 {
1006 png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
1007 }
1008 }
1009#endif
1010#if defined(PNG_pCAL_SUPPORTED)
1011 {
1012 png_charp purpose, units;
1013 png_charpp params;
1014 png_int_32 X0, X1;
1015 int type, nparams;
1016
1017 if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
1018 &nparams, &units, &params))
1019 {
1020 png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
1021 nparams, units, params);
1022 }
1023 }
1024#endif
1025#if defined(PNG_pHYs_SUPPORTED)
1026 {
1027 png_uint_32 res_x, res_y;
1028 int unit_type;
1029
1030 if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
1031 {
1032 png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
1033 }
1034 }
1035#endif
1036#if defined(PNG_sBIT_SUPPORTED)
1037 {
1038 png_color_8p sig_bit;
1039
1040 if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
1041 {
1042 png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
1043 }
1044 }
1045#endif
1046#if defined(PNG_sCAL_SUPPORTED)
1047#ifdef PNG_FLOATING_POINT_SUPPORTED
1048 {
1049 int unit;
1050 double scal_width, scal_height;
1051
1052 if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,
1053 &scal_height))
1054 {
1055 png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);
1056 }
1057 }
1058#else
1059#ifdef PNG_FIXED_POINT_SUPPORTED
1060 {
1061 int unit;
1062 png_charp scal_width, scal_height;
1063
1064 if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,
1065 &scal_height))
1066 {
1067 png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, scal_height);
1068 }
1069 }
1070#endif
1071#endif
1072#endif
1073#if defined(PNG_TEXT_SUPPORTED)
1074 {
1075 png_textp text_ptr;
1076 int num_text;
1077
1078 if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
1079 {
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001080 png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks", num_text);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001081 png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
1082 }
1083 }
1084#endif
1085#if defined(PNG_tIME_SUPPORTED)
1086 {
1087 png_timep mod_time;
1088
1089 if (png_get_tIME(read_ptr, read_info_ptr, &mod_time))
1090 {
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
1095 we use it */
1096 png_memcpy(tIME_string,
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001097 png_convert_to_rfc1123(read_ptr, mod_time),
The Android Open Source Project893912b2009-03-03 19:30:05 -08001098 png_sizeof(tIME_string));
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001099 tIME_string[png_sizeof(tIME_string) - 1] = '\0';
The Android Open Source Project893912b2009-03-03 19:30:05 -08001100 tIME_chunk_present++;
1101#endif /* PNG_TIME_RFC1123_SUPPORTED */
1102 }
1103 }
1104#endif
1105#if defined(PNG_tRNS_SUPPORTED)
1106 {
1107 png_bytep trans;
1108 int num_trans;
1109 png_color_16p trans_values;
1110
1111 if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans,
1112 &trans_values))
1113 {
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,
1123 trans_values);
1124 }
1125 }
1126#endif
1127#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1128 {
1129 png_unknown_chunkp unknowns;
1130 int num_unknowns = (int)png_get_unknown_chunks(read_ptr, read_info_ptr,
1131 &unknowns);
1132 if (num_unknowns)
1133 {
1134 png_size_t i;
1135 png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns,
1136 num_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);
1143 }
1144 }
1145#endif
1146
1147#ifdef PNG_WRITE_SUPPORTED
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001148 png_debug(0, "Writing info struct");
The Android Open Source Project893912b2009-03-03 19:30:05 -08001149
1150/* If we wanted, we could write info in two steps:
1151 png_write_info_before_PLTE(write_ptr, write_info_ptr);
1152 */
1153 png_write_info(write_ptr, write_info_ptr);
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001154
1155#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
1156 if (user_chunk_data[0] != 0)
1157 {
1158 png_byte png_sTER[5] = {115, 84, 69, 82, '\0'};
1159
1160 unsigned char
1161 ster_chunk_data[1];
1162
1163 if (verbose)
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);
1168 }
1169 if (user_chunk_data[1] != 0 || user_chunk_data[2] != 0)
1170 {
1171 png_byte png_vpAg[5] = {118, 112, 65, 103, '\0'};
1172
1173 unsigned char
1174 vpag_chunk_data[9];
1175
1176 if (verbose)
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);
1185 }
1186
1187#endif
The Android Open Source Project893912b2009-03-03 19:30:05 -08001188#endif
1189
1190#ifdef SINGLE_ROWBUF_ALLOC
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001191 png_debug(0, "Allocating row buffer...");
The Android Open Source Project893912b2009-03-03 19:30:05 -08001192 row_buf = (png_bytep)png_malloc(read_ptr,
1193 png_get_rowbytes(read_ptr, read_info_ptr));
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001194 png_debug1(0, "0x%08lx", (unsigned long)row_buf);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001195#endif /* SINGLE_ROWBUF_ALLOC */
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001196 png_debug(0, "Writing row data");
The Android Open Source Project893912b2009-03-03 19:30:05 -08001197
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);
1203# endif
1204#else
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001205 num_pass = 1;
The Android Open Source Project893912b2009-03-03 19:30:05 -08001206#endif
1207
1208#ifdef PNGTEST_TIMING
1209 t_stop = (float)clock();
1210 t_misc += (t_stop - t_start);
1211 t_start = t_stop;
1212#endif
1213 for (pass = 0; pass < num_pass; pass++)
1214 {
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001215 png_debug1(0, "Writing row data for pass %d", pass);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001216 for (y = 0; y < height; y++)
1217 {
1218#ifndef SINGLE_ROWBUF_ALLOC
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001219 png_debug2(0, "Allocating row buffer (pass %d, y = %ld)...", pass, y);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001220 row_buf = (png_bytep)png_malloc(read_ptr,
1221 png_get_rowbytes(read_ptr, read_info_ptr));
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001222 png_debug2(0, "0x%08lx (%ld bytes)", (unsigned long)row_buf,
The Android Open Source Project893912b2009-03-03 19:30:05 -08001223 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);
1226
1227#ifdef PNG_WRITE_SUPPORTED
1228#ifdef PNGTEST_TIMING
1229 t_stop = (float)clock();
1230 t_decode += (t_stop - t_start);
1231 t_start = t_stop;
1232#endif
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);
1237 t_start = t_stop;
1238#endif
1239#endif /* PNG_WRITE_SUPPORTED */
1240
1241#ifndef SINGLE_ROWBUF_ALLOC
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001242 png_debug2(0, "Freeing row buffer (pass %d, y = %ld)", pass, y);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001243 png_free(read_ptr, row_buf);
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001244 row_buf = NULL;
The Android Open Source Project893912b2009-03-03 19:30:05 -08001245#endif /* !SINGLE_ROWBUF_ALLOC */
1246 }
1247 }
1248
1249#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
1250 png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1);
1251#endif
1252#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1253 png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1);
1254#endif
1255
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001256 png_debug(0, "Reading and writing end_info data");
The Android Open Source Project893912b2009-03-03 19:30:05 -08001257
1258 png_read_end(read_ptr, end_info_ptr);
1259#if defined(PNG_TEXT_SUPPORTED)
1260 {
1261 png_textp text_ptr;
1262 int num_text;
1263
1264 if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0)
1265 {
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001266 png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks", num_text);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001267 png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text);
1268 }
1269 }
1270#endif
1271#if defined(PNG_tIME_SUPPORTED)
1272 {
1273 png_timep mod_time;
1274
1275 if (png_get_tIME(read_ptr, end_info_ptr, &mod_time))
1276 {
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
1281 we use it */
1282 png_memcpy(tIME_string,
1283 png_convert_to_rfc1123(read_ptr, mod_time),
1284 png_sizeof(tIME_string));
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001285 tIME_string[png_sizeof(tIME_string) - 1] = '\0';
The Android Open Source Project893912b2009-03-03 19:30:05 -08001286 tIME_chunk_present++;
1287#endif /* PNG_TIME_RFC1123_SUPPORTED */
1288 }
1289 }
1290#endif
1291#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1292 {
1293 png_unknown_chunkp unknowns;
1294 int num_unknowns;
1295 num_unknowns = (int)png_get_unknown_chunks(read_ptr, end_info_ptr,
1296 &unknowns);
1297 if (num_unknowns)
1298 {
1299 png_size_t i;
1300 png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,
1301 num_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);
1308 }
1309 }
1310#endif
1311#ifdef PNG_WRITE_SUPPORTED
1312 png_write_end(write_ptr, write_end_info_ptr);
1313#endif
1314
1315#ifdef PNG_EASY_ACCESS_SUPPORTED
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001316 if (verbose)
The Android Open Source Project893912b2009-03-03 19:30:05 -08001317 {
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);
1323 }
1324#endif
1325
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001326 png_debug(0, "Destroying data structs");
The Android Open Source Project893912b2009-03-03 19:30:05 -08001327#ifdef SINGLE_ROWBUF_ALLOC
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001328 png_debug(1, "destroying row_buf for read_ptr");
The Android Open Source Project893912b2009-03-03 19:30:05 -08001329 png_free(read_ptr, row_buf);
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001330 row_buf = NULL;
The Android Open Source Project893912b2009-03-03 19:30:05 -08001331#endif /* SINGLE_ROWBUF_ALLOC */
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001332 png_debug(1, "destroying read_ptr, read_info_ptr, end_info_ptr");
The Android Open Source Project893912b2009-03-03 19:30:05 -08001333 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
1334#ifdef PNG_WRITE_SUPPORTED
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001335 png_debug(1, "destroying write_end_info_ptr");
The Android Open Source Project893912b2009-03-03 19:30:05 -08001336 png_destroy_info_struct(write_ptr, &write_end_info_ptr);
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001337 png_debug(1, "destroying write_ptr, write_info_ptr");
The Android Open Source Project893912b2009-03-03 19:30:05 -08001338 png_destroy_write_struct(&write_ptr, &write_info_ptr);
1339#endif
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001340 png_debug(0, "Destruction complete.");
The Android Open Source Project893912b2009-03-03 19:30:05 -08001341
1342 FCLOSE(fpin);
1343 FCLOSE(fpout);
1344
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001345 png_debug(0, "Opening files for comparison");
The Android Open Source Project893912b2009-03-03 19:30:05 -08001346#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)
1349#else
1350 if ((fpin = fopen(inname, "rb")) == NULL)
1351#endif
1352 {
1353 fprintf(STDERR, "Could not find file %s\n", inname);
1354 return (1);
1355 }
1356
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)
1360#else
1361 if ((fpout = fopen(outname, "rb")) == NULL)
1362#endif
1363 {
1364 fprintf(STDERR, "Could not find file %s\n", outname);
1365 FCLOSE(fpin);
1366 return (1);
1367 }
1368
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001369 for (;;)
The Android Open Source Project893912b2009-03-03 19:30:05 -08001370 {
1371 png_size_t num_in, num_out;
1372
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001373 READFILE(fpin, inbuf, 1, num_in);
1374 READFILE(fpout, outbuf, 1, num_out);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001375
1376 if (num_in != num_out)
1377 {
1378 fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
1379 inname, outname);
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001380 if (wrote_question == 0)
The Android Open Source Project893912b2009-03-03 19:30:05 -08001381 {
1382 fprintf(STDERR,
1383 " Was %s written with the same maximum IDAT chunk size (%d bytes),",
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001384 inname, PNG_ZBUF_SIZE);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001385 fprintf(STDERR,
1386 "\n filtering heuristic (libpng default), compression");
1387 fprintf(STDERR,
1388 " level (zlib default),\n and zlib version (%s)?\n\n",
1389 ZLIB_VERSION);
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001390 wrote_question = 1;
The Android Open Source Project893912b2009-03-03 19:30:05 -08001391 }
1392 FCLOSE(fpin);
1393 FCLOSE(fpout);
1394 return (0);
1395 }
1396
1397 if (!num_in)
1398 break;
1399
1400 if (png_memcmp(inbuf, outbuf, num_in))
1401 {
1402 fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname);
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001403 if (wrote_question == 0)
The Android Open Source Project893912b2009-03-03 19:30:05 -08001404 {
1405 fprintf(STDERR,
1406 " Was %s written with the same maximum IDAT chunk size (%d bytes),",
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001407 inname, PNG_ZBUF_SIZE);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001408 fprintf(STDERR,
1409 "\n filtering heuristic (libpng default), compression");
1410 fprintf(STDERR,
1411 " level (zlib default),\n and zlib version (%s)?\n\n",
1412 ZLIB_VERSION);
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001413 wrote_question = 1;
The Android Open Source Project893912b2009-03-03 19:30:05 -08001414 }
1415 FCLOSE(fpin);
1416 FCLOSE(fpout);
1417 return (0);
1418 }
1419 }
1420
1421 FCLOSE(fpin);
1422 FCLOSE(fpout);
1423
1424 return (0);
1425}
1426
1427/* input and output filenames */
1428#ifdef RISCOS
1429static PNG_CONST char *inname = "pngtest/png";
1430static PNG_CONST char *outname = "pngout/png";
1431#else
1432static PNG_CONST char *inname = "pngtest.png";
1433static PNG_CONST char *outname = "pngout.png";
1434#endif
1435
1436int
1437main(int argc, char *argv[])
1438{
1439 int multiple = 0;
1440 int ierror = 0;
1441
1442 fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
1443 fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION);
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001444 fprintf(STDERR, "%s", png_get_copyright(NULL));
The Android Open Source Project893912b2009-03-03 19:30:05 -08001445 /* Show the version of libpng used in building the library */
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001446 fprintf(STDERR, " library (%lu):%s",
The Android Open Source Project893912b2009-03-03 19:30:05 -08001447 (unsigned long)png_access_version_number(),
1448 png_get_header_version(NULL));
1449 /* Show the version of libpng used in building the application */
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001450 fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER,
The Android Open Source Project893912b2009-03-03 19:30:05 -08001451 PNG_HEADER_VERSION_STRING);
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001452 fprintf(STDERR, " sizeof(png_struct)=%ld, sizeof(png_info)=%ld\n",
The Android Open Source Project893912b2009-03-03 19:30:05 -08001453 (long)png_sizeof(png_struct), (long)png_sizeof(png_info));
1454
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
1458 in pngconf.h */
1459#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
1460 fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n");
1461#endif
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");
1465#endif
1466
1467 if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
1468 {
1469 fprintf(STDERR,
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);
1473 ++ierror;
1474 }
1475
1476 if (argc > 1)
1477 {
1478 if (strcmp(argv[1], "-m") == 0)
1479 {
1480 multiple = 1;
1481 status_dots_requested = 0;
1482 }
1483 else if (strcmp(argv[1], "-mv") == 0 ||
1484 strcmp(argv[1], "-vm") == 0 )
1485 {
1486 multiple = 1;
1487 verbose = 1;
1488 status_dots_requested = 1;
1489 }
1490 else if (strcmp(argv[1], "-v") == 0)
1491 {
1492 verbose = 1;
1493 status_dots_requested = 1;
1494 inname = argv[2];
1495 }
1496 else
1497 {
1498 inname = argv[1];
1499 status_dots_requested = 0;
1500 }
1501 }
1502
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001503 if (!multiple && argc == 3 + verbose)
1504 outname = argv[2 + verbose];
The Android Open Source Project893912b2009-03-03 19:30:05 -08001505
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001506 if ((!multiple && argc > 3 + verbose) || (multiple && argc < 2))
The Android Open Source Project893912b2009-03-03 19:30:05 -08001507 {
1508 fprintf(STDERR,
1509 "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
1510 argv[0], argv[0]);
1511 fprintf(STDERR,
1512 " reads/writes one PNG file (without -m) or multiple files (-m)\n");
1513 fprintf(STDERR,
1514 " with -m %s is used as a temporary file\n", outname);
1515 exit(1);
1516 }
1517
1518 if (multiple)
1519 {
1520 int i;
1521#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1522 int allocation_now = current_allocation;
1523#endif
1524 for (i=2; i<argc; ++i)
1525 {
1526#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1527 int k;
1528#endif
1529 int kerror;
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001530 fprintf(STDERR, "Testing %s:", argv[i]);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001531 kerror = test_one_file(argv[i], outname);
1532 if (kerror == 0)
1533 {
1534#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
1535 fprintf(STDERR, "\n PASS (%lu zero samples)\n",
1536 (unsigned long)zero_samples);
1537#else
1538 fprintf(STDERR, " PASS\n");
1539#endif
1540#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001541 for (k = 0; k<256; k++)
1542 if (filters_used[k])
The Android Open Source Project893912b2009-03-03 19:30:05 -08001543 fprintf(STDERR, " Filter %d was used %lu times\n",
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001544 k, (unsigned long)filters_used[k]);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001545#endif
1546#if defined(PNG_TIME_RFC1123_SUPPORTED)
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001547 if (tIME_chunk_present != 0)
1548 fprintf(STDERR, " tIME = %s\n", tIME_string);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001549 tIME_chunk_present = 0;
1550#endif /* PNG_TIME_RFC1123_SUPPORTED */
1551 }
1552 else
1553 {
1554 fprintf(STDERR, " FAIL\n");
1555 ierror += kerror;
1556 }
1557#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1558 if (allocation_now != current_allocation)
1559 fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001560 current_allocation - allocation_now);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001561 if (current_allocation != 0)
1562 {
1563 memory_infop pinfo = pinformation;
1564
1565 fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
1566 current_allocation);
1567 while (pinfo != NULL)
1568 {
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001569 fprintf(STDERR, " %lu bytes at %x\n",
1570 (unsigned long)pinfo->size,
The Android Open Source Project893912b2009-03-03 19:30:05 -08001571 (unsigned int) pinfo->pointer);
1572 pinfo = pinfo->next;
1573 }
1574 }
1575#endif
1576 }
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",
1583 total_allocation);
1584 fprintf(STDERR, " Number of allocations: %10d\n",
1585 num_allocations);
1586#endif
1587 }
1588 else
1589 {
1590 int i;
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001591 for (i = 0; i<3; ++i)
The Android Open Source Project893912b2009-03-03 19:30:05 -08001592 {
1593 int kerror;
1594#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1595 int allocation_now = current_allocation;
1596#endif
1597 if (i == 1) status_dots_requested = 1;
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001598 else if (verbose == 0)status_dots_requested = 0;
The Android Open Source Project893912b2009-03-03 19:30:05 -08001599 if (i == 0 || verbose == 1 || ierror != 0)
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001600 fprintf(STDERR, "Testing %s:", inname);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001601 kerror = test_one_file(inname, outname);
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001602 if (kerror == 0)
The Android Open Source Project893912b2009-03-03 19:30:05 -08001603 {
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001604 if (verbose == 1 || i == 2)
The Android Open Source Project893912b2009-03-03 19:30:05 -08001605 {
1606#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1607 int k;
1608#endif
1609#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
1610 fprintf(STDERR, "\n PASS (%lu zero samples)\n",
1611 (unsigned long)zero_samples);
1612#else
1613 fprintf(STDERR, " PASS\n");
1614#endif
1615#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001616 for (k = 0; k<256; k++)
1617 if (filters_used[k])
The Android Open Source Project893912b2009-03-03 19:30:05 -08001618 fprintf(STDERR, " Filter %d was used %lu times\n",
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001619 k,
1620 (unsigned long)filters_used[k]);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001621#endif
1622#if defined(PNG_TIME_RFC1123_SUPPORTED)
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001623 if (tIME_chunk_present != 0)
1624 fprintf(STDERR, " tIME = %s\n", tIME_string);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001625#endif /* PNG_TIME_RFC1123_SUPPORTED */
1626 }
1627 }
1628 else
1629 {
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001630 if (verbose == 0 && i != 2)
1631 fprintf(STDERR, "Testing %s:", inname);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001632 fprintf(STDERR, " FAIL\n");
1633 ierror += kerror;
1634 }
1635#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1636 if (allocation_now != current_allocation)
1637 fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001638 current_allocation - allocation_now);
The Android Open Source Project893912b2009-03-03 19:30:05 -08001639 if (current_allocation != 0)
1640 {
1641 memory_infop pinfo = pinformation;
1642
1643 fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
1644 current_allocation);
1645 while (pinfo != NULL)
1646 {
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001647 fprintf(STDERR, " %lu bytes at %x\n",
The Android Open Source Project893912b2009-03-03 19:30:05 -08001648 (unsigned long)pinfo->size, (unsigned int)pinfo->pointer);
1649 pinfo = pinfo->next;
1650 }
1651 }
1652#endif
1653 }
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",
1660 total_allocation);
1661 fprintf(STDERR, " Number of allocations: %10d\n",
1662 num_allocations);
1663#endif
1664 }
1665
1666#ifdef PNGTEST_TIMING
1667 t_stop = (float)clock();
1668 t_misc += (t_stop - t_start);
1669 t_start = t_stop;
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001670 fprintf(STDERR, " CPU time used = %.3f seconds",
The Android Open Source Project893912b2009-03-03 19:30:05 -08001671 (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001672 fprintf(STDERR, " (decoding %.3f,\n",
The Android Open Source Project893912b2009-03-03 19:30:05 -08001673 t_decode/(float)CLOCKS_PER_SEC);
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001674 fprintf(STDERR, " encoding %.3f ,",
The Android Open Source Project893912b2009-03-03 19:30:05 -08001675 t_encode/(float)CLOCKS_PER_SEC);
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001676 fprintf(STDERR, " other %.3f seconds)\n\n",
The Android Open Source Project893912b2009-03-03 19:30:05 -08001677 t_misc/(float)CLOCKS_PER_SEC);
1678#endif
1679
1680 if (ierror == 0)
1681 fprintf(STDERR, "libpng passes test\n");
1682 else
1683 fprintf(STDERR, "libpng FAILS test\n");
1684 return (int)(ierror != 0);
1685}
1686
1687/* Generate a compiler error if there is an old png.h in the search path. */
The Android Open Source Project4215dd12009-03-09 11:52:12 -07001688typedef version_1_2_35 your_png_h_is_not_version_1_2_35;