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

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.9 static const char RCSid[] = "$Id$";
3 greg 1.1 #endif
4     /*
5     * program to convert between RADIANCE and Poskanzer Pixmaps
6     */
7    
8     #include <stdio.h>
9    
10 greg 2.3 #ifdef MSDOS
11     #include <fcntl.h>
12     #endif
13    
14 greg 2.4 #include <math.h>
15    
16 greg 1.1 #include <ctype.h>
17    
18 greg 2.9 #include <time.h>
19    
20 greg 1.1 #include "color.h"
21    
22 greg 1.2 #include "resolu.h"
23    
24 greg 1.1
25     int agryscan(), bgryscan(), aclrscan(), bclrscan();
26 gwlarson 2.8 int agryscan2(), bgryscan2(), aclrscan2(), bclrscan2();
27     int normval();
28     unsigned int scanint(), intv(), getby2();
29 greg 1.1
30 gwlarson 2.8 #define fltv(i) (((i)+.5)/(maxval+1.))
31    
32 greg 1.1 int bradj = 0; /* brightness adjustment */
33    
34 gwlarson 2.8 double gamcor = 2.2; /* gamma correction value */
35    
36 greg 1.1 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 greg 2.3 char inpbuf[2];
48 gwlarson 2.8 int gryflag = 0;
49 greg 1.1 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 gwlarson 2.8 case 's':
60     maxval = atoi(argv[++i]) & 0xffff;
61     break;
62     case 'b':
63     gryflag = 1;
64     break;
65 greg 1.1 case 'g':
66 greg 2.5 gamcor = atof(argv[++i]);
67 greg 1.1 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 greg 2.6 fprintf(stderr, "%s: can't open output \"%s\"\n",
94 greg 1.1 progname, argv[i+1]);
95     exit(1);
96     }
97 gwlarson 2.8 if (maxval < 256)
98     setcolrgam(gamcor);
99 greg 1.1 if (reverse) {
100     /* get header */
101 greg 2.3 if (read(fileno(stdin), inpbuf, 2) != 2 || inpbuf[0] != 'P')
102 greg 1.1 quiterr("input not a Poskanzer Pixmap");
103 greg 2.3 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 greg 1.1 xmax = scanint(stdin);
110     ymax = scanint(stdin);
111     maxval = scanint(stdin);
112     /* put header */
113 greg 2.7 newheader("RADIANCE", stdout);
114 greg 1.1 printargs(i, argv, stdout);
115     fputformat(COLRFMT, stdout);
116     putchar('\n');
117 greg 1.2 fprtresolu(xmax, ymax, stdout);
118 greg 1.1 /* convert file */
119 gwlarson 2.8 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 greg 1.1 } else {
154 greg 2.3 #ifdef MSDOS
155     setmode(fileno(stdin), O_BINARY);
156     if (binflag)
157     setmode(fileno(stdout), O_BINARY);
158     #endif
159 greg 1.1 /* get header info. */
160     if (checkheader(stdin, COLRFMT, NULL) < 0 ||
161 greg 1.2 fgetresolu(&xmax, &ymax, stdin) < 0)
162 greg 1.1 quiterr("bad picture format");
163     /* write PPM header */
164 gwlarson 2.8 printf("P%1d\n%d %d\n%u\n", (gryflag?2:3)+(binflag?3:0),
165 greg 1.1 xmax, ymax, maxval);
166     /* convert file */
167 gwlarson 2.8 if (maxval >= 256)
168     ra2ppm2(binflag, gryflag);
169     else
170     ra2ppm(binflag, gryflag);
171 greg 1.1 }
172     exit(0);
173     userr:
174     fprintf(stderr,
175 gwlarson 2.8 "Usage: %s [-r][-a][-b][-s maxv][-g gamma][-e +/-stops] [input [output]]\n",
176 greg 1.1 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 gwlarson 2.8 ppm2ra(getscan) /* convert 1-byte Pixmap to Radiance picture */
193 greg 1.1 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 greg 2.9 free((void *)scanout);
213 greg 1.1 }
214    
215    
216 gwlarson 2.8 ra2ppm(binary, grey) /* convert Radiance picture to Pixmap */
217     int binary, grey;
218 greg 1.1 {
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 gwlarson 2.8 quiterr("out of memory in ra2ppm");
226 greg 1.1 /* 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 gwlarson 2.8 for (x = grey?xmax:0; x--; )
233     scanin[x][GRN] = normbright(scanin[x]);
234 greg 1.1 colrs_gambs(scanin, xmax);
235 gwlarson 2.8 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 greg 2.9 free((void *)scanin);
259 gwlarson 2.8 }
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 greg 2.9 free((void *)scanout);
294 gwlarson 2.8 }
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 greg 1.1 }
327 gwlarson 2.8 }
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 greg 1.1 else
338 gwlarson 2.8 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 greg 1.1 if (ferror(stdout))
354     quiterr("error writing Pixmap");
355     }
356     /* free scanline */
357 greg 2.9 free((void *)scanin);
358 greg 1.1 }
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 gwlarson 2.8 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 greg 1.1 scanint(fp) /* scan the next positive integer value */
511     register FILE *fp;
512     {
513 gwlarson 2.8 register int c;
514     register unsigned int i;
515 greg 1.1 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 gwlarson 2.8 register unsigned int v;
540 greg 1.1 {
541     if (v >= maxval)
542     return(255);
543     if (maxval == 255)
544     return(v);
545     return(v*255L/maxval);
546 gwlarson 2.8 }
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 greg 1.1 }