project config: Debug support added.
[mines3d.git] / opengl / readtex.h
blob9124ba7fc37e2304e1da7ec3e45ff1ec0443e1a5
1 /* readtex.¨h */
3 /*
4 * Read an SGI .rgb image file and generate a mipmap texture set.
5 * Much of this code was borrowed from SGI's tk OpenGL toolkit.
6 */
10 #include <GL/gl.h>
11 #include <GL/glu.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
17 #ifndef SEEK_SET
18 # define SEEK_SET 0
19 #endif
24 ** RGB Image Structure
27 typedef struct _TK_RGBImageRec {
28 GLint sizeX, sizeY;
29 GLint components;
30 unsigned char *data;
31 } TK_RGBImageRec;
35 /******************************************************************************/
37 typedef struct _rawImageRec {
38 unsigned short imagic;
39 unsigned short type;
40 unsigned short dim;
41 unsigned short sizeX, sizeY, sizeZ;
42 unsigned long min, max;
43 unsigned long wasteBytes;
44 char name[80];
45 unsigned long colorMap;
46 FILE *file;
47 unsigned char *tmp, *tmpR, *tmpG, *tmpB, *tmpA;
48 unsigned long rleEnd;
49 GLuint *rowStart;
50 GLint *rowSize;
51 } rawImageRec;
53 /******************************************************************************/
55 static void ConvertShort(unsigned short *array, long length)
57 unsigned long b1, b2;
58 unsigned char *ptr;
60 ptr = (unsigned char *)array;
61 while (length--) {
62 b1 = *ptr++;
63 b2 = *ptr++;
64 *array++ = (unsigned short) ((b1 << 8) | (b2));
68 static void ConvertLong(GLuint *array, long length)
70 unsigned long b1, b2, b3, b4;
71 unsigned char *ptr;
73 ptr = (unsigned char *)array;
74 while (length--) {
75 b1 = *ptr++;
76 b2 = *ptr++;
77 b3 = *ptr++;
78 b4 = *ptr++;
79 *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
83 static rawImageRec *RawImageOpen(const char *fileName)
85 union {
86 int testWord;
87 char testByte[4];
88 } endianTest;
89 rawImageRec *raw;
90 GLenum swapFlag;
91 int x;
93 endianTest.testWord = 1;
94 if (endianTest.testByte[0] == 1) {
95 swapFlag = GL_TRUE;
96 } else {
97 swapFlag = GL_FALSE;
100 raw = (rawImageRec *)malloc(sizeof(rawImageRec));
101 if (raw == NULL) {
102 fprintf(stderr, "Out of memory!\n");
103 return NULL;
105 if ((raw->file = fopen(fileName, "rb")) == NULL) {
106 perror(fileName);
107 return NULL;
110 fread(raw, 1, 12, raw->file);
112 if (swapFlag) {
113 ConvertShort(&raw->imagic, 6);
116 raw->tmp = (unsigned char *)malloc(raw->sizeX*256);
117 raw->tmpR = (unsigned char *)malloc(raw->sizeX*256);
118 raw->tmpG = (unsigned char *)malloc(raw->sizeX*256);
119 raw->tmpB = (unsigned char *)malloc(raw->sizeX*256);
120 if (raw->sizeZ==4) {
121 raw->tmpA = (unsigned char *)malloc(raw->sizeX*256);
123 if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL ||
124 raw->tmpB == NULL) {
125 fprintf(stderr, "Out of memory!\n");
126 return NULL;
129 if ((raw->type & 0xFF00) == 0x0100) {
130 x = raw->sizeY * raw->sizeZ * sizeof(GLuint);
131 raw->rowStart = (GLuint *)malloc(x);
132 raw->rowSize = (GLint *)malloc(x);
133 if (raw->rowStart == NULL || raw->rowSize == NULL) {
134 fprintf(stderr, "Out of memory!\n");
135 return NULL;
137 raw->rleEnd = 512 + (2 * x);
138 fseek(raw->file, 512, SEEK_SET);
139 fread(raw->rowStart, 1, x, raw->file);
140 fread(raw->rowSize, 1, x, raw->file);
141 if (swapFlag) {
142 ConvertLong(raw->rowStart, (long) (x/sizeof(GLuint)));
143 ConvertLong((GLuint *)raw->rowSize, (long) (x/sizeof(GLint)));
146 return raw;
149 static rawImageRec *RawImageOpenUserAlpha(const char *fileName)
151 union {
152 int testWord;
153 char testByte[4];
154 } endianTest;
155 rawImageRec *raw;
156 GLenum swapFlag;
157 int x;
159 endianTest.testWord = 1;
160 if (endianTest.testByte[0] == 1) {
161 swapFlag = GL_TRUE;
162 } else {
163 swapFlag = GL_FALSE;
166 raw = (rawImageRec *)malloc(sizeof(rawImageRec));
167 if (raw == NULL) {
168 fprintf(stderr, "Out of memory!\n");
169 return NULL;
171 if ((raw->file = fopen(fileName, "rb")) == NULL) {
172 perror(fileName);
173 return NULL;
176 fread(raw, 1, 12, raw->file);
178 if (swapFlag) {
179 ConvertShort(&raw->imagic, 6);
182 raw->tmp = (unsigned char *)malloc(raw->sizeX*256);
183 raw->tmpR = (unsigned char *)malloc(raw->sizeX*256);
184 raw->tmpG = (unsigned char *)malloc(raw->sizeX*256);
185 raw->tmpB = (unsigned char *)malloc(raw->sizeX*256);
186 raw->sizeZ = 4;
187 raw->tmpA = (unsigned char *)malloc(raw->sizeX*256);
188 if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL ||
189 raw->tmpB == NULL) {
190 fprintf(stderr, "Out of memory!\n");
191 return NULL;
194 if ((raw->type & 0xFF00) == 0x0100) {
195 x = raw->sizeY * raw->sizeZ * sizeof(GLuint);
196 raw->rowStart = (GLuint *)malloc(x);
197 raw->rowSize = (GLint *)malloc(x);
198 if (raw->rowStart == NULL || raw->rowSize == NULL) {
199 fprintf(stderr, "Out of memory!\n");
200 return NULL;
202 raw->rleEnd = 512 + (2 * x);
203 fseek(raw->file, 512, SEEK_SET);
204 fread(raw->rowStart, 1, x, raw->file);
205 fread(raw->rowSize, 1, x, raw->file);
206 if (swapFlag) {
207 ConvertLong(raw->rowStart, (long) (x/sizeof(GLuint)));
208 ConvertLong((GLuint *)raw->rowSize, (long) (x/sizeof(GLint)));
211 return raw;
214 static void RawImageClose(rawImageRec *raw)
217 fclose(raw->file);
218 free(raw->tmp);
219 free(raw->tmpR);
220 free(raw->tmpG);
221 free(raw->tmpB);
222 if (raw->sizeZ>3) {
223 free(raw->tmpA);
225 free(raw);
228 static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z)
230 unsigned char *iPtr, *oPtr, pixel;
231 int count, done = 0;
233 if ((raw->type & 0xFF00) == 0x0100) {
234 fseek(raw->file, (long) raw->rowStart[y+z*raw->sizeY], SEEK_SET);
235 fread(raw->tmp, 1, (unsigned int)raw->rowSize[y+z*raw->sizeY],
236 raw->file);
238 iPtr = raw->tmp;
239 oPtr = buf;
240 while (!done) {
241 pixel = *iPtr++;
242 count = (int)(pixel & 0x7F);
243 if (!count) {
244 done = 1;
245 return;
247 if (pixel & 0x80) {
248 while (count--) {
249 *oPtr++ = *iPtr++;
251 } else {
252 pixel = *iPtr++;
253 while (count--) {
254 *oPtr++ = pixel;
259 } else {
260 fseek(raw->file, 512+(y*raw->sizeX)+(z*raw->sizeX*raw->sizeY),
261 SEEK_SET);
262 fread(buf, 1, raw->sizeX, raw->file);
267 static void RawImageGetData(rawImageRec *raw, TK_RGBImageRec *final)
269 unsigned char *ptr;
270 int i, j;
272 final->data = (unsigned char *)malloc((raw->sizeX+1)*(raw->sizeY+1)*4);
273 if (final->data == NULL) {
274 fprintf(stderr, "Out of memory!\n");
277 ptr = final->data;
278 for (i = 0; i < (int)(raw->sizeY); i++) {
279 RawImageGetRow(raw, raw->tmpR, i, 0);
280 RawImageGetRow(raw, raw->tmpG, i, 1);
281 RawImageGetRow(raw, raw->tmpB, i, 2);
282 if (raw->sizeZ>3) {
283 RawImageGetRow(raw, raw->tmpA, i, 3);
285 for (j = 0; j < (int)(raw->sizeX); j++) {
286 *ptr++ = *(raw->tmpR + j);
287 *ptr++ = *(raw->tmpG + j);
288 *ptr++ = *(raw->tmpB + j);
289 if (raw->sizeZ>3) {
290 *ptr++ = *(raw->tmpA + j);
296 static void RawImageGetDataUserAlpha(rawImageRec *raw, TK_RGBImageRec *final, float alpha)
298 unsigned char *ptr;
299 int i, j;
301 final->data = (unsigned char *)malloc((raw->sizeX+1)*(raw->sizeY+1)*4);
302 if (final->data == NULL) {
303 fprintf(stderr, "Out of memory!\n");
306 ptr = final->data;
307 for (i = 0; i < (int)(raw->sizeY); i++) {
308 RawImageGetRow(raw, raw->tmpR, i, 0);
309 RawImageGetRow(raw, raw->tmpG, i, 1);
310 RawImageGetRow(raw, raw->tmpB, i, 2);
311 if (raw->sizeZ>3) {
312 RawImageGetRow(raw, raw->tmpA, i, 3);
314 for (j = 0; j < (int)(raw->sizeX); j++) {
315 *ptr++ = *(raw->tmpR + j);
316 *ptr++ = *(raw->tmpG + j);
317 *ptr++ = *(raw->tmpB + j);
318 if (raw->sizeZ>3) {
319 *ptr++ = (unsigned char) (alpha * 255);
326 static TK_RGBImageRec *tkRGBImageLoad(const char *fileName)
328 rawImageRec *raw;
329 TK_RGBImageRec *final;
331 raw = RawImageOpen(fileName);
332 if (!raw) {
333 fprintf(stderr, "File not found\n");
334 return NULL;
336 final = (TK_RGBImageRec *)malloc(sizeof(TK_RGBImageRec));
337 if (final == NULL) {
338 fprintf(stderr, "Out of memory!\n");
339 return NULL;
341 final->sizeX = raw->sizeX;
342 final->sizeY = raw->sizeY;
343 final->components = raw->sizeZ;
344 RawImageGetData(raw, final);
345 RawImageClose(raw);
346 return final;
349 static TK_RGBImageRec *tkRGBImageLoadUserAlpha(const char *fileName, float alpha)
351 rawImageRec *raw;
352 TK_RGBImageRec *final;
354 raw = RawImageOpenUserAlpha(fileName);
355 if (!raw) {
356 fprintf(stderr, "File not found\n");
357 return NULL;
359 final = (TK_RGBImageRec *)malloc(sizeof(TK_RGBImageRec));
360 if (final == NULL) {
361 fprintf(stderr, "Out of memory!\n");
362 return NULL;
364 final->sizeX = raw->sizeX;
365 final->sizeY = raw->sizeY;
366 final->components = raw->sizeZ;
367 RawImageGetDataUserAlpha(raw, final,alpha);
368 RawImageClose(raw);
369 return final;
374 static void FreeImage( TK_RGBImageRec *image )
376 free(image->data);
377 free(image);
382 * Load an SGI .rgb file and generate a set of 2-D mipmaps from it.
383 * Input: imageFile - name of .rgb to read
384 * intFormat - internal texture format to use, or number of components
385 * Return: GL_TRUE if success, GL_FALSE if error.
387 GLboolean LoadRGBMipmaps( const char *imageFile, GLint intFormat )
389 GLint error;
390 GLenum format;
391 TK_RGBImageRec *image;
393 image = tkRGBImageLoad( imageFile );
394 if (!image) {
395 return GL_FALSE;
398 if (image->components==3) {
399 format = GL_RGB;
401 else if (image->components==4) {
402 format = GL_RGBA;
404 else {
405 /* not implemented */
406 fprintf(stderr,
407 "Error in LoadRGBMipmaps %d-component images not implemented\n",
408 image->components );
409 return GL_FALSE;
412 error = gluBuild2DMipmaps( GL_TEXTURE_2D,
413 intFormat,
414 image->sizeX, image->sizeY,
415 format,
416 GL_UNSIGNED_BYTE,
417 image->data );
419 FreeImage(image);
420 return error ? GL_FALSE : GL_TRUE;
423 GLboolean LoadRGBMipmapsUserAlpha( const char *imageFile, GLint intFormat, float alpha )
425 GLint error;
426 GLenum format;
427 TK_RGBImageRec *image;
429 image = tkRGBImageLoadUserAlpha( imageFile, alpha );
430 if (!image) {
431 return GL_FALSE;
434 if (image->components==3) {
435 format = GL_RGB;
437 else if (image->components==4) {
438 format = GL_RGBA;
440 else {
441 /* not implemented */
442 fprintf(stderr,
443 "Error in LoadRGBMipmaps %d-component images not implemented\n",
444 image->components );
445 return GL_FALSE;
448 error = gluBuild2DMipmaps( GL_TEXTURE_2D,
449 intFormat,
450 image->sizeX, image->sizeY,
451 format,
452 GL_UNSIGNED_BYTE,
453 image->data );
455 FreeImage(image);
456 return error ? GL_FALSE : GL_TRUE;
462 * Load an SGI .rgb file and return a pointer to the image data.
463 * Input: imageFile - name of .rgb to read
464 * Output: width - width of image
465 * height - height of image
466 * format - format of image (GL_RGB or GL_RGBA)
467 * Return: pointer to image data or NULL if error
469 GLubyte *LoadRGBImage( const char *imageFile, GLint *width, GLint *height,
470 GLenum *format )
472 TK_RGBImageRec *image;
473 GLint bytes;
474 GLubyte *buffer;
476 image = tkRGBImageLoad( imageFile );
477 if (!image) {
478 return NULL;
481 if (image->components==3) {
482 *format = GL_RGB;
484 else if (image->components==4) {
485 *format = GL_RGBA;
487 else {
488 /* not implemented */
489 fprintf(stderr,
490 "Error in LoadRGBImage %d-component images not implemented\n",
491 image->components );
492 return NULL;
495 *width = image->sizeX;
496 *height = image->sizeY;
498 bytes = image->sizeX * image->sizeY * image->components;
499 buffer = (GLubyte *) malloc(bytes);
500 if (!buffer)
501 return NULL;
503 memcpy( (void *) buffer, (void *) image->data, bytes );
505 FreeImage(image);
507 return buffer;