2 /* texture.c - by David Blythe, SGI */
4 /* texload is a simplistic routine for reading an SGI .rgb image file. */
18 #include <simgear/sg_zlib.h>
23 typedef struct _ImageRec {
24 unsigned short imagic;
27 unsigned short xsize, ysize, zsize;
28 unsigned int min, max;
29 unsigned int wasteBytes;
31 unsigned long colorMap;
35 unsigned int *rowStart;
40 rgbtorgb(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) {
45 l += 3; r++; g++; b++;
50 ConvertShort(unsigned short *array, unsigned int length) {
51 unsigned short b1, b2;
54 ptr = (unsigned char *)array;
58 *array++ = (b1 << 8) | (b2);
63 ConvertUint(unsigned *array, unsigned int length) {
64 unsigned int b1, b2, b3, b4;
67 ptr = (unsigned char *)array;
73 *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
77 static ImageRec *ImageOpen(const char *fileName)
88 endianTest.testWord = 1;
89 if (endianTest.testByte[0] == 1) {
95 image = (ImageRec *)malloc(sizeof(ImageRec));
97 fprintf(stderr, "Out of memory!\n");
100 if ((image->file = sgopen(fileName, "rb")) == NULL) {
104 // fread(image, 1, 12, image->file);
105 sgread(image->file, image, 12);
108 ConvertShort(&image->imagic, 6);
111 image->tmp = (unsigned char *)malloc(image->xsize*256);
112 if (image->tmp == NULL) {
113 fprintf(stderr, "\nOut of memory!\n");
117 if ((image->type & 0xFF00) == 0x0100) {
118 x = image->ysize * image->zsize * (int) sizeof(unsigned);
119 image->rowStart = (unsigned *)malloc(x);
120 image->rowSize = (int *)malloc(x);
121 if (image->rowStart == NULL || image->rowSize == NULL) {
122 fprintf(stderr, "\nOut of memory!\n");
125 image->rleEnd = 512 + (2 * x);
126 sgseek(image->file, 512, SEEK_SET);
127 // fread(image->rowStart, 1, x, image->file);
128 sgread(image->file, image->rowStart, x);
129 // fread(image->rowSize, 1, x, image->file);
130 sgread(image->file, image->rowSize, x);
132 ConvertUint(image->rowStart, x/(int) sizeof(unsigned));
133 ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int));
140 ImageClose(ImageRec *image) {
141 sgclose(image->file);
147 ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
148 unsigned char *iPtr, *oPtr, pixel;
151 if ((image->type & 0xFF00) == 0x0100) {
152 sgseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET);
153 // fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
155 sgread(image->file, image->tmp,
156 (unsigned int)image->rowSize[y+z*image->ysize]);
162 count = (int)(pixel & 0x7F);
178 sgseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
180 // fread(buf, 1, image->xsize, image->file);
181 sgread(image->file, buf, image->xsize);
186 read_alpha_texture(const char *name, int *width, int *height)
188 unsigned char *base, *lptr;
192 image = ImageOpen(name);
197 (*width)=image->xsize;
198 (*height)=image->ysize;
200 printf("image->zsize = %d\n", image->zsize);
202 if (image->zsize != 1) {
207 base = (unsigned char *)malloc(image->xsize*image->ysize*sizeof(unsigned char));
209 for(y=0; y<image->ysize; y++) {
210 ImageGetRow(image,lptr,y,0);
211 lptr += image->xsize;
215 return (unsigned char *) base;
219 read_rgb_texture(const char *name, int *width, int *height)
221 unsigned char *base, *ptr;
222 unsigned char *rbuf, *gbuf, *bbuf, *abuf;
226 image = ImageOpen(name);
230 (*width)=image->xsize;
231 (*height)=image->ysize;
232 if (image->zsize != 3 && image->zsize != 4) {
237 base = (unsigned char*)malloc(image->xsize*image->ysize*sizeof(unsigned int)*3);
238 rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
239 gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
240 bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
241 abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
242 if(!base || !rbuf || !gbuf || !bbuf || !abuf) {
243 if (base) free(base);
244 if (rbuf) free(rbuf);
245 if (gbuf) free(gbuf);
246 if (bbuf) free(bbuf);
247 if (abuf) free(abuf);
251 for(y=0; y<image->ysize; y++) {
252 if(image->zsize == 4) {
253 ImageGetRow(image,rbuf,y,0);
254 ImageGetRow(image,gbuf,y,1);
255 ImageGetRow(image,bbuf,y,2);
256 ImageGetRow(image,abuf,y,3); /* Discard. */
257 rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
258 ptr += (image->xsize * 3);
260 ImageGetRow(image,rbuf,y,0);
261 ImageGetRow(image,gbuf,y,1);
262 ImageGetRow(image,bbuf,y,2);
263 rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
264 ptr += (image->xsize * 3);
273 return (GLubyte *) base;
277 static ImageRec *RawImageOpen(const char *fileName)
287 endianTest.testWord = 1;
288 if (endianTest.testByte[0] == 1) {
294 image = (ImageRec *)malloc(sizeof(ImageRec));
296 fprintf(stderr, "Out of memory!\n");
299 if ((image->file = sgopen(fileName, "rb")) == NULL) {
303 sgread(image->file, image, 12);
306 ConvertShort(&image->imagic, 6);
310 image->tmp = (unsigned char *)malloc(1); //just allocate a pseudo value as I'm too lazy to change ImageClose()...
311 if (image->tmp == NULL) {
312 fprintf(stderr, "\nOut of memory!\n");
321 read_raw_texture(const char *name, int *width, int *height)
323 unsigned char *base, *ptr;
327 image = RawImageOpen(name);
334 base = (unsigned char*)malloc(256*256*sizeof(unsigned char)*3);
336 if (base) free(base);
340 for(y=0; y<256; y++) {
341 sgread(image->file, ptr, 256*3);
346 return (GLubyte *) base;
351 read_r8_texture(const char *name, int *width, int *height)
353 unsigned char *base, *ptr;
358 image = RawImageOpen(name); //it wouldn't make sense to write a new function...
365 base = (unsigned char*)malloc(256*256*sizeof(unsigned char)*3);
367 if (base) free(base);
371 for(xy=0; xy<(256*256); xy++) {
372 sgread(image->file,c,1);
373 ptr[0]=msfs_colour[c[0]][0]; //look in the table for the right colours
374 ptr[1]=msfs_colour[c[0]][1];
375 ptr[2]=msfs_colour[c[0]][2];
381 return (GLubyte *) base;