ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_pr.c
Revision: 1.11
Committed: Wed Aug 7 08:36:31 1991 UTC (32 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.10: +14 -5 lines
Log Message:
added -e +/-stops option

File Contents

# Content
1 /* Copyright (c) 1991 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 #include "rasterfile.h"
17
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 int bradj = 0; /* brightness adjustment */
45
46 pic *inpic, *outpic;
47
48 char *progname;
49
50 char errmsg[128];
51
52 COLR *inl;
53
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 case 'e':
84 if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
85 goto userr;
86 bradj = atoi(argv[++i]);
87 break;
88 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 if (fread((char *)&head, sizeof(head), 1, stdin) != 1)
113 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 printargs(i, argv, stdout);
124 fputformat(COLRFMT, stdout);
125 putchar('\n');
126 fputresolu(YMAJOR|YDECR, xmax, ymax, stdout);
127 /* convert file */
128 pr2ra(&head);
129 } else {
130 if (i < argc-2 || (!greyscale && i > argc-1))
131 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 "Usage: %s [-d][-c ncolors][-b][-g gamma][-e +/-stops] input [output]\n",
151 progname);
152 fprintf(stderr, " Or: %s -r [-g gamma][-e +/-stops] [input [output]]\n",
153 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 /* check header */
197 if (checkheader(p->fp, COLRFMT, NULL) < 0 ||
198 fgetresolu(&xmax, &ymax, p->fp) != (YMAJOR|YDECR))
199 quiterr("bad picture format");
200 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 inl = (COLR *)emalloc(xmax*sizeof(COLR));
215
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 fwrite((char *)h, sizeof(*h), 1, p->fp);
235 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 if (fread((char *)cmap[i], h->ras_maplength/3, 1, stdin) != 1)
255 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 if (bradj)
263 shiftcolrs(ctab, 256, bradj);
264 /* 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 register int i;
285
286 if (inpic->nexty != y) { /* find scanline */
287 if (inpic->bytes_line == 0) {
288 if (inpic->pos.y[y] == 0) {
289 while (inpic->nexty < y) {
290 if (freadcolrs(inl, xmax, inpic->fp) < 0)
291 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 if (freadcolrs(inl, xmax, inpic->fp) < 0) /* read scanline */
301 quiterr("read error in picreadline3");
302 inpic->nexty = y+1;
303 /* convert scanline */
304 normcolrs(inl, xmax, bradj);
305 for (i = 0; i < xmax; i++) {
306 l3[i].r = inl[i][RED];
307 l3[i].g = inl[i][GRN];
308 l3[i].b = inl[i][BLU];
309 }
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 if (fwrite((char *)l, sizeof(pixel), xmax, outpic->fp) != xmax)
328 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 val = pow((i+0.5)/256.0, 1.0/gamma) * 256.0;
363 map[0][i] = map[1][i] = map[2][i] = val;
364 }
365 }