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

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