blob: 8ca4012c17ad50782b2f34636e8692af5eb3179c [file] [log] [blame]
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001
Guy Schalnat4ee97b01996-01-16 01:51:56 -06002/* pngtest.c - a simple test program to test libpng
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06003 *
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06004 * libpng 1.00
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06005 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
7 * Copyright (c) 1996, 1997 Andreas Dilger
Glenn Randers-Pehrson2687fcc1998-01-07 20:54:20 -06008 * Copyright (c) 1998, Glenn Randers-Pehrson
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06009 * March 7, 1998
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060010 *
11 * This program reads in a PNG image, writes it out again, and then
12 * compares the two files. If the files are identical, this shows that
13 * the basic chunk handling, filtering, and (de)compression code is working
14 * properly. It does not currently test all of the transforms, although
15 * it probably should.
16 *
17 * The program will fail in certain legitimate cases:
18 * 1) when the compression level or filter selection method is changed.
19 * 2) when the chunk size is smaller than 8K.
20 * 3) unknown ancillary chunks 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 images 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.
28 */
Guy Schalnat0d580581995-07-20 02:43:20 -050029
30#include <stdio.h>
31#include <stdlib.h>
Andreas Dilger47a0c421997-05-16 02:46:07 -050032
33/* Makes pngtest verbose so we can find problems (needs to be before png.h) */
34#ifndef PNG_DEBUG
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060035#define PNG_DEBUG 0
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -060036#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -050037
Guy Schalnat0d580581995-07-20 02:43:20 -050038#include "png.h"
39
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -060040int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname));
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -060041
Guy Schalnat0d580581995-07-20 02:43:20 -050042#ifdef __TURBOC__
43#include <mem.h>
44#endif
45
46/* defined so I can write to a file on gui/windowing platforms */
Guy Schalnat6d764711995-12-19 03:22:19 -060047/* #define STDERR stderr */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060048#define STDERR stdout /* for DOS */
Guy Schalnat0d580581995-07-20 02:43:20 -050049
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060050/* example of using row callbacks to make a simple progress meter */
51static int status_pass=1;
52static int status_dots_requested=0;
53static int status_dots=1;
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -060054
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -060055void
56read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060057{
Glenn Randers-Pehrson983ec161998-03-07 11:24:03 -060058 if(png_ptr == NULL || row_number > 0x3fffffffL) return;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060059 if(status_pass != pass)
60 {
61 fprintf(stdout,"\n Pass %d: ",pass);
62 status_pass = pass;
63 status_dots = 30;
64 }
65 status_dots--;
66 if(status_dots == 0)
67 {
68 fprintf(stdout, "\n ");
69 status_dots=30;
70 }
71 fprintf(stdout, "r");
72}
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -060073
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -060074void
75write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060076{
Glenn Randers-Pehrson983ec161998-03-07 11:24:03 -060077 if(png_ptr == NULL || row_number > 0x3fffffffL || pass > 7) return;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060078 fprintf(stdout, "w");
79}
80
81
82#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
83 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
84/* example of using user transform callback (we don't transform anything,
85 but merely count the black pixels) */
86
87static png_uint_32 black_pixels;
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -060088
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -060089void
90count_black_pixels(png_structp png_ptr, png_row_infop row_info, png_bytep data)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060091{
92 png_bytep dp = data;
93 if(png_ptr == NULL)return;
94
95 /* contents of row_info:
96 * png_uint_32 width width of row
97 * png_uint_32 rowbytes number of bytes in row
98 * png_byte color_type color type of pixels
99 * png_byte bit_depth bit depth of samples
100 * png_byte channels number of channels (1-4)
101 * png_byte pixel_depth bits per pixel (depth*channels)
102 */
103
104 /* counts the number of black pixels (or zero pixels if color_type is 3 */
105
106 if(row_info->color_type == 0 || row_info->color_type == 3)
107 {
108 int pos=0;
109 png_uint_32 n;
Glenn Randers-Pehrson983ec161998-03-07 11:24:03 -0600110 for (n=0; n<row_info->width; n++)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600111 {
112 if(row_info->bit_depth == 1)
113 if(((*dp << pos++ )& 0x80) == 0) black_pixels++;
114 if(pos == 8)
115 {
116 pos=0;
117 dp++;
118 }
119 if(row_info->bit_depth == 2)
120 if(((*dp << (pos+=2))& 0xc0) == 0) black_pixels++;
121 if(pos == 8)
122 {
123 pos=0;
124 dp++;
125 }
126 if(row_info->bit_depth == 4)
127 if(((*dp << (pos+=4))& 0xf0) == 0) black_pixels++;
128 if(pos == 8)
129 {
130 pos=0;
131 dp++;
132 }
133 if(row_info->bit_depth == 8)
134 if(*dp++ == 0) black_pixels++;
135 if(row_info->bit_depth == 16)
136 {
137 if((*dp | *(dp+1)) == 0) black_pixels++;
138 dp+=2;
139 }
140 }
141 }
142 else /* other color types */
143 {
144 png_uint_32 n;
145 int channel;
146 int color_channels = row_info->channels;
147 if(row_info->color_type > 3)color_channels--;
148
149 for (n=0; n<row_info->width; n++)
150 {
151 for (channel = 0; channel < color_channels; channel++)
152 {
153 if(row_info->bit_depth == 8)
154 if(*dp++ == 0) black_pixels++;
155 if(row_info->bit_depth == 16)
156 {
157 if((*dp | *(dp+1)) == 0) black_pixels++;
158 dp+=2;
159 }
160 }
161 if(row_info->color_type > 3)
162 {
163 dp++;
164 if(row_info->bit_depth == 16)dp++;
165 }
166 }
167 }
168}
169#endif /* PNG_READ|WRITE_USER_TRANSFORM_SUPPORTED */
170
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600171static int verbose = 0;
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600172static int wrote_question = 0;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600173
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600174#if defined(PNG_NO_STDIO)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600175/* START of code to validate stdio-free compilation */
176/* These copies of the default read/write functions come from pngrio.c and */
177/* pngwio.c. They allow "don't include stdio" testing of the library. */
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600178/* This is the function which does the actual reading of data. If you are
179 not reading from a standard C stream, you should create a replacement
180 read_data function and use it at run time with png_set_read_fn(), rather
181 than changing the library. */
182#ifndef USE_FAR_KEYWORD
183static void
184png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
185{
186 png_size_t check;
187
188 /* fread() returns 0 on error, so it is OK to store this in a png_size_t
189 * instead of an int, which is what fread() actually returns.
190 */
191 check = (png_size_t)fread(data, (png_size_t)1, length,
192 (FILE *)png_ptr->io_ptr);
193
194 if (check != length)
195 {
196 png_error(png_ptr, "Read Error");
197 }
198}
Guy Schalnate5a37791996-06-05 15:50:50 -0500199#else
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600200/* this is the model-independent version. Since the standard I/O library
201 can't handle far buffers in the medium and small models, we have to copy
202 the data.
203*/
204
205#define NEAR_BUF_SIZE 1024
206#define MIN(a,b) (a <= b ? a : b)
207
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600208static void
209png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600210{
211 int check;
212 png_byte *n_data;
213 FILE *io_ptr;
214
215 /* Check if data really is near. If so, use usual code. */
216 n_data = (png_byte *)CVT_PTR_NOCHECK(data);
217 io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
218 if ((png_bytep)n_data == data)
219 {
220 check = fread(n_data, 1, length, io_ptr);
221 }
222 else
223 {
224 png_byte buf[NEAR_BUF_SIZE];
225 png_size_t read, remaining, err;
226 check = 0;
227 remaining = length;
228 do
229 {
230 read = MIN(NEAR_BUF_SIZE, remaining);
231 err = fread(buf, (png_size_t)1, read, io_ptr);
232 png_memcpy(data, buf, read); /* copy far buffer to near buffer */
233 if(err != read)
234 break;
235 else
236 check += err;
237 data += read;
238 remaining -= read;
239 }
240 while (remaining != 0);
241 }
242 if (check != length)
243 {
244 png_error(png_ptr, "read Error");
245 }
246}
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600247#endif /* USE_FAR_KEYWORD */
Guy Schalnat0d580581995-07-20 02:43:20 -0500248
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600249#if defined(PNG_WRITE_FLUSH_SUPPORTED)
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600250static void
251png_default_flush(png_structp png_ptr)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600252{
253 FILE *io_ptr;
254 io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));
255 if (io_ptr != NULL)
256 fflush(io_ptr);
257}
258#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500259
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600260/* This is the function which does the actual writing of data. If you are
261 not writing to a standard C stream, you should create a replacement
262 write_data function and use it at run time with png_set_write_fn(), rather
263 than changing the library. */
264#ifndef USE_FAR_KEYWORD
265static void
266png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
267{
268 png_uint_32 check;
269
270 check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr));
271 if (check != length)
272 {
273 png_error(png_ptr, "Write Error");
274 }
275}
276#else
277/* this is the model-independent version. Since the standard I/O library
278 can't handle far buffers in the medium and small models, we have to copy
279 the data.
280*/
281
282#define NEAR_BUF_SIZE 1024
283#define MIN(a,b) (a <= b ? a : b)
284
285static void
286png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
287{
288 png_uint_32 check;
289 png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
290 FILE *io_ptr;
291
292 /* Check if data really is near. If so, use usual code. */
293 near_data = (png_byte *)CVT_PTR_NOCHECK(data);
294 io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
295 if ((png_bytep)near_data == data)
296 {
297 check = fwrite(near_data, 1, length, io_ptr);
298 }
299 else
300 {
301 png_byte buf[NEAR_BUF_SIZE];
302 png_size_t written, remaining, err;
303 check = 0;
304 remaining = length;
305 do
306 {
307 written = MIN(NEAR_BUF_SIZE, remaining);
308 png_memcpy(buf, data, written); /* copy far buffer to near buffer */
309 err = fwrite(buf, 1, written, io_ptr);
310 if (err != written)
311 break;
312 else
313 check += err;
314 data += written;
315 remaining -= written;
316 }
317 while (remaining != 0);
318 }
319 if (check != length)
320 {
321 png_error(png_ptr, "Write Error");
322 }
323}
324
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600325#endif /* USE_FAR_KEYWORD */
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600326
327/* This function is called when there is a warning, but the library thinks
328 * it can continue anyway. Replacement functions don't have to do anything
329 * here if you don't want to. In the default configuration, png_ptr is
330 * not used, but it is passed in case it may be useful.
331 */
332static void
333png_default_warning(png_structp png_ptr, png_const_charp message)
334{
335 PNG_CONST char *name = "UNKNOWN (ERROR!)";
336 if (png_ptr != NULL && png_ptr->error_ptr != NULL)
337 name = png_ptr->error_ptr;
338 fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
339}
340
341/* This is the default error handling function. Note that replacements for
342 * this function MUST NOT RETURN, or the program will likely crash. This
343 * function is used by default, or if the program supplies NULL for the
344 * error function pointer in png_set_error_fn().
345 */
346static void
347png_default_error(png_structp png_ptr, png_const_charp message)
348{
349 png_default_warning(png_ptr, message);
350 /* We can return because png_error calls the default handler which is
351 * actually ok in this case. */
352}
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600353#endif /* PNG_NO_STDIO */
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600354/* END of code to validate stdio-free compilation */
355
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600356/* START of code to validate memory allocation and deallocation */
357#ifdef PNGTEST_MEMORY_DEBUG
358/* Borland DOS special memory handler */
359#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
360ERROR - memory debugging is not supported on this platform
361#else
362
363/* Allocate memory. For reasonable files, size should never exceed
364 64K. However, zlib may allocate more then 64K if you don't tell
365 it not to. See zconf.h and png.h for more information. zlib does
366 need to allocate exactly 64K, so whatever you call here must
367 have the ability to do that.
368
369 This piece of code can be compiled to validate max 64K allocations
370 by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. */
371typedef struct memory_information {
372 png_uint_32 size;
373 png_voidp pointer;
374 struct memory_information FAR *next;
375} memory_information;
376typedef memory_information FAR *memory_infop;
377
378static memory_infop pinformation = NULL;
379static int current_allocation = 0;
380static int maximum_allocation = 0;
381
382extern PNG_EXPORT(png_voidp,png_debug_malloc) PNGARG((png_structp png_ptr,
383 png_uint_32 size));
384extern PNG_EXPORT(void,png_debug_free) PNGARG((png_structp png_ptr,
385 png_voidp ptr));
386
387png_voidp
388png_malloc(png_structp png_ptr, png_uint_32 size) {
389 if (png_ptr == NULL) {
390 fprintf(STDERR, "NULL pointer to memory allocator\n");
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600391 return (NULL);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600392 }
393 if (size == 0)
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600394 return (png_voidp)(NULL);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600395
396 /* This calls the library allocator twice, once to get the requested
397 buffer and once to get a new free list entry. */
398 {
399 memory_infop pinfo = png_debug_malloc(png_ptr, sizeof *pinfo);
400 pinfo->size = size;
401 current_allocation += size;
402 if (current_allocation > maximum_allocation)
403 maximum_allocation = current_allocation;
404 pinfo->pointer = png_debug_malloc(png_ptr, size);
405 pinfo->next = pinformation;
406 pinformation = pinfo;
407 /* Make sure the caller isn't assuming zeroed memory. */
408 png_memset(pinfo->pointer, 0xdd, pinfo->size);
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600409 return (png_voidp)(pinfo->pointer);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600410 }
411}
412
413/* Free a pointer. It is removed from the list at the same time. */
414void
415png_free(png_structp png_ptr, png_voidp ptr)
416{
417 if (png_ptr == NULL)
418 fprintf(STDERR, "NULL pointer to memory allocator\n");
419 if (ptr == 0) {
420#if 0 /* This happens all the time. */
421 fprintf(STDERR, "WARNING: freeing NULL pointer\n");
422#endif
423 return;
424 }
425
426 /* Unlink the element from the list. */
427 {
428 memory_infop FAR *ppinfo = &pinformation;
429 for (;;) {
430 memory_infop pinfo = *ppinfo;
431 if (pinfo->pointer == ptr) {
432 *ppinfo = pinfo->next;
433 current_allocation -= pinfo->size;
434 if (current_allocation < 0)
435 fprintf(STDERR, "Duplicate free of memory\n");
436 /* We must free the list element too, but first kill
437 the memory which is to be freed. */
438 memset(ptr, 0x55, pinfo->size);
439 png_debug_free(png_ptr, pinfo);
440 break;
441 }
442 if (pinfo->next == NULL) {
443 fprintf(STDERR, "Pointer %x not found\n", ptr);
444 break;
445 }
446 ppinfo = &pinfo->next;
447 }
448 }
449
450 /* Finally free the data. */
451 png_debug_free(png_ptr, ptr);
452}
453#endif /* Not Borland DOS special memory handler */
454#endif
455/* END of code to test memory allocation/deallocation */
456
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600457/* Test one file */
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600458int
459test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
Guy Schalnat0d580581995-07-20 02:43:20 -0500460{
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600461 static FILE *fpin, *fpout; /* "static" prevents setjmp corruption */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500462 png_structp read_ptr, write_ptr;
463 png_infop read_info_ptr, write_info_ptr, end_info_ptr;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600464 png_bytep row_buf;
Guy Schalnat0d580581995-07-20 02:43:20 -0500465 png_uint_32 y;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500466 png_uint_32 width, height;
467 int num_pass, pass;
468 int bit_depth, color_type;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600469#ifdef USE_FAR_KEYWORD
470 jmp_buf jmpbuf;
471#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600472
473 char inbuf[256], outbuf[256];
474
Guy Schalnate5a37791996-06-05 15:50:50 -0500475 row_buf = (png_bytep)NULL;
Guy Schalnat0d580581995-07-20 02:43:20 -0500476
Andreas Dilger47a0c421997-05-16 02:46:07 -0500477 if ((fpin = fopen(inname, "rb")) == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -0600478 {
479 fprintf(STDERR, "Could not find input file %s\n", inname);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600480 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600481 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500482
Andreas Dilger47a0c421997-05-16 02:46:07 -0500483 if ((fpout = fopen(outname, "wb")) == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -0600484 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500485 fprintf(STDERR, "Could not open output file %s\n", outname);
Guy Schalnat0f716451995-11-28 11:22:13 -0600486 fclose(fpin);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600487 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600488 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500489
Andreas Dilger47a0c421997-05-16 02:46:07 -0500490 png_debug(0, "Allocating read and write structures\n");
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600491 read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
Andreas Dilger47a0c421997-05-16 02:46:07 -0500492 (png_error_ptr)NULL, (png_error_ptr)NULL);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600493#if defined(PNG_NO_STDIO)
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600494 png_set_error_fn(read_ptr, (png_voidp)inname, png_default_error,
495 png_default_warning);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600496#endif
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600497 write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
Guy Schalnate5a37791996-06-05 15:50:50 -0500498 (png_error_ptr)NULL, (png_error_ptr)NULL);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600499#if defined(PNG_NO_STDIO)
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600500 png_set_error_fn(write_ptr, (png_voidp)inname, png_default_error,
501 png_default_warning);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600502#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500503 png_debug(0, "Allocating read_info, write_info and end_info structures\n");
504 read_info_ptr = png_create_info_struct(read_ptr);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600505 write_info_ptr = png_create_info_struct(write_ptr);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500506 end_info_ptr = png_create_info_struct(read_ptr);
Guy Schalnate5a37791996-06-05 15:50:50 -0500507
Andreas Dilger47a0c421997-05-16 02:46:07 -0500508 png_debug(0, "Setting jmpbuf for read struct\n");
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600509#ifdef USE_FAR_KEYWORD
510 if (setjmp(jmpbuf))
511#else
Guy Schalnate5a37791996-06-05 15:50:50 -0500512 if (setjmp(read_ptr->jmpbuf))
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600513#endif
Guy Schalnat0f716451995-11-28 11:22:13 -0600514 {
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600515 fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500516 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
517 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Guy Schalnat0f716451995-11-28 11:22:13 -0600518 fclose(fpin);
519 fclose(fpout);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600520 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600521 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500522
523 png_debug(0, "Setting jmpbuf for write struct\n");
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600524#ifdef USE_FAR_KEYWORD
525 png_memcpy(read_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
526 if (setjmp(jmpbuf))
527#else
Guy Schalnate5a37791996-06-05 15:50:50 -0500528 if (setjmp(write_ptr->jmpbuf))
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600529#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600530 {
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600531 fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500532 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
533 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Guy Schalnat0f716451995-11-28 11:22:13 -0600534 fclose(fpin);
535 fclose(fpout);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600536 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600537 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500538
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600539#ifdef USE_FAR_KEYWORD
540 png_memcpy(write_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
541#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500542 png_debug(0, "Initializing input and output streams\n");
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600543#if !defined(PNG_NO_STDIO)
Guy Schalnate5a37791996-06-05 15:50:50 -0500544 png_init_io(read_ptr, fpin);
545 png_init_io(write_ptr, fpout);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600546#else
547 png_set_read_fn(read_ptr, (png_voidp)fpin, png_default_read_data);
548 png_set_write_fn(write_ptr, (png_voidp)fpout, png_default_write_data,
549#if defined(PNG_WRITE_FLUSH_SUPPORTED)
550 png_default_flush);
551#else
552 NULL);
553#endif
554#endif
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600555 if(status_dots_requested == 1)
556 {
557 png_set_write_status_fn(write_ptr, write_row_callback);
558 png_set_read_status_fn(read_ptr, read_row_callback);
559 }
560 else
561 {
562 png_set_write_status_fn(write_ptr, NULL);
563 png_set_read_status_fn(read_ptr, NULL);
564 }
565
566#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
567 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
568 black_pixels=0;
569 png_set_write_user_transform_fn(write_ptr, count_black_pixels);
570#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500571
Andreas Dilger47a0c421997-05-16 02:46:07 -0500572 png_debug(0, "Reading info struct\n");
573 png_read_info(read_ptr, read_info_ptr);
Guy Schalnat0d580581995-07-20 02:43:20 -0500574
Andreas Dilger47a0c421997-05-16 02:46:07 -0500575 png_debug(0, "Transferring info struct\n");
576 {
577 int interlace_type, compression_type, filter_type;
Guy Schalnat0d580581995-07-20 02:43:20 -0500578
Andreas Dilger47a0c421997-05-16 02:46:07 -0500579 if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
580 &color_type, &interlace_type, &compression_type, &filter_type))
581 {
582 png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600583#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500584 color_type, interlace_type, compression_type, filter_type);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600585#else
586 color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
587#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500588 }
589 }
590#if defined(PNG_READ_bKGD_SUPPORTED) && defined(PNG_WRITE_bKGD_SUPPORTED)
591 {
592 png_color_16p background;
593
594 if (png_get_bKGD(read_ptr, read_info_ptr, &background))
595 {
596 png_set_bKGD(write_ptr, write_info_ptr, background);
597 }
598 }
599#endif
600#if defined(PNG_READ_cHRM_SUPPORTED) && defined(PNG_WRITE_cHRM_SUPPORTED)
601 {
602 double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
603
604 if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
605 &red_y, &green_x, &green_y, &blue_x, &blue_y))
606 {
607 png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
608 red_y, green_x, green_y, blue_x, blue_y);
609 }
610 }
611#endif
612#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_WRITE_gAMA_SUPPORTED)
613 {
614 double gamma;
615
616 if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
617 {
618 png_set_gAMA(write_ptr, write_info_ptr, gamma);
619 }
620 }
621#endif
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600622#if defined(PNG_READ_sRGB_SUPPORTED) && defined(PNG_WRITE_sRGB_SUPPORTED)
623 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600624 int intent;
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600625
626 if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
627 {
628 png_set_sRGB(write_ptr, write_info_ptr, intent);
629 }
630 }
631#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500632#if defined(PNG_READ_hIST_SUPPORTED) && defined(PNG_WRITE_hIST_SUPPORTED)
633 {
634 png_uint_16p hist;
635
636 if (png_get_hIST(read_ptr, read_info_ptr, &hist))
637 {
638 png_set_hIST(write_ptr, write_info_ptr, hist);
639 }
640 }
641#endif
642#if defined(PNG_READ_oFFs_SUPPORTED) && defined(PNG_WRITE_oFFs_SUPPORTED)
643 {
644 png_uint_32 offset_x, offset_y;
645 int unit_type;
646
647 if (png_get_oFFs(read_ptr, read_info_ptr,&offset_x,&offset_y,&unit_type))
648 {
649 png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
650 }
651 }
652#endif
653#if defined(PNG_READ_pCAL_SUPPORTED) && defined(PNG_WRITE_pCAL_SUPPORTED)
654 {
655 png_charp purpose, units;
656 png_charpp params;
657 png_int_32 X0, X1;
658 int type, nparams;
659
660 if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
661 &nparams, &units, &params))
662 {
663 png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
664 nparams, units, params);
665 }
666 }
667#endif
668#if defined(PNG_READ_pHYs_SUPPORTED) && defined(PNG_WRITE_pHYs_SUPPORTED)
669 {
670 png_uint_32 res_x, res_y;
671 int unit_type;
672
673 if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
674 {
675 png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
676 }
677 }
678#endif
679 {
680 png_colorp palette;
681 int num_palette;
682
683 if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
684 {
685 png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
686 }
687 }
688#if defined(PNG_READ_sBIT_SUPPORTED) && defined(PNG_WRITE_sBIT_SUPPORTED)
689 {
690 png_color_8p sig_bit;
691
692 if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
693 {
694 png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
695 }
696 }
697#endif
698#if (defined(PNG_READ_tEXt_SUPPORTED) && defined(PNG_WRITE_tEXt_SUPPORTED)) || \
699 (defined(PNG_READ_zTXt_SUPPORTED) && defined(PNG_WRITE_zTXt_SUPPORTED))
700 {
701 png_textp text_ptr;
702 int num_text;
703
704 if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
705 {
706 png_debug1(0, "Handling %d tEXt/zTXt chunks\n", num_text);
707 png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
708 }
709 }
710#endif
711#if defined(PNG_READ_tIME_SUPPORTED) && defined(PNG_WRITE_tIME_SUPPORTED)
712 {
713 png_timep mod_time;
714
715 if (png_get_tIME(read_ptr, read_info_ptr, &mod_time))
716 {
717 png_set_tIME(write_ptr, write_info_ptr, mod_time);
718 }
719 }
720#endif
721#if defined(PNG_READ_tRNS_SUPPORTED) && defined(PNG_WRITE_tRNS_SUPPORTED)
722 {
723 png_bytep trans;
724 int num_trans;
725 png_color_16p trans_values;
726
727 if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans,
728 &trans_values))
729 {
730 png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans,
731 trans_values);
732 }
733 }
734#endif
735
736 png_debug(0, "\nWriting info struct\n");
737 png_write_info(write_ptr, write_info_ptr);
738
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600739 png_debug(0, "\nAllocating row buffer \n");
Andreas Dilger47a0c421997-05-16 02:46:07 -0500740 row_buf = (png_bytep)png_malloc(read_ptr,
741 png_get_rowbytes(read_ptr, read_info_ptr));
742 if (row_buf == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -0600743 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500744 fprintf(STDERR, "No memory to allocate row buffer\n");
Andreas Dilger47a0c421997-05-16 02:46:07 -0500745 png_destroy_read_struct(&read_ptr, &read_info_ptr, (png_infopp)NULL);
746 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Guy Schalnat0f716451995-11-28 11:22:13 -0600747 fclose(fpin);
748 fclose(fpout);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600749 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600750 }
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600751 png_debug(0, "Writing row data\n");
Guy Schalnat0d580581995-07-20 02:43:20 -0500752
Andreas Dilger47a0c421997-05-16 02:46:07 -0500753 num_pass = png_set_interlace_handling(read_ptr);
754 png_set_interlace_handling(write_ptr);
Guy Schalnat0d580581995-07-20 02:43:20 -0500755
Guy Schalnat0f716451995-11-28 11:22:13 -0600756 for (pass = 0; pass < num_pass; pass++)
757 {
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600758 png_debug1(0, "Writing row data for pass %d\n",pass);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500759 for (y = 0; y < height; y++)
Guy Schalnat0f716451995-11-28 11:22:13 -0600760 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500761 png_read_rows(read_ptr, (png_bytepp)&row_buf, (png_bytepp)NULL, 1);
Guy Schalnate5a37791996-06-05 15:50:50 -0500762 png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600763 }
764 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500765
Andreas Dilger47a0c421997-05-16 02:46:07 -0500766 png_debug(0, "Reading and writing end_info data\n");
767 png_read_end(read_ptr, end_info_ptr);
768 png_write_end(write_ptr, end_info_ptr);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600769
770#ifdef PNG_EASY_ACCESS_SUPPORTED
771 if(verbose)
772 {
773 png_uint_32 iwidth, iheight;
774 iwidth = png_get_image_width(write_ptr, write_info_ptr);
775 iheight = png_get_image_height(write_ptr, write_info_ptr);
776 fprintf(STDERR, "Image width = %lu, height = %lu\n",
777 iwidth, iheight);
778 }
779#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500780
Andreas Dilger47a0c421997-05-16 02:46:07 -0500781 png_debug(0, "Destroying data structs\n");
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600782 png_free(read_ptr, row_buf);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500783 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
784 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Guy Schalnat0d580581995-07-20 02:43:20 -0500785
Guy Schalnat0f716451995-11-28 11:22:13 -0600786 fclose(fpin);
787 fclose(fpout);
Guy Schalnat0d580581995-07-20 02:43:20 -0500788
Andreas Dilger47a0c421997-05-16 02:46:07 -0500789 png_debug(0, "Opening files for comparison\n");
790 if ((fpin = fopen(inname, "rb")) == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -0600791 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500792 fprintf(STDERR, "Could not find file %s\n", inname);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600793 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600794 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500795
Andreas Dilger47a0c421997-05-16 02:46:07 -0500796 if ((fpout = fopen(outname, "rb")) == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -0600797 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500798 fprintf(STDERR, "Could not find file %s\n", outname);
Guy Schalnat0f716451995-11-28 11:22:13 -0600799 fclose(fpin);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600800 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600801 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500802
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600803 for(;;)
Guy Schalnat0f716451995-11-28 11:22:13 -0600804 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500805 png_size_t num_in, num_out;
Guy Schalnat0d580581995-07-20 02:43:20 -0500806
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600807 num_in = fread(inbuf, 1, 1, fpin);
808 num_out = fread(outbuf, 1, 1, fpout);
Guy Schalnat0d580581995-07-20 02:43:20 -0500809
Guy Schalnat0f716451995-11-28 11:22:13 -0600810 if (num_in != num_out)
811 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500812 fprintf(STDERR, "Files %s and %s are of a different size\n",
813 inname, outname);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600814 if(wrote_question == 0)
815 {
816 fprintf(STDERR,
817 " Was %s written with the same chunk size (8k),",inname);
818 fprintf(STDERR,
819 " filtering\n heuristic (libpng default), compression");
820 fprintf(STDERR,
821 " level (zlib default)\n and zlib version (%s)?\n\n",
822 ZLIB_VERSION);
823 wrote_question=1;
824 }
Guy Schalnat0f716451995-11-28 11:22:13 -0600825 fclose(fpin);
826 fclose(fpout);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600827 return (0);
Guy Schalnat0f716451995-11-28 11:22:13 -0600828 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500829
Guy Schalnat0f716451995-11-28 11:22:13 -0600830 if (!num_in)
831 break;
Guy Schalnat0d580581995-07-20 02:43:20 -0500832
Andreas Dilger47a0c421997-05-16 02:46:07 -0500833 if (png_memcmp(inbuf, outbuf, num_in))
Guy Schalnat0f716451995-11-28 11:22:13 -0600834 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500835 fprintf(STDERR, "Files %s and %s are different\n", inname, outname);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600836 if(wrote_question == 0)
837 {
838 fprintf(STDERR,
839 " Was %s written with the same chunk size (8k),",inname);
840 fprintf(STDERR,
841 " filtering\n heuristic (libpng default), compression");
842 fprintf(STDERR,
843 " level (zlib default)\n and zlib version (%s)?\n\n",
844 ZLIB_VERSION);
845 wrote_question=1;
846 }
Guy Schalnat0f716451995-11-28 11:22:13 -0600847 fclose(fpin);
848 fclose(fpout);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600849 return (0);
Guy Schalnat0f716451995-11-28 11:22:13 -0600850 }
851 }
852
853 fclose(fpin);
854 fclose(fpout);
Guy Schalnat0d580581995-07-20 02:43:20 -0500855
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600856 return (0);
Guy Schalnat0d580581995-07-20 02:43:20 -0500857}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500858
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600859/* input and output filenames */
860#ifdef RISCOS
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600861PNG_CONST char *inname = "pngtest/png";
862PNG_CONST char *outname = "pngout/png";
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600863#else
Glenn Randers-Pehrson983ec161998-03-07 11:24:03 -0600864static PNG_CONST char *inname = "pngtest.png";
865static PNG_CONST char *outname = "pngout.png";
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600866#endif
867
868int
869main(int argc, char *argv[])
870{
871 int multiple = 0;
872 int ierror = 0;
873
874 fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600875 fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION);
876
877 /* Do some consistency checking on the memory allocation settings, I'm
878 not sure this matters, but it is nice to know, the first of these
879 tests should be impossible because of the way the macros are set
880 in pngconf.h */
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600881#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600882 fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n");
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600883#endif
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600884 /* I think the following can happen. */
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600885#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600886 fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n");
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600887#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600888
889 if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
890 {
891 fprintf(STDERR,
892 "Warning: versions are different between png.h and png.c\n");
893 fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING);
894 fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver);
895 ++ierror;
896 }
897
898 if (argc > 1)
899 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600900 if (strcmp(argv[1], "-m") == 0)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600901 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600902 multiple = 1;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600903 status_dots_requested = 0;
904 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600905 else if (strcmp(argv[1], "-mv") == 0 ||
906 strcmp(argv[1], "-vm") == 0 )
907 {
908 multiple = 1;
909 verbose = 1;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600910 status_dots_requested = 1;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600911 }
912 else if (strcmp(argv[1], "-v") == 0)
913 {
914 verbose = 1;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600915 status_dots_requested = 1;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600916 inname = argv[2];
917 }
918 else
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600919 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600920 inname = argv[1];
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600921 status_dots_requested = 0;
922 }
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600923 }
924
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600925 if (!multiple && argc == 3+verbose)
926 outname = argv[2+verbose];
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600927
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600928 if ((!multiple && argc > 3+verbose) || (multiple && argc < 2))
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600929 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600930 fprintf(STDERR,
931 "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600932 argv[0], argv[0]);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600933 fprintf(STDERR,
934 " reads/writes one PNG file (without -m) or multiple files (-m)\n");
935 fprintf(STDERR,
936 " with -m %s is used as a temporary file\n", outname);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600937 exit(1);
938 }
939
940 if (multiple)
941 {
942 int i;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600943#ifdef PNGTEST_MEMORY_DEBUG
944 int allocation_now = current_allocation;
945#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600946 for (i=2; i<argc; ++i)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600947 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600948 int kerror;
949 fprintf(STDERR, "Testing %s:",argv[i]);
950 kerror = test_one_file(argv[i], outname);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600951 if (kerror == 0)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600952#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
953 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
954 fprintf(STDERR, " PASS (%lu black pixels)\n",black_pixels);
955#else
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600956 fprintf(STDERR, " PASS\n");
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600957#endif
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600958 else {
959 fprintf(STDERR, " FAIL\n");
960 ierror += kerror;
961 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600962#ifdef PNGTEST_MEMORY_DEBUG
963 if (allocation_now != current_allocation)
964 fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
965 current_allocation-allocation_now);
966 if (current_allocation != 0) {
967 memory_infop pinfo = pinformation;
968
969 fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
970 current_allocation);
971 while (pinfo != NULL) {
972 fprintf(STDERR, " %d bytes at %x\n", pinfo->size, pinfo->pointer);
973 pinfo = pinfo->next;
974 }
Glenn Randers-Pehrson2687fcc1998-01-07 20:54:20 -0600975 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600976#endif
977 }
978#ifdef PNGTEST_MEMORY_DEBUG
979 fprintf(STDERR, "Maximum memory allocation: %d bytes\n",
980 maximum_allocation);
981#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600982 }
983 else
984 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600985 int i;
986 for (i=0; i<3; ++i) {
987 int kerror;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600988#ifdef PNGTEST_MEMORY_DEBUG
989 int allocation_now = current_allocation;
990#endif
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600991 if (i == 1) status_dots_requested = 1;
992 else if(verbose == 0)status_dots_requested = 0;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600993 if (i == 0 || verbose == 1 || ierror != 0)
994 fprintf(STDERR, "Testing %s:",inname);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600995 kerror = test_one_file(inname, outname);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600996 if(kerror == 0)
997 {
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600998 if(verbose == 1 || i == 2)
999#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
1000 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
1001 fprintf(STDERR, " PASS (%lu black pixels)\n",black_pixels);
1002#else
1003 fprintf(STDERR, " PASS\n");
1004#endif
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001005 }
1006 else
1007 {
1008 if(verbose == 0 && i != 2)
1009 fprintf(STDERR, "Testing %s:",inname);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001010 fprintf(STDERR, " FAIL\n");
1011 ierror += kerror;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001012 }
1013#ifdef PNGTEST_MEMORY_DEBUG
1014 if (allocation_now != current_allocation)
1015 fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
1016 current_allocation-allocation_now);
1017 if (current_allocation != 0) {
1018 memory_infop pinfo = pinformation;
1019
1020 fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
1021 current_allocation);
1022 while (pinfo != NULL) {
1023 fprintf(STDERR, " %d bytes at %x\n", pinfo->size, pinfo->pointer);
1024 pinfo = pinfo->next;
1025 }
1026 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001027#endif
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001028 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001029#ifdef PNGTEST_MEMORY_DEBUG
1030 fprintf(STDERR, "Maximum memory allocation: %d bytes\n",
1031 maximum_allocation);
1032#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001033 }
1034
1035 if (ierror == 0)
1036 fprintf(STDERR, "libpng passes test\n");
1037 else
1038 fprintf(STDERR, "libpng FAILS test\n");
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001039 return (int)(ierror != 0);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001040}