| 1 | – | /* Copyright (c) 1992 Regents of the University of California */ | 
| 2 | – |  | 
| 1 |  | #ifndef lint | 
| 2 | < | static char SCCSid[] = "$SunId$ LBL"; | 
| 2 | > | static const char RCSid[] = "$Id$"; | 
| 3 |  | #endif | 
| 6 | – |  | 
| 4 |  | /* | 
| 5 |  | *  pfilt.c - program to post-process picture file. | 
| 6 |  | * | 
| 8 |  | *     6/23/93  Added additional buffers for value spreading | 
| 9 |  | */ | 
| 10 |  |  | 
| 11 | < | #include  "standard.h" | 
| 11 | > | #include  "copyright.h" | 
| 12 |  |  | 
| 13 |  | #include  <signal.h> | 
| 14 | + | #include  <string.h> | 
| 15 |  |  | 
| 16 | + | #include  "platform.h" | 
| 17 | + | #include  "standard.h" | 
| 18 | + | #include  "rtio.h" | 
| 19 |  | #include  "color.h" | 
| 20 | < |  | 
| 20 | < | #include  "resolu.h" | 
| 21 | < |  | 
| 20 | > | #include  "view.h" | 
| 21 |  | #include  "paths.h" | 
| 22 | + | #include  "pfilt.h" | 
| 23 |  |  | 
| 24 | – | extern float  *matchlamp(); | 
| 24 |  |  | 
| 25 |  | #define  FEQ(a,b)       ((a) >= .98*(b) && (a) <= 1.02*(b)) | 
| 26 |  |  | 
| 27 | < | double   CHECKRAD = 1.5;        /* radius to check for filtering */ | 
| 27 | > | double   CHECKRAD = 2.0;        /* radius to check for filtering */ | 
| 28 |  |  | 
| 29 |  | #define  THRESHRAD      5.0     /* maximum sample spread in output */ | 
| 30 |  |  | 
| 63 |  |  | 
| 64 |  | int  wrongformat = 0; | 
| 65 |  |  | 
| 66 | + | VIEW  ourview = STDVIEW; | 
| 67 | + | int  gotview = 0; | 
| 68 | + | int  wrapfilt = 0;              /* wrap filter horizontally? */ | 
| 69 | + |  | 
| 70 | + | int  estatus = 0;               /* exit status (for non-fatal errors) */ | 
| 71 | + |  | 
| 72 |  | int  xrad;                      /* x search radius */ | 
| 73 |  | int  yrad;                      /* y search radius */ | 
| 74 |  | int  xbrad;                     /* x box size */ | 
| 84 |  |  | 
| 85 |  | char  *progname; | 
| 86 |  |  | 
| 87 | + | static gethfunc headline; | 
| 88 | + | static brightfunc_t rgb_bright; | 
| 89 | + | static brightfunc_t xyz_bright; | 
| 90 | + | static void copyfile(FILE  *in, FILE  *out); | 
| 91 | + | static void pass1(FILE  *in); | 
| 92 | + | static void pass2(FILE  *in); | 
| 93 | + | static void scan2init(void); | 
| 94 | + | static void scan2sync(int  r); | 
| 95 | + | static void scan2flush(void); | 
| 96 |  |  | 
| 97 | < | main(argc, argv) | 
| 98 | < | int  argc; | 
| 99 | < | char  **argv; | 
| 97 | > |  | 
| 98 | > | int | 
| 99 | > | main( | 
| 100 | > | int  argc, | 
| 101 | > | char  **argv | 
| 102 | > | ) | 
| 103 |  | { | 
| 87 | – | extern long  ftell(); | 
| 88 | – | extern int  quit(), headline(); | 
| 104 |  | FILE  *fin; | 
| 105 |  | float  *lampcolor; | 
| 106 |  | char  *lamptype = NULL; | 
| 108 |  | double  outaspect = 0.0; | 
| 109 |  | double  d; | 
| 110 |  | int  i, j; | 
| 111 | < | #ifdef MSDOS | 
| 112 | < | extern int  _fmode; | 
| 113 | < | _fmode = O_BINARY; | 
| 99 | < | setmode(fileno(stdin), O_BINARY); | 
| 100 | < | setmode(fileno(stdout), O_BINARY); | 
| 101 | < | #endif | 
| 111 | > | SET_DEFAULT_BINARY(); | 
| 112 | > | SET_FILE_BINARY(stdin); | 
| 113 | > | SET_FILE_BINARY(stdout); | 
| 114 |  | if (signal(SIGINT, quit) == SIG_IGN) | 
| 115 |  | signal(SIGINT, SIG_IGN); | 
| 116 | + | #ifdef SIGHUP | 
| 117 |  | if (signal(SIGHUP, quit) == SIG_IGN) | 
| 118 |  | signal(SIGHUP, SIG_IGN); | 
| 119 | + | #endif | 
| 120 |  | signal(SIGTERM, quit); | 
| 121 | + | #ifdef SIGPIPE | 
| 122 |  | signal(SIGPIPE, quit); | 
| 123 | + | #endif | 
| 124 |  | #ifdef  SIGXCPU | 
| 125 |  | signal(SIGXCPU, quit); | 
| 126 |  | signal(SIGXFSZ, quit); | 
| 163 |  | fprintf(stderr, | 
| 164 |  | "%s: exposure out of range\n", | 
| 165 |  | argv[0]); | 
| 166 | < | exit(1); | 
| 166 | > | quit(1); | 
| 167 |  | } | 
| 168 |  | switch (argv[i][2]) { | 
| 169 |  | case '\0': | 
| 213 |  | case 'm': | 
| 214 |  | thresh = atof(argv[++i]); | 
| 215 |  | if (rad <= FTINY) | 
| 216 | < | rad = 1.0; | 
| 216 | > | rad = 0.6; | 
| 217 |  | break; | 
| 218 |  | case 'b': | 
| 219 |  | rad = thresh = 0.0; | 
| 283 |  | } | 
| 284 |  | if (!(order & YMAJOR)) | 
| 285 |  | inpaspect = 1.0/inpaspect; | 
| 286 | + | /* wrap around for cylindrical view? */ | 
| 287 | + | wrapfilt = gotview && ourview.type == VT_CYL && | 
| 288 | + | ourview.horiz >= 360.-FTINY && order & YMAJOR; | 
| 289 |  | /* compute output resolution */ | 
| 290 |  | if (ncols <= 0) | 
| 291 |  | ncols = x_c*xres + .5; | 
| 317 |  | } | 
| 318 |  | pass2(fin); | 
| 319 |  |  | 
| 320 | < | quit(0); | 
| 320 | > | quit(estatus); | 
| 321 | > | return estatus; /* pro forma return */ | 
| 322 |  | } | 
| 323 |  |  | 
| 324 |  |  | 
| 325 | < | double | 
| 326 | < | rgb_bright(clr) | 
| 327 | < | COLOR  clr; | 
| 325 | > | static double | 
| 326 | > | rgb_bright( | 
| 327 | > | COLOR  clr | 
| 328 | > | ) | 
| 329 |  | { | 
| 330 |  | return(bright(clr)); | 
| 331 |  | } | 
| 332 |  |  | 
| 333 |  |  | 
| 334 | < | double | 
| 335 | < | xyz_bright(clr) | 
| 336 | < | COLOR  clr; | 
| 334 | > | static double | 
| 335 | > | xyz_bright( | 
| 336 | > | COLOR  clr | 
| 337 | > | ) | 
| 338 |  | { | 
| 339 |  | return(clr[CIEY]); | 
| 340 |  | } | 
| 341 |  |  | 
| 342 |  |  | 
| 343 | < | double  (*ourbright)() = rgb_bright; | 
| 343 | > | brightfunc_t *ourbright = rgb_bright; | 
| 344 |  |  | 
| 345 | < |  | 
| 346 | < | headline(s)                             /* process line from header */ | 
| 347 | < | char  *s; | 
| 345 | > | static int | 
| 346 | > | headline(                               /* process line from header */ | 
| 347 | > | char    *s, | 
| 348 | > | void    *p | 
| 349 | > | ) | 
| 350 |  | { | 
| 351 |  | char  fmt[32]; | 
| 352 |  |  | 
| 363 |  | ourbright = xyz_bright; | 
| 364 |  | else | 
| 365 |  | wrongformat = !globmatch(PICFMT, fmt); | 
| 366 | < | } | 
| 366 | > | } else if (isview(s) && sscanview(&ourview, s) > 0) | 
| 367 | > | gotview++; | 
| 368 | > | return(0); | 
| 369 |  | } | 
| 370 |  |  | 
| 371 |  |  | 
| 372 | < | copyfile(in, out)                       /* copy a file */ | 
| 373 | < | register FILE  *in, *out; | 
| 372 | > | static void | 
| 373 | > | copyfile(                       /* copy a file */ | 
| 374 | > | register FILE  *in, | 
| 375 | > | register FILE  *out | 
| 376 | > | ) | 
| 377 |  | { | 
| 378 |  | register int  c; | 
| 379 |  |  | 
| 387 |  | } | 
| 388 |  |  | 
| 389 |  |  | 
| 390 | < | pass1(in)                               /* first pass of picture file */ | 
| 391 | < | FILE  *in; | 
| 390 | > | static void | 
| 391 | > | pass1(                          /* first pass of picture file */ | 
| 392 | > | FILE  *in | 
| 393 | > | ) | 
| 394 |  | { | 
| 395 |  | int  i; | 
| 396 |  | COLOR  *scan; | 
| 413 |  | progname, (int)(100L*i/yres)); | 
| 414 |  | yres = i; | 
| 415 |  | y_r = (double)nrows/yres; | 
| 416 | + | estatus++; | 
| 417 |  | break; | 
| 418 |  | } | 
| 419 |  | pass1scan(scan, i); | 
| 420 |  | } | 
| 421 | < | free((char *)scan); | 
| 421 | > | free((void *)scan); | 
| 422 |  | } | 
| 423 |  |  | 
| 424 |  |  | 
| 425 | < | pass2(in)                       /* last pass on file, write to stdout */ | 
| 426 | < | FILE  *in; | 
| 425 | > | static void | 
| 426 | > | pass2(                  /* last pass on file, write to stdout */ | 
| 427 | > | FILE  *in | 
| 428 | > | ) | 
| 429 |  | { | 
| 430 |  | int  yread; | 
| 431 |  | int  ycent, xcent; | 
| 435 |  | scan2init(); | 
| 436 |  | yread = 0; | 
| 437 |  | for (r = 0; r < nrows; r++) { | 
| 438 | < | ycent = (long)r*yres/nrows; | 
| 438 | > | ycent = (r+.5)*yres/nrows; | 
| 439 |  | while (yread <= ycent+yrad) { | 
| 440 |  | if (yread < yres) { | 
| 441 |  | if (freadscan(scanin[yread%barsize], | 
| 452 |  | if (obarsize > 0) | 
| 453 |  | scan2sync(r); | 
| 454 |  | for (c = 0; c < ncols; c++) { | 
| 455 | < | xcent = (long)c*xres/ncols; | 
| 455 | > | xcent = (c+.5)*xres/ncols; | 
| 456 |  | if (thresh > FTINY) | 
| 457 |  | dothresh(xcent, ycent, c, r); | 
| 458 |  | else if (rad > FTINY) | 
| 475 |  | } | 
| 476 |  |  | 
| 477 |  |  | 
| 478 | < | scan2init()                     /* prepare scanline arrays */ | 
| 478 | > | static void | 
| 479 | > | scan2init(void)                 /* prepare scanline arrays */ | 
| 480 |  | { | 
| 481 |  | COLOR   ctmp; | 
| 482 |  | double  d; | 
| 489 |  | rad *= (y_r + x_c)/2.0; | 
| 490 |  |  | 
| 491 |  | if (thresh > FTINY) { | 
| 457 | – | xrad = CHECKRAD*THRESHRAD*rad/x_c + xbrad; | 
| 458 | – | yrad = CHECKRAD*THRESHRAD*rad/y_r + ybrad; | 
| 492 |  | orad = CHECKRAD*THRESHRAD*rad + 1; | 
| 493 | + | xrad = orad/x_c + xbrad; | 
| 494 | + | yrad = orad/y_r + ybrad; | 
| 495 |  | obarsize = 2*orad + 1; | 
| 496 |  | } else { | 
| 497 |  | xrad = CHECKRAD*rad/x_c + 1; | 
| 514 |  | if (obarsize > 0) { | 
| 515 |  | scoutbar = (COLOR **)malloc(obarsize*sizeof(COLOR *)); | 
| 516 |  | greybar = (float **)malloc(obarsize*sizeof(float *)); | 
| 517 | < | if (scoutbar == NULL | greybar == NULL) | 
| 517 | > | if ((scoutbar == NULL) | (greybar == NULL)) | 
| 518 |  | goto memerr; | 
| 519 |  | for (i = 0; i < obarsize; i++) { | 
| 520 |  | scoutbar[i] = (COLOR *)malloc(ncols*sizeof(COLOR)); | 
| 521 |  | greybar[i] = (float *)malloc(ncols*sizeof(float)); | 
| 522 | < | if (scoutbar[i] == NULL | greybar[i] == NULL) | 
| 522 | > | if ((scoutbar[i] == NULL) | (greybar[i] == NULL)) | 
| 523 |  | goto memerr; | 
| 524 |  | } | 
| 525 |  | } else { | 
| 553 |  | } | 
| 554 |  |  | 
| 555 |  |  | 
| 556 | < | scan2sync(r)                    /* synchronize grey averages and output scan */ | 
| 557 | < | int  r; | 
| 556 | > | static void | 
| 557 | > | scan2sync(                      /* synchronize grey averages and output scan */ | 
| 558 | > | int  r | 
| 559 | > | ) | 
| 560 |  | { | 
| 561 |  | static int  nextrow = 0; | 
| 562 |  | COLOR  ctmp; | 
| 563 |  | int  ybot; | 
| 564 |  | register int  c; | 
| 565 |  | /* average input scanlines */ | 
| 566 | < | while (nextrow < r+orad && nextrow < nrows) { | 
| 567 | < | ybot = (long)nextrow*yres/nrows; | 
| 566 | > | while (nextrow <= r+orad && nextrow < nrows) { | 
| 567 | > | ybot = (nextrow+.5)*yres/nrows; | 
| 568 |  | for (c = 0; c < ncols; c++) { | 
| 569 | < | dobox(ctmp, (int)((long)c*xres/ncols),ybot, c,nextrow); | 
| 569 | > | dobox(ctmp, (int)((c+.5)*xres/ncols),ybot, c,nextrow); | 
| 570 |  | greybar[nextrow%obarsize][c] = (*ourbright)(ctmp); | 
| 571 |  | } | 
| 572 |  | /* and zero output scanline */ | 
| 573 | < | bzero((char *)scoutbar[nextrow%obarsize], ncols*sizeof(COLOR)); | 
| 573 | > | memset((char *)scoutbar[nextrow%obarsize], '\0', ncols*sizeof(COLOR)); | 
| 574 |  | nextrow++; | 
| 575 |  | } | 
| 576 |  | /* point to top scanline for output */ | 
| 581 |  | } | 
| 582 |  |  | 
| 583 |  |  | 
| 584 | < | scan2flush()                    /* flush output buffer */ | 
| 584 | > | static void | 
| 585 | > | scan2flush(void)                        /* flush output buffer */ | 
| 586 |  | { | 
| 587 |  | register int  r; | 
| 588 |  |  | 
| 591 |  | break; | 
| 592 |  | if (fflush(stdout) < 0) { | 
| 593 |  | fprintf(stderr, "%s: write error at end of pass2\n", progname); | 
| 594 | < | exit(1); | 
| 594 | > | quit(1); | 
| 595 |  | } | 
| 596 |  | } | 
| 597 |  |  | 
| 598 |  |  | 
| 599 | + | void | 
| 600 |  | quit(code)              /* remove temporary file and exit */ | 
| 601 |  | int  code; | 
| 602 |  | { |