ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t16.c
Revision: 1.13
Committed: Wed Aug 7 08:36:35 1991 UTC (32 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.12: +12 -1 lines
Log Message:
added -e +/-stops option

File Contents

# User Rev Content
1 greg 1.12 /* Copyright (c) 1991 Regents of the University of California */
2 greg 1.1
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 greg 1.5 #include "random.h"
19    
20 greg 1.1 #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 greg 1.13 int bradj = 0; /* brightness adjustment */
40    
41 greg 1.1 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 greg 1.13 case 'e':
73     if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
74     goto userr;
75     bradj = atoi(argv[++i]);
76     break;
77 greg 1.1 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 greg 1.9 /* set gamma */
96     setcolrgam(gamma);
97 greg 1.1 /* 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 greg 1.7 printargs(i, argv, stdout);
106 greg 1.11 fputformat(COLRFMT, stdout);
107 greg 1.1 putchar('\n');
108 greg 1.4 fputresolu(YMAJOR|YDECR, head.x, head.y, stdout);
109 greg 1.1 /* convert file */
110     tg2ra(&head);
111     } else {
112 greg 1.11 if (checkheader(stdin, COLRFMT, NULL) < 0 ||
113     fgetresolu(&head.x, &head.y, stdin) != (YMAJOR|YDECR))
114 greg 1.1 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 greg 1.13 fprintf(stderr, "Usage: %s [-2|-3|-r][-g gamma][-e +/-stops] [input [output]]\n",
130 greg 1.1 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 greg 1.6 fread((char *)ip, nidbytes, 1, fp);
203 greg 1.1 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 greg 1.9 COLR *scanline;
244 greg 1.1 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 greg 1.9 scanline = (COLR *)emalloc(hp->x*sizeof(COLR));
255 greg 1.1 /* 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 greg 1.9 scanline[j][RED] = *dp>>7 & 0xf8;
262     scanline[j][GRN] = *dp>>2 & 0xf8;
263     scanline[j][BLU] = *dp<<3 & 0xf8;
264 greg 1.1 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 greg 1.9 scanline[j][RED] = dp[2];
271     scanline[j][GRN] = dp[1];
272     scanline[j][BLU] = dp[0];
273 greg 1.1 dp += 3;
274     }
275     }
276 greg 1.9 gambs_colrs(scanline, hp->x);
277 greg 1.13 if (bradj)
278     shiftcolrs(scanline, hp->x, bradj);
279 greg 1.9 if (fwritecolrs(scanline, hp->x, stdout) < 0)
280 greg 1.1 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 greg 1.3 register int i, j;
291 greg 1.1 unsigned char *tarData;
292 greg 1.9 COLR *inl;
293 greg 1.1 /* allocate space for data */
294 greg 1.9 inl = (COLR *)emalloc(hp->x*sizeof(COLR));
295 greg 1.1 tarData = taralloc(hp);
296     /* convert file */
297     for (j = hp->y-1; j >= 0; j--) {
298 greg 1.9 if (freadcolrs(inl, hp->x, stdin) < 0)
299 greg 1.1 quiterr("error reading RADIANCE file");
300 greg 1.13 if (bradj)
301     shiftcolrs(inl, hp->x, bradj);
302 greg 1.9 colrs_gambs(inl, hp->x);
303 greg 1.1 if (hp->dataBits == 16) {
304     register unsigned short *dp;
305 greg 1.12 register int v;
306 greg 1.1 dp = (unsigned short *)tarData + j*hp->x;
307     for (i = 0; i < hp->x; i++) {
308 greg 1.12 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 greg 1.1 }
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 greg 1.10 *dp++ = inl[i][BLU];
323     *dp++ = inl[i][GRN];
324 greg 1.9 *dp++ = inl[i][RED];
325 greg 1.1 }
326     }
327     }
328     /* write out targa data */
329     writetarga(hp, tarData, stdout);
330    
331 greg 1.8 free((char *)inl);
332 greg 1.1 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 greg 1.6 if (fwrite((char *)d, 3*h->x, h->y, fp) != h->y)
343 greg 1.1 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 greg 1.6 if (fread((char *)data, 3*h->x, h->y, fp) != h->y)
379 greg 1.1 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 greg 1.2 b = getc(fp); g = getc(fp);
388     if ((r = getc(fp)) == EOF)
389 greg 1.1 goto readerr;
390     while (cnt--) {
391 greg 1.2 *dp++ = b;
392     *dp++ = g;
393 greg 1.1 *dp++ = r;
394     }
395     } else /* non-repeating pixels */
396     while (cnt--) {
397     *dp++ = getc(fp); *dp++ = getc(fp);
398 greg 1.2 if ((r = getc(fp)) == EOF)
399 greg 1.1 goto readerr;
400 greg 1.2 *dp++ = r;
401 greg 1.1 }
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     }