ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_pr.c
Revision: 1.12
Committed: Mon Oct 14 17:09:36 1991 UTC (32 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.11: +1 -1 lines
Log Message:
changed default gamma correction to 2.2

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