ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_ppm.c
Revision: 2.8
Committed: Wed Feb 10 08:43:41 1999 UTC (25 years, 2 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 2.7: +291 -37 lines
Log Message:
added -s and -b options for greyscale and high-precision output

File Contents

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