1*a67afe4dSAndroid Build Coastguard Worker /*---------------------------------------------------------------------------
2*a67afe4dSAndroid Build Coastguard Worker
3*a67afe4dSAndroid Build Coastguard Worker rpng - simple PNG display program readppm.c
4*a67afe4dSAndroid Build Coastguard Worker
5*a67afe4dSAndroid Build Coastguard Worker ---------------------------------------------------------------------------
6*a67afe4dSAndroid Build Coastguard Worker
7*a67afe4dSAndroid Build Coastguard Worker This is a special-purpose replacement for readpng.c that allows binary
8*a67afe4dSAndroid Build Coastguard Worker PPM files to be used in place of PNG images.
9*a67afe4dSAndroid Build Coastguard Worker
10*a67afe4dSAndroid Build Coastguard Worker ---------------------------------------------------------------------------
11*a67afe4dSAndroid Build Coastguard Worker
12*a67afe4dSAndroid Build Coastguard Worker Copyright (c) 1998-2007,2017 Greg Roelofs. All rights reserved.
13*a67afe4dSAndroid Build Coastguard Worker
14*a67afe4dSAndroid Build Coastguard Worker This software is provided "as is," without warranty of any kind,
15*a67afe4dSAndroid Build Coastguard Worker express or implied. In no event shall the author or contributors
16*a67afe4dSAndroid Build Coastguard Worker be held liable for any damages arising in any way from the use of
17*a67afe4dSAndroid Build Coastguard Worker this software.
18*a67afe4dSAndroid Build Coastguard Worker
19*a67afe4dSAndroid Build Coastguard Worker The contents of this file are DUAL-LICENSED. You may modify and/or
20*a67afe4dSAndroid Build Coastguard Worker redistribute this software according to the terms of one of the
21*a67afe4dSAndroid Build Coastguard Worker following two licenses (at your option):
22*a67afe4dSAndroid Build Coastguard Worker
23*a67afe4dSAndroid Build Coastguard Worker
24*a67afe4dSAndroid Build Coastguard Worker LICENSE 1 ("BSD-like with advertising clause"):
25*a67afe4dSAndroid Build Coastguard Worker
26*a67afe4dSAndroid Build Coastguard Worker Permission is granted to anyone to use this software for any purpose,
27*a67afe4dSAndroid Build Coastguard Worker including commercial applications, and to alter it and redistribute
28*a67afe4dSAndroid Build Coastguard Worker it freely, subject to the following restrictions:
29*a67afe4dSAndroid Build Coastguard Worker
30*a67afe4dSAndroid Build Coastguard Worker 1. Redistributions of source code must retain the above copyright
31*a67afe4dSAndroid Build Coastguard Worker notice, disclaimer, and this list of conditions.
32*a67afe4dSAndroid Build Coastguard Worker 2. Redistributions in binary form must reproduce the above copyright
33*a67afe4dSAndroid Build Coastguard Worker notice, disclaimer, and this list of conditions in the documenta-
34*a67afe4dSAndroid Build Coastguard Worker tion and/or other materials provided with the distribution.
35*a67afe4dSAndroid Build Coastguard Worker 3. All advertising materials mentioning features or use of this
36*a67afe4dSAndroid Build Coastguard Worker software must display the following acknowledgment:
37*a67afe4dSAndroid Build Coastguard Worker
38*a67afe4dSAndroid Build Coastguard Worker This product includes software developed by Greg Roelofs
39*a67afe4dSAndroid Build Coastguard Worker and contributors for the book, "PNG: The Definitive Guide,"
40*a67afe4dSAndroid Build Coastguard Worker published by O'Reilly and Associates.
41*a67afe4dSAndroid Build Coastguard Worker
42*a67afe4dSAndroid Build Coastguard Worker
43*a67afe4dSAndroid Build Coastguard Worker LICENSE 2 (GNU GPL v2 or later):
44*a67afe4dSAndroid Build Coastguard Worker
45*a67afe4dSAndroid Build Coastguard Worker This program is free software; you can redistribute it and/or modify
46*a67afe4dSAndroid Build Coastguard Worker it under the terms of the GNU General Public License as published by
47*a67afe4dSAndroid Build Coastguard Worker the Free Software Foundation; either version 2 of the License, or
48*a67afe4dSAndroid Build Coastguard Worker (at your option) any later version.
49*a67afe4dSAndroid Build Coastguard Worker
50*a67afe4dSAndroid Build Coastguard Worker This program is distributed in the hope that it will be useful,
51*a67afe4dSAndroid Build Coastguard Worker but WITHOUT ANY WARRANTY; without even the implied warranty of
52*a67afe4dSAndroid Build Coastguard Worker MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53*a67afe4dSAndroid Build Coastguard Worker GNU General Public License for more details.
54*a67afe4dSAndroid Build Coastguard Worker
55*a67afe4dSAndroid Build Coastguard Worker You should have received a copy of the GNU General Public License
56*a67afe4dSAndroid Build Coastguard Worker along with this program; if not, write to the Free Software Foundation,
57*a67afe4dSAndroid Build Coastguard Worker Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
58*a67afe4dSAndroid Build Coastguard Worker
59*a67afe4dSAndroid Build Coastguard Worker ---------------------------------------------------------------------------*/
60*a67afe4dSAndroid Build Coastguard Worker
61*a67afe4dSAndroid Build Coastguard Worker #include <stdio.h>
62*a67afe4dSAndroid Build Coastguard Worker #include <stdlib.h>
63*a67afe4dSAndroid Build Coastguard Worker
64*a67afe4dSAndroid Build Coastguard Worker #include "readpng.h" /* typedefs, common macros, public prototypes */
65*a67afe4dSAndroid Build Coastguard Worker
66*a67afe4dSAndroid Build Coastguard Worker
67*a67afe4dSAndroid Build Coastguard Worker ulg width, height;
68*a67afe4dSAndroid Build Coastguard Worker int bit_depth, color_type, channels;
69*a67afe4dSAndroid Build Coastguard Worker uch *image_data = NULL;
70*a67afe4dSAndroid Build Coastguard Worker FILE *saved_infile;
71*a67afe4dSAndroid Build Coastguard Worker
72*a67afe4dSAndroid Build Coastguard Worker
readpng_version_info()73*a67afe4dSAndroid Build Coastguard Worker void readpng_version_info()
74*a67afe4dSAndroid Build Coastguard Worker {
75*a67afe4dSAndroid Build Coastguard Worker fprintf(stderr, " Compiled without libpng, zlib or PBMPLUS/NetPBM.\n");
76*a67afe4dSAndroid Build Coastguard Worker }
77*a67afe4dSAndroid Build Coastguard Worker
78*a67afe4dSAndroid Build Coastguard Worker
79*a67afe4dSAndroid Build Coastguard Worker /* return value = 0 for success, 1 for bad sig, 2 for bad IHDR, 4 for no mem */
80*a67afe4dSAndroid Build Coastguard Worker
readpng_init(FILE * infile,ulg * pWidth,ulg * pHeight)81*a67afe4dSAndroid Build Coastguard Worker int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight)
82*a67afe4dSAndroid Build Coastguard Worker {
83*a67afe4dSAndroid Build Coastguard Worker static uch ppmline[256];
84*a67afe4dSAndroid Build Coastguard Worker int maxval;
85*a67afe4dSAndroid Build Coastguard Worker
86*a67afe4dSAndroid Build Coastguard Worker
87*a67afe4dSAndroid Build Coastguard Worker saved_infile = infile;
88*a67afe4dSAndroid Build Coastguard Worker
89*a67afe4dSAndroid Build Coastguard Worker fgets(ppmline, 256, infile);
90*a67afe4dSAndroid Build Coastguard Worker if (ppmline[0] != 'P' || ppmline[1] != '6') {
91*a67afe4dSAndroid Build Coastguard Worker fprintf(stderr, "ERROR: not a PPM file\n");
92*a67afe4dSAndroid Build Coastguard Worker return 1;
93*a67afe4dSAndroid Build Coastguard Worker }
94*a67afe4dSAndroid Build Coastguard Worker /* possible color types: P5 = grayscale (0), P6 = RGB (2), P8 = RGBA (6) */
95*a67afe4dSAndroid Build Coastguard Worker if (ppmline[1] == '6') {
96*a67afe4dSAndroid Build Coastguard Worker color_type = 2;
97*a67afe4dSAndroid Build Coastguard Worker channels = 3;
98*a67afe4dSAndroid Build Coastguard Worker } else if (ppmline[1] == '8') {
99*a67afe4dSAndroid Build Coastguard Worker color_type = 6;
100*a67afe4dSAndroid Build Coastguard Worker channels = 4;
101*a67afe4dSAndroid Build Coastguard Worker } else /* if (ppmline[1] == '5') */ {
102*a67afe4dSAndroid Build Coastguard Worker color_type = 0;
103*a67afe4dSAndroid Build Coastguard Worker channels = 1;
104*a67afe4dSAndroid Build Coastguard Worker }
105*a67afe4dSAndroid Build Coastguard Worker
106*a67afe4dSAndroid Build Coastguard Worker do {
107*a67afe4dSAndroid Build Coastguard Worker fgets(ppmline, 256, infile);
108*a67afe4dSAndroid Build Coastguard Worker } while (ppmline[0] == '#');
109*a67afe4dSAndroid Build Coastguard Worker sscanf(ppmline, "%lu %lu", &width, &height);
110*a67afe4dSAndroid Build Coastguard Worker
111*a67afe4dSAndroid Build Coastguard Worker do {
112*a67afe4dSAndroid Build Coastguard Worker fgets(ppmline, 256, infile);
113*a67afe4dSAndroid Build Coastguard Worker } while (ppmline[0] == '#');
114*a67afe4dSAndroid Build Coastguard Worker sscanf(ppmline, "%d", &maxval);
115*a67afe4dSAndroid Build Coastguard Worker if (maxval != 255) {
116*a67afe4dSAndroid Build Coastguard Worker fprintf(stderr, "ERROR: maxval = %d\n", maxval);
117*a67afe4dSAndroid Build Coastguard Worker return 2;
118*a67afe4dSAndroid Build Coastguard Worker }
119*a67afe4dSAndroid Build Coastguard Worker bit_depth = 8;
120*a67afe4dSAndroid Build Coastguard Worker
121*a67afe4dSAndroid Build Coastguard Worker *pWidth = width;
122*a67afe4dSAndroid Build Coastguard Worker *pHeight = height;
123*a67afe4dSAndroid Build Coastguard Worker
124*a67afe4dSAndroid Build Coastguard Worker return 0;
125*a67afe4dSAndroid Build Coastguard Worker }
126*a67afe4dSAndroid Build Coastguard Worker
127*a67afe4dSAndroid Build Coastguard Worker
128*a67afe4dSAndroid Build Coastguard Worker
129*a67afe4dSAndroid Build Coastguard Worker
130*a67afe4dSAndroid Build Coastguard Worker /* returns 0 if succeeds, 1 if fails due to no bKGD chunk, 2 if libpng error;
131*a67afe4dSAndroid Build Coastguard Worker * scales values to 8-bit if necessary */
132*a67afe4dSAndroid Build Coastguard Worker
readpng_get_bgcolor(uch * red,uch * green,uch * blue)133*a67afe4dSAndroid Build Coastguard Worker int readpng_get_bgcolor(uch *red, uch *green, uch *blue)
134*a67afe4dSAndroid Build Coastguard Worker {
135*a67afe4dSAndroid Build Coastguard Worker return 1;
136*a67afe4dSAndroid Build Coastguard Worker }
137*a67afe4dSAndroid Build Coastguard Worker
138*a67afe4dSAndroid Build Coastguard Worker
139*a67afe4dSAndroid Build Coastguard Worker
140*a67afe4dSAndroid Build Coastguard Worker
141*a67afe4dSAndroid Build Coastguard Worker /* display_exponent == LUT_exponent * CRT_exponent */
142*a67afe4dSAndroid Build Coastguard Worker
readpng_get_image(double display_exponent,int * pChannels,ulg * pRowbytes)143*a67afe4dSAndroid Build Coastguard Worker uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes)
144*a67afe4dSAndroid Build Coastguard Worker {
145*a67afe4dSAndroid Build Coastguard Worker ulg rowbytes;
146*a67afe4dSAndroid Build Coastguard Worker
147*a67afe4dSAndroid Build Coastguard Worker
148*a67afe4dSAndroid Build Coastguard Worker /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
149*a67afe4dSAndroid Build Coastguard Worker * transparency chunks to full alpha channel; strip 16-bit-per-sample
150*a67afe4dSAndroid Build Coastguard Worker * images to 8 bits per sample; and convert grayscale to RGB[A] */
151*a67afe4dSAndroid Build Coastguard Worker
152*a67afe4dSAndroid Build Coastguard Worker /* GRR WARNING: grayscale needs to be expanded and channels reset! */
153*a67afe4dSAndroid Build Coastguard Worker
154*a67afe4dSAndroid Build Coastguard Worker *pRowbytes = rowbytes = channels*width;
155*a67afe4dSAndroid Build Coastguard Worker *pChannels = channels;
156*a67afe4dSAndroid Build Coastguard Worker
157*a67afe4dSAndroid Build Coastguard Worker Trace((stderr, "readpng_get_image: rowbytes = %ld, height = %ld\n", rowbytes, height));
158*a67afe4dSAndroid Build Coastguard Worker
159*a67afe4dSAndroid Build Coastguard Worker /* Guard against integer overflow */
160*a67afe4dSAndroid Build Coastguard Worker if (height > ((size_t)(-1))/rowbytes) {
161*a67afe4dSAndroid Build Coastguard Worker fprintf(stderr, PROGNAME ": image_data buffer would be too large\n",
162*a67afe4dSAndroid Build Coastguard Worker return NULL;
163*a67afe4dSAndroid Build Coastguard Worker }
164*a67afe4dSAndroid Build Coastguard Worker
165*a67afe4dSAndroid Build Coastguard Worker if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) {
166*a67afe4dSAndroid Build Coastguard Worker return NULL;
167*a67afe4dSAndroid Build Coastguard Worker }
168*a67afe4dSAndroid Build Coastguard Worker
169*a67afe4dSAndroid Build Coastguard Worker /* now we can go ahead and just read the whole image */
170*a67afe4dSAndroid Build Coastguard Worker
171*a67afe4dSAndroid Build Coastguard Worker if (fread(image_data, 1L, rowbytes*height, saved_infile) <
172*a67afe4dSAndroid Build Coastguard Worker rowbytes*height) {
173*a67afe4dSAndroid Build Coastguard Worker free (image_data);
174*a67afe4dSAndroid Build Coastguard Worker image_data = NULL;
175*a67afe4dSAndroid Build Coastguard Worker return NULL;
176*a67afe4dSAndroid Build Coastguard Worker }
177*a67afe4dSAndroid Build Coastguard Worker
178*a67afe4dSAndroid Build Coastguard Worker return image_data;
179*a67afe4dSAndroid Build Coastguard Worker }
180*a67afe4dSAndroid Build Coastguard Worker
181*a67afe4dSAndroid Build Coastguard Worker
182*a67afe4dSAndroid Build Coastguard Worker void readpng_cleanup(int free_image_data)
183*a67afe4dSAndroid Build Coastguard Worker {
184*a67afe4dSAndroid Build Coastguard Worker if (free_image_data && image_data) {
185*a67afe4dSAndroid Build Coastguard Worker free(image_data);
186*a67afe4dSAndroid Build Coastguard Worker image_data = NULL;
187*a67afe4dSAndroid Build Coastguard Worker }
188*a67afe4dSAndroid Build Coastguard Worker }
189