1*a67afe4dSAndroid Build Coastguard Worker
2*a67afe4dSAndroid Build Coastguard Worker /* pngtest.c - a test program for libpng
3*a67afe4dSAndroid Build Coastguard Worker *
4*a67afe4dSAndroid Build Coastguard Worker * Copyright (c) 2018-2024 Cosmin Truta
5*a67afe4dSAndroid Build Coastguard Worker * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
6*a67afe4dSAndroid Build Coastguard Worker * Copyright (c) 1996-1997 Andreas Dilger
7*a67afe4dSAndroid Build Coastguard Worker * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
8*a67afe4dSAndroid Build Coastguard Worker *
9*a67afe4dSAndroid Build Coastguard Worker * This code is released under the libpng license.
10*a67afe4dSAndroid Build Coastguard Worker * For conditions of distribution and use, see the disclaimer
11*a67afe4dSAndroid Build Coastguard Worker * and license in png.h
12*a67afe4dSAndroid Build Coastguard Worker *
13*a67afe4dSAndroid Build Coastguard Worker * This program reads in a PNG image, writes it out again, and then
14*a67afe4dSAndroid Build Coastguard Worker * compares the two files. If the files are identical, this shows that
15*a67afe4dSAndroid Build Coastguard Worker * the basic chunk handling, filtering, and (de)compression code is working
16*a67afe4dSAndroid Build Coastguard Worker * properly. It does not currently test all of the transforms, although
17*a67afe4dSAndroid Build Coastguard Worker * it probably should.
18*a67afe4dSAndroid Build Coastguard Worker *
19*a67afe4dSAndroid Build Coastguard Worker * The program will report "FAIL" in certain legitimate cases:
20*a67afe4dSAndroid Build Coastguard Worker * 1) when the compression level or filter selection method is changed.
21*a67afe4dSAndroid Build Coastguard Worker * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192.
22*a67afe4dSAndroid Build Coastguard Worker * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks
23*a67afe4dSAndroid Build Coastguard Worker * exist in the input file.
24*a67afe4dSAndroid Build Coastguard Worker * 4) others not listed here...
25*a67afe4dSAndroid Build Coastguard Worker * In these cases, it is best to check with another tool such as "pngcheck"
26*a67afe4dSAndroid Build Coastguard Worker * to see what the differences between the two files are.
27*a67afe4dSAndroid Build Coastguard Worker *
28*a67afe4dSAndroid Build Coastguard Worker * If a filename is given on the command-line, then this file is used
29*a67afe4dSAndroid Build Coastguard Worker * for the input, rather than the default "pngtest.png". This allows
30*a67afe4dSAndroid Build Coastguard Worker * testing a wide variety of files easily. You can also test a number
31*a67afe4dSAndroid Build Coastguard Worker * of files at once by typing "pngtest -m file1.png file2.png ..."
32*a67afe4dSAndroid Build Coastguard Worker */
33*a67afe4dSAndroid Build Coastguard Worker
34*a67afe4dSAndroid Build Coastguard Worker #define _POSIX_SOURCE 1
35*a67afe4dSAndroid Build Coastguard Worker
36*a67afe4dSAndroid Build Coastguard Worker #include <stdio.h>
37*a67afe4dSAndroid Build Coastguard Worker #include <stdlib.h>
38*a67afe4dSAndroid Build Coastguard Worker #include <string.h>
39*a67afe4dSAndroid Build Coastguard Worker
40*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_ZLIB_HEADER
41*a67afe4dSAndroid Build Coastguard Worker # include PNG_ZLIB_HEADER /* defined by pnglibconf.h from 1.7 */
42*a67afe4dSAndroid Build Coastguard Worker #else
43*a67afe4dSAndroid Build Coastguard Worker # include <zlib.h>
44*a67afe4dSAndroid Build Coastguard Worker #endif
45*a67afe4dSAndroid Build Coastguard Worker
46*a67afe4dSAndroid Build Coastguard Worker #include "png.h"
47*a67afe4dSAndroid Build Coastguard Worker
48*a67afe4dSAndroid Build Coastguard Worker /* This hack was introduced for historical reasons, and we are
49*a67afe4dSAndroid Build Coastguard Worker * still keeping it in libpng-1.6.x for compatibility reasons.
50*a67afe4dSAndroid Build Coastguard Worker */
51*a67afe4dSAndroid Build Coastguard Worker #define STDERR stdout
52*a67afe4dSAndroid Build Coastguard Worker
53*a67afe4dSAndroid Build Coastguard Worker /* Generate a compiler error if there is an old png.h in the search path. */
54*a67afe4dSAndroid Build Coastguard Worker typedef png_libpng_version_1_6_44 Your_png_h_is_not_version_1_6_44;
55*a67afe4dSAndroid Build Coastguard Worker
56*a67afe4dSAndroid Build Coastguard Worker /* Ensure that all version numbers in png.h are consistent with one another. */
57*a67afe4dSAndroid Build Coastguard Worker #if (PNG_LIBPNG_VER != PNG_LIBPNG_VER_MAJOR * 10000 + \
58*a67afe4dSAndroid Build Coastguard Worker PNG_LIBPNG_VER_MINOR * 100 + \
59*a67afe4dSAndroid Build Coastguard Worker PNG_LIBPNG_VER_RELEASE) || \
60*a67afe4dSAndroid Build Coastguard Worker (PNG_LIBPNG_VER_SHAREDLIB != PNG_LIBPNG_VER_MAJOR * 10 + \
61*a67afe4dSAndroid Build Coastguard Worker PNG_LIBPNG_VER_MINOR) || \
62*a67afe4dSAndroid Build Coastguard Worker (PNG_LIBPNG_VER_SHAREDLIB != PNG_LIBPNG_VER_SONUM) || \
63*a67afe4dSAndroid Build Coastguard Worker (PNG_LIBPNG_VER_SHAREDLIB != PNG_LIBPNG_VER_DLLNUM)
64*a67afe4dSAndroid Build Coastguard Worker # error "Inconsistent version numbers in png.h"
65*a67afe4dSAndroid Build Coastguard Worker #endif
66*a67afe4dSAndroid Build Coastguard Worker
67*a67afe4dSAndroid Build Coastguard Worker /* In version 1.6.1, we added support for the configure test harness, which
68*a67afe4dSAndroid Build Coastguard Worker * uses 77 to indicate a skipped test. On the other hand, in cmake build tests,
69*a67afe4dSAndroid Build Coastguard Worker * we still need to succeed on a skipped test, so:
70*a67afe4dSAndroid Build Coastguard Worker */
71*a67afe4dSAndroid Build Coastguard Worker #if defined(HAVE_CONFIG_H)
72*a67afe4dSAndroid Build Coastguard Worker # define SKIP 77
73*a67afe4dSAndroid Build Coastguard Worker #else
74*a67afe4dSAndroid Build Coastguard Worker # define SKIP 0
75*a67afe4dSAndroid Build Coastguard Worker #endif
76*a67afe4dSAndroid Build Coastguard Worker
77*a67afe4dSAndroid Build Coastguard Worker /* Known chunks that exist in pngtest.png must be supported, or pngtest will
78*a67afe4dSAndroid Build Coastguard Worker * fail simply as a result of re-ordering them. This may be fixed in the next
79*a67afe4dSAndroid Build Coastguard Worker * generation of libpng.
80*a67afe4dSAndroid Build Coastguard Worker *
81*a67afe4dSAndroid Build Coastguard Worker * pngtest allocates a single row buffer for each row and overwrites it,
82*a67afe4dSAndroid Build Coastguard Worker * therefore if the write side doesn't support the writing of interlaced images
83*a67afe4dSAndroid Build Coastguard Worker * nothing can be done for an interlaced image (and the code below will fail
84*a67afe4dSAndroid Build Coastguard Worker * horribly trying to write extra data after writing garbage).
85*a67afe4dSAndroid Build Coastguard Worker */
86*a67afe4dSAndroid Build Coastguard Worker #if defined PNG_READ_SUPPORTED && /* else nothing can be done */ \
87*a67afe4dSAndroid Build Coastguard Worker defined PNG_READ_bKGD_SUPPORTED && \
88*a67afe4dSAndroid Build Coastguard Worker defined PNG_READ_cHRM_SUPPORTED && \
89*a67afe4dSAndroid Build Coastguard Worker defined PNG_READ_gAMA_SUPPORTED && \
90*a67afe4dSAndroid Build Coastguard Worker defined PNG_READ_oFFs_SUPPORTED && \
91*a67afe4dSAndroid Build Coastguard Worker defined PNG_READ_pCAL_SUPPORTED && \
92*a67afe4dSAndroid Build Coastguard Worker defined PNG_READ_pHYs_SUPPORTED && \
93*a67afe4dSAndroid Build Coastguard Worker defined PNG_READ_sBIT_SUPPORTED && \
94*a67afe4dSAndroid Build Coastguard Worker defined PNG_READ_sCAL_SUPPORTED && \
95*a67afe4dSAndroid Build Coastguard Worker defined PNG_READ_sRGB_SUPPORTED && \
96*a67afe4dSAndroid Build Coastguard Worker defined PNG_READ_sPLT_SUPPORTED && \
97*a67afe4dSAndroid Build Coastguard Worker defined PNG_READ_tEXt_SUPPORTED && \
98*a67afe4dSAndroid Build Coastguard Worker defined PNG_READ_tIME_SUPPORTED && \
99*a67afe4dSAndroid Build Coastguard Worker defined PNG_READ_zTXt_SUPPORTED && \
100*a67afe4dSAndroid Build Coastguard Worker (defined PNG_WRITE_INTERLACING_SUPPORTED || PNG_LIBPNG_VER >= 10700)
101*a67afe4dSAndroid Build Coastguard Worker
102*a67afe4dSAndroid Build Coastguard Worker /* Copied from pngpriv.h but only used in error messages below. */
103*a67afe4dSAndroid Build Coastguard Worker #ifndef PNG_ZBUF_SIZE
104*a67afe4dSAndroid Build Coastguard Worker # define PNG_ZBUF_SIZE 8192
105*a67afe4dSAndroid Build Coastguard Worker #endif
106*a67afe4dSAndroid Build Coastguard Worker
107*a67afe4dSAndroid Build Coastguard Worker #ifndef PNG_STDIO_SUPPORTED
108*a67afe4dSAndroid Build Coastguard Worker typedef FILE * png_FILE_p;
109*a67afe4dSAndroid Build Coastguard Worker #endif
110*a67afe4dSAndroid Build Coastguard Worker
111*a67afe4dSAndroid Build Coastguard Worker #ifndef PNG_DEBUG
112*a67afe4dSAndroid Build Coastguard Worker # define PNG_DEBUG 0
113*a67afe4dSAndroid Build Coastguard Worker #endif
114*a67afe4dSAndroid Build Coastguard Worker
115*a67afe4dSAndroid Build Coastguard Worker #if PNG_DEBUG > 1
116*a67afe4dSAndroid Build Coastguard Worker # define pngtest_debug(m) ((void)fprintf(stderr, m "\n"))
117*a67afe4dSAndroid Build Coastguard Worker # define pngtest_debug1(m, p1) ((void)fprintf(stderr, m "\n", p1))
118*a67afe4dSAndroid Build Coastguard Worker # define pngtest_debug2(m, p1, p2) ((void)fprintf(stderr, m "\n", p1, p2))
119*a67afe4dSAndroid Build Coastguard Worker #elif PNG_DEBUG == 0 || PNG_DEBUG == 1
120*a67afe4dSAndroid Build Coastguard Worker # define pngtest_debug(m) ((void)0)
121*a67afe4dSAndroid Build Coastguard Worker # define pngtest_debug1(m, p1) ((void)0)
122*a67afe4dSAndroid Build Coastguard Worker # define pngtest_debug2(m, p1, p2) ((void)0)
123*a67afe4dSAndroid Build Coastguard Worker #else /* PNG_DEBUG < 0 */
124*a67afe4dSAndroid Build Coastguard Worker # error "Bad PNG_DEBUG value"
125*a67afe4dSAndroid Build Coastguard Worker #endif
126*a67afe4dSAndroid Build Coastguard Worker
127*a67afe4dSAndroid Build Coastguard Worker /* Turn on CPU timing
128*a67afe4dSAndroid Build Coastguard Worker #define PNGTEST_TIMING
129*a67afe4dSAndroid Build Coastguard Worker */
130*a67afe4dSAndroid Build Coastguard Worker
131*a67afe4dSAndroid Build Coastguard Worker #ifndef PNG_FLOATING_POINT_SUPPORTED
132*a67afe4dSAndroid Build Coastguard Worker #undef PNGTEST_TIMING
133*a67afe4dSAndroid Build Coastguard Worker #endif
134*a67afe4dSAndroid Build Coastguard Worker
135*a67afe4dSAndroid Build Coastguard Worker #ifdef PNGTEST_TIMING
136*a67afe4dSAndroid Build Coastguard Worker static float t_start, t_stop, t_decode, t_encode, t_misc;
137*a67afe4dSAndroid Build Coastguard Worker #include <time.h>
138*a67afe4dSAndroid Build Coastguard Worker #endif
139*a67afe4dSAndroid Build Coastguard Worker
140*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_TIME_RFC1123_SUPPORTED
141*a67afe4dSAndroid Build Coastguard Worker static int tIME_chunk_present = 0;
142*a67afe4dSAndroid Build Coastguard Worker static char tIME_string[29] = "tIME chunk is not present";
143*a67afe4dSAndroid Build Coastguard Worker /* This use case is deprecated.
144*a67afe4dSAndroid Build Coastguard Worker * See the declaration of png_convert_to_rfc1123_buffer for more details.
145*a67afe4dSAndroid Build Coastguard Worker */
146*a67afe4dSAndroid Build Coastguard Worker #endif
147*a67afe4dSAndroid Build Coastguard Worker
148*a67afe4dSAndroid Build Coastguard Worker static int verbose = 0;
149*a67afe4dSAndroid Build Coastguard Worker static int strict = 0;
150*a67afe4dSAndroid Build Coastguard Worker static int relaxed = 0;
151*a67afe4dSAndroid Build Coastguard Worker static int xfail = 0;
152*a67afe4dSAndroid Build Coastguard Worker static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */
153*a67afe4dSAndroid Build Coastguard Worker static int error_count = 0; /* count calls to png_error */
154*a67afe4dSAndroid Build Coastguard Worker static int warning_count = 0; /* count calls to png_warning */
155*a67afe4dSAndroid Build Coastguard Worker
156*a67afe4dSAndroid Build Coastguard Worker /* Example of using row callbacks to make a simple progress meter */
157*a67afe4dSAndroid Build Coastguard Worker static int status_pass = 1;
158*a67afe4dSAndroid Build Coastguard Worker static int status_dots_requested = 0;
159*a67afe4dSAndroid Build Coastguard Worker static int status_dots = 1;
160*a67afe4dSAndroid Build Coastguard Worker
161*a67afe4dSAndroid Build Coastguard Worker static void PNGCBAPI
read_row_callback(png_structp png_ptr,png_uint_32 row_number,int pass)162*a67afe4dSAndroid Build Coastguard Worker read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
163*a67afe4dSAndroid Build Coastguard Worker {
164*a67afe4dSAndroid Build Coastguard Worker /* The callback should always receive correct parameters. */
165*a67afe4dSAndroid Build Coastguard Worker if (png_ptr == NULL)
166*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "read_row_callback: bad png_ptr");
167*a67afe4dSAndroid Build Coastguard Worker if (row_number > PNG_UINT_31_MAX)
168*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "read_row_callback: bad row number");
169*a67afe4dSAndroid Build Coastguard Worker if (pass < 0 || pass > 7)
170*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "read_row_callback: bad pass");
171*a67afe4dSAndroid Build Coastguard Worker
172*a67afe4dSAndroid Build Coastguard Worker if (status_pass != pass)
173*a67afe4dSAndroid Build Coastguard Worker {
174*a67afe4dSAndroid Build Coastguard Worker fprintf(stdout, "\n Pass %d: ", pass);
175*a67afe4dSAndroid Build Coastguard Worker status_pass = pass;
176*a67afe4dSAndroid Build Coastguard Worker status_dots = 31;
177*a67afe4dSAndroid Build Coastguard Worker }
178*a67afe4dSAndroid Build Coastguard Worker
179*a67afe4dSAndroid Build Coastguard Worker status_dots--;
180*a67afe4dSAndroid Build Coastguard Worker
181*a67afe4dSAndroid Build Coastguard Worker if (status_dots == 0)
182*a67afe4dSAndroid Build Coastguard Worker {
183*a67afe4dSAndroid Build Coastguard Worker fprintf(stdout, "\n ");
184*a67afe4dSAndroid Build Coastguard Worker status_dots = 30;
185*a67afe4dSAndroid Build Coastguard Worker }
186*a67afe4dSAndroid Build Coastguard Worker
187*a67afe4dSAndroid Build Coastguard Worker fprintf(stdout, "r");
188*a67afe4dSAndroid Build Coastguard Worker }
189*a67afe4dSAndroid Build Coastguard Worker
190*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_SUPPORTED
191*a67afe4dSAndroid Build Coastguard Worker static void PNGCBAPI
write_row_callback(png_structp png_ptr,png_uint_32 row_number,int pass)192*a67afe4dSAndroid Build Coastguard Worker write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
193*a67afe4dSAndroid Build Coastguard Worker {
194*a67afe4dSAndroid Build Coastguard Worker /* The callback should always receive correct parameters. */
195*a67afe4dSAndroid Build Coastguard Worker if (png_ptr == NULL)
196*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "write_row_callback: bad png_ptr");
197*a67afe4dSAndroid Build Coastguard Worker if (row_number > PNG_UINT_31_MAX)
198*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "write_row_callback: bad row number");
199*a67afe4dSAndroid Build Coastguard Worker if (pass < 0 || pass > 7)
200*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "write_row_callback: bad pass");
201*a67afe4dSAndroid Build Coastguard Worker
202*a67afe4dSAndroid Build Coastguard Worker fprintf(stdout, "w");
203*a67afe4dSAndroid Build Coastguard Worker }
204*a67afe4dSAndroid Build Coastguard Worker #endif
205*a67afe4dSAndroid Build Coastguard Worker
206*a67afe4dSAndroid Build Coastguard Worker
207*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
208*a67afe4dSAndroid Build Coastguard Worker /* Example of using a user transform callback (doesn't do anything at present).
209*a67afe4dSAndroid Build Coastguard Worker */
210*a67afe4dSAndroid Build Coastguard Worker static void PNGCBAPI
read_user_callback(png_structp png_ptr,png_row_infop row_info,png_bytep data)211*a67afe4dSAndroid Build Coastguard Worker read_user_callback(png_structp png_ptr, png_row_infop row_info, png_bytep data)
212*a67afe4dSAndroid Build Coastguard Worker {
213*a67afe4dSAndroid Build Coastguard Worker /* The callback should always receive correct parameters. */
214*a67afe4dSAndroid Build Coastguard Worker if (png_ptr == NULL)
215*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "read_user_callback: bad png_ptr");
216*a67afe4dSAndroid Build Coastguard Worker if (row_info == NULL)
217*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "read_user_callback: bad row info");
218*a67afe4dSAndroid Build Coastguard Worker if (data == NULL)
219*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "read_user_callback: bad data");
220*a67afe4dSAndroid Build Coastguard Worker }
221*a67afe4dSAndroid Build Coastguard Worker #endif
222*a67afe4dSAndroid Build Coastguard Worker
223*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
224*a67afe4dSAndroid Build Coastguard Worker /* Example of using user transform callback (we don't transform anything,
225*a67afe4dSAndroid Build Coastguard Worker * but merely count the zero samples)
226*a67afe4dSAndroid Build Coastguard Worker */
227*a67afe4dSAndroid Build Coastguard Worker
228*a67afe4dSAndroid Build Coastguard Worker static png_uint_32 zero_samples;
229*a67afe4dSAndroid Build Coastguard Worker
230*a67afe4dSAndroid Build Coastguard Worker static void PNGCBAPI
count_zero_samples(png_structp png_ptr,png_row_infop row_info,png_bytep data)231*a67afe4dSAndroid Build Coastguard Worker count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
232*a67afe4dSAndroid Build Coastguard Worker {
233*a67afe4dSAndroid Build Coastguard Worker png_bytep dp = data;
234*a67afe4dSAndroid Build Coastguard Worker
235*a67afe4dSAndroid Build Coastguard Worker /* The callback should always receive correct parameters. */
236*a67afe4dSAndroid Build Coastguard Worker if (png_ptr == NULL)
237*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "count_zero_samples: bad png_ptr");
238*a67afe4dSAndroid Build Coastguard Worker if (row_info == NULL)
239*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "count_zero_samples: bad row info");
240*a67afe4dSAndroid Build Coastguard Worker if (data == NULL)
241*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "count_zero_samples: bad data");
242*a67afe4dSAndroid Build Coastguard Worker
243*a67afe4dSAndroid Build Coastguard Worker /* Contents of row_info:
244*a67afe4dSAndroid Build Coastguard Worker * png_uint_32 width width of row
245*a67afe4dSAndroid Build Coastguard Worker * png_uint_32 rowbytes number of bytes in row
246*a67afe4dSAndroid Build Coastguard Worker * png_byte color_type color type of pixels
247*a67afe4dSAndroid Build Coastguard Worker * png_byte bit_depth bit depth of samples
248*a67afe4dSAndroid Build Coastguard Worker * png_byte channels number of channels (1-4)
249*a67afe4dSAndroid Build Coastguard Worker * png_byte pixel_depth bits per pixel (depth*channels)
250*a67afe4dSAndroid Build Coastguard Worker */
251*a67afe4dSAndroid Build Coastguard Worker
252*a67afe4dSAndroid Build Coastguard Worker /* Counts the number of zero samples (or zero pixels if color_type is 3 */
253*a67afe4dSAndroid Build Coastguard Worker
254*a67afe4dSAndroid Build Coastguard Worker if (row_info->color_type == 0 || row_info->color_type == 3)
255*a67afe4dSAndroid Build Coastguard Worker {
256*a67afe4dSAndroid Build Coastguard Worker int pos = 0;
257*a67afe4dSAndroid Build Coastguard Worker png_uint_32 n, nstop;
258*a67afe4dSAndroid Build Coastguard Worker
259*a67afe4dSAndroid Build Coastguard Worker for (n = 0, nstop = row_info->width; n < nstop; n++)
260*a67afe4dSAndroid Build Coastguard Worker {
261*a67afe4dSAndroid Build Coastguard Worker if (row_info->bit_depth == 1)
262*a67afe4dSAndroid Build Coastguard Worker {
263*a67afe4dSAndroid Build Coastguard Worker if (((*dp << pos++ ) & 0x80) == 0)
264*a67afe4dSAndroid Build Coastguard Worker zero_samples++;
265*a67afe4dSAndroid Build Coastguard Worker
266*a67afe4dSAndroid Build Coastguard Worker if (pos == 8)
267*a67afe4dSAndroid Build Coastguard Worker {
268*a67afe4dSAndroid Build Coastguard Worker pos = 0;
269*a67afe4dSAndroid Build Coastguard Worker dp++;
270*a67afe4dSAndroid Build Coastguard Worker }
271*a67afe4dSAndroid Build Coastguard Worker }
272*a67afe4dSAndroid Build Coastguard Worker
273*a67afe4dSAndroid Build Coastguard Worker if (row_info->bit_depth == 2)
274*a67afe4dSAndroid Build Coastguard Worker {
275*a67afe4dSAndroid Build Coastguard Worker if (((*dp << (pos+=2)) & 0xc0) == 0)
276*a67afe4dSAndroid Build Coastguard Worker zero_samples++;
277*a67afe4dSAndroid Build Coastguard Worker
278*a67afe4dSAndroid Build Coastguard Worker if (pos == 8)
279*a67afe4dSAndroid Build Coastguard Worker {
280*a67afe4dSAndroid Build Coastguard Worker pos = 0;
281*a67afe4dSAndroid Build Coastguard Worker dp++;
282*a67afe4dSAndroid Build Coastguard Worker }
283*a67afe4dSAndroid Build Coastguard Worker }
284*a67afe4dSAndroid Build Coastguard Worker
285*a67afe4dSAndroid Build Coastguard Worker if (row_info->bit_depth == 4)
286*a67afe4dSAndroid Build Coastguard Worker {
287*a67afe4dSAndroid Build Coastguard Worker if (((*dp << (pos+=4)) & 0xf0) == 0)
288*a67afe4dSAndroid Build Coastguard Worker zero_samples++;
289*a67afe4dSAndroid Build Coastguard Worker
290*a67afe4dSAndroid Build Coastguard Worker if (pos == 8)
291*a67afe4dSAndroid Build Coastguard Worker {
292*a67afe4dSAndroid Build Coastguard Worker pos = 0;
293*a67afe4dSAndroid Build Coastguard Worker dp++;
294*a67afe4dSAndroid Build Coastguard Worker }
295*a67afe4dSAndroid Build Coastguard Worker }
296*a67afe4dSAndroid Build Coastguard Worker
297*a67afe4dSAndroid Build Coastguard Worker if (row_info->bit_depth == 8)
298*a67afe4dSAndroid Build Coastguard Worker if (*dp++ == 0)
299*a67afe4dSAndroid Build Coastguard Worker zero_samples++;
300*a67afe4dSAndroid Build Coastguard Worker
301*a67afe4dSAndroid Build Coastguard Worker if (row_info->bit_depth == 16)
302*a67afe4dSAndroid Build Coastguard Worker {
303*a67afe4dSAndroid Build Coastguard Worker if ((*dp | *(dp+1)) == 0)
304*a67afe4dSAndroid Build Coastguard Worker zero_samples++;
305*a67afe4dSAndroid Build Coastguard Worker dp += 2;
306*a67afe4dSAndroid Build Coastguard Worker }
307*a67afe4dSAndroid Build Coastguard Worker }
308*a67afe4dSAndroid Build Coastguard Worker }
309*a67afe4dSAndroid Build Coastguard Worker else /* Other color types */
310*a67afe4dSAndroid Build Coastguard Worker {
311*a67afe4dSAndroid Build Coastguard Worker png_uint_32 n, nstop;
312*a67afe4dSAndroid Build Coastguard Worker int channel;
313*a67afe4dSAndroid Build Coastguard Worker int color_channels = row_info->channels;
314*a67afe4dSAndroid Build Coastguard Worker if (row_info->color_type > 3)
315*a67afe4dSAndroid Build Coastguard Worker color_channels--;
316*a67afe4dSAndroid Build Coastguard Worker
317*a67afe4dSAndroid Build Coastguard Worker for (n = 0, nstop = row_info->width; n < nstop; n++)
318*a67afe4dSAndroid Build Coastguard Worker {
319*a67afe4dSAndroid Build Coastguard Worker for (channel = 0; channel < color_channels; channel++)
320*a67afe4dSAndroid Build Coastguard Worker {
321*a67afe4dSAndroid Build Coastguard Worker if (row_info->bit_depth == 8)
322*a67afe4dSAndroid Build Coastguard Worker if (*dp++ == 0)
323*a67afe4dSAndroid Build Coastguard Worker zero_samples++;
324*a67afe4dSAndroid Build Coastguard Worker
325*a67afe4dSAndroid Build Coastguard Worker if (row_info->bit_depth == 16)
326*a67afe4dSAndroid Build Coastguard Worker {
327*a67afe4dSAndroid Build Coastguard Worker if ((*dp | *(dp+1)) == 0)
328*a67afe4dSAndroid Build Coastguard Worker zero_samples++;
329*a67afe4dSAndroid Build Coastguard Worker
330*a67afe4dSAndroid Build Coastguard Worker dp += 2;
331*a67afe4dSAndroid Build Coastguard Worker }
332*a67afe4dSAndroid Build Coastguard Worker }
333*a67afe4dSAndroid Build Coastguard Worker if (row_info->color_type > 3)
334*a67afe4dSAndroid Build Coastguard Worker {
335*a67afe4dSAndroid Build Coastguard Worker dp++;
336*a67afe4dSAndroid Build Coastguard Worker if (row_info->bit_depth == 16)
337*a67afe4dSAndroid Build Coastguard Worker dp++;
338*a67afe4dSAndroid Build Coastguard Worker }
339*a67afe4dSAndroid Build Coastguard Worker }
340*a67afe4dSAndroid Build Coastguard Worker }
341*a67afe4dSAndroid Build Coastguard Worker }
342*a67afe4dSAndroid Build Coastguard Worker #endif /* WRITE_USER_TRANSFORM */
343*a67afe4dSAndroid Build Coastguard Worker
344*a67afe4dSAndroid Build Coastguard Worker #ifndef PNG_STDIO_SUPPORTED
345*a67afe4dSAndroid Build Coastguard Worker /* START of code to validate stdio-free compilation */
346*a67afe4dSAndroid Build Coastguard Worker /* These copies of the default read/write functions come from pngrio.c and
347*a67afe4dSAndroid Build Coastguard Worker * pngwio.c. They allow "don't include stdio" testing of the library.
348*a67afe4dSAndroid Build Coastguard Worker * This is the function that does the actual reading of data. If you are
349*a67afe4dSAndroid Build Coastguard Worker * not reading from a standard C stream, you should create a replacement
350*a67afe4dSAndroid Build Coastguard Worker * read_data function and use it at run time with png_set_read_fn(), rather
351*a67afe4dSAndroid Build Coastguard Worker * than changing the library.
352*a67afe4dSAndroid Build Coastguard Worker */
353*a67afe4dSAndroid Build Coastguard Worker
354*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_IO_STATE_SUPPORTED
355*a67afe4dSAndroid Build Coastguard Worker void
pngtest_check_io_state(png_structp png_ptr,size_t data_length,png_uint_32 io_op)356*a67afe4dSAndroid Build Coastguard Worker pngtest_check_io_state(png_structp png_ptr, size_t data_length,
357*a67afe4dSAndroid Build Coastguard Worker png_uint_32 io_op)
358*a67afe4dSAndroid Build Coastguard Worker {
359*a67afe4dSAndroid Build Coastguard Worker png_uint_32 io_state = png_get_io_state(png_ptr);
360*a67afe4dSAndroid Build Coastguard Worker int err = 0;
361*a67afe4dSAndroid Build Coastguard Worker
362*a67afe4dSAndroid Build Coastguard Worker /* Check if the current operation (reading / writing) is as expected. */
363*a67afe4dSAndroid Build Coastguard Worker if ((io_state & PNG_IO_MASK_OP) != io_op)
364*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "Incorrect operation in I/O state");
365*a67afe4dSAndroid Build Coastguard Worker
366*a67afe4dSAndroid Build Coastguard Worker /* Check if the buffer size specific to the current location
367*a67afe4dSAndroid Build Coastguard Worker * (file signature / header / data / crc) is as expected.
368*a67afe4dSAndroid Build Coastguard Worker */
369*a67afe4dSAndroid Build Coastguard Worker switch ((io_state & PNG_IO_MASK_LOC) != 0)
370*a67afe4dSAndroid Build Coastguard Worker {
371*a67afe4dSAndroid Build Coastguard Worker case PNG_IO_SIGNATURE:
372*a67afe4dSAndroid Build Coastguard Worker if (data_length > 8)
373*a67afe4dSAndroid Build Coastguard Worker err = 1;
374*a67afe4dSAndroid Build Coastguard Worker break;
375*a67afe4dSAndroid Build Coastguard Worker case PNG_IO_CHUNK_HDR:
376*a67afe4dSAndroid Build Coastguard Worker if (data_length != 8)
377*a67afe4dSAndroid Build Coastguard Worker err = 1;
378*a67afe4dSAndroid Build Coastguard Worker break;
379*a67afe4dSAndroid Build Coastguard Worker case PNG_IO_CHUNK_DATA:
380*a67afe4dSAndroid Build Coastguard Worker break; /* no restrictions here */
381*a67afe4dSAndroid Build Coastguard Worker case PNG_IO_CHUNK_CRC:
382*a67afe4dSAndroid Build Coastguard Worker if (data_length != 4)
383*a67afe4dSAndroid Build Coastguard Worker err = 1;
384*a67afe4dSAndroid Build Coastguard Worker break;
385*a67afe4dSAndroid Build Coastguard Worker default:
386*a67afe4dSAndroid Build Coastguard Worker err = 1; /* uninitialized */
387*a67afe4dSAndroid Build Coastguard Worker }
388*a67afe4dSAndroid Build Coastguard Worker if (err != 0)
389*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "Bad I/O state or buffer size");
390*a67afe4dSAndroid Build Coastguard Worker }
391*a67afe4dSAndroid Build Coastguard Worker #endif
392*a67afe4dSAndroid Build Coastguard Worker
393*a67afe4dSAndroid Build Coastguard Worker static void PNGCBAPI
pngtest_read_data(png_structp png_ptr,png_bytep data,size_t length)394*a67afe4dSAndroid Build Coastguard Worker pngtest_read_data(png_structp png_ptr, png_bytep data, size_t length)
395*a67afe4dSAndroid Build Coastguard Worker {
396*a67afe4dSAndroid Build Coastguard Worker size_t check = 0;
397*a67afe4dSAndroid Build Coastguard Worker png_voidp io_ptr;
398*a67afe4dSAndroid Build Coastguard Worker
399*a67afe4dSAndroid Build Coastguard Worker if (png_ptr == NULL)
400*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "pngtest_read_data: bad png_ptr");
401*a67afe4dSAndroid Build Coastguard Worker
402*a67afe4dSAndroid Build Coastguard Worker /* fread() returns 0 on error, so it is OK to store this in a size_t
403*a67afe4dSAndroid Build Coastguard Worker * instead of an int, which is what fread() actually returns.
404*a67afe4dSAndroid Build Coastguard Worker */
405*a67afe4dSAndroid Build Coastguard Worker io_ptr = png_get_io_ptr(png_ptr);
406*a67afe4dSAndroid Build Coastguard Worker if (io_ptr != NULL)
407*a67afe4dSAndroid Build Coastguard Worker check = fread(data, 1, length, (png_FILE_p)io_ptr);
408*a67afe4dSAndroid Build Coastguard Worker
409*a67afe4dSAndroid Build Coastguard Worker if (check != length)
410*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "Read Error");
411*a67afe4dSAndroid Build Coastguard Worker
412*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_IO_STATE_SUPPORTED
413*a67afe4dSAndroid Build Coastguard Worker pngtest_check_io_state(png_ptr, length, PNG_IO_READING);
414*a67afe4dSAndroid Build Coastguard Worker #endif
415*a67afe4dSAndroid Build Coastguard Worker }
416*a67afe4dSAndroid Build Coastguard Worker
417*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_FLUSH_SUPPORTED
418*a67afe4dSAndroid Build Coastguard Worker static void PNGCBAPI
pngtest_flush(png_structp png_ptr)419*a67afe4dSAndroid Build Coastguard Worker pngtest_flush(png_structp png_ptr)
420*a67afe4dSAndroid Build Coastguard Worker {
421*a67afe4dSAndroid Build Coastguard Worker if (png_ptr == NULL)
422*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "pngtest_flush: bad png_ptr");
423*a67afe4dSAndroid Build Coastguard Worker
424*a67afe4dSAndroid Build Coastguard Worker /* Do nothing; fflush() is said to be just a waste of energy. */
425*a67afe4dSAndroid Build Coastguard Worker }
426*a67afe4dSAndroid Build Coastguard Worker #endif
427*a67afe4dSAndroid Build Coastguard Worker
428*a67afe4dSAndroid Build Coastguard Worker /* This is the function that does the actual writing of data. If you are
429*a67afe4dSAndroid Build Coastguard Worker * not writing to a standard C stream, you should create a replacement
430*a67afe4dSAndroid Build Coastguard Worker * write_data function and use it at run time with png_set_write_fn(), rather
431*a67afe4dSAndroid Build Coastguard Worker * than changing the library.
432*a67afe4dSAndroid Build Coastguard Worker */
433*a67afe4dSAndroid Build Coastguard Worker static void PNGCBAPI
pngtest_write_data(png_structp png_ptr,png_bytep data,size_t length)434*a67afe4dSAndroid Build Coastguard Worker pngtest_write_data(png_structp png_ptr, png_bytep data, size_t length)
435*a67afe4dSAndroid Build Coastguard Worker {
436*a67afe4dSAndroid Build Coastguard Worker size_t check;
437*a67afe4dSAndroid Build Coastguard Worker
438*a67afe4dSAndroid Build Coastguard Worker if (png_ptr == NULL)
439*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "pngtest_write_data: bad png_ptr");
440*a67afe4dSAndroid Build Coastguard Worker
441*a67afe4dSAndroid Build Coastguard Worker check = fwrite(data, 1, length, (png_FILE_p)png_get_io_ptr(png_ptr));
442*a67afe4dSAndroid Build Coastguard Worker
443*a67afe4dSAndroid Build Coastguard Worker if (check != length)
444*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "Write Error");
445*a67afe4dSAndroid Build Coastguard Worker
446*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_IO_STATE_SUPPORTED
447*a67afe4dSAndroid Build Coastguard Worker pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING);
448*a67afe4dSAndroid Build Coastguard Worker #endif
449*a67afe4dSAndroid Build Coastguard Worker }
450*a67afe4dSAndroid Build Coastguard Worker #endif /* !STDIO */
451*a67afe4dSAndroid Build Coastguard Worker
452*a67afe4dSAndroid Build Coastguard Worker /* This function is called when there is a warning, but the library thinks
453*a67afe4dSAndroid Build Coastguard Worker * it can continue anyway. Replacement functions don't have to do anything
454*a67afe4dSAndroid Build Coastguard Worker * here if you don't want to. In the default configuration, png_ptr is
455*a67afe4dSAndroid Build Coastguard Worker * not used, but it is passed in case it may be useful.
456*a67afe4dSAndroid Build Coastguard Worker */
457*a67afe4dSAndroid Build Coastguard Worker typedef struct
458*a67afe4dSAndroid Build Coastguard Worker {
459*a67afe4dSAndroid Build Coastguard Worker const char *file_name;
460*a67afe4dSAndroid Build Coastguard Worker } pngtest_error_parameters;
461*a67afe4dSAndroid Build Coastguard Worker
462*a67afe4dSAndroid Build Coastguard Worker static void PNGCBAPI
pngtest_warning(png_structp png_ptr,png_const_charp message)463*a67afe4dSAndroid Build Coastguard Worker pngtest_warning(png_structp png_ptr, png_const_charp message)
464*a67afe4dSAndroid Build Coastguard Worker {
465*a67afe4dSAndroid Build Coastguard Worker const char *name = "UNKNOWN (ERROR!)";
466*a67afe4dSAndroid Build Coastguard Worker pngtest_error_parameters *test =
467*a67afe4dSAndroid Build Coastguard Worker (pngtest_error_parameters*)png_get_error_ptr(png_ptr);
468*a67afe4dSAndroid Build Coastguard Worker
469*a67afe4dSAndroid Build Coastguard Worker ++warning_count;
470*a67afe4dSAndroid Build Coastguard Worker
471*a67afe4dSAndroid Build Coastguard Worker if (test != NULL && test->file_name != NULL)
472*a67afe4dSAndroid Build Coastguard Worker name = test->file_name;
473*a67afe4dSAndroid Build Coastguard Worker
474*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "\n%s: libpng warning: %s\n", name, message);
475*a67afe4dSAndroid Build Coastguard Worker }
476*a67afe4dSAndroid Build Coastguard Worker
477*a67afe4dSAndroid Build Coastguard Worker /* This is the default error handling function. Note that replacements for
478*a67afe4dSAndroid Build Coastguard Worker * this function MUST NOT RETURN, or the program will likely crash. This
479*a67afe4dSAndroid Build Coastguard Worker * function is used by default, or if the program supplies NULL for the
480*a67afe4dSAndroid Build Coastguard Worker * error function pointer in png_set_error_fn().
481*a67afe4dSAndroid Build Coastguard Worker */
482*a67afe4dSAndroid Build Coastguard Worker static void PNGCBAPI
pngtest_error(png_structp png_ptr,png_const_charp message)483*a67afe4dSAndroid Build Coastguard Worker pngtest_error(png_structp png_ptr, png_const_charp message)
484*a67afe4dSAndroid Build Coastguard Worker {
485*a67afe4dSAndroid Build Coastguard Worker ++error_count;
486*a67afe4dSAndroid Build Coastguard Worker
487*a67afe4dSAndroid Build Coastguard Worker pngtest_warning(png_ptr, message);
488*a67afe4dSAndroid Build Coastguard Worker /* We can return because png_error calls the default handler, which is
489*a67afe4dSAndroid Build Coastguard Worker * actually OK in this case.
490*a67afe4dSAndroid Build Coastguard Worker */
491*a67afe4dSAndroid Build Coastguard Worker }
492*a67afe4dSAndroid Build Coastguard Worker
493*a67afe4dSAndroid Build Coastguard Worker /* END of code to validate stdio-free compilation */
494*a67afe4dSAndroid Build Coastguard Worker
495*a67afe4dSAndroid Build Coastguard Worker /* START of code to validate memory allocation and deallocation */
496*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
497*a67afe4dSAndroid Build Coastguard Worker
498*a67afe4dSAndroid Build Coastguard Worker /* Allocate memory. For reasonable files, size should never exceed
499*a67afe4dSAndroid Build Coastguard Worker * 64K. However, zlib may allocate more than 64K if you don't tell
500*a67afe4dSAndroid Build Coastguard Worker * it not to. See zconf.h and png.h for more information. zlib does
501*a67afe4dSAndroid Build Coastguard Worker * need to allocate exactly 64K, so whatever you call here must
502*a67afe4dSAndroid Build Coastguard Worker * have the ability to do that.
503*a67afe4dSAndroid Build Coastguard Worker *
504*a67afe4dSAndroid Build Coastguard Worker * This piece of code can be compiled to validate max 64K allocations
505*a67afe4dSAndroid Build Coastguard Worker * by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K.
506*a67afe4dSAndroid Build Coastguard Worker */
507*a67afe4dSAndroid Build Coastguard Worker typedef struct memory_information
508*a67afe4dSAndroid Build Coastguard Worker {
509*a67afe4dSAndroid Build Coastguard Worker png_alloc_size_t size;
510*a67afe4dSAndroid Build Coastguard Worker png_voidp pointer;
511*a67afe4dSAndroid Build Coastguard Worker struct memory_information *next;
512*a67afe4dSAndroid Build Coastguard Worker } memory_information;
513*a67afe4dSAndroid Build Coastguard Worker typedef memory_information *memory_infop;
514*a67afe4dSAndroid Build Coastguard Worker
515*a67afe4dSAndroid Build Coastguard Worker static memory_infop pinformation = NULL;
516*a67afe4dSAndroid Build Coastguard Worker static int current_allocation = 0;
517*a67afe4dSAndroid Build Coastguard Worker static int maximum_allocation = 0;
518*a67afe4dSAndroid Build Coastguard Worker static int total_allocation = 0;
519*a67afe4dSAndroid Build Coastguard Worker static int num_allocations = 0;
520*a67afe4dSAndroid Build Coastguard Worker
521*a67afe4dSAndroid Build Coastguard Worker png_voidp PNGCBAPI png_debug_malloc(png_structp png_ptr,
522*a67afe4dSAndroid Build Coastguard Worker png_alloc_size_t size);
523*a67afe4dSAndroid Build Coastguard Worker void PNGCBAPI png_debug_free(png_structp png_ptr, png_voidp ptr);
524*a67afe4dSAndroid Build Coastguard Worker
525*a67afe4dSAndroid Build Coastguard Worker png_voidp
png_debug_malloc(png_structp png_ptr,png_alloc_size_t size)526*a67afe4dSAndroid Build Coastguard Worker PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size)
527*a67afe4dSAndroid Build Coastguard Worker {
528*a67afe4dSAndroid Build Coastguard Worker
529*a67afe4dSAndroid Build Coastguard Worker /* png_malloc has already tested for NULL; png_create_struct calls
530*a67afe4dSAndroid Build Coastguard Worker * png_debug_malloc directly, with png_ptr == NULL which is OK
531*a67afe4dSAndroid Build Coastguard Worker */
532*a67afe4dSAndroid Build Coastguard Worker
533*a67afe4dSAndroid Build Coastguard Worker if (size == 0)
534*a67afe4dSAndroid Build Coastguard Worker return NULL;
535*a67afe4dSAndroid Build Coastguard Worker
536*a67afe4dSAndroid Build Coastguard Worker /* This calls the library allocator twice, once to get the requested
537*a67afe4dSAndroid Build Coastguard Worker buffer and once to get a new free list entry. */
538*a67afe4dSAndroid Build Coastguard Worker {
539*a67afe4dSAndroid Build Coastguard Worker /* Disable malloc_fn and free_fn */
540*a67afe4dSAndroid Build Coastguard Worker memory_infop pinfo;
541*a67afe4dSAndroid Build Coastguard Worker png_set_mem_fn(png_ptr, NULL, NULL, NULL);
542*a67afe4dSAndroid Build Coastguard Worker pinfo = (memory_infop)png_malloc(png_ptr,
543*a67afe4dSAndroid Build Coastguard Worker (sizeof *pinfo));
544*a67afe4dSAndroid Build Coastguard Worker pinfo->size = size;
545*a67afe4dSAndroid Build Coastguard Worker current_allocation += size;
546*a67afe4dSAndroid Build Coastguard Worker total_allocation += size;
547*a67afe4dSAndroid Build Coastguard Worker ++num_allocations;
548*a67afe4dSAndroid Build Coastguard Worker
549*a67afe4dSAndroid Build Coastguard Worker if (current_allocation > maximum_allocation)
550*a67afe4dSAndroid Build Coastguard Worker maximum_allocation = current_allocation;
551*a67afe4dSAndroid Build Coastguard Worker
552*a67afe4dSAndroid Build Coastguard Worker pinfo->pointer = png_malloc(png_ptr, size);
553*a67afe4dSAndroid Build Coastguard Worker /* Restore malloc_fn and free_fn */
554*a67afe4dSAndroid Build Coastguard Worker
555*a67afe4dSAndroid Build Coastguard Worker png_set_mem_fn(png_ptr,
556*a67afe4dSAndroid Build Coastguard Worker NULL, png_debug_malloc, png_debug_free);
557*a67afe4dSAndroid Build Coastguard Worker
558*a67afe4dSAndroid Build Coastguard Worker if (size != 0 && pinfo->pointer == NULL)
559*a67afe4dSAndroid Build Coastguard Worker {
560*a67afe4dSAndroid Build Coastguard Worker current_allocation -= size;
561*a67afe4dSAndroid Build Coastguard Worker total_allocation -= size;
562*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr,
563*a67afe4dSAndroid Build Coastguard Worker "out of memory in pngtest->png_debug_malloc");
564*a67afe4dSAndroid Build Coastguard Worker }
565*a67afe4dSAndroid Build Coastguard Worker
566*a67afe4dSAndroid Build Coastguard Worker pinfo->next = pinformation;
567*a67afe4dSAndroid Build Coastguard Worker pinformation = pinfo;
568*a67afe4dSAndroid Build Coastguard Worker /* Make sure the caller isn't assuming zeroed memory. */
569*a67afe4dSAndroid Build Coastguard Worker memset(pinfo->pointer, 0xdd, pinfo->size);
570*a67afe4dSAndroid Build Coastguard Worker
571*a67afe4dSAndroid Build Coastguard Worker if (verbose != 0)
572*a67afe4dSAndroid Build Coastguard Worker printf("png_malloc %lu bytes at %p\n", (unsigned long)size,
573*a67afe4dSAndroid Build Coastguard Worker pinfo->pointer);
574*a67afe4dSAndroid Build Coastguard Worker
575*a67afe4dSAndroid Build Coastguard Worker return (png_voidp)pinfo->pointer;
576*a67afe4dSAndroid Build Coastguard Worker }
577*a67afe4dSAndroid Build Coastguard Worker }
578*a67afe4dSAndroid Build Coastguard Worker
579*a67afe4dSAndroid Build Coastguard Worker /* Free a pointer. It is removed from the list at the same time. */
580*a67afe4dSAndroid Build Coastguard Worker void PNGCBAPI
png_debug_free(png_structp png_ptr,png_voidp ptr)581*a67afe4dSAndroid Build Coastguard Worker png_debug_free(png_structp png_ptr, png_voidp ptr)
582*a67afe4dSAndroid Build Coastguard Worker {
583*a67afe4dSAndroid Build Coastguard Worker if (png_ptr == NULL)
584*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "NULL pointer to png_debug_free.\n");
585*a67afe4dSAndroid Build Coastguard Worker
586*a67afe4dSAndroid Build Coastguard Worker if (ptr == 0)
587*a67afe4dSAndroid Build Coastguard Worker {
588*a67afe4dSAndroid Build Coastguard Worker #if 0 /* This happens all the time. */
589*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "WARNING: freeing NULL pointer\n");
590*a67afe4dSAndroid Build Coastguard Worker #endif
591*a67afe4dSAndroid Build Coastguard Worker return;
592*a67afe4dSAndroid Build Coastguard Worker }
593*a67afe4dSAndroid Build Coastguard Worker
594*a67afe4dSAndroid Build Coastguard Worker /* Unlink the element from the list. */
595*a67afe4dSAndroid Build Coastguard Worker if (pinformation != NULL)
596*a67afe4dSAndroid Build Coastguard Worker {
597*a67afe4dSAndroid Build Coastguard Worker memory_infop *ppinfo = &pinformation;
598*a67afe4dSAndroid Build Coastguard Worker
599*a67afe4dSAndroid Build Coastguard Worker for (;;)
600*a67afe4dSAndroid Build Coastguard Worker {
601*a67afe4dSAndroid Build Coastguard Worker memory_infop pinfo = *ppinfo;
602*a67afe4dSAndroid Build Coastguard Worker
603*a67afe4dSAndroid Build Coastguard Worker if (pinfo->pointer == ptr)
604*a67afe4dSAndroid Build Coastguard Worker {
605*a67afe4dSAndroid Build Coastguard Worker *ppinfo = pinfo->next;
606*a67afe4dSAndroid Build Coastguard Worker current_allocation -= pinfo->size;
607*a67afe4dSAndroid Build Coastguard Worker if (current_allocation < 0)
608*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "Duplicate free of memory\n");
609*a67afe4dSAndroid Build Coastguard Worker /* We must free the list element too, but first kill
610*a67afe4dSAndroid Build Coastguard Worker the memory that is to be freed. */
611*a67afe4dSAndroid Build Coastguard Worker memset(ptr, 0x55, pinfo->size);
612*a67afe4dSAndroid Build Coastguard Worker free(pinfo);
613*a67afe4dSAndroid Build Coastguard Worker pinfo = NULL;
614*a67afe4dSAndroid Build Coastguard Worker break;
615*a67afe4dSAndroid Build Coastguard Worker }
616*a67afe4dSAndroid Build Coastguard Worker
617*a67afe4dSAndroid Build Coastguard Worker if (pinfo->next == NULL)
618*a67afe4dSAndroid Build Coastguard Worker {
619*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "Pointer %p not found\n", ptr);
620*a67afe4dSAndroid Build Coastguard Worker break;
621*a67afe4dSAndroid Build Coastguard Worker }
622*a67afe4dSAndroid Build Coastguard Worker
623*a67afe4dSAndroid Build Coastguard Worker ppinfo = &pinfo->next;
624*a67afe4dSAndroid Build Coastguard Worker }
625*a67afe4dSAndroid Build Coastguard Worker }
626*a67afe4dSAndroid Build Coastguard Worker
627*a67afe4dSAndroid Build Coastguard Worker /* Finally free the data. */
628*a67afe4dSAndroid Build Coastguard Worker if (verbose != 0)
629*a67afe4dSAndroid Build Coastguard Worker printf("Freeing %p\n", ptr);
630*a67afe4dSAndroid Build Coastguard Worker
631*a67afe4dSAndroid Build Coastguard Worker if (ptr != NULL)
632*a67afe4dSAndroid Build Coastguard Worker free(ptr);
633*a67afe4dSAndroid Build Coastguard Worker ptr = NULL;
634*a67afe4dSAndroid Build Coastguard Worker }
635*a67afe4dSAndroid Build Coastguard Worker #endif /* USER_MEM && DEBUG */
636*a67afe4dSAndroid Build Coastguard Worker /* END of code to test memory allocation/deallocation */
637*a67afe4dSAndroid Build Coastguard Worker
638*a67afe4dSAndroid Build Coastguard Worker
639*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
640*a67afe4dSAndroid Build Coastguard Worker /* Demonstration of user chunk support of the sTER and vpAg chunks */
641*a67afe4dSAndroid Build Coastguard Worker
642*a67afe4dSAndroid Build Coastguard Worker /* (sTER is a public chunk not yet known by libpng. vpAg is a private
643*a67afe4dSAndroid Build Coastguard Worker chunk used in ImageMagick to store "virtual page" size). */
644*a67afe4dSAndroid Build Coastguard Worker
645*a67afe4dSAndroid Build Coastguard Worker typedef struct user_chunk_info_def
646*a67afe4dSAndroid Build Coastguard Worker {
647*a67afe4dSAndroid Build Coastguard Worker png_const_infop info_ptr;
648*a67afe4dSAndroid Build Coastguard Worker png_uint_32 vpAg_width, vpAg_height;
649*a67afe4dSAndroid Build Coastguard Worker png_byte vpAg_units;
650*a67afe4dSAndroid Build Coastguard Worker png_byte sTER_mode;
651*a67afe4dSAndroid Build Coastguard Worker int location[2];
652*a67afe4dSAndroid Build Coastguard Worker } user_chunk_info;
653*a67afe4dSAndroid Build Coastguard Worker
654*a67afe4dSAndroid Build Coastguard Worker /* Used for location and order; zero means nothing. */
655*a67afe4dSAndroid Build Coastguard Worker #define have_sTER 0x01
656*a67afe4dSAndroid Build Coastguard Worker #define have_vpAg 0x02
657*a67afe4dSAndroid Build Coastguard Worker #define before_PLTE 0x10
658*a67afe4dSAndroid Build Coastguard Worker #define before_IDAT 0x20
659*a67afe4dSAndroid Build Coastguard Worker #define after_IDAT 0x40
660*a67afe4dSAndroid Build Coastguard Worker
661*a67afe4dSAndroid Build Coastguard Worker static void
init_user_chunk_info(png_const_infop info_ptr,user_chunk_info * chunk_data)662*a67afe4dSAndroid Build Coastguard Worker init_user_chunk_info(png_const_infop info_ptr, user_chunk_info *chunk_data)
663*a67afe4dSAndroid Build Coastguard Worker {
664*a67afe4dSAndroid Build Coastguard Worker memset(chunk_data, 0, sizeof(*chunk_data));
665*a67afe4dSAndroid Build Coastguard Worker chunk_data->info_ptr = info_ptr;
666*a67afe4dSAndroid Build Coastguard Worker }
667*a67afe4dSAndroid Build Coastguard Worker
668*a67afe4dSAndroid Build Coastguard Worker static int
set_chunk_location(png_structp png_ptr,user_chunk_info * chunk_data,int what)669*a67afe4dSAndroid Build Coastguard Worker set_chunk_location(png_structp png_ptr, user_chunk_info *chunk_data, int what)
670*a67afe4dSAndroid Build Coastguard Worker {
671*a67afe4dSAndroid Build Coastguard Worker int location;
672*a67afe4dSAndroid Build Coastguard Worker
673*a67afe4dSAndroid Build Coastguard Worker if ((chunk_data->location[0] & what) != 0 ||
674*a67afe4dSAndroid Build Coastguard Worker (chunk_data->location[1] & what) != 0)
675*a67afe4dSAndroid Build Coastguard Worker return 0; /* we already have one of these */
676*a67afe4dSAndroid Build Coastguard Worker
677*a67afe4dSAndroid Build Coastguard Worker /* Find where we are (the code below zeroes info_ptr to indicate that the
678*a67afe4dSAndroid Build Coastguard Worker * chunks before the first IDAT have been read.)
679*a67afe4dSAndroid Build Coastguard Worker */
680*a67afe4dSAndroid Build Coastguard Worker if (chunk_data->info_ptr == NULL) /* after IDAT */
681*a67afe4dSAndroid Build Coastguard Worker location = what | after_IDAT;
682*a67afe4dSAndroid Build Coastguard Worker
683*a67afe4dSAndroid Build Coastguard Worker else if (png_get_valid(png_ptr, chunk_data->info_ptr, PNG_INFO_PLTE) != 0)
684*a67afe4dSAndroid Build Coastguard Worker location = what | before_IDAT;
685*a67afe4dSAndroid Build Coastguard Worker
686*a67afe4dSAndroid Build Coastguard Worker else
687*a67afe4dSAndroid Build Coastguard Worker location = what | before_PLTE;
688*a67afe4dSAndroid Build Coastguard Worker
689*a67afe4dSAndroid Build Coastguard Worker if (chunk_data->location[0] == 0)
690*a67afe4dSAndroid Build Coastguard Worker chunk_data->location[0] = location;
691*a67afe4dSAndroid Build Coastguard Worker
692*a67afe4dSAndroid Build Coastguard Worker else
693*a67afe4dSAndroid Build Coastguard Worker chunk_data->location[1] = location;
694*a67afe4dSAndroid Build Coastguard Worker
695*a67afe4dSAndroid Build Coastguard Worker return 1; /* handled */
696*a67afe4dSAndroid Build Coastguard Worker }
697*a67afe4dSAndroid Build Coastguard Worker
698*a67afe4dSAndroid Build Coastguard Worker static int PNGCBAPI
read_user_chunk_callback(png_struct * png_ptr,png_unknown_chunkp chunk)699*a67afe4dSAndroid Build Coastguard Worker read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk)
700*a67afe4dSAndroid Build Coastguard Worker {
701*a67afe4dSAndroid Build Coastguard Worker user_chunk_info *my_user_chunk_data =
702*a67afe4dSAndroid Build Coastguard Worker (user_chunk_info*)png_get_user_chunk_ptr(png_ptr);
703*a67afe4dSAndroid Build Coastguard Worker
704*a67afe4dSAndroid Build Coastguard Worker if (my_user_chunk_data == NULL)
705*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "lost pointer to user chunk data");
706*a67afe4dSAndroid Build Coastguard Worker
707*a67afe4dSAndroid Build Coastguard Worker /* Return one of the following:
708*a67afe4dSAndroid Build Coastguard Worker * return -n; chunk had an error
709*a67afe4dSAndroid Build Coastguard Worker * return 0; did not recognize
710*a67afe4dSAndroid Build Coastguard Worker * return n; success
711*a67afe4dSAndroid Build Coastguard Worker *
712*a67afe4dSAndroid Build Coastguard Worker * The unknown chunk structure contains the chunk data:
713*a67afe4dSAndroid Build Coastguard Worker * png_byte name[5];
714*a67afe4dSAndroid Build Coastguard Worker * png_byte *data;
715*a67afe4dSAndroid Build Coastguard Worker * size_t size;
716*a67afe4dSAndroid Build Coastguard Worker *
717*a67afe4dSAndroid Build Coastguard Worker * Note that libpng has already taken care of the CRC handling.
718*a67afe4dSAndroid Build Coastguard Worker */
719*a67afe4dSAndroid Build Coastguard Worker
720*a67afe4dSAndroid Build Coastguard Worker if (chunk->name[0] == 115 && chunk->name[1] == 84 && /* s T */
721*a67afe4dSAndroid Build Coastguard Worker chunk->name[2] == 69 && chunk->name[3] == 82) /* E R */
722*a67afe4dSAndroid Build Coastguard Worker {
723*a67afe4dSAndroid Build Coastguard Worker /* Found sTER chunk */
724*a67afe4dSAndroid Build Coastguard Worker if (chunk->size != 1)
725*a67afe4dSAndroid Build Coastguard Worker return -1; /* Error return */
726*a67afe4dSAndroid Build Coastguard Worker
727*a67afe4dSAndroid Build Coastguard Worker if (chunk->data[0] != 0 && chunk->data[0] != 1)
728*a67afe4dSAndroid Build Coastguard Worker return -1; /* Invalid mode */
729*a67afe4dSAndroid Build Coastguard Worker
730*a67afe4dSAndroid Build Coastguard Worker if (set_chunk_location(png_ptr, my_user_chunk_data, have_sTER) != 0)
731*a67afe4dSAndroid Build Coastguard Worker {
732*a67afe4dSAndroid Build Coastguard Worker my_user_chunk_data->sTER_mode = chunk->data[0];
733*a67afe4dSAndroid Build Coastguard Worker return 1;
734*a67afe4dSAndroid Build Coastguard Worker }
735*a67afe4dSAndroid Build Coastguard Worker
736*a67afe4dSAndroid Build Coastguard Worker else
737*a67afe4dSAndroid Build Coastguard Worker return 0; /* duplicate sTER - give it to libpng */
738*a67afe4dSAndroid Build Coastguard Worker }
739*a67afe4dSAndroid Build Coastguard Worker
740*a67afe4dSAndroid Build Coastguard Worker if (chunk->name[0] != 118 || chunk->name[1] != 112 || /* v p */
741*a67afe4dSAndroid Build Coastguard Worker chunk->name[2] != 65 || chunk->name[3] != 103) /* A g */
742*a67afe4dSAndroid Build Coastguard Worker return 0; /* Did not recognize */
743*a67afe4dSAndroid Build Coastguard Worker
744*a67afe4dSAndroid Build Coastguard Worker /* Found ImageMagick vpAg chunk */
745*a67afe4dSAndroid Build Coastguard Worker
746*a67afe4dSAndroid Build Coastguard Worker if (chunk->size != 9)
747*a67afe4dSAndroid Build Coastguard Worker return -1; /* Error return */
748*a67afe4dSAndroid Build Coastguard Worker
749*a67afe4dSAndroid Build Coastguard Worker if (set_chunk_location(png_ptr, my_user_chunk_data, have_vpAg) == 0)
750*a67afe4dSAndroid Build Coastguard Worker return 0; /* duplicate vpAg */
751*a67afe4dSAndroid Build Coastguard Worker
752*a67afe4dSAndroid Build Coastguard Worker my_user_chunk_data->vpAg_width = png_get_uint_31(png_ptr, chunk->data);
753*a67afe4dSAndroid Build Coastguard Worker my_user_chunk_data->vpAg_height = png_get_uint_31(png_ptr, chunk->data + 4);
754*a67afe4dSAndroid Build Coastguard Worker my_user_chunk_data->vpAg_units = chunk->data[8];
755*a67afe4dSAndroid Build Coastguard Worker
756*a67afe4dSAndroid Build Coastguard Worker return 1;
757*a67afe4dSAndroid Build Coastguard Worker }
758*a67afe4dSAndroid Build Coastguard Worker
759*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_SUPPORTED
760*a67afe4dSAndroid Build Coastguard Worker static void
write_sTER_chunk(png_structp write_ptr,user_chunk_info * data)761*a67afe4dSAndroid Build Coastguard Worker write_sTER_chunk(png_structp write_ptr, user_chunk_info *data)
762*a67afe4dSAndroid Build Coastguard Worker {
763*a67afe4dSAndroid Build Coastguard Worker png_byte sTER[5] = {115, 84, 69, 82, '\0'};
764*a67afe4dSAndroid Build Coastguard Worker
765*a67afe4dSAndroid Build Coastguard Worker if (verbose != 0)
766*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "\n stereo mode = %d\n", data->sTER_mode);
767*a67afe4dSAndroid Build Coastguard Worker
768*a67afe4dSAndroid Build Coastguard Worker png_write_chunk(write_ptr, sTER, &data->sTER_mode, 1);
769*a67afe4dSAndroid Build Coastguard Worker }
770*a67afe4dSAndroid Build Coastguard Worker
771*a67afe4dSAndroid Build Coastguard Worker static void
write_vpAg_chunk(png_structp write_ptr,user_chunk_info * data)772*a67afe4dSAndroid Build Coastguard Worker write_vpAg_chunk(png_structp write_ptr, user_chunk_info *data)
773*a67afe4dSAndroid Build Coastguard Worker {
774*a67afe4dSAndroid Build Coastguard Worker png_byte vpAg[5] = {118, 112, 65, 103, '\0'};
775*a67afe4dSAndroid Build Coastguard Worker
776*a67afe4dSAndroid Build Coastguard Worker png_byte vpag_chunk_data[9];
777*a67afe4dSAndroid Build Coastguard Worker
778*a67afe4dSAndroid Build Coastguard Worker if (verbose != 0)
779*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " vpAg = %lu x %lu, units = %d\n",
780*a67afe4dSAndroid Build Coastguard Worker (unsigned long)data->vpAg_width,
781*a67afe4dSAndroid Build Coastguard Worker (unsigned long)data->vpAg_height,
782*a67afe4dSAndroid Build Coastguard Worker data->vpAg_units);
783*a67afe4dSAndroid Build Coastguard Worker
784*a67afe4dSAndroid Build Coastguard Worker png_save_uint_32(vpag_chunk_data, data->vpAg_width);
785*a67afe4dSAndroid Build Coastguard Worker png_save_uint_32(vpag_chunk_data + 4, data->vpAg_height);
786*a67afe4dSAndroid Build Coastguard Worker vpag_chunk_data[8] = data->vpAg_units;
787*a67afe4dSAndroid Build Coastguard Worker png_write_chunk(write_ptr, vpAg, vpag_chunk_data, 9);
788*a67afe4dSAndroid Build Coastguard Worker }
789*a67afe4dSAndroid Build Coastguard Worker
790*a67afe4dSAndroid Build Coastguard Worker static void
write_chunks(png_structp write_ptr,user_chunk_info * data,int location)791*a67afe4dSAndroid Build Coastguard Worker write_chunks(png_structp write_ptr, user_chunk_info *data, int location)
792*a67afe4dSAndroid Build Coastguard Worker {
793*a67afe4dSAndroid Build Coastguard Worker int i;
794*a67afe4dSAndroid Build Coastguard Worker
795*a67afe4dSAndroid Build Coastguard Worker /* Notice that this preserves the original chunk order, however chunks
796*a67afe4dSAndroid Build Coastguard Worker * intercepted by the callback will be written *after* chunks passed to
797*a67afe4dSAndroid Build Coastguard Worker * libpng. This will actually reverse a pair of sTER chunks or a pair of
798*a67afe4dSAndroid Build Coastguard Worker * vpAg chunks, resulting in an error later. This is not worth worrying
799*a67afe4dSAndroid Build Coastguard Worker * about - the chunks should not be duplicated!
800*a67afe4dSAndroid Build Coastguard Worker */
801*a67afe4dSAndroid Build Coastguard Worker for (i = 0; i < 2; ++i)
802*a67afe4dSAndroid Build Coastguard Worker {
803*a67afe4dSAndroid Build Coastguard Worker if (data->location[i] == (location | have_sTER))
804*a67afe4dSAndroid Build Coastguard Worker write_sTER_chunk(write_ptr, data);
805*a67afe4dSAndroid Build Coastguard Worker
806*a67afe4dSAndroid Build Coastguard Worker else if (data->location[i] == (location | have_vpAg))
807*a67afe4dSAndroid Build Coastguard Worker write_vpAg_chunk(write_ptr, data);
808*a67afe4dSAndroid Build Coastguard Worker }
809*a67afe4dSAndroid Build Coastguard Worker }
810*a67afe4dSAndroid Build Coastguard Worker #endif /* WRITE */
811*a67afe4dSAndroid Build Coastguard Worker #else /* !READ_USER_CHUNKS */
812*a67afe4dSAndroid Build Coastguard Worker # define write_chunks(pp,loc) ((void)0)
813*a67afe4dSAndroid Build Coastguard Worker #endif
814*a67afe4dSAndroid Build Coastguard Worker /* END of code to demonstrate user chunk support */
815*a67afe4dSAndroid Build Coastguard Worker
816*a67afe4dSAndroid Build Coastguard Worker /* START of code to check that libpng has the required text support; this only
817*a67afe4dSAndroid Build Coastguard Worker * checks for the write support because if read support is missing the chunk
818*a67afe4dSAndroid Build Coastguard Worker * will simply not be reported back to pngtest.
819*a67afe4dSAndroid Build Coastguard Worker */
820*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_TEXT_SUPPORTED
821*a67afe4dSAndroid Build Coastguard Worker static void
pngtest_check_text_support(png_structp png_ptr,png_textp text_ptr,int num_text)822*a67afe4dSAndroid Build Coastguard Worker pngtest_check_text_support(png_structp png_ptr, png_textp text_ptr,
823*a67afe4dSAndroid Build Coastguard Worker int num_text)
824*a67afe4dSAndroid Build Coastguard Worker {
825*a67afe4dSAndroid Build Coastguard Worker while (num_text > 0)
826*a67afe4dSAndroid Build Coastguard Worker {
827*a67afe4dSAndroid Build Coastguard Worker switch (text_ptr[--num_text].compression)
828*a67afe4dSAndroid Build Coastguard Worker {
829*a67afe4dSAndroid Build Coastguard Worker case PNG_TEXT_COMPRESSION_NONE:
830*a67afe4dSAndroid Build Coastguard Worker break;
831*a67afe4dSAndroid Build Coastguard Worker
832*a67afe4dSAndroid Build Coastguard Worker case PNG_TEXT_COMPRESSION_zTXt:
833*a67afe4dSAndroid Build Coastguard Worker # ifndef PNG_WRITE_zTXt_SUPPORTED
834*a67afe4dSAndroid Build Coastguard Worker ++unsupported_chunks;
835*a67afe4dSAndroid Build Coastguard Worker /* In libpng 1.7 this now does an app-error, so stop it: */
836*a67afe4dSAndroid Build Coastguard Worker text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
837*a67afe4dSAndroid Build Coastguard Worker # endif
838*a67afe4dSAndroid Build Coastguard Worker break;
839*a67afe4dSAndroid Build Coastguard Worker
840*a67afe4dSAndroid Build Coastguard Worker case PNG_ITXT_COMPRESSION_NONE:
841*a67afe4dSAndroid Build Coastguard Worker case PNG_ITXT_COMPRESSION_zTXt:
842*a67afe4dSAndroid Build Coastguard Worker # ifndef PNG_WRITE_iTXt_SUPPORTED
843*a67afe4dSAndroid Build Coastguard Worker ++unsupported_chunks;
844*a67afe4dSAndroid Build Coastguard Worker text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
845*a67afe4dSAndroid Build Coastguard Worker # endif
846*a67afe4dSAndroid Build Coastguard Worker break;
847*a67afe4dSAndroid Build Coastguard Worker
848*a67afe4dSAndroid Build Coastguard Worker default:
849*a67afe4dSAndroid Build Coastguard Worker /* This is an error */
850*a67afe4dSAndroid Build Coastguard Worker png_error(png_ptr, "invalid text chunk compression field");
851*a67afe4dSAndroid Build Coastguard Worker break;
852*a67afe4dSAndroid Build Coastguard Worker }
853*a67afe4dSAndroid Build Coastguard Worker }
854*a67afe4dSAndroid Build Coastguard Worker }
855*a67afe4dSAndroid Build Coastguard Worker #endif
856*a67afe4dSAndroid Build Coastguard Worker /* END of code to check that libpng has the required text support */
857*a67afe4dSAndroid Build Coastguard Worker
858*a67afe4dSAndroid Build Coastguard Worker /* Test one file */
859*a67afe4dSAndroid Build Coastguard Worker static int
test_one_file(const char * inname,const char * outname)860*a67afe4dSAndroid Build Coastguard Worker test_one_file(const char *inname, const char *outname)
861*a67afe4dSAndroid Build Coastguard Worker {
862*a67afe4dSAndroid Build Coastguard Worker static png_FILE_p fpin;
863*a67afe4dSAndroid Build Coastguard Worker static png_FILE_p fpout; /* "static" prevents setjmp corruption */
864*a67afe4dSAndroid Build Coastguard Worker pngtest_error_parameters error_parameters;
865*a67afe4dSAndroid Build Coastguard Worker png_structp read_ptr;
866*a67afe4dSAndroid Build Coastguard Worker png_infop read_info_ptr, end_info_ptr;
867*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_SUPPORTED
868*a67afe4dSAndroid Build Coastguard Worker png_structp write_ptr;
869*a67afe4dSAndroid Build Coastguard Worker png_infop write_info_ptr;
870*a67afe4dSAndroid Build Coastguard Worker png_infop write_end_info_ptr;
871*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_FILTER_SUPPORTED
872*a67afe4dSAndroid Build Coastguard Worker int interlace_preserved = 1;
873*a67afe4dSAndroid Build Coastguard Worker #endif /* WRITE_FILTER */
874*a67afe4dSAndroid Build Coastguard Worker #else /* !WRITE */
875*a67afe4dSAndroid Build Coastguard Worker png_structp write_ptr = NULL;
876*a67afe4dSAndroid Build Coastguard Worker png_infop write_info_ptr = NULL;
877*a67afe4dSAndroid Build Coastguard Worker png_infop write_end_info_ptr = NULL;
878*a67afe4dSAndroid Build Coastguard Worker #endif /* !WRITE */
879*a67afe4dSAndroid Build Coastguard Worker png_bytep row_buf;
880*a67afe4dSAndroid Build Coastguard Worker png_uint_32 y;
881*a67afe4dSAndroid Build Coastguard Worker png_uint_32 width, height;
882*a67afe4dSAndroid Build Coastguard Worker int bit_depth, color_type;
883*a67afe4dSAndroid Build Coastguard Worker user_chunk_info my_user_chunk_data;
884*a67afe4dSAndroid Build Coastguard Worker int pass, num_passes;
885*a67afe4dSAndroid Build Coastguard Worker
886*a67afe4dSAndroid Build Coastguard Worker row_buf = NULL;
887*a67afe4dSAndroid Build Coastguard Worker error_parameters.file_name = inname;
888*a67afe4dSAndroid Build Coastguard Worker
889*a67afe4dSAndroid Build Coastguard Worker if ((fpin = fopen(inname, "rb")) == NULL)
890*a67afe4dSAndroid Build Coastguard Worker {
891*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "Could not find input file %s\n", inname);
892*a67afe4dSAndroid Build Coastguard Worker return 1;
893*a67afe4dSAndroid Build Coastguard Worker }
894*a67afe4dSAndroid Build Coastguard Worker
895*a67afe4dSAndroid Build Coastguard Worker if ((fpout = fopen(outname, "wb")) == NULL)
896*a67afe4dSAndroid Build Coastguard Worker {
897*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "Could not open output file %s\n", outname);
898*a67afe4dSAndroid Build Coastguard Worker fclose(fpin);
899*a67afe4dSAndroid Build Coastguard Worker return 1;
900*a67afe4dSAndroid Build Coastguard Worker }
901*a67afe4dSAndroid Build Coastguard Worker
902*a67afe4dSAndroid Build Coastguard Worker pngtest_debug("Allocating read and write structures");
903*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
904*a67afe4dSAndroid Build Coastguard Worker read_ptr =
905*a67afe4dSAndroid Build Coastguard Worker png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL,
906*a67afe4dSAndroid Build Coastguard Worker NULL, NULL, NULL, png_debug_malloc, png_debug_free);
907*a67afe4dSAndroid Build Coastguard Worker #else
908*a67afe4dSAndroid Build Coastguard Worker read_ptr =
909*a67afe4dSAndroid Build Coastguard Worker png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
910*a67afe4dSAndroid Build Coastguard Worker #endif
911*a67afe4dSAndroid Build Coastguard Worker png_set_error_fn(read_ptr, &error_parameters, pngtest_error,
912*a67afe4dSAndroid Build Coastguard Worker pngtest_warning);
913*a67afe4dSAndroid Build Coastguard Worker
914*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_SUPPORTED
915*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
916*a67afe4dSAndroid Build Coastguard Worker write_ptr =
917*a67afe4dSAndroid Build Coastguard Worker png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL,
918*a67afe4dSAndroid Build Coastguard Worker NULL, NULL, NULL, png_debug_malloc, png_debug_free);
919*a67afe4dSAndroid Build Coastguard Worker #else
920*a67afe4dSAndroid Build Coastguard Worker write_ptr =
921*a67afe4dSAndroid Build Coastguard Worker png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
922*a67afe4dSAndroid Build Coastguard Worker #endif
923*a67afe4dSAndroid Build Coastguard Worker png_set_error_fn(write_ptr, &error_parameters, pngtest_error,
924*a67afe4dSAndroid Build Coastguard Worker pngtest_warning);
925*a67afe4dSAndroid Build Coastguard Worker #endif
926*a67afe4dSAndroid Build Coastguard Worker pngtest_debug("Allocating read_info, write_info and end_info structures");
927*a67afe4dSAndroid Build Coastguard Worker read_info_ptr = png_create_info_struct(read_ptr);
928*a67afe4dSAndroid Build Coastguard Worker end_info_ptr = png_create_info_struct(read_ptr);
929*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_SUPPORTED
930*a67afe4dSAndroid Build Coastguard Worker write_info_ptr = png_create_info_struct(write_ptr);
931*a67afe4dSAndroid Build Coastguard Worker write_end_info_ptr = png_create_info_struct(write_ptr);
932*a67afe4dSAndroid Build Coastguard Worker #endif
933*a67afe4dSAndroid Build Coastguard Worker
934*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
935*a67afe4dSAndroid Build Coastguard Worker init_user_chunk_info(read_info_ptr, &my_user_chunk_data);
936*a67afe4dSAndroid Build Coastguard Worker png_set_read_user_chunk_fn(read_ptr, &my_user_chunk_data,
937*a67afe4dSAndroid Build Coastguard Worker read_user_chunk_callback);
938*a67afe4dSAndroid Build Coastguard Worker #endif
939*a67afe4dSAndroid Build Coastguard Worker
940*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_SETJMP_SUPPORTED
941*a67afe4dSAndroid Build Coastguard Worker pngtest_debug("Setting jmpbuf for read struct");
942*a67afe4dSAndroid Build Coastguard Worker if (setjmp(png_jmpbuf(read_ptr)))
943*a67afe4dSAndroid Build Coastguard Worker {
944*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
945*a67afe4dSAndroid Build Coastguard Worker png_free(read_ptr, row_buf);
946*a67afe4dSAndroid Build Coastguard Worker row_buf = NULL;
947*a67afe4dSAndroid Build Coastguard Worker if (verbose != 0)
948*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " destroy read structs\n");
949*a67afe4dSAndroid Build Coastguard Worker png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
950*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_SUPPORTED
951*a67afe4dSAndroid Build Coastguard Worker if (verbose != 0)
952*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " destroy write structs\n");
953*a67afe4dSAndroid Build Coastguard Worker png_destroy_info_struct(write_ptr, &write_end_info_ptr);
954*a67afe4dSAndroid Build Coastguard Worker png_destroy_write_struct(&write_ptr, &write_info_ptr);
955*a67afe4dSAndroid Build Coastguard Worker #endif
956*a67afe4dSAndroid Build Coastguard Worker fclose(fpin);
957*a67afe4dSAndroid Build Coastguard Worker fclose(fpout);
958*a67afe4dSAndroid Build Coastguard Worker return 1;
959*a67afe4dSAndroid Build Coastguard Worker }
960*a67afe4dSAndroid Build Coastguard Worker
961*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_SUPPORTED
962*a67afe4dSAndroid Build Coastguard Worker pngtest_debug("Setting jmpbuf for write struct");
963*a67afe4dSAndroid Build Coastguard Worker
964*a67afe4dSAndroid Build Coastguard Worker if (setjmp(png_jmpbuf(write_ptr)))
965*a67afe4dSAndroid Build Coastguard Worker {
966*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
967*a67afe4dSAndroid Build Coastguard Worker png_free(read_ptr, row_buf);
968*a67afe4dSAndroid Build Coastguard Worker row_buf = NULL;
969*a67afe4dSAndroid Build Coastguard Worker if (verbose != 0)
970*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " destroying read structs\n");
971*a67afe4dSAndroid Build Coastguard Worker png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
972*a67afe4dSAndroid Build Coastguard Worker if (verbose != 0)
973*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " destroying write structs\n");
974*a67afe4dSAndroid Build Coastguard Worker png_destroy_info_struct(write_ptr, &write_end_info_ptr);
975*a67afe4dSAndroid Build Coastguard Worker png_destroy_write_struct(&write_ptr, &write_info_ptr);
976*a67afe4dSAndroid Build Coastguard Worker fclose(fpin);
977*a67afe4dSAndroid Build Coastguard Worker fclose(fpout);
978*a67afe4dSAndroid Build Coastguard Worker return 1;
979*a67afe4dSAndroid Build Coastguard Worker }
980*a67afe4dSAndroid Build Coastguard Worker #endif
981*a67afe4dSAndroid Build Coastguard Worker #endif
982*a67afe4dSAndroid Build Coastguard Worker
983*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_BENIGN_ERRORS_SUPPORTED
984*a67afe4dSAndroid Build Coastguard Worker if (strict != 0)
985*a67afe4dSAndroid Build Coastguard Worker {
986*a67afe4dSAndroid Build Coastguard Worker /* Treat png_benign_error() as errors on read */
987*a67afe4dSAndroid Build Coastguard Worker png_set_benign_errors(read_ptr, 0);
988*a67afe4dSAndroid Build Coastguard Worker
989*a67afe4dSAndroid Build Coastguard Worker # ifdef PNG_WRITE_SUPPORTED
990*a67afe4dSAndroid Build Coastguard Worker /* Treat them as errors on write */
991*a67afe4dSAndroid Build Coastguard Worker png_set_benign_errors(write_ptr, 0);
992*a67afe4dSAndroid Build Coastguard Worker # endif
993*a67afe4dSAndroid Build Coastguard Worker
994*a67afe4dSAndroid Build Coastguard Worker /* if strict is not set, then app warnings and errors are treated as
995*a67afe4dSAndroid Build Coastguard Worker * warnings in release builds, but not in unstable builds; this can be
996*a67afe4dSAndroid Build Coastguard Worker * changed with '--relaxed'.
997*a67afe4dSAndroid Build Coastguard Worker */
998*a67afe4dSAndroid Build Coastguard Worker }
999*a67afe4dSAndroid Build Coastguard Worker
1000*a67afe4dSAndroid Build Coastguard Worker else if (relaxed != 0)
1001*a67afe4dSAndroid Build Coastguard Worker {
1002*a67afe4dSAndroid Build Coastguard Worker /* Allow application (pngtest) errors and warnings to pass */
1003*a67afe4dSAndroid Build Coastguard Worker png_set_benign_errors(read_ptr, 1);
1004*a67afe4dSAndroid Build Coastguard Worker
1005*a67afe4dSAndroid Build Coastguard Worker /* Turn off CRC checking while reading */
1006*a67afe4dSAndroid Build Coastguard Worker png_set_crc_action(read_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE);
1007*a67afe4dSAndroid Build Coastguard Worker
1008*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_IGNORE_ADLER32
1009*a67afe4dSAndroid Build Coastguard Worker /* Turn off ADLER32 checking while reading */
1010*a67afe4dSAndroid Build Coastguard Worker png_set_option(read_ptr, PNG_IGNORE_ADLER32, PNG_OPTION_ON);
1011*a67afe4dSAndroid Build Coastguard Worker #endif
1012*a67afe4dSAndroid Build Coastguard Worker
1013*a67afe4dSAndroid Build Coastguard Worker # ifdef PNG_WRITE_SUPPORTED
1014*a67afe4dSAndroid Build Coastguard Worker png_set_benign_errors(write_ptr, 1);
1015*a67afe4dSAndroid Build Coastguard Worker # endif
1016*a67afe4dSAndroid Build Coastguard Worker
1017*a67afe4dSAndroid Build Coastguard Worker }
1018*a67afe4dSAndroid Build Coastguard Worker #endif /* BENIGN_ERRORS */
1019*a67afe4dSAndroid Build Coastguard Worker
1020*a67afe4dSAndroid Build Coastguard Worker pngtest_debug("Initializing input and output streams");
1021*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_STDIO_SUPPORTED
1022*a67afe4dSAndroid Build Coastguard Worker png_init_io(read_ptr, fpin);
1023*a67afe4dSAndroid Build Coastguard Worker # ifdef PNG_WRITE_SUPPORTED
1024*a67afe4dSAndroid Build Coastguard Worker png_init_io(write_ptr, fpout);
1025*a67afe4dSAndroid Build Coastguard Worker # endif
1026*a67afe4dSAndroid Build Coastguard Worker #else
1027*a67afe4dSAndroid Build Coastguard Worker png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data);
1028*a67afe4dSAndroid Build Coastguard Worker # ifdef PNG_WRITE_SUPPORTED
1029*a67afe4dSAndroid Build Coastguard Worker png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data,
1030*a67afe4dSAndroid Build Coastguard Worker # ifdef PNG_WRITE_FLUSH_SUPPORTED
1031*a67afe4dSAndroid Build Coastguard Worker pngtest_flush);
1032*a67afe4dSAndroid Build Coastguard Worker # else
1033*a67afe4dSAndroid Build Coastguard Worker NULL);
1034*a67afe4dSAndroid Build Coastguard Worker # endif
1035*a67afe4dSAndroid Build Coastguard Worker # endif
1036*a67afe4dSAndroid Build Coastguard Worker #endif
1037*a67afe4dSAndroid Build Coastguard Worker
1038*a67afe4dSAndroid Build Coastguard Worker if (status_dots_requested == 1)
1039*a67afe4dSAndroid Build Coastguard Worker {
1040*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_SUPPORTED
1041*a67afe4dSAndroid Build Coastguard Worker png_set_write_status_fn(write_ptr, write_row_callback);
1042*a67afe4dSAndroid Build Coastguard Worker #endif
1043*a67afe4dSAndroid Build Coastguard Worker png_set_read_status_fn(read_ptr, read_row_callback);
1044*a67afe4dSAndroid Build Coastguard Worker }
1045*a67afe4dSAndroid Build Coastguard Worker
1046*a67afe4dSAndroid Build Coastguard Worker else
1047*a67afe4dSAndroid Build Coastguard Worker {
1048*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_SUPPORTED
1049*a67afe4dSAndroid Build Coastguard Worker png_set_write_status_fn(write_ptr, NULL);
1050*a67afe4dSAndroid Build Coastguard Worker #endif
1051*a67afe4dSAndroid Build Coastguard Worker png_set_read_status_fn(read_ptr, NULL);
1052*a67afe4dSAndroid Build Coastguard Worker }
1053*a67afe4dSAndroid Build Coastguard Worker
1054*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
1055*a67afe4dSAndroid Build Coastguard Worker png_set_read_user_transform_fn(read_ptr, read_user_callback);
1056*a67afe4dSAndroid Build Coastguard Worker #endif
1057*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
1058*a67afe4dSAndroid Build Coastguard Worker zero_samples = 0;
1059*a67afe4dSAndroid Build Coastguard Worker png_set_write_user_transform_fn(write_ptr, count_zero_samples);
1060*a67afe4dSAndroid Build Coastguard Worker #endif
1061*a67afe4dSAndroid Build Coastguard Worker
1062*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
1063*a67afe4dSAndroid Build Coastguard Worker /* Preserve all the unknown chunks, if possible. If this is disabled, then
1064*a67afe4dSAndroid Build Coastguard Worker * even if the png_{get,set}_unknown_chunks stuff is enabled, we can't use
1065*a67afe4dSAndroid Build Coastguard Worker * libpng to *save* the unknown chunks on read (because we can't switch the
1066*a67afe4dSAndroid Build Coastguard Worker * save option on!)
1067*a67afe4dSAndroid Build Coastguard Worker *
1068*a67afe4dSAndroid Build Coastguard Worker * Notice that if SET_UNKNOWN_CHUNKS is *not* supported, the reader will
1069*a67afe4dSAndroid Build Coastguard Worker * discard all unknown chunks, and the writer will write them all.
1070*a67afe4dSAndroid Build Coastguard Worker */
1071*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
1072*a67afe4dSAndroid Build Coastguard Worker png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS,
1073*a67afe4dSAndroid Build Coastguard Worker NULL, 0);
1074*a67afe4dSAndroid Build Coastguard Worker #endif
1075*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
1076*a67afe4dSAndroid Build Coastguard Worker png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS,
1077*a67afe4dSAndroid Build Coastguard Worker NULL, 0);
1078*a67afe4dSAndroid Build Coastguard Worker #endif
1079*a67afe4dSAndroid Build Coastguard Worker #endif
1080*a67afe4dSAndroid Build Coastguard Worker
1081*a67afe4dSAndroid Build Coastguard Worker pngtest_debug("Reading info struct");
1082*a67afe4dSAndroid Build Coastguard Worker png_read_info(read_ptr, read_info_ptr);
1083*a67afe4dSAndroid Build Coastguard Worker
1084*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
1085*a67afe4dSAndroid Build Coastguard Worker /* This is a bit of a hack; there is no obvious way in the callback function
1086*a67afe4dSAndroid Build Coastguard Worker * to determine that the chunks before the first IDAT have been read, so
1087*a67afe4dSAndroid Build Coastguard Worker * remove the info_ptr (which is only used to determine position relative to
1088*a67afe4dSAndroid Build Coastguard Worker * PLTE) here to indicate that we are after the IDAT.
1089*a67afe4dSAndroid Build Coastguard Worker */
1090*a67afe4dSAndroid Build Coastguard Worker my_user_chunk_data.info_ptr = NULL;
1091*a67afe4dSAndroid Build Coastguard Worker #endif
1092*a67afe4dSAndroid Build Coastguard Worker
1093*a67afe4dSAndroid Build Coastguard Worker pngtest_debug("Transferring info struct");
1094*a67afe4dSAndroid Build Coastguard Worker {
1095*a67afe4dSAndroid Build Coastguard Worker int interlace_type, compression_type, filter_type;
1096*a67afe4dSAndroid Build Coastguard Worker
1097*a67afe4dSAndroid Build Coastguard Worker if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
1098*a67afe4dSAndroid Build Coastguard Worker &color_type, &interlace_type, &compression_type, &filter_type) != 0)
1099*a67afe4dSAndroid Build Coastguard Worker {
1100*a67afe4dSAndroid Build Coastguard Worker png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
1101*a67afe4dSAndroid Build Coastguard Worker color_type, interlace_type, compression_type, filter_type);
1102*a67afe4dSAndroid Build Coastguard Worker /* num_passes may not be available below if interlace support is not
1103*a67afe4dSAndroid Build Coastguard Worker * provided by libpng for both read and write.
1104*a67afe4dSAndroid Build Coastguard Worker */
1105*a67afe4dSAndroid Build Coastguard Worker switch (interlace_type)
1106*a67afe4dSAndroid Build Coastguard Worker {
1107*a67afe4dSAndroid Build Coastguard Worker case PNG_INTERLACE_NONE:
1108*a67afe4dSAndroid Build Coastguard Worker num_passes = 1;
1109*a67afe4dSAndroid Build Coastguard Worker break;
1110*a67afe4dSAndroid Build Coastguard Worker
1111*a67afe4dSAndroid Build Coastguard Worker case PNG_INTERLACE_ADAM7:
1112*a67afe4dSAndroid Build Coastguard Worker num_passes = 7;
1113*a67afe4dSAndroid Build Coastguard Worker break;
1114*a67afe4dSAndroid Build Coastguard Worker
1115*a67afe4dSAndroid Build Coastguard Worker default:
1116*a67afe4dSAndroid Build Coastguard Worker png_error(read_ptr, "invalid interlace type");
1117*a67afe4dSAndroid Build Coastguard Worker /*NOT REACHED*/
1118*a67afe4dSAndroid Build Coastguard Worker }
1119*a67afe4dSAndroid Build Coastguard Worker }
1120*a67afe4dSAndroid Build Coastguard Worker
1121*a67afe4dSAndroid Build Coastguard Worker else
1122*a67afe4dSAndroid Build Coastguard Worker png_error(read_ptr, "png_get_IHDR failed");
1123*a67afe4dSAndroid Build Coastguard Worker }
1124*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_FIXED_POINT_SUPPORTED
1125*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_cHRM_SUPPORTED
1126*a67afe4dSAndroid Build Coastguard Worker {
1127*a67afe4dSAndroid Build Coastguard Worker png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
1128*a67afe4dSAndroid Build Coastguard Worker blue_y;
1129*a67afe4dSAndroid Build Coastguard Worker
1130*a67afe4dSAndroid Build Coastguard Worker if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y,
1131*a67afe4dSAndroid Build Coastguard Worker &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
1132*a67afe4dSAndroid Build Coastguard Worker {
1133*a67afe4dSAndroid Build Coastguard Worker png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x,
1134*a67afe4dSAndroid Build Coastguard Worker red_y, green_x, green_y, blue_x, blue_y);
1135*a67afe4dSAndroid Build Coastguard Worker }
1136*a67afe4dSAndroid Build Coastguard Worker }
1137*a67afe4dSAndroid Build Coastguard Worker #endif
1138*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_gAMA_SUPPORTED
1139*a67afe4dSAndroid Build Coastguard Worker {
1140*a67afe4dSAndroid Build Coastguard Worker png_fixed_point gamma;
1141*a67afe4dSAndroid Build Coastguard Worker
1142*a67afe4dSAndroid Build Coastguard Worker if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma) != 0)
1143*a67afe4dSAndroid Build Coastguard Worker png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma);
1144*a67afe4dSAndroid Build Coastguard Worker }
1145*a67afe4dSAndroid Build Coastguard Worker #endif
1146*a67afe4dSAndroid Build Coastguard Worker #else /* Use floating point versions */
1147*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_FLOATING_POINT_SUPPORTED
1148*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_cHRM_SUPPORTED
1149*a67afe4dSAndroid Build Coastguard Worker {
1150*a67afe4dSAndroid Build Coastguard Worker double white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
1151*a67afe4dSAndroid Build Coastguard Worker blue_y;
1152*a67afe4dSAndroid Build Coastguard Worker
1153*a67afe4dSAndroid Build Coastguard Worker if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
1154*a67afe4dSAndroid Build Coastguard Worker &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
1155*a67afe4dSAndroid Build Coastguard Worker {
1156*a67afe4dSAndroid Build Coastguard Worker png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
1157*a67afe4dSAndroid Build Coastguard Worker red_y, green_x, green_y, blue_x, blue_y);
1158*a67afe4dSAndroid Build Coastguard Worker }
1159*a67afe4dSAndroid Build Coastguard Worker }
1160*a67afe4dSAndroid Build Coastguard Worker #endif
1161*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_gAMA_SUPPORTED
1162*a67afe4dSAndroid Build Coastguard Worker {
1163*a67afe4dSAndroid Build Coastguard Worker double gamma;
1164*a67afe4dSAndroid Build Coastguard Worker
1165*a67afe4dSAndroid Build Coastguard Worker if (png_get_gAMA(read_ptr, read_info_ptr, &gamma) != 0)
1166*a67afe4dSAndroid Build Coastguard Worker png_set_gAMA(write_ptr, write_info_ptr, gamma);
1167*a67afe4dSAndroid Build Coastguard Worker }
1168*a67afe4dSAndroid Build Coastguard Worker #endif
1169*a67afe4dSAndroid Build Coastguard Worker #endif /* Floating point */
1170*a67afe4dSAndroid Build Coastguard Worker #endif /* Fixed point */
1171*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_iCCP_SUPPORTED
1172*a67afe4dSAndroid Build Coastguard Worker {
1173*a67afe4dSAndroid Build Coastguard Worker png_charp name;
1174*a67afe4dSAndroid Build Coastguard Worker png_bytep profile;
1175*a67afe4dSAndroid Build Coastguard Worker png_uint_32 proflen;
1176*a67afe4dSAndroid Build Coastguard Worker int compression_type;
1177*a67afe4dSAndroid Build Coastguard Worker
1178*a67afe4dSAndroid Build Coastguard Worker if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,
1179*a67afe4dSAndroid Build Coastguard Worker &profile, &proflen) != 0)
1180*a67afe4dSAndroid Build Coastguard Worker {
1181*a67afe4dSAndroid Build Coastguard Worker png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,
1182*a67afe4dSAndroid Build Coastguard Worker profile, proflen);
1183*a67afe4dSAndroid Build Coastguard Worker }
1184*a67afe4dSAndroid Build Coastguard Worker }
1185*a67afe4dSAndroid Build Coastguard Worker #endif
1186*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_sRGB_SUPPORTED
1187*a67afe4dSAndroid Build Coastguard Worker {
1188*a67afe4dSAndroid Build Coastguard Worker int intent;
1189*a67afe4dSAndroid Build Coastguard Worker
1190*a67afe4dSAndroid Build Coastguard Worker if (png_get_sRGB(read_ptr, read_info_ptr, &intent) != 0)
1191*a67afe4dSAndroid Build Coastguard Worker png_set_sRGB(write_ptr, write_info_ptr, intent);
1192*a67afe4dSAndroid Build Coastguard Worker }
1193*a67afe4dSAndroid Build Coastguard Worker #endif
1194*a67afe4dSAndroid Build Coastguard Worker {
1195*a67afe4dSAndroid Build Coastguard Worker png_colorp palette;
1196*a67afe4dSAndroid Build Coastguard Worker int num_palette;
1197*a67afe4dSAndroid Build Coastguard Worker
1198*a67afe4dSAndroid Build Coastguard Worker if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette) != 0)
1199*a67afe4dSAndroid Build Coastguard Worker png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
1200*a67afe4dSAndroid Build Coastguard Worker }
1201*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_bKGD_SUPPORTED
1202*a67afe4dSAndroid Build Coastguard Worker {
1203*a67afe4dSAndroid Build Coastguard Worker png_color_16p background;
1204*a67afe4dSAndroid Build Coastguard Worker
1205*a67afe4dSAndroid Build Coastguard Worker if (png_get_bKGD(read_ptr, read_info_ptr, &background) != 0)
1206*a67afe4dSAndroid Build Coastguard Worker png_set_bKGD(write_ptr, write_info_ptr, background);
1207*a67afe4dSAndroid Build Coastguard Worker }
1208*a67afe4dSAndroid Build Coastguard Worker #endif
1209*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_READ_eXIf_SUPPORTED
1210*a67afe4dSAndroid Build Coastguard Worker {
1211*a67afe4dSAndroid Build Coastguard Worker png_bytep exif = NULL;
1212*a67afe4dSAndroid Build Coastguard Worker png_uint_32 exif_length;
1213*a67afe4dSAndroid Build Coastguard Worker
1214*a67afe4dSAndroid Build Coastguard Worker if (png_get_eXIf_1(read_ptr, read_info_ptr, &exif_length, &exif) != 0)
1215*a67afe4dSAndroid Build Coastguard Worker {
1216*a67afe4dSAndroid Build Coastguard Worker if (exif_length > 1)
1217*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR," eXIf type %c%c, %lu bytes\n",exif[0],exif[1],
1218*a67afe4dSAndroid Build Coastguard Worker (unsigned long)exif_length);
1219*a67afe4dSAndroid Build Coastguard Worker # ifdef PNG_WRITE_eXIf_SUPPORTED
1220*a67afe4dSAndroid Build Coastguard Worker png_set_eXIf_1(write_ptr, write_info_ptr, exif_length, exif);
1221*a67afe4dSAndroid Build Coastguard Worker # endif
1222*a67afe4dSAndroid Build Coastguard Worker }
1223*a67afe4dSAndroid Build Coastguard Worker }
1224*a67afe4dSAndroid Build Coastguard Worker #endif
1225*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_hIST_SUPPORTED
1226*a67afe4dSAndroid Build Coastguard Worker {
1227*a67afe4dSAndroid Build Coastguard Worker png_uint_16p hist;
1228*a67afe4dSAndroid Build Coastguard Worker
1229*a67afe4dSAndroid Build Coastguard Worker if (png_get_hIST(read_ptr, read_info_ptr, &hist) != 0)
1230*a67afe4dSAndroid Build Coastguard Worker png_set_hIST(write_ptr, write_info_ptr, hist);
1231*a67afe4dSAndroid Build Coastguard Worker }
1232*a67afe4dSAndroid Build Coastguard Worker #endif
1233*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_oFFs_SUPPORTED
1234*a67afe4dSAndroid Build Coastguard Worker {
1235*a67afe4dSAndroid Build Coastguard Worker png_int_32 offset_x, offset_y;
1236*a67afe4dSAndroid Build Coastguard Worker int unit_type;
1237*a67afe4dSAndroid Build Coastguard Worker
1238*a67afe4dSAndroid Build Coastguard Worker if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y,
1239*a67afe4dSAndroid Build Coastguard Worker &unit_type) != 0)
1240*a67afe4dSAndroid Build Coastguard Worker png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
1241*a67afe4dSAndroid Build Coastguard Worker }
1242*a67afe4dSAndroid Build Coastguard Worker #endif
1243*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_pCAL_SUPPORTED
1244*a67afe4dSAndroid Build Coastguard Worker {
1245*a67afe4dSAndroid Build Coastguard Worker png_charp purpose, units;
1246*a67afe4dSAndroid Build Coastguard Worker png_charpp params;
1247*a67afe4dSAndroid Build Coastguard Worker png_int_32 X0, X1;
1248*a67afe4dSAndroid Build Coastguard Worker int type, nparams;
1249*a67afe4dSAndroid Build Coastguard Worker
1250*a67afe4dSAndroid Build Coastguard Worker if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
1251*a67afe4dSAndroid Build Coastguard Worker &nparams, &units, ¶ms) != 0)
1252*a67afe4dSAndroid Build Coastguard Worker png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
1253*a67afe4dSAndroid Build Coastguard Worker nparams, units, params);
1254*a67afe4dSAndroid Build Coastguard Worker }
1255*a67afe4dSAndroid Build Coastguard Worker #endif
1256*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_pHYs_SUPPORTED
1257*a67afe4dSAndroid Build Coastguard Worker {
1258*a67afe4dSAndroid Build Coastguard Worker png_uint_32 res_x, res_y;
1259*a67afe4dSAndroid Build Coastguard Worker int unit_type;
1260*a67afe4dSAndroid Build Coastguard Worker
1261*a67afe4dSAndroid Build Coastguard Worker if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y,
1262*a67afe4dSAndroid Build Coastguard Worker &unit_type) != 0)
1263*a67afe4dSAndroid Build Coastguard Worker png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
1264*a67afe4dSAndroid Build Coastguard Worker }
1265*a67afe4dSAndroid Build Coastguard Worker #endif
1266*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_sBIT_SUPPORTED
1267*a67afe4dSAndroid Build Coastguard Worker {
1268*a67afe4dSAndroid Build Coastguard Worker png_color_8p sig_bit;
1269*a67afe4dSAndroid Build Coastguard Worker
1270*a67afe4dSAndroid Build Coastguard Worker if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit) != 0)
1271*a67afe4dSAndroid Build Coastguard Worker png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
1272*a67afe4dSAndroid Build Coastguard Worker }
1273*a67afe4dSAndroid Build Coastguard Worker #endif
1274*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_sCAL_SUPPORTED
1275*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_FLOATING_POINT_SUPPORTED) && \
1276*a67afe4dSAndroid Build Coastguard Worker defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
1277*a67afe4dSAndroid Build Coastguard Worker {
1278*a67afe4dSAndroid Build Coastguard Worker int unit;
1279*a67afe4dSAndroid Build Coastguard Worker double scal_width, scal_height;
1280*a67afe4dSAndroid Build Coastguard Worker
1281*a67afe4dSAndroid Build Coastguard Worker if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,
1282*a67afe4dSAndroid Build Coastguard Worker &scal_height) != 0)
1283*a67afe4dSAndroid Build Coastguard Worker png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);
1284*a67afe4dSAndroid Build Coastguard Worker }
1285*a67afe4dSAndroid Build Coastguard Worker #else
1286*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_FIXED_POINT_SUPPORTED
1287*a67afe4dSAndroid Build Coastguard Worker {
1288*a67afe4dSAndroid Build Coastguard Worker int unit;
1289*a67afe4dSAndroid Build Coastguard Worker png_charp scal_width, scal_height;
1290*a67afe4dSAndroid Build Coastguard Worker
1291*a67afe4dSAndroid Build Coastguard Worker if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,
1292*a67afe4dSAndroid Build Coastguard Worker &scal_height) != 0)
1293*a67afe4dSAndroid Build Coastguard Worker {
1294*a67afe4dSAndroid Build Coastguard Worker png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width,
1295*a67afe4dSAndroid Build Coastguard Worker scal_height);
1296*a67afe4dSAndroid Build Coastguard Worker }
1297*a67afe4dSAndroid Build Coastguard Worker }
1298*a67afe4dSAndroid Build Coastguard Worker #endif
1299*a67afe4dSAndroid Build Coastguard Worker #endif
1300*a67afe4dSAndroid Build Coastguard Worker #endif
1301*a67afe4dSAndroid Build Coastguard Worker
1302*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_sPLT_SUPPORTED
1303*a67afe4dSAndroid Build Coastguard Worker {
1304*a67afe4dSAndroid Build Coastguard Worker png_sPLT_tp entries;
1305*a67afe4dSAndroid Build Coastguard Worker
1306*a67afe4dSAndroid Build Coastguard Worker int num_entries = png_get_sPLT(read_ptr, read_info_ptr, &entries);
1307*a67afe4dSAndroid Build Coastguard Worker if (num_entries != 0)
1308*a67afe4dSAndroid Build Coastguard Worker png_set_sPLT(write_ptr, write_info_ptr, entries, num_entries);
1309*a67afe4dSAndroid Build Coastguard Worker }
1310*a67afe4dSAndroid Build Coastguard Worker #endif
1311*a67afe4dSAndroid Build Coastguard Worker
1312*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_TEXT_SUPPORTED
1313*a67afe4dSAndroid Build Coastguard Worker {
1314*a67afe4dSAndroid Build Coastguard Worker png_textp text_ptr;
1315*a67afe4dSAndroid Build Coastguard Worker int num_text;
1316*a67afe4dSAndroid Build Coastguard Worker
1317*a67afe4dSAndroid Build Coastguard Worker if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
1318*a67afe4dSAndroid Build Coastguard Worker {
1319*a67afe4dSAndroid Build Coastguard Worker pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text);
1320*a67afe4dSAndroid Build Coastguard Worker
1321*a67afe4dSAndroid Build Coastguard Worker pngtest_check_text_support(read_ptr, text_ptr, num_text);
1322*a67afe4dSAndroid Build Coastguard Worker
1323*a67afe4dSAndroid Build Coastguard Worker if (verbose != 0)
1324*a67afe4dSAndroid Build Coastguard Worker {
1325*a67afe4dSAndroid Build Coastguard Worker int i;
1326*a67afe4dSAndroid Build Coastguard Worker
1327*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR,"\n");
1328*a67afe4dSAndroid Build Coastguard Worker for (i = 0; i < num_text; i++)
1329*a67afe4dSAndroid Build Coastguard Worker {
1330*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR," Text compression[%d]=%d\n",
1331*a67afe4dSAndroid Build Coastguard Worker i, text_ptr[i].compression);
1332*a67afe4dSAndroid Build Coastguard Worker }
1333*a67afe4dSAndroid Build Coastguard Worker }
1334*a67afe4dSAndroid Build Coastguard Worker
1335*a67afe4dSAndroid Build Coastguard Worker png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
1336*a67afe4dSAndroid Build Coastguard Worker }
1337*a67afe4dSAndroid Build Coastguard Worker }
1338*a67afe4dSAndroid Build Coastguard Worker #endif
1339*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_tIME_SUPPORTED
1340*a67afe4dSAndroid Build Coastguard Worker {
1341*a67afe4dSAndroid Build Coastguard Worker png_timep mod_time;
1342*a67afe4dSAndroid Build Coastguard Worker
1343*a67afe4dSAndroid Build Coastguard Worker if (png_get_tIME(read_ptr, read_info_ptr, &mod_time) != 0)
1344*a67afe4dSAndroid Build Coastguard Worker {
1345*a67afe4dSAndroid Build Coastguard Worker png_set_tIME(write_ptr, write_info_ptr, mod_time);
1346*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_TIME_RFC1123_SUPPORTED
1347*a67afe4dSAndroid Build Coastguard Worker if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0)
1348*a67afe4dSAndroid Build Coastguard Worker tIME_string[(sizeof tIME_string) - 1] = '\0';
1349*a67afe4dSAndroid Build Coastguard Worker
1350*a67afe4dSAndroid Build Coastguard Worker else
1351*a67afe4dSAndroid Build Coastguard Worker {
1352*a67afe4dSAndroid Build Coastguard Worker strncpy(tIME_string, "*** invalid time ***", (sizeof tIME_string));
1353*a67afe4dSAndroid Build Coastguard Worker tIME_string[(sizeof tIME_string) - 1] = '\0';
1354*a67afe4dSAndroid Build Coastguard Worker }
1355*a67afe4dSAndroid Build Coastguard Worker
1356*a67afe4dSAndroid Build Coastguard Worker tIME_chunk_present++;
1357*a67afe4dSAndroid Build Coastguard Worker #endif /* TIME_RFC1123 */
1358*a67afe4dSAndroid Build Coastguard Worker }
1359*a67afe4dSAndroid Build Coastguard Worker }
1360*a67afe4dSAndroid Build Coastguard Worker #endif
1361*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_tRNS_SUPPORTED
1362*a67afe4dSAndroid Build Coastguard Worker {
1363*a67afe4dSAndroid Build Coastguard Worker png_bytep trans_alpha;
1364*a67afe4dSAndroid Build Coastguard Worker int num_trans;
1365*a67afe4dSAndroid Build Coastguard Worker png_color_16p trans_color;
1366*a67afe4dSAndroid Build Coastguard Worker
1367*a67afe4dSAndroid Build Coastguard Worker if (png_get_tRNS(read_ptr, read_info_ptr, &trans_alpha, &num_trans,
1368*a67afe4dSAndroid Build Coastguard Worker &trans_color) != 0)
1369*a67afe4dSAndroid Build Coastguard Worker {
1370*a67afe4dSAndroid Build Coastguard Worker int sample_max = (1 << bit_depth);
1371*a67afe4dSAndroid Build Coastguard Worker /* libpng doesn't reject a tRNS chunk with out-of-range samples */
1372*a67afe4dSAndroid Build Coastguard Worker if (!((color_type == PNG_COLOR_TYPE_GRAY &&
1373*a67afe4dSAndroid Build Coastguard Worker (int)trans_color->gray > sample_max) ||
1374*a67afe4dSAndroid Build Coastguard Worker (color_type == PNG_COLOR_TYPE_RGB &&
1375*a67afe4dSAndroid Build Coastguard Worker ((int)trans_color->red > sample_max ||
1376*a67afe4dSAndroid Build Coastguard Worker (int)trans_color->green > sample_max ||
1377*a67afe4dSAndroid Build Coastguard Worker (int)trans_color->blue > sample_max))))
1378*a67afe4dSAndroid Build Coastguard Worker png_set_tRNS(write_ptr, write_info_ptr, trans_alpha, num_trans,
1379*a67afe4dSAndroid Build Coastguard Worker trans_color);
1380*a67afe4dSAndroid Build Coastguard Worker }
1381*a67afe4dSAndroid Build Coastguard Worker }
1382*a67afe4dSAndroid Build Coastguard Worker #endif
1383*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
1384*a67afe4dSAndroid Build Coastguard Worker {
1385*a67afe4dSAndroid Build Coastguard Worker png_unknown_chunkp unknowns;
1386*a67afe4dSAndroid Build Coastguard Worker int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr,
1387*a67afe4dSAndroid Build Coastguard Worker &unknowns);
1388*a67afe4dSAndroid Build Coastguard Worker
1389*a67afe4dSAndroid Build Coastguard Worker if (num_unknowns != 0)
1390*a67afe4dSAndroid Build Coastguard Worker png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns,
1391*a67afe4dSAndroid Build Coastguard Worker num_unknowns);
1392*a67afe4dSAndroid Build Coastguard Worker }
1393*a67afe4dSAndroid Build Coastguard Worker #endif
1394*a67afe4dSAndroid Build Coastguard Worker
1395*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_SUPPORTED
1396*a67afe4dSAndroid Build Coastguard Worker pngtest_debug("Writing info struct");
1397*a67afe4dSAndroid Build Coastguard Worker
1398*a67afe4dSAndroid Build Coastguard Worker /* Write the info in two steps so that if we write the 'unknown' chunks here
1399*a67afe4dSAndroid Build Coastguard Worker * they go to the correct place.
1400*a67afe4dSAndroid Build Coastguard Worker */
1401*a67afe4dSAndroid Build Coastguard Worker png_write_info_before_PLTE(write_ptr, write_info_ptr);
1402*a67afe4dSAndroid Build Coastguard Worker
1403*a67afe4dSAndroid Build Coastguard Worker write_chunks(write_ptr, &my_user_chunk_data, before_PLTE); /* before PLTE */
1404*a67afe4dSAndroid Build Coastguard Worker
1405*a67afe4dSAndroid Build Coastguard Worker png_write_info(write_ptr, write_info_ptr);
1406*a67afe4dSAndroid Build Coastguard Worker
1407*a67afe4dSAndroid Build Coastguard Worker write_chunks(write_ptr, &my_user_chunk_data, before_IDAT); /* after PLTE */
1408*a67afe4dSAndroid Build Coastguard Worker
1409*a67afe4dSAndroid Build Coastguard Worker png_write_info(write_ptr, write_end_info_ptr);
1410*a67afe4dSAndroid Build Coastguard Worker
1411*a67afe4dSAndroid Build Coastguard Worker write_chunks(write_ptr, &my_user_chunk_data, after_IDAT); /* after IDAT */
1412*a67afe4dSAndroid Build Coastguard Worker
1413*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_COMPRESSION_COMPAT
1414*a67afe4dSAndroid Build Coastguard Worker /* Test the 'compatibility' setting here, if it is available. */
1415*a67afe4dSAndroid Build Coastguard Worker png_set_compression(write_ptr, PNG_COMPRESSION_COMPAT);
1416*a67afe4dSAndroid Build Coastguard Worker #endif
1417*a67afe4dSAndroid Build Coastguard Worker #endif
1418*a67afe4dSAndroid Build Coastguard Worker
1419*a67afe4dSAndroid Build Coastguard Worker pngtest_debug("Writing row data");
1420*a67afe4dSAndroid Build Coastguard Worker
1421*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_READ_INTERLACING_SUPPORTED) &&\
1422*a67afe4dSAndroid Build Coastguard Worker defined(PNG_WRITE_INTERLACING_SUPPORTED)
1423*a67afe4dSAndroid Build Coastguard Worker /* Both must be defined for libpng to be able to handle the interlace,
1424*a67afe4dSAndroid Build Coastguard Worker * otherwise it gets handled below by simply reading and writing the passes
1425*a67afe4dSAndroid Build Coastguard Worker * directly.
1426*a67afe4dSAndroid Build Coastguard Worker */
1427*a67afe4dSAndroid Build Coastguard Worker if (png_set_interlace_handling(read_ptr) != num_passes)
1428*a67afe4dSAndroid Build Coastguard Worker png_error(write_ptr,
1429*a67afe4dSAndroid Build Coastguard Worker "png_set_interlace_handling(read): wrong pass count ");
1430*a67afe4dSAndroid Build Coastguard Worker if (png_set_interlace_handling(write_ptr) != num_passes)
1431*a67afe4dSAndroid Build Coastguard Worker png_error(write_ptr,
1432*a67afe4dSAndroid Build Coastguard Worker "png_set_interlace_handling(write): wrong pass count ");
1433*a67afe4dSAndroid Build Coastguard Worker #else /* png_set_interlace_handling not called on either read or write */
1434*a67afe4dSAndroid Build Coastguard Worker # define calc_pass_height
1435*a67afe4dSAndroid Build Coastguard Worker #endif /* not using libpng interlace handling */
1436*a67afe4dSAndroid Build Coastguard Worker
1437*a67afe4dSAndroid Build Coastguard Worker #ifdef PNGTEST_TIMING
1438*a67afe4dSAndroid Build Coastguard Worker t_stop = (float)clock();
1439*a67afe4dSAndroid Build Coastguard Worker t_misc += (t_stop - t_start);
1440*a67afe4dSAndroid Build Coastguard Worker t_start = t_stop;
1441*a67afe4dSAndroid Build Coastguard Worker #endif
1442*a67afe4dSAndroid Build Coastguard Worker for (pass = 0; pass < num_passes; pass++)
1443*a67afe4dSAndroid Build Coastguard Worker {
1444*a67afe4dSAndroid Build Coastguard Worker # ifdef calc_pass_height
1445*a67afe4dSAndroid Build Coastguard Worker png_uint_32 pass_height;
1446*a67afe4dSAndroid Build Coastguard Worker
1447*a67afe4dSAndroid Build Coastguard Worker if (num_passes == 7) /* interlaced */
1448*a67afe4dSAndroid Build Coastguard Worker {
1449*a67afe4dSAndroid Build Coastguard Worker if (PNG_PASS_COLS(width, pass) > 0)
1450*a67afe4dSAndroid Build Coastguard Worker pass_height = PNG_PASS_ROWS(height, pass);
1451*a67afe4dSAndroid Build Coastguard Worker
1452*a67afe4dSAndroid Build Coastguard Worker else
1453*a67afe4dSAndroid Build Coastguard Worker pass_height = 0;
1454*a67afe4dSAndroid Build Coastguard Worker }
1455*a67afe4dSAndroid Build Coastguard Worker
1456*a67afe4dSAndroid Build Coastguard Worker else /* not interlaced */
1457*a67afe4dSAndroid Build Coastguard Worker pass_height = height;
1458*a67afe4dSAndroid Build Coastguard Worker # else
1459*a67afe4dSAndroid Build Coastguard Worker # define pass_height height
1460*a67afe4dSAndroid Build Coastguard Worker # endif
1461*a67afe4dSAndroid Build Coastguard Worker
1462*a67afe4dSAndroid Build Coastguard Worker pngtest_debug1("Writing row data for pass %d", pass);
1463*a67afe4dSAndroid Build Coastguard Worker for (y = 0; y < pass_height; y++)
1464*a67afe4dSAndroid Build Coastguard Worker {
1465*a67afe4dSAndroid Build Coastguard Worker pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y);
1466*a67afe4dSAndroid Build Coastguard Worker
1467*a67afe4dSAndroid Build Coastguard Worker row_buf = (png_bytep)png_malloc(read_ptr,
1468*a67afe4dSAndroid Build Coastguard Worker png_get_rowbytes(read_ptr, read_info_ptr));
1469*a67afe4dSAndroid Build Coastguard Worker
1470*a67afe4dSAndroid Build Coastguard Worker pngtest_debug2("\t%p (%lu bytes)", row_buf,
1471*a67afe4dSAndroid Build Coastguard Worker (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr));
1472*a67afe4dSAndroid Build Coastguard Worker
1473*a67afe4dSAndroid Build Coastguard Worker png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1);
1474*a67afe4dSAndroid Build Coastguard Worker
1475*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_SUPPORTED
1476*a67afe4dSAndroid Build Coastguard Worker #ifdef PNGTEST_TIMING
1477*a67afe4dSAndroid Build Coastguard Worker t_stop = (float)clock();
1478*a67afe4dSAndroid Build Coastguard Worker t_decode += (t_stop - t_start);
1479*a67afe4dSAndroid Build Coastguard Worker t_start = t_stop;
1480*a67afe4dSAndroid Build Coastguard Worker #endif
1481*a67afe4dSAndroid Build Coastguard Worker png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
1482*a67afe4dSAndroid Build Coastguard Worker #ifdef PNGTEST_TIMING
1483*a67afe4dSAndroid Build Coastguard Worker t_stop = (float)clock();
1484*a67afe4dSAndroid Build Coastguard Worker t_encode += (t_stop - t_start);
1485*a67afe4dSAndroid Build Coastguard Worker t_start = t_stop;
1486*a67afe4dSAndroid Build Coastguard Worker #endif
1487*a67afe4dSAndroid Build Coastguard Worker #endif /* WRITE */
1488*a67afe4dSAndroid Build Coastguard Worker
1489*a67afe4dSAndroid Build Coastguard Worker pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y);
1490*a67afe4dSAndroid Build Coastguard Worker png_free(read_ptr, row_buf);
1491*a67afe4dSAndroid Build Coastguard Worker row_buf = NULL;
1492*a67afe4dSAndroid Build Coastguard Worker }
1493*a67afe4dSAndroid Build Coastguard Worker }
1494*a67afe4dSAndroid Build Coastguard Worker
1495*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
1496*a67afe4dSAndroid Build Coastguard Worker # ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
1497*a67afe4dSAndroid Build Coastguard Worker png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1);
1498*a67afe4dSAndroid Build Coastguard Worker # endif
1499*a67afe4dSAndroid Build Coastguard Worker # ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
1500*a67afe4dSAndroid Build Coastguard Worker png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1);
1501*a67afe4dSAndroid Build Coastguard Worker # endif
1502*a67afe4dSAndroid Build Coastguard Worker #endif
1503*a67afe4dSAndroid Build Coastguard Worker
1504*a67afe4dSAndroid Build Coastguard Worker pngtest_debug("Reading and writing end_info data");
1505*a67afe4dSAndroid Build Coastguard Worker
1506*a67afe4dSAndroid Build Coastguard Worker png_read_end(read_ptr, end_info_ptr);
1507*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_TEXT_SUPPORTED
1508*a67afe4dSAndroid Build Coastguard Worker {
1509*a67afe4dSAndroid Build Coastguard Worker png_textp text_ptr;
1510*a67afe4dSAndroid Build Coastguard Worker int num_text;
1511*a67afe4dSAndroid Build Coastguard Worker
1512*a67afe4dSAndroid Build Coastguard Worker if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0)
1513*a67afe4dSAndroid Build Coastguard Worker {
1514*a67afe4dSAndroid Build Coastguard Worker pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text);
1515*a67afe4dSAndroid Build Coastguard Worker
1516*a67afe4dSAndroid Build Coastguard Worker pngtest_check_text_support(read_ptr, text_ptr, num_text);
1517*a67afe4dSAndroid Build Coastguard Worker
1518*a67afe4dSAndroid Build Coastguard Worker if (verbose != 0)
1519*a67afe4dSAndroid Build Coastguard Worker {
1520*a67afe4dSAndroid Build Coastguard Worker int i;
1521*a67afe4dSAndroid Build Coastguard Worker
1522*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR,"\n");
1523*a67afe4dSAndroid Build Coastguard Worker for (i = 0; i < num_text; i++)
1524*a67afe4dSAndroid Build Coastguard Worker {
1525*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR," Text compression[%d]=%d\n",
1526*a67afe4dSAndroid Build Coastguard Worker i, text_ptr[i].compression);
1527*a67afe4dSAndroid Build Coastguard Worker }
1528*a67afe4dSAndroid Build Coastguard Worker }
1529*a67afe4dSAndroid Build Coastguard Worker
1530*a67afe4dSAndroid Build Coastguard Worker png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text);
1531*a67afe4dSAndroid Build Coastguard Worker }
1532*a67afe4dSAndroid Build Coastguard Worker }
1533*a67afe4dSAndroid Build Coastguard Worker #endif
1534*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_READ_eXIf_SUPPORTED
1535*a67afe4dSAndroid Build Coastguard Worker {
1536*a67afe4dSAndroid Build Coastguard Worker png_bytep exif = NULL;
1537*a67afe4dSAndroid Build Coastguard Worker png_uint_32 exif_length;
1538*a67afe4dSAndroid Build Coastguard Worker
1539*a67afe4dSAndroid Build Coastguard Worker if (png_get_eXIf_1(read_ptr, end_info_ptr, &exif_length, &exif) != 0)
1540*a67afe4dSAndroid Build Coastguard Worker {
1541*a67afe4dSAndroid Build Coastguard Worker if (exif_length > 1)
1542*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR," eXIf type %c%c, %lu bytes\n",exif[0],exif[1],
1543*a67afe4dSAndroid Build Coastguard Worker (unsigned long)exif_length);
1544*a67afe4dSAndroid Build Coastguard Worker # ifdef PNG_WRITE_eXIf_SUPPORTED
1545*a67afe4dSAndroid Build Coastguard Worker png_set_eXIf_1(write_ptr, write_end_info_ptr, exif_length, exif);
1546*a67afe4dSAndroid Build Coastguard Worker # endif
1547*a67afe4dSAndroid Build Coastguard Worker }
1548*a67afe4dSAndroid Build Coastguard Worker }
1549*a67afe4dSAndroid Build Coastguard Worker #endif
1550*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_tIME_SUPPORTED
1551*a67afe4dSAndroid Build Coastguard Worker {
1552*a67afe4dSAndroid Build Coastguard Worker png_timep mod_time;
1553*a67afe4dSAndroid Build Coastguard Worker
1554*a67afe4dSAndroid Build Coastguard Worker if (png_get_tIME(read_ptr, end_info_ptr, &mod_time) != 0)
1555*a67afe4dSAndroid Build Coastguard Worker {
1556*a67afe4dSAndroid Build Coastguard Worker png_set_tIME(write_ptr, write_end_info_ptr, mod_time);
1557*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_TIME_RFC1123_SUPPORTED
1558*a67afe4dSAndroid Build Coastguard Worker if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0)
1559*a67afe4dSAndroid Build Coastguard Worker tIME_string[(sizeof tIME_string) - 1] = '\0';
1560*a67afe4dSAndroid Build Coastguard Worker
1561*a67afe4dSAndroid Build Coastguard Worker else
1562*a67afe4dSAndroid Build Coastguard Worker {
1563*a67afe4dSAndroid Build Coastguard Worker strncpy(tIME_string, "*** invalid time ***", sizeof tIME_string);
1564*a67afe4dSAndroid Build Coastguard Worker tIME_string[(sizeof tIME_string)-1] = '\0';
1565*a67afe4dSAndroid Build Coastguard Worker }
1566*a67afe4dSAndroid Build Coastguard Worker
1567*a67afe4dSAndroid Build Coastguard Worker tIME_chunk_present++;
1568*a67afe4dSAndroid Build Coastguard Worker #endif /* TIME_RFC1123 */
1569*a67afe4dSAndroid Build Coastguard Worker }
1570*a67afe4dSAndroid Build Coastguard Worker }
1571*a67afe4dSAndroid Build Coastguard Worker #endif
1572*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
1573*a67afe4dSAndroid Build Coastguard Worker {
1574*a67afe4dSAndroid Build Coastguard Worker png_unknown_chunkp unknowns;
1575*a67afe4dSAndroid Build Coastguard Worker int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr,
1576*a67afe4dSAndroid Build Coastguard Worker &unknowns);
1577*a67afe4dSAndroid Build Coastguard Worker
1578*a67afe4dSAndroid Build Coastguard Worker if (num_unknowns != 0)
1579*a67afe4dSAndroid Build Coastguard Worker png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,
1580*a67afe4dSAndroid Build Coastguard Worker num_unknowns);
1581*a67afe4dSAndroid Build Coastguard Worker }
1582*a67afe4dSAndroid Build Coastguard Worker #endif
1583*a67afe4dSAndroid Build Coastguard Worker
1584*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_SUPPORTED
1585*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
1586*a67afe4dSAndroid Build Coastguard Worker /* Normally one would use Z_DEFAULT_STRATEGY for text compression.
1587*a67afe4dSAndroid Build Coastguard Worker * This is here just to make pngtest replicate the results from libpng
1588*a67afe4dSAndroid Build Coastguard Worker * versions prior to 1.5.4, and to test this new API.
1589*a67afe4dSAndroid Build Coastguard Worker */
1590*a67afe4dSAndroid Build Coastguard Worker png_set_text_compression_strategy(write_ptr, Z_FILTERED);
1591*a67afe4dSAndroid Build Coastguard Worker #endif
1592*a67afe4dSAndroid Build Coastguard Worker
1593*a67afe4dSAndroid Build Coastguard Worker /* When the unknown vpAg/sTER chunks are written by pngtest the only way to
1594*a67afe4dSAndroid Build Coastguard Worker * do it is to write them *before* calling png_write_end. When unknown
1595*a67afe4dSAndroid Build Coastguard Worker * chunks are written by libpng, however, they are written just before IEND.
1596*a67afe4dSAndroid Build Coastguard Worker * There seems to be no way round this, however vpAg/sTER are not expected
1597*a67afe4dSAndroid Build Coastguard Worker * after IDAT.
1598*a67afe4dSAndroid Build Coastguard Worker */
1599*a67afe4dSAndroid Build Coastguard Worker write_chunks(write_ptr, &my_user_chunk_data, after_IDAT);
1600*a67afe4dSAndroid Build Coastguard Worker
1601*a67afe4dSAndroid Build Coastguard Worker png_write_end(write_ptr, write_end_info_ptr);
1602*a67afe4dSAndroid Build Coastguard Worker #endif
1603*a67afe4dSAndroid Build Coastguard Worker
1604*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_EASY_ACCESS_SUPPORTED
1605*a67afe4dSAndroid Build Coastguard Worker if (verbose != 0)
1606*a67afe4dSAndroid Build Coastguard Worker {
1607*a67afe4dSAndroid Build Coastguard Worker png_uint_32 iwidth, iheight;
1608*a67afe4dSAndroid Build Coastguard Worker iwidth = png_get_image_width(write_ptr, write_info_ptr);
1609*a67afe4dSAndroid Build Coastguard Worker iheight = png_get_image_height(write_ptr, write_info_ptr);
1610*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "\n Image width = %lu, height = %lu\n",
1611*a67afe4dSAndroid Build Coastguard Worker (unsigned long)iwidth, (unsigned long)iheight);
1612*a67afe4dSAndroid Build Coastguard Worker }
1613*a67afe4dSAndroid Build Coastguard Worker #endif
1614*a67afe4dSAndroid Build Coastguard Worker
1615*a67afe4dSAndroid Build Coastguard Worker pngtest_debug("Destroying data structs");
1616*a67afe4dSAndroid Build Coastguard Worker pngtest_debug("Destroying read_ptr, read_info_ptr, end_info_ptr");
1617*a67afe4dSAndroid Build Coastguard Worker png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
1618*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_SUPPORTED
1619*a67afe4dSAndroid Build Coastguard Worker pngtest_debug("Destroying write_end_info_ptr");
1620*a67afe4dSAndroid Build Coastguard Worker png_destroy_info_struct(write_ptr, &write_end_info_ptr);
1621*a67afe4dSAndroid Build Coastguard Worker pngtest_debug("Destroying write_ptr, write_info_ptr");
1622*a67afe4dSAndroid Build Coastguard Worker png_destroy_write_struct(&write_ptr, &write_info_ptr);
1623*a67afe4dSAndroid Build Coastguard Worker #endif
1624*a67afe4dSAndroid Build Coastguard Worker pngtest_debug("Destruction complete.");
1625*a67afe4dSAndroid Build Coastguard Worker
1626*a67afe4dSAndroid Build Coastguard Worker fclose(fpin);
1627*a67afe4dSAndroid Build Coastguard Worker fclose(fpout);
1628*a67afe4dSAndroid Build Coastguard Worker
1629*a67afe4dSAndroid Build Coastguard Worker /* Summarize any warnings or errors and in 'strict' mode fail the test.
1630*a67afe4dSAndroid Build Coastguard Worker * Unsupported chunks can result in warnings, in that case ignore the strict
1631*a67afe4dSAndroid Build Coastguard Worker * setting, otherwise fail the test on warnings as well as errors.
1632*a67afe4dSAndroid Build Coastguard Worker */
1633*a67afe4dSAndroid Build Coastguard Worker if (error_count > 0)
1634*a67afe4dSAndroid Build Coastguard Worker {
1635*a67afe4dSAndroid Build Coastguard Worker /* We don't really expect to get here because of the setjmp handling
1636*a67afe4dSAndroid Build Coastguard Worker * above, but this is safe.
1637*a67afe4dSAndroid Build Coastguard Worker */
1638*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "\n %s: %d libpng errors found (%d warnings)",
1639*a67afe4dSAndroid Build Coastguard Worker inname, error_count, warning_count);
1640*a67afe4dSAndroid Build Coastguard Worker
1641*a67afe4dSAndroid Build Coastguard Worker if (strict != 0)
1642*a67afe4dSAndroid Build Coastguard Worker return 1;
1643*a67afe4dSAndroid Build Coastguard Worker }
1644*a67afe4dSAndroid Build Coastguard Worker
1645*a67afe4dSAndroid Build Coastguard Worker # ifdef PNG_WRITE_SUPPORTED
1646*a67afe4dSAndroid Build Coastguard Worker /* If there is no write support nothing was written! */
1647*a67afe4dSAndroid Build Coastguard Worker else if (unsupported_chunks > 0)
1648*a67afe4dSAndroid Build Coastguard Worker {
1649*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "\n %s: unsupported chunks (%d)%s",
1650*a67afe4dSAndroid Build Coastguard Worker inname, unsupported_chunks, strict ? ": IGNORED --strict!" : "");
1651*a67afe4dSAndroid Build Coastguard Worker }
1652*a67afe4dSAndroid Build Coastguard Worker # endif
1653*a67afe4dSAndroid Build Coastguard Worker
1654*a67afe4dSAndroid Build Coastguard Worker else if (warning_count > 0)
1655*a67afe4dSAndroid Build Coastguard Worker {
1656*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "\n %s: %d libpng warnings found",
1657*a67afe4dSAndroid Build Coastguard Worker inname, warning_count);
1658*a67afe4dSAndroid Build Coastguard Worker
1659*a67afe4dSAndroid Build Coastguard Worker if (strict != 0)
1660*a67afe4dSAndroid Build Coastguard Worker return 1;
1661*a67afe4dSAndroid Build Coastguard Worker }
1662*a67afe4dSAndroid Build Coastguard Worker
1663*a67afe4dSAndroid Build Coastguard Worker pngtest_debug("Opening files for comparison");
1664*a67afe4dSAndroid Build Coastguard Worker if ((fpin = fopen(inname, "rb")) == NULL)
1665*a67afe4dSAndroid Build Coastguard Worker {
1666*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "Could not find file %s\n", inname);
1667*a67afe4dSAndroid Build Coastguard Worker return 1;
1668*a67afe4dSAndroid Build Coastguard Worker }
1669*a67afe4dSAndroid Build Coastguard Worker
1670*a67afe4dSAndroid Build Coastguard Worker if ((fpout = fopen(outname, "rb")) == NULL)
1671*a67afe4dSAndroid Build Coastguard Worker {
1672*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "Could not find file %s\n", outname);
1673*a67afe4dSAndroid Build Coastguard Worker fclose(fpin);
1674*a67afe4dSAndroid Build Coastguard Worker return 1;
1675*a67afe4dSAndroid Build Coastguard Worker }
1676*a67afe4dSAndroid Build Coastguard Worker
1677*a67afe4dSAndroid Build Coastguard Worker #if defined (PNG_WRITE_SUPPORTED) /* else nothing was written */ &&\
1678*a67afe4dSAndroid Build Coastguard Worker defined (PNG_WRITE_FILTER_SUPPORTED)
1679*a67afe4dSAndroid Build Coastguard Worker if (interlace_preserved != 0) /* else the files will be changed */
1680*a67afe4dSAndroid Build Coastguard Worker {
1681*a67afe4dSAndroid Build Coastguard Worker for (;;)
1682*a67afe4dSAndroid Build Coastguard Worker {
1683*a67afe4dSAndroid Build Coastguard Worker static int wrote_question = 0;
1684*a67afe4dSAndroid Build Coastguard Worker size_t num_in, num_out;
1685*a67afe4dSAndroid Build Coastguard Worker char inbuf[256], outbuf[256];
1686*a67afe4dSAndroid Build Coastguard Worker
1687*a67afe4dSAndroid Build Coastguard Worker num_in = fread(inbuf, 1, sizeof inbuf, fpin);
1688*a67afe4dSAndroid Build Coastguard Worker num_out = fread(outbuf, 1, sizeof outbuf, fpout);
1689*a67afe4dSAndroid Build Coastguard Worker
1690*a67afe4dSAndroid Build Coastguard Worker if (num_in != num_out)
1691*a67afe4dSAndroid Build Coastguard Worker {
1692*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
1693*a67afe4dSAndroid Build Coastguard Worker inname, outname);
1694*a67afe4dSAndroid Build Coastguard Worker
1695*a67afe4dSAndroid Build Coastguard Worker if (wrote_question == 0 && unsupported_chunks == 0)
1696*a67afe4dSAndroid Build Coastguard Worker {
1697*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR,
1698*a67afe4dSAndroid Build Coastguard Worker " Was %s written with the same maximum IDAT"
1699*a67afe4dSAndroid Build Coastguard Worker " chunk size (%d bytes),",
1700*a67afe4dSAndroid Build Coastguard Worker inname, PNG_ZBUF_SIZE);
1701*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR,
1702*a67afe4dSAndroid Build Coastguard Worker "\n filtering heuristic (libpng default), compression");
1703*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR,
1704*a67afe4dSAndroid Build Coastguard Worker " level (zlib default),\n and zlib version (%s)?\n\n",
1705*a67afe4dSAndroid Build Coastguard Worker ZLIB_VERSION);
1706*a67afe4dSAndroid Build Coastguard Worker wrote_question = 1;
1707*a67afe4dSAndroid Build Coastguard Worker }
1708*a67afe4dSAndroid Build Coastguard Worker
1709*a67afe4dSAndroid Build Coastguard Worker fclose(fpin);
1710*a67afe4dSAndroid Build Coastguard Worker fclose(fpout);
1711*a67afe4dSAndroid Build Coastguard Worker
1712*a67afe4dSAndroid Build Coastguard Worker if (strict != 0 && unsupported_chunks == 0)
1713*a67afe4dSAndroid Build Coastguard Worker return 1;
1714*a67afe4dSAndroid Build Coastguard Worker
1715*a67afe4dSAndroid Build Coastguard Worker else
1716*a67afe4dSAndroid Build Coastguard Worker return 0;
1717*a67afe4dSAndroid Build Coastguard Worker }
1718*a67afe4dSAndroid Build Coastguard Worker
1719*a67afe4dSAndroid Build Coastguard Worker if (num_in == 0)
1720*a67afe4dSAndroid Build Coastguard Worker break;
1721*a67afe4dSAndroid Build Coastguard Worker
1722*a67afe4dSAndroid Build Coastguard Worker if (memcmp(inbuf, outbuf, num_in))
1723*a67afe4dSAndroid Build Coastguard Worker {
1724*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "\nFiles %s and %s are different\n", inname,
1725*a67afe4dSAndroid Build Coastguard Worker outname);
1726*a67afe4dSAndroid Build Coastguard Worker
1727*a67afe4dSAndroid Build Coastguard Worker if (wrote_question == 0 && unsupported_chunks == 0)
1728*a67afe4dSAndroid Build Coastguard Worker {
1729*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR,
1730*a67afe4dSAndroid Build Coastguard Worker " Was %s written with the same maximum"
1731*a67afe4dSAndroid Build Coastguard Worker " IDAT chunk size (%d bytes),",
1732*a67afe4dSAndroid Build Coastguard Worker inname, PNG_ZBUF_SIZE);
1733*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR,
1734*a67afe4dSAndroid Build Coastguard Worker "\n filtering heuristic (libpng default), compression");
1735*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR,
1736*a67afe4dSAndroid Build Coastguard Worker " level (zlib default),\n and zlib version (%s)?\n\n",
1737*a67afe4dSAndroid Build Coastguard Worker ZLIB_VERSION);
1738*a67afe4dSAndroid Build Coastguard Worker wrote_question = 1;
1739*a67afe4dSAndroid Build Coastguard Worker }
1740*a67afe4dSAndroid Build Coastguard Worker
1741*a67afe4dSAndroid Build Coastguard Worker fclose(fpin);
1742*a67afe4dSAndroid Build Coastguard Worker fclose(fpout);
1743*a67afe4dSAndroid Build Coastguard Worker
1744*a67afe4dSAndroid Build Coastguard Worker /* NOTE: the unsupported_chunks escape is permitted here because
1745*a67afe4dSAndroid Build Coastguard Worker * unsupported text chunk compression will result in the compression
1746*a67afe4dSAndroid Build Coastguard Worker * mode being changed (to NONE) yet, in the test case, the result
1747*a67afe4dSAndroid Build Coastguard Worker * can be exactly the same size!
1748*a67afe4dSAndroid Build Coastguard Worker */
1749*a67afe4dSAndroid Build Coastguard Worker if (strict != 0 && unsupported_chunks == 0)
1750*a67afe4dSAndroid Build Coastguard Worker return 1;
1751*a67afe4dSAndroid Build Coastguard Worker
1752*a67afe4dSAndroid Build Coastguard Worker else
1753*a67afe4dSAndroid Build Coastguard Worker return 0;
1754*a67afe4dSAndroid Build Coastguard Worker }
1755*a67afe4dSAndroid Build Coastguard Worker }
1756*a67afe4dSAndroid Build Coastguard Worker }
1757*a67afe4dSAndroid Build Coastguard Worker #endif /* WRITE && WRITE_FILTER */
1758*a67afe4dSAndroid Build Coastguard Worker
1759*a67afe4dSAndroid Build Coastguard Worker fclose(fpin);
1760*a67afe4dSAndroid Build Coastguard Worker fclose(fpout);
1761*a67afe4dSAndroid Build Coastguard Worker
1762*a67afe4dSAndroid Build Coastguard Worker return 0;
1763*a67afe4dSAndroid Build Coastguard Worker }
1764*a67afe4dSAndroid Build Coastguard Worker
1765*a67afe4dSAndroid Build Coastguard Worker /* Input and output filenames */
1766*a67afe4dSAndroid Build Coastguard Worker #ifdef RISCOS
1767*a67afe4dSAndroid Build Coastguard Worker static const char *inname = "pngtest/png";
1768*a67afe4dSAndroid Build Coastguard Worker static const char *outname = "pngout/png";
1769*a67afe4dSAndroid Build Coastguard Worker #else
1770*a67afe4dSAndroid Build Coastguard Worker static const char *inname = "pngtest.png";
1771*a67afe4dSAndroid Build Coastguard Worker static const char *outname = "pngout.png";
1772*a67afe4dSAndroid Build Coastguard Worker #endif
1773*a67afe4dSAndroid Build Coastguard Worker
1774*a67afe4dSAndroid Build Coastguard Worker int
main(int argc,char * argv[])1775*a67afe4dSAndroid Build Coastguard Worker main(int argc, char *argv[])
1776*a67afe4dSAndroid Build Coastguard Worker {
1777*a67afe4dSAndroid Build Coastguard Worker int multiple = 0;
1778*a67afe4dSAndroid Build Coastguard Worker int ierror = 0;
1779*a67afe4dSAndroid Build Coastguard Worker
1780*a67afe4dSAndroid Build Coastguard Worker png_structp dummy_ptr;
1781*a67afe4dSAndroid Build Coastguard Worker
1782*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
1783*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION);
1784*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "%s", png_get_copyright(NULL));
1785*a67afe4dSAndroid Build Coastguard Worker /* Show the version of libpng used in building the library */
1786*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " library (%lu):%s",
1787*a67afe4dSAndroid Build Coastguard Worker (unsigned long)png_access_version_number(),
1788*a67afe4dSAndroid Build Coastguard Worker png_get_header_version(NULL));
1789*a67afe4dSAndroid Build Coastguard Worker
1790*a67afe4dSAndroid Build Coastguard Worker /* Show the version of libpng used in building the application */
1791*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER,
1792*a67afe4dSAndroid Build Coastguard Worker PNG_HEADER_VERSION_STRING);
1793*a67afe4dSAndroid Build Coastguard Worker
1794*a67afe4dSAndroid Build Coastguard Worker /* Do some consistency checking on the memory allocation settings, I'm
1795*a67afe4dSAndroid Build Coastguard Worker * not sure this matters, but it is nice to know, the first of these
1796*a67afe4dSAndroid Build Coastguard Worker * tests should be impossible because of the way the macros are set
1797*a67afe4dSAndroid Build Coastguard Worker * in pngconf.h
1798*a67afe4dSAndroid Build Coastguard Worker */
1799*a67afe4dSAndroid Build Coastguard Worker #if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
1800*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n");
1801*a67afe4dSAndroid Build Coastguard Worker #endif
1802*a67afe4dSAndroid Build Coastguard Worker /* I think the following can happen. */
1803*a67afe4dSAndroid Build Coastguard Worker #if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
1804*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n");
1805*a67afe4dSAndroid Build Coastguard Worker #endif
1806*a67afe4dSAndroid Build Coastguard Worker
1807*a67afe4dSAndroid Build Coastguard Worker if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING) != 0)
1808*a67afe4dSAndroid Build Coastguard Worker {
1809*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "Warning: mismatching versions of png.h and png.c\n");
1810*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " png.h version string: %s\n", PNG_LIBPNG_VER_STRING);
1811*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " png.c version string: %s\n\n", png_libpng_ver);
1812*a67afe4dSAndroid Build Coastguard Worker ++ierror;
1813*a67afe4dSAndroid Build Coastguard Worker }
1814*a67afe4dSAndroid Build Coastguard Worker
1815*a67afe4dSAndroid Build Coastguard Worker if (argc > 1)
1816*a67afe4dSAndroid Build Coastguard Worker {
1817*a67afe4dSAndroid Build Coastguard Worker if (strcmp(argv[1], "-m") == 0)
1818*a67afe4dSAndroid Build Coastguard Worker {
1819*a67afe4dSAndroid Build Coastguard Worker multiple = 1;
1820*a67afe4dSAndroid Build Coastguard Worker status_dots_requested = 0;
1821*a67afe4dSAndroid Build Coastguard Worker }
1822*a67afe4dSAndroid Build Coastguard Worker
1823*a67afe4dSAndroid Build Coastguard Worker else if (strcmp(argv[1], "-mv") == 0 ||
1824*a67afe4dSAndroid Build Coastguard Worker strcmp(argv[1], "-vm") == 0 )
1825*a67afe4dSAndroid Build Coastguard Worker {
1826*a67afe4dSAndroid Build Coastguard Worker multiple = 1;
1827*a67afe4dSAndroid Build Coastguard Worker verbose = 1;
1828*a67afe4dSAndroid Build Coastguard Worker status_dots_requested = 1;
1829*a67afe4dSAndroid Build Coastguard Worker }
1830*a67afe4dSAndroid Build Coastguard Worker
1831*a67afe4dSAndroid Build Coastguard Worker else if (strcmp(argv[1], "-v") == 0)
1832*a67afe4dSAndroid Build Coastguard Worker {
1833*a67afe4dSAndroid Build Coastguard Worker verbose = 1;
1834*a67afe4dSAndroid Build Coastguard Worker status_dots_requested = 1;
1835*a67afe4dSAndroid Build Coastguard Worker inname = argv[2];
1836*a67afe4dSAndroid Build Coastguard Worker }
1837*a67afe4dSAndroid Build Coastguard Worker
1838*a67afe4dSAndroid Build Coastguard Worker else if (strcmp(argv[1], "--strict") == 0)
1839*a67afe4dSAndroid Build Coastguard Worker {
1840*a67afe4dSAndroid Build Coastguard Worker status_dots_requested = 0;
1841*a67afe4dSAndroid Build Coastguard Worker verbose = 1;
1842*a67afe4dSAndroid Build Coastguard Worker inname = argv[2];
1843*a67afe4dSAndroid Build Coastguard Worker strict++;
1844*a67afe4dSAndroid Build Coastguard Worker relaxed = 0;
1845*a67afe4dSAndroid Build Coastguard Worker multiple = 1;
1846*a67afe4dSAndroid Build Coastguard Worker }
1847*a67afe4dSAndroid Build Coastguard Worker
1848*a67afe4dSAndroid Build Coastguard Worker else if (strcmp(argv[1], "--relaxed") == 0)
1849*a67afe4dSAndroid Build Coastguard Worker {
1850*a67afe4dSAndroid Build Coastguard Worker status_dots_requested = 0;
1851*a67afe4dSAndroid Build Coastguard Worker verbose = 1;
1852*a67afe4dSAndroid Build Coastguard Worker inname = argv[2];
1853*a67afe4dSAndroid Build Coastguard Worker strict = 0;
1854*a67afe4dSAndroid Build Coastguard Worker relaxed++;
1855*a67afe4dSAndroid Build Coastguard Worker multiple = 1;
1856*a67afe4dSAndroid Build Coastguard Worker }
1857*a67afe4dSAndroid Build Coastguard Worker else if (strcmp(argv[1], "--xfail") == 0)
1858*a67afe4dSAndroid Build Coastguard Worker {
1859*a67afe4dSAndroid Build Coastguard Worker status_dots_requested = 0;
1860*a67afe4dSAndroid Build Coastguard Worker verbose = 1;
1861*a67afe4dSAndroid Build Coastguard Worker inname = argv[2];
1862*a67afe4dSAndroid Build Coastguard Worker strict = 0;
1863*a67afe4dSAndroid Build Coastguard Worker xfail++;
1864*a67afe4dSAndroid Build Coastguard Worker relaxed++;
1865*a67afe4dSAndroid Build Coastguard Worker multiple = 1;
1866*a67afe4dSAndroid Build Coastguard Worker }
1867*a67afe4dSAndroid Build Coastguard Worker
1868*a67afe4dSAndroid Build Coastguard Worker else
1869*a67afe4dSAndroid Build Coastguard Worker {
1870*a67afe4dSAndroid Build Coastguard Worker inname = argv[1];
1871*a67afe4dSAndroid Build Coastguard Worker status_dots_requested = 0;
1872*a67afe4dSAndroid Build Coastguard Worker }
1873*a67afe4dSAndroid Build Coastguard Worker }
1874*a67afe4dSAndroid Build Coastguard Worker
1875*a67afe4dSAndroid Build Coastguard Worker if (multiple == 0 && argc == 3 + verbose)
1876*a67afe4dSAndroid Build Coastguard Worker outname = argv[2 + verbose];
1877*a67afe4dSAndroid Build Coastguard Worker
1878*a67afe4dSAndroid Build Coastguard Worker if ((multiple == 0 && argc > 3 + verbose) ||
1879*a67afe4dSAndroid Build Coastguard Worker (multiple != 0 && argc < 2))
1880*a67afe4dSAndroid Build Coastguard Worker {
1881*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR,
1882*a67afe4dSAndroid Build Coastguard Worker "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
1883*a67afe4dSAndroid Build Coastguard Worker argv[0], argv[0]);
1884*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR,
1885*a67afe4dSAndroid Build Coastguard Worker " reads/writes one PNG file (without -m) or multiple files (-m)\n");
1886*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR,
1887*a67afe4dSAndroid Build Coastguard Worker " with -m %s is used as a temporary file\n", outname);
1888*a67afe4dSAndroid Build Coastguard Worker exit(1);
1889*a67afe4dSAndroid Build Coastguard Worker }
1890*a67afe4dSAndroid Build Coastguard Worker
1891*a67afe4dSAndroid Build Coastguard Worker if (multiple != 0)
1892*a67afe4dSAndroid Build Coastguard Worker {
1893*a67afe4dSAndroid Build Coastguard Worker int i;
1894*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1895*a67afe4dSAndroid Build Coastguard Worker int allocation_now = current_allocation;
1896*a67afe4dSAndroid Build Coastguard Worker #endif
1897*a67afe4dSAndroid Build Coastguard Worker for (i = 2; i < argc; ++i)
1898*a67afe4dSAndroid Build Coastguard Worker {
1899*a67afe4dSAndroid Build Coastguard Worker int kerror;
1900*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "\n Testing %s:", argv[i]);
1901*a67afe4dSAndroid Build Coastguard Worker #if PNG_DEBUG > 0
1902*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "\n");
1903*a67afe4dSAndroid Build Coastguard Worker #endif
1904*a67afe4dSAndroid Build Coastguard Worker kerror = test_one_file(argv[i], outname);
1905*a67afe4dSAndroid Build Coastguard Worker if (kerror == 0)
1906*a67afe4dSAndroid Build Coastguard Worker {
1907*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
1908*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "\n PASS (%lu zero samples)\n",
1909*a67afe4dSAndroid Build Coastguard Worker (unsigned long)zero_samples);
1910*a67afe4dSAndroid Build Coastguard Worker #else
1911*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " PASS\n");
1912*a67afe4dSAndroid Build Coastguard Worker #endif
1913*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_TIME_RFC1123_SUPPORTED
1914*a67afe4dSAndroid Build Coastguard Worker if (tIME_chunk_present != 0)
1915*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " tIME = %s\n", tIME_string);
1916*a67afe4dSAndroid Build Coastguard Worker
1917*a67afe4dSAndroid Build Coastguard Worker tIME_chunk_present = 0;
1918*a67afe4dSAndroid Build Coastguard Worker #endif /* TIME_RFC1123 */
1919*a67afe4dSAndroid Build Coastguard Worker }
1920*a67afe4dSAndroid Build Coastguard Worker
1921*a67afe4dSAndroid Build Coastguard Worker else
1922*a67afe4dSAndroid Build Coastguard Worker {
1923*a67afe4dSAndroid Build Coastguard Worker if (xfail)
1924*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " XFAIL\n");
1925*a67afe4dSAndroid Build Coastguard Worker else
1926*a67afe4dSAndroid Build Coastguard Worker {
1927*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " FAIL\n");
1928*a67afe4dSAndroid Build Coastguard Worker ierror += kerror;
1929*a67afe4dSAndroid Build Coastguard Worker }
1930*a67afe4dSAndroid Build Coastguard Worker }
1931*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1932*a67afe4dSAndroid Build Coastguard Worker if (allocation_now != current_allocation)
1933*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
1934*a67afe4dSAndroid Build Coastguard Worker current_allocation - allocation_now);
1935*a67afe4dSAndroid Build Coastguard Worker
1936*a67afe4dSAndroid Build Coastguard Worker if (current_allocation != 0)
1937*a67afe4dSAndroid Build Coastguard Worker {
1938*a67afe4dSAndroid Build Coastguard Worker memory_infop pinfo = pinformation;
1939*a67afe4dSAndroid Build Coastguard Worker
1940*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
1941*a67afe4dSAndroid Build Coastguard Worker current_allocation);
1942*a67afe4dSAndroid Build Coastguard Worker
1943*a67afe4dSAndroid Build Coastguard Worker while (pinfo != NULL)
1944*a67afe4dSAndroid Build Coastguard Worker {
1945*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " %lu bytes at %p\n",
1946*a67afe4dSAndroid Build Coastguard Worker (unsigned long)pinfo->size,
1947*a67afe4dSAndroid Build Coastguard Worker pinfo->pointer);
1948*a67afe4dSAndroid Build Coastguard Worker pinfo = pinfo->next;
1949*a67afe4dSAndroid Build Coastguard Worker }
1950*a67afe4dSAndroid Build Coastguard Worker }
1951*a67afe4dSAndroid Build Coastguard Worker #endif
1952*a67afe4dSAndroid Build Coastguard Worker }
1953*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1954*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " Current memory allocation: %10d bytes\n",
1955*a67afe4dSAndroid Build Coastguard Worker current_allocation);
1956*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
1957*a67afe4dSAndroid Build Coastguard Worker maximum_allocation);
1958*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " Total memory allocation: %10d bytes\n",
1959*a67afe4dSAndroid Build Coastguard Worker total_allocation);
1960*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " Number of allocations: %10d\n",
1961*a67afe4dSAndroid Build Coastguard Worker num_allocations);
1962*a67afe4dSAndroid Build Coastguard Worker #endif
1963*a67afe4dSAndroid Build Coastguard Worker }
1964*a67afe4dSAndroid Build Coastguard Worker
1965*a67afe4dSAndroid Build Coastguard Worker else
1966*a67afe4dSAndroid Build Coastguard Worker {
1967*a67afe4dSAndroid Build Coastguard Worker int i;
1968*a67afe4dSAndroid Build Coastguard Worker for (i = 0; i < 3; ++i)
1969*a67afe4dSAndroid Build Coastguard Worker {
1970*a67afe4dSAndroid Build Coastguard Worker int kerror;
1971*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1972*a67afe4dSAndroid Build Coastguard Worker int allocation_now = current_allocation;
1973*a67afe4dSAndroid Build Coastguard Worker #endif
1974*a67afe4dSAndroid Build Coastguard Worker if (i == 1)
1975*a67afe4dSAndroid Build Coastguard Worker status_dots_requested = 1;
1976*a67afe4dSAndroid Build Coastguard Worker
1977*a67afe4dSAndroid Build Coastguard Worker else if (verbose == 0)
1978*a67afe4dSAndroid Build Coastguard Worker status_dots_requested = 0;
1979*a67afe4dSAndroid Build Coastguard Worker
1980*a67afe4dSAndroid Build Coastguard Worker if (i == 0 || verbose == 1 || ierror != 0)
1981*a67afe4dSAndroid Build Coastguard Worker {
1982*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "\n Testing %s:", inname);
1983*a67afe4dSAndroid Build Coastguard Worker #if PNG_DEBUG > 0
1984*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "\n");
1985*a67afe4dSAndroid Build Coastguard Worker #endif
1986*a67afe4dSAndroid Build Coastguard Worker }
1987*a67afe4dSAndroid Build Coastguard Worker
1988*a67afe4dSAndroid Build Coastguard Worker kerror = test_one_file(inname, outname);
1989*a67afe4dSAndroid Build Coastguard Worker
1990*a67afe4dSAndroid Build Coastguard Worker if (kerror == 0)
1991*a67afe4dSAndroid Build Coastguard Worker {
1992*a67afe4dSAndroid Build Coastguard Worker if (verbose == 1 || i == 2)
1993*a67afe4dSAndroid Build Coastguard Worker {
1994*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
1995*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "\n PASS (%lu zero samples)\n",
1996*a67afe4dSAndroid Build Coastguard Worker (unsigned long)zero_samples);
1997*a67afe4dSAndroid Build Coastguard Worker #else
1998*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " PASS\n");
1999*a67afe4dSAndroid Build Coastguard Worker #endif
2000*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_TIME_RFC1123_SUPPORTED
2001*a67afe4dSAndroid Build Coastguard Worker if (tIME_chunk_present != 0)
2002*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " tIME = %s\n", tIME_string);
2003*a67afe4dSAndroid Build Coastguard Worker #endif /* TIME_RFC1123 */
2004*a67afe4dSAndroid Build Coastguard Worker }
2005*a67afe4dSAndroid Build Coastguard Worker }
2006*a67afe4dSAndroid Build Coastguard Worker
2007*a67afe4dSAndroid Build Coastguard Worker else
2008*a67afe4dSAndroid Build Coastguard Worker {
2009*a67afe4dSAndroid Build Coastguard Worker if (verbose == 0 && i != 2)
2010*a67afe4dSAndroid Build Coastguard Worker {
2011*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "\n Testing %s:", inname);
2012*a67afe4dSAndroid Build Coastguard Worker #if PNG_DEBUG > 0
2013*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "\n");
2014*a67afe4dSAndroid Build Coastguard Worker #endif
2015*a67afe4dSAndroid Build Coastguard Worker }
2016*a67afe4dSAndroid Build Coastguard Worker
2017*a67afe4dSAndroid Build Coastguard Worker if (xfail)
2018*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " XFAIL\n");
2019*a67afe4dSAndroid Build Coastguard Worker else
2020*a67afe4dSAndroid Build Coastguard Worker {
2021*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " FAIL\n");
2022*a67afe4dSAndroid Build Coastguard Worker ierror += kerror;
2023*a67afe4dSAndroid Build Coastguard Worker }
2024*a67afe4dSAndroid Build Coastguard Worker }
2025*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
2026*a67afe4dSAndroid Build Coastguard Worker if (allocation_now != current_allocation)
2027*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
2028*a67afe4dSAndroid Build Coastguard Worker current_allocation - allocation_now);
2029*a67afe4dSAndroid Build Coastguard Worker
2030*a67afe4dSAndroid Build Coastguard Worker if (current_allocation != 0)
2031*a67afe4dSAndroid Build Coastguard Worker {
2032*a67afe4dSAndroid Build Coastguard Worker memory_infop pinfo = pinformation;
2033*a67afe4dSAndroid Build Coastguard Worker
2034*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
2035*a67afe4dSAndroid Build Coastguard Worker current_allocation);
2036*a67afe4dSAndroid Build Coastguard Worker
2037*a67afe4dSAndroid Build Coastguard Worker while (pinfo != NULL)
2038*a67afe4dSAndroid Build Coastguard Worker {
2039*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " %lu bytes at %p\n",
2040*a67afe4dSAndroid Build Coastguard Worker (unsigned long)pinfo->size, pinfo->pointer);
2041*a67afe4dSAndroid Build Coastguard Worker pinfo = pinfo->next;
2042*a67afe4dSAndroid Build Coastguard Worker }
2043*a67afe4dSAndroid Build Coastguard Worker }
2044*a67afe4dSAndroid Build Coastguard Worker #endif
2045*a67afe4dSAndroid Build Coastguard Worker }
2046*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
2047*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " Current memory allocation: %10d bytes\n",
2048*a67afe4dSAndroid Build Coastguard Worker current_allocation);
2049*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
2050*a67afe4dSAndroid Build Coastguard Worker maximum_allocation);
2051*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " Total memory allocation: %10d bytes\n",
2052*a67afe4dSAndroid Build Coastguard Worker total_allocation);
2053*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " Number of allocations: %10d\n",
2054*a67afe4dSAndroid Build Coastguard Worker num_allocations);
2055*a67afe4dSAndroid Build Coastguard Worker #endif
2056*a67afe4dSAndroid Build Coastguard Worker }
2057*a67afe4dSAndroid Build Coastguard Worker
2058*a67afe4dSAndroid Build Coastguard Worker #ifdef PNGTEST_TIMING
2059*a67afe4dSAndroid Build Coastguard Worker t_stop = (float)clock();
2060*a67afe4dSAndroid Build Coastguard Worker t_misc += (t_stop - t_start);
2061*a67afe4dSAndroid Build Coastguard Worker t_start = t_stop;
2062*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " CPU time used = %.3f seconds",
2063*a67afe4dSAndroid Build Coastguard Worker (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
2064*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " (decoding %.3f,\n",
2065*a67afe4dSAndroid Build Coastguard Worker t_decode/(float)CLOCKS_PER_SEC);
2066*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " encoding %.3f ,",
2067*a67afe4dSAndroid Build Coastguard Worker t_encode/(float)CLOCKS_PER_SEC);
2068*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " other %.3f seconds)\n\n",
2069*a67afe4dSAndroid Build Coastguard Worker t_misc/(float)CLOCKS_PER_SEC);
2070*a67afe4dSAndroid Build Coastguard Worker #endif
2071*a67afe4dSAndroid Build Coastguard Worker
2072*a67afe4dSAndroid Build Coastguard Worker if (ierror == 0)
2073*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " libpng passes test\n");
2074*a67afe4dSAndroid Build Coastguard Worker
2075*a67afe4dSAndroid Build Coastguard Worker else
2076*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " libpng FAILS test\n");
2077*a67afe4dSAndroid Build Coastguard Worker
2078*a67afe4dSAndroid Build Coastguard Worker dummy_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
2079*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " Default limits:\n");
2080*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " width_max = %lu\n",
2081*a67afe4dSAndroid Build Coastguard Worker (unsigned long) png_get_user_width_max(dummy_ptr));
2082*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " height_max = %lu\n",
2083*a67afe4dSAndroid Build Coastguard Worker (unsigned long) png_get_user_height_max(dummy_ptr));
2084*a67afe4dSAndroid Build Coastguard Worker if (png_get_chunk_cache_max(dummy_ptr) == 0)
2085*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " cache_max = unlimited\n");
2086*a67afe4dSAndroid Build Coastguard Worker else
2087*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " cache_max = %lu\n",
2088*a67afe4dSAndroid Build Coastguard Worker (unsigned long) png_get_chunk_cache_max(dummy_ptr));
2089*a67afe4dSAndroid Build Coastguard Worker if (png_get_chunk_malloc_max(dummy_ptr) == 0)
2090*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " malloc_max = unlimited\n");
2091*a67afe4dSAndroid Build Coastguard Worker else
2092*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR, " malloc_max = %lu\n",
2093*a67afe4dSAndroid Build Coastguard Worker (unsigned long) png_get_chunk_malloc_max(dummy_ptr));
2094*a67afe4dSAndroid Build Coastguard Worker png_destroy_read_struct(&dummy_ptr, NULL, NULL);
2095*a67afe4dSAndroid Build Coastguard Worker
2096*a67afe4dSAndroid Build Coastguard Worker return (ierror != 0);
2097*a67afe4dSAndroid Build Coastguard Worker }
2098*a67afe4dSAndroid Build Coastguard Worker #else
2099*a67afe4dSAndroid Build Coastguard Worker int
main(void)2100*a67afe4dSAndroid Build Coastguard Worker main(void)
2101*a67afe4dSAndroid Build Coastguard Worker {
2102*a67afe4dSAndroid Build Coastguard Worker fprintf(STDERR,
2103*a67afe4dSAndroid Build Coastguard Worker " test ignored because libpng was not built with read support\n");
2104*a67afe4dSAndroid Build Coastguard Worker /* And skip this test */
2105*a67afe4dSAndroid Build Coastguard Worker return SKIP;
2106*a67afe4dSAndroid Build Coastguard Worker }
2107*a67afe4dSAndroid Build Coastguard Worker #endif
2108