summaryrefslogtreecommitdiff
path: root/spectro
diff options
context:
space:
mode:
Diffstat (limited to 'spectro')
-rwxr-xr-x[-rw-r--r--]spectro/IntsLib_Readme.txt0
-rwxr-xr-x[-rw-r--r--]spectro/Jamfile34
-rwxr-xr-x[-rw-r--r--]spectro/License.txt0
-rwxr-xr-x[-rw-r--r--]spectro/License2.txt0
-rwxr-xr-x[-rw-r--r--]spectro/License3.txt0
-rwxr-xr-x[-rw-r--r--]spectro/LzmaDec.c0
-rwxr-xr-x[-rw-r--r--]spectro/LzmaDec.h0
-rwxr-xr-x[-rw-r--r--]spectro/LzmaTypes.h0
-rwxr-xr-x[-rw-r--r--]spectro/Makefile.OSX0
-rwxr-xr-x[-rw-r--r--]spectro/Makefile.SA0
-rwxr-xr-x[-rw-r--r--]spectro/Makefile.UNIX0
-rwxr-xr-x[-rw-r--r--]spectro/Makefile.WNT0
-rwxr-xr-x[-rw-r--r--]spectro/Readme.txt0
-rwxr-xr-x[-rw-r--r--]spectro/SOtele.sp0
-rwxr-xr-x[-rw-r--r--]spectro/afiles3
-rwxr-xr-x[-rw-r--r--]spectro/aglob.c0
-rwxr-xr-x[-rw-r--r--]spectro/aglob.h0
-rwxr-xr-x[-rw-r--r--]spectro/average.c0
-rwxr-xr-x[-rw-r--r--]spectro/base64.c0
-rwxr-xr-x[-rw-r--r--]spectro/base64.h0
-rwxr-xr-x[-rw-r--r--]spectro/ccwin.c0
-rwxr-xr-x[-rw-r--r--]spectro/ccwin.h0
-rwxr-xr-x[-rw-r--r--]spectro/ccxx.ti10
-rwxr-xr-x[-rw-r--r--]spectro/ccxxmake.c48
-rwxr-xr-x[-rw-r--r--]spectro/chartread.c34
-rwxr-xr-x[-rw-r--r--]spectro/colorhug.c7
-rwxr-xr-x[-rw-r--r--]spectro/colorhug.h0
-rwxr-xr-x[-rw-r--r--]spectro/conv.c41
-rwxr-xr-x[-rw-r--r--]spectro/conv.h4
-rwxr-xr-x[-rw-r--r--]spectro/cubecal.h0
-rwxr-xr-x[-rw-r--r--]spectro/dev.h6
-rwxr-xr-x[-rw-r--r--]spectro/dispcal.c217
-rwxr-xr-x[-rw-r--r--]spectro/dispread.c39
-rwxr-xr-x[-rw-r--r--]spectro/dispsup.c2
-rwxr-xr-x[-rw-r--r--]spectro/dispsup.h0
-rwxr-xr-x[-rw-r--r--]spectro/disptechs.c0
-rwxr-xr-x[-rw-r--r--]spectro/disptechs.h0
-rwxr-xr-x[-rw-r--r--]spectro/dispwin.c580
-rwxr-xr-x[-rw-r--r--]spectro/dispwin.h14
-rwxr-xr-x[-rw-r--r--]spectro/dtp20.c5
-rwxr-xr-x[-rw-r--r--]spectro/dtp20.h0
-rwxr-xr-x[-rw-r--r--]spectro/dtp22.c15
-rwxr-xr-x[-rw-r--r--]spectro/dtp22.h0
-rwxr-xr-x[-rw-r--r--]spectro/dtp41.c5
-rwxr-xr-x[-rw-r--r--]spectro/dtp41.h0
-rwxr-xr-x[-rw-r--r--]spectro/dtp51.c5
-rwxr-xr-x[-rw-r--r--]spectro/dtp51.h0
-rwxr-xr-x[-rw-r--r--]spectro/dtp92.c37
-rwxr-xr-x[-rw-r--r--]spectro/dtp92.h0
-rwxr-xr-x[-rw-r--r--]spectro/ex1.c7
-rwxr-xr-x[-rw-r--r--]spectro/ex1.h0
-rwxr-xr-x[-rw-r--r--]spectro/fakeread.c0
-rwxr-xr-x[-rw-r--r--]spectro/hcfr.c7
-rwxr-xr-x[-rw-r--r--]spectro/hcfr.h0
-rwxr-xr-x[-rw-r--r--]spectro/hidio.c3
-rwxr-xr-x[-rw-r--r--]spectro/hidio.h0
-rwxr-xr-x[-rw-r--r--]spectro/huey.c28
-rwxr-xr-x[-rw-r--r--]spectro/huey.h0
-rwxr-xr-x[-rw-r--r--]spectro/i1d3.c81
-rwxr-xr-x[-rw-r--r--]spectro/i1d3.h5
-rwxr-xr-x[-rw-r--r--]spectro/i1disp.c81
-rwxr-xr-x[-rw-r--r--]spectro/i1disp.h7
-rwxr-xr-x[-rw-r--r--]spectro/i1pro.c11
-rwxr-xr-x[-rw-r--r--]spectro/i1pro.h2
-rwxr-xr-x[-rw-r--r--]spectro/i1pro_imp.c117
-rwxr-xr-x[-rw-r--r--]spectro/i1pro_imp.h0
-rwxr-xr-x[-rw-r--r--]spectro/icoms.c179
-rwxr-xr-x[-rw-r--r--]spectro/icoms.h32
-rwxr-xr-x[-rw-r--r--]spectro/icoms_nt.c26
-rwxr-xr-x[-rw-r--r--]spectro/icoms_ux.c62
-rwxr-xr-x[-rw-r--r--]spectro/ifiles0
-rwxr-xr-x[-rw-r--r--]spectro/illumread.c8
-rwxr-xr-x[-rw-r--r--]spectro/inflate.c0
-rwxr-xr-x[-rw-r--r--]spectro/inst.c365
-rwxr-xr-x[-rw-r--r--]spectro/inst.h37
-rwxr-xr-x[-rw-r--r--]spectro/instappsup.c3
-rwxr-xr-x[-rw-r--r--]spectro/instappsup.h0
-rwxr-xr-x[-rw-r--r--]spectro/instlib.ksh0
-rwxr-xr-x[-rw-r--r--]spectro/instlib.txt0
-rwxr-xr-x[-rw-r--r--]spectro/insttypeinst.h0
-rwxr-xr-x[-rw-r--r--]spectro/insttypes.c90
-rwxr-xr-x[-rw-r--r--]spectro/insttypes.h30
-rwxr-xr-x[-rw-r--r--]spectro/iusb.h0
-rwxr-xr-x[-rw-r--r--]spectro/kleink10.c11
-rwxr-xr-x[-rw-r--r--]spectro/kleink10.h0
-rwxr-xr-x[-rw-r--r--]spectro/linear.sp0
-rwxr-xr-x[-rw-r--r--]spectro/madvrwin.c0
-rwxr-xr-x[-rw-r--r--]spectro/madvrwin.h0
-rwxr-xr-x[-rw-r--r--]spectro/mongoose.c0
-rwxr-xr-x[-rw-r--r--]spectro/mongoose.h0
-rwxr-xr-x[-rw-r--r--]spectro/munki.c5
-rwxr-xr-x[-rw-r--r--]spectro/munki.h2
-rwxr-xr-x[-rw-r--r--]spectro/munki_imp.c12
-rwxr-xr-x[-rw-r--r--]spectro/munki_imp.h3
-rwxr-xr-x[-rw-r--r--]spectro/oemarch.c1
-rwxr-xr-x[-rw-r--r--]spectro/oemarch.h0
-rwxr-xr-x[-rw-r--r--]spectro/oeminst.c4
-rwxr-xr-x[-rw-r--r--]spectro/pollem.c0
-rwxr-xr-x[-rw-r--r--]spectro/pollem.h0
-rwxr-xr-x[-rw-r--r--]spectro/rspec.c7
-rwxr-xr-x[-rw-r--r--]spectro/rspec.h0
-rwxr-xr-x[-rw-r--r--]spectro/sa_conv.c0
-rwxr-xr-x[-rw-r--r--]spectro/sa_conv.h0
-rwxr-xr-x[-rw-r--r--]spectro/smcube.c7
-rwxr-xr-x[-rw-r--r--]spectro/smcube.h0
-rwxr-xr-x[-rw-r--r--]spectro/spec2cie.c159
-rwxr-xr-x[-rw-r--r--]spectro/specbos.c260
-rwxr-xr-x[-rw-r--r--]spectro/specbos.h3
-rwxr-xr-x[-rw-r--r--]spectro/spotread.c153
-rwxr-xr-x[-rw-r--r--]spectro/spyd2.c72
-rwxr-xr-x[-rw-r--r--]spectro/spyd2.h0
-rwxr-xr-x[-rw-r--r--]spectro/ss.c71
-rwxr-xr-x[-rw-r--r--]spectro/ss.h0
-rwxr-xr-x[-rw-r--r--]spectro/ss_imp.c1
-rwxr-xr-x[-rw-r--r--]spectro/ss_imp.h0
-rwxr-xr-x[-rw-r--r--]spectro/synthcal.c0
-rwxr-xr-x[-rw-r--r--]spectro/synthread.c0
-rwxr-xr-x[-rw-r--r--]spectro/usbio.c1
-rwxr-xr-x[-rw-r--r--]spectro/usbio.h0
-rwxr-xr-x[-rw-r--r--]spectro/usbio_bsd.c0
-rwxr-xr-x[-rw-r--r--]spectro/usbio_lx.c4
-rwxr-xr-x[-rw-r--r--]spectro/usbio_nt.c6
-rwxr-xr-x[-rw-r--r--]spectro/usbio_ox.c13
-rwxr-xr-x[-rw-r--r--]spectro/vinflate.c0
-rwxr-xr-xspectro/vtpglut.c570
-rwxr-xr-xspectro/vtpglut.h243
-rwxr-xr-xspectro/vtpgluttypes.h44
-rwxr-xr-x[-rw-r--r--]spectro/webwin.c0
-rwxr-xr-x[-rw-r--r--]spectro/webwin.h0
-rwxr-xr-x[-rw-r--r--]spectro/xdg_bds.c52
-rwxr-xr-x[-rw-r--r--]spectro/xdg_bds.h7
-rwxr-xr-x[-rw-r--r--]spectro/xrga.c1
-rwxr-xr-x[-rw-r--r--]spectro/xrga.h0
133 files changed, 3038 insertions, 951 deletions
diff --git a/spectro/IntsLib_Readme.txt b/spectro/IntsLib_Readme.txt
index c8df3d3..c8df3d3 100644..100755
--- a/spectro/IntsLib_Readme.txt
+++ b/spectro/IntsLib_Readme.txt
diff --git a/spectro/Jamfile b/spectro/Jamfile
index 94a2f70..f40ef19 100644..100755
--- a/spectro/Jamfile
+++ b/spectro/Jamfile
@@ -11,6 +11,11 @@ if $(OS) = MACOSX {
ObjectCcFlags dispwin_dispwin : -ObjC ;
}
+if $(USE_CMFM) = true {
+ echo "CMF Measurement device support is enabled" ;
+ DEFINES += ENABLE_CMFM ;
+}
+
if [ GLOB [ NormPaths . ] : fastserio.c ] {
# echo "!!!!!!!!! fastserio.c is enabled !!!!!!!!!" ;
# DEFINES += ENABLE_FTDI ;
@@ -127,6 +132,24 @@ if $(USE_DEMOINST) = true && [ GLOB [ NormPaths . ] : demoinst.c ] {
INST_SRCS += demoinst.c ;
}
+if $(USE_VTPGLUT) = true && [ GLOB [ NormPaths . ] : vtpglut.c ] {
+ echo "Compiling Video Test Pattern Generator and 3DLUT support" ;
+ DEFINES += ENABLE_VTPGLUT ;
+ INST_SRCS += vtpglut.c ;
+}
+
+if $(USE_PRINTERS) = true && [ GLOB [ NormPaths . ] : printers.c ] {
+ echo "Compiling Printer support" ;
+ DEFINES += ENABLE_DEMOINST ;
+ INST_SRCS += printers.c ;
+}
+
+if $(USE_CMFM) = true && [ GLOB [ NormPaths . ] : colvis.c ] {
+ echo "Compiling ColVis support" ;
+ DEFINES += ENABLE_CMFM ;
+ INST_SRCS += colvis.c ;
+}
+
Library libinst : inst.c insttypes.c icoms.c disptechs.c rspec.c xrga.c $(INST_SRCS) ;
# Display access library
@@ -138,7 +161,8 @@ Library libdisp : dispsup.c dispwin.c webwin.c ccwin.c
# applications need to know about different instrument or display types, but not access them. */
# (Note we're working around a bug in Jam caused by objects shared between libraries)
Object insttypes2 : insttypes.c ;
-LibraryFromObjects libinsttypes : insttypes2 ;
+Object xrga2 : xrga.c ;
+LibraryFromObjects libinsttypes : insttypes2 xrga2 ;
Object disptechs2 : disptechs.c ;
LibraryFromObjects libdisptechs : disptechs2 ;
@@ -171,6 +195,8 @@ if $(LIBUSB_IS_DLL) = true {
LINKLIBS += $(LIBUSBDIR)/$(LIBUSB) ;
}
+LINKFLAGS += $(GUILINKFLAGS) ;
+
# General target reader program
Main chartread : chartread.c ../target/alphix.c : : : ../target : : ;
@@ -180,10 +206,8 @@ Main illumread : illumread.c : : : ../target : : ;
# Printed target spot reader utility
Main spotread : spotread.c : : : : : ;
-# Test code
-if $(HOME) = "d:\\usr\\graeme" && $(PWD) = "/src/argyll/spectro" {
- Main setoem : setoem.c : : : : : ../numlib/libui ;
-}
+echo "HOME = " $(HOME) ;
+echo "PWD = " $(PWD) ;
# CCMX and CCSStool
Main ccxxmake : ccxxmake.c : : : : : libdisp ;
diff --git a/spectro/License.txt b/spectro/License.txt
index a871fcf..a871fcf 100644..100755
--- a/spectro/License.txt
+++ b/spectro/License.txt
diff --git a/spectro/License2.txt b/spectro/License2.txt
index 05ca889..05ca889 100644..100755
--- a/spectro/License2.txt
+++ b/spectro/License2.txt
diff --git a/spectro/License3.txt b/spectro/License3.txt
index 94a9ed0..94a9ed0 100644..100755
--- a/spectro/License3.txt
+++ b/spectro/License3.txt
diff --git a/spectro/LzmaDec.c b/spectro/LzmaDec.c
index 8c1a148..8c1a148 100644..100755
--- a/spectro/LzmaDec.c
+++ b/spectro/LzmaDec.c
diff --git a/spectro/LzmaDec.h b/spectro/LzmaDec.h
index 6045fae..6045fae 100644..100755
--- a/spectro/LzmaDec.h
+++ b/spectro/LzmaDec.h
diff --git a/spectro/LzmaTypes.h b/spectro/LzmaTypes.h
index 7732c24..7732c24 100644..100755
--- a/spectro/LzmaTypes.h
+++ b/spectro/LzmaTypes.h
diff --git a/spectro/Makefile.OSX b/spectro/Makefile.OSX
index 485cbf4..485cbf4 100644..100755
--- a/spectro/Makefile.OSX
+++ b/spectro/Makefile.OSX
diff --git a/spectro/Makefile.SA b/spectro/Makefile.SA
index 5913126..5913126 100644..100755
--- a/spectro/Makefile.SA
+++ b/spectro/Makefile.SA
diff --git a/spectro/Makefile.UNIX b/spectro/Makefile.UNIX
index adafa67..adafa67 100644..100755
--- a/spectro/Makefile.UNIX
+++ b/spectro/Makefile.UNIX
diff --git a/spectro/Makefile.WNT b/spectro/Makefile.WNT
index 83eef28..83eef28 100644..100755
--- a/spectro/Makefile.WNT
+++ b/spectro/Makefile.WNT
diff --git a/spectro/Readme.txt b/spectro/Readme.txt
index b9fe0aa..b9fe0aa 100644..100755
--- a/spectro/Readme.txt
+++ b/spectro/Readme.txt
diff --git a/spectro/SOtele.sp b/spectro/SOtele.sp
index f63d90e..f63d90e 100644..100755
--- a/spectro/SOtele.sp
+++ b/spectro/SOtele.sp
diff --git a/spectro/afiles b/spectro/afiles
index 8891ce7..9c14a9b 100644..100755
--- a/spectro/afiles
+++ b/spectro/afiles
@@ -111,6 +111,9 @@ usbio_lx.c
usbio_bsd.c
hidio.h
hidio.c
+vtpglut.h
+vtpglut.c
+vtpgluttypes.h
pollem.h
pollem.c
dispwin.c
diff --git a/spectro/aglob.c b/spectro/aglob.c
index dbf9157..dbf9157 100644..100755
--- a/spectro/aglob.c
+++ b/spectro/aglob.c
diff --git a/spectro/aglob.h b/spectro/aglob.h
index dbb5025..dbb5025 100644..100755
--- a/spectro/aglob.h
+++ b/spectro/aglob.h
diff --git a/spectro/average.c b/spectro/average.c
index e961262..e961262 100644..100755
--- a/spectro/average.c
+++ b/spectro/average.c
diff --git a/spectro/base64.c b/spectro/base64.c
index 8e07967..8e07967 100644..100755
--- a/spectro/base64.c
+++ b/spectro/base64.c
diff --git a/spectro/base64.h b/spectro/base64.h
index 29ca140..29ca140 100644..100755
--- a/spectro/base64.h
+++ b/spectro/base64.h
diff --git a/spectro/ccwin.c b/spectro/ccwin.c
index a89bc65..a89bc65 100644..100755
--- a/spectro/ccwin.c
+++ b/spectro/ccwin.c
diff --git a/spectro/ccwin.h b/spectro/ccwin.h
index 9fb902d..9fb902d 100644..100755
--- a/spectro/ccwin.h
+++ b/spectro/ccwin.h
diff --git a/spectro/ccxx.ti1 b/spectro/ccxx.ti1
index 47f2b13..47f2b13 100644..100755
--- a/spectro/ccxx.ti1
+++ b/spectro/ccxx.ti1
diff --git a/spectro/ccxxmake.c b/spectro/ccxxmake.c
index 740eb0a..4d8c057 100644..100755
--- a/spectro/ccxxmake.c
+++ b/spectro/ccxxmake.c
@@ -179,7 +179,7 @@ usage(int flag, char *diag, ...) {
// fprintf(stderr," -V Use adaptive measurement mode (if available)\n");
fprintf(stderr," -C \"command\" Invoke shell \"command\" each time a color is set\n");
fprintf(stderr," -o observ Choose CIE Observer for CCMX spectrometer 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," -s steps Override default patch sequence combination steps (default %d)\n",DEFAULT_MSTEPS);
fprintf(stderr," -W n|h|x Override serial port flow control: n = none, h = HW, x = Xon/Xoff\n");
fprintf(stderr," -D [level] Print debug diagnostics to stderr\n");
@@ -221,7 +221,8 @@ int main(int argc, char *argv[]) {
int faketoggle = 0; /* Toggle fake between "colorimeter" and "spectro" */
int fakeseq = 0; /* Fake auto CCMX sequence */
int spec = 0; /* Need spectral data to implement option */
- icxObserverType observ = icxOT_CIE_1931_2;
+ icxObserverType obType = icxOT_CIE_1931_2;
+ xspect custObserver[3]; /* If obType = icxOT_custom */
int override = 1; /* Override redirect on X11 */
icompaths *icmps = NULL; /* Ports to choose from */
int comno = COMPORT; /* COM port used */
@@ -466,21 +467,30 @@ int main(int argc, char *argv[]) {
if (na == NULL) usage(0,"Parameter expecte after -o");
if (strcmp(na, "1931_2") == 0) { /* Classic 2 degree */
spec = 2;
- observ = icxOT_CIE_1931_2;
+ obType = icxOT_CIE_1931_2;
} else if (strcmp(na, "1964_10") == 0) { /* Classic 10 degree */
spec = 2;
- observ = icxOT_CIE_1964_10;
+ obType = icxOT_CIE_1964_10;
+ } else if (strcmp(na, "2012_2") == 0) { /* Latest 2 degree */
+ spec = 2;
+ obType = icxOT_CIE_2012_2;
+ } else if (strcmp(na, "2012_10") == 0) { /* Latest 10 degree */
+ spec = 2;
+ obType = icxOT_CIE_2012_10;
} else if (strcmp(na, "1955_2") == 0) { /* Stiles and Burch 1955 2 degree */
spec = 2;
- observ = icxOT_Stiles_Burch_2;
+ obType = icxOT_Stiles_Burch_2;
} else if (strcmp(na, "1978_2") == 0) { /* Judd and Voss 1978 2 degree */
spec = 2;
- observ = icxOT_Judd_Voss_2;
+ obType = icxOT_Judd_Voss_2;
} else if (strcmp(na, "shaw") == 0) { /* Shaw and Fairchilds 1997 2 degree */
spec = 2;
- observ = icxOT_Shaw_Fairchild_2;
- } else
- usage(0,"-o parameter '%s' not recognised",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);
+ }
} else if (argv[fa][1] == 's') {
fa = nfa;
@@ -874,7 +884,7 @@ int main(int argc, char *argv[]) {
}
/* Create a spectral conversion object */
- if ((sp2cie = new_xsp2cie(icxIT_none, NULL, observ, NULL, icSigXYZData, icxClamp)) == NULL)
+ if ((sp2cie = new_xsp2cie(icxIT_none, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL)
error("Creation of spectral conversion object failed");
for (i = 0; i < npat; i++) {
@@ -938,8 +948,8 @@ int main(int argc, char *argv[]) {
cgf = NULL;
}
- if (spec != 0 && observ != icxOT_CIE_1931_2)
- oname = standardObserverDescription(observ);
+ if (spec != 0 && obType != icxOT_CIE_1931_2)
+ oname = standardObserverDescription(obType);
if (oname != NULL) {
char *tt = colname;
@@ -1211,8 +1221,8 @@ int main(int argc, char *argv[]) {
for (i = 0; ; i++) {
if (paths[i] == NULL)
break;
- if ((paths[i]->itype == instSpyder1 && setup_spyd2(0) == 0)
- || (paths[i]->itype == instSpyder2 && setup_spyd2(1) == 0))
+ if ((paths[i]->dtype == instSpyder1 && setup_spyd2(0) == 0)
+ || (paths[i]->dtype == instSpyder2 && setup_spyd2(1) == 0))
fprintf(stderr," %d = '%s' !! Disabled - no firmware !!\n",i+1,paths[i]->name);
else
fprintf(stderr," %d = '%s'\n",i+1,paths[i]->name);
@@ -1308,7 +1318,7 @@ int main(int argc, char *argv[]) {
if (spec) {
/* Create a spectral conversion object */
- if ((sp2cie = new_xsp2cie(icxIT_none, NULL, observ, NULL, icSigXYZData, icxClamp)) == NULL)
+ if ((sp2cie = new_xsp2cie(icxIT_none, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL)
error("Creation of spectral conversion object failed");
}
for (i = 0; i < npat; i++) { /* For all grid points */
@@ -1327,7 +1337,7 @@ int main(int argc, char *argv[]) {
if (fake)
refname = "fake spectrometer";
else
- refname = inst_name(it->itype);
+ refname = inst_name(it->dtype);
gotref = 1;
if (sp2cie != NULL)
sp2cie->del(sp2cie);
@@ -1342,7 +1352,7 @@ int main(int argc, char *argv[]) {
if (fake)
colname = "fake colorimeter";
else
- colname = inst_name(it->itype);
+ colname = inst_name(it->dtype);
gotcol = 1;
}
}
@@ -1427,8 +1437,8 @@ int main(int argc, char *argv[]) {
continue;
}
- if (spec != 0 && observ != icxOT_CIE_1931_2)
- oname = standardObserverDescription(observ);
+ if (spec != 0 && obType != icxOT_CIE_1931_2)
+ oname = standardObserverDescription(obType);
if (oname != NULL) { /* Incorporate observer name in colname */
char *tt = colname;
diff --git a/spectro/chartread.c b/spectro/chartread.c
index e1624e1..6a9db39 100644..100755
--- a/spectro/chartread.c
+++ b/spectro/chartread.c
@@ -265,6 +265,7 @@ int disbidi, /* Disable automatic bi-directional strip recognition */
int highres, /* Use high res spectral mode */
char *ccxxname, /* Colorimeter Correction/Colorimeter Calibration name */
icxObserverType obType, /* ccss observer */
+xspect custObserver[3], /* If obType = icxOT_custom */
double scan_tol, /* Modify patch consistency tolerance */
int pbypatch, /* Patch by patch measurement */
int xtern, /* Use external (user supplied) values rather than instument read */
@@ -468,7 +469,7 @@ a1log *log /* verb, debug & error log */
it->del(it);
return -1;
}
- if ((rv = it->get_set_opt(it, inst_opt_set_ccss_obs, obType, NULL)) != inst_ok) {
+ if ((rv = it->get_set_opt(it, inst_opt_set_ccss_obs, obType, custObserver)) != inst_ok) {
printf("\nSetting CCSS observer failed with error :'%s' (%s)\n",
it->inst_interp_error(it, rv), it->interp_error(it, rv));
cs->del(cs);
@@ -489,7 +490,7 @@ a1log *log /* verb, debug & error log */
/* 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, NULL)) != inst_ok) {
+ if ((rv = it->get_set_opt(it, inst_opt_set_ccss_obs, obType, custObserver)) != inst_ok) {
printf("\nSetting CCSS observer failed with error :'%s' (%s)\n",
it->inst_interp_error(it, rv), it->interp_error(it, rv));
it->del(it);
@@ -552,12 +553,10 @@ 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) {
-printf("~1 using emis mode\n");
if (pbypatch
&& it->check_mode(it, inst_mode_emis_spot) == inst_ok) {
mode = inst_mode_emis_spot;
@@ -1466,7 +1465,7 @@ printf("~1 using emis mode\n");
/* DTP51 has a nasty habit of misaligning test squares by +/- 1 */
/* See if this might have happened */
- if (it->itype == instDTP51) {
+ if (it->dtype == instDTP51) {
loff = -1;
hoff = 1;
}
@@ -2155,9 +2154,9 @@ usage() {
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");
+ fprintf(stderr," 1931_2 (def), 1964_10, 2012_2, 2012_10\n");
#else /* !SALONEINSTLIB */
- 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");
#endif /* !SALONEINSTLIB */
}
fprintf(stderr," -T ratio Modify strip patch consistency tolerance by ratio\n");
@@ -2208,6 +2207,7 @@ int main(int argc, char *argv[]) {
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 */
+ xspect custObserver[3]; /* If obType = icxOT_custom */
static char inname[MAXNAMEL+1] = { 0 }; /* Input cgats file base name */
static char outname[MAXNAMEL+1] = { 0 }; /* Output cgats file base name */
cgats *icg; /* input cgats structure */
@@ -2300,6 +2300,10 @@ 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;
+ } else if (strcmp(na, "2012_2") == 0) { /* Latest 2 degree */
+ obType = icxOT_CIE_2012_2;
+ } else if (strcmp(na, "2012_10") == 0) { /* Latest 10 degree */
+ obType = icxOT_CIE_2012_10;
#ifndef SALONEINSTLIB
} else if (strcmp(na, "1955_2") == 0) { /* Stiles and Burch 1955 2 degree */
obType = icxOT_Stiles_Burch_2;
@@ -2308,8 +2312,11 @@ int main(int argc, char *argv[]) {
} else if (strcmp(na, "shaw") == 0) { /* Shaw and Fairchilds 1997 2 degree */
obType = icxOT_Shaw_Fairchild_2;
#endif /* !SALONEINSTLIB */
- } else
- usage();
+ } else { /* Assume it's a filename */
+ obType = icxOT_custom;
+ if (read_cmf(custObserver, na) != 0)
+ usage();
+ }
}
/* Scan tolerance ratio */
@@ -2992,7 +2999,7 @@ int main(int argc, char *argv[]) {
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, scalstd, &ucalstd, nocal, disbidi, highres,
- ccxxname, obType,
+ ccxxname, obType, custObserver,
scan_tol, pbypatch, xtern, spectral, uvmode, accurate_expd,
emit_warnings, doplot, g_log) == 0) {
/* And save the result */
@@ -3009,6 +3016,13 @@ int main(int argc, char *argv[]) {
if (displ == 0 && trans == 0 && ucalstd != xcalstd_none)
ocg->add_kword(ocg, 0, "DEVCALSTD",xcalstd2str(ucalstd), NULL);
+ if (fe == inst_opt_filter_pol)
+ ocg->add_kword(ocg, 0, "INSTRUMENT_FILTER", "POLARIZED", NULL);
+ else if (fe == inst_opt_filter_D65)
+ ocg->add_kword(ocg, 0, "INSTRUMENT_FILTER", "D65", NULL);
+ else if (fe == inst_opt_filter_UVCut)
+ ocg->add_kword(ocg, 0, "INSTRUMENT_FILTER", "UVCUT", NULL);
+
/* Count patches actually read */
for (nrpat = i = 0; i < npat; i++) {
if (cols[i].rr) {
diff --git a/spectro/colorhug.c b/spectro/colorhug.c
index fefe766..aa8ba21 100644..100755
--- a/spectro/colorhug.c
+++ b/spectro/colorhug.c
@@ -33,6 +33,7 @@
#include "sa_config.h"
#include "numsup.h"
#endif /* SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -1197,7 +1198,7 @@ colorhug_get_set_opt(inst *pp, inst_opt_type m, ...) {
}
/* Constructor */
-extern colorhug *new_colorhug(icoms *icom, instType itype) {
+extern colorhug *new_colorhug(icoms *icom, instType dtype) {
colorhug *p;
int i;
@@ -1223,9 +1224,9 @@ extern colorhug *new_colorhug(icoms *icom, instType itype) {
p->del = colorhug_del;
p->icom = icom;
- p->itype = itype;
+ p->dtype = dtype;
- if (itype == instColorHug2)
+ if (dtype == instColorHug2)
p->stype = ch_two;
icmSetUnity3x3(p->ccmat);
diff --git a/spectro/colorhug.h b/spectro/colorhug.h
index 8617705..8617705 100644..100755
--- a/spectro/colorhug.h
+++ b/spectro/colorhug.h
diff --git a/spectro/conv.c b/spectro/conv.c
index 284a30c..a728566 100644..100755
--- a/spectro/conv.c
+++ b/spectro/conv.c
@@ -41,6 +41,9 @@
#include <stdarg.h>
#include <errno.h>
#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <pwd.h>
/* select() defined, but not poll(), so emulate poll() */
#if defined(FD_CLR) && !defined(POLLIN)
@@ -59,6 +62,7 @@
#include "sa_config.h"
#endif
#include "numsup.h"
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -241,6 +245,12 @@ void empty_con_chars(void) {
if ((stdinh = GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE)
return;
for (;;) {
+ /* Wait for 1msec */
+
+ /* Do dummy read, as stdin seems to be signalled on startup */
+ if (WaitForSingleObject(stdinh, 1) == WAIT_OBJECT_0)
+ ReadFile(stdinh, buf, 0, &bread, NULL);
+
if (WaitForSingleObject(stdinh, 1) == WAIT_OBJECT_0) {
ReadFile(stdinh, buf, 100, &bread, NULL);
} else {
@@ -423,6 +433,13 @@ athread *new_athread(
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/* Return the login $HOME directory. */
+/* (Useful if we might be running sudo) */
+/* No NT equivalent ?? */
+char *login_HOME() {
+ return getenv("HOME");
+}
+
/* Delete a file */
void delete_file(char *fname) {
_unlink(fname);
@@ -789,6 +806,7 @@ static void *threadproc(
athread *p = (athread *)param;
/* Register this thread with the Objective-C garbage collector */
+ /* (Hmm. Done by default in latter versions though, hence deprecated in them ?) */
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
objc_registerThreadWithCollector();
#endif
@@ -833,6 +851,29 @@ athread *new_athread(
/* - - - - - - - - - - - - - - - - - - - - - - - - */
+/* Return the login $HOME directory. */
+/* (Useful if we might be running sudo) */
+char *login_HOME() {
+
+ if (getuid() == 0) { /* If we are running as root */
+ char *uids;
+
+ if ((uids = getenv("SUDO_UID")) != NULL) { /* And we sudo's to get it */
+ int uid;
+ struct passwd *pwd;
+
+ uid = atoi(uids);
+
+ if ((pwd = getpwuid(uid)) != NULL) {
+ return pwd->pw_dir;
+ }
+ }
+ }
+
+ return getenv("HOME");
+}
+
+
/* Delete a file */
void delete_file(char *fname) {
unlink(fname);
diff --git a/spectro/conv.h b/spectro/conv.h
index a6adcbf..14e5636 100644..100755
--- a/spectro/conv.h
+++ b/spectro/conv.h
@@ -168,6 +168,10 @@ athread *new_athread(int (*function)(void *context), void *context);
/* - - - - - - - - - - - - - - - - - - -- */
+/* Return the login $HOME directory. */
+/* (Useful if we might be running sudo) */
+char *login_HOME();
+
/* Delete a file */
void delete_file(char *fname);
diff --git a/spectro/cubecal.h b/spectro/cubecal.h
index 93f1ada..93f1ada 100644..100755
--- a/spectro/cubecal.h
+++ b/spectro/cubecal.h
diff --git a/spectro/dev.h b/spectro/dev.h
index 0b62de3..004c20f 100644..100755
--- a/spectro/dev.h
+++ b/spectro/dev.h
@@ -29,13 +29,15 @@
/* Device base object. */
#define DEV_OBJ_BASE \
a1log *log; /* Pointer to debug & error logging class */ \
+ devType dtype; /* Device type determined by driver */ \
icoms *icom; /* Device coms object */ \
- instType itype; /* Device type determined by driver */ \
+ int gotcoms; /* Coms established flag */ \
+ int inited; /* Device open and initialized flag */ \
/* The base object type */
struct _dev {
DEV_OBJ_BASE
- }; typedef struct _dev dev;
+}; typedef struct _dev dev;
#define DEV_H
#endif /* DEV_H */
diff --git a/spectro/dispcal.c b/spectro/dispcal.c
index 65e2f10..a4798af 100644..100755
--- a/spectro/dispcal.c
+++ b/spectro/dispcal.c
@@ -151,6 +151,8 @@
#undef CHECK_MODEL /* Do readings to check the accuracy of our model */
#undef SHOW_WINDOW_ONFAKE /* Display a test window up for a fake device */
+#undef DEBUG_MEAS_RES /* Debug just VideoLUT resolution code */
+
/* Invoke with -dfake for testing with a fake device. */
/* Will use a fake.icm/.icc profile if present, or a built in fake */
/* device behaviour if not. */
@@ -178,18 +180,19 @@
#define RDAC_SMOOTH 0.3 /* RAMDAC curve fitting smoothness */
#define MEAS_RES /* Measure the RAMNDAC entry size */
-#ifdef DEBUG_PLOT
+#if defined(DEBUG_PLOT) || defined(DEBUG) || defined(DEBUG_MEAS_RES)
#include "plot.h"
#endif
#if defined(DEBUG)
-
-#define DBG(xxx) fprintf xxx ;
-#define dbgo stderr
+# define DBG(xxx) fprintf xxx ;
+# define DEBUG_MEAS_RES
#else
-#define DBG(xxx)
+# define DBG(xxx)
#endif /* DEBUG */
+#define dbgo stderr
+
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Sample points used in initial device model optimisation */
@@ -1242,6 +1245,7 @@ static double comp_ct(
int plank, /* NZ if Plankian locus, 0 if Daylight locus */
int dovct, /* NZ if visual match, 0 if traditional correlation */
icxObserverType obType, /* If not default, set a custom observer */
+ xspect custObserver[3], /* If obType = icxOT_custom */
double xyz[3] /* Color to match */
) {
double ct_xyz[3]; /* XYZ on locus */
@@ -1254,7 +1258,7 @@ static double comp_ct(
obType = icxOT_CIE_1931_2;
if ((ct = icx_XYZ2ill_ct(ct_xyz, plank != 0 ? icxIT_Ptemp : icxIT_Dtemp,
- obType, NULL, xyz, NULL, dovct)) < 0)
+ obType, custObserver, xyz, NULL, dovct)) < 0)
error("Got bad color temperature conversion\n");
if (de != NULL) {
@@ -1317,7 +1321,7 @@ static int comp_ramdac_prec(
val[i] = (double)i;
meas[i] = ttt[i].XYZ[1];
}
-#ifdef DEBUG
+#ifdef DEBUG_MEAS_RES
fprintf(dbgo,"raw measurements:\n");
do_plot(val, meas, NULL, NULL, 17);
#endif
@@ -1337,67 +1341,85 @@ static int comp_ramdac_prec(
/* Create score for each hypothesis */
scale = 1.0;
- for (j = 0; j < 5; j++) {
+ for (j = 0; j < 5; j++) { /* Res 8, 9, 10, 11, 12 bits */
int k;
- int step = 1 << (4 - j);
+ int step = 1 << (4 - j); /* Step 16, 8, 4, 2, 1 */
double v = 0.0;
double merr;
+ int off;
+ double oscore; /* Offset score */
bits[j] = 8.0 + j;
+ score[j] = 1e38;
- /* Create the target response */
- for (i = 0; i < 17;) {
- for (k = 0; k < step && (i+k) < 17; k++) {
- targ[i + k] = v;
+ /* Try possible offsets */
+ for (off = 0; off < step; off++) {
+ int ik = off; /* Initial k */
+
+ /* Create the target response */
+ for (i = 0; i < 17;) {
+ int ii; /* Actual count of loop */
+ for (ii = 0, k = ik; k < step && (i+k) < 17; k++, ii++) {
+ targ[i + ii] = v;
//printf("j %d: targ[%d] = %f\n",j,i+k,v);
+ }
+ v += step/16.0;
+ i += ii;
+ ik = 0;
}
- v += step/16.0;
- i += k;
- }
- /* Tweak it for typical display non-linearity */
- min = 1e9, max = -1e9;
- for (i = 0; i < 17; i++) {
- targ[i] = pow((NVAL + targ[i]/16.0)/255.0, 2.2);
- if (targ[i] < min)
- min = targ[i];
- if (targ[i] > max)
- max = targ[i];
- }
- for (i = 0; i < 17; i++)
- targ[i] = (targ[i] - min)/(max - min);
+ /* Tweak it for typical display non-linearity */
+ min = 1e9, max = -1e9;
+ for (i = 0; i < 17; i++) {
+ targ[i] = pow((NVAL + targ[i]/16.0)/255.0, 2.2);
+ if (targ[i] < min)
+ min = targ[i];
+ if (targ[i] > max)
+ max = targ[i];
+ }
+ for (i = 0; i < 17; i++)
+ targ[i] = (targ[i] - min)/(max - min);
+
+ /* Try and make fit a little better */
+ /* with a crude optimisation */
+ for (k = 0; k < 50; k++) {
+
+ merr = 0.0;
+ for (i = 0; i < 17; i++)
+ merr += targ[i] - meas[i];
+ merr /= 17.0;
- /* Try and make fit a little better */
- /* with a crude optimisation */
- for (k = 0; k < 50; k++) {
+ for (i = 0; i < 17; i++) {
+ targ[i] *= (1.0 + 0.5 * merr);
+ targ[i] -= 0.5 * merr;
+// targ[i] -= merr;
+ }
+ }
- merr = 0.0;
- for (i = 0; i < 17; i++)
- merr += targ[i] - meas[i];
- merr /= 17.0;
-
+ oscore = 0.0;
for (i = 0; i < 17; i++) {
- targ[i] *= (1.0 + 0.5 * merr);
- targ[i] -= 0.5 * merr;
-// targ[i] -= merr;
+ double tt = targ[i] - meas[i];
+ tt *= tt;
+ oscore += tt;
}
- }
- score[j] = 0.0;
- for (i = 0; i < 17; i++) {
- double tt = targ[i] - meas[i];
- score[j] += tt * tt;
+#ifdef DEBUG_MEAS_RES
+ printf("%d bits %d offset score %f\n",8+j,off,oscore);
+ do_plot(val, meas, targ, NULL, 17);
+#endif
+ /* keep best score from offsets */
+ if (oscore < score[j])
+ score[j] = oscore;
}
+
score[j] *= scale;
- scale *= 1.1;
+ scale *= 1.7; /* De-weight higher bit depth slightly */
+ /* Correct if overall graph is symetrical */
+ /* around minimum value ? */
-#ifdef DEBUG
- printf("%d bits score %f\n",8+j,score[j]);
- do_plot(val, meas, targ, NULL, 17);
-#endif
}
- /* Pick the best score */
+ /* Locate the best and second best scores */
bcor = bcor2 = 1e8;
bbits = 0;
@@ -1415,9 +1437,15 @@ static int comp_ramdac_prec(
/* Don't pick anything if it's not reasonably certain */
if (bcor2/bcor < 1.3
|| (bcor2/bcor < 2.1 && bcor > 0.15)
- ) rbits = 0;
+ ) {
+#ifdef DEBUG_MEAS_RES
+ printf("bcor2/bcor < 1.3 %d\n",bcor2/bcor < 1.3);
+ printf("bcor2/bcor < 2.1 %d && bcor > 0.15 %d -> %d\n", bcor2/bcor < 2.1, bcor > 0.15, bcor2/bcor < 2.1 && bcor > 0.15);
+#endif
+ rbits = 0;
+ }
-#ifdef DEBUG
+#ifdef DEBUG_MEAS_RES
printf("Win score %f by cor %f, ratio %f\n",bcor, bcor2 - bcor, bcor2/bcor);
printf("Best %d, returning %d bits\n",bbits,rbits);
do_plot10(bits, score, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 5, 1);
@@ -1489,7 +1517,7 @@ double g_def_gamma = 2.4;
*/
/* Flag = 0x0000 = default */
-/* Flag & 0x0001 = list ChromCast's */
+/* Flag & 0x0001 = list ChromeCast's */
void usage(int flag, char *diag, ...) {
int i;
disppath **dp;
@@ -1532,10 +1560,10 @@ void usage(int flag, char *diag, ...) {
if (flag & 0x001) {
ccast_id **ids;
if ((ids = get_ccids()) == NULL) {
- fprintf(stderr," ** Error discovering ChromCasts **\n");
+ fprintf(stderr," ** Error discovering ChromeCasts **\n");
} else {
if (ids[0] == NULL)
- fprintf(stderr," ** No ChromCasts found **\n");
+ fprintf(stderr," ** No ChromeCasts found **\n");
else {
int i;
for (i = 0; ids[i] != NULL; i++)
@@ -1548,7 +1576,7 @@ void usage(int flag, char *diag, ...) {
fprintf(stderr," -dmadvr Display via MadVR Video Renderer\n");
#endif
// fprintf(stderr," -d fake Use a fake display device for testing, fake%s if present\n",ICC_FILE_EXT);
- fprintf(stderr," -c listno Set communication port from the following list (default %d)\n",COMPORT);
+ fprintf(stderr," -c listno Choose instrument from the following list (default %d)\n",COMPORT);
if ((icmps = new_icompaths(g_log)) != NULL) {
icompath **paths;
if ((paths = icmps->paths) != NULL) {
@@ -1556,8 +1584,8 @@ void usage(int flag, char *diag, ...) {
for (i = 0; ; i++) {
if (paths[i] == NULL)
break;
- if ((paths[i]->itype == instSpyder1 && setup_spyd2(0) == 0)
- || (paths[i]->itype == instSpyder2 && setup_spyd2(1) == 0))
+ if ((paths[i]->dtype == instSpyder1 && setup_spyd2(0) == 0)
+ || (paths[i]->dtype == instSpyder2 && setup_spyd2(1) == 0))
fprintf(stderr," %d = '%s' !! Disabled - no firmware !!\n",i+1,paths[i]->name);
else
fprintf(stderr," %d = '%s'\n",i+1,paths[i]->name);
@@ -1614,7 +1642,7 @@ void usage(int flag, char *diag, ...) {
if (cap2 & inst2_ccss) {
fprintf(stderr," -X file.ccss Use Colorimeter Calibration Spectral Samples for calibration\n");
fprintf(stderr," -Q observ Choose CIE Observer for spectrometer or CCSS colorimeter data:\n");
- fprintf(stderr," 1931_2 (def), 1964_10, S&B 1955_2, shaw, J&V 1978_2, 1964_10c\n");
+ fprintf(stderr," 1931_2 (def), 1964_10, 2012_2, 2012_10, S&B 1955_2, shaw, J&V 1978_2, 1964_10c or file.cmf\n");
}
fprintf(stderr," -I b|w Drift compensation, Black: -Ib, White: -Iw, Both: -Ibw\n");
fprintf(stderr," -Y R:rate Override measured refresh rate with rate Hz\n");
@@ -1702,6 +1730,8 @@ int main(int argc, char *argv[]) {
ccss *ccs = NULL; /* Colorimeter Calibration Spectral Samples */
int spec = 0; /* Want spectral data from instrument */
icxObserverType obType = icxOT_default;
+ xspect custObserver[3]; /* If obType = icxOT_custom */
+
disprd *dr = NULL; /* Display patch read object */
csamp asgrey; /* Main calibration loop test points */
double dispLum = 0.0; /* Display luminence reading */
@@ -1733,12 +1763,18 @@ int main(int argc, char *argv[]) {
/* causes warning messages in 10.10. */
/* OS X 10.6+ uses a nominal gamma of 2.2 */
- if (Gestalt(gestaltSystemVersionMajor, &MacMajVers) == noErr
+ if (
+#ifdef NEVER
+ Gestalt(gestaltSystemVersionMajor, &MacMajVers) == noErr
&& Gestalt(gestaltSystemVersionMinor, &MacMinVers) == noErr
- && Gestalt(gestaltSystemVersionBugFix, &MacBFVers) == noErr) {
- if (MacMajVers >= 10 && MacMinVers >= 6) {
+ && Gestalt(gestaltSystemVersionBugFix, &MacBFVers) == noErr
+ && MacMajVers >= 10 && MacMinVers >= 6
+#else
+ floor(kCFCoreFoundationVersionNumber) >= kCFCoreFoundationVersionNumber10_6
+#endif
+
+ ) {
g_def_gamma = 2.4;
- }
}
#endif /* >= 1040 */
}
@@ -1818,7 +1854,7 @@ int main(int argc, char *argv[]) {
ccdisp = atoi(na+3);
if (ccdisp <= 0)
- usage(0,"ChromCast number must be in range 1..N");
+ usage(0,"ChromeCast number must be in range 1..N");
}
fa = nfa;
#ifdef NT
@@ -1916,6 +1952,10 @@ 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;
+ } else if (strcmp(na, "2012_2") == 0) { /* Latest 2 degree */
+ obType = icxOT_CIE_2012_2;
+ } else if (strcmp(na, "2012_10") == 0) { /* Latest 10 degree */
+ obType = icxOT_CIE_2012_10;
} else if (strcmp(na, "1964_10c") == 0) { /* 10 degree corrected */
obType = icxOT_CIE_1964_10c;
} else if (strcmp(na, "1955_2") == 0) { /* Stiles and Burch 1955 2 degree */
@@ -1924,8 +1964,11 @@ int main(int argc, char *argv[]) {
obType = icxOT_Judd_Voss_2;
} else if (strcmp(na, "shaw") == 0) { /* Shaw and Fairchilds 1997 2 degree */
obType = icxOT_Shaw_Fairchild_2;
- } else
- usage(0,"-Q parameter '%s' not recognised",na);
+ } else { /* Assume it's a filename */
+ obType = icxOT_custom;
+ if (read_cmf(custObserver, na) != 0)
+ usage(0,"Failed to read custom observer CMF from -Q file '%s'",na);
+ }
/* Change color callout */
} else if (argv[fa][1] == 'C') {
@@ -2288,13 +2331,13 @@ int main(int argc, char *argv[]) {
/* If we've requested ChromeCast, look it up */
if (ccdisp) {
if ((ccids = get_ccids()) == NULL)
- error("discovering ChromCasts failed");
+ error("discovering ChromeCasts failed");
if (ccids[0] == NULL)
- error("There are no ChromCasts to use\n");
+ error("There are no ChromeCasts to use\n");
for (i = 0; ccids[i] != NULL; i++)
;
if (ccdisp < 1 || ccdisp > i)
- error("Chosen ChromCasts (%d) is outside list (1..%d)\n",ccdisp,i);
+ error("Chosen ChromeCasts (%d) is outside list (1..%d)\n",ccdisp,i);
ccid = ccids[ccdisp-1];
}
@@ -2353,7 +2396,7 @@ int main(int argc, char *argv[]) {
cmx != NULL ? cmx->cc_cbid : 0,
cmx != NULL ? cmx->matrix : NULL,
ccs != NULL ? ccs->samples : NULL, ccs != NULL ? ccs->no_samp : 0,
- spec, obType, NULL, bdrift, wdrift,
+ spec, obType, custObserver, bdrift, wdrift,
"fake" ICC_FILE_EXT, g_log)) == NULL)
error("new_disprd() failed with '%s'\n",disprd_err(errc));
@@ -2409,10 +2452,10 @@ int main(int argc, char *argv[]) {
wp[0] = w[0]/(w[0] + w[1] + w[2]);
wp[1] = w[1]/(w[0] + w[1] + w[2]);
- cct = comp_ct(&cct_de, NULL, 1, 0, obType, w); /* Compute CCT */
- cdt = comp_ct(&cdt_de, NULL, 0, 0, obType, w); /* Compute CDT */
- vct = comp_ct(&vct_de, NULL, 1, 1, obType, w); /* Compute VCT */
- vdt = comp_ct(&vdt_de, NULL, 0, 1, obType, w); /* Compute VDT */
+ cct = comp_ct(&cct_de, NULL, 1, 0, obType, custObserver, w); /* Compute CCT */
+ cdt = comp_ct(&cdt_de, NULL, 0, 0, obType, custObserver, w); /* Compute CDT */
+ vct = comp_ct(&vct_de, NULL, 1, 1, obType, custObserver, w); /* Compute VCT */
+ vdt = comp_ct(&vdt_de, NULL, 0, 1, obType, custObserver, w); /* Compute VDT */
/* Compute advertised current gamma - use the gross curve shape for robustness */
cgamma = pop_gamma(tcols[0].XYZ[1], tcols[1].XYZ[1], tcols[2].XYZ[1]);
@@ -3193,9 +3236,9 @@ int main(int argc, char *argv[]) {
} else if (temp > 0.0) { /* Daylight color temperature */
double XYZ[3];
if (planckian)
- rv = icx_ill_sp2XYZ(XYZ, icxOT_default, NULL, icxIT_Ptemp, temp, NULL);
+ rv = icx_ill_sp2XYZ(XYZ, icxOT_default, NULL, icxIT_Ptemp, temp, NULL, 0);
else
- rv = icx_ill_sp2XYZ(XYZ, icxOT_default, NULL, icxIT_Dtemp, temp, NULL);
+ rv = icx_ill_sp2XYZ(XYZ, icxOT_default, NULL, icxIT_Dtemp, temp, NULL, 0);
if (rv != 0)
error("Failed to compute XYZ of target color temperature %f\n",temp);
icmXYZ2Yxy(tYxy, XYZ);
@@ -3222,7 +3265,7 @@ int main(int argc, char *argv[]) {
} else { /* Target is native white */
printf("\nAdjust R,G & B gain to desired white point. Press space when done.\n");
/* Compute the CT and delta E to white locus of target */
- ct = comp_ct(&ct_de, NULL, planckian, dovct, obType, tcols[0].XYZ);
+ ct = comp_ct(&ct_de, NULL, planckian, dovct, obType, custObserver, tcols[0].XYZ);
printf(" Initial Br %.2f, x %.4f , y %.4f , %c%cT %4.0fK DE 2K %4.1f\n",
tarw, tYxy[1],tYxy[2],
dovct ? 'V' : 'C', planckian ? 'C' : 'D', ct,ct_de);
@@ -3264,7 +3307,7 @@ int main(int argc, char *argv[]) {
} else { /* Target is native white */
double lxyz[3]; /* Locus XYZ */
- ct = comp_ct(&ct_de, lxyz, planckian, dovct, obType, tcols[0].XYZ);
+ ct = comp_ct(&ct_de, lxyz, planckian, dovct, obType, custObserver, tcols[0].XYZ);
icmXYZ2Yxy(tYxy, lxyz);
/* lxyz is already normalised */
@@ -3476,9 +3519,9 @@ int main(int argc, char *argv[]) {
} else if (temp > 0.0) { /* Daylight color temperature */
double XYZ[3];
if (planckian)
- rv = icx_ill_sp2XYZ(XYZ, icxOT_default, NULL, icxIT_Ptemp, temp, NULL);
+ rv = icx_ill_sp2XYZ(XYZ, icxOT_default, NULL, icxIT_Ptemp, temp, NULL, 0);
else
- rv = icx_ill_sp2XYZ(XYZ, icxOT_default, NULL, icxIT_Dtemp, temp, NULL);
+ rv = icx_ill_sp2XYZ(XYZ, icxOT_default, NULL, icxIT_Dtemp, temp, NULL, 0);
if (rv != 0)
error("Failed to compute XYZ of target color temperature %f\n",temp);
icmXYZ2Yxy(tYxy, XYZ);
@@ -3652,9 +3695,9 @@ int main(int argc, char *argv[]) {
} else if (temp > 0.0) { /* Daylight color temperature */
double XYZ[3];
if (planckian)
- rv = icx_ill_sp2XYZ(XYZ, icxOT_default, NULL, icxIT_Ptemp, temp, NULL);
+ rv = icx_ill_sp2XYZ(XYZ, icxOT_default, NULL, icxIT_Ptemp, temp, NULL, 0);
else
- rv = icx_ill_sp2XYZ(XYZ, icxOT_default, NULL, icxIT_Dtemp, temp, NULL);
+ rv = icx_ill_sp2XYZ(XYZ, icxOT_default, NULL, icxIT_Dtemp, temp, NULL, 0);
if (rv != 0)
error("Failed to compute XYZ of target color temperature %f\n",temp);
icmXYZ2Yxy(tYxy, XYZ);
@@ -3695,7 +3738,7 @@ int main(int argc, char *argv[]) {
icmXYZ2Lab(&tXYZ, bLab, bLab);
/* And color temperature */
- ct = comp_ct(&ct_de, NULL, planckian, dovct, obType, tcols[2].XYZ);
+ ct = comp_ct(&ct_de, NULL, planckian, dovct, obType, custObserver, tcols[2].XYZ);
printf("\n");
@@ -4187,9 +4230,9 @@ int main(int argc, char *argv[]) {
} else if (temp > 0.0) { /* Daylight color temperature */
if (planckian)
- rv = icx_ill_sp2XYZ(x.twh, icxOT_default, NULL, icxIT_Ptemp, temp, NULL);
+ rv = icx_ill_sp2XYZ(x.twh, icxOT_default, NULL, icxIT_Ptemp, temp, NULL, 0);
else
- rv = icx_ill_sp2XYZ(x.twh, icxOT_default, NULL, icxIT_Dtemp, temp, NULL);
+ rv = icx_ill_sp2XYZ(x.twh, icxOT_default, NULL, icxIT_Dtemp, temp, NULL, 0);
if (rv != 0)
error("Failed to compute XYZ of target color temperature %f\n",temp);
//printf("~1 Raw target from temp %f XYZ = %f %f %f\n",temp,x.twh[0],x.twh[1],x.twh[2]);
@@ -4360,7 +4403,7 @@ int main(int argc, char *argv[]) {
0.2, /* Background relative to reference white */
80.0, /* Display is 80 cd/m^2 */
0.0, 0.01, x.nwh, /* 0% flare and 1% glare same white point */
- 0, 1.0);
+ 0, 1.0, 0.0, NULL);
break;
case gt_Rec709:
@@ -4371,7 +4414,7 @@ int main(int argc, char *argv[]) {
0.2, /* Background relative to reference white */
1000.0/3.1415, /* Luminance of white in the Image field (cd/m^2) */
0.0, 0.01, x.nwh, /* 0% flare and 1% glare same white point */
- 0, 1.0);
+ 0, 1.0, 0.0, NULL);
break;
default:
@@ -4384,7 +4427,7 @@ int main(int argc, char *argv[]) {
0.2, /* Background relative to reference white */
x.twh[1], /* Target white level (cd/m^2) */
0.0, 0.01, x.nwh, /* 0% flare and 1% glare same white point */
- 0, 1.0);
+ 0, 1.0, 0.0, NULL);
/* Compute the normalisation values */
x.svc->XYZ_to_cam(x.svc, Jab, x.nwh); /* Relative white point */
diff --git a/spectro/dispread.c b/spectro/dispread.c
index 4c96b76..5e332cc 100644..100755
--- a/spectro/dispread.c
+++ b/spectro/dispread.c
@@ -53,8 +53,8 @@
#include "copyright.h"
#include "aconfig.h"
#include "numlib.h"
-#include "xspect.h"
#include "cgats.h"
+#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
#include "icoms.h"
@@ -98,7 +98,7 @@ static int gcc_bug_fix(int i) {
*/
/* Flag = 0x0000 = default */
-/* Flag & 0x0001 = list ChromCast's */
+/* Flag & 0x0001 = list ChromeCast's */
void usage(int flag, char *diag, ...) {
int i;
disppath **dp;
@@ -141,10 +141,10 @@ void usage(int flag, char *diag, ...) {
if (flag & 0x001) {
ccast_id **ids;
if ((ids = get_ccids()) == NULL) {
- fprintf(stderr," ** Error discovering ChromCasts **\n");
+ fprintf(stderr," ** Error discovering ChromeCasts **\n");
} else {
if (ids[0] == NULL)
- fprintf(stderr," ** No ChromCasts found **\n");
+ fprintf(stderr," ** No ChromeCasts found **\n");
else {
int i;
for (i = 0; ids[i] != NULL; i++)
@@ -165,8 +165,8 @@ void usage(int flag, char *diag, ...) {
for (i = 0; ; i++) {
if (paths[i] == NULL)
break;
- if ((paths[i]->itype == instSpyder1 && setup_spyd2(0) == 0)
- || (paths[i]->itype == instSpyder2 && setup_spyd2(1) == 0))
+ if ((paths[i]->dtype == instSpyder1 && setup_spyd2(0) == 0)
+ || (paths[i]->dtype == instSpyder2 && setup_spyd2(1) == 0))
fprintf(stderr," %d = '%s' !! Disabled - no firmware !!\n",i+1,paths[i]->name);
else
fprintf(stderr," %d = '%s'\n",i+1,paths[i]->name);
@@ -201,7 +201,7 @@ void usage(int flag, char *diag, ...) {
if (cap2 & inst2_ccss) {
fprintf(stderr," -X file.ccss Use Colorimeter Calibration Spectral Samples for calibration\n");
fprintf(stderr," -Q observ Choose CIE Observer for spectrometer or CCSS colorimeter data:\n");
- fprintf(stderr," 1931_2 (def), 1964_10, S&B 1955_2, shaw, J&V 1978_2, 1964_10c\n");
+ fprintf(stderr," 1931_2 (def), 1964_10, 2012_2, 2012_10, S&B 1955_2, shaw, J&V 1978_2, 1964_10c or file.cmf\n");
}
fprintf(stderr," -I b|w Drift compensation, Black: -Ib, White: -Iw, Both: -Ibw\n");
fprintf(stderr," -Y R:rate Override measured refresh rate with rate Hz\n");
@@ -252,6 +252,7 @@ int main(int argc, char *argv[]) {
ccss *ccs = NULL; /* Colorimeter Calibration Spectral Samples */
int spec = 0; /* Don't save spectral information */
icxObserverType obType = icxOT_default;
+ xspect custObserver[3]; /* If obType = icxOT_custom */
int webdisp = 0; /* NZ for web display, == port number */
int ccdisp = 0; /* NZ for ChromeCast, == list index */
ccast_id **ccids = NULL;
@@ -356,7 +357,7 @@ int main(int argc, char *argv[]) {
ccdisp = atoi(na+3);
if (ccdisp <= 0)
- usage(0,"ChromCast number must be in range 1..N");
+ usage(0,"ChromeCast number must be in range 1..N");
}
fa = nfa;
#ifdef NT
@@ -531,6 +532,10 @@ 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;
+ } else if (strcmp(na, "2012_2") == 0) { /* Latest 2 degree */
+ obType = icxOT_CIE_2012_2;
+ } else if (strcmp(na, "2012_10") == 0) { /* Latest 10 degree */
+ obType = icxOT_CIE_2012_10;
} else if (strcmp(na, "1964_10c") == 0) { /* 10 degree corrected */
obType = icxOT_CIE_1964_10c;
} else if (strcmp(na, "1955_2") == 0) { /* Stiles and Burch 1955 2 degree */
@@ -539,9 +544,11 @@ int main(int argc, char *argv[]) {
obType = icxOT_Judd_Voss_2;
} else if (strcmp(na, "shaw") == 0) { /* Shaw and Fairchilds 1997 2 degree */
obType = icxOT_Shaw_Fairchild_2;
- } else
- usage(0,"-Q parameter '%s' not recognised",na);
-
+ } else { /* Assume it's a filename */
+ obType = icxOT_custom;
+ if (read_cmf(custObserver, na) != 0)
+ usage(0,"Failed to read custom observer CMF from -Q file '%s'",na);
+ }
/* Change color callout */
} else if (argv[fa][1] == 'C') {
@@ -683,13 +690,13 @@ int main(int argc, char *argv[]) {
/* If we've requested ChromeCast, look it up */
if (ccdisp) {
if ((ccids = get_ccids()) == NULL)
- error("discovering ChromCasts failed");
+ error("discovering ChromeCasts failed");
if (ccids[0] == NULL)
- error("There are no ChromCasts to use\n");
+ error("There are no ChromeCasts to use\n");
for (i = 0; ccids[i] != NULL; i++)
;
if (ccdisp < 1 || ccdisp > i)
- error("Chosen ChromCasts (%d) is outside list (1..%d)\n",ccdisp,i);
+ error("Chosen ChromeCasts (%d) is outside list (1..%d)\n",ccdisp,i);
ccid = ccids[ccdisp-1];
}
@@ -924,7 +931,7 @@ int main(int argc, char *argv[]) {
cmx != NULL ? cmx->cc_cbid : 0,
cmx != NULL ? cmx->matrix : NULL,
ccs != NULL ? ccs->samples : NULL, ccs != NULL ? ccs->no_samp : 0,
- spec, obType, NULL, bdrift, wdrift,
+ spec, obType, custObserver, bdrift, wdrift,
"fake" ICC_FILE_EXT, g_log)) == NULL)
error("new_disprd failed with '%s'\n",disprd_err(errc));
@@ -1083,7 +1090,7 @@ int main(int argc, char *argv[]) {
ocg->add_kword(ocg, 0, "NORMALIZED_TO_Y_100","NO", NULL);
/* Write out the calibration if we have it */
- if (cal != NULL && cal[0][0] >= 0.0) {
+ if (cal[0][0] >= 0.0) {
ocg->add_other(ocg, "CAL"); /* our special type is Calibration file */
ocg->add_table(ocg, tt_other, 1); /* Add another table for RAMDAC values */
ocg->add_kword(ocg, 1, "DESCRIPTOR", "Argyll Device Calibration State",NULL);
diff --git a/spectro/dispsup.c b/spectro/dispsup.c
index 281912d..21e847f 100644..100755
--- a/spectro/dispsup.c
+++ b/spectro/dispsup.c
@@ -32,9 +32,11 @@
#include <sys/types.h>
#include <time.h>
#include <string.h>
+#include <ctype.h>
#include "copyright.h"
#include "aconfig.h"
#include "numlib.h"
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
diff --git a/spectro/dispsup.h b/spectro/dispsup.h
index 07a66e2..07a66e2 100644..100755
--- a/spectro/dispsup.h
+++ b/spectro/dispsup.h
diff --git a/spectro/disptechs.c b/spectro/disptechs.c
index bade777..bade777 100644..100755
--- a/spectro/disptechs.c
+++ b/spectro/disptechs.c
diff --git a/spectro/disptechs.h b/spectro/disptechs.h
index 9860eac..9860eac 100644..100755
--- a/spectro/disptechs.h
+++ b/spectro/disptechs.h
diff --git a/spectro/dispwin.c b/spectro/dispwin.c
index 368f707..7761db1 100644..100755
--- a/spectro/dispwin.c
+++ b/spectro/dispwin.c
@@ -17,6 +17,15 @@
/* TTBD
*
+ * Should add support for XRandR 1.5 MST support, so that a Monitor driven
+ * by multiple CRTCs gets treated as a single item. (How does Xinerama emulation
+ * handle this though ?) - i.e. might have to duplicate profile atoms,
+ * set both VideoLUTs when one is set, deal with EDID/ucmm confusion etc.
+ * Note that XRandR Xinerama emulation changes with v1.5 and MST.
+ *
+ * Should look at MSWin & OS X uninstall profile function, and see if
+ * requirement of supplying profile name can be removed (just like X11 case).
+ *
* Should probably check the display attributes (like visual depth)
* and complain if we aren't using 24 bit color or better.
*
@@ -56,7 +65,7 @@
#include "numlib.h"
#include "cgats.h"
#include "conv.h"
-#include "xicc.h"
+# include "xicc.h"
#include "disptechs.h"
#include "dispwin.h"
#include "ui.h"
@@ -66,6 +75,9 @@
#ifdef NT
# include "madvrwin.h"
#endif
+#include "insttypes.h"
+#include "inst.h"
+#include "icoms.h"
#if defined(UNIX_X11)
# include <dlfcn.h>
# if defined(USE_UCMM)
@@ -92,6 +104,7 @@
*/
#include <Foundation/Foundation.h>
+#include <CoreFoundation/CoreFoundation.h>
#include <AppKit/AppKit.h>
@@ -153,8 +166,9 @@ CFUUIDRef CGDisplayCreateUUIDFromDisplayID (uint32_t displayID);
#endif
-/* ----------------------------------------------- */
-/* Dealing with locating displays */
+/* ===================================================================== */
+/* Display enumeration code */
+/* ===================================================================== */
int callback_ddebug = 0; /* Diagnostic global for get_displays() and get_a_display() */
/* and events */
@@ -597,11 +611,16 @@ disppath **get_displays() {
}
#if RANDR_MAJOR == 1 && RANDR_MINOR >= 2 && !defined(DISABLE_RANDR)
- /* Use Xrandr 1.2 if it's available, and if it's not disabled */
+ /* Use Xrandr 1.2 if it's available, and if it's not disabled. */
if (getenv("ARGYLL_IGNORE_XRANDR1_2") == NULL
&& XRRQueryExtension(mydisplay, &evb, &erb) != 0
&& XRRQueryVersion(mydisplay, &majv, &minv)
&& majv == 1 && minv >= 2) {
+ static void *xrr_found = NULL; /* .so handle */
+ static XRRScreenResources *(*_XRRGetScreenResourcesCurrent)
+ (Display *dpy, Window window) = NULL;
+ static RROutput (*_XRRGetOutputPrimary)(Display *dpy, Window window) = NULL;
+ int defsix; /* Default Screen index */
if (XSetErrorHandler(null_error_handler) == 0) {
debugrr("get_displays failed on XSetErrorHandler\n");
@@ -610,20 +629,38 @@ disppath **get_displays() {
return NULL;
}
+ /* Get functions available in Xrandr V1.3 */
+ if (minv >= 3 && xrr_found == NULL) {
+ if ((xrr_found = dlopen("libXrandr.so", RTLD_LAZY)) != NULL) {
+ _XRRGetScreenResourcesCurrent = dlsym(xrr_found, "XRRGetScreenResourcesCurrent");
+ _XRRGetOutputPrimary = dlsym(xrr_found, "XRRGetOutputPrimary");
+ }
+ }
+
+ /* Hmm. Do Xrandr systems alway have only one Screen, */
+ /* just like Xinerama ? */
dcount = ScreenCount(mydisplay);
- /* Go through all the screens */
+ debugrr2((errout,"get_displays using %d XRandR Screens\n",dcount));
+
+ /* Not sure what to do with this. */
+ /* Should we go through X11 screens with this first ? */
+ /* (How does Xrandr translate Screen 1..n to Xinerama ?????) */
+ defsix = DefaultScreen(mydisplay);
+
+ /* In order to be in sync with an application using Xinerama, */
+ /* we need to generate our screen indexes in the same */
+ /* order as Xinerama. */
+
+ /* Go through all the X11 screens */
for (i = 0; i < dcount; i++) {
- static void *xrr_found = NULL; /* .so handle */
- static XRRScreenResources *(*_XRRGetScreenResourcesCurrent)
- (Display *dpy, Window window) = NULL;
XRRScreenResources *scrnres;
- int jj; /* Screen index */
-
- if (minv >= 3 && xrr_found == NULL) {
- if ((xrr_found = dlopen("libXrandr.so", RTLD_LAZY)) != NULL)
- _XRRGetScreenResourcesCurrent = dlsym(xrr_found, "XRRGetScreenResourcesCurrent");
- }
+ int has_primary = 0;
+ int pix = -1; /* CRTC index containing primary */
+ int pop = -1; /* Output index containing primary */
+ int jj; /* Xinerama screen ix */
+ int xj; /* working crtc index */
+ int xk; /* working output index */
if (minv >= 3 && _XRRGetScreenResourcesCurrent != NULL) {
scrnres = _XRRGetScreenResourcesCurrent(mydisplay, RootWindow(mydisplay,i));
@@ -637,70 +674,150 @@ disppath **get_displays() {
free_disppaths(disps);
return NULL;
}
+ /* We have to scan through CRTC's & outputs in the same order */
+ /* as the XRANDR XInerama implementation in the X server. */
+ /* This is a little tricky, as we need to do the primary output, */
+ /* first, while keeping the rest in order. */
+
+ /* Locate the crtc index that contains the primary (if any) */
+ if (minv >= 3 && _XRRGetOutputPrimary != NULL) {
+ XID primary; /* Primary output ID */
+
+ primary = _XRRGetOutputPrimary(mydisplay, RootWindow(mydisplay,i));
+ debugrr2((errout,"XRRGetOutputPrimary returned XID %x\n",primary));
+
+ if (primary != None) {
+ for (j = 0; j < scrnres->ncrtc; j++) {
+ XRRCrtcInfo *crtci = NULL;
+
+ if ((crtci = XRRGetCrtcInfo(mydisplay, scrnres, scrnres->crtcs[j])) == NULL)
+ continue;
+
+ if (crtci->mode == None || crtci->noutput == 0) {
+ XRRFreeCrtcInfo(crtci);
+ continue;
+ }
+
+ for (k = 0; k < crtci->noutput; k++) {
+ if (crtci->outputs[k] == primary) {
+ pix = j;
+ pop = k;
+ }
+ }
+ XRRFreeCrtcInfo(crtci);
+ }
+ if (pix < 0) { /* Didn't locate primary */
+ debugrr2((errout,"Couldn't locate primary CRTC!\n"));
+ } else {
+ debugrr2((errout,"Primary is at CRTC %d Output %d\n",pix,pop));
+ has_primary = 1;
+ }
+ }
+ }
- /* Look at all the screens outputs */
- for (jj = j = 0; j < scrnres->noutput; j++) {
- XRROutputInfo *outi = NULL;
+ /* Look through all the Screens CRTC's */
+ for (jj = xj = j = 0; j < scrnres->ncrtc; j++, xj++) {
+ char *pp;
XRRCrtcInfo *crtci = NULL;
-
- if ((outi = XRRGetOutputInfo(mydisplay, scrnres, scrnres->outputs[j])) == NULL) {
- debugrr("XRRGetOutputInfo failed\n");
- XRRFreeScreenResources(scrnres);
- XCloseDisplay(mydisplay);
- free_disppaths(disps);
- return NULL;
+ XRROutputInfo *outi0 = NULL;
+
+ if (has_primary) {
+ if (j == 0)
+ xj = pix; /* Start with crtc containing primary */
+
+ else if (xj == pix) /* We've up to primary that we've alread done */
+ xj++; /* Skip it */
}
-
- if (outi->connection == RR_Disconnected ||
- outi->crtc == None) {
- XRRFreeOutputInfo(outi);
+
+ if ((crtci = XRRGetCrtcInfo(mydisplay, scrnres, scrnres->crtcs[xj])) == NULL) {
+ debugrr2((errout,"XRRGetCrtcInfo of Screen %d CRTC %d failed\n",i,xj));
+ if (has_primary && j == 0)
+ xj = -1; /* Start at beginning */
continue;
}
- /* Check that the VideoLUT's are accessible */
- {
- XRRCrtcGamma *crtcgam = NULL;
-
- debugrr("Checking XRandR 1.2 VideoLUT access\n");
- if ((crtcgam = XRRGetCrtcGamma(mydisplay, outi->crtc)) == NULL
- || crtcgam->size == 0) {
- fprintf(stderr,"XRandR 1.2 is faulty - falling back to older extensions\n");
+ debugrr2((errout,"XRRGetCrtcInfo of Screen %d CRTC %d has %d Outputs %s Mode\n",i,xj,crtci->noutput,crtci->mode == None ? "No" : "Valid"));
+
+ if (crtci->mode == None || crtci->noutput == 0) {
+ debugrr2((errout,"CRTC skipped as it has no mode or no outputs\n",i,xj,crtci->noutput));
+ XRRFreeCrtcInfo(crtci);
+ if (has_primary && j == 0)
+ xj = -1; /* Start at beginning */
+ continue;
+ }
+
+ /* This CRTC will now be counted as an Xinerama screen */
+ /* For each output of Crtc */
+ for (xk = k = 0; k < crtci->noutput; k++, xk++) {
+ XRROutputInfo *outi = NULL;
+
+ if (has_primary && xj == pix) {
+ if (k == 0)
+ xk = pop; /* Start with primary output */
+ else if (xk == pop) /* We've up to primary that we've alread done */
+ xk++; /* Skip it */
+ }
+
+ if ((outi = XRRGetOutputInfo(mydisplay, scrnres, crtci->outputs[xk])) == NULL) {
+ debugrr2((errout,"XRRGetOutputInfo failed for Screen %d CRTC %d Output %d\n",i,xj,xk));
+ goto next_output;
+ }
+ if (k == 0) /* Save this so we can label any clones */
+ outi0 = outi;
+
+ if (outi->connection == RR_Disconnected) {
+ debugrr2((errout,"Screen %d CRTC %d Output %d is disconnected\n",i,xj,xk));
+ goto next_output;
+ }
+
+ /* Check that the VideoLUT's are accessible */
+ {
+ XRRCrtcGamma *crtcgam = NULL;
+
+ debugrr("Checking XRandR 1.2 VideoLUT access\n");
+ if ((crtcgam = XRRGetCrtcGamma(mydisplay, scrnres->crtcs[xj])) == NULL
+ || crtcgam->size == 0) {
+ fprintf(stderr,"XRRGetCrtcGamma failed - falling back to older extensions\n");
+ if (crtcgam != NULL)
+ XRRFreeGamma(crtcgam);
+ if (outi != NULL && outi != outi0)
+ XRRFreeOutputInfo(outi);
+ if (outi0 != NULL)
+ XRRFreeOutputInfo(outi0);
+ XRRFreeCrtcInfo(crtci);
+ XRRFreeScreenResources(scrnres);
+ free_disppaths(disps);
+ disps = NULL;
+ goto done_xrandr;
+ }
if (crtcgam != NULL)
XRRFreeGamma(crtcgam);
- free_disppaths(disps);
- disps = NULL;
- j = scrnres->noutput;
- i = dcount;
- XRRFreeOutputInfo(outi);
- continue; /* Abort XRandR 1.2 */
}
- if (crtcgam != NULL)
- XRRFreeGamma(crtcgam);
- }
#ifdef NEVER
- {
- Atom *oprops;
- int noprop;
+ {
+ Atom *oprops;
+ int noprop;
- /* Get a list of the properties of the output */
- oprops = XRRListOutputProperties(mydisplay, scrnres->outputs[j], &noprop);
+ /* Get a list of the properties of the output */
+ oprops = XRRListOutputProperties(mydisplay, crtci->outputs[xk], &noprop);
- printf("num props = %d\n", noprop);
- for (k = 0; k < noprop; k++) {
- printf("%d: atom 0x%x, name = '%s'\n", k, oprops[k], XGetAtomName(mydisplay, oprops[k]));
+ printf("num props = %d\n", noprop);
+ for (k = 0; k < noprop; k++) {
+ printf("%d: atom 0x%x, name = '%s'\n", k, oprops[k], XGetAtomName(mydisplay, oprops[k]));
+ }
}
- }
#endif /* NEVER */
- if ((crtci = XRRGetCrtcInfo(mydisplay, scrnres, outi->crtc)) != NULL) {
- char *pp;
-
/* Add the output to the list */
+ debugrr2((errout,"Adding Screen %d CRTC %d Output %d\n",i,xj,xk));
if (disps == NULL) {
if ((disps = (disppath **)calloc(sizeof(disppath *), 1 + 1)) == NULL) {
debugrr("get_displays failed on malloc\n");
XRRFreeCrtcInfo(crtci);
- XRRFreeOutputInfo(outi);
+ if (outi != NULL && outi != outi0)
+ XRRFreeOutputInfo(outi);
+ if (outi0 != NULL)
+ XRRFreeOutputInfo(outi0);
XRRFreeScreenResources(scrnres);
XCloseDisplay(mydisplay);
return NULL;
@@ -710,7 +827,10 @@ disppath **get_displays() {
sizeof(disppath *) * (ndisps + 2))) == NULL) {
debugrr("get_displays failed on malloc\n");
XRRFreeCrtcInfo(crtci);
- XRRFreeOutputInfo(outi);
+ if (outi != NULL && outi != outi0)
+ XRRFreeOutputInfo(outi);
+ if (outi0 != NULL)
+ XRRFreeOutputInfo(outi0);
XRRFreeScreenResources(scrnres);
XCloseDisplay(mydisplay);
return NULL;
@@ -721,44 +841,49 @@ disppath **get_displays() {
if ((disps[ndisps] = calloc(sizeof(disppath),1)) == NULL) {
debugrr("get_displays failed on malloc\n");
XRRFreeCrtcInfo(crtci);
- XRRFreeOutputInfo(outi);
+ if (outi != NULL && outi != outi0)
+ XRRFreeOutputInfo(outi);
+ if (outi0 != NULL)
+ XRRFreeOutputInfo(outi0);
XRRFreeScreenResources(scrnres);
XCloseDisplay(mydisplay);
free_disppaths(disps);
return NULL;
}
- disps[ndisps]->screen = i;
- disps[ndisps]->uscreen = i;
- disps[ndisps]->rscreen = i;
+ disps[ndisps]->screen = i; /* X11 (virtual) Screen */
+ disps[ndisps]->uscreen = jj; /* Xinerama/Xrandr screen */
+ disps[ndisps]->rscreen = jj;
disps[ndisps]->sx = crtci->x;
disps[ndisps]->sy = crtci->y;
disps[ndisps]->sw = crtci->width;
disps[ndisps]->sh = crtci->height;
- disps[ndisps]->crtc = outi->crtc; /* XID of crtc */
- disps[ndisps]->output = scrnres->outputs[j]; /* XID of output */
+ disps[ndisps]->crtc = scrnres->crtcs[xj]; /* XID of CRTC */
+ disps[ndisps]->output = crtci->outputs[xk]; /* XID of output */
- sprintf(desc1,"Screen %d, Output %s",ndisps+1,outi->name);
+ sprintf(desc1,"Monitor %d, Output %s",ndisps+1,outi->name);
sprintf(desc2,"%s at %d, %d, width %d, height %d",desc1,
disps[ndisps]->sx, disps[ndisps]->sy, disps[ndisps]->sw, disps[ndisps]->sh);
- /* See if it is a clone */
- for (k = 0; k < ndisps; k++) {
- if (disps[k]->crtc == disps[ndisps]->crtc) {
- sprintf(desc1, "[ Clone of %d ]",k+1);
- strcat(desc2, desc1);
- }
+ /* If it is a clone */
+ if (k > 0 & outi0 != NULL) {
+ sprintf(desc1, "[ Clone of %s ]",outi0->name);
+ strcat(desc2, desc1);
}
+
if ((disps[ndisps]->description = strdup(desc2)) == NULL) {
debugrr("get_displays failed on malloc\n");
XRRFreeCrtcInfo(crtci);
- XRRFreeOutputInfo(outi);
+ if (outi != NULL && outi != outi0)
+ XRRFreeOutputInfo(outi);
+ if (outi0 != NULL)
+ XRRFreeOutputInfo(outi0);
XRRFreeScreenResources(scrnres);
XCloseDisplay(mydisplay);
free_disppaths(disps);
return NULL;
}
-
+
/* Form the display name */
if ((pp = strrchr(dnbuf, ':')) != NULL) {
if ((pp = strchr(pp, '.')) != NULL) {
@@ -768,27 +893,29 @@ disppath **get_displays() {
if ((disps[ndisps]->name = strdup(dnbuf)) == NULL) {
debugrr("get_displays failed on malloc\n");
XRRFreeCrtcInfo(crtci);
- XRRFreeOutputInfo(outi);
+ if (outi != NULL && outi != outi0)
+ XRRFreeOutputInfo(outi);
+ if (outi0 != NULL)
+ XRRFreeOutputInfo(outi0);
XRRFreeScreenResources(scrnres);
XCloseDisplay(mydisplay);
free_disppaths(disps);
return NULL;
}
debugrr2((errout, "Display %d name = '%s'\n",ndisps,disps[ndisps]->name));
-
+
/* Create the X11 root atom of the default screen */
- /* that may contain the associated ICC profile */
- /* (The _%d variant will probably break with non-Xrandr */
- /* aware software if Xrandr is configured to have more than */
- /* a single virtual screen.) */
+ /* that may contain the associated ICC profile. */
if (jj == 0)
strcpy(desc1, "_ICC_PROFILE");
else
- sprintf(desc1, "_ICC_PROFILE_%d",jj);
+ sprintf(desc1, "_ICC_PROFILE_%d",disps[ndisps]->uscreen);
if ((disps[ndisps]->icc_atom = XInternAtom(mydisplay, desc1, False)) == None)
error("Unable to intern atom '%s'",desc1);
+ debugrr2((errout,"Root atom '%s'\n",desc1));
+
/* Create the atom of the output that may contain the associated ICC profile */
if ((disps[ndisps]->icc_out_atom = XInternAtom(mydisplay, "_ICC_PROFILE", False)) == None)
error("Unable to intern atom '%s'","_ICC_PROFILE");
@@ -810,19 +937,22 @@ disppath **get_displays() {
for (ii = 0; keys[ii][0] != '\000'; ii++) {
/* Get the atom for the EDID data */
if ((edid_atom = XInternAtom(mydisplay, keys[ii], True)) == None) {
- debugrr2((errout, "Unable to intern atom '%s'\n",keys[ii]));
+ // debugrr2((errout, "Unable to intern atom '%s'\n",keys[ii]));
/* Try the next key */
- } else {
- /* Get the EDID_DATA */
- if (XRRGetOutputProperty(mydisplay, scrnres->outputs[j], edid_atom,
+ /* Get the EDID_DATA */
+ } else {
+ if (XRRGetOutputProperty(mydisplay, crtci->outputs[xk], edid_atom,
0, 0x7ffffff, False, False, XA_INTEGER,
&ret_type, &ret_format, &ret_len, &ret_togo, &atomv) == Success
&& (ret_len == 128 || ret_len == 256)) {
if ((disps[ndisps]->edid = malloc(sizeof(unsigned char) * ret_len)) == NULL) {
debugrr("get_displays failed on malloc\n");
XRRFreeCrtcInfo(crtci);
- XRRFreeOutputInfo(outi);
+ if (outi != NULL && outi != outi0)
+ XRRFreeOutputInfo(outi);
+ if (outi0 != NULL)
+ XRRFreeOutputInfo(outi0);
XRRFreeScreenResources(scrnres);
XCloseDisplay(mydisplay);
free_disppaths(disps);
@@ -840,22 +970,30 @@ disppath **get_displays() {
if (keys[ii][0] == '\000')
debugrr2((errout, "Failed to get EDID for display\n"));
}
-
- jj++; /* Next enabled index */
ndisps++; /* Now it's number of displays */
- XRRFreeCrtcInfo(crtci);
+
+ next_output:;
+ if (outi != NULL && outi != outi0)
+ XRRFreeOutputInfo(outi);
+ if (has_primary && xj == pix && k == 0)
+ xk = -1; /* Go to first output */
}
- XRRFreeOutputInfo(outi);
+ next_screen:;
+ if (outi0 != NULL)
+ XRRFreeOutputInfo(outi0);
+ XRRFreeCrtcInfo(crtci);
+ jj++; /* Next Xinerama screen index */
+ if (has_primary && j == 0)
+ xj = -1; /* Go to first screen */
}
XRRFreeScreenResources(scrnres);
}
+ done_xrandr:;
XSetErrorHandler(NULL);
- defsix = DefaultScreen(mydisplay);
}
#endif /* randr >= V 1.2 */
if (disps == NULL) { /* Use Older style identification */
- debugrr("get_displays checking for Xinerama\n");
if (XSetErrorHandler(null_error_handler) == 0) {
debugrr("get_displays failed on XSetErrorHandler\n");
@@ -863,7 +1001,8 @@ disppath **get_displays() {
return NULL;
}
- if (XineramaQueryExtension(mydisplay, &evb, &erb) != 0
+ if (getenv("ARGYLL_IGNORE_XINERAMA") == NULL
+ && XineramaQueryExtension(mydisplay, &evb, &erb) != 0
&& XineramaIsActive(mydisplay)) {
xai = XineramaQueryScreens(mydisplay, &dcount);
@@ -873,10 +1012,10 @@ disppath **get_displays() {
XCloseDisplay(mydisplay);
return NULL;
}
- defsix = 0;
+ debugrr2((errout,"get_displays using %d Xinerama Screens\n",dcount));
} else {
dcount = ScreenCount(mydisplay);
- defsix = DefaultScreen(mydisplay);
+ debugrr2((errout,"get_displays using %d X11 Screens\n",dcount));
}
/* Allocate our list */
@@ -903,7 +1042,10 @@ disppath **get_displays() {
/* Form the display name */
if ((pp = strrchr(dnbuf, ':')) != NULL) {
if ((pp = strchr(pp, '.')) != NULL) {
- sprintf(pp,".%d",i);
+ if (xai != NULL) /* Xinerama */
+ sprintf(pp,".%d",0);
+ else
+ sprintf(pp,".%d",i);
}
}
if ((disps[i]->name = strdup(dnbuf)) == NULL) {
@@ -915,14 +1057,15 @@ disppath **get_displays() {
debugrr2((errout, "Display %d name = '%s'\n",i,disps[i]->name));
if (xai != NULL) { /* Xinerama */
- disps[i]->screen = 0; /* We are asuming Xinerame creates a single virtual screen */
- disps[i]->uscreen = i; /* We are assuming xinerama lists screens in the same order */
+ /* xai[i].screen_number should be == i */
+ disps[i]->screen = 0; /* Assume Xinerame creates a single virtual X11 screen */
+ disps[i]->uscreen = i; /* Underlying Xinerma screen */
disps[i]->rscreen = i;
disps[i]->sx = xai[i].x_org;
disps[i]->sy = xai[i].y_org;
disps[i]->sw = xai[i].width;
disps[i]->sh = xai[i].height;
- } else {
+ } else { /* Plain X11 Screens */
disps[i]->screen = i;
disps[i]->uscreen = i;
disps[i]->rscreen = i;
@@ -992,9 +1135,9 @@ disppath **get_displays() {
&& monitor.model != NULL && monitor.model[0] != '\000')
sprintf(desc1, "%s",monitor.model);
else
- sprintf(desc1,"Screen %d",i+1);
+ sprintf(desc1,"Monitor %d",i+1);
} else
- sprintf(desc1,"Screen %d",i+1);
+ sprintf(desc1,"Monitor %d",i+1);
sprintf(desc2,"%s at %d, %d, width %d, height %d",desc1,
disps[i]->sx, disps[i]->sy, disps[i]->sw, disps[i]->sh);
@@ -1006,14 +1149,15 @@ disppath **get_displays() {
}
}
XSetErrorHandler(NULL);
- }
- /* Put the screen given by the display name at the top */
- {
- disppath *tdispp;
- tdispp = disps[defsix];
- disps[defsix] = disps[0];
- disps[0] = tdispp;
+ /* Put the default Screen the top of the list */
+ if (xai == NULL) {
+ int defsix = DefaultScreen(mydisplay);
+ disppath *tdispp;
+ tdispp = disps[defsix];
+ disps[defsix] = disps[0];
+ disps[0] = tdispp;
+ }
}
if (xai != NULL)
@@ -1087,6 +1231,8 @@ disppath *get_a_display(int ix) {
disppath **paths, *rv = NULL;
int i;
+ debugrr2((errout, "get_a_display called with ix %d\n",ix));
+
if ((paths = get_displays()) == NULL)
return NULL;
@@ -1095,8 +1241,9 @@ disppath *get_a_display(int ix) {
free_disppaths(paths);
return NULL;
}
- if (i == ix)
+ if (i == ix) {
break;
+ }
}
if ((rv = malloc(sizeof(disppath))) == NULL) {
debugrr("get_a_display failed malloc\n");
@@ -1129,6 +1276,8 @@ disppath *get_a_display(int ix) {
memmove(rv->edid, paths[i]->edid, rv->edid_len );
}
#endif
+ debugrr2((errout, " Selected ix %d '%s' %s'\n",i,rv->name,rv->description));
+
free_disppaths(paths);
return rv;
}
@@ -1147,7 +1296,9 @@ void free_a_disppath(disppath *path) {
}
}
-/* ----------------------------------------------- */
+/* ===================================================================== */
+/* RAMDAC access code */
+/* ===================================================================== */
/* For VideoLUT/RAMDAC use, we assume that the frame buffer */
/* may map through some intermediate hardware or lookup */
@@ -1465,7 +1616,7 @@ static char *iprof_path(p_scope scope, char *fname) {
dirname = COLORSYNC_DIR_LOCAL;
else {
dirname = COLORSYNC_DIR_USER;
- if ((home = getenv("HOME")) == NULL){
+ if ((home = login_HOME()) == NULL){
return NULL;
}
}
@@ -2273,7 +2424,10 @@ void dispwin_del_ramdac(ramdac *r) {
free(r);
}
-/* ----------------------------------------------- */
+/* ===================================================================== */
+/* Profile install code */
+/* ===================================================================== */
+
/* Useful function for X11 profile atom settings */
#if defined(UNIX_X11)
@@ -2283,7 +2437,10 @@ static int set_X11_atom(dispwin *p, char *fname) {
unsigned long psize, bread;
unsigned char *atomv;
- debugr("Setting _ICC_PROFILE property\n");
+ if (p->myuscreen == 0)
+ debugr("Setting _ICC_PROFILE property\n");
+ else
+ debugr2((errout,"Setting _ICC_PROFILE_%d property\n",p->myuscreen));
/* Read in the ICC profile, then set the X11 atom value */
#if !defined(O_CREAT) && !defined(_O_CREAT)
@@ -2323,11 +2480,13 @@ static int set_X11_atom(dispwin *p, char *fname) {
fclose(fp);
- XChangeProperty(p->mydisplay, RootWindow(p->mydisplay, 0), p->icc_atom,
+ if (p->icc_atom != None) {
+ XChangeProperty(p->mydisplay, RootWindow(p->mydisplay, 0), p->icc_atom,
XA_CARDINAL, 8, PropModeReplace, atomv, psize);
+ }
#if RANDR_MAJOR == 1 && RANDR_MINOR >= 2 && !defined(DISABLE_RANDR)
- if (p->icc_out_atom != 0) {
+ if (p->icc_out_atom != None) {
/* If Xrandr 1.2, set property on output */
/* This seems to fail on some servers. Ignore the error ? */
if (XSetErrorHandler(null_error_handler) == 0) {
@@ -2351,7 +2510,8 @@ static int set_X11_atom(dispwin *p, char *fname) {
}
#endif /* UNXI X11 */
-/* ----------------------------------------------- */
+/* ---------------------------------------------- */
+
/* See if colord is available */
#if defined(UNIX_X11) && defined(USE_UCMM)
@@ -2373,7 +2533,8 @@ int dispwin_checkfor_colord() {
cd_found = NULL;
- if ((cd_found = dlopen("libcolordcompat.so", RTLD_LAZY)) != NULL) {
+ if (getenv("ARGYLL_USE_COLORD") != NULL
+ && (cd_found = dlopen("libcolordcompat.so", RTLD_LAZY)) != NULL) {
cd_edid_install_profile = dlsym(cd_found, "cd_edid_install_profile");
cd_edid_remove_profile = dlsym(cd_found, "cd_edid_remove_profile");
@@ -2394,7 +2555,6 @@ int dispwin_checkfor_colord() {
#endif
-
/* ----------------------------------------------- */
/* Install a display profile and make */
/* it the default for this display. */
@@ -2630,7 +2790,7 @@ int dispwin_install_profile(dispwin *p, char *fname, ramdac *r, p_scope scope) {
return 0;
}
-#else /* 10.6 and prior */
+#else /* OS X 10.6 and prior */
// Switch to using iprof_path() to simplify ?
{
CMError ev;
@@ -2766,8 +2926,9 @@ int dispwin_install_profile(dispwin *p, char *fname, ramdac *r, p_scope scope) {
/* Un-Install a display profile */
/* Return nz if failed, */
-/* 1 if not sucessfully deleted */
+/* 1 if not successfully deleted */
/* 2 if profile not found */
+/* NT and OS X need fname, *NIX does not. */
int dispwin_uninstall_profile(dispwin *p, char *fname, p_scope scope) {
debugr2((errout,"dispwin_uninstall_profile '%s'\n", fname));
#ifdef NT
@@ -2883,7 +3044,7 @@ int dispwin_uninstall_profile(dispwin *p, char *fname, p_scope scope) {
}
debug2((errout,"Set euid %d and egid %d\n",uid,gid));
}
- /* If setting local system proile and not effective root, but sudo */
+ /* If setting local system profile and not effective root, but sudo */
} else if (scope != p_scope_user && getuid() == 0 && geteuid() != 0) {
if (getenv("SUDO_UID") != NULL
&& getenv("SUDO_GID") != NULL) {
@@ -3029,14 +3190,15 @@ int dispwin_uninstall_profile(dispwin *p, char *fname, p_scope scope) {
if (cd_found)
ev = cd_edid_remove_profile(p->edid, p->edid_len, fname);
else
- ev = ucmm_uninstall_monitor_profile(sc, p->edid, p->edid_len, p->name, fname);
+ ev = ucmm_uninstall_monitor_profile(sc, p->edid, p->edid_len, p->name);
if (ev != ucmm_ok) {
debugr2((errout,"Installing profile '%s' failed with error %d '%s'\n",fname,ev,ucmm_error_string(ev)));
return 1;
}
- XDeleteProperty(p->mydisplay, RootWindow(p->mydisplay, 0), p->icc_atom);
+ if (p->icc_atom != None)
+ XDeleteProperty(p->mydisplay, RootWindow(p->mydisplay, 0), p->icc_atom);
#if RANDR_MAJOR == 1 && RANDR_MINOR >= 2 && !defined(DISABLE_RANDR)
/* If Xrandr 1.2, set property on output */
@@ -3254,6 +3416,7 @@ icmFile *dispwin_get_profile(dispwin *p, char *name, int mxlen) {
debugr2((errout,"Setting X11 atom to profile '%s' failed",profile));
/* Hmm. We ignore this error */
}
+ free(profile);
return rd_fp;
}
if (ev != ucmm_no_profile) {
@@ -3291,9 +3454,14 @@ icmFile *dispwin_get_profile(dispwin *p, char *name, int mxlen) {
#endif /* randr >= V 1.2 */
if (atomv == NULL) {
+ if (p->icc_atom == None) {
+ debugr("Second or subsequent Output doesn't have ICC_PROFILE property\n");
+ return NULL;
+ }
+
if (p->myuscreen != 0)
sprintf(aname, "_ICC_PROFILE_%d",p->myuscreen);
-
+
/* Get the ICC profile property */
if (XGetWindowProperty(p->mydisplay, RootWindow(p->mydisplay, 0), p->icc_atom,
0, 0x7ffffff, False, XA_CARDINAL,
@@ -3336,7 +3504,7 @@ icmFile *dispwin_get_profile(dispwin *p, char *name, int mxlen) {
return NULL;
}
-/* ----------------------------------------------- */
+/* ===================================================================== */
/* Restore the display state and free ramdacs */
static void restore_display(dispwin *p) {
@@ -3416,6 +3584,8 @@ static void dispwin_sighandler(int arg) {
static amutex_static(lock);
dispwin *pp, *np;
+ debugrr("dispwin_sighandler called\n");
+
/* Make sure we don't re-enter */
if (amutex_trylock(lock)) {
return;
@@ -3483,7 +3653,10 @@ static void dispwin_uninstall_signal_handlers(dispwin *p) {
p->next = NULL;
}
-/* ----------------------------------------------- */
+/* ===================================================================== */
+/* Test patch window code */
+/* ===================================================================== */
+
/* Test patch window specific declarations */
#ifdef UNIX_APPLE
@@ -3531,6 +3704,7 @@ unsigned char emptyCursor[43] = {
* the mouse enters the window. This needs the main thread
* to be dedicated to running the event loop, so would involve
* some trickiness after main() in every program.
+ * - we have done this with numlib/ui.c, so this is possible.
*/
- (void)resetCursorRects {
[super resetCursorRects];
@@ -3671,8 +3845,7 @@ static void create_my_win(void *cntx) {
/* Moves the window to the front of the screen list within its level, */
/* and show the window (i.e. make it "key") */
- /* Trigger warning on OS X 10.11 El Capitan ? */
- /* (Doesn't happen using 1.6.3 which ran everything in the main thread.) */
+ /* Trigger warning on OS X 10.11 El Capitan if not run in the main thread. */
[cx->window makeKeyAndOrderFront: nil];
/* Use a null color transform to ensure device values */
@@ -3720,17 +3893,23 @@ static void create_my_win(void *cntx) {
#endif /* >= 10.6 */
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
- /* >= 10.6+ device colors don't work on secondary display, need null transform. */
- /* < 10.6 null transform doesn't work. */
+ /* >= 10.6+ device colors don't work on secondary displays and need a null transform. */
+ /* < 10.6 null transform doesn't work, but isn't needed. */
- if (Gestalt(gestaltSystemVersionMajor, &MacMajVers) == noErr
+ if (
+#ifdef NEVER
+ Gestalt(gestaltSystemVersionMajor, &MacMajVers) == noErr
&& Gestalt(gestaltSystemVersionMinor, &MacMinVers) == noErr
&& Gestalt(gestaltSystemVersionBugFix, &MacBFVers) == noErr
&& MacMajVers >= 10 && MacMinVers >= 6
+#else
+ floor(kCFCoreFoundationVersionNumber) >= kCFCoreFoundationVersionNumber10_6
+#endif
+
&& cx->nscs == NULL) {
warning("Unable to create null color transform - test colors may be wrong!");
}
-#endif
+#endif /* >= 1040 */
cx->err = 0;
}
@@ -3750,7 +3929,7 @@ double r, double g, double b /* Color values 0.0 - 1.0 */
double kr, kf;
int update_delay = 0;
- debugr("dispwin_set_color called\n");
+ debugrr2((errout, "dispwin_set_color called on disp '%s'\n",p->name));
if (p->nowin) {
return 1;
@@ -3941,8 +4120,15 @@ double r, double g, double b /* Color values 0.0 - 1.0 */
/* Stop the system going to sleep */
UpdateSystemActivity(OverallAct);
+/*
+ replacement ?
+ IOPMAssertionID assertionID;
+ IOPMAssertionDeclareUserActivity(CFSTR(""), kIOPMUserActiveLocal, &assertionID);
+*/
+
/* Make sure our window is brought to the front at least once, */
/* but not every time, in case the user wants to kill the application. */
+ /* is orderFrontRegardless a replacement ?? */
if (p->btf == 0){
OSStatus stat;
ProcessSerialNumber cpsn;
@@ -4748,6 +4934,11 @@ int ddebug /* >0 to print debug statements to stderr */
dispwin_del(p);
return NULL;
}
+ if ((p->description = strdup(disp->description)) == NULL) {
+ debugr2((errout,"new_dispwin: Malloc failed\n"));
+ dispwin_del(p);
+ return NULL;
+ }
p->ddid = disp->ddid; /* Display we're working on */
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
@@ -4816,7 +5007,7 @@ int ddebug /* >0 to print debug statements to stderr */
if (p->rdepth != p->ndepth) {
if (!p->warned) {
- warning("new_dispwin: Frame buffer depth %d doesn't matcv VideoLUT %d",p->rdepth, p->ndepth);
+ warning("new_dispwin: Frame buffer depth %d doesn't match VideoLUT %d",p->rdepth, p->ndepth);
p->warned = 1;
}
}
@@ -4975,20 +5166,25 @@ int ddebug /* >0 to print debug statements to stderr */
/* open the display */
p->mydisplay = XOpenDisplay(bname);
- if(!p->mydisplay) {
- debugr2((errout,"new_dispwin: Unable to open display '%s'\n",bname));
+ if (!p->mydisplay) {
+ debugrr2((errout,"new_dispwin: Unable to open display '%s'\n",bname));
dispwin_del(p);
free(bname);
return NULL;
}
+ debugrr2((errout,"new_dispwin: Opened display '%s' OK\n",bname));
free(bname);
- debugr("new_dispwin: Opened display OK\n");
if ((p->name = strdup(disp->name)) == NULL) {
debugr2((errout,"new_dispwin: Malloc failed\n"));
dispwin_del(p);
return NULL;
}
+ if ((p->description = strdup(disp->description)) == NULL) {
+ debugr2((errout,"new_dispwin: Malloc failed\n"));
+ dispwin_del(p);
+ return NULL;
+ }
p->myscreen = disp->screen;
p->myuscreen = disp->uscreen;
p->myrscreen = disp->rscreen;
@@ -5181,7 +5377,7 @@ int ddebug /* >0 to print debug statements to stderr */
}
}
- debugr2((errout,"new_dispwin: %s fdepth %d, rdepth %d, ndepth %d, edepth %d, r/g/b shifts %d %d %d\n", vinfo->class != TrueColor ? "TreuColor" : "DirectColor", p->fdepth,p->rdepth,p->ndepth,p->edepth, p->shift[0], p->shift[1], p->shift[2]));
+ debugrr2((errout,"new_dispwin: %s fdepth %d, rdepth %d, ndepth %d, edepth %d, r/g/b shifts %d %d %d\n", vinfo->class != TrueColor ? "TreuColor" : "DirectColor", p->fdepth,p->rdepth,p->ndepth,p->edepth, p->shift[0], p->shift[1], p->shift[2]));
if (nowin == 0) { /* Create a window */
unsigned long attrmask = 0;
@@ -5228,6 +5424,8 @@ int ddebug /* >0 to print debug statements to stderr */
p->ww = wi;
p->wh = he;
+ debugrr2((errout,"new_dispwin: at %d, %d size %d, %d\n",p->tx,p->ty,p->ww,p->wh));
+
/* Setup Size Hints */
mysizehints.flags = PPosition | USSize;
mysizehints.x = xo;
@@ -5630,7 +5828,7 @@ int ddebug /* >0 to print debug statements to stderr */
p->native = native &= ~2;
}
- debugr("new_dispwin: return sucessfully\n");
+ debugr("new_dispwin: return successfully\n");
return p;
}
@@ -5887,7 +6085,8 @@ static int gcc_bug_fix(int i) {
#include "numlib.h"
/* Flag = 0x0000 = default */
-/* Flag & 0x0001 = list ChromCast's */
+/* Flag & 0x0001 = list ChromeCast's */
+/* Flag & 0x0002 = list VTPG's's */
static void usage(int flag, char *diag, ...) {
disppath **dp;
fprintf(stderr,"Test display patch window, Set Video LUTs, Install profiles, Version %s\n",ARGYLL_VERSION_STR);
@@ -5923,13 +6122,13 @@ static void usage(int flag, char *diag, ...) {
free_disppaths(dp);
fprintf(stderr," -dweb[:port] Display via web server at port (default 8080)\n");
fprintf(stderr," -dcc[:n] Display via n'th ChromeCast (default 1, ? for list)\n");
- if (flag & 0x001) {
+ if (flag & 0x0001) {
ccast_id **ids;
if ((ids = get_ccids()) == NULL) {
- fprintf(stderr," ** Error discovering ChromCasts **\n");
+ fprintf(stderr," ** Error discovering ChromeCasts **\n");
} else {
if (ids[0] == NULL)
- fprintf(stderr," ** No ChromCasts found **\n");
+ fprintf(stderr," ** No ChromeCasts found **\n");
else {
int i;
for (i = 0; ids[i] != NULL; i++)
@@ -5942,8 +6141,28 @@ static void usage(int flag, char *diag, ...) {
fprintf(stderr," -dmadvr Display via MadVR Video Renderer\n");
#endif
+#ifdef ENABLE_VTPGLUT
+ fprintf(stderr," -dvtpg[:n] Display via n'th Video Test Patch Generator (default 1, ? for list)\n");
+ if (flag & 0x0002) {
+ icompaths *icmps;
+ if ((icmps = new_icompaths_sel(g_log, icomt_vtpg | icomt_portattr_all)) != NULL) {
+ icompath **paths;
+ if ((paths = icmps->dpaths[dtix_vtpg]) != NULL) {
+ int i;
+ for (i = 0; ; i++) {
+ if (paths[i] == NULL)
+ break;
+ fprintf(stderr," %d = '%s'\n",i+1,paths[i]->name);
+ }
+ } else
+ fprintf(stderr," ** No VTPG's found **\n");
+ }
+ }
+#endif
+
fprintf(stderr," -P ho,vo,ss[,vs] Position test window and scale it\n");
fprintf(stderr," -F Fill whole screen with black background\n");
+ fprintf(stderr," -E Video encode output as (16-235)/255 \"TV\" levels\n");
fprintf(stderr," -i Run forever with random values\n");
fprintf(stderr," -G filename Display RGB colors from CGATS (ie .ti1) file\n");
fprintf(stderr," -C r.rr,g.gg,b.bb Add this RGB color to list to be displayed\n");
@@ -5954,7 +6173,7 @@ static void usage(int flag, char *diag, ...) {
fprintf(stderr," -s filename Save the currently loaded Video LUT to 'filename'\n");
fprintf(stderr," -c Load a linear display calibration\n");
fprintf(stderr," -V Verify that calfile/profile cal. is currently loaded in LUT\n");
- fprintf(stderr," -I Install profile for display and use it's calibration\n");
+ fprintf(stderr," -I Install profile for display and use its calibration\n");
fprintf(stderr," -U Un-install profile for display\n");
fprintf(stderr," -S d Specify the install/uninstall scope for OS X [nlu] or X11/Vista [lu]\n");
fprintf(stderr," d is one of: n = network, l = local system, u = user (default)\n");
@@ -5981,6 +6200,9 @@ main(int argc, char *argv[]) {
#ifdef NT
int madvrdisp = 0; /* NZ for MadVR display */
#endif
+#ifdef ENABLE_VTPGLUT
+ int vtpgdisp = 0; /* NZ for Video Test Pattern Generator, == list index */
+#endif
disppath *disp = NULL; /* Display being used */
double hpatscale = 1.0, vpatscale = 1.0; /* scale factor for test patch size */
double ho = 0.0, vo = 0.0; /* Test window offsets, -1.0 to 1.0 */
@@ -6073,7 +6295,7 @@ main(int argc, char *argv[]) {
ccdisp = atoi(na+3);
if (ccdisp <= 0)
- usage(0,"ChromCast number must be in range 1..N");
+ usage(0,"ChromeCast number must be in range 1..N");
}
fa = nfa;
#ifdef NT
@@ -6082,6 +6304,20 @@ main(int argc, char *argv[]) {
madvrdisp = 1;
fa = nfa;
#endif
+#ifdef ENABLE_VTPGLUT
+ } else if (strncmp(na,"vtpg",4) == 0
+ || strncmp(na,"VTPG",4) == 0) {
+ vtpgdisp = 1;
+ if (na[4] == ':') {
+ if (na[3] < '0' || na[3] > '9')
+ usage(0x0002,"Available VTPG's");
+
+ vtpgdisp = atoi(na+3);
+ if (vtpgdisp <= 0)
+ usage(0,"VTPG number must be in range 1..N");
+ }
+ fa = nfa;
+#endif /* ENABLE_VTPGLUT */
} else {
#if defined(UNIX_X11)
int ix, iv;
@@ -6259,8 +6495,13 @@ main(int argc, char *argv[]) {
#endif
/* Bomb on bad combinations (not all are being detected) */
- if (installprofile && calname[0] == '\000')
- error("Can't install or uninstall a displays profile without profile argument");
+ if (installprofile == 1 && calname[0] == '\000')
+ error("Can't install a displays profile without profile argument");
+
+#if !defined(UNIX)
+ if (installprofile == 2 && calname[0] == '\000')
+ error("Can't uninstall a displays profile without profile argument");
+#endif
if (verify && calname[0] == '\000' && loadprofile == 0)
error("No calibration/profile provided to verify against");
@@ -6285,17 +6526,17 @@ main(int argc, char *argv[]) {
} else if (ccdisp != 0) {
ccast_id **ids;
if ((ids = get_ccids()) == NULL) {
- printf("Error - discovering ChromCasts failed\n");
+ printf("Error - discovering ChromeCasts failed\n");
return -1;
}
if (ids[0] == NULL) {
- printf("Error - there are no ChromCasts to use\n");
+ printf("Error - there are no ChromeCasts to use\n");
return -1;
}
for (i = 0; ids[i] != NULL; i++)
;
if (ccdisp < 1 || ccdisp > i) {
- printf("Error - chosen ChromCasts (%d) is outside list (1..%d)\n",ccdisp,i);
+ printf("Error - chosen ChromeCasts (%d) is outside list (1..%d)\n",ccdisp,i);
return -1;
}
@@ -6427,10 +6668,10 @@ main(int argc, char *argv[]) {
if (rv == 2)
warning("Profile '%s' not found to uninstall!",calname);
else
- error("Error trying to uninstall profile '%s'!",calname);
+ error("Error trying to uninstall profile for display '%s'!",dw->description);
}
if (verb) {
- printf("Un-Installed '%s'\n",calname);
+ printf("Un-Installed profile for display '%s'\n",dw->description);
}
}
@@ -6582,25 +6823,28 @@ main(int argc, char *argv[]) {
dw->r->v[j][i] = val + w * (cal[j][ix+1] - val);
}
}
- /* If the calibration was created with a restricted range video encoding, */
- /* ensure that the installed calibration applies this encoding. */
- if (out_tvenc) {
- for (i = 0; i < dw->r->nent; i++) {
- for (j = 0; j < 3; j++) {
- dw->r->v[j][i] = (dw->r->v[j][i] * (235.0-16.0) + 16.0)/255.0;
-
- /* For video encoding the extra bits of precision are created by bit */
- /* shifting rather than scaling, so we need to scale the fp value to */
- /* account for this. */
- if (dw->edepth > 8)
- dw->r->v[j][i] = (dw->r->v[j][i] * 255 * (1 << (dw->edepth - 8)))
- /((1 << dw->edepth) - 1.0);
- }
+ debug("Got cal file calibration\n");
+ }
+
+ /* If the calibration was created with a restricted range video encoding, */
+ /* ensure that the installed calibration applies this encoding. */
+ if (out_tvenc) {
+ if (verb)
+ printf("Using output TV encoding range of (16-235)/255\n");
+ for (i = 0; i < dw->r->nent; i++) {
+ for (j = 0; j < 3; j++) {
+ dw->r->v[j][i] = (dw->r->v[j][i] * (235.0-16.0) + 16.0)/255.0;
+
+ /* For video encoding the extra bits of precision are created by bit */
+ /* shifting rather than scaling, so we need to scale the fp value to */
+ /* account for this. */
+ if (dw->edepth > 8)
+ dw->r->v[j][i] = (dw->r->v[j][i] * 255 * (1 << (dw->edepth - 8)))
+ /((1 << dw->edepth) - 1.0);
}
}
-
- debug("Got cal file calibration\n");
}
+
if (ccg != NULL)
ccg->del(ccg);
if (icco != NULL)
diff --git a/spectro/dispwin.h b/spectro/dispwin.h
index 47fd256..8130d5f 100644..100755
--- a/spectro/dispwin.h
+++ b/spectro/dispwin.h
@@ -118,10 +118,10 @@ typedef struct {
CGDirectDisplayID ddid;
#endif /* UNIX_APPLE */
#if defined(UNIX_X11)
- int screen; /* Screen to select */
- int uscreen; /* Underlying screen */
- int rscreen; /* Underlying RAMDAC screen */
- Atom icc_atom; /* ICC profile root atom for this display */
+ int screen; /* X11 (possibly virtual) Screen */
+ int uscreen; /* Underlying Xinerma/XRandr screen */
+ int rscreen; /* Underlying RAMDAC screen (user override) */
+ Atom icc_atom; /* ICC profile root/output atom for this display */
unsigned char *edid; /* 128 or 256 bytes of monitor EDID, NULL if none */
int edid_len; /* 128 or 256 */
@@ -272,9 +272,9 @@ struct _dispwin {
#if defined(UNIX_X11)
Display *mydisplay;
- int myscreen; /* Usual or virtual screen with Xinerama */
- int myuscreen; /* Underlying screen */
- int myrscreen; /* Underlying RAMDAC screen */
+ int myscreen; /* Overall X11 (possibly virtual) Screen */
+ int myuscreen; /* Underlying Xinerma/Xrandr screen */
+ int myrscreen; /* Underlying RAMDAC screen (user override) */
Atom icc_atom; /* ICC profile root atom for this display */
unsigned char *edid; /* 128 or 256 bytes of monitor EDID, NULL if none */
int edid_len; /* 128 or 256 */
diff --git a/spectro/dtp20.c b/spectro/dtp20.c
index a125a53..c33dc3d 100644..100755
--- a/spectro/dtp20.c
+++ b/spectro/dtp20.c
@@ -67,6 +67,7 @@
#include "sa_config.h"
#endif /* SALONEINSTLIB */
#include "numsup.h"
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -1737,7 +1738,7 @@ inst_opt_type m, /* Requested status type */
}
/* Constructor */
-extern dtp20 *new_dtp20(icoms *icom, instType itype) {
+extern dtp20 *new_dtp20(icoms *icom, instType dtype) {
dtp20 *p;
if ((p = (dtp20 *)calloc(sizeof(dtp20),1)) == NULL) {
a1loge(icom->log, 1, "new_dtp20: malloc failed!\n");
@@ -1761,7 +1762,7 @@ extern dtp20 *new_dtp20(icoms *icom, instType itype) {
p->del = dtp20_del;
p->icom = icom;
- p->itype = itype;
+ p->dtype = dtype;
p->cap = inst_mode_none; /* Unknown until set */
p->mode = inst_mode_none; /* Not in a known mode yet */
diff --git a/spectro/dtp20.h b/spectro/dtp20.h
index a8b6862..a8b6862 100644..100755
--- a/spectro/dtp20.h
+++ b/spectro/dtp20.h
diff --git a/spectro/dtp22.c b/spectro/dtp22.c
index 37249f0..34a8506 100644..100755
--- a/spectro/dtp22.c
+++ b/spectro/dtp22.c
@@ -51,6 +51,7 @@
#include "sa_config.h"
#include "numsup.h"
#endif /* !SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -97,9 +98,7 @@ extract_ec(char *s) {
if (*p == '>')
break;
}
- if ( (p-3) < s
- || p[0] != '>'
- || p[-3] != '<')
+ if ((p-3) < s || p[0] != '>' || p[-3] != '<')
return -1;
tt[0] = p[-2];
tt[1] = p[-1];
@@ -517,8 +516,8 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
}
}
} else { /* Inst error or switch activated */
- if (strlen(buf) >= 4
- && buf[0] == '<' && isdigit(buf[1]) && isdigit(buf[2]) && buf[3] == '>') {
+ if ((strlen(buf) >= 4
+ && buf[0] == '<' && isdigit(buf[1]) && isdigit(buf[2]) && buf[3] == '>')) {
if ((ev = dtp22_interp_code((inst *)p, extract_ec(buf))) != inst_ok) {
dtp22_command(p, "CE\r", buf, MAX_MES_SIZE, 0.5);
dtp22_command(p, "2PB\r", buf, MAX_MES_SIZE, 0.5);
@@ -747,8 +746,8 @@ char id[CALIDLEN] /* Condition identifier (ie. white reference ID) */
}
}
} else { /* Inst error or switch activated */
- if (strlen(buf) >= 4
- && buf[0] == '<' && isdigit(buf[1]) && isdigit(buf[2]) && buf[3] == '>') {
+ if ((strlen(buf) >= 4
+ && buf[0] == '<' && isdigit(buf[1]) && isdigit(buf[2]) && buf[3] == '>')) {
if ((ev = dtp22_interp_code((inst *)p, extract_ec(buf))) != inst_ok) {
dtp22_command(p, "CE\r", buf, MAX_MES_SIZE, 0.5);
if (ev != inst_ok)
@@ -1145,7 +1144,7 @@ extern dtp22 *new_dtp22(icoms *icom, instType itype) {
p->del = dtp22_del;
p->icom = icom;
- p->itype = itype;
+ p->dtype = itype;
p->mode = inst_mode_none;
p->need_cal = 1; /* Do a white calibration each time we open the device */
diff --git a/spectro/dtp22.h b/spectro/dtp22.h
index af565e8..af565e8 100644..100755
--- a/spectro/dtp22.h
+++ b/spectro/dtp22.h
diff --git a/spectro/dtp41.c b/spectro/dtp41.c
index 97a3db1..e536cfc 100644..100755
--- a/spectro/dtp41.c
+++ b/spectro/dtp41.c
@@ -48,6 +48,7 @@
#include "sa_config.h"
#include "numsup.h"
#endif /* !SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -1331,7 +1332,7 @@ dtp41_get_set_opt(inst *pp, inst_opt_type m, ...)
}
/* Constructor */
-extern dtp41 *new_dtp41(icoms *icom, instType itype) {
+extern dtp41 *new_dtp41(icoms *icom, instType dtype) {
dtp41 *p;
if ((p = (dtp41 *)calloc(sizeof(dtp41),1)) == NULL) {
a1loge(icom->log, 1, "new_dtp41: malloc failed!\n");
@@ -1354,7 +1355,7 @@ extern dtp41 *new_dtp41(icoms *icom, instType itype) {
p->del = dtp41_del;
p->icom = icom;
- p->itype = itype;
+ p->dtype = dtype;
p->cap = inst_mode_none; /* Unknown until set */
p->mode = inst_mode_none; /* Not in a known mode yet */
p->nstaticr = 5; /* Number of static readings */
diff --git a/spectro/dtp41.h b/spectro/dtp41.h
index 018ed5c..018ed5c 100644..100755
--- a/spectro/dtp41.h
+++ b/spectro/dtp41.h
diff --git a/spectro/dtp51.c b/spectro/dtp51.c
index 0b2ecab..70932e5 100644..100755
--- a/spectro/dtp51.c
+++ b/spectro/dtp51.c
@@ -51,6 +51,7 @@
#include "sa_config.h"
#include "numsup.h"
#endif /* !SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -896,7 +897,7 @@ dtp51_get_set_opt(inst *pp, inst_opt_type m, ...) {
}
/* Constructor */
-extern dtp51 *new_dtp51(icoms *icom, instType itype) {
+extern dtp51 *new_dtp51(icoms *icom, instType dtype) {
dtp51 *p;
if ((p = (dtp51 *)calloc(sizeof(dtp51),1)) == NULL) {
a1loge(icom->log, 1, "new_dtp51: malloc failed!\n");
@@ -918,7 +919,7 @@ extern dtp51 *new_dtp51(icoms *icom, instType itype) {
p->del = dtp51_del;
p->icom = icom;
- p->itype = itype;
+ p->dtype = dtype;
p->native_calstd = xcalstd_xrdi; /* Not alterable */
diff --git a/spectro/dtp51.h b/spectro/dtp51.h
index 804b8ae..804b8ae 100644..100755
--- a/spectro/dtp51.h
+++ b/spectro/dtp51.h
diff --git a/spectro/dtp92.c b/spectro/dtp92.c
index 33b8fa0..fbcbd7e 100644..100755
--- a/spectro/dtp92.c
+++ b/spectro/dtp92.c
@@ -51,6 +51,7 @@
#include "sa_config.h"
#include "numsup.h"
#endif /* !SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -179,7 +180,7 @@ dtp92_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
char *brc[5] = { "30BR\r", "60BR\r", "18BR\r", "0CBR\r", "06BR\r" };
char *fcc;
unsigned int etime;
- instType itype = pp->itype;
+ instType dtype = pp->dtype;
int ci, bi, i, se;
inst_code ev = inst_ok;
@@ -202,7 +203,7 @@ dtp92_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
/* */
/* Set config, interface, write end point, read end point, read quanta */
- if (itype == instDTP94) {
+ if (dtype == instDTP94) {
wr_ep = 0x02;
rd_ep = 0x81;
} else {
@@ -407,17 +408,17 @@ dtp92_init_inst(inst *pp) {
return inst_unknown_model;
if (strncmp(buf,"X-Rite DTP94",12) == 0)
- p->itype = instDTP94;
+ p->dtype = instDTP94;
else
- p->itype = instDTP92;
+ p->dtype = instDTP92;
- if (p->itype == instDTP92) {
+ if (p->dtype == instDTP92) {
/* Turn echoing of characters off */
if ((ev = dtp92_command(p, "DEC\r", buf, MAX_MES_SIZE, DEF_TIMEOUT)) != inst_ok)
return ev;
}
- if (p->itype == instDTP92) {
+ if (p->dtype == instDTP92) {
/* Set decimal point on */
if ((ev = dtp92_command(p, "0106CF\r", buf, MAX_MES_SIZE, DEF_TIMEOUT)) != inst_ok)
return ev;
@@ -435,7 +436,7 @@ dtp92_init_inst(inst *pp) {
if ((ev = dtp92_command(p, "010ACF\r", buf, MAX_MES_SIZE, DEF_TIMEOUT)) != inst_ok)
return ev;
- if (p->itype == instDTP92) {
+ if (p->dtype == instDTP92) {
/* Set absolute (luminance) calibration */
if ((ev = dtp92_command(p, "0118CF\r", buf, MAX_MES_SIZE, DEF_TIMEOUT)) != inst_ok)
return ev;
@@ -449,13 +450,13 @@ dtp92_init_inst(inst *pp) {
if ((ev = dtp92_command(p, "EFC\r", buf, MAX_MES_SIZE, DEF_TIMEOUT)) != inst_ok)
return ev;
- if (p->itype == instDTP94) {
+ if (p->dtype == instDTP94) {
/* Compensate for offset drift */
if ((ev = dtp92_command(p, "0117CF\r", buf, MAX_MES_SIZE, DEF_TIMEOUT)) != inst_ok)
return ev;
}
- if (p->itype == instDTP92) {
+ if (p->dtype == instDTP92) {
/* Enable ABS mode (in case firmware doesn't default to this after EFC) */
if ((ev = dtp92_command(p, "0118CF\r", buf, MAX_MES_SIZE, DEF_TIMEOUT)) != inst_ok)
return ev;
@@ -505,7 +506,7 @@ dtp92_init_inst(inst *pp) {
/* ??? Need to set CTYP appropriately ??? */
#ifdef NEVER /* Debug code */
- if (p->itype == instDTP94) {
+ if (p->dtype == instDTP94) {
int i, val;
char tb[50];
@@ -571,7 +572,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
/* Could change SS to suite level expected. */
#ifdef NEVER
- if (p->itype == instDTP92) {
+ if (p->dtype == instDTP92) {
/* Set sample size to 31 (default is 16) for low level readings */
if ((rv = dtp92_command(p, "1fSS\r", buf, MAX_MES_SIZE, DEF_TIMEOUT)) != inst_ok)
return rv;
@@ -652,7 +653,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
}
#ifdef NEVER
- if (p->itype == instDTP92) {
+ if (p->dtype == instDTP92) {
/* Set sample size back to 16 */
if ((rv = dtp92_command(p, "10SS\r", buf, MAX_MES_SIZE, DEF_TIMEOUT)) != inst_ok)
return rv;
@@ -759,7 +760,7 @@ static inst_code dtp92_get_n_a_cals(inst *pp, inst_cal_type *pn_cals, inst_cal_t
inst_cal_type n_cals = inst_calt_none;
inst_cal_type a_cals = inst_calt_none;
- if (p->itype == instDTP92) {
+ if (p->dtype == instDTP92) {
if (p->need_ratio_cal)
n_cals |= inst_calt_emis_ratio;
a_cals |= inst_calt_emis_ratio;
@@ -1058,7 +1059,7 @@ inst3_capability *pcap3) {
| inst2_ccmx
; /* The '92 does have a switch, but we're not currently supporting it */
- if (p->itype == instDTP94) {
+ if (p->dtype == instDTP94) {
cap2 |= inst2_disptype;
} else {
cap2 |= inst2_get_refresh_rate;
@@ -1167,7 +1168,7 @@ static inst_disptypesel dtp94_disptypesel[4] = {
};
static void set_base_disptype_list(dtp92 *p) {
- if (p->itype == instDTP94) {
+ if (p->dtype == instDTP94) {
p->_dtlist = dtp94_disptypesel;
} else {
p->_dtlist = dtp92_disptypesel;
@@ -1218,7 +1219,7 @@ static inst_code set_disp_type(dtp92 *p, inst_disptypesel *dentry) {
p->cbid = dentry->cbid;
p->ucbid = dentry->cbid; /* is underying base if dentry is base selection */
- if (p->itype == instDTP92) {
+ if (p->dtype == instDTP92) {
if (p->icx != 0)
return inst_unsupported;
@@ -1395,7 +1396,7 @@ dtp92_get_set_opt(inst *pp, inst_opt_type m, ...) {
}
/* Constructor */
-extern dtp92 *new_dtp92(icoms *icom, instType itype) {
+extern dtp92 *new_dtp92(icoms *icom, instType dtype) {
dtp92 *p;
if ((p = (dtp92 *)calloc(sizeof(dtp92),1)) == NULL) {
a1loge(icom->log, 1, "new_dtp92: malloc failed!\n");
@@ -1423,7 +1424,7 @@ extern dtp92 *new_dtp92(icoms *icom, instType itype) {
p->del = dtp92_del;
p->icom = icom;
- p->itype = itype;
+ p->dtype = dtype;
icmSetUnity3x3(p->ccmat); /* Set the colorimeter correction matrix to do nothing */
set_base_disptype_list(p);
diff --git a/spectro/dtp92.h b/spectro/dtp92.h
index 8a6885e..8a6885e 100644..100755
--- a/spectro/dtp92.h
+++ b/spectro/dtp92.h
diff --git a/spectro/ex1.c b/spectro/ex1.c
index 5f4eae2..929af3d 100644..100755
--- a/spectro/ex1.c
+++ b/spectro/ex1.c
@@ -54,6 +54,7 @@
#include "sa_config.h"
#include "numsup.h"
#endif /* !SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -158,7 +159,7 @@ static int ex1_touch_calibration(ex1 *p);
static inst_code
ex1_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
ex1 *p = (ex1 *) pp;
- instType itype = pp->itype;
+ instType dtype = pp->dtype;
int se;
inst_code ev = inst_ok;
@@ -1210,7 +1211,7 @@ ex1_get_set_opt(inst *pp, inst_opt_type m, ...) {
}
/* Constructor */
-extern ex1 *new_ex1(icoms *icom, instType itype) {
+extern ex1 *new_ex1(icoms *icom, instType dtype) {
ex1 *p;
if ((p = (ex1 *)calloc(sizeof(ex1),1)) == NULL) {
a1loge(icom->log, 1, "new_ex1: malloc failed!\n");
@@ -1241,7 +1242,7 @@ extern ex1 *new_ex1(icoms *icom, instType itype) {
p->del = ex1_del;
p->icom = icom;
- p->itype = itype;
+ p->dtype = dtype;
p->want_dcalib = 1; /* Always do an initial dark calibration */
diff --git a/spectro/ex1.h b/spectro/ex1.h
index a278777..a278777 100644..100755
--- a/spectro/ex1.h
+++ b/spectro/ex1.h
diff --git a/spectro/fakeread.c b/spectro/fakeread.c
index 3cad93a..3cad93a 100644..100755
--- a/spectro/fakeread.c
+++ b/spectro/fakeread.c
diff --git a/spectro/hcfr.c b/spectro/hcfr.c
index 22b5170..568c69f 100644..100755
--- a/spectro/hcfr.c
+++ b/spectro/hcfr.c
@@ -53,6 +53,7 @@
#include "sa_config.h"
#include "numsup.h"
#endif /* SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -125,7 +126,7 @@ hcfr_flush(
int rv;
for (rv = ICOM_OK;;) {
- rv = c->read(c, buf, MAX_MES_SIZE, NULL, '\000', 100000, 0.05);
+ rv = c->read(c, buf, MAX_MES_SIZE, NULL, NULL, 100000, 0.05);
if (rv != ICOM_OK)
break; /* Expect timeout with nothing to read */
}
@@ -933,7 +934,7 @@ hcfr_get_set_opt(inst *pp, inst_opt_type m, ...) {
}
/* Constructor */
-extern hcfr *new_hcfr(icoms *icom, instType itype) {
+extern hcfr *new_hcfr(icoms *icom, instType dtype) {
hcfr *p;
if ((p = (hcfr *)calloc(sizeof(hcfr),1)) == NULL) {
a1loge(icom->log, 1, "new_hcfr: malloc failed!\n");
@@ -957,7 +958,7 @@ extern hcfr *new_hcfr(icoms *icom, instType itype) {
p->del = hcfr_del;
p->icom = icom;
- p->itype = itype;
+ p->dtype = dtype;
icmSetUnity3x3(p->ccmat); /* Set the colorimeter correction matrix to do nothing */
p->dtech = disptech_unknown;
diff --git a/spectro/hcfr.h b/spectro/hcfr.h
index 2420fdf..2420fdf 100644..100755
--- a/spectro/hcfr.h
+++ b/spectro/hcfr.h
diff --git a/spectro/hidio.c b/spectro/hidio.c
index 2d8649f..e78fb98 100644..100755
--- a/spectro/hidio.c
+++ b/spectro/hidio.c
@@ -73,6 +73,7 @@
#include "sa_config.h"
#endif
#include "numsup.h"
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -419,6 +420,8 @@ int hid_get_paths(icompaths *p) {
/* Add the path to the list */
p->add_hid(p, pname, vid, pid, 0, hidd, itype);
+ } else {
+ a1logd(p->log, 4, "skipping HID device VID 0x%x PID 0x%x lid 0x%x that we don't want\n",vid, pid, lid);
}
if (ioob != 0) /* If we haven't kept it */
IOObjectRelease(ioob); /* Release found object */
diff --git a/spectro/hidio.h b/spectro/hidio.h
index 87edd43..87edd43 100644..100755
--- a/spectro/hidio.h
+++ b/spectro/hidio.h
diff --git a/spectro/huey.c b/spectro/huey.c
index 2c82b4c..7739f96 100644..100755
--- a/spectro/huey.c
+++ b/spectro/huey.c
@@ -49,6 +49,7 @@
#include "sa_config.h"
#include "numsup.h"
#endif /* SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -885,25 +886,38 @@ huey_check_unlock(
if ((ev = huey_command(p, i1d_status, buf, buf, 1.0,1.0)) != inst_ok)
return ev;
- /* Hmm. Some Lenovo Huey's say they are unlocked, even when they are not. */
+ /* Hmm. Some Lenovo Huey's (the HueyColors ?) aren't locked, */
+ /* so the unlock command fails. */
if (p->lenovo || strncmp((char *)buf, "Locked", 6) == 0) {
memset(buf, 0, 7);
+
+ /* Set unlock codes */
if (p->lenovo)
strcpy((char *)buf,"huyL");
else
strcpy((char *)buf,"GrMb");
- if ((ev = huey_command(p, i1d_unlock, buf, buf, 1.0,1.0)) != inst_ok)
- return ev;
+ if ((ev = huey_command(p, i1d_unlock, buf, buf, 1.0,1.0)) != inst_ok) {
+ a1logd(p->log,2,"huey_check_unlock: warning, unlock command returned error\n");
+ /* Perhaps the error code is for wrong unlock code, so ignore this */
+ /* and try a status command */
+ }
memset(buf, 0, 7);
if ((ev = huey_command(p, i1d_status, buf, buf, 1.0,1.0)) != inst_ok)
return ev;
}
+ /*
+ Apparently the "ECCM3" is a "hueyCOLOR", which is actually
+ a monochrome sensor! It uses different instructions to the Huey,
+ and wouldn't be terribly useful to ArgyllCMS.
+ See <https://github.com/hughsie/colord/tree/master/src/sensors/huey2>
+ */
+
if (strncmp((char *)buf, "huL002", 6) != 0 /* Lenovo Huey ? */
- && strncmp((char *)buf, "ECCM2 ", 6) != 0 /* Lenovo Thinkpad W530 Huey ? */
- && strncmp((char *)buf, "ECCM3 ", 6) != 0 /* Lenovo Thinkpad W530 Huey ? */
+ && strncmp((char *)buf, "ECCM2 ", 6) != 0 /* Lenovo Thinkpad W530 HueyPro ? */
+// && strncmp((char *)buf, "ECCM3 ", 6) != 0 /* Lenovo Thinkpad P70 HueyColor ? */
&& strncmp((char *)buf, "Cir001", 6) != 0) { /* Huey */
a1logd(p->log,1,"huey_check_unlock: unknown model '%s'\n",buf);
return huey_interp_code((inst *)p, HUEY_UNKNOWN_MODEL);
@@ -1732,7 +1746,7 @@ huey_get_set_opt(inst *pp, inst_opt_type m, ...) {
}
/* Constructor */
-extern huey *new_huey(icoms *icom, instType itype) {
+extern huey *new_huey(icoms *icom, instType dtype) {
huey *p;
if ((p = (huey *)calloc(sizeof(huey),1)) == NULL) {
a1loge(icom->log, 1, "new_huey: malloc failed!\n");
@@ -1756,7 +1770,7 @@ extern huey *new_huey(icoms *icom, instType itype) {
p->del = huey_del;
p->icom = icom;
- p->itype = itype;
+ p->dtype = dtype;
icmSetUnity3x3(p->ccmat); /* Set the colorimeter correction matrix to do nothing */
p->dtech = disptech_unknown;
diff --git a/spectro/huey.h b/spectro/huey.h
index f13056b..f13056b 100644..100755
--- a/spectro/huey.h
+++ b/spectro/huey.h
diff --git a/spectro/i1d3.c b/spectro/i1d3.c
index 4562a52..7e5c396 100644..100755
--- a/spectro/i1d3.c
+++ b/spectro/i1d3.c
@@ -53,6 +53,7 @@
#include "sa_config.h"
#include "numsup.h"
#endif /* SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -125,8 +126,8 @@ typedef enum {
i1d3_firmver = 0x0012, /* Firmware version string */
i1d3_firmdate = 0x0013, /* Firmware date string */
i1d3_locked = 0x0020, /* Get locked status */
- i1d3_measure1 = 0x0100, /* Used by all measure */
- i1d3_measure2 = 0x0200, /* Used by all measure except ambient */
+ i1d3_freqmeas = 0x0100, /* Measure transition over given time */
+ i1d3_periodmeas = 0x0200, /* Measure time between transition count */
i1d3_readintee = 0x0800, /* Read internal EEPROM */
i1d3_readextee = 0x1200, /* Read external EEPROM */
i1d3_setled = 0x2100, /* Set the LED state */
@@ -155,10 +156,10 @@ static char *inst_desc(i1Disp3CC cc) {
return "GetFirmwareDate";
case i1d3_locked:
return "GetLockedStatus";
- case i1d3_measure1:
- return "Measure1";
- case i1d3_measure2:
- return "Measure2";
+ case i1d3_freqmeas:
+ return "Frequency Measure";
+ case i1d3_periodmeas:
+ return "Period Measure";
case i1d3_readintee:
return "ReadInternalEEPROM";
case i1d3_readextee:
@@ -278,9 +279,9 @@ i1d3_command(
}
/* Hmm. Not sure about this bug workaround. Is this a rev B thing ? */
- /* May get status 0x83 on i1d3_measure2 when there are no transitions ? */
+ /* May get status 0x83 on i1d3_periodmeas when there are no transitions ? */
/* If so, ignore the error. */
- if (rv == inst_ok && cc == i1d3_measure2 && recv[1] == 0x02 && recv[0] == 0x83) {
+ if (rv == inst_ok && cc == i1d3_periodmeas && recv[1] == 0x02 && recv[0] == 0x83) {
int i;
for (i = 2; i < 14; i++) {
if (recv[i] != 0)
@@ -587,7 +588,7 @@ i1d3_unlock(
struct {
char *pname; /* Product name */
unsigned int key[2]; /* Unlock code */
- i1d3_dtype dtype; /* Base type enumerator */
+ i1d3_dtype btype; /* Base type enumerator */
i1d3_dtype stype; /* Sub type enumerator */
} codes[] = {
{ "i1Display3 ", { 0xe9622e9f, 0x8d63e133 }, i1d3_disppro, i1d3_disppro },
@@ -597,6 +598,7 @@ i1d3_unlock(
{ "i1Display3 ", { 0x160eb6ae, 0x14440e70 }, i1d3_disppro, i1d3_quato_sh3 },
{ "i1Display3 ", { 0x291e41d7, 0x51937bdd }, i1d3_disppro, i1d3_hp_dreamc },
{ "i1Display3 ", { 0xc9bfafe0, 0x02871166 }, i1d3_disppro, i1d3_sc_c6 },
+ { "i1Display3 ", { 0x1abfae03, 0xf25ac8e8 }, i1d3_disppro, i1d3_wacom_dc },
{ NULL }
};
inst_code ev;
@@ -630,7 +632,7 @@ i1d3_unlock(
// codes[ix].key[0], codes[ix].key[1]);
a1logd(p->log, 3, "i1d3_unlock: Trying unlock key %d/%d\n", ix+1, nix);
- p->dtype = codes[ix].dtype;
+ p->btype = codes[ix].btype;
p->stype = codes[ix].stype;
/* Attempt unlock */
@@ -778,7 +780,7 @@ i1d3_read_external_eeprom(
/* Take a raw measurement using a given integration time. */
/* The measurent is the count of (both) edges from the L2V */
-/* over the integration time */
+/* over the integration time. */
static inst_code
i1d3_freq_measure(
i1d3 *p, /* Object */
@@ -804,21 +806,31 @@ i1d3_freq_measure(
todev[23] = 0; /* Unknown parameter, always 0 */
- if ((ev = i1d3_command(p, i1d3_measure1, todev, fromdev, I1D3_MEAS_TIMEOUT, 0)) != inst_ok)
+ if ((ev = i1d3_command(p, i1d3_freqmeas, todev, fromdev, I1D3_MEAS_TIMEOUT, 0)) != inst_ok)
return ev;
rgb[0] = (double)buf2uint(fromdev + 2);
rgb[1] = (double)buf2uint(fromdev + 6);
rgb[2] = (double)buf2uint(fromdev + 10);
+ /* The HW holds the L2F *OE high (disabled) until the start of the measurement period, */
+ /* and this has the effect of holding the internal integrator in a reset state. */
+ /* This then synchronizes the frequency output to the start of */
+ /* the measurement, which has the effect of rounding down the count output. */
+ /* To compensate, we have to add 0.5 to the count. */
+ rgb[0] += 0.5;
+ rgb[1] += 0.5;
+ rgb[2] += 0.5;
+
return inst_ok;
}
/* Take a raw measurement that returns the number of clocks */
-/* between and initial edge and edgec[] subsequent edges of the L2F. */
-/* The edge count must be between 1 and 65535 inclusive. */
-/* Both edges are counted. It's advisable to use an even edgec[], */
-/* because the L2F output may not be symetric. */
+/* between and initial edge at the start of the period (triggered by */
+/* the *OE going low and the integrator being started) and edgec[] */
+/* subsequent edges of the L2F. The edge count must be between */
+/* 1 and 65535 inclusive. Both edges are counted. It's advisable */
+/* to use an even edgec[], because the L2F output may not be symetric. */
/* If there are no edges within 10 seconds, return a count of 0 */
static inst_code
i1d3_period_measure(
@@ -841,7 +853,7 @@ i1d3_period_measure(
todev[7] = (unsigned char)mask;
todev[8] = 0; /* Unknown parameter, always 0 */
- if ((ev = i1d3_command(p, i1d3_measure2, todev, fromdev, I1D3_MEAS_TIMEOUT, 0)) != inst_ok)
+ if ((ev = i1d3_command(p, i1d3_periodmeas, todev, fromdev, I1D3_MEAS_TIMEOUT, 0)) != inst_ok)
return ev;
rgb[0] = (double)buf2uint(fromdev + 2);
@@ -932,6 +944,9 @@ i1d3_set_LEDs(
To break up the USB synchronization, the integration time
is randomized slightly.
+
+ NOTE :- we should really switch to using period measurement mode here,
+ since it is more accurate ?
*/
#ifndef PSRAND32L
@@ -1577,7 +1592,8 @@ i1d3_take_emis_measurement(
isth = p->th_en;
p->th_en = 0;
- /* If we should take a frequency measurement first */
+ /* If we should take a frequency measurement first, */
+ /* since it is done in a predictable duration */
if (mode == i1d3_adaptive || mode == i1d3_frequency) {
/* Typically this is 200msec for non-refresh, 400msec for refresh. */
@@ -1635,7 +1651,7 @@ i1d3_take_emis_measurement(
continue;
if (rmeas[i] < 10.0
- || (p->dtype != i1d3_munkdisp && rmeas[i] < 20.0)) {
+ || (p->btype != i1d3_munkdisp && rmeas[i] < 20.0)) {
a1logd(p->log,3,"chan %d needs pre-measurement\n",i);
mask2 |= 1 << i;
} else {
@@ -1667,7 +1683,7 @@ i1d3_take_emis_measurement(
/* Transfer updated counts from 1st initial measurement */
for (i = 0; i < 3; i++) {
if ((mask2 & (1 << i)) != 0) {
- rmeas[i] = rmeas2[i];
+ rmeas[i] = rmeas2[i];
/* Compute trial RGB in case we need it later */
if (rmeas[i] >= 0.5) {
@@ -1680,7 +1696,7 @@ i1d3_take_emis_measurement(
/* we are measuring a CRT with a refresh rate which adds innacuracy, */
/* and could result in a unecessarily long re-reading. */
/* Don't do this for Munki Display, because of its slow measurements. */
- if (p->dtype != i1d3_munkdisp) {
+ if (p->btype != i1d3_munkdisp) {
for (i = 0; i < 3; i++) {
if ((mask2 & (1 << i)) == 0)
continue;
@@ -2465,9 +2481,12 @@ i1d3_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
/* something to do with detaching the default HID driver ?? */
#if defined(UNIX_X11)
usbflags |= icomuf_detach;
- usbflags |= icomuf_no_open_clear;
usbflags |= icomuf_reset_before_close;
#endif
+
+ /* On MSWin it doesn't like clearing on open when running direct (i.e not HID) */
+ usbflags |= icomuf_no_open_clear;
+
/* Open as an HID if available */
if (p->icom->port_type(p->icom) == icomt_hid) {
@@ -2579,7 +2598,7 @@ i1d3_init_inst(inst *pp) {
return ev;
if (p->prod_type == 0x0002) { /* If ColorMunki Display */
/* Set this in case it doesn't need unlocking */
- p->dtype = p->stype = i1d3_munkdisp;
+ p->btype = p->stype = i1d3_munkdisp;
}
if ((ev = i1d3_get_firmver(p, p->firm_ver)) != inst_ok)
return ev;
@@ -2731,7 +2750,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
}
/* Attempt a refresh display frame rate calibration if needed */
- if (p->dtype != i1d3_munkdisp && p->refrmode != 0 && p->rrset == 0) {
+ if (p->btype != i1d3_munkdisp && p->refrmode != 0 && p->rrset == 0) {
inst_code ev = inst_ok;
p->mininttime = 2.0 * p->dinttime;
@@ -2804,7 +2823,7 @@ double *ref_rate) {
if (!p->inited)
return inst_no_init;
- if (p->dtype == i1d3_munkdisp)
+ if (p->btype == i1d3_munkdisp)
return inst_unsupported;
if (ref_rate != NULL)
@@ -2928,7 +2947,7 @@ static inst_code i1d3_get_n_a_cals(inst *pp, inst_cal_type *pn_cals, inst_cal_ty
inst_cal_type n_cals = inst_calt_none;
inst_cal_type a_cals = inst_calt_none;
- if (p->dtype != i1d3_munkdisp && p->refrmode != 0) {
+ if (p->btype != i1d3_munkdisp && p->refrmode != 0) {
if (p->rrset == 0)
n_cals |= inst_calt_ref_freq;
a_cals |= inst_calt_ref_freq;
@@ -2988,7 +3007,7 @@ char id[CALIDLEN] /* Condition identifier (ie. white reference ID) */
return inst_unsupported;
}
- if ((*calt & inst_calt_ref_freq) && p->dtype != i1d3_munkdisp && p->refrmode != 0) {
+ if ((*calt & inst_calt_ref_freq) && p->btype != i1d3_munkdisp && p->refrmode != 0) {
inst_code ev = inst_ok;
p->mininttime = 2.0 * p->dinttime;
@@ -3498,7 +3517,7 @@ inst3_capability *pcap3) {
| inst2_set_min_int_time
;
- if (p->dtype != i1d3_munkdisp) {
+ if (p->btype != i1d3_munkdisp) {
cap2 |= inst2_meas_disp_update;
cap2 |= inst2_get_refresh_rate;
cap2 |= inst2_set_refresh_rate;
@@ -3865,7 +3884,7 @@ i1d3_get_set_opt(inst *pp, inst_opt_type m, ...) {
p->omininttime = dval;
/* Hmm. This code is duplicated a lot.. */
- if (p->dtype != i1d3_munkdisp && p->refrmode != 0) {
+ if (p->btype != i1d3_munkdisp && p->refrmode != 0) {
inst_code ev = inst_ok;
p->mininttime = 2.0 * p->dinttime;
@@ -4038,7 +4057,7 @@ i1d3_get_set_opt(inst *pp, inst_opt_type m, ...) {
}
/* Constructor */
-extern i1d3 *new_i1d3(icoms *icom, instType itype) {
+extern i1d3 *new_i1d3(icoms *icom, instType dtype) {
i1d3 *p;
if ((p = (i1d3 *)calloc(sizeof(i1d3),1)) == NULL) {
@@ -4073,7 +4092,7 @@ extern i1d3 *new_i1d3(icoms *icom, instType itype) {
p->del = i1d3_del;
p->icom = icom;
- p->itype = itype;
+ p->dtype = dtype;
amutex_init(p->lock);
icmSetUnity3x3(p->ccmat);
diff --git a/spectro/i1d3.h b/spectro/i1d3.h
index a7c3b24..6152a00 100644..100755
--- a/spectro/i1d3.h
+++ b/spectro/i1d3.h
@@ -87,7 +87,8 @@ typedef enum {
i1d3_nec_ssp = 3, /* NEC SpectraSensor Pro */
i1d3_quato_sh3 = 4, /* Quato Silver Haze 3 */
i1d3_hp_dreamc = 5, /* HP DreameColor */
- i1d3_sc_c6 = 6 /* SpectraCal C6 */
+ i1d3_sc_c6 = 6, /* SpectraCal C6 */
+ i1d3_wacom_dc = 7 /* Wacom DC */
} i1d3_dtype;
/* Measurement mode */
@@ -108,7 +109,7 @@ struct _i1d3 {
inst_opt_type trig; /* Reading trigger mode */
/* Information and EEPROM values */
- i1d3_dtype dtype; /* Base type of instrument, ie i1d3_disppro or i1d3_munkdisp */
+ i1d3_dtype btype; /* Base type of instrument, ie i1d3_disppro or i1d3_munkdisp */
i1d3_dtype stype; /* Sub type of instrument, ie. any of i1d3_dtype. */
/* (Only accurate if it needed unlocking). */
int status; /* 0 if status is ok (not sure what this is) */
diff --git a/spectro/i1disp.c b/spectro/i1disp.c
index 9e4b01f..dfe4a60 100644..100755
--- a/spectro/i1disp.c
+++ b/spectro/i1disp.c
@@ -47,6 +47,7 @@
#include "sa_config.h"
#include "numsup.h"
#endif /* !SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -276,7 +277,7 @@ i1disp_rdreg_byte(
int rsize;
inst_code ev;
- if (p->dtype == 0) {
+ if (p->btype == 0) {
if (addr < 0 || addr > 127)
return i1disp_interp_code((inst *)p, I1DISP_BAD_REG_ADDRESS);
} else {
@@ -484,7 +485,7 @@ i1disp_rdexreg_bytes(
int ooff, rsize;
inst_code ev;
- if (p->dtype != 2) /* Only ColorMunki Smile ? */
+ if (p->btype != 2) /* Only ColorMunki Smile ? */
return i1disp_interp_code((inst *)p, I1DISP_WRONG_DEVICE);
if (addr < 0 || addr > 0x0200)
@@ -649,7 +650,7 @@ i1d1_take_measurement(
if (p->inited == 0)
return i1disp_interp_code((inst *)p, I1DISP_NOT_INITED);
- if (p->dtype != 0)
+ if (p->btype != 0)
return i1disp_interp_code((inst *)p, I1DISP_WRONG_DEVICE);
/* Do an initial measurement with minimum edge count of 1 */
@@ -858,13 +859,13 @@ i1d2_take_measurement(
if (p->inited == 0)
return i1disp_interp_code((inst *)p, I1DISP_NOT_INITED);
- if (p->dtype == 0)
+ if (p->btype == 0)
return i1disp_interp_code((inst *)p, I1DISP_WRONG_DEVICE);
a1logd(p->log, 3, "i1d2_take_measurement called with refreshm = %d\n",refreshm);
/* Do refresh period measurement */
- if (p->dtype == 1 && refreshm && p->rrset == 0) {
+ if (p->btype == 1 && refreshm && p->rrset == 0) {
if ((ev = i1disp_do_fcal_setit(p)) != inst_ok)
return ev;
@@ -1040,13 +1041,13 @@ i1d2_take_measurement(
if (p->inited == 0)
return i1disp_interp_code((inst *)p, I1DISP_NOT_INITED);
- if (p->dtype == 0)
+ if (p->btype == 0)
return i1disp_interp_code((inst *)p, I1DISP_WRONG_DEVICE);
a1logd(p->log, 3, "i1d2_take_measurement called with refreshm = %d\n",refreshm);
/* Do refresh period measurement */
- if (p->dtype == 1 && refreshm && p->rrset == 0) {
+ if (p->btype == 1 && refreshm && p->rrset == 0) {
if ((ev = i1disp_do_fcal_setit(p)) != inst_ok)
return ev;
@@ -1238,7 +1239,7 @@ i1disp_take_XYZ_measurement(
inst_code ev;
double *mat; /* Pointer to matrix */
- if (p->dtype == 0) { /* i1 disp 1 */
+ if (p->btype == 0) { /* i1 disp 1 */
if ((ev = i1d1_take_measurement(p, 0, rgb)) != inst_ok)
return ev;
} else { /* i1 disp 2 or ColorMunki Smile */
@@ -1289,7 +1290,7 @@ i1disp_do_black_cal(
double rgb1[3], rgb2[3]; /* RGB Readings */
inst_code ev;
- if (p->dtype != 0)
+ if (p->btype != 0)
return i1disp_interp_code((inst *)p, I1DISP_CANT_BLACK_CALIB);
/* Do a couple of readings without subtracting the black */
@@ -1331,7 +1332,7 @@ i1disp_read_refrate(
a1logd(p->log, 3, "Frequency calibration called\n");
- if (p->dtype != 1)
+ if (p->btype != 1)
return inst_unsupported;
if (ref_rate != NULL)
@@ -1376,7 +1377,7 @@ i1disp_do_fcal_setit(
a1logd(p->log, 3, "Frequency calibration called\n");
- if (p->dtype != 1)
+ if (p->btype != 1)
return i1disp_interp_code((inst *)p, I1DISP_CANT_MEASP_CALIB);
if ((ev = i1disp_read_refrate((inst *)p, &p->refrate)) != inst_ok
@@ -1410,7 +1411,7 @@ i1disp_check_unlock(
struct {
unsigned char code[4];
- i1d2_dtype stype;
+ i1d2_stype stype;
} codes[] = {
{ { 'G','r','M','b' }, i1d2_norm }, /* "GrMb" i1 Display */
{ { 'L','i','t','e' }, i1d2_lite }, /* "Lite" i1 Display LT */
@@ -1429,7 +1430,7 @@ i1disp_check_unlock(
{ { 0x0e,0x0e,0x0e,0x0e }, i1d2_norm }, /* */
{ { 0x11,0x02,0xde,0xf0 }, i1d2_norm }, /* Barco Chroma 5 ? */
// { { 0xff,0xff,0xff,0xff }, i1d2_norm }, /* Chroma 5 isn't locked ? */
- { { ' ',' ',' ',' ' }, -1 }
+ { { ' ',' ',' ',' ' }, i1d2_unkn }
};
a1logd(p->log, 3, "i1disp: about to check response and unlock instrument if needed\n");
@@ -1444,7 +1445,7 @@ i1disp_check_unlock(
/* Try each code in turn */
for (i = 0; ;i++) {
- if (codes[i].stype == -1) {
+ if (codes[i].stype == i1d2_unkn) {
a1logd(p->log, 3, "Failed to find correct unlock code\n");
return i1disp_interp_code((inst *)p, I1DISP_UNKNOWN_MODEL);
}
@@ -1489,37 +1490,37 @@ i1disp_check_unlock(
/* Barco Chroma 5 with ver = 5.01 vv = '5' */
if (ver >= 4.0 && ver < 5.1 && vv == '5') {
- p->dtype = 0; /* Sequel Chroma 4 ?? */
+ p->btype = 0; /* Sequel Chroma 4 ?? */
p->stype = i1d1_chroma4; /* Treat like an Eye-One Display 1 */
/* Sequel Chroma 4 with vv == 0xff ???? */
/* Sencore ColorPro III with ver = 5.01 and vv = 0xff */
} else if (ver >= 4.0 && ver < 5.1 && vv == 0xff) {
- p->dtype = 0; /* Eye-One Display 1 */
+ p->btype = 0; /* Eye-One Display 1 */
p->stype = i1d1_sencoreIII;
/* Sencore ColorPro IV with ver = 5.01 and vv = 'L' */
} else if (ver >= 4.0 && ver < 5.1 && vv == 'L') {
- p->dtype = 0; /* Eye-One Display 1 */
+ p->btype = 0; /* Eye-One Display 1 */
p->stype = i1d1_sencoreIV; /* Treat like an Eye-One Display 1 */
/* Sencore ColorPro V with ver = 5.01 and vv = 'B' */
} else if (ver >= 4.0 && ver < 5.1 && vv == 'B') {
- p->dtype = 0; /* Eye-One Display 1 */
+ p->btype = 0; /* Eye-One Display 1 */
p->stype = i1d1_sencoreV; /* Treat like an Eye-One Display 1 */
} else if (ver >= 5.1 && ver <= 5.3 && vv == 'L') {
- p->dtype = 0; /* Eye-One Display 1 */
+ p->btype = 0; /* Eye-One Display 1 */
} else if (ver >= 6.0 && ver <= 6.29 && vv == 'L') {
- p->dtype = 1; /* Eye-One Display 2 */
+ p->btype = 1; /* Eye-One Display 2 */
} else if (ver >= 6.0 && ver <= 6.29
&& (vv = 0xff || vv == 'M')) { // Faulty Smile's have vv = 0xff
/* ColorMunki Create ? */
/* ColorMunki Smile */
- if (p->dtype == 0) /* Not sure if this is set by Create */
- p->dtype = 1;
+ if (p->btype == 0) /* Not sure if this is set by Create */
+ p->btype = 1;
} else {
/* Reject any version or model we don't know about */
@@ -1642,7 +1643,7 @@ i1disp_read_all_regs(
p->serno[0] = '\000';
/* Read extra registers */
- if (p->dtype == 1) {
+ if (p->btype == 1) {
#ifdef NEVER /* Not used, so don't bother */
for (i = 0; i < 3; i++) {
@@ -1668,7 +1669,7 @@ i1disp_read_all_regs(
/* ColorMunki Smile extra information */
/* (Colormunki Create too ????) */
- } else if (p->dtype == 2) {
+ } else if (p->btype == 2) {
int i, v;
/* Smile doesn't have ambient - reg144 seems to contain LCD cal type, */
@@ -1813,12 +1814,12 @@ i1disp_init_inst(inst *pp) {
if (p->log->debug >= 3) {
/* Dump all the register space */
- if (p->dtype < 2) {
+ if (p->btype < 2) {
unsigned char buf[0x200];
int i, len;
len = 128;
- if (p->dtype != 0)
+ if (p->btype != 0)
len = 160;
for (i = 0; i < len; i++) {
@@ -1985,11 +1986,11 @@ static inst_code i1disp_get_n_a_cals(inst *pp, inst_cal_type *pn_cals, inst_cal_
inst_cal_type n_cals = inst_calt_none;
inst_cal_type a_cals = inst_calt_none;
- if (p->dtype == 0) { /* Eye-One Display 1 */
+ if (p->btype == 0) { /* Eye-One Display 1 */
a_cals |= inst_calt_emis_offset;
}
- if (p->dtype == 1 && p->refrmode != 0) {
+ if (p->btype == 1 && p->refrmode != 0) {
if (p->rrset == 0)
n_cals |= inst_calt_ref_freq;
a_cals |= inst_calt_ref_freq;
@@ -2015,7 +2016,7 @@ inst_code i1disp_calibrate(
inst *pp,
inst_cal_type *calt, /* Calibration type to do/remaining */
inst_cal_cond *calc, /* Current condition/desired condition */
-inst_calc_id_type *idtype, /* Condition identifier type */
+inst_calc_id_type *btype, /* Condition identifier type */
char id[CALIDLEN] /* Condition identifier (ie. white reference ID) */
) {
i1disp *p = (i1disp *)pp;
@@ -2027,7 +2028,7 @@ char id[CALIDLEN] /* Condition identifier (ie. white reference ID) */
if (!p->inited)
return inst_no_init;
- *idtype = inst_calc_id_none;
+ *btype = inst_calc_id_none;
id[0] = '\000';
if ((ev = i1disp_get_n_a_cals((inst *)p, &needed, &available)) != inst_ok)
@@ -2056,7 +2057,7 @@ char id[CALIDLEN] /* Condition identifier (ie. white reference ID) */
}
/* Do the appropriate calibration */
- if (p->dtype == 0) { /* Eye-One Display 1 */
+ if (p->btype == 0) { /* Eye-One Display 1 */
if (*calt & inst_calt_emis_offset) {
if ((*calc & inst_calc_cond_mask) != inst_calc_man_ref_dark) {
@@ -2284,7 +2285,7 @@ inst3_capability *pcap3) {
/* i1D2 has refresh display & ambient capability */
/* but i1D1 & ColorMunki Smile don't */
- if (p->dtype == 1) {
+ if (p->btype == 1) {
cap1 |= inst_mode_emis_ambient
| inst_mode_emis_refresh_ovd
| inst_mode_emis_norefresh_ovd
@@ -2322,7 +2323,7 @@ static inst_code i1disp_check_mode(inst *pp, inst_mode m) {
/* Only display emission mode supported */
if (!IMODETST(m, inst_mode_emis_spot)
- && !(p->dtype == 1 && IMODETST(m, inst_mode_emis_ambient))) {
+ && !(p->btype == 1 && IMODETST(m, inst_mode_emis_ambient))) {
return inst_unsupported;
}
@@ -2410,7 +2411,7 @@ static inst_disptypesel smile_disptypesel[3] = {
static void set_base_disptype_list(i1disp *p) {
/* set the base display type list */
- if (p->itype == instSmile) {
+ if (p->dtype == instSmile) {
p->_dtlist = smile_disptypesel;
} else {
p->_dtlist = i1disp_disptypesel;
@@ -2632,7 +2633,7 @@ i1disp_get_set_opt(inst *pp, inst_opt_type m, ...) {
}
/* Constructor */
-extern i1disp *new_i1disp(icoms *icom, instType itype) {
+extern i1disp *new_i1disp(icoms *icom, instType dtype) {
i1disp *p;
@@ -2663,13 +2664,13 @@ extern i1disp *new_i1disp(icoms *icom, instType itype) {
p->del = i1disp_del;
p->icom = icom;
- p->itype = itype;
+ p->dtype = dtype;
- if (p->itype == instI1Disp2)
- p->dtype = 1; /* i1Display2 */
+ if (p->dtype == instI1Disp2)
+ p->btype = 1; /* i1Display2 */
- else if (p->itype == instSmile) {
- p->dtype = 2; /* Smile */
+ else if (p->btype == instSmile) {
+ p->btype = 2; /* Smile */
}
icmSetUnity3x3(p->ccmat); /* Set the colorimeter correction matrix to do nothing */
diff --git a/spectro/i1disp.h b/spectro/i1disp.h
index eada827..61423b7 100644..100755
--- a/spectro/i1disp.h
+++ b/spectro/i1disp.h
@@ -78,6 +78,7 @@
/* Sub-type of instrument (i.e. based on vers, char code, unlock code) */
typedef enum {
+ i1d2_unkn = -1,
i1d2_norm = 0, /* Normal (i1d1, i1d2, Smile) */
i1d2_lite = 1, /* "Lite" */
i1d2_munki = 2, /* "Munk" */
@@ -88,15 +89,15 @@ typedef enum {
i1d1_sencoreIII = 7, /* Sencore ColorPro III */
i1d1_sencoreIV = 8, /* Sencore ColorPro IV */
i1d1_sencoreV = 9 /* Sencore ColorPro V */
-} i1d2_dtype;
+} i1d2_stype;
/* I1DISP communication object */
struct _i1disp {
INST_OBJ_BASE
- int dtype; /* Device type: 0 = i1D1, 1 = i1D2, 2 = Smile */
- i1d2_dtype stype; /* Sub type */
+ int btype; /* Device type: 0 = i1D1, 1 = i1D2, 2 = Smile */
+ i1d2_stype stype; /* Sub type */
inst_mode mode; /* Currently selected mode */
diff --git a/spectro/i1pro.c b/spectro/i1pro.c
index 44614d2..4399c57 100644..100755
--- a/spectro/i1pro.c
+++ b/spectro/i1pro.c
@@ -64,6 +64,7 @@
#include "numsup.h"
#include "rspl1.h"
#endif /* SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -140,15 +141,15 @@ i1pro_determine_capabilities(i1pro *p) {
;
/* Set the Pro capabilities mask */
- if (p->itype == instI1Pro
- || p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro
+ || p->dtype == instI1Pro2) {
p->cap |= inst_mode_ref_spot
| inst_mode_ref_strip
;
}
/* Set the Pro2 capabilities mask */
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
p->cap |= inst_mode_ref_uv
;
}
@@ -911,7 +912,7 @@ i1pro_del(inst *pp) {
}
/* Constructor */
-extern i1pro *new_i1pro(icoms *icom, instType itype) {
+extern i1pro *new_i1pro(icoms *icom, instType dtype) {
i1pro *p;
int rv;
if ((p = (i1pro *)calloc(sizeof(i1pro),1)) == NULL) {
@@ -940,7 +941,7 @@ extern i1pro *new_i1pro(icoms *icom, instType itype) {
p->del = i1pro_del;
p->icom = icom;
- p->itype = itype;
+ p->dtype = dtype;
i1pro_determine_capabilities(p);
diff --git a/spectro/i1pro.h b/spectro/i1pro.h
index e449f2c..378dc30 100644..100755
--- a/spectro/i1pro.h
+++ b/spectro/i1pro.h
@@ -45,7 +45,7 @@
struct _i1pro {
INST_OBJ_BASE
- int dtype; /* Device type: 0 = ?? */
+ int idtype; /* Device type: 0 = ?? */
/* *** i1pro private data **** */
inst_mode cap; /* Instrument mode capability */
diff --git a/spectro/i1pro_imp.c b/spectro/i1pro_imp.c
index a8cb9e0..03f0a0d 100644..100755
--- a/spectro/i1pro_imp.c
+++ b/spectro/i1pro_imp.c
@@ -92,6 +92,7 @@
#include "numsup.h"
#include "rspl1.h"
#endif /* SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -372,7 +373,7 @@ void del_i1proimp(i1pro *p) {
i1pro_state *s;
i1pro_code ev;
- if (p->itype != instI1Pro2 && (ev = i1pro_update_log(p)) != I1PRO_OK) {
+ if (p->dtype != instI1Pro2 && (ev = i1pro_update_log(p)) != I1PRO_OK) {
a1logd(p->log,2,"i1pro_update_log: Updating the cal and log parameters to"
" EEProm failed failed\n");
}
@@ -458,7 +459,7 @@ i1pro_code i1pro_imp_init(i1pro *p) {
a1logd(p->log,5,"i1pro_init:\n");
m->native_calstd = xcalstd_gmdi; /* Rev A-D */
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
m->native_calstd = xcalstd_xrga; /* Rev E */
}
m->target_calstd = xcalstd_native; /* Default to native calibration */
@@ -474,17 +475,17 @@ i1pro_code i1pro_imp_init(i1pro *p) {
}
/* Revert to i1pro if i1pro2 driver is not enabled */
- if (p->itype == instI1Pro2
+ if (p->dtype == instI1Pro2
#ifdef ENABLE_2
&& getenv("ARGYLL_DISABLE_I1PRO2_DRIVER") != NULL /* Disabled by environment */
#endif
) {
- p->itype = instI1Pro;
+ p->dtype = instI1Pro;
}
- if (p->itype != instI1Monitor
- && p->itype != instI1Pro
- && p->itype != instI1Pro2)
+ if (p->dtype != instI1Monitor
+ && p->dtype != instI1Pro
+ && p->dtype != instI1Pro2)
return I1PRO_UNKNOWN_MODEL;
m->trig = inst_opt_trig_user;
@@ -513,14 +514,14 @@ i1pro_code i1pro_imp_init(i1pro *p) {
return ev;
a1logd(p->log,2,"Firmware rev = %d, max +ve value = 0x%x\n",m->fwrev, m->maxpve);
- if (p->itype == instI1Pro2 && m->fwrev < 600) { /* Hmm */
+ if (p->dtype == instI1Pro2 && m->fwrev < 600) { /* Hmm */
a1logd(p->log,2, "Strange, firmware isn't up to i1pro2 but has extra pipe..revert to i1pro driver\n",m->fwrev);
- p->itype = instI1Pro;
+ p->dtype = instI1Pro;
}
/* Get the EEProm size */
m->eesize = 8192; /* Rev A..D */
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
#ifdef NEVER
// ~~99 Hmm. makes it worse. Why ???
// /* Make sure LED sequence is finished, because it interferes with EEProm read! */
@@ -550,7 +551,7 @@ i1pro_code i1pro_imp_init(i1pro *p) {
return ev;
}
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
/* Get the Chip ID (This doesn't work until after reading the EEProm !) */
if ((ev = i1pro2_getchipid(p, m->chipid)) != I1PRO_OK) {
free(eeprom);
@@ -565,7 +566,7 @@ i1pro_code i1pro_imp_init(i1pro *p) {
}
/* Parse the i1pro2 extra data */
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
if ((ev = m->data->parse_eeprom(m->data, eeprom, m->eesize, 1)) != I1PRO_OK) {
free(eeprom);
return ev;
@@ -624,7 +625,7 @@ i1pro_code i1pro_imp_init(i1pro *p) {
m->nsen = 128;
m->nraw = 128;
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
int clkusec, subdiv, xraw, nraw;
if ((ev = i1pro2_getmeaschar(p, &clkusec, &xraw, &nraw, &subdiv)) != I1PRO_OK)
return ev;
@@ -685,7 +686,7 @@ i1pro_code i1pro_imp_init(i1pro *p) {
m->min_int_time = dp[0];
/* And then override it */
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
m->min_int_time = m->subclkdiv2 * m->intclkp2; /* 0.004896 */
} else {
if (m->fwrev >= 301)
@@ -716,7 +717,7 @@ i1pro_code i1pro_imp_init(i1pro *p) {
if ((m->white_ref[0] = m->data->get_doubles(m->data, &count, key_white_ref)) == NULL
|| count != m->nwav[0]) {
- if (p->itype != instI1Monitor)
+ if (p->dtype != instI1Monitor)
return I1PRO_HW_CALIBINFO;
m->white_ref[0] = NULL;
}
@@ -727,7 +728,7 @@ i1pro_code i1pro_imp_init(i1pro *p) {
if ((m->amb_coef[0] = m->data->get_doubles(m->data, &count, key_amb_coef)) == NULL
|| count != m->nwav[0]) {
- if (p->itype != instI1Monitor
+ if (p->dtype != instI1Monitor
&& m->capabilities & 0x6000) /* Expect ambient calibration */
return I1PRO_HW_CALIBINFO;
m->amb_coef[0] = NULL;
@@ -799,7 +800,7 @@ i1pro_code i1pro_imp_init(i1pro *p) {
}
/* Read Rev E specific keys */
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
int i, j;
double *dp;
int *sip;
@@ -1001,7 +1002,7 @@ i1pro_code i1pro_imp_init(i1pro *p) {
s->dark_int_time4 = DISP_INTT4; /* 0.1 */
s->idark_int_time[0] = s->idark_int_time[2] = m->min_int_time;
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
s->idark_int_time[1] = s->idark_int_time[3] = ADARKINT_MAX2; /* 4.0 */
} else {
#ifdef USE_HIGH_GAIN_MODE
@@ -1242,8 +1243,8 @@ i1pro_code i1pro_imp_init(i1pro *p) {
}
}
- if (p->itype != instI1Monitor /* Monitor doesn't have reflective cal */
- && p->itype != instI1Pro2) { /* Rev E mode has different calibration */
+ if (p->dtype != instI1Monitor /* Monitor doesn't have reflective cal */
+ && p->dtype != instI1Pro2) { /* Rev E mode has different calibration */
/* Restore the previous reflective spot calibration from the EEProm */
/* Get ready to operate the instrument */
if ((ev = i1pro_restore_refspot_cal(p)) != I1PRO_OK)
@@ -1266,11 +1267,11 @@ i1pro_code i1pro_imp_init(i1pro *p) {
return ev;
if (p->log->verb >= 1) {
- a1logv(p->log,1,"Instrument Type: %s\n",inst_name(p->itype));
+ a1logv(p->log,1,"Instrument Type: %s\n",inst_name(p->dtype));
a1logv(p->log,1,"Serial Number: %d\n",m->serno);
a1logv(p->log,1,"Firmware version: %d\n",m->fwrev);
a1logv(p->log,1,"CPLD version: %d\n",m->cpldrev);
- if (p->itype == instI1Pro2)
+ if (p->dtype == instI1Pro2)
a1logv(p->log,1,"Chip ID: %02x-%02x%02x%02x%02x%02x%02x%02x\n",
m->chipid[0], m->chipid[1], m->chipid[2], m->chipid[3],
m->chipid[4], m->chipid[5], m->chipid[6], m->chipid[7]);
@@ -1290,7 +1291,7 @@ i1pro_code i1pro_imp_init(i1pro *p) {
#ifdef NEVER
// ~~99 play with LED settings
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
/* Makes it white */
unsigned char b2[] = {
@@ -1355,7 +1356,7 @@ i1pro_code i1pro_imp_set_mode(
switch(mmode) {
case i1p_refl_spot:
case i1p_refl_scan:
- if (p->itype == instI1Monitor)
+ if (p->dtype == instI1Monitor)
return I1PRO_INT_ILLEGALMODE; /* i1Monitor can't do reflection */
break;
case i1p_emiss_spot_na:
@@ -1414,11 +1415,11 @@ i1pro_code i1pro_imp_get_n_a_cals(i1pro *p, inst_cal_type *pn_cals, inst_cal_typ
wl_valid = 0;
}
}
- if ((curtime - cs->iddate) > ((p->itype == instI1Pro2) ? DCALTOUT2 : DCALTOUT)) {
+ if ((curtime - cs->iddate) > ((p->dtype == instI1Pro2) ? DCALTOUT2 : DCALTOUT)) {
a1logd(p->log,2,"Invalidating adaptive dark cal as %d secs from last cal\n",curtime - cs->iddate);
idark_valid = 0;
}
- if ((curtime - cs->ddate) > ((p->itype == instI1Pro2) ? DCALTOUT2 : DCALTOUT)) {
+ if ((curtime - cs->ddate) > ((p->dtype == instI1Pro2) ? DCALTOUT2 : DCALTOUT)) {
a1logd(p->log,2,"Invalidating dark cal as %d secs from last cal\n",curtime - cs->ddate);
dark_valid = 0;
}
@@ -1486,7 +1487,7 @@ i1pro_code i1pro_imp_get_n_a_cals(i1pro *p, inst_cal_type *pn_cals, inst_cal_typ
&& m->hr_inited /* and hi-res has been setup */
&& (!m->emis_hr_cal || (n_cals & inst_calt_em_dark)) /* and the emis cal hasn't been */
/* fine tuned or we will be doing a dark cal */
- && p->itype != instI1Monitor) { /* i1Monitor doesn't have reflective cal capability */
+ && p->dtype != instI1Monitor) { /* i1Monitor doesn't have reflective cal capability */
n_cals |= inst_calt_ref_white; /* Need a reflective white calibration */
a_cals |= inst_calt_ref_white;
}
@@ -1833,7 +1834,7 @@ i1pro_code i1pro_imp_calibrate(
}
#ifdef USE_HIGH_GAIN_MODE
- if (p->itype != instI1Pro2) { /* Rev E doesn't have high gain mode */
+ if (p->dtype != instI1Pro2) { /* Rev E doesn't have high gain mode */
nummeas = i1pro_comp_nummeas(p, s->dcaltime, s->idark_int_time[2]);
a1logd(p->log,2,"Doing adaptive interpolated black calibration, dcaltime %f, idark_int_time[2] %f, nummeas %d, gainmode %d\n", s->dcaltime, s->idark_int_time[2], nummeas, 1);
if ((ev = i1pro_dark_measure(p, s->idark_data[2],
@@ -1883,7 +1884,7 @@ i1pro_code i1pro_imp_calibrate(
ss->dark_int_time = s->dark_int_time;
ss->dark_gain_mode = s->dark_gain_mode;
#ifdef USE_HIGH_GAIN_MODE
- for (j = 0; j < (p->itype != instI1Pro2) ? 4 : 2; j++)
+ for (j = 0; j < (p->dtype != instI1Pro2) ? 4 : 2; j++)
#else
for (j = 0; j < 2; j++)
#endif
@@ -1933,7 +1934,7 @@ i1pro_code i1pro_imp_calibrate(
#endif
#ifdef USE_HIGH_GAIN_MODE
- if (p->itype != instI1Pro2) { /* Rev E doesn't have high gain mode */
+ if (p->dtype != instI1Pro2) { /* Rev E doesn't have high gain mode */
// fprintf(stderr,"High gain offsets:\n");
// plot_raw(s->idark_data[2]);
// fprintf(stderr,"High gain multiplier:\n");
@@ -1993,7 +1994,7 @@ i1pro_code i1pro_imp_calibrate(
}
#ifdef USE_HIGH_GAIN_MODE
- if (p->itype != instI1Pro2) { /* Rev E doesn't have high gain mode */
+ if (p->dtype != instI1Pro2) { /* Rev E doesn't have high gain mode */
s->idark_int_time[2] = s->inttime;
nummeas = i1pro_comp_nummeas(p, s->dcaltime, s->idark_int_time[2]);
a1logd(p->log,2,"Doing adaptive scan black calibration, dcaltime %f, idark_int_time[2] %f, nummeas %d, gainmode %d\n", s->dcaltime, s->idark_int_time[2], nummeas, s->gainmode);
@@ -2043,7 +2044,7 @@ i1pro_code i1pro_imp_calibrate(
ss->dark_int_time = s->dark_int_time;
ss->dark_gain_mode = s->dark_gain_mode;
#ifdef USE_HIGH_GAIN_MODE
- for (j = 0; j < (p->itype != instI1Pro2) ? 4 : 2; j += 2)
+ for (j = 0; j < (p->dtype != instI1Pro2) ? 4 : 2; j += 2)
#else
for (j = 0; j < 2; j += 2)
#endif
@@ -2207,7 +2208,7 @@ i1pro_code i1pro_imp_calibrate(
m->mmode = mmode; /* Restore actual mode */
return ev;
}
- } else if (p->itype != instI1Pro2 && s->gainmode == 0 && scale > m->highgain) {
+ } else if (p->dtype != instI1Pro2 && s->gainmode == 0 && scale > m->highgain) {
#ifdef USE_HIGH_GAIN_MODE
a1logd(p->log,3,"Scan signal is so low we're switching to high gain mode\n");
s->gainmode = 1;
@@ -4218,7 +4219,7 @@ i1pro_code i1pro_save_calibration(i1pro *p) {
i1pnonv x;
int ss;
int argyllversion = ARGYLL_VERSION;
- int isRevE = p->itype == instI1Pro2 ? 1 : 0;
+ int isRevE = p->dtype == instI1Pro2 ? 1 : 0;
strcpy(nmode, "w");
#if !defined(O_CREAT) && !defined(_O_CREAT)
@@ -4230,7 +4231,8 @@ i1pro_code i1pro_save_calibration(i1pro *p) {
/* Create the file name */
sprintf(cal_name, "ArgyllCMS/.i1p_%d.cal", m->serno);
- if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_write, xdg_user, cal_name)) < 1) {
+ if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_write, xdg_user, xdg_none,
+ cal_name)) < 1) {
a1logd(p->log,1,"i1pro_save_calibration xdg_bds returned no paths\n");
return I1PRO_INT_CAL_SAVE;
}
@@ -4353,7 +4355,8 @@ i1pro_code i1pro_restore_calibration(i1pro *p) {
#endif
/* Create the file name */
sprintf(cal_name, "ArgyllCMS/.i1p_%d.cal" SSEPS "color/.i1p_%d.cal", m->serno, m->serno);
- if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_read, xdg_user, cal_name)) < 1) {
+ if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_read, xdg_user, xdg_none,
+ cal_name)) < 1) {
a1logd(p->log,2,"i1pro_restore_calibration xdg_bds failed to locate file'\n");
return I1PRO_INT_CAL_RESTORE;
}
@@ -4394,7 +4397,7 @@ i1pro_code i1pro_restore_calibration(i1pro *p) {
|| argyllversion != ARGYLL_VERSION
|| ss != (sizeof(i1pro_state) + sizeof(i1proimp))
|| serno != m->serno
- || isRevE != (p->itype == instI1Pro2 ? 1 : 0)
+ || isRevE != (p->dtype == instI1Pro2 ? 1 : 0)
|| nraw != m->nraw
|| nwav0 != m->nwav[0]
|| nwav1 != m->nwav[1]) {
@@ -4675,7 +4678,8 @@ i1pro_code i1pro_touch_calibration(i1pro *p) {
/* Locate the file name */
sprintf(cal_name, "ArgyllCMS/.i1p_%d.cal" SSEPS "color/.i1p_%d.cal", m->serno, m->serno);
- if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_read, xdg_user, cal_name)) < 1) {
+ if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_read, xdg_user, xdg_none,
+ cal_name)) < 1) {
a1logd(p->log,2,"i1pro_restore_calibration xdg_bds failed to locate file'\n");
return I1PRO_INT_CAL_TOUCH;
}
@@ -5822,7 +5826,7 @@ i1pro_trigger_one_measure(
*inttime = m->min_int_time;
/* The Rev E measure mode has it's own settings */
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
m->intclkp = m->intclkp2; /* From i1pro2_getmeaschar() ? */
m->subclkdiv = m->subclkdiv2;
m->subtmode = 0;
@@ -5892,7 +5896,7 @@ i1pro_trigger_one_measure(
/* Compute integration clocks */
dintclocks = floor(*inttime/m->intclkp + 0.5);
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
if (dintclocks > 4294967296.0) /* This is probably not the actual limit */
return I1PRO_INT_INTTOOBIG;
} else {
@@ -5926,7 +5930,7 @@ i1pro_trigger_one_measure(
if (gainmode == 0)
measmodeflags |= I1PRO_MMF_LOWGAIN; /* Normal gain mode */
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
measmodeflags2 = 0;
if (s->scan && !(mmodif & 0x20)) /* Never scan on a calibration */
measmodeflags2 |= I1PRO2_MMF_SCAN;
@@ -5958,7 +5962,7 @@ i1pro_trigger_one_measure(
#endif /* NEVER */
{
- if (p->itype != instI1Pro2) { /* Rev E sets the params in the measure command */
+ if (p->dtype != instI1Pro2) { /* Rev E sets the params in the measure command */
/* Set the hardware for measurement */
if ((ev = i1pro_setmeasparams(p, intclocks, lampclocks, nummeas, measmodeflags)) != I1PRO_OK)
return ev;
@@ -5988,7 +5992,7 @@ i1pro_trigger_one_measure(
/* Trigger a measurement */
usb_reinit_cancel(&m->rd_sync); /* Prepare to sync rd and trigger */
- if (p->itype != instI1Pro2) {
+ if (p->dtype != instI1Pro2) {
if ((ev = i1pro_triggermeasure(p, TRIG_DELAY)) != I1PRO_OK)
return ev;
} else {
@@ -7396,7 +7400,7 @@ void i1pro_sub_absraw(
/* black. It's not clear why it works best this way, or how */
/* dependent on the particular instrument the magic numbers are, */
/* but it reduces the black level error from over 10% to about 0.3% */
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
// double xx[NSEN_MAX], in[NSEN_MAX], res[NSEN_MAX];
double asub[NSEN_MAX];
double avgscell, zero;
@@ -7516,7 +7520,7 @@ void i1pro_absraw_to_abswav(
abswav[i][j] = tm[j] = oval;
}
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
/* Now apply stray light compensation */
/* For each output wavelength */
for (j = 0; j < m->nwav[highres]; j++) {
@@ -7613,7 +7617,7 @@ static double i1pro_raw2wav_uncal(i1pro *p, double raw) {
double ov;
int k;
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
raw = 128.0 - raw; /* Quadratic expects +ve correlation */
/* Compute polinomial */
@@ -7641,7 +7645,7 @@ static double i1pro_raw2wav(i1pro *p, int refl, double raw) {
double ov;
int k;
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
i1pro_state *s = &m->ms[m->mmode];
/* Correct for CCD offset and scale back to reference */
@@ -7980,6 +7984,7 @@ i1pro_code i1pro2_match_wl_meas(i1pro *p, double *pled_off, double *wlraw) {
/* at 550 nm. (see above), which amounts to about +0.026, leaving 0.2528 */
/* unexplained. It appears the CCD wavelength has a dependence on the */
/* angle that the light enters the optics ?? */
+ /* (- is it just a change in the spectrum shape ??) */
led_off += 0.2528; /* Hack to make ambient cap correction == white tile correction */
@@ -8813,7 +8818,7 @@ i1pro_code i1pro_create_hr(i1pro *p) {
/* use the orginal filters to figure this out. */
if (m->raw2wav == NULL
#ifndef ANALIZE_EXISTING
- && p->itype != instI1Pro2
+ && p->dtype != instI1Pro2
#endif
) {
i1pro_fc coeff[100][16]; /* Existing filter cooefficients */
@@ -9418,7 +9423,7 @@ i1pro_code i1pro_create_hr(i1pro *p) {
trspl->del(trspl);
/* Upsample stray light */
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
#ifdef ONEDSTRAYLIGHTUS
double **slp; /* 2D Array of stray light values */
@@ -10727,7 +10732,7 @@ i1pro_code i1pro_optimise_sensor(
/* expected level is < target_level/gain */
/* Hmm. It may not be a good idea to use high gain mode if it compromises */
/* the longer integration time which reduces noise. */
- if (p->itype != instI1Pro2 && new_int_time > m->max_int_time && permithg) {
+ if (p->dtype != instI1Pro2 && new_int_time > m->max_int_time && permithg) {
new_int_time /= m->highgain;
new_gain_mode = 1;
a1logd(p->log,3,"Switching to high gain mode\n");
@@ -10810,7 +10815,7 @@ i1pro_prepare_idark(
/* Compute base */
s->idark_data[i+0][j] = d01 - s->idark_data[i+1][j] * s->idark_int_time[i+0];
}
- if (p->itype == instI1Pro2) /* Rev E doesn't have high gain mode */
+ if (p->dtype == instI1Pro2) /* Rev E doesn't have high gain mode */
break;
}
}
@@ -10928,7 +10933,7 @@ i1pro_reset(
pbuf[0] = mask;
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
pbuf[1] = 0; /* Not known what i1pro2 second byte is for */
len = 2;
}
@@ -10978,7 +10983,7 @@ i1pro_readEEProm(
short2buf(&pbuf[4], size);
pbuf[6] = pbuf[7] = 0; /* Ignored */
- if (p->itype == instI1Pro2)
+ if (p->dtype == instI1Pro2)
len = 6;
se = p->icom->usb_control(p->icom,
@@ -11066,7 +11071,7 @@ i1pro_writeEEProm(
short2buf(&pbuf[4], size);
short2buf(&pbuf[6], 0x100); /* Might be accidental, left over from getmisc.. */
- if (p->itype == instI1Pro2)
+ if (p->dtype == instI1Pro2)
len = 6;
se = p->icom->usb_control(p->icom,
@@ -12112,7 +12117,7 @@ i1pro2_indLEDoff(void *pp) {
#ifdef NEVER
// ~~99 play with LED settings
- if (p->itype == instI1Pro2) {
+ if (p->dtype == instI1Pro2) {
// LED is capable of white and red
@@ -12927,7 +12932,7 @@ static i1_dtype i1data_det_type(i1data *d, i1key key) {
if (key < 0x100)
return i1_dtype_section;
- switch(key) {
+ switch((int)key) {
/* Log keys */
case key_meascount:
case key_meascount + 1000:
diff --git a/spectro/i1pro_imp.h b/spectro/i1pro_imp.h
index 582cc98..582cc98 100644..100755
--- a/spectro/i1pro_imp.h
+++ b/spectro/i1pro_imp.h
diff --git a/spectro/icoms.c b/spectro/icoms.c
index eadecc9..875f3b6 100644..100755
--- a/spectro/icoms.c
+++ b/spectro/icoms.c
@@ -35,12 +35,16 @@
#include "sa_config.h"
#endif
#include "numsup.h"
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
#include "icoms.h"
+icom_type dev_category(instType itype);
+int serial_get_paths(icompaths *p, icom_type mask);
+
/* ----------------------------------------------------- */
/* Fake display & instrument device */
@@ -118,24 +122,32 @@ static icompath *icompaths_get_path(
/* Return the device path corresponding to the port number, or NULL if out of range */
static icompath *icompaths_get_path_sel(
icompaths *p,
- icom_type dctype, /* Device type list */
+ icom_dtix dtix, /* Device type list */
int port /* Enumerated port number, 1..n */
) {
/* Check it is an enumeration */
- if (dctype != dtix_combined
- && dctype != dtix_inst
- && dctype != dtix_3dlut
- && dctype != dtix_vtpg
- && dctype != dtix_printer)
+ if (dtix != dtix_combined
+ && dtix != dtix_inst
+ && dtix != dtix_3dlut
+ && dtix != dtix_vtpg
+ && dtix != dtix_printer
+ && dtix != dtix_cmfm) {
+//printf("~1 unrec index\n");
return NULL;
+ }
- if (dctype == dtix_inst)
+ if (dtix == dtix_inst) {
+//printf("~1 inst\n");
return icompaths_get_path(p, port);
+ }
- if (port <= 0 || port > p->ndpaths[dctype])
+ if (port <= 0 || port > p->ndpaths[dtix]) {
+//printf("~1 port %d out of range %d - %d\n", port,0, p->ndpaths[dtix]);
return NULL;
+ }
- return p->dpaths[dctype][port-1];
+//printf("~1 OK index for port %d\n",port);
+ return p->dpaths[dtix][port-1];
}
/* Clear a single device paths list */
@@ -172,6 +184,7 @@ static void icompaths_clear_all(icompaths *p) {
icompaths_clear(p, dtix_3dlut);
icompaths_clear(p, dtix_vtpg);
icompaths_clear(p, dtix_printer);
+ icompaths_clear(p, dtix_cmfm);
icompaths_clear(p, dtix_combined);
}
@@ -183,7 +196,7 @@ static int icompaths_add_path(icompaths *p, int ix, icompath *xp) {
if (xp == NULL)
ix = dtix_combined;
if (p->dpaths[ix] == NULL) {
- if ((p->dpaths[ix] = (icompath **)calloc(sizeof(icompath *), 1 + 1)) == NULL) {
+ if ((p->dpaths[ix] = (icompath **)calloc(1 + 1, sizeof(icompath *))) == NULL) {
a1loge(p->log, ICOM_SYS, "icompaths: calloc failed!\n");
return ICOM_SYS;
}
@@ -198,7 +211,7 @@ static int icompaths_add_path(icompaths *p, int ix, icompath *xp) {
p->dpaths[ix][p->ndpaths[ix]+1] = NULL;
}
if (xp == NULL) {
- if ((xp = calloc(sizeof(icompath), 1)) == NULL) {
+ if ((xp = calloc(1, sizeof(icompath))) == NULL) {
a1loge(p->log, ICOM_SYS, "icompaths: malloc failed!\n");
return ICOM_SYS;
}
@@ -227,7 +240,7 @@ int icompaths_make_dslists(icompaths *p) {
if ((rv = icompaths_add_path(p, dtix_inst, xp)) != ICOM_OK)
return rv;
}
- if (xp->dctype & icomt_3dlut) {
+ if (xp->dctype & icomt_v3dlut) {
if ((rv = icompaths_add_path(p, dtix_3dlut, xp)) != ICOM_OK)
return rv;
}
@@ -239,6 +252,10 @@ int icompaths_make_dslists(icompaths *p) {
if ((rv = icompaths_add_path(p, dtix_printer, xp)) != ICOM_OK)
return rv;
}
+ if (xp->dctype & icomt_cmfm) {
+ if ((rv = icompaths_add_path(p, dtix_cmfm, xp)) != ICOM_OK)
+ return rv;
+ }
}
/* Maintain backwards compatible instrument list alias */
@@ -289,9 +306,9 @@ int icompaths_set_serial_itype(icompath *p, devType itype) {
char pname[400], *cp;
/* Convert device type to category */
- p->dctype = (p->dctype & ~icomt_cat_mask) | inst_category(itype);
+ p->dctype = (p->dctype & ~icomt_cat_mask) | dev_category(itype);
- p->itype = itype;
+ p->dtype = itype;
/* Strip any existing description in brackets */
if ((cp = strchr(p->name, '(')) != NULL && cp > p->name)
@@ -330,13 +347,13 @@ int icompath_set_usb(a1log *log, icompath *p, char *name, unsigned int vid, unsi
a1logd(g_log, 8, "icompath_set_usb '%s' got dctype 0x%x\n",p->name,p->dctype);
p->dctype |= icomt_usb;
- p->dctype = (p->dctype & ~icomt_cat_mask) | inst_category(itype);
+ p->dctype = (p->dctype & ~icomt_cat_mask) | dev_category(itype);
p->nep = nep;
p->vid = vid;
p->pid = pid;
p->usbd = usbd;
- p->itype = itype;
+ p->dtype = itype;
a1logd(g_log, 8, "icompath_set_usb '%s' returning dctype 0x%x\n",p->name,p->dctype);
@@ -375,7 +392,7 @@ static int icompaths_add_hid(icompaths *p, char *name, unsigned int vid, unsigne
a1logd(g_log, 8, "icompaths_add_hid '%s' got dctype 0x%x\n",xp->name,xp->dctype);
xp->dctype |= icomt_hid;
- xp->dctype = (xp->dctype & ~icomt_cat_mask) | inst_category(itype);
+ xp->dctype = (xp->dctype & ~icomt_cat_mask) | dev_category(itype);
if ((xp->name = strdup(name)) == NULL) {
a1loge(p->log, ICOM_SYS, "icompaths: strdup failed!\n");
@@ -386,7 +403,7 @@ static int icompaths_add_hid(icompaths *p, char *name, unsigned int vid, unsigne
xp->vid = vid;
xp->pid = pid;
xp->hidd = hidd;
- xp->itype = itype;
+ xp->dtype = itype;
a1logd(g_log, 8, "icompath_set_usb '%s' returning dctype 0x%x\n",xp->name,xp->dctype);
@@ -398,20 +415,26 @@ static void icompaths_del(icompaths *p) {
if (p != NULL) {
icompaths_clear_all(p);
+ if (p->exlist != NULL) {
+ int i;
+ for (i = 0; i < p->exno; i++) {
+ if (p->exlist[i] != NULL)
+ free(p->exlist[i]);
+ }
+ free(p->exlist);
+ }
p->log = del_a1log(p->log); /* Unreference it and set to NULL */
free(p);
}
}
/* Create and return a list of available serial ports or USB devices for this system. */
-/* We look at the registry key "HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM" */
-/* to determine serial ports, and use libusb to discover USB devices. */
-/* return icom error */
+/* Return icom error */
int icompaths_refresh_paths_sel(icompaths *p, icom_type mask) {
int rv, usbend = 0;
int i, j;
- a1logd(p->log, 7, "icoms_refresh_paths: called with mask = %d\n",mask);
+ a1logd(p->log, 7, "icoms_refresh_paths: called with mask = 0x%x\n",mask);
/* Clear any existing device paths */
p->clear(p);
@@ -451,9 +474,9 @@ int icompaths_refresh_paths_sel(icompaths *p, icom_type mask) {
for (i = usbend; i < (np-1); i++) {
for (j = i+1; j < np; j++) {
- if ((pl[i]->itype == instUnknown && pl[j]->itype != instUnknown)
- || (((pl[i]->itype == instUnknown && pl[j]->itype == instUnknown)
- || (pl[i]->itype != instUnknown && pl[j]->itype != instUnknown))
+ if ((pl[i]->dtype == instUnknown && pl[j]->dtype != instUnknown)
+ || (((pl[i]->dtype == instUnknown && pl[j]->dtype == instUnknown)
+ || (pl[i]->dtype != instUnknown && pl[j]->dtype != instUnknown))
&& strcmp(pl[i]->name, pl[j]->name) > 0)) {
icompath *tt = pl[i];
pl[i] = pl[j];
@@ -501,12 +524,91 @@ int icompaths_refresh_paths(icompaths *p) {
return icompaths_refresh_paths_sel(p, icomt_instrument | icomt_portattr_all);
}
+static int create_fserexcl(icompaths *p) {
+ char *envv;
+
+ p->exno = 0;
+
+ /* Get the exclusion list */
+ if ((envv = getenv("ARGYLL_EXCLUDE_SERIAL_SCAN")) != NULL) {
+ char *cp, *pcp;
+
+ /* Count the number of strings */
+ for (cp = envv;; cp++) {
+ if (*cp == ';'
+ || *cp == ','
+ || *cp == '\000')
+ p->exno++;
+ if (*cp == '\000')
+ break;
+ }
+
+ if ((p->exlist = (char **)calloc(p->exno, sizeof(char *))) == NULL) {
+ a1logd(p->log, 1, "create_fserexcl: calloc failed!\n");
+ return 1;
+ }
+
+ /* Copy strings to array */
+ p->exno = 0;
+ for (pcp = cp = envv;; cp++) {
+ if (*cp == ';'
+ || *cp == ','
+ || *cp == '\000') {
+
+ if (cp - pcp > 0) {
+ if ((p->exlist[p->exno] = (char *)calloc(cp - pcp +1, sizeof(char))) == NULL) {
+ a1logd(p->log, 1, "create_fserexcl: calloc failed!\n");
+ return 1;
+ }
+ memmove(p->exlist[p->exno], pcp, cp - pcp);
+ p->exlist[p->exno][cp - pcp] = '\000';
+ p->exno++;
+ }
+ pcp = cp + 1;
+ }
+ if (*cp == '\000')
+ break;
+ }
+
+#ifdef NEVER
+ printf("Exclusion list len %d =\n",p->exno);
+ for (i = 0; i < p->exno; i++)
+ printf(" '%s'\n",p->exlist[i]);
+#endif
+ }
+ return 0;
+}
+
+/* Return nz if the given path is on the fast serial scan */
+/* exclusion list */
+static int icompaths_fs_excluded(icompaths *p, icompath *path) {
+
+ a1logd(p->log, 5, "fs_excluded check '%s'\n",path->spath);
+
+#if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL)
+ if (p->exlist != NULL) {
+ int i;
+
+ for (i = 0; i < p->exno; i++) {
+ if (strcmp(p->exlist[i], path->spath) == 0) {
+ a1logd(p->log, 5, "excluding '%s' from fast scan\n",path->spath);
+ return 1;
+ }
+ }
+ }
+#endif
+ return 0;
+}
+
/* Allocate an icom paths and set it to the list of available devices */
/* that match the icom_type mask. */
/* Return NULL on error */
icompaths *new_icompaths_sel(a1log *log, icom_type mask) {
icompaths *p;
- if ((p = (icompaths *)calloc(sizeof(icompaths), 1)) == NULL) {
+
+ a1logd(log, 3, "new_icompath: called with mask 0x%x\n",mask);
+
+ if ((p = (icompaths *)calloc(1, sizeof(icompaths))) == NULL) {
a1loge(log, ICOM_SYS, "new_icompath: calloc failed!\n");
return NULL;
}
@@ -521,7 +623,9 @@ icompaths *new_icompaths_sel(a1log *log, icom_type mask) {
p->del = icompaths_del;
/* ====== internal implementation ======= */
+
#if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL)
+ p->fs_excluded = icompaths_fs_excluded;
p->add_serial = icompaths_add_serial;
#endif /* ENABLE_SERIAL */
#ifdef ENABLE_USB
@@ -532,6 +636,9 @@ icompaths *new_icompaths_sel(a1log *log, icom_type mask) {
p->get_last_path = icompaths_get_last_path;
/* ====================================== */
+ /* Get list of fast scan exclusion devices */
+ create_fserexcl(p);
+
if (icompaths_refresh_paths_sel(p, mask)) {
a1loge(log, ICOM_SYS, "new_icompaths: icompaths_refresh_paths failed!\n");
free(p);
@@ -581,7 +688,7 @@ static int icom_copy_path_to_icom(icoms *p, icompath *pp) {
return rv;
#endif
p->dctype = pp->dctype;
- p->itype = pp->itype;
+ p->dtype = pp->dtype;
a1logd(g_log, 8, "icom_copy_path_to_icom '%s' returning dctype 0x%x\n",p->name,p->dctype);
@@ -671,14 +778,20 @@ int frbw /* nz to Flush Read Before Write */
/* Return error if coms */
if (rv != ICOM_OK) {
- a1logd(p->log, 8, "icoms_write_read: failed - returning 0x%x\n",rv);
+ if (rv & ICOM_TO)
+ a1logd(p->log, 8, "icoms_write_read: write T.O. %f sec. returning 0x%x\n",tout, rv);
+ else
+ a1logd(p->log, 8, "icoms_write_read: write failed - returning 0x%x\n",rv);
return rv;
}
/* Read response */
rv = p->read(p, rbuf, bsize, bread, tc, ntc, tout);
- a1logd(p->log, 8, "icoms_write_read: returning 0x%x\n",rv);
+ if (rv & ICOM_TO)
+ a1logd(p->log, 8, "icoms_write_read: read T.O. %f sec. returning 0x%x\n",tout, rv);
+ else
+ a1logd(p->log, 8, "icoms_write_read: read returning 0x%x\n",rv);
return rv;
}
@@ -739,9 +852,9 @@ icoms *new_icoms(
) {
icoms *p;
- a1logd(log, 2, "new_icoms '%s' itype '%s' dctype 0x%x\n",ipath->name,inst_sname(ipath->itype),ipath->dctype);
+ a1logd(log, 2, "new_icoms '%s' itype '%s' dctype 0x%x\n",ipath->name,inst_sname(ipath->dtype),ipath->dctype);
- if ((p = (icoms *)calloc(sizeof(icoms), 1)) == NULL) {
+ if ((p = (icoms *)calloc(1, sizeof(icoms))) == NULL) {
a1loge(log, ICOM_SYS, "new_icoms: calloc failed!\n");
return NULL;
}
@@ -750,7 +863,7 @@ icoms *new_icoms(
a1loge(log, ICOM_SYS, "new_icoms: strdup failed!\n");
return NULL;
}
- p->itype = ipath->itype;
+ p->dtype = ipath->dtype;
/* Copy ipath info to this icoms */
if (icom_copy_path_to_icom(p, ipath)) {
@@ -857,6 +970,8 @@ char *baud_rate_to_str(baud_rate br) {
return "57600";
case baud_115200:
return "115200";
+ case baud_230400:
+ return "230400";
case baud_921600:
return "921600";
}
diff --git a/spectro/icoms.h b/spectro/icoms.h
index be36cac..4e18b62 100644..100755
--- a/spectro/icoms.h
+++ b/spectro/icoms.h
@@ -55,11 +55,12 @@ typedef enum {
/* Category of device */
icomt_instrument = 0x010000, /* Color measurement instrument (default) */
- icomt_3dlut = 0x020000, /* A 3D cLUT box */
- icomt_vtpg = 0x040000, /* A video test patern generator box */
+ icomt_v3dlut = 0x020000, /* A Video 3D cLUT box */
+ icomt_vtpg = 0x040000, /* A Video test patern generator box */
icomt_printer = 0x080000, /* A printing device */
+ icomt_cmfm = 0x100000, /* A CMF Measuring device */
- icomt_cat_any = 0x0f0000, /* Could be any device category */
+ icomt_cat_any = 0x1f0000, /* Could be any device category */
icomt_cat_mask = 0xff0000, /* Mask for device category */
/* Type of underlying communication port */
@@ -68,6 +69,7 @@ typedef enum {
icomt_usb = 0x000002, /* USB port */
icomt_hid = 0x000004, /* HID USB port */
icomt_bt = 0x000008, /* Bluetooth (non-serial) */
+// icomt_net = 0x000010, /* Network Connected */
icomt_port_mask = 0x0000ff, /* Mask for port type */
@@ -83,7 +85,6 @@ typedef enum {
icomt_portattr_all = icomt_portattr_mask /* Scan for all port types */
-
} icom_type;
/* Status bits/return values */
@@ -145,9 +146,9 @@ typedef struct {
/* - - - - - - - - - - - - - - - - - - - - */
/* Store information about a possible instrument communication path */
-/* (Note a path doesn't have a reference to icompaths or its' log) */
+/* (Note a path doesn't have a reference to icompaths or its log) */
struct _icompath {
- devType itype; /* Type of device if known */
+ devType dtype; /* Type of device if known */
char *name; /* instance description */
icom_type dctype; /* Device and com. type */
@@ -171,6 +172,7 @@ typedef enum {
dtix_3dlut,
dtix_vtpg,
dtix_printer,
+ dtix_cmfm,
dtix_number /* Number of entries */
} icom_dtix;
@@ -209,7 +211,7 @@ struct _icompaths {
/* Return the device path corresponding to the port number, or NULL if out of range */
icompath *(*get_path_sel)(
struct _icompaths *p,
- icom_type dctype, /* Device type list */
+ icom_dtix dtix, /* Device type list */
int port); /* Enumerated port number, 1..n */
/* Clear all the device paths */
@@ -220,7 +222,14 @@ struct _icompaths {
/* ====== internal implementation ======= */
+ /* Fast serial scan exclusion list - from ARGYLL_EXCLUDE_SERIAL_SCAN env. var. */
+ int exno;
+ char **exlist;
+
#if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL)
+ /* Return nz if the serial port is on the fast serial scan exclusion list */
+ int (*fs_excluded)(struct _icompaths *p, struct _icompath *path);
+
/* Add a serial path to combined. path is copied. Return icom error */
int (*add_serial)(struct _icompaths *p, char *name, char *spath, icom_type dctype);
#endif /* ENABLE_SERIAL */
@@ -228,11 +237,11 @@ struct _icompaths {
#ifdef ENABLE_USB
/* Add a usb path to combined. usbd is taken, others are copied. Return icom error */
int (*add_usb)(struct _icompaths *p, char *name, unsigned int vid, unsigned int pid,
- int nep, struct usb_idevice *usbd, devType itype);
+ int nep, struct usb_idevice *usbd, devType dtype);
/* Add an hid path to combined. hidd is taken, others are copied. Return icom error */
int (*add_hid)(struct _icompaths *p, char *name, unsigned int vid, unsigned int pid,
- int nep, struct hid_idevice *hidd, devType itype);
+ int nep, struct hid_idevice *hidd, devType dtype);
#endif /* ENABLE_USB */
/* Delete the last combined path */
@@ -279,7 +288,8 @@ typedef enum {
baud_38400 = 10,
baud_57600 = 11,
baud_115200 = 12,
- baud_921600 = 13
+ baud_230400 = 13,
+ baud_921600 = 14
} baud_rate;
char *baud_rate_to_str(baud_rate br);
@@ -327,7 +337,7 @@ struct _icoms {
/* Copy of some of icompath contents: */
icom_type dctype; /* Device cat. and com. type */
- devType itype; /* Type of device if known */
+ devType dtype; /* Type of device if known */
char *name; /* Device description */
diff --git a/spectro/icoms_nt.c b/spectro/icoms_nt.c
index b9e0d0c..39ff6f0 100644..100755
--- a/spectro/icoms_nt.c
+++ b/spectro/icoms_nt.c
@@ -18,7 +18,7 @@
#include <conio.h>
-instType fast_ser_inst_type(icoms *p, int tryhard, void *, void *);
+devType fast_ser_dev_type(icoms *p, int tryhard, void *, void *);
/* Add paths to serial connected device. */
/* Return an icom error */
@@ -128,12 +128,14 @@ int serial_get_paths(icompaths *p, icom_type mask) {
icoms *icom;
if ((path = p->get_last_path(p)) != NULL
&& (icom = new_icoms(path, p->log)) != NULL) {
- devType itype = fast_ser_inst_type(icom, 0, NULL, NULL);
- if (itype != instUnknown)
- icompaths_set_serial_itype(path, itype); /* And set category */
+ if (!p->fs_excluded(p, path)) {
+ devType itype = fast_ser_dev_type(icom, 0, NULL, NULL);
+ if (itype != instUnknown)
+ icompaths_set_serial_itype(path, itype); /* And set category */
+ }
icom->del(icom);
}
- a1logd(p->log, 8, "serial_get_paths: Identified '%s' dctype 0x%x\n",inst_sname(path->itype),path->dctype);
+ a1logd(p->log, 8, "serial_get_paths: Identified '%s' dctype 0x%x\n",inst_sname(path->dtype),path->dctype);
}
}
if ((stat = RegCloseKey(sch)) != ERROR_SUCCESS) {
@@ -163,6 +165,15 @@ void serial_close_port(icoms *p) {
/* -------------------------------------------------------------------- */
+#ifndef CBR_230400
+# define CBR_230400 230400
+#endif
+#ifndef CBR_460800
+# define CBR_460800 460800
+#endif
+#ifndef CBR_512000
+# define CBR_512000 512000
+#endif
#ifndef CBR_921600
# define CBR_921600 921600
#endif
@@ -190,10 +201,12 @@ int delayms) { /* Delay after open in msec */
" Open delay = %d ms\n"
,p->name ,fc ,baud_rate_to_str(baud) ,parity ,stop ,word, delayms);
+#ifdef NEVER /* Is this needed ? */
if (p->is_open) {
a1logd(p->log, 8, "icoms_set_ser_port: closing port '%s'\n",p->name);
p->close_port(p);
}
+#endif
if (p->port_type(p) == icomt_serial) {
DCB dcb;
@@ -386,6 +399,9 @@ int delayms) { /* Delay after open in msec */
case baud_115200:
dcb.BaudRate = CBR_115200;
break;
+ case baud_230400:
+ dcb.BaudRate = CBR_230400;
+ break;
case baud_921600:
dcb.BaudRate = CBR_921600;
break;
diff --git a/spectro/icoms_ux.c b/spectro/icoms_ux.c
index 9e79d7f..2ee19bd 100644..100755
--- a/spectro/icoms_ux.c
+++ b/spectro/icoms_ux.c
@@ -1,5 +1,6 @@
/* Unix icoms and serial I/O class */
+/* This is #includeed in icom.c */
/*
* Argyll Color Correction System
@@ -49,7 +50,7 @@
#endif /* UNIX_APPLE */
-instType fast_ser_inst_type(icoms *p, int tryhard, void *, void *);
+devType fast_ser_dev_type(icoms *p, int tryhard, void *, void *);
/* Add paths to serial connected device. */
/* Return an icom error */
@@ -142,12 +143,14 @@ int serial_get_paths(icompaths *p, icom_type mask) {
icoms *icom;
if ((path = p->get_last_path(p)) != NULL
&& (icom = new_icoms(path, p->log)) != NULL) {
- instType itype = fast_ser_inst_type(icom, 0, NULL, NULL);
- if (itype != instUnknown)
- icompaths_set_serial_itype(path, itype); /* And set category */
+ if (!p->fs_excluded(p, path)) {
+ instType itype = fast_ser_dev_type(icom, 0, NULL, NULL);
+ if (itype != instUnknown)
+ icompaths_set_serial_itype(path, itype); /* And set category */
+ }
icom->del(icom);
}
- a1logd(p->log, 8, "serial_get_paths: Identified '%s' dctype 0x%x\n",inst_sname(path->itype),path->dctype);
+ a1logd(p->log, 8, "serial_get_paths: Identified '%s' dctype 0x%x\n",inst_sname(path->dtype),path->dctype);
}
continue2:
CFRelease(dfp);
@@ -258,7 +261,7 @@ int serial_get_paths(icompaths *p, icom_type mask) {
strcpy(dpath, dirn);
strcat(dpath, de->d_name);
- /* See if the serial port is real */
+ /* See if the (not fast) serial port is real */
if (strncmp(de->d_name, "ttyUSB", 6) != 0
&& strncmp(de->d_name, "ttyHS", 5) != 0
&& strncmp(de->d_name, "rfcomm", 6) != 0) {
@@ -320,12 +323,14 @@ int serial_get_paths(icompaths *p, icom_type mask) {
icoms *icom;
if ((path = p->get_last_path(p)) != NULL
&& (icom = new_icoms(path, p->log)) != NULL) {
- instType itype = fast_ser_inst_type(icom, 0, NULL, NULL);
- if (itype != instUnknown)
- icompaths_set_serial_itype(path, itype); /* And set category */
+ if (!p->fs_excluded(p, path)) {
+ instType itype = fast_ser_dev_type(icom, 0, NULL, NULL);
+ if (itype != instUnknown)
+ icompaths_set_serial_itype(path, itype); /* And set category */
+ }
icom->del(icom);
}
- a1logd(p->log, 8, "serial_get_paths: Identified '%s' dctype 0x%x\n",inst_sname(path->itype),path->dctype);
+ a1logd(p->log, 8, "serial_get_paths: Identified '%s' dctype 0x%x\n",inst_sname(path->dtype),path->dctype);
}
}
closedir(dd);
@@ -361,6 +366,15 @@ void serial_close_port(icoms *p) {
#endif
#if defined(UNIX_APPLE) || defined(__OpenBSD__)
+# ifndef B230400
+# define B230400 230400
+# endif
+# ifndef B460800
+# define B460800 460800
+# endif
+# ifndef B512000
+# define B512000 512000
+# endif
# ifndef B921600
# define B921600 921600
# endif
@@ -393,10 +407,12 @@ int delayms) { /* Delay after open in msec */
,p->name ,fc ,baud_rate_to_str(baud) ,parity ,stop ,word, delayms);
+#ifdef NEVER /* This is too slow on OS X */
if (p->is_open) { /* Close it and re-open it */
a1logd(p->log, 8, "icoms_set_ser_port: closing port\n");
p->close_port(p);
}
+#endif
if (p->port_type(p) == icomt_serial) {
@@ -418,13 +434,27 @@ int delayms) { /* Delay after open in msec */
a1logd(p->log, 8, "icoms_set_ser_port: about to open serial port '%s'\n",p->spath);
+ /* Hmm. Recent OS X to FTDI can take 1500 msec to open. Why ? */
+ /* O_NONBLOCK O_SYNC */
if ((p->fd = open(p->spath, O_RDWR | O_NOCTTY )) < 0) {
- a1logd(p->log, 1, "icoms_set_ser_port: open port '%s' r/w failed with %d (%s)\n",p->spath,p->fd,strerror(errno));
+ a1logd(p->log, 1, "icoms_set_ser_port: open port '%s' r/w failed with %d (%s)\n",
+ p->spath,p->fd,strerror(errno));
+ return ICOM_SYS;
+ }
if (delayms < 160) /* Seems to need at least 80 msec for many drivers */
delayms = 160;
- msec_sleep(delayms); /* For Bluetooth */
+ msec_sleep(delayms); /* For Bluetooth and other drivers */
+
+#ifdef NEVER
+ /* If we used O_NONBLOCK */
+ if (fcntl(p->fd, F_SETFL, 0) == -1) {
+ a1logd(p->log, 1, "icoms_set_ser_port: clearing O_NONBLOCK failed with %d (%s)\n",
+ p->spath,p->fd,strerror(errno));
+ return ICOM_SYS;
+ }
+#endif
#ifdef NEVER /* See what supplementary groups we are a member of */
{
@@ -460,11 +490,6 @@ int delayms) { /* Delay after open in msec */
fail:;
}
#endif
- return ICOM_SYS;
- }
-
- /* O_NONBLOCK O_SYNC */
-
p->is_open = 1;
}
@@ -622,6 +647,9 @@ int delayms) { /* Delay after open in msec */
case baud_115200:
speed = B115200;
break;
+ case baud_230400:
+ speed = B230400;
+ break;
case baud_921600:
speed = B921600;
break;
diff --git a/spectro/ifiles b/spectro/ifiles
index 706d0b7..706d0b7 100644..100755
--- a/spectro/ifiles
+++ b/spectro/ifiles
diff --git a/spectro/illumread.c b/spectro/illumread.c
index 58569e3..28ecbca 100644..100755
--- a/spectro/illumread.c
+++ b/spectro/illumread.c
@@ -253,8 +253,8 @@ usage(char *diag, ...) {
for (i = 0; ; i++) {
if (paths[i] == NULL)
break;
- if ((paths[i]->itype == instSpyder1 && setup_spyd2(0) == 0)
- || (paths[i]->itype == instSpyder2 && setup_spyd2(1) == 0))
+ if ((paths[i]->dtype == instSpyder1 && setup_spyd2(0) == 0)
+ || (paths[i]->dtype == instSpyder2 && setup_spyd2(1) == 0))
fprintf(stderr," %d = '%s' !! Disabled - no firmware !!\n",i+1,paths[i]->name);
else
fprintf(stderr," %d = '%s'\n",i+1,paths[i]->name);
@@ -999,8 +999,8 @@ int main(int argc, char *argv[])
for (i = 0; ; i++) {
if (paths[i] == NULL)
break;
- if ((paths[i]->itype == instSpyder1 && setup_spyd2(0) == 0)
- || (paths[i]->itype == instSpyder2 && setup_spyd2(1) == 0))
+ if ((paths[i]->dtype == instSpyder1 && setup_spyd2(0) == 0)
+ || (paths[i]->dtype == instSpyder2 && setup_spyd2(1) == 0))
fprintf(stderr," %d = '%s' !! Disabled - no firmware !!\n",i+1,paths[i]->name);
else
fprintf(stderr," %d = '%s'\n",i+1,paths[i]->name);
diff --git a/spectro/inflate.c b/spectro/inflate.c
index 55d8e65..55d8e65 100644..100755
--- a/spectro/inflate.c
+++ b/spectro/inflate.c
diff --git a/spectro/inst.c b/spectro/inst.c
index 681ef0a..07ace6e 100644..100755
--- a/spectro/inst.c
+++ b/spectro/inst.c
@@ -45,6 +45,8 @@
#include "sa_config.h"
#endif /* !SALONEINSTLIB */
#include "numsup.h"
+#include "rand.h"
+#include "cgats.h"
#include "xspect.h"
#include "conv.h"
@@ -58,7 +60,7 @@
#include "sort.h"
#if defined(ENABLE_FAST_SERIAL)
-instType fast_ser_inst_type(icoms *p, int tryhard,
+devType fast_ser_dev_type(icoms *p, int tryhard,
inst_code (*uicallback)(void *cntx, inst_ui_purp purp), void *cntx);
# if defined(ENABLE_SERIAL)
static instType ser_inst_type(icoms *p,
@@ -66,6 +68,8 @@ static instType ser_inst_type(icoms *p,
# endif /* ENABLE_SERIAL */
#endif /* ENABLE_FAST_SERIAL */
+icom_type dev_category(instType itype);
+
/* ------------------------------------ */
/* Default methods for instrument class */
@@ -89,7 +93,7 @@ inst *p) {
/* Return the instrument type */
static instType get_itype(inst *p) {
if (p != NULL)
- return p->itype;
+ return p->dtype;
return instUnknown;
}
@@ -523,6 +527,8 @@ static char *inst_interp_error(inst *p, inst_code ec) {
return "Internal error - communications needed but not established";
case inst_no_init:
return "Internal error - initialisation needed but not done";
+ case inst_unsupported:
+ return "Unsupported function";
case inst_internal_error:
return "Internal software error";
case inst_coms_fail:
@@ -545,8 +551,6 @@ static char *inst_interp_error(inst *p, inst_code ec) {
return "Instrument needs calibration";
case inst_cal_setup:
return "Instrument needs to be setup for calibration";
- case inst_unsupported:
- return "Unsupported function";
case inst_unexpected_reply:
return "Unexpected Reply";
case inst_wrong_config:
@@ -613,7 +617,7 @@ void *cntx /* Context for callback */
return NULL;
}
- a1logd(log, 2, "new_inst: called with path '%s' type '%s'\n",path->name,inst_sname(path->itype));
+ a1logd(log, 2, "new_inst: called with path '%s' type '%s'\n",path->name,inst_sname(path->dtype));
if ((icom = new_icoms(path, log)) == NULL) {
a1logd(log, 2, "new_inst: new_icoms failed to open it\n");
@@ -623,12 +627,12 @@ void *cntx /* Context for callback */
/* Set instrument type from USB port, if not specified */
- itype = icom->itype; /* Instrument type if its known from usb/hid */
+ itype = icom->dtype; /* Instrument type if its known from usb/hid */
#if defined(ENABLE_FAST_SERIAL)
if (itype == instUnknown && !nocoms && (icom->dctype & icomt_fastserial)) {
- itype = fast_ser_inst_type(icom, 1, uicallback, cntx); /* Else type from serial */
- icom->dctype = (icom->dctype & ~icomt_cat_mask) | inst_category(itype);
+ itype = fast_ser_dev_type(icom, 1, uicallback, cntx); /* Else type from serial */
+ icom->dctype = (icom->dctype & ~icomt_cat_mask) | dev_category(itype);
a1logd(log, 8, "new_inst: fast set '%s' dctype 0x%x\n",icom->name,icom->dctype);
}
#endif /* ENABLE_FAST_SERIAL */
@@ -636,7 +640,7 @@ void *cntx /* Context for callback */
#if defined(ENABLE_SERIAL)
if (itype == instUnknown && !nocoms) {
itype = ser_inst_type(icom, uicallback, cntx); /* Else type from serial */
- icom->dctype = (icom->dctype & ~icomt_cat_mask) | inst_category(itype);
+ icom->dctype = (icom->dctype & ~icomt_cat_mask) | dev_category(itype);
a1logd(log, 8, "new_inst: set '%s' dctype 0x%x\n",icom->name,icom->dctype);
}
#endif /* ENABLE_SERIAL */
@@ -957,7 +961,7 @@ int doccmx /* Add matching installed ccmx files */
iccmx *ss_list;
/* Just ccmx's for this instrument */
- if ((ss_list = list_iccmx(p->itype, NULL)) == NULL) {
+ if ((ss_list = list_iccmx(p->dtype, NULL)) == NULL) {
free(list);
return inst_internal_error;
}
@@ -1111,7 +1115,7 @@ iccmx *list_iccmx(instType itype, int *no) {
int npaths = 0;
- npaths = xdg_bds(NULL, &paths, xdg_data, xdg_read, xdg_user,
+ npaths = xdg_bds(NULL, &paths, xdg_data, xdg_read, xdg_user, xdg_none,
"ArgyllCMS/\052.ccmx" XDG_FUDGE "color/\052.ccmx"
);
@@ -1251,7 +1255,7 @@ iccss *list_iccss(int *no) {
int npaths = 0;
- npaths = xdg_bds(NULL, &paths, xdg_data, xdg_read, xdg_user,
+ npaths = xdg_bds(NULL, &paths, xdg_data, xdg_read, xdg_user, xdg_none,
"ArgyllCMS/\052.ccss" XDG_FUDGE "color/\052.ccss"
);
@@ -1375,15 +1379,18 @@ void free_iccss(iccss *list) {
/* Detect fast serial instruments */
#ifdef ENABLE_FAST_SERIAL
+
+static void radiance_delimiters(icoms *p, int lgchsum);
+static void radiance_random(icoms *p, int lgchsum);
static void hex2bin(char *buf, int len);
/* Heuristicly determine the instrument type for */
/* a fast serial connection, and instUnknown if not serial. */
/* Set it in icoms and also return it. */
-instType fast_ser_inst_type(
+devType fast_ser_dev_type(
icoms *p,
int tryhard,
- inst_code (*uicallback)(void *cntx, inst_ui_purp purp), /* optional uicallback */
+ inst_code (*uicallback)(void *cntx, inst_ui_purp purp), /* optional uicallback for abort */
void *cntx /* Context for callback */
) {
instType rv = instUnknown;
@@ -1400,16 +1407,20 @@ instType fast_ser_inst_type(
int se, len;
double tryto = 0.1; /* [0.1] Communication timout */
// double tryto = 0.9; /* Communication timout (test) */
-
- a1logd(p->log, 8, "fast_ser_inst_type: on '%s' dctype 0x%x\n",p->name,p->dctype);
+
+ a1logd(p->log, 8, "fast_ser_dev_type: on '%s' dctype 0x%x\n",p->name,p->dctype);
if (!(p->dctype & icomt_seriallike)
&& !(p->dctype & icomt_fastserial)) {
- return p->itype;
+ return p->dtype;
}
/* The tick to give up on */
+#if defined(__APPLE__)
+ etime = msec_time() + (long)(2500.0 + 0.5); /* OS X open() is really slow (1500msec) */
+#else
etime = msec_time() + (long)(2000.0 + 0.5);
+#endif
// etime = msec_time() + (long)(20000.0 + 0.5); /* (test) */
a1logd(p->log, 1, "fser_inst_type: Trying different baud rates (%u msec to go) Path %s%s\n",
@@ -1427,7 +1438,7 @@ instType fast_ser_inst_type(
if (!tryhard)
break; /* try only once */
}
- a1logd(p->log, 5, "Trying %s baud\n",baud_rate_to_str(brt[i]));
+ a1logd(p->log, 5, "Trying %s baud, %d msec to go\n",baud_rate_to_str(brt[i]),etime - msec_time());
if ((se = p->set_ser_port_ex(p, fc_None, brt[i], parity_none,
stop_1, length_8, delayms)) != ICOM_OK) {
@@ -1437,76 +1448,148 @@ instType fast_ser_inst_type(
/* Assume Klein K10 only uses 9600. */
/* We need to also assume that we might be talking to a Spectrolino, */
- /* and avoid upsetting it. */
+ /* and avoid upsetting it, or some other serial instrument that */
+ /* is set to 9600 baud. */
if ((p->dctype & icomt_btserial) == 0 && brt[i] == baud_9600) {
double sto = 0.2; /* Give 9600 a little more time */
int bread, len;
+ int lgchsum = 0;
/* Try a spectrolino/spectroscan command first */
if (tryto > sto)
sto = tryto;
- p->write_read_ex(p, ";D024\r\n", 0, buf, BUFSZ-1, &bread, "\r", 1, sto, 1);
+
+ /* Do first character only and see if there is an echo */
+ p->write_read_ex(p, ";", 1, buf, BUFSZ-1, &bread, "\r", 1, 0.2, 1);
+ if (bread == 1 && buf[0] == ';')
+#ifdef ENABLE_VTPGLUT
+ goto check_lumagen;
+#else
+ goto continue_looking;
+#endif
+
+ /* Send the rest of the spectrolino command */
+ p->write_read_ex(p, "D024\r\n", 0, buf, BUFSZ-1, &bread, "\r", 1, 0.2, 1);
if (bread == 0) {
- a1logd(p->log, 5, "fser_inst_type: Spectroino command returned nothing\n");
- goto not_k10;
+ char *bp;
+ a1logd(p->log, 5, "fser_inst_type: Spectrolino command returned nothing\n");
+
+#ifdef ENABLE_VTPGLUT
+ /* It could be a Lumagen Radiance with echo off, */
+ /* so poke it and see if it responds. */
+ /* (Unfortunately the Lumagen delimeters modes aren't */
+ /* backwards compatible, so we may have to poke it twice...) */
+ /* Send "X" first, to get it out of menu mode ? */
+ p->write_read_ex(p, "X", 1, buf, BUFSZ, NULL, "\n", 1, 0.1, 1); // Menu off
+ a1logd(p->log, 5, "fser_inst_type: Checking for Lumagen Radiance\n");
+ p->write_read_ex(p, "#ZQS00\r", 0, buf, BUFSZ, &bread, "\n", 1, sto, 1);
+ if (bread == 0) {
+ p->write_read_ex(p, "#0ZQS008E\r", 0, buf, BUFSZ, &bread, "\n", 1, sto, 1);
+ lgchsum = 1;
+ }
+
+ if (bread > 0
+ && (bp = strrchr(buf, '!')) != NULL
+ && strlen(bp) >= 4
+ && strncmp(bp,"!S00",4) == 0) {
+ goto check_lumagen;
+ }
+#endif /* ENABLE_VTPGLUT */
+
+ /* Nope - look for something at a different baud rate */
+ goto continue_looking;
}
+
buf[bread] = '\000';
len = strlen(buf);
a1logd(p->log, 5, "fser_inst_type: got %d bytes\n",len);
- if (len < 4) {
- a1logd(p->log, 5, "fser_inst_type: Reply was too short\n");
- goto not_k10; /* Not K10, X-Rite or Spectrolino */
- }
-
/* Is this a Spectrolino or Spectroscan error resonse ? */
- if (len >= 5 && strncmp(buf, ":26", 3) == 0
- || len >= 7 && strncmp(buf, ":D183", 5) == 0) {
+ if ((len >= 5 && strncmp(buf, ":26", 3) == 0)
+ || (len >= 7 && strncmp(buf, ":D183", 5) == 0)) {
a1logd(p->log, 5, "fser_inst_type: Ignore Spectrolino\n");
return instUnknown; /* Not doing Spectrolino detection here */
}
/* Is this an X-Rite error value such as "<01>" ? */
- if (buf[0] == '<' && isdigit(buf[1]) && isdigit(buf[2]) && buf[3] == '>') {
+ if ((buf[0] == '<' && isdigit(buf[1]) && isdigit(buf[2]) && buf[3] == '>')
+ || (isdigit(buf[0]) && isdigit(buf[1]) && buf[2] == '>')) {
a1logd(p->log, 5, "fser_inst_type: Ignore X-Rite\n");
return instUnknown; /* Not doing X-Rite detection here */
}
/* The Klein K10 seems to respond with it's calibration list, preceeded by "D4" ? */
- if (buf[0] != 'D' || buf[1] != '4') {
- a1logd(p->log, 5, "fser_inst_type: Not Klein response\n");
- goto not_k10;;
+ if (buf[0] == 'D' && buf[1] == '4') {
+ a1logd(p->log, 5, "fser_inst_type: Looks like it may be a Klein\n");
+
+ /* Confirm this is a Klein instrument */
+
+ /* The first response is the calibration list, and it may need flushing. */
+ /* (write_read_ex doesn't cope with time it takes to dump this.) */
+ for (;;) {
+ bread = 0;
+ p->read(p, buf, BUFSZ, &bread, NULL, BUFSZ, 0.1);
+ if (bread == 0)
+ break;
+ }
+
+ if ((se = p->write_read_ex(p, "P0\r", 0, buf, BUFSZ, NULL, ">", 1, tryto, 1)) == inst_ok) {
+
+ /* Is this a Klein K1/K8/K10 response ? */
+ if (strncmp(buf, "P0K-1 ", 6) == 0
+ || strncmp(buf, "P0K-8 ", 6) == 0
+ || strncmp(buf, "P0K-10", 6) == 0
+ || strncmp(buf, "P0KV-10", 7) == 0) {
+ a1logd(p->log, 5, "fser_inst_type: found Klein K1/K8/K10\n");
+ rv = instKleinK10;
+ break;
+ }
+ }
}
- a1logd(p->log, 5, "fser_inst_type: Looks like it may be a Klein\n");
+#ifdef ENABLE_VTPGLUT
+ /* Is this a Lumagen Radiance with echo on, it responds with ";D024..." */
+ if ((len >= 4 && strncmp(buf, ";D024", 4) == 0)
+ || (len >= 4 && strncmp(buf, "!N\n\r", 4) == 0)) {
+ char *bp;
- /* Confirm this is a Klein instrument */
+ check_lumagen:;
- /* The first response is the calibration list, and it may need flushing. */
- /* (write_read_ex doesn't cope with time it takes to dump this.) */
- for (;;) {
- bread = 0;
- p->read(p, buf, BUFSZ, &bread, NULL, BUFSZ, 0.1);
- if (bread == 0)
- break;
- }
+ /* Send "X" first, to get it out of menu mode ? */
+ p->write_read_ex(p, "X", 1, buf, BUFSZ, NULL, "\n", 1, 0.1, 1); // Menu off
- if ((se = p->write_read_ex(p, "P0\r", 0, buf, BUFSZ, NULL, ">", 1, tryto, 1)) == inst_ok) {
+ /* Get the Lumagen device information */
+ p->write_read_ex(p, lgchsum ? "#0ZQS018F\r" : "#ZQS01\r",
+ 0, buf, BUFSZ, &bread, "\n", 1, sto, 1);
- /* Is this a Klein K1/K8/K10 response ? */
- if (strncmp(buf, "P0K-1 ", 6) == 0
- || strncmp(buf, "P0K-8 ", 6) == 0
- || strncmp(buf, "P0K-10", 6) == 0
- || strncmp(buf, "P0KV-10", 7) == 0) {
- a1logd(p->log, 5, "fser_inst_type: found Klein K1/K8/K10\n");
- rv = instKleinK10;
- break;
+ /* Might have echo with checksum, so lgchsum not set correctly */
+ if (!lgchsum && bread > 0 && strstr(buf, "!N") != NULL) {
+ p->write_read_ex(p, "#0ZQS018F\r", 0, buf, BUFSZ, &bread, "\n", 1, sto, 1);
+ if (bread >= 11 && strncmp(buf, "#0ZQS018F!Y", 11) == 0)
+ lgchsum = 1;
+ }
+
+ /* returns something like "ZQS01!S01,Radiance2020,030115,1016,001309\r\m" */
+ if ((bp = strrchr(buf, '!')) != NULL && strlen(bp) >= 13) {
+ if (strncmp(bp,"!S01,Radiance",13) == 0) {
+ a1logd(p->log, 5, "fser_inst_type: Found Lumagen Radiance\n");
+
+#ifdef NEVER /* Test various Lumagen com. settings */
+ radiance_random(p, lgchsum);
+// radiance_delimiters(p, lgchsum);
+#endif
+ radiance_delimiters(p, lgchsum);
+ return devRadiance;
+ }
}
+ a1logd(p->log, 5, "fser_inst_type: Not Lumagen Radiance\n");
+ return instUnknown;
}
+#endif /* ENABLE_VTPGLUT */
- not_k10:;
+ continue_looking:;
/* Check for user abort */
if (uicallback != NULL) {
@@ -1516,7 +1599,7 @@ instType fast_ser_inst_type(
return instUnknown;
}
}
- }
+ } /* 9600 baud */
/* SwatchMate Cube only uses 38400 */
if ((p->dctype & icomt_btserial) == 0 && brt[i] == baud_38400) {
@@ -1549,7 +1632,7 @@ instType fast_ser_inst_type(
}
/* JETI specbos or spectraval. */
- /* We are fudging the baud rate selection here - */
+ /* We are not allowing for all possible baud rate selections here - */
/* the 1211 RS and BT can't handle 921600, */
/* while the 15x1 can handle 230400 & 3000000, which we don't test for... */
// if ((p->dctype & icomt_btserial) == 0 || brt[i] == baud_115200)
@@ -1610,16 +1693,116 @@ instType fast_ser_inst_type(
if (rv == instUnknown
&& msec_time() >= etime) { /* We haven't established comms */
a1logd(p->log, 5, "fser_inst_type: Failed to establish coms\n");
- p->itype = rv;
+ p->dtype = rv;
return instUnknown;
}
a1logd(p->log, 5, "fser_inst_type: Instrument type is '%s'\n", inst_name(rv));
- p->itype = rv;
+ p->dtype = rv;
return rv;
}
+
+#ifdef ENABLE_VTPGLUT
+
+
+/*
+ Lumagen uses following sequence to setup coms:
+
+ Sent Recieved Comments
+ ---- -------- --------
+ M0931 M0931 use %M0931 to ensure it's on
+ f Ok if on, else echo's 'f'
+ B009600 then close & re-open port at 9600 baud.
+20x e 20x Ok Some sort of exit menu command ?
+ e Ok
+ I 030115.14.051d......
+ g Ok5b28
+ L000100NQ .....
+ lots more
+
+ These sequences seem to not honour the Delimeters etc., but
+ work all the time ??
+
+ Needs 'X' to exit M0931 to respond to normal "Z" sequences.
+
+*/
+
+/* Switch Lumagen Radiance to Echo + Delimiters mode */
+static void radiance_delimiters(icoms *p, int lgchsum) {
+ time_t clk = time(0);
+ char *com, *chcom;
+ char buf[BUFSZ];
+
+ // Echo On
+ p->write_read_ex(p, lgchsum ? "#0ZE100\r" : "#ZE1\r",
+ 0, buf, BUFSZ, NULL, "\n", 1, 0.1, 1);
+
+#ifndef NEVER
+ // Delimeters off
+ com = "#ZD0\r";
+ chcom = "#0ZD0FE\r";
+#else
+ // Delimiters on
+ com = "#ZD1\r";
+ chcom = "#0ZD1FF\r";
+#endif
+
+ p->write_read_ex(p, lgchsum ? chcom : com, 0, buf, BUFSZ, NULL, "\n", 1, 0.1, 1);
+
+#ifdef NEVER
+ // ~~~999 see if delimiters works
+// p->write_read_ex(p, "%", 1, buf, BUFSZ, NULL, "\n", 1, 0.2, 1); // Doesn't work !
+// msec_sleep(1000);
+ p->write_read_ex(p, "M0931", 5, buf, BUFSZ, NULL, "\n", 1, 0.2, 1);
+ p->write_read_ex(p, "f", 1, buf, BUFSZ, NULL, "\n", 1, 0.2, 1);
+ p->write_read_ex(p, "X", 1, buf, BUFSZ, NULL, "\n", 1, 0.2, 1); // Menu off
+// p->write_read_ex(p, "eeeeeeeeeeeeeeeeeeee", 20, buf, BUFSZ, NULL, "\n", 1, 0.2, 1);
+#endif
+}
+
+/* Test code for Lumagen com. settings; */
+/* - set a random echo and delimeters. */
+static void radiance_random(icoms *p, int lgchsum) {
+ time_t clk = time(0);
+ int ech, del;
+ char *com, *chcom;
+ char buf[BUFSZ];
+
+ rand32(clk);
+
+ del = i_rand(0, 3);
+ ech = i_rand(0, 1);
+
+ fprintf(stderr, "echo %d, del %d\n",ech, del);
+ // Random Echo:
+ if (ech == 1) {
+ p->write_read_ex(p, lgchsum ? "#0ZE100\r" : "#ZE1\r",
+ 0, buf, BUFSZ, NULL, "\n", 1, 0.1, 1);
+ } else {
+ p->write_read_ex(p, lgchsum ? "#0ZE0FF\r" : "#ZE0\r",
+ 0, buf, BUFSZ, NULL, "\n", 1, 0.1, 1);
+ }
+
+ // Random Delimeters:
+ if (del == 0) {
+ com = "#ZD0\r";
+ chcom = "#0ZD0FE\r";
+ } else if (del == 1) {
+ com = "#ZD1\r";
+ chcom = "#0ZD1FF\r";
+ } else if (del == 2) {
+ com = "#ZD2\r";
+ chcom = "#0ZD200\r";
+ } else {
+ com = "#ZD3\r";
+ chcom = "#0ZD301\r";
+ }
+ p->write_read_ex(p, lgchsum ? chcom : com, 0, buf, BUFSZ, NULL, "\n", 1, 0.1, 1);
+}
+#endif /* ENABLE_VTPGLUT */
+
#undef BUFSZ
#endif /* ENABLE_FAST_SERIAL */
@@ -1654,7 +1837,7 @@ static instType ser_inst_type(
#ifdef ENABLE_USB
if (p->usbd != NULL || p->hidd != NULL)
- return p->itype;
+ return p->dtype;
#endif /* ENABLE_USB */
bi = 0;
@@ -1677,38 +1860,35 @@ static instType ser_inst_type(
a1logd(p->log, 5, "Trying %s baud\n",baud_rate_to_str(brt[i]));
bread = 0;
- /* Try a spectrolino/spectroscan command first */
- p->write_read_ex(p, ";D024\r\n", 0, buf, BUFSZ-1, &bread, "\r", 1, 0.5, 1);
+ /* Try a spectrolino/spectroscan command first, */
+ /* but do first character only and see if there is an echo */
+ p->write_read_ex(p, ";", 1, buf, BUFSZ-1, &bread, "\r", 1, 0.2, 1);
+ if (bread == 1 && buf[0] == ';')
+ goto continue_looking; /* It may be a Lumagen, so skip it. */
+
+ /* Send the rest of the spectrolino command */
+ p->write_read_ex(p, "D024\r\n", 0, buf, BUFSZ-1, &bread, "\r", 1, 0.5, 1);
if (bread == 0) {
- /* Check for user abort */
- if (uicallback != NULL) {
- inst_code ev;
- if ((ev = uicallback(cntx, inst_negcoms)) == inst_user_abort) {
- a1logd(p->log, 5, "ser_inst_type: User aborted\n");
- return instUnknown;
- }
- }
- continue;
+ goto continue_looking;
}
buf[bread] = '\000';
len = strlen(buf);
// a1logd(p->log, 5, "len = %d\n",len);
- if (len < 4)
- continue;
/* The Klein K10 seems to respond with it's calibration list, preceeded by "D4" ? */
/* - don't know how reliable this is though. Another way may be to look for a */
/* response len > 100 characters ?? */
- if (buf[0] == 'D' && buf[1] == '4') {
+ if (len >= 3 && buf[0] == 'D' && buf[1] == '4') {
// a1logd(p->log, 5, "klein\n");
klein = 1;
break;
}
/* Is this an X-Rite error value such as "<01>" ? */
- if (buf[0] == '<' && isdigit(buf[1]) && isdigit(buf[2]) && buf[3] == '>') {
+ if ((len >= 4 && buf[0] == '<' && isdigit(buf[1]) && isdigit(buf[2]) && buf[3] == '>')
+ || (len >= 3 && isdigit(buf[0]) && isdigit(buf[1]) && buf[2] == '>')) {
// a1logd(p->log, 5, "xrite\n");
xrite = 1;
break;
@@ -1726,9 +1906,24 @@ static instType ser_inst_type(
ss = 1;
break;
}
+
+ continue_looking:;
+
+ /* Check for user abort */
+ if (uicallback != NULL) {
+ inst_code ev;
+ if ((ev = uicallback(cntx, inst_negcoms)) == inst_user_abort) {
+ a1logd(p->log, 5, "ser_inst_type: User aborted\n");
+ return instUnknown;
+ }
+ }
}
if (rv == instUnknown
+ && klein == 0
+ && xrite == 0
+ && ss == 0
+ && so == 0
&& msec_time() >= etime) { /* We haven't established comms */
a1logd(p->log, 5, "ser_inst_type: Failed to establish coms\n");
return instUnknown;
@@ -1806,7 +2001,7 @@ static instType ser_inst_type(
p->close_port(p); /* Or should we leave it open ?? */
- p->itype = rv;
+ p->dtype = rv;
return rv;
}
@@ -1921,28 +2116,6 @@ int sym_to_inst_mode(inst_mode *mode, const char *sym) {
return rv;
}
-/* ============================================================= */
-/* Utilities */
-
-/* Return a string for the xcalstd enum */
-char *xcalstd2str(xcalstd std) {
- switch(std) {
- case xcalstd_native:
- return "NATIVE";
- case xcalstd_xrdi:
- return "XRDI";
- case xcalstd_gmdi:
- return "GMDI";
- case xcalstd_xrga:
- return "XRGA";
- default:
- break;
- }
- return "None";
-}
-
-
-
diff --git a/spectro/inst.h b/spectro/inst.h
index 01f579d..04e02d6 100644..100755
--- a/spectro/inst.h
+++ b/spectro/inst.h
@@ -43,6 +43,7 @@
and agreed to support.
*/
+#include "dev.h" /* Base device class */
#include "insttypes.h" /* libinst Includes this functionality */
#include "disptechs.h" /* libinst Includes this functionality */
#include "icoms.h" /* libinst Includes this functionality */
@@ -101,20 +102,6 @@ struct _ipatch {
}; typedef struct _ipatch ipatch;
-/* ------------------------------------------------------ */
-/* Gretag/X-Rite specific reflective measurement standard */
-
-typedef enum {
- xcalstd_none = -2, /* Not set */
- xcalstd_native = -1, /* No conversion */
- xcalstd_xrdi = 0, /* Historical X-Rite */
- xcalstd_gmdi = 1, /* Historical Gretag-Macbeth */
- xcalstd_xrga = 2, /* Current X-Rite */
-} xcalstd;
-
-/* Return a string for the xcalstd enum */
-char *xcalstd2str(xcalstd std);
-
/* ---------------------------------------- */
/* Instrument interface abstract base class */
@@ -301,7 +288,7 @@ typedef enum {
/* Return a string with a symbolic encoding of the mode flags */
void inst_mode_to_sym(char sym[MAX_INST_MODE_SYM_SZ], inst_mode mode);
-/* Return a set of mode flags that correspondf to the symbolic encoding */
+/* Return a set of mode flags that correspond to the symbolic encoding */
/* Return nz if a symbol wasn't recognized */
int sym_to_inst_mode(inst_mode *mode, const char *sym);
@@ -363,6 +350,9 @@ typedef enum {
typedef enum {
inst3_none = 0x00000000, /* No capabilities */
+ inst3_average = 0x00000001 /* Can set to average multiple measurements into 1 */
+ /* See inst_opt_set_averages */
+
} inst3_capability;
/* - - - - - - - - - - - - - - - - - - - */
@@ -511,7 +501,10 @@ typedef enum {
/* [xcalstd standard] */
inst_opt_get_xcalstd = 0x0023, /* Get the effective X-Rite ref. cal. standard */
/* [xcalstd *standard] */
- inst_opt_lamp_remediate = 0x0024 /* Remediate i1Pro lamp [double seconds] */
+ inst_opt_lamp_remediate = 0x0024, /* Remediate i1Pro lamp [double seconds] */
+
+ inst_opt_set_averages = 0x0025 /* Set the number of measurements to average [int] */
+ /* 0 for default */
} inst_opt_type;
@@ -680,7 +673,7 @@ typedef enum {
inst_conf_ambient
} inst_config;
-# define EXRA_INST_OBJ
+# define EXTRA_INST_OBJ
/* Off-line pending readings available (status) */
#define CALIDLEN 200 /* Maxumum length of calibration tile ID string */
@@ -692,12 +685,10 @@ typedef enum {
/* after initialisation. */
#define INST_OBJ_BASE \
\
- EXRA_INST_OBJ \
- a1log *log; /* Pointer to debug & error logging class */ \
- instType itype; /* Instrument type determined by driver */ \
- icoms *icom; /* Instrument coms object */ \
- int gotcoms; /* Coms established flag */ \
- int inited; /* Instrument open and initialized flag */ \
+ DEV_OBJ_BASE \
+ \
+ EXTRA_INST_OBJ \
+ \
double cal_gy_level; /* Display calibration test window state */ \
int cal_gy_count; /* Display calibration test window state */ \
inst_code (*uicallback)(void *cntx, inst_ui_purp purp); \
diff --git a/spectro/instappsup.c b/spectro/instappsup.c
index fc550b4..6c3dd68 100644..100755
--- a/spectro/instappsup.c
+++ b/spectro/instappsup.c
@@ -27,6 +27,7 @@
#include "sa_config.h"
#endif /* !SALONEINSTLIB */
#include "numsup.h"
+#include "cgats.h"
#include "xspect.h"
#include "conv.h"
#include "insttypes.h"
@@ -504,7 +505,7 @@ inst2_capability inst_show_disptype_options(FILE *fp, char *oline, icompaths *ic
strcat(extra, "]");
}
- fprintf(fp, "%s%s: %s%s\n",buf, inst_sname(it->itype), sels[j].desc, extra);
+ fprintf(fp, "%s%s: %s%s\n",buf, inst_sname(it->dtype), sels[j].desc, extra);
if (j == 0) {
for (m = 0; m < pstart; m++)
diff --git a/spectro/instappsup.h b/spectro/instappsup.h
index 8da4325..8da4325 100644..100755
--- a/spectro/instappsup.h
+++ b/spectro/instappsup.h
diff --git a/spectro/instlib.ksh b/spectro/instlib.ksh
index 8b0303f..8b0303f 100644..100755
--- a/spectro/instlib.ksh
+++ b/spectro/instlib.ksh
diff --git a/spectro/instlib.txt b/spectro/instlib.txt
index 661584d..661584d 100644..100755
--- a/spectro/instlib.txt
+++ b/spectro/instlib.txt
diff --git a/spectro/insttypeinst.h b/spectro/insttypeinst.h
index 081d130..081d130 100644..100755
--- a/spectro/insttypeinst.h
+++ b/spectro/insttypeinst.h
diff --git a/spectro/insttypes.c b/spectro/insttypes.c
index 760d678..2a61d21 100644..100755
--- a/spectro/insttypes.c
+++ b/spectro/insttypes.c
@@ -26,6 +26,7 @@
#include "sa_config.h"
#endif /* !SALONEINSTLIB */
#include "numsup.h"
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -39,8 +40,8 @@
/* Given a device type, return the corrsponding */
/* category */
-extern icom_type inst_category(instType itype) {
- switch (itype) {
+extern icom_type dev_category(devType dtype) {
+ switch (dtype) {
/* Color measurement instruments */
case instDTP22:
@@ -80,19 +81,26 @@ extern icom_type inst_category(instType itype) {
return icomt_instrument;
+#ifdef ENABLE_VTPGLUT
/* 3D cLUT box */
+ case devRadiance:
+ return icomt_v3dlut | icomt_vtpg;
+ case devPrisma:
+ return icomt_v3dlut;
/* Video test patern generator box */
- /* Printers */
- case devEpsonR1800:
- return icomt_printer;
+#endif
+
+
case instFakeDisp:
return icomt_unknown; // ???
- }
+ case devUnknown:
+ return icomt_unknown; // ???
+ }
return icomt_cat_any;
}
@@ -166,6 +174,16 @@ char *inst_sname(instType itype) {
case instColorHug2:
return "ColorHug2";
+
+#ifdef ENABLE_VTPGLUT
+ case devRadiance:
+ return "Radiance";
+ case devPrisma:
+ return "Prisma";
+#endif
+
+
+
default:
break;
}
@@ -242,6 +260,16 @@ char *inst_name(instType itype) {
case instColorHug2:
return "Hughski ColorHug2";
+
+#ifdef ENABLE_VTPGLUT
+ case devRadiance:
+ return "Lumagen Radiance";
+ case devPrisma:
+ return "Q, Inc Prisma";
+#endif
+
+
+
default:
break;
}
@@ -337,6 +365,16 @@ instType inst_enum(char *name) {
return instColorHug2;
+#ifdef ENABLE_VTPGLUT
+ if (strcmp(name, "Lumagen Radiance") == 0)
+ return devRadiance;
+
+ if (strcmp(name, "Q, Inc Prisma") == 0)
+ return devPrisma;
+#endif
+
+
+
return instUnknown;
}
@@ -371,6 +409,8 @@ int nep) { /* Number of end points */
return instI1Disp3;
if (idProduct == 0x6003) /* ColorMinki Smile (aka. ColorMunki Display Lite) */
return instSmile;
+ if (idProduct == 0x6008) /* ColorMunki i1Studio */
+ return instColorMunki;
if (idProduct == 0xD020) /* DTP20 */
return instDTP20;
if (idProduct == 0xD092) /* DTP92Q */
@@ -427,6 +467,8 @@ int nep) { /* Number of end points */
+
+
return instUnknown;
}
@@ -536,4 +578,40 @@ int inst_illuminant(xspect *sp, instType itype) {
return 1;
}
+/* ============================================================= */
+/* XRGA support */
+
+/* Return a string for the xcalstd enum */
+char *xcalstd2str(xcalstd std) {
+ switch(std) {
+ case xcalstd_native:
+ return "NATIVE";
+ case xcalstd_xrdi:
+ return "XRDI";
+ case xcalstd_gmdi:
+ return "GMDI";
+ case xcalstd_xrga:
+ return "XRGA";
+ default:
+ break;
+ }
+ return "None";
+}
+
+/* Parse a string to xcalstd, */
+/* return xcalstd_none if not recognized */
+xcalstd str2xcalstd(char *str) {
+ if (strcmp(str, "NATIVE") == 0)
+ return xcalstd_native;
+ if (strcmp(str, "XRDI") == 0)
+ return xcalstd_xrdi;
+ if (strcmp(str, "GMDI") == 0)
+ return xcalstd_gmdi;
+ if (strcmp(str, "XRGA") == 0)
+ return xcalstd_xrga;
+
+ return xcalstd_none;
+}
+
+
diff --git a/spectro/insttypes.h b/spectro/insttypes.h
index 8306bc8..104b25d 100644..100755
--- a/spectro/insttypes.h
+++ b/spectro/insttypes.h
@@ -65,21 +65,23 @@ typedef enum {
instFakeDisp = 9998, /* Fake display & instrument device id */
+#ifdef ENABLE_VTPGLUT
/* 3D cLUT box */
- // 20000
+ devRadiance = 20000, /* Lumagen Radiance v3dlut & vtpg */
+ devPrisma, /* Q, Inc Prisma v3dlut */
/* Video test patern generator box */
// 30000
+#endif
+
- /* Printers */
- devEpsonR1800 = 40000 /* Epson R1800 printer */
} devType;
/* Aliases for backwards compatibility */
#define instUnknown devUnknown
typedef devType instType;
-typedef devType cLUTType;
+typedef devType vcLUTType;
typedef devType vtpgType;
typedef devType printerType;
@@ -90,7 +92,7 @@ enum _icom_type;
/* Given a device type, return the corrsponding */
/* category */
-//extern _icom_type inst_category(instType itype);
+//extern _icom_type dev_category(instType itype);
/* Given its instrument type, return the matching */
/* short instrument name (static string), */
@@ -127,6 +129,24 @@ int nep); /* Number of end points (0 for prelim match) */
extern int inst_illuminant(xspect *sp, instType itype);
+/* ------------------------------------------------------ */
+/* Gretag/X-Rite specific reflective measurement standard */
+
+typedef enum {
+ xcalstd_none = -2, /* Not set */
+ xcalstd_native = -1, /* No conversion */
+ xcalstd_xrdi = 0, /* Historical X-Rite */
+ xcalstd_gmdi = 1, /* Historical Gretag-Macbeth */
+ xcalstd_xrga = 2, /* Current X-Rite */
+} xcalstd;
+
+/* Return a string for the xcalstd enum */
+char *xcalstd2str(xcalstd std);
+
+/* Parse a string to xcalstd, */
+/* return xcalstd_none if not recognized */
+xcalstd str2xcalstd(char *str);
+
#ifdef __cplusplus
}
#endif
diff --git a/spectro/iusb.h b/spectro/iusb.h
index 94047cf..94047cf 100644..100755
--- a/spectro/iusb.h
+++ b/spectro/iusb.h
diff --git a/spectro/kleink10.c b/spectro/kleink10.c
index 3d67b6c..d169156 100644..100755
--- a/spectro/kleink10.c
+++ b/spectro/kleink10.c
@@ -54,6 +54,7 @@
#include "sa_config.h"
#include "numsup.h"
#endif /* !SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -354,7 +355,7 @@ k10_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
baud_rate brt[] = { baud_9600, baud_nc };
unsigned int etime;
unsigned int i;
- instType itype = pp->itype;
+ instType dtype = pp->dtype;
int se;
char *cp;
@@ -1486,8 +1487,8 @@ static inst_code k10_imp_measure_refresh(
/* Locate the smallest values and maximum time */
maxt = -1e6;
- minv = minv = minv = 1e20;
- maxv = maxv = maxv = -11e20;
+ minv = 1e20;
+ maxv = -11e20;
for (i = nfsamps-1; i >= 0; i--) {
if (samp[i] < minv)
minv = samp[i];
@@ -2842,7 +2843,7 @@ k10_get_set_opt(inst *pp, inst_opt_type m, ...) {
}
/* Constructor */
-extern kleink10 *new_kleink10(icoms *icom, instType itype) {
+extern kleink10 *new_kleink10(icoms *icom, instType dtype) {
kleink10 *p;
if ((p = (kleink10 *)calloc(sizeof(kleink10),1)) == NULL) {
a1loge(icom->log, 1, "new_kleink10: malloc failed!\n");
@@ -2871,7 +2872,7 @@ extern kleink10 *new_kleink10(icoms *icom, instType itype) {
p->del = k10_del;
p->icom = icom;
- p->itype = itype;
+ p->dtype = dtype;
p->dtech = disptech_unknown;
amutex_init(p->lock);
diff --git a/spectro/kleink10.h b/spectro/kleink10.h
index 136476a..136476a 100644..100755
--- a/spectro/kleink10.h
+++ b/spectro/kleink10.h
diff --git a/spectro/linear.sp b/spectro/linear.sp
index 8851462..8851462 100644..100755
--- a/spectro/linear.sp
+++ b/spectro/linear.sp
diff --git a/spectro/madvrwin.c b/spectro/madvrwin.c
index 305a240..305a240 100644..100755
--- a/spectro/madvrwin.c
+++ b/spectro/madvrwin.c
diff --git a/spectro/madvrwin.h b/spectro/madvrwin.h
index bbaf32e..bbaf32e 100644..100755
--- a/spectro/madvrwin.h
+++ b/spectro/madvrwin.h
diff --git a/spectro/mongoose.c b/spectro/mongoose.c
index 019101e..019101e 100644..100755
--- a/spectro/mongoose.c
+++ b/spectro/mongoose.c
diff --git a/spectro/mongoose.h b/spectro/mongoose.h
index 1ee0c47..1ee0c47 100644..100755
--- a/spectro/mongoose.h
+++ b/spectro/mongoose.h
diff --git a/spectro/munki.c b/spectro/munki.c
index 16cd863..306f1dc 100644..100755
--- a/spectro/munki.c
+++ b/spectro/munki.c
@@ -49,6 +49,7 @@
#include "sa_config.h"
#include "numsup.h"
#endif /* SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -1012,7 +1013,7 @@ munki_del(inst *pp) {
}
/* Constructor */
-extern munki *new_munki(icoms *icom, instType itype) {
+extern munki *new_munki(icoms *icom, instType dtype) {
munki *p;
int rv;
if ((p = (munki *)calloc(sizeof(munki),1)) == NULL) {
@@ -1043,7 +1044,7 @@ extern munki *new_munki(icoms *icom, instType itype) {
p->del = munki_del;
p->icom = icom;
- p->itype = itype;
+ p->dtype = dtype;
/* Preliminary capabilities */
munki_determine_capabilities(p);
diff --git a/spectro/munki.h b/spectro/munki.h
index 01eda29..cb4d917 100644..100755
--- a/spectro/munki.h
+++ b/spectro/munki.h
@@ -46,7 +46,7 @@
struct _munki {
INST_OBJ_BASE
- int dtype; /* Device type: 0 = ?? */
+ int idtype; /* Device type: 0 = ?? */
/* *** munki private data **** */
inst_mode cap; /* Instrument mode capability */
diff --git a/spectro/munki_imp.c b/spectro/munki_imp.c
index eae2837..d8690e8 100644..100755
--- a/spectro/munki_imp.c
+++ b/spectro/munki_imp.c
@@ -60,6 +60,7 @@
#include "numsup.h"
#include "rspl1.h"
#endif /* SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -483,7 +484,7 @@ munki_code munki_imp_init(munki *p) {
a1logd(p->log,2,"munki_init:\n");
- if (p->itype != instColorMunki)
+ if (p->dtype != instColorMunki)
return MUNKI_UNKNOWN_MODEL;
@@ -3183,7 +3184,8 @@ munki_code munki_save_calibration(munki *p) {
#endif
sprintf(cal_name, "ArgyllCMS/.mk_%s.cal", m->serno);
- if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_write, xdg_user, cal_name)) < 1) {
+ if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_write, xdg_user, xdg_none,
+ cal_name)) < 1) {
a1logd(p->log,1,"munki_save_calibration xdg_bds returned no paths\n");
return MUNKI_INT_CAL_SAVE;
}
@@ -3299,7 +3301,8 @@ munki_code munki_restore_calibration(munki *p) {
#endif
sprintf(cal_name, "ArgyllCMS/.mk_%s.cal" SSEPS "color/.mk_%s.cal", m->serno, m->serno);
- if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_read, xdg_user, cal_name)) < 1) {
+ if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_read, xdg_user, xdg_none,
+ cal_name)) < 1) {
a1logd(p->log,1,"munki_restore_calibration xdg_bds returned no paths\n");
return MUNKI_INT_CAL_RESTORE;
}
@@ -3616,7 +3619,8 @@ munki_code munki_touch_calibration(munki *p) {
int rv;
sprintf(cal_name, "ArgyllCMS/.mk_%s.cal" SSEPS "color/.mk_%s.cal", m->serno, m->serno);
- if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_read, xdg_user, cal_name)) < 1)
+ if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_read, xdg_user, xdg_none,
+ cal_name)) < 1)
return MUNKI_INT_CAL_TOUCH;
a1logd(p->log,2,"munki_touch_calibration touching file '%s'\n",cal_paths[0]);
diff --git a/spectro/munki_imp.h b/spectro/munki_imp.h
index f639395..fca4c5f 100644..100755
--- a/spectro/munki_imp.h
+++ b/spectro/munki_imp.h
@@ -186,7 +186,8 @@ struct _munkiimp {
/* Information from the HW */
int fwrev; /* int - Firmware revision number, from getfirm() */
- /* Typically 0120 = V1.32 */
+ /* Typically 0120 = V1.32 (Build 1303) */
+ /* i1Studio 0200 = V2.00 (Build 1310) */
unsigned char chipid[8]; /* HW serial number */
char vstring[37]; /* Asciiz version string */
int tickdur; /* Tick duration (usec, converted to intclkp) */
diff --git a/spectro/oemarch.c b/spectro/oemarch.c
index c8775bf..1837e63 100644..100755
--- a/spectro/oemarch.c
+++ b/spectro/oemarch.c
@@ -51,6 +51,7 @@
#include "numsup.h"
#endif /* SALONEINSTLIB */
#include "xdg_bds.h"
+#include "cgats.h"
#include "xspect.h"
#include "conv.h"
#include "aglob.h"
diff --git a/spectro/oemarch.h b/spectro/oemarch.h
index b0b1a65..b0b1a65 100644..100755
--- a/spectro/oemarch.h
+++ b/spectro/oemarch.h
diff --git a/spectro/oeminst.c b/spectro/oeminst.c
index 726a54c..3a4b03b 100644..100755
--- a/spectro/oeminst.c
+++ b/spectro/oeminst.c
@@ -30,6 +30,7 @@
#include "conv.h"
#include "aglob.h"
#include "oemarch.h"
+#include "cgats.h"
#include "xspect.h"
#include "disptechs.h"
#include "ccmx.h"
@@ -260,7 +261,8 @@ main(int argc, char *argv[]) {
int npaths = 0;
/* Get destination path. This may drop uid/gid if we are su */
- if ((npaths = xdg_bds(NULL, &paths, xdg_data, xdg_write, scope, install_name)) < 1) {
+ if ((npaths = xdg_bds(NULL, &paths, xdg_data, xdg_write, scope, xdg_none,
+ install_name)) < 1) {
error("Failed to find/create XDG_DATA path '%s'",install_name);
}
if (install)
diff --git a/spectro/pollem.c b/spectro/pollem.c
index 855702b..855702b 100644..100755
--- a/spectro/pollem.c
+++ b/spectro/pollem.c
diff --git a/spectro/pollem.h b/spectro/pollem.h
index bd879e1..bd879e1 100644..100755
--- a/spectro/pollem.h
+++ b/spectro/pollem.h
diff --git a/spectro/rspec.c b/spectro/rspec.c
index 6a7f8c7..c50cd83 100644..100755
--- a/spectro/rspec.c
+++ b/spectro/rspec.c
@@ -47,6 +47,7 @@
#ifndef SALONEINSTLIB
# include "plot.h"
#endif
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -928,7 +929,8 @@ int calf_open(calf *x, a1log *log, char *fname, int wr) {
sprintf(cal_name, "ArgyllCMS/%s", fname);
else
sprintf(cal_name, "ArgyllCMS/%s" SSEPS "color/%s", fname, fname);
- if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_write, xdg_user, cal_name)) < 1) {
+ if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_write, xdg_user, xdg_none,
+ cal_name)) < 1) {
a1logd(x->log,1,"calf_open: xdg_bds returned no paths\n");
return 1;
}
@@ -971,7 +973,8 @@ int calf_touch(a1log *log, char *fname) {
/* Locate the file name */
sprintf(cal_name, "ArgyllCMS/%s" SSEPS "color/%s", fname, fname);
- if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_read, xdg_user, cal_name)) < 1) {
+ if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_read, xdg_user, xdg_none,
+ cal_name)) < 1) {
a1logd(log,2,"calf_touch: xdg_bds failed to locate file'\n");
return 1;
}
diff --git a/spectro/rspec.h b/spectro/rspec.h
index 0cbee58..0cbee58 100644..100755
--- a/spectro/rspec.h
+++ b/spectro/rspec.h
diff --git a/spectro/sa_conv.c b/spectro/sa_conv.c
index 84286ba..84286ba 100644..100755
--- a/spectro/sa_conv.c
+++ b/spectro/sa_conv.c
diff --git a/spectro/sa_conv.h b/spectro/sa_conv.h
index 0f7e635..0f7e635 100644..100755
--- a/spectro/sa_conv.h
+++ b/spectro/sa_conv.h
diff --git a/spectro/smcube.c b/spectro/smcube.c
index c450d48..9f6947d 100644..100755
--- a/spectro/smcube.c
+++ b/spectro/smcube.c
@@ -73,6 +73,7 @@
#include "numsup.h"
#include "sa_conv.h"
#endif /* !SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -203,7 +204,7 @@ smcube_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
baud_rate brt[] = { baud_38400, baud_nc };
unsigned int etime;
unsigned int i;
- instType itype = pp->itype;
+ instType dtype = pp->dtype;
int se;
inst_code ev = inst_ok;
@@ -1133,7 +1134,7 @@ smcube_get_set_opt(inst *pp, inst_opt_type m, ...) {
}
/* Constructor */
-extern smcube *new_smcube(icoms *icom, instType itype) {
+extern smcube *new_smcube(icoms *icom, instType dtype) {
smcube *p;
if ((p = (smcube *)calloc(sizeof(smcube),1)) == NULL) {
a1loge(icom->log, 1, "new_smcube: malloc failed!\n");
@@ -1158,7 +1159,7 @@ extern smcube *new_smcube(icoms *icom, instType itype) {
p->icom = icom;
icom->icntx = (void *)p; /* Allow us to get instrument from icom */
- p->itype = itype;
+ p->dtype = dtype;
amutex_init(p->lock);
diff --git a/spectro/smcube.h b/spectro/smcube.h
index 06aee9d..06aee9d 100644..100755
--- a/spectro/smcube.h
+++ b/spectro/smcube.h
diff --git a/spectro/spec2cie.c b/spectro/spec2cie.c
index d77c334..6c56e67 100644..100755
--- a/spectro/spec2cie.c
+++ b/spectro/spec2cie.c
@@ -73,6 +73,7 @@
#include "conv.h"
#include "icoms.h"
#include "inst.h"
+#include "xrga.h"
#ifdef ALLOW_PLOT
#include "plot.h"
#include "ui.h"
@@ -87,6 +88,7 @@ usage (void)
fprintf (stderr, "\n");
fprintf (stderr, "Usage: spec2cie [options] input.[ti3|sp] output.[ti3|sp]\n");
fprintf (stderr, " -v Verbose mode\n");
+ fprintf (stderr, " -A NN|AX|AG|XA|XG|GA|GX XRGA conversion (default NN)\n");
fprintf (stderr, " -I illum Override actual instrument illuminant in .ti3 or .sp file:\n");
fprintf (stderr, " A, C, D50, D50M2, D65, F5, F8, F10 or file.sp\n");
fprintf (stderr, " (only used in conjunction with -f)\n");
@@ -95,7 +97,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 or file.cmf\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, " -n Don't output spectral values\n");
#ifdef ALLOW_PLOT
fprintf (stderr, " -p Plot each values spectrum\n");
@@ -110,6 +112,10 @@ main(int argc, char *argv[])
{
int fa, nfa; /* current argument we're looking at */
int verb = 0;
+ xcalstd calstd = xcalstd_none; /* X-Rite calibration standard of .ti3 file */
+ xcalpol calpol = xcalstd_nonpol; /* If measurement is polarized */
+ xcalstd calstdi = xcalstd_none; /* X-Rite calibration standard conversion in */
+ xcalstd calstdo = xcalstd_none; /* X-Rite calibration standard conversion out */
int nospec = 0; /* NZ if not to output spectral values */
char *in_ti3_name;
char *out_ti3_name;
@@ -117,7 +123,7 @@ main(int argc, char *argv[])
cgats *ocg; /* output cgats structure */
cgats_set_elem *elems;
- int isspect = 0; /* nz if SPECT file rathe than TI3 */
+ int isspect = 0; /* nz if SPECT file rather than TI3 */
int isemis = 0; /* nz if this is an emissive reference */
int isdisp = 0; /* nz if this is a display device */
int isdnormed = 0; /* Has display data been normalised to 100 ? */
@@ -140,11 +146,11 @@ main(int argc, char *argv[])
xspect inst_cust_illum; /* Custom actual instrument illumination spectrum */
/* if inst_illum == icxIT_custom */
- icxObserverType observ = icxOT_none;
- xspect cust_observ[3]; /* Custom observer CMF's */
+ icxObserverType obType = icxOT_none;
+ xspect custObserver[3]; /* Custom observer CMF's */
int npat; /* Number of patches */
- int dti; /* Device Type index */
+ int ti; /* Field index */
char *kw;
int i, j, jj, k;
@@ -175,12 +181,43 @@ main(int argc, char *argv[])
}
if (argv[fa][1] == '?')
- usage ();
+ usage();
/* Verbose */
else if (argv[fa][1] == 'v' || argv[fa][1] == 'V')
verb = 1;
+ /* XRGA conversion */
+ else if (argv[fa][1] == 'A') {
+ fa = nfa;
+ if (na == NULL) usage();
+ if (na[0] == 'N' && na[1] == 'N') {
+ calstdi = xcalstd_none;
+ calstdo = xcalstd_none;
+ } else if (na[0] == 'A' && na[1] == 'X') {
+ calstdi = xcalstd_xrga;
+ calstdo = xcalstd_xrdi;
+ } else if (na[0] == 'A' && na[1] == 'G') {
+ calstdi = xcalstd_xrga;
+ calstdo = xcalstd_gmdi;
+ } else if (na[0] == 'X' && na[1] == 'A') {
+ calstdi = xcalstd_xrdi;
+ calstdo = xcalstd_xrga;
+ } else if (na[0] == 'X' && na[1] == 'G') {
+ calstdi = xcalstd_xrdi;
+ calstdo = xcalstd_gmdi;
+ } else if (na[0] == 'G' && na[1] == 'A') {
+ calstdi = xcalstd_gmdi;
+ calstdo = xcalstd_xrga;
+ } else if (na[0] == 'G' && na[1] == 'X') {
+ calstdi = xcalstd_gmdi;
+ calstdo = xcalstd_xrdi;
+ } else {
+ //usage("Paramater after -A '%c%c' not recognized",na[0],na[1]);
+ usage();
+ }
+ }
+
/* Don't output spectral */
else if (argv[fa][1] == 'n' || argv[fa][1] == 'N')
nospec = 1;
@@ -327,25 +364,25 @@ main(int argc, char *argv[])
else if (argv[fa][1] == 'o' || argv[fa][1] == 'O') {
fa = nfa;
if (na == NULL)
- usage ();
+ usage();
if (strcmp (na, "1931_2") == 0) { /* Classic 2 degree */
- observ = icxOT_CIE_1931_2;
+ obType = icxOT_CIE_1931_2;
}
else if (strcmp (na, "1964_10") == 0) { /* Classic 10 degree */
- observ = icxOT_CIE_1964_10;
- }
- else if (strcmp (na, "1955_2") == 0) { /* Stiles and Burch 1955 2 degree */
- observ = icxOT_Stiles_Burch_2;
- }
- else if (strcmp (na, "1978_2") == 0) { /* Judd and Voss 1978 2 degree */
- observ = icxOT_Judd_Voss_2;
- }
- else if (strcmp (na, "shaw") == 0) { /* Shaw and Fairchilds 1997 2 degree */
- observ = icxOT_Shaw_Fairchild_2;
- }
- else { /* Assume it's a filename */
- observ = icxOT_custom;
- if (read_cmf (cust_observ, na) != 0)
+ obType = icxOT_CIE_1964_10;
+ } else if (strcmp(na, "2012_2") == 0) { /* Latest 2 degree */
+ obType = icxOT_CIE_2012_2;
+ } else if (strcmp(na, "2012_10") == 0) { /* Latest 10 degree */
+ obType = icxOT_CIE_2012_10;
+ } 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;
+ } else { /* Assume it's a filename */
+ obType = icxOT_custom;
+ if (read_cmf (custObserver, na) != 0)
usage ();
}
}
@@ -376,21 +413,21 @@ main(int argc, char *argv[])
ocg = new_cgats (); /* Create a CGATS structure */
ocg->add_other (ocg, "CTI3"); /* Calibration Target Information 3 */
- icg->add_other (ocg, "SPECT"); /* Spectral file */
+ ocg->add_other (ocg, "SPECT"); /* Spectral file */
if (icg->read_name (icg, in_ti3_name))
error ("CGATS file read error: %s", icg->err);
+ if (icg->ntables < 1)
+ error ("Input file doesn't contain at least one table");
+
if (icg->ntables == 0 || icg->t[0].tt != tt_other
|| (icg->t[0].oi != 0 && icg->t[0].oi != 1))
error ("Input file isn't a CTI3 or SPECT format file");
- if (icg->t[0].oi == 1)
+ if (icg->t[0].oi == 1) /* SPECT type */
isspect = 1;
- if (icg->ntables < 1)
- error ("Input file doesn't contain at least one table");
-
/* add table to output file */
if (isspect)
ocg->add_table(ocg, tt_other, 1);
@@ -416,14 +453,14 @@ main(int argc, char *argv[])
}
if (isspect) {
- if ((dti = icg->find_kword (icg, 0, "MEAS_TYPE")) < 0)
+ if ((ti = icg->find_kword (icg, 0, "MEAS_TYPE")) < 0)
error ("Input file doesn't contain keyword MEAS_TYPE");
/* Reflective options when not a reflective profile type */
- if (strcmp(icg->t[0].kdata[dti],"EMISSION") == 0
- || strcmp(icg->t[0].kdata[dti],"AMBIENT") == 0
- || strcmp(icg->t[0].kdata[dti],"EMISSION_FLASH") == 0
- || strcmp(icg->t[0].kdata[dti],"AMBIENT_FLASH") == 0) {
+ if (strcmp(icg->t[0].kdata[ti],"EMISSION") == 0
+ || strcmp(icg->t[0].kdata[ti],"AMBIENT") == 0
+ || strcmp(icg->t[0].kdata[ti],"EMISSION_FLASH") == 0
+ || strcmp(icg->t[0].kdata[ti],"AMBIENT_FLASH") == 0) {
isemis = 1;
if (illum != icxIT_none)
error("-i illuminant can't be used for emissive reference type");
@@ -434,12 +471,12 @@ main(int argc, char *argv[])
}
} else {
- if ((dti = icg->find_kword (icg, 0, "DEVICE_CLASS")) < 0)
+ if ((ti = icg->find_kword (icg, 0, "DEVICE_CLASS")) < 0)
error ("Input file doesn't contain keyword DEVICE_CLASS");
/* Reflective options when not a reflective profile type */
- if (strcmp(icg->t[0].kdata[dti],"DISPLAY") == 0
- || strcmp(icg->t[0].kdata[dti],"EMISINPUT") == 0) {
+ if (strcmp(icg->t[0].kdata[ti],"DISPLAY") == 0
+ || strcmp(icg->t[0].kdata[ti],"EMISINPUT") == 0) {
isemis = 1;
if (illum != icxIT_none)
error("-i illuminant can't be used for emissive reference type");
@@ -454,8 +491,38 @@ 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 the measurements were polarized */
+ if ((ti = icg->find_kword(icg, 0, "INSTRUMENT_FILTER")) >= 0
+ && strcmp(icg->t[0].kdata[ti], "POLARIZED") == 0) {
+ calpol = xcalstd_pol; /* If measurement is polarized */
+ }
+
+ /* See if there is an XRGA anotation in the incoming file */
+ if ((ti = icg->find_kword(icg, 0, "DEVCALSTD")) >= 0) {
+ calstd = str2xcalstd(icg->t[0].kdata[ti]);
+ }
+
+ /* Check XRGA conversion */
+ if (calstdo != xcalstd_none) {
+
+ if (isemis || isdisp)
+ error("XRGA conversion only applies to reflective measurements");
+
+ if (calstd != xcalstd_none
+ && calstd != calstdi) {
+ warning("Input file calibration standard '%s' doesn't match -A parameter '%s'",
+ xcalstd2str(calstd), xcalstd2str(calstdi));
+ }
+
+ /* Anotate output file */
+ if ((ti = ocg->find_kword (ocg, 0, "DEVCALSTD")) >= 0)
+ ocg->add_kword_at(ocg, 0, ti, "DEVCALSTD",xcalstd2str(calstdo), NULL);
+ else
+ ocg->add_kword(ocg, 0, "DEVCALSTD",xcalstd2str(calstdo), NULL);
+ }
/* See if the display CIE data has been normalised to Y = 100 */
{
@@ -477,7 +544,7 @@ main(int argc, char *argv[])
if ((ti = icg->find_kword(icg, 0, "COLOR_REP")) < 0)
error("Input file doesn't contain keyword COLOR_REP");
- if (strcmp (icg->t[0].kdata[dti], "DISPLAY") == 0) {
+ if (strcmp (icg->t[0].kdata[ti], "DISPLAY") == 0) {
isdisp = 1;
}
@@ -700,16 +767,16 @@ main(int argc, char *argv[])
}
/* If CIE calculation illuminant is not standard, compute it's white point */
- if (illum != icxIT_D50) {
+ if (illum != icxIT_D50 && illum != icxIT_none) {
ill_wp = _ill_wp;
- /* Compute XYZ of illuminant */
- if (icx_ill_sp2XYZ(ill_wp, observ, cust_observ, 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, cust_observ,
+ if ((sp2cie = new_xsp2cie(illum, &cust_illum, obType, custObserver,
icSigXYZData, icxClamp)) == NULL)
{
error ("Creation of spectral conversion object failed");
@@ -789,6 +856,10 @@ main(int argc, char *argv[])
for (j = 0; j < rmwsp.spec_n; j++) {
rmwsp.spec[j] /= nw; /* Compute average */
}
+
+ if (calstdo != xcalstd_none)
+ xspec_convert_xrga(&rmwsp, &rmwsp, calpol, calstdo, calstdi);
+
mwsp = rmwsp; /* Structure copy */
}
@@ -838,7 +909,7 @@ main(int argc, char *argv[])
printf("FWA content = %f\n",FWAc);
}
- /* Create an FWA compensated white spectrum and XYZ value */
+ /* Create an FWA compensated white spectrum and XYZ value */
sp2cie->sconvert (sp2cie, &rmwsp, mwXYZ, &mwsp);
}
@@ -895,6 +966,8 @@ main(int argc, char *argv[])
for (j = 0; j < sp.spec_n; j++) {
sp.spec[j] = *((double *)icg->t[0].fdata[i][spi[j]]);
}
+ if (calstdo != xcalstd_none)
+ xspec_convert_xrga(&sp, &sp, calpol, calstdo, calstdi);
if (fwacomp) {
corr_sp = sp; /* Copy spectrum */
diff --git a/spectro/specbos.c b/spectro/specbos.c
index 4c5e4ba..136fb34 100644..100755
--- a/spectro/specbos.c
+++ b/spectro/specbos.c
@@ -63,6 +63,7 @@
#include "sa_config.h"
#include "numsup.h"
#endif /* !SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -74,6 +75,9 @@ static inst_code specbos_interp_code(inst *pp, int ec);
#define MAX_MES_SIZE 500 /* Maximum normal message reply size */
#define MAX_RD_SIZE 8000 /* Maximum reading message reply size */
+#define DEFAULT_TRANS_NAV 10 /* Default transmission mode number of averages */
+#define DEFAULT_NAV 1 /* Default other mode number of averages */
+
/* Interpret an icoms error into a SPECBOS error */
static int icoms2specbos_err(int se) {
if (se != ICOM_OK) {
@@ -132,13 +136,18 @@ int nd /* nz to disable debug messages */
return icoms2specbos_err(se);
}
- /* Over Bluetooth, we get an erronious string "AT+JSCR\r\n" mixed in our output. */
+ /* Over Bluetooth, we get an erroneous string "AT+JSCR\r\n" mixed in our output. */
/* This would appear to be from the eBMU Bluetooth adapter AT command set. */
if (bread > 9 && strncmp(out, "AT+JSCR\r\n", 9) == 0) {
a1logd(p->log, 8, "specbos: ignored 'AT+JSCR\\r\\n' response\n");
memmove(out, out+9, bsize-9);
bread -= 9;
}
+ if (bread > 8 && strncmp(out, "AT+JSCR\r", 8) == 0) {
+ a1logd(p->log, 8, "specbos: ignored 'AT+JSCR\\r' response\n");
+ memmove(out, out+8, bsize-8);
+ bread -= 8;
+ }
/* See if there was an error, and remove any enquire codes */
for (dp = cp = out; *cp != '\000' && (dp - out) < bsize; cp++) {
@@ -221,7 +230,7 @@ specbos_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
unsigned int etime;
unsigned int len, i;
- instType itype = pp->itype;
+ instType dtype = pp->dtype;
int se;
inst_code ev = inst_ok;
@@ -250,6 +259,8 @@ specbos_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
return ev;
}
+ msec_sleep(600);
+
/* We need to setup communications */
} else {
int delayms = 0;
@@ -261,7 +272,7 @@ specbos_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
a1logd(p->log, 1, "specbos_init_coms: Trying different baud rates (%u msec to go)\n",etime - msec_time());
/* Spectraval Bluetooth serial doesn't seem to actuall function */
- /* until 600msec after it is opened. We get arroneos "AT+JSCR\r\n" reply */
+ /* until 600msec after it is opened. We get an erroneous "AT+JSCR\r\n" reply */
/* within that time, and it won't re-open after closing. */
if (p->icom->dctype & icomt_btserial)
delayms = 600;
@@ -321,8 +332,8 @@ specbos_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
p->model = 1201;
} else if ((len >= 10 && strncmp(buf, "JETI_SDCM3", 10) == 0)
|| (len >= 9 && strncmp(buf, "DCM3_JETI", 9) == 0)
- || (len >= 17 && strncmp(buf, "PECFIRM_JETI_1501", 18) == 0)
- || (len >= 18 && strncmp(buf, "SPECFIRM_JETI_1501", 17) == 0)) {
+ || (len >= 17 && strncmp(buf, "PECFIRM_JETI_1501", 17) == 0)
+ || (len >= 18 && strncmp(buf, "SPECFIRM_JETI_1501", 18) == 0)) {
p->model = 1501;
} else {
if (len < 11
@@ -342,22 +353,32 @@ specbos_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
}
a1logd(p->log, 2, "specbos_init_coms: init coms has suceeded\n");
- p->gotcoms = 1;
-
/* See if it's a 1501 or 1511 */
if (p->model == 1501) {
+ int i;
int dispen = 0;
- if ((ev = specbos_command(p, "*conf:dispen?\r", buf, MAX_MES_SIZE, 1.0)) != inst_ok) {
- amutex_unlock(p->lock);
- a1logd(p->log, 2, "specbos_init_coms: failed to get display status\n");
- return inst_protocol_error;
- }
- if (sscanf(buf, "%d ",&dispen) != 1) {
- amutex_unlock(p->lock);
- a1loge(p->log, 1, "specbos_init_inst: failed to parse display status\n");
- return ev;
+ /* Try a few times because of BT misbehaviour */
+ for (i = 0; i < 3; i++) {
+ if ((ev = specbos_command(p, "*conf:dispen?\r", buf, MAX_MES_SIZE, 1.0)) != inst_ok) {
+ if (i < 3)
+ continue;
+ amutex_unlock(p->lock);
+ a1logd(p->log, 2, "specbos_init_coms: failed to get display status\n");
+ return inst_protocol_error;
+ }
+
+ if (sscanf(buf, "%d ",&dispen) != 1) {
+ if (i < 3)
+ continue;
+ amutex_unlock(p->lock);
+ a1loge(p->log, 1, "specbos_init_inst: failed to parse display status\n");
+ return specbos_interp_code((inst *)p, SPECBOS_DATA_PARSE_ERROR);
+ } else {
+ break;
+ }
}
+
a1logd(p->log, 1, " spectraval %s display\n",dispen ? "has" : "doesn't have");
if (dispen) {
p->model = 1511;
@@ -393,6 +414,8 @@ specbos_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
}
#endif
+ p->gotcoms = 1;
+
amutex_unlock(p->lock);
return inst_ok;
}
@@ -559,25 +582,33 @@ specbos_init_inst(inst *pp) {
p->measto = 20.0; /* Set default. Specbos default is 60.0 */
if (p->model == 1211)
- p->measto = 6.0; /* Same overall time as i1d3 ?? */
+ p->measto = 6.0 + 3.6; /* Aprox. Same overall time as i1d3 ?? */
else if (p->model == 1201)
- p->measto = 16.0;
+ p->measto = 16.0 + 3.6;
else if (p->model == 1501 || p->model == 1511)
- p->measto = 6.0;
+ p->measto = 6.0 + 3.6;
/* Implement max auto int. time, to speed up display measurement */
if (p->model == 1501 || p->model == 1511) {
+#ifdef NEVER /* Bound auto by integration time (worse for inttime > 1.0) */
int maxaver = 2; /* Maximum averages for auto int time */
double dmaxtint;
int maxtint;
/* Actual time taken depends on maxtint, autoavc & fudge factor. */
- dmaxtint = p->measto/(maxaver + 3.5);
+ dmaxtint = (p->measto - 3.6)/(2.0 * maxaver);
+
+ //printf("dmaxtint %f\n",dmaxtint);
maxtint = (int)(dmaxtint * 1000.0+0.5);
- if (maxtint < 1000 || maxtint > 64999)
- error("specbos: assert, maxtint %d out of range",maxtint);
+ if (maxtint < 1000 || maxtint > 64999) {
+ warning("specbos: assert, maxtint %d out of range",maxtint);
+ if (maxtint < 1000)
+ maxtint = 1000;
+ else if (maxtint > 64999)
+ maxtint = 64999;
+ }
/* Set maximum integration time */
sprintf(mes, "*para:maxtint %d\r", maxtint);
@@ -592,6 +623,45 @@ specbos_init_inst(inst *pp) {
amutex_unlock(p->lock);
return ev;
}
+#else /* Bound auto by no. averages (better - limit maxint to 1.0) */
+ double dmaxtint = 1.0; /* Recommended maximum */
+ int maxtint;
+ int maxaver; /* Maximum averages for auto int time */
+
+ maxtint = (int)(dmaxtint * 1000.0+0.5);
+
+ if (maxtint < 1000 || maxtint > 64999) {
+ warning("specbos: assert, maxtint %d out of range",maxtint);
+ if (maxtint < 1000)
+ maxtint = 1000;
+ else if (maxtint > 64999)
+ maxtint = 64999;
+ }
+
+ /* Set maximum integration time */
+ sprintf(mes, "*para:maxtint %d\r", maxtint);
+ if ((ev = specbos_command(p, mes, buf, MAX_MES_SIZE, 1.0)) != inst_ok) {
+ amutex_unlock(p->lock);
+ return ev;
+ }
+
+ /* Total time = overhead + initial sample + 2 * int time per measure */
+ maxaver = (int)ceil((p->measto - 3.6)/(2.0 * dmaxtint));
+
+ //printf("maxaver %d\n",maxaver);
+
+ if (maxaver < 2) {
+ warning("specbos: assert, maxaver %d out of range",maxaver);
+ maxaver = 2;
+ }
+
+ /* Set maximum number of auto averages. Min value is 2 */
+ sprintf(mes, "*para:maxaver %d\r", maxaver);
+ if ((ev = specbos_command(p, mes, buf, MAX_MES_SIZE, 1.0)) != inst_ok) {
+ amutex_unlock(p->lock);
+ return ev;
+ }
+#endif
/* spectraval doesn't support *fetch:XYZ command */
p->noXYZ = 1;
@@ -600,38 +670,69 @@ specbos_init_inst(inst *pp) {
double dmaxtin;
int maxtin;
- dmaxtin = p->measto/2.5; /* Fudge factor */
+ /* Total time = overhead + initial sample + 2 * int time per measure */
+ dmaxtin = (p->measto - 3.6)/2.0; /* Fudge factor */
+
maxtin = (int)(dmaxtin * 1000.0+0.5);
- if (maxtin < 1000 || maxtin > 64999)
- error("specbos: assert, maxtin %d out of range",maxtin);
+ if (maxtin < 1000 || maxtin > 64999) {
+ warning("specbos: assert, maxtint %d out of range",maxtin);
+ if (maxtin < 1000)
+ maxtin = 1000;
+ else if (maxtin > 64999)
+ maxtin = 64999;
+ }
/* Set maximum integration time */
- sprintf(mes, "*para:maxtint %d\r", maxtin);
+ /* (1201 *para:maxtint doesn't work !!) */
+ sprintf(mes, "*conf:maxtin %d\r", maxtin);
+ if ((ev = specbos_command(p, mes, buf, MAX_MES_SIZE, 1.0)) != inst_ok) {
+ amutex_unlock(p->lock);
+ return ev;
+ }
+
+#ifdef NEVER /* Use default */
+ /* Set split time to limit dark current error for long integration times */
+ sprintf(mes, "*para:splitt %d\r", 1000);
if ((ev = specbos_command(p, mes, buf, MAX_MES_SIZE, 1.0)) != inst_ok) {
amutex_unlock(p->lock);
return ev;
}
+#endif
+
}
if (p->model == 1501 || p->model == 1511) {
+ int i;
int wstart, wend, wstep;
- /* Set the measurement format to None. We will read measurement manually. */
- /* (0 = None, 1 = Binary, 2 = ASCII) */
- if ((ev = specbos_command(p, "*para:form 0\r", buf, MAX_MES_SIZE, 1.0)) != inst_ok) {
- amutex_unlock(p->lock);
- return ev;
- }
+ /* Try several times due to BT problems */
+ for (i = 0; i < 3; i++) {
+ /* Set the measurement format to None. We will read measurement manually. */
+ /* (0 = None, 1 = Binary, 2 = ASCII) */
+ if ((ev = specbos_command(p, "*para:form 0\r", buf, MAX_MES_SIZE, 1.0)) != inst_ok) {
+ if (i < 3)
+ continue;
+ amutex_unlock(p->lock);
+ return ev;
+ }
- if ((ev = specbos_command(p, "*para:wran?\r", buf, MAX_MES_SIZE, 1.0)) != inst_ok) {
- amutex_unlock(p->lock);
- return ev;
- }
- if (sscanf(buf, "%d %d %d",&wstart,&wend,&wstep) != 3) {
- amutex_unlock(p->lock);
- a1loge(p->log, 1, "specbos_init_inst: failed to parse wavelength range\n");
- return ev;
+ if ((ev = specbos_command(p, "*para:wran?\r", buf, MAX_MES_SIZE, 1.0)) != inst_ok) {
+ if (i < 3)
+ continue;
+ amutex_unlock(p->lock);
+ return ev;
+ }
+ if (sscanf(buf, "%d %d %d",&wstart,&wend,&wstep) != 3) {
+ if (i < 3)
+ continue;
+ amutex_unlock(p->lock);
+ a1loge(p->log, 1, "specbos_init_inst: failed to parse wavelength range\n");
+ return specbos_interp_code((inst *)p, SPECBOS_DATA_PARSE_ERROR);
+
+ } else {
+ break;
+ }
}
p->wl_short = (double)wstart;
@@ -679,7 +780,7 @@ specbos_init_inst(inst *pp) {
if (sscanf(buf, "Predefined start wave: %lf ",&p->wl_short) != 1) {
amutex_unlock(p->lock);
a1loge(p->log, 1, "specbos_init_inst: failed to parse start wave\n");
- return ev;
+ return specbos_interp_code((inst *)p, SPECBOS_DATA_PARSE_ERROR);
}
a1logd(p->log, 1, " Short wl range %f\n",p->wl_short);
@@ -690,7 +791,7 @@ specbos_init_inst(inst *pp) {
if (sscanf(buf, "Predefined end wave: %lf ",&p->wl_long) != 1) {
amutex_unlock(p->lock);
a1loge(p->log, 1, "specbos_init_inst: failed to parse end wave\n");
- return ev;
+ return specbos_interp_code((inst *)p, SPECBOS_DATA_PARSE_ERROR);
}
if (p->wl_long > 830.0) /* Could go to 1000 with 1211 */
p->wl_long = 830.0; /* Limit it to useful visual range */
@@ -807,13 +908,13 @@ specbos_get_target_laser(
}
if (p->model == 1501 || p->model == 1511) {
if (sscanf(buf, "%d ",&lstate) != 1) {
- a1loge(p->log, 2, "specbos_get_target_laser: failed to parse laser state\n");
- return inst_protocol_error;
+ a1logd(p->log, 1, "specbos_get_target_laser: failed to parse laser state\n");
+ return specbos_interp_code((inst *)p, SPECBOS_DATA_PARSE_ERROR);
}
} else {
if (sscanf(buf, "laser: %d ",&lstate) != 1) {
- a1loge(p->log, 2, "specbos_get_target_laser: failed to parse laser state\n");
- return inst_protocol_error;
+ a1logd(p->log, 1, "specbos_get_target_laser: failed to parse laser state\n");
+ return specbos_interp_code((inst *)p, SPECBOS_DATA_PARSE_ERROR);
}
}
*laser = lstate;
@@ -956,9 +1057,18 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
}
}
+ /* If we have a requested number of averages */
+ if (p->noaverage != 0) {
+ if ((rv = set_average(p, p->noaverage, 0)) != inst_ok)
+ return rv;
+
/* Set to average 10 readings for transmission */
- if ((p->mode & inst_mode_illum_mask) == inst_mode_transmission) {
- if ((rv = set_average(p, 10, 0)) != inst_ok)
+ } else if ((p->mode & inst_mode_illum_mask) == inst_mode_transmission) {
+ if ((rv = set_average(p, DEFAULT_TRANS_NAV, 0)) != inst_ok)
+ return rv;
+ /* Or default 1 otherwise */
+ } else {
+ if ((rv = set_average(p, DEFAULT_NAV, 0)) != inst_ok)
return rv;
}
@@ -1037,7 +1147,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
&val->XYZ[0], &val->XYZ[1], &val->XYZ[2]) != 3) {
amutex_unlock(p->lock);
a1logd(p->log, 1, "specbos_read_sample: failed to parse '%s'\n",buf);
- return inst_protocol_error;
+ return specbos_interp_code((inst *)p, SPECBOS_DATA_PARSE_ERROR);
}
/* Hmm. Some older firmware versions are reported to not support the */
@@ -1048,7 +1158,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
p->noXYZ = 1;
if (p->model == 1501 || p->model == 1511) {
- if ((ec = specbos_fcommand(p, "*calc:PHOTOmetric\r", buf, MAX_RD_SIZE, 0.5, 1, tnorm, 0))
+ if ((ec = specbos_fcommand(p, "*calc:PHOTOmetric\r", buf, MAX_RD_SIZE, 1.0, 1, tnorm, 0))
!= SPECBOS_OK) {
amutex_unlock(p->lock);
return specbos_interp_code((inst *)p, ec);
@@ -1056,7 +1166,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
if (sscanf(buf, "%lf ", &Yxy[0]) != 1) {
amutex_unlock(p->lock);
a1logd(p->log, 1, "specbos_read_sample: failed to parse '%s'\n",buf);
- return inst_protocol_error;
+ return specbos_interp_code((inst *)p, SPECBOS_DATA_PARSE_ERROR);
}
} else {
if ((ec = specbos_fcommand(p, "*fetch:PHOTOmetric\r", buf, MAX_RD_SIZE, 0.5, 1, tnorm, 0))
@@ -1067,7 +1177,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
if (sscanf(buf, "Luminance[cd/m^2]: %lf ", &Yxy[0]) != 1) {
amutex_unlock(p->lock);
a1logd(p->log, 1, "specbos_read_sample: failed to parse '%s'\n",buf);
- return inst_protocol_error;
+ return specbos_interp_code((inst *)p, SPECBOS_DATA_PARSE_ERROR);
}
}
@@ -1080,7 +1190,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
if (sscanf(buf, " %lf %lf ", &Yxy[1], &Yxy[2]) != 2) {
amutex_unlock(p->lock);
a1logd(p->log, 1, "specbos_read_sample: failed to parse '%s'\n",buf);
- return inst_protocol_error;
+ return specbos_interp_code((inst *)p, SPECBOS_DATA_PARSE_ERROR);
}
} else {
if ((ec = specbos_fcommand(p, "*fetch:CHROMXY\r", buf, MAX_RD_SIZE, 0.5, 1, tnorm, 0))
@@ -1147,10 +1257,10 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
/* Fetch the spectral readings */
if (p->model == 1501 || p->model == 1511)
- ec = specbos_fcommand(p, "*calc:sprad\r", buf, MAX_RD_SIZE, 4.0,
+ ec = specbos_fcommand(p, "*calc:sprad\r", buf, MAX_RD_SIZE, 6.0,
1, tspec, 0);
else
- ec = specbos_fcommand(p, "*fetch:sprad\r", buf, MAX_RD_SIZE, 4.0,
+ ec = specbos_fcommand(p, "*fetch:sprad\r", buf, MAX_RD_SIZE, 6.0,
2+p->nbands+1, tnorm, 0);
if (ec != SPECBOS_OK) {
a1logd(p->log, 1, "specbos_fcommand: failed with 0x%x\n",ec);
@@ -1196,7 +1306,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
try_again:;
}
if (tries >= maxtries) {
- a1logd(p->log, 1, "specbos_fcommand: ran out of retries\n");
+ a1logd(p->log, 1, "specbos_fcommand: ran out of retries - parsing error ?\n");
amutex_unlock(p->lock);
return inst_protocol_error;
}
@@ -1616,7 +1726,7 @@ char id[CALIDLEN] /* Condition identifier (ie. white reference ID) */
p->mode = inst_mode_emis_tele | inst_mode_spectral;
p->doing_cal = 1;
- /* Set to average 50 readings */
+ /* Set to average 50 readings for calibration */
if ((ev = set_average(p, 50, 1)) != inst_ok)
return ev;
@@ -1982,9 +2092,9 @@ specbos_del(inst *pp) {
if (p->th != NULL) { /* Terminate diffuser monitor thread */
int i;
p->th_term = 1; /* Tell thread to exit on error */
- for (i = 0; p->th_termed == 0 && i < 5; i++)
+ for (i = 0; p->th_termed == 0 && i < 50; i++)
msec_sleep(100); /* Wait for thread to terminate */
- if (i >= 5) {
+ if (i >= 50) {
a1logd(p->log,3,"specbos diffuser thread termination failed\n");
}
p->th->del(p->th);
@@ -2007,6 +2117,7 @@ inst3_capability *pcap3) {
specbos *p = (specbos *)pp;
inst_mode cap1 = 0;
inst2_capability cap2 = 0;
+ inst3_capability cap3 = 0;
cap1 |= inst_mode_emis_tele
| inst_mode_trans_spot /* Emulated transmission mode diffuse/90 */
@@ -2034,12 +2145,15 @@ inst3_capability *pcap3) {
cap2 |= inst2_get_refresh_rate;
}
+ /* Can average multiple measurements */
+ cap3 |= inst3_average;
+
if (pcap1 != NULL)
*pcap1 = cap1;
if (pcap2 != NULL)
*pcap2 = cap2;
if (pcap3 != NULL)
- *pcap3 = inst3_none;
+ *pcap3 = cap3;
}
/* Return current or given configuration available measurement modes. */
@@ -2368,6 +2482,24 @@ specbos_get_set_opt(inst *pp, inst_opt_type m, ...) {
if (!p->inited)
return inst_no_init;
+ if (m == inst_opt_set_averages) {
+ va_list args;
+ int nav = 1;
+
+ va_start(args, m);
+ nav = va_arg(args, int);
+ va_end(args);
+
+ if (nav < 0)
+ return inst_bad_parameter;
+
+ p->noaverage = nav;
+
+ /* Averages will get set before each measurement */
+
+ return inst_ok;
+ }
+
/* Use default implementation of other inst_opt_type's */
{
inst_code rv;
@@ -2382,7 +2514,7 @@ specbos_get_set_opt(inst *pp, inst_opt_type m, ...) {
}
/* Constructor */
-extern specbos *new_specbos(icoms *icom, instType itype) {
+extern specbos *new_specbos(icoms *icom, instType dtype) {
specbos *p;
if ((p = (specbos *)calloc(sizeof(specbos),1)) == NULL) {
a1loge(icom->log, 1, "new_specbos: malloc failed!\n");
@@ -2410,12 +2542,14 @@ extern specbos *new_specbos(icoms *icom, instType itype) {
p->del = specbos_del;
p->icom = icom;
- p->itype = itype;
- if (p->itype == instSpecbos1201)
+ p->dtype = dtype;
+ if (p->dtype == instSpecbos1201)
p->model = 1201;
amutex_init(p->lock);
+ p->noaverage = 1;
+
return p;
}
diff --git a/spectro/specbos.h b/spectro/specbos.h
index 5c89fd5..ef6fc2f 100644..100755
--- a/spectro/specbos.h
+++ b/spectro/specbos.h
@@ -160,6 +160,9 @@ struct _specbos {
int doing_cal; /* Flag - doing internal calibration measure */
/* Other state */
+ int noaverage; /* Current setting of number of measurements to average */
+ /* 0 for default */
+
athread *th; /* Diffuser position monitoring thread */
volatile int th_term; /* nz to terminate thread */
volatile int th_termed; /* nz when thread terminated */
diff --git a/spectro/spotread.c b/spectro/spotread.c
index c5ac955..16f6f2d 100644..100755
--- a/spectro/spotread.c
+++ b/spectro/spotread.c
@@ -277,7 +277,7 @@ usage(char *diag, ...) {
#ifndef SALONEINSTLIB
fprintf(stderr," -S Plot spectrum for each reading\n");
#endif /* !SALONEINSTLIB */
- fprintf(stderr," -c listno Set communication port from the following list (default %d)\n",COMPORT);
+ fprintf(stderr," -c listno Set instrument port from the following list (default %d)\n",COMPORT);
if ((icmps = new_icompaths(g_log)) != NULL) {
icompath **paths;
if ((paths = icmps->paths) != NULL) {
@@ -286,8 +286,8 @@ usage(char *diag, ...) {
if (paths[i] == NULL)
break;
#if !defined(NOT_ALLINSTS) || defined(EN_SPYD2)
- if ((paths[i]->itype == instSpyder1 && setup_spyd2(0) == 0)
- || (paths[i]->itype == instSpyder2 && setup_spyd2(1) == 0))
+ if ((paths[i]->dtype == instSpyder1 && setup_spyd2(0) == 0)
+ || (paths[i]->dtype == instSpyder2 && setup_spyd2(1) == 0))
fprintf(stderr," %d = '%s' !! Disabled - no firmware !!\n",i+1,paths[i]->name);
else
#endif
@@ -318,9 +318,9 @@ usage(char *diag, ...) {
#endif
fprintf(stderr," -Q observ Choose CIE Observer for spectral data or CCSS instrument:\n");
#ifndef SALONEINSTLIB
- 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");
#else
- fprintf(stderr," 1931_2 (def), 1964_10\n");
+ fprintf(stderr," 1931_2 (def), 1964_10, 2012_2, 2012_10 or file.cmf\n");
#endif
#ifndef SALONEINSTLIB
fprintf(stderr," (Choose FWA during operation)\n");
@@ -334,6 +334,9 @@ usage(char *diag, ...) {
fprintf(stderr," -A N|A|X|G XRGA conversion (default N)\n");
fprintf(stderr," -x Display Yxy instead of Lab\n");
fprintf(stderr," -h Display LCh instead of Lab\n");
+#ifndef SALONEINSTLIB
+ fprintf(stderr," -u Display Yuv instead of Lab\n");
+#endif
fprintf(stderr," -V Show running average and std. devation from ref.\n");
#ifndef SALONEINSTLIB
fprintf(stderr," -T Display correlated color temperatures, CRI and TLCI\n");
@@ -354,6 +357,7 @@ usage(char *diag, ...) {
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 l|L Test for i1Pro Lamp Drift (l), and remediate it (L)\n");
+ fprintf(stderr," -Y a Use Averaging mode (if available).\n");
// fprintf(stderr," -Y U Test i1pro2 UV measurement mode\n");
#ifndef SALONEINSTLIB
fprintf(stderr," -Y W:fname.sp Save white tile ref. spectrum to file\n");
@@ -389,8 +393,12 @@ int main(int argc, char *argv[]) {
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 averagemode = 0; /* Use averaging mode if available */
int doYxy= 0; /* Display Yxy instead of Lab */
int doLCh= 0; /* Display LCh instead of Lab */
+#ifndef SALONEINSTLIB
+ int doYuv= 0; /* Display Yuv instead of Lab */
+#endif
int doCCT= 0; /* Display correlated color temperatures */
inst_mode mode = 0, smode = 0; /* Normal mode and saved readings mode */
inst_opt_type trigmode = inst_opt_unknown; /* Chosen trigger mode */
@@ -423,6 +431,7 @@ int main(int argc, char *argv[]) {
icxIllumeType illum = icxIT_D50; /* Spectral defaults */
xspect cust_illum; /* Custom illumination spectrum */
icxObserverType obType = icxOT_default;
+ xspect custObserver[3]; /* If obType = icxOT_custom */
xspect sp; /* Last spectrum read */
xspect rsp; /* Reference spectrum */
xsp2cie *sp2cie = NULL; /* default conversion */
@@ -435,6 +444,9 @@ int main(int argc, char *argv[]) {
double rLab[3] = { -10.0, 0, 0}; /* Reference Lab */
double Yxy[3] = { 0.0, 0, 0}; /* Yxy value */
double LCh[3] = { 0.0, 0, 0}; /* LCh value */
+#ifndef SALONEINSTLIB
+ double Yuv[3] = { 0.0, 0, 0}; /* Yuv value */
+#endif
double refstats = 0; /* Print running avg & stddev against ref */
double rstat_n; /* Stats N */
double rstat_XYZ[3]; /* Stats sum of XYZ's */
@@ -616,6 +628,10 @@ 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;
+ } else if (strcmp(na, "2012_2") == 0) { /* Latest 2 degree */
+ obType = icxOT_CIE_2012_2;
+ } else if (strcmp(na, "2012_10") == 0) { /* Latest 10 degree */
+ obType = icxOT_CIE_2012_10;
#ifndef SALONEINSTLIB
} else if (strcmp(na, "1955_2") == 0) { /* Stiles and Burch 1955 2 degree */
obType = icxOT_Stiles_Burch_2;
@@ -624,8 +640,11 @@ int main(int argc, char *argv[]) {
} else if (strcmp(na, "shaw") == 0) { /* Shaw and Fairchilds 1997 2 degree */
obType = icxOT_Shaw_Fairchild_2;
#endif /* !SALONEINSTLIB */
- } else
- usage("Spectral observer type '%s' not recognised",na);
+ } else {
+ obType = icxOT_custom;
+ if (read_cmf(custObserver, na) != 0)
+ usage(0,"Failed to read custom observer CMF from -Q file '%s'",na);
+ }
/* Request transmission measurement */
} else if (argv[fa][1] == 't') {
@@ -730,11 +749,25 @@ int main(int argc, char *argv[]) {
} else if (argv[fa][1] == 'x') {
doYxy = 1;
doLCh = 0;
+#ifndef SALONEINSTLIB
+ doYuv = 0;
+#endif
/* Show LCh */
} else if (argv[fa][1] == 'h') {
doYxy = 0;
doLCh = 1;
+#ifndef SALONEINSTLIB
+ doYuv = 0;
+#endif
+
+#ifndef SALONEINSTLIB
+ /* Show Yuv */
+ } else if (argv[fa][1] == 'u') {
+ doYxy = 0;
+ doLCh = 0;
+ doYuv = 1;
+#endif
/* Compute running average and standard deviation from ref. */
/* Also turns off clamping */
@@ -792,6 +825,8 @@ int main(int argc, char *argv[]) {
if (na[0] == 'A') {
nadaptive = 1;
+ } else if (na[0] == 'a') {
+ averagemode = 1;
} else if (na[0] == 'r') {
refrmode = 1;
} else if (na[0] == 'n') {
@@ -936,8 +971,8 @@ int main(int argc, char *argv[]) {
double remtime = 0.0;
int cooltime = 30;
- if (it->itype != instI1Pro
- && it->itype != instI1Pro2) {
+ if (it->dtype != instI1Pro
+ && it->dtype != instI1Pro2) {
printf("LampDrift is only applicable to i1Pro instrument");
}
@@ -1289,6 +1324,18 @@ int main(int argc, char *argv[]) {
}
it->capabilities(it, &cap, &cap2, &cap3);
+ /* If requested, average several readings (i.e. JETI 1211) */
+ if (averagemode) {
+ if (!IMODETST(cap3, inst3_average)) {
+ if (verb)
+ printf("Requested averaging mode and instrument doesn't support it (ignored)\n");
+ averagemode = 0;
+ } else if ((rv = it->get_set_opt(it, inst_opt_set_averages, 10)) != inst_ok) {
+ printf("Setting no of averages to 10 failed with '%s' (%s) !!!\n",
+ it->inst_interp_error(it, rv), it->interp_error(it, rv));
+ }
+ }
+
/* Apply Extra filter compensation */
if (filtername[0] != '\000') {
if ((rv = it->comp_filter(it, filtername)) != inst_ok) {
@@ -1356,7 +1403,7 @@ int main(int argc, char *argv[]) {
it->del(it);
return -1;
}
- if ((rv = it->get_set_opt(it, inst_opt_set_ccss_obs, obType, NULL)) != inst_ok) {
+ if ((rv = it->get_set_opt(it, inst_opt_set_ccss_obs, obType, custObserver)) != inst_ok) {
printf("\nSetting CCS Observer failed with error :'%s' (%s)\n",
it->inst_interp_error(it, rv), it->interp_error(it, rv));
cs->del(cs);
@@ -1392,7 +1439,7 @@ int main(int argc, char *argv[]) {
/* 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) {
+ if ((rv = it->get_set_opt(it, inst_opt_set_ccss_obs, obType, custObserver)) != inst_ok) {
printf("\nSetting CCSS Observer failed with error :'%s' (%s)\n",
it->inst_interp_error(it, rv), it->interp_error(it, rv));
it->del(it);
@@ -1500,7 +1547,7 @@ int main(int argc, char *argv[]) {
illum = icxIT_none;
/* Create a spectral conversion object */
- if ((sp2cie = new_xsp2cie(illum, &cust_illum, obType, NULL, icSigXYZData,
+ if ((sp2cie = new_xsp2cie(illum, &cust_illum, obType, custObserver, icSigXYZData,
refstats ? icxNoClamp : icxClamp)) == NULL)
error("Creation of spectral conversion object failed");
@@ -1573,6 +1620,7 @@ int main(int argc, char *argv[]) {
#ifndef SALONEINSTLIB
double cct, vct, vdt;
double cct_de, vct_de, vdt_de;
+ double cct_sn, vct_sn, vdt_sn; /* Sign: 1 + above, -1 = below */
#endif /* !SALONEINSTLIB */
int ch = '0'; /* Character */
int sufwa = 0; /* Setup for FWA compensation */
@@ -2087,6 +2135,9 @@ int main(int argc, char *argv[]) {
if (ch == 'K' || ch == 'k') { /* Do a calibration */
inst_code ev;
+ /* Should we do a get_n_a_cals() first, so we can abort */
+ /* if no calibrations are available ?? */
+
printf("\nDoing a calibration\n");
/* save current location */
@@ -2265,7 +2316,7 @@ int main(int argc, char *argv[]) {
/* Creat the base conversion object */
if (sp2cief[fidx] == NULL) {
if ((sp2cief[fidx] = new_xsp2cie(illum, &cust_illum, obType,
- NULL, icSigXYZData, refstats ? icxNoClamp : icxClamp)) == NULL)
+ custObserver, icSigXYZData, refstats ? icxNoClamp : icxClamp)) == NULL)
error("Creation of spectral conversion object failed");
}
@@ -2404,24 +2455,36 @@ int main(int argc, char *argv[]) {
icmXYZNumber wp;
double nxyz[3], axyz[3];
double lab[3], alab[3];
+ double yxy[3], ayxy[3];
+ /* Y normalized sample */
nxyz[0] = XYZ[0] / XYZ[1];
nxyz[2] = XYZ[2] / XYZ[1];
nxyz[1] = XYZ[1] / XYZ[1];
/* Compute CCT */
- if ((cct = icx_XYZ2ill_ct(axyz, icxIT_Ptemp, obType, NULL, XYZ, NULL, 0)) < 0)
+ if ((cct = icx_XYZ2ill_ct(axyz, icxIT_Ptemp, obType, custObserver, nxyz, NULL, 0)) < 0)
error ("Got bad cct\n");
axyz[0] /= axyz[1];
axyz[2] /= axyz[1];
axyz[1] /= axyz[1];
- icmAry2XYZ(wp, axyz);
- icmXYZ2Lab(&wp, lab, nxyz);
- icmXYZ2Lab(&wp, alab, axyz);
- cct_de = icmLabDE(lab, alab);
+ icmXYZ21960UCS(lab, nxyz);
+ icmXYZ21960UCS(alab, axyz);
+ cct_de = sqrt((lab[1] - alab[1]) * (lab[1] - alab[1])
+ + (lab[2] - alab[2]) * (lab[2] - alab[2]));
+
+
+ cct_sn = 1.0;
+ icmXYZ2Yxy(yxy, nxyz);
+ icmXYZ2Yxy(ayxy, axyz);
+ /* Dot product of vector from aprox. locus curve "center" */
+ /* xy 0.5, 0.25 with vector from */
+ if ((yxy[1] - ayxy[1]) * (ayxy[1] - 0.5)
+ + (yxy[2] - ayxy[2]) * (ayxy[2] - 0.25) < 0.0)
+ cct_sn = -1.0;
/* Compute VCT */
- if ((vct = icx_XYZ2ill_ct(axyz, icxIT_Ptemp, obType, NULL, XYZ, NULL, 1)) < 0)
+ if ((vct = icx_XYZ2ill_ct(axyz, icxIT_Ptemp, obType, custObserver, nxyz, NULL, 1)) < 0)
error ("Got bad vct\n");
axyz[0] /= axyz[1];
axyz[2] /= axyz[1];
@@ -2429,10 +2492,17 @@ int main(int argc, char *argv[]) {
icmAry2XYZ(wp, axyz);
icmXYZ2Lab(&wp, lab, nxyz);
icmXYZ2Lab(&wp, alab, axyz);
- vct_de = icmLabDE(lab, alab);
-
+ vct_de = icmCIE2K(lab, alab);
+
+ vct_sn = 1.0;
+ icmXYZ2Yxy(yxy, nxyz);
+ icmXYZ2Yxy(ayxy, axyz);
+ if ((yxy[1] - ayxy[1]) * (ayxy[1] - 0.5)
+ + (yxy[2] - ayxy[2]) * (ayxy[2] - 0.25) < 0.0)
+ vct_sn = -1.0;
+
/* Compute VDT */
- if ((vdt = icx_XYZ2ill_ct(axyz, icxIT_Dtemp, obType, NULL, XYZ, NULL, 1)) < 0)
+ if ((vdt = icx_XYZ2ill_ct(axyz, icxIT_Dtemp, obType, custObserver, nxyz, NULL, 1)) < 0)
error ("Got bad vct\n");
axyz[0] /= axyz[1];
axyz[2] /= axyz[1];
@@ -2440,7 +2510,14 @@ int main(int argc, char *argv[]) {
icmAry2XYZ(wp, axyz);
icmXYZ2Lab(&wp, lab, nxyz);
icmXYZ2Lab(&wp, alab, axyz);
- vdt_de = icmLabDE(lab, alab);
+ vdt_de = icmCIE2K(lab, alab);
+
+ vdt_sn = 1.0;
+ icmXYZ2Yxy(yxy, nxyz);
+ icmXYZ2Yxy(ayxy, axyz);
+ if ((yxy[1] - ayxy[1]) * (ayxy[1] - 0.5)
+ + (yxy[2] - ayxy[2]) * (ayxy[2] - 0.25) < 0.0)
+ vdt_sn = -1.0;
}
/* Compute D50 Lab from XYZ */
@@ -2452,6 +2529,9 @@ int main(int argc, char *argv[]) {
/* Compute LCh from Lab */
icmLab2LCh(LCh, Lab);
+ /* Compute D50 Yuv from XYZ */
+ icmXYZ21976UCS(Yuv, XYZ);
+
#else /* SALONEINSTLIB */
/* Compute D50 Lab from XYZ */
XYZ2Lab(Lab, XYZ);
@@ -2503,6 +2583,9 @@ int main(int argc, char *argv[]) {
/* recompute LCh from Lab */
icmLab2LCh(LCh, Lab);
+
+ /* recompute Yuv */
+ icmXYZ21976UCS(Yuv, XYZ);
#else /* SALONEINSTLIB */
else {
@@ -2534,6 +2617,12 @@ int main(int argc, char *argv[]) {
/* Print out the XYZ and LCh */
printf("\n Result is XYZ: %f %f %f, LCh: %f %f %f\n",
XYZ[0], XYZ[1], XYZ[2], LCh[0], LCh[1], LCh[2]);
+#ifndef SALONEINSTLIB
+ } else if (doYuv) {
+ /* Print out the XYZ and Yuv */
+ printf("\n Result is XYZ: %f %f %f, Yuv: %f %f %f\n",
+ XYZ[0], XYZ[1], XYZ[2], Yuv[0], Yuv[1], Yuv[2]);
+#endif
} else {
/* Print out the XYZ and Lab */
printf("\n Result is XYZ: %f %f %f, D50 Lab: %f %f %f\n",
@@ -2588,15 +2677,15 @@ int main(int argc, char *argv[]) {
log(XYZ[1]/2.5)/log(2.0));
} else {
#ifndef SALONEINSTLIB
- printf(" Ambient = %.1f Lux%s, CCT = %.0fK (Delta E %f)\n",
+ printf(" Ambient = %.1f Lux%s, CCT = %.0fK (Duv %.4f)\n",
XYZ[1], ambient == 2 ? "-Seconds" : "",
- cct, cct_de);
+ cct, cct_sn * cct_de);
if (ambient != 2)
printf(" Suggested EV @ ISO100 for %.1f Lux incident light = %.1f\n",
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);
+ printf(" Closest Planckian temperature = %.0fK (DE2K %.1f)\n",vct, vct_sn * vct_de);
+ printf(" Closest Daylight temperature = %.0fK (DE2K %.1f)\n",vdt, vdt_sn * vdt_de);
#else /* SALONEINSTLIB */
printf(" Ambient = %.1f Lux%s\n",
XYZ[1], ambient == 2 ? "-Seconds" : "");
@@ -2604,9 +2693,9 @@ int main(int argc, char *argv[]) {
}
#ifndef SALONEINSTLIB
} else if (doCCT) {
- printf(" CCT = %.0fK (Delta E %f)\n",cct, cct_de);
- printf(" Closest Planckian temperature = %.0fK (Delta E %f)\n",vct, vct_de);
- printf(" Closest Daylight temperature = %.0fK (Delta E %f)\n",vdt, vdt_de);
+ printf(" CCT = %.0fK (Duv %.4f)\n",cct, cct_sn * cct_de);
+ printf(" Closest Planckian temperature = %.0fK (DE2K %.1f)\n",vct, vct_sn * vct_de);
+ printf(" Closest Daylight temperature = %.0fK (DE2K %.1f)\n",vdt, vdt_sn * vdt_de);
#endif
}
#ifndef SALONEINSTLIB
@@ -2616,7 +2705,7 @@ int main(int argc, char *argv[]) {
double cri;
cri = icx_CIE1995_CRI(&invalid, RR, &sp);
printf(" Color Rendering Index (Ra) = %.1f [ R9 = %.1f ]%s\n",
- cri, RR[9-1], invalid ? " (Invalid)" : "");
+ cri, RR[9-1], invalid ? " (Caution)" : "");
for (i = 0; i < 14; i++) {
printf(" R%d%s = %.1f", i+1, i < 9 ? " " : "", RR[i]);
if (i == 6)
@@ -2628,7 +2717,7 @@ int main(int argc, char *argv[]) {
int invalid = 0;
double tlci;
tlci = icx_EBU2012_TLCI(&invalid, &sp);
- printf(" Television Lighting Consistency Index 2012 (Qa) = %.1f%s\n",tlci,invalid ? " (Invalid)" : "");
+ printf(" Television Lighting Consistency Index 2012 (Qa) = %.1f%s\n",tlci,invalid ? " (Caution)" : "");
}
#endif
diff --git a/spectro/spyd2.c b/spectro/spyd2.c
index 85a2d7f..28051f3 100644..100755
--- a/spectro/spyd2.c
+++ b/spectro/spyd2.c
@@ -95,6 +95,7 @@
#include "sa_config.h"
#include "numsup.h"
#endif /* SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -2677,7 +2678,7 @@ spyd2_download_pld(
int i;
int id;
- if (p->itype == instSpyder1)
+ if (p->dtype == instSpyder1)
id = 0;
else
id = 1;
@@ -2748,7 +2749,7 @@ spyd4_load_cal(spyd2 *p) {
for (;;) { /* So we can break */
- if ((no_paths = xdg_bds(NULL, &bin_paths, xdg_data, xdg_read, xdg_user,
+ if ((no_paths = xdg_bds(NULL, &bin_paths, xdg_data, xdg_read, xdg_user, xdg_none,
"ArgyllCMS/spyd4cal.bin" XDG_FUDGE "color/spyd4cal.bin"
)) < 1)
break;
@@ -2884,15 +2885,15 @@ spyd2_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
/* it needs icomuf_resetep_before_read to work at all, and */
/* gets retries anyway. So we use the libusb-win32 driver for it. */
#if defined(NT)
- if (p->itype == instSpyder3) {
+ if (p->dtype == instSpyder3) {
usbflags |= icomuf_resetep_before_read; /* The spyder USB is buggy ? */
}
#endif
/* On OS X the Spyder 2 can't close properly */
#if defined(UNIX_APPLE) /* OS X*/
- if (p->itype == instSpyder1
- || p->itype == instSpyder2) {
+ if (p->dtype == instSpyder1
+ || p->dtype == instSpyder2) {
usbflags |= icomuf_reset_before_close; /* The spyder 2 USB is buggy ? */
}
#endif
@@ -2901,8 +2902,8 @@ spyd2_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
#if defined(UNIX_X11) /* Linux*/
/* On Linux the Spyder 2 doesn't work reliably unless each */
/* read is preceeded by a reset endpoint. */
- if (p->itype == instSpyder1
- || p->itype == instSpyder2) {
+ if (p->dtype == instSpyder1
+ || p->dtype == instSpyder2) {
usbflags |= icomuf_resetep_before_read; /* The spyder USB is buggy ? */
}
#endif
@@ -2937,11 +2938,11 @@ spyd2_init_inst(inst *pp) {
if (p->gotcoms == 0) /* Must establish coms before calling init */
return spyd2_interp_code((inst *)p, SPYD2_NO_COMS);
- if (p->itype != instSpyder1
- && p->itype != instSpyder2
- && p->itype != instSpyder3
- && p->itype != instSpyder4
- && p->itype != instSpyder5)
+ if (p->dtype != instSpyder1
+ && p->dtype != instSpyder2
+ && p->dtype != instSpyder3
+ && p->dtype != instSpyder4
+ && p->dtype != instSpyder5)
return spyd2_interp_code((inst *)p, SPYD2_UNKNOWN_MODEL);
p->refrate = DEFRRATE;
@@ -2950,9 +2951,9 @@ spyd2_init_inst(inst *pp) {
p->prevrawinv = 0; /* prevraw is valid */
/* For Spyder 1 & 2, reset the hardware and wait for it to become ready. */
- if (p->itype != instSpyder3
- && p->itype != instSpyder4
- && p->itype != instSpyder5) {
+ if (p->dtype != instSpyder3
+ && p->dtype != instSpyder4
+ && p->dtype != instSpyder5) {
/* Reset the instrument */
if ((ev = spyd2_reset(p)) != inst_ok)
@@ -3038,7 +3039,7 @@ spyd2_init_inst(inst *pp) {
a1logv(p->log, 1, "Instrument Type: %s\n"
"Serial Number: %s\n"
"Hardware version: 0x%02x%02x\n"
- ,inst_name(p->itype) ,p->serno ,p->hwver,p->fbits);
+ ,inst_name(p->dtype) ,p->serno ,p->hwver,p->fbits);
return inst_ok;
}
@@ -3504,9 +3505,9 @@ inst3_capability *pcap3) {
/* We don't seem to have a way of detecting the lack */
/* of ambinent capability, short of doing a read */
/* and noticing the result is zero. */
- if (p->itype == instSpyder3
- || p->itype == instSpyder4
- || p->itype == instSpyder5) {
+ if (p->dtype == instSpyder3
+ || p->dtype == instSpyder4
+ || p->dtype == instSpyder5) {
cap1 |= inst_mode_emis_ambient;
}
@@ -3518,9 +3519,9 @@ inst3_capability *pcap3) {
| inst2_emis_refr_meas
;
- if (p->itype == instSpyder3
- || p->itype == instSpyder4
- || p->itype == instSpyder5) {
+ if (p->dtype == instSpyder3
+ || p->dtype == instSpyder4
+ || p->dtype == instSpyder5) {
cap2 |= inst2_disptype;
cap2 |= inst2_has_leds;
cap2 |= inst2_ambient_mono;
@@ -3528,8 +3529,8 @@ inst3_capability *pcap3) {
cap2 |= inst2_disptype;
}
- if (p->itype == instSpyder4
- || p->itype == instSpyder5)
+ if (p->dtype == instSpyder4
+ || p->dtype == instSpyder5)
cap2 |= inst2_ccss; /* Spyder4 & 5 has spectral sensivities */
if (pcap1 != NULL)
@@ -3747,8 +3748,8 @@ static inst_disptypesel spyd4_disptypesel[8] = {
static void set_base_disptype_list(spyd2 *p) {
/* set the base display type list */
- if (p->itype == instSpyder4
- || p->itype == instSpyder5) {
+ if (p->dtype == instSpyder4
+ || p->dtype == instSpyder5) {
if (spyd4_nocals <= 1) {
p->_dtlist = spyd4_disptypesel_1;
} else { /* spyd4_nocals == 6 or 7, Spyder 4 or 5. */
@@ -3757,7 +3758,7 @@ static void set_base_disptype_list(spyd2 *p) {
/* So use the spyder 4 list */
p->_dtlist = spyd4_disptypesel;
}
- } else if (p->itype == instSpyder3) {
+ } else if (p->dtype == instSpyder3) {
p->_dtlist = spyd3_disptypesel;
} else {
p->_dtlist = spyd2_disptypesel;
@@ -4079,7 +4080,7 @@ spyd2_get_set_opt(inst *pp, inst_opt_type m, ...) {
}
/* Constructor */
-extern spyd2 *new_spyd2(icoms *icom, instType itype) {
+extern spyd2 *new_spyd2(icoms *icom, instType dtype) {
spyd2 *p;
if ((p = (spyd2 *)calloc(sizeof(spyd2),1)) == NULL) {
a1loge(icom->log, 1, "new_spyd2: malloc failed!\n");
@@ -4109,11 +4110,11 @@ extern spyd2 *new_spyd2(icoms *icom, instType itype) {
p->del = spyd2_del;
p->icom = icom;
- p->itype = itype;
+ p->dtype = dtype;
/* Load manufacturers Spyder4 calibrations */
- if (itype == instSpyder4
- || itype == instSpyder5) {
+ if (dtype == instSpyder4
+ || dtype == instSpyder5) {
int rv;
p->hwver = 7; /* Set preliminary version */
if ((rv = spyd4_load_cal(p)) != SPYD2_OK)
@@ -4121,11 +4122,11 @@ extern spyd2 *new_spyd2(icoms *icom, instType itype) {
if (spyd4_nocals < 1)
a1logd(p->log, 1, "Spyder4 choice of calibrations not available\n");
}
- if (itype == instSpyder3) {
+ if (dtype == instSpyder3) {
p->hwver = 4; /* Set preliminary version */
}
- if (itype == instSpyder1 // ????
- || itype == instSpyder2) {
+ if (dtype == instSpyder1 // ????
+ || dtype == instSpyder2) {
p->hwver = 3; /* Set preliminary version */
}
@@ -4164,7 +4165,8 @@ int setup_spyd2(int id) {
else
p1 = "ArgyllCMS/spyd2PLD.bin" XDG_FUDGE "color/spyd2PLD.bin";
- if ((no_paths = xdg_bds(NULL, &bin_paths, xdg_data, xdg_read, xdg_user, p1)) < 1) {
+ if ((no_paths = xdg_bds(NULL, &bin_paths, xdg_data, xdg_read, xdg_user, xdg_none,
+ p1)) < 1) {
a1logd(g_log, 1, "setup_spyd2: failed to find PLD file on path '%s'\n",p1);
break;
}
diff --git a/spectro/spyd2.h b/spectro/spyd2.h
index 318ed7c..318ed7c 100644..100755
--- a/spectro/spyd2.h
+++ b/spectro/spyd2.h
diff --git a/spectro/ss.c b/spectro/ss.c
index 260df4a..4f95fdb 100644..100755
--- a/spectro/ss.c
+++ b/spectro/ss.c
@@ -76,6 +76,7 @@
#include "sa_config.h"
#include "numsup.h"
#endif /* SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -223,7 +224,7 @@ ss_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
ss_command(p, SH_TMO);
if (ss_sub_1(p) == ss_AnsPFX) { /* Got comms */
- p->itype = instSpectroScan; /* Preliminary */
+ p->dtype = instSpectroScan; /* Preliminary */
break;
}
@@ -233,7 +234,7 @@ ss_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
ss_command(p, SH_TMO);
if (ss_sub_1(p) == ss_ParameterAnswer) { /* Got comms */
- p->itype = instSpectrolino;
+ p->dtype = instSpectrolino;
break;
}
@@ -259,7 +260,7 @@ ss_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
a1logd(p->log, 4, "ss_init_coms: got basic communications\n");
/* Finalise the communications */
- if (p->itype == instSpectrolino) {
+ if (p->dtype == instSpectrolino) {
if ((ev = so_do_MeasControlDownload(p, fcc1)) != inst_ok)
return ev;
@@ -326,7 +327,7 @@ ss_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
a1logd(p->log, 4, "ss_init_coms: establish communications\n");
/* See if we have a Spectroscan or SpectroscanT, and get other details */
- p->itype = instUnknown;
+ p->dtype = instUnknown;
{
char devn[19];
@@ -335,9 +336,9 @@ ss_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
if (ev == inst_ok) {
a1logd(p->log, 5, "ss_init_coms: got device name '%s'\n",devn);
if (strncmp(devn, "SpectroScanT",12) == 0) {
- p->itype = instSpectroScanT;
+ p->dtype = instSpectroScanT;
} else if (strncmp(devn, "SpectroScan",11) == 0) {
- p->itype = instSpectroScan;
+ p->dtype = instSpectroScan;
}
}
}
@@ -363,8 +364,8 @@ ss_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
|| strncmp(devn, "Spectrolino",11) != 0)
return inst_unknown_model;
- if (p->itype == instUnknown) /* No SpectroScan */
- p->itype = instSpectrolino;
+ if (p->dtype == instUnknown) /* No SpectroScan */
+ p->dtype = instSpectrolino;
}
}
@@ -390,15 +391,15 @@ static void ss_determine_capabilities(ss *p) {
| inst_mode_spectral
;
- if (p->itype == instSpectrolino) {
+ if (p->dtype == instSpectrolino) {
p->cap |= inst_mode_trans_spot; /* Support this manually using a light table */
}
- if (p->itype == instSpectroScan
- || p->itype == instSpectroScanT) /* Only in reflective mode */
+ if (p->dtype == instSpectroScan
+ || p->dtype == instSpectroScanT) /* Only in reflective mode */
p->cap |= inst_mode_ref_xy;
- if (p->itype == instSpectroScanT) {
+ if (p->dtype == instSpectroScanT) {
p->cap |= inst_mode_trans_spot;
}
@@ -408,8 +409,8 @@ static void ss_determine_capabilities(ss *p) {
| inst2_user_switch_trig
;
- if (p->itype == instSpectroScan
- || p->itype == instSpectroScanT) {
+ if (p->dtype == instSpectroScan
+ || p->dtype == instSpectroScanT) {
/* These are not available in transmission mode */
if ((p->mode & inst_mode_illum_mask) != inst_mode_transmission) {
p->cap2 |= inst2_xy_holdrel
@@ -451,10 +452,10 @@ ss_init_inst(inst *pp) {
}
/* Reset the instrument to a known state */
- if (p->itype != instSpectrolino) {
+ if (p->dtype != instSpectrolino) {
/* Initialise the device without resetting the baud rate */
- if (p->itype == instSpectroScanT) {
+ if (p->dtype == instSpectroScanT) {
if ((rv = ss_do_SetTableMode(p, ss_tmt_Reflectance)) != inst_ok)
return rv;
}
@@ -726,8 +727,8 @@ ipatch *vals) { /* Pointer to array of values */
if (!p->inited)
return inst_no_init;
- if (p->itype != instSpectroScan
- && p->itype != instSpectroScanT)
+ if (p->dtype != instSpectroScan
+ && p->dtype != instSpectroScanT)
return inst_unsupported;
/* Move quickest in X direction to minimise noise, */
@@ -1044,7 +1045,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
break;
}
/* If SpectroScanT transmission, poll the enter key */
- if (p->itype == instSpectroScanT
+ if (p->dtype == instSpectroScanT
&& (p->mode & inst_mode_illum_mask) == inst_mode_transmission) {
ss_sks sk;
ss_ptt pt;
@@ -1117,14 +1118,14 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
/* For the spectroscan, make sure the instrument is on line, */
/* since it may be off line to allow the user to position it. */
- if (p->itype != instSpectrolino && p->offline) {
+ if (p->dtype != instSpectrolino && p->offline) {
if ((rv = p->xy_locate_end((inst *)p)) != inst_ok)
return rv;
}
/* For reflection spot mode on a SpectroScan, lower the head. */
/* (A SpectroScanT in transmission will position automatically) */
- if (p->itype != instSpectrolino
+ if (p->dtype != instSpectrolino
&& (p->mode & inst_mode_illum_mask) != inst_mode_transmission) {
if ((rv = ss_do_MoveDown(p)) != inst_ok)
return rv;
@@ -1139,7 +1140,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
/* For reflection spot mode on a SpectroScan, raise the head. */
/* (A SpectroScanT in transmission will position automatically) */
- if (p->itype != instSpectrolino
+ if (p->dtype != instSpectrolino
&& (p->mode & inst_mode_illum_mask) != inst_mode_transmission) {
if ((rv = ss_do_MoveUp(p)) != inst_ok)
return rv;
@@ -1153,7 +1154,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
/* Emulated spot transmission mode: */
if ((p->mode & inst_mode_illum_mask) == inst_mode_transmission
- && p->itype == instSpectrolino) {
+ && p->dtype == instSpectrolino) {
ss_st rst; /* Return Spectrum Type (Reflectance/Density) */
ss_rvt rvf; /* Return Reference Valid Flag */
ss_aft af; /* Return filter being used (None/Pol/D65/UV/custom */
@@ -1376,7 +1377,7 @@ static inst_code ss_get_n_a_cals(inst *pp, inst_cal_type *pn_cals, inst_cal_type
inst_cal_type a_cals = inst_calt_none;
if ((p->mode & inst_mode_illum_mask) == inst_mode_transmission) {
- if (p->itype == instSpectrolino) { /* Emulated transmission */
+ if (p->dtype == instSpectrolino) { /* Emulated transmission */
if (p->need_wd_cal && p->noinitcalib == 0)
n_cals |= inst_calt_ref_white;
a_cals |= inst_calt_ref_white;
@@ -1464,7 +1465,7 @@ char id[CALIDLEN] /* Condition identifier (ie. white reference ID) */
p->filt = ss_aft_NoFilter; /* Need no filter for emission */
/* Set mode to reflection as a default for calibration */
- if (p->itype == instSpectroScanT) {
+ if (p->dtype == instSpectroScanT) {
if ((rv = ss_do_SetTableMode(p, ss_tmt_Reflectance)) != inst_ok)
return rv;
} else {
@@ -1484,7 +1485,7 @@ char id[CALIDLEN] /* Condition identifier (ie. white reference ID) */
if (p->noinitcalib == 0) {
/* Make sure we're in a condition to do the calibration */
- if (p->itype == instSpectrolino
+ if (p->dtype == instSpectrolino
&& (*calc & inst_calc_cond_mask) != inst_calc_man_ref_white) {
*calc = inst_calc_man_ref_white;
a1logd(p->log, 3, "ss cal need cond. inst_calc_man_ref_white and haven't got it\n");
@@ -1496,7 +1497,7 @@ char id[CALIDLEN] /* Condition identifier (ie. white reference ID) */
a1logd(p->log, 3, "ss cal doing white reflective cal\n");
/* For SpectroScan, move to the white reference in slot 1 and lower */
- if (p->itype != instSpectrolino) {
+ if (p->dtype != instSpectrolino) {
if ((rv = ss_do_MoveToWhiteRefPos(p, ss_wrpt_RefTile1)) != inst_ok)
return rv;
if ((rv = ss_do_MoveDown(p)) != inst_ok)
@@ -1510,7 +1511,7 @@ char id[CALIDLEN] /* Condition identifier (ie. white reference ID) */
rv = inst_ok;
/* For SpectroScan, raise */
- if (p->itype != instSpectrolino) {
+ if (p->dtype != instSpectrolino) {
if ((rv = ss_do_MoveUp(p)) != inst_ok)
return rv;
}
@@ -1541,7 +1542,7 @@ char id[CALIDLEN] /* Condition identifier (ie. white reference ID) */
/* Emission or spot transmission mode, dark calibration. */
if ((p->mode & inst_mode_illum_mask) == inst_mode_emission
|| ((p->mode & inst_mode_illum_mask) == inst_mode_transmission
- && p->itype == instSpectrolino)) {
+ && p->dtype == instSpectrolino)) {
a1logd(p->log, 3, "emmission/transmission dark calibration:\n");
/* Set emission mode */
if ((rv = so_do_MeasControlDownload(p, ss_ctt_EmissionMeas)) != inst_ok)
@@ -1563,7 +1564,7 @@ char id[CALIDLEN] /* Condition identifier (ie. white reference ID) */
/* Restore the instrument to the desired mode */
/* SpectroScanT - Transmission mode, set transmission mode. */
if ((p->mode & inst_mode_illum_mask) == inst_mode_transmission
- && p->itype == instSpectroScanT) {
+ && p->dtype == instSpectroScanT) {
if ((p->mode & inst_mode_illum_mask) == inst_mode_transmission) {
if ((rv = ss_do_SetTableMode(p, ss_tmt_Transmission)) != inst_ok)
@@ -1584,7 +1585,7 @@ char id[CALIDLEN] /* Condition identifier (ie. white reference ID) */
a1logd(p->log, 3, "ss cal need trans with calt = trans_white\n");
/* Emulated spot transmission using spectrolino */
- if ((*calt & inst_calt_trans_vwhite) && p->itype == instSpectrolino) {
+ if ((*calt & inst_calt_trans_vwhite) && p->dtype == instSpectrolino) {
ss_st rst; /* Return Spectrum Type (Reflectance/Density) */
ss_rvt rvf; /* Return Reference Valid Flag */
ss_aft af; /* Return filter being used (None/Pol/D65/UV/custom */
@@ -1631,7 +1632,7 @@ char id[CALIDLEN] /* Condition identifier (ie. white reference ID) */
a1logd(p->log, 3, "transmission lino cal done\n");
/* SpectroScanT */
- } else if ((*calt & inst_calt_trans_white) && p->itype != instSpectrolino) {
+ } else if ((*calt & inst_calt_trans_white) && p->dtype != instSpectrolino) {
/* Hmm. Should we really return a message and resume somehow, */
/* rather than communicating directly with the user... */
@@ -2154,7 +2155,7 @@ ss_del(inst *pp) {
ss *p = (ss *)pp;
if (p->inited
- && p->itype == instSpectroScanT
+ && p->dtype == instSpectroScanT
&& (p->mode & inst_mode_illum_mask) == inst_mode_transmission) {
ss_do_SetDeviceOnline(p);
ss_do_SetTableMode(p, ss_tmt_Reflectance);
@@ -2175,7 +2176,7 @@ ss_del(inst *pp) {
}
/* Constructor */
-extern ss *new_ss(icoms *icom, instType itype) {
+extern ss *new_ss(icoms *icom, instType dtype) {
ss *p;
if ((p = (ss *)calloc(sizeof(ss),1)) == NULL) {
a1loge(icom->log, 1, "new_ss: malloc failed!\n");
@@ -2209,7 +2210,7 @@ extern ss *new_ss(icoms *icom, instType itype) {
/* Init state */
p->icom = icom;
- p->itype = itype;
+ p->dtype = dtype;
p->cap = inst_mode_none; /* Unknown until initialised */
p->mode = inst_mode_none; /* Not in a known mode yet */
p->nextmode = inst_mode_none; /* Not in a known mode yet */
diff --git a/spectro/ss.h b/spectro/ss.h
index bc816e7..bc816e7 100644..100755
--- a/spectro/ss.h
+++ b/spectro/ss.h
diff --git a/spectro/ss_imp.c b/spectro/ss_imp.c
index 05f0602..0de14ea 100644..100755
--- a/spectro/ss_imp.c
+++ b/spectro/ss_imp.c
@@ -50,6 +50,7 @@
#include "sa_config.h"
#include "numsup.h"
#endif /* SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
diff --git a/spectro/ss_imp.h b/spectro/ss_imp.h
index ccd9ce3..ccd9ce3 100644..100755
--- a/spectro/ss_imp.h
+++ b/spectro/ss_imp.h
diff --git a/spectro/synthcal.c b/spectro/synthcal.c
index 14471f6..14471f6 100644..100755
--- a/spectro/synthcal.c
+++ b/spectro/synthcal.c
diff --git a/spectro/synthread.c b/spectro/synthread.c
index 3a23c31..3a23c31 100644..100755
--- a/spectro/synthread.c
+++ b/spectro/synthread.c
diff --git a/spectro/usbio.c b/spectro/usbio.c
index fca997d..efd0dc8 100644..100755
--- a/spectro/usbio.c
+++ b/spectro/usbio.c
@@ -33,6 +33,7 @@
#include "sa_config.h"
#endif
#include "numsup.h"
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
diff --git a/spectro/usbio.h b/spectro/usbio.h
index 2a01ea3..2a01ea3 100644..100755
--- a/spectro/usbio.h
+++ b/spectro/usbio.h
diff --git a/spectro/usbio_bsd.c b/spectro/usbio_bsd.c
index 4b3e038..4b3e038 100644..100755
--- a/spectro/usbio_bsd.c
+++ b/spectro/usbio_bsd.c
diff --git a/spectro/usbio_lx.c b/spectro/usbio_lx.c
index 6edcb29..135f8eb 100644..100755
--- a/spectro/usbio_lx.c
+++ b/spectro/usbio_lx.c
@@ -22,6 +22,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
+#include <sys/time.h>
#include <linux/usbdevice_fs.h>
/* select() defined, but not poll(), so emulate poll() */
@@ -785,6 +786,9 @@ static int icoms_usb_transaction(
in_usb_rw++;
a1logd(p->log, 8, "icoms_usb_transaction: req type 0x%x ep 0x%x size %d to %d\n",ttype,endpoint,length, timeout);
+ if (transferred != NULL)
+ *transferred = 0;
+
if (!p->usbd->running) {
in_usb_rw--;
a1logv(p->log, 1, "icoms_usb_transaction: reaper thread is not running\n");
diff --git a/spectro/usbio_nt.c b/spectro/usbio_nt.c
index 34426fd..f3748bb 100644..100755
--- a/spectro/usbio_nt.c
+++ b/spectro/usbio_nt.c
@@ -589,6 +589,9 @@ static int icoms_usb_transaction(
a1logd(p->log, 8, "icoms_usb_transaction: req type 0x%x ep 0x%x size %d\n",ttype,endpoint,length);
+ if (transferred != NULL)
+ *transferred = 0;
+
if (ttype != icom_usb_trantype_interrutpt
&& ttype != icom_usb_trantype_bulk) {
/* We only handle interrupt & bulk, not control */
@@ -692,6 +695,9 @@ int timeout) {
a1logd(p->log, 8, "icoms_usb_control_msg: type 0x%x req 0x%x size %d\n",requesttype,request,size);
+ if (transferred != NULL)
+ *transferred = 0;
+
memset(&req, 0, sizeof(libusb_request));
req.timeout = timeout;
diff --git a/spectro/usbio_ox.c b/spectro/usbio_ox.c
index 2b09955..3923d6d 100644..100755
--- a/spectro/usbio_ox.c
+++ b/spectro/usbio_ox.c
@@ -457,12 +457,20 @@ char **pnames /* List of process names to try and kill before opening */
(*pluginref)->Stop(pluginref);
IODestroyPlugInInterface(pluginref); // this stops IOServices though ??
+ /* This can fail if the device has multiple interfaces, and */
+ /* one of them is grabbed by a system interface (i.e. debug serial port) */
+ /* So soft fail, and rely on ep use to fail for invalid interface */
if ((rv = (*(p->usbd->interfaces[i]))->USBInterfaceOpen(
p->usbd->interfaces[i])) != kIOReturnSuccess) {
- a1loge(p->log, rv, "usb_open_port: USBInterfaceOpen failed with 0x%x\n",rv);
+#ifdef NEVER
+ a1loge(p->log, rv, "usb_open_port: USBInterfaceOpen %d failed with 0x%x\n",i, rv);
IOObjectRelease(ioit);
cleanup_device(p);
return ICOM_SYS;
+#else
+ a1logw(p->log, "usb_open_port: USBInterfaceOpen %d failed with 0x%x\n",i,rv);
+ continue;
+#endif
}
/* Get the end point details, and set reference to pipe no and interfece ix */
@@ -580,6 +588,9 @@ static int icoms_usb_transaction(
a1logd(p->log, 8, "icoms_usb_transaction: req type 0x%x ep 0x%x size %d\n",ttype,endpoint,length);
+ if (transferred != NULL)
+ *transferred = 0;
+
if (ttype != icom_usb_trantype_interrutpt
&& ttype != icom_usb_trantype_bulk) {
/* We only handle interrupt & bulk, not control */
diff --git a/spectro/vinflate.c b/spectro/vinflate.c
index 847fa28..847fa28 100644..100755
--- a/spectro/vinflate.c
+++ b/spectro/vinflate.c
diff --git a/spectro/vtpglut.c b/spectro/vtpglut.c
new file mode 100755
index 0000000..2308466
--- /dev/null
+++ b/spectro/vtpglut.c
@@ -0,0 +1,570 @@
+
+/* Abstract Video Test Patch Generator and/or 3dLUT class implemenation */
+
+/*
+ * Argyll Color Correction System
+ *
+ * Author: Graeme W. Gill
+ * Date: 10/3/2001
+ *
+ * Copyright 2001 - 2013 Graeme W. Gill
+ * All rights reserved.
+ *
+ * This material is licenced under the GNU GENERAL PUBLIC LICENSE Version 2 or later :-
+ * see the License2.txt file for licencing details.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <string.h>
+#include <time.h>
+#ifndef SALONEINSTLIB
+#include "copyright.h"
+#include "aconfig.h"
+#else
+#include "sa_config.h"
+#endif /* !SALONEINSTLIB */
+#include "numsup.h"
+#include "cgats.h"
+#include "xspect.h"
+#include "conv.h"
+
+#include "insttypes.h"
+#include "icoms.h"
+#include "vtpglut.h"
+#include "rspec.h"
+#include "vtpgluttypes.h"
+#include "sort.h"
+
+icom_type dev_category(instType itype);
+
+/* --------------------------------------------------------- */
+
+#if defined(ENABLE_FAST_SERIAL)
+extern devType fast_ser_dev_type(icoms *p, int tryhard,
+ inst_code (*uicallback)(void *cntx, inst_ui_purp purp), void *cntx);
+# if defined(ENABLE_SERIAL)
+static devType ser_vtpglut_type(icoms *p,
+ vtpglut_code (*uicallback)(void *cntx, vtpglut_ui_purp purp), void *cntx);
+
+/* Translate vtpglut uicallback into inst callback */
+typedef struct {
+ void *cntx;
+ vtpglut_code (*uicallback)(void *cntx, vtpglut_ui_purp purp);
+} vtpglut_callback_cntx;
+
+static inst_code ser_uicallback(void *cntx, inst_ui_purp purp) {
+ vtpglut_callback_cntx *p = (vtpglut_callback_cntx *)cntx;
+ vtpglut_ui_purp ser_purp;
+
+ if (purp == vtpglut_negcoms)
+ ser_purp = inst_negcoms;
+ else
+ return inst_internal_error;
+ return p->uicallback(p->cntx, ser_purp);
+}
+
+# endif /* ENABLE_SERIAL */
+#endif /* ENABLE_FAST_SERIAL */
+
+
+/* ------------------------------------ */
+/* Default methods for instrument class */
+
+/* Establish communications at the indicated baud rate. */
+/* Timout in to seconds, and return non-zero error code */
+static vtpglut_code init_coms(
+vtpglut *p) { /* Timeout */
+ return vtpglut_unsupported;
+}
+
+/* Initialise or re-initialise the INST */
+/* return non-zero on an error, with inst error code */
+static vtpglut_code init_vtpglut(
+vtpglut *p) {
+ return vtpglut_unsupported;
+}
+
+/* Return the device type */
+static devType get_dtype(vtpglut *p) {
+ if (p != NULL)
+ return p->dtype;
+ return devUnknown;
+}
+
+/* Return the device serial number. */
+/* (This will be an empty string if there is no serial no) */
+static char *get_serial_no(vtpglut *p) {
+ return "";
+}
+
+/* Return the device mode/capabilities */
+static void capabilities(vtpglut *p, vtpglut_mode *cap1,
+ vtpglut_capability *cap2) {
+ if (cap1 != NULL)
+ *cap1 = vtpglut_mode_none;
+ if (cap2 != NULL)
+ *cap2 = vtpglut2_none;
+}
+
+/* Check the device mode */
+static vtpglut_code check_mode(
+vtpglut *p,
+vtpglut_mode m) { /* Requested mode */
+ return vtpglut_unsupported;
+}
+
+/* Set the device mode */
+static vtpglut_code set_mode(
+vtpglut *p,
+vtpglut_mode m) { /* Requested mode */
+ return vtpglut_unsupported;
+}
+
+/* Get a status or set or get an option (default implementation) */
+vtpglut_code vtpglut_get_set_opt_def(
+vtpglut *p,
+vtpglut_opt_type m, /* Requested option type */
+va_list args) { /* Option parameters */
+ return vtpglut_unsupported;
+}
+
+/* Get a status or set or get an option */
+static vtpglut_code get_set_opt(
+vtpglut *p,
+vtpglut_opt_type m, /* Requested status type */
+...) { /* Status parameters */
+ vtpglut_code rv;
+ va_list args;
+
+ va_start(args, m);
+ rv = vtpglut_get_set_opt_def(p, m, args); /* Call the above */
+ va_end(args);
+
+ return rv;
+}
+
+/* Supply a user interaction callback function. */
+static void set_uicallback(
+vtpglut *pp,
+vtpglut_code (*uicallback)(void *cntx, vtpglut_ui_purp purp),
+void *cntx) {
+ pp->uicallback = uicallback;
+ pp->uic_cntx = cntx;
+}
+
+/* Supply an asynchronous event callback function. */
+static void set_event_callback(
+vtpglut *pp,
+void (*eventcallback)(void *cntx, vtpglut_event_type event),
+void *cntx) {
+ pp->eventcallback = eventcallback;
+ pp->event_cntx = cntx;
+}
+
+/* Generic inst error codes interpretation */
+static char *vtpglut_interp_error(vtpglut *p, vtpglut_code ec) {
+ switch(ec & vtpglut_mask) {
+ case vtpglut_ok:
+ return "No error";
+ case vtpglut_notify:
+ return "Notification";
+ case vtpglut_warning:
+ return "Warning";
+ case vtpglut_no_coms:
+ return "Internal error - communications needed but not established";
+ case vtpglut_no_init:
+ return "Internal error - initialisation needed but not done";
+ case vtpglut_unsupported:
+ return "Unsupported function";
+ case vtpglut_internal_error:
+ return "Internal software error";
+ case vtpglut_coms_fail:
+ return "Communications failure";
+ case vtpglut_unknown_model:
+ return "Not expected device model";
+ case vtpglut_protocol_error:
+ return "Communication protocol breakdown";
+ case vtpglut_user_abort:
+ return "User hit Abort Key";
+ case vtpglut_user_trig:
+ return "User hit Trigger Key";
+ case vtpglut_unexpected_reply:
+ return "Unexpected Reply";
+ case vtpglut_wrong_setup:
+ return "Wrong or conflicting setup";
+ case vtpglut_hardware_fail:
+ return "Hardware Failure";
+ case vtpglut_system_error:
+ return "Operating System Error";
+ case vtpglut_bad_parameter:
+ return "Bad Parameter Value";
+ case vtpglut_other_error:
+ return "Non-specific error";
+ }
+ return "Unknown inst error code";
+}
+
+/* Instrument specific error codes interpretation */
+static char *interp_error(vtpglut *p, int ec) {
+ return "interp_error is uninplemented in base class!";
+}
+
+/* Return the last serial communication error code */
+/* (This is used for deciding fallback/retry strategies) */
+static int last_scomerr(vtpglut *p) {
+ return p->icom->lserr;
+}
+
+/* ---------------------------------------------- */
+
+/* Delete things set/done by new_vtpglut() */
+static vtpglut_code virtual_del(vtpglut *p) {
+
+#if defined(UNIX_APPLE)
+ osx_latencycritical_end();
+#endif
+
+ return vtpglut_ok;
+}
+
+
+/* Virtual constructor. */
+/* Return NULL for unknown instrument, */
+/* or serial instrument if nocoms == 0. */
+extern vtpglut *new_vtpglut(
+icompath *path, /* Device path to instrument */
+int nocoms, /* Don't open if communications are needed to establish inst type */
+a1log *log, /* log to use */
+vtpglut_code (*uicallback)(void *cntx, vtpglut_ui_purp purp), /* optional uicallback for abort */
+void *cntx /* Context for callback */
+) {
+ devType itype = devUnknown; /* Actual type */
+ icoms *icom;
+ vtpglut *p = NULL;
+
+ if (path == NULL) {
+ a1logd(log, 2, "new_vtpglut: got NULL path\n");
+ return NULL;
+ }
+
+ a1logd(log, 2, "new_vtpglut: called with path '%s' type '%s'\n",path->name,inst_sname(path->itype));
+
+ if ((icom = new_icoms(path, log)) == NULL) {
+ a1logd(log, 2, "new_vtpglut: new_icoms failed to open it\n");
+ return NULL;
+ }
+
+
+
+ /* Set device type from USB port, if not specified */
+ itype = icom->itype; /* Instrument type if its known from usb/hid */
+
+#if defined(ENABLE_FAST_SERIAL)
+ if (itype == instUnknown && !nocoms && (icom->dctype & icomt_fastserial)) {
+ vtpglut_callback_cntx wcntx;
+
+ /* Wrap vtpglut callback in inst callback */
+ wcntx.cntx = cntx;
+ wcntx.uicallback = uicallback;
+
+ itype = fast_ser_dev_type(icom, 1, ser_uicallback, &wcntx); /* Else type from serial */
+ icom->dctype = (icom->dctype & ~icomt_cat_mask) | dev_category(itype);
+ a1logd(log, 8, "new_vtpglut: fast set '%s' dctype 0x%x\n",icom->name,icom->dctype);
+ }
+#endif /* ENABLE_FAST_SERIAL */
+
+#if defined(ENABLE_SERIAL)
+ if (itype == instUnknown && !nocoms) {
+ itype = ser_vtpglut_type(icom, uicallback, cntx); /* Else type from serial */
+ icom->dctype = (icom->dctype & ~icomt_cat_mask) | dev_category(itype);
+ a1logd(log, 8, "new_vtpglut: set '%s' dctype 0x%x\n",icom->name,icom->dctype);
+ }
+#endif /* ENABLE_SERIAL */
+
+
+#ifdef ENABLE_SERIAL
+// if (itype == devRadiance)
+// p = (vtpglut *)new_radiance(icom, itype);
+#endif /* ENABLE_SERIAL */
+
+#ifdef ENABLE_USB
+// if (itype == instXXXX)
+// p = (vtpglut *)new_XXXX(icom, itype);
+#endif /* ENABLE_USB */
+
+
+ /* Nothing matched */
+ if (p == NULL) {
+ a1logd(log, 2, "new_vtpglut: device type not recognised\n");
+ icom->del(icom);
+ return NULL;
+ }
+
+ p->vdel = virtual_del;
+
+ /* Add default methods if constructor did not supply them */
+ if (p->init_coms == NULL)
+ p->init_coms = init_coms;
+ if (p->init_vtpglut == NULL)
+ p->init_vtpglut = init_vtpglut;
+ if (p->get_dtype == NULL)
+ p->get_dtype = get_dtype;
+ if (p->get_serial_no == NULL)
+ p->get_serial_no = get_serial_no;
+ if (p->capabilities == NULL)
+ p->capabilities = capabilities;
+ if (p->check_mode == NULL)
+ p->check_mode = check_mode;
+ if (p->set_mode == NULL)
+ p->set_mode = set_mode;
+ if (p->get_set_opt == NULL)
+ p->get_set_opt = get_set_opt;
+ if (p->set_uicallback == NULL)
+ p->set_uicallback = set_uicallback;
+ if (p->set_event_callback == NULL)
+ p->set_event_callback = set_event_callback;
+ if (p->vtpglut_interp_error == NULL)
+ p->vtpglut_interp_error = vtpglut_interp_error;
+ if (p->interp_error == NULL)
+ p->interp_error = interp_error;
+ if (p->last_scomerr == NULL)
+ p->last_scomerr = last_scomerr;
+
+ /* Set the provided user interaction callback */
+ p->set_uicallback(p, uicallback, cntx);
+
+#if defined(UNIX_APPLE)
+ osx_latencycritical_start();
+#endif
+
+ return p;
+}
+
+/* ============================================================= */
+/* Detect serial device */
+
+#ifdef ENABLE_SERIAL
+static void hex2bin(char *buf, int len);
+
+/* Heuristicly determine the device type for */
+/* a serial connection, and devUnknown if not serial. */
+/* Set it in icoms and also return it. */
+static devType ser_vtpglut_type(
+ icoms *p,
+ vtpglut_code (*uicallback)(void *cntx, vtpglut_ui_purp purp), /* optional uicallback */
+ void *cntx /* Context for callback */
+) {
+ devType rv = instUnknown;
+#define BUFSZ (128 + 10)
+ char buf[BUFSZ];
+ baud_rate brt[] = { baud_9600, baud_57600, baud_115200, baud_230400, baud_nc };
+ unsigned int etime;
+ unsigned int bi, i;
+ int se, len, bread;
+ int lumagen = 0, lgchsum = 0;
+
+#ifdef ENABLE_USB
+ if (p->usbd != NULL || p->hidd != NULL)
+ return p->itype;
+#endif /* ENABLE_USB */
+
+ bi = 0;
+
+ /* The tick to give up on */
+ etime = msec_time() + (long)(20.0 * 1000.0 + 0.5);
+
+ a1logd(p->log, 1, "ser_vtpglut_type: Trying different baud rates (%u msec to go)\n",etime - msec_time());
+
+ /* Until we time out, find the correct baud rate */
+ for (i = bi; msec_time() < etime; i++) {
+ lgchsum = 0;
+
+ if (brt[i] == baud_nc)
+ i = 0;
+ if ((se = p->set_ser_port(p, fc_None, brt[i], parity_none,
+ stop_1, length_8)) != ICOM_OK) {
+ a1logd(p->log, 5, "ser_vtpglut_type: set_ser_port failed with 0x%x\n",se);
+ return instUnknown; /* Give up */
+ }
+
+ a1logd(p->log, 5, "Trying %s baud\n",baud_rate_to_str(brt[i]));
+ bread = 0;
+
+ /* If Lumagen baud rate */
+ if (brt[i] == baud_9600
+ || brt[i] == baud_57600
+ || brt[i] == baud_115200
+ || brt[i] == baud_230400) {
+
+ /* Try a spectrolino/spectroscan command first, so as not to upset it, */
+ /* but do first character only and see if there is an echo */
+ p->write_read_ex(p, ";", 1, buf, BUFSZ-1, &bread, "\r", 1, 0.2, 1);
+ if (bread == 1 && buf[0] == ';')
+ goto check_lumagen; /* It may be a Lumagen, so skip it. */
+
+ /* Send the rest of the spectrolino command */
+ p->write_read_ex(p, "D024\r\n", 0, buf, BUFSZ-1, &bread, "\r", 1, 0.5, 1);
+
+
+ if (bread == 0) {
+ char *bp;
+ a1logd(p->log, 5, "ser_vtpglut_type: Spectrolino command returned nothing\n");
+
+ /* It could be a Lumagen Radiance with echo off, */
+ /* so poke it and see if it responds. */
+ /* (Unfortunately the Lumagen delimeters modes aren't */
+ /* backwards compatible, so we may have to poke it twice...) */
+
+ /* Send "X" first, to get it out of menu mode ? */
+ p->write_read_ex(p, "X", 1, buf, BUFSZ, NULL, "\n", 1, 0.1, 1); // Menu off
+
+ a1logd(p->log, 5, "ser_vtpglut_type: Checking for Lumagen Radiance\n");
+ p->write_read_ex(p, "#ZQS00\r", 0, buf, BUFSZ, &bread, "\n", 1, 0.5, 1);
+ if (bread == 0) {
+ p->write_read_ex(p, "#0ZQS008E\r", 0, buf, BUFSZ, &bread, "\n", 1, 0.5, 1);
+ lgchsum = 1;
+ }
+
+ if (bread > 0
+ && (bp = strrchr(buf, '!')) != NULL
+ && strlen(bp) >= 4
+ && strncmp(bp,"!S00",4) == 0) {
+ goto check_lumagen;
+ }
+
+ /* Nope - look for something at a different baud rate */
+ goto continue_looking;
+ }
+ buf[bread] = '\000';
+ len = strlen(buf);
+
+ /* Is this a Lumagen Radiance with echo on, it responds with ";D024..." */
+ if ((len >= 4 && strncmp(buf, ";D024", 4) == 0)
+ || (len >= 4 && strncmp(buf, "!N\n\r", 4) == 0)) {
+ char *bp;
+
+ check_lumagen:;
+
+ /* Get the Lumagen device information */
+ p->write_read_ex(p, lgchsum ? "#0ZQS018F\r" : "#ZQS01\r",
+ 0, buf, BUFSZ, &bread, "\n", 1, 0.5, 1);
+
+ /* Might have echo with checksum, so lgchsum not set correctly */
+ if (!lgchsum && bread > 0 && strstr(buf, "!N") != NULL) {
+ p->write_read_ex(p, "#0ZQS018F\r", 0, buf, BUFSZ, &bread, "\n", 1, 0.5, 1);
+ if (bread >= 11 && strncmp(buf, "#0ZQS018F!Y", 11) == 0)
+ lgchsum = 1;
+ }
+
+ /* returns something like "ZQS01!S01,Radiance2020,030115,1016,001309\r\m" */
+ if ((bp = strrchr(buf, '!')) != NULL && strlen(bp) >= 13) {
+ if (strncmp(bp,"!S01,Radiance",13) == 0) {
+ a1logd(p->log, 5, "ser_vtpglut_type: Found Lumagen Radiance\n");
+ lumagen = 1;
+ break;
+ }
+ }
+ a1logd(p->log, 5, "ser_vtpglut_type: Not Lumagen Radiance\n");
+ goto continue_looking;
+ }
+ } /* Possibly Lumagen */
+
+ continue_looking:;
+
+ /* Check for user abort */
+ if (uicallback != NULL) {
+ vtpglut_code ev;
+ if ((ev = uicallback(cntx, vtpglut_negcoms)) == vtpglut_user_abort) {
+ a1logd(p->log, 5, "ser_vtpglut_type: User aborted\n");
+ return instUnknown;
+ }
+ }
+ } /* next baud */
+
+ if (rv == instUnknown
+ && lumagen == 0
+ && msec_time() >= etime) { /* We haven't established comms */
+ a1logd(p->log, 5, "ser_vtpglut_type: Failed to establish coms\n");
+ return instUnknown;
+ }
+
+ a1logd(p->log, 5, "ser_vtpglut_type: Got coms with device\n");
+
+ if (lumagen) {
+ char *bp;
+
+ /* Get the Lumagen device information */
+ if ((se = p->write_read_ex(p, "ZQS01", 0, buf, BUFSZ, NULL, "\n", 1, 2.5, 1)) != 0)
+ return instUnknown;
+
+ /* returns something like "ZQS01!S01,Radiance2020,030115,1016,001309\r\m" */
+ if ((bp = strstr(buf, "!")) != NULL && strlen(bp) >= 13) {
+ if (strncmp(bp,"!S01,Radiance",13) == 0) {
+ rv = devRadiance;
+ }
+ }
+ }
+
+ a1logd(p->log, 5, "ser_vtpglut_type: Device type is '%s'\n", inst_name(rv));
+
+ p->close_port(p); /* Or should we leave it open ?? */
+
+ p->itype = rv;
+
+ return rv;
+}
+#undef BUFSZ
+
+#endif /* ENABLE_SERIAL */
+
+#if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL)
+
+/* Convert an ASCII Hex character to an integer. */
+static int h2b(char c) {
+ if (c >= '0' && c <= '9')
+ return (c-(int)'0');
+ if (c >= 'A' && c <= 'F')
+ return (10 + c-(int)'A');
+ if (c >= 'a' && c <= 'f')
+ return (10 + c-(int)'a');
+ return 0;
+}
+
+/* Convert a Hex encoded buffer into binary. */
+/* len is number of bytes out */
+static void hex2bin(char *buf, int len) {
+ int i;
+
+ for (i = 0; i < len; i++) {
+ buf[i] = (char)((h2b(buf[2 * i + 0]) << 4)
+ | (h2b(buf[2 * i + 1]) << 0));
+ }
+}
+
+#endif /* ENABLE_SERIAL */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spectro/vtpglut.h b/spectro/vtpglut.h
new file mode 100755
index 0000000..c461887
--- /dev/null
+++ b/spectro/vtpglut.h
@@ -0,0 +1,243 @@
+
+#ifndef VTPGLUT_H
+
+/*
+ * v3dlut/vtpg API definition.
+ *
+ * Abstract base class for common color Video Test Pattern Generator interface
+ * and Video 3DLut devices.
+ */
+
+/*
+ * Argyll Color Correction System
+ *
+ * Author: Graeme W. Gill
+ * Date: 15/3/2001
+ *
+ * Copyright 2001 - 2013 Graeme W. Gill
+ * All rights reserved.
+ *
+ * This material is licenced under the GNU GENERAL PUBLIC LICENSE Version 2 or later :-
+ * see the License2.txt file for licencing details.
+ *
+ */
+
+#include "dev.h" /* Device base class */
+#include "insttypes.h" /* libinst Includes this functionality */
+#include "icoms.h" /* libinst Includes this functionality */
+#include "conv.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* ------------------------------------------------- */
+/* aprox. debug level guide:
+
+ 1,2 Applications, internal errors
+ 2,3 High level instrument drivers
+ 4,5 High level instrument communications
+ 6,7 High level serial/USB communications
+ 8,9 Low level serial/USB communications
+
+*/
+
+/* ---------------------------------------- */
+/* Device interface abstract base class. */
+
+/* This is used for all device types except color instruments */
+
+/* Abstract return codes in ms 8bits. */
+/* Device dependant codes in ls 16 bits. */
+/* Note :- update vtpglut_interp_error() in other.c if anything here is changed. */
+/* and also check all the device specific XXX_interp_code() routines too. */
+typedef enum {
+ vtpglut_ok = 0x000000,
+ vtpglut_notify = 0x010000, /* A Notification */
+ vtpglut_warning = 0x020000, /* A Warning */
+ vtpglut_no_coms = 0x030000, /* init_coms() hasn't been called yet */
+ vtpglut_no_init = 0x040000, /* init_dev() hasn't been called yet */
+ vtpglut_unsupported = 0x050000, /* Unsupported function */
+ vtpglut_internal_error = 0x060000, /* Internal software error */
+ vtpglut_coms_fail = 0x070000, /* Communication failure */
+ vtpglut_unknown_model = 0x080000, /* Not the expected device */
+ vtpglut_protocol_error = 0x090000, /* Read or Write protocol error */
+ vtpglut_user_abort = 0x0A0000, /* User hit escape */
+ vtpglut_user_trig = 0x0C0000, /* User hit trigger key */
+ vtpglut_unexpected_reply = 0x140000, /* Unexpected Reply */
+ vtpglut_wrong_setup = 0x150000, /* Setup is wrong or conflicting */
+ vtpglut_hardware_fail = 0x160000, /* Hardware failure */
+ vtpglut_system_error = 0x170000, /* System call (ie malloc) fail */
+ vtpglut_bad_parameter = 0x180000, /* Bad parameter value */
+ vtpglut_other_error = 0x190000, /* Some other error */
+ vtpglut_mask = 0xff0000, /* vtpglut_code mask value */
+ vtpglut_dmask = 0x00ffff /* device specific mask value */
+} vtpglut_code;
+
+/* Device capabilities & modes */
+/* Note that due to the binary combinations, capabilities is not definititive */
+/* as to valid modes. check_mode() is definitive. */
+/* #defines are for saving modes in a version independent way. */
+/* Note :- update vtpglut_mode_sym[] table in vtpglut.c if anything here is changed. */
+typedef enum {
+ vtpglut_mode_none = 0x00000000, /* No capability/mode */
+} vtpglut_mode;
+
+typedef enum {
+ vtpglut2_none = 0x00000000, /* No capability */
+} vtpglut_capability;
+
+
+/* Device options for get_set_opt() */
+typedef enum {
+ vtpglut_opt_unknown = 0x0000, /* Option not specified */
+} vtpglut_opt_type;
+
+/* User interaction callback (uicallback()) function purpose */
+/* (Make sure vtpglut.c inst_code ser_uicallbac() is updated if this changes. */
+typedef enum {
+ vtpglut_negcoms /* Negotiating communications - can abort */
+} vtpglut_ui_purp;
+
+/* Asynchronous event callback type */
+typedef enum {
+ inst_event_none /* (Placeholder) */
+} vtpglut_event_type;
+
+/* ---------------------------------------- */
+/* Device interface abstract base class */
+
+# define EXTRA_VTPGLUT_OBJ
+
+/* vtpg/v3dlut interface base object */
+/* Note that some methods work after creation, while many */
+/* will return an error if communications hasn't been established and */
+/* the device initialised. Some may change their response before and */
+/* after initialisation. */
+#define VTPGLUT_OBJ_BASE \
+ \
+ DEV_OBJ_BASE \
+ \
+ EXTRA_VTPGLUT_OBJ \
+ \
+ vtpglut_code (*uicallback)(void *cntx, vtpglut_ui_purp purp); \
+ void *uic_cntx; /* User interaction callback function */ \
+ void (*eventcallback)(void *cntx, vtpglut_event_type event); \
+ void *event_cntx; /* Asynchronous event callback function */ \
+ \
+ /* Virtual delete. Cleans up things done by new_vtpglut(). */ \
+ vtpglut_code (*vdel)( \
+ struct _vtpglut *p); \
+ \
+ /* Establish communications at the indicated baud rate. */ \
+ /* (Serial parameters are ignored for USB/Network device) */ \
+ /* Timout in to seconds, and return non-zero error code */ \
+ vtpglut_code (*init_coms)( \
+ struct _vtpglut *p); \
+ \
+ /* Initialise or re-initialise the vtpglut. */ \
+ /* return non-zero on an error, with dev error code */ \
+ vtpglut_code (*init_vtpglut)( \
+ struct _vtpglut *p); \
+ \
+ /* Return the device type */ \
+ /* (this could concievably change after init_vtpglut()) */ \
+ /* Can be called before init */ \
+ devType (*get_dtype)( \
+ struct _vtpglut *p); \
+ \
+ /* Return the device serial number. */ \
+ /* (This will be an empty string if there is no serial no) */ \
+ char *(*get_serial_no)( \
+ struct _vtpglut *p); \
+ \
+ /* Return the avilable devices modes and capabilities. */ \
+ /* Can be called before init, but may be different to */ \
+ /* what's returned after initilisation. */ \
+ /* Note that these may change with the mode. */ \
+ /* Arguments may be NULL */ \
+ void (*capabilities)(struct _vtpglut *p, \
+ vtpglut_mode *cap1, \
+ vtpglut_capability *cap2); \
+ \
+ /* Check that the particular device measurement mode is valid, */ \
+ /* since it's not possible to be 100% sure from capabilities */ \
+ vtpglut_code (*check_mode)( \
+ struct _vtpglut *p, \
+ vtpglut_mode m); /* Requested mode */ \
+ \
+ /* Set the device mode */ \
+ /* Note that this may change the capabilities. */ \
+ vtpglut_code (*set_mode)( \
+ struct _vtpglut *p, \
+ vtpglut_mode m); /* Requested mode */ \
+ \
+ /* Get a status or get or set an option */ \
+ /* option state. */ \
+ /* Some options can be set before init */ \
+ /* See vtpglut_opt_type typedef for list of mode types */ \
+ vtpglut_code (*get_set_opt)( \
+ struct _vtpglut *p, \
+ vtpglut_opt_type m, /* Requested option mode */ \
+ ...); /* Option parameters */ \
+ \
+ /* Supply a user interaction callback function. \
+ * (Nothing currentlt defined) \
+ * \
+ * NULL can be set to disable the callback. \
+ */ \
+ void (*set_uicallback)(struct _vtpglut *p, \
+ vtpglut_code (*uicallback)(void *cntx, vtpglut_ui_purp purp), \
+ void *cntx); \
+ \
+ /* Supply an aynchronous event callback function. \
+ * This is called from a different thread with the following possible events: \
+ * \
+ * inst_event_XXX: (placeholder) \
+ * \
+ * NULL can be set to disable the callback. \
+ */ \
+ void (*set_event_callback)(struct _vtpglut *p, \
+ void (*eventcallback)(void *cntx, vtpglut_event_type event), \
+ void *cntx); \
+ \
+ /* Generic device error codes interpretation */ \
+ char * (*vtpglut_interp_error)(struct _vtpglut *p, vtpglut_code ec); \
+ \
+ /* Instrument specific error codes interpretation */ \
+ char * (*interp_error)(struct _vtpglut *p, int ec); \
+ \
+ /* Return the last serial communication error code */ \
+ /* (This is used for deciding fallback/retry strategies) */ \
+ int (*last_scomerr)(struct _vtpglut *p); \
+ \
+ /* Destroy ourselves */ \
+ void (*del)(struct _vtpglut *p); \
+
+
+/* The base object type */
+struct _vtpglut {
+ VTPGLUT_OBJ_BASE
+ }; typedef struct _vtpglut vtpglut;
+
+/* Virtual constructor. */
+/* Return NULL for unknown device, */
+/* or serial device if nocoms == 0. */
+/* (Doesn't copy icompaths log!) */
+extern vtpglut *new_vtpglut(
+ icompath *path, /* Device path for this device */
+ int nocoms, /* Don't open if communications are needed to establish device type */
+ a1log *log, /* Log to use */
+ vtpglut_code (*uicallback)(void *cntx, vtpglut_ui_purp purp),
+ /* optional uicallback for abort */
+ void *cntx /* Context for callback */
+);
+
+/* - - - - - - - - - - - - - - - - - - -- */
+
+#ifdef __cplusplus
+ }
+#endif
+
+#define VTPGLUT_H
+#endif /* VTPGLUT_H */
diff --git a/spectro/vtpgluttypes.h b/spectro/vtpgluttypes.h
new file mode 100755
index 0000000..081d130
--- /dev/null
+++ b/spectro/vtpgluttypes.h
@@ -0,0 +1,44 @@
+
+/* Add instrument instance headers here */
+
+/*
+ * Copyright 2001 - 2013 Graeme W. Gill
+ * All rights reserved.
+ *
+ * This material is licenced under the GNU GENERAL PUBLIC LICENSE Version 2 or later :-
+ * see the License2.txt file for licencing details.
+ */
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+#ifdef ENABLE_SERIAL
+# include "dtp22.h"
+# include "dtp41.h"
+# include "dtp51.h"
+# include "ss.h"
+#endif
+
+#ifdef ENABLE_FAST_SERIAL
+# include "specbos.h"
+# include "kleink10.h"
+# include "smcube.h"
+#endif
+
+#ifdef ENABLE_USB
+# include "dtp20.h"
+# include "dtp92.h"
+# include "i1disp.h"
+# include "i1d3.h"
+# include "i1pro.h"
+# include "munki.h"
+# include "spyd2.h"
+# include "huey.h"
+# include "ex1.h"
+# include "hcfr.h"
+# include "colorhug.h"
+#endif
+
+
diff --git a/spectro/webwin.c b/spectro/webwin.c
index 1d5f713..1d5f713 100644..100755
--- a/spectro/webwin.c
+++ b/spectro/webwin.c
diff --git a/spectro/webwin.h b/spectro/webwin.h
index 1f4412a..1f4412a 100644..100755
--- a/spectro/webwin.h
+++ b/spectro/webwin.h
diff --git a/spectro/xdg_bds.c b/spectro/xdg_bds.c
index 03f7561..73e3edd 100644..100755
--- a/spectro/xdg_bds.c
+++ b/spectro/xdg_bds.c
@@ -263,7 +263,10 @@ void xdg_free(char **paths, int nopaths) {
/* type of storage and access required. Return 0 if there is an error. */
/* The files are always unique (ie. the first match to a given filename */
/* in the possible XDG list of directories is returned, and files with */
-/* the same name in other XDG directories are ignored) */
+/* the same name in other XDG directories are ignored), unless the */
+/* xdg_all_matches flag is set. */
+/* If xdg_read, then first user then local scope are searched. */
+/* If xdf_write, then only the specified scope is used. */
/* Wildcards should not be used for xdg_write. */
/* The list should be free'd using xdg_free() after use. */
/* XDG environment variables and the subpath are assumed to be using */
@@ -279,6 +282,7 @@ int xdg_bds(
xdg_storage_type st, /* Specify the storage type */
xdg_op_type op, /* Operation type */
xdg_scope sc, /* Scope if write */
+ xdg_options opt, /* Options flags */
char *pfname /* Sub-path and file name(s) */
) {
char *path = NULL; /* Directory paths to search, separated by ':' or ';' */
@@ -315,7 +319,7 @@ int xdg_bds(
return 0;
}
#ifdef NT
- } else if (getenv("HOME") == NULL && (xdg = getenv("APPDATA")) != NULL) {
+ } else if (login_HOME() == NULL && (xdg = getenv("APPDATA")) != NULL) {
if ((path = cappend(path, xdg)) == NULL) {
if (er != NULL) *er = xdg_alloc;
a1loge(g_log, 1, "xdg_bds: malloc failed\n");
@@ -323,7 +327,7 @@ int xdg_bds(
}
#endif
} else {
- if ((home = getenv("HOME")) == NULL
+ if ((home = login_HOME()) == NULL
#ifdef NT
&& (home = getenv("APPDATA")) == NULL
#endif
@@ -339,7 +343,7 @@ int xdg_bds(
return 0;
}
#ifdef NT
- if (getenv("HOME") != NULL)
+ if (login_HOME() != NULL)
path = dappend(path, ".local/share");
#else
#ifdef UNIX_APPLE
@@ -363,7 +367,7 @@ int xdg_bds(
return 0;
}
#ifdef NT
- } else if (getenv("HOME") == NULL && (xdg = getenv("APPDATA")) != NULL) {
+ } else if (login_HOME() == NULL && (xdg = getenv("APPDATA")) != NULL) {
if ((path = cappend(path, xdg)) == NULL) {
if (er != NULL) *er = xdg_alloc;
a1loge(g_log, 1, "xdg_bds: malloc failed\n");
@@ -371,7 +375,7 @@ int xdg_bds(
}
#endif
} else {
- if ((home = getenv("HOME")) == NULL
+ if ((home = login_HOME()) == NULL
#ifdef NT
&& (home = getenv("APPDATA")) == NULL
#endif
@@ -387,7 +391,7 @@ int xdg_bds(
return 0;
}
#ifdef NT
- if (getenv("HOME") != NULL)
+ if (login_HOME() != NULL)
path = dappend(path, ".config");
#else
#ifdef UNIX_APPLE
@@ -411,7 +415,7 @@ int xdg_bds(
return 0;
}
#ifdef NT
- } else if (getenv("HOME") == NULL && (xdg = getenv("APPDATA")) != NULL) {
+ } else if (login_HOME() == NULL && (xdg = getenv("APPDATA")) != NULL) {
if ((path = cappend(path, xdg)) == NULL) {
if (er != NULL) *er = xdg_alloc;
a1loge(g_log, 1, "xdg_bds: malloc failed\n");
@@ -424,7 +428,7 @@ int xdg_bds(
}
#endif
} else {
- if ((home = getenv("HOME")) == NULL
+ if ((home = login_HOME()) == NULL
#ifdef NT
&& (home = getenv("APPDATA")) == NULL
#endif
@@ -440,7 +444,7 @@ int xdg_bds(
return 0;
}
#ifdef NT
- if (getenv("HOME") != NULL)
+ if (login_HOME() != NULL)
path = dappend(path, ".cache");
else
path = dappend(path, "Cache");
@@ -662,18 +666,20 @@ int xdg_bds(
}
DBG((DBGA,"Found match with '%s'\n",fpath))
- /* Check that this one hasn't already been found */
- /* in a different search directory */
- for (i = 0; i < npaths; i++) {
- if (strcmp(fpath + rlen, fnames[i]) == 0) {
- /* Already been found earlier - ignore it */
- break;
+ if (opt != xdg_all_matches) {
+ /* Check that this one hasn't already been found */
+ /* in a different search directory */
+ for (i = 0; i < npaths; i++) {
+ if (strcmp(fpath + rlen, fnames[i]) == 0) {
+ /* Already been found earlier - ignore it */
+ break;
+ }
+ }
+ if (i < npaths) {
+ free(fpath);
+ DBG((DBGA,"Ignoring it because it's already in list\n"))
+ continue; /* Ignore it */
}
- }
- if (i < npaths) {
- free(fpath);
- DBG((DBGA,"Ignoring it because it's already in list\n"))
- continue; /* Ignore it */
}
/* Found a file, so append it to the list */
@@ -969,7 +975,7 @@ static int runtest(
}
printf("\nTesting Variable %s\n",env);
- if ((nopaths = xdg_bds(&er, &paths, st, xdg_write, sc, pfname)) == 0) {
+ if ((nopaths = xdg_bds(&er, &paths, st, xdg_write, sc, xdg_none, pfname)) == 0) {
printf("Write test failed with %s\n",xdg_errstr(er));
return 1;
}
@@ -996,7 +1002,7 @@ static int runtest(
}
xdg_free(paths, nopaths);
- if ((nopaths = xdg_bds(&er, &paths, st, xdg_read, sc, pfname)) < 1) {
+ if ((nopaths = xdg_bds(&er, &paths, st, xdg_read, sc, xdg_none, pfname)) < 1) {
printf("Read test failed with %s\n",xdg_errstr(er));
return 1;
}
diff --git a/spectro/xdg_bds.h b/spectro/xdg_bds.h
index 18101b0..9eb6651 100644..100755
--- a/spectro/xdg_bds.h
+++ b/spectro/xdg_bds.h
@@ -51,6 +51,12 @@ typedef enum {
xdg_local /* Local System wide context */
} xdg_scope;
+/* Optional flags */
+typedef enum {
+ xdg_none = 0x0000, /* No options */
+ xdg_all_matches = 0x0001 /* Return all matching files */
+} xdg_options;
+
/* An error code */
typedef enum {
xdg_ok = 0,
@@ -96,6 +102,7 @@ int xdg_bds(
xdg_storage_type st, /* Specify the storage type */
xdg_op_type op, /* Operation type */
xdg_scope sc, /* Scope if write */
+ xdg_options opt, /* Options flags */
char *spath /* Sub-path and file name or file pattern */
);
diff --git a/spectro/xrga.c b/spectro/xrga.c
index 0bf22fa..7318fce 100644..100755
--- a/spectro/xrga.c
+++ b/spectro/xrga.c
@@ -42,6 +42,7 @@
#ifndef SALONEINSTLIB
# include "plot.h"
#endif
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
diff --git a/spectro/xrga.h b/spectro/xrga.h
index 0605fc8..0605fc8 100644..100755
--- a/spectro/xrga.h
+++ b/spectro/xrga.h