Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] Annotation of /examples/util/load-png.c
ViewVC logotype

Annotation of /examples/util/load-png.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3349 - (view) (download) (as text)

1 : jhr 1884 /*! \file load-png.c
2 :     *
3 :     * \brief This file implements a simple texture loading API on top of libpng.
4 :     *
5 :     * \author John Reppy
6 :     */
7 :    
8 :     /*
9 : jhr 3349 * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
10 :     *
11 :     * COPYRIGHT (c) 2015 The University of Chicago
12 : jhr 1884 * All rights reserved.
13 :     */
14 :    
15 :     #include <png.h>
16 :     #include "util.h"
17 :     #include "load-png.h"
18 :    
19 :     /* LoadImage:
20 :     */
21 :     Image2D_t *LoadImage (const char *file, bool flip, ImageFormat_t fmt)
22 :     {
23 :     // open image file
24 :     FILE *inS = fopen(file, "rb");
25 :     if (inS == NULL) {
26 :     fprintf (stderr, "unable to open \"%s\"\n", file);
27 :     return 0;
28 :     }
29 :    
30 :     /* check PNG signature */
31 :     unsigned char sig[8];
32 :     if ((fread(sig, 1, 8, inS) != 8)
33 :     || (! png_check_sig(sig, 8))) {
34 :     fprintf (stderr, "error reading \"%s\": bad signature\n", file);
35 :     fclose(inS);
36 :     return 0;
37 :     }
38 :    
39 :     /* setup read structures */
40 :     png_structp pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
41 :     if (pngPtr == 0) {
42 :     fprintf (stderr, "error reading \"%s\"\n", file);
43 :     fclose(inS);
44 :     return 0;
45 :     }
46 :     png_infop infoPtr = png_create_info_struct(pngPtr);
47 :     if (infoPtr == 0) {
48 :     fprintf (stderr, "error reading \"%s\"\n", file);
49 :     png_destroy_read_struct(&pngPtr, (png_infopp)0, (png_infopp)0);
50 :     fclose(inS);
51 :     return 0;
52 :     }
53 :     png_infop endPtr = png_create_info_struct(pngPtr);
54 :     if (!endPtr) {
55 :     fprintf (stderr, "error reading \"%s\"\n", file);
56 :     png_destroy_read_struct (&pngPtr, &infoPtr, (png_infopp)0);
57 :     fclose (inS);
58 :     return 0;
59 :     }
60 :    
61 :     /* error handler */
62 :     if (setjmp (png_jmpbuf(pngPtr))) {
63 :     fprintf (stderr, "error reading \"%s\"\n", file);
64 :     png_destroy_read_struct (&pngPtr, &infoPtr, &endPtr);
65 :     fclose (inS);
66 :     return 0;
67 :     }
68 :    
69 :     /* set the input stream */
70 :     png_init_io (pngPtr, inS);
71 :    
72 :     /* let the PNG library know that we already checked the signature */
73 :     png_set_sig_bytes (pngPtr, 8);
74 :    
75 :     /* get file info */
76 :     png_uint_32 width, height;
77 :     int bitDepth, colorType;
78 :     png_read_info (pngPtr, infoPtr);
79 :     png_get_IHDR (pngPtr, infoPtr, &width, &height,
80 :     &bitDepth, &colorType, 0 /* interlace type */,
81 :     0 /* compression type */, 0 /* filter method */);
82 :    
83 :     // check file format against expected format
84 :     switch (colorType) {
85 :     case PNG_COLOR_TYPE_GRAY:
86 :     if (bitDepth < 8) {
87 :     png_set_expand_gray_1_2_4_to_8(pngPtr);
88 :     }
89 :     if (fmt != GRAY_IMAGE) {
90 :     fprintf(stderr, "unexpected GRAY image format\n");
91 :     png_destroy_read_struct (&pngPtr, &infoPtr, (png_infopp)0);
92 :     fclose (inS);
93 :     return 0;
94 :     }
95 :     break;
96 :     case PNG_COLOR_TYPE_GRAY_ALPHA:
97 :     if (fmt != GRAY_ALPHA_IMAGE) {
98 :     fprintf(stderr, "unexpected GRAY_ALPHA image format\n");
99 :     png_destroy_read_struct (&pngPtr, &infoPtr, (png_infopp)0);
100 :     fclose (inS);
101 :     return 0;
102 :     }
103 :     break;
104 :     case PNG_COLOR_TYPE_PALETTE:
105 :     png_set_palette_to_rgb (pngPtr);
106 :     if (fmt != RGB_IMAGE) {
107 :     fprintf(stderr, "unexpected PALETTE image format\n");
108 :     png_destroy_read_struct (&pngPtr, &infoPtr, (png_infopp)0);
109 :     fclose (inS);
110 :     return 0;
111 :     }
112 :     break;
113 :     case PNG_COLOR_TYPE_RGB:
114 :     if (fmt != RGB_IMAGE) {
115 :     fprintf(stderr, "unexpected RGB image format\n");
116 :     png_destroy_read_struct (&pngPtr, &infoPtr, (png_infopp)0);
117 :     fclose (inS);
118 :     return 0;
119 :     }
120 :     break;
121 :     case PNG_COLOR_TYPE_RGB_ALPHA:
122 :     if (fmt != RGBA_IMAGE) {
123 :     fprintf(stderr, "unexpected RGBA image format\n");
124 :     png_destroy_read_struct (&pngPtr, &infoPtr, (png_infopp)0);
125 :     fclose (inS);
126 :     return 0;
127 :     }
128 :     break;
129 :     default:
130 :     fprintf(stderr, "unknown color type %d\n", colorType);
131 :     png_destroy_read_struct (&pngPtr, &infoPtr, (png_infopp)0);
132 :     fclose (inS);
133 :     return 0;
134 :     }
135 :    
136 :     // figure out the OpenGL image type
137 :     GLenum type;
138 :     if (bitDepth <= 8) type = GL_UNSIGNED_BYTE;
139 : jhr 1920 else if (bitDepth == 16) type = GL_UNSIGNED_SHORT;
140 : jhr 1884 else {
141 :     fprintf(stderr, "unsupported bit depth\n");
142 :     png_destroy_read_struct (&pngPtr, &infoPtr, (png_infopp)0);
143 :     fclose (inS);
144 :     return 0;
145 :     }
146 :    
147 :     /* allocate image data */
148 :     unsigned char *imgData = 0;
149 :     png_bytepp rowPtrs = 0;
150 :     int bytesPerRow = png_get_rowbytes(pngPtr, infoPtr);
151 :     if ((imgData = NEWVEC(unsigned char, height * bytesPerRow)) == 0) {
152 :     png_destroy_read_struct (&pngPtr, &infoPtr, &endPtr);
153 :     free (rowPtrs);
154 :     fclose (inS);
155 :     return 0;
156 :     }
157 :    
158 :     rowPtrs = (png_bytepp) malloc (height * sizeof(png_bytep));
159 :     if (rowPtrs == 0) {
160 :     png_destroy_read_struct (&pngPtr, &infoPtr, &endPtr);
161 :     free (imgData);
162 :     fclose (inS);
163 :     return 0;
164 :     }
165 :    
166 :     if (flip) {
167 :     /* setup row pointers */
168 :     for (int i = 0; i < height; i++)
169 :     rowPtrs[i] = imgData + i*bytesPerRow;
170 :     }
171 :     else {
172 :     /* setup row pointers so that the texture has OpenGL orientation */
173 :     for (int i = 1; i <= height; i++)
174 :     rowPtrs[height - i] = imgData + (i-1)*bytesPerRow;
175 :     }
176 :    
177 :     /* read the image */
178 :     png_read_image(pngPtr, rowPtrs);
179 :    
180 :     /* Clean up. */
181 :     png_destroy_read_struct (&pngPtr, &infoPtr, &endPtr);
182 :     free (rowPtrs);
183 :     fclose (inS);
184 :    
185 :     /* allocate and initialize the image data structure */
186 :     Image2D_t *img = NEW(Image2D_t);
187 :     img->wid = width;
188 :     img->ht = height;
189 :     img->fmt = fmt;
190 :     img->type = type;
191 :     img->data = imgData;
192 :    
193 :     return img;
194 :    
195 :     } /* end of LoadImage */
196 :    
197 :     /* FreeImage:
198 :     */
199 :     void FreeImage (Image2D_t *img)
200 :     {
201 :     if (img == 0) return;
202 :    
203 :     free (img->data);
204 :     free (img);
205 :    
206 :     } /* end of FreeImage */
207 :    
208 :     /* TexImage:
209 :     */
210 :     int TexImage (Image2D_t *img)
211 :     {
212 :     assert (img != 0);
213 :    
214 :     glTexImage2D (GL_TEXTURE_2D, 0, img->fmt, img->wid, img->ht, 0, img->fmt, img->type, img->data);
215 :    
216 :     return (glGetError());
217 :    
218 :     } /* end of TexImage */

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0