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.
13 #include "../util/readtex.h"
22 ** RGB Image Structure
25 typedef struct _TK_RGBImageRec
{
33 /******************************************************************************/
35 typedef struct _rawImageRec
{
36 unsigned short imagic
;
39 unsigned short sizeX
, sizeY
, sizeZ
;
40 unsigned long min
, max
;
41 unsigned long wasteBytes
;
43 unsigned long colorMap
;
45 unsigned char *tmp
, *tmpR
, *tmpG
, *tmpB
, *tmpA
;
51 /******************************************************************************/
53 static void ConvertShort(unsigned short *array
, long length
)
58 ptr
= (unsigned char *)array
;
62 *array
++ = (unsigned short) ((b1
<< 8) | (b2
));
66 static void ConvertLong(GLuint
*array
, long length
)
68 unsigned long b1
, b2
, b3
, b4
;
71 ptr
= (unsigned char *)array
;
77 *array
++ = (b1
<< 24) | (b2
<< 16) | (b3
<< 8) | (b4
);
81 static rawImageRec
*RawImageOpen(const char *fileName
)
91 endianTest
.testWord
= 1;
92 if (endianTest
.testByte
[0] == 1) {
98 raw
= (rawImageRec
*)malloc(sizeof(rawImageRec
));
100 fprintf(stderr
, "Out of memory!\n");
103 if ((raw
->file
= fopen(fileName
, "rb")) == NULL
) {
108 fread(raw
, 1, 12, raw
->file
);
111 ConvertShort(&raw
->imagic
, 6);
114 raw
->tmp
= (unsigned char *)malloc(raw
->sizeX
*256);
115 raw
->tmpR
= (unsigned char *)malloc(raw
->sizeX
*256);
116 raw
->tmpG
= (unsigned char *)malloc(raw
->sizeX
*256);
117 raw
->tmpB
= (unsigned char *)malloc(raw
->sizeX
*256);
119 raw
->tmpA
= (unsigned char *)malloc(raw
->sizeX
*256);
121 if (raw
->tmp
== NULL
|| raw
->tmpR
== NULL
|| raw
->tmpG
== NULL
||
123 fprintf(stderr
, "Out of memory!\n");
127 if ((raw
->type
& 0xFF00) == 0x0100) {
128 x
= raw
->sizeY
* raw
->sizeZ
* sizeof(GLuint
);
129 raw
->rowStart
= (GLuint
*)malloc(x
);
130 raw
->rowSize
= (GLint
*)malloc(x
);
131 if (raw
->rowStart
== NULL
|| raw
->rowSize
== NULL
) {
132 fprintf(stderr
, "Out of memory!\n");
135 raw
->rleEnd
= 512 + (2 * x
);
136 fseek(raw
->file
, 512, SEEK_SET
);
137 fread(raw
->rowStart
, 1, x
, raw
->file
);
138 fread(raw
->rowSize
, 1, x
, raw
->file
);
140 ConvertLong(raw
->rowStart
, (long) (x
/sizeof(GLuint
)));
141 ConvertLong((GLuint
*)raw
->rowSize
, (long) (x
/sizeof(GLint
)));
147 static void RawImageClose(rawImageRec
*raw
)
161 static void RawImageGetRow(rawImageRec
*raw
, unsigned char *buf
, int y
, int z
)
163 unsigned char *iPtr
, *oPtr
, pixel
;
166 if ((raw
->type
& 0xFF00) == 0x0100) {
167 fseek(raw
->file
, (long) raw
->rowStart
[y
+z
*raw
->sizeY
], SEEK_SET
);
168 fread(raw
->tmp
, 1, (unsigned int)raw
->rowSize
[y
+z
*raw
->sizeY
],
175 count
= (int)(pixel
& 0x7F);
192 fseek(raw
->file
, 512+(y
*raw
->sizeX
)+(z
*raw
->sizeX
*raw
->sizeY
),
194 fread(buf
, 1, raw
->sizeX
, raw
->file
);
199 static void RawImageGetData(rawImageRec
*raw
, TK_RGBImageRec
*final
)
204 final
->data
= (unsigned char *)malloc((raw
->sizeX
+1)*(raw
->sizeY
+1)*4);
205 if (final
->data
== NULL
) {
206 fprintf(stderr
, "Out of memory!\n");
210 for (i
= 0; i
< (int)(raw
->sizeY
); i
++) {
211 RawImageGetRow(raw
, raw
->tmpR
, i
, 0);
212 RawImageGetRow(raw
, raw
->tmpG
, i
, 1);
213 RawImageGetRow(raw
, raw
->tmpB
, i
, 2);
215 RawImageGetRow(raw
, raw
->tmpA
, i
, 3);
217 for (j
= 0; j
< (int)(raw
->sizeX
); j
++) {
218 *ptr
++ = *(raw
->tmpR
+ j
);
219 *ptr
++ = *(raw
->tmpG
+ j
);
220 *ptr
++ = *(raw
->tmpB
+ j
);
222 *ptr
++ = *(raw
->tmpA
+ j
);
229 static TK_RGBImageRec
*tkRGBImageLoad(const char *fileName
)
232 TK_RGBImageRec
*final
;
234 raw
= RawImageOpen(fileName
);
236 fprintf(stderr
, "File not found\n");
239 final
= (TK_RGBImageRec
*)malloc(sizeof(TK_RGBImageRec
));
241 fprintf(stderr
, "Out of memory!\n");
244 final
->sizeX
= raw
->sizeX
;
245 final
->sizeY
= raw
->sizeY
;
246 final
->components
= raw
->sizeZ
;
247 RawImageGetData(raw
, final
);
253 static void FreeImage( TK_RGBImageRec
*image
)
261 * Load an SGI .rgb file and generate a set of 2-D mipmaps from it.
262 * Input: imageFile - name of .rgb to read
263 * intFormat - internal texture format to use, or number of components
264 * Return: GL_TRUE if success, GL_FALSE if error.
266 GLboolean
LoadRGBMipmaps( const char *imageFile
, GLint intFormat
)
269 return LoadRGBMipmaps2( imageFile
, GL_TEXTURE_2D
, intFormat
, &w
, &h
);
274 GLboolean
LoadRGBMipmaps2( const char *imageFile
, GLenum target
,
275 GLint intFormat
, GLint
*width
, GLint
*height
)
279 TK_RGBImageRec
*image
;
281 image
= tkRGBImageLoad( imageFile
);
286 if (image
->components
==3) {
289 else if (image
->components
==4) {
293 /* not implemented */
295 "Error in LoadRGBMipmaps %d-component images not implemented\n",
300 error
= gluBuild2DMipmaps( target
,
302 image
->sizeX
, image
->sizeY
,
307 *width
= image
->sizeX
;
308 *height
= image
->sizeY
;
312 return error
? GL_FALSE
: GL_TRUE
;
318 * Load an SGI .rgb file and return a pointer to the image data.
319 * Input: imageFile - name of .rgb to read
320 * Output: width - width of image
321 * height - height of image
322 * format - format of image (GL_RGB or GL_RGBA)
323 * Return: pointer to image data or NULL if error
325 GLubyte
*LoadRGBImage( const char *imageFile
, GLint
*width
, GLint
*height
,
328 TK_RGBImageRec
*image
;
332 image
= tkRGBImageLoad( imageFile
);
337 if (image
->components
==3) {
340 else if (image
->components
==4) {
344 /* not implemented */
346 "Error in LoadRGBImage %d-component images not implemented\n",
351 *width
= image
->sizeX
;
352 *height
= image
->sizeY
;
354 bytes
= image
->sizeX
* image
->sizeY
* image
->components
;
355 buffer
= (GLubyte
*) malloc(bytes
);
359 memcpy( (void *) buffer
, (void *) image
->data
, bytes
);