ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t16.c
Revision: 2.5
Committed: Sun Feb 27 10:17:20 1994 UTC (30 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +1 -0 lines
Log Message:
Added new ID to first line of header and changed use of formatval

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