| 1 | < | /* Copyright (c) 1986 Regents of the University of California */ | 
| 1 | > | /* Copyright (c) 1992 Regents of the University of California */ | 
| 2 |  |  | 
| 3 |  | #ifndef lint | 
| 4 |  | static char SCCSid[] = "$SunId$ LBL"; | 
| 12 |  |  | 
| 13 |  | #include  <stdio.h> | 
| 14 |  |  | 
| 15 | + | #ifdef MSDOS | 
| 16 | + | #include  <fcntl.h> | 
| 17 | + | #endif | 
| 18 | + |  | 
| 19 | + | #include  <math.h> | 
| 20 | + |  | 
| 21 |  | #include  <signal.h> | 
| 22 |  |  | 
| 23 |  | #include  "color.h" | 
| 24 |  |  | 
| 25 | + | #include  "resolu.h" | 
| 26 |  |  | 
| 27 | + | #include  "paths.h" | 
| 28 | + |  | 
| 29 |  | extern char  *malloc(); | 
| 30 | + | extern float  *matchlamp(); | 
| 31 |  |  | 
| 32 | < | #define  CHECKRAD       1.5     /* radius to check for filtering */ | 
| 32 | > | #define  FEQ(a,b)       ((a) >= .98*(b) && (a) <= 1.02*(b)) | 
| 33 |  |  | 
| 34 | + | #define  CHECKRAD       1.5     /* radius to check for filtering */ | 
| 35 | + |  | 
| 36 |  | COLOR  exposure = WHTCOLOR;     /* exposure for the frame */ | 
| 37 |  |  | 
| 38 | < | double  rad = 0.0;              /* output pixel radius for filtering */ | 
| 38 | > | double  rad = 0.0;              /* output pixel radius for filtering */ | 
| 39 |  |  | 
| 40 |  | int  nrows = 0;                 /* number of rows for output */ | 
| 41 |  | int  ncols = 0;                 /* number of columns for output */ | 
| 42 |  |  | 
| 43 | < | double  x_c = 1.0;              /* ratio of output x size to input */ | 
| 44 | < | double  y_r = 1.0;              /* ratio of output y size to input */ | 
| 43 | > | double  x_c = 1.0;              /* ratio of output x size to input */ | 
| 44 | > | double  y_r = 1.0;              /* ratio of output y size to input */ | 
| 45 |  |  | 
| 46 |  | int  singlepass = 0;            /* true means skip first pass */ | 
| 47 |  |  | 
| 48 |  | int  avghot = 0;                /* true means average in bright spots */ | 
| 49 |  |  | 
| 50 | < | double  hotlvl = 1000.0;        /* level considered "hot" */ | 
| 50 | > | double  hotlvl = 1000.0;        /* level considered "hot" */ | 
| 51 |  |  | 
| 52 |  | int  npts = 0;                  /* (half) number of points for stars */ | 
| 53 |  |  | 
| 54 | < | double  spread = 1e-4;          /* spread for star points */ | 
| 54 | > | double  spread = 1e-4;          /* spread for star points */ | 
| 55 |  |  | 
| 44 | – | #define  TEMPLATE       "/usr/tmp/pfXXXXXX" | 
| 45 | – |  | 
| 56 |  | char  *tfname = NULL; | 
| 57 |  |  | 
| 58 | + | char  *lampdat = "lamp.tab";    /* lamp data file */ | 
| 59 | + |  | 
| 60 | + | int  order;                     /* scanline ordering of input */ | 
| 61 |  | int  xres, yres;                /* resolution of input */ | 
| 62 | + | double  inpaspect = 1.0;        /* pixel aspect ratio of input */ | 
| 63 | + | int  correctaspect = 0;         /* aspect ratio correction? */ | 
| 64 |  |  | 
| 65 | + | int  wrongformat = 0; | 
| 66 | + |  | 
| 67 |  | int  xrad;                      /* x window size */ | 
| 68 |  | int  yrad;                      /* y window size */ | 
| 69 |  |  | 
| 78 |  | int  argc; | 
| 79 |  | char  **argv; | 
| 80 |  | { | 
| 64 | – | extern char  *mktemp(); | 
| 65 | – | extern double  atof(), pow(); | 
| 81 |  | extern long  ftell(); | 
| 82 | < | extern int  quit(); | 
| 82 | > | extern int  quit(), headline(); | 
| 83 |  | FILE  *fin; | 
| 84 | + | float  *lampcolor; | 
| 85 | + | char  *lamptype = NULL; | 
| 86 |  | long  fpos; | 
| 87 | < | double  d; | 
| 88 | < | int  i; | 
| 89 | < |  | 
| 87 | > | double  outaspect = 0.0; | 
| 88 | > | double  d; | 
| 89 | > | int  i, j; | 
| 90 | > | #ifdef MSDOS | 
| 91 | > | extern int  _fmode; | 
| 92 | > | _fmode = O_BINARY; | 
| 93 | > | setmode(fileno(stdin), O_BINARY); | 
| 94 | > | setmode(fileno(stdout), O_BINARY); | 
| 95 | > | #endif | 
| 96 |  | if (signal(SIGINT, quit) == SIG_IGN) | 
| 97 |  | signal(SIGINT, SIG_IGN); | 
| 98 |  | if (signal(SIGHUP, quit) == SIG_IGN) | 
| 99 |  | signal(SIGINT, SIG_IGN); | 
| 100 |  | signal(SIGTERM, quit); | 
| 101 |  | signal(SIGPIPE, quit); | 
| 102 | < | #ifdef  SIGXCPU | 
| 102 | > | #ifdef  SIGXCPU | 
| 103 |  | signal(SIGXCPU, quit); | 
| 104 |  | signal(SIGXFSZ, quit); | 
| 105 |  | #endif | 
| 125 |  | } else | 
| 126 |  | nrows = atoi(argv[i]); | 
| 127 |  | break; | 
| 128 | + | case 'c': | 
| 129 | + | correctaspect = !correctaspect; | 
| 130 | + | break; | 
| 131 | + | case 'p': | 
| 132 | + | i++; | 
| 133 | + | outaspect = atof(argv[i]); | 
| 134 | + | break; | 
| 135 |  | case 'e': | 
| 136 |  | if (argv[i+1][0] == '+' || argv[i+1][0] == '-') | 
| 137 |  | d = pow(2.0, atof(argv[i+1])); | 
| 138 |  | else | 
| 139 |  | d = atof(argv[i+1]); | 
| 140 | + | if (d < 1e-20 || d > 1e20) { | 
| 141 | + | fprintf(stderr, | 
| 142 | + | "%s: exposure out of range\n", | 
| 143 | + | argv[0]); | 
| 144 | + | exit(1); | 
| 145 | + | } | 
| 146 |  | switch (argv[i][2]) { | 
| 147 |  | case '\0': | 
| 148 |  | scalecolor(exposure, d); | 
| 161 |  | } | 
| 162 |  | i++; | 
| 163 |  | break; | 
| 164 | + | case 'f': | 
| 165 | + | lampdat = argv[++i]; | 
| 166 | + | break; | 
| 167 | + | case 't': | 
| 168 | + | lamptype = argv[++i]; | 
| 169 | + | break; | 
| 170 |  | case '1': | 
| 171 |  | singlepass = 1; | 
| 172 |  | break; | 
| 173 |  | case '2': | 
| 174 |  | singlepass = 0; | 
| 175 |  | break; | 
| 176 | < | case 'p': | 
| 176 | > | case 'n': | 
| 177 |  | npts = atoi(argv[++i]) / 2; | 
| 178 |  | break; | 
| 179 |  | case 's': | 
| 200 |  | } | 
| 201 |  | else | 
| 202 |  | break; | 
| 203 | < |  | 
| 203 | > | /* get lamp data (if necessary) */ | 
| 204 | > | if (lamptype != NULL) { | 
| 205 | > | if (loadlamps(lampdat) < 0) | 
| 206 | > | quit(1); | 
| 207 | > | if ((lampcolor = matchlamp(lamptype)) == NULL) { | 
| 208 | > | fprintf(stderr, "%s: unknown lamp type\n", lamptype); | 
| 209 | > | quit(1); | 
| 210 | > | } | 
| 211 | > | for (i = 0; i < 3; i++) | 
| 212 | > | if (lampcolor[i] > 1e-4) | 
| 213 | > | colval(exposure,i) /= lampcolor[i]; | 
| 214 | > | freelamps(); | 
| 215 | > | } | 
| 216 | > | /* open input file */ | 
| 217 |  | if (i == argc) { | 
| 218 |  | if (singlepass) | 
| 219 |  | fin = stdin; | 
| 240 |  | fprintf(stderr, "%s: bad # file arguments\n", progname); | 
| 241 |  | quit(1); | 
| 242 |  | } | 
| 243 | < | /* copy header */ | 
| 244 | < | copyheader(fin, stdout); | 
| 243 | > | /* get header */ | 
| 244 | > | getheader(fin, headline, NULL); | 
| 245 | > | if (wrongformat) { | 
| 246 | > | fprintf(stderr, "%s: input must be a Radiance picture\n", | 
| 247 | > | progname); | 
| 248 | > | quit(1); | 
| 249 | > | } | 
| 250 |  | /* add new header info. */ | 
| 251 |  | printargs(i, argv, stdout); | 
| 252 |  | /* get picture size */ | 
| 253 | < | if (fgetresolu(&xres, &yres, fin) != (YMAJOR|YDECR)) { | 
| 253 | > | if ((order = fgetresolu(&xres, &yres, fin)) < 0) { | 
| 254 |  | fprintf(stderr, "%s: bad picture size\n", progname); | 
| 255 |  | quit(1); | 
| 256 |  | } | 
| 257 | < | if (ncols > 0) | 
| 258 | < | x_c = (double)ncols/xres; | 
| 259 | < | else | 
| 257 | > | if (!(order & YMAJOR)) | 
| 258 | > | inpaspect = 1.0/inpaspect; | 
| 259 | > | /* compute output resolution */ | 
| 260 | > | if (ncols <= 0) | 
| 261 |  | ncols = x_c*xres + .5; | 
| 262 | < | if (nrows > 0) | 
| 202 | < | y_r = (double)nrows/yres; | 
| 203 | < | else | 
| 262 | > | if (nrows <= 0) | 
| 263 |  | nrows = y_r*yres + .5; | 
| 264 | + | if (outaspect > .01) { | 
| 265 | + | d = inpaspect * yres/xres / outaspect; | 
| 266 | + | if (d * ncols > nrows) | 
| 267 | + | ncols = nrows / d; | 
| 268 | + | else | 
| 269 | + | nrows = ncols * d; | 
| 270 | + | } | 
| 271 | + | x_c = (double)ncols/xres; | 
| 272 | + | y_r = (double)nrows/yres; | 
| 273 |  |  | 
| 274 | < | if (singlepass) { | 
| 207 | < | /* skip exposure, etc. */ | 
| 274 | > | if (singlepass) {               /* skip exposure, etc. */ | 
| 275 |  | pass1default(); | 
| 276 |  | pass2(fin); | 
| 277 |  | quit(0); | 
| 291 |  | } | 
| 292 |  |  | 
| 293 |  |  | 
| 294 | + | headline(s)                             /* process line from header */ | 
| 295 | + | char  *s; | 
| 296 | + | { | 
| 297 | + | char  fmt[32]; | 
| 298 | + |  | 
| 299 | + | fputs(s, stdout);               /* copy to output */ | 
| 300 | + | if (isaspect(s))                /* get aspect ratio */ | 
| 301 | + | inpaspect *= aspectval(s); | 
| 302 | + | else if (isformat(s)) { | 
| 303 | + | formatval(fmt, s); | 
| 304 | + | wrongformat = strcmp(fmt, COLRFMT); | 
| 305 | + | } | 
| 306 | + | } | 
| 307 | + |  | 
| 308 | + |  | 
| 309 |  | copyfile(in, out)                       /* copy a file */ | 
| 310 |  | register FILE  *in, *out; | 
| 311 |  | { | 
| 344 |  | fprintf(stderr, "%s: warning - partial frame (%d%%)\n", | 
| 345 |  | progname, 100*i/yres); | 
| 346 |  | yres = i; | 
| 347 | + | y_r = (double)nrows/yres; | 
| 348 |  | break; | 
| 349 |  | } | 
| 350 |  | pass1scan(scan, i); | 
| 359 |  | int  yread; | 
| 360 |  | int  ycent, xcent; | 
| 361 |  | int  r, c; | 
| 362 | < |  | 
| 362 | > |  | 
| 363 |  | pass2init(); | 
| 364 |  | scan2init(); | 
| 365 |  | yread = 0; | 
| 390 |  | quit(1); | 
| 391 |  | } | 
| 392 |  | } | 
| 393 | + | /* skip leftovers */ | 
| 394 | + | while (yread < yres) { | 
| 395 | + | if (freadscan(scanin[0], xres, in) < 0) | 
| 396 | + | break; | 
| 397 | + | yread++; | 
| 398 | + | } | 
| 399 |  | } | 
| 400 |  |  | 
| 401 |  |  | 
| 402 |  | scan2init()                     /* prepare scanline arrays */ | 
| 403 |  | { | 
| 404 | < | double  e; | 
| 404 | > | COLOR   ctmp; | 
| 405 | > | double  d; | 
| 406 |  | register int  i; | 
| 407 |  |  | 
| 408 |  | if (rad <= 0.0) { | 
| 417 |  |  | 
| 418 |  | initmask();             /* initialize filter table */ | 
| 419 |  | } | 
| 420 | < | barsize = 2 * yrad; | 
| 420 | > | barsize = 2*yrad + 1; | 
| 421 |  | scanin = (COLOR **)malloc(barsize*sizeof(COLOR *)); | 
| 422 |  | for (i = 0; i < barsize; i++) { | 
| 423 |  | scanin[i] = (COLOR *)malloc(xres*sizeof(COLOR)); | 
| 431 |  | fprintf(stderr, "%s: out of memory\n", progname); | 
| 432 |  | quit(1); | 
| 433 |  | } | 
| 434 | < | e = bright(exposure); | 
| 435 | < | if (e < 1-1e-7 || e > 1+1e-7)           /* record exposure */ | 
| 436 | < | fputexpos(e, stdout); | 
| 434 | > | /* record pixel aspect ratio */ | 
| 435 | > | if (!correctaspect) { | 
| 436 | > | d = order & YMAJOR ? x_c/y_r : y_r/x_c ; | 
| 437 | > | if (!FEQ(d,1.0)) | 
| 438 | > | fputaspect(d, stdout); | 
| 439 | > | } | 
| 440 | > | /* record exposure */ | 
| 441 | > | d = bright(exposure); | 
| 442 | > | if (!FEQ(d,1.0)) | 
| 443 | > | fputexpos(d, stdout); | 
| 444 | > | /* record color correction */ | 
| 445 | > | copycolor(ctmp, exposure); | 
| 446 | > | scalecolor(ctmp, 1.0/d); | 
| 447 | > | if (!FEQ(colval(ctmp,RED),colval(ctmp,GRN)) || | 
| 448 | > | !FEQ(colval(ctmp,GRN),colval(ctmp,BLU))) | 
| 449 | > | fputcolcor(ctmp, stdout); | 
| 450 |  | printf("\n"); | 
| 451 | < | fputresolu(YMAJOR|YDECR, ncols, nrows, stdout); /* resolution */ | 
| 451 | > | /* write out resolution */ | 
| 452 | > | fputresolu(order, ncols, nrows, stdout); | 
| 453 |  | } | 
| 454 |  |  | 
| 455 |  |  |