ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/ra_ppm.c
(Generate patch)

Comparing ray/src/px/ra_ppm.c (file contents):
Revision 1.1 by greg, Fri Aug 16 12:41:59 1991 UTC vs.
Revision 2.14 by greg, Mon May 26 17:58:33 2008 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines