1 /* $Id: LoadImage.cpp,v 1.6 2002/12/24 14:56:15 nan Exp $ */
2
3 // Copyright (C) 2000, 2002 $B?@Fn(B $B5H9((B(Kanna Yoshihiro)
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 #include "ttinc.h"
20 #include "LoadImage.h"
21
22 #ifdef HAVE_LIBZ
23 #include "z.h"
24 #endif
25
ImageData()26 ImageData::ImageData() {
27 m_image = NULL;
28 m_width = m_height = m_bytes = 0;
29 }
30
ImageData(long width,long height,long bytes)31 ImageData::ImageData( long width, long height, long bytes) {
32 m_image = new GLubyte[width*height*bytes];
33
34 if ( m_image ) {
35 m_width = width;
36 m_height = height;
37 m_bytes = bytes;
38 }
39 }
40
~ImageData()41 ImageData::~ImageData() {
42 if ( m_image )
43 delete m_image;
44 }
45
46 GLubyte
GetPixel(long width,long height,long bytes)47 ImageData::GetPixel( long width, long height, long bytes ) {
48 if ( width > m_width || width < 0 || height > m_height || height < 0 ||
49 bytes > m_bytes || bytes < 0 )
50 return 0;
51
52 return m_image[height*m_width*m_bytes + width*m_bytes + bytes];
53 }
54
55 bool
SetPixel(long width,long height,long bytes,GLubyte val)56 ImageData::SetPixel( long width, long height, long bytes , GLubyte val ) {
57 if ( width > m_width || width < 0 || height > m_height || height < 0 ||
58 bytes > m_bytes || bytes < 0 )
59 return false;
60
61 m_image[height*m_width*m_bytes + width*m_bytes + bytes] = val;
62 return true;
63 }
64
65 bool
LoadPPM(const char * filename)66 ImageData::LoadPPM(const char* filename ) {
67 int i, j;
68 #ifndef HAVE_LIBZ
69 FILE *fp;
70 #else
71 gzFile fp;
72 #endif
73 char *w;
74 int pb;
75
76 #ifndef HAVE_LIBZ
77 if( (fp = fopen(filename, "r")) == NULL ) {
78 return false;
79 }
80 #else
81 if (NULL == (fp = gzopenx(filename, "rs"))) return false;
82 #endif
83
84 w = getWord(fp);
85 if( !strcmp("P3", w) )
86 pb = 3;
87 else if( !strcmp("P2", w) )
88 pb = 2;
89 else if( !strcmp("P4", w) )
90 pb = 4;
91 else if ( !strcmp("P5", w) )
92 pb = 5;
93 else if ( !strcmp("P6", w) )
94 pb = 6;
95 else
96 return false;
97
98 m_width = atoi( getWord(fp) );
99 m_height = atoi( getWord(fp) );
100 m_bytes = 4;
101
102 if ( pb != 4 )
103 getWord( fp );
104
105 if ( m_image )
106 delete m_image;
107
108 m_image = new GLubyte[m_width*m_height*m_bytes];
109 if ( !m_image ) {
110 m_width = m_height = m_bytes = 0;
111 return false;
112 }
113
114 if ( pb == 5 ) {
115 GLubyte b;
116 for ( i = 0 ; i < m_height ; i++ ){
117 for ( j = 0 ; j < m_width ; j++ ){
118 #ifndef HAVE_LIBZ
119 fread( &b , 1, 1, fp );
120 #else
121 gzread(fp, &b, 1 * 1);
122 #endif
123 SetPixel( j, i, 0, b );
124 SetPixel( j, i, 1, b );
125 SetPixel( j, i, 2, b );
126 SetPixel( j, i, 3, 255 );
127 }
128 }
129 } else if ( pb == 6 ) {
130 GLubyte b;
131 for ( i = 0 ; i < m_height ; i++ ){
132 for ( j = 0 ; j < m_width ; j++ ){
133 #ifndef HAVE_LIBZ
134 fread( &b , 1, 1, fp ); SetPixel( j, i, 0, b );
135 fread( &b , 1, 1, fp ); SetPixel( j, i, 1, b );
136 fread( &b , 1, 1, fp ); SetPixel( j, i, 2, b );
137 #else
138 gzread(fp, &b , 1 * 1); SetPixel( j, i, 0, b );
139 gzread(fp, &b , 1 * 1); SetPixel( j, i, 1, b );
140 gzread(fp, &b , 1 * 1); SetPixel( j, i, 2, b );
141 #endif
142 SetPixel( j, i, 3, 255 );
143 }
144 }
145 } else if ( pb == 4 ) {
146 int rowbytes = m_width/8;
147 if ( m_width%8 > 0 )
148 rowbytes++;
149
150 #ifndef HAVE_LIBZ
151 fread( m_image, 1, rowbytes*m_height, fp );
152 #else
153 gzread( fp, m_image, rowbytes*m_height );
154 #endif
155 } else {
156 for ( i = 0 ; i < m_height ; i++ ){
157 for ( j = 0 ; j < m_width ; j++ ){
158 if ( pb == 3 ) {
159 SetPixel( j, i, 0, (GLubyte)atoi(getWord( fp ) ) );
160 SetPixel( j, i, 1, (GLubyte)atoi(getWord( fp ) ) );
161 SetPixel( j, i, 2, (GLubyte)atoi(getWord( fp ) ) );
162 SetPixel( j, i, 3, 255 );
163 } else if ( pb == 2 ) {
164 SetPixel( j, i, 0, (GLubyte)atoi(getWord( fp ) ) );
165 SetPixel( j, i, 1, (GLubyte)atoi(getWord( fp ) ) );
166 SetPixel( j, i, 2, (GLubyte)atoi(getWord( fp ) ) );
167 SetPixel( j, i, 3, (GLubyte)atoi(getWord( fp ) ) );
168 }
169 }
170 }
171 }
172
173 #ifndef HAVE_LIBZ
174 fclose( fp );
175 #else
176 gzclose(fp);
177 #endif
178
179 return true;
180 }
181
182 #ifdef HAVE_LIBZ
183 char*
getWord(gzFile fp)184 getWord( gzFile fp ) {
185 static char buf[256];
186 static char* ptr = buf;
187 char* ptr2;
188
189 while(1) {
190 if( *ptr == 0 || *ptr == '#' ) {
191 gzgets(fp, buf, 256);
192 ptr = buf;
193 continue;
194 } else if( isspace(*ptr) ) {
195 ptr++;
196 continue;
197 } else
198 break;
199 }
200
201 ptr2 = ptr;
202 while( !isspace(*ptr) && *ptr != 0 ) {
203 ptr++;
204 }
205 *ptr = 0;
206 ptr++;
207
208 return ptr2;
209 }
210 #else
211 char*
getWord(FILE * fp)212 getWord( FILE *fp ) {
213 static char buf[256];
214 static char* ptr = buf;
215 char* ptr2;
216
217 while(1) {
218 if( *ptr == 0 || *ptr == '#' ) {
219 fgets( buf, 256, fp );
220 ptr = buf;
221 continue;
222 } else if( isspace(*ptr) ) {
223 ptr++;
224 continue;
225 } else
226 break;
227 }
228
229 ptr2 = ptr;
230 while( !isspace(*ptr) && *ptr != 0 ) {
231 ptr++;
232 }
233 *ptr = 0;
234 ptr++;
235
236 return ptr2;
237 }
238 #endif
239
LoadJPG(const char * filename)240 bool ImageData::LoadJPG(const char *filename)
241 {
242 SDL_Surface *img = SDL_GL_LoadTexture((char *)filename);
243 m_width = img->w;
244 m_height = img->h;
245 m_bytes = 4;
246
247 m_image = new GLubyte[m_width*m_height*m_bytes];
248 memcpy( m_image, img->pixels, m_width*m_height*m_bytes );
249
250 SDL_FreeSurface(img);
251
252 return true;
253 }
254
extmatch(const char * filename,const char * ext)255 inline bool extmatch(const char *filename, const char *ext)
256 {
257 int lf = strlen(filename);
258 int le = strlen(ext);
259 return 0 == strcmp(&filename[lf-le], ext);
260 }
261
LoadFile(const char * filename)262 bool ImageData::LoadFile(const char *filename)
263 {
264 if (extmatch(filename, ".jpg")) {
265 return LoadJPG(filename);
266 }
267 else if (extmatch(filename, ".ppm") || extmatch(filename, ".ppm.gz") ||
268 extmatch(filename, ".pbm") || extmatch(filename, ".pbm.gz") ) {
269 return LoadPPM(filename);
270 }
271 else {
272 return false;
273 }
274 }
275
276 // Copyed from testgl.c of SDL source code
SDL_GL_LoadTexture(char * filename)277 SDL_Surface* SDL_GL_LoadTexture(char *filename)
278 {
279 GLuint texture;
280 int w, h;
281 SDL_Surface *image, *jpg;
282 SDL_Rect area;
283 Uint32 saved_flags;
284 Uint8 saved_alpha;
285
286 jpg = IMG_Load( filename );
287 /* Use the surface width and height expanded to powers of 2 */
288
289 image = SDL_CreateRGBSurface(
290 SDL_SWSURFACE,
291 jpg->w, jpg->h,
292 32,
293 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
294 0x000000FF,
295 0x0000FF00,
296 0x00FF0000,
297 0xFF000000
298 #else
299 0xFF000000,
300 0x00FF0000,
301 0x0000FF00,
302 0x000000FF
303 #endif
304 );
305 if ( image == NULL ) {
306 return 0;
307 }
308
309 /* Save the alpha blending attributes */
310 saved_flags = jpg->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
311 saved_alpha = jpg->format->alpha;
312 if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
313 SDL_SetAlpha(jpg, 0, 0);
314 }
315
316 /* Copy the surface into the GL texture image */
317 area.x = 0;
318 area.y = 0;
319 area.w = jpg->w;
320 area.h = jpg->h;
321 SDL_BlitSurface(jpg, &area, image, &area);
322
323 /* Restore the alpha blending attributes */
324 if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
325 SDL_SetAlpha(jpg, saved_flags, saved_alpha);
326 }
327
328 return image;
329 }
330