blob: 6652bb32ec1e9dfbf9bd7abc819d082c61c99086 [file] [log] [blame]
jtgafb833d1999-08-19 00:55:39 +00001
2/* texture.c - by David Blythe, SGI */
3
4/* texload is a simplistic routine for reading an SGI .rgb image file. */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9
10#include <GL/glut.h>
11
12typedef struct _ImageRec {
13 unsigned short imagic;
14 unsigned short type;
15 unsigned short dim;
16 unsigned short xsize, ysize, zsize;
17 unsigned int min, max;
18 unsigned int wasteBytes;
19 char name[80];
20 unsigned long colorMap;
21 FILE *file;
22 unsigned char *tmp;
23 unsigned long rleEnd;
24 unsigned int *rowStart;
25 int *rowSize;
26} ImageRec;
27
28void
29rgbtorgb(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) {
30 while(n--) {
31 l[0] = r[0];
32 l[1] = g[0];
33 l[2] = b[0];
34 l += 3; r++; g++; b++;
35 }
36}
37
38static void
39ConvertShort(unsigned short *array, unsigned int length) {
40 unsigned short b1, b2;
41 unsigned char *ptr;
42
43 ptr = (unsigned char *)array;
44 while (length--) {
45 b1 = *ptr++;
46 b2 = *ptr++;
47 *array++ = (b1 << 8) | (b2);
48 }
49}
50
51static void
52ConvertUint(unsigned *array, unsigned int length) {
53 unsigned int b1, b2, b3, b4;
54 unsigned char *ptr;
55
56 ptr = (unsigned char *)array;
57 while (length--) {
58 b1 = *ptr++;
59 b2 = *ptr++;
60 b3 = *ptr++;
61 b4 = *ptr++;
62 *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
63 }
64}
65
66static ImageRec *ImageOpen(char *fileName)
67{
68 union {
69 int testWord;
70 char testByte[4];
71 } endianTest;
72 ImageRec *image;
73 int swapFlag;
74 int x;
75
76 endianTest.testWord = 1;
77 if (endianTest.testByte[0] == 1) {
78 swapFlag = 1;
79 } else {
80 swapFlag = 0;
81 }
82
83 image = (ImageRec *)malloc(sizeof(ImageRec));
84 if (image == NULL) {
85 fprintf(stderr, "Out of memory!\n");
86 exit(1);
87 }
88 if ((image->file = fopen(fileName, "rb")) == NULL) {
Vinson Lee412aeee2009-12-05 01:38:14 -080089 free(image);
90 return NULL;
jtgafb833d1999-08-19 00:55:39 +000091 }
92
93 fread(image, 1, 12, image->file);
94
95 if (swapFlag) {
96 ConvertShort(&image->imagic, 6);
97 }
98
99 image->tmp = (unsigned char *)malloc(image->xsize*256);
100 if (image->tmp == NULL) {
101 fprintf(stderr, "\nOut of memory!\n");
102 exit(1);
103 }
104
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");
111 exit(1);
112 }
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);
117 if (swapFlag) {
118 ConvertUint(image->rowStart, x/(int) sizeof(unsigned));
119 ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int));
120 }
121 }
122 return image;
123}
124
125static void
126ImageClose(ImageRec *image) {
127 fclose(image->file);
128 free(image->tmp);
129 free(image);
130}
131
132static void
133ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
134 unsigned char *iPtr, *oPtr, pixel;
135 int count;
136
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],
140 image->file);
141
142 iPtr = image->tmp;
143 oPtr = buf;
144 for (;;) {
145 pixel = *iPtr++;
146 count = (int)(pixel & 0x7F);
147 if (!count) {
148 return;
149 }
150 if (pixel & 0x80) {
151 while (count--) {
152 *oPtr++ = *iPtr++;
153 }
154 } else {
155 pixel = *iPtr++;
156 while (count--) {
157 *oPtr++ = pixel;
158 }
159 }
160 }
161 } else {
162 fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
163 SEEK_SET);
164 fread(buf, 1, image->xsize, image->file);
165 }
166}
167
168GLubyte *
169read_alpha_texture(char *name, int *width, int *height)
170{
171 unsigned char *base, *lptr;
172 ImageRec *image;
173 int y;
174
175 image = ImageOpen(name);
176 if(!image) {
177 return NULL;
178 }
179
180 (*width)=image->xsize;
181 (*height)=image->ysize;
182 if (image->zsize != 1) {
183 ImageClose(image);
184 return NULL;
185 }
186
187 base = (unsigned char *)malloc(image->xsize*image->ysize*sizeof(unsigned char));
188 lptr = base;
189 for(y=0; y<image->ysize; y++) {
190 ImageGetRow(image,lptr,y,0);
191 lptr += image->xsize;
192 }
193 ImageClose(image);
194
195 return (unsigned char *) base;
196}
197
198GLubyte *
199read_rgb_texture(char *name, int *width, int *height)
200{
201 unsigned char *base, *ptr;
202 unsigned char *rbuf, *gbuf, *bbuf, *abuf;
203 ImageRec *image;
204 int y;
205
206 image = ImageOpen(name);
207
208 if(!image)
209 return NULL;
210 (*width)=image->xsize;
211 (*height)=image->ysize;
212 if (image->zsize != 3 && image->zsize != 4) {
213 ImageClose(image);
214 return NULL;
215 }
216
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);
228 return NULL;
229 }
230 ptr = base;
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);
239 } else {
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);
245 }
246 }
247 ImageClose(image);
248 free(rbuf);
249 free(gbuf);
250 free(bbuf);
251 free(abuf);
252
253 return (GLubyte *) base;
254}
255
256int main(int argc, char **argv)
257{
258 int width, height;
259 GLubyte *data;
Brian Paule5ed2f02003-02-04 12:34:02 +0000260 char buff[32];
261 int n;
262 FILE *fo;
jtgafb833d1999-08-19 00:55:39 +0000263
Brian Paule5ed2f02003-02-04 12:34:02 +0000264 if (argc != 3)
jtgafb833d1999-08-19 00:55:39 +0000265 {
Brian Paule5ed2f02003-02-04 12:34:02 +0000266 fprintf(stderr, "usage: %s <infile.rgb> <outfile.p6>\n", argv[0]);
jtgafb833d1999-08-19 00:55:39 +0000267 return 1;
268 }
269
270 data = read_rgb_texture(argv[1], &width, &height);
271
Brian Paule5ed2f02003-02-04 12:34:02 +0000272 n = sprintf(buff, "P6\n%d %d\n255\n", width, height);
273
274 /* [dBorca] avoid LF to CRLF conversion */
275 if ((fo = fopen(argv[2], "wb")) == NULL) {
276 fprintf(stderr, "Cannot open output file!\n");
277 exit(1);
278 }
279
280 fwrite(buff, n, 1, fo);
281 fwrite(data, width * 3, height, fo);
282
283 fclose(fo);
jtgafb833d1999-08-19 00:55:39 +0000284
285 return 0;
286}