ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t16.c
Revision: 1.3
Committed: Sun Jul 23 11:35:48 1989 UTC (34 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.2: +16 -21 lines
Log Message:
Added dithering to 16-bit conversion

File Contents

# User Rev Content
1 greg 1.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 greg 1.2 setcolor(scanline[j], gmap[dp[2]],
263 greg 1.1 gmap[dp[1]],
264 greg 1.2 gmap[dp[0]]);
265 greg 1.1 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 greg 1.3 #define map(v) (v >= 1.0 ? 1023 : (int)(v*1023.+.5))
280 greg 1.1 unsigned char gmap[1024];
281 greg 1.3 register int i, j;
282 greg 1.1 unsigned char *tarData;
283     COLOR *inline;
284     /* set up gamma correction */
285 greg 1.3 for (i = 0; i < 1024; i++) {
286     j = 256.*pow((i+.5)/1024., 1./gamma);
287     gmap[i] = hp->dataBits == 16 && j > 248 ? 248 : j;
288     }
289 greg 1.1 /* allocate space for data */
290     inline = (COLOR *)emalloc(hp->x*sizeof(COLOR));
291     tarData = taralloc(hp);
292     /* convert file */
293     for (j = hp->y-1; j >= 0; j--) {
294     if (freadscan(inline, hp->x, stdin) < 0)
295     quiterr("error reading RADIANCE file");
296     if (hp->dataBits == 16) {
297     register unsigned short *dp;
298     dp = (unsigned short *)tarData + j*hp->x;
299     for (i = 0; i < hp->x; i++) {
300 greg 1.3 *dp = ((gmap[map(colval(inline[i],RED))]
301     +(random()&7)) & 0xf8)<<7;
302     *dp |= ((gmap[map(colval(inline[i],GRN))]
303     +(random()&7)) & 0xf8)<<2;
304     *dp++ |= (gmap[map(colval(inline[i],BLU))]
305     +(random()&7))>>3;
306 greg 1.1 }
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 greg 1.3 *dp++ = gmap[map(colval(inline[i],BLU))];
312     *dp++ = gmap[map(colval(inline[i],GRN))];
313     *dp++ = gmap[map(colval(inline[i],RED))];
314 greg 1.1 }
315     }
316     }
317     /* write out targa data */
318     writetarga(hp, tarData, stdout);
319    
320     free((char *)inline);
321     free((char *)tarData);
322 greg 1.3 #undef map
323 greg 1.1 }
324    
325    
326     writet24(h, d, fp) /* write out 24-bit targa data */
327     struct hdStruct *h;
328     unsigned char *d;
329     FILE *fp;
330     {
331     if (h->dataType == IM_RGB) { /* uncompressed */
332     if (fwrite(d, 3*h->x, h->y, fp) != h->y)
333     quiterr("error writing targa file");
334     return;
335     }
336     quiterr("unsupported output type");
337     }
338    
339    
340     writet16(h, d, fp) /* write out 16-bit targa data */
341     struct hdStruct *h;
342     register unsigned short *d;
343     FILE *fp;
344     {
345     register int cnt;
346    
347     if (h->dataType == IM_RGB) { /* uncompressed */
348     for (cnt = h->x*h->y; cnt-- > 0; )
349     putint2(*d++, fp);
350     if (ferror(fp))
351     quiterr("error writing targa file");
352     return;
353     }
354     quiterr("unsupported output type");
355     }
356    
357    
358     readt24(h, data, fp) /* read in 24-bit targa data */
359     register struct hdStruct *h;
360     unsigned char *data;
361     FILE *fp;
362     {
363     register int cnt, c;
364     register unsigned char *dp;
365     int r, g, b;
366    
367     if (h->dataType == IM_RGB) { /* uncompressed */
368     if (fread(data, 3*h->x, h->y, fp) != h->y)
369     goto readerr;
370     return;
371     }
372     for (dp = data; dp < data+3*h->x*h->y; ) {
373     if ((c = getc(fp)) == EOF)
374     goto readerr;
375     cnt = (c & 0x7f) + 1;
376     if (c & 0x80) { /* repeated pixel */
377 greg 1.2 b = getc(fp); g = getc(fp);
378     if ((r = getc(fp)) == EOF)
379 greg 1.1 goto readerr;
380     while (cnt--) {
381 greg 1.2 *dp++ = b;
382     *dp++ = g;
383 greg 1.1 *dp++ = r;
384     }
385     } else /* non-repeating pixels */
386     while (cnt--) {
387     *dp++ = getc(fp); *dp++ = getc(fp);
388 greg 1.2 if ((r = getc(fp)) == EOF)
389 greg 1.1 goto readerr;
390 greg 1.2 *dp++ = r;
391 greg 1.1 }
392     }
393     return;
394     readerr:
395     quiterr("error reading targa file");
396     }
397    
398    
399     readt16(h, data, fp) /* read in 16-bit targa data */
400     register struct hdStruct *h;
401     unsigned short *data;
402     FILE *fp;
403     {
404     register int cnt, c;
405     register unsigned short *dp;
406    
407     if (h->dataType == IM_RGB) { /* uncompressed */
408     dp = data;
409     for (cnt = h->x*h->y; cnt-- > 0; )
410     *dp++ = getint2(fp);
411     return;
412     }
413     for (dp = data; dp < data+h->x*h->y; ) {
414     if ((c = getc(fp)) == EOF)
415     goto readerr;
416     cnt = (c & 0x7f) + 1;
417     if (c & 0x80) { /* repeated pixel */
418     c = getint2(fp);
419     while (cnt--)
420     *dp++ = c;
421     } else /* non-repeating pixels */
422     while (cnt--)
423     *dp++ = getint2(fp);
424     }
425     return;
426     readerr:
427     quiterr("error reading targa file");
428     }