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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines