| 10 | 
  | 
 * Warping code depends on conformance of COLOR and W3VEC types. | 
| 11 | 
  | 
 */ | 
| 12 | 
  | 
 | 
| 13 | 
– | 
#include <stdio.h> | 
| 13 | 
  | 
#include <math.h> | 
| 15 | 
– | 
#include <time.h> | 
| 14 | 
  | 
 | 
| 15 | 
  | 
#include "platform.h" | 
| 16 | 
< | 
#include "rtprocess.h" | 
| 16 | 
> | 
#include "paths.h" | 
| 17 | 
  | 
#include "rtio.h" | 
| 18 | 
  | 
#include "color.h" | 
| 19 | 
  | 
#include "resolu.h" | 
| 46 | 
  | 
#define Neutral5        21 | 
| 47 | 
  | 
#define Neutral35       22 | 
| 48 | 
  | 
#define Black           23 | 
| 49 | 
< | 
                                /* computed from 5nm spectral measurements */ | 
| 49 | 
> | 
                                /* computed from 10nm spectral measurements */ | 
| 50 | 
  | 
                                /* CIE 1931 2 degree obs, equal-energy white */ | 
| 51 | 
  | 
float   mbxyY[24][3] = { | 
| 52 | 
< | 
                {0.462, 0.3769, 0.0932961},     /* DarkSkin */ | 
| 53 | 
< | 
                {0.4108, 0.3542, 0.410348},     /* LightSkin */ | 
| 54 | 
< | 
                {0.2626, 0.267, 0.181554},      /* BlueSky */ | 
| 55 | 
< | 
                {0.36, 0.4689, 0.108447},       /* Foliage */ | 
| 56 | 
< | 
                {0.2977, 0.2602, 0.248407},     /* BlueFlower */ | 
| 57 | 
< | 
                {0.2719, 0.3485, 0.401156},     /* BluishGreen */ | 
| 58 | 
< | 
                {0.52, 0.4197, 0.357899},       /* Orange */ | 
| 59 | 
< | 
                {0.229, 0.1866, 0.103911},      /* PurplishBlue */ | 
| 60 | 
< | 
                {0.4909, 0.3262, 0.242615},     /* ModerateRed */ | 
| 61 | 
< | 
                {0.3361, 0.2249, 0.0600102},    /* Purple */ | 
| 62 | 
< | 
                {0.3855, 0.4874, 0.42963},      /* YellowGreen */ | 
| 63 | 
< | 
                {0.4853, 0.4457, 0.476343},     /* OrangeYellow */ | 
| 64 | 
< | 
                {0.2026, 0.1369, 0.0529249},    /* Blue */ | 
| 65 | 
< | 
                {0.3007, 0.4822, 0.221226},     /* Green */ | 
| 66 | 
< | 
                {0.5805, 0.3238, 0.162167},     /* Red */ | 
| 67 | 
< | 
                {0.4617, 0.472, 0.64909},       /* Yellow */ | 
| 68 | 
< | 
                {0.4178, 0.2625, 0.233662},     /* Magenta */ | 
| 69 | 
< | 
                {0.2038, 0.2508, 0.167275},     /* Cyan */ | 
| 70 | 
< | 
                {0.3358, 0.337, 0.916877},      /* White */ | 
| 71 | 
< | 
                {0.3338, 0.3348, 0.604678},     /* Neutral.8 */ | 
| 72 | 
< | 
                {0.3333, 0.3349, 0.364566},     /* Neutral.65 */ | 
| 73 | 
< | 
                {0.3353, 0.3359, 0.200238},     /* Neutral.5 */ | 
| 74 | 
< | 
                {0.3363, 0.336, 0.0878721},     /* Neutral.35 */ | 
| 75 | 
< | 
                {0.3346, 0.3349, 0.0308383}     /* Black */ | 
| 52 | 
> | 
                {0.421236, 0.361196, 0.103392},         /* DarkSkin */ | 
| 53 | 
> | 
                {0.40868, 0.358157, 0.352867},          /* LightSkin */ | 
| 54 | 
> | 
                {0.265063, 0.271424, 0.185124},         /* BlueSky */ | 
| 55 | 
> | 
                {0.362851, 0.43055, 0.132625},          /* Foliage */ | 
| 56 | 
> | 
                {0.28888, 0.260851, 0.233138},          /* BlueFlower */ | 
| 57 | 
> | 
                {0.277642, 0.365326, 0.416443},         /* BluishGreen */ | 
| 58 | 
> | 
                {0.524965, 0.40068, 0.312039},          /* Orange */ | 
| 59 | 
> | 
                {0.225018, 0.190392, 0.114999},         /* PurplishBlue */ | 
| 60 | 
> | 
                {0.487199, 0.315372, 0.198616},         /* ModerateRed */ | 
| 61 | 
> | 
                {0.314245, 0.227231, 0.0646047},        /* Purple */ | 
| 62 | 
> | 
                {0.396202, 0.489732, 0.440724},         /* YellowGreen */ | 
| 63 | 
> | 
                {0.493297, 0.435299, 0.43444},          /* OrangeYellow */ | 
| 64 | 
> | 
                {0.198191, 0.149265, 0.0588122},        /* Blue */ | 
| 65 | 
> | 
                {0.322838, 0.487601, 0.229258},         /* Green */ | 
| 66 | 
> | 
                {0.561833, 0.321165, 0.126978},         /* Red */ | 
| 67 | 
> | 
                {0.468113, 0.467021, 0.605289},         /* Yellow */ | 
| 68 | 
> | 
                {0.397128, 0.248535, 0.201761},         /* Magenta */ | 
| 69 | 
> | 
                {0.209552, 0.276256, 0.190917},         /* Cyan */ | 
| 70 | 
> | 
                {0.337219, 0.339042, 0.912482},         /* White */ | 
| 71 | 
> | 
                {0.333283, 0.335077, 0.588297},         /* Neutral.8 */ | 
| 72 | 
> | 
                {0.332747, 0.334371, 0.3594},           /* Neutral.65 */ | 
| 73 | 
> | 
                {0.331925, 0.334202, 0.19114},          /* Neutral.5 */ | 
| 74 | 
> | 
                {0.330408, 0.332615, 0.0892964},        /* Neutral.35 */ | 
| 75 | 
> | 
                {0.331841, 0.331405, 0.0319541},        /* Black */ | 
| 76 | 
  | 
        }; | 
