ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_pr.c
Revision: 2.6
Committed: Sat Feb 22 02:07:28 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.5: +6 -5 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

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