| 1 | < | /* Copyright (c) 1987 Regents of the University of California */ | 
| 1 | > | /* Copyright (c) 1991 Regents of the University of California */ | 
| 2 |  |  | 
| 3 |  | #ifndef lint | 
| 4 |  | static char SCCSid[] = "$SunId$ LBL"; | 
| 14 |  |  | 
| 15 |  | #include  "color.h" | 
| 16 |  |  | 
| 17 | + | #include  "resolu.h" | 
| 18 |  |  | 
| 19 | < | #define  MAXFILE        16 | 
| 19 | > | #define  MAXFILE        64 | 
| 20 |  |  | 
| 21 |  | /* output picture size */ | 
| 22 |  | int  xsiz = 0; | 
| 29 |  |  | 
| 30 |  | COLR  bgcolr = BLKCOLR;                 /* background color */ | 
| 31 |  |  | 
| 32 | + | int  labelht = 24;                      /* label height */ | 
| 33 | + |  | 
| 34 |  | int  checkthresh = 0;                   /* check threshold value */ | 
| 35 |  |  | 
| 36 |  | char  *progname; | 
| 37 |  |  | 
| 38 |  | struct { | 
| 39 | < | char  *name;                    /* file name */ | 
| 39 | > | char  *name;                    /* file or command name */ | 
| 40 |  | FILE  *fp;                      /* stream pointer */ | 
| 41 |  | int  xres, yres;                /* picture size */ | 
| 42 |  | int  xloc, yloc;                /* anchor point */ | 
| 46 |  |  | 
| 47 |  | int  nfile;                     /* number of files */ | 
| 48 |  |  | 
| 49 | + | int  wrongformat = 0; | 
| 50 |  |  | 
| 51 | + | FILE  *popen(), *lblopen(); | 
| 52 | + |  | 
| 53 | + |  | 
| 54 |  | tabputs(s)                      /* print line preceded by a tab */ | 
| 55 |  | char  *s; | 
| 56 |  | { | 
| 57 | < | putc('\t', stdout); | 
| 58 | < | fputs(s, stdout); | 
| 57 | > | char  fmt[32]; | 
| 58 | > |  | 
| 59 | > | if (isformat(s)) { | 
| 60 | > | formatval(fmt, s); | 
| 61 | > | wrongformat = strcmp(fmt, COLRFMT); | 
| 62 | > | } else { | 
| 63 | > | putc('\t', stdout); | 
| 64 | > | fputs(s, stdout); | 
| 65 | > | } | 
| 66 |  | } | 
| 67 |  |  | 
| 68 |  |  | 
| 70 |  | int  argc; | 
| 71 |  | char  *argv[]; | 
| 72 |  | { | 
| 73 | < | double  atof(); | 
| 73 | > | int  ncolumns = 0; | 
| 74 | > | int  autolabel = 0; | 
| 75 | > | int  curcol = 0, curx = 0, cury = 0; | 
| 76 | > | char  *thislabel; | 
| 77 |  | int  an; | 
| 78 |  |  | 
| 79 |  | progname = argv[0]; | 
| 92 |  | atof(argv[an+3])); | 
| 93 |  | an += 3; | 
| 94 |  | break; | 
| 95 | + | case 'a': | 
| 96 | + | ncolumns = atoi(argv[++an]); | 
| 97 | + | break; | 
| 98 | + | case 'l': | 
| 99 | + | switch (argv[an][2]) { | 
| 100 | + | case 'a': | 
| 101 | + | autolabel++; | 
| 102 | + | break; | 
| 103 | + | case 'h': | 
| 104 | + | labelht = atoi(argv[++an]); | 
| 105 | + | break; | 
| 106 | + | case '\0': | 
| 107 | + | goto dofiles; | 
| 108 | + | default: | 
| 109 | + | goto userr; | 
| 110 | + | } | 
| 111 | + | break; | 
| 112 |  | case '\0': | 
| 113 |  | case 't': | 
| 114 |  | goto dofiles; | 
| 117 |  | } | 
| 118 |  | dofiles: | 
| 119 |  | for (nfile = 0; an < argc; nfile++) { | 
| 120 | < | if (nfile >= MAXFILE) { | 
| 121 | < | fprintf(stderr, "%s: too many files\n", progname); | 
| 122 | < | quit(1); | 
| 89 | < | } | 
| 120 | > | if (nfile >= MAXFILE) | 
| 121 | > | goto toomany; | 
| 122 | > | thislabel = NULL; | 
| 123 |  | input[nfile].hasmin = input[nfile].hasmax = 0; | 
| 124 |  | while (an < argc && (argv[an][0] == '-' || argv[an][0] == '+')) | 
| 125 |  | switch (argv[an][1]) { | 
| 140 |  | } | 
| 141 |  | an += 2; | 
| 142 |  | break; | 
| 143 | + | case 'l': | 
| 144 | + | if (strcmp(argv[an], "-l")) | 
| 145 | + | goto userr; | 
| 146 | + | thislabel = argv[an+1]; | 
| 147 | + | an += 2; | 
| 148 | + | break; | 
| 149 |  | case '\0': | 
| 150 |  | if (argv[an][0] == '-') | 
| 151 |  | goto getfile; | 
| 152 | < | /* fall through */ | 
| 152 | > | goto userr; | 
| 153 |  | default: | 
| 154 |  | goto userr; | 
| 155 |  | } | 
| 156 |  | getfile: | 
| 157 | < | if (argc-an < 3) | 
| 157 | > | if (argc-an < (ncolumns ? 1 : 3)) | 
| 158 |  | goto userr; | 
| 159 | + | if (autolabel && thislabel == NULL) | 
| 160 | + | thislabel = argv[an]; | 
| 161 |  | if (!strcmp(argv[an], "-")) { | 
| 162 |  | input[nfile].name = "<stdin>"; | 
| 163 |  | input[nfile].fp = stdin; | 
| 164 |  | } else { | 
| 165 | < | input[nfile].name = argv[an]; | 
| 166 | < | if ((input[nfile].fp = fopen(argv[an], "r")) == NULL) { | 
| 167 | < | fprintf(stderr, "%s: cannot open\n", argv[an]); | 
| 165 | > | if (argv[an][0] == '!') { | 
| 166 | > | input[nfile].name = "<Command>"; | 
| 167 | > | input[nfile].fp = popen(argv[an]+1, "r"); | 
| 168 | > | } else { | 
| 169 | > | input[nfile].name = argv[an]; | 
| 170 | > | input[nfile].fp = fopen(argv[an], "r"); | 
| 171 | > | } | 
| 172 | > | if (input[nfile].fp == NULL) { | 
| 173 | > | perror(argv[an]); | 
| 174 |  | quit(1); | 
| 175 |  | } | 
| 176 |  | } | 
| 177 |  | an++; | 
| 178 |  | /* get header */ | 
| 179 |  | printf("%s:\n", input[nfile].name); | 
| 180 | < | getheader(input[nfile].fp, tabputs); | 
| 180 | > | getheader(input[nfile].fp, tabputs, NULL); | 
| 181 | > | if (wrongformat) { | 
| 182 | > | fprintf(stderr, "%s: not a Radiance picture\n", | 
| 183 | > | input[nfile].name); | 
| 184 | > | quit(1); | 
| 185 | > | } | 
| 186 |  | /* get picture size */ | 
| 187 |  | if (fgetresolu(&input[nfile].xres, &input[nfile].yres, | 
| 188 | < | input[nfile].fp) != (YMAJOR|YDECR)) { | 
| 188 | > | input[nfile].fp) < 0) { | 
| 189 |  | fprintf(stderr, "%s: bad picture size\n", | 
| 190 |  | input[nfile].name); | 
| 191 |  | quit(1); | 
| 192 |  | } | 
| 193 | < | input[nfile].xloc = atoi(argv[an++]); | 
| 194 | < | input[nfile].yloc = atoi(argv[an++]); | 
| 193 | > | if (ncolumns > 0) { | 
| 194 | > | if (curcol >= ncolumns) { | 
| 195 | > | cury = ymax; | 
| 196 | > | curx = 0; | 
| 197 | > | curcol = 0; | 
| 198 | > | } | 
| 199 | > | input[nfile].xloc = curx; | 
| 200 | > | input[nfile].yloc = cury; | 
| 201 | > | curx += input[nfile].xres; | 
| 202 | > | curcol++; | 
| 203 | > | } else { | 
| 204 | > | input[nfile].xloc = atoi(argv[an++]); | 
| 205 | > | input[nfile].yloc = atoi(argv[an++]); | 
| 206 | > | } | 
| 207 |  | if (input[nfile].xloc < xmin) | 
| 208 |  | xmin = input[nfile].xloc; | 
| 209 |  | if (input[nfile].yloc < ymin) | 
| 212 |  | xmax = input[nfile].xloc+input[nfile].xres; | 
| 213 |  | if (input[nfile].yloc+input[nfile].yres > ymax) | 
| 214 |  | ymax = input[nfile].yloc+input[nfile].yres; | 
| 215 | + | if (thislabel != NULL) { | 
| 216 | + | if (++nfile >= MAXFILE) | 
| 217 | + | goto toomany; | 
| 218 | + | input[nfile].name = "<Label>"; | 
| 219 | + | input[nfile].hasmin = input[nfile].hasmax = 0; | 
| 220 | + | input[nfile].xres = input[nfile-1].xres; | 
| 221 | + | input[nfile].yres = labelht; | 
| 222 | + | if ((input[nfile].fp = lblopen(thislabel, | 
| 223 | + | &input[nfile].xres, | 
| 224 | + | &input[nfile].yres)) == NULL) | 
| 225 | + | goto labelerr; | 
| 226 | + | input[nfile].xloc = input[nfile-1].xloc; | 
| 227 | + | input[nfile].yloc = input[nfile-1].yloc + | 
| 228 | + | input[nfile-1].yres-input[nfile].yres; | 
| 229 | + | } | 
| 230 |  | } | 
| 231 |  | if (xsiz <= 0) | 
| 232 |  | xsiz = xmax; | 
| 234 |  | ysiz = ymax; | 
| 235 |  | /* add new header info. */ | 
| 236 |  | printargs(argc, argv, stdout); | 
| 237 | < | printf("\n-Y %d +X %d\n", ysiz, xsiz); | 
| 237 | > | fputformat(COLRFMT, stdout); | 
| 238 | > | putchar('\n'); | 
| 239 | > | fprtresolu(xsiz, ysiz, stdout); | 
| 240 |  |  | 
| 241 |  | compos(); | 
| 242 |  |  | 
| 243 |  | quit(0); | 
| 244 |  | userr: | 
| 245 | < | fprintf(stderr, "Usage: %s [-x xres][-y yres][-b r g b] ", progname); | 
| 246 | < | fprintf(stderr, "[-t min1][+t max1] file1 x1 y1 ..\n"); | 
| 245 | > | fprintf(stderr, "Usage: %s [-x xr][-y yr][-b r g b][-a n][-la][-lh h] ", | 
| 246 | > | progname); | 
| 247 | > | fprintf(stderr, "[-t min1][+t max1][-l lab] pic1 x1 y1 ..\n"); | 
| 248 |  | quit(1); | 
| 249 | + | toomany: | 
| 250 | + | fprintf(stderr, "%s: only %d files and labels allowed\n", | 
| 251 | + | progname, MAXFILE); | 
| 252 | + | quit(1); | 
| 253 | + | labelerr: | 
| 254 | + | fprintf(stderr, "%s: error opening label\n", progname); | 
| 255 | + | quit(1); | 
| 256 |  | } | 
| 257 |  |  | 
| 258 |  |  | 
| 306 |  | if (y >= ysiz) | 
| 307 |  | continue; | 
| 308 |  | if (fwritecolrs(scanout, xsiz, stdout) < 0) { | 
| 309 | < | fprintf(stderr, "%s: write error\n", progname); | 
| 309 | > | perror(progname); | 
| 310 |  | quit(1); | 
| 311 |  | } | 
| 312 |  | } | 
| 313 |  | return; | 
| 314 |  | memerr: | 
| 315 | < | fprintf(stderr, "%s: out of memory\n", progname); | 
| 315 | > | perror(progname); | 
| 316 |  | quit(1); | 
| 317 |  | } | 
| 318 |  |  | 
| 331 |  | } | 
| 332 |  |  | 
| 333 |  |  | 
| 334 | + | FILE * | 
| 335 | + | lblopen(s, xp, yp)              /* open pipe to label generator */ | 
| 336 | + | char  *s; | 
| 337 | + | int  *xp, *yp; | 
| 338 | + | { | 
| 339 | + | char  com[128]; | 
| 340 | + | FILE  *fp; | 
| 341 | + |  | 
| 342 | + | sprintf(com, "psign -s -.15 -a 2 -x %d -y %d '%.90s'", *xp, *yp, s); | 
| 343 | + | if ((fp = popen(com, "r")) == NULL) | 
| 344 | + | return(NULL); | 
| 345 | + | if (checkheader(fp, COLRFMT, NULL) < 0) | 
| 346 | + | goto err; | 
| 347 | + | if (fgetresolu(xp, yp, fp) < 0) | 
| 348 | + | goto err; | 
| 349 | + | return(fp); | 
| 350 | + | err: | 
| 351 | + | pclose(fp); | 
| 352 | + | return(NULL); | 
| 353 | + | } | 
| 354 | + |  | 
| 355 | + |  | 
| 356 |  | quit(code)              /* exit gracefully */ | 
| 357 |  | int  code; | 
| 358 |  | { | 
| 359 | + | int  status; | 
| 360 | + |  | 
| 361 | + | if (code == 0)                  /* reap any children */ | 
| 362 | + | while (wait(&status) != -1) | 
| 363 | + | if (code == 0) | 
| 364 | + | code = status>>8 & 0xff; | 
| 365 |  | exit(code); | 
| 366 |  | } |