ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t16.c
Revision: 1.12
Committed: Fri May 17 08:41:52 1991 UTC (32 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.11: +11 -4 lines
Log Message:
fixed bug in 16-bit ra2tg() code

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