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.4 by greg, Fri Oct 2 16:25:15 1992 UTC vs.
Revision 2.17 by greg, Sat Dec 28 18:05:14 2019 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines