ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_pr.c
Revision: 2.5
Committed: Sun Feb 27 10:17:12 1994 UTC (30 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +1 -0 lines
Log Message:
Added new ID to first line of header and changed use of formatval

File Contents

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