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.
23 ** RGB Image Structure
26 typedef struct _TK_RGBImageRec
{
34 /******************************************************************************/
36 typedef struct _rawImageRec
{
37 unsigned short imagic
;
40 unsigned short sizeX
, sizeY
, sizeZ
;
41 unsigned long min
, max
;
42 unsigned long wasteBytes
;
44 unsigned long colorMap
;
46 unsigned char *tmp
, *tmpR
, *tmpG
, *tmpB
, *tmpA
;
52 /******************************************************************************/
54 static void ConvertShort(unsigned short *array
, long length
)
59 ptr
= (unsigned char *)array
;
63 *array
++ = (unsigned short) ((b1
<< 8) | (b2
));
67 static void ConvertLong(GLuint
*array
, long length
)
69 unsigned long b1
, b2
, b3
, b4
;
72 ptr
= (unsigned char *)array
;
78 *array
++ = (b1
<< 24) | (b2
<< 16) | (b3
<< 8) | (b4
);
82 static rawImageRec
*RawImageOpen(const char *fileName
)
92 endianTest
.testWord
= 1;
93 if (endianTest
.testByte
[0] == 1) {
99 raw
= (rawImageRec
*)malloc(sizeof(rawImageRec
));
101 fprintf(stderr
, "Out of memory!\n");
104 if ((raw
->file
= fopen(fileName
, "rb")) == NULL
) {
109 fread(raw
, 1, 12, raw
->file
);
112 ConvertShort(&raw
->imagic
, 6);
115 raw
->tmp
= (unsigned char *)malloc(raw
->sizeX
*256);
116 raw
->tmpR
= (unsigned char *)malloc(raw
->sizeX
*256);
117 raw
->tmpG
= (unsigned char *)malloc(raw
->sizeX
*256);
118 raw
->tmpB
= (unsigned char *)malloc(raw
->sizeX
*256);
120 raw
->tmpA
= (unsigned char *)malloc(raw
->sizeX
*256);
122 if (raw
->tmp
== NULL
|| raw
->tmpR
== NULL
|| raw
->tmpG
== NULL
||
124 fprintf(stderr
, "Out of memory!\n");
128 if ((raw
->type
& 0xFF00) == 0x0100) {
129 x
= raw
->sizeY
* raw
->sizeZ
* sizeof(GLuint
);
130 raw
->rowStart
= (GLuint
*)malloc(x
);
131 raw
->rowSize
= (GLint
*)malloc(x
);
132 if (raw
->rowStart
== NULL
|| raw
->rowSize
== NULL
) {
133 fprintf(stderr
, "Out of memory!\n");
136 raw
->rleEnd
= 512 + (2 * x
);
137 fseek(raw
->file
, 512, SEEK_SET
);
138 fread(raw
->rowStart
, 1, x
, raw
->file
);
139 fread(raw
->rowSize
, 1, x
, raw
->file
);
141 ConvertLong(raw
->rowStart
, (long) (x
/sizeof(GLuint
)));
142 ConvertLong((GLuint
*)raw
->rowSize
, (long) (x
/sizeof(GLint
)));
148 static void RawImageClose(rawImageRec
*raw
)
162 static void RawImageGetRow(rawImageRec
*raw
, unsigned char *buf
, int y
, int z
)
164 unsigned char *iPtr
, *oPtr
, pixel
;
167 if ((raw
->type
& 0xFF00) == 0x0100) {
168 fseek(raw
->file
, (long) raw
->rowStart
[y
+z
*raw
->sizeY
], SEEK_SET
);
169 fread(raw
->tmp
, 1, (unsigned int)raw
->rowSize
[y
+z
*raw
->sizeY
],
176 count
= (int)(pixel
& 0x7F);
193 fseek(raw
->file
, 512+(y
*raw
->sizeX
)+(z
*raw
->sizeX
*raw
->sizeY
),
195 fread(buf
, 1, raw
->sizeX
, raw
->file
);
200 static void RawImageGetData(rawImageRec
*raw
, TK_RGBImageRec
*final
)
205 final
->data
= (unsigned char *)malloc((raw
->sizeX
+1)*(raw
->sizeY
+1)*4);
206 if (final
->data
== NULL
) {
207 fprintf(stderr
, "Out of memory!\n");
211 for (i
= 0; i
< (int)(raw
->sizeY
); i
++) {
212 RawImageGetRow(raw
, raw
->tmpR
, i
, 0);
213 RawImageGetRow(raw
, raw
->tmpG
, i
, 1);
214 RawImageGetRow(raw
, raw
->tmpB
, i
, 2);
216 RawImageGetRow(raw
, raw
->tmpA
, i
, 3);
218 for (j
= 0; j
< (int)(raw
->sizeX
); j
++) {
219 *ptr
++ = *(raw
->tmpR
+ j
);
220 *ptr
++ = *(raw
->tmpG
+ j
);
221 *ptr
++ = *(raw
->tmpB
+ j
);
223 *ptr
++ = *(raw
->tmpA
+ j
);
230 static TK_RGBImageRec
*tkRGBImageLoad(const char *fileName
)
233 TK_RGBImageRec
*final
;
235 raw
= RawImageOpen(fileName
);
237 fprintf(stderr
, "File not found\n");
240 final
= (TK_RGBImageRec
*)malloc(sizeof(TK_RGBImageRec
));
242 fprintf(stderr
, "Out of memory!\n");
245 final
->sizeX
= raw
->sizeX
;
246 final
->sizeY
= raw
->sizeY
;
247 final
->components
= raw
->sizeZ
;
248 RawImageGetData(raw
, final
);
254 static void FreeImage( TK_RGBImageRec
*image
)
262 * Load an SGI .rgb file and generate a set of 2-D mipmaps from it.
263 * Input: imageFile - name of .rgb to read
264 * intFormat - internal texture format to use, or number of components
265 * Return: GL_TRUE if success, GL_FALSE if error.
267 GLboolean
LoadRGBMipmaps( const char *imageFile
, GLint intFormat
)
271 TK_RGBImageRec
*image
;
273 image
= tkRGBImageLoad( imageFile
);
278 if (image
->components
==3) {
281 else if (image
->components
==4) {
285 /* not implemented */
287 "Error in LoadRGBMipmaps %d-component images not implemented\n",
292 error
= gluBuild2DMipmaps( GL_TEXTURE_2D
,
294 image
->sizeX
, image
->sizeY
,
300 return error
? GL_FALSE
: GL_TRUE
;
306 * Load an SGI .rgb file and return a pointer to the image data.
307 * Input: imageFile - name of .rgb to read
308 * Output: width - width of image
309 * height - height of image
310 * format - format of image (GL_RGB or GL_RGBA)
311 * Return: pointer to image data or NULL if error
313 GLubyte
*LoadRGBImage( const char *imageFile
, GLint
*width
, GLint
*height
,
316 TK_RGBImageRec
*image
;
320 image
= tkRGBImageLoad( imageFile
);
325 if (image
->components
==3) {
328 else if (image
->components
==4) {
332 /* not implemented */
334 "Error in LoadRGBImage %d-component images not implemented\n",
339 *width
= image
->sizeX
;
340 *height
= image
->sizeY
;
342 bytes
= image
->sizeX
* image
->sizeY
* image
->components
;
343 buffer
= (GLubyte
*) malloc(bytes
);
347 memcpy( (void *) buffer
, (void *) image
->data
, bytes
);