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