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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines