blob: 8acd9a684c72530a779044468ad722695676e755 [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-Pehrsond60b8fa2006-04-20 21:31:14 -05004 * Last changed in libpng 1.4.0 April 20, 2006
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06005 * For conditions of distribution and use, see copyright notice in png.h
Glenn Randers-Pehrsond60b8fa2006-04-20 21:31:14 -05006 * Copyright (c) 1998-2006 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
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -050035 __error__ "(f|w)printf functions are not supported on old WindowsCE.";
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -050036# endif
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -050037#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -050038
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -050039#include <stdio.h>
40#include <stdlib.h>
41
42#ifdef PNG_NO_STDIO
43 typedef FILE * png_FILE_p;
Glenn Randers-Pehrsonbe9de0f2001-01-22 08:52:16 -060044#endif
45
Andreas Dilger47a0c421997-05-16 02:46:07 -050046/* Makes pngtest verbose so we can find problems (needs to be before png.h) */
47#ifndef PNG_DEBUG
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -050048# define PNG_DEBUG 0
49#endif
50
51#if !PNG_DEBUG
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -050052# define SINGLE_ROWBUF_ALLOC /* makes buffer overruns easier to nail */
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -060053#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -050054
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -050055/* Turn on CPU timing
56#define PNGTEST_TIMING
57*/
58
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -060059#ifdef PNG_NO_FLOATING_POINT_SUPPORTED
60#undef PNGTEST_TIMING
61#endif
62
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -050063#ifdef PNGTEST_TIMING
64static float t_start, t_stop, t_decode, t_encode, t_misc;
65#include <time.h>
66#endif
67
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -060068/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
69#ifndef png_jmpbuf
70# define png_jmpbuf(png_ptr) png_ptr->jmpbuf
71#endif
72
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -050073#ifdef PNGTEST_TIMING
74static float t_start, t_stop, t_decode, t_encode, t_misc;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -060075#if !defined(PNG_tIME_SUPPORTED)
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -050076#include <time.h>
77#endif
78#endif
79
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050080#if defined(PNG_TIME_RFC1123_SUPPORTED)
81static int tIME_chunk_present=0;
Glenn Randers-Pehrson345bc271998-06-14 14:43:31 -050082static char tIME_string[30] = "no tIME chunk present in file";
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -060083#endif
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050084
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -050085static int verbose = 0;
86
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -060087int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname));
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -060088
Guy Schalnat0d580581995-07-20 02:43:20 -050089#ifdef __TURBOC__
90#include <mem.h>
91#endif
92
93/* defined so I can write to a file on gui/windowing platforms */
Guy Schalnat6d764711995-12-19 03:22:19 -060094/* #define STDERR stderr */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060095#define STDERR stdout /* for DOS */
Guy Schalnat0d580581995-07-20 02:43:20 -050096
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -060097/* example of using row callbacks to make a simple progress meter */
98static int status_pass=1;
99static int status_dots_requested=0;
100static int status_dots=1;
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600101
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600102void
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500103read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
Glenn Randers-Pehrson0cc2f952002-10-03 06:32:37 -0500104void
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600105read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600106{
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500107 if(png_ptr == NULL || row_number > PNG_UINT_31_MAX) return;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600108 if(status_pass != pass)
109 {
110 fprintf(stdout,"\n Pass %d: ",pass);
111 status_pass = pass;
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500112 status_dots = 31;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600113 }
114 status_dots--;
115 if(status_dots == 0)
116 {
117 fprintf(stdout, "\n ");
118 status_dots=30;
119 }
120 fprintf(stdout, "r");
121}
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600122
Glenn Randers-Pehrson0cc2f952002-10-03 06:32:37 -0500123void
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500124write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
Glenn Randers-Pehrson0cc2f952002-10-03 06:32:37 -0500125void
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600126write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600127{
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500128 if(png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) return;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600129 fprintf(stdout, "w");
130}
131
132
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500133#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
134/* Example of using user transform callback (we don't transform anything,
135 but merely examine the row filters. We set this to 256 rather than
136 5 in case illegal filter values are present.) */
137static png_uint_32 filters_used[256];
138void
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500139count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data);
140void
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500141count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data)
142{
143 if(png_ptr != NULL && row_info != NULL)
144 ++filters_used[*(data-1)];
145}
146#endif
147
Glenn Randers-Pehrson38d73af1998-03-07 21:30:44 -0600148#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600149/* example of using user transform callback (we don't transform anything,
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500150 but merely count the zero samples) */
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600151
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500152static png_uint_32 zero_samples;
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -0600153
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600154void
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500155count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data);
156void
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500157count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600158{
159 png_bytep dp = data;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600160 if(png_ptr == NULL)return;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600161
162 /* contents of row_info:
163 * png_uint_32 width width of row
164 * png_uint_32 rowbytes number of bytes in row
165 * png_byte color_type color type of pixels
166 * png_byte bit_depth bit depth of samples
167 * png_byte channels number of channels (1-4)
168 * png_byte pixel_depth bits per pixel (depth*channels)
169 */
170
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500171
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500172 /* counts the number of zero samples (or zero pixels if color_type is 3 */
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600173
174 if(row_info->color_type == 0 || row_info->color_type == 3)
175 {
176 int pos=0;
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500177 png_uint_32 n, nstop;
178 for (n=0, nstop=row_info->width; n<nstop; n++)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600179 {
180 if(row_info->bit_depth == 1)
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500181 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600182 if(((*dp << pos++ ) & 0x80) == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600183 if(pos == 8)
184 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500185 pos = 0;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600186 dp++;
187 }
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500188 }
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600189 if(row_info->bit_depth == 2)
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500190 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600191 if(((*dp << (pos+=2)) & 0xc0) == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600192 if(pos == 8)
193 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500194 pos = 0;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600195 dp++;
196 }
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500197 }
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600198 if(row_info->bit_depth == 4)
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500199 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600200 if(((*dp << (pos+=4)) & 0xf0) == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600201 if(pos == 8)
202 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500203 pos = 0;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600204 dp++;
205 }
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500206 }
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600207 if(row_info->bit_depth == 8)
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500208 if(*dp++ == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600209 if(row_info->bit_depth == 16)
210 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500211 if((*dp | *(dp+1)) == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600212 dp+=2;
213 }
214 }
215 }
216 else /* other color types */
217 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500218 png_uint_32 n, nstop;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600219 int channel;
220 int color_channels = row_info->channels;
221 if(row_info->color_type > 3)color_channels--;
222
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500223 for (n=0, nstop=row_info->width; n<nstop; n++)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600224 {
225 for (channel = 0; channel < color_channels; channel++)
226 {
227 if(row_info->bit_depth == 8)
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500228 if(*dp++ == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600229 if(row_info->bit_depth == 16)
230 {
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500231 if((*dp | *(dp+1)) == 0) zero_samples++;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600232 dp+=2;
233 }
234 }
235 if(row_info->color_type > 3)
236 {
237 dp++;
238 if(row_info->bit_depth == 16)dp++;
239 }
240 }
241 }
242}
Glenn Randers-Pehrson38d73af1998-03-07 21:30:44 -0600243#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600244
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -0600245static int wrote_question = 0;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600246
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600247#if defined(PNG_NO_STDIO)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600248/* START of code to validate stdio-free compilation */
249/* These copies of the default read/write functions come from pngrio.c and */
250/* pngwio.c. They allow "don't include stdio" testing of the library. */
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500251/* This is the function that does the actual reading of data. If you are
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600252 not reading from a standard C stream, you should create a replacement
253 read_data function and use it at run time with png_set_read_fn(), rather
254 than changing the library. */
Glenn Randers-Pehrsonbe9de0f2001-01-22 08:52:16 -0600255
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600256#ifndef USE_FAR_KEYWORD
257static void
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500258pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600259{
260 png_size_t check;
261
262 /* fread() returns 0 on error, so it is OK to store this in a png_size_t
263 * instead of an int, which is what fread() actually returns.
264 */
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -0500265 check = (png_size_t)fread(data, 1, length, (png_FILE_p)png_ptr->io_ptr);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600266 if (check != length)
267 {
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500268 png_error(png_ptr, "Read Error!");
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600269 }
270}
Guy Schalnate5a37791996-06-05 15:50:50 -0500271#else
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600272/* this is the model-independent version. Since the standard I/O library
273 can't handle far buffers in the medium and small models, we have to copy
274 the data.
275*/
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600276
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600277#define NEAR_BUF_SIZE 1024
278#define MIN(a,b) (a <= b ? a : b)
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600279
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600280static void
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500281pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600282{
283 int check;
284 png_byte *n_data;
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500285 png_FILE_p io_ptr;
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600286
287 /* Check if data really is near. If so, use usual code. */
288 n_data = (png_byte *)CVT_PTR_NOCHECK(data);
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500289 io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600290 if ((png_bytep)n_data == data)
291 {
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -0500292 check = (png_size_t)fread(n_data, 1, length, io_ptr);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600293 }
294 else
295 {
296 png_byte buf[NEAR_BUF_SIZE];
297 png_size_t read, remaining, err;
298 check = 0;
299 remaining = length;
300 do
301 {
302 read = MIN(NEAR_BUF_SIZE, remaining);
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -0500303 err = (png_size_t)fread(buf, 1, 1, io_ptr);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600304 png_memcpy(data, buf, read); /* copy far buffer to near buffer */
305 if(err != read)
306 break;
307 else
308 check += err;
309 data += read;
310 remaining -= read;
311 }
312 while (remaining != 0);
313 }
314 if (check != length)
315 {
316 png_error(png_ptr, "read Error");
317 }
318}
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600319#endif /* USE_FAR_KEYWORD */
Guy Schalnat0d580581995-07-20 02:43:20 -0500320
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600321#if defined(PNG_WRITE_FLUSH_SUPPORTED)
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600322static void
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500323pngtest_flush(png_structp png_ptr)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600324{
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500325 png_FILE_p io_ptr;
326 io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600327 if (io_ptr != NULL)
328 fflush(io_ptr);
329}
330#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500331
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500332/* This is the function that does the actual writing of data. If you are
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600333 not writing to a standard C stream, you should create a replacement
334 write_data function and use it at run time with png_set_write_fn(), rather
335 than changing the library. */
336#ifndef USE_FAR_KEYWORD
337static void
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500338pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600339{
340 png_uint_32 check;
341
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -0500342 check = (png_size_t)fwrite(data, 1, length, (png_FILE_p)png_ptr->io_ptr);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600343 if (check != length)
344 {
345 png_error(png_ptr, "Write Error");
346 }
347}
348#else
349/* this is the model-independent version. Since the standard I/O library
350 can't handle far buffers in the medium and small models, we have to copy
351 the data.
352*/
353
354#define NEAR_BUF_SIZE 1024
355#define MIN(a,b) (a <= b ? a : b)
356
357static void
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500358pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600359{
360 png_uint_32 check;
361 png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500362 png_FILE_p io_ptr;
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600363
364 /* Check if data really is near. If so, use usual code. */
365 near_data = (png_byte *)CVT_PTR_NOCHECK(data);
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500366 io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600367 if ((png_bytep)near_data == data)
368 {
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -0500369 check = (png_size_t)fwrite(near_data, 1, length, io_ptr);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600370 }
371 else
372 {
373 png_byte buf[NEAR_BUF_SIZE];
374 png_size_t written, remaining, err;
375 check = 0;
376 remaining = length;
377 do
378 {
379 written = MIN(NEAR_BUF_SIZE, remaining);
380 png_memcpy(buf, data, written); /* copy far buffer to near buffer */
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -0500381 err = (png_size_t)fwrite(buf, 1, written, io_ptr);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600382 if (err != written)
383 break;
384 else
385 check += err;
386 data += written;
387 remaining -= written;
388 }
389 while (remaining != 0);
390 }
391 if (check != length)
392 {
393 png_error(png_ptr, "Write Error");
394 }
395}
396
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600397#endif /* USE_FAR_KEYWORD */
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600398
399/* This function is called when there is a warning, but the library thinks
400 * it can continue anyway. Replacement functions don't have to do anything
401 * here if you don't want to. In the default configuration, png_ptr is
402 * not used, but it is passed in case it may be useful.
403 */
404static void
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500405pngtest_warning(png_structp png_ptr, png_const_charp message)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600406{
407 PNG_CONST char *name = "UNKNOWN (ERROR!)";
408 if (png_ptr != NULL && png_ptr->error_ptr != NULL)
409 name = png_ptr->error_ptr;
410 fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
411}
412
413/* This is the default error handling function. Note that replacements for
414 * this function MUST NOT RETURN, or the program will likely crash. This
415 * function is used by default, or if the program supplies NULL for the
416 * error function pointer in png_set_error_fn().
417 */
418static void
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500419pngtest_error(png_structp png_ptr, png_const_charp message)
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600420{
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500421 pngtest_warning(png_ptr, message);
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500422 /* We can return because png_error calls the default handler, which is
423 * actually OK in this case. */
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600424}
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600425#endif /* PNG_NO_STDIO */
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600426/* END of code to validate stdio-free compilation */
427
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600428/* START of code to validate memory allocation and deallocation */
Glenn Randers-Pehrson37f116a2004-08-15 07:15:39 -0500429#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600430
431/* Allocate memory. For reasonable files, size should never exceed
432 64K. However, zlib may allocate more then 64K if you don't tell
433 it not to. See zconf.h and png.h for more information. zlib does
434 need to allocate exactly 64K, so whatever you call here must
435 have the ability to do that.
436
437 This piece of code can be compiled to validate max 64K allocations
438 by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. */
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600439typedef struct memory_information
440{
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500441 png_uint_32 size;
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500442 png_voidp pointer;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600443 struct memory_information FAR *next;
444} memory_information;
445typedef memory_information FAR *memory_infop;
446
447static memory_infop pinformation = NULL;
448static int current_allocation = 0;
449static int maximum_allocation = 0;
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500450static int total_allocation = 0;
451static int num_allocations = 0;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600452
Glenn Randers-Pehrsonb1828932001-06-23 08:03:17 -0500453png_voidp png_debug_malloc PNGARG((png_structp png_ptr, png_uint_32 size));
454void png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr));
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600455
456png_voidp
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600457png_debug_malloc(png_structp png_ptr, png_uint_32 size)
458{
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500459
460 /* png_malloc has already tested for NULL; png_create_struct calls
461 png_debug_malloc directly, with png_ptr == NULL which is OK */
462
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600463 if (size == 0)
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500464 return (NULL);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600465
466 /* This calls the library allocator twice, once to get the requested
467 buffer and once to get a new free list entry. */
468 {
Glenn Randers-Pehrsondff799e2004-08-07 21:42:49 -0500469 /* Disable malloc_fn and free_fn */
Glenn Randers-Pehrson36d7bc72004-08-10 06:55:02 -0500470 memory_infop pinfo;
Glenn Randers-Pehrsondff799e2004-08-07 21:42:49 -0500471 png_set_mem_fn(png_ptr, NULL, NULL, NULL);
Glenn Randers-Pehrson36d7bc72004-08-10 06:55:02 -0500472 pinfo = (memory_infop)png_malloc(png_ptr,
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500473 (png_uint_32)png_sizeof (*pinfo));
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600474 pinfo->size = size;
475 current_allocation += size;
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500476 total_allocation += size;
477 num_allocations ++;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600478 if (current_allocation > maximum_allocation)
479 maximum_allocation = current_allocation;
Glenn Randers-Pehrsondff799e2004-08-07 21:42:49 -0500480 pinfo->pointer = (png_voidp)png_malloc(png_ptr, size);
481 /* Restore malloc_fn and free_fn */
482 png_set_mem_fn(png_ptr, png_voidp_NULL, (png_malloc_ptr)png_debug_malloc,
483 (png_free_ptr)png_debug_free);
Glenn Randers-Pehrson272489d2004-08-04 06:34:52 -0500484 if (size != 0 && pinfo->pointer == NULL)
485 {
486 current_allocation -= size;
487 total_allocation -= size;
Glenn Randers-Pehrsondff799e2004-08-07 21:42:49 -0500488 png_error(png_ptr,
489 "out of memory in pngtest->png_debug_malloc.");
Glenn Randers-Pehrson272489d2004-08-04 06:34:52 -0500490 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600491 pinfo->next = pinformation;
492 pinformation = pinfo;
493 /* Make sure the caller isn't assuming zeroed memory. */
494 png_memset(pinfo->pointer, 0xdd, pinfo->size);
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -0500495 if(verbose)
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -0500496 printf("png_malloc %lu bytes at %x\n",(unsigned long) size,
497 pinfo->pointer);
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600498 return (png_voidp)(pinfo->pointer);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600499 }
500}
501
502/* Free a pointer. It is removed from the list at the same time. */
503void
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500504png_debug_free(png_structp png_ptr, png_voidp ptr)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600505{
506 if (png_ptr == NULL)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500507 fprintf(STDERR, "NULL pointer to png_debug_free.\n");
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600508 if (ptr == 0)
509 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600510#if 0 /* This happens all the time. */
511 fprintf(STDERR, "WARNING: freeing NULL pointer\n");
512#endif
513 return;
514 }
515
516 /* Unlink the element from the list. */
517 {
518 memory_infop FAR *ppinfo = &pinformation;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600519 for (;;)
520 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600521 memory_infop pinfo = *ppinfo;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600522 if (pinfo->pointer == ptr)
523 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600524 *ppinfo = pinfo->next;
525 current_allocation -= pinfo->size;
526 if (current_allocation < 0)
527 fprintf(STDERR, "Duplicate free of memory\n");
528 /* We must free the list element too, but first kill
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500529 the memory that is to be freed. */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500530 png_memset(ptr, 0x55, pinfo->size);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500531 png_free_default(png_ptr, pinfo);
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500532 pinfo=NULL;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600533 break;
534 }
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600535 if (pinfo->next == NULL)
536 {
Glenn Randers-Pehrsonb1828932001-06-23 08:03:17 -0500537 fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600538 break;
539 }
540 ppinfo = &pinfo->next;
541 }
542 }
543
544 /* Finally free the data. */
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -0500545 if(verbose)
546 printf("Freeing %x\n",ptr);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500547 png_free_default(png_ptr, ptr);
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500548 ptr=NULL;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600549}
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500550#endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600551/* END of code to test memory allocation/deallocation */
552
Glenn Randers-Pehrsond1209962006-06-21 19:40:52 -0500553
554
555
556/* Demonstration of user chunk support of the sTER and vpAg chunks */
557#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
558
559/* (sTER is a public chunk not yet understood by libpng. vpAg is a private
560chunk used in ImageMagick to store "virtual page" size). */
561
562static png_uint_32 user_chunk_data[4];
563
Glenn Randers-Pehrsone826d7e2006-07-03 00:21:58 -0500564 /* 0: sTER mode + 1
565 * 1: vpAg width
566 * 2: vpAg height
567 * 3: vpAg units
Glenn Randers-Pehrsond1209962006-06-21 19:40:52 -0500568 */
569
570static int read_user_chunk_callback(png_struct *png_ptr,
571 png_unknown_chunkp chunk)
572{
573 png_uint_32
574 *user_chunk_data;
575
576 /* Return one of the following: */
577 /* return (-n); chunk had an error */
578 /* return (0); did not recognize */
579 /* return (n); success */
580
581 /* The unknown chunk structure contains the chunk data:
582 * png_byte name[5];
583 * png_byte *data;
584 * png_size_t size;
585 *
586 * Note that libpng has already taken care of the CRC handling.
587 */
588
589 if (chunk->name[0] == 115 && chunk->name[1] == 84 && /* s T */
Glenn Randers-Pehrsone826d7e2006-07-03 00:21:58 -0500590 chunk->name[2] == 69 && chunk->name[3] == 82) /* E R */
Glenn Randers-Pehrsond1209962006-06-21 19:40:52 -0500591 {
592 /* Found sTER chunk */
593 if (chunk->size != 1)
594 return (-1); /* Error return */
595 if (chunk->data[0] != 0 && chunk->data[0] != 1)
596 return (-1); /* Invalid mode */
597 user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr);
598 user_chunk_data[0]=chunk->data[0]+1;
599 return (1);
600 }
601 if (chunk->name[0] != 118 || chunk->name[1] != 112 || /* v p */
602 chunk->name[2] != 65 || chunk->name[3] != 103) /* A g */
603 return (0); /* Did not recognize */
604
605 /* Found ImageMagick vpAg chunk */
606
607 if (chunk->size != 9)
608 return (-1); /* Error return */
609
610 user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr);
611
Glenn Randers-Pehrsone826d7e2006-07-03 00:21:58 -0500612 user_chunk_data[1]=png_get_uint_31(png_ptr,chunk->data);
613 user_chunk_data[2]=png_get_uint_31(png_ptr,chunk->data + 4);
Glenn Randers-Pehrsond1209962006-06-21 19:40:52 -0500614 user_chunk_data[3]=(unsigned long) chunk->data[8];
615
616 return (1);
617
618}
619#endif
620/* END of code to demonstrate user chunk support */
621
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600622/* Test one file */
Glenn Randers-Pehrson7cd899c1998-03-07 16:17:42 -0600623int
624test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
Guy Schalnat0d580581995-07-20 02:43:20 -0500625{
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -0500626 static png_FILE_p fpin;
627 static png_FILE_p fpout; /* "static" prevents setjmp corruption */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500628 png_structp read_ptr;
629 png_infop read_info_ptr, end_info_ptr;
630#ifdef PNG_WRITE_SUPPORTED
631 png_structp write_ptr;
632 png_infop write_info_ptr;
633 png_infop write_end_info_ptr;
634#else
635 png_structp write_ptr = NULL;
636 png_infop write_info_ptr = NULL;
637 png_infop write_end_info_ptr = NULL;
638#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600639 png_bytep row_buf;
Guy Schalnat0d580581995-07-20 02:43:20 -0500640 png_uint_32 y;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500641 png_uint_32 width, height;
642 int num_pass, pass;
643 int bit_depth, color_type;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600644#ifdef PNG_SETJMP_SUPPORTED
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600645#ifdef USE_FAR_KEYWORD
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -0600646 jmp_buf jmpbuf;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600647#endif
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600648#endif
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600649
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600650 char inbuf[256], outbuf[256];
651
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500652 row_buf = NULL;
Guy Schalnat0d580581995-07-20 02:43:20 -0500653
Andreas Dilger47a0c421997-05-16 02:46:07 -0500654 if ((fpin = fopen(inname, "rb")) == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -0600655 {
656 fprintf(STDERR, "Could not find input file %s\n", inname);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600657 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600658 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500659
Andreas Dilger47a0c421997-05-16 02:46:07 -0500660 if ((fpout = fopen(outname, "wb")) == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -0600661 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500662 fprintf(STDERR, "Could not open output file %s\n", outname);
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -0500663 fclose(fpin);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600664 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600665 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500666
Andreas Dilger47a0c421997-05-16 02:46:07 -0500667 png_debug(0, "Allocating read and write structures\n");
Glenn Randers-Pehrson37f116a2004-08-15 07:15:39 -0500668#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500669 read_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
670 png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500671 (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
672#else
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500673 read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
674 png_error_ptr_NULL, png_error_ptr_NULL);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500675#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600676#if defined(PNG_NO_STDIO)
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500677 png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error,
678 pngtest_warning);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600679#endif
Glenn Randers-Pehrsond1209962006-06-21 19:40:52 -0500680
681#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
682 user_chunk_data[0]=0;
683 user_chunk_data[1]=0;
684 user_chunk_data[2]=0;
685 user_chunk_data[3]=0;
686 png_set_read_user_chunk_fn(read_ptr, user_chunk_data,
687 read_user_chunk_callback);
688#endif
689
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500690#ifdef PNG_WRITE_SUPPORTED
Glenn Randers-Pehrson37f116a2004-08-15 07:15:39 -0500691#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500692 write_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
693 png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500694 (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
695#else
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500696 write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
697 png_error_ptr_NULL, png_error_ptr_NULL);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500698#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600699#if defined(PNG_NO_STDIO)
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500700 png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error,
701 pngtest_warning);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600702#endif
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500703#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500704 png_debug(0, "Allocating read_info, write_info and end_info structures\n");
705 read_info_ptr = png_create_info_struct(read_ptr);
Glenn Randers-Pehrson1fd5fb32001-05-06 05:34:26 -0500706 end_info_ptr = png_create_info_struct(read_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500707#ifdef PNG_WRITE_SUPPORTED
708 write_info_ptr = png_create_info_struct(write_ptr);
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -0500709 write_end_info_ptr = png_create_info_struct(write_ptr);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500710#endif
Guy Schalnate5a37791996-06-05 15:50:50 -0500711
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600712#ifdef PNG_SETJMP_SUPPORTED
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -0600713 png_debug(0, "Setting jmpbuf for read struct\n");
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600714#ifdef USE_FAR_KEYWORD
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -0600715 if (setjmp(jmpbuf))
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600716#else
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -0600717 if (setjmp(png_jmpbuf(read_ptr)))
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600718#endif
Guy Schalnat0f716451995-11-28 11:22:13 -0600719 {
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600720 fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
Glenn Randers-Pehrsond020e9d2002-06-28 09:34:00 -0500721 if (row_buf)
722 png_free(read_ptr, row_buf);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500723 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500724#ifdef PNG_WRITE_SUPPORTED
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -0500725 png_destroy_info_struct(write_ptr, &write_end_info_ptr);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500726 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500727#endif
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -0500728 fclose(fpin);
729 fclose(fpout);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600730 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600731 }
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600732#ifdef USE_FAR_KEYWORD
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500733 png_memcpy(png_jmpbuf(read_ptr),jmpbuf,png_sizeof(jmp_buf));
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600734#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500735
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500736#ifdef PNG_WRITE_SUPPORTED
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -0600737 png_debug(0, "Setting jmpbuf for write struct\n");
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600738#ifdef USE_FAR_KEYWORD
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -0600739 if (setjmp(jmpbuf))
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600740#else
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -0600741 if (setjmp(png_jmpbuf(write_ptr)))
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600742#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600743 {
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600744 fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500745 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -0500746 png_destroy_info_struct(write_ptr, &write_end_info_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500747#ifdef PNG_WRITE_SUPPORTED
Andreas Dilger47a0c421997-05-16 02:46:07 -0500748 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500749#endif
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -0500750 fclose(fpin);
751 fclose(fpout);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600752 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -0600753 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600754#ifdef USE_FAR_KEYWORD
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500755 png_memcpy(png_jmpbuf(write_ptr),jmpbuf,png_sizeof(jmp_buf));
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600756#endif
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600757#endif
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500758#endif
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600759
Andreas Dilger47a0c421997-05-16 02:46:07 -0500760 png_debug(0, "Initializing input and output streams\n");
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600761#if !defined(PNG_NO_STDIO)
Guy Schalnate5a37791996-06-05 15:50:50 -0500762 png_init_io(read_ptr, fpin);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500763# ifdef PNG_WRITE_SUPPORTED
Guy Schalnate5a37791996-06-05 15:50:50 -0500764 png_init_io(write_ptr, fpout);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500765# endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600766#else
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500767 png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data);
Glenn Randers-Pehrson8b6a8892001-05-18 04:54:50 -0500768# ifdef PNG_WRITE_SUPPORTED
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500769 png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data,
Glenn Randers-Pehrson8b6a8892001-05-18 04:54:50 -0500770# if defined(PNG_WRITE_FLUSH_SUPPORTED)
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500771 pngtest_flush);
Glenn Randers-Pehrson8b6a8892001-05-18 04:54:50 -0500772# else
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600773 NULL);
Glenn Randers-Pehrson8b6a8892001-05-18 04:54:50 -0500774# endif
775# endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600776#endif
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600777 if(status_dots_requested == 1)
778 {
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500779#ifdef PNG_WRITE_SUPPORTED
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600780 png_set_write_status_fn(write_ptr, write_row_callback);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500781#endif
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600782 png_set_read_status_fn(read_ptr, read_row_callback);
783 }
784 else
785 {
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500786#ifdef PNG_WRITE_SUPPORTED
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500787 png_set_write_status_fn(write_ptr, png_write_status_ptr_NULL);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500788#endif
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500789 png_set_read_status_fn(read_ptr, png_read_status_ptr_NULL);
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -0600790 }
791
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500792#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
793 {
794 int i;
795 for(i=0; i<256; i++)
796 filters_used[i]=0;
797 png_set_read_user_transform_fn(read_ptr, count_filters);
798 }
799#endif
800#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
801 zero_samples=0;
802 png_set_write_user_transform_fn(write_ptr, count_zero_samples);
803#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500804
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600805#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
Glenn Randers-Pehrsondff799e2004-08-07 21:42:49 -0500806# ifndef PNG_HANDLE_CHUNK_ALWAYS
807# define PNG_HANDLE_CHUNK_ALWAYS 3
808# endif
809 png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS,
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500810 png_bytep_NULL, 0);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600811#endif
812#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
Glenn Randers-Pehrsondff799e2004-08-07 21:42:49 -0500813# ifndef PNG_HANDLE_CHUNK_IF_SAFE
814# define PNG_HANDLE_CHUNK_IF_SAFE 2
815# endif
816 png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE,
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500817 png_bytep_NULL, 0);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600818#endif
819
Andreas Dilger47a0c421997-05-16 02:46:07 -0500820 png_debug(0, "Reading info struct\n");
821 png_read_info(read_ptr, read_info_ptr);
Guy Schalnat0d580581995-07-20 02:43:20 -0500822
Andreas Dilger47a0c421997-05-16 02:46:07 -0500823 png_debug(0, "Transferring info struct\n");
824 {
825 int interlace_type, compression_type, filter_type;
Guy Schalnat0d580581995-07-20 02:43:20 -0500826
Andreas Dilger47a0c421997-05-16 02:46:07 -0500827 if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
828 &color_type, &interlace_type, &compression_type, &filter_type))
829 {
830 png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600831#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500832 color_type, interlace_type, compression_type, filter_type);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600833#else
834 color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
835#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -0500836 }
837 }
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500838#if defined(PNG_FIXED_POINT_SUPPORTED)
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600839#if defined(PNG_cHRM_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500840 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600841 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 -0600842 blue_y;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600843 if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
Andreas Dilger47a0c421997-05-16 02:46:07 -0500844 &red_y, &green_x, &green_y, &blue_x, &blue_y))
845 {
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600846 png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x,
Andreas Dilger47a0c421997-05-16 02:46:07 -0500847 red_y, green_x, green_y, blue_x, blue_y);
848 }
849 }
850#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600851#if defined(PNG_gAMA_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500852 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600853 png_fixed_point gamma;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500854
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600855 if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma))
Andreas Dilger47a0c421997-05-16 02:46:07 -0500856 {
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600857 png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500858 }
859 }
860#endif
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -0500861#else /* Use floating point versions */
862#if defined(PNG_FLOATING_POINT_SUPPORTED)
863#if defined(PNG_cHRM_SUPPORTED)
864 {
865 double white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
866 blue_y;
867 if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
868 &red_y, &green_x, &green_y, &blue_x, &blue_y))
869 {
870 png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
871 red_y, green_x, green_y, blue_x, blue_y);
872 }
873 }
874#endif
875#if defined(PNG_gAMA_SUPPORTED)
876 {
877 double gamma;
878
879 if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
880 {
881 png_set_gAMA(write_ptr, write_info_ptr, gamma);
882 }
883 }
884#endif
885#endif /* floating point */
886#endif /* fixed point */
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600887#if defined(PNG_iCCP_SUPPORTED)
888 {
889 png_charp name;
890 png_charp profile;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600891 png_uint_32 proflen;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600892 int compression_type;
893
894 if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,
895 &profile, &proflen))
896 {
897 png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,
898 profile, proflen);
899 }
900 }
901#endif
902#if defined(PNG_sRGB_SUPPORTED)
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600903 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -0600904 int intent;
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600905
906 if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
907 {
908 png_set_sRGB(write_ptr, write_info_ptr, intent);
909 }
910 }
911#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600912 {
913 png_colorp palette;
914 int num_palette;
915
916 if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
917 {
918 png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
919 }
920 }
921#if defined(PNG_bKGD_SUPPORTED)
922 {
923 png_color_16p background;
924
925 if (png_get_bKGD(read_ptr, read_info_ptr, &background))
926 {
927 png_set_bKGD(write_ptr, write_info_ptr, background);
928 }
929 }
930#endif
931#if defined(PNG_hIST_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500932 {
933 png_uint_16p hist;
934
935 if (png_get_hIST(read_ptr, read_info_ptr, &hist))
936 {
937 png_set_hIST(write_ptr, write_info_ptr, hist);
938 }
939 }
940#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600941#if defined(PNG_oFFs_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500942 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600943 png_int_32 offset_x, offset_y;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500944 int unit_type;
945
946 if (png_get_oFFs(read_ptr, read_info_ptr,&offset_x,&offset_y,&unit_type))
947 {
948 png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
949 }
950 }
951#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600952#if defined(PNG_pCAL_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500953 {
954 png_charp purpose, units;
955 png_charpp params;
956 png_int_32 X0, X1;
957 int type, nparams;
958
959 if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
960 &nparams, &units, &params))
961 {
962 png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
963 nparams, units, params);
964 }
965 }
966#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600967#if defined(PNG_pHYs_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500968 {
969 png_uint_32 res_x, res_y;
970 int unit_type;
971
972 if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
973 {
974 png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
975 }
976 }
977#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600978#if defined(PNG_sBIT_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500979 {
980 png_color_8p sig_bit;
981
982 if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
983 {
984 png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
985 }
986 }
987#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600988#if defined(PNG_sCAL_SUPPORTED)
989#ifdef PNG_FLOATING_POINT_SUPPORTED
990 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600991 int unit;
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500992 double scal_width, scal_height;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600993
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500994 if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,
995 &scal_height))
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600996 {
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -0500997 png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600998 }
999 }
1000#else
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001001#ifdef PNG_FIXED_POINT_SUPPORTED
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001002 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001003 int unit;
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -05001004 png_charp scal_width, scal_height;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001005
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -05001006 if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,
1007 &scal_height))
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001008 {
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -05001009 png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, scal_height);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001010 }
1011 }
1012#endif
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001013#endif
1014#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001015#if defined(PNG_TEXT_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -05001016 {
1017 png_textp text_ptr;
1018 int num_text;
1019
1020 if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
1021 {
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001022 png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text);
Andreas Dilger47a0c421997-05-16 02:46:07 -05001023 png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
1024 }
1025 }
1026#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001027#if defined(PNG_tIME_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -05001028 {
1029 png_timep mod_time;
1030
1031 if (png_get_tIME(read_ptr, read_info_ptr, &mod_time))
1032 {
1033 png_set_tIME(write_ptr, write_info_ptr, mod_time);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001034#if defined(PNG_TIME_RFC1123_SUPPORTED)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001035 /* we have to use png_strcpy instead of "=" because the string
1036 pointed to by png_convert_to_rfc1123() gets free'ed before
1037 we use it */
1038 png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time));
1039 tIME_chunk_present++;
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001040#endif /* PNG_TIME_RFC1123_SUPPORTED */
Glenn Randers-Pehrsonc9442291999-01-06 21:50:16 -06001041 }
Andreas Dilger47a0c421997-05-16 02:46:07 -05001042 }
1043#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001044#if defined(PNG_tRNS_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -05001045 {
1046 png_bytep trans;
1047 int num_trans;
1048 png_color_16p trans_values;
1049
1050 if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans,
1051 &trans_values))
1052 {
1053 png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans,
1054 trans_values);
1055 }
1056 }
1057#endif
Glenn Randers-Pehrsond1209962006-06-21 19:40:52 -05001058
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001059#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1060 {
1061 png_unknown_chunkp unknowns;
1062 int num_unknowns = (int)png_get_unknown_chunks(read_ptr, read_info_ptr,
1063 &unknowns);
1064 if (num_unknowns)
1065 {
1066 png_size_t i;
1067 png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns,
1068 num_unknowns);
1069 /* copy the locations from the read_info_ptr. The automatically
1070 generated locations in write_info_ptr are wrong because we
1071 haven't written anything yet */
1072 for (i = 0; i < (png_size_t)num_unknowns; i++)
Glenn Randers-Pehrson228bd392000-04-23 23:14:02 -05001073 png_set_unknown_chunk_location(write_ptr, write_info_ptr, i,
1074 unknowns[i].location);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001075 }
1076 }
1077#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -05001078
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001079#ifdef PNG_WRITE_SUPPORTED
Andreas Dilger47a0c421997-05-16 02:46:07 -05001080 png_debug(0, "\nWriting info struct\n");
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -06001081
1082/* If we wanted, we could write info in two steps:
1083 png_write_info_before_PLTE(write_ptr, write_info_ptr);
1084 */
Andreas Dilger47a0c421997-05-16 02:46:07 -05001085 png_write_info(write_ptr, write_info_ptr);
Glenn Randers-Pehrsond1209962006-06-21 19:40:52 -05001086
1087#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
1088 if (user_chunk_data[0] != 0)
1089 {
1090 png_byte png_sTER[5] = {115, 84, 69, 82, '\0'};
1091
1092 unsigned char
1093 ster_chunk_data[1];
1094
1095 if(verbose)
1096 fprintf(STDERR, "stereo mode = %lu\n",
1097 (unsigned long)(user_chunk_data[0]-1));
1098 ster_chunk_data[0]=(unsigned char)(user_chunk_data[0]-1);
1099 png_write_chunk(write_ptr,png_sTER,ster_chunk_data,1);
1100 }
1101 if (user_chunk_data[1] != 0 || user_chunk_data[2] != 0)
1102 {
1103 png_byte png_vpAg[5] = {118, 112, 65, 103, '\0'};
1104
1105 unsigned char
1106 vpag_chunk_data[9];
1107
1108 if(verbose)
1109 fprintf(STDERR, "vpAg = %lu x %lu, units=%lu\n",
1110 (unsigned long)user_chunk_data[1],
1111 (unsigned long)user_chunk_data[2],
1112 (unsigned long)user_chunk_data[3]);
1113 vpag_chunk_data[0]=(user_chunk_data[1]>>24) & 0xff;
1114 vpag_chunk_data[1]=(user_chunk_data[1]>>16) & 0xff;
1115 vpag_chunk_data[2]=(user_chunk_data[1]>>8 ) & 0xff;
1116 vpag_chunk_data[3]=(user_chunk_data[1] ) & 0xff;
1117 vpag_chunk_data[4]=(user_chunk_data[2]>>24) & 0xff;
1118 vpag_chunk_data[5]=(user_chunk_data[2]>>16) & 0xff;
1119 vpag_chunk_data[6]=(user_chunk_data[2]>>8 ) & 0xff;
1120 vpag_chunk_data[7]=(user_chunk_data[2] ) & 0xff;
1121 vpag_chunk_data[8]=(user_chunk_data[3] ) & 0xff;
1122 png_write_chunk(write_ptr, png_vpAg,vpag_chunk_data,9);
1123 }
1124
1125#endif
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001126#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -05001127
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001128#ifdef SINGLE_ROWBUF_ALLOC
1129 png_debug(0, "\nAllocating row buffer...");
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001130 row_buf = (png_bytep)png_malloc(read_ptr,
Andreas Dilger47a0c421997-05-16 02:46:07 -05001131 png_get_rowbytes(read_ptr, read_info_ptr));
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001132 png_debug1(0, "0x%08lx\n\n", (unsigned long)row_buf);
1133#endif /* SINGLE_ROWBUF_ALLOC */
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001134 png_debug(0, "Writing row data\n");
Guy Schalnat0d580581995-07-20 02:43:20 -05001135
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001136#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
1137 defined(PNG_WRITE_INTERLACING_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -05001138 num_pass = png_set_interlace_handling(read_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001139# ifdef PNG_WRITE_SUPPORTED
Andreas Dilger47a0c421997-05-16 02:46:07 -05001140 png_set_interlace_handling(write_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001141# endif
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001142#else
1143 num_pass=1;
1144#endif
Guy Schalnat0d580581995-07-20 02:43:20 -05001145
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001146#ifdef PNGTEST_TIMING
1147 t_stop = (float)clock();
1148 t_misc += (t_stop - t_start);
1149 t_start = t_stop;
1150#endif
Guy Schalnat0f716451995-11-28 11:22:13 -06001151 for (pass = 0; pass < num_pass; pass++)
1152 {
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001153 png_debug1(0, "Writing row data for pass %d\n",pass);
Andreas Dilger47a0c421997-05-16 02:46:07 -05001154 for (y = 0; y < height; y++)
Guy Schalnat0f716451995-11-28 11:22:13 -06001155 {
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001156#ifndef SINGLE_ROWBUF_ALLOC
1157 png_debug2(0, "\nAllocating row buffer (pass %d, y = %ld)...", pass,y);
1158 row_buf = (png_bytep)png_malloc(read_ptr,
1159 png_get_rowbytes(read_ptr, read_info_ptr));
1160 png_debug2(0, "0x%08lx (%ld bytes)\n", (unsigned long)row_buf,
1161 png_get_rowbytes(read_ptr, read_info_ptr));
1162#endif /* !SINGLE_ROWBUF_ALLOC */
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -05001163 png_read_rows(read_ptr, (png_bytepp)&row_buf, png_bytepp_NULL, 1);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001164
1165#ifdef PNG_WRITE_SUPPORTED
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001166#ifdef PNGTEST_TIMING
1167 t_stop = (float)clock();
1168 t_decode += (t_stop - t_start);
1169 t_start = t_stop;
1170#endif
Guy Schalnate5a37791996-06-05 15:50:50 -05001171 png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001172#ifdef PNGTEST_TIMING
1173 t_stop = (float)clock();
1174 t_encode += (t_stop - t_start);
1175 t_start = t_stop;
1176#endif
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001177#endif /* PNG_WRITE_SUPPORTED */
1178
1179#ifndef SINGLE_ROWBUF_ALLOC
1180 png_debug2(0, "Freeing row buffer (pass %d, y = %ld)\n\n", pass, y);
1181 png_free(read_ptr, row_buf);
1182#endif /* !SINGLE_ROWBUF_ALLOC */
Guy Schalnat0f716451995-11-28 11:22:13 -06001183 }
1184 }
Guy Schalnat0d580581995-07-20 02:43:20 -05001185
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001186#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
Glenn Randers-Pehrsona77ef622000-02-18 13:48:52 -06001187 png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001188#endif
1189#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
Glenn Randers-Pehrsona77ef622000-02-18 13:48:52 -06001190 png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001191#endif
1192
Andreas Dilger47a0c421997-05-16 02:46:07 -05001193 png_debug(0, "Reading and writing end_info data\n");
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001194
Andreas Dilger47a0c421997-05-16 02:46:07 -05001195 png_read_end(read_ptr, end_info_ptr);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001196#if defined(PNG_TEXT_SUPPORTED)
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -05001197 {
1198 png_textp text_ptr;
1199 int num_text;
1200
1201 if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0)
1202 {
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001203 png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text);
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -05001204 png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text);
1205 }
1206 }
1207#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001208#if defined(PNG_tIME_SUPPORTED)
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -05001209 {
1210 png_timep mod_time;
1211
1212 if (png_get_tIME(read_ptr, end_info_ptr, &mod_time))
1213 {
1214 png_set_tIME(write_ptr, write_end_info_ptr, mod_time);
1215#if defined(PNG_TIME_RFC1123_SUPPORTED)
1216 /* we have to use png_strcpy instead of "=" because the string
1217 pointed to by png_convert_to_rfc1123() gets free'ed before
1218 we use it */
1219 png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time));
1220 tIME_chunk_present++;
1221#endif /* PNG_TIME_RFC1123_SUPPORTED */
1222 }
1223 }
1224#endif
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001225#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1226 {
1227 png_unknown_chunkp unknowns;
1228 int num_unknowns;
1229 num_unknowns = (int)png_get_unknown_chunks(read_ptr, end_info_ptr,
1230 &unknowns);
1231 if (num_unknowns)
1232 {
1233 png_size_t i;
1234 png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,
1235 num_unknowns);
1236 /* copy the locations from the read_info_ptr. The automatically
1237 generated locations in write_end_info_ptr are wrong because we
1238 haven't written the end_info yet */
1239 for (i = 0; i < (png_size_t)num_unknowns; i++)
Glenn Randers-Pehrson228bd392000-04-23 23:14:02 -05001240 png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i,
1241 unknowns[i].location);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001242 }
1243 }
1244#endif
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001245#ifdef PNG_WRITE_SUPPORTED
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -05001246 png_write_end(write_ptr, write_end_info_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001247#endif
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001248
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001249#ifdef PNG_EASY_ACCESS_SUPPORTED
1250 if(verbose)
1251 {
1252 png_uint_32 iwidth, iheight;
1253 iwidth = png_get_image_width(write_ptr, write_info_ptr);
1254 iheight = png_get_image_height(write_ptr, write_info_ptr);
1255 fprintf(STDERR, "Image width = %lu, height = %lu\n",
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -05001256 (unsigned long) iwidth, (unsigned long) iheight);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001257 }
1258#endif
Guy Schalnat0d580581995-07-20 02:43:20 -05001259
Andreas Dilger47a0c421997-05-16 02:46:07 -05001260 png_debug(0, "Destroying data structs\n");
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001261#ifdef SINGLE_ROWBUF_ALLOC
1262 png_debug(1, "destroying row_buf for read_ptr\n");
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001263 png_free(read_ptr, row_buf);
Glenn Randers-Pehrson4766a242000-07-17 06:17:09 -05001264 row_buf=NULL;
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001265#endif /* SINGLE_ROWBUF_ALLOC */
1266 png_debug(1, "destroying read_ptr, read_info_ptr, end_info_ptr\n");
Andreas Dilger47a0c421997-05-16 02:46:07 -05001267 png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001268#ifdef PNG_WRITE_SUPPORTED
1269 png_debug(1, "destroying write_end_info_ptr\n");
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -05001270 png_destroy_info_struct(write_ptr, &write_end_info_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001271 png_debug(1, "destroying write_ptr, write_info_ptr\n");
Andreas Dilger47a0c421997-05-16 02:46:07 -05001272 png_destroy_write_struct(&write_ptr, &write_info_ptr);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001273#endif
1274 png_debug(0, "Destruction complete.\n");
Guy Schalnat0d580581995-07-20 02:43:20 -05001275
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -05001276 fclose(fpin);
1277 fclose(fpout);
Guy Schalnat0d580581995-07-20 02:43:20 -05001278
Andreas Dilger47a0c421997-05-16 02:46:07 -05001279 png_debug(0, "Opening files for comparison\n");
1280 if ((fpin = fopen(inname, "rb")) == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -06001281 {
Guy Schalnate5a37791996-06-05 15:50:50 -05001282 fprintf(STDERR, "Could not find file %s\n", inname);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -06001283 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -06001284 }
Guy Schalnat0d580581995-07-20 02:43:20 -05001285
Andreas Dilger47a0c421997-05-16 02:46:07 -05001286 if ((fpout = fopen(outname, "rb")) == NULL)
Guy Schalnat0f716451995-11-28 11:22:13 -06001287 {
Guy Schalnate5a37791996-06-05 15:50:50 -05001288 fprintf(STDERR, "Could not find file %s\n", outname);
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -05001289 fclose(fpin);
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -06001290 return (1);
Guy Schalnat0f716451995-11-28 11:22:13 -06001291 }
Andreas Dilger47a0c421997-05-16 02:46:07 -05001292
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -06001293 for(;;)
Guy Schalnat0f716451995-11-28 11:22:13 -06001294 {
Andreas Dilger47a0c421997-05-16 02:46:07 -05001295 png_size_t num_in, num_out;
Guy Schalnat0d580581995-07-20 02:43:20 -05001296
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -05001297 num_in = (png_size_t)fread(inbuf, 1, 1, fpin);
1298 num_out = (png_size_t)fread(outbuf, 1, 1, fpout);
Guy Schalnat0d580581995-07-20 02:43:20 -05001299
Guy Schalnat0f716451995-11-28 11:22:13 -06001300 if (num_in != num_out)
1301 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001302 fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
Guy Schalnate5a37791996-06-05 15:50:50 -05001303 inname, outname);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001304 if(wrote_question == 0)
1305 {
1306 fprintf(STDERR,
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001307 " Was %s written with the same maximum IDAT chunk size (%d bytes),",
1308 inname,PNG_ZBUF_SIZE);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001309 fprintf(STDERR,
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001310 "\n filtering heuristic (libpng default), compression");
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001311 fprintf(STDERR,
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001312 " level (zlib default),\n and zlib version (%s)?\n\n",
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001313 ZLIB_VERSION);
1314 wrote_question=1;
1315 }
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -05001316 fclose(fpin);
1317 fclose(fpout);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001318 return (0);
Guy Schalnat0f716451995-11-28 11:22:13 -06001319 }
Guy Schalnat0d580581995-07-20 02:43:20 -05001320
Guy Schalnat0f716451995-11-28 11:22:13 -06001321 if (!num_in)
1322 break;
Guy Schalnat0d580581995-07-20 02:43:20 -05001323
Andreas Dilger47a0c421997-05-16 02:46:07 -05001324 if (png_memcmp(inbuf, outbuf, num_in))
Guy Schalnat0f716451995-11-28 11:22:13 -06001325 {
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001326 fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001327 if(wrote_question == 0)
1328 {
1329 fprintf(STDERR,
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001330 " Was %s written with the same maximum IDAT chunk size (%d bytes),",
1331 inname,PNG_ZBUF_SIZE);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001332 fprintf(STDERR,
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001333 "\n filtering heuristic (libpng default), compression");
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001334 fprintf(STDERR,
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001335 " level (zlib default),\n and zlib version (%s)?\n\n",
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001336 ZLIB_VERSION);
1337 wrote_question=1;
1338 }
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -05001339 fclose(fpin);
1340 fclose(fpout);
Glenn Randers-Pehrsoncbe52d81998-02-28 07:00:24 -06001341 return (0);
Guy Schalnat0f716451995-11-28 11:22:13 -06001342 }
1343 }
1344
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -05001345 fclose(fpin);
1346 fclose(fpout);
Guy Schalnat0d580581995-07-20 02:43:20 -05001347
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -06001348 return (0);
Guy Schalnat0d580581995-07-20 02:43:20 -05001349}
Guy Schalnat51f0eb41995-09-26 05:22:39 -05001350
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001351/* input and output filenames */
1352#ifdef RISCOS
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001353static PNG_CONST char *inname = "pngtest/png";
1354static PNG_CONST char *outname = "pngout/png";
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001355#else
Glenn Randers-Pehrson983ec161998-03-07 11:24:03 -06001356static PNG_CONST char *inname = "pngtest.png";
1357static PNG_CONST char *outname = "pngout.png";
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001358#endif
1359
1360int
1361main(int argc, char *argv[])
1362{
1363 int multiple = 0;
1364 int ierror = 0;
1365
1366 fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001367 fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION);
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001368 fprintf(STDERR,"%s",png_get_copyright(NULL));
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -06001369 /* Show the version of libpng used in building the library */
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -05001370 fprintf(STDERR," library (%lu):%s",
1371 (unsigned long) png_access_version_number(),
Glenn Randers-Pehrson1ef65b62000-05-12 06:19:53 -05001372 png_get_header_version(NULL));
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -06001373 /* Show the version of libpng used in building the application */
Glenn Randers-Pehrson13944802000-06-24 07:42:42 -05001374 fprintf(STDERR," pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER,
Glenn Randers-Pehrson1ef65b62000-05-12 06:19:53 -05001375 PNG_HEADER_VERSION_STRING);
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -05001376 fprintf(STDERR," png_sizeof(png_struct)=%ld, png_sizeof(png_info)=%ld\n",
1377 (long)png_sizeof(png_struct), (long)png_sizeof(png_info));
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001378
1379 /* Do some consistency checking on the memory allocation settings, I'm
1380 not sure this matters, but it is nice to know, the first of these
1381 tests should be impossible because of the way the macros are set
1382 in pngconf.h */
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -06001383#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001384 fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n");
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -06001385#endif
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001386 /* I think the following can happen. */
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -06001387#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001388 fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n");
Glenn Randers-Pehrsonea3bcd71998-03-07 14:33:00 -06001389#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001390
1391 if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
1392 {
1393 fprintf(STDERR,
1394 "Warning: versions are different between png.h and png.c\n");
1395 fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING);
1396 fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver);
1397 ++ierror;
1398 }
1399
1400 if (argc > 1)
1401 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001402 if (strcmp(argv[1], "-m") == 0)
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001403 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001404 multiple = 1;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001405 status_dots_requested = 0;
1406 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001407 else if (strcmp(argv[1], "-mv") == 0 ||
1408 strcmp(argv[1], "-vm") == 0 )
1409 {
1410 multiple = 1;
1411 verbose = 1;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001412 status_dots_requested = 1;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001413 }
1414 else if (strcmp(argv[1], "-v") == 0)
1415 {
1416 verbose = 1;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001417 status_dots_requested = 1;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001418 inname = argv[2];
1419 }
1420 else
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001421 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001422 inname = argv[1];
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001423 status_dots_requested = 0;
1424 }
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001425 }
1426
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001427 if (!multiple && argc == 3+verbose)
1428 outname = argv[2+verbose];
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001429
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001430 if ((!multiple && argc > 3+verbose) || (multiple && argc < 2))
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001431 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001432 fprintf(STDERR,
1433 "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001434 argv[0], argv[0]);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001435 fprintf(STDERR,
1436 " reads/writes one PNG file (without -m) or multiple files (-m)\n");
1437 fprintf(STDERR,
1438 " with -m %s is used as a temporary file\n", outname);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001439 exit(1);
1440 }
1441
1442 if (multiple)
1443 {
1444 int i;
Glenn Randers-Pehrson37f116a2004-08-15 07:15:39 -05001445#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001446 int allocation_now = current_allocation;
1447#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001448 for (i=2; i<argc; ++i)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001449 {
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -05001450#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1451 int k;
1452#endif
1453 int kerror;
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001454 fprintf(STDERR, "Testing %s:",argv[i]);
1455 kerror = test_one_file(argv[i], outname);
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001456 if (kerror == 0)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001457 {
Glenn Randers-Pehrson38d73af1998-03-07 21:30:44 -06001458#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -05001459 fprintf(STDERR, "\n PASS (%lu zero samples)\n",
1460 (unsigned long) zero_samples);
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001461#else
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001462 fprintf(STDERR, " PASS\n");
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001463#endif
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001464#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1465 for (k=0; k<256; k++)
1466 if(filters_used[k])
1467 fprintf(STDERR, " Filter %d was used %lu times\n",
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -05001468 k, (unsigned long) filters_used[k]);
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001469#endif
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001470#if defined(PNG_TIME_RFC1123_SUPPORTED)
1471 if(tIME_chunk_present != 0)
1472 fprintf(STDERR, " tIME = %s\n",tIME_string);
1473 tIME_chunk_present = 0;
1474#endif /* PNG_TIME_RFC1123_SUPPORTED */
1475 }
1476 else
1477 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001478 fprintf(STDERR, " FAIL\n");
1479 ierror += kerror;
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001480 }
Glenn Randers-Pehrson37f116a2004-08-15 07:15:39 -05001481#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001482 if (allocation_now != current_allocation)
1483 fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
1484 current_allocation-allocation_now);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001485 if (current_allocation != 0)
1486 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001487 memory_infop pinfo = pinformation;
1488
1489 fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
1490 current_allocation);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001491 while (pinfo != NULL)
1492 {
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -05001493 fprintf(STDERR, " %lu bytes at %x\n",
1494 (unsigned long) pinfo->size,
Glenn Randers-Pehrsonb1828932001-06-23 08:03:17 -05001495 (unsigned int) pinfo->pointer);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001496 pinfo = pinfo->next;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001497 }
Glenn Randers-Pehrson2687fcc1998-01-07 20:54:20 -06001498 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001499#endif
1500 }
Glenn Randers-Pehrson37f116a2004-08-15 07:15:39 -05001501#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -05001502 fprintf(STDERR, " Current memory allocation: %10d bytes\n",
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001503 current_allocation);
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -05001504 fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001505 maximum_allocation);
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -05001506 fprintf(STDERR, " Total memory allocation: %10d bytes\n",
1507 total_allocation);
1508 fprintf(STDERR, " Number of allocations: %10d\n",
1509 num_allocations);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001510#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001511 }
1512 else
1513 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001514 int i;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001515 for (i=0; i<3; ++i)
1516 {
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001517 int kerror;
Glenn Randers-Pehrson37f116a2004-08-15 07:15:39 -05001518#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001519 int allocation_now = current_allocation;
1520#endif
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001521 if (i == 1) status_dots_requested = 1;
1522 else if(verbose == 0)status_dots_requested = 0;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001523 if (i == 0 || verbose == 1 || ierror != 0)
1524 fprintf(STDERR, "Testing %s:",inname);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001525 kerror = test_one_file(inname, outname);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001526 if(kerror == 0)
1527 {
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001528 if(verbose == 1 || i == 2)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001529 {
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -05001530#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001531 int k;
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -05001532#endif
Glenn Randers-Pehrson38d73af1998-03-07 21:30:44 -06001533#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -05001534 fprintf(STDERR, "\n PASS (%lu zero samples)\n",
1535 (unsigned long) zero_samples);
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001536#else
1537 fprintf(STDERR, " PASS\n");
1538#endif
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001539#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1540 for (k=0; k<256; k++)
1541 if(filters_used[k])
1542 fprintf(STDERR, " Filter %d was used %lu times\n",
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -05001543 k,
1544 (unsigned long) filters_used[k]);
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001545#endif
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001546#if defined(PNG_TIME_RFC1123_SUPPORTED)
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -05001547 if(tIME_chunk_present != 0)
1548 fprintf(STDERR, " tIME = %s\n",tIME_string);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001549#endif /* PNG_TIME_RFC1123_SUPPORTED */
1550 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001551 }
1552 else
1553 {
1554 if(verbose == 0 && i != 2)
1555 fprintf(STDERR, "Testing %s:",inname);
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001556 fprintf(STDERR, " FAIL\n");
1557 ierror += kerror;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001558 }
Glenn Randers-Pehrson37f116a2004-08-15 07:15:39 -05001559#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001560 if (allocation_now != current_allocation)
1561 fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
1562 current_allocation-allocation_now);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001563 if (current_allocation != 0)
1564 {
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001565 memory_infop pinfo = pinformation;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001566
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001567 fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
1568 current_allocation);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001569 while (pinfo != NULL)
1570 {
Glenn Randers-Pehrsonb1828932001-06-23 08:03:17 -05001571 fprintf(STDERR," %lu bytes at %x\n",
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -05001572 (unsigned long) pinfo->size, (unsigned int)pinfo->pointer);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001573 pinfo = pinfo->next;
1574 }
1575 }
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001576#endif
Glenn Randers-Pehrsonc4a2ae61998-01-16 22:06:18 -06001577 }
Glenn Randers-Pehrson37f116a2004-08-15 07:15:39 -05001578#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -05001579 fprintf(STDERR, " Current memory allocation: %10d bytes\n",
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001580 current_allocation);
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -05001581 fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001582 maximum_allocation);
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -05001583 fprintf(STDERR, " Total memory allocation: %10d bytes\n",
1584 total_allocation);
1585 fprintf(STDERR, " Number of allocations: %10d\n",
1586 num_allocations);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001587#endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001588 }
1589
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001590#ifdef PNGTEST_TIMING
1591 t_stop = (float)clock();
1592 t_misc += (t_stop - t_start);
1593 t_start = t_stop;
1594 fprintf(STDERR," CPU time used = %.3f seconds",
1595 (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
1596 fprintf(STDERR," (decoding %.3f,\n",
1597 t_decode/(float)CLOCKS_PER_SEC);
1598 fprintf(STDERR," encoding %.3f ,",
1599 t_encode/(float)CLOCKS_PER_SEC);
1600 fprintf(STDERR," other %.3f seconds)\n\n",
1601 t_misc/(float)CLOCKS_PER_SEC);
1602#endif
1603
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001604 if (ierror == 0)
1605 fprintf(STDERR, "libpng passes test\n");
1606 else
1607 fprintf(STDERR, "libpng FAILS test\n");
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001608 return (int)(ierror != 0);
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -06001609}
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -05001610
Glenn Randers-Pehrsonbcfd15d1999-10-01 14:22:25 -05001611/* Generate a compiler error if there is an old png.h in the search path. */
Glenn Randers-Pehrsone826d7e2006-07-03 00:21:58 -05001612typedef version_1_4_0beta9 your_png_h_is_not_version_1_4_0beta9;