blob: 221b310b5b7895b9734af5682dc577819c9293a3 [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-Pehrson5fea36f2004-07-28 08:20:44 -05004 * libpng 1.2.6beta4 - July 28, 2004
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06005 * For conditions of distribution and use, see copyright notice in png.h
Glenn Randers-Pehrson5b5dcf82004-07-17 22:45:44 -05006 * Copyright (c) 1998-2004 Glenn Randers-Pehrson
Glenn Randers-Pehrsond4366722000-06-04 14:29:29 -05007 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
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-Pehrson61c32d92000-02-04 23:40:16 -060018 * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192.
Glenn Randers-Pehrson5e5c1e12000-11-10 12:26:19 -060019 * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks
20 * exist in the input file.
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060021 * 4) others not listed here...
22 * In these cases, it is best to check with another tool such as "pngcheck"
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -060023 * to see what the differences between the two files are.
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060024 *
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
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050027 * testing a wide variety of files easily. You can also test a number
28 * of files at once by typing "pngtest -m file1.png file2.png ..."
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060029 */
Guy Schalnat0d580581995-07-20 02:43:20 -050030
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -050031#include "png.h"
32
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -050033#if defined(_WIN32_WCE)
34# if _WIN32_WCE < 211
35 __error__ (f|w)printf functions are not supported on old WindowsCE.;
36# endif
37# include <windows.h>
38# include <stdlib.h>
39# define READFILE(file, data, length, check) \
Glenn Randers-Pehrson15dac0b2000-07-10 07:48:54 -050040 if (ReadFile(file, data, length, &check,NULL)) check = 0
41# define WRITEFILE(file, data, length, check)) \
42 if (WriteFile(file, data, length, &check, NULL)) check = 0
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -050043# define FCLOSE(file) CloseHandle(file)
44#else
45# include <stdio.h>
46# include <stdlib.h>
47# include <assert.h>
48# define READFILE(file, data, length, check) \
49 check=(png_size_t)fread(data,(png_size_t)1,length,file)
50# define WRITEFILE(file, data, length, check) \
Glenn Randers-Pehrson15dac0b2000-07-10 07:48:54 -050051 check=(png_size_t)fwrite(data,(png_size_t)1, length, file)
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -050052# define FCLOSE(file) fclose(file)
53#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -050054
Glenn Randers-Pehrsonbe9de0f2001-01-22 08:52:16 -060055#if defined(PNG_NO_STDIO)
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -050056# if defined(_WIN32_WCE)
57 typedef HANDLE png_FILE_p;
58# else
59 typedef FILE * png_FILE_p;
60# endif
Glenn Randers-Pehrsonbe9de0f2001-01-22 08:52:16 -060061#endif
62
Andreas Dilger47a0c421997-05-16 02:46:07 -050063/* Makes pngtest verbose so we can find problems (needs to be before png.h) */
64#ifndef PNG_DEBUG
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -050065# define PNG_DEBUG 0
66#endif
67
68#if !PNG_DEBUG
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -050069# define SINGLE_ROWBUF_ALLOC /* makes buffer overruns easier to nail */
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -060070#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -050071
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -050072/* Turn on CPU timing
73#define PNGTEST_TIMING
74*/
75
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -060076#ifdef PNG_NO_FLOATING_POINT_SUPPORTED
77#undef PNGTEST_TIMING
78#endif
79
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -050080#ifdef PNGTEST_TIMING
81static float t_start, t_stop, t_decode, t_encode, t_misc;
82#include <time.h>
83#endif
84
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -060085/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
86#ifndef png_jmpbuf
87# define png_jmpbuf(png_ptr) png_ptr->jmpbuf
88#endif
89
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -050090#ifdef PNGTEST_TIMING
91static float t_start, t_stop, t_decode, t_encode, t_misc;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -060092#if !defined(PNG_tIME_SUPPORTED)
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -050093#include <time.h>
94#endif
95#endif
96
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050097#if defined(PNG_TIME_RFC1123_SUPPORTED)
98static int tIME_chunk_present=0;
Glenn Randers-Pehrson345bc271998-06-14 14:43:31 -050099static char tIME_string[30] = "no tIME chunk present in file";
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600100#endif
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500101
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500102static int verbose = 0;
103
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600104int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname));
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600105
Guy Schalnat0d580581995-07-20 02:43:20 -0500106#ifdef __TURBOC__
107#include <mem.h>
108#endif
109
110/* defined so I can write to a file on gui/windowing platforms */
Guy Schalnat6d764711995-12-19 03:22:19 -0600111/* #define STDERR stderr */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600112#define STDERR stdout /* for DOS */
Guy Schalnat0d580581995-07-20 02:43:20 -0500113
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600114/* example of using row callbacks to make a simple progress meter */
115static int status_pass=1;
116static int status_dots_requested=0;
117static int status_dots=1;
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600118
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600119void
Glenn Randers-Pehrson2ae022d2002-07-01 22:23:46 -0500120#ifdef PNG_1_0_X
121PNGAPI
122#endif
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500123read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
Glenn Randers-Pehrson0cc2f952002-10-03 06:32:37 -0500124void
Glenn Randers-Pehrson2ae022d2002-07-01 22:23:46 -0500125#ifdef PNG_1_0_X
126PNGAPI
127#endif
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600128read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600129{
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500130 if(png_ptr == NULL || row_number > PNG_UINT_31_MAX) return;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600131 if(status_pass != pass)
132 {
133 fprintf(stdout,"\n Pass %d: ",pass);
134 status_pass = pass;
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500135 status_dots = 31;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600136 }
137 status_dots--;
138 if(status_dots == 0)
139 {
140 fprintf(stdout, "\n ");
141 status_dots=30;
142 }
143 fprintf(stdout, "r");
144}
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600145
Glenn Randers-Pehrson0cc2f952002-10-03 06:32:37 -0500146void
Glenn Randers-Pehrson2ae022d2002-07-01 22:23:46 -0500147#ifdef PNG_1_0_X
148PNGAPI
149#endif
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500150write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
Glenn Randers-Pehrson0cc2f952002-10-03 06:32:37 -0500151void
Glenn Randers-Pehrson2ae022d2002-07-01 22:23:46 -0500152#ifdef PNG_1_0_X
153PNGAPI
154#endif
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600155write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600156{
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500157 if(png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) return;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600158 fprintf(stdout, "w");
159}
160
161
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500162#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
163/* Example of using user transform callback (we don't transform anything,
164 but merely examine the row filters. We set this to 256 rather than
165 5 in case illegal filter values are present.) */
166static png_uint_32 filters_used[256];
167void
Glenn Randers-Pehrson2ae022d2002-07-01 22:23:46 -0500168#ifdef PNG_1_0_X
169PNGAPI
170#endif
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500171count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data);
172void
Glenn Randers-Pehrson2ae022d2002-07-01 22:23:46 -0500173#ifdef PNG_1_0_X
174PNGAPI
175#endif
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500176count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data)
177{
178 if(png_ptr != NULL && row_info != NULL)
179 ++filters_used[*(data-1)];
180}
181#endif
182
Glenn Randers-Pehrson38d73af1998-03-07 21:30:44 -0600183#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600184/* example of using user transform callback (we don't transform anything,
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500185 but merely count the zero samples) */
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600186
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500187static png_uint_32 zero_samples;
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600188
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600189void
Glenn Randers-Pehrson2ae022d2002-07-01 22:23:46 -0500190#ifdef PNG_1_0_X
191PNGAPI
192#endif
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500193count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data);
194void
Glenn Randers-Pehrson2ae022d2002-07-01 22:23:46 -0500195#ifdef PNG_1_0_X
196PNGAPI
197#endif
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500198count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600199{
200 png_bytep dp = data;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600201 if(png_ptr == NULL)return;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600202
203 /* contents of row_info:
204 * png_uint_32 width width of row
205 * png_uint_32 rowbytes number of bytes in row
206 * png_byte color_type color type of pixels
207 * png_byte bit_depth bit depth of samples
208 * png_byte channels number of channels (1-4)
209 * png_byte pixel_depth bits per pixel (depth*channels)
210 */
211
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500212
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500213 /* counts the number of zero samples (or zero pixels if color_type is 3 */
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600214
215 if(row_info->color_type == 0 || row_info->color_type == 3)
216 {
217 int pos=0;
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500218 png_uint_32 n, nstop;
219 for (n=0, nstop=row_info->width; n<nstop; n++)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600220 {
221 if(row_info->bit_depth == 1)
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500222 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600223 if(((*dp << pos++ ) & 0x80) == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600224 if(pos == 8)
225 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500226 pos = 0;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600227 dp++;
228 }
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500229 }
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600230 if(row_info->bit_depth == 2)
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500231 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600232 if(((*dp << (pos+=2)) & 0xc0) == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600233 if(pos == 8)
234 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500235 pos = 0;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600236 dp++;
237 }
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500238 }
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600239 if(row_info->bit_depth == 4)
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500240 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600241 if(((*dp << (pos+=4)) & 0xf0) == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600242 if(pos == 8)
243 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500244 pos = 0;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600245 dp++;
246 }
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500247 }
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600248 if(row_info->bit_depth == 8)
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500249 if(*dp++ == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600250 if(row_info->bit_depth == 16)
251 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500252 if((*dp | *(dp+1)) == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600253 dp+=2;
254 }
255 }
256 }
257 else /* other color types */
258 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500259 png_uint_32 n, nstop;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600260 int channel;
261 int color_channels = row_info->channels;
262 if(row_info->color_type > 3)color_channels--;
263
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500264 for (n=0, nstop=row_info->width; n<nstop; n++)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600265 {
266 for (channel = 0; channel < color_channels; channel++)
267 {
268 if(row_info->bit_depth == 8)
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500269 if(*dp++ == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600270 if(row_info->bit_depth == 16)
271 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500272 if((*dp | *(dp+1)) == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600273 dp+=2;
274 }
275 }
276 if(row_info->color_type > 3)
277 {
278 dp++;
279 if(row_info->bit_depth == 16)dp++;
280 }
281 }
282 }
283}
Glenn Randers-Pehrson38d73af1998-03-07 21:30:44 -0600284#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600285
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600286static int wrote_question = 0;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600287
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600288#if defined(PNG_NO_STDIO)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600289/* START of code to validate stdio-free compilation */
290/* These copies of the default read/write functions come from pngrio.c and */
291/* pngwio.c. They allow "don't include stdio" testing of the library. */
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500292/* This is the function that does the actual reading of data. If you are
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600293 not reading from a standard C stream, you should create a replacement
294 read_data function and use it at run time with png_set_read_fn(), rather
295 than changing the library. */
Glenn Randers-Pehrsonbe9de0f2001-01-22 08:52:16 -0600296
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600297#ifndef USE_FAR_KEYWORD
298static void
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500299pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600300{
301 png_size_t check;
302
303 /* fread() returns 0 on error, so it is OK to store this in a png_size_t
304 * instead of an int, which is what fread() actually returns.
305 */
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500306 READFILE((png_FILE_p)png_ptr->io_ptr, data, length, check);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600307
308 if (check != length)
309 {
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500310 png_error(png_ptr, "Read Error!");
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600311 }
312}
Guy Schalnate5a37791996-06-05 15:50:50 -0500313#else
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600314/* this is the model-independent version. Since the standard I/O library
315 can't handle far buffers in the medium and small models, we have to copy
316 the data.
317*/
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600318
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600319#define NEAR_BUF_SIZE 1024
320#define MIN(a,b) (a <= b ? a : b)
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600321
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600322static void
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500323pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600324{
325 int check;
326 png_byte *n_data;
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500327 png_FILE_p io_ptr;
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600328
329 /* Check if data really is near. If so, use usual code. */
330 n_data = (png_byte *)CVT_PTR_NOCHECK(data);
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500331 io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600332 if ((png_bytep)n_data == data)
333 {
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500334 READFILE(io_ptr, n_data, length, check);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600335 }
336 else
337 {
338 png_byte buf[NEAR_BUF_SIZE];
339 png_size_t read, remaining, err;
340 check = 0;
341 remaining = length;
342 do
343 {
344 read = MIN(NEAR_BUF_SIZE, remaining);
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500345 READFILE(io_ptr, buf, 1, err);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600346 png_memcpy(data, buf, read); /* copy far buffer to near buffer */
347 if(err != read)
348 break;
349 else
350 check += err;
351 data += read;
352 remaining -= read;
353 }
354 while (remaining != 0);
355 }
356 if (check != length)
357 {
358 png_error(png_ptr, "read Error");
359 }
360}
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600361#endif /* USE_FAR_KEYWORD */
Guy Schalnat0d580581995-07-20 02:43:20 -0500362
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600363#if defined(PNG_WRITE_FLUSH_SUPPORTED)
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600364static void
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500365pngtest_flush(png_structp png_ptr)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600366{
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500367#if !defined(_WIN32_WCE)
368 png_FILE_p io_ptr;
369 io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600370 if (io_ptr != NULL)
371 fflush(io_ptr);
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500372#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600373}
374#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500375
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500376/* This is the function that does the actual writing of data. If you are
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600377 not writing to a standard C stream, you should create a replacement
378 write_data function and use it at run time with png_set_write_fn(), rather
379 than changing the library. */
380#ifndef USE_FAR_KEYWORD
381static void
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500382pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600383{
384 png_uint_32 check;
385
Glenn Randers-Pehrson5e5c1e12000-11-10 12:26:19 -0600386 WRITEFILE((png_FILE_p)png_ptr->io_ptr, data, length, check);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600387 if (check != length)
388 {
389 png_error(png_ptr, "Write Error");
390 }
391}
392#else
393/* this is the model-independent version. Since the standard I/O library
394 can't handle far buffers in the medium and small models, we have to copy
395 the data.
396*/
397
398#define NEAR_BUF_SIZE 1024
399#define MIN(a,b) (a <= b ? a : b)
400
401static void
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500402pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600403{
404 png_uint_32 check;
405 png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500406 png_FILE_p io_ptr;
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600407
408 /* Check if data really is near. If so, use usual code. */
409 near_data = (png_byte *)CVT_PTR_NOCHECK(data);
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500410 io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600411 if ((png_bytep)near_data == data)
412 {
Glenn Randers-Pehrson5e5c1e12000-11-10 12:26:19 -0600413 WRITEFILE(io_ptr, near_data, length, check);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600414 }
415 else
416 {
417 png_byte buf[NEAR_BUF_SIZE];
418 png_size_t written, remaining, err;
419 check = 0;
420 remaining = length;
421 do
422 {
423 written = MIN(NEAR_BUF_SIZE, remaining);
424 png_memcpy(buf, data, written); /* copy far buffer to near buffer */
Glenn Randers-Pehrson5e5c1e12000-11-10 12:26:19 -0600425 WRITEFILE(io_ptr, buf, written, err);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600426 if (err != written)
427 break;
428 else
429 check += err;
430 data += written;
431 remaining -= written;
432 }
433 while (remaining != 0);
434 }
435 if (check != length)
436 {
437 png_error(png_ptr, "Write Error");
438 }
439}
440
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600441#endif /* USE_FAR_KEYWORD */
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600442
443/* This function is called when there is a warning, but the library thinks
444 * it can continue anyway. Replacement functions don't have to do anything
445 * here if you don't want to. In the default configuration, png_ptr is
446 * not used, but it is passed in case it may be useful.
447 */
448static void
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500449pngtest_warning(png_structp png_ptr, png_const_charp message)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600450{
451 PNG_CONST char *name = "UNKNOWN (ERROR!)";
452 if (png_ptr != NULL && png_ptr->error_ptr != NULL)
453 name = png_ptr->error_ptr;
454 fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
455}
456
457/* This is the default error handling function. Note that replacements for
458 * this function MUST NOT RETURN, or the program will likely crash. This
459 * function is used by default, or if the program supplies NULL for the
460 * error function pointer in png_set_error_fn().
461 */
462static void
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500463pngtest_error(png_structp png_ptr, png_const_charp message)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600464{
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500465 pngtest_warning(png_ptr, message);
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500466 /* We can return because png_error calls the default handler, which is
467 * actually OK in this case. */
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600468}
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600469#endif /* PNG_NO_STDIO */
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600470/* END of code to validate stdio-free compilation */
471
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600472/* START of code to validate memory allocation and deallocation */
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500473#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600474
475/* Allocate memory. For reasonable files, size should never exceed
476 64K. However, zlib may allocate more then 64K if you don't tell
477 it not to. See zconf.h and png.h for more information. zlib does
478 need to allocate exactly 64K, so whatever you call here must
479 have the ability to do that.
480
481 This piece of code can be compiled to validate max 64K allocations
482 by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. */
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600483typedef struct memory_information
484{
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500485 png_uint_32 size;
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500486 png_voidp pointer;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600487 struct memory_information FAR *next;
488} memory_information;
489typedef memory_information FAR *memory_infop;
490
491static memory_infop pinformation = NULL;
492static int current_allocation = 0;
493static int maximum_allocation = 0;
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500494static int total_allocation = 0;
495static int num_allocations = 0;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600496
Glenn Randers-Pehrsonb1828932001-06-23 08:03:17 -0500497png_voidp png_debug_malloc PNGARG((png_structp png_ptr, png_uint_32 size));
498void png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr));
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600499
500png_voidp
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600501png_debug_malloc(png_structp png_ptr, png_uint_32 size)
502{
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500503
504 /* png_malloc has already tested for NULL; png_create_struct calls
505 png_debug_malloc directly, with png_ptr == NULL which is OK */
506
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600507 if (size == 0)
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500508 return (NULL);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600509
510 /* This calls the library allocator twice, once to get the requested
511 buffer and once to get a new free list entry. */
512 {
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500513 memory_infop pinfo = (memory_infop)png_malloc_default(png_ptr,
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500514 (png_uint_32)png_sizeof (*pinfo));
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600515 pinfo->size = size;
516 current_allocation += size;
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500517 total_allocation += size;
518 num_allocations ++;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600519 if (current_allocation > maximum_allocation)
520 maximum_allocation = current_allocation;
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500521 pinfo->pointer = (png_voidp)png_malloc_default(png_ptr, size);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600522 pinfo->next = pinformation;
523 pinformation = pinfo;
524 /* Make sure the caller isn't assuming zeroed memory. */
525 png_memset(pinfo->pointer, 0xdd, pinfo->size);
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -0500526#if PNG_DEBUG
527 if(verbose)
Glenn Randers-Pehrsonb1828932001-06-23 08:03:17 -0500528 printf("png_malloc %lu bytes at %x\n",size,pinfo->pointer);
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -0500529#endif
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500530 assert(pinfo->size != 12345678);
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600531 return (png_voidp)(pinfo->pointer);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600532 }
533}
534
535/* Free a pointer. It is removed from the list at the same time. */
536void
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500537png_debug_free(png_structp png_ptr, png_voidp ptr)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600538{
539 if (png_ptr == NULL)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500540 fprintf(STDERR, "NULL pointer to png_debug_free.\n");
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600541 if (ptr == 0)
542 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600543#if 0 /* This happens all the time. */
544 fprintf(STDERR, "WARNING: freeing NULL pointer\n");
545#endif
546 return;
547 }
548
549 /* Unlink the element from the list. */
550 {
551 memory_infop FAR *ppinfo = &pinformation;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600552 for (;;)
553 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600554 memory_infop pinfo = *ppinfo;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600555 if (pinfo->pointer == ptr)
556 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600557 *ppinfo = pinfo->next;
558 current_allocation -= pinfo->size;
559 if (current_allocation < 0)
560 fprintf(STDERR, "Duplicate free of memory\n");
561 /* We must free the list element too, but first kill
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500562 the memory that is to be freed. */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500563 png_memset(ptr, 0x55, pinfo->size);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500564 png_free_default(png_ptr, pinfo);
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500565 pinfo=NULL;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600566 break;
567 }
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600568 if (pinfo->next == NULL)
569 {
Glenn Randers-Pehrsonb1828932001-06-23 08:03:17 -0500570 fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600571 break;
572 }
573 ppinfo = &pinfo->next;
574 }
575 }
576
577 /* Finally free the data. */
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -0500578#if PNG_DEBUG
579 if(verbose)
580 printf("Freeing %x\n",ptr);
581#endif
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500582 png_free_default(png_ptr, ptr);
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500583 ptr=NULL;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600584}
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500585#endif /* PNG_USER_MEM_SUPPORTED */
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600586/* END of code to test memory allocation/deallocation */
587
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600588/* Test one file */
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600589int
590test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
Guy Schalnat0d580581995-07-20 02:43:20 -0500591{
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500592 static png_FILE_p fpin;
593 static png_FILE_p fpout; /* "static" prevents setjmp corruption */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500594 png_structp read_ptr;
595 png_infop read_info_ptr, end_info_ptr;
596#ifdef PNG_WRITE_SUPPORTED
597 png_structp write_ptr;
598 png_infop write_info_ptr;
599 png_infop write_end_info_ptr;
600#else
601 png_structp write_ptr = NULL;
602 png_infop write_info_ptr = NULL;
603 png_infop write_end_info_ptr = NULL;
604#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600605 png_bytep row_buf;
Guy Schalnat0d580581995-07-20 02:43:20 -0500606 png_uint_32 y;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500607 png_uint_32 width, height;
608 int num_pass, pass;
609 int bit_depth, color_type;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600610#ifdef PNG_SETJMP_SUPPORTED
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600611#ifdef USE_FAR_KEYWORD
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -0600612 jmp_buf jmpbuf;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600613#endif
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600614#endif
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600615
Glenn Randers-Pehrsonff9c9472000-07-11 07:12:36 -0500616#if defined(_WIN32_WCE)
617 TCHAR path[MAX_PATH];
618#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600619 char inbuf[256], outbuf[256];
620
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500621 row_buf = NULL;
Guy Schalnat0d580581995-07-20 02:43:20 -0500622
Glenn Randers-Pehrsonff9c9472000-07-11 07:12:36 -0500623#if defined(_WIN32_WCE)
624 MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH);
625 if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
626#else
Andreas Dilger47a0c421997-05-16 02:46:07 -0500627 if ((fpin = fopen(inname, "rb")) == NULL)
Glenn Randers-Pehrsonff9c9472000-07-11 07:12:36 -0500628#endif
Guy Schalnat0f716451995-11-28 11:22:13 -0600629 {
630 fprintf(STDERR, "Could not find input file %s\n", inname);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600631 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600632 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500633
Glenn Randers-Pehrsonff9c9472000-07-11 07:12:36 -0500634#if defined(_WIN32_WCE)
635 MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH);
636 if ((fpout = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE)
637#else
Andreas Dilger47a0c421997-05-16 02:46:07 -0500638 if ((fpout = fopen(outname, "wb")) == NULL)
Glenn Randers-Pehrsonff9c9472000-07-11 07:12:36 -0500639#endif
Guy Schalnat0f716451995-11-28 11:22:13 -0600640 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500641 fprintf(STDERR, "Could not open output file %s\n", outname);
Glenn Randers-Pehrsonff9c9472000-07-11 07:12:36 -0500642 FCLOSE(fpin);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600643 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600644 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500645
Andreas Dilger47a0c421997-05-16 02:46:07 -0500646 png_debug(0, "Allocating read and write structures\n");
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500647#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500648 read_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
649 png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500650 (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
651#else
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500652 read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
653 png_error_ptr_NULL, png_error_ptr_NULL);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500654#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600655#if defined(PNG_NO_STDIO)
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500656 png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error,
657 pngtest_warning);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600658#endif
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500659#ifdef PNG_WRITE_SUPPORTED
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500660#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500661 write_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
662 png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500663 (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
664#else
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500665 write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
666 png_error_ptr_NULL, png_error_ptr_NULL);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500667#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600668#if defined(PNG_NO_STDIO)
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500669 png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error,
670 pngtest_warning);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600671#endif
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500672#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500673 png_debug(0, "Allocating read_info, write_info and end_info structures\n");
674 read_info_ptr = png_create_info_struct(read_ptr);
Glenn Randers-Pehrson1fd5fb32001-05-06 05:34:26 -0500675 end_info_ptr = png_create_info_struct(read_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500676#ifdef PNG_WRITE_SUPPORTED
677 write_info_ptr = png_create_info_struct(write_ptr);
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -0500678 write_end_info_ptr = png_create_info_struct(write_ptr);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500679#endif
Guy Schalnate5a37791996-06-05 15:50:50 -0500680
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600681#ifdef PNG_SETJMP_SUPPORTED
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -0600682 png_debug(0, "Setting jmpbuf for read struct\n");
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600683#ifdef USE_FAR_KEYWORD
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -0600684 if (setjmp(jmpbuf))
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600685#else
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -0600686 if (setjmp(png_jmpbuf(read_ptr)))
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600687#endif
Guy Schalnat0f716451995-11-28 11:22:13 -0600688 {
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600689 fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
Glenn Randers-Pehrsond020e9d2002-06-28 09:34:00 -0500690 if (row_buf)
691 png_free(read_ptr, row_buf);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500692 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500693#ifdef PNG_WRITE_SUPPORTED
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -0500694 png_destroy_info_struct(write_ptr, &write_end_info_ptr);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500695 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500696#endif
Glenn Randers-Pehrsonff9c9472000-07-11 07:12:36 -0500697 FCLOSE(fpin);
698 FCLOSE(fpout);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600699 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600700 }
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600701#ifdef USE_FAR_KEYWORD
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500702 png_memcpy(png_jmpbuf(read_ptr),jmpbuf,png_sizeof(jmp_buf));
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600703#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500704
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500705#ifdef PNG_WRITE_SUPPORTED
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -0600706 png_debug(0, "Setting jmpbuf for write struct\n");
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600707#ifdef USE_FAR_KEYWORD
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -0600708 if (setjmp(jmpbuf))
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600709#else
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -0600710 if (setjmp(png_jmpbuf(write_ptr)))
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600711#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600712 {
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600713 fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500714 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -0500715 png_destroy_info_struct(write_ptr, &write_end_info_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500716#ifdef PNG_WRITE_SUPPORTED
Andreas Dilger47a0c421997-05-16 02:46:07 -0500717 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500718#endif
Glenn Randers-Pehrsonff9c9472000-07-11 07:12:36 -0500719 FCLOSE(fpin);
720 FCLOSE(fpout);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600721 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600722 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600723#ifdef USE_FAR_KEYWORD
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500724 png_memcpy(png_jmpbuf(write_ptr),jmpbuf,png_sizeof(jmp_buf));
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600725#endif
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600726#endif
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500727#endif
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600728
Andreas Dilger47a0c421997-05-16 02:46:07 -0500729 png_debug(0, "Initializing input and output streams\n");
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600730#if !defined(PNG_NO_STDIO)
Guy Schalnate5a37791996-06-05 15:50:50 -0500731 png_init_io(read_ptr, fpin);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500732# ifdef PNG_WRITE_SUPPORTED
Guy Schalnate5a37791996-06-05 15:50:50 -0500733 png_init_io(write_ptr, fpout);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500734# endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600735#else
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500736 png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data);
Glenn Randers-Pehrson8b6a8892001-05-18 04:54:50 -0500737# ifdef PNG_WRITE_SUPPORTED
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500738 png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data,
Glenn Randers-Pehrson8b6a8892001-05-18 04:54:50 -0500739# if defined(PNG_WRITE_FLUSH_SUPPORTED)
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500740 pngtest_flush);
Glenn Randers-Pehrson8b6a8892001-05-18 04:54:50 -0500741# else
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600742 NULL);
Glenn Randers-Pehrson8b6a8892001-05-18 04:54:50 -0500743# endif
744# endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600745#endif
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600746 if(status_dots_requested == 1)
747 {
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500748#ifdef PNG_WRITE_SUPPORTED
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600749 png_set_write_status_fn(write_ptr, write_row_callback);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500750#endif
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600751 png_set_read_status_fn(read_ptr, read_row_callback);
752 }
753 else
754 {
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500755#ifdef PNG_WRITE_SUPPORTED
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500756 png_set_write_status_fn(write_ptr, png_write_status_ptr_NULL);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500757#endif
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500758 png_set_read_status_fn(read_ptr, png_read_status_ptr_NULL);
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600759 }
760
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500761#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
762 {
763 int i;
764 for(i=0; i<256; i++)
765 filters_used[i]=0;
766 png_set_read_user_transform_fn(read_ptr, count_filters);
767 }
768#endif
769#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
770 zero_samples=0;
771 png_set_write_user_transform_fn(write_ptr, count_zero_samples);
772#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500773
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600774#define HANDLE_CHUNK_IF_SAFE 2
775#define HANDLE_CHUNK_ALWAYS 3
776#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
Glenn Randers-Pehrson6c97ddb2001-10-24 22:01:19 -0500777 png_set_keep_unknown_chunks(read_ptr, HANDLE_CHUNK_ALWAYS,
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500778 png_bytep_NULL, 0);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600779#endif
780#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
Glenn Randers-Pehrson6c97ddb2001-10-24 22:01:19 -0500781 png_set_keep_unknown_chunks(write_ptr, HANDLE_CHUNK_IF_SAFE,
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500782 png_bytep_NULL, 0);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600783#endif
784
Andreas Dilger47a0c421997-05-16 02:46:07 -0500785 png_debug(0, "Reading info struct\n");
786 png_read_info(read_ptr, read_info_ptr);
Guy Schalnat0d580581995-07-20 02:43:20 -0500787
Andreas Dilger47a0c421997-05-16 02:46:07 -0500788 png_debug(0, "Transferring info struct\n");
789 {
790 int interlace_type, compression_type, filter_type;
Guy Schalnat0d580581995-07-20 02:43:20 -0500791
Andreas Dilger47a0c421997-05-16 02:46:07 -0500792 if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
793 &color_type, &interlace_type, &compression_type, &filter_type))
794 {
795 png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600796#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500797 color_type, interlace_type, compression_type, filter_type);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600798#else
799 color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
800#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500801 }
802 }
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500803#if defined(PNG_FIXED_POINT_SUPPORTED)
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600804#if defined(PNG_cHRM_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500805 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600806 png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600807 blue_y;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600808 if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
Andreas Dilger47a0c421997-05-16 02:46:07 -0500809 &red_y, &green_x, &green_y, &blue_x, &blue_y))
810 {
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600811 png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x,
Andreas Dilger47a0c421997-05-16 02:46:07 -0500812 red_y, green_x, green_y, blue_x, blue_y);
813 }
814 }
815#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600816#if defined(PNG_gAMA_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500817 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600818 png_fixed_point gamma;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500819
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600820 if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma))
Andreas Dilger47a0c421997-05-16 02:46:07 -0500821 {
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600822 png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500823 }
824 }
825#endif
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500826#else /* Use floating point versions */
827#if defined(PNG_FLOATING_POINT_SUPPORTED)
828#if defined(PNG_cHRM_SUPPORTED)
829 {
830 double white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
831 blue_y;
832 if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
833 &red_y, &green_x, &green_y, &blue_x, &blue_y))
834 {
835 png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
836 red_y, green_x, green_y, blue_x, blue_y);
837 }
838 }
839#endif
840#if defined(PNG_gAMA_SUPPORTED)
841 {
842 double gamma;
843
844 if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
845 {
846 png_set_gAMA(write_ptr, write_info_ptr, gamma);
847 }
848 }
849#endif
850#endif /* floating point */
851#endif /* fixed point */
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600852#if defined(PNG_iCCP_SUPPORTED)
853 {
854 png_charp name;
855 png_charp profile;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600856 png_uint_32 proflen;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600857 int compression_type;
858
859 if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,
860 &profile, &proflen))
861 {
862 png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,
863 profile, proflen);
864 }
865 }
866#endif
867#if defined(PNG_sRGB_SUPPORTED)
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600868 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600869 int intent;
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600870
871 if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
872 {
873 png_set_sRGB(write_ptr, write_info_ptr, intent);
874 }
875 }
876#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600877 {
878 png_colorp palette;
879 int num_palette;
880
881 if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
882 {
883 png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
884 }
885 }
886#if defined(PNG_bKGD_SUPPORTED)
887 {
888 png_color_16p background;
889
890 if (png_get_bKGD(read_ptr, read_info_ptr, &background))
891 {
892 png_set_bKGD(write_ptr, write_info_ptr, background);
893 }
894 }
895#endif
896#if defined(PNG_hIST_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500897 {
898 png_uint_16p hist;
899
900 if (png_get_hIST(read_ptr, read_info_ptr, &hist))
901 {
902 png_set_hIST(write_ptr, write_info_ptr, hist);
903 }
904 }
905#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600906#if defined(PNG_oFFs_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500907 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600908 png_int_32 offset_x, offset_y;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500909 int unit_type;
910
911 if (png_get_oFFs(read_ptr, read_info_ptr,&offset_x,&offset_y,&unit_type))
912 {
913 png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
914 }
915 }
916#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600917#if defined(PNG_pCAL_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500918 {
919 png_charp purpose, units;
920 png_charpp params;
921 png_int_32 X0, X1;
922 int type, nparams;
923
924 if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
925 &nparams, &units, &params))
926 {
927 png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
928 nparams, units, params);
929 }
930 }
931#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600932#if defined(PNG_pHYs_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500933 {
934 png_uint_32 res_x, res_y;
935 int unit_type;
936
937 if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
938 {
939 png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
940 }
941 }
942#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600943#if defined(PNG_sBIT_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500944 {
945 png_color_8p sig_bit;
946
947 if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
948 {
949 png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
950 }
951 }
952#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600953#if defined(PNG_sCAL_SUPPORTED)
954#ifdef PNG_FLOATING_POINT_SUPPORTED
955 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600956 int unit;
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500957 double scal_width, scal_height;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600958
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500959 if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,
960 &scal_height))
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600961 {
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500962 png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600963 }
964 }
965#else
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600966#ifdef PNG_FIXED_POINT_SUPPORTED
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600967 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600968 int unit;
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500969 png_charp scal_width, scal_height;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600970
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500971 if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,
972 &scal_height))
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600973 {
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500974 png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, scal_height);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600975 }
976 }
977#endif
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600978#endif
979#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600980#if defined(PNG_TEXT_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500981 {
982 png_textp text_ptr;
983 int num_text;
984
985 if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
986 {
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600987 png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500988 png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
989 }
990 }
991#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600992#if defined(PNG_tIME_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500993 {
994 png_timep mod_time;
995
996 if (png_get_tIME(read_ptr, read_info_ptr, &mod_time))
997 {
998 png_set_tIME(write_ptr, write_info_ptr, mod_time);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500999#if defined(PNG_TIME_RFC1123_SUPPORTED)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001000 /* we have to use png_strcpy instead of "=" because the string
1001 pointed to by png_convert_to_rfc1123() gets free'ed before
1002 we use it */
1003 png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time));
1004 tIME_chunk_present++;
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001005#endif /* PNG_TIME_RFC1123_SUPPORTED */
Glenn Randers-Pehrsonc9442291999-01-06 21:50:16 -06001006 }
Andreas Dilger47a0c421997-05-16 02:46:07 -05001007 }
1008#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001009#if defined(PNG_tRNS_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -05001010 {
1011 png_bytep trans;
1012 int num_trans;
1013 png_color_16p trans_values;
1014
1015 if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans,
1016 &trans_values))
1017 {
1018 png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans,
1019 trans_values);
1020 }
1021 }
1022#endif
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001023#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1024 {
1025 png_unknown_chunkp unknowns;
1026 int num_unknowns = (int)png_get_unknown_chunks(read_ptr, read_info_ptr,
1027 &unknowns);
1028 if (num_unknowns)
1029 {
1030 png_size_t i;
1031 png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns,
1032 num_unknowns);
1033 /* copy the locations from the read_info_ptr. The automatically
1034 generated locations in write_info_ptr are wrong because we
1035 haven't written anything yet */
1036 for (i = 0; i < (png_size_t)num_unknowns; i++)
Glenn Randers-Pehrson228bd392000-04-23 23:14:02 -05001037 png_set_unknown_chunk_location(write_ptr, write_info_ptr, i,
1038 unknowns[i].location);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001039 }
1040 }
1041#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -05001042
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001043#ifdef PNG_WRITE_SUPPORTED
Andreas Dilger47a0c421997-05-16 02:46:07 -05001044 png_debug(0, "\nWriting info struct\n");
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -06001045
1046/* If we wanted, we could write info in two steps:
1047 png_write_info_before_PLTE(write_ptr, write_info_ptr);
1048 */
Andreas Dilger47a0c421997-05-16 02:46:07 -05001049 png_write_info(write_ptr, write_info_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001050#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -05001051
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001052#ifdef SINGLE_ROWBUF_ALLOC
1053 png_debug(0, "\nAllocating row buffer...");
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001054 row_buf = (png_bytep)png_malloc(read_ptr,
Andreas Dilger47a0c421997-05-16 02:46:07 -05001055 png_get_rowbytes(read_ptr, read_info_ptr));
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001056 png_debug1(0, "0x%08lx\n\n", (unsigned long)row_buf);
1057#endif /* SINGLE_ROWBUF_ALLOC */
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001058 png_debug(0, "Writing row data\n");
Guy Schalnat0d580581995-07-20 02:43:20 -05001059
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001060#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
1061 defined(PNG_WRITE_INTERLACING_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -05001062 num_pass = png_set_interlace_handling(read_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001063# ifdef PNG_WRITE_SUPPORTED
Andreas Dilger47a0c421997-05-16 02:46:07 -05001064 png_set_interlace_handling(write_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001065# endif
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001066#else
1067 num_pass=1;
1068#endif
Guy Schalnat0d580581995-07-20 02:43:20 -05001069
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001070#ifdef PNGTEST_TIMING
1071 t_stop = (float)clock();
1072 t_misc += (t_stop - t_start);
1073 t_start = t_stop;
1074#endif
Guy Schalnat0f716451995-11-28 11:22:13 -06001075 for (pass = 0; pass < num_pass; pass++)
1076 {
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001077 png_debug1(0, "Writing row data for pass %d\n",pass);
Andreas Dilger47a0c421997-05-16 02:46:07 -05001078 for (y = 0; y < height; y++)
Guy Schalnat0f716451995-11-28 11:22:13 -06001079 {
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001080#ifndef SINGLE_ROWBUF_ALLOC
1081 png_debug2(0, "\nAllocating row buffer (pass %d, y = %ld)...", pass,y);
1082 row_buf = (png_bytep)png_malloc(read_ptr,
1083 png_get_rowbytes(read_ptr, read_info_ptr));
1084 png_debug2(0, "0x%08lx (%ld bytes)\n", (unsigned long)row_buf,
1085 png_get_rowbytes(read_ptr, read_info_ptr));
1086#endif /* !SINGLE_ROWBUF_ALLOC */
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -05001087 png_read_rows(read_ptr, (png_bytepp)&row_buf, png_bytepp_NULL, 1);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001088
1089#ifdef PNG_WRITE_SUPPORTED
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001090#ifdef PNGTEST_TIMING
1091 t_stop = (float)clock();
1092 t_decode += (t_stop - t_start);
1093 t_start = t_stop;
1094#endif
Guy Schalnate5a37791996-06-05 15:50:50 -05001095 png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001096#ifdef PNGTEST_TIMING
1097 t_stop = (float)clock();
1098 t_encode += (t_stop - t_start);
1099 t_start = t_stop;
1100#endif
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001101#endif /* PNG_WRITE_SUPPORTED */
1102
1103#ifndef SINGLE_ROWBUF_ALLOC
1104 png_debug2(0, "Freeing row buffer (pass %d, y = %ld)\n\n", pass, y);
1105 png_free(read_ptr, row_buf);
1106#endif /* !SINGLE_ROWBUF_ALLOC */
Guy Schalnat0f716451995-11-28 11:22:13 -06001107 }
1108 }
Guy Schalnat0d580581995-07-20 02:43:20 -05001109
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001110#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
Glenn Randers-Pehrsona77ef622000-02-18 13:48:52 -06001111 png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001112#endif
1113#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
Glenn Randers-Pehrsona77ef622000-02-18 13:48:52 -06001114 png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001115#endif
1116
Andreas Dilger47a0c421997-05-16 02:46:07 -05001117 png_debug(0, "Reading and writing end_info data\n");
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001118
Andreas Dilger47a0c421997-05-16 02:46:07 -05001119 png_read_end(read_ptr, end_info_ptr);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001120#if defined(PNG_TEXT_SUPPORTED)
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -05001121 {
1122 png_textp text_ptr;
1123 int num_text;
1124
1125 if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0)
1126 {
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001127 png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text);
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -05001128 png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text);
1129 }
1130 }
1131#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001132#if defined(PNG_tIME_SUPPORTED)
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -05001133 {
1134 png_timep mod_time;
1135
1136 if (png_get_tIME(read_ptr, end_info_ptr, &mod_time))
1137 {
1138 png_set_tIME(write_ptr, write_end_info_ptr, mod_time);
1139#if defined(PNG_TIME_RFC1123_SUPPORTED)
1140 /* we have to use png_strcpy instead of "=" because the string
1141 pointed to by png_convert_to_rfc1123() gets free'ed before
1142 we use it */
1143 png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time));
1144 tIME_chunk_present++;
1145#endif /* PNG_TIME_RFC1123_SUPPORTED */
1146 }
1147 }
1148#endif
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001149#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1150 {
1151 png_unknown_chunkp unknowns;
1152 int num_unknowns;
1153 num_unknowns = (int)png_get_unknown_chunks(read_ptr, end_info_ptr,
1154 &unknowns);
1155 if (num_unknowns)
1156 {
1157 png_size_t i;
1158 png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,
1159 num_unknowns);
1160 /* copy the locations from the read_info_ptr. The automatically
1161 generated locations in write_end_info_ptr are wrong because we
1162 haven't written the end_info yet */
1163 for (i = 0; i < (png_size_t)num_unknowns; i++)
Glenn Randers-Pehrson228bd392000-04-23 23:14:02 -05001164 png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i,
1165 unknowns[i].location);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001166 }
1167 }
1168#endif
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001169#ifdef PNG_WRITE_SUPPORTED
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -05001170 png_write_end(write_ptr, write_end_info_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001171#endif
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001172
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001173#ifdef PNG_EASY_ACCESS_SUPPORTED
1174 if(verbose)
1175 {
1176 png_uint_32 iwidth, iheight;
1177 iwidth = png_get_image_width(write_ptr, write_info_ptr);
1178 iheight = png_get_image_height(write_ptr, write_info_ptr);
1179 fprintf(STDERR, "Image width = %lu, height = %lu\n",
1180 iwidth, iheight);
1181 }
1182#endif
Guy Schalnat0d580581995-07-20 02:43:20 -05001183
Andreas Dilger47a0c421997-05-16 02:46:07 -05001184 png_debug(0, "Destroying data structs\n");
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001185#ifdef SINGLE_ROWBUF_ALLOC
1186 png_debug(1, "destroying row_buf for read_ptr\n");
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001187 png_free(read_ptr, row_buf);
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -05001188 row_buf=NULL;
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001189#endif /* SINGLE_ROWBUF_ALLOC */
1190 png_debug(1, "destroying read_ptr, read_info_ptr, end_info_ptr\n");
Andreas Dilger47a0c421997-05-16 02:46:07 -05001191 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001192#ifdef PNG_WRITE_SUPPORTED
1193 png_debug(1, "destroying write_end_info_ptr\n");
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -05001194 png_destroy_info_struct(write_ptr, &write_end_info_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001195 png_debug(1, "destroying write_ptr, write_info_ptr\n");
Andreas Dilger47a0c421997-05-16 02:46:07 -05001196 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001197#endif
1198 png_debug(0, "Destruction complete.\n");
Guy Schalnat0d580581995-07-20 02:43:20 -05001199
Glenn Randers-Pehrsonff9c9472000-07-11 07:12:36 -05001200 FCLOSE(fpin);
1201 FCLOSE(fpout);
Guy Schalnat0d580581995-07-20 02:43:20 -05001202
Andreas Dilger47a0c421997-05-16 02:46:07 -05001203 png_debug(0, "Opening files for comparison\n");
Glenn Randers-Pehrsonff9c9472000-07-11 07:12:36 -05001204#if defined(_WIN32_WCE)
1205 MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH);
1206 if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
1207#else
Andreas Dilger47a0c421997-05-16 02:46:07 -05001208 if ((fpin = fopen(inname, "rb")) == NULL)
Glenn Randers-Pehrsonff9c9472000-07-11 07:12:36 -05001209#endif
Guy Schalnat0f716451995-11-28 11:22:13 -06001210 {
Guy Schalnate5a37791996-06-05 15:50:50 -05001211 fprintf(STDERR, "Could not find file %s\n", inname);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -06001212 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -06001213 }
Guy Schalnat0d580581995-07-20 02:43:20 -05001214
Glenn Randers-Pehrsonff9c9472000-07-11 07:12:36 -05001215#if defined(_WIN32_WCE)
1216 MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH);
1217 if ((fpout = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
1218#else
Andreas Dilger47a0c421997-05-16 02:46:07 -05001219 if ((fpout = fopen(outname, "rb")) == NULL)
Glenn Randers-Pehrsonff9c9472000-07-11 07:12:36 -05001220#endif
Guy Schalnat0f716451995-11-28 11:22:13 -06001221 {
Guy Schalnate5a37791996-06-05 15:50:50 -05001222 fprintf(STDERR, "Could not find file %s\n", outname);
Glenn Randers-Pehrsonff9c9472000-07-11 07:12:36 -05001223 FCLOSE(fpin);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -06001224 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -06001225 }
Andreas Dilger47a0c421997-05-16 02:46:07 -05001226
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -06001227 for(;;)
Guy Schalnat0f716451995-11-28 11:22:13 -06001228 {
Andreas Dilger47a0c421997-05-16 02:46:07 -05001229 png_size_t num_in, num_out;
Guy Schalnat0d580581995-07-20 02:43:20 -05001230
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -05001231 READFILE(fpin, inbuf, 1, num_in);
1232 READFILE(fpout, outbuf, 1, num_out);
Guy Schalnat0d580581995-07-20 02:43:20 -05001233
Guy Schalnat0f716451995-11-28 11:22:13 -06001234 if (num_in != num_out)
1235 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001236 fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
Guy Schalnate5a37791996-06-05 15:50:50 -05001237 inname, outname);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001238 if(wrote_question == 0)
1239 {
1240 fprintf(STDERR,
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001241 " Was %s written with the same maximum IDAT chunk size (%d bytes),",
1242 inname,PNG_ZBUF_SIZE);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001243 fprintf(STDERR,
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001244 "\n filtering heuristic (libpng default), compression");
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001245 fprintf(STDERR,
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001246 " level (zlib default),\n and zlib version (%s)?\n\n",
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001247 ZLIB_VERSION);
1248 wrote_question=1;
1249 }
Glenn Randers-Pehrsonff9c9472000-07-11 07:12:36 -05001250 FCLOSE(fpin);
1251 FCLOSE(fpout);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001252 return (0);
Guy Schalnat0f716451995-11-28 11:22:13 -06001253 }
Guy Schalnat0d580581995-07-20 02:43:20 -05001254
Guy Schalnat0f716451995-11-28 11:22:13 -06001255 if (!num_in)
1256 break;
Guy Schalnat0d580581995-07-20 02:43:20 -05001257
Andreas Dilger47a0c421997-05-16 02:46:07 -05001258 if (png_memcmp(inbuf, outbuf, num_in))
Guy Schalnat0f716451995-11-28 11:22:13 -06001259 {
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001260 fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001261 if(wrote_question == 0)
1262 {
1263 fprintf(STDERR,
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001264 " Was %s written with the same maximum IDAT chunk size (%d bytes),",
1265 inname,PNG_ZBUF_SIZE);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001266 fprintf(STDERR,
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001267 "\n filtering heuristic (libpng default), compression");
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001268 fprintf(STDERR,
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001269 " level (zlib default),\n and zlib version (%s)?\n\n",
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001270 ZLIB_VERSION);
1271 wrote_question=1;
1272 }
Glenn Randers-Pehrsonff9c9472000-07-11 07:12:36 -05001273 FCLOSE(fpin);
1274 FCLOSE(fpout);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001275 return (0);
Guy Schalnat0f716451995-11-28 11:22:13 -06001276 }
1277 }
1278
Glenn Randers-Pehrsonff9c9472000-07-11 07:12:36 -05001279 FCLOSE(fpin);
1280 FCLOSE(fpout);
Guy Schalnat0d580581995-07-20 02:43:20 -05001281
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -06001282 return (0);
Guy Schalnat0d580581995-07-20 02:43:20 -05001283}
Guy Schalnat51f0eb41995-09-26 05:22:39 -05001284
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001285/* input and output filenames */
1286#ifdef RISCOS
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001287static PNG_CONST char *inname = "pngtest/png";
1288static PNG_CONST char *outname = "pngout/png";
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001289#else
Glenn Randers-Pehrson983ec161998-03-07 11:24:03 -06001290static PNG_CONST char *inname = "pngtest.png";
1291static PNG_CONST char *outname = "pngout.png";
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001292#endif
1293
1294int
1295main(int argc, char *argv[])
1296{
1297 int multiple = 0;
1298 int ierror = 0;
1299
1300 fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001301 fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION);
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001302 fprintf(STDERR,"%s",png_get_copyright(NULL));
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -06001303 /* Show the version of libpng used in building the library */
Glenn Randers-Pehrson1ef65b62000-05-12 06:19:53 -05001304 fprintf(STDERR," library (%lu):%s", png_access_version_number(),
1305 png_get_header_version(NULL));
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -06001306 /* Show the version of libpng used in building the application */
Glenn Randers-Pehrson13944802000-06-24 07:42:42 -05001307 fprintf(STDERR," pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER,
Glenn Randers-Pehrson1ef65b62000-05-12 06:19:53 -05001308 PNG_HEADER_VERSION_STRING);
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -05001309 fprintf(STDERR," png_sizeof(png_struct)=%ld, png_sizeof(png_info)=%ld\n",
1310 (long)png_sizeof(png_struct), (long)png_sizeof(png_info));
1311 fprintf(STDERR," PNG_UINT_31_MAX=%lu, PNG_UINT_32_MAX=%lu\n",
1312 PNG_UINT_31_MAX, PNG_UINT_32_MAX);
1313 fprintf(STDERR," PNG_SIZE_MAX=%u\n",PNG_SIZE_MAX);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001314
1315 /* Do some consistency checking on the memory allocation settings, I'm
1316 not sure this matters, but it is nice to know, the first of these
1317 tests should be impossible because of the way the macros are set
1318 in pngconf.h */
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -06001319#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001320 fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n");
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -06001321#endif
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001322 /* I think the following can happen. */
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -06001323#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001324 fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n");
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -06001325#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001326
1327 if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
1328 {
1329 fprintf(STDERR,
1330 "Warning: versions are different between png.h and png.c\n");
1331 fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING);
1332 fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver);
1333 ++ierror;
1334 }
1335
1336 if (argc > 1)
1337 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001338 if (strcmp(argv[1], "-m") == 0)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001339 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001340 multiple = 1;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001341 status_dots_requested = 0;
1342 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001343 else if (strcmp(argv[1], "-mv") == 0 ||
1344 strcmp(argv[1], "-vm") == 0 )
1345 {
1346 multiple = 1;
1347 verbose = 1;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001348 status_dots_requested = 1;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001349 }
1350 else if (strcmp(argv[1], "-v") == 0)
1351 {
1352 verbose = 1;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001353 status_dots_requested = 1;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001354 inname = argv[2];
1355 }
1356 else
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001357 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001358 inname = argv[1];
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001359 status_dots_requested = 0;
1360 }
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001361 }
1362
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001363 if (!multiple && argc == 3+verbose)
1364 outname = argv[2+verbose];
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001365
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001366 if ((!multiple && argc > 3+verbose) || (multiple && argc < 2))
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001367 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001368 fprintf(STDERR,
1369 "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001370 argv[0], argv[0]);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001371 fprintf(STDERR,
1372 " reads/writes one PNG file (without -m) or multiple files (-m)\n");
1373 fprintf(STDERR,
1374 " with -m %s is used as a temporary file\n", outname);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001375 exit(1);
1376 }
1377
1378 if (multiple)
1379 {
1380 int i;
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001381#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001382 int allocation_now = current_allocation;
1383#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001384 for (i=2; i<argc; ++i)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001385 {
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -05001386#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1387 int k;
1388#endif
1389 int kerror;
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001390 fprintf(STDERR, "Testing %s:",argv[i]);
1391 kerror = test_one_file(argv[i], outname);
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001392 if (kerror == 0)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001393 {
Glenn Randers-Pehrson38d73af1998-03-07 21:30:44 -06001394#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -05001395 fprintf(STDERR, "\n PASS (%lu zero samples)\n",zero_samples);
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001396#else
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001397 fprintf(STDERR, " PASS\n");
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001398#endif
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001399#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1400 for (k=0; k<256; k++)
1401 if(filters_used[k])
1402 fprintf(STDERR, " Filter %d was used %lu times\n",
1403 k,filters_used[k]);
1404#endif
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001405#if defined(PNG_TIME_RFC1123_SUPPORTED)
1406 if(tIME_chunk_present != 0)
1407 fprintf(STDERR, " tIME = %s\n",tIME_string);
1408 tIME_chunk_present = 0;
1409#endif /* PNG_TIME_RFC1123_SUPPORTED */
1410 }
1411 else
1412 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001413 fprintf(STDERR, " FAIL\n");
1414 ierror += kerror;
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001415 }
1416#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001417 if (allocation_now != current_allocation)
1418 fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
1419 current_allocation-allocation_now);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001420 if (current_allocation != 0)
1421 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001422 memory_infop pinfo = pinformation;
1423
1424 fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
1425 current_allocation);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001426 while (pinfo != NULL)
1427 {
Glenn Randers-Pehrsonb1828932001-06-23 08:03:17 -05001428 fprintf(STDERR, " %lu bytes at %x\n", pinfo->size,
1429 (unsigned int) pinfo->pointer);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001430 pinfo = pinfo->next;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001431 }
Glenn Randers-Pehrson2687fcc1998-01-07 20:54:20 -06001432 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001433#endif
1434 }
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001435#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -05001436 fprintf(STDERR, " Current memory allocation: %10d bytes\n",
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001437 current_allocation);
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -05001438 fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001439 maximum_allocation);
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -05001440 fprintf(STDERR, " Total memory allocation: %10d bytes\n",
1441 total_allocation);
1442 fprintf(STDERR, " Number of allocations: %10d\n",
1443 num_allocations);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001444#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001445 }
1446 else
1447 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001448 int i;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001449 for (i=0; i<3; ++i)
1450 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001451 int kerror;
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001452#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001453 int allocation_now = current_allocation;
1454#endif
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001455 if (i == 1) status_dots_requested = 1;
1456 else if(verbose == 0)status_dots_requested = 0;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001457 if (i == 0 || verbose == 1 || ierror != 0)
1458 fprintf(STDERR, "Testing %s:",inname);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001459 kerror = test_one_file(inname, outname);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001460 if(kerror == 0)
1461 {
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001462 if(verbose == 1 || i == 2)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001463 {
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -05001464#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001465 int k;
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -05001466#endif
Glenn Randers-Pehrson38d73af1998-03-07 21:30:44 -06001467#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -05001468 fprintf(STDERR, "\n PASS (%lu zero samples)\n",zero_samples);
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001469#else
1470 fprintf(STDERR, " PASS\n");
1471#endif
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001472#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1473 for (k=0; k<256; k++)
1474 if(filters_used[k])
1475 fprintf(STDERR, " Filter %d was used %lu times\n",
1476 k,filters_used[k]);
1477#endif
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001478#if defined(PNG_TIME_RFC1123_SUPPORTED)
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001479 if(tIME_chunk_present != 0)
1480 fprintf(STDERR, " tIME = %s\n",tIME_string);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001481#endif /* PNG_TIME_RFC1123_SUPPORTED */
1482 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001483 }
1484 else
1485 {
1486 if(verbose == 0 && i != 2)
1487 fprintf(STDERR, "Testing %s:",inname);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001488 fprintf(STDERR, " FAIL\n");
1489 ierror += kerror;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001490 }
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001491#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001492 if (allocation_now != current_allocation)
1493 fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
1494 current_allocation-allocation_now);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001495 if (current_allocation != 0)
1496 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001497 memory_infop pinfo = pinformation;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001498
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001499 fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
1500 current_allocation);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001501 while (pinfo != NULL)
1502 {
Glenn Randers-Pehrsonb1828932001-06-23 08:03:17 -05001503 fprintf(STDERR," %lu bytes at %x\n",
1504 pinfo->size, (unsigned int)pinfo->pointer);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001505 pinfo = pinfo->next;
1506 }
1507 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001508#endif
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001509 }
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001510#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -05001511 fprintf(STDERR, " Current memory allocation: %10d bytes\n",
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001512 current_allocation);
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -05001513 fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001514 maximum_allocation);
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -05001515 fprintf(STDERR, " Total memory allocation: %10d bytes\n",
1516 total_allocation);
1517 fprintf(STDERR, " Number of allocations: %10d\n",
1518 num_allocations);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001519#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001520 }
1521
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001522#ifdef PNGTEST_TIMING
1523 t_stop = (float)clock();
1524 t_misc += (t_stop - t_start);
1525 t_start = t_stop;
1526 fprintf(STDERR," CPU time used = %.3f seconds",
1527 (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
1528 fprintf(STDERR," (decoding %.3f,\n",
1529 t_decode/(float)CLOCKS_PER_SEC);
1530 fprintf(STDERR," encoding %.3f ,",
1531 t_encode/(float)CLOCKS_PER_SEC);
1532 fprintf(STDERR," other %.3f seconds)\n\n",
1533 t_misc/(float)CLOCKS_PER_SEC);
1534#endif
1535
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001536 if (ierror == 0)
1537 fprintf(STDERR, "libpng passes test\n");
1538 else
1539 fprintf(STDERR, "libpng FAILS test\n");
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001540 return (int)(ierror != 0);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001541}
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001542
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001543/* Generate a compiler error if there is an old png.h in the search path. */
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -05001544typedef version_1_2_6beta4 your_png_h_is_not_version_1_2_6beta4;