blob: cff2362536edd3a28e373a3d16cbc897cbf465c7 [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-Pehrsonf8b008c1999-09-18 10:54:36 -05004 * libpng 1.0.4 - September 18, 1999
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-Pehrsonc9442291999-01-06 21:50:16 -06008 * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06009 *
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 *
Glenn Randers-Pehrson345bc271998-06-14 14:43:31 -050016 * The program will report "FAIL" in certain legitimate cases:
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060017 * 1) when the compression level or filter selection method is changed.
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050018 * 2) when the chunk size is not 8K.
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060019 * 3) unknown ancillary chunks exist in the input file.
20 * 4) others not listed here...
21 * In these cases, it is best to check with another tool such as "pngcheck"
22 * to see what the differences between the two images are.
23 *
24 * If a filename is given on the command-line, then this file is used
25 * for the input, rather than the default "pngtest.png". This allows
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050026 * testing a wide variety of files easily. You can also test a number
27 * of files at once by typing "pngtest -m file1.png file2.png ..."
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060028 */
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-Pehrsonf7d1a171998-06-06 15:31:35 -050040#if defined(PNG_TIME_RFC1123_SUPPORTED)
41static int tIME_chunk_present=0;
Glenn Randers-Pehrson345bc271998-06-14 14:43:31 -050042static char tIME_string[30] = "no tIME chunk present in file";
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050043#endif /* PNG_TIME_RFC1123_SUPPORTED */
44
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -050045static int verbose = 0;
46
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -060047int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname));
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -060048
Guy Schalnat0d580581995-07-20 02:43:20 -050049#ifdef __TURBOC__
50#include <mem.h>
51#endif
52
53/* defined so I can write to a file on gui/windowing platforms */
Guy Schalnat6d764711995-12-19 03:22:19 -060054/* #define STDERR stderr */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060055#define STDERR stdout /* for DOS */
Guy Schalnat0d580581995-07-20 02:43:20 -050056
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060057/* example of using row callbacks to make a simple progress meter */
58static int status_pass=1;
59static int status_dots_requested=0;
60static int status_dots=1;
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -060061
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -060062void
63read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060064{
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -050065 if(png_ptr == NULL || row_number > PNG_MAX_UINT) return;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060066 if(status_pass != pass)
67 {
68 fprintf(stdout,"\n Pass %d: ",pass);
69 status_pass = pass;
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -050070 status_dots = 31;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060071 }
72 status_dots--;
73 if(status_dots == 0)
74 {
75 fprintf(stdout, "\n ");
76 status_dots=30;
77 }
78 fprintf(stdout, "r");
79}
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -060080
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -060081void
82write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060083{
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -050084 if(png_ptr == NULL || row_number > PNG_MAX_UINT || pass > 7) return;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060085 fprintf(stdout, "w");
86}
87
88
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -050089#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
90/* Example of using user transform callback (we don't transform anything,
91 but merely examine the row filters. We set this to 256 rather than
92 5 in case illegal filter values are present.) */
93static png_uint_32 filters_used[256];
94void
95count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data)
96{
97 if(png_ptr != NULL && row_info != NULL)
98 ++filters_used[*(data-1)];
99}
100#endif
101
Glenn Randers-Pehrson38d73af1998-03-07 21:30:44 -0600102#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600103/* example of using user transform callback (we don't transform anything,
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500104 but merely count the zero samples) */
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600105
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500106static png_uint_32 zero_samples;
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600107
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600108void
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500109count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600110{
111 png_bytep dp = data;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600112 if(png_ptr == NULL)return;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600113
114 /* contents of row_info:
115 * png_uint_32 width width of row
116 * png_uint_32 rowbytes number of bytes in row
117 * png_byte color_type color type of pixels
118 * png_byte bit_depth bit depth of samples
119 * png_byte channels number of channels (1-4)
120 * png_byte pixel_depth bits per pixel (depth*channels)
121 */
122
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500123
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500124 /* counts the number of zero samples (or zero pixels if color_type is 3 */
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600125
126 if(row_info->color_type == 0 || row_info->color_type == 3)
127 {
128 int pos=0;
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500129 png_uint_32 n, nstop;
130 for (n=0, nstop=row_info->width; n<nstop; n++)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600131 {
132 if(row_info->bit_depth == 1)
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500133 {
134 if(((*dp << pos++ )& 0x80) == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600135 if(pos == 8)
136 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500137 pos = 0;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600138 dp++;
139 }
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500140 }
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600141 if(row_info->bit_depth == 2)
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500142 {
143 if(((*dp << (pos+=2))& 0xc0) == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600144 if(pos == 8)
145 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500146 pos = 0;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600147 dp++;
148 }
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500149 }
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600150 if(row_info->bit_depth == 4)
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500151 {
152 if(((*dp << (pos+=4))& 0xf0) == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600153 if(pos == 8)
154 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500155 pos = 0;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600156 dp++;
157 }
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500158 }
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600159 if(row_info->bit_depth == 8)
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500160 if(*dp++ == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600161 if(row_info->bit_depth == 16)
162 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500163 if((*dp | *(dp+1)) == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600164 dp+=2;
165 }
166 }
167 }
168 else /* other color types */
169 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500170 png_uint_32 n, nstop;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600171 int channel;
172 int color_channels = row_info->channels;
173 if(row_info->color_type > 3)color_channels--;
174
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500175 for (n=0, nstop=row_info->width; n<nstop; n++)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600176 {
177 for (channel = 0; channel < color_channels; channel++)
178 {
179 if(row_info->bit_depth == 8)
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500180 if(*dp++ == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600181 if(row_info->bit_depth == 16)
182 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500183 if((*dp | *(dp+1)) == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600184 dp+=2;
185 }
186 }
187 if(row_info->color_type > 3)
188 {
189 dp++;
190 if(row_info->bit_depth == 16)dp++;
191 }
192 }
193 }
194}
Glenn Randers-Pehrson38d73af1998-03-07 21:30:44 -0600195#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600196
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600197static int wrote_question = 0;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600198
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600199#if defined(PNG_NO_STDIO)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600200/* START of code to validate stdio-free compilation */
201/* These copies of the default read/write functions come from pngrio.c and */
202/* pngwio.c. They allow "don't include stdio" testing of the library. */
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500203/* This is the function that does the actual reading of data. If you are
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600204 not reading from a standard C stream, you should create a replacement
205 read_data function and use it at run time with png_set_read_fn(), rather
206 than changing the library. */
207#ifndef USE_FAR_KEYWORD
208static void
209png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
210{
211 png_size_t check;
212
213 /* fread() returns 0 on error, so it is OK to store this in a png_size_t
214 * instead of an int, which is what fread() actually returns.
215 */
216 check = (png_size_t)fread(data, (png_size_t)1, length,
217 (FILE *)png_ptr->io_ptr);
218
219 if (check != length)
220 {
221 png_error(png_ptr, "Read Error");
222 }
223}
Guy Schalnate5a37791996-06-05 15:50:50 -0500224#else
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600225/* this is the model-independent version. Since the standard I/O library
226 can't handle far buffers in the medium and small models, we have to copy
227 the data.
228*/
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600229
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600230#define NEAR_BUF_SIZE 1024
231#define MIN(a,b) (a <= b ? a : b)
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600232
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600233static void
234png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600235{
236 int check;
237 png_byte *n_data;
238 FILE *io_ptr;
239
240 /* Check if data really is near. If so, use usual code. */
241 n_data = (png_byte *)CVT_PTR_NOCHECK(data);
242 io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
243 if ((png_bytep)n_data == data)
244 {
245 check = fread(n_data, 1, length, io_ptr);
246 }
247 else
248 {
249 png_byte buf[NEAR_BUF_SIZE];
250 png_size_t read, remaining, err;
251 check = 0;
252 remaining = length;
253 do
254 {
255 read = MIN(NEAR_BUF_SIZE, remaining);
256 err = fread(buf, (png_size_t)1, read, io_ptr);
257 png_memcpy(data, buf, read); /* copy far buffer to near buffer */
258 if(err != read)
259 break;
260 else
261 check += err;
262 data += read;
263 remaining -= read;
264 }
265 while (remaining != 0);
266 }
267 if (check != length)
268 {
269 png_error(png_ptr, "read Error");
270 }
271}
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600272#endif /* USE_FAR_KEYWORD */
Guy Schalnat0d580581995-07-20 02:43:20 -0500273
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600274#if defined(PNG_WRITE_FLUSH_SUPPORTED)
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600275static void
276png_default_flush(png_structp png_ptr)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600277{
278 FILE *io_ptr;
279 io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));
280 if (io_ptr != NULL)
281 fflush(io_ptr);
282}
283#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500284
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500285/* This is the function that does the actual writing of data. If you are
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600286 not writing to a standard C stream, you should create a replacement
287 write_data function and use it at run time with png_set_write_fn(), rather
288 than changing the library. */
289#ifndef USE_FAR_KEYWORD
290static void
291png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
292{
293 png_uint_32 check;
294
295 check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr));
296 if (check != length)
297 {
298 png_error(png_ptr, "Write Error");
299 }
300}
301#else
302/* this is the model-independent version. Since the standard I/O library
303 can't handle far buffers in the medium and small models, we have to copy
304 the data.
305*/
306
307#define NEAR_BUF_SIZE 1024
308#define MIN(a,b) (a <= b ? a : b)
309
310static void
311png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
312{
313 png_uint_32 check;
314 png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
315 FILE *io_ptr;
316
317 /* Check if data really is near. If so, use usual code. */
318 near_data = (png_byte *)CVT_PTR_NOCHECK(data);
319 io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
320 if ((png_bytep)near_data == data)
321 {
322 check = fwrite(near_data, 1, length, io_ptr);
323 }
324 else
325 {
326 png_byte buf[NEAR_BUF_SIZE];
327 png_size_t written, remaining, err;
328 check = 0;
329 remaining = length;
330 do
331 {
332 written = MIN(NEAR_BUF_SIZE, remaining);
333 png_memcpy(buf, data, written); /* copy far buffer to near buffer */
334 err = fwrite(buf, 1, written, io_ptr);
335 if (err != written)
336 break;
337 else
338 check += err;
339 data += written;
340 remaining -= written;
341 }
342 while (remaining != 0);
343 }
344 if (check != length)
345 {
346 png_error(png_ptr, "Write Error");
347 }
348}
349
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600350#endif /* USE_FAR_KEYWORD */
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600351
352/* This function is called when there is a warning, but the library thinks
353 * it can continue anyway. Replacement functions don't have to do anything
354 * here if you don't want to. In the default configuration, png_ptr is
355 * not used, but it is passed in case it may be useful.
356 */
357static void
358png_default_warning(png_structp png_ptr, png_const_charp message)
359{
360 PNG_CONST char *name = "UNKNOWN (ERROR!)";
361 if (png_ptr != NULL && png_ptr->error_ptr != NULL)
362 name = png_ptr->error_ptr;
363 fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
364}
365
366/* This is the default error handling function. Note that replacements for
367 * this function MUST NOT RETURN, or the program will likely crash. This
368 * function is used by default, or if the program supplies NULL for the
369 * error function pointer in png_set_error_fn().
370 */
371static void
372png_default_error(png_structp png_ptr, png_const_charp message)
373{
374 png_default_warning(png_ptr, message);
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500375 /* We can return because png_error calls the default handler, which is
376 * actually OK in this case. */
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600377}
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600378#endif /* PNG_NO_STDIO */
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600379/* END of code to validate stdio-free compilation */
380
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600381/* START of code to validate memory allocation and deallocation */
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500382#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600383
384/* Allocate memory. For reasonable files, size should never exceed
385 64K. However, zlib may allocate more then 64K if you don't tell
386 it not to. See zconf.h and png.h for more information. zlib does
387 need to allocate exactly 64K, so whatever you call here must
388 have the ability to do that.
389
390 This piece of code can be compiled to validate max 64K allocations
391 by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. */
392typedef struct memory_information {
393 png_uint_32 size;
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500394 png_voidp pointer;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600395 struct memory_information FAR *next;
396} memory_information;
397typedef memory_information FAR *memory_infop;
398
399static memory_infop pinformation = NULL;
400static int current_allocation = 0;
401static int maximum_allocation = 0;
402
403extern PNG_EXPORT(png_voidp,png_debug_malloc) PNGARG((png_structp png_ptr,
404 png_uint_32 size));
405extern PNG_EXPORT(void,png_debug_free) PNGARG((png_structp png_ptr,
406 png_voidp ptr));
407
408png_voidp
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500409png_debug_malloc(png_structp png_ptr, png_uint_32 size) {
410
411 /* png_malloc has already tested for NULL; png_create_struct calls
412 png_debug_malloc directly, with png_ptr == NULL which is OK */
413
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600414 if (size == 0)
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600415 return (png_voidp)(NULL);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600416
417 /* This calls the library allocator twice, once to get the requested
418 buffer and once to get a new free list entry. */
419 {
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500420 memory_infop pinfo = png_malloc_default(png_ptr, sizeof *pinfo);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600421 pinfo->size = size;
422 current_allocation += size;
423 if (current_allocation > maximum_allocation)
424 maximum_allocation = current_allocation;
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500425 pinfo->pointer = png_malloc_default(png_ptr, size);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600426 pinfo->next = pinformation;
427 pinformation = pinfo;
428 /* Make sure the caller isn't assuming zeroed memory. */
429 png_memset(pinfo->pointer, 0xdd, pinfo->size);
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600430 return (png_voidp)(pinfo->pointer);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600431 }
432}
433
434/* Free a pointer. It is removed from the list at the same time. */
435void
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500436png_debug_free(png_structp png_ptr, png_voidp ptr)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600437{
438 if (png_ptr == NULL)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500439 fprintf(STDERR, "NULL pointer to png_debug_free.\n");
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600440 if (ptr == 0) {
441#if 0 /* This happens all the time. */
442 fprintf(STDERR, "WARNING: freeing NULL pointer\n");
443#endif
444 return;
445 }
446
447 /* Unlink the element from the list. */
448 {
449 memory_infop FAR *ppinfo = &pinformation;
450 for (;;) {
451 memory_infop pinfo = *ppinfo;
452 if (pinfo->pointer == ptr) {
453 *ppinfo = pinfo->next;
454 current_allocation -= pinfo->size;
455 if (current_allocation < 0)
456 fprintf(STDERR, "Duplicate free of memory\n");
457 /* We must free the list element too, but first kill
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500458 the memory that is to be freed. */
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600459 memset(ptr, 0x55, pinfo->size);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500460 png_free_default(png_ptr, pinfo);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600461 break;
462 }
463 if (pinfo->next == NULL) {
464 fprintf(STDERR, "Pointer %x not found\n", ptr);
465 break;
466 }
467 ppinfo = &pinfo->next;
468 }
469 }
470
471 /* Finally free the data. */
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500472 png_free_default(png_ptr, ptr);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600473}
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500474#endif /* PNG_USER_MEM_SUPPORTED */
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600475/* END of code to test memory allocation/deallocation */
476
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600477/* Test one file */
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600478int
479test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
Guy Schalnat0d580581995-07-20 02:43:20 -0500480{
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600481 static FILE *fpin, *fpout; /* "static" prevents setjmp corruption */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500482 png_structp read_ptr, write_ptr;
483 png_infop read_info_ptr, write_info_ptr, end_info_ptr;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600484 png_bytep row_buf;
Guy Schalnat0d580581995-07-20 02:43:20 -0500485 png_uint_32 y;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500486 png_uint_32 width, height;
487 int num_pass, pass;
488 int bit_depth, color_type;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600489#ifdef USE_FAR_KEYWORD
490 jmp_buf jmpbuf;
491#endif
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600492
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600493 char inbuf[256], outbuf[256];
494
Guy Schalnate5a37791996-06-05 15:50:50 -0500495 row_buf = (png_bytep)NULL;
Guy Schalnat0d580581995-07-20 02:43:20 -0500496
Andreas Dilger47a0c421997-05-16 02:46:07 -0500497 if ((fpin = fopen(inname, "rb")) == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -0600498 {
499 fprintf(STDERR, "Could not find input file %s\n", inname);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600500 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600501 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500502
Andreas Dilger47a0c421997-05-16 02:46:07 -0500503 if ((fpout = fopen(outname, "wb")) == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -0600504 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500505 fprintf(STDERR, "Could not open output file %s\n", outname);
Guy Schalnat0f716451995-11-28 11:22:13 -0600506 fclose(fpin);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600507 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600508 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500509
Andreas Dilger47a0c421997-05-16 02:46:07 -0500510 png_debug(0, "Allocating read and write structures\n");
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500511#ifdef PNG_USER_MEM_SUPPORTED
512 read_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
513 (png_error_ptr)NULL, (png_error_ptr)NULL, (png_voidp)NULL,
514 (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
515#else
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600516 read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
Andreas Dilger47a0c421997-05-16 02:46:07 -0500517 (png_error_ptr)NULL, (png_error_ptr)NULL);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500518#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600519#if defined(PNG_NO_STDIO)
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600520 png_set_error_fn(read_ptr, (png_voidp)inname, png_default_error,
521 png_default_warning);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600522#endif
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500523#ifdef PNG_USER_MEM_SUPPORTED
524 write_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
525 (png_error_ptr)NULL, (png_error_ptr)NULL, (png_voidp)NULL,
526 (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
527#else
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600528 write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
Guy Schalnate5a37791996-06-05 15:50:50 -0500529 (png_error_ptr)NULL, (png_error_ptr)NULL);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500530#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600531#if defined(PNG_NO_STDIO)
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600532 png_set_error_fn(write_ptr, (png_voidp)inname, png_default_error,
533 png_default_warning);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600534#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500535 png_debug(0, "Allocating read_info, write_info and end_info structures\n");
536 read_info_ptr = png_create_info_struct(read_ptr);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600537 write_info_ptr = png_create_info_struct(write_ptr);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500538 end_info_ptr = png_create_info_struct(read_ptr);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500539#ifdef PNG_USER_MEM_SUPPORTED
540#endif
Guy Schalnate5a37791996-06-05 15:50:50 -0500541
Andreas Dilger47a0c421997-05-16 02:46:07 -0500542 png_debug(0, "Setting jmpbuf for read struct\n");
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600543#ifdef USE_FAR_KEYWORD
544 if (setjmp(jmpbuf))
545#else
Guy Schalnate5a37791996-06-05 15:50:50 -0500546 if (setjmp(read_ptr->jmpbuf))
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600547#endif
Guy Schalnat0f716451995-11-28 11:22:13 -0600548 {
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600549 fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500550 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
551 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Guy Schalnat0f716451995-11-28 11:22:13 -0600552 fclose(fpin);
553 fclose(fpout);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600554 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600555 }
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600556#ifdef USE_FAR_KEYWORD
557 png_memcpy(read_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
558#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500559
560 png_debug(0, "Setting jmpbuf for write struct\n");
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600561#ifdef USE_FAR_KEYWORD
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600562 if (setjmp(jmpbuf))
563#else
Guy Schalnate5a37791996-06-05 15:50:50 -0500564 if (setjmp(write_ptr->jmpbuf))
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600565#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600566 {
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600567 fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500568 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
569 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Guy Schalnat0f716451995-11-28 11:22:13 -0600570 fclose(fpin);
571 fclose(fpout);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600572 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600573 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600574#ifdef USE_FAR_KEYWORD
575 png_memcpy(write_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
576#endif
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600577
Andreas Dilger47a0c421997-05-16 02:46:07 -0500578 png_debug(0, "Initializing input and output streams\n");
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600579#if !defined(PNG_NO_STDIO)
Guy Schalnate5a37791996-06-05 15:50:50 -0500580 png_init_io(read_ptr, fpin);
581 png_init_io(write_ptr, fpout);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600582#else
583 png_set_read_fn(read_ptr, (png_voidp)fpin, png_default_read_data);
584 png_set_write_fn(write_ptr, (png_voidp)fpout, png_default_write_data,
585#if defined(PNG_WRITE_FLUSH_SUPPORTED)
586 png_default_flush);
587#else
588 NULL);
589#endif
590#endif
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600591 if(status_dots_requested == 1)
592 {
593 png_set_write_status_fn(write_ptr, write_row_callback);
594 png_set_read_status_fn(read_ptr, read_row_callback);
595 }
596 else
597 {
598 png_set_write_status_fn(write_ptr, NULL);
599 png_set_read_status_fn(read_ptr, NULL);
600 }
601
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500602#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
603 {
604 int i;
605 for(i=0; i<256; i++)
606 filters_used[i]=0;
607 png_set_read_user_transform_fn(read_ptr, count_filters);
608 }
609#endif
610#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
611 zero_samples=0;
612 png_set_write_user_transform_fn(write_ptr, count_zero_samples);
613#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500614
Andreas Dilger47a0c421997-05-16 02:46:07 -0500615 png_debug(0, "Reading info struct\n");
616 png_read_info(read_ptr, read_info_ptr);
Guy Schalnat0d580581995-07-20 02:43:20 -0500617
Andreas Dilger47a0c421997-05-16 02:46:07 -0500618 png_debug(0, "Transferring info struct\n");
619 {
620 int interlace_type, compression_type, filter_type;
Guy Schalnat0d580581995-07-20 02:43:20 -0500621
Andreas Dilger47a0c421997-05-16 02:46:07 -0500622 if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
623 &color_type, &interlace_type, &compression_type, &filter_type))
624 {
625 png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600626#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500627 color_type, interlace_type, compression_type, filter_type);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600628#else
629 color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
630#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500631 }
632 }
633#if defined(PNG_READ_bKGD_SUPPORTED) && defined(PNG_WRITE_bKGD_SUPPORTED)
634 {
635 png_color_16p background;
636
637 if (png_get_bKGD(read_ptr, read_info_ptr, &background))
638 {
639 png_set_bKGD(write_ptr, write_info_ptr, background);
640 }
641 }
642#endif
643#if defined(PNG_READ_cHRM_SUPPORTED) && defined(PNG_WRITE_cHRM_SUPPORTED)
644 {
645 double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
646
647 if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
648 &red_y, &green_x, &green_y, &blue_x, &blue_y))
649 {
650 png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
651 red_y, green_x, green_y, blue_x, blue_y);
652 }
653 }
654#endif
655#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_WRITE_gAMA_SUPPORTED)
656 {
657 double gamma;
658
659 if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
660 {
661 png_set_gAMA(write_ptr, write_info_ptr, gamma);
662 }
663 }
664#endif
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600665#if defined(PNG_READ_sRGB_SUPPORTED) && defined(PNG_WRITE_sRGB_SUPPORTED)
666 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600667 int intent;
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600668
669 if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
670 {
671 png_set_sRGB(write_ptr, write_info_ptr, intent);
672 }
673 }
674#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500675#if defined(PNG_READ_hIST_SUPPORTED) && defined(PNG_WRITE_hIST_SUPPORTED)
676 {
677 png_uint_16p hist;
678
679 if (png_get_hIST(read_ptr, read_info_ptr, &hist))
680 {
681 png_set_hIST(write_ptr, write_info_ptr, hist);
682 }
683 }
684#endif
685#if defined(PNG_READ_oFFs_SUPPORTED) && defined(PNG_WRITE_oFFs_SUPPORTED)
686 {
687 png_uint_32 offset_x, offset_y;
688 int unit_type;
689
690 if (png_get_oFFs(read_ptr, read_info_ptr,&offset_x,&offset_y,&unit_type))
691 {
692 png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
693 }
694 }
695#endif
696#if defined(PNG_READ_pCAL_SUPPORTED) && defined(PNG_WRITE_pCAL_SUPPORTED)
697 {
698 png_charp purpose, units;
699 png_charpp params;
700 png_int_32 X0, X1;
701 int type, nparams;
702
703 if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
704 &nparams, &units, &params))
705 {
706 png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
707 nparams, units, params);
708 }
709 }
710#endif
711#if defined(PNG_READ_pHYs_SUPPORTED) && defined(PNG_WRITE_pHYs_SUPPORTED)
712 {
713 png_uint_32 res_x, res_y;
714 int unit_type;
715
716 if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
717 {
718 png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
719 }
720 }
721#endif
722 {
723 png_colorp palette;
724 int num_palette;
725
726 if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
727 {
728 png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
729 }
730 }
731#if defined(PNG_READ_sBIT_SUPPORTED) && defined(PNG_WRITE_sBIT_SUPPORTED)
732 {
733 png_color_8p sig_bit;
734
735 if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
736 {
737 png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
738 }
739 }
740#endif
741#if (defined(PNG_READ_tEXt_SUPPORTED) && defined(PNG_WRITE_tEXt_SUPPORTED)) || \
742 (defined(PNG_READ_zTXt_SUPPORTED) && defined(PNG_WRITE_zTXt_SUPPORTED))
743 {
744 png_textp text_ptr;
745 int num_text;
746
747 if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
748 {
749 png_debug1(0, "Handling %d tEXt/zTXt chunks\n", num_text);
750 png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
751 }
752 }
753#endif
754#if defined(PNG_READ_tIME_SUPPORTED) && defined(PNG_WRITE_tIME_SUPPORTED)
755 {
756 png_timep mod_time;
757
758 if (png_get_tIME(read_ptr, read_info_ptr, &mod_time))
759 {
760 png_set_tIME(write_ptr, write_info_ptr, mod_time);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500761#if defined(PNG_TIME_RFC1123_SUPPORTED)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500762 /* we have to use png_strcpy instead of "=" because the string
763 pointed to by png_convert_to_rfc1123() gets free'ed before
764 we use it */
765 png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time));
766 tIME_chunk_present++;
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500767#endif /* PNG_TIME_RFC1123_SUPPORTED */
Glenn Randers-Pehrsonc9442291999-01-06 21:50:16 -0600768 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500769 }
770#endif
771#if defined(PNG_READ_tRNS_SUPPORTED) && defined(PNG_WRITE_tRNS_SUPPORTED)
772 {
773 png_bytep trans;
774 int num_trans;
775 png_color_16p trans_values;
776
777 if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans,
778 &trans_values))
779 {
780 png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans,
781 trans_values);
782 }
783 }
784#endif
785
786 png_debug(0, "\nWriting info struct\n");
787 png_write_info(write_ptr, write_info_ptr);
788
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600789 png_debug(0, "\nAllocating row buffer \n");
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600790 row_buf = (png_bytep)png_malloc(read_ptr,
Andreas Dilger47a0c421997-05-16 02:46:07 -0500791 png_get_rowbytes(read_ptr, read_info_ptr));
792 if (row_buf == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -0600793 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500794 fprintf(STDERR, "No memory to allocate row buffer\n");
Andreas Dilger47a0c421997-05-16 02:46:07 -0500795 png_destroy_read_struct(&read_ptr, &read_info_ptr, (png_infopp)NULL);
796 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Guy Schalnat0f716451995-11-28 11:22:13 -0600797 fclose(fpin);
798 fclose(fpout);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600799 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600800 }
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600801 png_debug(0, "Writing row data\n");
Guy Schalnat0d580581995-07-20 02:43:20 -0500802
Andreas Dilger47a0c421997-05-16 02:46:07 -0500803 num_pass = png_set_interlace_handling(read_ptr);
804 png_set_interlace_handling(write_ptr);
Guy Schalnat0d580581995-07-20 02:43:20 -0500805
Guy Schalnat0f716451995-11-28 11:22:13 -0600806 for (pass = 0; pass < num_pass; pass++)
807 {
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600808 png_debug1(0, "Writing row data for pass %d\n",pass);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500809 for (y = 0; y < height; y++)
Guy Schalnat0f716451995-11-28 11:22:13 -0600810 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500811 png_read_rows(read_ptr, (png_bytepp)&row_buf, (png_bytepp)NULL, 1);
Guy Schalnate5a37791996-06-05 15:50:50 -0500812 png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600813 }
814 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500815
Andreas Dilger47a0c421997-05-16 02:46:07 -0500816 png_debug(0, "Reading and writing end_info data\n");
817 png_read_end(read_ptr, end_info_ptr);
818 png_write_end(write_ptr, end_info_ptr);
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600819
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600820#ifdef PNG_EASY_ACCESS_SUPPORTED
821 if(verbose)
822 {
823 png_uint_32 iwidth, iheight;
824 iwidth = png_get_image_width(write_ptr, write_info_ptr);
825 iheight = png_get_image_height(write_ptr, write_info_ptr);
826 fprintf(STDERR, "Image width = %lu, height = %lu\n",
827 iwidth, iheight);
828 }
829#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500830
Andreas Dilger47a0c421997-05-16 02:46:07 -0500831 png_debug(0, "Destroying data structs\n");
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600832 png_free(read_ptr, row_buf);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500833 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
834 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Guy Schalnat0d580581995-07-20 02:43:20 -0500835
Guy Schalnat0f716451995-11-28 11:22:13 -0600836 fclose(fpin);
837 fclose(fpout);
Guy Schalnat0d580581995-07-20 02:43:20 -0500838
Andreas Dilger47a0c421997-05-16 02:46:07 -0500839 png_debug(0, "Opening files for comparison\n");
840 if ((fpin = fopen(inname, "rb")) == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -0600841 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500842 fprintf(STDERR, "Could not find file %s\n", inname);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600843 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600844 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500845
Andreas Dilger47a0c421997-05-16 02:46:07 -0500846 if ((fpout = fopen(outname, "rb")) == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -0600847 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500848 fprintf(STDERR, "Could not find file %s\n", outname);
Guy Schalnat0f716451995-11-28 11:22:13 -0600849 fclose(fpin);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600850 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600851 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500852
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600853 for(;;)
Guy Schalnat0f716451995-11-28 11:22:13 -0600854 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500855 png_size_t num_in, num_out;
Guy Schalnat0d580581995-07-20 02:43:20 -0500856
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600857 num_in = fread(inbuf, 1, 1, fpin);
858 num_out = fread(outbuf, 1, 1, fpout);
Guy Schalnat0d580581995-07-20 02:43:20 -0500859
Guy Schalnat0f716451995-11-28 11:22:13 -0600860 if (num_in != num_out)
861 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500862 fprintf(STDERR, "Files %s and %s are of a different size\n",
863 inname, outname);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600864 if(wrote_question == 0)
865 {
866 fprintf(STDERR,
867 " Was %s written with the same chunk size (8k),",inname);
868 fprintf(STDERR,
869 " filtering\n heuristic (libpng default), compression");
870 fprintf(STDERR,
871 " level (zlib default)\n and zlib version (%s)?\n\n",
872 ZLIB_VERSION);
873 wrote_question=1;
874 }
Guy Schalnat0f716451995-11-28 11:22:13 -0600875 fclose(fpin);
876 fclose(fpout);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600877 return (0);
Guy Schalnat0f716451995-11-28 11:22:13 -0600878 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500879
Guy Schalnat0f716451995-11-28 11:22:13 -0600880 if (!num_in)
881 break;
Guy Schalnat0d580581995-07-20 02:43:20 -0500882
Andreas Dilger47a0c421997-05-16 02:46:07 -0500883 if (png_memcmp(inbuf, outbuf, num_in))
Guy Schalnat0f716451995-11-28 11:22:13 -0600884 {
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500885 fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600886 if(wrote_question == 0)
887 {
888 fprintf(STDERR,
889 " Was %s written with the same chunk size (8k),",inname);
890 fprintf(STDERR,
891 " filtering\n heuristic (libpng default), compression");
892 fprintf(STDERR,
893 " level (zlib default)\n and zlib version (%s)?\n\n",
894 ZLIB_VERSION);
895 wrote_question=1;
896 }
Guy Schalnat0f716451995-11-28 11:22:13 -0600897 fclose(fpin);
898 fclose(fpout);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600899 return (0);
Guy Schalnat0f716451995-11-28 11:22:13 -0600900 }
901 }
902
903 fclose(fpin);
904 fclose(fpout);
Guy Schalnat0d580581995-07-20 02:43:20 -0500905
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600906 return (0);
Guy Schalnat0d580581995-07-20 02:43:20 -0500907}
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500908
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600909/* input and output filenames */
910#ifdef RISCOS
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500911static PNG_CONST char *inname = "pngtest/png";
912static PNG_CONST char *outname = "pngout/png";
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600913#else
Glenn Randers-Pehrson983ec161998-03-07 11:24:03 -0600914static PNG_CONST char *inname = "pngtest.png";
915static PNG_CONST char *outname = "pngout.png";
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600916#endif
917
918int
919main(int argc, char *argv[])
920{
921 int multiple = 0;
922 int ierror = 0;
923
924 fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600925 fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION);
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600926 fprintf(STDERR,"%s",png_get_copyright(NULL));
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600927
928 /* Do some consistency checking on the memory allocation settings, I'm
929 not sure this matters, but it is nice to know, the first of these
930 tests should be impossible because of the way the macros are set
931 in pngconf.h */
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600932#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600933 fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n");
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600934#endif
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600935 /* I think the following can happen. */
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600936#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600937 fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n");
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600938#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600939
940 if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
941 {
942 fprintf(STDERR,
943 "Warning: versions are different between png.h and png.c\n");
944 fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING);
945 fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver);
946 ++ierror;
947 }
948
949 if (argc > 1)
950 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600951 if (strcmp(argv[1], "-m") == 0)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600952 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600953 multiple = 1;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600954 status_dots_requested = 0;
955 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600956 else if (strcmp(argv[1], "-mv") == 0 ||
957 strcmp(argv[1], "-vm") == 0 )
958 {
959 multiple = 1;
960 verbose = 1;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600961 status_dots_requested = 1;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600962 }
963 else if (strcmp(argv[1], "-v") == 0)
964 {
965 verbose = 1;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600966 status_dots_requested = 1;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600967 inname = argv[2];
968 }
969 else
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600970 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600971 inname = argv[1];
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600972 status_dots_requested = 0;
973 }
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600974 }
975
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600976 if (!multiple && argc == 3+verbose)
977 outname = argv[2+verbose];
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600978
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600979 if ((!multiple && argc > 3+verbose) || (multiple && argc < 2))
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600980 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600981 fprintf(STDERR,
982 "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600983 argv[0], argv[0]);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600984 fprintf(STDERR,
985 " reads/writes one PNG file (without -m) or multiple files (-m)\n");
986 fprintf(STDERR,
987 " with -m %s is used as a temporary file\n", outname);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600988 exit(1);
989 }
990
991 if (multiple)
992 {
993 int i;
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500994#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600995 int allocation_now = current_allocation;
996#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600997 for (i=2; i<argc; ++i)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600998 {
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500999 int k, kerror;
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001000 fprintf(STDERR, "Testing %s:",argv[i]);
1001 kerror = test_one_file(argv[i], outname);
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001002 if (kerror == 0)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001003 {
Glenn Randers-Pehrson38d73af1998-03-07 21:30:44 -06001004#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -05001005 fprintf(STDERR, " PASS (%lu zero samples)\n",zero_samples);
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001006#else
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001007 fprintf(STDERR, " PASS\n");
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001008#endif
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001009#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1010 for (k=0; k<256; k++)
1011 if(filters_used[k])
1012 fprintf(STDERR, " Filter %d was used %lu times\n",
1013 k,filters_used[k]);
1014#endif
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001015#if defined(PNG_TIME_RFC1123_SUPPORTED)
1016 if(tIME_chunk_present != 0)
1017 fprintf(STDERR, " tIME = %s\n",tIME_string);
1018 tIME_chunk_present = 0;
1019#endif /* PNG_TIME_RFC1123_SUPPORTED */
1020 }
1021 else
1022 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001023 fprintf(STDERR, " FAIL\n");
1024 ierror += kerror;
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001025 }
1026#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001027 if (allocation_now != current_allocation)
1028 fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
1029 current_allocation-allocation_now);
1030 if (current_allocation != 0) {
1031 memory_infop pinfo = pinformation;
1032
1033 fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
1034 current_allocation);
1035 while (pinfo != NULL) {
1036 fprintf(STDERR, " %d bytes at %x\n", pinfo->size, pinfo->pointer);
1037 pinfo = pinfo->next;
1038 }
Glenn Randers-Pehrson2687fcc1998-01-07 20:54:20 -06001039 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001040#endif
1041 }
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001042#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001043 fprintf(STDERR, "Maximum memory allocation: %d bytes\n",
1044 maximum_allocation);
1045#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001046 }
1047 else
1048 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001049 int i;
1050 for (i=0; i<3; ++i) {
1051 int kerror;
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001052#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001053 int allocation_now = current_allocation;
1054#endif
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001055 if (i == 1) status_dots_requested = 1;
1056 else if(verbose == 0)status_dots_requested = 0;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001057 if (i == 0 || verbose == 1 || ierror != 0)
1058 fprintf(STDERR, "Testing %s:",inname);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001059 kerror = test_one_file(inname, outname);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001060 if(kerror == 0)
1061 {
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001062 if(verbose == 1 || i == 2)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001063 {
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001064 int k;
Glenn Randers-Pehrson38d73af1998-03-07 21:30:44 -06001065#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -05001066 fprintf(STDERR, " PASS (%lu zero samples)\n",zero_samples);
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001067#else
1068 fprintf(STDERR, " PASS\n");
1069#endif
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001070#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1071 for (k=0; k<256; k++)
1072 if(filters_used[k])
1073 fprintf(STDERR, " Filter %d was used %lu times\n",
1074 k,filters_used[k]);
1075#endif
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001076#if defined(PNG_TIME_RFC1123_SUPPORTED)
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001077 if(tIME_chunk_present != 0)
1078 fprintf(STDERR, " tIME = %s\n",tIME_string);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001079#endif /* PNG_TIME_RFC1123_SUPPORTED */
1080 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001081 }
1082 else
1083 {
1084 if(verbose == 0 && i != 2)
1085 fprintf(STDERR, "Testing %s:",inname);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001086 fprintf(STDERR, " FAIL\n");
1087 ierror += kerror;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001088 }
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001089#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001090 if (allocation_now != current_allocation)
1091 fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
1092 current_allocation-allocation_now);
1093 if (current_allocation != 0) {
1094 memory_infop pinfo = pinformation;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001095
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001096 fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
1097 current_allocation);
1098 while (pinfo != NULL) {
1099 fprintf(STDERR, " %d bytes at %x\n", pinfo->size, pinfo->pointer);
1100 pinfo = pinfo->next;
1101 }
1102 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001103#endif
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001104 }
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001105#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001106 fprintf(STDERR, "Maximum memory allocation: %d bytes\n",
1107 maximum_allocation);
1108#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001109 }
1110
1111 if (ierror == 0)
1112 fprintf(STDERR, "libpng passes test\n");
1113 else
1114 fprintf(STDERR, "libpng FAILS test\n");
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001115 return (int)(ierror != 0);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001116}
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001117