ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_pr.c
Revision: 1.1
Committed: Thu Feb 2 10:49:35 1989 UTC (35 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

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