| 51 | 
  | 
 | 
| 52 | 
  | 
#define NMBNEU          6       /* Number of MacBeth neutral colors */ | 
| 53 | 
  | 
short   mbneu[NMBNEU] = {23,22,21,20,19,18}; | 
| 54 | 
< | 
#define NMBMOD          3       /* Number of MacBeth moderate colors */ | 
| 55 | 
< | 
short   mbmod[NMBMOD] = {1,2,21}; | 
| 54 | 
> | 
#define NMBMOD          16      /* Number of MacBeth unsaturated colors */ | 
| 55 | 
> | 
short   mbmod[NMBMOD] = {0,1,2,3,4,5,6,7,8,9,10,11,19,20,21,22}; | 
| 56 | 
  | 
#define NMBSAT          6       /* Number of MacBeth saturated colors */ | 
| 57 | 
  | 
short   mbsat[NMBSAT] = {14,12,13,15,16,17}; | 
| 58 | 
  | 
 | 
| 231 | 
  | 
bresp(y, x)             /* piecewise linear interpolation of primaries */ | 
| 232 | 
  | 
COLOR   y, x; | 
| 233 | 
  | 
{ | 
| 234 | 
+ | 
        double  cv[3]; | 
| 235 | 
  | 
        register int    i, n; | 
| 236 | 
  | 
 | 
| 237 | 
  | 
        for (i = 0; i < 3; i++) { | 
| 238 | 
  | 
                n = NMBNEU; | 
| 239 | 
  | 
                while (n > 0 && colval(x,i) < colval(bramp[--n][0],i)) | 
| 240 | 
  | 
                        ; | 
| 241 | 
< | 
                colval(y,i) = ((colval(bramp[n+1][0],i) - colval(x,i)) * | 
| 241 | 
> | 
                cv[i] = ((colval(bramp[n+1][0],i) - colval(x,i)) * | 
| 242 | 
  | 
                                                colval(bramp[n][1],i) + | 
| 243 | 
  | 
                                (colval(x,i) - colval(bramp[n][0],i)) * | 
| 244 | 
  | 
                                                colval(bramp[n+1][1],i)) / | 
| 245 | 
  | 
                        (colval(bramp[n+1][0],i) - colval(bramp[n][0],i)); | 
| 246 | 
+ | 
                if (cv[i] < 0.) cv[i] = 0.; | 
| 247 | 
  | 
        } | 
| 248 | 
+ | 
        setcolor(y, cv[0], cv[1], cv[2]); | 
| 249 | 
  | 
} | 
| 250 | 
  | 
 | 
| 251 | 
  | 
 | 
| 307 | 
  | 
        } | 
| 308 | 
  | 
                                        /* print color mapping */ | 
| 309 | 
  | 
        printf("ro = %g*rn + %g*gn + %g*bn ;\n", | 
| 310 | 
< | 
                        solmat[0][0], solmat[1][0], solmat[2][0]); | 
| 310 | 
> | 
                        solmat[0][0], solmat[0][1], solmat[0][2]); | 
| 311 | 
  | 
        printf("go = %g*rn + %g*gn + %g*bn ;\n", | 
| 312 | 
< | 
                        solmat[0][1], solmat[1][1], solmat[2][1]); | 
| 312 | 
> | 
                        solmat[1][0], solmat[1][1], solmat[1][2]); | 
| 313 | 
  | 
        printf("bo = %g*rn + %g*gn + %g*bn ;\n", | 
| 314 | 
< | 
                        solmat[0][2], solmat[1][2], solmat[2][2]); | 
| 314 | 
> | 
                        solmat[2][0], solmat[2][1], solmat[2][2]); | 
| 315 | 
  | 
} | 
| 316 | 
  | 
 | 
| 317 | 
  | 
 | 
| 318 | 
+ | 
#if NMBMOD == 3 | 
| 319 | 
  | 
compsoln(cin, cout, n)          /* solve 3x3 system */ | 
| 320 | 
  | 
COLOR   cin[], cout[]; | 
| 321 | 
  | 
int     n; | 
| 347 | 
  | 
                        invmat[i][j] /= det; | 
| 348 | 
  | 
        for (i = 0; i < 3; i++) { | 
| 349 | 
  | 
                for (j = 0; j < 3; j++) | 
| 350 | 
< | 
                        rowv[j] = colval(cout[j],i); | 
| 351 | 
< | 
                mx3d_transform(rowv, invmat, colv); | 
| 350 | 
> | 
                        colv[j] = colval(cout[j],i); | 
| 351 | 
> | 
                mx3d_transform(colv, invmat, rowv); | 
| 352 | 
  | 
                for (j = 0; j < 3; j++) | 
| 353 | 
< | 
                        solmat[j][i] = colv[j]; | 
| 353 | 
> | 
                        solmat[i][j] = rowv[j]; | 
| 354 | 
  | 
        } | 
