2 /* texture.c - by David Blythe, SGI */
4 /* texload is a simplistic routine for reading an SGI .rgb image file. */
12 typedef struct _ImageRec {
13 unsigned short imagic;
16 unsigned short xsize, ysize, zsize;
17 unsigned int min, max;
18 unsigned int wasteBytes;
20 unsigned long colorMap;
24 unsigned int *rowStart;
29 rgbtorgb(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) {
34 l += 3; r++; g++; b++;
39 ConvertShort(unsigned short *array, unsigned int length) {
40 unsigned short b1, b2;
43 ptr = (unsigned char *)array;
47 *array++ = (b1 << 8) | (b2);
52 ConvertUint(unsigned *array, unsigned int length) {
53 unsigned int b1, b2, b3, b4;
56 ptr = (unsigned char *)array;
62 *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
66 static ImageRec *ImageOpen(char *fileName)
77 endianTest.testWord = 1;
78 if (endianTest.testByte[0] == 1) {
84 image = (ImageRec *)malloc(sizeof(ImageRec));
86 fprintf(stderr, "Out of memory!\n");
89 if ((image->file = fopen(fileName, "rb")) == NULL) {
93 fread(image, 1, 12, image->file);
96 ConvertShort(&image->imagic, 6);
99 image->tmp = (unsigned char *)malloc(image->xsize*256);
100 if (image->tmp == NULL) {
101 fprintf(stderr, "\nOut of memory!\n");
105 if ((image->type & 0xFF00) == 0x0100) {
106 x = image->ysize * image->zsize * (int) sizeof(unsigned);
107 image->rowStart = (unsigned *)malloc(x);
108 image->rowSize = (int *)malloc(x);
109 if (image->rowStart == NULL || image->rowSize == NULL) {
110 fprintf(stderr, "\nOut of memory!\n");
113 image->rleEnd = 512 + (2 * x);
114 fseek(image->file, 512, SEEK_SET);
115 fread(image->rowStart, 1, x, image->file);
116 fread(image->rowSize, 1, x, image->file);
118 ConvertUint(image->rowStart, x/(int) sizeof(unsigned));
119 ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int));
126 ImageClose(ImageRec *image) {
133 ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
134 unsigned char *iPtr, *oPtr, pixel;
137 if ((image->type & 0xFF00) == 0x0100) {
138 fseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET);
139 fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
146 count = (int)(pixel & 0x7F);
162 fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
164 fread(buf, 1, image->xsize, image->file);
169 read_alpha_texture(char *name, int *width, int *height)
171 unsigned char *base, *lptr;
175 image = ImageOpen(name);
180 (*width)=image->xsize;
181 (*height)=image->ysize;
182 if (image->zsize != 1) {
187 base = (unsigned char *)malloc(image->xsize*image->ysize*sizeof(unsigned char));
189 for(y=0; y<image->ysize; y++) {
190 ImageGetRow(image,lptr,y,0);
191 lptr += image->xsize;
195 return (unsigned char *) base;
199 read_rgb_texture(char *name, int *width, int *height)
201 unsigned char *base, *ptr;
202 unsigned char *rbuf, *gbuf, *bbuf, *abuf;
206 image = ImageOpen(name);
210 (*width)=image->xsize;
211 (*height)=image->ysize;
212 if (image->zsize != 3 && image->zsize != 4) {
217 base = (unsigned char*)malloc(image->xsize*image->ysize*sizeof(unsigned int)*3);
218 rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
219 gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
220 bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
221 abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
222 if(!base || !rbuf || !gbuf || !bbuf || !abuf) {
223 if (base) free(base);
224 if (rbuf) free(rbuf);
225 if (gbuf) free(gbuf);
226 if (bbuf) free(bbuf);
227 if (abuf) free(abuf);
231 for(y=0; y<image->ysize; y++) {
232 if(image->zsize == 4) {
233 ImageGetRow(image,rbuf,y,0);
234 ImageGetRow(image,gbuf,y,1);
235 ImageGetRow(image,bbuf,y,2);
236 ImageGetRow(image,abuf,y,3); /* Discard. */
237 rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
238 ptr += (image->xsize * 3);
240 ImageGetRow(image,rbuf,y,0);
241 ImageGetRow(image,gbuf,y,1);
242 ImageGetRow(image,bbuf,y,2);
243 rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
244 ptr += (image->xsize * 3);
253 return (GLubyte *) base;