blob: 700ad743e80822611f40d306dffeab2cf0b6ce26 [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-Pehrson08a33431998-03-07 06:06:55 -060055void read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
56{
Glenn Randers-Pehrson983ec161998-03-07 11:24:03 -060057 if(png_ptr == NULL || row_number > 0x3fffffffL) return;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060058 if(status_pass != pass)
59 {
60 fprintf(stdout,"\n Pass %d: ",pass);
61 status_pass = pass;
62 status_dots = 30;
63 }
64 status_dots--;
65 if(status_dots == 0)
66 {
67 fprintf(stdout, "\n ");
68 status_dots=30;
69 }
70 fprintf(stdout, "r");
71}
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -060072
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060073void write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
74{
Glenn Randers-Pehrson983ec161998-03-07 11:24:03 -060075 if(png_ptr == NULL || row_number > 0x3fffffffL || pass > 7) return;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060076 fprintf(stdout, "w");
77}
78
79
80#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
81 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
82/* example of using user transform callback (we don't transform anything,
83 but merely count the black pixels) */
84
85static png_uint_32 black_pixels;
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -060086
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060087void count_black_pixels(png_structp png_ptr, png_row_infop row_info,
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -060088 png_bytep data)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060089{
90 png_bytep dp = data;
91 if(png_ptr == NULL)return;
92
93 /* contents of row_info:
94 * png_uint_32 width width of row
95 * png_uint_32 rowbytes number of bytes in row
96 * png_byte color_type color type of pixels
97 * png_byte bit_depth bit depth of samples
98 * png_byte channels number of channels (1-4)
99 * png_byte pixel_depth bits per pixel (depth*channels)
100 */
101
102 /* counts the number of black pixels (or zero pixels if color_type is 3 */
103
104 if(row_info->color_type == 0 || row_info->color_type == 3)
105 {
106 int pos=0;
107 png_uint_32 n;
Glenn Randers-Pehrson983ec161998-03-07 11:24:03 -0600108 for (n=0; n<row_info->width; n++)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600109 {
110 if(row_info->bit_depth == 1)
111 if(((*dp << pos++ )& 0x80) == 0) black_pixels++;
112 if(pos == 8)
113 {
114 pos=0;
115 dp++;
116 }
117 if(row_info->bit_depth == 2)
118 if(((*dp << (pos+=2))& 0xc0) == 0) black_pixels++;
119 if(pos == 8)
120 {
121 pos=0;
122 dp++;
123 }
124 if(row_info->bit_depth == 4)
125 if(((*dp << (pos+=4))& 0xf0) == 0) black_pixels++;
126 if(pos == 8)
127 {
128 pos=0;
129 dp++;
130 }
131 if(row_info->bit_depth == 8)
132 if(*dp++ == 0) black_pixels++;
133 if(row_info->bit_depth == 16)
134 {
135 if((*dp | *(dp+1)) == 0) black_pixels++;
136 dp+=2;
137 }
138 }
139 }
140 else /* other color types */
141 {
142 png_uint_32 n;
143 int channel;
144 int color_channels = row_info->channels;
145 if(row_info->color_type > 3)color_channels--;
146
147 for (n=0; n<row_info->width; n++)
148 {
149 for (channel = 0; channel < color_channels; channel++)
150 {
151 if(row_info->bit_depth == 8)
152 if(*dp++ == 0) black_pixels++;
153 if(row_info->bit_depth == 16)
154 {
155 if((*dp | *(dp+1)) == 0) black_pixels++;
156 dp+=2;
157 }
158 }
159 if(row_info->color_type > 3)
160 {
161 dp++;
162 if(row_info->bit_depth == 16)dp++;
163 }
164 }
165 }
166}
167#endif /* PNG_READ|WRITE_USER_TRANSFORM_SUPPORTED */
168
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600169static int verbose = 0;
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600170static int wrote_question = 0;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600171
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600172#if defined(PNG_NO_STDIO)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600173/* START of code to validate stdio-free compilation */
174/* These copies of the default read/write functions come from pngrio.c and */
175/* pngwio.c. They allow "don't include stdio" testing of the library. */
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600176/* This is the function which does the actual reading of data. If you are
177 not reading from a standard C stream, you should create a replacement
178 read_data function and use it at run time with png_set_read_fn(), rather
179 than changing the library. */
180#ifndef USE_FAR_KEYWORD
181static void
182png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
183{
184 png_size_t check;
185
186 /* fread() returns 0 on error, so it is OK to store this in a png_size_t
187 * instead of an int, which is what fread() actually returns.
188 */
189 check = (png_size_t)fread(data, (png_size_t)1, length,
190 (FILE *)png_ptr->io_ptr);
191
192 if (check != length)
193 {
194 png_error(png_ptr, "Read Error");
195 }
196}
Guy Schalnate5a37791996-06-05 15:50:50 -0500197#else
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600198/* this is the model-independent version. Since the standard I/O library
199 can't handle far buffers in the medium and small models, we have to copy
200 the data.
201*/
202
203#define NEAR_BUF_SIZE 1024
204#define MIN(a,b) (a <= b ? a : b)
205
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600206static void png_default_read_data(png_structp png_ptr, png_bytep data,
207 png_size_t length)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600208{
209 int check;
210 png_byte *n_data;
211 FILE *io_ptr;
212
213 /* Check if data really is near. If so, use usual code. */
214 n_data = (png_byte *)CVT_PTR_NOCHECK(data);
215 io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
216 if ((png_bytep)n_data == data)
217 {
218 check = fread(n_data, 1, length, io_ptr);
219 }
220 else
221 {
222 png_byte buf[NEAR_BUF_SIZE];
223 png_size_t read, remaining, err;
224 check = 0;
225 remaining = length;
226 do
227 {
228 read = MIN(NEAR_BUF_SIZE, remaining);
229 err = fread(buf, (png_size_t)1, read, io_ptr);
230 png_memcpy(data, buf, read); /* copy far buffer to near buffer */
231 if(err != read)
232 break;
233 else
234 check += err;
235 data += read;
236 remaining -= read;
237 }
238 while (remaining != 0);
239 }
240 if (check != length)
241 {
242 png_error(png_ptr, "read Error");
243 }
244}
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600245#endif /* USE_FAR_KEYWORD */
Guy Schalnat0d580581995-07-20 02:43:20 -0500246
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600247#if defined(PNG_WRITE_FLUSH_SUPPORTED)
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600248static void png_default_flush(png_structp png_ptr)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600249{
250 FILE *io_ptr;
251 io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));
252 if (io_ptr != NULL)
253 fflush(io_ptr);
254}
255#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500256
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600257/* This is the function which does the actual writing of data. If you are
258 not writing to a standard C stream, you should create a replacement
259 write_data function and use it at run time with png_set_write_fn(), rather
260 than changing the library. */
261#ifndef USE_FAR_KEYWORD
262static void
263png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
264{
265 png_uint_32 check;
266
267 check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr));
268 if (check != length)
269 {
270 png_error(png_ptr, "Write Error");
271 }
272}
273#else
274/* this is the model-independent version. Since the standard I/O library
275 can't handle far buffers in the medium and small models, we have to copy
276 the data.
277*/
278
279#define NEAR_BUF_SIZE 1024
280#define MIN(a,b) (a <= b ? a : b)
281
282static void
283png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
284{
285 png_uint_32 check;
286 png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
287 FILE *io_ptr;
288
289 /* Check if data really is near. If so, use usual code. */
290 near_data = (png_byte *)CVT_PTR_NOCHECK(data);
291 io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
292 if ((png_bytep)near_data == data)
293 {
294 check = fwrite(near_data, 1, length, io_ptr);
295 }
296 else
297 {
298 png_byte buf[NEAR_BUF_SIZE];
299 png_size_t written, remaining, err;
300 check = 0;
301 remaining = length;
302 do
303 {
304 written = MIN(NEAR_BUF_SIZE, remaining);
305 png_memcpy(buf, data, written); /* copy far buffer to near buffer */
306 err = fwrite(buf, 1, written, io_ptr);
307 if (err != written)
308 break;
309 else
310 check += err;
311 data += written;
312 remaining -= written;
313 }
314 while (remaining != 0);
315 }
316 if (check != length)
317 {
318 png_error(png_ptr, "Write Error");
319 }
320}
321
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600322#endif /* USE_FAR_KEYWORD */
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600323
324/* This function is called when there is a warning, but the library thinks
325 * it can continue anyway. Replacement functions don't have to do anything
326 * here if you don't want to. In the default configuration, png_ptr is
327 * not used, but it is passed in case it may be useful.
328 */
329static void
330png_default_warning(png_structp png_ptr, png_const_charp message)
331{
332 PNG_CONST char *name = "UNKNOWN (ERROR!)";
333 if (png_ptr != NULL && png_ptr->error_ptr != NULL)
334 name = png_ptr->error_ptr;
335 fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
336}
337
338/* This is the default error handling function. Note that replacements for
339 * this function MUST NOT RETURN, or the program will likely crash. This
340 * function is used by default, or if the program supplies NULL for the
341 * error function pointer in png_set_error_fn().
342 */
343static void
344png_default_error(png_structp png_ptr, png_const_charp message)
345{
346 png_default_warning(png_ptr, message);
347 /* We can return because png_error calls the default handler which is
348 * actually ok in this case. */
349}
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600350#endif /* PNG_NO_STDIO */
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600351/* END of code to validate stdio-free compilation */
352
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600353/* START of code to validate memory allocation and deallocation */
354#ifdef PNGTEST_MEMORY_DEBUG
355/* Borland DOS special memory handler */
356#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
357ERROR - memory debugging is not supported on this platform
358#else
359
360/* Allocate memory. For reasonable files, size should never exceed
361 64K. However, zlib may allocate more then 64K if you don't tell
362 it not to. See zconf.h and png.h for more information. zlib does
363 need to allocate exactly 64K, so whatever you call here must
364 have the ability to do that.
365
366 This piece of code can be compiled to validate max 64K allocations
367 by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. */
368typedef struct memory_information {
369 png_uint_32 size;
370 png_voidp pointer;
371 struct memory_information FAR *next;
372} memory_information;
373typedef memory_information FAR *memory_infop;
374
375static memory_infop pinformation = NULL;
376static int current_allocation = 0;
377static int maximum_allocation = 0;
378
379extern PNG_EXPORT(png_voidp,png_debug_malloc) PNGARG((png_structp png_ptr,
380 png_uint_32 size));
381extern PNG_EXPORT(void,png_debug_free) PNGARG((png_structp png_ptr,
382 png_voidp ptr));
383
384png_voidp
385png_malloc(png_structp png_ptr, png_uint_32 size) {
386 if (png_ptr == NULL) {
387 fprintf(STDERR, "NULL pointer to memory allocator\n");
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600388 return (NULL);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600389 }
390 if (size == 0)
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600391 return (png_voidp)(NULL);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600392
393 /* This calls the library allocator twice, once to get the requested
394 buffer and once to get a new free list entry. */
395 {
396 memory_infop pinfo = png_debug_malloc(png_ptr, sizeof *pinfo);
397 pinfo->size = size;
398 current_allocation += size;
399 if (current_allocation > maximum_allocation)
400 maximum_allocation = current_allocation;
401 pinfo->pointer = png_debug_malloc(png_ptr, size);
402 pinfo->next = pinformation;
403 pinformation = pinfo;
404 /* Make sure the caller isn't assuming zeroed memory. */
405 png_memset(pinfo->pointer, 0xdd, pinfo->size);
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600406 return (png_voidp)(pinfo->pointer);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600407 }
408}
409
410/* Free a pointer. It is removed from the list at the same time. */
411void
412png_free(png_structp png_ptr, png_voidp ptr)
413{
414 if (png_ptr == NULL)
415 fprintf(STDERR, "NULL pointer to memory allocator\n");
416 if (ptr == 0) {
417#if 0 /* This happens all the time. */
418 fprintf(STDERR, "WARNING: freeing NULL pointer\n");
419#endif
420 return;
421 }
422
423 /* Unlink the element from the list. */
424 {
425 memory_infop FAR *ppinfo = &pinformation;
426 for (;;) {
427 memory_infop pinfo = *ppinfo;
428 if (pinfo->pointer == ptr) {
429 *ppinfo = pinfo->next;
430 current_allocation -= pinfo->size;
431 if (current_allocation < 0)
432 fprintf(STDERR, "Duplicate free of memory\n");
433 /* We must free the list element too, but first kill
434 the memory which is to be freed. */
435 memset(ptr, 0x55, pinfo->size);
436 png_debug_free(png_ptr, pinfo);
437 break;
438 }
439 if (pinfo->next == NULL) {
440 fprintf(STDERR, "Pointer %x not found\n", ptr);
441 break;
442 }
443 ppinfo = &pinfo->next;
444 }
445 }
446
447 /* Finally free the data. */
448 png_debug_free(png_ptr, ptr);
449}
450#endif /* Not Borland DOS special memory handler */
451#endif
452/* END of code to test memory allocation/deallocation */
453
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600454/* Test one file */
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600455int test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
Guy Schalnat0d580581995-07-20 02:43:20 -0500456{
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600457 static FILE *fpin, *fpout; /* "static" prevents setjmp corruption */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500458 png_structp read_ptr, write_ptr;
459 png_infop read_info_ptr, write_info_ptr, end_info_ptr;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600460 png_bytep row_buf;
Guy Schalnat0d580581995-07-20 02:43:20 -0500461 png_uint_32 y;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500462 png_uint_32 width, height;
463 int num_pass, pass;
464 int bit_depth, color_type;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600465#ifdef USE_FAR_KEYWORD
466 jmp_buf jmpbuf;
467#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600468
469 char inbuf[256], outbuf[256];
470
Guy Schalnate5a37791996-06-05 15:50:50 -0500471 row_buf = (png_bytep)NULL;
Guy Schalnat0d580581995-07-20 02:43:20 -0500472
Andreas Dilger47a0c421997-05-16 02:46:07 -0500473 if ((fpin = fopen(inname, "rb")) == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -0600474 {
475 fprintf(STDERR, "Could not find input file %s\n", inname);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600476 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600477 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500478
Andreas Dilger47a0c421997-05-16 02:46:07 -0500479 if ((fpout = fopen(outname, "wb")) == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -0600480 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500481 fprintf(STDERR, "Could not open output file %s\n", outname);
Guy Schalnat0f716451995-11-28 11:22:13 -0600482 fclose(fpin);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600483 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600484 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500485
Andreas Dilger47a0c421997-05-16 02:46:07 -0500486 png_debug(0, "Allocating read and write structures\n");
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600487 read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
Andreas Dilger47a0c421997-05-16 02:46:07 -0500488 (png_error_ptr)NULL, (png_error_ptr)NULL);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600489#if defined(PNG_NO_STDIO)
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600490 png_set_error_fn(read_ptr, (png_voidp)inname, png_default_error,
491 png_default_warning);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600492#endif
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600493 write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
Guy Schalnate5a37791996-06-05 15:50:50 -0500494 (png_error_ptr)NULL, (png_error_ptr)NULL);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600495#if defined(PNG_NO_STDIO)
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600496 png_set_error_fn(write_ptr, (png_voidp)inname, png_default_error,
497 png_default_warning);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600498#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500499 png_debug(0, "Allocating read_info, write_info and end_info structures\n");
500 read_info_ptr = png_create_info_struct(read_ptr);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600501 write_info_ptr = png_create_info_struct(write_ptr);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500502 end_info_ptr = png_create_info_struct(read_ptr);
Guy Schalnate5a37791996-06-05 15:50:50 -0500503
Andreas Dilger47a0c421997-05-16 02:46:07 -0500504 png_debug(0, "Setting jmpbuf for read struct\n");
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600505#ifdef USE_FAR_KEYWORD
506 if (setjmp(jmpbuf))
507#else
Guy Schalnate5a37791996-06-05 15:50:50 -0500508 if (setjmp(read_ptr->jmpbuf))
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600509#endif
Guy Schalnat0f716451995-11-28 11:22:13 -0600510 {
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600511 fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500512 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
513 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Guy Schalnat0f716451995-11-28 11:22:13 -0600514 fclose(fpin);
515 fclose(fpout);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600516 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600517 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500518
519 png_debug(0, "Setting jmpbuf for write struct\n");
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600520#ifdef USE_FAR_KEYWORD
521 png_memcpy(read_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
522 if (setjmp(jmpbuf))
523#else
Guy Schalnate5a37791996-06-05 15:50:50 -0500524 if (setjmp(write_ptr->jmpbuf))
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600525#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600526 {
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600527 fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500528 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
529 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Guy Schalnat0f716451995-11-28 11:22:13 -0600530 fclose(fpin);
531 fclose(fpout);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600532 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600533 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500534
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600535#ifdef USE_FAR_KEYWORD
536 png_memcpy(write_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
537#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500538 png_debug(0, "Initializing input and output streams\n");
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600539#if !defined(PNG_NO_STDIO)
Guy Schalnate5a37791996-06-05 15:50:50 -0500540 png_init_io(read_ptr, fpin);
541 png_init_io(write_ptr, fpout);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600542#else
543 png_set_read_fn(read_ptr, (png_voidp)fpin, png_default_read_data);
544 png_set_write_fn(write_ptr, (png_voidp)fpout, png_default_write_data,
545#if defined(PNG_WRITE_FLUSH_SUPPORTED)
546 png_default_flush);
547#else
548 NULL);
549#endif
550#endif
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600551 if(status_dots_requested == 1)
552 {
553 png_set_write_status_fn(write_ptr, write_row_callback);
554 png_set_read_status_fn(read_ptr, read_row_callback);
555 }
556 else
557 {
558 png_set_write_status_fn(write_ptr, NULL);
559 png_set_read_status_fn(read_ptr, NULL);
560 }
561
562#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
563 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
564 black_pixels=0;
565 png_set_write_user_transform_fn(write_ptr, count_black_pixels);
566#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500567
Andreas Dilger47a0c421997-05-16 02:46:07 -0500568 png_debug(0, "Reading info struct\n");
569 png_read_info(read_ptr, read_info_ptr);
Guy Schalnat0d580581995-07-20 02:43:20 -0500570
Andreas Dilger47a0c421997-05-16 02:46:07 -0500571 png_debug(0, "Transferring info struct\n");
572 {
573 int interlace_type, compression_type, filter_type;
Guy Schalnat0d580581995-07-20 02:43:20 -0500574
Andreas Dilger47a0c421997-05-16 02:46:07 -0500575 if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
576 &color_type, &interlace_type, &compression_type, &filter_type))
577 {
578 png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600579#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500580 color_type, interlace_type, compression_type, filter_type);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600581#else
582 color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
583#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500584 }
585 }
586#if defined(PNG_READ_bKGD_SUPPORTED) && defined(PNG_WRITE_bKGD_SUPPORTED)
587 {
588 png_color_16p background;
589
590 if (png_get_bKGD(read_ptr, read_info_ptr, &background))
591 {
592 png_set_bKGD(write_ptr, write_info_ptr, background);
593 }
594 }
595#endif
596#if defined(PNG_READ_cHRM_SUPPORTED) && defined(PNG_WRITE_cHRM_SUPPORTED)
597 {
598 double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
599
600 if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
601 &red_y, &green_x, &green_y, &blue_x, &blue_y))
602 {
603 png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
604 red_y, green_x, green_y, blue_x, blue_y);
605 }
606 }
607#endif
608#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_WRITE_gAMA_SUPPORTED)
609 {
610 double gamma;
611
612 if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
613 {
614 png_set_gAMA(write_ptr, write_info_ptr, gamma);
615 }
616 }
617#endif
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600618#if defined(PNG_READ_sRGB_SUPPORTED) && defined(PNG_WRITE_sRGB_SUPPORTED)
619 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600620 int intent;
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600621
622 if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
623 {
624 png_set_sRGB(write_ptr, write_info_ptr, intent);
625 }
626 }
627#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500628#if defined(PNG_READ_hIST_SUPPORTED) && defined(PNG_WRITE_hIST_SUPPORTED)
629 {
630 png_uint_16p hist;
631
632 if (png_get_hIST(read_ptr, read_info_ptr, &hist))
633 {
634 png_set_hIST(write_ptr, write_info_ptr, hist);
635 }
636 }
637#endif
638#if defined(PNG_READ_oFFs_SUPPORTED) && defined(PNG_WRITE_oFFs_SUPPORTED)
639 {
640 png_uint_32 offset_x, offset_y;
641 int unit_type;
642
643 if (png_get_oFFs(read_ptr, read_info_ptr,&offset_x,&offset_y,&unit_type))
644 {
645 png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
646 }
647 }
648#endif
649#if defined(PNG_READ_pCAL_SUPPORTED) && defined(PNG_WRITE_pCAL_SUPPORTED)
650 {
651 png_charp purpose, units;
652 png_charpp params;
653 png_int_32 X0, X1;
654 int type, nparams;
655
656 if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
657 &nparams, &units, &params))
658 {
659 png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
660 nparams, units, params);
661 }
662 }
663#endif
664#if defined(PNG_READ_pHYs_SUPPORTED) && defined(PNG_WRITE_pHYs_SUPPORTED)
665 {
666 png_uint_32 res_x, res_y;
667 int unit_type;
668
669 if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
670 {
671 png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
672 }
673 }
674#endif
675 {
676 png_colorp palette;
677 int num_palette;
678
679 if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
680 {
681 png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
682 }
683 }
684#if defined(PNG_READ_sBIT_SUPPORTED) && defined(PNG_WRITE_sBIT_SUPPORTED)
685 {
686 png_color_8p sig_bit;
687
688 if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
689 {
690 png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
691 }
692 }
693#endif
694#if (defined(PNG_READ_tEXt_SUPPORTED) && defined(PNG_WRITE_tEXt_SUPPORTED)) || \
695 (defined(PNG_READ_zTXt_SUPPORTED) && defined(PNG_WRITE_zTXt_SUPPORTED))
696 {
697 png_textp text_ptr;
698 int num_text;
699
700 if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
701 {
702 png_debug1(0, "Handling %d tEXt/zTXt chunks\n", num_text);
703 png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
704 }
705 }
706#endif
707#if defined(PNG_READ_tIME_SUPPORTED) && defined(PNG_WRITE_tIME_SUPPORTED)
708 {
709 png_timep mod_time;
710
711 if (png_get_tIME(read_ptr, read_info_ptr, &mod_time))
712 {
713 png_set_tIME(write_ptr, write_info_ptr, mod_time);
714 }
715 }
716#endif
717#if defined(PNG_READ_tRNS_SUPPORTED) && defined(PNG_WRITE_tRNS_SUPPORTED)
718 {
719 png_bytep trans;
720 int num_trans;
721 png_color_16p trans_values;
722
723 if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans,
724 &trans_values))
725 {
726 png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans,
727 trans_values);
728 }
729 }
730#endif
731
732 png_debug(0, "\nWriting info struct\n");
733 png_write_info(write_ptr, write_info_ptr);
734
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600735 png_debug(0, "\nAllocating row buffer \n");
Andreas Dilger47a0c421997-05-16 02:46:07 -0500736 row_buf = (png_bytep)png_malloc(read_ptr,
737 png_get_rowbytes(read_ptr, read_info_ptr));
738 if (row_buf == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -0600739 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500740 fprintf(STDERR, "No memory to allocate row buffer\n");
Andreas Dilger47a0c421997-05-16 02:46:07 -0500741 png_destroy_read_struct(&read_ptr, &read_info_ptr, (png_infopp)NULL);
742 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Guy Schalnat0f716451995-11-28 11:22:13 -0600743 fclose(fpin);
744 fclose(fpout);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600745 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600746 }
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600747 png_debug(0, "Writing row data\n");
Guy Schalnat0d580581995-07-20 02:43:20 -0500748
Andreas Dilger47a0c421997-05-16 02:46:07 -0500749 num_pass = png_set_interlace_handling(read_ptr);
750 png_set_interlace_handling(write_ptr);
Guy Schalnat0d580581995-07-20 02:43:20 -0500751
Guy Schalnat0f716451995-11-28 11:22:13 -0600752 for (pass = 0; pass < num_pass; pass++)
753 {
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600754 png_debug1(0, "Writing row data for pass %d\n",pass);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500755 for (y = 0; y < height; y++)
Guy Schalnat0f716451995-11-28 11:22:13 -0600756 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500757 png_read_rows(read_ptr, (png_bytepp)&row_buf, (png_bytepp)NULL, 1);
Guy Schalnate5a37791996-06-05 15:50:50 -0500758 png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600759 }
760 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500761
Andreas Dilger47a0c421997-05-16 02:46:07 -0500762 png_debug(0, "Reading and writing end_info data\n");
763 png_read_end(read_ptr, end_info_ptr);
764 png_write_end(write_ptr, end_info_ptr);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600765
766#ifdef PNG_EASY_ACCESS_SUPPORTED
767 if(verbose)
768 {
769 png_uint_32 iwidth, iheight;
770 iwidth = png_get_image_width(write_ptr, write_info_ptr);
771 iheight = png_get_image_height(write_ptr, write_info_ptr);
772 fprintf(STDERR, "Image width = %lu, height = %lu\n",
773 iwidth, iheight);
774 }
775#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500776
Andreas Dilger47a0c421997-05-16 02:46:07 -0500777 png_debug(0, "Destroying data structs\n");
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600778 png_free(read_ptr, row_buf);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500779 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
780 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Guy Schalnat0d580581995-07-20 02:43:20 -0500781
Guy Schalnat0f716451995-11-28 11:22:13 -0600782 fclose(fpin);
783 fclose(fpout);
Guy Schalnat0d580581995-07-20 02:43:20 -0500784
Andreas Dilger47a0c421997-05-16 02:46:07 -0500785 png_debug(0, "Opening files for comparison\n");
786 if ((fpin = fopen(inname, "rb")) == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -0600787 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500788 fprintf(STDERR, "Could not find file %s\n", inname);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600789 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600790 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500791
Andreas Dilger47a0c421997-05-16 02:46:07 -0500792 if ((fpout = fopen(outname, "rb")) == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -0600793 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500794 fprintf(STDERR, "Could not find file %s\n", outname);
Guy Schalnat0f716451995-11-28 11:22:13 -0600795 fclose(fpin);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600796 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600797 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500798
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600799 for(;;)
Guy Schalnat0f716451995-11-28 11:22:13 -0600800 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500801 png_size_t num_in, num_out;
Guy Schalnat0d580581995-07-20 02:43:20 -0500802
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600803 num_in = fread(inbuf, 1, 1, fpin);
804 num_out = fread(outbuf, 1, 1, fpout);
Guy Schalnat0d580581995-07-20 02:43:20 -0500805
Guy Schalnat0f716451995-11-28 11:22:13 -0600806 if (num_in != num_out)
807 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500808 fprintf(STDERR, "Files %s and %s are of a different size\n",
809 inname, outname);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600810 if(wrote_question == 0)
811 {
812 fprintf(STDERR,
813 " Was %s written with the same chunk size (8k),",inname);
814 fprintf(STDERR,
815 " filtering\n heuristic (libpng default), compression");
816 fprintf(STDERR,
817 " level (zlib default)\n and zlib version (%s)?\n\n",
818 ZLIB_VERSION);
819 wrote_question=1;
820 }
Guy Schalnat0f716451995-11-28 11:22:13 -0600821 fclose(fpin);
822 fclose(fpout);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600823 return (0);
Guy Schalnat0f716451995-11-28 11:22:13 -0600824 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500825
Guy Schalnat0f716451995-11-28 11:22:13 -0600826 if (!num_in)
827 break;
Guy Schalnat0d580581995-07-20 02:43:20 -0500828
Andreas Dilger47a0c421997-05-16 02:46:07 -0500829 if (png_memcmp(inbuf, outbuf, num_in))
Guy Schalnat0f716451995-11-28 11:22:13 -0600830 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500831 fprintf(STDERR, "Files %s and %s are different\n", inname, outname);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600832 if(wrote_question == 0)
833 {
834 fprintf(STDERR,
835 " Was %s written with the same chunk size (8k),",inname);
836 fprintf(STDERR,
837 " filtering\n heuristic (libpng default), compression");
838 fprintf(STDERR,
839 " level (zlib default)\n and zlib version (%s)?\n\n",
840 ZLIB_VERSION);
841 wrote_question=1;
842 }
Guy Schalnat0f716451995-11-28 11:22:13 -0600843 fclose(fpin);
844 fclose(fpout);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600845 return (0);
Guy Schalnat0f716451995-11-28 11:22:13 -0600846 }
847 }
848
849 fclose(fpin);
850 fclose(fpout);
Guy Schalnat0d580581995-07-20 02:43:20 -0500851
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600852 return (0);
Guy Schalnat0d580581995-07-20 02:43:20 -0500853}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500854
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600855/* input and output filenames */
856#ifdef RISCOS
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600857PNG_CONST char *inname = "pngtest/png";
858PNG_CONST char *outname = "pngout/png";
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600859#else
Glenn Randers-Pehrson983ec161998-03-07 11:24:03 -0600860static PNG_CONST char *inname = "pngtest.png";
861static PNG_CONST char *outname = "pngout.png";
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600862#endif
863
864int
865main(int argc, char *argv[])
866{
867 int multiple = 0;
868 int ierror = 0;
869
870 fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600871 fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION);
872
873 /* Do some consistency checking on the memory allocation settings, I'm
874 not sure this matters, but it is nice to know, the first of these
875 tests should be impossible because of the way the macros are set
876 in pngconf.h */
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600877#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600878 fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n");
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600879#endif
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600880 /* I think the following can happen. */
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: libpng compiled for max 64k, zlib not\n");
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600883#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600884
885 if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
886 {
887 fprintf(STDERR,
888 "Warning: versions are different between png.h and png.c\n");
889 fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING);
890 fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver);
891 ++ierror;
892 }
893
894 if (argc > 1)
895 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600896 if (strcmp(argv[1], "-m") == 0)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600897 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600898 multiple = 1;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600899 status_dots_requested = 0;
900 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600901 else if (strcmp(argv[1], "-mv") == 0 ||
902 strcmp(argv[1], "-vm") == 0 )
903 {
904 multiple = 1;
905 verbose = 1;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600906 status_dots_requested = 1;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600907 }
908 else if (strcmp(argv[1], "-v") == 0)
909 {
910 verbose = 1;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600911 status_dots_requested = 1;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600912 inname = argv[2];
913 }
914 else
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600915 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600916 inname = argv[1];
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600917 status_dots_requested = 0;
918 }
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600919 }
920
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600921 if (!multiple && argc == 3+verbose)
922 outname = argv[2+verbose];
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600923
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600924 if ((!multiple && argc > 3+verbose) || (multiple && argc < 2))
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600925 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600926 fprintf(STDERR,
927 "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600928 argv[0], argv[0]);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600929 fprintf(STDERR,
930 " reads/writes one PNG file (without -m) or multiple files (-m)\n");
931 fprintf(STDERR,
932 " with -m %s is used as a temporary file\n", outname);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600933 exit(1);
934 }
935
936 if (multiple)
937 {
938 int i;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600939#ifdef PNGTEST_MEMORY_DEBUG
940 int allocation_now = current_allocation;
941#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600942 for (i=2; i<argc; ++i)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600943 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600944 int kerror;
945 fprintf(STDERR, "Testing %s:",argv[i]);
946 kerror = test_one_file(argv[i], outname);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600947 if (kerror == 0)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600948#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
949 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
950 fprintf(STDERR, " PASS (%lu black pixels)\n",black_pixels);
951#else
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600952 fprintf(STDERR, " PASS\n");
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600953#endif
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600954 else {
955 fprintf(STDERR, " FAIL\n");
956 ierror += kerror;
957 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600958#ifdef PNGTEST_MEMORY_DEBUG
959 if (allocation_now != current_allocation)
960 fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
961 current_allocation-allocation_now);
962 if (current_allocation != 0) {
963 memory_infop pinfo = pinformation;
964
965 fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
966 current_allocation);
967 while (pinfo != NULL) {
968 fprintf(STDERR, " %d bytes at %x\n", pinfo->size, pinfo->pointer);
969 pinfo = pinfo->next;
970 }
Glenn Randers-Pehrson2687fcc1998-01-07 20:54:20 -0600971 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600972#endif
973 }
974#ifdef PNGTEST_MEMORY_DEBUG
975 fprintf(STDERR, "Maximum memory allocation: %d bytes\n",
976 maximum_allocation);
977#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600978 }
979 else
980 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600981 int i;
982 for (i=0; i<3; ++i) {
983 int kerror;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600984#ifdef PNGTEST_MEMORY_DEBUG
985 int allocation_now = current_allocation;
986#endif
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600987 if (i == 1) status_dots_requested = 1;
988 else if(verbose == 0)status_dots_requested = 0;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600989 if (i == 0 || verbose == 1 || ierror != 0)
990 fprintf(STDERR, "Testing %s:",inname);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600991 kerror = test_one_file(inname, outname);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600992 if(kerror == 0)
993 {
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600994 if(verbose == 1 || i == 2)
995#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
996 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
997 fprintf(STDERR, " PASS (%lu black pixels)\n",black_pixels);
998#else
999 fprintf(STDERR, " PASS\n");
1000#endif
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001001 }
1002 else
1003 {
1004 if(verbose == 0 && i != 2)
1005 fprintf(STDERR, "Testing %s:",inname);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001006 fprintf(STDERR, " FAIL\n");
1007 ierror += kerror;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001008 }
1009#ifdef PNGTEST_MEMORY_DEBUG
1010 if (allocation_now != current_allocation)
1011 fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
1012 current_allocation-allocation_now);
1013 if (current_allocation != 0) {
1014 memory_infop pinfo = pinformation;
1015
1016 fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
1017 current_allocation);
1018 while (pinfo != NULL) {
1019 fprintf(STDERR, " %d bytes at %x\n", pinfo->size, pinfo->pointer);
1020 pinfo = pinfo->next;
1021 }
1022 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001023#endif
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001024 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001025#ifdef PNGTEST_MEMORY_DEBUG
1026 fprintf(STDERR, "Maximum memory allocation: %d bytes\n",
1027 maximum_allocation);
1028#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001029 }
1030
1031 if (ierror == 0)
1032 fprintf(STDERR, "libpng passes test\n");
1033 else
1034 fprintf(STDERR, "libpng FAILS test\n");
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001035 return (int)(ierror != 0);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001036}