| 77 | 
  | 
 | 
| 78 | 
  | 
COLOR   mbRGB[24];              /* MacBeth RGB values */ | 
| 99 | 
  | 
#define  RG_CORR        04      /* corrected color region */ | 
| 100 | 
  | 
 | 
| 101 | 
  | 
#ifndef  DISPCOM | 
| 102 | 
< | 
#define  DISPCOM        "ximage -op \"%s\"" | 
| 102 | 
> | 
#define  DISPCOM        "ximage -e auto -op \"%s\"" | 
| 103 | 
  | 
#endif | 
| 104 | 
  | 
 | 
| 105 | 
  | 
int     scanning = 1;           /* scanned input (or recorded output)? */ | 
| 128 | 
  | 
static void getpicture(void); | 
| 129 | 
  | 
static void getcolors(void); | 
| 130 | 
  | 
static void bresp(COLOR y, COLOR        x); | 
| 131 | 
+ | 
static void ibresp(COLOR        y, COLOR        x); | 
| 132 | 
  | 
static void compute(void); | 
| 133 | 
  | 
static void putmapping(void); | 
| 134 | 
  | 
static void compsoln(COLOR      cin[], COLOR    cout[], int     n); | 
| 235 | 
  | 
                getcolors(); | 
| 236 | 
  | 
        compute();                      /* compute color mapping */ | 
