From 3db384424bd7398ffbb7a355cab8f15f3add009f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 2 Oct 2016 19:24:58 +0200 Subject: New upstream version 1.9.1+repack --- spectro/chartread.c | 326 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 237 insertions(+), 89 deletions(-) (limited to 'spectro/chartread.c') diff --git a/spectro/chartread.c b/spectro/chartread.c index 9cf6c22..e1624e1 100644 --- a/spectro/chartread.c +++ b/spectro/chartread.c @@ -1,7 +1,8 @@ +/* Spectrometer/Colorimeter target test chart reader */ + /* * Argyll Color Correction System - * Spectrometer/Colorimeter target test chart reader * * Author: Graeme W. Gill * Date: 4/10/96 @@ -58,6 +59,11 @@ #define COMPORT 1 /* Default com port 1..4 */ +#undef TEST_EVENT_CALLBACK /* Report async event callbacks, and implement beep prompt there. */ + +#undef USESTRDELTA /* [Und] Use patch delat's for correlation rather than match DE */ + /* Doesn't seem to work as well. Why ? */ + #ifdef __MINGW32__ # define WINVER 0x0500 #endif @@ -69,22 +75,36 @@ #include #include #include +#ifndef SALONEINSTLIB #include "copyright.h" #include "aconfig.h" -#include "cgats.h" #include "numlib.h" -#include "icc.h" #include "xicc.h" -#include "insttypes.h" #include "conv.h" +#include "ui.h" +#include "icc.h" +#else /* SALONEINSTLIB */ +#include "sa_config.h" +#include "numsup.h" +#include "cgats.h" +#include "rspl1.h" +#include "xspect.h" +#include "xcolorants.h" +#include "xcal.h" +#include "conv.h" +#include "sa_conv.h" +#endif /* SALONEINSTLIB */ +#include "cgats.h" +#include "insttypes.h" #include "icoms.h" #include "inst.h" #include "ccmx.h" #include "ccss.h" +#ifndef SALONEINSTLIB #include "dispwin.h" -#include "ui.h" #include "ccast.h" #include "dispsup.h" +#endif /* !SALONEINSTLIB */ #include "alphix.h" #include "sort.h" #include "instappsup.h" @@ -132,6 +152,24 @@ static double xyzLabDE(double ynorm, double *pat, double *ref) { return icmLabDE(Lab1, Lab2); } +#ifdef USESTRDELTA +/* Return the -ve correlation of the delta E's between steps */ +static double xyzLabcorr(double *pat0, double *ref0, + double *pat1, double *ref1) { + double p0[3], p1[3], pd[3]; + double r0[3], r1[3], rd[3]; + + icmXYZ2Lab(&icmD50, p0, pat0); + icmXYZ2Lab(&icmD50, p1, pat1); + ICMSUB3(pd, p0, p1); + icmXYZ2Lab(&icmD50, r0, ref0); + icmXYZ2Lab(&icmD50, r1, ref1); + ICMSUB3(rd, r0, r1); + + return -icmDot3(rd, pd); +} +#endif + /* A chart read color structure */ /* This can hold all representations simultaniously */ typedef struct { @@ -169,6 +207,15 @@ static int b62_int(char *p) { return rv; } +#ifdef TEST_EVENT_CALLBACK +void test_event_callback(void *cntx, inst_event_type event) { + a1logd(g_log,0,"Got event_callback with 0x%x\n",event); + + if (event == inst_event_scan_ready) + normal_beep(); +} +#endif + /* Deal with an instrument error. */ /* Return 0 to retry, 1 to abort */ static int ierror(inst *it, inst_code ic) { @@ -211,6 +258,8 @@ int displ, /* 1 = Use display emissive mode, 2 = display bright rel. */ /* 3 = display white rel. */ int dtype, /* Display type selection charater */ inst_opt_filter fe, /* Optional filter */ +xcalstd scalstd, /* X-Rite calibration standard to set */ +xcalstd *ucalstd, /* X-Rite calibration standard actually used */ int nocal, /* Disable initial calibration */ int disbidi, /* Disable automatic bi-directional strip recognition */ int highres, /* Use high res spectral mode */ @@ -224,6 +273,7 @@ int spectral, /* Generate spectral info flag */ int uvmode, /* ~~~ i1pro2 test mode ~~~ */ int accurate_expd, /* Expected values can be assumed to be accurate */ int emit_warnings, /* Emit warnings for wrong strip, unexpected value */ +int doplot, /* Plot each spectra in patch by patch mode */ a1log *log /* verb, debug & error log */ ) { inst *it = NULL; @@ -251,6 +301,11 @@ a1log *log /* verb, debug & error log */ printf("Unknown, inappropriate or no instrument detected\n"); return -1; } + +#ifdef TEST_EVENT_CALLBACK + it->set_event_callback(it, test_event_callback, (void *)it); +#endif + /* Establish communications */ if ((rv = it->init_coms(it, br, fc, 15.0)) != inst_ok) { printf("Establishing communications with instrument failed with message '%s' (%s)\n", @@ -276,6 +331,24 @@ a1log *log /* verb, debug & error log */ return -1; } + /* For reflective */ + if (emis == 0 && trans == 0) { + + /* set XRGA conversion */ + if (scalstd != xcalstd_none) { + if ((rv = it->get_set_opt(it, inst_opt_set_xcalstd, scalstd)) != inst_ok) { + printf("Warning: Setting calibration standard not supported by instrument\n"); + } + } + + /* Get actual XRGA conversion */ + if (ucalstd != NULL) { + if ((rv = it->get_set_opt(it, inst_opt_get_xcalstd, ucalstd)) != inst_ok) { + *ucalstd = xcalstd_none; + } + } + } + *atype = it->get_itype(it); /* Actual instrument type */ if (*atype != itype) a1logv(log, 1, "Warning: chart is for %s, using instrument %s\n",inst_name(itype),inst_name(*atype)); @@ -297,8 +370,8 @@ a1log *log /* verb, debug & error log */ } else if (emis || displ) { if (emis) { - if (!IMODETST(cap, inst_mode_emis_spot) - && !IMODETST(cap, inst_mode_emis_strip)) { + if (it->check_mode(it, inst_mode_emis_spot) != inst_ok + && it->check_mode(it, inst_mode_emis_strip) != inst_ok) { printf("Need emissive spot or strip reading capability\n"); printf("and instrument doesn't support it\n"); it->del(it); @@ -306,7 +379,7 @@ a1log *log /* verb, debug & error log */ } } else { /* Should we allow for non-adaptive mode ? */ - if (!IMODETST(cap, inst_mode_emis_spot)) { + if (it->check_mode(it, inst_mode_emis_spot) != inst_ok) { printf("Need emissive reading capability\n"); printf("and instrument doesn't support it\n"); it->del(it); @@ -314,7 +387,7 @@ a1log *log /* verb, debug & error log */ } } - } else { + } else { /* reflectance */ if (!IMODETST(cap, inst_mode_reflection)) { printf("Need reflection spot, strip, xy or chart reading capability,\n"); printf("and instrument doesn't support it\n"); @@ -461,20 +534,17 @@ a1log *log /* verb, debug & error log */ /* Should look at instrument type & user spec ??? */ if (trans) { - if (pbypatch && IMODETST(cap, inst_mode_trans_spot) + if (pbypatch && it->check_mode(it, inst_mode_trans_spot) == inst_ok) { mode = inst_mode_trans_spot; rmode = 0; - } else if (IMODETST(cap, inst_mode_trans_chart) - && it->check_mode(it, inst_mode_trans_chart) == inst_ok) { + } else if (it->check_mode(it, inst_mode_trans_chart) == inst_ok) { mode = inst_mode_trans_chart; rmode = 3; - } else if (IMODETST(cap, inst_mode_trans_xy) - && it->check_mode(it, inst_mode_trans_xy) == inst_ok) { + } else if (it->check_mode(it, inst_mode_trans_xy) == inst_ok) { mode = inst_mode_trans_xy; rmode = 2; - } else if (IMODETST(cap, inst_mode_trans_strip) - && it->check_mode(it, inst_mode_trans_strip) == inst_ok) { + } else if (it->check_mode(it, inst_mode_trans_strip) == inst_ok) { mode = inst_mode_trans_strip; rmode = 1; } else { @@ -482,23 +552,24 @@ a1log *log /* verb, debug & error log */ rmode = 0; } } else if (displ) { +printf("~1 using displ mode\n"); /* We assume a display mode will always be spot by spot */ mode = inst_mode_emis_spot; rmode = 0; } else if (emis) { - if (pbypatch && IMODETST(cap, inst_mode_emis_spot) +printf("~1 using emis mode\n"); + if (pbypatch && it->check_mode(it, inst_mode_emis_spot) == inst_ok) { mode = inst_mode_emis_spot; rmode = 0; - } else if (IMODETST(cap, inst_mode_emis_strip) - && it->check_mode(it, inst_mode_emis_strip) == inst_ok) { + } else if (it->check_mode(it, inst_mode_emis_strip) == inst_ok) { mode = inst_mode_emis_strip; rmode = 1; } else { mode = inst_mode_emis_spot; rmode = 0; } - } else { + } else { /* Reflectance */ inst_stat_savdrd sv = inst_stat_savdrd_none; /* See if instrument has a saved mode, and if it has data that */ @@ -602,58 +673,50 @@ a1log *log /* verb, debug & error log */ } if (pbypatch - && IMODETST(cap, inst_mode_s_ref_spot) && it->check_mode(it, inst_mode_s_ref_spot) == inst_ok && (sv & inst_stat_savdrd_spot)) { mode = inst_mode_s_ref_spot; svdmode = 1; rmode = 0; - } else if (IMODETST(cap, inst_mode_s_ref_chart) - && it->check_mode(it, inst_mode_s_ref_chart) == inst_ok + } else if (it->check_mode(it, inst_mode_s_ref_chart) == inst_ok && (sv & inst_stat_savdrd_chart)) { mode = inst_mode_s_ref_chart; svdmode = 1; rmode = 3; - } else if (IMODETST(cap, inst_mode_s_ref_xy) - && it->check_mode(it, inst_mode_s_ref_xy) == inst_ok + } else if (it->check_mode(it, inst_mode_s_ref_xy) == inst_ok && (sv & inst_stat_savdrd_xy)) { mode = inst_mode_s_ref_xy; svdmode = 1; rmode = 2; - } else if (IMODETST(cap, inst_mode_s_ref_strip) - && it->check_mode(it, inst_mode_s_ref_strip) == inst_ok + } else if (it->check_mode(it, inst_mode_s_ref_strip) == inst_ok && (sv & inst_stat_savdrd_strip)) { mode = inst_mode_s_ref_strip; svdmode = 1; rmode = 1; - } else if (IMODETST(cap, inst_mode_s_ref_spot) - && it->check_mode(it, inst_mode_s_ref_spot) == inst_ok + } else if (it->check_mode(it, inst_mode_s_ref_spot) == inst_ok && (sv & inst_stat_savdrd_spot)) { mode = inst_mode_s_ref_spot; svdmode = 1; rmode = 0; - } else if (pbypatch && IMODETST(cap, inst_mode_ref_spot) + } else if (pbypatch && it->check_mode(it, inst_mode_ref_spot) == inst_ok) { mode = inst_mode_ref_spot; rmode = 0; - } else if (IMODETST(cap, inst_mode_ref_chart) - && it->check_mode(it, inst_mode_ref_chart) == inst_ok) { + } else if (it->check_mode(it, inst_mode_ref_chart) == inst_ok) { mode = inst_mode_ref_chart; rmode = 3; - } else if (IMODETST(cap, inst_mode_ref_xy) - && it->check_mode(it, inst_mode_ref_xy) == inst_ok) { + } else if (it->check_mode(it, inst_mode_ref_xy) == inst_ok) { mode = inst_mode_ref_xy; rmode = 2; - } else if (IMODETST(cap, inst_mode_ref_strip) - && it->check_mode(it, inst_mode_ref_strip) == inst_ok) { + } else if (it->check_mode(it, inst_mode_ref_strip) == inst_ok) { mode = inst_mode_ref_strip; rmode = 1; @@ -1076,6 +1139,12 @@ a1log *log /* verb, debug & error log */ int pai; /* Current pass in current strip */ int oroi; /* Overall row index */ + if ( + itype != instDTP20 && + !rand && disbidi == 0) { + warning("Can't do bi-directional strip recognition without randomized patch locations"); + } + /* Do any needed calibration before the user places the instrument on a desired spot */ if (it->needs_calibration(it) & inst_calt_n_dfrble_mask) { if ((rv = inst_handle_calibrate(it, inst_calt_needed, inst_calc_none, NULL, NULL, 0)) @@ -1168,6 +1237,7 @@ a1log *log /* verb, debug & error log */ pai = 0; } //printf("~1 stix = %d, pis[stix] = %d, oroi = %d, rr %d\n",stix, pis[stix],oroi,scols[oroi * stipa]->rr); + // Note we aren't protecting agains a bodgy pis[] value if (incflag == 1 || scols[oroi * stipa]->rr == 0 || oroi == s_oroi) break; } @@ -1261,8 +1331,8 @@ a1log *log /* verb, debug & error log */ /* Not all rows have been read */ empty_con_chars(); - printf("\nDone ? - At least one unread patch (%s), Are you sure [y/n]: ", - scols[i]->loc); + printf("\nDone ? - At least one unread patch (%s, %s), Are you sure [y/n]: ", + scols[i]->id, scols[i]->loc); fflush(stdout); ch = next_con_char(); printf("\n"); @@ -1333,7 +1403,8 @@ a1log *log /* verb, debug & error log */ return -1; } printf("\n"); - if (it->icom->port_type(it->icom) == icomt_serial) { + if ((it->icom->port_type(it->icom) & icomt_serial) + && !(it->icom->port_attr(it->icom) & icomt_fastserial)) { /* Allow retrying at a lower baud rate */ int tt = it->last_scomerr(it); if (tt & (ICOM_BRK | ICOM_FER | ICOM_PER | ICOM_OER)) { @@ -1386,9 +1457,9 @@ a1log *log /* verb, debug & error log */ double werror = 0.0; /* Worst case error in best correlation strip */ double xbcorr = 1e6; /* Expected pass correlation value */ - int xboff; /* Expected pass offset */ + int xboff; /* Expected pass best offset */ int xbdir; /* Expected pass overall pass direction */ - double xwerror = 0.0; /* Expected pass worst error in best strip */ + double xwerror = 0.0; /* Expected pass worst patcch error */ if (rand && disbidi == 0 && (cap2 & inst2_bidi_scan)) dirrg = 2; /* Enable bi-directional strip recognition */ @@ -1426,17 +1497,29 @@ a1log *log /* verb, debug & error log */ } /* Compare just sample patches (not padding Max/Min) */ - for (pwerr = corr = 0.0, n = 0, i = 0; i < stipa; i++, n++) { +#ifdef USESTRDELTA + for (pwerr = corr = 0.0, n = 0, i = 0; i < (stipa-1); i++, n++) +#else + for (pwerr = corr = 0.0, n = 0, i = 0; i < stipa; i++, n++) +#endif + { double vcorr; - int ix = i+skipp+toff; - if (dir != 0) + int ix = i+skipp+toff, ix1 = ix+1; + if (dir != 0) { ix = stipa - 1 - ix; + ix1 = stipa - 1 - ix1; + } if (vals[ix].XYZ_v == 0) error("Instrument didn't return XYZ value"); +#ifdef USESTRDELTA + vcorr = xyzLabcorr(vals[ix].XYZ, scb[i]->eXYZ, + vals[ix1].XYZ, scb[i+1]->eXYZ); +#else vcorr = xyzLabDE(ynorm, vals[ix].XYZ, scb[i]->eXYZ); +#endif //printf("DE %f from vals[%d] %f %f %f and scols[%d] %f %f %f\n", vcorr, ix, vals[ix].XYZ[0], vals[ix].XYZ[1], vals[ix].XYZ[2], i + choroi * stipa, scb[i]->eXYZ[0], scb[i]->eXYZ[1], scb[i]->eXYZ[2]); corr += vcorr; - if (vcorr > pwerr) + if (vcorr > pwerr) /* Worsed patch error */ pwerr = vcorr; } corr /= (double)n; @@ -1444,16 +1527,16 @@ a1log *log /* verb, debug & error log */ printf(" Strip %d dir %d offset %d correlation = %f\n",choroi,dir,toff,corr); #endif - /* Expected strip correlation and */ - /* best fir to off by 1 and direction */ + /* If this is the expected strip, */ + /* note correlation and best fit to off by 1 and direction */ if (choroi == oroi && corr < xbcorr) { - xbcorr = corr; + xbcorr = corr; /* Expected strip correlation */ xboff = toff; xbdir = dir; xwerror = pwerr; /* Expected passes worst error */ } - /* Best matched strip correlation */ + /* Best overall matched strip correlation */ if (corr < bcorr) { boroi = choroi; bcorr = corr; @@ -1624,6 +1707,7 @@ a1log *log /* verb, debug & error log */ inst_set_uih('G', 'G', DUIH_CMND); inst_set_uih('d', 'd', DUIH_CMND); inst_set_uih('D', 'D', DUIH_CMND); + inst_set_uih('k', 'k', DUIH_CMND); inst_set_uih('q', 'q', DUIH_ABORT); inst_set_uih('Q', 'Q', DUIH_ABORT); inst_set_uih(0xd, 0xd, DUIH_TRIG); /* Return */ @@ -1637,7 +1721,7 @@ a1log *log /* verb, debug & error log */ incflag = 3; /* Until we're done */ - for(;pix < npat;) { + for (;pix < npat;) { char buf[200], *bp = NULL, *ep = NULL; char ch = 0; @@ -1716,7 +1800,7 @@ a1log *log /* verb, debug & error log */ } if (xtern != 0) { /* User entered values */ - printf("\nReady to read patch '%s'%s\n",scols[pix]->loc, + printf("\nReady to read patch '%s' at '%s'%s\n",scols[pix]->id, scols[pix]->loc, i >= npat ? "(All patches read!)" : strcmp(scols[pix]->id, "0") == 0 ? " (Padding Patch)" : scols[pix]->rr ? " (Already read)" : ""); @@ -1747,7 +1831,7 @@ a1log *log /* verb, debug & error log */ empty_con_chars(); - printf("\nReady to read patch '%s'%s\n",scols[pix]->loc, + printf("\nReady to read patch '%s' at '%s'%s\n",scols[pix]->id, scols[pix]->loc, i >= npat ? " (All patches read!)" : strcmp(scols[pix]->id, "0") == 0 ? " (Padding Patch)" : scols[pix]->rr ? " (Already read)" : ""); @@ -1755,7 +1839,7 @@ a1log *log /* verb, debug & error log */ printf("hit 'f' to move forward, 'F' move forward 10,\n"); printf(" 'b' to move back, 'B; to move back 10,\n"); printf(" 'n' for next unread, 'g' to goto patch,\n"); - printf(" 'd' when done, to abort,\n"); + printf(" 'd' when done, 'k' to calibrate, to abort,\n"); if (uswitch) printf(" Instrument switch, or to read:"); @@ -1772,7 +1856,7 @@ a1log *log /* verb, debug & error log */ good_beep(); ch = '0'; - /* Deal with user trigger */ + /* Deal with user trigger via user interface callback function */ } else if ((rv & inst_mask) == inst_user_trig) { if (cap2 & inst2_no_feedback) good_beep(); @@ -1841,7 +1925,8 @@ a1log *log /* verb, debug & error log */ return -1; } printf("\n"); - if (it->icom->port_type(it->icom) == icomt_serial) { + if ((it->icom->port_type(it->icom) & icomt_serial) + && !(it->icom->port_attr(it->icom) & icomt_fastserial)) { /* Allow retrying at a lower baud rate */ int tt = it->last_scomerr(it); if (tt & (ICOM_BRK | ICOM_FER | ICOM_PER | ICOM_OER)) { @@ -1891,6 +1976,15 @@ a1log *log /* verb, debug & error log */ } printf("\n"); continue; + } else if (ch == 'k') { + inst_code ev; + + ev = inst_handle_calibrate(it, inst_calt_available, inst_calc_none, NULL, NULL, 0); + if (ev != inst_ok) { /* Abort or fatal error */ + it->del(it); + return -1; + } + continue; } else if (ch == 'f') { incflag = 1; continue; @@ -1920,8 +2014,8 @@ a1log *log /* verb, debug & error log */ /* Not all patches have been read */ empty_con_chars(); - printf("\nDone ? - At least one unread patch (%s), Are you sure [y/n]: ", - scols[i]->loc); + printf("\nDone ? - At least one unread patch (%s, %s), Are you sure [y/n]: ", + scols[i]->id, scols[i]->loc); fflush(stdout); if ((ch = next_con_char()) == 0x1b) { printf("\n"); @@ -1996,6 +2090,10 @@ a1log *log /* verb, debug & error log */ } scols[pix]->rr = 1; /* Has been read */ printf(" Patch read OK\n"); + + if (doplot && val.sp.spec_n > 0) + xspect_plot_w(&val.sp, NULL, NULL, 0); + /* Advance to next patch. */ incflag = 1; } else { /* Unrecognised response */ @@ -2018,7 +2116,7 @@ usage() { fprintf(stderr,"usage: chartread [-options] outfile\n"); fprintf(stderr," -v Verbose mode\n"); fprintf(stderr," -c listno Set communication port from the following list (default %d)\n",COMPORT); - if ((icmps = new_icompaths(NULL)) != NULL) { + if ((icmps = new_icompaths(g_log)) != NULL) { icompath **paths; if ((paths = icmps->paths) != NULL) { int i; @@ -2046,6 +2144,7 @@ usage() { fprintf(stderr," p Polarising filter\n"); fprintf(stderr," 6 D65\n"); fprintf(stderr," u U.V. Cut\n"); + fprintf(stderr," -A N|A|X|G XRGA conversion (default N)\n"); fprintf(stderr," -N Disable initial calibration of instrument if possible\n"); fprintf(stderr," -B Disable auto bi-directional strip recognition\n"); fprintf(stderr," -H Use high resolution spectrum mode (if available)\n"); @@ -2055,12 +2154,19 @@ usage() { int i; fprintf(stderr," -X file.ccss Use Colorimeter Calibration Spectral Samples for calibration\n"); fprintf(stderr," -Q observ Choose CIE Observer for CCSS instrument:\n"); +#ifdef SALONEINSTLIB + fprintf(stderr," 1931_2 (def), 1964_10\n"); +#else /* !SALONEINSTLIB */ fprintf(stderr," 1931_2 (def), 1964_10, S&B 1955_2, shaw, J&V 1978_2\n"); +#endif /* !SALONEINSTLIB */ } fprintf(stderr," -T ratio Modify strip patch consistency tolerance by ratio\n"); fprintf(stderr," -S Suppress wrong strip & unexpected value warnings\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"); +#ifndef SALONEINSTLIB + fprintf(stderr," -P Plot spectral if patch by patch\n"); +#endif fprintf(stderr," -D [level] Print debug diagnostics to stderr\n"); fprintf(stderr," outfile Base name for input[ti2]/output[ti3] file\n"); if (icmps != NULL) @@ -2092,11 +2198,14 @@ int main(int argc, char *argv[]) { int xtern = 0; /* Take external values, 1 = Lab, 2 = XYZ */ int spectral = 1; /* Save spectral information */ int uvmode = 0; /* ~~~ i1pro2 test mode ~~~ */ + xcalstd scalstd = xcalstd_none; /* X-Rite calibration standard to set */ + xcalstd ucalstd = xcalstd_none; /* X-Rite calibration standard actually used */ int accurate_expd = 0; /* Expected value assumed to be accurate */ int emit_warnings = 1; /* Emit warnings for wrong strip, unexpected value */ int dolab = 0; /* 1 = Save CIE as Lab, 2 = Save CIE as XYZ and Lab */ int doresume = 0; /* Resume reading a chart */ int nocal = 0; /* Disable initial calibration */ + int doplot = 0; /* Plot spectral of patch by patch */ char ccxxname[MAXNAMEL+1] = "\000"; /* Colorimeter Correction/Colorimeter Calibration name */ icxObserverType obType = icxOT_default; /* ccss observer */ static char inname[MAXNAMEL+1] = { 0 }; /* Input cgats file base name */ @@ -2191,12 +2300,14 @@ int main(int argc, char *argv[]) { obType = icxOT_CIE_1931_2; } else if (strcmp(na, "1964_10") == 0) { /* Classic 10 degree */ obType = icxOT_CIE_1964_10; +#ifndef SALONEINSTLIB } else if (strcmp(na, "1955_2") == 0) { /* Stiles and Burch 1955 2 degree */ obType = icxOT_Stiles_Burch_2; } else if (strcmp(na, "1978_2") == 0) { /* Judd and Voss 1978 2 degree */ obType = icxOT_Judd_Voss_2; } else if (strcmp(na, "shaw") == 0) { /* Shaw and Fairchilds 1997 2 degree */ obType = icxOT_Shaw_Fairchild_2; +#endif /* !SALONEINSTLIB */ } else usage(); } @@ -2217,7 +2328,7 @@ int main(int argc, char *argv[]) { fa = nfa; if (na == NULL) usage(); if (na[0] == 'n' || na[0] == 'N') - fc = fc_none; + fc = fc_None; else if (na[0] == 'h' || na[0] == 'H') fc = fc_Hardware; else if (na[0] == 'x' || na[0] == 'X') @@ -2320,6 +2431,27 @@ int main(int argc, char *argv[]) { else usage(); + /* XRGA conversion */ + } else if (argv[fa][1] == 'A') { + fa = nfa; + if (na == NULL) usage(); + if (na[0] == 'N') + scalstd = xcalstd_none; + else if (na[0] == 'A') + scalstd = xcalstd_xrga; + else if (na[0] == 'X') + scalstd = xcalstd_xrdi; + else if (na[0] == 'G') + scalstd = xcalstd_gmdi; + else + usage(); + +#ifndef SALONEINSTLIB + /* Plot spectral patch by patch */ + } else if (argv[fa][1] == 'P') { + doplot = 1; +#endif + /* Extra flags */ } else if (argv[fa][1] == 'Y') { if (na == NULL) @@ -2392,7 +2524,7 @@ int main(int argc, char *argv[]) { if ((itype = inst_enum(icg->t[0].kdata[ti])) == instUnknown) error ("Unrecognised chart target instrument '%s'", icg->t[0].kdata[ti]); } else { - itype = instDTP41; /* Default chart target instrument */ + itype = instI1Pro; /* Default chart target instrument */ } } @@ -2508,10 +2640,6 @@ int main(int argc, char *argv[]) { tlen = atof(icg->t[0].kdata[ti]); } - if (itype != instDTP20 && !rand && disbidi == 0) { - warning("Can't do bi-directional strip recognition without randomize patch locations"); - } - if (verb) { printf("Steps in each Pass = %d\n",stipa); printf("Passes in each Strip = "); @@ -2537,6 +2665,8 @@ int main(int argc, char *argv[]) { totpa = (npat + stipa -1)/stipa; /* Total passes for all strips */ runpat = stipa * totpa; /* Rounded up totao number of patches */ + if (runpat < npat) /* (If pattern doesn't match patches) */ + runpat = npat; if ((cols = (chcol *)malloc(sizeof(chcol) * runpat)) == NULL) error("Malloc failed!"); if ((scols = (chcol **)calloc(sizeof(chcol *), runpat)) == NULL) @@ -2684,29 +2814,40 @@ int main(int argc, char *argv[]) { cal = NULL; } - /* Set up the location sorted array of pointers */ - for (i = 0; i < npat; i++) { - scols[i] = &cols[i]; - if ((cols[i].loci = patch_location_order(paix, saix, ixord, cols[i].loc)) < 0) - error ("Bad location field value '%s' on patch %d", cols[i].loc, i); - } - for (; i < runpat; i++) { /* Extra on end */ - scols[i] = &cols[i]; - cols[i].loci = (totpa-1) * (256 - stipa) + i; + /* Set up the location sorted array of pointers. */ + /* If the order is not randomized, we don't care what form */ + /* the location identifiers take - i.e. they can be arbitrary. */ + { + int badloc = 0; + + for (i = 0; i < npat; i++) { + scols[i] = &cols[i]; + if ((cols[i].loci = patch_location_order(paix, saix, ixord, cols[i].loc)) < 0) + badloc = 1; + } + for (; i < runpat; i++) { /* Extra on end */ + scols[i] = &cols[i]; + cols[i].loci = (totpa-1) * (256 - stipa) + i; /* printf("~~extra = %d, %d\n",cols[i].loci >> 8, cols[i].loci & 255); */ - } + } - /* Reset 'read' flag and all data */ - for (i = 0; i < runpat; i++) { - cols[i].rr = 0; - cols[i].XYZ[0] = -1.0; - cols[i].XYZ[1] = -1.0; - cols[i].XYZ[2] = -1.0; - cols[i].sp.spec_n = 0; - } + /* Reset 'read' flag and all data */ + for (i = 0; i < runpat; i++) { + cols[i].rr = 0; + cols[i].XYZ[0] = -1.0; + cols[i].XYZ[1] = -1.0; + cols[i].XYZ[2] = -1.0; + cols[i].sp.spec_n = 0; + } + + if (rand && badloc) + error ("Bad location field value '%s' on patch %d", cols[i].loc, i); + if (!badloc) { #define HEAP_COMPARE(A,B) (A->loci < B->loci) - HEAPSORT(chcol *, scols, npat); + HEAPSORT(chcol *, scols, npat); + } + } /* If we're resuming a chartread, fill in all the patches that */ /* have been read. */ @@ -2840,17 +2981,20 @@ int main(int argc, char *argv[]) { } } - if ((icmps = new_icompaths(g_log)) == NULL) - error("Finding instrument paths failed"); - if ((ipath = icmps->get_path(icmps, comport)) == NULL) - error("No instrument at port %d",comport); + if (!xtern) { + if ((icmps = new_icompaths(g_log)) == NULL) + error("Finding instrument paths failed"); + if ((ipath = icmps->get_path(icmps, comport)) == NULL) + error("No instrument at port %d",comport); + } /* Read all of the strips in */ if (read_strips(itype, scols, &atype, npat, totpa, stipa, pis, paix, saix, ixord, rstart, rand, hex, ipath, fc, plen, glen, tlen, - trans, emis, displ, dtype, fe, nocal, disbidi, highres, ccxxname, obType, + trans, emis, displ, dtype, fe, scalstd, &ucalstd, nocal, disbidi, highres, + ccxxname, obType, scan_tol, pbypatch, xtern, spectral, uvmode, accurate_expd, - emit_warnings, g_log) == 0) { + emit_warnings, doplot, g_log) == 0) { /* And save the result */ int nrpat; /* Number of read patches */ @@ -2861,6 +3005,10 @@ int main(int argc, char *argv[]) { /* Note what instrument the chart was read with */ ocg->add_kword(ocg, 0, "TARGET_INSTRUMENT", inst_name(atype) , NULL); + /* X-Rite calibration standard (If reflective mode) */ + if (displ == 0 && trans == 0 && ucalstd != xcalstd_none) + ocg->add_kword(ocg, 0, "DEVCALSTD",xcalstd2str(ucalstd), NULL); + /* Count patches actually read */ for (nrpat = i = 0; i < npat; i++) { if (cols[i].rr) { -- cgit v1.2.3