ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_ppm.c
Revision: 2.9
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.8: +7 -10 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 * program to convert between RADIANCE and Poskanzer Pixmaps
6 */
7
8 #include <stdio.h>
9
10 #ifdef MSDOS
11 #include <fcntl.h>
12 #endif
13
14 #include <math.h>
15
16 #include <ctype.h>
17
18 #include <time.h>
19
20 #include "color.h"
21
22 #include "resolu.h"
23
24
25 int agryscan(), bgryscan(), aclrscan(), bclrscan();
26 int agryscan2(), bgryscan2(), aclrscan2(), bclrscan2();
27 int normval();
28 unsigned int scanint(), intv(), getby2();
29
30 #define fltv(i) (((i)+.5)/(maxval+1.))
31
32 int bradj = 0; /* brightness adjustment */
33
34 double gamcor = 2.2; /* gamma correction value */
35
36 int maxval = 255; /* maximum primary value */
37
38 char *progname;
39
40 int xmax, ymax;
41
42
43 main(argc, argv)
44 int argc;
45 char *argv[];
46 {
47 char inpbuf[2];
48 int gryflag = 0;
49 int binflag = 1;
50 int reverse = 0;
51 int ptype;
52 int i;
53
54 progname = argv[0];
55
56 for (i = 1; i < argc; i++)
57 if (argv[i][0] == '-')
58 switch (argv[i][1]) {
59 case 's':
60 maxval = atoi(argv[++i]) & 0xffff;
61 break;
62 case 'b':
63 gryflag = 1;
64 break;
65 case 'g':
66 gamcor = atof(argv[++i]);
67 break;
68 case 'e':
69 if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
70 goto userr;
71 bradj = atoi(argv[++i]);
72 break;
73 case 'a':
74 binflag = 0;
75 break;
76 case 'r':
77 reverse = !reverse;
78 break;
79 default:
80 goto userr;
81 }
82 else
83 break;
84
85 if (i < argc-2)
86 goto userr;
87 if (i <= argc-1 && freopen(argv[i], "r", stdin) == NULL) {
88 fprintf(stderr, "%s: can't open input \"%s\"\n",
89 progname, argv[i]);
90 exit(1);
91 }
92 if (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) {
93 fprintf(stderr, "%s: can't open output \"%s\"\n",
94 progname, argv[i+1]);
95 exit(1);
96 }
97 if (maxval < 256)
98 setcolrgam(gamcor);
99 if (reverse) {
100 /* get header */
101 if (read(fileno(stdin), inpbuf, 2) != 2 || inpbuf[0] != 'P')
102 quiterr("input not a Poskanzer Pixmap");
103 ptype = inpbuf[1];
104 #ifdef MSDOS
105 if (ptype > 4)
106 setmode(fileno(stdin), O_BINARY);
107 setmode(fileno(stdout), O_BINARY);
108 #endif
109 xmax = scanint(stdin);
110 ymax = scanint(stdin);
111 maxval = scanint(stdin);
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 if (maxval >= 256)
120 switch (ptype) {
121 case '2':
122 ppm2ra2(agryscan2);
123 break;
124 case '5':
125 ppm2ra2(bgryscan2);
126 break;
127 case '3':
128 ppm2ra2(aclrscan2);
129 break;
130 case '6':
131 ppm2ra2(bclrscan2);
132 break;
133 default:
134 quiterr("unsupported Pixmap type");
135 }
136 else
137 switch (ptype) {
138 case '2':
139 ppm2ra(agryscan);
140 break;
141 case '5':
142 ppm2ra(bgryscan);
143 break;
144 case '3':
145 ppm2ra(aclrscan);
146 break;
147 case '6':
148 ppm2ra(bclrscan);
149 break;
150 default:
151 quiterr("unsupported Pixmap type");
152 }
153 } else {
154 #ifdef MSDOS
155 setmode(fileno(stdin), O_BINARY);
156 if (binflag)
157 setmode(fileno(stdout), O_BINARY);
158 #endif
159 /* get header info. */
160 if (checkheader(stdin, COLRFMT, NULL) < 0 ||
161 fgetresolu(&xmax, &ymax, stdin) < 0)
162 quiterr("bad picture format");
163 /* write PPM header */
164 printf("P%1d\n%d %d\n%u\n", (gryflag?2:3)+(binflag?3:0),
165 xmax, ymax, maxval);
166 /* convert file */
167 if (maxval >= 256)
168 ra2ppm2(binflag, gryflag);
169 else
170 ra2ppm(binflag, gryflag);
171 }
172 exit(0);
173 userr:
174 fprintf(stderr,
175 "Usage: %s [-r][-a][-b][-s maxv][-g gamma][-e +/-stops] [input [output]]\n",
176 progname);
177 exit(1);
178 }
179
180
181 quiterr(err) /* print message and exit */
182 char *err;
183 {
184 if (err != NULL) {
185 fprintf(stderr, "%s: %s\n", progname, err);
186 exit(1);
187 }
188 exit(0);
189 }
190
191
192 ppm2ra(getscan) /* convert 1-byte Pixmap to Radiance picture */
193 int (*getscan)();
194 {
195 COLR *scanout;
196 int y;
197 /* allocate scanline */
198 scanout = (COLR *)malloc(xmax*sizeof(COLR));
199 if (scanout == NULL)
200 quiterr("out of memory in ppm2ra");
201 /* convert image */
202 for (y = ymax-1; y >= 0; y--) {
203 if ((*getscan)(scanout, xmax, stdin) < 0)
204 quiterr("error reading Pixmap");
205 gambs_colrs(scanout, xmax);
206 if (bradj)
207 shiftcolrs(scanout, xmax, bradj);
208 if (fwritecolrs(scanout, xmax, stdout) < 0)
209 quiterr("error writing Radiance picture");
210 }
211 /* free scanline */
212 free((void *)scanout);
213 }
214
215
216 ra2ppm(binary, grey) /* convert Radiance picture to Pixmap */
217 int binary, grey;
218 {
219 COLR *scanin;
220 register int x;
221 int y;
222 /* allocate scanline */
223 scanin = (COLR *)malloc(xmax*sizeof(COLR));
224 if (scanin == NULL)
225 quiterr("out of memory in ra2ppm");
226 /* convert image */
227 for (y = ymax-1; y >= 0; y--) {
228 if (freadcolrs(scanin, xmax, stdin) < 0)
229 quiterr("error reading Radiance picture");
230 if (bradj)
231 shiftcolrs(scanin, xmax, bradj);
232 for (x = grey?xmax:0; x--; )
233 scanin[x][GRN] = normbright(scanin[x]);
234 colrs_gambs(scanin, xmax);
235 if (grey)
236 if (binary)
237 for (x = 0; x < xmax; x++)
238 putc(scanin[x][GRN], stdout);
239 else
240 for (x = 0; x < xmax; x++)
241 printf("%d\n", scanin[x][GRN]);
242 else
243 if (binary)
244 for (x = 0; x < xmax; x++) {
245 putc(scanin[x][RED], stdout);
246 putc(scanin[x][GRN], stdout);
247 putc(scanin[x][BLU], stdout);
248 }
249 else
250 for (x = 0; x < xmax; x++)
251 printf("%d %d %d\n", scanin[x][RED],
252 scanin[x][GRN],
253 scanin[x][BLU]);
254 if (ferror(stdout))
255 quiterr("error writing Pixmap");
256 }
257 /* free scanline */
258 free((void *)scanin);
259 }
260
261
262 ppm2ra2(getscan) /* convert 2-byte Pixmap to Radiance picture */
263 int (*getscan)();
264 {
265 COLOR *scanout;
266 double mult;
267 int y;
268 register int x;
269 /* allocate scanline */
270 scanout = (COLOR *)malloc(xmax*sizeof(COLOR));
271 if (scanout == NULL)
272 quiterr("out of memory in ppm2ra2");
273 if (bradj)
274 mult = pow(2., (double)bradj);
275 /* convert image */
276 for (y = ymax-1; y >= 0; y--) {
277 if ((*getscan)(scanout, xmax, stdin) < 0)
278 quiterr("error reading Pixmap");
279 for (x = gamcor>1.01|gamcor<0.99?xmax:0; x--; ) {
280 colval(scanout[x],RED) =
281 pow(colval(scanout[x],RED), gamcor);
282 colval(scanout[x],GRN) =
283 pow(colval(scanout[x],GRN), gamcor);
284 colval(scanout[x],BLU) =
285 pow(colval(scanout[x],BLU), gamcor);
286 }
287 for (x = bradj?xmax:0; x--; )
288 scalecolor(scanout[x], mult);
289 if (fwritescan(scanout, xmax, stdout) < 0)
290 quiterr("error writing Radiance picture");
291 }
292 /* free scanline */
293 free((void *)scanout);
294 }
295
296
297 ra2ppm2(binary, grey) /* convert Radiance picture to Pixmap (2-byte) */
298 int binary, grey;
299 {
300 COLOR *scanin;
301 double mult, d;
302 register int x;
303 int y;
304 /* allocate scanline */
305 scanin = (COLOR *)malloc(xmax*sizeof(COLOR));
306 if (scanin == NULL)
307 quiterr("out of memory in ra2ppm2");
308 if (bradj)
309 mult = pow(2., (double)bradj);
310 /* convert image */
311 for (y = ymax-1; y >= 0; y--) {
312 if (freadscan(scanin, xmax, stdin) < 0)
313 quiterr("error reading Radiance picture");
314 for (x = bradj?xmax:0; x--; )
315 scalecolor(scanin[x], mult);
316 for (x = grey?xmax:0; x--; )
317 colval(scanin[x],GRN) = bright(scanin[x]);
318 d = 1./gamcor;
319 for (x = d>1.01|d<0.99?xmax:0; x--; ) {
320 colval(scanin[x],GRN) = pow(colval(scanin[x],GRN), d);
321 if (!grey) {
322 colval(scanin[x],RED) =
323 pow(colval(scanin[x],RED), d);
324 colval(scanin[x],BLU) =
325 pow(colval(scanin[x],BLU), d);
326 }
327 }
328 if (grey)
329 if (binary)
330 for (x = 0; x < xmax; x++)
331 putby2(intv(colval(scanin[x],GRN)),
332 stdout);
333 else
334 for (x = 0; x < xmax; x++)
335 printf("%u\n",
336 intv(colval(scanin[x],GRN)));
337 else
338 if (binary)
339 for (x = 0; x < xmax; x++) {
340 putby2(intv(colval(scanin[x],RED)),
341 stdout);
342 putby2(intv(colval(scanin[x],GRN)),
343 stdout);
344 putby2(intv(colval(scanin[x],BLU)),
345 stdout);
346 }
347 else
348 for (x = 0; x < xmax; x++)
349 printf("%u %u %u\n",
350 intv(colval(scanin[x],RED)),
351 intv(colval(scanin[x],GRN)),
352 intv(colval(scanin[x],BLU)));
353 if (ferror(stdout))
354 quiterr("error writing Pixmap");
355 }
356 /* free scanline */
357 free((void *)scanin);
358 }
359
360
361 agryscan(scan, len, fp) /* get an ASCII greyscale scanline */
362 register COLR *scan;
363 register int len;
364 FILE *fp;
365 {
366 while (len-- > 0) {
367 scan[0][RED] =
368 scan[0][GRN] =
369 scan[0][BLU] = normval(scanint(fp));
370 scan++;
371 }
372 return(0);
373 }
374
375
376 bgryscan(scan, len, fp) /* get a binary greyscale scanline */
377 register COLR *scan;
378 int len;
379 register FILE *fp;
380 {
381 register int c;
382
383 while (len-- > 0) {
384 if ((c = getc(fp)) == EOF)
385 return(-1);
386 if (maxval != 255)
387 c = normval(c);
388 scan[0][RED] =
389 scan[0][GRN] =
390 scan[0][BLU] = c;
391 scan++;
392 }
393 return(0);
394 }
395
396
397 aclrscan(scan, len, fp) /* get an ASCII color scanline */
398 register COLR *scan;
399 register int len;
400 FILE *fp;
401 {
402 while (len-- > 0) {
403 scan[0][RED] = normval(scanint(fp));
404 scan[0][GRN] = normval(scanint(fp));
405 scan[0][BLU] = normval(scanint(fp));
406 scan++;
407 }
408 return(0);
409 }
410
411
412 bclrscan(scan, len, fp) /* get a binary color scanline */
413 register COLR *scan;
414 int len;
415 register FILE *fp;
416 {
417 int r, g, b;
418
419 while (len-- > 0) {
420 r = getc(fp);
421 g = getc(fp);
422 if ((b = getc(fp)) == EOF)
423 return(-1);
424 if (maxval == 255) {
425 scan[0][RED] = r;
426 scan[0][GRN] = g;
427 scan[0][BLU] = b;
428 } else {
429 scan[0][RED] = normval(r);
430 scan[0][GRN] = normval(g);
431 scan[0][BLU] = normval(b);
432 }
433 scan++;
434 }
435 return(0);
436 }
437
438
439 agryscan2(scan, len, fp) /* get an ASCII greyscale scanline */
440 register COLOR *scan;
441 register int len;
442 FILE *fp;
443 {
444 while (len-- > 0) {
445 colval(scan[0],RED) =
446 colval(scan[0],GRN) =
447 colval(scan[0],BLU) = fltv(scanint(fp));
448 scan++;
449 }
450 return(0);
451 }
452
453
454 bgryscan2(scan, len, fp) /* get a binary greyscale scanline */
455 register COLOR *scan;
456 int len;
457 register FILE *fp;
458 {
459 register int c;
460
461 while (len-- > 0) {
462 if ((c = getby2(fp)) == EOF)
463 return(-1);
464 colval(scan[0],RED) =
465 colval(scan[0],GRN) =
466 colval(scan[0],BLU) = fltv(c);
467 scan++;
468 }
469 return(0);
470 }
471
472
473 aclrscan2(scan, len, fp) /* get an ASCII color scanline */
474 register COLOR *scan;
475 register int len;
476 FILE *fp;
477 {
478 while (len-- > 0) {
479 colval(scan[0],RED) = fltv(scanint(fp));
480 colval(scan[0],GRN) = fltv(scanint(fp));
481 colval(scan[0],BLU) = fltv(scanint(fp));
482 scan++;
483 }
484 return(0);
485 }
486
487
488 bclrscan2(scan, len, fp) /* get a binary color scanline */
489 register COLOR *scan;
490 int len;
491 register FILE *fp;
492 {
493 int r, g, b;
494
495 while (len-- > 0) {
496 r = getby2(fp);
497 g = getby2(fp);
498 if ((b = getby2(fp)) == EOF)
499 return(-1);
500 scan[0][RED] = fltv(r);
501 scan[0][GRN] = fltv(g);
502 scan[0][BLU] = fltv(b);
503 scan++;
504 }
505 return(0);
506 }
507
508
509 unsigned int
510 scanint(fp) /* scan the next positive integer value */
511 register FILE *fp;
512 {
513 register int c;
514 register unsigned int i;
515 tryagain:
516 while (isspace(c = getc(fp)))
517 ;
518 if (c == EOF)
519 quiterr("unexpected end of file");
520 if (c == '#') { /* comment */
521 while ((c = getc(fp)) != EOF && c != '\n')
522 ;
523 goto tryagain;
524 }
525 /* should be integer */
526 i = 0;
527 do {
528 if (!isdigit(c))
529 quiterr("error reading integer");
530 i = 10*i + c - '0';
531 c = getc(fp);
532 } while (c != EOF && !isspace(c));
533 return(i);
534 }
535
536
537 int
538 normval(v) /* normalize a value to [0,255] */
539 register unsigned int v;
540 {
541 if (v >= maxval)
542 return(255);
543 if (maxval == 255)
544 return(v);
545 return(v*255L/maxval);
546 }
547
548
549 unsigned int
550 getby2(fp) /* return 2-byte quantity from fp */
551 register FILE *fp;
552 {
553 register int lowerb, upperb;
554
555 lowerb = getc(fp);
556 upperb = getc(fp);
557 if (upperb == EOF)
558 return(EOF);
559 return(upperb<<8 | lowerb);
560 }
561
562
563 putby2(w, fp) /* put 2-byte quantity to fp */
564 register unsigned int w;
565 register FILE *fp;
566 {
567 putc(w & 0xff, fp);
568 putc(w>>8 & 0xff, fp);
569 if (ferror(fp)) {
570 fprintf(stderr, "%s: write error on PPM output\n", progname);
571 exit(1);
572 }
573 }
574
575
576 unsigned int
577 intv(v) /* return integer quantity for v */
578 register double v;
579 {
580 if (v >= 0.99999)
581 return(maxval);
582 if (v <= 0.)
583 return(0);
584 return((int)(v*(maxval+1)));
585 }