/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/png/pngtest.c
ViewVC logotype

Annotation of /trunk/3rdparty/wxWidgets/src/png/pngtest.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 4 months ago) by william
File MIME type: text/plain
File size: 51218 byte(s)
committing r3113 initial commit again...
1 william 31
2     /* pngtest.c - a simple test program to test libpng
3     *
4     * Last changed in libpng 1.2.37 [June 4, 2009]
5     * Copyright (c) 1998-2009 Glenn Randers-Pehrson
6     * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7     * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8     *
9     * This code is released under the libpng license.
10     * For conditions of distribution and use, see the disclaimer
11     * and license in png.h
12     *
13     * This program reads in a PNG image, writes it out again, and then
14     * compares the two files. If the files are identical, this shows that
15     * the basic chunk handling, filtering, and (de)compression code is working
16     * properly. It does not currently test all of the transforms, although
17     * it probably should.
18     *
19     * The program will report "FAIL" in certain legitimate cases:
20     * 1) when the compression level or filter selection method is changed.
21     * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192.
22     * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks
23     * exist in the input file.
24     * 4) others not listed here...
25     * In these cases, it is best to check with another tool such as "pngcheck"
26     * to see what the differences between the two files are.
27     *
28     * If a filename is given on the command-line, then this file is used
29     * for the input, rather than the default "pngtest.png". This allows
30     * testing a wide variety of files easily. You can also test a number
31     * of files at once by typing "pngtest -m file1.png file2.png ..."
32     */
33    
34     #include "png.h"
35    
36     #if defined(_WIN32_WCE)
37     # if _WIN32_WCE < 211
38     __error__ (f|w)printf functions are not supported on old WindowsCE.;
39     # endif
40     # include <windows.h>
41     # include <stdlib.h>
42     # define READFILE(file, data, length, check) \
43     if (ReadFile(file, data, length, &check, NULL)) check = 0
44     # define WRITEFILE(file, data, length, check)) \
45     if (WriteFile(file, data, length, &check, NULL)) check = 0
46     # define FCLOSE(file) CloseHandle(file)
47     #else
48     # include <stdio.h>
49     # include <stdlib.h>
50     # define READFILE(file, data, length, check) \
51     check=(png_size_t)fread(data, (png_size_t)1, length, file)
52     # define WRITEFILE(file, data, length, check) \
53     check=(png_size_t)fwrite(data, (png_size_t)1, length, file)
54     # define FCLOSE(file) fclose(file)
55     #endif
56    
57     #if defined(PNG_NO_STDIO)
58     # if defined(_WIN32_WCE)
59     typedef HANDLE png_FILE_p;
60     # else
61     typedef FILE * png_FILE_p;
62     # endif
63     #endif
64    
65     /* Makes pngtest verbose so we can find problems (needs to be before png.h) */
66     #ifndef PNG_DEBUG
67     # define PNG_DEBUG 0
68     #endif
69    
70     #if !PNG_DEBUG
71     # define SINGLE_ROWBUF_ALLOC /* Makes buffer overruns easier to nail */
72     #endif
73    
74     /* Turn on CPU timing
75     #define PNGTEST_TIMING
76     */
77    
78     #ifdef PNG_NO_FLOATING_POINT_SUPPORTED
79     #undef PNGTEST_TIMING
80     #endif
81    
82     #ifdef PNGTEST_TIMING
83     static float t_start, t_stop, t_decode, t_encode, t_misc;
84     #include <time.h>
85     #endif
86    
87     #if defined(PNG_TIME_RFC1123_SUPPORTED)
88     #define PNG_tIME_STRING_LENGTH 29
89     static int tIME_chunk_present = 0;
90     static char tIME_string[PNG_tIME_STRING_LENGTH] = "tIME chunk is not present";
91     #endif
92    
93     static int verbose = 0;
94    
95     int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname));
96    
97     #ifdef __TURBOC__
98     #include <mem.h>
99     #endif
100    
101     /* Defined so I can write to a file on gui/windowing platforms */
102     /* #define STDERR stderr */
103     #define STDERR stdout /* For DOS */
104    
105     /* In case a system header (e.g., on AIX) defined jmpbuf */
106     #ifdef jmpbuf
107     # undef jmpbuf
108     #endif
109    
110     /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
111     #ifndef png_jmpbuf
112     # define png_jmpbuf(png_ptr) png_ptr->jmpbuf
113     #endif
114    
115     /* Example of using row callbacks to make a simple progress meter */
116     static int status_pass = 1;
117     static int status_dots_requested = 0;
118     static int status_dots = 1;
119    
120     void
121     #ifdef PNG_1_0_X
122     PNGAPI
123     #endif
124     read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
125     void
126     #ifdef PNG_1_0_X
127     PNGAPI
128     #endif
129     read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
130     {
131     if (png_ptr == NULL || row_number > PNG_UINT_31_MAX)
132     return;
133     if (status_pass != pass)
134     {
135     fprintf(stdout, "\n Pass %d: ", pass);
136     status_pass = pass;
137     status_dots = 31;
138     }
139     status_dots--;
140     if (status_dots == 0)
141     {
142     fprintf(stdout, "\n ");
143     status_dots=30;
144     }
145     fprintf(stdout, "r");
146     }
147    
148     void
149     #ifdef PNG_1_0_X
150     PNGAPI
151     #endif
152     write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
153     void
154     #ifdef PNG_1_0_X
155     PNGAPI
156     #endif
157     write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
158     {
159     if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7)
160     return;
161     fprintf(stdout, "w");
162     }
163    
164    
165     #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
166     /* Example of using user transform callback (we don't transform anything,
167     * but merely examine the row filters. We set this to 256 rather than
168     * 5 in case illegal filter values are present.)
169     */
170     static png_uint_32 filters_used[256];
171     void
172     #ifdef PNG_1_0_X
173     PNGAPI
174     #endif
175     count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data);
176     void
177     #ifdef PNG_1_0_X
178     PNGAPI
179     #endif
180     count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data)
181     {
182     if (png_ptr != NULL && row_info != NULL)
183     ++filters_used[*(data - 1)];
184     }
185     #endif
186    
187     #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
188     /* Example of using user transform callback (we don't transform anything,
189     * but merely count the zero samples)
190     */
191    
192     static png_uint_32 zero_samples;
193    
194     void
195     #ifdef PNG_1_0_X
196     PNGAPI
197     #endif
198     count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data);
199     void
200     #ifdef PNG_1_0_X
201     PNGAPI
202     #endif
203     count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
204     {
205     png_bytep dp = data;
206     if (png_ptr == NULL)return;
207    
208     /* Contents of row_info:
209     * png_uint_32 width width of row
210     * png_uint_32 rowbytes number of bytes in row
211     * png_byte color_type color type of pixels
212     * png_byte bit_depth bit depth of samples
213     * png_byte channels number of channels (1-4)
214     * png_byte pixel_depth bits per pixel (depth*channels)
215     */
216    
217     /* Counts the number of zero samples (or zero pixels if color_type is 3 */
218    
219     if (row_info->color_type == 0 || row_info->color_type == 3)
220     {
221     int pos = 0;
222     png_uint_32 n, nstop;
223     for (n = 0, nstop=row_info->width; n<nstop; n++)
224     {
225     if (row_info->bit_depth == 1)
226     {
227     if (((*dp << pos++ ) & 0x80) == 0)
228     zero_samples++;
229     if (pos == 8)
230     {
231     pos = 0;
232     dp++;
233     }
234     }
235     if (row_info->bit_depth == 2)
236     {
237     if (((*dp << (pos+=2)) & 0xc0) == 0)
238     zero_samples++;
239     if (pos == 8)
240     {
241     pos = 0;
242     dp++;
243     }
244     }
245     if (row_info->bit_depth == 4)
246     {
247     if (((*dp << (pos+=4)) & 0xf0) == 0)
248     zero_samples++;
249     if (pos == 8)
250     {
251     pos = 0;
252     dp++;
253     }
254     }
255     if (row_info->bit_depth == 8)
256     if (*dp++ == 0)
257     zero_samples++;
258     if (row_info->bit_depth == 16)
259     {
260     if ((*dp | *(dp+1)) == 0)
261     zero_samples++;
262     dp+=2;
263     }
264     }
265     }
266     else /* Other color types */
267     {
268     png_uint_32 n, nstop;
269     int channel;
270     int color_channels = row_info->channels;
271     if (row_info->color_type > 3)color_channels--;
272    
273     for (n = 0, nstop=row_info->width; n<nstop; n++)
274     {
275     for (channel = 0; channel < color_channels; channel++)
276     {
277     if (row_info->bit_depth == 8)
278     if (*dp++ == 0)
279     zero_samples++;
280     if (row_info->bit_depth == 16)
281     {
282     if ((*dp | *(dp+1)) == 0)
283     zero_samples++;
284     dp+=2;
285     }
286     }
287     if (row_info->color_type > 3)
288     {
289     dp++;
290     if (row_info->bit_depth == 16)
291     dp++;
292     }
293     }
294     }
295     }
296     #endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
297    
298     static int wrote_question = 0;
299    
300     #if defined(PNG_NO_STDIO)
301     /* START of code to validate stdio-free compilation */
302     /* These copies of the default read/write functions come from pngrio.c and
303     * pngwio.c. They allow "don't include stdio" testing of the library.
304     * This is the function that does the actual reading of data. If you are
305     * not reading from a standard C stream, you should create a replacement
306     * read_data function and use it at run time with png_set_read_fn(), rather
307     * than changing the library.
308     */
309    
310     #ifndef USE_FAR_KEYWORD
311     static void
312     pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
313     {
314     png_size_t check;
315    
316     /* fread() returns 0 on error, so it is OK to store this in a png_size_t
317     * instead of an int, which is what fread() actually returns.
318     */
319     READFILE((png_FILE_p)png_ptr->io_ptr, data, length, check);
320    
321     if (check != length)
322     {
323     png_error(png_ptr, "Read Error!");
324     }
325     }
326     #else
327     /* This is the model-independent version. Since the standard I/O library
328     can't handle far buffers in the medium and small models, we have to copy
329     the data.
330     */
331    
332     #define NEAR_BUF_SIZE 1024
333     #define MIN(a,b) (a <= b ? a : b)
334    
335     static void
336     pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
337     {
338     int check;
339     png_byte *n_data;
340     png_FILE_p io_ptr;
341    
342     /* Check if data really is near. If so, use usual code. */
343     n_data = (png_byte *)CVT_PTR_NOCHECK(data);
344     io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
345     if ((png_bytep)n_data == data)
346     {
347     READFILE(io_ptr, n_data, length, check);
348     }
349     else
350     {
351     png_byte buf[NEAR_BUF_SIZE];
352     png_size_t read, remaining, err;
353     check = 0;
354     remaining = length;
355     do
356     {
357     read = MIN(NEAR_BUF_SIZE, remaining);
358     READFILE(io_ptr, buf, 1, err);
359     png_memcpy(data, buf, read); /* Copy far buffer to near buffer */
360     if (err != read)
361     break;
362     else
363     check += err;
364     data += read;
365     remaining -= read;
366     }
367     while (remaining != 0);
368     }
369     if (check != length)
370     png_error(png_ptr, "read Error");
371     }
372     #endif /* USE_FAR_KEYWORD */
373    
374     #if defined(PNG_WRITE_FLUSH_SUPPORTED)
375     static void
376     pngtest_flush(png_structp png_ptr)
377     {
378     /* Do nothing; fflush() is said to be just a waste of energy. */
379     png_ptr = png_ptr; /* Stifle compiler warning */
380     }
381     #endif
382    
383     /* This is the function that does the actual writing of data. If you are
384     * not writing to a standard C stream, you should create a replacement
385     * write_data function and use it at run time with png_set_write_fn(), rather
386     * than changing the library.
387     */
388     #ifndef USE_FAR_KEYWORD
389     static void
390     pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
391     {
392     png_uint_32 check;
393    
394     WRITEFILE((png_FILE_p)png_ptr->io_ptr, data, length, check);
395     if (check != length)
396     {
397     png_error(png_ptr, "Write Error");
398     }
399     }
400     #else
401     /* This is the model-independent version. Since the standard I/O library
402     can't handle far buffers in the medium and small models, we have to copy
403     the data.
404     */
405    
406     #define NEAR_BUF_SIZE 1024
407     #define MIN(a,b) (a <= b ? a : b)
408    
409     static void
410     pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
411     {
412     png_uint_32 check;
413     png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
414     png_FILE_p io_ptr;
415    
416     /* Check if data really is near. If so, use usual code. */
417     near_data = (png_byte *)CVT_PTR_NOCHECK(data);
418     io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
419     if ((png_bytep)near_data == data)
420     {
421     WRITEFILE(io_ptr, near_data, length, check);
422     }
423     else
424     {
425     png_byte buf[NEAR_BUF_SIZE];
426     png_size_t written, remaining, err;
427     check = 0;
428     remaining = length;
429     do
430     {
431     written = MIN(NEAR_BUF_SIZE, remaining);
432     png_memcpy(buf, data, written); /* Copy far buffer to near buffer */
433     WRITEFILE(io_ptr, buf, written, err);
434     if (err != written)
435     break;
436     else
437     check += err;
438     data += written;
439     remaining -= written;
440     }
441     while (remaining != 0);
442     }
443     if (check != length)
444     {
445     png_error(png_ptr, "Write Error");
446     }
447     }
448     #endif /* USE_FAR_KEYWORD */
449    
450     /* This function is called when there is a warning, but the library thinks
451     * it can continue anyway. Replacement functions don't have to do anything
452     * here if you don't want to. In the default configuration, png_ptr is
453     * not used, but it is passed in case it may be useful.
454     */
455     static void
456     pngtest_warning(png_structp png_ptr, png_const_charp message)
457     {
458     PNG_CONST char *name = "UNKNOWN (ERROR!)";
459     if (png_ptr != NULL && png_ptr->error_ptr != NULL)
460     name = png_ptr->error_ptr;
461     fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
462     }
463    
464     /* This is the default error handling function. Note that replacements for
465     * this function MUST NOT RETURN, or the program will likely crash. This
466     * function is used by default, or if the program supplies NULL for the
467     * error function pointer in png_set_error_fn().
468     */
469     static void
470     pngtest_error(png_structp png_ptr, png_const_charp message)
471     {
472     pngtest_warning(png_ptr, message);
473     /* We can return because png_error calls the default handler, which is
474     * actually OK in this case.
475     */
476     }
477     #endif /* PNG_NO_STDIO */
478     /* END of code to validate stdio-free compilation */
479    
480     /* START of code to validate memory allocation and deallocation */
481     #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
482    
483     /* Allocate memory. For reasonable files, size should never exceed
484     * 64K. However, zlib may allocate more then 64K if you don't tell
485     * it not to. See zconf.h and png.h for more information. zlib does
486     * need to allocate exactly 64K, so whatever you call here must
487     * have the ability to do that.
488     *
489     * This piece of code can be compiled to validate max 64K allocations
490     * by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K.
491     */
492     typedef struct memory_information
493     {
494     png_uint_32 size;
495     png_voidp pointer;
496     struct memory_information FAR *next;
497     } memory_information;
498     typedef memory_information FAR *memory_infop;
499    
500     static memory_infop pinformation = NULL;
501     static int current_allocation = 0;
502     static int maximum_allocation = 0;
503     static int total_allocation = 0;
504     static int num_allocations = 0;
505    
506     png_voidp png_debug_malloc PNGARG((png_structp png_ptr, png_uint_32 size));
507     void png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr));
508    
509     png_voidp
510     png_debug_malloc(png_structp png_ptr, png_uint_32 size)
511     {
512    
513     /* png_malloc has already tested for NULL; png_create_struct calls
514     * png_debug_malloc directly, with png_ptr == NULL which is OK
515     */
516    
517     if (size == 0)
518     return (NULL);
519    
520     /* This calls the library allocator twice, once to get the requested
521     buffer and once to get a new free list entry. */
522     {
523     /* Disable malloc_fn and free_fn */
524     memory_infop pinfo;
525     png_set_mem_fn(png_ptr, NULL, NULL, NULL);
526     pinfo = (memory_infop)png_malloc(png_ptr,
527     (png_uint_32)png_sizeof(*pinfo));
528     pinfo->size = size;
529     current_allocation += size;
530     total_allocation += size;
531     num_allocations ++;
532     if (current_allocation > maximum_allocation)
533     maximum_allocation = current_allocation;
534     pinfo->pointer = (png_voidp)png_malloc(png_ptr, size);
535     /* Restore malloc_fn and free_fn */
536     png_set_mem_fn(png_ptr,
537     png_voidp_NULL, (png_malloc_ptr)png_debug_malloc,
538     (png_free_ptr)png_debug_free);
539     if (size != 0 && pinfo->pointer == NULL)
540     {
541     current_allocation -= size;
542     total_allocation -= size;
543     png_error(png_ptr,
544     "out of memory in pngtest->png_debug_malloc.");
545     }
546     pinfo->next = pinformation;
547     pinformation = pinfo;
548     /* Make sure the caller isn't assuming zeroed memory. */
549     png_memset(pinfo->pointer, 0xdd, pinfo->size);
550     if (verbose)
551     printf("png_malloc %lu bytes at %x\n", (unsigned long)size,
552     pinfo->pointer);
553     return (png_voidp)(pinfo->pointer);
554     }
555     }
556    
557     /* Free a pointer. It is removed from the list at the same time. */
558     void
559     png_debug_free(png_structp png_ptr, png_voidp ptr)
560     {
561     if (png_ptr == NULL)
562     fprintf(STDERR, "NULL pointer to png_debug_free.\n");
563     if (ptr == 0)
564     {
565     #if 0 /* This happens all the time. */
566     fprintf(STDERR, "WARNING: freeing NULL pointer\n");
567     #endif
568     return;
569     }
570    
571     /* Unlink the element from the list. */
572     {
573     memory_infop FAR *ppinfo = &pinformation;
574     for (;;)
575     {
576     memory_infop pinfo = *ppinfo;
577     if (pinfo->pointer == ptr)
578     {
579     *ppinfo = pinfo->next;
580     current_allocation -= pinfo->size;
581     if (current_allocation < 0)
582     fprintf(STDERR, "Duplicate free of memory\n");
583     /* We must free the list element too, but first kill
584     the memory that is to be freed. */
585     png_memset(ptr, 0x55, pinfo->size);
586     png_free_default(png_ptr, pinfo);
587     pinfo = NULL;
588     break;
589     }
590     if (pinfo->next == NULL)
591     {
592     fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr);
593     break;
594     }
595     ppinfo = &pinfo->next;
596     }
597     }
598    
599     /* Finally free the data. */
600     if (verbose)
601     printf("Freeing %x\n", ptr);
602     png_free_default(png_ptr, ptr);
603     ptr = NULL;
604     }
605     #endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */
606     /* END of code to test memory allocation/deallocation */
607    
608    
609     /* Demonstration of user chunk support of the sTER and vpAg chunks */
610     #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
611    
612     /* (sTER is a public chunk not yet known by libpng. vpAg is a private
613     chunk used in ImageMagick to store "virtual page" size). */
614    
615     static png_uint_32 user_chunk_data[4];
616    
617     /* 0: sTER mode + 1
618     * 1: vpAg width
619     * 2: vpAg height
620     * 3: vpAg units
621     */
622    
623     static int read_user_chunk_callback(png_struct *png_ptr,
624     png_unknown_chunkp chunk)
625     {
626     png_uint_32
627     *my_user_chunk_data;
628    
629     /* Return one of the following:
630     * return (-n); chunk had an error
631     * return (0); did not recognize
632     * return (n); success
633     *
634     * The unknown chunk structure contains the chunk data:
635     * png_byte name[5];
636     * png_byte *data;
637     * png_size_t size;
638     *
639     * Note that libpng has already taken care of the CRC handling.
640     */
641    
642     if (chunk->name[0] == 115 && chunk->name[1] == 84 && /* s T */
643     chunk->name[2] == 69 && chunk->name[3] == 82) /* E R */
644     {
645     /* Found sTER chunk */
646     if (chunk->size != 1)
647     return (-1); /* Error return */
648     if (chunk->data[0] != 0 && chunk->data[0] != 1)
649     return (-1); /* Invalid mode */
650     my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr);
651     my_user_chunk_data[0]=chunk->data[0]+1;
652     return (1);
653     }
654    
655     if (chunk->name[0] != 118 || chunk->name[1] != 112 || /* v p */
656     chunk->name[2] != 65 || chunk->name[3] != 103) /* A g */
657     return (0); /* Did not recognize */
658    
659     /* Found ImageMagick vpAg chunk */
660    
661     if (chunk->size != 9)
662     return (-1); /* Error return */
663    
664     my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr);
665    
666     my_user_chunk_data[1]=png_get_uint_31(png_ptr, chunk->data);
667     my_user_chunk_data[2]=png_get_uint_31(png_ptr, chunk->data + 4);
668     my_user_chunk_data[3]=(png_uint_32)chunk->data[8];
669    
670     return (1);
671    
672     }
673     #endif
674     /* END of code to demonstrate user chunk support */
675    
676     /* Test one file */
677     int
678     test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
679     {
680     static png_FILE_p fpin;
681     static png_FILE_p fpout; /* "static" prevents setjmp corruption */
682     png_structp read_ptr;
683     png_infop read_info_ptr, end_info_ptr;
684     #ifdef PNG_WRITE_SUPPORTED
685     png_structp write_ptr;
686     png_infop write_info_ptr;
687     png_infop write_end_info_ptr;
688     #else
689     png_structp write_ptr = NULL;
690     png_infop write_info_ptr = NULL;
691     png_infop write_end_info_ptr = NULL;
692     #endif
693     png_bytep row_buf;
694     png_uint_32 y;
695     png_uint_32 width, height;
696     int num_pass, pass;
697     int bit_depth, color_type;
698     #ifdef PNG_SETJMP_SUPPORTED
699     #ifdef USE_FAR_KEYWORD
700     jmp_buf jmpbuf;
701     #endif
702     #endif
703    
704     #if defined(_WIN32_WCE)
705     TCHAR path[MAX_PATH];
706     #endif
707     char inbuf[256], outbuf[256];
708    
709     row_buf = NULL;
710    
711     #if defined(_WIN32_WCE)
712     MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH);
713     if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
714     #else
715     if ((fpin = fopen(inname, "rb")) == NULL)
716     #endif
717     {
718     fprintf(STDERR, "Could not find input file %s\n", inname);
719     return (1);
720     }
721    
722     #if defined(_WIN32_WCE)
723     MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH);
724     if ((fpout = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE)
725     #else
726     if ((fpout = fopen(outname, "wb")) == NULL)
727     #endif
728     {
729     fprintf(STDERR, "Could not open output file %s\n", outname);
730     FCLOSE(fpin);
731     return (1);
732     }
733    
734     png_debug(0, "Allocating read and write structures");
735     #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
736     read_ptr =
737     png_create_read_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
738     png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
739     (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
740     #else
741     read_ptr =
742     png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
743     png_error_ptr_NULL, png_error_ptr_NULL);
744     #endif
745     #if defined(PNG_NO_STDIO)
746     png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error,
747     pngtest_warning);
748     #endif
749    
750     #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
751     user_chunk_data[0] = 0;
752     user_chunk_data[1] = 0;
753     user_chunk_data[2] = 0;
754     user_chunk_data[3] = 0;
755     png_set_read_user_chunk_fn(read_ptr, user_chunk_data,
756     read_user_chunk_callback);
757    
758     #endif
759     #ifdef PNG_WRITE_SUPPORTED
760     #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
761     write_ptr =
762     png_create_write_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
763     png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
764     (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
765     #else
766     write_ptr =
767     png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
768     png_error_ptr_NULL, png_error_ptr_NULL);
769     #endif
770     #if defined(PNG_NO_STDIO)
771     png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error,
772     pngtest_warning);
773     #endif
774     #endif
775     png_debug(0, "Allocating read_info, write_info and end_info structures");
776     read_info_ptr = png_create_info_struct(read_ptr);
777     end_info_ptr = png_create_info_struct(read_ptr);
778     #ifdef PNG_WRITE_SUPPORTED
779     write_info_ptr = png_create_info_struct(write_ptr);
780     write_end_info_ptr = png_create_info_struct(write_ptr);
781     #endif
782    
783     #ifdef PNG_SETJMP_SUPPORTED
784     png_debug(0, "Setting jmpbuf for read struct");
785     #ifdef USE_FAR_KEYWORD
786     if (setjmp(jmpbuf))
787     #else
788     if (setjmp(png_jmpbuf(read_ptr)))
789     #endif
790     {
791     fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
792     png_free(read_ptr, row_buf);
793     row_buf = NULL;
794     png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
795     #ifdef PNG_WRITE_SUPPORTED
796     png_destroy_info_struct(write_ptr, &write_end_info_ptr);
797     png_destroy_write_struct(&write_ptr, &write_info_ptr);
798     #endif
799     FCLOSE(fpin);
800     FCLOSE(fpout);
801     return (1);
802     }
803     #ifdef USE_FAR_KEYWORD
804     png_memcpy(png_jmpbuf(read_ptr), jmpbuf, png_sizeof(jmp_buf));
805     #endif
806    
807     #ifdef PNG_WRITE_SUPPORTED
808     png_debug(0, "Setting jmpbuf for write struct");
809     #ifdef USE_FAR_KEYWORD
810     if (setjmp(jmpbuf))
811     #else
812     if (setjmp(png_jmpbuf(write_ptr)))
813     #endif
814     {
815     fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
816     png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
817     png_destroy_info_struct(write_ptr, &write_end_info_ptr);
818     #ifdef PNG_WRITE_SUPPORTED
819     png_destroy_write_struct(&write_ptr, &write_info_ptr);
820     #endif
821     FCLOSE(fpin);
822     FCLOSE(fpout);
823     return (1);
824     }
825     #ifdef USE_FAR_KEYWORD
826     png_memcpy(png_jmpbuf(write_ptr), jmpbuf, png_sizeof(jmp_buf));
827     #endif
828     #endif
829     #endif
830    
831     png_debug(0, "Initializing input and output streams");
832     #if !defined(PNG_NO_STDIO)
833     png_init_io(read_ptr, fpin);
834     # ifdef PNG_WRITE_SUPPORTED
835     png_init_io(write_ptr, fpout);
836     # endif
837     #else
838     png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data);
839     # ifdef PNG_WRITE_SUPPORTED
840     png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data,
841     # if defined(PNG_WRITE_FLUSH_SUPPORTED)
842     pngtest_flush);
843     # else
844     NULL);
845     # endif
846     # endif
847     #endif
848     if (status_dots_requested == 1)
849     {
850     #ifdef PNG_WRITE_SUPPORTED
851     png_set_write_status_fn(write_ptr, write_row_callback);
852     #endif
853     png_set_read_status_fn(read_ptr, read_row_callback);
854     }
855     else
856     {
857     #ifdef PNG_WRITE_SUPPORTED
858     png_set_write_status_fn(write_ptr, png_write_status_ptr_NULL);
859     #endif
860     png_set_read_status_fn(read_ptr, png_read_status_ptr_NULL);
861     }
862    
863     #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
864     {
865     int i;
866     for (i = 0; i<256; i++)
867     filters_used[i] = 0;
868     png_set_read_user_transform_fn(read_ptr, count_filters);
869     }
870     #endif
871     #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
872     zero_samples = 0;
873     png_set_write_user_transform_fn(write_ptr, count_zero_samples);
874     #endif
875    
876     #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
877     # ifndef PNG_HANDLE_CHUNK_ALWAYS
878     # define PNG_HANDLE_CHUNK_ALWAYS 3
879     # endif
880     png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS,
881     png_bytep_NULL, 0);
882     #endif
883     #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
884     # ifndef PNG_HANDLE_CHUNK_IF_SAFE
885     # define PNG_HANDLE_CHUNK_IF_SAFE 2
886     # endif
887     png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE,
888     png_bytep_NULL, 0);
889     #endif
890    
891     png_debug(0, "Reading info struct");
892     png_read_info(read_ptr, read_info_ptr);
893    
894     png_debug(0, "Transferring info struct");
895     {
896     int interlace_type, compression_type, filter_type;
897    
898     if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
899     &color_type, &interlace_type, &compression_type, &filter_type))
900     {
901     png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
902     #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
903     color_type, interlace_type, compression_type, filter_type);
904     #else
905     color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
906     #endif
907     }
908     }
909     #if defined(PNG_FIXED_POINT_SUPPORTED)
910     #if defined(PNG_cHRM_SUPPORTED)
911     {
912     png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
913     blue_y;
914     if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
915     &red_y, &green_x, &green_y, &blue_x, &blue_y))
916     {
917     png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x,
918     red_y, green_x, green_y, blue_x, blue_y);
919     }
920     }
921     #endif
922     #if defined(PNG_gAMA_SUPPORTED)
923     {
924     png_fixed_point gamma;
925    
926     if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma))
927     png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma);
928     }
929     #endif
930     #else /* Use floating point versions */
931     #if defined(PNG_FLOATING_POINT_SUPPORTED)
932     #if defined(PNG_cHRM_SUPPORTED)
933     {
934     double white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
935     blue_y;
936     if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
937     &red_y, &green_x, &green_y, &blue_x, &blue_y))
938     {
939     png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
940     red_y, green_x, green_y, blue_x, blue_y);
941     }
942     }
943     #endif
944     #if defined(PNG_gAMA_SUPPORTED)
945     {
946     double gamma;
947    
948     if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
949     png_set_gAMA(write_ptr, write_info_ptr, gamma);
950     }
951     #endif
952     #endif /* Floating point */
953     #endif /* Fixed point */
954     #if defined(PNG_iCCP_SUPPORTED)
955     {
956     png_charp name;
957     png_charp profile;
958     png_uint_32 proflen;
959     int compression_type;
960    
961     if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,
962     &profile, &proflen))
963     {
964     png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,
965     profile, proflen);
966     }
967     }
968     #endif
969     #if defined(PNG_sRGB_SUPPORTED)
970     {
971     int intent;
972    
973     if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
974     png_set_sRGB(write_ptr, write_info_ptr, intent);
975     }
976     #endif
977     {
978     png_colorp palette;
979     int num_palette;
980    
981     if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
982     png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
983     }
984     #if defined(PNG_bKGD_SUPPORTED)
985     {
986     png_color_16p background;
987    
988     if (png_get_bKGD(read_ptr, read_info_ptr, &background))
989     {
990     png_set_bKGD(write_ptr, write_info_ptr, background);
991     }
992     }
993     #endif
994     #if defined(PNG_hIST_SUPPORTED)
995     {
996     png_uint_16p hist;
997    
998     if (png_get_hIST(read_ptr, read_info_ptr, &hist))
999     png_set_hIST(write_ptr, write_info_ptr, hist);
1000     }
1001     #endif
1002     #if defined(PNG_oFFs_SUPPORTED)
1003     {
1004     png_int_32 offset_x, offset_y;
1005     int unit_type;
1006    
1007     if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y,
1008     &unit_type))
1009     {
1010     png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
1011     }
1012     }
1013     #endif
1014     #if defined(PNG_pCAL_SUPPORTED)
1015     {
1016     png_charp purpose, units;
1017     png_charpp params;
1018     png_int_32 X0, X1;
1019     int type, nparams;
1020    
1021     if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
1022     &nparams, &units, &params))
1023     {
1024     png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
1025     nparams, units, params);
1026     }
1027     }
1028     #endif
1029     #if defined(PNG_pHYs_SUPPORTED)
1030     {
1031     png_uint_32 res_x, res_y;
1032     int unit_type;
1033    
1034     if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
1035     png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
1036     }
1037     #endif
1038     #if defined(PNG_sBIT_SUPPORTED)
1039     {
1040     png_color_8p sig_bit;
1041    
1042     if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
1043     png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
1044     }
1045     #endif
1046     #if defined(PNG_sCAL_SUPPORTED)
1047     #ifdef PNG_FLOATING_POINT_SUPPORTED
1048     {
1049     int unit;
1050     double scal_width, scal_height;
1051    
1052     if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,
1053     &scal_height))
1054     {
1055     png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);
1056     }
1057     }
1058     #else
1059     #ifdef PNG_FIXED_POINT_SUPPORTED
1060     {
1061     int unit;
1062     png_charp scal_width, scal_height;
1063    
1064     if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,
1065     &scal_height))
1066     {
1067     png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, scal_height);
1068     }
1069     }
1070     #endif
1071     #endif
1072     #endif
1073     #if defined(PNG_TEXT_SUPPORTED)
1074     {
1075     png_textp text_ptr;
1076     int num_text;
1077    
1078     if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
1079     {
1080     png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks", num_text);
1081     png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
1082     }
1083     }
1084     #endif
1085     #if defined(PNG_tIME_SUPPORTED)
1086     {
1087     png_timep mod_time;
1088    
1089     if (png_get_tIME(read_ptr, read_info_ptr, &mod_time))
1090     {
1091     png_set_tIME(write_ptr, write_info_ptr, mod_time);
1092     #if defined(PNG_TIME_RFC1123_SUPPORTED)
1093     /* We have to use png_memcpy instead of "=" because the string
1094     * pointed to by png_convert_to_rfc1123() gets free'ed before
1095     * we use it.
1096     */
1097     png_memcpy(tIME_string,
1098     png_convert_to_rfc1123(read_ptr, mod_time),
1099     png_sizeof(tIME_string));
1100     tIME_string[png_sizeof(tIME_string) - 1] = '\0';
1101     tIME_chunk_present++;
1102     #endif /* PNG_TIME_RFC1123_SUPPORTED */
1103     }
1104     }
1105     #endif
1106     #if defined(PNG_tRNS_SUPPORTED)
1107     {
1108     png_bytep trans;
1109     int num_trans;
1110     png_color_16p trans_values;
1111    
1112     if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans,
1113     &trans_values))
1114     {
1115     int sample_max = (1 << read_info_ptr->bit_depth);
1116     /* libpng doesn't reject a tRNS chunk with out-of-range samples */
1117     if (!((read_info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
1118     (int)trans_values->gray > sample_max) ||
1119     (read_info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
1120     ((int)trans_values->red > sample_max ||
1121     (int)trans_values->green > sample_max ||
1122     (int)trans_values->blue > sample_max))))
1123     png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans,
1124     trans_values);
1125     }
1126     }
1127     #endif
1128     #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1129     {
1130     png_unknown_chunkp unknowns;
1131     int num_unknowns = (int)png_get_unknown_chunks(read_ptr, read_info_ptr,
1132     &unknowns);
1133     if (num_unknowns)
1134     {
1135     png_size_t i;
1136     png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns,
1137     num_unknowns);
1138     /* Copy the locations from the read_info_ptr. The automatically
1139     * generated locations in write_info_ptr are wrong because we
1140     * haven't written anything yet.
1141     */
1142     for (i = 0; i < (png_size_t)num_unknowns; i++)
1143     png_set_unknown_chunk_location(write_ptr, write_info_ptr, i,
1144     unknowns[i].location);
1145     }
1146     }
1147     #endif
1148    
1149     #ifdef PNG_WRITE_SUPPORTED
1150     png_debug(0, "Writing info struct");
1151    
1152     /* If we wanted, we could write info in two steps:
1153     * png_write_info_before_PLTE(write_ptr, write_info_ptr);
1154     */
1155     png_write_info(write_ptr, write_info_ptr);
1156    
1157     #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
1158     if (user_chunk_data[0] != 0)
1159     {
1160     png_byte png_sTER[5] = {115, 84, 69, 82, '\0'};
1161    
1162     unsigned char
1163     ster_chunk_data[1];
1164    
1165     if (verbose)
1166     fprintf(STDERR, "\n stereo mode = %lu\n",
1167     (unsigned long)(user_chunk_data[0] - 1));
1168     ster_chunk_data[0]=(unsigned char)(user_chunk_data[0] - 1);
1169     png_write_chunk(write_ptr, png_sTER, ster_chunk_data, 1);
1170     }
1171     if (user_chunk_data[1] != 0 || user_chunk_data[2] != 0)
1172     {
1173     png_byte png_vpAg[5] = {118, 112, 65, 103, '\0'};
1174    
1175     unsigned char
1176     vpag_chunk_data[9];
1177    
1178     if (verbose)
1179     fprintf(STDERR, " vpAg = %lu x %lu, units = %lu\n",
1180     (unsigned long)user_chunk_data[1],
1181     (unsigned long)user_chunk_data[2],
1182     (unsigned long)user_chunk_data[3]);
1183     png_save_uint_32(vpag_chunk_data, user_chunk_data[1]);
1184     png_save_uint_32(vpag_chunk_data + 4, user_chunk_data[2]);
1185     vpag_chunk_data[8] = (unsigned char)(user_chunk_data[3] & 0xff);
1186     png_write_chunk(write_ptr, png_vpAg, vpag_chunk_data, 9);
1187     }
1188    
1189     #endif
1190     #endif
1191    
1192     #ifdef SINGLE_ROWBUF_ALLOC
1193     png_debug(0, "Allocating row buffer...");
1194     row_buf = (png_bytep)png_malloc(read_ptr,
1195     png_get_rowbytes(read_ptr, read_info_ptr));
1196     png_debug1(0, "0x%08lx", (unsigned long)row_buf);
1197     #endif /* SINGLE_ROWBUF_ALLOC */
1198     png_debug(0, "Writing row data");
1199    
1200     #if defined(PNG_READ_INTERLACING_SUPPORTED) || \
1201     defined(PNG_WRITE_INTERLACING_SUPPORTED)
1202     num_pass = png_set_interlace_handling(read_ptr);
1203     # ifdef PNG_WRITE_SUPPORTED
1204     png_set_interlace_handling(write_ptr);
1205     # endif
1206     #else
1207     num_pass = 1;
1208     #endif
1209    
1210     #ifdef PNGTEST_TIMING
1211     t_stop = (float)clock();
1212     t_misc += (t_stop - t_start);
1213     t_start = t_stop;
1214     #endif
1215     for (pass = 0; pass < num_pass; pass++)
1216     {
1217     png_debug1(0, "Writing row data for pass %d", pass);
1218     for (y = 0; y < height; y++)
1219     {
1220     #ifndef SINGLE_ROWBUF_ALLOC
1221     png_debug2(0, "Allocating row buffer (pass %d, y = %ld)...", pass, y);
1222     row_buf = (png_bytep)png_malloc(read_ptr,
1223     png_get_rowbytes(read_ptr, read_info_ptr));
1224     png_debug2(0, "0x%08lx (%ld bytes)", (unsigned long)row_buf,
1225     png_get_rowbytes(read_ptr, read_info_ptr));
1226     #endif /* !SINGLE_ROWBUF_ALLOC */
1227     png_read_rows(read_ptr, (png_bytepp)&row_buf, png_bytepp_NULL, 1);
1228    
1229     #ifdef PNG_WRITE_SUPPORTED
1230     #ifdef PNGTEST_TIMING
1231     t_stop = (float)clock();
1232     t_decode += (t_stop - t_start);
1233     t_start = t_stop;
1234     #endif
1235     png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
1236     #ifdef PNGTEST_TIMING
1237     t_stop = (float)clock();
1238     t_encode += (t_stop - t_start);
1239     t_start = t_stop;
1240     #endif
1241     #endif /* PNG_WRITE_SUPPORTED */
1242    
1243     #ifndef SINGLE_ROWBUF_ALLOC
1244     png_debug2(0, "Freeing row buffer (pass %d, y = %ld)", pass, y);
1245     png_free(read_ptr, row_buf);
1246     row_buf = NULL;
1247     #endif /* !SINGLE_ROWBUF_ALLOC */
1248     }
1249     }
1250    
1251     #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
1252     png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1);
1253     #endif
1254     #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1255     png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1);
1256     #endif
1257    
1258     png_debug(0, "Reading and writing end_info data");
1259    
1260     png_read_end(read_ptr, end_info_ptr);
1261     #if defined(PNG_TEXT_SUPPORTED)
1262     {
1263     png_textp text_ptr;
1264     int num_text;
1265    
1266     if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0)
1267     {
1268     png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks", num_text);
1269     png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text);
1270     }
1271     }
1272     #endif
1273     #if defined(PNG_tIME_SUPPORTED)
1274     {
1275     png_timep mod_time;
1276    
1277     if (png_get_tIME(read_ptr, end_info_ptr, &mod_time))
1278     {
1279     png_set_tIME(write_ptr, write_end_info_ptr, mod_time);
1280     #if defined(PNG_TIME_RFC1123_SUPPORTED)
1281     /* We have to use png_memcpy instead of "=" because the string
1282     pointed to by png_convert_to_rfc1123() gets free'ed before
1283     we use it */
1284     png_memcpy(tIME_string,
1285     png_convert_to_rfc1123(read_ptr, mod_time),
1286     png_sizeof(tIME_string));
1287     tIME_string[png_sizeof(tIME_string) - 1] = '\0';
1288     tIME_chunk_present++;
1289     #endif /* PNG_TIME_RFC1123_SUPPORTED */
1290     }
1291     }
1292     #endif
1293     #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
1294     {
1295     png_unknown_chunkp unknowns;
1296     int num_unknowns;
1297     num_unknowns = (int)png_get_unknown_chunks(read_ptr, end_info_ptr,
1298     &unknowns);
1299     if (num_unknowns)
1300     {
1301     png_size_t i;
1302     png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,
1303     num_unknowns);
1304     /* Copy the locations from the read_info_ptr. The automatically
1305     * generated locations in write_end_info_ptr are wrong because we
1306     * haven't written the end_info yet.
1307     */
1308     for (i = 0; i < (png_size_t)num_unknowns; i++)
1309     png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i,
1310     unknowns[i].location);
1311     }
1312     }
1313     #endif
1314     #ifdef PNG_WRITE_SUPPORTED
1315     png_write_end(write_ptr, write_end_info_ptr);
1316     #endif
1317    
1318     #ifdef PNG_EASY_ACCESS_SUPPORTED
1319     if (verbose)
1320     {
1321     png_uint_32 iwidth, iheight;
1322     iwidth = png_get_image_width(write_ptr, write_info_ptr);
1323     iheight = png_get_image_height(write_ptr, write_info_ptr);
1324     fprintf(STDERR, "\n Image width = %lu, height = %lu\n",
1325     (unsigned long)iwidth, (unsigned long)iheight);
1326     }
1327     #endif
1328    
1329     png_debug(0, "Destroying data structs");
1330     #ifdef SINGLE_ROWBUF_ALLOC
1331     png_debug(1, "destroying row_buf for read_ptr");
1332     png_free(read_ptr, row_buf);
1333     row_buf = NULL;
1334     #endif /* SINGLE_ROWBUF_ALLOC */
1335     png_debug(1, "destroying read_ptr, read_info_ptr, end_info_ptr");
1336     png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
1337     #ifdef PNG_WRITE_SUPPORTED
1338     png_debug(1, "destroying write_end_info_ptr");
1339     png_destroy_info_struct(write_ptr, &write_end_info_ptr);
1340     png_debug(1, "destroying write_ptr, write_info_ptr");
1341     png_destroy_write_struct(&write_ptr, &write_info_ptr);
1342     #endif
1343     png_debug(0, "Destruction complete.");
1344    
1345     FCLOSE(fpin);
1346     FCLOSE(fpout);
1347    
1348     png_debug(0, "Opening files for comparison");
1349     #if defined(_WIN32_WCE)
1350     MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH);
1351     if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
1352     #else
1353     if ((fpin = fopen(inname, "rb")) == NULL)
1354     #endif
1355     {
1356     fprintf(STDERR, "Could not find file %s\n", inname);
1357     return (1);
1358     }
1359    
1360     #if defined(_WIN32_WCE)
1361     MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH);
1362     if ((fpout = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
1363     #else
1364     if ((fpout = fopen(outname, "rb")) == NULL)
1365     #endif
1366     {
1367     fprintf(STDERR, "Could not find file %s\n", outname);
1368     FCLOSE(fpin);
1369     return (1);
1370     }
1371    
1372     for (;;)
1373     {
1374     png_size_t num_in, num_out;
1375    
1376     READFILE(fpin, inbuf, 1, num_in);
1377     READFILE(fpout, outbuf, 1, num_out);
1378    
1379     if (num_in != num_out)
1380     {
1381     fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
1382     inname, outname);
1383     if (wrote_question == 0)
1384     {
1385     fprintf(STDERR,
1386     " Was %s written with the same maximum IDAT chunk size (%d bytes),",
1387     inname, PNG_ZBUF_SIZE);
1388     fprintf(STDERR,
1389     "\n filtering heuristic (libpng default), compression");
1390     fprintf(STDERR,
1391     " level (zlib default),\n and zlib version (%s)?\n\n",
1392     ZLIB_VERSION);
1393     wrote_question = 1;
1394     }
1395     FCLOSE(fpin);
1396     FCLOSE(fpout);
1397     return (0);
1398     }
1399    
1400     if (!num_in)
1401     break;
1402    
1403     if (png_memcmp(inbuf, outbuf, num_in))
1404     {
1405     fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname);
1406     if (wrote_question == 0)
1407     {
1408     fprintf(STDERR,
1409     " Was %s written with the same maximum IDAT chunk size (%d bytes),",
1410     inname, PNG_ZBUF_SIZE);
1411     fprintf(STDERR,
1412     "\n filtering heuristic (libpng default), compression");
1413     fprintf(STDERR,
1414     " level (zlib default),\n and zlib version (%s)?\n\n",
1415     ZLIB_VERSION);
1416     wrote_question = 1;
1417     }
1418     FCLOSE(fpin);
1419     FCLOSE(fpout);
1420     return (0);
1421     }
1422     }
1423    
1424     FCLOSE(fpin);
1425     FCLOSE(fpout);
1426    
1427     return (0);
1428     }
1429    
1430     /* Input and output filenames */
1431     #ifdef RISCOS
1432     static PNG_CONST char *inname = "pngtest/png";
1433     static PNG_CONST char *outname = "pngout/png";
1434     #else
1435     static PNG_CONST char *inname = "pngtest.png";
1436     static PNG_CONST char *outname = "pngout.png";
1437     #endif
1438    
1439     int
1440     main(int argc, char *argv[])
1441     {
1442     int multiple = 0;
1443     int ierror = 0;
1444    
1445     fprintf(STDERR, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
1446     fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION);
1447     fprintf(STDERR, "%s", png_get_copyright(NULL));
1448     /* Show the version of libpng used in building the library */
1449     fprintf(STDERR, " library (%lu):%s",
1450     (unsigned long)png_access_version_number(),
1451     png_get_header_version(NULL));
1452     /* Show the version of libpng used in building the application */
1453     fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER,
1454     PNG_HEADER_VERSION_STRING);
1455     fprintf(STDERR, " sizeof(png_struct)=%ld, sizeof(png_info)=%ld\n",
1456     (long)png_sizeof(png_struct), (long)png_sizeof(png_info));
1457    
1458     /* Do some consistency checking on the memory allocation settings, I'm
1459     * not sure this matters, but it is nice to know, the first of these
1460     * tests should be impossible because of the way the macros are set
1461     * in pngconf.h
1462     */
1463     #if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
1464     fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n");
1465     #endif
1466     /* I think the following can happen. */
1467     #if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
1468     fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n");
1469     #endif
1470    
1471     if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
1472     {
1473     fprintf(STDERR,
1474     "Warning: versions are different between png.h and png.c\n");
1475     fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING);
1476     fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver);
1477     ++ierror;
1478     }
1479    
1480     if (argc > 1)
1481     {
1482     if (strcmp(argv[1], "-m") == 0)
1483     {
1484     multiple = 1;
1485     status_dots_requested = 0;
1486     }
1487     else if (strcmp(argv[1], "-mv") == 0 ||
1488     strcmp(argv[1], "-vm") == 0 )
1489     {
1490     multiple = 1;
1491     verbose = 1;
1492     status_dots_requested = 1;
1493     }
1494     else if (strcmp(argv[1], "-v") == 0)
1495     {
1496     verbose = 1;
1497     status_dots_requested = 1;
1498     inname = argv[2];
1499     }
1500     else
1501     {
1502     inname = argv[1];
1503     status_dots_requested = 0;
1504     }
1505     }
1506    
1507     if (!multiple && argc == 3 + verbose)
1508     outname = argv[2 + verbose];
1509    
1510     if ((!multiple && argc > 3 + verbose) || (multiple && argc < 2))
1511     {
1512     fprintf(STDERR,
1513     "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
1514     argv[0], argv[0]);
1515     fprintf(STDERR,
1516     " reads/writes one PNG file (without -m) or multiple files (-m)\n");
1517     fprintf(STDERR,
1518     " with -m %s is used as a temporary file\n", outname);
1519     exit(1);
1520     }
1521    
1522     if (multiple)
1523     {
1524     int i;
1525     #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1526     int allocation_now = current_allocation;
1527     #endif
1528     for (i=2; i<argc; ++i)
1529     {
1530     #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1531     int k;
1532     #endif
1533     int kerror;
1534     fprintf(STDERR, "\n Testing %s:", argv[i]);
1535     kerror = test_one_file(argv[i], outname);
1536     if (kerror == 0)
1537     {
1538     #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
1539     fprintf(STDERR, "\n PASS (%lu zero samples)\n",
1540     (unsigned long)zero_samples);
1541     #else
1542     fprintf(STDERR, " PASS\n");
1543     #endif
1544     #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1545     for (k = 0; k<256; k++)
1546     if (filters_used[k])
1547     fprintf(STDERR, " Filter %d was used %lu times\n",
1548     k, (unsigned long)filters_used[k]);
1549     #endif
1550     #if defined(PNG_TIME_RFC1123_SUPPORTED)
1551     if (tIME_chunk_present != 0)
1552     fprintf(STDERR, " tIME = %s\n", tIME_string);
1553     tIME_chunk_present = 0;
1554     #endif /* PNG_TIME_RFC1123_SUPPORTED */
1555     }
1556     else
1557     {
1558     fprintf(STDERR, " FAIL\n");
1559     ierror += kerror;
1560     }
1561     #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1562     if (allocation_now != current_allocation)
1563     fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
1564     current_allocation - allocation_now);
1565     if (current_allocation != 0)
1566     {
1567     memory_infop pinfo = pinformation;
1568    
1569     fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
1570     current_allocation);
1571     while (pinfo != NULL)
1572     {
1573     fprintf(STDERR, " %lu bytes at %x\n",
1574     (unsigned long)pinfo->size,
1575     (unsigned int) pinfo->pointer);
1576     pinfo = pinfo->next;
1577     }
1578     }
1579     #endif
1580     }
1581     #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1582     fprintf(STDERR, " Current memory allocation: %10d bytes\n",
1583     current_allocation);
1584     fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
1585     maximum_allocation);
1586     fprintf(STDERR, " Total memory allocation: %10d bytes\n",
1587     total_allocation);
1588     fprintf(STDERR, " Number of allocations: %10d\n",
1589     num_allocations);
1590     #endif
1591     }
1592     else
1593     {
1594     int i;
1595     for (i = 0; i<3; ++i)
1596     {
1597     int kerror;
1598     #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1599     int allocation_now = current_allocation;
1600     #endif
1601     if (i == 1) status_dots_requested = 1;
1602     else if (verbose == 0)status_dots_requested = 0;
1603     if (i == 0 || verbose == 1 || ierror != 0)
1604     fprintf(STDERR, "\n Testing %s:", inname);
1605     kerror = test_one_file(inname, outname);
1606     if (kerror == 0)
1607     {
1608     if (verbose == 1 || i == 2)
1609     {
1610     #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1611     int k;
1612     #endif
1613     #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
1614     fprintf(STDERR, "\n PASS (%lu zero samples)\n",
1615     (unsigned long)zero_samples);
1616     #else
1617     fprintf(STDERR, " PASS\n");
1618     #endif
1619     #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1620     for (k = 0; k<256; k++)
1621     if (filters_used[k])
1622     fprintf(STDERR, " Filter %d was used %lu times\n",
1623     k,
1624     (unsigned long)filters_used[k]);
1625     #endif
1626     #if defined(PNG_TIME_RFC1123_SUPPORTED)
1627     if (tIME_chunk_present != 0)
1628     fprintf(STDERR, " tIME = %s\n", tIME_string);
1629     #endif /* PNG_TIME_RFC1123_SUPPORTED */
1630     }
1631     }
1632     else
1633     {
1634     if (verbose == 0 && i != 2)
1635     fprintf(STDERR, "\n Testing %s:", inname);
1636     fprintf(STDERR, " FAIL\n");
1637     ierror += kerror;
1638     }
1639     #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1640     if (allocation_now != current_allocation)
1641     fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
1642     current_allocation - allocation_now);
1643     if (current_allocation != 0)
1644     {
1645     memory_infop pinfo = pinformation;
1646    
1647     fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
1648     current_allocation);
1649     while (pinfo != NULL)
1650     {
1651     fprintf(STDERR, " %lu bytes at %x\n",
1652     (unsigned long)pinfo->size, (unsigned int)pinfo->pointer);
1653     pinfo = pinfo->next;
1654     }
1655     }
1656     #endif
1657     }
1658     #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
1659     fprintf(STDERR, " Current memory allocation: %10d bytes\n",
1660     current_allocation);
1661     fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
1662     maximum_allocation);
1663     fprintf(STDERR, " Total memory allocation: %10d bytes\n",
1664     total_allocation);
1665     fprintf(STDERR, " Number of allocations: %10d\n",
1666     num_allocations);
1667     #endif
1668     }
1669    
1670     #ifdef PNGTEST_TIMING
1671     t_stop = (float)clock();
1672     t_misc += (t_stop - t_start);
1673     t_start = t_stop;
1674     fprintf(STDERR, " CPU time used = %.3f seconds",
1675     (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
1676     fprintf(STDERR, " (decoding %.3f,\n",
1677     t_decode/(float)CLOCKS_PER_SEC);
1678     fprintf(STDERR, " encoding %.3f ,",
1679     t_encode/(float)CLOCKS_PER_SEC);
1680     fprintf(STDERR, " other %.3f seconds)\n\n",
1681     t_misc/(float)CLOCKS_PER_SEC);
1682     #endif
1683    
1684     if (ierror == 0)
1685     fprintf(STDERR, " libpng passes test\n");
1686     else
1687     fprintf(STDERR, " libpng FAILS test\n");
1688     return (int)(ierror != 0);
1689     }
1690    
1691     /* Generate a compiler error if there is an old png.h in the search path. */
1692     typedef version_1_2_39 your_png_h_is_not_version_1_2_39;

  ViewVC Help
Powered by ViewVC 1.1.22