ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_ppm.c
Revision: 2.10
Committed: Thu Jun 5 19:29:34 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.9: +8 -15 lines
Log Message:
Macros for setting binary file mode. Replacing MSDOS by _WIN32.

File Contents

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