Back to index

radiance  4R0+20100331
pcompos.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: pcompos.c,v 2.33 2009/08/10 04:26:38 greg Exp $";
00003 #endif
00004 /*
00005  *  pcompos.c - program to composite pictures.
00006  *
00007  *     6/30/87
00008  */
00009 
00010 #include  <stdio.h>
00011 #include  <math.h>
00012 #include  <time.h>
00013 #include  <string.h>
00014 
00015 #include "copyright.h"
00016 
00017 #include  "platform.h"
00018 #include  "rtprocess.h"
00019 #include  "rterror.h"
00020 #include  "color.h"
00021 #include  "resolu.h"
00022 
00023 #define        MAXFILE      1024
00024 
00025 #define  HASMIN             1
00026 #define  HASMAX             2
00027 
00028                                    /* output picture size */
00029 int  xsiz = 0;
00030 int  ysiz = 0;
00031                                    /* input dimensions */
00032 int  xmin = 0;
00033 int  ymin = 0;
00034 int  xmax = 0;
00035 int  ymax = 0;
00036 
00037 COLR  bgcolr = BLKCOLR;                   /* background color */
00038 
00039 int  labelht = 24;                 /* label height */
00040 
00041 int  checkthresh = 0;                     /* check threshold value */
00042 
00043 char  StandardInput[] = "<stdin>";
00044 char  Command[] = "<Command>";
00045 char  Label[] = "<Label>";
00046 
00047 char  *progname;
00048 
00049 struct {
00050        char  *name;                /* file or command name */
00051        FILE  *fp;                  /* stream pointer */
00052        int  xres, yres;            /* picture size */
00053        int  xloc, yloc;            /* anchor point */
00054        int  flags;                 /* HASMIN, HASMAX */
00055        double  thmin, thmax;              /* thresholds */
00056 } input[MAXFILE];           /* our input files */
00057 
00058 int  nfile;                 /* number of files */
00059 
00060 int  echoheader = 1;
00061 char  ourfmt[LPICFMT+1] = PICFMT;
00062 int  wrongformat = 0;
00063 
00064 
00065 static gethfunc headline;
00066 static void compos(void);
00067 static int cmpcolr(COLR  c1, double lv2);
00068 static FILE * lblopen(char  *s, int  *xp, int  *yp);
00069 
00070 
00071 
00072 static int
00073 headline(                   /* print line preceded by a tab */
00074        char   *s,
00075        void   *p
00076 )
00077 {
00078        char  fmt[32];
00079 
00080        if (isheadid(s))
00081               return(0);
00082        if (formatval(fmt, s)) {
00083               if (globmatch(ourfmt, fmt)) {
00084                      wrongformat = 0;
00085                      strcpy(ourfmt, fmt);
00086               } else
00087                      wrongformat = 1;
00088        } else if (echoheader) {
00089               putc('\t', stdout);
00090               fputs(s, stdout);
00091        }
00092        return(0);
00093 }
00094 
00095 
00096 int
00097 main(
00098        int  argc,
00099        char  *argv[]
00100 )
00101 {
00102        int  ncolumns = 0;
00103        int  autolabel = 0;
00104        int  curcol = 0, x0 = 0, curx = 0, cury = 0, spacing = 0;
00105        int  xsgn, ysgn;
00106        char  *thislabel;
00107        int  an;
00108        SET_DEFAULT_BINARY();
00109        SET_FILE_BINARY(stdin);
00110        SET_FILE_BINARY(stdout);
00111        progname = argv[0];
00112 
00113        for (an = 1; an < argc && argv[an][0] == '-'; an++)
00114               switch (argv[an][1]) {
00115               case 'h':
00116                      echoheader = !echoheader;
00117                      break;
00118               case 'x':
00119                      xsiz = atoi(argv[++an]);
00120                      break;
00121               case 'y':
00122                      ysiz = atoi(argv[++an]);
00123                      break;
00124               case 'b':
00125                      setcolr(bgcolr, atof(argv[an+1]),
00126                                    atof(argv[an+2]),
00127                                    atof(argv[an+3]));
00128                      an += 3;
00129                      break;
00130               case 'a':
00131                      ncolumns = atoi(argv[++an]);
00132                      break;
00133               case 's':
00134                      spacing = atoi(argv[++an]);
00135                      break;
00136               case 'o':
00137                      curx = x0 = atoi(argv[++an]);
00138                      cury = atoi(argv[++an]);
00139                      break;
00140               case 'l':
00141                      switch (argv[an][2]) {
00142                      case 'a':
00143                             autolabel++;
00144                             break;
00145                      case 'h':
00146                             labelht = atoi(argv[++an]);
00147                             break;
00148                      case '\0':
00149                             goto dofiles;
00150                      default:
00151                             goto userr;
00152                      }
00153                      break;
00154               case '\0':
00155               case 't':
00156                      goto dofiles;
00157               default:
00158                      goto userr;
00159               }
00160 dofiles:
00161        newheader("RADIANCE", stdout);
00162        fputnow(stdout);
00163        for (nfile = 0; an < argc; nfile++) {
00164               if (nfile >= MAXFILE)
00165                      goto toomany;
00166               thislabel = NULL;
00167               input[nfile].flags = 0;
00168               xsgn = ysgn = '-';
00169               while (an < argc && (argv[an][0] == '-' || argv[an][0] == '+'
00170                             || argv[an][0] == '=')) {
00171                      switch (argv[an][1]) {
00172                      case 't':
00173                             checkthresh = 1;
00174                             if (argv[an][0] == '-') {
00175                                    input[nfile].flags |= HASMIN;
00176                                    input[nfile].thmin = atof(argv[an+1]);
00177                             } else if (argv[an][0] == '+') {
00178                                    input[nfile].flags |= HASMAX;
00179                                    input[nfile].thmax = atof(argv[an+1]);
00180                             } else
00181                                    goto userr;
00182                             an++;
00183                             break;
00184                      case 'l':
00185                             if (strcmp(argv[an], "-l"))
00186                                    goto userr;
00187                             thislabel = argv[++an];
00188                             break;
00189                      case '+':
00190                      case '-':
00191                      case '0':
00192                             if (argv[an][0] != '=')
00193                                    goto userr;
00194                             xsgn = argv[an][1];
00195                             ysgn = argv[an][2];
00196                             if (ysgn != '+' && ysgn != '-' && ysgn != '0')
00197                                    goto userr;
00198                             break;
00199                      case '\0':
00200                             if (argv[an][0] == '-')
00201                                    goto getfile;
00202                             goto userr;
00203                      default:
00204                             goto userr;
00205                      }
00206                      an++;
00207               }
00208 getfile:
00209               if (argc-an < (ncolumns ? 1 : 3))
00210                      goto userr;
00211               if (autolabel && thislabel == NULL)
00212                      thislabel = argv[an];
00213               if (!strcmp(argv[an], "-")) {
00214                      input[nfile].name = StandardInput;
00215                      input[nfile].fp = stdin;
00216               } else {
00217                      if (argv[an][0] == '!') {
00218                             input[nfile].name = Command;
00219                             input[nfile].fp = popen(argv[an]+1, "r");
00220                      } else {
00221                             input[nfile].name = argv[an];
00222                             input[nfile].fp = fopen(argv[an], "r");
00223                      }
00224                      if (input[nfile].fp == NULL) {
00225                             perror(argv[an]);
00226                             quit(1);
00227                      }
00228               }
00229               an++;
00230                                           /* get header */
00231               if (echoheader)
00232                      printf("%s:\n", input[nfile].name);
00233               getheader(input[nfile].fp, headline, NULL);
00234               if (wrongformat) {
00235                      fprintf(stderr, "%s: incompatible input format\n",
00236                                    input[nfile].name);
00237                      quit(1);
00238               }
00239                                           /* get picture size */
00240               if (fgetresolu(&input[nfile].xres, &input[nfile].yres,
00241                             input[nfile].fp) < 0) {
00242                      fprintf(stderr, "%s: bad picture size\n",
00243                                    input[nfile].name);
00244                      quit(1);
00245               }
00246               if (ncolumns > 0) {
00247                      if (curcol >= ncolumns) {
00248                             cury = ymax + spacing;
00249                             curx = x0;
00250                             curcol = 0;
00251                      }
00252                      input[nfile].xloc = curx;
00253                      input[nfile].yloc = cury;
00254                      curx += input[nfile].xres + spacing;
00255                      curcol++;
00256               } else {
00257                      input[nfile].xloc = atoi(argv[an++]);
00258                      if (xsgn == '+')
00259                             input[nfile].xloc -= input[nfile].xres;
00260                      else if (xsgn == '0')
00261                             input[nfile].xloc -= input[nfile].xres/2;
00262                      input[nfile].yloc = atoi(argv[an++]);
00263                      if (ysgn == '+')
00264                             input[nfile].yloc -= input[nfile].yres;
00265                      else if (ysgn == '0')
00266                             input[nfile].yloc -= input[nfile].yres/2;
00267               }
00268               if (input[nfile].xloc < xmin)
00269                      xmin = input[nfile].xloc;
00270               if (input[nfile].yloc < ymin)
00271                      ymin = input[nfile].yloc;
00272               if (input[nfile].xloc+input[nfile].xres > xmax)
00273                      xmax = input[nfile].xloc+input[nfile].xres;
00274               if (input[nfile].yloc+input[nfile].yres > ymax)
00275                      ymax = input[nfile].yloc+input[nfile].yres;
00276               if (thislabel != NULL) {
00277                      if (++nfile >= MAXFILE)
00278                             goto toomany;
00279                      input[nfile].name = Label;
00280                      input[nfile].flags = 0;
00281                      input[nfile].xres = input[nfile-1].xres;
00282                      input[nfile].yres = labelht;
00283                      if ((input[nfile].fp = lblopen(thislabel,
00284                                    &input[nfile].xres,
00285                                    &input[nfile].yres)) == NULL)
00286                             goto labelerr;
00287                      input[nfile].xloc = input[nfile-1].xloc;
00288                      input[nfile].yloc = input[nfile-1].yloc +
00289                                    input[nfile-1].yres-input[nfile].yres;
00290               }
00291        }
00292        if (xsiz <= 0)
00293               xsiz = xmax;
00294        else if (xsiz > xmax)
00295               xmax = xsiz;
00296        if (ysiz <= 0)
00297               ysiz = ymax;
00298        else if (ysiz > ymax)
00299               ymax = ysiz;
00300                                    /* add new header info. */
00301        printargs(argc, argv, stdout);
00302        if (strcmp(ourfmt, PICFMT))
00303               fputformat(ourfmt, stdout); /* print format if known */
00304        putchar('\n');
00305        fprtresolu(xsiz, ysiz, stdout);
00306 
00307        compos();
00308        
00309        quit(0);
00310 userr:
00311        fprintf(stderr,
00312        "Usage: %s [-h][-x xr][-y yr][-b r g b][-a n][-s p][-o x0 y0][-la][-lh h] ",
00313                      progname);
00314        fprintf(stderr, "[-t min1][+t max1][-l lab][=SS] pic1 x1 y1 ..\n");
00315        quit(1);
00316 toomany:
00317        fprintf(stderr, "%s: only %d files and labels allowed\n",
00318                      progname, MAXFILE);
00319        quit(1);
00320 labelerr:
00321        fprintf(stderr, "%s: error opening label\n", progname);
00322        quit(1);
00323        return 1; /* pro forma return */
00324 }
00325 
00326 
00327 static void
00328 compos(void)                       /* composite pictures */
00329 {
00330        COLR  *scanin, *scanout;
00331        int  y;
00332        register int  x, i;
00333 
00334        scanin = (COLR *)malloc((xmax-xmin)*sizeof(COLR));
00335        if (scanin == NULL)
00336               goto memerr;
00337        scanin -= xmin;
00338        if (checkthresh) {
00339               scanout = (COLR *)malloc(xsiz*sizeof(COLR));
00340               if (scanout == NULL)
00341                      goto memerr;
00342        } else
00343               scanout = scanin;
00344        for (y = ymax-1; y >= 0; y--) {
00345               for (x = 0; x < xsiz; x++)
00346                      copycolr(scanout[x], bgcolr);
00347               for (i = 0; i < nfile; i++) {
00348                      if (input[i].yloc > y ||
00349                                    input[i].yloc+input[i].yres <= y)
00350                             continue;
00351                      if (freadcolrs(scanin+input[i].xloc,
00352                                    input[i].xres, input[i].fp) < 0) {
00353                             fprintf(stderr, "%s: read error (y==%d)\n",
00354                                           input[i].name,
00355                                           y-input[i].yloc);
00356                             quit(1);
00357                      }
00358                      if (y >= ysiz)
00359                             continue;
00360                      if (checkthresh) {
00361                             x = input[i].xloc+input[i].xres;
00362                             if (x > xsiz)
00363                                    x = xsiz;
00364                             for (x--; x >= 0 && x >= input[i].xloc; x--) {
00365                                    if (input[i].flags & HASMIN &&
00366                                    cmpcolr(scanin[x], input[i].thmin) <= 0)
00367                                           continue;
00368                                    if (input[i].flags & HASMAX &&
00369                                    cmpcolr(scanin[x], input[i].thmax) >= 0)
00370                                           continue;
00371                                    copycolr(scanout[x], scanin[x]);
00372                             }
00373                      }
00374               }
00375               if (y >= ysiz)
00376                      continue;
00377               if (fwritecolrs(scanout, xsiz, stdout) < 0) {
00378                      perror(progname);
00379                      quit(1);
00380               }
00381        }
00382                                    /* read remainders from streams */
00383        for (i = 0; i < nfile; i++)
00384               if (input[i].name[0] == '<')
00385                      while (getc(input[i].fp) != EOF)
00386                             ;
00387        return;
00388 memerr:
00389        perror(progname);
00390        quit(1);
00391 }
00392 
00393 
00394 static int
00395 cmpcolr(                    /* compare COLR to luminance */
00396        register COLR  c1,
00397        double lv2
00398 )
00399 {
00400        double lv1 = .0;
00401        
00402        if (c1[EXP])
00403               lv1 = ldexp((double)normbright(c1), (int)c1[EXP]-(COLXS+8));
00404        if (lv1 < lv2) return(-1);
00405        if (lv1 > lv2) return(1);
00406        return(0);
00407 }
00408 
00409 
00410 static FILE *
00411 lblopen(             /* open pipe to label generator */
00412        char  *s,
00413        int  *xp,
00414        int  *yp
00415 )
00416 {
00417        char  com[PATH_MAX];
00418        FILE  *fp;
00419 
00420        sprintf(com, "psign -s -.15 -a 2 -x %d -y %d '%.90s'", *xp, *yp, s);
00421        if ((fp = popen(com, "r")) == NULL)
00422               return(NULL);
00423        if (checkheader(fp, COLRFMT, NULL) < 0)
00424               goto err;
00425        if (fgetresolu(xp, yp, fp) < 0)
00426               goto err;
00427        return(fp);
00428 err:
00429        pclose(fp);
00430        return(NULL);
00431 }
00432 
00433 
00434 void
00435 quit(code)           /* exit gracefully */
00436 int  code;
00437 {
00438        register int  i;
00439                             /* close input files */
00440        for (i = 0; i < nfile; i++)
00441               if (input[i].name == Command || input[i].name == Label)
00442                      pclose(input[i].fp);
00443               else
00444                      fclose(input[i].fp);
00445        exit(code);
00446 }