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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines