ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t16.c
Revision: 1.2
Committed: Wed May 31 17:27:18 1989 UTC (34 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.1: +10 -10 lines
Log Message:
Swapped byte order on 24-bit images

File Contents

# Content
1 /* Copyright (c) 1986 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * ra_t16.c - program to convert between RADIANCE and
9 * Targa 16, 24 and 32-bit images.
10 *
11 * 11/2/88 Adapted from ra_t8.c
12 */
13
14 #include <stdio.h>
15
16 #include "color.h"
17
18 #include "targa.h"
19
20 #define goodpic(h) (((h)->dataType==IM_RGB || (h)->dataType==IM_CRGB) \
21 && ((h)->dataBits==16 || (h)->dataBits==24))
22
23 #define taralloc(h) (unsigned char *)emalloc((h)->x*(h)->y*(h)->dataBits/8)
24
25 #define readtarga(h,d,f) ((h)->dataBits==16 ? readt16(h,d,f) : \
26 readt24(h,d,f))
27
28 #define writetarga(h,d,f) ((h)->dataBits==16 ? writet16(h,d,f) : \
29 writet24(h,d,f))
30
31 extern char *ecalloc(), *emalloc();
32
33 extern double atof(), pow();
34
35 double gamma = 2.0; /* gamma correction */
36
37 char *progname;
38
39 char msg[128];
40
41
42 main(argc, argv)
43 int argc;
44 char *argv[];
45 {
46 struct hdStruct head;
47 int reverse = 0;
48 int i;
49
50 progname = argv[0];
51
52 head.dataBits = 16;
53 for (i = 1; i < argc; i++)
54 if (argv[i][0] == '-')
55 switch (argv[i][1]) {
56 case 'g':
57 gamma = atof(argv[++i]);
58 break;
59 case 'r':
60 reverse = !reverse;
61 break;
62 case '2':
63 head.dataBits = 16;
64 break;
65 case '3':
66 head.dataBits = 24;
67 break;
68 default:
69 goto userr;
70 }
71 else
72 break;
73
74 if (i < argc-2)
75 goto userr;
76 /* open input file */
77 if (i <= argc-1 && freopen(argv[i], "r", stdin) == NULL) {
78 sprintf(msg, "can't open input \"%s\"", argv[i]);
79 quiterr(msg);
80 }
81 /* open output file */
82 if (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) {
83 sprintf(msg, "can't open output \"%s\"", argv[i+1]);
84 quiterr(msg);
85 }
86 /* convert */
87 if (reverse) {
88 /* get header */
89 if (getthead(&head, NULL, stdin) < 0)
90 quiterr("bad targa file");
91 if (!goodpic(&head))
92 quiterr("incompatible format");
93 /* put header */
94 printargs(argc, argv, stdout);
95 putchar('\n');
96 printf("-Y %d +X %d\n", head.y, head.x);
97 /* convert file */
98 tg2ra(&head);
99 } else {
100 getheader(stdin, NULL);
101 if (scanf("-Y %d +X %d\n", &head.y, &head.x) != 2)
102 quiterr("bad picture file");
103 /* assign header */
104 head.textSize = 0;
105 head.mapType = CM_NOMAP;
106 head.dataType = IM_RGB;
107 head.XOffset = 0;
108 head.YOffset = 0;
109 head.imType = 0;
110 /* write header */
111 putthead(&head, NULL, stdout);
112 /* convert file */
113 ra2tg(&head);
114 }
115 exit(0);
116 userr:
117 fprintf(stderr, "Usage: %s [-2|-3|-r][-g gamma] [input [output]]\n",
118 progname);
119 exit(1);
120 }
121
122
123 int
124 getint2(fp) /* get a 2-byte positive integer */
125 register FILE *fp;
126 {
127 register int b1, b2;
128
129 if ((b1 = getc(fp)) == EOF || (b2 = getc(fp)) == EOF)
130 quiterr("read error");
131
132 return(b1 | b2<<8);
133 }
134
135
136 putint2(i, fp) /* put a 2-byte positive integer */
137 register int i;
138 register FILE *fp;
139 {
140 putc(i&0xff, fp);
141 putc(i>>8&0xff, fp);
142 }
143
144
145 quiterr(err) /* print message and exit */
146 char *err;
147 {
148 fprintf(stderr, "%s: %s\n", progname, err);
149 exit(1);
150 }
151
152
153 eputs(s)
154 char *s;
155 {
156 fputs(s, stderr);
157 }
158
159
160 quit(code)
161 int code;
162 {
163 exit(code);
164 }
165
166
167 getthead(hp, ip, fp) /* read header from input */
168 struct hdStruct *hp;
169 char *ip;
170 register FILE *fp;
171 {
172 int nidbytes;
173
174 if ((nidbytes = getc(fp)) == EOF)
175 return(-1);
176 hp->mapType = getc(fp);
177 hp->dataType = getc(fp);
178 hp->mapOrig = getint2(fp);
179 hp->mapLength = getint2(fp);
180 hp->CMapBits = getc(fp);
181 hp->XOffset = getint2(fp);
182 hp->YOffset = getint2(fp);
183 hp->x = getint2(fp);
184 hp->y = getint2(fp);
185 hp->dataBits = getc(fp);
186 hp->imType = getc(fp);
187
188 if (ip != NULL)
189 if (nidbytes)
190 fread(ip, nidbytes, 1, fp);
191 else
192 *ip = '\0';
193 else if (nidbytes)
194 fseek(fp, (long)nidbytes, 1);
195
196 return(feof(fp) || ferror(fp) ? -1 : 0);
197 }
198
199
200 putthead(hp, ip, fp) /* write header to output */
201 struct hdStruct *hp;
202 char *ip;
203 register FILE *fp;
204 {
205 if (ip != NULL)
206 putc(strlen(ip), fp);
207 else
208 putc(0, fp);
209 putc(hp->mapType, fp);
210 putc(hp->dataType, fp);
211 putint2(hp->mapOrig, fp);
212 putint2(hp->mapLength, fp);
213 putc(hp->CMapBits, fp);
214 putint2(hp->XOffset, fp);
215 putint2(hp->YOffset, fp);
216 putint2(hp->x, fp);
217 putint2(hp->y, fp);
218 putc(hp->dataBits, fp);
219 putc(hp->imType, fp);
220
221 if (ip != NULL)
222 fputs(ip, fp);
223
224 return(ferror(fp) ? -1 : 0);
225 }
226
227
228 tg2ra(hp) /* targa file to RADIANCE file */
229 struct hdStruct *hp;
230 {
231 float gmap[256];
232 COLOR *scanline;
233 unsigned char *tarData;
234 register int i, j;
235 /* set up gamma correction */
236 for (i = 0; i < 256; i++)
237 gmap[i] = pow((i+.5)/256., gamma);
238 /* skip color table */
239 if (hp->mapType == CM_HASMAP)
240 fseek(stdin, (long)hp->mapLength*hp->CMapBits/8, 1);
241 /* allocate targa data */
242 tarData = taralloc(hp);
243 /* get data */
244 readtarga(hp, tarData, stdin);
245 /* allocate input scanline */
246 scanline = (COLOR *)emalloc(hp->x*sizeof(COLOR));
247 /* convert file */
248 for (i = hp->y-1; i >= 0; i--) {
249 if (hp->dataBits == 16) {
250 register unsigned short *dp;
251 dp = (unsigned short *)tarData + i*hp->x;
252 for (j = 0; j < hp->x; j++) {
253 setcolor(scanline[j], gmap[*dp>>7 & 0xf8],
254 gmap[*dp>>2 & 0xf8],
255 gmap[*dp<<3 & 0xf8]);
256 dp++;
257 }
258 } else { /* hp->dataBits == 24 */
259 register unsigned char *dp;
260 dp = (unsigned char *)tarData + i*3*hp->x;
261 for (j = 0; j < hp->x; j++) {
262 setcolor(scanline[j], gmap[dp[2]],
263 gmap[dp[1]],
264 gmap[dp[0]]);
265 dp += 3;
266 }
267 }
268 if (fwritescan(scanline, hp->x, stdout) < 0)
269 quiterr("error writing RADIANCE file");
270 }
271 free((char *)scanline);
272 free((char *)tarData);
273 }
274
275
276 ra2tg(hp) /* convert radiance to targa file */
277 struct hdStruct *hp;
278 {
279 unsigned char gmap[1024];
280 register int i, j, c;
281 unsigned char *tarData;
282 COLOR *inline;
283 /* set up gamma correction */
284 for (i = 0; i < 1024; i++)
285 gmap[i] = 256.*pow((i+.5)/1024., 1./gamma);
286 /* allocate space for data */
287 inline = (COLOR *)emalloc(hp->x*sizeof(COLOR));
288 tarData = taralloc(hp);
289 /* convert file */
290 for (j = hp->y-1; j >= 0; j--) {
291 if (freadscan(inline, hp->x, stdin) < 0)
292 quiterr("error reading RADIANCE file");
293 if (hp->dataBits == 16) {
294 register unsigned short *dp;
295 dp = (unsigned short *)tarData + j*hp->x;
296 for (i = 0; i < hp->x; i++) {
297 c = 1024.*colval(inline[i],RED);
298 if (c > 1023) c = 1023;
299 *dp = (gmap[c] & 0xf8)<<7;
300 c = 1024.*colval(inline[i],GRN);
301 if (c > 1023) c = 1023;
302 *dp |= (gmap[c] & 0xf8)<<2;
303 c = 1024.*colval(inline[i],BLU);
304 if (c > 1023) c = 1023;
305 *dp++ |= gmap[c]>>3;
306 }
307 } else { /* hp->dataBits == 24 */
308 register unsigned char *dp;
309 dp = (unsigned char *)tarData + j*3*hp->x;
310 for (i = 0; i < hp->x; i++) {
311 c = 1024.*colval(inline[i],BLU);
312 if (c > 1023) c = 1023;
313 *dp++ = gmap[c];
314 c = 1024.*colval(inline[i],GRN);
315 if (c > 1023) c = 1023;
316 *dp++ = gmap[c];
317 c = 1024.*colval(inline[i],RED);
318 if (c > 1023) c = 1023;
319 *dp++ = gmap[c];
320 }
321 }
322 }
323 /* write out targa data */
324 writetarga(hp, tarData, stdout);
325
326 free((char *)inline);
327 free((char *)tarData);
328 }
329
330
331 writet24(h, d, fp) /* write out 24-bit targa data */
332 struct hdStruct *h;
333 unsigned char *d;
334 FILE *fp;
335 {
336 if (h->dataType == IM_RGB) { /* uncompressed */
337 if (fwrite(d, 3*h->x, h->y, fp) != h->y)
338 quiterr("error writing targa file");
339 return;
340 }
341 quiterr("unsupported output type");
342 }
343
344
345 writet16(h, d, fp) /* write out 16-bit targa data */
346 struct hdStruct *h;
347 register unsigned short *d;
348 FILE *fp;
349 {
350 register int cnt;
351
352 if (h->dataType == IM_RGB) { /* uncompressed */
353 for (cnt = h->x*h->y; cnt-- > 0; )
354 putint2(*d++, fp);
355 if (ferror(fp))
356 quiterr("error writing targa file");
357 return;
358 }
359 quiterr("unsupported output type");
360 }
361
362
363 readt24(h, data, fp) /* read in 24-bit targa data */
364 register struct hdStruct *h;
365 unsigned char *data;
366 FILE *fp;
367 {
368 register int cnt, c;
369 register unsigned char *dp;
370 int r, g, b;
371
372 if (h->dataType == IM_RGB) { /* uncompressed */
373 if (fread(data, 3*h->x, h->y, fp) != h->y)
374 goto readerr;
375 return;
376 }
377 for (dp = data; dp < data+3*h->x*h->y; ) {
378 if ((c = getc(fp)) == EOF)
379 goto readerr;
380 cnt = (c & 0x7f) + 1;
381 if (c & 0x80) { /* repeated pixel */
382 b = getc(fp); g = getc(fp);
383 if ((r = getc(fp)) == EOF)
384 goto readerr;
385 while (cnt--) {
386 *dp++ = b;
387 *dp++ = g;
388 *dp++ = r;
389 }
390 } else /* non-repeating pixels */
391 while (cnt--) {
392 *dp++ = getc(fp); *dp++ = getc(fp);
393 if ((r = getc(fp)) == EOF)
394 goto readerr;
395 *dp++ = r;
396 }
397 }
398 return;
399 readerr:
400 quiterr("error reading targa file");
401 }
402
403
404 readt16(h, data, fp) /* read in 16-bit targa data */
405 register struct hdStruct *h;
406 unsigned short *data;
407 FILE *fp;
408 {
409 register int cnt, c;
410 register unsigned short *dp;
411
412 if (h->dataType == IM_RGB) { /* uncompressed */
413 dp = data;
414 for (cnt = h->x*h->y; cnt-- > 0; )
415 *dp++ = getint2(fp);
416 return;
417 }
418 for (dp = data; dp < data+h->x*h->y; ) {
419 if ((c = getc(fp)) == EOF)
420 goto readerr;
421 cnt = (c & 0x7f) + 1;
422 if (c & 0x80) { /* repeated pixel */
423 c = getint2(fp);
424 while (cnt--)
425 *dp++ = c;
426 } else /* non-repeating pixels */
427 while (cnt--)
428 *dp++ = getint2(fp);
429 }
430 return;
431 readerr:
432 quiterr("error reading targa file");
433 }