xref: /aosp_15_r20/external/libpng/contrib/libtests/readpng.c (revision a67afe4df73cf47866eedc69947994b8ff839aba)
1*a67afe4dSAndroid Build Coastguard Worker 
2*a67afe4dSAndroid Build Coastguard Worker /* readpng.c
3*a67afe4dSAndroid Build Coastguard Worker  *
4*a67afe4dSAndroid Build Coastguard Worker  * Copyright (c) 2013 John Cunningham Bowler
5*a67afe4dSAndroid Build Coastguard Worker  *
6*a67afe4dSAndroid Build Coastguard Worker  * This code is released under the libpng license.
7*a67afe4dSAndroid Build Coastguard Worker  * For conditions of distribution and use, see the disclaimer
8*a67afe4dSAndroid Build Coastguard Worker  * and license in png.h
9*a67afe4dSAndroid Build Coastguard Worker  *
10*a67afe4dSAndroid Build Coastguard Worker  * Load an arbitrary number of PNG files (from the command line, or, if there
11*a67afe4dSAndroid Build Coastguard Worker  * are no arguments on the command line, from stdin) then run a time test by
12*a67afe4dSAndroid Build Coastguard Worker  * reading each file by row.  The test does nothing with the read result and
13*a67afe4dSAndroid Build Coastguard Worker  * does no transforms.  The only output is a time as a floating point number of
14*a67afe4dSAndroid Build Coastguard Worker  * seconds with 9 decimal digits.
15*a67afe4dSAndroid Build Coastguard Worker  */
16*a67afe4dSAndroid Build Coastguard Worker #include <stdlib.h>
17*a67afe4dSAndroid Build Coastguard Worker #include <stdio.h>
18*a67afe4dSAndroid Build Coastguard Worker #include <string.h>
19*a67afe4dSAndroid Build Coastguard Worker 
20*a67afe4dSAndroid Build Coastguard Worker #if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
21*a67afe4dSAndroid Build Coastguard Worker #  include <config.h>
22*a67afe4dSAndroid Build Coastguard Worker #endif
23*a67afe4dSAndroid Build Coastguard Worker 
24*a67afe4dSAndroid Build Coastguard Worker /* Define the following to use this test against your installed libpng, rather
25*a67afe4dSAndroid Build Coastguard Worker  * than the one being built here:
26*a67afe4dSAndroid Build Coastguard Worker  */
27*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_FREESTANDING_TESTS
28*a67afe4dSAndroid Build Coastguard Worker #  include <png.h>
29*a67afe4dSAndroid Build Coastguard Worker #else
30*a67afe4dSAndroid Build Coastguard Worker #  include "../../png.h"
31*a67afe4dSAndroid Build Coastguard Worker #endif
32*a67afe4dSAndroid Build Coastguard Worker 
33*a67afe4dSAndroid Build Coastguard Worker static int
read_png(FILE * fp)34*a67afe4dSAndroid Build Coastguard Worker read_png(FILE *fp)
35*a67afe4dSAndroid Build Coastguard Worker {
36*a67afe4dSAndroid Build Coastguard Worker    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);
37*a67afe4dSAndroid Build Coastguard Worker    png_infop info_ptr = NULL;
38*a67afe4dSAndroid Build Coastguard Worker    png_bytep row = NULL, display = NULL;
39*a67afe4dSAndroid Build Coastguard Worker 
40*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr == NULL)
41*a67afe4dSAndroid Build Coastguard Worker       return 0;
42*a67afe4dSAndroid Build Coastguard Worker 
43*a67afe4dSAndroid Build Coastguard Worker    if (setjmp(png_jmpbuf(png_ptr)))
44*a67afe4dSAndroid Build Coastguard Worker    {
45*a67afe4dSAndroid Build Coastguard Worker       png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
46*a67afe4dSAndroid Build Coastguard Worker       if (row != NULL) free(row);
47*a67afe4dSAndroid Build Coastguard Worker       if (display != NULL) free(display);
48*a67afe4dSAndroid Build Coastguard Worker       return 0;
49*a67afe4dSAndroid Build Coastguard Worker    }
50*a67afe4dSAndroid Build Coastguard Worker 
51*a67afe4dSAndroid Build Coastguard Worker    png_init_io(png_ptr, fp);
52*a67afe4dSAndroid Build Coastguard Worker 
53*a67afe4dSAndroid Build Coastguard Worker    info_ptr = png_create_info_struct(png_ptr);
54*a67afe4dSAndroid Build Coastguard Worker    if (info_ptr == NULL)
55*a67afe4dSAndroid Build Coastguard Worker       png_error(png_ptr, "OOM allocating info structure");
56*a67afe4dSAndroid Build Coastguard Worker 
57*a67afe4dSAndroid Build Coastguard Worker    png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, NULL, 0);
58*a67afe4dSAndroid Build Coastguard Worker 
59*a67afe4dSAndroid Build Coastguard Worker    png_read_info(png_ptr, info_ptr);
60*a67afe4dSAndroid Build Coastguard Worker 
61*a67afe4dSAndroid Build Coastguard Worker    {
62*a67afe4dSAndroid Build Coastguard Worker       size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);
63*a67afe4dSAndroid Build Coastguard Worker 
64*a67afe4dSAndroid Build Coastguard Worker       /* Failure to initialize these is harmless */
65*a67afe4dSAndroid Build Coastguard Worker       row = malloc(rowbytes);
66*a67afe4dSAndroid Build Coastguard Worker       display = malloc(rowbytes);
67*a67afe4dSAndroid Build Coastguard Worker 
68*a67afe4dSAndroid Build Coastguard Worker       if (row == NULL || display == NULL)
69*a67afe4dSAndroid Build Coastguard Worker          png_error(png_ptr, "OOM allocating row buffers");
70*a67afe4dSAndroid Build Coastguard Worker 
71*a67afe4dSAndroid Build Coastguard Worker       {
72*a67afe4dSAndroid Build Coastguard Worker          png_uint_32 height = png_get_image_height(png_ptr, info_ptr);
73*a67afe4dSAndroid Build Coastguard Worker #        ifdef PNG_READ_INTERLACING_SUPPORTED
74*a67afe4dSAndroid Build Coastguard Worker             int passes = png_set_interlace_handling(png_ptr);
75*a67afe4dSAndroid Build Coastguard Worker #        else /* !READ_INTERLACING */
76*a67afe4dSAndroid Build Coastguard Worker             int passes = png_get_interlace_type(png_ptr, info_ptr) ==
77*a67afe4dSAndroid Build Coastguard Worker                PNG_INTERLACE_ADAM7 ? PNG_INTERLACE_ADAM7_PASSES : 1;
78*a67afe4dSAndroid Build Coastguard Worker #        endif /* !READ_INTERLACING */
79*a67afe4dSAndroid Build Coastguard Worker          int pass;
80*a67afe4dSAndroid Build Coastguard Worker 
81*a67afe4dSAndroid Build Coastguard Worker          png_start_read_image(png_ptr);
82*a67afe4dSAndroid Build Coastguard Worker 
83*a67afe4dSAndroid Build Coastguard Worker          for (pass = 0; pass < passes; ++pass)
84*a67afe4dSAndroid Build Coastguard Worker          {
85*a67afe4dSAndroid Build Coastguard Worker             png_uint_32 y = height;
86*a67afe4dSAndroid Build Coastguard Worker 
87*a67afe4dSAndroid Build Coastguard Worker #           ifndef PNG_READ_INTERLACING_SUPPORTED
88*a67afe4dSAndroid Build Coastguard Worker                if (passes == PNG_INTERLACE_ADAM7_PASSES)
89*a67afe4dSAndroid Build Coastguard Worker                   y = PNG_PASS_ROWS(y, pass);
90*a67afe4dSAndroid Build Coastguard Worker #           endif /* READ_INTERLACING */
91*a67afe4dSAndroid Build Coastguard Worker 
92*a67afe4dSAndroid Build Coastguard Worker             /* NOTE: this trashes the row each time; interlace handling won't
93*a67afe4dSAndroid Build Coastguard Worker              * work, but this avoids memory thrashing for speed testing.
94*a67afe4dSAndroid Build Coastguard Worker              */
95*a67afe4dSAndroid Build Coastguard Worker             while (y-- > 0)
96*a67afe4dSAndroid Build Coastguard Worker                png_read_row(png_ptr, row, display);
97*a67afe4dSAndroid Build Coastguard Worker          }
98*a67afe4dSAndroid Build Coastguard Worker       }
99*a67afe4dSAndroid Build Coastguard Worker    }
100*a67afe4dSAndroid Build Coastguard Worker 
101*a67afe4dSAndroid Build Coastguard Worker    /* Make sure to read to the end of the file: */
102*a67afe4dSAndroid Build Coastguard Worker    png_read_end(png_ptr, info_ptr);
103*a67afe4dSAndroid Build Coastguard Worker    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
104*a67afe4dSAndroid Build Coastguard Worker    free(row);
105*a67afe4dSAndroid Build Coastguard Worker    free(display);
106*a67afe4dSAndroid Build Coastguard Worker    return 1;
107*a67afe4dSAndroid Build Coastguard Worker }
108*a67afe4dSAndroid Build Coastguard Worker 
109*a67afe4dSAndroid Build Coastguard Worker int
main(void)110*a67afe4dSAndroid Build Coastguard Worker main(void)
111*a67afe4dSAndroid Build Coastguard Worker {
112*a67afe4dSAndroid Build Coastguard Worker    /* Exit code 0 on success. */
113*a67afe4dSAndroid Build Coastguard Worker    return !read_png(stdin);
114*a67afe4dSAndroid Build Coastguard Worker }
115