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

  1. /* Copyright (c) 1991 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)ra_pr.c 2.4 10/30/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  ra_pr.c - program to convert between RADIANCE and pixrect picture format.
  9.  *
  10.  *    11/10/87
  11.  *    3/1/88        Added Paul Heckbert's color map allocation
  12.  */
  13.  
  14. #include  <stdio.h>
  15.  
  16. #include  <math.h>
  17.  
  18. #include  "rasterfile.h"
  19.  
  20. #include  "color.h"
  21.  
  22. #include  "resolu.h"
  23.  
  24. #include  "pic.h"
  25.  
  26.             /* descriptor for a picture file or frame buffer */
  27. typedef struct {
  28.     char    *name;            /* file name */
  29.     FILE    *fp;            /* file pointer */
  30.     int    nexty;            /* file positioning */
  31.     int    bytes_line;        /* 0 == variable length lines */
  32.     union {
  33.         long    b;            /* initial scanline */
  34.         long    *y;            /* individual scanline */
  35.     } pos;                /* position(s) */
  36. } pic;
  37.  
  38. extern pic    *openinput(), *openoutput();
  39.  
  40. extern char    *ecalloc(), *emalloc();
  41.  
  42. extern long  ftell();
  43.  
  44. double    gamcor = 2.2;            /* gamma correction */
  45.  
  46. int  bradj = 0;                /* brightness adjustment */
  47.  
  48. pic    *inpic, *outpic;
  49.  
  50. char  *progname;
  51.  
  52. char  errmsg[128];
  53.  
  54. COLR    *inl;
  55.  
  56. int  xmax, ymax;
  57.  
  58.  
  59. main(argc, argv)
  60. int  argc;
  61. char  *argv[];
  62. {
  63.     colormap  rasmap;
  64.     struct rasterfile  head;
  65.     int  dither = 1;
  66.     int  reverse = 0;
  67.     int  ncolors = 256;
  68.     int  greyscale = 0;
  69.     int  i;
  70.     
  71.     progname = argv[0];
  72.  
  73.     for (i = 1; i < argc; i++)
  74.         if (argv[i][0] == '-')
  75.             switch (argv[i][1]) {
  76.             case 'd':
  77.                 dither = !dither;
  78.                 break;
  79.             case 'g':
  80.                 gamcor = atof(argv[++i]);
  81.                 break;
  82.             case 'b':
  83.                 greyscale = !greyscale;
  84.                 break;
  85.             case 'e':
  86.                 if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
  87.                     goto userr;
  88.                 bradj = atoi(argv[++i]);
  89.                 break;
  90.             case 'r':
  91.                 reverse = !reverse;
  92.                 break;
  93.             case 'c':
  94.                 ncolors = atoi(argv[++i]);
  95.                 break;
  96.             default:
  97.                 goto userr;
  98.             }
  99.         else
  100.             break;
  101.  
  102.     if (reverse) {
  103.         if (i < argc-2)
  104.             goto userr;
  105.         if (i <= argc-1 && freopen(argv[i], "r", stdin) == NULL) {
  106.             sprintf(errmsg, "can't open input \"%s\"", argv[i]);
  107.             quiterr(errmsg);
  108.         }
  109.         if (i == argc-2 && freopen(argv[i+1], "w", stdout) == NULL) {
  110.             sprintf(errmsg, "can't open output \"%s\"", argv[i+1]);
  111.             quiterr(errmsg);
  112.         }
  113.                     /* get header */
  114.         if (fread((char *)&head, sizeof(head), 1, stdin) != 1)
  115.             quiterr("missing header");
  116.         if (head.ras_magic != RAS_MAGIC)
  117.             quiterr("bad raster format");
  118.         xmax = head.ras_width;
  119.         ymax = head.ras_height;
  120.         if (head.ras_type != RT_STANDARD ||
  121.                 head.ras_maptype != RMT_EQUAL_RGB ||
  122.                 head.ras_depth != 8)
  123.             quiterr("incompatible format");
  124.                     /* put header */
  125.         printargs(i, argv, stdout);
  126.         fputformat(COLRFMT, stdout);
  127.         putchar('\n');
  128.         fprtresolu(xmax, ymax, stdout);
  129.                     /* convert file */
  130.         pr2ra(&head);
  131.     } else {
  132.         if (i < argc-2 || (!greyscale && i > argc-1))
  133.             goto userr;
  134.         if ((inpic = openinput(argv[i], &head)) == NULL) {
  135.             sprintf(errmsg, "can't open input \"%s\"", argv[i]);
  136.             quiterr(errmsg);
  137.         }
  138.         if ((outpic = openoutput(i==argc-2 ? argv[i+1] : (char *)NULL,
  139.                 &head)) == NULL) {
  140.             sprintf(errmsg, "can't open output \"%s\"", argv[i+1]);
  141.             quiterr(errmsg);
  142.         }
  143.                     /* convert file */
  144.         if (greyscale)
  145.             biq(dither,ncolors,1,rasmap);
  146.         else
  147.             ciq(dither,ncolors,1,rasmap);
  148.     }
  149.     quiterr(NULL);
  150. userr:
  151.     fprintf(stderr,
  152.     "Usage: %s [-d][-c ncolors][-b][-g gamma][-e +/-stops] input [output]\n",
  153.             progname);
  154.     fprintf(stderr, "   Or: %s -r [-g gamma][-e +/-stops] [input [output]]\n",
  155.             progname);
  156.     exit(1);
  157. }
  158.  
  159.  
  160. quiterr(err)        /* print message and exit */
  161. char  *err;
  162. {
  163.     if (err != NULL) {
  164.         fprintf(stderr, "%s: %s\n", progname, err);
  165.         exit(1);
  166.     }
  167.     exit(0);
  168. }
  169.  
  170.  
  171. eputs(s)
  172. char *s;
  173. {
  174.     fputs(s, stderr);
  175. }
  176.  
  177.  
  178. quit(code)
  179. int code;
  180. {
  181.     exit(code);
  182. }
  183.  
  184.  
  185. pic *
  186. openinput(fname, h)        /* open RADIANCE input file */
  187. char  *fname;
  188. register struct rasterfile  *h;
  189. {
  190.     register pic  *p;
  191.  
  192.     p = (pic *)emalloc(sizeof(pic));
  193.     p->name = fname;
  194.     if (fname == NULL)
  195.         p->fp = stdin;
  196.     else if ((p->fp = fopen(fname, "r")) == NULL)
  197.         return(NULL);
  198.                     /* check header */
  199.     if (checkheader(p->fp, COLRFMT, NULL) < 0 ||
  200.             fgetresolu(&xmax, &ymax, p->fp) < 0)
  201.         quiterr("bad picture format");
  202.     p->nexty = 0;
  203.     p->bytes_line = 0;        /* variable length lines */
  204.     p->pos.y = (long *)ecalloc(ymax, sizeof(long));
  205.     p->pos.y[0] = ftell(p->fp);
  206.                     /* assign header */
  207.     h->ras_magic = RAS_MAGIC;
  208.     h->ras_width = xmax + (xmax&1);    /* round to 16 bits */
  209.     h->ras_height = ymax;
  210.     h->ras_depth = 8;
  211.     h->ras_type = RT_STANDARD;
  212.     h->ras_length = h->ras_width*h->ras_height;
  213.     h->ras_maptype = RMT_EQUAL_RGB;
  214.     h->ras_maplength = 256*3;
  215.                     /* allocate scanline */
  216.     inl = (COLR *)emalloc(xmax*sizeof(COLR));
  217.  
  218.     return(p);
  219. }
  220.  
  221.  
  222. pic *
  223. openoutput(fname, h)        /* open output rasterfile */
  224. char  *fname;
  225. register struct rasterfile  *h;
  226. {
  227.     register pic  *p;
  228.  
  229.     p = (pic *)emalloc(sizeof(pic));
  230.     p->name = fname;
  231.     if (fname == NULL)
  232.         p->fp = stdout;
  233.     else if ((p->fp = fopen(fname, "w")) == NULL)
  234.         return(NULL);
  235.                     /* write header */
  236.     fwrite((char *)h, sizeof(*h), 1, p->fp);
  237.     p->nexty = -1;            /* needs color map */
  238.     p->bytes_line = h->ras_width;
  239.     p->pos.b = 0;
  240.  
  241.     return(p);
  242. }
  243.  
  244.  
  245. pr2ra(h)            /* pixrect file to RADIANCE file */
  246. struct rasterfile  *h;
  247. {
  248.     BYTE  cmap[3][256];
  249.     COLR  ctab[256];
  250.     COLR  *scanline;
  251.     register int  i, j, c;
  252.  
  253.     scanline = (COLR *)emalloc(xmax*sizeof(COLR));
  254.                     /* get color table */
  255.     for (i = 0; i < 3; i ++)
  256.         if (fread((char *)cmap[i], h->ras_maplength/3, 1, stdin) != 1)
  257.             quiterr("error reading color table");
  258.                     /* convert table */
  259.     for (i = 0; i < h->ras_maplength/3; i++)
  260.         setcolr(ctab[i],
  261.                 pow((cmap[0][i]+.5)/256.,gamcor),
  262.                 pow((cmap[1][i]+.5)/256.,gamcor),
  263.                 pow((cmap[2][i]+.5)/256.,gamcor));
  264.     if (bradj)
  265.         shiftcolrs(ctab, 256, bradj);
  266.                     /* convert file */
  267.     for (i = 0; i < ymax; i++) {
  268.         for (j = 0; j < xmax; j++) {
  269.             if ((c = getc(stdin)) == EOF)
  270.                 quiterr("error reading rasterfile");
  271.             copycolr(scanline[j], ctab[c]);
  272.         }
  273.         if (xmax & 1)        /* extra byte */
  274.             getc(stdin);
  275.         if (fwritecolrs(scanline, xmax, stdout) < 0)
  276.             quiterr("error writing RADIANCE file");
  277.     }
  278.     free((char *)scanline);
  279. }
  280.  
  281.  
  282. picreadline3(y, l3)            /* read in 3-byte scanline */
  283. int  y;
  284. register rgbpixel  *l3;
  285. {
  286.     register int    i;
  287.  
  288.     if (inpic->nexty != y) {            /* find scanline */
  289.         if (inpic->bytes_line == 0) {
  290.             if (inpic->pos.y[y] == 0) {
  291.                 while (inpic->nexty < y) {
  292.                     if (freadcolrs(inl, xmax, inpic->fp) < 0)
  293.                         quiterr("read error in picreadline3");
  294.                     inpic->pos.y[++inpic->nexty] = ftell(inpic->fp);
  295.                 }
  296.             } else if (fseek(inpic->fp, inpic->pos.y[y], 0) == EOF)
  297.                 quiterr("seek error in picreadline3");
  298.         } else if (fseek(inpic->fp, y*inpic->bytes_line+inpic->pos.b, 0) == EOF)
  299.             quiterr("seek error in picreadline3");
  300.     } else if (inpic->bytes_line == 0 && inpic->pos.y[inpic->nexty] == 0)
  301.         inpic->pos.y[inpic->nexty] = ftell(inpic->fp);
  302.     if (freadcolrs(inl, xmax, inpic->fp) < 0)    /* read scanline */
  303.         quiterr("read error in picreadline3");
  304.     inpic->nexty = y+1;
  305.                             /* convert scanline */
  306.     normcolrs(inl, xmax, bradj);
  307.     for (i = 0; i < xmax; i++) {
  308.         l3[i].r = inl[i][RED];
  309.         l3[i].g = inl[i][GRN];
  310.         l3[i].b = inl[i][BLU];
  311.     }
  312. }
  313.  
  314.  
  315. picwriteline(y, l)            /* write out scanline */
  316. int  y;
  317. register pixel  *l;
  318. {
  319.     if (outpic->nexty != y) {            /* seek to scanline */
  320.         if (outpic->bytes_line == 0) {
  321.             if (outpic->pos.y[y] == 0)
  322.                 quiterr("cannot seek in picwriteline");
  323.             else if (fseek(outpic->fp, outpic->pos.y[y], 0) == EOF)
  324.                 quiterr("seek error in picwriteline");
  325.         } else if (fseek(outpic->fp, y*outpic->bytes_line+outpic->pos.b, 0) == EOF)
  326.             quiterr("seek error in picwriteline");
  327.     }
  328.                         /* write scanline */
  329.     if (fwrite((char *)l, sizeof(pixel), xmax, outpic->fp) != xmax)
  330.         quiterr("write error in picwriteline");
  331.     if (xmax&1)                /* on 16-bit boundary */
  332.         putc(l[xmax-1], outpic->fp);
  333.     outpic->nexty = y+1;
  334.     if (outpic->bytes_line == 0 && outpic->pos.y[outpic->nexty] == 0)
  335.         outpic->pos.y[outpic->nexty] = ftell(outpic->fp);
  336. }
  337.  
  338.  
  339. picwritecm(cm)            /* write out color map */
  340. colormap  cm;
  341. {
  342.     register int  i, j;
  343.  
  344.     if (outpic->nexty != -1 &&
  345.             fseek(outpic->fp, (long)sizeof(struct rasterfile), 0) == EOF)
  346.         quiterr("seek error in picwritecm");
  347.     for (i = 0; i < 3; i++)
  348.         for (j = 0; j < 256; j++)
  349.             putc(cm[i][j], outpic->fp);
  350.     outpic->nexty = 0;
  351.     if (outpic->bytes_line == 0)
  352.         outpic->pos.y[0] = ftell(outpic->fp);
  353.     else
  354.         outpic->pos.b = ftell(outpic->fp);
  355. }
  356.  
  357.  
  358. picreadcm(map)            /* do gamma correction if requested */
  359. colormap  map;
  360. {
  361.     register int  i, val;
  362.  
  363.     for (i = 0; i < 256; i++) {
  364.         val = pow((i+0.5)/256.0, 1.0/gamcor) * 256.0;
  365.         map[0][i] = map[1][i] = map[2][i] = val;
  366.     }
  367. }
  368.