From c07d0c2d2f6f7b0eb6e92cc6204bf05037957e82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 1 Sep 2014 15:43:52 +0200 Subject: Imported Upstream version 1.6.3 --- spectro/spotread.c | 206 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 147 insertions(+), 59 deletions(-) (limited to 'spectro/spotread.c') diff --git a/spectro/spotread.c b/spectro/spotread.c index 3218243..4d65916 100644 --- a/spectro/spotread.c +++ b/spectro/spotread.c @@ -20,6 +20,9 @@ /* a spectrometer or colorimeter. */ /* TTBD + * + * Make -V average the spectrum too (if present), and allow it to + * be saved to a .sp file. * * Should fix plot so that it is a separate object running its own thread, * so that it can be sent a graph without needing to be clicked in all the time. @@ -287,10 +290,10 @@ usage(char *diag, ...) { fprintf(stderr," -t Use transmission measurement mode\n"); fprintf(stderr," -e Use emissive measurement mode (absolute results)\n"); fprintf(stderr," -eb Use display white brightness relative measurement mode\n"); - fprintf(stderr," -ew Use display white relative measurement mode\n"); + fprintf(stderr," -ew Use display white point relative chromatically adjusted mode\n"); fprintf(stderr," -p Use telephoto measurement mode (absolute results)\n"); fprintf(stderr," -pb Use projector white brightness relative measurement mode\n"); - fprintf(stderr," -pw Use projector white relative measurement mode\n"); + fprintf(stderr," -pw Use projector white point relative chromatically adjusted mode\n"); fprintf(stderr," -a Use ambient measurement mode (absolute results)\n"); fprintf(stderr," -f Use ambient flash measurement mode (absolute results)\n"); cap2 = inst_show_disptype_options(stderr, " -y ", icmps, 0); @@ -334,6 +337,7 @@ usage(char *diag, ...) { fprintf(stderr," -X file.ccss Use Colorimeter Calibration Spectral Samples for calibration\n"); } fprintf(stderr," -Y r|n Override refresh, non-refresh display mode\n"); + fprintf(stderr," -Y R:rate Override measured refresh rate with rate Hz\n"); fprintf(stderr," -Y A Use non-adaptive integration time mode (if available).\n"); // fprintf(stderr," -Y U Test i1pro2 UV measurement mode\n"); fprintf(stderr," -W n|h|x Override serial port flow control: n = none, h = HW, x = Xon/Xoff\n"); @@ -361,7 +365,8 @@ int main(int argc, char *argv[]) { int ambient = 0; /* 1 = Use ambient emissive mode, 2 = ambient flash mode */ int highres = 0; /* Use high res mode if available */ int uvmode = 0; /* ~~~ i1pro2 test mode ~~~ */ - int refrmode = -1; /* -1 = default, 0 = non-refresh mode, 1 = non-refresh mode */ + int refrmode = -1; /* -1 = default, 0 = non-refresh mode, 1 = refresh mode */ + double refrate = 0.0; /* 0.0 = default, > 0.0 = override refresh rate */ int nadaptive = 0; /* Use non-apative mode if available */ int doYxy= 0; /* Display Yxy instead of Lab */ int doLCh= 0; /* Display LCh instead of Lab */ @@ -398,6 +403,7 @@ int main(int argc, char *argv[]) { xsp2cie *sp2cie = NULL; /* default conversion */ xsp2cie *sp2cief[26]; /* FWA corrected conversions */ double wXYZ[3] = { -10.0, 0, 0 };/* White XYZ for display white relative */ + double chmat[3][3]; /* Chromatic adapation matrix */ double Lab[3] = { -10.0, 0, 0}; /* Last Lab */ double rXYZ[3] = { 0.0, -10.0, 0}; /* Reference XYZ */ double rLab[3] = { -10.0, 0, 0}; /* Reference Lab */ @@ -467,8 +473,10 @@ int main(int argc, char *argv[]) { } else if (argv[fa][1] == 'c') { fa = nfa; if (na == NULL) usage("Paramater expected following -c"); - comport = atoi(na); - if (comport < 1 || comport > 40) usage("-c parameter %d out of range",comport); + { + comport = atoi(na); + if (comport < 1 || comport > 40) usage("-c parameter %d out of range",comport); + } /* Display type */ } else if (argv[fa][1] == 'y') { @@ -702,19 +710,6 @@ int main(int argc, char *argv[]) { if (na == NULL) usage("Parameter expected after -K"); strncpy(ccxxname,na,MAXNAMEL-1); ccxxname[MAXNAMEL-1] = '\000'; - /* Serial port flow control */ - } else if (argv[fa][1] == 'W') { - fa = nfa; - if (na == NULL) usage("Parameter expected after -W"); - if (na[0] == 'n' || na[0] == 'N') - fc = fc_none; - else if (na[0] == 'h' || na[0] == 'H') - fc = fc_Hardware; - else if (na[0] == 'x' || na[0] == 'X') - fc = fc_XonXOff; - else - usage("-W parameter '%c' not recognised",na[0]); - /* Extra flags */ } else if (argv[fa][1] == 'Y') { if (na == NULL) @@ -726,12 +721,32 @@ int main(int argc, char *argv[]) { refrmode = 1; } else if (na[0] == 'n') { refrmode = 0; + } else if (na[0] == 'R') { + if (na[1] != ':') + usage("-Y R:rate syntax incorrect"); + refrate = atof(na+2); + if (refrate < 5.0 || refrate > 150.0) + usage("-Y R:rate %f Hz not in valid range",refrate); /* ~~~ i1pro2 test code ~~~ */ } else if (na[0] == 'U') { uvmode = 1; } else { usage("-Y parameter '%c' not recognised",na[0]); } + fa = nfa; + + /* Serial port flow control */ + } else if (argv[fa][1] == 'W') { + fa = nfa; + if (na == NULL) usage("Parameter expected after -W"); + if (na[0] == 'n' || na[0] == 'N') + fc = fc_none; + else if (na[0] == 'h' || na[0] == 'H') + fc = fc_Hardware; + else if (na[0] == 'x' || na[0] == 'X') + fc = fc_XonXOff; + else + usage("-W parameter '%c' not recognised",na[0]); } else usage("Flag -%c not recognised",argv[fa][1]); @@ -765,7 +780,6 @@ int main(int argc, char *argv[]) { if ((ipath = icmps->get_path(icmps, comport)) == NULL) error("No instrument at port %d",comport); - /* Setup the instrument ready to do reads */ if ((it = new_inst(ipath, 0, g_log, DUIH_FUNC_AND_CONTEXT)) == NULL) { usage("Unknown, inappropriate or no instrument detected"); @@ -852,14 +866,7 @@ int main(int argc, char *argv[]) { || it->check_mode(it, inst_mode_emis_ambient) != inst_ok) { printf("Requested ambient light capability,\n"); printf("and instrument doesn't support it.\n"); - if (!IMODETST(cap, inst_mode_emis_spot)) { - it->del(it); - return -1; - } else { - printf("Will use emissive mode instead,\n"); - printf("but note that light level readings may be wrong!\n"); - - } + return -1; } else { if (verb) { printf("Please make sure the instrument is fitted with\n"); @@ -884,6 +891,12 @@ int main(int argc, char *argv[]) { } else if (emiss || tele) { + /* If there is a tele mode but no emission, use tele */ + if (!IMODETST(cap, inst_mode_emis_spot) + && IMODETST(cap, inst_mode_emis_tele)) { + tele = 1; + } + if (tele) { if (!IMODETST(cap, inst_mode_emis_tele) || it->check_mode(it, inst_mode_emis_tele) != inst_ok) { @@ -915,10 +928,8 @@ int main(int argc, char *argv[]) { refrmode = -1; } } - /* Set display type */ if (dtype != 0) { - if (cap2 & inst2_disptype) { int ix; if ((ix = inst_get_disptype_index(it, dtype, 0)) < 0) { @@ -973,21 +984,6 @@ int main(int argc, char *argv[]) { printf("Disable initial-calibrate not supported\n"); } } - if (highres) { - if (IMODETST(cap, inst_mode_highres)) { - inst_code ev; - if ((ev = it->get_set_opt(it, inst_opt_highres)) != inst_ok) { - printf("\nSetting high res mode failed with error :'%s' (%s)\n", - it->inst_interp_error(it, ev), it->interp_error(it, ev)); - it->del(it); - return -1; - } - highres = 1; - } else if (verb) { - printf("high resolution ignored - instrument doesn't support high res. mode\n"); - } - } - /* Set it to the appropriate mode */ /* Should look at instrument type & user spec ??? */ @@ -1032,6 +1028,16 @@ int main(int argc, char *argv[]) { smode |= inst_mode_spectral; } + if (highres) { + if (IMODETST(cap, inst_mode_highres)) { + mode |= inst_mode_highres; + smode |= inst_mode_highres; + } else if (verb) { + printf("high resolution ignored - instrument doesn't support high res. mode\n"); + highres = 0; + } + } + // ~~~ i1pro2 test code ~~~ */ if (uvmode) { if (!IMODETST(cap, inst_mode_ref_uv)) { @@ -1128,6 +1134,21 @@ int main(int argc, char *argv[]) { } } + if (refrate > 0.0) { + if (!(cap2 & inst2_set_refresh_rate)) { + if (verb) + printf("Attempted to set refresh rate and instrument doesn't support setting it (ignored)\n"); + refrate = 0.0; + } else { + if ((rv = it->set_refr_rate(it, refrate)) != inst_ok) { + printf("\nSetting instrument refresh rate to %f Hz failed with error :'%s' (%s)\n", + refrate, it->inst_interp_error(it, rv), it->interp_error(it, rv)); + it->del(it); + return -1; + } + } + } + /* If non-standard observer wasn't set by a CCSS file above */ if (obType != icxOT_default && (cap2 & inst2_ccss) && ccssset == 0) { if ((rv = it->get_set_opt(it, inst_opt_set_ccss_obs, obType, 0)) != inst_ok) { @@ -1138,7 +1159,12 @@ int main(int argc, char *argv[]) { } } - /* If it batter powered, show the status of the battery */ + /* Warm the user that they should do a frequency calibration */ + if (it->needs_calibration(it) & inst_calt_ref_freq) { + printf("Please read an 80%% white patch first to calibrate refresh frequency\n"); + } + + /* If it battery powered, show the status of the battery */ if ((cap2 & inst2_has_battery)) { double batstat = 0.0; if ((rv = it->get_set_opt(it, inst_stat_battery, &batstat)) != inst_ok) { @@ -1186,6 +1212,8 @@ int main(int argc, char *argv[]) { inst_set_uih('K', 'K', DUIH_CMND); inst_set_uih('s', 's', DUIH_CMND); inst_set_uih('S', 'S', DUIH_CMND); + if (cap2 & inst2_has_target) + inst_set_uih('t', 't', DUIH_CMND); inst_set_uih('f', 'f', DUIH_CMND); inst_set_uih('F', 'F', DUIH_CMND); inst_set_uih('q', 'q', DUIH_ABORT); @@ -1239,7 +1267,7 @@ int main(int argc, char *argv[]) { /* Read spots until the user quits */ for (ix = 1;; ix++) { ipatch val; - double XYZ[3]; /* XYZ scaled 0..100 or absolute */ + double XYZ[3] = { 0.0, 0.0, 0.0 }; /* XYZ scaled 0..100 or absolute */ double tXYZ[3]; #ifndef SALONEINSTLIB double cct, vct, vdt; @@ -1250,6 +1278,43 @@ int main(int argc, char *argv[]) { int dofwa = 0; /* Do FWA compensation */ int fidx = -1; /* FWA compensated index, default = none */ +#ifdef NEVER // test i1d3 min_int_time code + { + double cval; + char *cp; + + if ((rv = it->get_set_opt(it, inst_opt_get_min_int_time, &cval)) != inst_ok) { + printf("\nGetting min_int)time failed with error :'%s' (%s)\n", + it->inst_interp_error(it, rv), it->interp_error(it, rv)); + it->del(it); + return -1; + } + printf("Current min int time = %f\n",cval); + + if ((cp = getenv("I1D3_MIN_INT_TIME")) != NULL) { + cval = atof(cp); + + printf("Setting int time %f\n",cval); + if ((rv = it->get_set_opt(it, inst_opt_set_min_int_time, cval)) != inst_ok) { + printf("\nSetting min_int_time failed with error :'%s' (%s)\n", + it->inst_interp_error(it, rv), it->interp_error(it, rv)); + it->del(it); + return -1; + } + + if ((rv = it->get_set_opt(it, inst_opt_get_min_int_time, &cval)) != inst_ok) { + printf("\nGetting min_int)time failed with error :'%s' (%s)\n", + it->inst_interp_error(it, rv), it->interp_error(it, rv)); + it->del(it); + return -1; + } + + printf("Check current min int time = %f\n",cval); + } + } + +#endif // NEVER + if (savdrd != -1 && IMODETST(cap, inst_mode_s_ref_spot) && it->check_mode(it, inst_mode_s_ref_spot) == inst_ok) { inst_stat_savdrd sv; @@ -1429,6 +1494,8 @@ int main(int argc, char *argv[]) { printf("Hit 'r' to set reference\n"); #endif /* SALONEINSTLIB */ printf("'h' to toggle high res., 'k' to do a calibration\n"); + if (cap2 & inst2_has_target) + printf("'t' to toggle laser target\n"); } if (uswitch) printf("Hit ESC or Q to exit, instrument switch or any other key to take a reading: "); @@ -1610,9 +1677,21 @@ int main(int argc, char *argv[]) { if (ch == 0x1b || ch == 0x03 || ch == 'q' || ch == 'Q') { /* Or ^C */ break; } + if ((cap2 & inst2_has_target) && ch == 't') { // Toggle target + inst_code ev; + if ((ev = it->get_set_opt(it, inst_opt_set_target_state, 2)) != inst_ok) { + printf("\nToggling target failed with error :'%s' (%s)\n", + it->inst_interp_error(it, ev), it->interp_error(it, ev)); + it->del(it); + return -1; + } + --ix; + continue; + } if (ch == 'H' || ch == 'h') { /* Toggle high res mode */ if (IMODETST(cap, inst_mode_highres)) { inst_code ev; + /* Hmm. Could simply re-do set_mode() here instead */ if (highres) { if ((ev = it->get_set_opt(it, inst_opt_stdres)) != inst_ok) { printf("\nSetting std res mode failed with error :'%s' (%s)\n", @@ -1778,7 +1857,7 @@ int main(int argc, char *argv[]) { double refr; inst_code ev; - if (!(cap2 & inst2_refresh_rate)) { + if (!(cap2 & inst2_get_refresh_rate)) { printf("\nInstrument isn't capable of refresh rate calibration\n"); --ix; continue; @@ -2063,7 +2142,7 @@ int main(int argc, char *argv[]) { #endif /* SALONEINSTLIB */ if (emiss > 1 || tele > 1) { - if (wXYZ[0] < 0.0) { + if (wXYZ[0] < 0.0) { /* If we haven't save a white ref. yet */ if (XYZ[1] < 10.0) error ("White of XYZ %f %f %f doesn't seem reasonable",XYZ[0], XYZ[1], XYZ[2]); printf("\n Making result XYZ: %f %f %f, D50 Lab: %f %f %f white reference.\n", @@ -2071,6 +2150,13 @@ int main(int argc, char *argv[]) { wXYZ[0] = XYZ[0]; wXYZ[1] = XYZ[1]; wXYZ[2] = XYZ[2]; +#ifndef SALONEINSTLIB + { /* Compute a Chromatic adapation matrix to D50 */ + icmXYZNumber s_wp; + icmAry2XYZ(s_wp, wXYZ); + icmChromAdaptMatrix(ICM_CAM_BRADFORD, icmD50, s_wp, chmat); + } +#endif /* !SALONEINSTLIB */ continue; } if (emiss == 2 || tele == 2) { @@ -2080,12 +2166,14 @@ int main(int argc, char *argv[]) { XYZ[2] = 100.0 * XYZ[2] / wXYZ[1]; } #ifndef SALONEINSTLIB - else { + else { /* emiss == 3, white point relative */ /* Normalize to white and scale to 0..100 */ - XYZ[0] = XYZ[0] * icmD50_100.X / wXYZ[0]; - XYZ[1] = XYZ[1] * icmD50_100.Y / wXYZ[1]; - XYZ[2] = XYZ[2] * icmD50_100.Z / wXYZ[2]; +// XYZ[0] = XYZ[0] * icmD50_100.X / wXYZ[0]; +// XYZ[1] = XYZ[1] * icmD50_100.Y / wXYZ[1]; +// XYZ[2] = XYZ[2] * icmD50_100.Z / wXYZ[2]; + icmMulBy3x3(XYZ, chmat, XYZ); + icmScale3(XYZ, XYZ, 100.0); } /* recompute Lab */ @@ -2174,25 +2262,25 @@ int main(int argc, char *argv[]) { printf(" Apparent flash duration = %f seconds\n",val.duration); if (cap2 & inst2_ambient_mono) { printf(" Ambient = %.1f Lux%s\n", - 3.141592658 * XYZ[1], ambient == 2 ? "-Seconds" : ""); + XYZ[1], ambient == 2 ? "-Seconds" : ""); if (ambient != 2) printf(" Suggested EV @ ISO100 for %.1f Lux incident light = %.1f\n", - 3.141592658 * XYZ[1], - log(3.141592658 * XYZ[1]/2.5)/log(2.0)); + XYZ[1], + log(XYZ[1]/2.5)/log(2.0)); } else { #ifndef SALONEINSTLIB printf(" Ambient = %.1f Lux%s, CCT = %.0fK (Delta E %f)\n", - 3.1415926 * XYZ[1], ambient == 2 ? "-Seconds" : "", + XYZ[1], ambient == 2 ? "-Seconds" : "", cct, cct_de); if (ambient != 2) printf(" Suggested EV @ ISO100 for %.1f Lux incident light = %.1f\n", - 3.141592658 * XYZ[1], - log(3.141592658 * XYZ[1]/2.5)/log(2.0)); + XYZ[1], + log(XYZ[1]/2.5)/log(2.0)); printf(" Closest Planckian temperature = %.0fK (Delta E %f)\n",vct, vct_de); printf(" Closest Daylight temperature = %.0fK (Delta E %f)\n",vdt, vdt_de); #else /* SALONEINSTLIB */ printf(" Ambient = %.1f Lux%s\n", - 3.1415926 * XYZ[1], ambient == 2 ? "-Seconds" : ""); + XYZ[1], ambient == 2 ? "-Seconds" : ""); #endif /* SALONEINSTLIB */ } #ifndef SALONEINSTLIB -- cgit v1.2.3