2 /* texture.c - by David Blythe, SGI */
4 /* texload is a simplistic routine for reading an SGI .rgb image file. */
11 #include "glut_wrap.h"
13 typedef struct _ImageRec
{
14 unsigned short imagic
;
17 unsigned short xsize
, ysize
, zsize
;
18 unsigned int min
, max
;
19 unsigned int wasteBytes
;
21 unsigned long colorMap
;
25 unsigned int *rowStart
;
30 rgbtorgb(unsigned char *r
,unsigned char *g
,unsigned char *b
,unsigned char *l
,int n
) {
35 l
+= 3; r
++; g
++; b
++;
40 ConvertShort(unsigned short *array
, unsigned int length
) {
41 unsigned short b1
, b2
;
44 ptr
= (unsigned char *)array
;
48 *array
++ = (b1
<< 8) | (b2
);
53 ConvertUint(unsigned *array
, unsigned int length
) {
54 unsigned int b1
, b2
, b3
, b4
;
57 ptr
= (unsigned char *)array
;
63 *array
++ = (b1
<< 24) | (b2
<< 16) | (b3
<< 8) | (b4
);
67 static ImageRec
*ImageOpen(char *fileName
)
78 endianTest
.testWord
= 1;
79 if (endianTest
.testByte
[0] == 1) {
85 image
= (ImageRec
*)malloc(sizeof(ImageRec
));
87 fprintf(stderr
, "Out of memory!\n");
90 if ((image
->file
= fopen(fileName
, "rb")) == NULL
) {
95 result
= fread(image
, 1, 12, image
->file
);
99 ConvertShort(&image
->imagic
, 1);
100 ConvertShort(&image
->type
, 1);
101 ConvertShort(&image
->dim
, 1);
102 ConvertShort(&image
->xsize
, 1);
103 ConvertShort(&image
->ysize
, 1);
104 ConvertShort(&image
->zsize
, 1);
107 image
->tmp
= (unsigned char *)malloc(image
->xsize
*256);
108 if (image
->tmp
== NULL
) {
109 fprintf(stderr
, "\nOut of memory!\n");
113 if ((image
->type
& 0xFF00) == 0x0100) {
114 x
= image
->ysize
* image
->zsize
* (int) sizeof(unsigned);
115 image
->rowStart
= (unsigned *)malloc(x
);
116 image
->rowSize
= (int *)malloc(x
);
117 if (image
->rowStart
== NULL
|| image
->rowSize
== NULL
) {
118 fprintf(stderr
, "\nOut of memory!\n");
121 image
->rleEnd
= 512 + (2 * x
);
122 fseek(image
->file
, 512, SEEK_SET
);
123 result
= fread(image
->rowStart
, 1, x
, image
->file
);
125 result
= fread(image
->rowSize
, 1, x
, image
->file
);
128 ConvertUint(image
->rowStart
, x
/(int) sizeof(unsigned));
129 ConvertUint((unsigned *)image
->rowSize
, x
/(int) sizeof(int));
136 ImageClose(ImageRec
*image
) {
143 ImageGetRow(ImageRec
*image
, unsigned char *buf
, int y
, int z
) {
144 unsigned char *iPtr
, *oPtr
, pixel
;
148 if ((image
->type
& 0xFF00) == 0x0100) {
149 fseek(image
->file
, (long) image
->rowStart
[y
+z
*image
->ysize
], SEEK_SET
);
150 result
= fread(image
->tmp
, 1, (unsigned int)image
->rowSize
[y
+z
*image
->ysize
],
152 assert(result
== (unsigned int)image
->rowSize
[y
+z
*image
->ysize
]);
158 count
= (int)(pixel
& 0x7F);
174 fseek(image
->file
, 512+(y
*image
->xsize
)+(z
*image
->xsize
*image
->ysize
),
176 result
= fread(buf
, 1, image
->xsize
, image
->file
);
177 assert(result
== image
->xsize
);
183 read_alpha_texture(char *name
, int *width
, int *height
)
185 unsigned char *base
, *lptr
;
189 image
= ImageOpen(name
);
194 (*width
)=image
->xsize
;
195 (*height
)=image
->ysize
;
196 if (image
->zsize
!= 1) {
201 base
= (unsigned char *)malloc(image
->xsize
*image
->ysize
*sizeof(unsigned char));
203 for(y
=0; y
<image
->ysize
; y
++) {
204 ImageGetRow(image
,lptr
,y
,0);
205 lptr
+= image
->xsize
;
209 return (unsigned char *) base
;
214 read_rgb_texture(char *name
, int *width
, int *height
)
216 unsigned char *base
, *ptr
;
217 unsigned char *rbuf
, *gbuf
, *bbuf
, *abuf
;
221 image
= ImageOpen(name
);
225 (*width
)=image
->xsize
;
226 (*height
)=image
->ysize
;
227 if (image
->zsize
!= 3 && image
->zsize
!= 4) {
232 base
= (unsigned char*)malloc(image
->xsize
*image
->ysize
*sizeof(unsigned int)*3);
233 rbuf
= (unsigned char *)malloc(image
->xsize
*sizeof(unsigned char));
234 gbuf
= (unsigned char *)malloc(image
->xsize
*sizeof(unsigned char));
235 bbuf
= (unsigned char *)malloc(image
->xsize
*sizeof(unsigned char));
236 abuf
= (unsigned char *)malloc(image
->xsize
*sizeof(unsigned char));
237 if(!base
|| !rbuf
|| !gbuf
|| !bbuf
|| !abuf
) {
238 if (base
) free(base
);
239 if (rbuf
) free(rbuf
);
240 if (gbuf
) free(gbuf
);
241 if (bbuf
) free(bbuf
);
242 if (abuf
) free(abuf
);
247 for(y
=0; y
<image
->ysize
; y
++) {
248 if(image
->zsize
== 4) {
249 ImageGetRow(image
,rbuf
,y
,0);
250 ImageGetRow(image
,gbuf
,y
,1);
251 ImageGetRow(image
,bbuf
,y
,2);
252 ImageGetRow(image
,abuf
,y
,3); /* Discard. */
253 rgbtorgb(rbuf
,gbuf
,bbuf
,ptr
,image
->xsize
);
254 ptr
+= (image
->xsize
* 3);
256 ImageGetRow(image
,rbuf
,y
,0);
257 ImageGetRow(image
,gbuf
,y
,1);
258 ImageGetRow(image
,bbuf
,y
,2);
259 rgbtorgb(rbuf
,gbuf
,bbuf
,ptr
,image
->xsize
);
260 ptr
+= (image
->xsize
* 3);
269 return (GLubyte
*) base
;
272 int main(int argc
, char **argv
)
283 fprintf(stderr
, "usage: %s <infile.rgb> <outfile.p6>\n", argv
[0]);
287 data
= read_rgb_texture(argv
[1], &width
, &height
);
289 n
= sprintf(buff
, "P6\n%d %d\n255\n", width
, height
);
291 /* [dBorca] avoid LF to CRLF conversion */
292 if ((fo
= fopen(argv
[2], "wb")) == NULL
) {
293 fprintf(stderr
, "Cannot open output file!\n");
297 fwrite(buff
, n
, 1, fo
);
298 fwrite(data
, width
* 3, height
, fo
);