ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t16.c
Revision: 1.7
Committed: Fri Feb 9 13:59:21 1990 UTC (34 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.6: +1 -1 lines
Log Message:
changed arguments printed in header

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