ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_pr.c
Revision: 2.7
Committed: Sun Mar 28 20:33:14 2004 UTC (20 years, 1 month ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R6P1, rad3R6
Changes since 2.6: +45 -42 lines
Log Message:
Continued ANSIfication, and other fixes and clarifications.

File Contents

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