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

# 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 <math.h>
17
18 #include "rasterfile.h"
19
20 #include "color.h"
21
22 #include "resolu.h"
23
24 #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 double gamcor = 2.2; /* gamma correction */
45
46 int bradj = 0; /* brightness adjustment */
47
48 pic *inpic, *outpic;
49
50 char *progname;
51
52 char errmsg[128];
53
54 COLR *inl;
55
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 gamcor = atof(argv[++i]);
81 break;
82 case 'b':
83 greyscale = !greyscale;
84 break;
85 case 'e':
86 if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
87 goto userr;
88 bradj = atoi(argv[++i]);
89 break;
90 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 if (fread((char *)&head, sizeof(head), 1, stdin) != 1)
115 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 newheader("RADIANCE", stdout);
126 printargs(i, argv, stdout);
127 fputformat(COLRFMT, stdout);
128 putchar('\n');
129 fprtresolu(xmax, ymax, stdout);
130 /* convert file */
131 pr2ra(&head);
132 } else {
133 if (i < argc-2 || (!greyscale && i > argc-1))
134 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 "Usage: %s [-d][-c ncolors][-b][-g gamma][-e +/-stops] input [output]\n",
154 progname);
155 fprintf(stderr, " Or: %s -r [-g gamma][-e +/-stops] [input [output]]\n",
156 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 /* check header */
200 if (checkheader(p->fp, COLRFMT, NULL) < 0 ||
201 fgetresolu(&xmax, &ymax, p->fp) < 0)
202 quiterr("bad picture format");
203 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 inl = (COLR *)emalloc(xmax*sizeof(COLR));
218
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 fwrite((char *)h, sizeof(*h), 1, p->fp);
238 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 if (fread((char *)cmap[i], h->ras_maplength/3, 1, stdin) != 1)
258 quiterr("error reading color table");
259 /* convert table */
260 for (i = 0; i < h->ras_maplength/3; i++)
261 setcolr(ctab[i],
262 pow((cmap[0][i]+.5)/256.,gamcor),
263 pow((cmap[1][i]+.5)/256.,gamcor),
264 pow((cmap[2][i]+.5)/256.,gamcor));
265 if (bradj)
266 shiftcolrs(ctab, 256, bradj);
267 /* 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 register int i;
288
289 if (inpic->nexty != y) { /* find scanline */
290 if (inpic->bytes_line == 0) {
291 if (inpic->pos.y[y] == 0) {
292 while (inpic->nexty < y) {
293 if (freadcolrs(inl, xmax, inpic->fp) < 0)
294 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 if (freadcolrs(inl, xmax, inpic->fp) < 0) /* read scanline */
304 quiterr("read error in picreadline3");
305 inpic->nexty = y+1;
306 /* convert scanline */
307 normcolrs(inl, xmax, bradj);
308 for (i = 0; i < xmax; i++) {
309 l3[i].r = inl[i][RED];
310 l3[i].g = inl[i][GRN];
311 l3[i].b = inl[i][BLU];
312 }
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 if (fwrite((char *)l, sizeof(pixel), xmax, outpic->fp) != xmax)
331 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 val = pow((i+0.5)/256.0, 1.0/gamcor) * 256.0;
366 map[0][i] = map[1][i] = map[2][i] = val;
367 }
368 }