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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id$";
3 #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 #include <math.h>
14
15 #include <time.h>
16
17 #include "rasterfile.h"
18
19 #include "color.h"
20
21 #include "resolu.h"
22
23 #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 double gamcor = 2.2; /* gamma correction */
44
45 int bradj = 0; /* brightness adjustment */
46
47 pic *inpic, *outpic;
48
49 char *progname;
50
51 char errmsg[128];
52
53 COLR *inl;
54
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 gamcor = atof(argv[++i]);
80 break;
81 case 'b':
82 greyscale = !greyscale;
83 break;
84 case 'e':
85 if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
86 goto userr;
87 bradj = atoi(argv[++i]);
88 break;
89 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 if (fread((char *)&head, sizeof(head), 1, stdin) != 1)
114 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 newheader("RADIANCE", stdout);
125 printargs(i, argv, stdout);
126 fputformat(COLRFMT, stdout);
127 putchar('\n');
128 fprtresolu(xmax, ymax, stdout);
129 /* convert file */
130 pr2ra(&head);
131 } else {
132 if (i < argc-2 || (!greyscale && i > argc-1))
133 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 "Usage: %s [-d][-c ncolors][-b][-g gamma][-e +/-stops] input [output]\n",
153 progname);
154 fprintf(stderr, " Or: %s -r [-g gamma][-e +/-stops] [input [output]]\n",
155 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 void
172 eputs(s)
173 char *s;
174 {
175 fputs(s, stderr);
176 }
177
178
179 void
180 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 /* check header */
201 if (checkheader(p->fp, COLRFMT, NULL) < 0 ||
202 fgetresolu(&xmax, &ymax, p->fp) < 0)
203 quiterr("bad picture format");
204 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 inl = (COLR *)emalloc(xmax*sizeof(COLR));
219
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 fwrite((char *)h, sizeof(*h), 1, p->fp);
239 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 if (fread((char *)cmap[i], h->ras_maplength/3, 1, stdin) != 1)
259 quiterr("error reading color table");
260 /* convert table */
261 for (i = 0; i < h->ras_maplength/3; i++)
262 setcolr(ctab[i],
263 pow((cmap[0][i]+.5)/256.,gamcor),
264 pow((cmap[1][i]+.5)/256.,gamcor),
265 pow((cmap[2][i]+.5)/256.,gamcor));
266 if (bradj)
267 shiftcolrs(ctab, 256, bradj);
268 /* 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 free((void *)scanline);
281 }
282
283
284 picreadline3(y, l3) /* read in 3-byte scanline */
285 int y;
286 register rgbpixel *l3;
287 {
288 register int i;
289
290 if (inpic->nexty != y) { /* find scanline */
291 if (inpic->bytes_line == 0) {
292 if (inpic->pos.y[y] == 0) {
293 while (inpic->nexty < y) {
294 if (freadcolrs(inl, xmax, inpic->fp) < 0)
295 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 if (freadcolrs(inl, xmax, inpic->fp) < 0) /* read scanline */
305 quiterr("read error in picreadline3");
306 inpic->nexty = y+1;
307 /* convert scanline */
308 normcolrs(inl, xmax, bradj);
309 for (i = 0; i < xmax; i++) {
310 l3[i].r = inl[i][RED];
311 l3[i].g = inl[i][GRN];
312 l3[i].b = inl[i][BLU];
313 }
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 if (fwrite((char *)l, sizeof(pixel), xmax, outpic->fp) != xmax)
332 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 val = pow((i+0.5)/256.0, 1.0/gamcor) * 256.0;
367 map[0][i] = map[1][i] = map[2][i] = val;
368 }
369 }