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.
24 ** RGB Image Structure
27 typedef struct _TK_RGBImageRec
{
35 /******************************************************************************/
37 typedef struct _rawImageRec
{
38 unsigned short imagic
;
41 unsigned short sizeX
, sizeY
, sizeZ
;
42 unsigned long min
, max
;
43 unsigned long wasteBytes
;
45 unsigned long colorMap
;
47 unsigned char *tmp
, *tmpR
, *tmpG
, *tmpB
, *tmpA
;
53 /******************************************************************************/
55 static void ConvertShort(unsigned short *array
, long length
)
60 ptr
= (unsigned char *)array
;
64 *array
++ = (unsigned short) ((b1
<< 8) | (b2
));
68 static void ConvertLong(GLuint
*array
, long length
)
70 unsigned long b1
, b2
, b3
, b4
;
73 ptr
= (unsigned char *)array
;
79 *array
++ = (b1
<< 24) | (b2
<< 16) | (b3
<< 8) | (b4
);
83 static rawImageRec
*RawImageOpen(const char *fileName
)
93 endianTest
.testWord
= 1;
94 if (endianTest
.testByte
[0] == 1) {
100 raw
= (rawImageRec
*)malloc(sizeof(rawImageRec
));
102 fprintf(stderr
, "Out of memory!\n");
105 if ((raw
->file
= fopen(fileName
, "rb")) == NULL
) {
110 fread(raw
, 1, 12, raw
->file
);
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);
121 raw
->tmpA
= (unsigned char *)malloc(raw
->sizeX
*256);
123 if (raw
->tmp
== NULL
|| raw
->tmpR
== NULL
|| raw
->tmpG
== NULL
||
125 fprintf(stderr
, "Out of memory!\n");
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");
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
);
142 ConvertLong(raw
->rowStart
, (long) (x
/sizeof(GLuint
)));
143 ConvertLong((GLuint
*)raw
->rowSize
, (long) (x
/sizeof(GLint
)));
149 static rawImageRec
*RawImageOpenUserAlpha(const char *fileName
)
159 endianTest
.testWord
= 1;
160 if (endianTest
.testByte
[0] == 1) {
166 raw
= (rawImageRec
*)malloc(sizeof(rawImageRec
));
168 fprintf(stderr
, "Out of memory!\n");
171 if ((raw
->file
= fopen(fileName
, "rb")) == NULL
) {
176 fread(raw
, 1, 12, raw
->file
);
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);
187 raw
->tmpA
= (unsigned char *)malloc(raw
->sizeX
*256);
188 if (raw
->tmp
== NULL
|| raw
->tmpR
== NULL
|| raw
->tmpG
== NULL
||
190 fprintf(stderr
, "Out of memory!\n");
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");
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
);
207 ConvertLong(raw
->rowStart
, (long) (x
/sizeof(GLuint
)));
208 ConvertLong((GLuint
*)raw
->rowSize
, (long) (x
/sizeof(GLint
)));
214 static void RawImageClose(rawImageRec
*raw
)
228 static void RawImageGetRow(rawImageRec
*raw
, unsigned char *buf
, int y
, int z
)
230 unsigned char *iPtr
, *oPtr
, pixel
;
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
],
242 count
= (int)(pixel
& 0x7F);
260 fseek(raw
->file
, 512+(y
*raw
->sizeX
)+(z
*raw
->sizeX
*raw
->sizeY
),
262 fread(buf
, 1, raw
->sizeX
, raw
->file
);
267 static void RawImageGetData(rawImageRec
*raw
, TK_RGBImageRec
*final
)
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");
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);
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
);
290 *ptr
++ = *(raw
->tmpA
+ j
);
296 static void RawImageGetDataUserAlpha(rawImageRec
*raw
, TK_RGBImageRec
*final
, float alpha
)
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");
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);
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
);
319 *ptr
++ = (unsigned char) (alpha
* 255);
326 static TK_RGBImageRec
*tkRGBImageLoad(const char *fileName
)
329 TK_RGBImageRec
*final
;
331 raw
= RawImageOpen(fileName
);
333 fprintf(stderr
, "File not found\n");
336 final
= (TK_RGBImageRec
*)malloc(sizeof(TK_RGBImageRec
));
338 fprintf(stderr
, "Out of memory!\n");
341 final
->sizeX
= raw
->sizeX
;
342 final
->sizeY
= raw
->sizeY
;
343 final
->components
= raw
->sizeZ
;
344 RawImageGetData(raw
, final
);
349 static TK_RGBImageRec
*tkRGBImageLoadUserAlpha(const char *fileName
, float alpha
)
352 TK_RGBImageRec
*final
;
354 raw
= RawImageOpenUserAlpha(fileName
);
356 fprintf(stderr
, "File not found\n");
359 final
= (TK_RGBImageRec
*)malloc(sizeof(TK_RGBImageRec
));
361 fprintf(stderr
, "Out of memory!\n");
364 final
->sizeX
= raw
->sizeX
;
365 final
->sizeY
= raw
->sizeY
;
366 final
->components
= raw
->sizeZ
;
367 RawImageGetDataUserAlpha(raw
, final
,alpha
);
374 static void FreeImage( TK_RGBImageRec
*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
)
391 TK_RGBImageRec
*image
;
393 image
= tkRGBImageLoad( imageFile
);
398 if (image
->components
==3) {
401 else if (image
->components
==4) {
405 /* not implemented */
407 "Error in LoadRGBMipmaps %d-component images not implemented\n",
412 error
= gluBuild2DMipmaps( GL_TEXTURE_2D
,
414 image
->sizeX
, image
->sizeY
,
420 return error
? GL_FALSE
: GL_TRUE
;
423 GLboolean
LoadRGBMipmapsUserAlpha( const char *imageFile
, GLint intFormat
, float alpha
)
427 TK_RGBImageRec
*image
;
429 image
= tkRGBImageLoadUserAlpha( imageFile
, alpha
);
434 if (image
->components
==3) {
437 else if (image
->components
==4) {
441 /* not implemented */
443 "Error in LoadRGBMipmaps %d-component images not implemented\n",
448 error
= gluBuild2DMipmaps( GL_TEXTURE_2D
,
450 image
->sizeX
, image
->sizeY
,
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
,
472 TK_RGBImageRec
*image
;
476 image
= tkRGBImageLoad( imageFile
);
481 if (image
->components
==3) {
484 else if (image
->components
==4) {
488 /* not implemented */
490 "Error in LoadRGBImage %d-component images not implemented\n",
495 *width
= image
->sizeX
;
496 *height
= image
->sizeY
;
498 bytes
= image
->sizeX
* image
->sizeY
* image
->components
;
499 buffer
= (GLubyte
*) malloc(bytes
);
503 memcpy( (void *) buffer
, (void *) image
->data
, bytes
);