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 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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: ra_pr.c,v 2.6 2003/02/22 02:07:28 greg Exp $";
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 #include <math.h>
13 #include <time.h>
14
15 #include "rtmisc.h"
16 #include "rasterfile.h"
17 #include "color.h"
18 #include "resolu.h"
19 #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 double gamcor = 2.2; /* gamma correction */
35 int bradj = 0; /* brightness adjustment */
36 pic *inpic, *outpic;
37 char *progname;
38 char errmsg[128];
39 COLR *inl;
40 int xmax, ymax;
41
42 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
47
48 int
49 main(int argc, char *argv[])
50 {
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 gamcor = atof(argv[++i]);
69 break;
70 case 'b':
71 greyscale = !greyscale;
72 break;
73 case 'e':
74 if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
75 goto userr;
76 bradj = atoi(argv[++i]);
77 break;
78 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 if (fread((char *)&head, sizeof(head), 1, stdin) != 1)
103 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 newheader("RADIANCE", stdout);
114 printargs(i, argv, stdout);
115 fputformat(COLRFMT, stdout);
116 putchar('\n');
117 fprtresolu(xmax, ymax, stdout);
118 /* convert file */
119 pr2ra(&head);
120 } else {
121 if (i < argc-2 || (!greyscale && i > argc-1))
122 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 "Usage: %s [-d][-c ncolors][-b][-g gamma][-e +/-stops] input [output]\n",
142 progname);
143 fprintf(stderr, " Or: %s -r [-g gamma][-e +/-stops] [input [output]]\n",
144 progname);
145 exit(1);
146 }
147
148
149 static void
150 quiterr( /* print message and exit */
151 char *err
152 )
153 {
154 if (err != NULL) {
155 fprintf(stderr, "%s: %s\n", progname, err);
156 exit(1);
157 }
158 exit(0);
159 }
160
161
162 void
163 eputs(s)
164 char *s;
165 {
166 fputs(s, stderr);
167 }
168
169
170 void
171 quit(code)
172 int code;
173 {
174 exit(code);
175 }
176
177
178 static pic *
179 openinput( /* open RADIANCE input file */
180 char *fname,
181 register struct rasterfile *h
182 )
183 {
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 /* check header */
193 if (checkheader(p->fp, COLRFMT, NULL) < 0 ||
194 fgetresolu(&xmax, &ymax, p->fp) < 0)
195 quiterr("bad picture format");
196 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 inl = (COLR *)emalloc(xmax*sizeof(COLR));
211
212 return(p);
213 }
214
215
216 static pic *
217 openoutput( /* open output rasterfile */
218 char *fname,
219 register struct rasterfile *h
220 )
221 {
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 fwrite((char *)h, sizeof(*h), 1, p->fp);
232 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 static void
241 pr2ra( /* pixrect file to RADIANCE file */
242 struct rasterfile *h
243 )
244 {
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 if (fread((char *)cmap[i], h->ras_maplength/3, 1, stdin) != 1)
254 quiterr("error reading color table");
255 /* convert table */
256 for (i = 0; i < h->ras_maplength/3; i++)
257 setcolr(ctab[i],
258 pow((cmap[0][i]+.5)/256.,gamcor),
259 pow((cmap[1][i]+.5)/256.,gamcor),
260 pow((cmap[2][i]+.5)/256.,gamcor));
261 if (bradj)
262 shiftcolrs(ctab, 256, bradj);
263 /* 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 free((void *)scanline);
276 }
277
278
279 extern void
280 picreadline3( /* read in 3-byte scanline */
281 int y,
282 register rgbpixel *l3
283 )
284 {
285 register int i;
286
287 if (inpic->nexty != y) { /* find scanline */
288 if (inpic->bytes_line == 0) {
289 if (inpic->pos.y[y] == 0) {
290 while (inpic->nexty < y) {
291 if (freadcolrs(inl, xmax, inpic->fp) < 0)
292 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 if (freadcolrs(inl, xmax, inpic->fp) < 0) /* read scanline */
302 quiterr("read error in picreadline3");
303 inpic->nexty = y+1;
304 /* convert scanline */
305 normcolrs(inl, xmax, bradj);
306 for (i = 0; i < xmax; i++) {
307 l3[i].r = inl[i][RED];
308 l3[i].g = inl[i][GRN];
309 l3[i].b = inl[i][BLU];
310 }
311 }
312
313
314 extern void
315 picwriteline( /* write out scanline */
316 int y,
317 register pixel *l
318 )
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 extern void
341 picwritecm( /* write out color map */
342 colormap cm
343 )
344 {
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 extern void
362 picreadcm( /* do gamma correction if requested */
363 colormap map
364 )
365 {
366 register int i, val;
367
368 for (i = 0; i < 256; i++) {
369 val = pow((i+0.5)/256.0, 1.0/gamcor) * 256.0;
370 map[0][i] = map[1][i] = map[2][i] = val;
371 }
372 }