home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Raytrace & Morphing / SOS-RAYTRACE.ISO / programm / source / radsrc22 / src / px / ra_ppm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-02  |  6.6 KB  |  335 lines

  1. /* Copyright (c) 1992 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)ra_ppm.c 2.4 10/2/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  program to convert between RADIANCE and Poskanzer Pixmaps
  9.  */
  10.  
  11. #include  <stdio.h>
  12.  
  13. #ifdef MSDOS
  14. #include  <fcntl.h>
  15. #endif
  16.  
  17. #include  <math.h>
  18.  
  19. #include  <ctype.h>
  20.  
  21. #include  "color.h"
  22.  
  23. #include  "resolu.h"
  24.  
  25.  
  26. extern char  *malloc();
  27.  
  28. int  agryscan(), bgryscan(), aclrscan(), bclrscan();
  29.  
  30. int  bradj = 0;                /* brightness adjustment */
  31.  
  32. int  maxval = 255;            /* maximum primary value */
  33.  
  34. char  *progname;
  35.  
  36. int  xmax, ymax;
  37.  
  38.  
  39. main(argc, argv)
  40. int  argc;
  41. char  *argv[];
  42. {
  43.     char  inpbuf[2];
  44.     double    gamma = 2.2;
  45.     int  binflag = 1;
  46.     int  reverse = 0;
  47.     int  ptype;
  48.     int  i;
  49.     
  50.     progname = argv[0];
  51.  
  52.     for (i = 1; i < argc; i++)
  53.         if (argv[i][0] == '-')
  54.             switch (argv[i][1]) {
  55.             case 'g':
  56.                 gamma = atof(argv[++i]);
  57.                 break;
  58.             case 'e':
  59.                 if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
  60.                     goto userr;
  61.                 bradj = atoi(argv[++i]);
  62.                 break;
  63.             case 'a':
  64.                 binflag = 0;
  65.                 break;
  66.             case 'r':
  67.                 reverse = !reverse;
  68.                 break;
  69.             default:
  70.                 goto userr;
  71.             }
  72.         else
  73.             break;
  74.  
  75.     if (i < argc-2)
  76.         goto userr;
  77.     if (i <= argc-1 && freopen(argv[i], "r", stdin) == NULL) {
  78.         fprintf(stderr, "%s: can't open input \"%s\"\n",
  79.                 progname, argv[i]);
  80.         exit(1);
  81.     }
  82.     if (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) {
  83.         fprintf(stderr, "can't open output \"%s\"\n",
  84.                 progname, argv[i+1]);
  85.         exit(1);
  86.     }
  87.     setcolrgam(gamma);
  88.     if (reverse) {
  89.                     /* get header */
  90.         if (read(fileno(stdin), inpbuf, 2) != 2 || inpbuf[0] != 'P')
  91.             quiterr("input not a Poskanzer Pixmap");
  92.         ptype = inpbuf[1];
  93. #ifdef MSDOS
  94.         if (ptype > 4)
  95.             setmode(fileno(stdin), O_BINARY);
  96.         setmode(fileno(stdout), O_BINARY);
  97. #endif
  98.         xmax = scanint(stdin);
  99.         ymax = scanint(stdin);
  100.         maxval = scanint(stdin);
  101.                     /* put header */
  102.         printargs(i, argv, stdout);
  103.         fputformat(COLRFMT, stdout);
  104.         putchar('\n');
  105.         fprtresolu(xmax, ymax, stdout);
  106.                     /* convert file */
  107.         switch (ptype) {
  108.         case '2':
  109.             ppm2ra(agryscan);
  110.             break;
  111.         case '5':
  112.             ppm2ra(bgryscan);
  113.             break;
  114.         case '3':
  115.             ppm2ra(aclrscan);
  116.             break;
  117.         case '6':
  118.             ppm2ra(bclrscan);
  119.             break;
  120.         default:
  121.             quiterr("unsupported Pixmap type");
  122.         }
  123.     } else {
  124. #ifdef MSDOS
  125.         setmode(fileno(stdin), O_BINARY);
  126.         if (binflag)
  127.             setmode(fileno(stdout), O_BINARY);
  128. #endif
  129.                     /* get header info. */
  130.         if (checkheader(stdin, COLRFMT, NULL) < 0 ||
  131.                 fgetresolu(&xmax, &ymax, stdin) < 0)
  132.             quiterr("bad picture format");
  133.                     /* write PPM header */
  134.         printf("P%c\n%d %d\n%d\n", binflag ? '6' : '3',
  135.                 xmax, ymax, maxval);
  136.                     /* convert file */
  137.         ra2ppm(binflag);
  138.     }
  139.     exit(0);
  140. userr:
  141.     fprintf(stderr,
  142.         "Usage: %s [-r][-a][-g gamma][-e +/-stops] [input [output]]\n",
  143.             progname);
  144.     exit(1);
  145. }
  146.  
  147.  
  148. quiterr(err)        /* print message and exit */
  149. char  *err;
  150. {
  151.     if (err != NULL) {
  152.         fprintf(stderr, "%s: %s\n", progname, err);
  153.         exit(1);
  154.     }
  155.     exit(0);
  156. }
  157.  
  158.  
  159. ppm2ra(getscan)        /* convert color Pixmap to Radiance picture */
  160. int  (*getscan)();
  161. {
  162.     COLR    *scanout;
  163.     register int    x;
  164.     int    y;
  165.                         /* allocate scanline */
  166.     scanout = (COLR *)malloc(xmax*sizeof(COLR));
  167.     if (scanout == NULL)
  168.         quiterr("out of memory in ppm2ra");
  169.                         /* convert image */
  170.     for (y = ymax-1; y >= 0; y--) {
  171.         if ((*getscan)(scanout, xmax, stdin) < 0)
  172.             quiterr("error reading Pixmap");
  173.         gambs_colrs(scanout, xmax);
  174.         if (bradj)
  175.             shiftcolrs(scanout, xmax, bradj);
  176.         if (fwritecolrs(scanout, xmax, stdout) < 0)
  177.             quiterr("error writing Radiance picture");
  178.     }
  179.                         /* free scanline */
  180.     free((char *)scanout);
  181. }
  182.  
  183.  
  184. ra2ppm(binary)        /* convert Radiance picture to Pixmap */
  185. int  binary;
  186. {
  187.     COLR    *scanin;
  188.     register int    x;
  189.     int    y;
  190.                         /* allocate scanline */
  191.     scanin = (COLR *)malloc(xmax*sizeof(COLR));
  192.     if (scanin == NULL)
  193.         quiterr("out of memory in ra2pr");
  194.                         /* convert image */
  195.     for (y = ymax-1; y >= 0; y--) {
  196.         if (freadcolrs(scanin, xmax, stdin) < 0)
  197.             quiterr("error reading Radiance picture");
  198.         if (bradj)
  199.             shiftcolrs(scanin, xmax, bradj);
  200.         colrs_gambs(scanin, xmax);
  201.         if (binary)
  202.             for (x = 0; x < xmax; x++) {
  203.                 putc(scanin[x][RED], stdout);
  204.                 putc(scanin[x][GRN], stdout);
  205.                 putc(scanin[x][BLU], stdout);
  206.             }
  207.         else
  208.             for (x = 0; x < xmax; x++)
  209.                 printf("%d %d %d\n", scanin[x][RED],
  210.                         scanin[x][GRN],
  211.                         scanin[x][BLU]);
  212.         if (ferror(stdout))
  213.             quiterr("error writing Pixmap");
  214.     }
  215.                         /* free scanline */
  216.     free((char *)scanin);
  217. }
  218.  
  219.  
  220. agryscan(scan, len, fp)            /* get an ASCII greyscale scanline */
  221. register COLR  *scan;
  222. register int  len;
  223. FILE  *fp;
  224. {
  225.     while (len-- > 0) {
  226.         scan[0][RED] =
  227.         scan[0][GRN] =
  228.         scan[0][BLU] = normval(scanint(fp));
  229.         scan++;
  230.     }
  231.     return(0);
  232. }
  233.  
  234.  
  235. bgryscan(scan, len, fp)            /* get a binary greyscale scanline */
  236. register COLR  *scan;
  237. int  len;
  238. register FILE  *fp;
  239. {
  240.     register int  c;
  241.  
  242.     while (len-- > 0) {
  243.         if ((c = getc(fp)) == EOF)
  244.             return(-1);
  245.         if (maxval != 255)
  246.             c = normval(c);
  247.         scan[0][RED] =
  248.         scan[0][GRN] =
  249.         scan[0][BLU] = c;
  250.         scan++;
  251.     }
  252.     return(0);
  253. }
  254.  
  255.  
  256. aclrscan(scan, len, fp)            /* get an ASCII color scanline */
  257. register COLR  *scan;
  258. register int  len;
  259. FILE  *fp;
  260. {
  261.     while (len-- > 0) {
  262.         scan[0][RED] = normval(scanint(fp));
  263.         scan[0][GRN] = normval(scanint(fp));
  264.         scan[0][BLU] = normval(scanint(fp));
  265.         scan++;
  266.     }
  267.     return(0);
  268. }
  269.  
  270.  
  271. bclrscan(scan, len, fp)            /* get a binary color scanline */
  272. register COLR  *scan;
  273. int  len;
  274. register FILE  *fp;
  275. {
  276.     int  r, g, b;
  277.  
  278.     while (len-- > 0) {
  279.         r = getc(fp);
  280.         g = getc(fp);
  281.         if ((b = getc(fp)) == EOF)
  282.             return(-1);
  283.         if (maxval == 255) {
  284.             scan[0][RED] = r;
  285.             scan[0][GRN] = g;
  286.             scan[0][BLU] = b;
  287.         } else {
  288.             scan[0][RED] = normval(r);
  289.             scan[0][GRN] = normval(g);
  290.             scan[0][BLU] = normval(b);
  291.         }
  292.         scan++;
  293.     }
  294.     return(0);
  295. }
  296.  
  297.  
  298. int
  299. scanint(fp)            /* scan the next positive integer value */
  300. register FILE  *fp;
  301. {
  302.     register int  i, c;
  303. tryagain:
  304.     while (isspace(c = getc(fp)))
  305.         ;
  306.     if (c == EOF)
  307.         quiterr("unexpected end of file");
  308.     if (c == '#') {        /* comment */
  309.         while ((c = getc(fp)) != EOF && c != '\n')
  310.             ;
  311.         goto tryagain;
  312.     }
  313.                 /* should be integer */
  314.     i = 0;
  315.     do {
  316.         if (!isdigit(c))
  317.             quiterr("error reading integer");
  318.         i = 10*i + c - '0';
  319.         c = getc(fp);
  320.     } while (c != EOF && !isspace(c));
  321.     return(i);
  322. }
  323.  
  324.  
  325. int
  326. normval(v)            /* normalize a value to [0,255] */
  327. register int  v;
  328. {
  329.     if (v >= maxval)
  330.         return(255);
  331.     if (maxval == 255)
  332.         return(v);
  333.     return(v*255L/maxval);
  334. }
  335.