| 355 | 
  | 
} | 
| 356 | 
+ | 
#else | 
| 357 | 
+ | 
compsoln(cin, cout, n)          /* solve 3xN system (N > 3) */ | 
| 358 | 
+ | 
COLOR   cin[], cout[]; | 
| 359 | 
+ | 
int     n; | 
| 360 | 
+ | 
{ | 
| 361 | 
+ | 
        double  *au[NMBMOD], *v[3], vv[3][3], auv[NMBMOD][3], w[3]; | 
| 362 | 
+ | 
        double  b[NMBMOD]; | 
| 363 | 
+ | 
        register int    i, j; | 
| 364 | 
  | 
 | 
| 365 | 
+ | 
        if (n > NMBMOD) { | 
| 366 | 
+ | 
                fprintf(stderr, "%s: inconsistent code!\n", progname); | 
| 367 | 
+ | 
                exit(1); | 
| 368 | 
+ | 
        } | 
| 369 | 
+ | 
        for (i = 0; i < n; i++)         /* assign rectangular matrix A */ | 
| 370 | 
+ | 
                for (j = 0; j < 3; j++) | 
| 371 | 
+ | 
                        auv[i][j] = colval(cin[i],j); | 
| 372 | 
+ | 
                                /* svdcmp indexing requires pointer offsets */ | 
| 373 | 
+ | 
        for (j = 0; j < 3; j++) | 
| 374 | 
+ | 
                v[j] = vv[j] - 1; | 
| 375 | 
+ | 
        for (i = 0; i < n; i++) | 
| 376 | 
+ | 
                au[i] = auv[i] - 1; | 
| 377 | 
+ | 
                                /* compute singular value decomposition */ | 
| 378 | 
+ | 
fprintf(stderr, "A:\n"); | 
| 379 | 
+ | 
for (i = 1; i <= n; i++) | 
| 380 | 
+ | 
fprintf(stderr, "%g %g %g\n", (au-1)[i][1], (au-1)[i][2], (au-1)[i][3]); | 
| 381 | 
+ | 
        svdcmp(au-1, n, 3, w-1, v-1); | 
| 382 | 
+ | 
fprintf(stderr, "U:\n"); | 
| 383 | 
+ | 
for (i = 0; i < n; i++) | 
| 384 | 
+ | 
fprintf(stderr, "%g %g %g\n", auv[i][0], auv[i][1], auv[i][2]); | 
| 385 | 
+ | 
fprintf(stderr, "V:\n"); | 
| 386 | 
+ | 
for (i = 0; i < 3; i++) | 
| 387 | 
+ | 
fprintf(stderr, "%g %g %g\n", vv[i][0], vv[i][1], vv[i][2]); | 
| 388 | 
+ | 
fprintf(stderr, "W: %g %g %g\n", w[0], w[1], w[2]); | 
| 389 | 
+ | 
                                /* zero out small weights */ | 
| 390 | 
+ | 
        for (j = 0; j < 3; j++) | 
| 391 | 
+ | 
                if (w[j] < 1e-4) | 
| 392 | 
+ | 
                        w[j] = 0.; | 
| 393 | 
+ | 
                                /* back substitution for each row vector */ | 
| 394 | 
+ | 
        for (j = 0; j < 3; j++) { | 
| 395 | 
+ | 
                for (i = 0; i < n; i++) | 
| 396 | 
+ | 
                        b[i] = colval(cout[i],j); | 
| 397 | 
+ | 
                svbksb(au-1, w-1, v-1, n, 3, b-1, solmat[j]-1); | 
| 398 | 
+ | 
        } | 
| 399 | 
+ | 
} | 
| 400 | 
+ | 
#endif | 
| 401 | 
  | 
 | 
| 402 | 
+ | 
 | 
| 403 | 
  | 
cvtcolor(cout, cin)             /* convert color according to our mapping */ | 
| 404 | 
  | 
COLOR   cout, cin; | 
| 405 | 
  | 
{ | 
| 406 | 
  | 
        double  r, g, b; | 
| 407 | 
  | 
 | 
| 408 | 
  | 
        bresp(cout, cin); | 
| 409 | 
< | 
        r = colval(cout,0)*solmat[0][0] + colval(cout,1)*solmat[1][0] | 
| 410 | 
< | 
                        + colval(cout,2)*solmat[2][0]; | 
| 409 | 
> | 
        r = colval(cout,0)*solmat[0][0] + colval(cout,1)*solmat[0][1] | 
| 410 | 
> | 
                        + colval(cout,2)*solmat[0][2]; | 
| 411 | 
  | 
        if (r < 0) r = 0; | 
| 412 | 
< | 
        g = colval(cout,0)*solmat[0][1] + colval(cout,1)*solmat[1][1] | 
| 413 | 
< | 
                        + colval(cout,2)*solmat[2][1]; | 
| 412 | 
> | 
        g = colval(cout,0)*solmat[1][0] + colval(cout,1)*solmat[1][1] | 
| 413 | 
> | 
                        + colval(cout,2)*solmat[1][2]; | 
| 414 | 
  | 
        if (g < 0) g = 0; | 
| 415 | 
< | 
        b = colval(cout,0)*solmat[0][2] + colval(cout,1)*solmat[1][2] | 
| 415 | 
> | 
        b = colval(cout,0)*solmat[2][0] + colval(cout,1)*solmat[2][1] | 
| 416 | 
  | 
                        + colval(cout,2)*solmat[2][2]; | 
| 417 | 
  | 
        if (b < 0) b = 0; | 
| 418 | 
  | 
        setcolor(cout, r, g, b); |