17dd7cddfSDavid du Colombier
27dd7cddfSDavid du Colombier /* pngtest.c - a simple test program to test libpng
37dd7cddfSDavid du Colombier *
4*593dc095SDavid du Colombier * libpng 1.2.8 - December 3, 2004
57dd7cddfSDavid du Colombier * For conditions of distribution and use, see copyright notice in png.h
6*593dc095SDavid du Colombier * Copyright (c) 1998-2004 Glenn Randers-Pehrson
7*593dc095SDavid du Colombier * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8*593dc095SDavid du Colombier * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
97dd7cddfSDavid du Colombier *
107dd7cddfSDavid du Colombier * This program reads in a PNG image, writes it out again, and then
117dd7cddfSDavid du Colombier * compares the two files. If the files are identical, this shows that
127dd7cddfSDavid du Colombier * the basic chunk handling, filtering, and (de)compression code is working
137dd7cddfSDavid du Colombier * properly. It does not currently test all of the transforms, although
147dd7cddfSDavid du Colombier * it probably should.
157dd7cddfSDavid du Colombier *
16*593dc095SDavid du Colombier * The program will report "FAIL" in certain legitimate cases:
177dd7cddfSDavid du Colombier * 1) when the compression level or filter selection method is changed.
18*593dc095SDavid du Colombier * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192.
19*593dc095SDavid du Colombier * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks
20*593dc095SDavid du Colombier * exist in the input file.
217dd7cddfSDavid du Colombier * 4) others not listed here...
227dd7cddfSDavid du Colombier * In these cases, it is best to check with another tool such as "pngcheck"
23*593dc095SDavid du Colombier * to see what the differences between the two files are.
247dd7cddfSDavid du Colombier *
257dd7cddfSDavid du Colombier * If a filename is given on the command-line, then this file is used
267dd7cddfSDavid du Colombier * for the input, rather than the default "pngtest.png". This allows
27*593dc095SDavid du Colombier * testing a wide variety of files easily. You can also test a number
28*593dc095SDavid du Colombier * of files at once by typing "pngtest -m file1.png file2.png ..."
297dd7cddfSDavid du Colombier */
307dd7cddfSDavid du Colombier
31*593dc095SDavid du Colombier #include "png.h"
32*593dc095SDavid du Colombier
33*593dc095SDavid du Colombier #if defined(_WIN32_WCE)
34*593dc095SDavid du Colombier # if _WIN32_WCE < 211
35*593dc095SDavid du Colombier __error__ (f|w)printf functions are not supported on old WindowsCE.;
36*593dc095SDavid du Colombier # endif
37*593dc095SDavid du Colombier # include <windows.h>
38*593dc095SDavid du Colombier # include <stdlib.h>
39*593dc095SDavid du Colombier # define READFILE(file, data, length, check) \
40*593dc095SDavid du Colombier if (ReadFile(file, data, length, &check,NULL)) check = 0
41*593dc095SDavid du Colombier # define WRITEFILE(file, data, length, check)) \
42*593dc095SDavid du Colombier if (WriteFile(file, data, length, &check, NULL)) check = 0
43*593dc095SDavid du Colombier # define FCLOSE(file) CloseHandle(file)
44*593dc095SDavid du Colombier #else
457dd7cddfSDavid du Colombier # include <stdio.h>
467dd7cddfSDavid du Colombier # include <stdlib.h>
47*593dc095SDavid du Colombier # include <assert.h>
48*593dc095SDavid du Colombier # define READFILE(file, data, length, check) \
49*593dc095SDavid du Colombier check=(png_size_t)fread(data,(png_size_t)1,length,file)
50*593dc095SDavid du Colombier # define WRITEFILE(file, data, length, check) \
51*593dc095SDavid du Colombier check=(png_size_t)fwrite(data,(png_size_t)1, length, file)
52*593dc095SDavid du Colombier # define FCLOSE(file) fclose(file)
53*593dc095SDavid du Colombier #endif
54*593dc095SDavid du Colombier
55*593dc095SDavid du Colombier #if defined(PNG_NO_STDIO)
56*593dc095SDavid du Colombier # if defined(_WIN32_WCE)
57*593dc095SDavid du Colombier typedef HANDLE png_FILE_p;
58*593dc095SDavid du Colombier # else
59*593dc095SDavid du Colombier typedef FILE * png_FILE_p;
60*593dc095SDavid du Colombier # endif
61*593dc095SDavid du Colombier #endif
627dd7cddfSDavid du Colombier
637dd7cddfSDavid du Colombier /* Makes pngtest verbose so we can find problems (needs to be before png.h) */
647dd7cddfSDavid du Colombier #ifndef PNG_DEBUG
657dd7cddfSDavid du Colombier # define PNG_DEBUG 0
667dd7cddfSDavid du Colombier #endif
677dd7cddfSDavid du Colombier
68*593dc095SDavid du Colombier #if !PNG_DEBUG
69*593dc095SDavid du Colombier # define SINGLE_ROWBUF_ALLOC /* makes buffer overruns easier to nail */
707dd7cddfSDavid du Colombier #endif
717dd7cddfSDavid du Colombier
72*593dc095SDavid du Colombier /* Turn on CPU timing
73*593dc095SDavid du Colombier #define PNGTEST_TIMING
74*593dc095SDavid du Colombier */
75*593dc095SDavid du Colombier
76*593dc095SDavid du Colombier #ifdef PNG_NO_FLOATING_POINT_SUPPORTED
77*593dc095SDavid du Colombier #undef PNGTEST_TIMING
78*593dc095SDavid du Colombier #endif
79*593dc095SDavid du Colombier
80*593dc095SDavid du Colombier #ifdef PNGTEST_TIMING
81*593dc095SDavid du Colombier static float t_start, t_stop, t_decode, t_encode, t_misc;
82*593dc095SDavid du Colombier #include <time.h>
83*593dc095SDavid du Colombier #endif
84*593dc095SDavid du Colombier
85*593dc095SDavid du Colombier /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
86*593dc095SDavid du Colombier #ifndef png_jmpbuf
87*593dc095SDavid du Colombier # define png_jmpbuf(png_ptr) png_ptr->jmpbuf
88*593dc095SDavid du Colombier #endif
89*593dc095SDavid du Colombier
90*593dc095SDavid du Colombier #ifdef PNGTEST_TIMING
91*593dc095SDavid du Colombier static float t_start, t_stop, t_decode, t_encode, t_misc;
92*593dc095SDavid du Colombier #if !defined(PNG_tIME_SUPPORTED)
93*593dc095SDavid du Colombier #include <time.h>
94*593dc095SDavid du Colombier #endif
95*593dc095SDavid du Colombier #endif
96*593dc095SDavid du Colombier
97*593dc095SDavid du Colombier #if defined(PNG_TIME_RFC1123_SUPPORTED)
98*593dc095SDavid du Colombier static int tIME_chunk_present=0;
99*593dc095SDavid du Colombier static char tIME_string[30] = "no tIME chunk present in file";
100*593dc095SDavid du Colombier #endif
101*593dc095SDavid du Colombier
102*593dc095SDavid du Colombier static int verbose = 0;
103*593dc095SDavid du Colombier
104*593dc095SDavid du Colombier int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname));
1057dd7cddfSDavid du Colombier
1067dd7cddfSDavid du Colombier #ifdef __TURBOC__
1077dd7cddfSDavid du Colombier #include <mem.h>
1087dd7cddfSDavid du Colombier #endif
1097dd7cddfSDavid du Colombier
1107dd7cddfSDavid du Colombier /* defined so I can write to a file on gui/windowing platforms */
1117dd7cddfSDavid du Colombier /* #define STDERR stderr */
1127dd7cddfSDavid du Colombier #define STDERR stdout /* for DOS */
1137dd7cddfSDavid du Colombier
114*593dc095SDavid du Colombier /* example of using row callbacks to make a simple progress meter */
115*593dc095SDavid du Colombier static int status_pass=1;
116*593dc095SDavid du Colombier static int status_dots_requested=0;
117*593dc095SDavid du Colombier static int status_dots=1;
118*593dc095SDavid du Colombier
119*593dc095SDavid du Colombier void
120*593dc095SDavid du Colombier #ifdef PNG_1_0_X
121*593dc095SDavid du Colombier PNGAPI
122*593dc095SDavid du Colombier #endif
123*593dc095SDavid du Colombier read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
124*593dc095SDavid du Colombier void
125*593dc095SDavid du Colombier #ifdef PNG_1_0_X
126*593dc095SDavid du Colombier PNGAPI
127*593dc095SDavid du Colombier #endif
read_row_callback(png_structp png_ptr,png_uint_32 row_number,int pass)128*593dc095SDavid du Colombier read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
129*593dc095SDavid du Colombier {
130*593dc095SDavid du Colombier if(png_ptr == NULL || row_number > PNG_UINT_31_MAX) return;
131*593dc095SDavid du Colombier if(status_pass != pass)
132*593dc095SDavid du Colombier {
133*593dc095SDavid du Colombier fprintf(stdout,"\n Pass %d: ",pass);
134*593dc095SDavid du Colombier status_pass = pass;
135*593dc095SDavid du Colombier status_dots = 31;
136*593dc095SDavid du Colombier }
137*593dc095SDavid du Colombier status_dots--;
138*593dc095SDavid du Colombier if(status_dots == 0)
139*593dc095SDavid du Colombier {
140*593dc095SDavid du Colombier fprintf(stdout, "\n ");
141*593dc095SDavid du Colombier status_dots=30;
142*593dc095SDavid du Colombier }
143*593dc095SDavid du Colombier fprintf(stdout, "r");
144*593dc095SDavid du Colombier }
145*593dc095SDavid du Colombier
146*593dc095SDavid du Colombier void
147*593dc095SDavid du Colombier #ifdef PNG_1_0_X
148*593dc095SDavid du Colombier PNGAPI
149*593dc095SDavid du Colombier #endif
150*593dc095SDavid du Colombier write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
151*593dc095SDavid du Colombier void
152*593dc095SDavid du Colombier #ifdef PNG_1_0_X
153*593dc095SDavid du Colombier PNGAPI
154*593dc095SDavid du Colombier #endif
write_row_callback(png_structp png_ptr,png_uint_32 row_number,int pass)155*593dc095SDavid du Colombier write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
156*593dc095SDavid du Colombier {
157*593dc095SDavid du Colombier if(png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) return;
158*593dc095SDavid du Colombier fprintf(stdout, "w");
159*593dc095SDavid du Colombier }
160*593dc095SDavid du Colombier
161*593dc095SDavid du Colombier
162*593dc095SDavid du Colombier #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
163*593dc095SDavid du Colombier /* Example of using user transform callback (we don't transform anything,
164*593dc095SDavid du Colombier but merely examine the row filters. We set this to 256 rather than
165*593dc095SDavid du Colombier 5 in case illegal filter values are present.) */
166*593dc095SDavid du Colombier static png_uint_32 filters_used[256];
167*593dc095SDavid du Colombier void
168*593dc095SDavid du Colombier #ifdef PNG_1_0_X
169*593dc095SDavid du Colombier PNGAPI
170*593dc095SDavid du Colombier #endif
171*593dc095SDavid du Colombier count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data);
172*593dc095SDavid du Colombier void
173*593dc095SDavid du Colombier #ifdef PNG_1_0_X
174*593dc095SDavid du Colombier PNGAPI
175*593dc095SDavid du Colombier #endif
count_filters(png_structp png_ptr,png_row_infop row_info,png_bytep data)176*593dc095SDavid du Colombier count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data)
177*593dc095SDavid du Colombier {
178*593dc095SDavid du Colombier if(png_ptr != NULL && row_info != NULL)
179*593dc095SDavid du Colombier ++filters_used[*(data-1)];
180*593dc095SDavid du Colombier }
181*593dc095SDavid du Colombier #endif
182*593dc095SDavid du Colombier
183*593dc095SDavid du Colombier #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
184*593dc095SDavid du Colombier /* example of using user transform callback (we don't transform anything,
185*593dc095SDavid du Colombier but merely count the zero samples) */
186*593dc095SDavid du Colombier
187*593dc095SDavid du Colombier static png_uint_32 zero_samples;
188*593dc095SDavid du Colombier
189*593dc095SDavid du Colombier void
190*593dc095SDavid du Colombier #ifdef PNG_1_0_X
191*593dc095SDavid du Colombier PNGAPI
192*593dc095SDavid du Colombier #endif
193*593dc095SDavid du Colombier count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data);
194*593dc095SDavid du Colombier void
195*593dc095SDavid du Colombier #ifdef PNG_1_0_X
196*593dc095SDavid du Colombier PNGAPI
197*593dc095SDavid du Colombier #endif
count_zero_samples(png_structp png_ptr,png_row_infop row_info,png_bytep data)198*593dc095SDavid du Colombier count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
199*593dc095SDavid du Colombier {
200*593dc095SDavid du Colombier png_bytep dp = data;
201*593dc095SDavid du Colombier if(png_ptr == NULL)return;
202*593dc095SDavid du Colombier
203*593dc095SDavid du Colombier /* contents of row_info:
204*593dc095SDavid du Colombier * png_uint_32 width width of row
205*593dc095SDavid du Colombier * png_uint_32 rowbytes number of bytes in row
206*593dc095SDavid du Colombier * png_byte color_type color type of pixels
207*593dc095SDavid du Colombier * png_byte bit_depth bit depth of samples
208*593dc095SDavid du Colombier * png_byte channels number of channels (1-4)
209*593dc095SDavid du Colombier * png_byte pixel_depth bits per pixel (depth*channels)
210*593dc095SDavid du Colombier */
211*593dc095SDavid du Colombier
212*593dc095SDavid du Colombier
213*593dc095SDavid du Colombier /* counts the number of zero samples (or zero pixels if color_type is 3 */
214*593dc095SDavid du Colombier
215*593dc095SDavid du Colombier if(row_info->color_type == 0 || row_info->color_type == 3)
216*593dc095SDavid du Colombier {
217*593dc095SDavid du Colombier int pos=0;
218*593dc095SDavid du Colombier png_uint_32 n, nstop;
219*593dc095SDavid du Colombier for (n=0, nstop=row_info->width; n<nstop; n++)
220*593dc095SDavid du Colombier {
221*593dc095SDavid du Colombier if(row_info->bit_depth == 1)
222*593dc095SDavid du Colombier {
223*593dc095SDavid du Colombier if(((*dp << pos++ ) & 0x80) == 0) zero_samples++;
224*593dc095SDavid du Colombier if(pos == 8)
225*593dc095SDavid du Colombier {
226*593dc095SDavid du Colombier pos = 0;
227*593dc095SDavid du Colombier dp++;
228*593dc095SDavid du Colombier }
229*593dc095SDavid du Colombier }
230*593dc095SDavid du Colombier if(row_info->bit_depth == 2)
231*593dc095SDavid du Colombier {
232*593dc095SDavid du Colombier if(((*dp << (pos+=2)) & 0xc0) == 0) zero_samples++;
233*593dc095SDavid du Colombier if(pos == 8)
234*593dc095SDavid du Colombier {
235*593dc095SDavid du Colombier pos = 0;
236*593dc095SDavid du Colombier dp++;
237*593dc095SDavid du Colombier }
238*593dc095SDavid du Colombier }
239*593dc095SDavid du Colombier if(row_info->bit_depth == 4)
240*593dc095SDavid du Colombier {
241*593dc095SDavid du Colombier if(((*dp << (pos+=4)) & 0xf0) == 0) zero_samples++;
242*593dc095SDavid du Colombier if(pos == 8)
243*593dc095SDavid du Colombier {
244*593dc095SDavid du Colombier pos = 0;
245*593dc095SDavid du Colombier dp++;
246*593dc095SDavid du Colombier }
247*593dc095SDavid du Colombier }
248*593dc095SDavid du Colombier if(row_info->bit_depth == 8)
249*593dc095SDavid du Colombier if(*dp++ == 0) zero_samples++;
250*593dc095SDavid du Colombier if(row_info->bit_depth == 16)
251*593dc095SDavid du Colombier {
252*593dc095SDavid du Colombier if((*dp | *(dp+1)) == 0) zero_samples++;
253*593dc095SDavid du Colombier dp+=2;
254*593dc095SDavid du Colombier }
255*593dc095SDavid du Colombier }
256*593dc095SDavid du Colombier }
257*593dc095SDavid du Colombier else /* other color types */
258*593dc095SDavid du Colombier {
259*593dc095SDavid du Colombier png_uint_32 n, nstop;
260*593dc095SDavid du Colombier int channel;
261*593dc095SDavid du Colombier int color_channels = row_info->channels;
262*593dc095SDavid du Colombier if(row_info->color_type > 3)color_channels--;
263*593dc095SDavid du Colombier
264*593dc095SDavid du Colombier for (n=0, nstop=row_info->width; n<nstop; n++)
265*593dc095SDavid du Colombier {
266*593dc095SDavid du Colombier for (channel = 0; channel < color_channels; channel++)
267*593dc095SDavid du Colombier {
268*593dc095SDavid du Colombier if(row_info->bit_depth == 8)
269*593dc095SDavid du Colombier if(*dp++ == 0) zero_samples++;
270*593dc095SDavid du Colombier if(row_info->bit_depth == 16)
271*593dc095SDavid du Colombier {
272*593dc095SDavid du Colombier if((*dp | *(dp+1)) == 0) zero_samples++;
273*593dc095SDavid du Colombier dp+=2;
274*593dc095SDavid du Colombier }
275*593dc095SDavid du Colombier }
276*593dc095SDavid du Colombier if(row_info->color_type > 3)
277*593dc095SDavid du Colombier {
278*593dc095SDavid du Colombier dp++;
279*593dc095SDavid du Colombier if(row_info->bit_depth == 16)dp++;
280*593dc095SDavid du Colombier }
281*593dc095SDavid du Colombier }
282*593dc095SDavid du Colombier }
283*593dc095SDavid du Colombier }
284*593dc095SDavid du Colombier #endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
285*593dc095SDavid du Colombier
286*593dc095SDavid du Colombier static int wrote_question = 0;
2877dd7cddfSDavid du Colombier
2887dd7cddfSDavid du Colombier #if defined(PNG_NO_STDIO)
2897dd7cddfSDavid du Colombier /* START of code to validate stdio-free compilation */
2907dd7cddfSDavid du Colombier /* These copies of the default read/write functions come from pngrio.c and */
2917dd7cddfSDavid du Colombier /* pngwio.c. They allow "don't include stdio" testing of the library. */
292*593dc095SDavid du Colombier /* This is the function that does the actual reading of data. If you are
2937dd7cddfSDavid du Colombier not reading from a standard C stream, you should create a replacement
2947dd7cddfSDavid du Colombier read_data function and use it at run time with png_set_read_fn(), rather
2957dd7cddfSDavid du Colombier than changing the library. */
296*593dc095SDavid du Colombier
2977dd7cddfSDavid du Colombier #ifndef USE_FAR_KEYWORD
2987dd7cddfSDavid du Colombier static void
pngtest_read_data(png_structp png_ptr,png_bytep data,png_size_t length)299*593dc095SDavid du Colombier pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
3007dd7cddfSDavid du Colombier {
3017dd7cddfSDavid du Colombier png_size_t check;
3027dd7cddfSDavid du Colombier
3037dd7cddfSDavid du Colombier /* fread() returns 0 on error, so it is OK to store this in a png_size_t
3047dd7cddfSDavid du Colombier * instead of an int, which is what fread() actually returns.
3057dd7cddfSDavid du Colombier */
306*593dc095SDavid du Colombier READFILE((png_FILE_p)png_ptr->io_ptr, data, length, check);
3077dd7cddfSDavid du Colombier
3087dd7cddfSDavid du Colombier if (check != length)
3097dd7cddfSDavid du Colombier {
310*593dc095SDavid du Colombier png_error(png_ptr, "Read Error!");
3117dd7cddfSDavid du Colombier }
3127dd7cddfSDavid du Colombier }
3137dd7cddfSDavid du Colombier #else
3147dd7cddfSDavid du Colombier /* this is the model-independent version. Since the standard I/O library
3157dd7cddfSDavid du Colombier can't handle far buffers in the medium and small models, we have to copy
3167dd7cddfSDavid du Colombier the data.
3177dd7cddfSDavid du Colombier */
3187dd7cddfSDavid du Colombier
3197dd7cddfSDavid du Colombier #define NEAR_BUF_SIZE 1024
3207dd7cddfSDavid du Colombier #define MIN(a,b) (a <= b ? a : b)
3217dd7cddfSDavid du Colombier
3227dd7cddfSDavid du Colombier static void
pngtest_read_data(png_structp png_ptr,png_bytep data,png_size_t length)323*593dc095SDavid du Colombier pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
3247dd7cddfSDavid du Colombier {
3257dd7cddfSDavid du Colombier int check;
3267dd7cddfSDavid du Colombier png_byte *n_data;
327*593dc095SDavid du Colombier png_FILE_p io_ptr;
3287dd7cddfSDavid du Colombier
3297dd7cddfSDavid du Colombier /* Check if data really is near. If so, use usual code. */
3307dd7cddfSDavid du Colombier n_data = (png_byte *)CVT_PTR_NOCHECK(data);
331*593dc095SDavid du Colombier io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
3327dd7cddfSDavid du Colombier if ((png_bytep)n_data == data)
3337dd7cddfSDavid du Colombier {
334*593dc095SDavid du Colombier READFILE(io_ptr, n_data, length, check);
3357dd7cddfSDavid du Colombier }
3367dd7cddfSDavid du Colombier else
3377dd7cddfSDavid du Colombier {
3387dd7cddfSDavid du Colombier png_byte buf[NEAR_BUF_SIZE];
3397dd7cddfSDavid du Colombier png_size_t read, remaining, err;
3407dd7cddfSDavid du Colombier check = 0;
3417dd7cddfSDavid du Colombier remaining = length;
3427dd7cddfSDavid du Colombier do
3437dd7cddfSDavid du Colombier {
3447dd7cddfSDavid du Colombier read = MIN(NEAR_BUF_SIZE, remaining);
345*593dc095SDavid du Colombier READFILE(io_ptr, buf, 1, err);
3467dd7cddfSDavid du Colombier png_memcpy(data, buf, read); /* copy far buffer to near buffer */
3477dd7cddfSDavid du Colombier if(err != read)
3487dd7cddfSDavid du Colombier break;
3497dd7cddfSDavid du Colombier else
3507dd7cddfSDavid du Colombier check += err;
3517dd7cddfSDavid du Colombier data += read;
3527dd7cddfSDavid du Colombier remaining -= read;
3537dd7cddfSDavid du Colombier }
3547dd7cddfSDavid du Colombier while (remaining != 0);
3557dd7cddfSDavid du Colombier }
3567dd7cddfSDavid du Colombier if (check != length)
3577dd7cddfSDavid du Colombier {
3587dd7cddfSDavid du Colombier png_error(png_ptr, "read Error");
3597dd7cddfSDavid du Colombier }
3607dd7cddfSDavid du Colombier }
3617dd7cddfSDavid du Colombier #endif /* USE_FAR_KEYWORD */
3627dd7cddfSDavid du Colombier
3637dd7cddfSDavid du Colombier #if defined(PNG_WRITE_FLUSH_SUPPORTED)
3647dd7cddfSDavid du Colombier static void
pngtest_flush(png_structp png_ptr)365*593dc095SDavid du Colombier pngtest_flush(png_structp png_ptr)
3667dd7cddfSDavid du Colombier {
367*593dc095SDavid du Colombier #if !defined(_WIN32_WCE)
368*593dc095SDavid du Colombier png_FILE_p io_ptr;
369*593dc095SDavid du Colombier io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
3707dd7cddfSDavid du Colombier if (io_ptr != NULL)
3717dd7cddfSDavid du Colombier fflush(io_ptr);
372*593dc095SDavid du Colombier #endif
3737dd7cddfSDavid du Colombier }
3747dd7cddfSDavid du Colombier #endif
3757dd7cddfSDavid du Colombier
376*593dc095SDavid du Colombier /* This is the function that does the actual writing of data. If you are
3777dd7cddfSDavid du Colombier not writing to a standard C stream, you should create a replacement
3787dd7cddfSDavid du Colombier write_data function and use it at run time with png_set_write_fn(), rather
3797dd7cddfSDavid du Colombier than changing the library. */
3807dd7cddfSDavid du Colombier #ifndef USE_FAR_KEYWORD
3817dd7cddfSDavid du Colombier static void
pngtest_write_data(png_structp png_ptr,png_bytep data,png_size_t length)382*593dc095SDavid du Colombier pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
3837dd7cddfSDavid du Colombier {
3847dd7cddfSDavid du Colombier png_uint_32 check;
3857dd7cddfSDavid du Colombier
386*593dc095SDavid du Colombier WRITEFILE((png_FILE_p)png_ptr->io_ptr, data, length, check);
3877dd7cddfSDavid du Colombier if (check != length)
3887dd7cddfSDavid du Colombier {
3897dd7cddfSDavid du Colombier png_error(png_ptr, "Write Error");
3907dd7cddfSDavid du Colombier }
3917dd7cddfSDavid du Colombier }
3927dd7cddfSDavid du Colombier #else
3937dd7cddfSDavid du Colombier /* this is the model-independent version. Since the standard I/O library
3947dd7cddfSDavid du Colombier can't handle far buffers in the medium and small models, we have to copy
3957dd7cddfSDavid du Colombier the data.
3967dd7cddfSDavid du Colombier */
3977dd7cddfSDavid du Colombier
3987dd7cddfSDavid du Colombier #define NEAR_BUF_SIZE 1024
3997dd7cddfSDavid du Colombier #define MIN(a,b) (a <= b ? a : b)
4007dd7cddfSDavid du Colombier
4017dd7cddfSDavid du Colombier static void
pngtest_write_data(png_structp png_ptr,png_bytep data,png_size_t length)402*593dc095SDavid du Colombier pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
4037dd7cddfSDavid du Colombier {
4047dd7cddfSDavid du Colombier png_uint_32 check;
4057dd7cddfSDavid du Colombier png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
406*593dc095SDavid du Colombier png_FILE_p io_ptr;
4077dd7cddfSDavid du Colombier
4087dd7cddfSDavid du Colombier /* Check if data really is near. If so, use usual code. */
4097dd7cddfSDavid du Colombier near_data = (png_byte *)CVT_PTR_NOCHECK(data);
410*593dc095SDavid du Colombier io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
4117dd7cddfSDavid du Colombier if ((png_bytep)near_data == data)
4127dd7cddfSDavid du Colombier {
413*593dc095SDavid du Colombier WRITEFILE(io_ptr, near_data, length, check);
4147dd7cddfSDavid du Colombier }
4157dd7cddfSDavid du Colombier else
4167dd7cddfSDavid du Colombier {
4177dd7cddfSDavid du Colombier png_byte buf[NEAR_BUF_SIZE];
4187dd7cddfSDavid du Colombier png_size_t written, remaining, err;
4197dd7cddfSDavid du Colombier check = 0;
4207dd7cddfSDavid du Colombier remaining = length;
4217dd7cddfSDavid du Colombier do
4227dd7cddfSDavid du Colombier {
4237dd7cddfSDavid du Colombier written = MIN(NEAR_BUF_SIZE, remaining);
4247dd7cddfSDavid du Colombier png_memcpy(buf, data, written); /* copy far buffer to near buffer */
425*593dc095SDavid du Colombier WRITEFILE(io_ptr, buf, written, err);
4267dd7cddfSDavid du Colombier if (err != written)
4277dd7cddfSDavid du Colombier break;
4287dd7cddfSDavid du Colombier else
4297dd7cddfSDavid du Colombier check += err;
4307dd7cddfSDavid du Colombier data += written;
4317dd7cddfSDavid du Colombier remaining -= written;
4327dd7cddfSDavid du Colombier }
4337dd7cddfSDavid du Colombier while (remaining != 0);
4347dd7cddfSDavid du Colombier }
4357dd7cddfSDavid du Colombier if (check != length)
4367dd7cddfSDavid du Colombier {
4377dd7cddfSDavid du Colombier png_error(png_ptr, "Write Error");
4387dd7cddfSDavid du Colombier }
4397dd7cddfSDavid du Colombier }
4407dd7cddfSDavid du Colombier
4417dd7cddfSDavid du Colombier #endif /* USE_FAR_KEYWORD */
4427dd7cddfSDavid du Colombier
4437dd7cddfSDavid du Colombier /* This function is called when there is a warning, but the library thinks
4447dd7cddfSDavid du Colombier * it can continue anyway. Replacement functions don't have to do anything
4457dd7cddfSDavid du Colombier * here if you don't want to. In the default configuration, png_ptr is
4467dd7cddfSDavid du Colombier * not used, but it is passed in case it may be useful.
4477dd7cddfSDavid du Colombier */
4487dd7cddfSDavid du Colombier static void
pngtest_warning(png_structp png_ptr,png_const_charp message)449*593dc095SDavid du Colombier pngtest_warning(png_structp png_ptr, png_const_charp message)
4507dd7cddfSDavid du Colombier {
4517dd7cddfSDavid du Colombier PNG_CONST char *name = "UNKNOWN (ERROR!)";
4527dd7cddfSDavid du Colombier if (png_ptr != NULL && png_ptr->error_ptr != NULL)
4537dd7cddfSDavid du Colombier name = png_ptr->error_ptr;
4547dd7cddfSDavid du Colombier fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
4557dd7cddfSDavid du Colombier }
4567dd7cddfSDavid du Colombier
4577dd7cddfSDavid du Colombier /* This is the default error handling function. Note that replacements for
4587dd7cddfSDavid du Colombier * this function MUST NOT RETURN, or the program will likely crash. This
4597dd7cddfSDavid du Colombier * function is used by default, or if the program supplies NULL for the
4607dd7cddfSDavid du Colombier * error function pointer in png_set_error_fn().
4617dd7cddfSDavid du Colombier */
4627dd7cddfSDavid du Colombier static void
pngtest_error(png_structp png_ptr,png_const_charp message)463*593dc095SDavid du Colombier pngtest_error(png_structp png_ptr, png_const_charp message)
4647dd7cddfSDavid du Colombier {
465*593dc095SDavid du Colombier pngtest_warning(png_ptr, message);
466*593dc095SDavid du Colombier /* We can return because png_error calls the default handler, which is
467*593dc095SDavid du Colombier * actually OK in this case. */
4687dd7cddfSDavid du Colombier }
4697dd7cddfSDavid du Colombier #endif /* PNG_NO_STDIO */
4707dd7cddfSDavid du Colombier /* END of code to validate stdio-free compilation */
4717dd7cddfSDavid du Colombier
4727dd7cddfSDavid du Colombier /* START of code to validate memory allocation and deallocation */
473*593dc095SDavid du Colombier #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
4747dd7cddfSDavid du Colombier
4757dd7cddfSDavid du Colombier /* Allocate memory. For reasonable files, size should never exceed
4767dd7cddfSDavid du Colombier 64K. However, zlib may allocate more then 64K if you don't tell
4777dd7cddfSDavid du Colombier it not to. See zconf.h and png.h for more information. zlib does
4787dd7cddfSDavid du Colombier need to allocate exactly 64K, so whatever you call here must
4797dd7cddfSDavid du Colombier have the ability to do that.
4807dd7cddfSDavid du Colombier
4817dd7cddfSDavid du Colombier This piece of code can be compiled to validate max 64K allocations
4827dd7cddfSDavid du Colombier by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. */
483*593dc095SDavid du Colombier typedef struct memory_information
484*593dc095SDavid du Colombier {
4857dd7cddfSDavid du Colombier png_uint_32 size;
4867dd7cddfSDavid du Colombier png_voidp pointer;
4877dd7cddfSDavid du Colombier struct memory_information FAR *next;
4887dd7cddfSDavid du Colombier } memory_information;
4897dd7cddfSDavid du Colombier typedef memory_information FAR *memory_infop;
4907dd7cddfSDavid du Colombier
4917dd7cddfSDavid du Colombier static memory_infop pinformation = NULL;
4927dd7cddfSDavid du Colombier static int current_allocation = 0;
4937dd7cddfSDavid du Colombier static int maximum_allocation = 0;
494*593dc095SDavid du Colombier static int total_allocation = 0;
495*593dc095SDavid du Colombier static int num_allocations = 0;
4967dd7cddfSDavid du Colombier
497*593dc095SDavid du Colombier png_voidp png_debug_malloc PNGARG((png_structp png_ptr, png_uint_32 size));
498*593dc095SDavid du Colombier void png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr));
4997dd7cddfSDavid du Colombier
5007dd7cddfSDavid du Colombier png_voidp
png_debug_malloc(png_structp png_ptr,png_uint_32 size)501*593dc095SDavid du Colombier png_debug_malloc(png_structp png_ptr, png_uint_32 size)
502*593dc095SDavid du Colombier {
503*593dc095SDavid du Colombier
504*593dc095SDavid du Colombier /* png_malloc has already tested for NULL; png_create_struct calls
505*593dc095SDavid du Colombier png_debug_malloc directly, with png_ptr == NULL which is OK */
506*593dc095SDavid du Colombier
5077dd7cddfSDavid du Colombier if (size == 0)
508*593dc095SDavid du Colombier return (NULL);
5097dd7cddfSDavid du Colombier
5107dd7cddfSDavid du Colombier /* This calls the library allocator twice, once to get the requested
5117dd7cddfSDavid du Colombier buffer and once to get a new free list entry. */
5127dd7cddfSDavid du Colombier {
513*593dc095SDavid du Colombier /* Disable malloc_fn and free_fn */
514*593dc095SDavid du Colombier memory_infop pinfo;
515*593dc095SDavid du Colombier png_set_mem_fn(png_ptr, NULL, NULL, NULL);
516*593dc095SDavid du Colombier pinfo = (memory_infop)png_malloc(png_ptr,
517*593dc095SDavid du Colombier (png_uint_32)png_sizeof (*pinfo));
5187dd7cddfSDavid du Colombier pinfo->size = size;
5197dd7cddfSDavid du Colombier current_allocation += size;
520*593dc095SDavid du Colombier total_allocation += size;
521*593dc095SDavid du Colombier num_allocations ++;
5227dd7cddfSDavid du Colombier if (current_allocation > maximum_allocation)
5237dd7cddfSDavid du Colombier maximum_allocation = current_allocation;
524*593dc095SDavid du Colombier pinfo->pointer = (png_voidp)png_malloc(png_ptr, size);
525*593dc095SDavid du Colombier /* Restore malloc_fn and free_fn */
526*593dc095SDavid du Colombier png_set_mem_fn(png_ptr, png_voidp_NULL, (png_malloc_ptr)png_debug_malloc,
527*593dc095SDavid du Colombier (png_free_ptr)png_debug_free);
528*593dc095SDavid du Colombier if (size != 0 && pinfo->pointer == NULL)
529*593dc095SDavid du Colombier {
530*593dc095SDavid du Colombier current_allocation -= size;
531*593dc095SDavid du Colombier total_allocation -= size;
532*593dc095SDavid du Colombier png_error(png_ptr,
533*593dc095SDavid du Colombier "out of memory in pngtest->png_debug_malloc.");
534*593dc095SDavid du Colombier }
5357dd7cddfSDavid du Colombier pinfo->next = pinformation;
5367dd7cddfSDavid du Colombier pinformation = pinfo;
5377dd7cddfSDavid du Colombier /* Make sure the caller isn't assuming zeroed memory. */
5387dd7cddfSDavid du Colombier png_memset(pinfo->pointer, 0xdd, pinfo->size);
539*593dc095SDavid du Colombier if(verbose)
540*593dc095SDavid du Colombier printf("png_malloc %lu bytes at %x\n",size,pinfo->pointer);
541*593dc095SDavid du Colombier assert(pinfo->size != 12345678);
5427dd7cddfSDavid du Colombier return (png_voidp)(pinfo->pointer);
5437dd7cddfSDavid du Colombier }
5447dd7cddfSDavid du Colombier }
5457dd7cddfSDavid du Colombier
5467dd7cddfSDavid du Colombier /* Free a pointer. It is removed from the list at the same time. */
5477dd7cddfSDavid du Colombier void
png_debug_free(png_structp png_ptr,png_voidp ptr)548*593dc095SDavid du Colombier png_debug_free(png_structp png_ptr, png_voidp ptr)
5497dd7cddfSDavid du Colombier {
5507dd7cddfSDavid du Colombier if (png_ptr == NULL)
551*593dc095SDavid du Colombier fprintf(STDERR, "NULL pointer to png_debug_free.\n");
552*593dc095SDavid du Colombier if (ptr == 0)
553*593dc095SDavid du Colombier {
5547dd7cddfSDavid du Colombier #if 0 /* This happens all the time. */
5557dd7cddfSDavid du Colombier fprintf(STDERR, "WARNING: freeing NULL pointer\n");
5567dd7cddfSDavid du Colombier #endif
5577dd7cddfSDavid du Colombier return;
5587dd7cddfSDavid du Colombier }
5597dd7cddfSDavid du Colombier
5607dd7cddfSDavid du Colombier /* Unlink the element from the list. */
5617dd7cddfSDavid du Colombier {
5627dd7cddfSDavid du Colombier memory_infop FAR *ppinfo = &pinformation;
563*593dc095SDavid du Colombier for (;;)
564*593dc095SDavid du Colombier {
5657dd7cddfSDavid du Colombier memory_infop pinfo = *ppinfo;
566*593dc095SDavid du Colombier if (pinfo->pointer == ptr)
567*593dc095SDavid du Colombier {
5687dd7cddfSDavid du Colombier *ppinfo = pinfo->next;
5697dd7cddfSDavid du Colombier current_allocation -= pinfo->size;
5707dd7cddfSDavid du Colombier if (current_allocation < 0)
5717dd7cddfSDavid du Colombier fprintf(STDERR, "Duplicate free of memory\n");
5727dd7cddfSDavid du Colombier /* We must free the list element too, but first kill
573*593dc095SDavid du Colombier the memory that is to be freed. */
574*593dc095SDavid du Colombier png_memset(ptr, 0x55, pinfo->size);
575*593dc095SDavid du Colombier png_free_default(png_ptr, pinfo);
576*593dc095SDavid du Colombier pinfo=NULL;
5777dd7cddfSDavid du Colombier break;
5787dd7cddfSDavid du Colombier }
579*593dc095SDavid du Colombier if (pinfo->next == NULL)
580*593dc095SDavid du Colombier {
581*593dc095SDavid du Colombier fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr);
5827dd7cddfSDavid du Colombier break;
5837dd7cddfSDavid du Colombier }
5847dd7cddfSDavid du Colombier ppinfo = &pinfo->next;
5857dd7cddfSDavid du Colombier }
5867dd7cddfSDavid du Colombier }
5877dd7cddfSDavid du Colombier
5887dd7cddfSDavid du Colombier /* Finally free the data. */
589*593dc095SDavid du Colombier if(verbose)
590*593dc095SDavid du Colombier printf("Freeing %x\n",ptr);
591*593dc095SDavid du Colombier png_free_default(png_ptr, ptr);
592*593dc095SDavid du Colombier ptr=NULL;
5937dd7cddfSDavid du Colombier }
594*593dc095SDavid du Colombier #endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */
5957dd7cddfSDavid du Colombier /* END of code to test memory allocation/deallocation */
5967dd7cddfSDavid du Colombier
5977dd7cddfSDavid du Colombier /* Test one file */
598*593dc095SDavid du Colombier int
test_one_file(PNG_CONST char * inname,PNG_CONST char * outname)599*593dc095SDavid du Colombier test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
6007dd7cddfSDavid du Colombier {
601*593dc095SDavid du Colombier static png_FILE_p fpin;
602*593dc095SDavid du Colombier static png_FILE_p fpout; /* "static" prevents setjmp corruption */
603*593dc095SDavid du Colombier png_structp read_ptr;
604*593dc095SDavid du Colombier png_infop read_info_ptr, end_info_ptr;
605*593dc095SDavid du Colombier #ifdef PNG_WRITE_SUPPORTED
606*593dc095SDavid du Colombier png_structp write_ptr;
607*593dc095SDavid du Colombier png_infop write_info_ptr;
608*593dc095SDavid du Colombier png_infop write_end_info_ptr;
609*593dc095SDavid du Colombier #else
610*593dc095SDavid du Colombier png_structp write_ptr = NULL;
611*593dc095SDavid du Colombier png_infop write_info_ptr = NULL;
612*593dc095SDavid du Colombier png_infop write_end_info_ptr = NULL;
613*593dc095SDavid du Colombier #endif
6147dd7cddfSDavid du Colombier png_bytep row_buf;
6157dd7cddfSDavid du Colombier png_uint_32 y;
6167dd7cddfSDavid du Colombier png_uint_32 width, height;
6177dd7cddfSDavid du Colombier int num_pass, pass;
6187dd7cddfSDavid du Colombier int bit_depth, color_type;
619*593dc095SDavid du Colombier #ifdef PNG_SETJMP_SUPPORTED
6207dd7cddfSDavid du Colombier #ifdef USE_FAR_KEYWORD
6217dd7cddfSDavid du Colombier jmp_buf jmpbuf;
6227dd7cddfSDavid du Colombier #endif
623*593dc095SDavid du Colombier #endif
6247dd7cddfSDavid du Colombier
625*593dc095SDavid du Colombier #if defined(_WIN32_WCE)
626*593dc095SDavid du Colombier TCHAR path[MAX_PATH];
627*593dc095SDavid du Colombier #endif
6287dd7cddfSDavid du Colombier char inbuf[256], outbuf[256];
6297dd7cddfSDavid du Colombier
630*593dc095SDavid du Colombier row_buf = NULL;
6317dd7cddfSDavid du Colombier
632*593dc095SDavid du Colombier #if defined(_WIN32_WCE)
633*593dc095SDavid du Colombier MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH);
634*593dc095SDavid du Colombier if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
635*593dc095SDavid du Colombier #else
6367dd7cddfSDavid du Colombier if ((fpin = fopen(inname, "rb")) == NULL)
637*593dc095SDavid du Colombier #endif
6387dd7cddfSDavid du Colombier {
6397dd7cddfSDavid du Colombier fprintf(STDERR, "Could not find input file %s\n", inname);
6407dd7cddfSDavid du Colombier return (1);
6417dd7cddfSDavid du Colombier }
6427dd7cddfSDavid du Colombier
643*593dc095SDavid du Colombier #if defined(_WIN32_WCE)
644*593dc095SDavid du Colombier MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH);
645*593dc095SDavid du Colombier if ((fpout = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE)
646*593dc095SDavid du Colombier #else
6477dd7cddfSDavid du Colombier if ((fpout = fopen(outname, "wb")) == NULL)
648*593dc095SDavid du Colombier #endif
6497dd7cddfSDavid du Colombier {
6507dd7cddfSDavid du Colombier fprintf(STDERR, "Could not open output file %s\n", outname);
651*593dc095SDavid du Colombier FCLOSE(fpin);
6527dd7cddfSDavid du Colombier return (1);
6537dd7cddfSDavid du Colombier }
6547dd7cddfSDavid du Colombier
6557dd7cddfSDavid du Colombier png_debug(0, "Allocating read and write structures\n");
656*593dc095SDavid du Colombier #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
657*593dc095SDavid du Colombier read_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
658*593dc095SDavid du Colombier png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
659*593dc095SDavid du Colombier (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
660*593dc095SDavid du Colombier #else
661*593dc095SDavid du Colombier read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
662*593dc095SDavid du Colombier png_error_ptr_NULL, png_error_ptr_NULL);
6637dd7cddfSDavid du Colombier #endif
6647dd7cddfSDavid du Colombier #if defined(PNG_NO_STDIO)
665*593dc095SDavid du Colombier png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error,
666*593dc095SDavid du Colombier pngtest_warning);
667*593dc095SDavid du Colombier #endif
668*593dc095SDavid du Colombier #ifdef PNG_WRITE_SUPPORTED
669*593dc095SDavid du Colombier #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
670*593dc095SDavid du Colombier write_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
671*593dc095SDavid du Colombier png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
672*593dc095SDavid du Colombier (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
673*593dc095SDavid du Colombier #else
674*593dc095SDavid du Colombier write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
675*593dc095SDavid du Colombier png_error_ptr_NULL, png_error_ptr_NULL);
676*593dc095SDavid du Colombier #endif
677*593dc095SDavid du Colombier #if defined(PNG_NO_STDIO)
678*593dc095SDavid du Colombier png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error,
679*593dc095SDavid du Colombier pngtest_warning);
680*593dc095SDavid du Colombier #endif
6817dd7cddfSDavid du Colombier #endif
6827dd7cddfSDavid du Colombier png_debug(0, "Allocating read_info, write_info and end_info structures\n");
6837dd7cddfSDavid du Colombier read_info_ptr = png_create_info_struct(read_ptr);
6847dd7cddfSDavid du Colombier end_info_ptr = png_create_info_struct(read_ptr);
685*593dc095SDavid du Colombier #ifdef PNG_WRITE_SUPPORTED
686*593dc095SDavid du Colombier write_info_ptr = png_create_info_struct(write_ptr);
687*593dc095SDavid du Colombier write_end_info_ptr = png_create_info_struct(write_ptr);
688*593dc095SDavid du Colombier #endif
6897dd7cddfSDavid du Colombier
690*593dc095SDavid du Colombier #ifdef PNG_SETJMP_SUPPORTED
6917dd7cddfSDavid du Colombier png_debug(0, "Setting jmpbuf for read struct\n");
6927dd7cddfSDavid du Colombier #ifdef USE_FAR_KEYWORD
6937dd7cddfSDavid du Colombier if (setjmp(jmpbuf))
6947dd7cddfSDavid du Colombier #else
695*593dc095SDavid du Colombier if (setjmp(png_jmpbuf(read_ptr)))
6967dd7cddfSDavid du Colombier #endif
6977dd7cddfSDavid du Colombier {
6987dd7cddfSDavid du Colombier fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
699*593dc095SDavid du Colombier if (row_buf)
700*593dc095SDavid du Colombier png_free(read_ptr, row_buf);
7017dd7cddfSDavid du Colombier png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
702*593dc095SDavid du Colombier #ifdef PNG_WRITE_SUPPORTED
703*593dc095SDavid du Colombier png_destroy_info_struct(write_ptr, &write_end_info_ptr);
7047dd7cddfSDavid du Colombier png_destroy_write_struct(&write_ptr, &write_info_ptr);
705*593dc095SDavid du Colombier #endif
706*593dc095SDavid du Colombier FCLOSE(fpin);
707*593dc095SDavid du Colombier FCLOSE(fpout);
7087dd7cddfSDavid du Colombier return (1);
7097dd7cddfSDavid du Colombier }
710*593dc095SDavid du Colombier #ifdef USE_FAR_KEYWORD
711*593dc095SDavid du Colombier png_memcpy(png_jmpbuf(read_ptr),jmpbuf,png_sizeof(jmp_buf));
712*593dc095SDavid du Colombier #endif
7137dd7cddfSDavid du Colombier
714*593dc095SDavid du Colombier #ifdef PNG_WRITE_SUPPORTED
7157dd7cddfSDavid du Colombier png_debug(0, "Setting jmpbuf for write struct\n");
7167dd7cddfSDavid du Colombier #ifdef USE_FAR_KEYWORD
7177dd7cddfSDavid du Colombier if (setjmp(jmpbuf))
7187dd7cddfSDavid du Colombier #else
719*593dc095SDavid du Colombier if (setjmp(png_jmpbuf(write_ptr)))
7207dd7cddfSDavid du Colombier #endif
7217dd7cddfSDavid du Colombier {
7227dd7cddfSDavid du Colombier fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
7237dd7cddfSDavid du Colombier png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
724*593dc095SDavid du Colombier png_destroy_info_struct(write_ptr, &write_end_info_ptr);
725*593dc095SDavid du Colombier #ifdef PNG_WRITE_SUPPORTED
7267dd7cddfSDavid du Colombier png_destroy_write_struct(&write_ptr, &write_info_ptr);
727*593dc095SDavid du Colombier #endif
728*593dc095SDavid du Colombier FCLOSE(fpin);
729*593dc095SDavid du Colombier FCLOSE(fpout);
7307dd7cddfSDavid du Colombier return (1);
7317dd7cddfSDavid du Colombier }
7327dd7cddfSDavid du Colombier #ifdef USE_FAR_KEYWORD
733*593dc095SDavid du Colombier png_memcpy(png_jmpbuf(write_ptr),jmpbuf,png_sizeof(jmp_buf));
7347dd7cddfSDavid du Colombier #endif
735*593dc095SDavid du Colombier #endif
736*593dc095SDavid du Colombier #endif
737*593dc095SDavid du Colombier
7387dd7cddfSDavid du Colombier png_debug(0, "Initializing input and output streams\n");
7397dd7cddfSDavid du Colombier #if !defined(PNG_NO_STDIO)
7407dd7cddfSDavid du Colombier png_init_io(read_ptr, fpin);
741*593dc095SDavid du Colombier # ifdef PNG_WRITE_SUPPORTED
7427dd7cddfSDavid du Colombier png_init_io(write_ptr, fpout);
743*593dc095SDavid du Colombier # endif
7447dd7cddfSDavid du Colombier #else
745*593dc095SDavid du Colombier png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data);
746*593dc095SDavid du Colombier # ifdef PNG_WRITE_SUPPORTED
747*593dc095SDavid du Colombier png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data,
7487dd7cddfSDavid du Colombier # if defined(PNG_WRITE_FLUSH_SUPPORTED)
749*593dc095SDavid du Colombier pngtest_flush);
7507dd7cddfSDavid du Colombier # else
7517dd7cddfSDavid du Colombier NULL);
7527dd7cddfSDavid du Colombier # endif
7537dd7cddfSDavid du Colombier # endif
754*593dc095SDavid du Colombier #endif
755*593dc095SDavid du Colombier if(status_dots_requested == 1)
756*593dc095SDavid du Colombier {
757*593dc095SDavid du Colombier #ifdef PNG_WRITE_SUPPORTED
758*593dc095SDavid du Colombier png_set_write_status_fn(write_ptr, write_row_callback);
759*593dc095SDavid du Colombier #endif
760*593dc095SDavid du Colombier png_set_read_status_fn(read_ptr, read_row_callback);
761*593dc095SDavid du Colombier }
762*593dc095SDavid du Colombier else
763*593dc095SDavid du Colombier {
764*593dc095SDavid du Colombier #ifdef PNG_WRITE_SUPPORTED
765*593dc095SDavid du Colombier png_set_write_status_fn(write_ptr, png_write_status_ptr_NULL);
766*593dc095SDavid du Colombier #endif
767*593dc095SDavid du Colombier png_set_read_status_fn(read_ptr, png_read_status_ptr_NULL);
768*593dc095SDavid du Colombier }
769*593dc095SDavid du Colombier
770*593dc095SDavid du Colombier #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
771*593dc095SDavid du Colombier {
772*593dc095SDavid du Colombier int i;
773*593dc095SDavid du Colombier for(i=0; i<256; i++)
774*593dc095SDavid du Colombier filters_used[i]=0;
775*593dc095SDavid du Colombier png_set_read_user_transform_fn(read_ptr, count_filters);
776*593dc095SDavid du Colombier }
777*593dc095SDavid du Colombier #endif
778*593dc095SDavid du Colombier #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
779*593dc095SDavid du Colombier zero_samples=0;
780*593dc095SDavid du Colombier png_set_write_user_transform_fn(write_ptr, count_zero_samples);
781*593dc095SDavid du Colombier #endif
782*593dc095SDavid du Colombier
783*593dc095SDavid du Colombier #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
784*593dc095SDavid du Colombier # ifndef PNG_HANDLE_CHUNK_ALWAYS
785*593dc095SDavid du Colombier # define PNG_HANDLE_CHUNK_ALWAYS 3
786*593dc095SDavid du Colombier # endif
787*593dc095SDavid du Colombier png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS,
788*593dc095SDavid du Colombier png_bytep_NULL, 0);
789*593dc095SDavid du Colombier #endif
790*593dc095SDavid du Colombier #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
791*593dc095SDavid du Colombier # ifndef PNG_HANDLE_CHUNK_IF_SAFE
792*593dc095SDavid du Colombier # define PNG_HANDLE_CHUNK_IF_SAFE 2
793*593dc095SDavid du Colombier # endif
794*593dc095SDavid du Colombier png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE,
795*593dc095SDavid du Colombier png_bytep_NULL, 0);
796*593dc095SDavid du Colombier #endif
7977dd7cddfSDavid du Colombier
7987dd7cddfSDavid du Colombier png_debug(0, "Reading info struct\n");
7997dd7cddfSDavid du Colombier png_read_info(read_ptr, read_info_ptr);
8007dd7cddfSDavid du Colombier
8017dd7cddfSDavid du Colombier png_debug(0, "Transferring info struct\n");
8027dd7cddfSDavid du Colombier {
8037dd7cddfSDavid du Colombier int interlace_type, compression_type, filter_type;
8047dd7cddfSDavid du Colombier
8057dd7cddfSDavid du Colombier if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
8067dd7cddfSDavid du Colombier &color_type, &interlace_type, &compression_type, &filter_type))
8077dd7cddfSDavid du Colombier {
8087dd7cddfSDavid du Colombier png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
8097dd7cddfSDavid du Colombier #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
8107dd7cddfSDavid du Colombier color_type, interlace_type, compression_type, filter_type);
8117dd7cddfSDavid du Colombier #else
8127dd7cddfSDavid du Colombier color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
8137dd7cddfSDavid du Colombier #endif
8147dd7cddfSDavid du Colombier }
8157dd7cddfSDavid du Colombier }
816*593dc095SDavid du Colombier #if defined(PNG_FIXED_POINT_SUPPORTED)
817*593dc095SDavid du Colombier #if defined(PNG_cHRM_SUPPORTED)
8187dd7cddfSDavid du Colombier {
819*593dc095SDavid du Colombier png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
820*593dc095SDavid du Colombier blue_y;
821*593dc095SDavid du Colombier if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
822*593dc095SDavid du Colombier &red_y, &green_x, &green_y, &blue_x, &blue_y))
8237dd7cddfSDavid du Colombier {
824*593dc095SDavid du Colombier png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x,
825*593dc095SDavid du Colombier red_y, green_x, green_y, blue_x, blue_y);
8267dd7cddfSDavid du Colombier }
8277dd7cddfSDavid du Colombier }
8287dd7cddfSDavid du Colombier #endif
829*593dc095SDavid du Colombier #if defined(PNG_gAMA_SUPPORTED)
8307dd7cddfSDavid du Colombier {
831*593dc095SDavid du Colombier png_fixed_point gamma;
8327dd7cddfSDavid du Colombier
833*593dc095SDavid du Colombier if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma))
834*593dc095SDavid du Colombier {
835*593dc095SDavid du Colombier png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma);
836*593dc095SDavid du Colombier }
837*593dc095SDavid du Colombier }
838*593dc095SDavid du Colombier #endif
839*593dc095SDavid du Colombier #else /* Use floating point versions */
840*593dc095SDavid du Colombier #if defined(PNG_FLOATING_POINT_SUPPORTED)
841*593dc095SDavid du Colombier #if defined(PNG_cHRM_SUPPORTED)
842*593dc095SDavid du Colombier {
843*593dc095SDavid du Colombier double white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
844*593dc095SDavid du Colombier blue_y;
8457dd7cddfSDavid du Colombier if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
8467dd7cddfSDavid du Colombier &red_y, &green_x, &green_y, &blue_x, &blue_y))
8477dd7cddfSDavid du Colombier {
8487dd7cddfSDavid du Colombier png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
8497dd7cddfSDavid du Colombier red_y, green_x, green_y, blue_x, blue_y);
8507dd7cddfSDavid du Colombier }
8517dd7cddfSDavid du Colombier }
8527dd7cddfSDavid du Colombier #endif
853*593dc095SDavid du Colombier #if defined(PNG_gAMA_SUPPORTED)
8547dd7cddfSDavid du Colombier {
8557dd7cddfSDavid du Colombier double gamma;
8567dd7cddfSDavid du Colombier
8577dd7cddfSDavid du Colombier if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
8587dd7cddfSDavid du Colombier {
8597dd7cddfSDavid du Colombier png_set_gAMA(write_ptr, write_info_ptr, gamma);
8607dd7cddfSDavid du Colombier }
8617dd7cddfSDavid du Colombier }
8627dd7cddfSDavid du Colombier #endif
863*593dc095SDavid du Colombier #endif /* floating point */
864*593dc095SDavid du Colombier #endif /* fixed point */
865*593dc095SDavid du Colombier #if defined(PNG_iCCP_SUPPORTED)
866*593dc095SDavid du Colombier {
867*593dc095SDavid du Colombier png_charp name;
868*593dc095SDavid du Colombier png_charp profile;
869*593dc095SDavid du Colombier png_uint_32 proflen;
870*593dc095SDavid du Colombier int compression_type;
871*593dc095SDavid du Colombier
872*593dc095SDavid du Colombier if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,
873*593dc095SDavid du Colombier &profile, &proflen))
874*593dc095SDavid du Colombier {
875*593dc095SDavid du Colombier png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,
876*593dc095SDavid du Colombier profile, proflen);
877*593dc095SDavid du Colombier }
878*593dc095SDavid du Colombier }
879*593dc095SDavid du Colombier #endif
880*593dc095SDavid du Colombier #if defined(PNG_sRGB_SUPPORTED)
8817dd7cddfSDavid du Colombier {
8827dd7cddfSDavid du Colombier int intent;
8837dd7cddfSDavid du Colombier
8847dd7cddfSDavid du Colombier if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
8857dd7cddfSDavid du Colombier {
8867dd7cddfSDavid du Colombier png_set_sRGB(write_ptr, write_info_ptr, intent);
8877dd7cddfSDavid du Colombier }
8887dd7cddfSDavid du Colombier }
8897dd7cddfSDavid du Colombier #endif
890*593dc095SDavid du Colombier {
891*593dc095SDavid du Colombier png_colorp palette;
892*593dc095SDavid du Colombier int num_palette;
893*593dc095SDavid du Colombier
894*593dc095SDavid du Colombier if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
895*593dc095SDavid du Colombier {
896*593dc095SDavid du Colombier png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
897*593dc095SDavid du Colombier }
898*593dc095SDavid du Colombier }
899*593dc095SDavid du Colombier #if defined(PNG_bKGD_SUPPORTED)
900*593dc095SDavid du Colombier {
901*593dc095SDavid du Colombier png_color_16p background;
902*593dc095SDavid du Colombier
903*593dc095SDavid du Colombier if (png_get_bKGD(read_ptr, read_info_ptr, &background))
904*593dc095SDavid du Colombier {
905*593dc095SDavid du Colombier png_set_bKGD(write_ptr, write_info_ptr, background);
906*593dc095SDavid du Colombier }
907*593dc095SDavid du Colombier }
908*593dc095SDavid du Colombier #endif
909*593dc095SDavid du Colombier #if defined(PNG_hIST_SUPPORTED)
9107dd7cddfSDavid du Colombier {
9117dd7cddfSDavid du Colombier png_uint_16p hist;
9127dd7cddfSDavid du Colombier
9137dd7cddfSDavid du Colombier if (png_get_hIST(read_ptr, read_info_ptr, &hist))
9147dd7cddfSDavid du Colombier {
9157dd7cddfSDavid du Colombier png_set_hIST(write_ptr, write_info_ptr, hist);
9167dd7cddfSDavid du Colombier }
9177dd7cddfSDavid du Colombier }
9187dd7cddfSDavid du Colombier #endif
919*593dc095SDavid du Colombier #if defined(PNG_oFFs_SUPPORTED)
9207dd7cddfSDavid du Colombier {
921*593dc095SDavid du Colombier png_int_32 offset_x, offset_y;
9227dd7cddfSDavid du Colombier int unit_type;
9237dd7cddfSDavid du Colombier
9247dd7cddfSDavid du Colombier if (png_get_oFFs(read_ptr, read_info_ptr,&offset_x,&offset_y,&unit_type))
9257dd7cddfSDavid du Colombier {
9267dd7cddfSDavid du Colombier png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
9277dd7cddfSDavid du Colombier }
9287dd7cddfSDavid du Colombier }
9297dd7cddfSDavid du Colombier #endif
930*593dc095SDavid du Colombier #if defined(PNG_pCAL_SUPPORTED)
9317dd7cddfSDavid du Colombier {
9327dd7cddfSDavid du Colombier png_charp purpose, units;
9337dd7cddfSDavid du Colombier png_charpp params;
9347dd7cddfSDavid du Colombier png_int_32 X0, X1;
9357dd7cddfSDavid du Colombier int type, nparams;
9367dd7cddfSDavid du Colombier
9377dd7cddfSDavid du Colombier if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
9387dd7cddfSDavid du Colombier &nparams, &units, ¶ms))
9397dd7cddfSDavid du Colombier {
9407dd7cddfSDavid du Colombier png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
9417dd7cddfSDavid du Colombier nparams, units, params);
9427dd7cddfSDavid du Colombier }
9437dd7cddfSDavid du Colombier }
9447dd7cddfSDavid du Colombier #endif
945*593dc095SDavid du Colombier #if defined(PNG_pHYs_SUPPORTED)
9467dd7cddfSDavid du Colombier {
9477dd7cddfSDavid du Colombier png_uint_32 res_x, res_y;
9487dd7cddfSDavid du Colombier int unit_type;
9497dd7cddfSDavid du Colombier
9507dd7cddfSDavid du Colombier if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
9517dd7cddfSDavid du Colombier {
9527dd7cddfSDavid du Colombier png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
9537dd7cddfSDavid du Colombier }
9547dd7cddfSDavid du Colombier }
9557dd7cddfSDavid du Colombier #endif
956*593dc095SDavid du Colombier #if defined(PNG_sBIT_SUPPORTED)
9577dd7cddfSDavid du Colombier {
9587dd7cddfSDavid du Colombier png_color_8p sig_bit;
9597dd7cddfSDavid du Colombier
9607dd7cddfSDavid du Colombier if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
9617dd7cddfSDavid du Colombier {
9627dd7cddfSDavid du Colombier png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
9637dd7cddfSDavid du Colombier }
9647dd7cddfSDavid du Colombier }
9657dd7cddfSDavid du Colombier #endif
966*593dc095SDavid du Colombier #if defined(PNG_sCAL_SUPPORTED)
967*593dc095SDavid du Colombier #ifdef PNG_FLOATING_POINT_SUPPORTED
968*593dc095SDavid du Colombier {
969*593dc095SDavid du Colombier int unit;
970*593dc095SDavid du Colombier double scal_width, scal_height;
971*593dc095SDavid du Colombier
972*593dc095SDavid du Colombier if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,
973*593dc095SDavid du Colombier &scal_height))
974*593dc095SDavid du Colombier {
975*593dc095SDavid du Colombier png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);
976*593dc095SDavid du Colombier }
977*593dc095SDavid du Colombier }
978*593dc095SDavid du Colombier #else
979*593dc095SDavid du Colombier #ifdef PNG_FIXED_POINT_SUPPORTED
980*593dc095SDavid du Colombier {
981*593dc095SDavid du Colombier int unit;
982*593dc095SDavid du Colombier png_charp scal_width, scal_height;
983*593dc095SDavid du Colombier
984*593dc095SDavid du Colombier if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,
985*593dc095SDavid du Colombier &scal_height))
986*593dc095SDavid du Colombier {
987*593dc095SDavid du Colombier png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, scal_height);
988*593dc095SDavid du Colombier }
989*593dc095SDavid du Colombier }
990*593dc095SDavid du Colombier #endif
991*593dc095SDavid du Colombier #endif
992*593dc095SDavid du Colombier #endif
993*593dc095SDavid du Colombier #if defined(PNG_TEXT_SUPPORTED)
9947dd7cddfSDavid du Colombier {
9957dd7cddfSDavid du Colombier png_textp text_ptr;
9967dd7cddfSDavid du Colombier int num_text;
9977dd7cddfSDavid du Colombier
9987dd7cddfSDavid du Colombier if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
9997dd7cddfSDavid du Colombier {
1000*593dc095SDavid du Colombier png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text);
10017dd7cddfSDavid du Colombier png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
10027dd7cddfSDavid du Colombier }
10037dd7cddfSDavid du Colombier }
10047dd7cddfSDavid du Colombier #endif
1005*593dc095SDavid du Colombier #if defined(PNG_tIME_SUPPORTED)
10067dd7cddfSDavid du Colombier {
10077dd7cddfSDavid du Colombier png_timep mod_time;
10087dd7cddfSDavid du Colombier
10097dd7cddfSDavid du Colombier if (png_get_tIME(read_ptr, read_info_ptr, &mod_time))
10107dd7cddfSDavid du Colombier {
10117dd7cddfSDavid du Colombier png_set_tIME(write_ptr, write_info_ptr, mod_time);
1012*593dc095SDavid du Colombier #if defined(PNG_TIME_RFC1123_SUPPORTED)
1013*593dc095SDavid du Colombier /* we have to use png_strcpy instead of "=" because the string
1014*593dc095SDavid du Colombier pointed to by png_convert_to_rfc1123() gets free'ed before
1015*593dc095SDavid du Colombier we use it */
1016*593dc095SDavid du Colombier png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time));
1017*593dc095SDavid du Colombier tIME_chunk_present++;
1018*593dc095SDavid du Colombier #endif /* PNG_TIME_RFC1123_SUPPORTED */
10197dd7cddfSDavid du Colombier }
10207dd7cddfSDavid du Colombier }
10217dd7cddfSDavid du Colombier #endif
1022*593dc095SDavid du Colombier #if defined(PNG_tRNS_SUPPORTED)
10237dd7cddfSDavid du Colombier {
10247dd7cddfSDavid du Colombier png_bytep trans;
10257dd7cddfSDavid du Colombier int num_trans;
10267dd7cddfSDavid du Colombier png_color_16p trans_values;
10277dd7cddfSDavid du Colombier
10287dd7cddfSDavid du Colombier if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans,
10297dd7cddfSDavid du Colombier &trans_values))
10307dd7cddfSDavid du Colombier {
10317dd7cddfSDavid du Colombier png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans,
10327dd7cddfSDavid du Colombier trans_values);
10337dd7cddfSDavid du Colombier }
10347dd7cddfSDavid du Colombier }
10357dd7cddfSDavid du Colombier #endif
1036*593dc095SDavid du Colombier #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1037*593dc095SDavid du Colombier {
1038*593dc095SDavid du Colombier png_unknown_chunkp unknowns;
1039*593dc095SDavid du Colombier int num_unknowns = (int)png_get_unknown_chunks(read_ptr, read_info_ptr,
1040*593dc095SDavid du Colombier &unknowns);
1041*593dc095SDavid du Colombier if (num_unknowns)
1042*593dc095SDavid du Colombier {
1043*593dc095SDavid du Colombier png_size_t i;
1044*593dc095SDavid du Colombier png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns,
1045*593dc095SDavid du Colombier num_unknowns);
1046*593dc095SDavid du Colombier /* copy the locations from the read_info_ptr. The automatically
1047*593dc095SDavid du Colombier generated locations in write_info_ptr are wrong because we
1048*593dc095SDavid du Colombier haven't written anything yet */
1049*593dc095SDavid du Colombier for (i = 0; i < (png_size_t)num_unknowns; i++)
1050*593dc095SDavid du Colombier png_set_unknown_chunk_location(write_ptr, write_info_ptr, i,
1051*593dc095SDavid du Colombier unknowns[i].location);
1052*593dc095SDavid du Colombier }
1053*593dc095SDavid du Colombier }
1054*593dc095SDavid du Colombier #endif
10557dd7cddfSDavid du Colombier
1056*593dc095SDavid du Colombier #ifdef PNG_WRITE_SUPPORTED
10577dd7cddfSDavid du Colombier png_debug(0, "\nWriting info struct\n");
10587dd7cddfSDavid du Colombier
1059*593dc095SDavid du Colombier /* If we wanted, we could write info in two steps:
1060*593dc095SDavid du Colombier png_write_info_before_PLTE(write_ptr, write_info_ptr);
1061*593dc095SDavid du Colombier */
1062*593dc095SDavid du Colombier png_write_info(write_ptr, write_info_ptr);
1063*593dc095SDavid du Colombier #endif
1064*593dc095SDavid du Colombier
1065*593dc095SDavid du Colombier #ifdef SINGLE_ROWBUF_ALLOC
1066*593dc095SDavid du Colombier png_debug(0, "\nAllocating row buffer...");
10677dd7cddfSDavid du Colombier row_buf = (png_bytep)png_malloc(read_ptr,
10687dd7cddfSDavid du Colombier png_get_rowbytes(read_ptr, read_info_ptr));
1069*593dc095SDavid du Colombier png_debug1(0, "0x%08lx\n\n", (unsigned long)row_buf);
1070*593dc095SDavid du Colombier #endif /* SINGLE_ROWBUF_ALLOC */
10717dd7cddfSDavid du Colombier png_debug(0, "Writing row data\n");
10727dd7cddfSDavid du Colombier
1073*593dc095SDavid du Colombier #if defined(PNG_READ_INTERLACING_SUPPORTED) || \
1074*593dc095SDavid du Colombier defined(PNG_WRITE_INTERLACING_SUPPORTED)
10757dd7cddfSDavid du Colombier num_pass = png_set_interlace_handling(read_ptr);
1076*593dc095SDavid du Colombier # ifdef PNG_WRITE_SUPPORTED
10777dd7cddfSDavid du Colombier png_set_interlace_handling(write_ptr);
1078*593dc095SDavid du Colombier # endif
1079*593dc095SDavid du Colombier #else
1080*593dc095SDavid du Colombier num_pass=1;
1081*593dc095SDavid du Colombier #endif
10827dd7cddfSDavid du Colombier
1083*593dc095SDavid du Colombier #ifdef PNGTEST_TIMING
1084*593dc095SDavid du Colombier t_stop = (float)clock();
1085*593dc095SDavid du Colombier t_misc += (t_stop - t_start);
1086*593dc095SDavid du Colombier t_start = t_stop;
1087*593dc095SDavid du Colombier #endif
10887dd7cddfSDavid du Colombier for (pass = 0; pass < num_pass; pass++)
10897dd7cddfSDavid du Colombier {
10907dd7cddfSDavid du Colombier png_debug1(0, "Writing row data for pass %d\n",pass);
10917dd7cddfSDavid du Colombier for (y = 0; y < height; y++)
10927dd7cddfSDavid du Colombier {
1093*593dc095SDavid du Colombier #ifndef SINGLE_ROWBUF_ALLOC
1094*593dc095SDavid du Colombier png_debug2(0, "\nAllocating row buffer (pass %d, y = %ld)...", pass,y);
1095*593dc095SDavid du Colombier row_buf = (png_bytep)png_malloc(read_ptr,
1096*593dc095SDavid du Colombier png_get_rowbytes(read_ptr, read_info_ptr));
1097*593dc095SDavid du Colombier png_debug2(0, "0x%08lx (%ld bytes)\n", (unsigned long)row_buf,
1098*593dc095SDavid du Colombier png_get_rowbytes(read_ptr, read_info_ptr));
1099*593dc095SDavid du Colombier #endif /* !SINGLE_ROWBUF_ALLOC */
1100*593dc095SDavid du Colombier png_read_rows(read_ptr, (png_bytepp)&row_buf, png_bytepp_NULL, 1);
1101*593dc095SDavid du Colombier
1102*593dc095SDavid du Colombier #ifdef PNG_WRITE_SUPPORTED
1103*593dc095SDavid du Colombier #ifdef PNGTEST_TIMING
1104*593dc095SDavid du Colombier t_stop = (float)clock();
1105*593dc095SDavid du Colombier t_decode += (t_stop - t_start);
1106*593dc095SDavid du Colombier t_start = t_stop;
1107*593dc095SDavid du Colombier #endif
11087dd7cddfSDavid du Colombier png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
1109*593dc095SDavid du Colombier #ifdef PNGTEST_TIMING
1110*593dc095SDavid du Colombier t_stop = (float)clock();
1111*593dc095SDavid du Colombier t_encode += (t_stop - t_start);
1112*593dc095SDavid du Colombier t_start = t_stop;
1113*593dc095SDavid du Colombier #endif
1114*593dc095SDavid du Colombier #endif /* PNG_WRITE_SUPPORTED */
1115*593dc095SDavid du Colombier
1116*593dc095SDavid du Colombier #ifndef SINGLE_ROWBUF_ALLOC
1117*593dc095SDavid du Colombier png_debug2(0, "Freeing row buffer (pass %d, y = %ld)\n\n", pass, y);
1118*593dc095SDavid du Colombier png_free(read_ptr, row_buf);
1119*593dc095SDavid du Colombier #endif /* !SINGLE_ROWBUF_ALLOC */
11207dd7cddfSDavid du Colombier }
11217dd7cddfSDavid du Colombier }
11227dd7cddfSDavid du Colombier
1123*593dc095SDavid du Colombier #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
1124*593dc095SDavid du Colombier png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1);
1125*593dc095SDavid du Colombier #endif
1126*593dc095SDavid du Colombier #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1127*593dc095SDavid du Colombier png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1);
1128*593dc095SDavid du Colombier #endif
1129*593dc095SDavid du Colombier
11307dd7cddfSDavid du Colombier png_debug(0, "Reading and writing end_info data\n");
1131*593dc095SDavid du Colombier
11327dd7cddfSDavid du Colombier png_read_end(read_ptr, end_info_ptr);
1133*593dc095SDavid du Colombier #if defined(PNG_TEXT_SUPPORTED)
1134*593dc095SDavid du Colombier {
1135*593dc095SDavid du Colombier png_textp text_ptr;
1136*593dc095SDavid du Colombier int num_text;
1137*593dc095SDavid du Colombier
1138*593dc095SDavid du Colombier if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0)
1139*593dc095SDavid du Colombier {
1140*593dc095SDavid du Colombier png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text);
1141*593dc095SDavid du Colombier png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text);
1142*593dc095SDavid du Colombier }
1143*593dc095SDavid du Colombier }
1144*593dc095SDavid du Colombier #endif
1145*593dc095SDavid du Colombier #if defined(PNG_tIME_SUPPORTED)
1146*593dc095SDavid du Colombier {
1147*593dc095SDavid du Colombier png_timep mod_time;
1148*593dc095SDavid du Colombier
1149*593dc095SDavid du Colombier if (png_get_tIME(read_ptr, end_info_ptr, &mod_time))
1150*593dc095SDavid du Colombier {
1151*593dc095SDavid du Colombier png_set_tIME(write_ptr, write_end_info_ptr, mod_time);
1152*593dc095SDavid du Colombier #if defined(PNG_TIME_RFC1123_SUPPORTED)
1153*593dc095SDavid du Colombier /* we have to use png_strcpy instead of "=" because the string
1154*593dc095SDavid du Colombier pointed to by png_convert_to_rfc1123() gets free'ed before
1155*593dc095SDavid du Colombier we use it */
1156*593dc095SDavid du Colombier png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time));
1157*593dc095SDavid du Colombier tIME_chunk_present++;
1158*593dc095SDavid du Colombier #endif /* PNG_TIME_RFC1123_SUPPORTED */
1159*593dc095SDavid du Colombier }
1160*593dc095SDavid du Colombier }
1161*593dc095SDavid du Colombier #endif
1162*593dc095SDavid du Colombier #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1163*593dc095SDavid du Colombier {
1164*593dc095SDavid du Colombier png_unknown_chunkp unknowns;
1165*593dc095SDavid du Colombier int num_unknowns;
1166*593dc095SDavid du Colombier num_unknowns = (int)png_get_unknown_chunks(read_ptr, end_info_ptr,
1167*593dc095SDavid du Colombier &unknowns);
1168*593dc095SDavid du Colombier if (num_unknowns)
1169*593dc095SDavid du Colombier {
1170*593dc095SDavid du Colombier png_size_t i;
1171*593dc095SDavid du Colombier png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,
1172*593dc095SDavid du Colombier num_unknowns);
1173*593dc095SDavid du Colombier /* copy the locations from the read_info_ptr. The automatically
1174*593dc095SDavid du Colombier generated locations in write_end_info_ptr are wrong because we
1175*593dc095SDavid du Colombier haven't written the end_info yet */
1176*593dc095SDavid du Colombier for (i = 0; i < (png_size_t)num_unknowns; i++)
1177*593dc095SDavid du Colombier png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i,
1178*593dc095SDavid du Colombier unknowns[i].location);
1179*593dc095SDavid du Colombier }
1180*593dc095SDavid du Colombier }
1181*593dc095SDavid du Colombier #endif
1182*593dc095SDavid du Colombier #ifdef PNG_WRITE_SUPPORTED
1183*593dc095SDavid du Colombier png_write_end(write_ptr, write_end_info_ptr);
1184*593dc095SDavid du Colombier #endif
11857dd7cddfSDavid du Colombier
11867dd7cddfSDavid du Colombier #ifdef PNG_EASY_ACCESS_SUPPORTED
11877dd7cddfSDavid du Colombier if(verbose)
11887dd7cddfSDavid du Colombier {
11897dd7cddfSDavid du Colombier png_uint_32 iwidth, iheight;
11907dd7cddfSDavid du Colombier iwidth = png_get_image_width(write_ptr, write_info_ptr);
11917dd7cddfSDavid du Colombier iheight = png_get_image_height(write_ptr, write_info_ptr);
11927dd7cddfSDavid du Colombier fprintf(STDERR, "Image width = %lu, height = %lu\n",
11937dd7cddfSDavid du Colombier iwidth, iheight);
11947dd7cddfSDavid du Colombier }
11957dd7cddfSDavid du Colombier #endif
11967dd7cddfSDavid du Colombier
11977dd7cddfSDavid du Colombier png_debug(0, "Destroying data structs\n");
1198*593dc095SDavid du Colombier #ifdef SINGLE_ROWBUF_ALLOC
1199*593dc095SDavid du Colombier png_debug(1, "destroying row_buf for read_ptr\n");
12007dd7cddfSDavid du Colombier png_free(read_ptr, row_buf);
1201*593dc095SDavid du Colombier row_buf=NULL;
1202*593dc095SDavid du Colombier #endif /* SINGLE_ROWBUF_ALLOC */
1203*593dc095SDavid du Colombier png_debug(1, "destroying read_ptr, read_info_ptr, end_info_ptr\n");
12047dd7cddfSDavid du Colombier png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
1205*593dc095SDavid du Colombier #ifdef PNG_WRITE_SUPPORTED
1206*593dc095SDavid du Colombier png_debug(1, "destroying write_end_info_ptr\n");
1207*593dc095SDavid du Colombier png_destroy_info_struct(write_ptr, &write_end_info_ptr);
1208*593dc095SDavid du Colombier png_debug(1, "destroying write_ptr, write_info_ptr\n");
12097dd7cddfSDavid du Colombier png_destroy_write_struct(&write_ptr, &write_info_ptr);
1210*593dc095SDavid du Colombier #endif
1211*593dc095SDavid du Colombier png_debug(0, "Destruction complete.\n");
12127dd7cddfSDavid du Colombier
1213*593dc095SDavid du Colombier FCLOSE(fpin);
1214*593dc095SDavid du Colombier FCLOSE(fpout);
12157dd7cddfSDavid du Colombier
12167dd7cddfSDavid du Colombier png_debug(0, "Opening files for comparison\n");
1217*593dc095SDavid du Colombier #if defined(_WIN32_WCE)
1218*593dc095SDavid du Colombier MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH);
1219*593dc095SDavid du Colombier if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
1220*593dc095SDavid du Colombier #else
12217dd7cddfSDavid du Colombier if ((fpin = fopen(inname, "rb")) == NULL)
1222*593dc095SDavid du Colombier #endif
12237dd7cddfSDavid du Colombier {
12247dd7cddfSDavid du Colombier fprintf(STDERR, "Could not find file %s\n", inname);
12257dd7cddfSDavid du Colombier return (1);
12267dd7cddfSDavid du Colombier }
12277dd7cddfSDavid du Colombier
1228*593dc095SDavid du Colombier #if defined(_WIN32_WCE)
1229*593dc095SDavid du Colombier MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH);
1230*593dc095SDavid du Colombier if ((fpout = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
1231*593dc095SDavid du Colombier #else
12327dd7cddfSDavid du Colombier if ((fpout = fopen(outname, "rb")) == NULL)
1233*593dc095SDavid du Colombier #endif
12347dd7cddfSDavid du Colombier {
12357dd7cddfSDavid du Colombier fprintf(STDERR, "Could not find file %s\n", outname);
1236*593dc095SDavid du Colombier FCLOSE(fpin);
12377dd7cddfSDavid du Colombier return (1);
12387dd7cddfSDavid du Colombier }
12397dd7cddfSDavid du Colombier
1240*593dc095SDavid du Colombier for(;;)
12417dd7cddfSDavid du Colombier {
12427dd7cddfSDavid du Colombier png_size_t num_in, num_out;
12437dd7cddfSDavid du Colombier
1244*593dc095SDavid du Colombier READFILE(fpin, inbuf, 1, num_in);
1245*593dc095SDavid du Colombier READFILE(fpout, outbuf, 1, num_out);
12467dd7cddfSDavid du Colombier
12477dd7cddfSDavid du Colombier if (num_in != num_out)
12487dd7cddfSDavid du Colombier {
1249*593dc095SDavid du Colombier fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
12507dd7cddfSDavid du Colombier inname, outname);
1251*593dc095SDavid du Colombier if(wrote_question == 0)
1252*593dc095SDavid du Colombier {
1253*593dc095SDavid du Colombier fprintf(STDERR,
1254*593dc095SDavid du Colombier " Was %s written with the same maximum IDAT chunk size (%d bytes),",
1255*593dc095SDavid du Colombier inname,PNG_ZBUF_SIZE);
1256*593dc095SDavid du Colombier fprintf(STDERR,
1257*593dc095SDavid du Colombier "\n filtering heuristic (libpng default), compression");
1258*593dc095SDavid du Colombier fprintf(STDERR,
1259*593dc095SDavid du Colombier " level (zlib default),\n and zlib version (%s)?\n\n",
1260*593dc095SDavid du Colombier ZLIB_VERSION);
1261*593dc095SDavid du Colombier wrote_question=1;
1262*593dc095SDavid du Colombier }
1263*593dc095SDavid du Colombier FCLOSE(fpin);
1264*593dc095SDavid du Colombier FCLOSE(fpout);
1265*593dc095SDavid du Colombier return (0);
12667dd7cddfSDavid du Colombier }
12677dd7cddfSDavid du Colombier
12687dd7cddfSDavid du Colombier if (!num_in)
12697dd7cddfSDavid du Colombier break;
12707dd7cddfSDavid du Colombier
12717dd7cddfSDavid du Colombier if (png_memcmp(inbuf, outbuf, num_in))
12727dd7cddfSDavid du Colombier {
1273*593dc095SDavid du Colombier fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname);
1274*593dc095SDavid du Colombier if(wrote_question == 0)
1275*593dc095SDavid du Colombier {
1276*593dc095SDavid du Colombier fprintf(STDERR,
1277*593dc095SDavid du Colombier " Was %s written with the same maximum IDAT chunk size (%d bytes),",
1278*593dc095SDavid du Colombier inname,PNG_ZBUF_SIZE);
1279*593dc095SDavid du Colombier fprintf(STDERR,
1280*593dc095SDavid du Colombier "\n filtering heuristic (libpng default), compression");
1281*593dc095SDavid du Colombier fprintf(STDERR,
1282*593dc095SDavid du Colombier " level (zlib default),\n and zlib version (%s)?\n\n",
1283*593dc095SDavid du Colombier ZLIB_VERSION);
1284*593dc095SDavid du Colombier wrote_question=1;
1285*593dc095SDavid du Colombier }
1286*593dc095SDavid du Colombier FCLOSE(fpin);
1287*593dc095SDavid du Colombier FCLOSE(fpout);
1288*593dc095SDavid du Colombier return (0);
12897dd7cddfSDavid du Colombier }
12907dd7cddfSDavid du Colombier }
12917dd7cddfSDavid du Colombier
1292*593dc095SDavid du Colombier FCLOSE(fpin);
1293*593dc095SDavid du Colombier FCLOSE(fpout);
12947dd7cddfSDavid du Colombier
12957dd7cddfSDavid du Colombier return (0);
12967dd7cddfSDavid du Colombier }
12977dd7cddfSDavid du Colombier
12987dd7cddfSDavid du Colombier /* input and output filenames */
12997dd7cddfSDavid du Colombier #ifdef RISCOS
1300*593dc095SDavid du Colombier static PNG_CONST char *inname = "pngtest/png";
1301*593dc095SDavid du Colombier static PNG_CONST char *outname = "pngout/png";
13027dd7cddfSDavid du Colombier #else
1303*593dc095SDavid du Colombier static PNG_CONST char *inname = "pngtest.png";
1304*593dc095SDavid du Colombier static PNG_CONST char *outname = "pngout.png";
13057dd7cddfSDavid du Colombier #endif
13067dd7cddfSDavid du Colombier
13077dd7cddfSDavid du Colombier int
main(int argc,char * argv[])13087dd7cddfSDavid du Colombier main(int argc, char *argv[])
13097dd7cddfSDavid du Colombier {
13107dd7cddfSDavid du Colombier int multiple = 0;
13117dd7cddfSDavid du Colombier int ierror = 0;
13127dd7cddfSDavid du Colombier
13137dd7cddfSDavid du Colombier fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
13147dd7cddfSDavid du Colombier fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION);
1315*593dc095SDavid du Colombier fprintf(STDERR,"%s",png_get_copyright(NULL));
1316*593dc095SDavid du Colombier /* Show the version of libpng used in building the library */
1317*593dc095SDavid du Colombier fprintf(STDERR," library (%lu):%s", png_access_version_number(),
1318*593dc095SDavid du Colombier png_get_header_version(NULL));
1319*593dc095SDavid du Colombier /* Show the version of libpng used in building the application */
1320*593dc095SDavid du Colombier fprintf(STDERR," pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER,
1321*593dc095SDavid du Colombier PNG_HEADER_VERSION_STRING);
1322*593dc095SDavid du Colombier fprintf(STDERR," png_sizeof(png_struct)=%ld, png_sizeof(png_info)=%ld\n",
1323*593dc095SDavid du Colombier (long)png_sizeof(png_struct), (long)png_sizeof(png_info));
13247dd7cddfSDavid du Colombier
13257dd7cddfSDavid du Colombier /* Do some consistency checking on the memory allocation settings, I'm
13267dd7cddfSDavid du Colombier not sure this matters, but it is nice to know, the first of these
13277dd7cddfSDavid du Colombier tests should be impossible because of the way the macros are set
13287dd7cddfSDavid du Colombier in pngconf.h */
13297dd7cddfSDavid du Colombier #if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
13307dd7cddfSDavid du Colombier fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n");
13317dd7cddfSDavid du Colombier #endif
13327dd7cddfSDavid du Colombier /* I think the following can happen. */
13337dd7cddfSDavid du Colombier #if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
13347dd7cddfSDavid du Colombier fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n");
13357dd7cddfSDavid du Colombier #endif
13367dd7cddfSDavid du Colombier
13377dd7cddfSDavid du Colombier if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
13387dd7cddfSDavid du Colombier {
13397dd7cddfSDavid du Colombier fprintf(STDERR,
13407dd7cddfSDavid du Colombier "Warning: versions are different between png.h and png.c\n");
13417dd7cddfSDavid du Colombier fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING);
13427dd7cddfSDavid du Colombier fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver);
13437dd7cddfSDavid du Colombier ++ierror;
13447dd7cddfSDavid du Colombier }
13457dd7cddfSDavid du Colombier
13467dd7cddfSDavid du Colombier if (argc > 1)
13477dd7cddfSDavid du Colombier {
13487dd7cddfSDavid du Colombier if (strcmp(argv[1], "-m") == 0)
1349*593dc095SDavid du Colombier {
13507dd7cddfSDavid du Colombier multiple = 1;
1351*593dc095SDavid du Colombier status_dots_requested = 0;
1352*593dc095SDavid du Colombier }
13537dd7cddfSDavid du Colombier else if (strcmp(argv[1], "-mv") == 0 ||
13547dd7cddfSDavid du Colombier strcmp(argv[1], "-vm") == 0 )
13557dd7cddfSDavid du Colombier {
13567dd7cddfSDavid du Colombier multiple = 1;
13577dd7cddfSDavid du Colombier verbose = 1;
1358*593dc095SDavid du Colombier status_dots_requested = 1;
13597dd7cddfSDavid du Colombier }
13607dd7cddfSDavid du Colombier else if (strcmp(argv[1], "-v") == 0)
13617dd7cddfSDavid du Colombier {
13627dd7cddfSDavid du Colombier verbose = 1;
1363*593dc095SDavid du Colombier status_dots_requested = 1;
13647dd7cddfSDavid du Colombier inname = argv[2];
13657dd7cddfSDavid du Colombier }
13667dd7cddfSDavid du Colombier else
1367*593dc095SDavid du Colombier {
13687dd7cddfSDavid du Colombier inname = argv[1];
1369*593dc095SDavid du Colombier status_dots_requested = 0;
1370*593dc095SDavid du Colombier }
13717dd7cddfSDavid du Colombier }
13727dd7cddfSDavid du Colombier
13737dd7cddfSDavid du Colombier if (!multiple && argc == 3+verbose)
13747dd7cddfSDavid du Colombier outname = argv[2+verbose];
13757dd7cddfSDavid du Colombier
13767dd7cddfSDavid du Colombier if ((!multiple && argc > 3+verbose) || (multiple && argc < 2))
13777dd7cddfSDavid du Colombier {
13787dd7cddfSDavid du Colombier fprintf(STDERR,
13797dd7cddfSDavid du Colombier "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
13807dd7cddfSDavid du Colombier argv[0], argv[0]);
13817dd7cddfSDavid du Colombier fprintf(STDERR,
13827dd7cddfSDavid du Colombier " reads/writes one PNG file (without -m) or multiple files (-m)\n");
13837dd7cddfSDavid du Colombier fprintf(STDERR,
13847dd7cddfSDavid du Colombier " with -m %s is used as a temporary file\n", outname);
13857dd7cddfSDavid du Colombier exit(1);
13867dd7cddfSDavid du Colombier }
13877dd7cddfSDavid du Colombier
13887dd7cddfSDavid du Colombier if (multiple)
13897dd7cddfSDavid du Colombier {
13907dd7cddfSDavid du Colombier int i;
1391*593dc095SDavid du Colombier #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
13927dd7cddfSDavid du Colombier int allocation_now = current_allocation;
13937dd7cddfSDavid du Colombier #endif
13947dd7cddfSDavid du Colombier for (i=2; i<argc; ++i)
13957dd7cddfSDavid du Colombier {
1396*593dc095SDavid du Colombier #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1397*593dc095SDavid du Colombier int k;
1398*593dc095SDavid du Colombier #endif
13997dd7cddfSDavid du Colombier int kerror;
14007dd7cddfSDavid du Colombier fprintf(STDERR, "Testing %s:",argv[i]);
14017dd7cddfSDavid du Colombier kerror = test_one_file(argv[i], outname);
14027dd7cddfSDavid du Colombier if (kerror == 0)
1403*593dc095SDavid du Colombier {
1404*593dc095SDavid du Colombier #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
1405*593dc095SDavid du Colombier fprintf(STDERR, "\n PASS (%lu zero samples)\n",zero_samples);
1406*593dc095SDavid du Colombier #else
14077dd7cddfSDavid du Colombier fprintf(STDERR, " PASS\n");
1408*593dc095SDavid du Colombier #endif
1409*593dc095SDavid du Colombier #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1410*593dc095SDavid du Colombier for (k=0; k<256; k++)
1411*593dc095SDavid du Colombier if(filters_used[k])
1412*593dc095SDavid du Colombier fprintf(STDERR, " Filter %d was used %lu times\n",
1413*593dc095SDavid du Colombier k,filters_used[k]);
1414*593dc095SDavid du Colombier #endif
1415*593dc095SDavid du Colombier #if defined(PNG_TIME_RFC1123_SUPPORTED)
1416*593dc095SDavid du Colombier if(tIME_chunk_present != 0)
1417*593dc095SDavid du Colombier fprintf(STDERR, " tIME = %s\n",tIME_string);
1418*593dc095SDavid du Colombier tIME_chunk_present = 0;
1419*593dc095SDavid du Colombier #endif /* PNG_TIME_RFC1123_SUPPORTED */
1420*593dc095SDavid du Colombier }
1421*593dc095SDavid du Colombier else
1422*593dc095SDavid du Colombier {
14237dd7cddfSDavid du Colombier fprintf(STDERR, " FAIL\n");
14247dd7cddfSDavid du Colombier ierror += kerror;
14257dd7cddfSDavid du Colombier }
1426*593dc095SDavid du Colombier #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
14277dd7cddfSDavid du Colombier if (allocation_now != current_allocation)
14287dd7cddfSDavid du Colombier fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
14297dd7cddfSDavid du Colombier current_allocation-allocation_now);
1430*593dc095SDavid du Colombier if (current_allocation != 0)
1431*593dc095SDavid du Colombier {
14327dd7cddfSDavid du Colombier memory_infop pinfo = pinformation;
14337dd7cddfSDavid du Colombier
14347dd7cddfSDavid du Colombier fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
14357dd7cddfSDavid du Colombier current_allocation);
1436*593dc095SDavid du Colombier while (pinfo != NULL)
1437*593dc095SDavid du Colombier {
1438*593dc095SDavid du Colombier fprintf(STDERR, " %lu bytes at %x\n", pinfo->size,
1439*593dc095SDavid du Colombier (unsigned int) pinfo->pointer);
14407dd7cddfSDavid du Colombier pinfo = pinfo->next;
14417dd7cddfSDavid du Colombier }
14427dd7cddfSDavid du Colombier }
14437dd7cddfSDavid du Colombier #endif
14447dd7cddfSDavid du Colombier }
1445*593dc095SDavid du Colombier #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1446*593dc095SDavid du Colombier fprintf(STDERR, " Current memory allocation: %10d bytes\n",
1447*593dc095SDavid du Colombier current_allocation);
1448*593dc095SDavid du Colombier fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
14497dd7cddfSDavid du Colombier maximum_allocation);
1450*593dc095SDavid du Colombier fprintf(STDERR, " Total memory allocation: %10d bytes\n",
1451*593dc095SDavid du Colombier total_allocation);
1452*593dc095SDavid du Colombier fprintf(STDERR, " Number of allocations: %10d\n",
1453*593dc095SDavid du Colombier num_allocations);
14547dd7cddfSDavid du Colombier #endif
14557dd7cddfSDavid du Colombier }
14567dd7cddfSDavid du Colombier else
14577dd7cddfSDavid du Colombier {
14587dd7cddfSDavid du Colombier int i;
1459*593dc095SDavid du Colombier for (i=0; i<3; ++i)
1460*593dc095SDavid du Colombier {
14617dd7cddfSDavid du Colombier int kerror;
1462*593dc095SDavid du Colombier #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
14637dd7cddfSDavid du Colombier int allocation_now = current_allocation;
14647dd7cddfSDavid du Colombier #endif
1465*593dc095SDavid du Colombier if (i == 1) status_dots_requested = 1;
1466*593dc095SDavid du Colombier else if(verbose == 0)status_dots_requested = 0;
14677dd7cddfSDavid du Colombier if (i == 0 || verbose == 1 || ierror != 0)
14687dd7cddfSDavid du Colombier fprintf(STDERR, "Testing %s:",inname);
14697dd7cddfSDavid du Colombier kerror = test_one_file(inname, outname);
14707dd7cddfSDavid du Colombier if(kerror == 0)
14717dd7cddfSDavid du Colombier {
1472*593dc095SDavid du Colombier if(verbose == 1 || i == 2)
1473*593dc095SDavid du Colombier {
1474*593dc095SDavid du Colombier #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1475*593dc095SDavid du Colombier int k;
1476*593dc095SDavid du Colombier #endif
1477*593dc095SDavid du Colombier #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
1478*593dc095SDavid du Colombier fprintf(STDERR, "\n PASS (%lu zero samples)\n",zero_samples);
1479*593dc095SDavid du Colombier #else
1480*593dc095SDavid du Colombier fprintf(STDERR, " PASS\n");
1481*593dc095SDavid du Colombier #endif
1482*593dc095SDavid du Colombier #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1483*593dc095SDavid du Colombier for (k=0; k<256; k++)
1484*593dc095SDavid du Colombier if(filters_used[k])
1485*593dc095SDavid du Colombier fprintf(STDERR, " Filter %d was used %lu times\n",
1486*593dc095SDavid du Colombier k,filters_used[k]);
1487*593dc095SDavid du Colombier #endif
1488*593dc095SDavid du Colombier #if defined(PNG_TIME_RFC1123_SUPPORTED)
1489*593dc095SDavid du Colombier if(tIME_chunk_present != 0)
1490*593dc095SDavid du Colombier fprintf(STDERR, " tIME = %s\n",tIME_string);
1491*593dc095SDavid du Colombier #endif /* PNG_TIME_RFC1123_SUPPORTED */
1492*593dc095SDavid du Colombier }
14937dd7cddfSDavid du Colombier }
14947dd7cddfSDavid du Colombier else
14957dd7cddfSDavid du Colombier {
14967dd7cddfSDavid du Colombier if(verbose == 0 && i != 2)
14977dd7cddfSDavid du Colombier fprintf(STDERR, "Testing %s:",inname);
14987dd7cddfSDavid du Colombier fprintf(STDERR, " FAIL\n");
14997dd7cddfSDavid du Colombier ierror += kerror;
15007dd7cddfSDavid du Colombier }
1501*593dc095SDavid du Colombier #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
15027dd7cddfSDavid du Colombier if (allocation_now != current_allocation)
15037dd7cddfSDavid du Colombier fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
15047dd7cddfSDavid du Colombier current_allocation-allocation_now);
1505*593dc095SDavid du Colombier if (current_allocation != 0)
1506*593dc095SDavid du Colombier {
15077dd7cddfSDavid du Colombier memory_infop pinfo = pinformation;
15087dd7cddfSDavid du Colombier
15097dd7cddfSDavid du Colombier fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
15107dd7cddfSDavid du Colombier current_allocation);
1511*593dc095SDavid du Colombier while (pinfo != NULL)
1512*593dc095SDavid du Colombier {
1513*593dc095SDavid du Colombier fprintf(STDERR," %lu bytes at %x\n",
1514*593dc095SDavid du Colombier pinfo->size, (unsigned int)pinfo->pointer);
15157dd7cddfSDavid du Colombier pinfo = pinfo->next;
15167dd7cddfSDavid du Colombier }
15177dd7cddfSDavid du Colombier }
15187dd7cddfSDavid du Colombier #endif
15197dd7cddfSDavid du Colombier }
1520*593dc095SDavid du Colombier #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1521*593dc095SDavid du Colombier fprintf(STDERR, " Current memory allocation: %10d bytes\n",
1522*593dc095SDavid du Colombier current_allocation);
1523*593dc095SDavid du Colombier fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
15247dd7cddfSDavid du Colombier maximum_allocation);
1525*593dc095SDavid du Colombier fprintf(STDERR, " Total memory allocation: %10d bytes\n",
1526*593dc095SDavid du Colombier total_allocation);
1527*593dc095SDavid du Colombier fprintf(STDERR, " Number of allocations: %10d\n",
1528*593dc095SDavid du Colombier num_allocations);
15297dd7cddfSDavid du Colombier #endif
15307dd7cddfSDavid du Colombier }
15317dd7cddfSDavid du Colombier
1532*593dc095SDavid du Colombier #ifdef PNGTEST_TIMING
1533*593dc095SDavid du Colombier t_stop = (float)clock();
1534*593dc095SDavid du Colombier t_misc += (t_stop - t_start);
1535*593dc095SDavid du Colombier t_start = t_stop;
1536*593dc095SDavid du Colombier fprintf(STDERR," CPU time used = %.3f seconds",
1537*593dc095SDavid du Colombier (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
1538*593dc095SDavid du Colombier fprintf(STDERR," (decoding %.3f,\n",
1539*593dc095SDavid du Colombier t_decode/(float)CLOCKS_PER_SEC);
1540*593dc095SDavid du Colombier fprintf(STDERR," encoding %.3f ,",
1541*593dc095SDavid du Colombier t_encode/(float)CLOCKS_PER_SEC);
1542*593dc095SDavid du Colombier fprintf(STDERR," other %.3f seconds)\n\n",
1543*593dc095SDavid du Colombier t_misc/(float)CLOCKS_PER_SEC);
1544*593dc095SDavid du Colombier #endif
1545*593dc095SDavid du Colombier
15467dd7cddfSDavid du Colombier if (ierror == 0)
15477dd7cddfSDavid du Colombier fprintf(STDERR, "libpng passes test\n");
15487dd7cddfSDavid du Colombier else
15497dd7cddfSDavid du Colombier fprintf(STDERR, "libpng FAILS test\n");
15507dd7cddfSDavid du Colombier return (int)(ierror != 0);
15517dd7cddfSDavid du Colombier }
1552*593dc095SDavid du Colombier
1553*593dc095SDavid du Colombier /* Generate a compiler error if there is an old png.h in the search path. */
1554*593dc095SDavid du Colombier typedef version_1_2_8 your_png_h_is_not_version_1_2_8;
1555