blob: dcb74228dfffde8743d802a6306e5070a836eed4 [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) {
Vinson Lee1cf60c92009-12-10 15:41:13 -080096 ConvertShort(&image->imagic, 1);
97 ConvertShort(&image->type, 1);
98 ConvertShort(&image->dim, 1);
99 ConvertShort(&image->xsize, 1);
100 ConvertShort(&image->ysize, 1);
101 ConvertShort(&image->zsize, 1);
jtgafb833d1999-08-19 00:55:39 +0000102 }
103
104 image->tmp = (unsigned char *)malloc(image->xsize*256);
105 if (image->tmp == NULL) {
106 fprintf(stderr, "\nOut of memory!\n");
107 exit(1);
108 }
109
110 if ((image->type & 0xFF00) == 0x0100) {
111 x = image->ysize * image->zsize * (int) sizeof(unsigned);
112 image->rowStart = (unsigned *)malloc(x);
113 image->rowSize = (int *)malloc(x);
114 if (image->rowStart == NULL || image->rowSize == NULL) {
115 fprintf(stderr, "\nOut of memory!\n");
116 exit(1);
117 }
118 image->rleEnd = 512 + (2 * x);
119 fseek(image->file, 512, SEEK_SET);
120 fread(image->rowStart, 1, x, image->file);
121 fread(image->rowSize, 1, x, image->file);
122 if (swapFlag) {
123 ConvertUint(image->rowStart, x/(int) sizeof(unsigned));
124 ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int));
125 }
126 }
127 return image;
128}
129
130static void
131ImageClose(ImageRec *image) {
132 fclose(image->file);
133 free(image->tmp);
134 free(image);
135}
136
137static void
138ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
139 unsigned char *iPtr, *oPtr, pixel;
140 int count;
141
142 if ((image->type & 0xFF00) == 0x0100) {
143 fseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET);
144 fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
145 image->file);
146
147 iPtr = image->tmp;
148 oPtr = buf;
149 for (;;) {
150 pixel = *iPtr++;
151 count = (int)(pixel & 0x7F);
152 if (!count) {
153 return;
154 }
155 if (pixel & 0x80) {
156 while (count--) {
157 *oPtr++ = *iPtr++;
158 }
159 } else {
160 pixel = *iPtr++;
161 while (count--) {
162 *oPtr++ = pixel;
163 }
164 }
165 }
166 } else {
167 fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
168 SEEK_SET);
169 fread(buf, 1, image->xsize, image->file);
170 }
171}
172
173GLubyte *
174read_alpha_texture(char *name, int *width, int *height)
175{
176 unsigned char *base, *lptr;
177 ImageRec *image;
178 int y;
179
180 image = ImageOpen(name);
181 if(!image) {
182 return NULL;
183 }
184
185 (*width)=image->xsize;
186 (*height)=image->ysize;
187 if (image->zsize != 1) {
188 ImageClose(image);
189 return NULL;
190 }
191
192 base = (unsigned char *)malloc(image->xsize*image->ysize*sizeof(unsigned char));
193 lptr = base;
194 for(y=0; y<image->ysize; y++) {
195 ImageGetRow(image,lptr,y,0);
196 lptr += image->xsize;
197 }
198 ImageClose(image);
199
200 return (unsigned char *) base;
201}
202
203GLubyte *
204read_rgb_texture(char *name, int *width, int *height)
205{
206 unsigned char *base, *ptr;
207 unsigned char *rbuf, *gbuf, *bbuf, *abuf;
208 ImageRec *image;
209 int y;
210
211 image = ImageOpen(name);
212
213 if(!image)
214 return NULL;
215 (*width)=image->xsize;
216 (*height)=image->ysize;
217 if (image->zsize != 3 && image->zsize != 4) {
218 ImageClose(image);
219 return NULL;
220 }
221
222 base = (unsigned char*)malloc(image->xsize*image->ysize*sizeof(unsigned int)*3);
223 rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
224 gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
225 bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
226 abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
227 if(!base || !rbuf || !gbuf || !bbuf || !abuf) {
228 if (base) free(base);
229 if (rbuf) free(rbuf);
230 if (gbuf) free(gbuf);
231 if (bbuf) free(bbuf);
232 if (abuf) free(abuf);
Vinson Lee1446f302009-12-05 01:43:29 -0800233 ImageClose(image);
jtgafb833d1999-08-19 00:55:39 +0000234 return NULL;
235 }
236 ptr = base;
237 for(y=0; y<image->ysize; y++) {
238 if(image->zsize == 4) {
239 ImageGetRow(image,rbuf,y,0);
240 ImageGetRow(image,gbuf,y,1);
241 ImageGetRow(image,bbuf,y,2);
242 ImageGetRow(image,abuf,y,3); /* Discard. */
243 rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
244 ptr += (image->xsize * 3);
245 } else {
246 ImageGetRow(image,rbuf,y,0);
247 ImageGetRow(image,gbuf,y,1);
248 ImageGetRow(image,bbuf,y,2);
249 rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
250 ptr += (image->xsize * 3);
251 }
252 }
253 ImageClose(image);
254 free(rbuf);
255 free(gbuf);
256 free(bbuf);
257 free(abuf);
258
259 return (GLubyte *) base;
260}
261
262int main(int argc, char **argv)
263{
264 int width, height;
265 GLubyte *data;
Brian Paule5ed2f02003-02-04 12:34:02 +0000266 char buff[32];
267 int n;
268 FILE *fo;
jtgafb833d1999-08-19 00:55:39 +0000269
Brian Paule5ed2f02003-02-04 12:34:02 +0000270 if (argc != 3)
jtgafb833d1999-08-19 00:55:39 +0000271 {
Brian Paule5ed2f02003-02-04 12:34:02 +0000272 fprintf(stderr, "usage: %s <infile.rgb> <outfile.p6>\n", argv[0]);
jtgafb833d1999-08-19 00:55:39 +0000273 return 1;
274 }
275
276 data = read_rgb_texture(argv[1], &width, &height);
277
Brian Paule5ed2f02003-02-04 12:34:02 +0000278 n = sprintf(buff, "P6\n%d %d\n255\n", width, height);
279
280 /* [dBorca] avoid LF to CRLF conversion */
281 if ((fo = fopen(argv[2], "wb")) == NULL) {
282 fprintf(stderr, "Cannot open output file!\n");
283 exit(1);
284 }
285
286 fwrite(buff, n, 1, fo);
287 fwrite(data, width * 3, height, fo);
288
289 fclose(fo);
jtgafb833d1999-08-19 00:55:39 +0000290
291 return 0;
292}