ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_t8.c
Revision: 1.1
Committed: Thu Feb 2 10:49:37 1989 UTC (35 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

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_t8.c - program to convert between RADIANCE and
9     * Targa 8-bit color-mapped images.
10     *
11     * 8/22/88 Adapted from ra_pr.c
12     */
13    
14     #include <stdio.h>
15    
16     #include "color.h"
17    
18     #include "pic.h"
19    
20     #include "targa.h"
21    
22     /* descriptor for a picture file or frame buffer */
23     typedef struct {
24     char *name; /* file name */
25     FILE *fp; /* file pointer */
26     int nexty; /* file positioning */
27     int bytes_line; /* 0 == variable length lines */
28     union {
29     long b; /* initial scanline */
30     long *y; /* individual scanline */
31     } pos; /* position(s) */
32     } pic;
33    
34     #define goodpic(h) (my_imType(h) && my_mapType(h))
35     #define my_imType(h) (((h)->dataType==IM_CMAP || (h)->dataType==IM_CCMAP) \
36     && (h)->dataBits==8 && (h)->imType==0)
37     #define my_mapType(h) ((h)->mapType==CM_HASMAP && \
38     ((h)->CMapBits==24 || (h)->CMapBits==32))
39    
40     #define taralloc(h) (pixel *)emalloc((h)->x*(h)->y*sizeof(pixel))
41    
42     extern pic *openinput();
43    
44     extern char *ecalloc(), *emalloc();
45    
46     extern long ftell();
47    
48     extern double atof(), pow();
49    
50     double gamma = 2.0; /* gamma correction */
51    
52     pic *inpic;
53    
54     char *progname;
55    
56     char errmsg[128];
57    
58     COLR *inline;
59    
60     pixel *tarData;
61    
62     int xmax, ymax;
63    
64    
65     main(argc, argv)
66     int argc;
67     char *argv[];
68     {
69     colormap rasmap;
70     struct hdStruct head;
71     int dither = 1;
72     int reverse = 0;
73     int ncolors = 256;
74     int greyscale = 0;
75     int i;
76    
77     progname = argv[0];
78    
79     for (i = 1; i < argc; i++)
80     if (argv[i][0] == '-')
81     switch (argv[i][1]) {
82     case 'd':
83     dither = !dither;
84     break;
85     case 'g':
86     gamma = atof(argv[++i]);
87     break;
88     case 'r':
89     reverse = !reverse;
90     break;
91     case 'b':
92     greyscale = 1;
93     break;
94     case 'c':
95     ncolors = atoi(argv[++i]);
96     break;
97     default:
98     goto userr;
99     }
100     else
101     break;
102    
103     if (reverse) {
104     if (i < argc-2)
105     goto userr;
106     if (i <= argc-1 && freopen(argv[i], "r", stdin) == NULL) {
107     sprintf(errmsg, "can't open input \"%s\"", argv[i]);
108     quiterr(errmsg);
109     }
110     /* get header */
111     if (getthead(&head, NULL, stdin) < 0)
112     quiterr("bad targa file");
113     if (!goodpic(&head))
114     quiterr("incompatible format");
115     xmax = head.x;
116     ymax = head.y;
117     /* open output file */
118     if (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) {
119     sprintf(errmsg, "can't open output \"%s\"", argv[i+1]);
120     quiterr(errmsg);
121     }
122     /* put header */
123     printargs(argc, argv, stdout);
124     putchar('\n');
125     printf("-Y %d +X %d\n", ymax, xmax);
126     /* convert file */
127     tg2ra(&head);
128     } else {
129     if (i > argc-1 || i < argc-2)
130     goto userr;
131     if ((inpic = openinput(argv[i], &head)) == NULL) {
132     sprintf(errmsg, "can't open input \"%s\"", argv[i]);
133     quiterr(errmsg);
134     }
135     if (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) {
136     sprintf(errmsg, "can't open output \"%s\"", argv[i+1]);
137     quiterr(errmsg);
138     }
139     /* write header */
140     putthead(&head, NULL, stdout);
141     /* convert file */
142     if (greyscale)
143     biq(dither,ncolors,1,rasmap);
144     else
145     ciq(dither,ncolors,1,rasmap);
146     /* write data */
147     writetarga(&head, tarData, stdout);
148     }
149     quiterr(NULL);
150     userr:
151     fprintf(stderr,
152     "Usage: %s [-d][-c ncolors][-b][-g gamma] input [output]\n",
153     progname);
154     fprintf(stderr, " Or: %s -r [-g gamma] [input [output]]\n",
155     progname);
156     exit(1);
157     }
158    
159    
160     int
161     getint2(fp) /* get a 2-byte positive integer */
162     register FILE *fp;
163     {
164     register int b1, b2;
165    
166     if ((b1 = getc(fp)) == EOF || (b2 = getc(fp)) == EOF)
167     quiterr("read error");
168    
169     return(b1 | b2<<8);
170     }
171    
172    
173     putint2(i, fp) /* put a 2-byte positive integer */
174     register int i;
175     register FILE *fp;
176     {
177     putc(i&0xff, fp);
178     putc(i>>8&0xff, fp);
179     }
180    
181    
182     quiterr(err) /* print message and exit */
183     char *err;
184     {
185     if (err != NULL) {
186     fprintf(stderr, "%s: %s\n", progname, err);
187     exit(1);
188     }
189     exit(0);
190     }
191    
192    
193     eputs(s)
194     char *s;
195     {
196     fputs(s, stderr);
197     }
198    
199    
200     quit(code)
201     int code;
202     {
203     exit(code);
204     }
205    
206    
207     getthead(hp, ip, fp) /* read header from input */
208     struct hdStruct *hp;
209     char *ip;
210     register FILE *fp;
211     {
212     int nidbytes;
213    
214     if ((nidbytes = getc(fp)) == EOF)
215     return(-1);
216     hp->mapType = getc(fp);
217     hp->dataType = getc(fp);
218     hp->mapOrig = getint2(fp);
219     hp->mapLength = getint2(fp);
220     hp->CMapBits = getc(fp);
221     hp->XOffset = getint2(fp);
222     hp->YOffset = getint2(fp);
223     hp->x = getint2(fp);
224     hp->y = getint2(fp);
225     hp->dataBits = getc(fp);
226     hp->imType = getc(fp);
227    
228     if (ip != NULL)
229     if (nidbytes)
230     fread(ip, nidbytes, 1, fp);
231     else
232     *ip = '\0';
233     else if (nidbytes)
234     fseek(fp, (long)nidbytes, 1);
235    
236     return(feof(fp) || ferror(fp) ? -1 : 0);
237     }
238    
239    
240     putthead(hp, ip, fp) /* write header to output */
241     struct hdStruct *hp;
242     char *ip;
243     register FILE *fp;
244     {
245     if (ip != NULL)
246     putc(strlen(ip), fp);
247     else
248     putc(0, fp);
249     putc(hp->mapType, fp);
250     putc(hp->dataType, fp);
251     putint2(hp->mapOrig, fp);
252     putint2(hp->mapLength, fp);
253     putc(hp->CMapBits, fp);
254     putint2(hp->XOffset, fp);
255     putint2(hp->YOffset, fp);
256     putint2(hp->x, fp);
257     putint2(hp->y, fp);
258     putc(hp->dataBits, fp);
259     putc(hp->imType, fp);
260    
261     if (ip != NULL)
262     fputs(ip, fp);
263    
264     return(ferror(fp) ? -1 : 0);
265     }
266    
267    
268     pic *
269     openinput(fname, h) /* open RADIANCE input file */
270     char *fname;
271     register struct hdStruct *h;
272     {
273     register pic *p;
274    
275     p = (pic *)emalloc(sizeof(pic));
276     p->name = fname;
277     if (fname == NULL)
278     p->fp = stdin;
279     else if ((p->fp = fopen(fname, "r")) == NULL)
280     return(NULL);
281     /* discard header */
282     getheader(p->fp, NULL);
283     if (fscanf(p->fp, "-Y %d +X %d\n", &ymax, &xmax) != 2)
284     quiterr("bad picture size");
285     p->nexty = 0;
286     p->bytes_line = 0; /* variable length lines */
287     p->pos.y = (long *)ecalloc(ymax, sizeof(long));
288     p->pos.y[0] = ftell(p->fp);
289     /* assign header */
290     h->textSize = 0;
291     h->mapType = CM_HASMAP;
292     h->dataType = IM_CMAP;
293     h->mapOrig = 0;
294     h->mapLength = 256;
295     h->CMapBits = 24;
296     h->XOffset = 0;
297     h->YOffset = 0;
298     h->x = xmax;
299     h->y = ymax;
300     h->dataBits = 8;
301     h->imType = 0;
302     /* allocate scanline */
303     inline = (COLR *)emalloc(xmax*sizeof(COLR));
304     /* allocate targa data */
305     tarData = taralloc(h);
306    
307     return(p);
308     }
309    
310    
311     tg2ra(hp) /* targa file to RADIANCE file */
312     struct hdStruct *hp;
313     {
314     union {
315     BYTE c3[256][3];
316     BYTE c4[256][4];
317     } map;
318     COLR ctab[256];
319     COLR *scanline;
320     register int i, j;
321    
322     /* get color table */
323     if ((hp->CMapBits==24 ? fread(map.c3, sizeof(map.c3), 1, stdin) :
324     fread(map.c4, sizeof(map.c4), 1, stdin)) != 1)
325     quiterr("error reading color table");
326     /* convert table */
327     for (i = hp->mapOrig; i < hp->mapOrig+hp->mapLength; i++)
328     if (hp->CMapBits == 24)
329     setcolr(ctab[i],
330     pow((map.c3[i][2]+.5)/256.,gamma),
331     pow((map.c3[i][1]+.5)/256.,gamma),
332     pow((map.c3[i][0]+.5)/256.,gamma));
333     else
334     setcolr(ctab[i],
335     pow((map.c4[i][3]+.5)/256.,gamma),
336     pow((map.c4[i][2]+.5)/256.,gamma),
337     pow((map.c4[i][1]+.5)/256.,gamma));
338    
339     /* allocate targa data */
340     tarData = taralloc(hp);
341     /* get data */
342     readtarga(hp, tarData, stdin);
343     /* allocate input scanline */
344     scanline = (COLR *)emalloc(xmax*sizeof(COLR));
345     /* convert file */
346     for (i = ymax-1; i >= 0; i--) {
347     for (j = 0; j < xmax; j++)
348     copycolr(scanline[j], ctab[tarData[i*xmax+j]]);
349     if (fwritecolrs(scanline, xmax, stdout) < 0)
350     quiterr("error writing RADIANCE file");
351     }
352     free((char *)scanline);
353     free((char *)tarData);
354     }
355    
356    
357     picreadline3(y, l3) /* read in 3-byte scanline */
358     int y;
359     register rgbpixel *l3;
360     {
361     register BYTE *l4;
362     register int shift, c;
363     int i;
364    
365     if (inpic->nexty != y) { /* find scanline */
366     if (inpic->bytes_line == 0) {
367     if (inpic->pos.y[y] == 0) {
368     while (inpic->nexty < y) {
369     if (freadcolrs(inline, xmax, inpic->fp) < 0)
370     quiterr("read error in picreadline3");
371     inpic->pos.y[++inpic->nexty] = ftell(inpic->fp);
372     }
373     } else if (fseek(inpic->fp, inpic->pos.y[y], 0) == EOF)
374     quiterr("seek error in picreadline3");
375     } else if (fseek(inpic->fp, y*inpic->bytes_line+inpic->pos.b, 0) == EOF)
376     quiterr("seek error in picreadline3");
377     } else if (inpic->bytes_line == 0 && inpic->pos.y[inpic->nexty] == 0)
378     inpic->pos.y[inpic->nexty] = ftell(inpic->fp);
379     if (freadcolrs(inline, xmax, inpic->fp) < 0) /* read scanline */
380     quiterr("read error in picreadline3");
381     inpic->nexty = y+1;
382     /* convert scanline */
383     for (l4=inline[0], i=xmax; i--; l4+=4, l3++) {
384     shift = l4[EXP] - COLXS;
385     if (shift >= 8) {
386     l3->r = l3->g = l3->b = 255;
387     } else if (shift <= -8) {
388     l3->r = l3->g = l3->b = 0;
389     } else if (shift > 0) {
390     c = l4[RED] << shift;
391     l3->r = c > 255 ? 255 : c;
392     c = l4[GRN] << shift;
393     l3->g = c > 255 ? 255 : c;
394     c = l4[BLU] << shift;
395     l3->b = c > 255 ? 255 : c;
396     } else if (shift < 0) {
397     l3->r = l4[RED] >> -shift;
398     l3->g = l4[GRN] >> -shift;
399     l3->b = l4[BLU] >> -shift;
400     } else {
401     l3->r = l4[RED];
402     l3->g = l4[GRN];
403     l3->b = l4[BLU];
404     }
405     }
406     }
407    
408    
409     picwriteline(y, l) /* save output scanline */
410     int y;
411     pixel *l;
412     {
413     bcopy(l, &tarData[(ymax-1-y)*xmax], xmax*sizeof(pixel));
414     }
415    
416    
417     writetarga(h, d, fp) /* write out targa data */
418     struct hdStruct *h;
419     pixel *d;
420     FILE *fp;
421     {
422     if (h->dataType == IM_CMAP) { /* uncompressed */
423     if (fwrite(d, h->x*sizeof(pixel), h->y, fp) != h->y)
424     quiterr("error writing targa file");
425     return;
426     }
427     quiterr("unsupported output type");
428     }
429    
430    
431     readtarga(h, data, fp) /* read in targa data */
432     struct hdStruct *h;
433     pixel *data;
434     FILE *fp;
435     {
436     register int cnt, c;
437     register pixel *dp;
438    
439     if (h->dataType == IM_CMAP) { /* uncompressed */
440     if (fread(data, h->x*sizeof(pixel), h->y, fp) != h->y)
441     goto readerr;
442     return;
443     }
444     for (dp = data; dp < data+h->x*h->y; ) {
445     if ((c = getc(fp)) == EOF)
446     goto readerr;
447     cnt = (c & 0x7f) + 1;
448     if (c & 0x80) { /* repeated pixel */
449     if ((c = getc(fp)) == EOF)
450     goto readerr;
451     while (cnt--)
452     *dp++ = c;
453     } else /* non-repeating pixels */
454     while (cnt--) {
455     if ((c = getc(fp)) == EOF)
456     goto readerr;
457     *dp++ = c;
458     }
459     }
460     return;
461     readerr:
462     quiterr("error reading targa file");
463     }
464    
465    
466     picwritecm(cm) /* write out color map */
467     colormap cm;
468     {
469     register int i, j;
470    
471     for (j = 0; j < 256; j++)
472     for (i = 2; i >= 0; i--)
473     putc(cm[i][j], stdout);
474     }
475    
476    
477     picreadcm(map) /* do gamma correction if requested */
478     colormap map;
479     {
480     register int i, val;
481    
482     for (i = 0; i < 256; i++) {
483     val = pow(i/256.0, 1.0/gamma) * 256.0;
484     map[0][i] = map[1][i] = map[2][i] = val;
485     }
486     }