home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / RADIANCE / SRC / PX / PCOMPOS.C < prev    next >
C/C++ Source or Header  |  1993-10-07  |  9KB  |  394 lines

  1. /* Copyright (c) 1992 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)pcompos.c 2.14 9/8/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  pcompos.c - program to composite pictures.
  9.  *
  10.  *     6/30/87
  11.  */
  12.  
  13. #include  <stdio.h>
  14.  
  15. #ifdef MSDOS
  16. #include  <fcntl.h>
  17. #endif
  18.  
  19. #include  "color.h"
  20.  
  21. #include  "resolu.h"
  22.  
  23. #define  MAXFILE        64
  24.  
  25.                     /* output picture size */
  26. int  xsiz = 0;
  27. int  ysiz = 0;
  28.                     /* input dimensions */
  29. int  xmin = 0;
  30. int  ymin = 0;
  31. int  xmax = 0;
  32. int  ymax = 0;
  33.  
  34. COLR  bgcolr = BLKCOLR;                 /* background color */
  35.  
  36. int  labelht = 24;                      /* label height */
  37.  
  38. int  checkthresh = 0;                   /* check threshold value */
  39.  
  40. char  Command[] = "<Command>";
  41. char  Label[] = "<Label>";
  42.  
  43. char  *progname;
  44.  
  45. struct {
  46.     char  *name;                    /* file or command name */
  47.     FILE  *fp;                      /* stream pointer */
  48.     int  xres, yres;                /* picture size */
  49.     int  xloc, yloc;                /* anchor point */
  50.     int  hasmin, hasmax;            /* has threshold values */
  51.     COLR  thmin, thmax;             /* thresholds */
  52. } input[MAXFILE];               /* our input files */
  53.  
  54. int  nfile;                     /* number of files */
  55.  
  56. int  wrongformat = 0;
  57.  
  58. FILE  *popen(), *lblopen();
  59.  
  60. extern char  *malloc();
  61.  
  62.  
  63. tabputs(s)                      /* print line preceded by a tab */
  64. char  *s;
  65. {
  66.     char  fmt[32];
  67.  
  68.     if (isformat(s)) {
  69.         formatval(fmt, s);
  70.         wrongformat = strcmp(fmt, COLRFMT);
  71.     } else {
  72.         putc('\t', stdout);
  73.         fputs(s, stdout);
  74.     }
  75. }
  76.  
  77.  
  78. main(argc, argv)
  79. int  argc;
  80. char  *argv[];
  81. {
  82.     int  ncolumns = 0;
  83.     int  autolabel = 0;
  84.     int  curcol = 0, x0 = 0, curx = 0, cury = 0, spacing = 0;
  85.     char  *thislabel;
  86.     int  an;
  87. #ifdef MSDOS
  88.     extern int  _fmode;
  89.     _fmode = O_BINARY;
  90.     setmode(fileno(stdin), O_BINARY);
  91.     setmode(fileno(stdout), O_BINARY);
  92. #endif
  93.     progname = argv[0];
  94.  
  95.     for (an = 1; an < argc && argv[an][0] == '-'; an++)
  96.         switch (argv[an][1]) {
  97.         case 'x':
  98.             xsiz = atoi(argv[++an]);
  99.             break;
  100.         case 'y':
  101.             ysiz = atoi(argv[++an]);
  102.             break;
  103.         case 'b':
  104.             setcolr(bgcolr, atof(argv[an+1]),
  105.                     atof(argv[an+2]),
  106.                     atof(argv[an+3]));
  107.             an += 3;
  108.             break;
  109.         case 'a':
  110.             ncolumns = atoi(argv[++an]);
  111.             break;
  112.         case 's':
  113.             spacing = atoi(argv[++an]);
  114.             break;
  115.         case 'o':
  116.             curx = x0 = atoi(argv[++an]);
  117.             cury = atoi(argv[++an]);
  118.             break;
  119.         case 'l':
  120.             switch (argv[an][2]) {
  121.             case 'a':
  122.                 autolabel++;
  123.                 break;
  124.             case 'h':
  125.                 labelht = atoi(argv[++an]);
  126.                 break;
  127.             case '\0':
  128.                 goto dofiles;
  129.             default:
  130.                 goto userr;
  131.             }
  132.             break;
  133.         case '\0':
  134.         case 't':
  135.             goto dofiles;
  136.         default:
  137.             goto userr;
  138.         }
  139. dofiles:
  140.     for (nfile = 0; an < argc; nfile++) {
  141.         if (nfile >= MAXFILE)
  142.             goto toomany;
  143.         thislabel = NULL;
  144.         input[nfile].hasmin = input[nfile].hasmax = 0;
  145.         while (an < argc && (argv[an][0] == '-' || argv[an][0] == '+'))
  146.             switch (argv[an][1]) {
  147.             case 't':
  148.                 checkthresh = 1;
  149.                 if (argv[an][0] == '-') {
  150.                     input[nfile].hasmin = 1;
  151.                     setcolr(input[nfile].thmin,
  152.                             atof(argv[an+1]),
  153.                             atof(argv[an+1]),
  154.                             atof(argv[an+1]));
  155.                 } else {
  156.                     input[nfile].hasmax = 1;
  157.                     setcolr(input[nfile].thmax,
  158.                             atof(argv[an+1]),
  159.                             atof(argv[an+1]),
  160.                             atof(argv[an+1]));
  161.                 }
  162.                 an += 2;
  163.                 break;
  164.             case 'l':
  165.                 if (strcmp(argv[an], "-l"))
  166.                     goto userr;
  167.                 thislabel = argv[an+1];
  168.                 an += 2;
  169.                 break;
  170.             case '\0':
  171.                 if (argv[an][0] == '-')
  172.                     goto getfile;
  173.                 goto userr;
  174.             default:
  175.                 goto userr;
  176.             }
  177. getfile:
  178.         if (argc-an < (ncolumns ? 1 : 3))
  179.             goto userr;
  180.         if (autolabel && thislabel == NULL)
  181.             thislabel = argv[an];
  182.         if (!strcmp(argv[an], "-")) {
  183.             input[nfile].name = "<stdin>";
  184.             input[nfile].fp = stdin;
  185.         } else {
  186.             if (argv[an][0] == '!') {
  187.                 input[nfile].name = Command;
  188.                 input[nfile].fp = popen(argv[an]+1, "r");
  189.             } else {
  190.                 input[nfile].name = argv[an];
  191.                 input[nfile].fp = fopen(argv[an], "r");
  192.             }
  193.             if (input[nfile].fp == NULL) {
  194.                 perror(argv[an]);
  195.                 quit(1);
  196.             }
  197.         }
  198.         an++;
  199.                         /* get header */
  200.         printf("%s:\n", input[nfile].name);
  201.         getheader(input[nfile].fp, tabputs, NULL);
  202.         if (wrongformat) {
  203.             fprintf(stderr, "%s: not a Radiance picture\n",
  204.                     input[nfile].name);
  205.             quit(1);
  206.         }
  207.                         /* get picture size */
  208.         if (fgetresolu(&input[nfile].xres, &input[nfile].yres,
  209.                 input[nfile].fp) < 0) {
  210.             fprintf(stderr, "%s: bad picture size\n",
  211.                     input[nfile].name);
  212.             quit(1);
  213.         }
  214.         if (ncolumns > 0) {
  215.             if (curcol >= ncolumns) {
  216.                 cury = ymax + spacing;
  217.                 curx = x0;
  218.                 curcol = 0;
  219.             }
  220.             input[nfile].xloc = curx;
  221.             input[nfile].yloc = cury;
  222.             curx += input[nfile].xres + spacing;
  223.             curcol++;
  224.         } else {
  225.             input[nfile].xloc = atoi(argv[an++]);
  226.             input[nfile].yloc = atoi(argv[an++]);
  227.         }
  228.         if (input[nfile].xloc < xmin)
  229.             xmin = input[nfile].xloc;
  230.         if (input[nfile].yloc < ymin)
  231.             ymin = input[nfile].yloc;
  232.         if (input[nfile].xloc+input[nfile].xres > xmax)
  233.             xmax = input[nfile].xloc+input[nfile].xres;
  234.         if (input[nfile].yloc+input[nfile].yres > ymax)
  235.             ymax = input[nfile].yloc+input[nfile].yres;
  236.         if (thislabel != NULL) {
  237.             if (++nfile >= MAXFILE)
  238.                 goto toomany;
  239.             input[nfile].name = Label;
  240.             input[nfile].hasmin = input[nfile].hasmax = 0;
  241.             input[nfile].xres = input[nfile-1].xres;
  242.             input[nfile].yres = labelht;
  243.             if ((input[nfile].fp = lblopen(thislabel,
  244.                     &input[nfile].xres,
  245.                     &input[nfile].yres)) == NULL)
  246.                 goto labelerr;
  247.             input[nfile].xloc = input[nfile-1].xloc;
  248.             input[nfile].yloc = input[nfile-1].yloc +
  249.                     input[nfile-1].yres-input[nfile].yres;
  250.         }
  251.     }
  252.     if (xsiz <= 0)
  253.         xsiz = xmax;
  254.     else if (xsiz > xmax)
  255.         xmax = xsiz;
  256.     if (ysiz <= 0)
  257.         ysiz = ymax;
  258.     else if (ysiz > ymax)
  259.         ymax = ysiz;
  260.                     /* add new header info. */
  261.     printargs(argc, argv, stdout);
  262.     fputformat(COLRFMT, stdout);
  263.     putchar('\n');
  264.     fprtresolu(xsiz, ysiz, stdout);
  265.  
  266.     compos();
  267.     
  268.     quit(0);
  269. userr:
  270.     fprintf(stderr,
  271.     "Usage: %s [-x xr][-y yr][-b r g b][-a n][-s p][-o x0 y0][-la][-lh h] ",
  272.             progname);
  273.     fprintf(stderr, "[-t min1][+t max1][-l lab] pic1 x1 y1 ..\n");
  274.     quit(1);
  275. toomany:
  276.     fprintf(stderr, "%s: only %d files and labels allowed\n",
  277.             progname, MAXFILE);
  278.     quit(1);
  279. labelerr:
  280.     fprintf(stderr, "%s: error opening label\n", progname);
  281.     quit(1);
  282. }
  283.  
  284.  
  285. compos()                                /* composite pictures */
  286. {
  287.     COLR  *scanin, *scanout;
  288.     int  y;
  289.     register int  x, i;
  290.  
  291.     scanin = (COLR *)malloc((xmax-xmin)*sizeof(COLR));
  292.     if (scanin == NULL)
  293.         goto memerr;
  294.     scanin -= xmin;
  295.     if (checkthresh) {
  296.         scanout = (COLR *)malloc(xsiz*sizeof(COLR));
  297.         if (scanout == NULL)
  298.             goto memerr;
  299.     } else
  300.         scanout = scanin;
  301.     for (y = ymax-1; y >= 0; y--) {
  302.         for (x = 0; x < xsiz; x++)
  303.             copycolr(scanout[x], bgcolr);
  304.         for (i = 0; i < nfile; i++) {
  305.             if (input[i].yloc > y ||
  306.                     input[i].yloc+input[i].yres <= y)
  307.                 continue;
  308.             if (freadcolrs(scanin+input[i].xloc,
  309.                     input[i].xres, input[i].fp) < 0) {
  310.                 fprintf(stderr, "%s: read error (y==%d)\n",
  311.                         input[i].name,
  312.                         y-input[i].yloc);
  313.                 quit(1);
  314.             }
  315.             if (y >= ysiz)
  316.                 continue;
  317.             if (checkthresh) {
  318.                 x = input[i].xloc+input[i].xres;
  319.                 if (x > xsiz)
  320.                     x = xsiz;
  321.                 for (x--; x >= 0 && x >= input[i].xloc; x--) {
  322.                     if (input[i].hasmin &&
  323.                     cmpcolr(scanin[x], input[i].thmin) <= 0)
  324.                         continue;
  325.                     if (input[i].hasmax &&
  326.                     cmpcolr(scanin[x], input[i].thmax) >= 0)
  327.                         continue;
  328.                     copycolr(scanout[x], scanin[x]);
  329.                 }
  330.             }
  331.         }
  332.         if (y >= ysiz)
  333.             continue;
  334.         if (fwritecolrs(scanout, xsiz, stdout) < 0) {
  335.             perror(progname);
  336.             quit(1);
  337.         }
  338.     }
  339.     return;
  340. memerr:
  341.     perror(progname);
  342.     quit(1);
  343. }
  344.  
  345.  
  346. int
  347. cmpcolr(c1, c2)                 /* compare two colr's (improvisation) */
  348. register COLR  c1, c2;
  349. {
  350.     register int  i, j;
  351.  
  352.     j = 4;                          /* check exponents first! */
  353.     while (j--)
  354.         if (i = c1[j] - c2[j])
  355.             return(i);
  356.     return(0);
  357. }
  358.  
  359.  
  360. FILE *
  361. lblopen(s, xp, yp)              /* open pipe to label generator */
  362. char  *s;
  363. int  *xp, *yp;
  364. {
  365.     char  com[128];
  366.     FILE  *fp;
  367.  
  368.     sprintf(com, "psign -s -.15 -a 2 -x %d -y %d '%.90s'", *xp, *yp, s);
  369.     if ((fp = popen(com, "r")) == NULL)
  370.         return(NULL);
  371.     if (checkheader(fp, COLRFMT, NULL) < 0)
  372.         goto err;
  373.     if (fgetresolu(xp, yp, fp) < 0)
  374.         goto err;
  375.     return(fp);
  376. err:
  377.     pclose(fp);
  378.     return(NULL);
  379. }
  380.  
  381.  
  382. quit(code)              /* exit gracefully */
  383. int  code;
  384. {
  385.     register int  i;
  386.                 /* close input files */
  387.     for (i = 0; i < nfile; i++)
  388.         if (input[i].name == Command || input[i].name == Label)
  389.             pclose(input[i].fp);
  390.         else
  391.             fclose(input[i].fp);
  392.     exit(code);
  393. }
  394.