| 237 | 
  | 
        if (rawmap) {                   /* print out raw correspondence */ | 
| 238 | 
< | 
                register int    j; | 
| 238 | 
> | 
                int     j; | 
| 239 | 
  | 
 | 
| 240 | 
  | 
                printf("# Color correspondence produced by:\n#\t\t"); | 
| 241 | 
  | 
                printargs(argc, argv, stdout); | 
| 284 | 
  | 
init(void)                              /* initialize */ | 
| 285 | 
  | 
{ | 
| 286 | 
  | 
        double  quad[4][2]; | 
| 287 | 
< | 
        register int    i; | 
| 287 | 
> | 
        int     i; | 
| 288 | 
  | 
                                        /* make coordinate transformation */ | 
| 289 | 
  | 
        quad[0][0] = bounds[0][0]; | 
| 290 | 
  | 
        quad[0][1] = bounds[0][1]; | 
| 324 | 
  | 
        mx3d_transform(ipos, imgxfm, cpos); | 
| 325 | 
  | 
        cpos[0] /= cpos[2]; | 
| 326 | 
  | 
        cpos[1] /= cpos[2]; | 
| 327 | 
< | 
        if (cpos[0] < 0. || cpos[0] >= 6. || cpos[1] < 0. || cpos[1] >= 4.) | 
| 327 | 
> | 
        if ((cpos[0] < 0.) | (cpos[0] >= 6.) | (cpos[1] < 0.) | (cpos[1] >= 4.)) | 
| 328 | 
  | 
                return(RG_BORD); | 
| 329 | 
  | 
        ix = cpos[0]; | 
| 330 | 
  | 
        iy = cpos[1]; | 
| 331 | 
  | 
        fx = cpos[0] - ix; | 
| 332 | 
  | 
        fy = cpos[1] - iy; | 
| 333 | 
  | 
        *np = iy*6 + ix; | 
| 334 | 
< | 
        if (fx >= 0.35 && fx < 0.65 && fy >= 0.35 && fy < 0.65) | 
| 334 | 
> | 
        if ((fx >= 0.35) & (fx < 0.65) & (fy >= 0.35) & (fy < 0.65)) | 
| 335 | 
  | 
                return(RG_CENT); | 
| 336 | 
< | 
        if (fx < 0.05 || fx >= 0.95 || fy < 0.05 || fy >= 0.95) | 
| 336 | 
> | 
        if ((fx < 0.05) | (fx >= 0.95) | (fy < 0.05) | (fy >= 0.95)) | 
| 337 | 
  | 
                return(RG_BORD); | 
| 338 | 
  | 
        if (fx >= 0.5)                  /* right side is corrected */ | 
| 339 | 
  | 
                return(RG_CORR); | 
| 349 | 
  | 
        int     ccount[24]; | 
| 350 | 
  | 
        double  d; | 
| 351 | 
  | 
        int     y, i; | 
| 352 | 
< | 
        register int    x; | 
| 352 | 
> | 
        int     x; | 
| 353 | 
  | 
 | 
| 354 | 
  | 
        scanln = (COLR *)malloc(xmax*sizeof(COLR)); | 
| 355 | 
  | 
        if (scanln == NULL) { | 
| 435 | 
  | 
 | 
| 436 | 
  | 
static void | 
| 437 | 
  | 
bresp(          /* piecewise linear interpolation of primaries */ | 
| 438 | 
< | 
        COLOR   y, | 
| 439 | 
< | 
        COLOR   x | 
| 438 | 
> | 
        COLOR   y,              /* y is linear output */ | 
| 439 | 
> | 
        COLOR   x               /* x is non-linear input */ | 
| 440 | 
  | 
) | 
| 441 | 
  | 
{ | 
| 442 | 
< | 
        register int    i, n; | 
| 442 | 
> | 
        int     i, n; | 
| 443 | 
  | 
 | 
| 444 | 
  | 
        for (i = 0; i < 3; i++) { | 
| 445 | 
  | 
                for (n = 0; n < NMBNEU-2; n++) | 
| 455 | 
  | 
 | 
| 456 | 
  | 
 | 
| 457 | 
  | 
static void | 
| 458 | 
+ | 
ibresp(         /* inverse mapping (delinearization) */ | 
| 459 | 
+ | 
        COLOR   x,              /* x is non-linear output */ | 
| 460 | 
+ | 
        COLOR   y               /* y is linear input */ | 
| 461 | 
+ | 
) | 
| 462 | 
+ | 
{ | 
| 463 | 
+ | 
        int     i, n; | 
| 464 | 
+ | 
 | 
| 465 | 
+ | 
        for (i = 0; i < 3; i++) { | 
| 466 | 
+ | 
                for (n = 0; n < NMBNEU-2; n++) | 
| 467 | 
+ | 
                        if (colval(y,i) < colval(bramp[n+1][1],i)) | 
| 468 | 
+ | 
                                break; | 
| 469 | 
+ | 
                colval(x,i) = ((colval(bramp[n+1][1],i) - colval(y,i)) * | 
| 470 | 
+ | 
                                                colval(bramp[n][0],i) + | 
| 471 | 
+ | 
                                (colval(y,i) - colval(bramp[n][1],i)) * | 
| 472 | 
+ | 
                                                colval(bramp[n+1][0],i)) / | 
| 473 | 
+ | 
                        (colval(bramp[n+1][1],i) - colval(bramp[n][1],i)); | 
| 474 | 
+ | 
        } | 
| 475 | 
+ | 
} | 
| 476 | 
+ | 
 | 
| 477 | 
+ | 
 | 
| 478 | 
+ | 
static void | 
| 479 | 
  | 
compute(void)                   /* compute color mapping */ | 
| 480 | 
  | 
{ | 
| 481 | 
  | 
        COLOR   clrin[24], clrout[24]; | 
| 482 | 
  | 
        long    cflags; | 
| 483 | 
  | 
        COLOR   ctmp; | 
| 484 | 
< | 
        register int    i, n; | 
| 484 | 
> | 
        int     i, n; | 
| 485 | 
  | 
                                        /* did we get what we need? */ | 
| 486 | 
  | 
        if ((inpflags & REQFLGS) != REQFLGS) { | 
| 487 | 
  | 
                fprintf(stderr, "%s: missing required input colors\n", | 
| 491 | 
  | 
                                        /* compute piecewise luminance curve */ | 
| 492 | 
  | 
        for (i = 0; i < NMBNEU; i++) { | 
| 493 | 
  | 
                copycolor(bramp[i][0], inpRGB[mbneu[i]]); | 
| 494 | 
< | 
                for (n = i ? 3 : 0; n--; ) | 
| 494 | 
> | 
                for (n = 3*(i>0); n--; ) | 
| 495 | 
  | 
                        if (colval(bramp[i][0],n) <= | 
| 496 | 
  | 
                                        colval(bramp[i-1][0],n)+1e-7) { | 
| 497 | 
  | 
                                fprintf(stderr, | 
| 501 | 
  | 
                copycolor(bramp[i][1], mbRGB[mbneu[i]]); | 
| 502 | 
  | 
        } | 
| 503 | 
  | 
                                        /* compute color space gamut */ | 
| 504 | 
< | 
        if (scanning) { | 
| 505 | 
< | 
                copycolor(colmin, cblack); | 
| 506 | 
< | 
                copycolor(colmax, cwhite); | 
| 507 | 
< | 
                scalecolor(colmax, irrad); | 
| 508 | 
< | 
        } else | 
| 509 | 
< | 
                for (i = 0; i < 3; i++) { | 
| 510 | 
< | 
                        colval(colmin,i) = colval(bramp[0][0],i) - | 
| 491 | 
< | 
                                colval(bramp[0][1],i) * | 
| 492 | 
< | 
                                (colval(bramp[1][0],i)-colval(bramp[0][0],i)) / | 
| 493 | 
< | 
                                (colval(bramp[1][1],i)-colval(bramp[1][0],i)); | 
| 494 | 
< | 
                        colval(colmax,i) = colval(bramp[NMBNEU-2][0],i) + | 
| 495 | 
< | 
                                (1.-colval(bramp[NMBNEU-2][1],i)) * | 
| 496 | 
< | 
                                (colval(bramp[NMBNEU-1][0],i) - | 
| 497 | 
< | 
                                        colval(bramp[NMBNEU-2][0],i)) / | 
| 498 | 
< | 
                                (colval(bramp[NMBNEU-1][1],i) - | 
| 499 | 
< | 
                                        colval(bramp[NMBNEU-2][1],i)); | 
| 500 | 
< | 
                } | 
| 504 | 
> | 
        copycolor(colmin, cblack); | 
| 505 | 
> | 
        copycolor(colmax, cwhite); | 
| 506 | 
> | 
        scalecolor(colmax, irrad); | 
| 507 | 
> | 
        if (!scanning) { | 
| 508 | 
> | 
                ibresp(colmin, colmin); | 
| 509 | 
> | 
                ibresp(colmax, colmax); | 
| 510 | 
> | 
        } | 
| 511 | 
  | 
                                        /* compute color mapping */ | 
| 512 | 
  | 
        do { | 
| 513 | 
  | 
                cflags = inpflags & ~gmtflags; | 
| 514 | 
  | 
                n = 0;                          /* compute transform matrix */ | 
| 515 | 
< | 
                for (i = 0; i < 24; i++) | 
| 516 | 
< | 
                        if (cflags & 1L<<i) { | 
| 515 | 
> | 
                for (i = 0; i < 24; i++) { | 
| 516 | 
> | 
                        if (!(cflags & 1L<<i)) | 
| 517 | 
> | 
                                continue; | 
| 518 | 
> | 
                        if (scanning) { | 
| 519 | 
  | 
                                bresp(clrin[n], inpRGB[i]); | 
| 520 | 
  | 
                                copycolor(clrout[n], mbRGB[i]); | 
| 521 | 
< | 
                                n++; | 
| 521 | 
> | 
                        } else { | 
| 522 | 
> | 
                                copycolor(clrin[n], inpRGB[i]); | 
| 523 | 
> | 
                                ibresp(clrout[n], mbRGB[i]); | 
| 524 | 
  | 
                        } | 
| 525 | 
+ | 
                        n++; | 
| 526 | 
+ | 
                } | 
| 527 | 
  | 
                compsoln(clrin, clrout, n); | 
| 528 | 
< | 
                if (irrad > 0.99 && irrad < 1.01)       /* check gamut */ | 
| 529 | 
< | 
                        for (i = 0; i < 24; i++) | 
| 530 | 
< | 
                                if (cflags & 1L<<i && cvtcolor(ctmp, mbRGB[i])) | 
| 515 | 
< | 
                                        gmtflags |= 1L<<i; | 
| 528 | 
> | 
                for (i = 0; i < 24; i++)        /* check gamut */ | 
| 529 | 
> | 
                        if (cflags & 1L<<i && cvtcolor(ctmp, inpRGB[i])) | 
| 530 | 
> | 
                                gmtflags |= 1L<<i; | 
| 531 | 
  | 
        } while (cflags & gmtflags); | 
| 532 | 
+ | 
 | 
| 533 | 
  | 
        if (gmtflags & MODFLGS) | 
| 534 | 
  | 
                fprintf(stderr, | 
| 535 | 
  | 
                "%s: warning - some moderate colors are out of gamut\n", | 
| 541 | 
  | 
putmapping(void)                        /* put out color mapping */ | 
| 542 | 
  | 
{ | 
| 543 | 
  | 
        static char     cchar[3] = {'r', 'g', 'b'}; | 
| 544 | 
< | 
        register int    i, j; | 
| 544 | 
> | 
        int     i, j; | 
| 545 | 
  | 
                                        /* print brightness mapping */ | 
| 546 | 
  | 
        for (j = 0; j < 3; j++) { | 
| 547 | 
  | 
                printf("%cxa(i) : select(i", cchar[j]); | 
| 597 | 
  | 
        double  mat[3][3], invmat[3][3]; | 
| 598 | 
  | 
        double  det; | 
| 599 | 
  | 
        double  colv[3], rowv[3]; | 
| 600 | 
< | 
        register int    i, j, k; | 
| 600 | 
> | 
        int     i, j, k; | 
| 601 | 
  | 
 | 
| 602 | 
  | 
        if (n < 3) { | 
| 603 | 
  | 
                fprintf(stderr, "%s: too few colors to match!\n", progname); | 
| 652 | 
  | 
static void | 
| 653 | 
  | 
cwarp(void)                             /* compute color warp map */ | 
| 654 | 
  | 
{ | 
| 655 | 
< | 
        register int    i; | 
| 655 | 
> | 
        int     i; | 
| 656 | 
  | 
 | 
| 657 | 
  | 
        if ((wcor = new3dw(W3EXACT)) == NULL) | 
| 658 | 
  | 
                goto memerr; | 
| 703 | 
  | 
static void | 
| 704 | 
  | 
xyY2RGB(                /* convert xyY to RGB */ | 
| 705 | 
  | 
        COLOR   rgbout, | 
| 706 | 
< | 
        register float  xyYin[3] | 
| 706 | 
> | 
        float   xyYin[3] | 
| 707 | 
  | 
) | 
| 708 | 
  | 
{ | 
| 709 | 
  | 
        COLOR   ctmp; | 
| 724 | 
  | 
        static COLOR    blkcol = BLKCOLOR; | 
| 725 | 
  | 
        COLOR   *scan; | 
| 726 | 
  | 
        int     y, i; | 
| 727 | 
< | 
        register int    x, rg; | 
| 727 | 
> | 
        int     x, rg; | 
| 728 | 
  | 
 | 
| 729 | 
  | 
        if (fseek(stdin, 0L, 0) == EOF) { | 
| 730 | 
  | 
                fprintf(stderr, "%s: cannot seek on input picture\n", progname); | 
| 783 | 
  | 
        COLR    *scan; | 
| 784 | 
  | 
        COLOR   ctmp, ct2; | 
| 785 | 
  | 
        int     y, i; | 
| 786 | 
< | 
        register int    x, rg; | 
| 786 | 
> | 
        int     x, rg; | 
| 787 | 
  | 
                                                /* convert colors */ | 
| 788 | 
  | 
        for (i = 0; i < 24; i++) { | 
| 789 | 
  | 
                copycolor(ctmp, mbRGB[i]); |