ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t16.c
Revision: 1.14
Committed: Fri Aug 23 13:40:04 1991 UTC (32 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.13: +1 -1 lines
Log Message:
changed default gamma to 2.2, the NTSC standard value

File Contents

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