ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_pr.c
Revision: 1.2
Committed: Fri Sep 1 12:07:48 1989 UTC (34 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.1: +1 -1 lines
Log Message:
made rasterfile.h local

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_pr.c - program to convert between RADIANCE and pixrect picture format.
9     *
10     * 11/10/87
11     * 3/1/88 Added Paul Heckbert's color map allocation
12     */
13    
14     #include <stdio.h>
15    
16 greg 1.2 #include "rasterfile.h"
17 greg 1.1
18     #include "color.h"
19    
20     #include "pic.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     extern pic *openinput(), *openoutput();
35    
36     extern char *ecalloc(), *emalloc();
37    
38     extern long ftell();
39    
40     extern double atof(), pow();
41    
42     double gamma = 2.0; /* gamma correction */
43    
44     pic *inpic, *outpic;
45    
46     char *progname;
47    
48     char errmsg[128];
49    
50     COLR *inline;
51    
52     int xmax, ymax;
53    
54    
55     main(argc, argv)
56     int argc;
57     char *argv[];
58     {
59     colormap rasmap;
60     struct rasterfile head;
61     int dither = 1;
62     int reverse = 0;
63     int ncolors = 256;
64     int greyscale = 0;
65     int i;
66    
67     progname = argv[0];
68    
69     for (i = 1; i < argc; i++)
70     if (argv[i][0] == '-')
71     switch (argv[i][1]) {
72     case 'd':
73     dither = !dither;
74     break;
75     case 'g':
76     gamma = atof(argv[++i]);
77     break;
78     case 'b':
79     greyscale = !greyscale;
80     break;
81     case 'r':
82     reverse = !reverse;
83     break;
84     case 'c':
85     ncolors = atoi(argv[++i]);
86     break;
87     default:
88     goto userr;
89     }
90     else
91     break;
92    
93     if (reverse) {
94     if (i < argc-2)
95     goto userr;
96     if (i <= argc-1 && freopen(argv[i], "r", stdin) == NULL) {
97     sprintf(errmsg, "can't open input \"%s\"", argv[i]);
98     quiterr(errmsg);
99     }
100     if (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) {
101     sprintf(errmsg, "can't open output \"%s\"", argv[i+1]);
102     quiterr(errmsg);
103     }
104     /* get header */
105     if (fread(&head, sizeof(head), 1, stdin) != 1)
106     quiterr("missing header");
107     if (head.ras_magic != RAS_MAGIC)
108     quiterr("bad raster format");
109     xmax = head.ras_width;
110     ymax = head.ras_height;
111     if (head.ras_type != RT_STANDARD ||
112     head.ras_maptype != RMT_EQUAL_RGB ||
113     head.ras_depth != 8)
114     quiterr("incompatible format");
115     /* put header */
116     printargs(argc, argv, stdout);
117     putchar('\n');
118     printf("-Y %d +X %d\n", ymax, xmax);
119     /* convert file */
120     pr2ra(&head);
121     } else {
122     if (i > argc-1 || i < argc-2)
123     goto userr;
124     if ((inpic = openinput(argv[i], &head)) == NULL) {
125     sprintf(errmsg, "can't open input \"%s\"", argv[i]);
126     quiterr(errmsg);
127     }
128     if ((outpic = openoutput(i==argc-2 ? argv[i+1] : (char *)NULL,
129     &head)) == NULL) {
130     sprintf(errmsg, "can't open output \"%s\"", argv[i+1]);
131     quiterr(errmsg);
132     }
133     /* convert file */
134     if (greyscale)
135     biq(dither,ncolors,1,rasmap);
136     else
137     ciq(dither,ncolors,1,rasmap);
138     }
139     quiterr(NULL);
140     userr:
141     fprintf(stderr,
142     "Usage: %s [-d][-c ncolors][-b][-g gamma] input [output]\n",
143     progname);
144     fprintf(stderr, " Or: %s -r [-g gamma] [input [output]]\n",
145     progname);
146     exit(1);
147     }
148    
149    
150     quiterr(err) /* print message and exit */
151     char *err;
152     {
153     if (err != NULL) {
154     fprintf(stderr, "%s: %s\n", progname, err);
155     exit(1);
156     }
157     exit(0);
158     }
159    
160    
161     eputs(s)
162     char *s;
163     {
164     fputs(s, stderr);
165     }
166    
167    
168     quit(code)
169     int code;
170     {
171     exit(code);
172     }
173    
174    
175     pic *
176     openinput(fname, h) /* open RADIANCE input file */
177     char *fname;
178     register struct rasterfile *h;
179     {
180     register pic *p;
181    
182     p = (pic *)emalloc(sizeof(pic));
183     p->name = fname;
184     if (fname == NULL)
185     p->fp = stdin;
186     else if ((p->fp = fopen(fname, "r")) == NULL)
187     return(NULL);
188     /* discard header */
189     getheader(p->fp, NULL);
190     if (fscanf(p->fp, "-Y %d +X %d\n", &ymax, &xmax) != 2)
191     quiterr("bad picture size");
192     p->nexty = 0;
193     p->bytes_line = 0; /* variable length lines */
194     p->pos.y = (long *)ecalloc(ymax, sizeof(long));
195     p->pos.y[0] = ftell(p->fp);
196     /* assign header */
197     h->ras_magic = RAS_MAGIC;
198     h->ras_width = xmax + (xmax&1); /* round to 16 bits */
199     h->ras_height = ymax;
200     h->ras_depth = 8;
201     h->ras_type = RT_STANDARD;
202     h->ras_length = h->ras_width*h->ras_height;
203     h->ras_maptype = RMT_EQUAL_RGB;
204     h->ras_maplength = 256*3;
205     /* allocate scanline */
206     inline = (COLR *)emalloc(xmax*sizeof(COLR));
207    
208     return(p);
209     }
210    
211    
212     pic *
213     openoutput(fname, h) /* open output rasterfile */
214     char *fname;
215     register struct rasterfile *h;
216     {
217     register pic *p;
218    
219     p = (pic *)emalloc(sizeof(pic));
220     p->name = fname;
221     if (fname == NULL)
222     p->fp = stdout;
223     else if ((p->fp = fopen(fname, "w")) == NULL)
224     return(NULL);
225     /* write header */
226     fwrite(h, sizeof(*h), 1, p->fp);
227     p->nexty = -1; /* needs color map */
228     p->bytes_line = h->ras_width;
229     p->pos.b = 0;
230    
231     return(p);
232     }
233    
234    
235     pr2ra(h) /* pixrect file to RADIANCE file */
236     struct rasterfile *h;
237     {
238     BYTE cmap[3][256];
239     COLR ctab[256];
240     COLR *scanline;
241     register int i, j, c;
242    
243     scanline = (COLR *)emalloc(xmax*sizeof(COLR));
244     /* get color table */
245     for (i = 0; i < 3; i ++)
246     if (fread(cmap[i], h->ras_maplength/3, 1, stdin) != 1)
247     quiterr("error reading color table");
248     /* convert table */
249     for (i = 0; i < h->ras_maplength/3; i++)
250     setcolr(ctab[i],
251     pow((cmap[0][i]+.5)/256.,gamma),
252     pow((cmap[1][i]+.5)/256.,gamma),
253     pow((cmap[2][i]+.5)/256.,gamma));
254     /* convert file */
255     for (i = 0; i < ymax; i++) {
256     for (j = 0; j < xmax; j++) {
257     if ((c = getc(stdin)) == EOF)
258     quiterr("error reading rasterfile");
259     copycolr(scanline[j], ctab[c]);
260     }
261     if (xmax & 1) /* extra byte */
262     getc(stdin);
263     if (fwritecolrs(scanline, xmax, stdout) < 0)
264     quiterr("error writing RADIANCE file");
265     }
266     free((char *)scanline);
267     }
268    
269    
270     picreadline3(y, l3) /* read in 3-byte scanline */
271     int y;
272     register rgbpixel *l3;
273     {
274     register BYTE *l4;
275     register int shift, c;
276     int i;
277    
278     if (inpic->nexty != y) { /* find scanline */
279     if (inpic->bytes_line == 0) {
280     if (inpic->pos.y[y] == 0) {
281     while (inpic->nexty < y) {
282     if (freadcolrs(inline, xmax, inpic->fp) < 0)
283     quiterr("read error in picreadline3");
284     inpic->pos.y[++inpic->nexty] = ftell(inpic->fp);
285     }
286     } else if (fseek(inpic->fp, inpic->pos.y[y], 0) == EOF)
287     quiterr("seek error in picreadline3");
288     } else if (fseek(inpic->fp, y*inpic->bytes_line+inpic->pos.b, 0) == EOF)
289     quiterr("seek error in picreadline3");
290     } else if (inpic->bytes_line == 0 && inpic->pos.y[inpic->nexty] == 0)
291     inpic->pos.y[inpic->nexty] = ftell(inpic->fp);
292     if (freadcolrs(inline, xmax, inpic->fp) < 0) /* read scanline */
293     quiterr("read error in picreadline3");
294     inpic->nexty = y+1;
295     /* convert scanline */
296     for (l4=inline[0], i=xmax; i--; l4+=4, l3++) {
297     shift = l4[EXP] - COLXS;
298     if (shift >= 8) {
299     l3->r = l3->g = l3->b = 255;
300     } else if (shift <= -8) {
301     l3->r = l3->g = l3->b = 0;
302     } else if (shift > 0) {
303     c = l4[RED] << shift;
304     l3->r = c > 255 ? 255 : c;
305     c = l4[GRN] << shift;
306     l3->g = c > 255 ? 255 : c;
307     c = l4[BLU] << shift;
308     l3->b = c > 255 ? 255 : c;
309     } else if (shift < 0) {
310     l3->r = l4[RED] >> -shift;
311     l3->g = l4[GRN] >> -shift;
312     l3->b = l4[BLU] >> -shift;
313     } else {
314     l3->r = l4[RED];
315     l3->g = l4[GRN];
316     l3->b = l4[BLU];
317     }
318     }
319     }
320    
321    
322     picwriteline(y, l) /* write out scanline */
323     int y;
324     register pixel *l;
325     {
326     if (outpic->nexty != y) { /* seek to scanline */
327     if (outpic->bytes_line == 0) {
328     if (outpic->pos.y[y] == 0)
329     quiterr("cannot seek in picwriteline");
330     else if (fseek(outpic->fp, outpic->pos.y[y], 0) == EOF)
331     quiterr("seek error in picwriteline");
332     } else if (fseek(outpic->fp, y*outpic->bytes_line+outpic->pos.b, 0) == EOF)
333     quiterr("seek error in picwriteline");
334     }
335     /* write scanline */
336     if (fwrite(l, sizeof(pixel), xmax, outpic->fp) != xmax)
337     quiterr("write error in picwriteline");
338     if (xmax&1) /* on 16-bit boundary */
339     putc(l[xmax-1], outpic->fp);
340     outpic->nexty = y+1;
341     if (outpic->bytes_line == 0 && outpic->pos.y[outpic->nexty] == 0)
342     outpic->pos.y[outpic->nexty] = ftell(outpic->fp);
343     }
344    
345    
346     picwritecm(cm) /* write out color map */
347     colormap cm;
348     {
349     register int i, j;
350    
351     if (outpic->nexty != -1 &&
352     fseek(outpic->fp, (long)sizeof(struct rasterfile), 0) == EOF)
353     quiterr("seek error in picwritecm");
354     for (i = 0; i < 3; i++)
355     for (j = 0; j < 256; j++)
356     putc(cm[i][j], outpic->fp);
357     outpic->nexty = 0;
358     if (outpic->bytes_line == 0)
359     outpic->pos.y[0] = ftell(outpic->fp);
360     else
361     outpic->pos.b = ftell(outpic->fp);
362     }
363    
364    
365     picreadcm(map) /* do gamma correction if requested */
366     colormap map;
367     {
368     register int i, val;
369    
370     for (i = 0; i < 256; i++) {
371     val = pow(i/256.0, 1.0/gamma) * 256.0;
372     map[0][i] = map[1][i] = map[2][i] = val;
373     }
374     }