xref: /aosp_15_r20/external/libpng/contrib/gregbook/readppm.c (revision a67afe4df73cf47866eedc69947994b8ff839aba)
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