diff options
Diffstat (limited to 'profile')
-rw-r--r-- | profile/Jamfile | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | profile/applycal.c | 5 | ||||
-rwxr-xr-x[-rw-r--r--] | profile/cb2ti3.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | profile/colprof.c | 84 | ||||
-rwxr-xr-x[-rw-r--r--] | profile/colverify.c | 38 | ||||
-rwxr-xr-x[-rw-r--r--] | profile/invprofcheck.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | profile/kodak2ti3.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | profile/ls2ti3.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | profile/mppcheck.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | profile/mppprof.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | profile/printcal.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | profile/prof.h | 6 | ||||
-rwxr-xr-x[-rw-r--r--] | profile/profcheck.c | 36 | ||||
-rwxr-xr-x[-rw-r--r--] | profile/profin.c | 16 | ||||
-rwxr-xr-x[-rw-r--r--] | profile/profout.c | 34 | ||||
-rwxr-xr-x[-rw-r--r--] | profile/simpprof.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | profile/splitti3.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | profile/txt2ti3.c | 157 |
18 files changed, 283 insertions, 95 deletions
diff --git a/profile/Jamfile b/profile/Jamfile index 0c857a8..988e556 100644 --- a/profile/Jamfile +++ b/profile/Jamfile @@ -30,6 +30,8 @@ Library libprof : profin.c profout.c ; LINKLIBS = ../rspl/librspl ../icc/libicc ../cgats/libcgats ../numlib/libnum ../plot/libplot ../plot/libvrml ../numlib/libui ; +LINKFLAGS += $(GUILINKFLAGS) ; + # Simple profile generator Main simpprof : simpprof.c ; diff --git a/profile/applycal.c b/profile/applycal.c index ff9a76d..991ce72 100644..100755 --- a/profile/applycal.c +++ b/profile/applycal.c @@ -524,10 +524,7 @@ main(int argc, char *argv[]) { double val; val = i/(ro->size-1.0); //printf("~1 Input val %f", val); - if (inp) - val = cal->interp_ch(cal, j, val); /* Input calibration */ - else - val = cal->inv_interp_ch(cal, j, val); /* Inverse output calibration */ + val = cal->inv_interp_ch(cal, j, val); /* Inverse output calibration */ //printf(", after inv curve %f", val); wo->lookup_fwd(wo, &val, &val); /* Original curve */ //printf(", after orig %f\n", val); diff --git a/profile/cb2ti3.c b/profile/cb2ti3.c index 4fc7866..4fc7866 100644..100755 --- a/profile/cb2ti3.c +++ b/profile/cb2ti3.c diff --git a/profile/colprof.c b/profile/colprof.c index b359ebb..eb3417f 100644..100755 --- a/profile/colprof.c +++ b/profile/colprof.c @@ -25,6 +25,10 @@ /* * TTBD: + * + * Should add -ua option, to restore option to force input profile to be + * absolute intent for all ICC intents. + * * Should allow ICC Device attributes to be set. * * Add Argyll private tag to record ink limit etc. to automate link parameters. @@ -121,6 +125,7 @@ void usage(char *diag, ...) { // fprintf(stderr," -I ver Set ICC profile version > 2.2.0\n"); // fprintf(stderr," ver = 4, Enable ICC V4 creation\n"); fprintf(stderr," -u If input profile, auto scale WP to allow extrapolation\n"); + fprintf(stderr," -ua If input profile, force absolute intent\n"); fprintf(stderr," -uc If input profile, clip cLUT values above WP\n"); fprintf(stderr," -U scale If input profile, scale media white point by scale\n"); fprintf(stderr," -R Restrict white <= 1.0, black and primaries to be +ve\n"); @@ -131,7 +136,7 @@ void usage(char *diag, ...) { fprintf(stderr," -i illum Choose illuminant for computation of CIE XYZ from spectral data & FWA:\n"); fprintf(stderr," A, C, D50 (def.), D50M2, D65, F5, F8, F10 or file.sp\n"); fprintf(stderr," -o observ Choose CIE Observer for spectral data:\n"); - fprintf(stderr," 1931_2 (def), 1964_10, S&B 1955_2, shaw, J&V 1978_2\n"); + fprintf(stderr," 1931_2 (def), 1964_10, 2012_2, 2012_10, S&B 1955_2, shaw, J&V 1978_2, or file.cmf\n"); fprintf(stderr," -r avgdev Average deviation of device+instrument readings as a percentage (default %4.2f%%)\n",DEFAVGDEV); /* Research options: */ /* fprintf(stderr," -r sSMOOTH RSPL or shaper suplimental optimised smoothing factor\n"); */ @@ -187,7 +192,8 @@ int main(int argc, char *argv[]) { int noptop = 0; /* Use colormetric source gamut to make perceptual table */ int nostos = 0; /* Use colormetric source gamut to make saturation table */ int gamdiag = 0; /* Make gamut mapping diagnostic wrl plots */ - int autowpsc = 0; /* Auto scale the WP to prevent clipping above WP patch */ + int autowpsc = 0; /* 1 = Auto scale the WP to prevent clipping above WP patch */ + /* 2 = Force absolute colorimetric */ int clipovwp = 0; /* Clip cLUT values above WP */ int clipprims = 0; /* Clip white, black and primaries */ // double bpo[3] = { -1,-1,-1 }; /* Black point override hack XYZ value */ @@ -209,7 +215,8 @@ int main(int argc, char *argv[]) { /* xspect will use illum/cust_illum if tillum == none */ icxIllumeType illum = icxIT_none; /* Spectral illuminant (defaults to D50) */ xspect cust_illum; /* Custom illumination spectrum */ - icxObserverType observ = icxOT_none; /* Observer (defaults to 1931 2 degree) */ + icxObserverType obType = icxOT_none; /* Observer (defaults to 1931 2 degree) */ + xspect custObserver[3]; /* If obType = icxOT_custom */ int gcompr = 0, gexpr = 0; /* Gamut compression/expansion % instead of Input icc profile */ char ipname[MAXNAMEL+1] = ""; /* Input icc profile - enables gamut map */ char sgname[MAXNAMEL+1] = ""; /* Image source gamut name */ @@ -251,6 +258,9 @@ int main(int argc, char *argv[]) { ivc_p.Yf = -1.0; ivc_p.Yg = -1.0; ivc_p.Gxyz[0] = -1.0; ivc_p.Gxyz[1] = -1.0; ivc_p.Gxyz[2] = -1.0; + ivc_p.hkscale = -1.0; + ivc_p.mtaf = -1.0; + ivc_p.Wxyz2[0] = -1.0; ivc_p.Wxyz2[1] = -1.0; ivc_p.Wxyz2[2] = -1.0; ovc_p.Ev = -1; ovc_p.Wxyz[0] = -1.0; ovc_p.Wxyz[1] = -1.0; ovc_p.Wxyz[2] = -1.0; @@ -260,6 +270,9 @@ int main(int argc, char *argv[]) { ovc_p.Yf = -1.0; ovc_p.Yg = -1.0; ovc_p.Gxyz[0] = -1.0; ovc_p.Gxyz[1] = -1.0; ovc_p.Gxyz[2] = -1.0; + ovc_p.hkscale = -1.0; + ovc_p.mtaf = -1.0; + ovc_p.Wxyz2[0] = -1.0; ovc_p.Wxyz2[1] = -1.0; ovc_p.Wxyz2[2] = -1.0; xicc_enum_gmapintent(&pgmi, icxPerceptualGMIntent, NULL); xicc_enum_gmapintent(&sgmi, icxSaturationGMIntent, NULL); @@ -462,7 +475,10 @@ int main(int argc, char *argv[]) { else if (argv[fa][1] == 'u') { autowpsc = 1; clipovwp = 0; - if (argv[fa][2] == 'c') { + if (argv[fa][2] == 'a') { + autowpsc = 2; + clipovwp = 0; + } else if (argv[fa][2] == 'c') { autowpsc = 0; clipovwp = 1; } else if (argv[fa][2] != '\000') { @@ -713,24 +729,32 @@ int main(int argc, char *argv[]) { fa = nfa; if (strcmp(na, "1931_2") == 0) { /* Classic 2 degree */ spec = 1; - observ = icxOT_CIE_1931_2; + obType = icxOT_CIE_1931_2; } else if (strcmp(na, "1964_10") == 0) { /* Classic 10 degree */ spec = 1; - observ = icxOT_CIE_1964_10; + obType = icxOT_CIE_1964_10; + } else if (strcmp(na, "2012_2") == 0) { /* Latest 2 degree */ + spec = 1; + obType = icxOT_CIE_2012_2; + } else if (strcmp(na, "2012_10") == 0) { /* Latest 10 degree */ + spec = 1; + obType = icxOT_CIE_2012_10; } else if (strcmp(na, "1955_2") == 0) { /* Stiles and Burch 1955 2 degree */ spec = 1; - observ = icxOT_Stiles_Burch_2; + obType = icxOT_Stiles_Burch_2; } else if (strcmp(na, "1978_2") == 0) { /* Judd and Voss 1978 2 degree */ spec = 1; - observ = icxOT_Judd_Voss_2; + obType = icxOT_Judd_Voss_2; } else if (strcmp(na, "shaw") == 0) { /* Shaw and Fairchilds 1997 2 degree */ spec = 1; - observ = icxOT_Shaw_Fairchild_2; - } else - usage("Unrecognised argument '%s' to observer flag -o",na); + obType = icxOT_Shaw_Fairchild_2; + } else { /* Assume it's a filename */ + obType = icxOT_custom; + if (read_cmf(custObserver, na) != 0) + usage(0,"Failed to read custom observer CMF from -o file '%s'",na); + } } - /* Average Deviation percentage */ else if (argv[fa][1] == 'r') { if (na == NULL) usage("Expected argument to average deviation flag -r"); @@ -915,6 +939,22 @@ int main(int argc, char *argv[]) { vc->Yg = x/100.0; } else usage("Viewing condition (-%cg) unrecognised flare '%s'",argv[fa][1],na+1); + + } else if (na[0] == 'h' || na[0] == 'H') { + if (na[1] != ':') + usage("Viewing conditions (-%ch) missing ':'",argv[fa][1]); + vc->hkscale = atof(na+2); + } else if (na[0] == 'm' || na[0] == 'M') { + double x, y, z; + if (sscanf(na+1,":%lf:%lf:%lf",&x,&y,&z) == 3) { + vc->Wxyz2[0] = x; vc->Wxyz2[1] = y; vc->Wxyz2[2] = z; + } else if (sscanf(na+1,":%lf:%lf",&x,&y) == 2) { + vc->Wxyz2[0] = x; vc->Wxyz2[1] = y; vc->Wxyz2[2] = -1; + } else if (sscanf(na+1,":%lf",&x) == 1) { + vc->mtaf = x; + } else + usage("Viewing condition (-%cm) unrecognised flare '%s'",argv[fa][1],na+1); + } else usage("Viewing condition (-%c) unrecognised sub flag '%c'",argv[fa][1],na[0]); } @@ -1018,8 +1058,8 @@ int main(int argc, char *argv[]) { if (illum == icxIT_none) illum = icxIT_D50; - if (observ == icxOT_none) - observ = icxOT_CIE_1931_2; + if (obType == icxOT_none) + obType = icxOT_CIE_1931_2; /* See if CIE is actually available - some sources of .TI3 don't provide it */ if (!spec @@ -1034,7 +1074,7 @@ int main(int argc, char *argv[]) { printf("No CIE data found, switching to spectral with standard observer & D50\n"); spec = 1; illum = icxIT_D50; - observ = icxOT_CIE_1931_2; + obType = icxOT_CIE_1931_2; } /* If we requested spectral, check that it is available */ @@ -1164,8 +1204,10 @@ int main(int argc, char *argv[]) { error ("Output profile can only be a cLUT algorithm"); } - if (autowpsc) + if (autowpsc == 1) error ("Input auto WP scale mode isn't applicable to an output device"); + if (autowpsc == 2) + error ("Force absolute colorimetric isn't applicable to an output device"); if (clipovwp) error ("Input cLUT clipping above WP mode isn't applicable to an output device"); @@ -1174,8 +1216,8 @@ int main(int argc, char *argv[]) { gamdiag, verify, clipprims, iwpscale, // NULL, /* bpo */ &ink, inname, outname, icg, - spec, tillum, &cust_tillum, illum, &cust_illum, observ, fwacomp, - smooth, avgdev, 1.0, + spec, tillum, &cust_tillum, illum, &cust_illum, obType, custObserver, + fwacomp, smooth, avgdev, 1.0, gcompr, gexpr, ipname[0] != '\000' ? ipname : NULL, sgname[0] != '\000' ? sgname : NULL, @@ -1200,7 +1242,7 @@ int main(int argc, char *argv[]) { make_input_icc(ptype, iccver, verb, iquality, oquality, noisluts, noipluts, nooluts, nocied, verify, autowpsc, clipovwp, iwpscale, doinb2a, doinextrap, clipprims, - inname, outname, icg, emis, spec, illum, &cust_illum, observ, + inname, outname, icg, emis, spec, illum, &cust_illum, obType, custObserver, smooth, avgdev, &xpi); /* Display or Projector */ @@ -1223,8 +1265,8 @@ int main(int argc, char *argv[]) { gamdiag, verify, clipprims, iwpscale, // bpo[1] >= 0.0 ? bpo : NULL, NULL, inname, outname, icg, - spec, icxIT_none, NULL, illum, &cust_illum, observ, 0, - smooth, avgdev, demph, + spec, icxIT_none, NULL, illum, &cust_illum, obType, custObserver, + 0, smooth, avgdev, demph, gcompr, gexpr, ipname[0] != '\000' ? ipname : NULL, sgname[0] != '\000' ? sgname : NULL, diff --git a/profile/colverify.c b/profile/colverify.c index 86d5575..d7100a3 100644..100755 --- a/profile/colverify.c +++ b/profile/colverify.c @@ -81,8 +81,8 @@ usage(void) { fprintf(stderr," -i illum Choose illuminant for computation of CIE XYZ from spectral data & FWA:\n"); fprintf(stderr," A, C, D50 (def.), D50M2, D65, F5, F8, F10 or file.sp\n"); fprintf(stderr," -o observ Choose CIE Observer for spectral data:\n"); - fprintf(stderr," 1931_2 (def), 1964_10, S&B 1955_2, shaw, J&V 1978_2\n"); - fprintf(stderr," -L profile.%s Skip any first file out of profile gamut patches\n",ICC_FILE_EXT_ND); + fprintf(stderr," 1931_2 (def), 1964_10, 2012_2, 2012_10, S&B 1955_2, shaw, J&V 1978_2 or file.cmf\n"); + fprintf(stderr," -L profile.%s Skip any first file, out of profile gamut patches\n",ICC_FILE_EXT_ND); fprintf(stderr," -X file.ccmx Apply Colorimeter Correction Matrix to second file\n"); // fprintf(stderr," -Z A|X Just print Average|Max +tab\n"); fprintf(stderr," target.ti3 Target (reference) PCS or spectral values.\n"); @@ -156,7 +156,8 @@ int main(int argc, char *argv[]) xspect cust_tillum, *tillump = NULL; /* Custom target/simulated illumination spectrum */ icxIllumeType illum = icxIT_none; /* Spectral defaults to D50 */ xspect cust_illum; /* Custom illumination spectrum */ - icxObserverType observ = icxOT_none; /* Defaults to 1931 2 degree */ + icxObserverType obType = icxOT_none; /* Defaults to 1931 2 degree */ + xspect custObserver[3]; /* If obType = icxOT_custom */ icmXYZNumber labw = icmD50; /* The Lab white reference */ @@ -375,21 +376,30 @@ int main(int argc, char *argv[]) fa = nfa; if (strcmp(na, "1931_2") == 0) { /* Classic 2 degree */ spec = 1; - observ = icxOT_CIE_1931_2; + obType = icxOT_CIE_1931_2; } else if (strcmp(na, "1964_10") == 0) { /* Classic 10 degree */ spec = 1; - observ = icxOT_CIE_1964_10; + obType = icxOT_CIE_1964_10; + } else if (strcmp(na, "2012_2") == 0) { /* Latest 2 degree */ + spec = 1; + obType = icxOT_CIE_2012_2; + } else if (strcmp(na, "2012_10") == 0) { /* Latest 10 degree */ + spec = 1; + obType = icxOT_CIE_2012_10; } else if (strcmp(na, "1955_2") == 0) { /* Stiles and Burch 1955 2 degree */ spec = 1; - observ = icxOT_Stiles_Burch_2; + obType = icxOT_Stiles_Burch_2; } else if (strcmp(na, "1978_2") == 0) { /* Judd and Voss 1978 2 degree */ spec = 1; - observ = icxOT_Judd_Voss_2; + obType = icxOT_Judd_Voss_2; } else if (strcmp(na, "shaw") == 0) { /* Shaw and Fairchilds 1997 2 degree */ spec = 1; - observ = icxOT_Shaw_Fairchild_2; - } else - usage(); + obType = icxOT_Shaw_Fairchild_2; + } else { /* Assume it's a filename */ + obType = icxOT_custom; + if (read_cmf(custObserver, na) != 0) + usage(); + } } /* Gamut limit profile for first file */ @@ -697,7 +707,7 @@ int main(int argc, char *argv[]) icxIllumeType l_tillum = tillum; xspect *l_tillump = tillump; icxIllumeType l_illum = illum; - icxObserverType l_observ = observ; + icxObserverType l_observ = obType; if ((ii = cgf->find_kword(cgf, 0, "SPECTRAL_BANDS")) < 0) error ("Input file doesn't contain keyword SPECTRAL_BANDS"); @@ -750,7 +760,7 @@ int main(int argc, char *argv[]) l_observ = icxOT_CIE_1931_2; if ((sp2cie = new_xsp2cie(l_illum, l_illum == icxIT_none ? NULL : &cust_illum, - l_observ, NULL, icSigXYZData, icxClamp)) == NULL) + l_observ, custObserver, icSigXYZData, icxClamp)) == NULL) error("Creation of spectral conversion object failed"); if (l_fwacomp) { @@ -939,8 +949,8 @@ int main(int argc, char *argv[]) /* Use location to match */ if (useloc) { for (i = 0; i < cg[0].npat; i++) { - if (cg[0].pat[0].loc == '\000' - || cg[1].pat[0].loc == '\000') + if (cg[0].pat[0].loc[0] == '\000' + || cg[1].pat[0].loc[0] == '\000') error("Need both files to have SAMPLE_LOC field to match on location"); for (j = 0; j < cg[1].npat; j++) { diff --git a/profile/invprofcheck.c b/profile/invprofcheck.c index 0d6176c..0d6176c 100644..100755 --- a/profile/invprofcheck.c +++ b/profile/invprofcheck.c diff --git a/profile/kodak2ti3.c b/profile/kodak2ti3.c index b510719..b510719 100644..100755 --- a/profile/kodak2ti3.c +++ b/profile/kodak2ti3.c diff --git a/profile/ls2ti3.c b/profile/ls2ti3.c index 3330e16..3330e16 100644..100755 --- a/profile/ls2ti3.c +++ b/profile/ls2ti3.c diff --git a/profile/mppcheck.c b/profile/mppcheck.c index 6615a84..6615a84 100644..100755 --- a/profile/mppcheck.c +++ b/profile/mppcheck.c diff --git a/profile/mppprof.c b/profile/mppprof.c index 41fe2fc..41fe2fc 100644..100755 --- a/profile/mppprof.c +++ b/profile/mppprof.c diff --git a/profile/printcal.c b/profile/printcal.c index 9bbcb41..9bbcb41 100644..100755 --- a/profile/printcal.c +++ b/profile/printcal.c diff --git a/profile/prof.h b/profile/prof.h index 486c5b8..eae8c9a 100644..100755 --- a/profile/prof.h +++ b/profile/prof.h @@ -62,7 +62,8 @@ void make_output_icc( icxIllumeType illum, /* CIE calc. illuminant spectrum, and FWA inst. */ /* illuminant if tillum not set. */ xspect *cust_illum, /* Custom CIE illumination spectrum if illum == icxIT_custom */ - icxObserverType observ, /* CIE calc. observer */ + icxObserverType obType, /* CIE calc. observer */ + xspect custObserver[3], /* If obType = icxOT_custom */ int fwacomp, /* FWA compensation requested */ double smooth, /* RSPL smoothing factor, -ve if raw */ double avgdev, /* reading Average Deviation as a proportion of the input range */ @@ -108,7 +109,8 @@ void make_input_icc( int spec, /* Use spectral data flag */ icxIllumeType illum, /* Spectral illuminant */ xspect *cust_illum, /* Possible custom illumination */ - icxObserverType observ, /* Spectral observer */ + icxObserverType obType, /* Spectral observer */ + xspect custObserver[3], /* If obType = icxOT_custom */ double smooth, /* RSPL smoothing factor, -ve if raw */ double avgdev, /* reading Average Deviation as a proportion of the input range */ profxinf *xpi /* Optional Profile creation extra data */ diff --git a/profile/profcheck.c b/profile/profcheck.c index c5703da..62d39bd 100644..100755 --- a/profile/profcheck.c +++ b/profile/profcheck.c @@ -71,7 +71,7 @@ usage(void) { fprintf(stderr," -i illum Choose illuminant for computation of CIE XYZ from spectral data & FWA:\n"); fprintf(stderr," A, C, D50 (def.), D50M2, D65, F5, F8, F10 or file.sp\n"); fprintf(stderr," -o observ Choose CIE Observer for spectral data:\n"); - fprintf(stderr," 1931_2 (def), 1964_10, S&B 1955_2, shaw, J&V 1978_2\n"); + fprintf(stderr," 1931_2 (def), 1964_10, 2012_2, 2012_10, S&B 1955_2, shaw, J&V 1978_2 or file.cmf\n"); fprintf(stderr," -I intent r = relative colorimetric, a = absolute (default)\n"); fprintf(stderr," data.ti3 Test data file\n"); fprintf(stderr," iccprofile.icm Profile to check against\n"); @@ -130,7 +130,8 @@ int main(int argc, char *argv[]) xspect cust_tillum, *tillump = NULL; /* Custom target/simulated illumination spectrum */ icxIllumeType illum = icxIT_none; /* Spectral defaults */ xspect cust_illum; /* Custom illumination spectrum */ - icxObserverType observ = icxOT_none; + icxObserverType obType = icxOT_none; + xspect custObserver[3]; /* If obType = icxOT_custom */ int sortbyde = 0; /* Sort by delta E */ @@ -363,21 +364,30 @@ int main(int argc, char *argv[]) fa = nfa; if (strcmp(na, "1931_2") == 0) { /* Classic 2 degree */ spec = 1; - observ = icxOT_CIE_1931_2; + obType = icxOT_CIE_1931_2; } else if (strcmp(na, "1964_10") == 0) { /* Classic 10 degree */ spec = 1; - observ = icxOT_CIE_1964_10; + obType = icxOT_CIE_1964_10; + } else if (strcmp(na, "2012_2") == 0) { /* Latest 2 degree */ + spec = 1; + obType = icxOT_CIE_2012_2; + } else if (strcmp(na, "2012_10") == 0) { /* Latest 10 degree */ + spec = 1; + obType = icxOT_CIE_2012_10; } else if (strcmp(na, "1955_2") == 0) { /* Stiles and Burch 1955 2 degree */ spec = 1; - observ = icxOT_Stiles_Burch_2; + obType = icxOT_Stiles_Burch_2; } else if (strcmp(na, "1978_2") == 0) { /* Judd and Voss 1978 2 degree */ spec = 1; - observ = icxOT_Judd_Voss_2; + obType = icxOT_Judd_Voss_2; } else if (strcmp(na, "shaw") == 0) { /* Shaw and Fairchilds 1997 2 degree */ spec = 1; - observ = icxOT_Shaw_Fairchild_2; - } else - usage(); + obType = icxOT_Shaw_Fairchild_2; + } else { /* Assume it's a filename */ + obType = icxOT_custom; + if (read_cmf(custObserver, na) != 0) + usage(); + } } /* Intent (only applies to ICC profile) */ @@ -466,8 +476,8 @@ int main(int argc, char *argv[]) if (illum == icxIT_none) illum = icxIT_D50; - if (observ == icxOT_none) - observ = icxOT_CIE_1931_2; + if (obType == icxOT_none) + obType = icxOT_CIE_1931_2; /* See if CIE is actually available - some sources of .TI3 don't provide it */ if (!spec @@ -482,7 +492,7 @@ int main(int argc, char *argv[]) printf("No CIE data found, switching to spectral with standard observer & D50\n"); spec = 1; illum = icxIT_D50; - observ = icxOT_CIE_1931_2; + obType = icxOT_CIE_1931_2; } /* Figure out what sort of device colorspace it is */ @@ -772,7 +782,7 @@ int main(int argc, char *argv[]) /* Create a spectral conversion object */ if ((sp2cie = new_xsp2cie(illum, illum == icxIT_none ? NULL : &cust_illum, - observ, NULL, icSigLabData, icxClamp)) == NULL) + obType, custObserver, icSigLabData, icxClamp)) == NULL) error("Creation of spectral conversion object failed"); if (fwacomp) { diff --git a/profile/profin.c b/profile/profin.c index 9287cf9..92317bb 100644..100755 --- a/profile/profin.c +++ b/profile/profin.c @@ -261,7 +261,8 @@ make_input_icc( int nooluts, /* nz to supress creation of output (PCS) shaper luts */ int nocied, /* nz to supress inclusion of .ti3 data in profile */ int verify, - int autowpsc, /* nz for Auto scale the WP to prevent clipping above WP patch */ + int autowpsc, /* 1 for Auto scale the WP to prevent clipping above WP patch */ + /* 2 = Force absolute colorimetric */ int clipovwp, /* nz for Clip cLUT values above WP */ double wpscale, /* >= 0.0 for media white point scale factor */ int dob2a, /* nz to create a B2A table as well */ @@ -274,7 +275,8 @@ make_input_icc( int spec, /* Use spectral data flag */ icxIllumeType illum, /* Spectral illuminant */ xspect *cust_illum, /* Possible custom illumination */ - icxObserverType observ, /* Spectral observer */ + icxObserverType obType, /* Spectral observer */ + xspect custObserver[3], /* If obType = icxOT_custom */ double smooth, /* RSPL smoothing factor, -ve if raw */ double avgdev, /* reading Average Deviation as a proportion of the input range */ profxinf *xpi /* Optional Profile creation extra data */ @@ -784,7 +786,7 @@ make_input_icc( illum = icxIT_none; cust_illum = NULL; } - if ((sp2cie = new_xsp2cie(illum, cust_illum, observ, NULL, + if ((sp2cie = new_xsp2cie(illum, cust_illum, obType, custObserver, wantLab ? icSigLabData : icSigXYZData, icxClamp)) == NULL) error("Creation of spectral conversion object failed"); @@ -835,8 +837,10 @@ make_input_icc( flags |= ICX_SET_WHITE; /* Compute & use white */ /* ICX_SET_WHITE_C isn't applicable to matrix profiles */ - if (autowpsc) + if (autowpsc == 1) flags |= ICX_SET_WHITE_US; /* Compute & use white without scaling to L */ + else if (autowpsc == 2) + flags |= ICX_SET_WHITE_ABS; /* Set dummy D50 white point to force absolute intent */ flags |= ICX_WRITE_WBL; /* Matrix: write white/black/luminence */ @@ -1117,8 +1121,10 @@ make_input_icc( flags |= ICX_SET_WHITE; /* Compute & use white */ if (clipovwp) flags |= ICX_SET_WHITE_C; /* Compute & use white and clip cLUT over D50 */ - else if (autowpsc) + else if (autowpsc == 1) flags |= ICX_SET_WHITE_US; /* Compute & use white without scaling to L */ + else if (autowpsc == 2) + flags |= ICX_SET_WHITE_ABS; /* Set dummy D50 white point to force absolute intent */ /* Setup RGB -> Lab conversion object from scattered data. */ /* Note that we've layered it on a native XYZ icc profile. */ diff --git a/profile/profout.c b/profile/profout.c index f12589b..47726f1 100644..100755 --- a/profile/profout.c +++ b/profile/profout.c @@ -684,7 +684,8 @@ make_output_icc( icxIllumeType illum, /* CIE calc. illuminant spectrum, and FWA inst. */ /* illuminant if tillum not set. */ xspect *cust_illum, /* Custom CIE illumination spectrum if illum == icxIT_custom */ - icxObserverType observ, /* CIE calc. observer */ + icxObserverType obType, /* CIE calc. observer */ + xspect custObserver[3], /* If obType = icxOT_custom */ int fwacomp, /* FWA compensation requested */ double smooth, /* RSPL smoothing factor, -ve if raw */ double avgdev, /* reading Average Deviation as a proportion of the input range */ @@ -1711,7 +1712,6 @@ make_output_icc( if (isdisp) { if (isLab) { icmLab2XYZ(&icmD50, tpat[i].v, tpat[i].v); - isLab = 0; } else if (isdnormed) { tpat[i].v[0] /= 100.0; /* Normalise XYZ to range 0.0 - 1.0 */ tpat[i].v[1] /= 100.0; @@ -1737,6 +1737,8 @@ make_output_icc( } } } + if (isdisp) /* Converted to XYZ for display */ + isLab = 0; } else { /* Using spectral data */ int ii; @@ -1790,13 +1792,13 @@ make_output_icc( if (!isdisp && illum != icxIT_D50) { ill_wp = _ill_wp; - /* Compute XYZ of illuminant */ - if (icx_ill_sp2XYZ(ill_wp, observ, NULL, illum, 0.0, cust_illum) != 0) + /* Compute normalised XYZ of illuminant */ + if (icx_ill_sp2XYZ(ill_wp, obType, custObserver, illum, 0.0, cust_illum, 0) != 0) error("icx_ill_sp2XYZ returned error"); } /* Create a spectral conversion object */ - if ((sp2cie = new_xsp2cie(illum, cust_illum, observ, NULL, + if ((sp2cie = new_xsp2cie(illum, cust_illum, obType, custObserver, wantLab ? icSigLabData : icSigXYZData, icxClamp)) == NULL) error("Creation of spectral conversion object failed"); @@ -2019,7 +2021,7 @@ make_output_icc( #ifdef IGNORE_DISP_ZEROS /* If a display has a very good black, and the instrument is not sensitive */ - /* enough to properly measur the near black values and returns 0.0, */ + /* enough to properly measure the near black values and returns 0.0, */ /* then the resulting profile will tend to incorrectly boost the */ /* dark shadows. A heuristic to counteract this problem is to */ /* ignore any readings that have any value <= 0.0 except */ @@ -2204,7 +2206,7 @@ make_output_icc( if (v->Yg >= 0.0) vc->Yg = v->Yg; if (v->Gxyz[0] >= 0.0 && v->Gxyz[1] > 0.0 && v->Gxyz[2] >= 0.0) { - /* Normalise XYZ to current media white */ + /* Normalise XYZ */ vc->Gxyz[0] = v->Gxyz[0]/v->Gxyz[1] * vc->Gxyz[1]; vc->Gxyz[2] = v->Gxyz[2]/v->Gxyz[1] * vc->Gxyz[1]; } @@ -2218,6 +2220,21 @@ make_output_icc( } if (v->hkscale >= 0.0) vc->hkscale = v->hkscale; + if (v->mtaf >= 0.0) + vc->mtaf = v->mtaf; + if (v->Wxyz2[0] >= 0.0 && v->Wxyz2[1] > 0.0 && v->Wxyz2[2] >= 0.0) { + /* Normalise XYZ */ + vc->Wxyz2[0] = v->Wxyz2[0]/v->Wxyz2[1] * vc->Wxyz2[1]; + vc->Wxyz2[2] = v->Wxyz2[2]/v->Wxyz2[1] * vc->Wxyz2[1]; + } + if (v->Wxyz2[0] >= 0.0 && v->Wxyz2[1] >= 0.0 && v->Wxyz2[2] < 0.0) { + /* Convert Yxy to XYZ */ + double x = v->Wxyz2[0]; + double y = v->Wxyz2[1]; /* If Y == 1.0, then X+Y+Z = 1/y */ + double z = 1.0 - x - y; + vc->Wxyz2[0] = x/y * vc->Wxyz2[1]; + vc->Wxyz2[2] = z/y * vc->Wxyz2[1]; + } } /* Get a suitable forward conversion object to invert. */ @@ -2540,7 +2557,8 @@ make_output_icc( cx.icam = new_icxcam(cam_default); cx.icam->set_view(cx.icam, ivc.Ev, ivc.Wxyz, ivc.La, ivc.Yb, ivc.Lv, ivc.Yf, ivc.Yg, ivc.Gxyz, - XICC_USE_HK, ivc.hkscale); + XICC_USE_HK, ivc.hkscale, + ivc.mtaf, ivc.Wxyz2); } /* Create a dumy source gamut, used by new_gammap to create */ diff --git a/profile/simpprof.c b/profile/simpprof.c index 61128ff..61128ff 100644..100755 --- a/profile/simpprof.c +++ b/profile/simpprof.c diff --git a/profile/splitti3.c b/profile/splitti3.c index eb92938..eb92938 100644..100755 --- a/profile/splitti3.c +++ b/profile/splitti3.c diff --git a/profile/txt2ti3.c b/profile/txt2ti3.c index 662fdc3..2a3d9e7 100644..100755 --- a/profile/txt2ti3.c +++ b/profile/txt2ti3.c @@ -24,7 +24,47 @@ Do we need to worry about normalising display values to Y = 100, or marking them not normalised ? - Should have an option to output .ti1 files instead of .ti3. + Should have an option to output .ti1 files instead of .ti3 ? + + Should parse and support XRGA & Polarized tags. + + + ~~ + + MEASUREMENT_SOURCE + iSis_INFO + Illumination=D50 + + ObserverAngle=2 + + Filter=Unknown + Filter=None + Filter=No + Filter=UVcut + Filter=D50 + + (??? + Filter=Polarizer + Filter=D65 + ???) + + MeasurementCondition=M1 + + ILLUMINATION_NAME "D50" + OBSERVER_ANGLE "2" + FILTER "UVcut" + + ICCOLOR_CSV + MeasurementOptics=Remission + + DEVCALSTD UNKNOWN + DEVCALSTD XRDI + DEVCALSTD GMDI + DEVCALSTD XRGA + + Cxf:DevicePolarization + Cxf:DeviceFilter + SpectralPolFilter */ @@ -57,7 +97,8 @@ usage(char *mes) { /* fprintf(stderr," -v Verbose mode\n"); */ fprintf(stderr," -2 Create dummy .ti2 file as well\n"); fprintf(stderr," -l limit set ink limit, 0 - 400%% (default max in file)\n"); - fprintf(stderr," -d Set type of device as Display, not Output\n"); + fprintf(stderr," -d Set type of device as Display, rather than Output\n"); + fprintf(stderr," -D Set type of device as Display and not normalized\n"); fprintf(stderr," -i Set type of device as Input, not Output\n"); fprintf(stderr," -T Transpose sample name Letters and Numbers\n"); fprintf(stderr," [devfile] Input Device CMYK target file (typically file.txt)\n"); @@ -73,7 +114,7 @@ int main(int argc, char *argv[]) int fa,nfa; /* current argument we're looking at */ int verb = 0; int out2 = 0; /* Create dumy .ti2 file output */ - int disp = 0; /* nz if this is a display device */ + int disp = 0; /* 1 if this is a display device, 2 if nor normalized */ int inp = 0; /* nz if this is an input device */ int transpose = 0; /* nz to transpose letters and numbers */ static char devname[MAXNAMEL+1] = { 0 }; /* Input CMYK/Device .txt file (may be null) */ @@ -96,7 +137,8 @@ int main(int argc, char *argv[]) time_t clk = time(0); struct tm *tsp = localtime(&clk); char *atm = asctime(tsp); /* Ascii time */ - char *devcalstd = NULL; /* X-Rite calibration standard if any */ + xcalstd calstd = xcalstd_none; /* X-Rite Calibration standard */ + int isPolarize = 0; /* nz if polarized measurement */ int islab = 0; /* CIE is Lab rather than XYZ */ int specmin = 0, specmax = 0, specnum = 0; /* Min and max spectral in nm, inclusive */ int npat = 0; /* Number of patches */ @@ -145,6 +187,10 @@ int main(int argc, char *argv[]) disp = 1; inp = 0; + } else if (argv[fa][1] == 'D') { + disp = 2; + inp = 0; + } else if (argv[fa][1] == 'i') { disp = 0; inp = 1; @@ -217,11 +263,25 @@ int main(int argc, char *argv[]) if ((npat = cmy->t[0].nsets) <= 0) error("No patches"); + /* See if we can figure out polarization and xrga */ + if ((ti = cmy->find_field(cmy, 0, "MEASUREMENT_SOURCE")) >= 0) { + if (strstr(cmy->t[0].kdata[ti], "Filter=Polarizer") != NULL) + isPolarize = 1; + } + if ((ti = cmy->find_field(cmy, 0, "FILTER")) >= 0) { + if (strstr(cmy->t[0].kdata[ti], "Polariz") != NULL) + isPolarize = 1; + } + if ((ti = cmy->find_field(cmy, 0, "DEVCALSTD")) >= 0) { + calstd = str2xcalstd(cmy->t[0].kdata[ti]); + } + if ((f_id1 = cmy->find_field(cmy, 0, "SampleName")) < 0 && (f_id1 = cmy->find_field(cmy, 0, "Sample_Name")) < 0 && (f_id1 = cmy->find_field(cmy, 0, "SAMPLE_NAME")) < 0 - && (f_id1 = cmy->find_field(cmy, 0, "SAMPLE_ID")) < 0) - error("Input file '%s' doesn't contain field SampleName, Sample_Name, SAMPLE_NAME or SAMPLE_ID",devname); + && (f_id1 = cmy->find_field(cmy, 0, "SAMPLE_ID")) < 0 + && (f_id1 = cmy->find_field(cmy, 0, "SampleID")) < 0) + error("Input file '%s' doesn't contain field SampleName, Sample_Name, SAMPLE_NAME, SAMPLE_ID or SampleID",devname); if (cmy->t[0].ftype[f_id1] != nqcs_t && cmy->t[0].ftype[f_id1] != cs_t && cmy->t[0].ftype[f_id1] != i_t) @@ -285,7 +345,8 @@ int main(int argc, char *argv[]) if (verb && ndchan > 0) printf("Read device values\n"); if (cmy->find_field(cmy, 0, "XYZ_X") >= 0 - || cmy->find_field(cmy, 0, "LAB_L") >= 0) { + || cmy->find_field(cmy, 0, "LAB_L") >= 0 + || cmy->find_field(cmy, 0, "Lab_L") >= 0) { /* We've got a new combined device+cie file as the first one. */ /* Shuffle it into ciename , and ciename into specname */ @@ -308,21 +369,33 @@ int main(int argc, char *argv[]) if (npat != ncie->t[0].nsets) error("Number of patches between '%s' and '%s' doesn't match",devname,ciename); + /* See if we can figure out polarization and xrga */ + if ((ti = ncie->find_field(ncie, 0, "MEASUREMENT_SOURCE")) >= 0) { + if (strstr(ncie->t[0].kdata[ti], "Filter=Polarizer") != NULL) + isPolarize = 1; + } + if ((ti = ncie->find_field(ncie, 0, "FILTER")) >= 0) { + if (strstr(ncie->t[0].kdata[ti], "Polariz") != NULL) + isPolarize = 1; + } + if ((ti = ncie->find_field(ncie, 0, "DEVCALSTD")) >= 0) { + calstd = str2xcalstd(ncie->t[0].kdata[ti]); + } + if ((f_id2 = ncie->find_field(ncie, 0, "SampleName")) < 0 && (f_id2 = ncie->find_field(ncie, 0, "Sample_Name")) < 0 && (f_id2 = ncie->find_field(ncie, 0, "SAMPLE_NAME")) < 0 - && (f_id2 = ncie->find_field(ncie, 0, "SAMPLE_ID")) < 0) - error("Input file '%s' doesn't contain field SampleName, Sample_Name, SAMPLE_NAME or SAMPLE_ID",ciename); + && (f_id2 = ncie->find_field(ncie, 0, "SAMPLE_ID")) < 0 + && (f_id2 = ncie->find_field(ncie, 0, "SampleID")) < 0) + error("Input file '%s' doesn't contain field SampleName, Sample_Name, SAMPLE_NAME, SAMPLE_ID or SampleID",ciename); if (ncie->t[0].ftype[f_id2] != nqcs_t && ncie->t[0].ftype[f_id2] != cs_t - && cmy->t[0].ftype[f_id2] != i_t) + && ncie->t[0].ftype[f_id2] != i_t) error("Field SampleName (%s) from cie file '%s' is wrong type",ncie->t[0].fsym[f_id2],ciename); - if ((ti = ncie->find_kword(ncie, 0, "DEVCALSTD")) >= 0) - devcalstd = ncie->t[0].kdata[ti]; - if (ncie->find_field(ncie, 0, "XYZ_X") < 0 - && ncie->find_field(ncie, 0, "LAB_L") < 0) { + && ncie->find_field(ncie, 0, "LAB_L") < 0 + && ncie->find_field(ncie, 0, "Lab_L") < 0) { /* Not a cie file. See if it's a spectral file */ if (ncie->find_field(ncie, 0, "nm500") < 0 @@ -330,7 +403,7 @@ int main(int argc, char *argv[]) && ncie->find_field(ncie, 0, "SPECTRAL_NM_500") < 0 && ncie->find_field(ncie, 0, "R_500") < 0 && ncie->find_field(ncie, 0, "SPECTRAL_500") < 0) - error("Input file '%s' doesn't contain field XYZ_X or spectral",ciename); /* Nope */ + error("Input file '%s' doesn't contain field XYZ_X, LAB_L or spectral",ciename); /* Nope */ /* We have a spectral file only. Fix things and drop through */ ncie->del(ncie); @@ -339,9 +412,11 @@ int main(int argc, char *argv[]) ciename[0] = '\000'; } else { /* Continue dealing with cie value file */ - char *fields[2][3] = { + int fix = 0; + char *fields[3][3] = { { "XYZ_X", "XYZ_Y", "XYZ_Z" }, - { "LAB_L", "LAB_A", "LAB_B" } + { "LAB_L", "LAB_A", "LAB_B" }, + { "Lab_L", "Lab_a", "Lab_b" } }; if (ncie->find_field(ncie, 0, "nm500") >= 0 @@ -354,16 +429,22 @@ int main(int argc, char *argv[]) strcpy(specname, ciename); } - if (ncie->find_field(ncie, 0, "LAB_L") >= 0) + if (ncie->find_field(ncie, 0, "LAB_L") >= 0) { + fix = 1; + islab = 1; + } else if (ncie->find_field(ncie, 0, "Lab_L") >= 0) { + fix = 2; islab = 1; + } for (i = 0; i < 3; i++) { - if ((f_cie[i] = ncie->find_field(ncie, 0, fields[islab][i])) < 0) - error("Input file '%s' doesn't contain field XYZ_Y",fields[islab][i], ciename); + if ((f_cie[i] = ncie->find_field(ncie, 0, fields[fix][i])) < 0 + && (f_cie[i] = ncie->find_field(ncie, 0, fields[fix+1][i])) < 0) + error("Input file '%s' doesn't contain field %s",ciename,fields[fix][i]); if (ncie->t[0].ftype[f_cie[i]] != r_t) - error("Field %s from file '%s' is wrong type - expect float",fields[islab][i], ciename); + error("Field %s from file '%s' is wrong type - expect float",fields[fix][i], ciename); } if (verb) printf("Found CIE values\n"); @@ -385,14 +466,28 @@ int main(int argc, char *argv[]) if (npat != spec->t[0].nsets) error("Number of patches between '%s' and '%s' doesn't match",specname); + /* See if we can figure out polarization and xrga */ + if ((ti = spec->find_field(spec, 0, "MEASUREMENT_SOURCE")) >= 0) { + if (strstr(spec->t[0].kdata[ti], "Filter=Polarizer") != NULL) + isPolarize = 1; + } + if ((ti = spec->find_field(spec, 0, "FILTER")) >= 0) { + if (strstr(spec->t[0].kdata[ti], "Polariz") != NULL) + isPolarize = 1; + } + if ((ti = spec->find_field(spec, 0, "DEVCALSTD")) >= 0) { + calstd = str2xcalstd(spec->t[0].kdata[ti]); + } + if ((f_id3 = spec->find_field(spec, 0, "SampleName")) < 0 && (f_id3 = spec->find_field(spec, 0, "Sample_Name")) < 0 && (f_id3 = spec->find_field(spec, 0, "SAMPLE_NAME")) < 0 - && (f_id3 = spec->find_field(spec, 0, "SAMPLE_ID")) < 0) - error("Input file '%s' doesn't contain field SampleName, Sample_Name, SAMPLE_NAME or SAMPLE_ID",specname); + && (f_id3 = spec->find_field(spec, 0, "SAMPLE_ID")) < 0 + && (f_id3 = spec->find_field(spec, 0, "SampleID")) < 0) + error("Input file '%s' doesn't contain field SampleName, Sample_Name, SAMPLE_NAME, SAMPLE_ID or SampleID",specname); if (spec->t[0].ftype[f_id3] != nqcs_t && spec->t[0].ftype[f_id3] != cs_t - && cmy->t[0].ftype[f_id3] != i_t) + && spec->t[0].ftype[f_id3] != i_t) error("Field SampleName (%s) from spec file '%s' is wrong type",spec->t[0].fsym[f_id3],specname); /* Find the spectral readings nm range */ @@ -486,9 +581,12 @@ int main(int argc, char *argv[]) ocg->add_kword(ocg, 0, "ORIGINATOR", "Argyll target", NULL); atm[strlen(atm)-1] = '\000'; /* Remove \n from end */ ocg->add_kword(ocg, 0, "CREATED",atm, NULL); - if (disp) + if (disp) { ocg->add_kword(ocg, 0, "DEVICE_CLASS","DISPLAY", NULL); /* What sort of device this is */ - else if (inp) + + if (disp == 2) + ocg->add_kword(ocg, 0, "NORMALIZED_TO_Y_100","NO", NULL); /* What sort of device this is */ + }else if (inp) ocg->add_kword(ocg, 0, "DEVICE_CLASS","INPUT", NULL); /* What sort of device this is */ else ocg->add_kword(ocg, 0, "DEVICE_CLASS","OUTPUT", NULL); /* What sort of device this is */ @@ -497,8 +595,11 @@ int main(int argc, char *argv[]) /* Assume this - could try reading from file INSTRUMENTATION "SpectroScan" ?? */ ocg->add_kword(ocg, 0, "TARGET_INSTRUMENT", inst_name(instSpectrolino) , NULL); - if (devcalstd != NULL) - ocg->add_kword(ocg, 0, "DEVCALSTD", devcalstd, NULL); + if (calstd != xcalstd_none) + ocg->add_kword(ocg, 0, "DEVCALSTD", xcalstd2str(calstd), NULL); + + if (isPolarize) + ocg->add_kword(ocg, 0, "INSTRUMENT_FILTER", "POLARIZED", NULL); /* Fields we want */ ocg->add_field(ocg, 0, "SAMPLE_ID", nqcs_t); |