ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/macbethcal.c
(Generate patch)

Comparing ray/src/px/macbethcal.c (file contents):
Revision 2.12 by greg, Thu Jan 30 19:14:11 1997 UTC vs.
Revision 2.15 by greg, Thu Feb 6 11:36:53 1997 UTC

# Line 7 | Line 7 | static char SCCSid[] = "$SunId$ LBL";
7   /*
8   * Calibrate a scanned MacBeth Color Checker Chart
9   *
10 < * Produce a .cal file suitable for use with pcomb.
10 > * Produce a .cal file suitable for use with pcomb,
11 > * or .cwp file suitable for use with pcwarp.
12 > *
13 > * Warping code depends on conformance of COLOR and W3VEC types.
14   */
15  
16   #include <stdio.h>
17 + #include <math.h>
18   #ifdef MSDOS
19   #include <fcntl.h>
20   #endif
21   #include "color.h"
22   #include "resolu.h"
23   #include "pmap.h"
24 + #include "warp3d.h"
25  
26                                  /* MacBeth colors */
27   #define DarkSkin        0
# Line 96 | Line 101 | short  mbneu[NMBNEU] = {Black,Neutral35,Neutral5,Neutra
101   #define  RG_CORR        04      /* corrected color region */
102  
103   int     scanning = 1;           /* scanned input (or recorded output)? */
104 + double  irrad = 1.0;            /* irradiance multiplication factor */
105 + int     rawmap = 0;             /* put out raw color mapping? */
106  
107   int     xmax, ymax;             /* input image dimensions */
108   int     bounds[4][2];           /* image coordinates of chart corners */
# Line 106 | Line 113 | long   inpflags = 0;           /* flags of which colors were inpu
113   long    gmtflags = 0;           /* flags of out-of-gamut colors */
114  
115   COLOR   bramp[NMBNEU][2];       /* brightness ramp (per primary) */
116 < double  solmat[3][3];           /* color mapping matrix */
116 > COLORMAT        solmat;         /* color mapping matrix */
117 > COLOR   colmin, colmax;         /* gamut limits */
118  
119 + WARP3D  *wcor = NULL;           /* color space warp */
120 +
121   FILE    *debugfp = NULL;        /* debug output picture */
122   char    *progname;
123  
# Line 150 | Line 160 | char   **argv;
160                          bounds[3][1] = atoi(argv[++i]);
161                          scanning = 2;
162                          break;
163 +                case 'i':                               /* irradiance factor */
164 +                        i++;
165 +                        if (badarg(argc-i, argv+i, "f"))
166 +                                goto userr;
167 +                        irrad = atof(argv[i]);
168 +                        break;
169 +                case 'm':                               /* raw map output */
170 +                        rawmap = 1;
171 +                        break;
172                  case 'c':                               /* color input */
173                          scanning = 0;
174                          break;
# Line 158 | Line 177 | char   **argv;
177                  }
178                                                          /* open files */
179          if (i < argc && freopen(argv[i], "r", stdin) == NULL) {
180 <                perror(argv[1]);
180 >                perror(argv[i]);
181                  exit(1);
182          }
183          if (i+1 < argc && freopen(argv[i+1], "w", stdout) == NULL) {
184 <                perror(argv[2]);
184 >                perror(argv[i+1]);
185                  exit(1);
186          }
187          if (scanning) {                 /* load input picture header */
# Line 190 | Line 209 | char   **argv;
209          else
210                  getcolors();
211          compute();                      /* compute color mapping */
212 <                                        /* print comment */
213 <        printf("{\n\tColor correction file computed by:\n\t\t");
214 <        printargs(argc, argv, stdout);
215 <        printf("\n\tUsage: pcomb -f %s uncorrected.pic > corrected.pic\n",
216 <                        i+1 < argc ? argv[i+1] : "{this_file}");
217 <        if (!scanning)
199 <                printf("\t   Or: pcond [options] -f %s orig.pic > output.pic\n",
212 >        if (rawmap) {                   /* print out raw correspondence */
213 >                register int    j;
214 >
215 >                printf("# Color correspondence produced by:\n#\t\t");
216 >                printargs(argc, argv, stdout);
217 >                printf("#\tUsage: pcwarp %s uncorrected.pic > corrected.pic\n",
218                                  i+1 < argc ? argv[i+1] : "{this_file}");
219 <        printf("}\n");
220 <        putmapping();                   /* put out color mapping */
219 >                printf("#\t   Or: pcond [options] -m %s orig.pic > output.pic\n",
220 >                                i+1 < argc ? argv[i+1] : "{this_file}");
221 >                for (j = 0; j < 24; j++)
222 >                        printf("%f %f %f    %f %f %f\n",
223 >                                colval(inpRGB[j],RED), colval(inpRGB[j],GRN),
224 >                                colval(inpRGB[j],BLU), colval(mbRGB[j],RED),
225 >                                colval(mbRGB[j],GRN), colval(mbRGB[j],BLU));
226 >                if (scanning && debugfp != NULL)
227 >                        cwarp();                /* color warp for debugging */
228 >        } else {                        /* print color mapping */
229 >                                                /* print header */
230 >                printf("{\n\tColor correction file computed by:\n\t\t");
231 >                printargs(argc, argv, stdout);
232 >                printf("\n\tUsage: pcomb -f %s uncorrected.pic > corrected.pic\n",
233 >                                i+1 < argc ? argv[i+1] : "{this_file}");
234 >                if (!scanning)
235 >                        printf("\t   Or: pcond [options] -f %s orig.pic > output.pic\n",
236 >                                        i+1 < argc ? argv[i+1] : "{this_file}");
237 >                printf("}\n");
238 >                putmapping();                   /* put out color mapping */
239 >        }
240          if (debugfp != NULL)            /* put out debug picture */
241                  if (scanning)
242                          picdebug();
# Line 208 | Line 245 | char   **argv;
245          exit(0);
246   userr:
247          fprintf(stderr,
248 < "Usage: %s [-d dbg.pic][-p xul yul xur yur xll yll xlr ylr] input.pic [output.cal]\n",
248 > "Usage: %s [-d dbg.pic][-p xul yul xur yur xll yll xlr ylr][-i irrad][-m] input.pic [output.{cal|cwp}]\n",
249                          progname);
250 <        fprintf(stderr, "   or: %s [-d dbg.pic] -c [xyY.dat [output.cal]]\n",
250 >        fprintf(stderr, "   or: %s [-d dbg.pic][-i irrad][-m] -c [xyY.dat [output.{cal|cwp}]]\n",
251                          progname);
252          exit(1);
253   }
# Line 235 | Line 272 | init()                         /* initialize */
272                  exit(1);
273          }
274                                          /* map MacBeth colors to RGB space */
275 <        for (i = 0; i < 24; i++)
275 >        for (i = 0; i < 24; i++) {
276                  xyY2RGB(mbRGB[i], mbxyY[i]);
277 +                scalecolor(mbRGB[i], irrad);
278 +        }
279   }
280  
281  
# Line 385 | Line 424 | compute()                      /* compute color mapping */
424          COLOR   clrin[24], clrout[24];
425          long    cflags;
426          COLOR   ctmp;
427 <        register int    i, j, n;
427 >        register int    i, n;
428                                          /* did we get what we need? */
429          if ((inpflags & REQFLGS) != REQFLGS) {
430                  fprintf(stderr, "%s: missing required input colors\n",
# Line 397 | Line 436 | compute()                      /* compute color mapping */
436                  copycolor(bramp[i][0], inpRGB[mbneu[i]]);
437                  copycolor(bramp[i][1], mbRGB[mbneu[i]]);
438          }
439 +                                        /* compute color space gamut */
440 +        if (scanning) {
441 +                copycolor(colmin, cblack);
442 +                copycolor(colmax, cwhite);
443 +                scalecolor(colmax, irrad);
444 +        } else
445 +                for (i = 0; i < 3; i++) {
446 +                        colval(colmin,i) = colval(bramp[0][0],i) -
447 +                                colval(bramp[0][1],i) *
448 +                                (colval(bramp[1][0],i)-colval(bramp[0][0],i)) /
449 +                                (colval(bramp[1][1],i)-colval(bramp[1][0],i));
450 +                        colval(colmax,i) = colval(bramp[NMBNEU-2][0],i) +
451 +                                (1.-colval(bramp[NMBNEU-2][1],i)) *
452 +                                (colval(bramp[NMBNEU-1][0],i) -
453 +                                        colval(bramp[NMBNEU-2][0],i)) /
454 +                                (colval(bramp[NMBNEU-1][1],i) -
455 +                                        colval(bramp[NMBNEU-2][1],i));
456 +                }
457                                          /* compute color mapping */
458          do {
459                  cflags = inpflags & ~gmtflags;
# Line 408 | Line 465 | compute()                      /* compute color mapping */
465                                  n++;
466                          }
467                  compsoln(clrin, clrout, n);
468 <                                                /* check out-of-gamut colors */
469 <                for (i = 0; i < 24; i++)
470 <                        if (cflags & 1L<<i) {
471 <                                cvtcolor(ctmp, mbRGB[i]);
415 <                                for (j = 0; j < 3; j++)
416 <                                        if (colval(ctmp,j) <= 1e-6 ||
417 <                                                colval(ctmp,j) >= 1.-1e-6) {
418 <                                                gmtflags |= 1L<<i;
419 <                                                break;
420 <                                        }
421 <                        }
468 >                if (irrad > 0.99 && irrad < 1.01)       /* check gamut */
469 >                        for (i = 0; i < 24; i++)
470 >                                if (cflags & 1L<<i && cvtcolor(ctmp, mbRGB[i]))
471 >                                        gmtflags |= 1L<<i;
472          } while (cflags & gmtflags);
473          if (gmtflags & MODFLGS)
474                  fprintf(stderr,
# Line 427 | Line 477 | compute()                      /* compute color mapping */
477   }
478  
479  
480 < putmapping()                    /* put out color mapping for pcomb -f */
480 > putmapping()                    /* put out color mapping */
481   {
482          static char     cchar[3] = {'r', 'g', 'b'};
483          register int    i, j;
# Line 535 | Line 585 | int    n;
585   }
586  
587  
588 + cwarp()                         /* compute color warp map */
589 + {
590 +        register int    i;
591 +
592 +        if ((wcor = new3dw(W3EXACT)) == NULL)
593 +                goto memerr;
594 +        for (i = 0; i < 24; i++)
595 +                if (!add3dpt(wcor, inpRGB[i], mbRGB[i]))
596 +                        goto memerr;
597 +        return;
598 + memerr:
599 +        perror(progname);
600 +        exit(1);
601 + }
602 +
603 +
604 + int
605   cvtcolor(cout, cin)             /* convert color according to our mapping */
606   COLOR   cout, cin;
607   {
608          COLOR   ctmp;
609 +        int     clipped;
610  
611 <        if (scanning) {
611 >        if (wcor != NULL) {
612 >                clipped = warp3d(cout, cin, wcor);
613 >                clipped |= clipgamut(cout,bright(cout),CGAMUT,colmin,colmax);
614 >        } else if (scanning) {
615                  bresp(ctmp, cin);
616 <                cresp(cout, ctmp);
616 >                clipped = cresp(cout, ctmp);
617          } else {
618 <                cresp(ctmp, cin);
618 >                clipped = cresp(ctmp, cin);
619                  bresp(cout, ctmp);
620          }
621 <        if (colval(cout,RED) < 0.)
551 <                colval(cout,RED) = 0.;
552 <        if (colval(cout,GRN) < 0.)
553 <                colval(cout,GRN) = 0.;
554 <        if (colval(cout,BLU) < 0.)
555 <                colval(cout,BLU) = 0.;
621 >        return(clipped);
622   }
623  
624  
625 + int
626   cresp(cout, cin)                /* transform color according to matrix */
627   COLOR   cout, cin;
628   {
629 <        double  r, g, b;
630 <
564 <        r = colval(cin,0)*solmat[0][0] + colval(cin,1)*solmat[0][1]
565 <                        + colval(cin,2)*solmat[0][2];
566 <        g = colval(cin,0)*solmat[1][0] + colval(cin,1)*solmat[1][1]
567 <                        + colval(cin,2)*solmat[1][2];
568 <        b = colval(cin,0)*solmat[2][0] + colval(cin,1)*solmat[2][1]
569 <                        + colval(cin,2)*solmat[2][2];
570 <        setcolor(cout, r, g, b);
629 >        colortrans(cout, solmat, cin);
630 >        return(clipgamut(cout, bright(cout), CGAMUT, colmin, colmax));
631   }
632  
633  
# Line 582 | Line 642 | register float xyYin[3];
642          ctmp[0] = xyYin[0] * d;
643          ctmp[1] = xyYin[2];
644          ctmp[2] = (1. - xyYin[0] - xyYin[1]) * d;
585        cie_rgb(rgbout, ctmp);
645                                  /* allow negative values */
646 <        colortrans(rgbout, xyz2rgbmat, ctmp, 0);
646 >        colortrans(rgbout, xyz2rgbmat, ctmp);
647   }
648  
649  
# Line 621 | Line 680 | picdebug()                     /* put out debugging picture */
680                  for (x = 0; x < xmax; x++) {
681                          rg = chartndx(x, y, &i);
682                          if (rg == RG_CENT) {
683 <                                if (!(1L<<i & gmtflags) || (x+y)&07)
683 >                                if (!(1L<<i & gmtflags) || (x+y)&07) {
684                                          copycolor(scan[x], mbRGB[i]);
685 <                                else
685 >                                        clipgamut(scan[x], bright(scan[x]),
686 >                                                CGAMUT, colmin, colmax);
687 >                                } else
688                                          copycolor(scan[x], blkcol);
689                          } else if (rg == RG_CORR)
690                                  cvtcolor(scan[x], scan[x]);
# Line 647 | Line 708 | clrdebug()                     /* put out debug picture from color input
708          static COLR     blkclr = BLKCOLR;
709          COLR    mbclr[24], cvclr[24], orclr[24];
710          COLR    *scan;
711 <        COLOR   ctmp;
711 >        COLOR   ctmp, ct2;
712          int     y, i;
713          register int    x, rg;
714                                                  /* convert colors */
715          for (i = 0; i < 24; i++) {
716 <                setcolr(mbclr[i], colval(mbRGB[i],RED),
717 <                                colval(mbRGB[i],GRN), colval(mbRGB[i],BLU));
716 >                copycolor(ctmp, mbRGB[i]);
717 >                clipgamut(ctmp, bright(ctmp), CGAMUT, cblack, cwhite);
718 >                setcolr(mbclr[i], colval(ctmp,RED),
719 >                                colval(ctmp,GRN), colval(ctmp,BLU));
720                  if (inpflags & 1L<<i) {
721 <                        setcolr(orclr[i], colval(inpRGB[i],RED),
722 <                                        colval(inpRGB[i],GRN),
723 <                                        colval(inpRGB[i],BLU));
661 <                        cvtcolor(ctmp, inpRGB[i]);
662 <                        setcolr(cvclr[i], colval(ctmp,RED),
721 >                        copycolor(ctmp, inpRGB[i]);
722 >                        clipgamut(ctmp, bright(ctmp), CGAMUT, cblack, cwhite);
723 >                        setcolr(orclr[i], colval(ctmp,RED),
724                                          colval(ctmp,GRN), colval(ctmp,BLU));
725 +                        if (rawmap)
726 +                                copycolr(cvclr[i], mbclr[i]);
727 +                        else {
728 +                                bresp(ctmp, inpRGB[i]);
729 +                                colortrans(ct2, solmat, ctmp);
730 +                                clipgamut(ct2, bright(ct2), CGAMUT,
731 +                                                cblack, cwhite);
732 +                                setcolr(cvclr[i], colval(ct2,RED),
733 +                                                colval(ct2,GRN),
734 +                                                colval(ct2,BLU));
735 +                        }
736                  }
737          }
738                                                  /* allocate scanline */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines