summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rwxr-xr-xJambase4
-rwxr-xr-xReadme.txt6
-rw-r--r--debian/argyll.install1
-rw-r--r--debian/changelog8
-rw-r--r--debian/maintscript1
-rw-r--r--debian/patches/0001_jam.patch6
-rw-r--r--debian/patches/0100_spelling.patch137
-rw-r--r--debian/patches/0105_dispwin_segfault.patch2
-rwxr-xr-x[-rw-r--r--]doc/ArgyllDoc.html800
-rwxr-xr-x[-rw-r--r--]doc/ChangesSummary.html2509
-rwxr-xr-xdoc/XRGA.html24
-rwxr-xr-xdoc/collink.html130
-rwxr-xr-xdoc/instruments.html219
-rwxr-xr-xdoc/profcheck.html16
-rwxr-xr-xdoc/spec2cie.html24
-rwxr-xr-xdoc/spotread.html50
-rwxr-xr-xgamut/gammap.c2
-rwxr-xr-xh/aconfig.h9
-rwxr-xr-xh/counters.h6
-rwxr-xr-xicc/Jamfile2
-rwxr-xr-xicc/icc.c240
-rwxr-xr-xicc/icc.h62
-rwxr-xr-xlink/collink.c1422
-rwxr-xr-xlog.txt42
-rwxr-xr-xmakepackagebin.sh7
-rwxr-xr-xnamedc/namedc.c8
-rwxr-xr-xnumlib/Jamfile4
-rwxr-xr-xnumlib/afiles5
-rwxr-xr-xnumlib/dhsx.c11
-rwxr-xr-xnumlib/dhsx.h6
-rwxr-xr-xnumlib/dnsq.c1
-rwxr-xr-xnumlib/dnsq.h3
-rwxr-xr-xnumlib/dnsqtest.c2
-rwxr-xr-xnumlib/gnewt.c413
-rwxr-xr-xnumlib/gnewt.h59
-rwxr-xr-xnumlib/ludecomp.c73
-rwxr-xr-xnumlib/ludecomp.h26
-rwxr-xr-xnumlib/numlib.h2
-rwxr-xr-xnumlib/numsup.c200
-rwxr-xr-xnumlib/numsup.h45
-rwxr-xr-xnumlib/powell.c712
-rwxr-xr-xnumlib/powell.h23
-rwxr-xr-xnumlib/quadprog.c35
-rwxr-xr-xnumlib/quadprog.h18
-rwxr-xr-xnumlib/rand.c21
-rwxr-xr-xnumlib/rand.h10
-rwxr-xr-xnumlib/roots.c217
-rwxr-xr-xnumlib/roots.h23
-rwxr-xr-xnumlib/tconjgrad.c162
-rwxr-xr-xplot/plot.c346
-rwxr-xr-xplot/plot.h30
-rwxr-xr-xprofile/colverify.c2
-rwxr-xr-xprofile/mppcheck.c2
-rwxr-xr-xprofile/mppprof.c8
-rwxr-xr-xprofile/printcal.c2
-rwxr-xr-xprofile/profcheck.c4
-rwxr-xr-xprofile/profin.c3
-rwxr-xr-xprofile/profout.c3
-rwxr-xr-xref/linear.cal2
-rwxr-xr-xref/strange.cal2
-rwxr-xr-xrender/render.h2
-rw-r--r--rspl/Jamfile2
-rwxr-xr-xrspl/smtmpp.c1
-rwxr-xr-xrspl/smtnd.c1
-rwxr-xr-xrspl/t2d.c1
-rwxr-xr-xrspl/t2ddf.c1
-rwxr-xr-xrspl/t3d.c1
-rwxr-xr-xrspl/t3ddf.c1
-rwxr-xr-xspectro/ccxxmake.c16
-rwxr-xr-xspectro/chartread.c15
-rwxr-xr-xspectro/colorhug.c12
-rwxr-xr-xspectro/conv.c3
-rwxr-xr-xspectro/dispcal.c32
-rwxr-xr-xspectro/dispread.c10
-rwxr-xr-xspectro/dispsup.c46
-rwxr-xr-xspectro/dispsup.h18
-rwxr-xr-xspectro/disptechs.c2
-rwxr-xr-xspectro/dispwin.c4
-rwxr-xr-xspectro/ex1.c2
-rwxr-xr-xspectro/i1d3.c6
-rwxr-xr-xspectro/i1d3.h20
-rwxr-xr-xspectro/i1pro_imp.c171
-rwxr-xr-xspectro/i1pro_imp.h37
-rwxr-xr-xspectro/icoms.c10
-rwxr-xr-xspectro/icoms.h3
-rwxr-xr-xspectro/icoms_nt.c11
-rwxr-xr-xspectro/illumread.c6
-rwxr-xr-xspectro/inst.c59
-rwxr-xr-xspectro/inst.h6
-rwxr-xr-xspectro/instappsup.c30
-rwxr-xr-xspectro/instappsup.h5
-rwxr-xr-xspectro/instlib.ksh1
-rwxr-xr-xspectro/kleink10.c21
-rwxr-xr-xspectro/munki_imp.c4
-rwxr-xr-xspectro/sa_conv.h4
-rwxr-xr-xspectro/spec2cie.c129
-rwxr-xr-xspectro/specbos.c64
-rwxr-xr-xspectro/specbos.h4
-rwxr-xr-xspectro/spotread.c100
-rwxr-xr-xspectro/spyd2.c2
-rwxr-xr-xspectro/ss.c5
-rwxr-xr-xspectro/ss_imp.c34
-rwxr-xr-xspectro/vtpglut.c10
-rwxr-xr-xspectro/xrga.c15
-rwxr-xr-xtarget/ofps.c1
-rwxr-xr-xtarget/prand.c1
-rwxr-xr-xtarget/targen.c2
-rwxr-xr-xtweak/refine.c2
-rwxr-xr-xusb/ArgyllCMS.catbin3635 -> 3635 bytes
-rwxr-xr-xusb/ArgyllCMS_x64.catbin3619 -> 3619 bytes
-rwxr-xr-xxicc/bt1886.c2
-rwxr-xr-xxicc/bt1886.h3
-rwxr-xr-xxicc/ccmx.c7
-rwxr-xr-xxicc/ccss.c10
-rwxr-xr-xxicc/ccttest.c1
-rwxr-xr-xxicc/cgatsplot.c1
-rwxr-xr-xxicc/cv.c1
-rwxr-xr-xxicc/cvtest.c1
-rwxr-xr-xxicc/mpp.c8
-rwxr-xr-xxicc/mpplu.c1
-rwxr-xr-xxicc/specplot.c1
-rwxr-xr-xxicc/specsubsamp.c1
-rwxr-xr-xxicc/spectest.c11
-rwxr-xr-xxicc/spectest2.c7
-rwxr-xr-xxicc/transplot.c1
-rwxr-xr-xxicc/xcal.c1
-rwxr-xr-xxicc/xdgb.c2
-rwxr-xr-xxicc/xfit.c2
-rwxr-xr-xxicc/xicc.c1
-rwxr-xr-xxicc/xicclu.c2
-rwxr-xr-xxicc/xlutfix.c3
-rwxr-xr-xxicc/xspect.c306
-rwxr-xr-xxicc/xspect.h27
134 files changed, 6455 insertions, 3093 deletions
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 6c270cd..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-.bzr
-.bzrignore
-.pc \ No newline at end of file
diff --git a/Jambase b/Jambase
index a54a03f..3d046e4 100755
--- a/Jambase
+++ b/Jambase
@@ -647,6 +647,10 @@ if $(NT)
Wbemuuid.lib
Version.lib
;
+ if $(MSVCVER) >= 8 {
+ STDLIBS += psapi.lib ;
+ }
+
SHSTDLIBS ?= $(STDLIBS) ;
LINKFLAG ?= ;
STDHDRS ?= $(MSNTSDK)\\Include ;
diff --git a/Readme.txt b/Readme.txt
index 38c9ce1..82e9ee1 100755
--- a/Readme.txt
+++ b/Readme.txt
@@ -1,8 +1,8 @@
-Argyll CMS README file - Version 2.0.0
+Argyll CMS README file - Version 2.0.1
--------------------------------------
-Date: 17th November 2017
+Date: 9th July 2018
Author: Graeme Gill
Introduction
@@ -26,7 +26,7 @@ provided for each major tool, and a general guide to using the tools for
typical color management tasks is also available. A mailing list provides
support for more advanced usage.
-This is Version 2.0.0, a feature and bug fix update to the last major release V1.9.2.
+This is Version 2.0.1, a bug fix update to the last major release V2.0.0.
The first public release of icclib was in November 1998,
and of Argyll was in October 2000. Code development commenced in 1995. See
Changes Summary for an overview of changes since the last release. Changes
diff --git a/debian/argyll.install b/debian/argyll.install
index 0b1afee..731397a 100644
--- a/debian/argyll.install
+++ b/debian/argyll.install
@@ -1,3 +1,2 @@
usb/55-Argyll.rules lib/udev/rules.d/
-usb/Argyll.usermap etc/hotplug/usb
usr/bin/*
diff --git a/debian/changelog b/debian/changelog
index bb38595..5436b25 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,12 @@
-argyll (2.0.0+repack-2) UNRELEASED; urgency=medium
+argyll (2.0.1+repack-1) UNRELEASED; urgency=medium
+ * New upstream release:
+ - Refresh patches.
* debian/copyright: Add copyright for numlib/quadprog.*.
+ * Remove obsolete /etc/hotplug/usb/Argyll.usermap (Closes: #885549).
+ * Add more typos to patches/0100_spelling.patch.
- -- Jörg Frings-Fürst <debian@jff.email> Sun, 03 Dec 2017 20:41:38 +0100
+ -- Jörg Frings-Fürst <debian@jff.email> Wed, 11 Jul 2018 22:21:14 +0200
argyll (2.0.0+repack-1) unstable; urgency=medium
diff --git a/debian/maintscript b/debian/maintscript
new file mode 100644
index 0000000..99b4d26
--- /dev/null
+++ b/debian/maintscript
@@ -0,0 +1 @@
+rm_conffile /etc/hotplug/usb/Argyll.usermap 2.0.1-1~
diff --git a/debian/patches/0001_jam.patch b/debian/patches/0001_jam.patch
index b0469f3..976f485 100644
--- a/debian/patches/0001_jam.patch
+++ b/debian/patches/0001_jam.patch
@@ -8,7 +8,7 @@ Index: trunk/Jambase
===================================================================
--- trunk.orig/Jambase
+++ trunk/Jambase
-@@ -941,7 +941,7 @@ else if $(UNIX)
+@@ -945,7 +945,7 @@ else if $(UNIX)
# UNIX defaults
@@ -17,7 +17,7 @@ Index: trunk/Jambase
CCOPTFLAG ?= -O2 ;
CCDEBUGFLAG ?= -g ;
CCPROFFLAG ?= ;
-@@ -951,7 +951,7 @@ else if $(UNIX)
+@@ -955,7 +955,7 @@ else if $(UNIX)
CHGRP ?= chgrp ;
CHOWN ?= chown ;
LEX ?= lex ;
@@ -26,7 +26,7 @@ Index: trunk/Jambase
LINKOPTFLAG ?= -O ; # Affects creating .so's
LINKSTRIPFLAG ?= -s ;
LINKDEBUGFLAG ?= ;
-@@ -1037,7 +1037,7 @@ else if $(UNIX)
+@@ -1041,7 +1041,7 @@ else if $(UNIX)
RMDIR ?= $(RM) ;
RSH ?= rsh ;
SED ?= sed ;
diff --git a/debian/patches/0100_spelling.patch b/debian/patches/0100_spelling.patch
index 9797224..04dc5e9 100644
--- a/debian/patches/0100_spelling.patch
+++ b/debian/patches/0100_spelling.patch
@@ -41,7 +41,7 @@ Index: trunk/spectro/dispcal.c
comport = atoi(na);
if (comport < 1 || comport > 50) usage(0,"-c parameter %d out of range",comport);
-@@ -3111,7 +3111,7 @@ int main(int argc, char *argv[]) {
+@@ -3114,7 +3114,7 @@ int main(int argc, char *argv[]) {
/* Black level adjustment */
/* Due to the possibility of the channel offsets not being even, */
/* we use the largest of the XYZ values after they have been */
@@ -54,7 +54,7 @@ Index: trunk/spectro/spotread.c
===================================================================
--- trunk.orig/spectro/spotread.c
+++ trunk/spectro/spotread.c
-@@ -509,7 +509,7 @@ int main(int argc, char *argv[]) {
+@@ -517,7 +517,7 @@ int main(int argc, char *argv[]) {
/* COM port */
} else if (argv[fa][1] == 'c') {
fa = nfa;
@@ -63,16 +63,16 @@ Index: trunk/spectro/spotread.c
{
comport = atoi(na);
if (comport < 1 || comport > 40) usage("-c parameter %d out of range",comport);
-@@ -518,7 +518,7 @@ int main(int argc, char *argv[]) {
+@@ -526,7 +526,7 @@ int main(int argc, char *argv[]) {
/* Display type */
} else if (argv[fa][1] == 'y') {
fa = nfa;
- if (na == NULL) usage("Paramater expected following -y");
+ if (na == NULL) usage("Parameter expected following -y");
- dtype = na[0];
-
- #ifndef SALONEINSTLIB
-@@ -526,7 +526,7 @@ int main(int argc, char *argv[]) {
+ ditype = na[0];
+ if (ditype == '_' && na[1] != '\000')
+ ditype = ditype << 8 | na[1];
+@@ -536,7 +536,7 @@ int main(int argc, char *argv[]) {
} else if (argv[fa][1] == 'I') {
fa = nfa;
@@ -81,7 +81,7 @@ Index: trunk/spectro/spotread.c
if (strcmp(na, "A") == 0
|| strcmp(na, "M0") == 0) {
tillum_set = spec = 1;
-@@ -574,7 +574,7 @@ int main(int argc, char *argv[]) {
+@@ -584,7 +584,7 @@ int main(int argc, char *argv[]) {
/* Spectral Illuminant type for XYZ computation */
} else if (argv[fa][1] == 'i') {
fa = nfa;
@@ -90,7 +90,7 @@ Index: trunk/spectro/spotread.c
if (strcmp(na, "A") == 0) {
illum_set = spec = 1;
illum = icxIT_A;
-@@ -623,7 +623,7 @@ int main(int argc, char *argv[]) {
+@@ -639,7 +639,7 @@ int main(int argc, char *argv[]) {
/* Spectral Observer type */
} else if (argv[fa][1] == 'Q') {
fa = nfa;
@@ -99,7 +99,7 @@ Index: trunk/spectro/spotread.c
if (strcmp(na, "1931_2") == 0) { /* Classic 2 degree */
obType = icxOT_CIE_1931_2;
} else if (strcmp(na, "1964_10") == 0) { /* Classic 10 degree */
-@@ -712,7 +712,7 @@ int main(int argc, char *argv[]) {
+@@ -728,7 +728,7 @@ int main(int argc, char *argv[]) {
/* Filter configuration */
} else if (argv[fa][1] == 'F') {
fa = nfa;
@@ -108,7 +108,7 @@ Index: trunk/spectro/spotread.c
if (na[0] == 'n' || na[0] == 'N')
fe = inst_opt_filter_none;
else if (na[0] == 'p' || na[0] == 'P')
-@@ -727,13 +727,13 @@ int main(int argc, char *argv[]) {
+@@ -743,13 +743,13 @@ int main(int argc, char *argv[]) {
/* Extra filter compensation file */
} else if (argv[fa][1] == 'E') {
fa = nfa;
@@ -124,7 +124,7 @@ Index: trunk/spectro/spotread.c
if (na[0] == 'N')
calstd = xcalstd_none;
else if (na[0] == 'A')
-@@ -743,7 +743,7 @@ int main(int argc, char *argv[]) {
+@@ -759,7 +759,7 @@ int main(int argc, char *argv[]) {
else if (na[0] == 'G')
calstd = xcalstd_gmdi;
else
@@ -133,7 +133,7 @@ Index: trunk/spectro/spotread.c
/* Show Yxy */
} else if (argv[fa][1] == 'x') {
-@@ -1479,7 +1479,7 @@ int main(int argc, char *argv[]) {
+@@ -1513,7 +1513,7 @@ int main(int argc, char *argv[]) {
/* Or something is wrong with instrument capabilities */
} else {
@@ -159,7 +159,7 @@ Index: trunk/spectro/dispwin.c
===================================================================
--- trunk.orig/spectro/dispwin.c
+++ trunk/spectro/dispwin.c
-@@ -5234,7 +5234,7 @@ int ddebug /* >0 to print debug sta
+@@ -5238,7 +5238,7 @@ int ddebug /* >0 to print debug sta
vinfo = XGetVisualInfo(p->mydisplay, VisualIDMask, &template, &nitems);
if (nitems < 1) {
@@ -242,7 +242,7 @@ Index: trunk/spectro/i1pro_imp.c
===================================================================
--- trunk.orig/spectro/i1pro_imp.c
+++ trunk/spectro/i1pro_imp.c
-@@ -2701,7 +2701,7 @@ int *pinstmsec) { /* Return instrument l
+@@ -2780,7 +2780,7 @@ int *pinstmsec) { /* Return instrument l
break;
}
@@ -251,7 +251,7 @@ Index: trunk/spectro/i1pro_imp.c
/* Compute overall delay */
dispmsec = (int)(samp[i].sec * 1000.0 + 0.5); /* Display update time */
-@@ -3154,7 +3154,7 @@ i1pro_code i1pro_imp_measure(
+@@ -3233,7 +3233,7 @@ i1pro_code i1pro_imp_measure(
}
}
@@ -260,7 +260,7 @@ Index: trunk/spectro/i1pro_imp.c
if (user_trig)
return I1PRO_USER_TRIG;
return ev;
-@@ -3816,7 +3816,7 @@ i1pro_code i1pro_imp_meas_refrate(
+@@ -3895,7 +3895,7 @@ i1pro_code i1pro_imp_meas_refrate(
}
}
} else {
@@ -269,7 +269,7 @@ Index: trunk/spectro/i1pro_imp.c
}
return I1PRO_RD_NOREFR_FOUND;
-@@ -3911,7 +3911,7 @@ i1pro_code i1pro_restore_refspot_cal(i1p
+@@ -3990,7 +3990,7 @@ i1pro_code i1pro_restore_refspot_cal(i1p
return I1PRO_OK;
}
@@ -278,7 +278,7 @@ Index: trunk/spectro/i1pro_imp.c
s->dark_valid = 1;
s->ddate = m->caldate;
-@@ -3956,7 +3956,7 @@ i1pro_code i1pro_restore_refspot_cal(i1p
+@@ -4035,7 +4035,7 @@ i1pro_code i1pro_restore_refspot_cal(i1p
return I1PRO_OK;
}
@@ -287,7 +287,7 @@ Index: trunk/spectro/i1pro_imp.c
s->cal_valid = 1;
s->cfdate = m->caldate;
-@@ -4312,7 +4312,7 @@ i1pro_code i1pro_save_calibration(i1pro
+@@ -4391,7 +4391,7 @@ i1pro_code i1pro_save_calibration(i1pro
write_doubles(&x, fp, s->idark_data[3]-1, m->nraw+1);
}
@@ -313,7 +313,7 @@ Index: trunk/spectro/ss.c
===================================================================
--- trunk.orig/spectro/ss.c
+++ trunk/spectro/ss.c
-@@ -375,7 +375,7 @@ ss_init_coms(inst *pp, baud_rate br, flo
+@@ -376,7 +376,7 @@ ss_init_coms(inst *pp, baud_rate br, flo
p->gotcoms = 1;
@@ -322,7 +322,7 @@ Index: trunk/spectro/ss.c
return inst_ok;
}
-@@ -1744,7 +1744,7 @@ ss_interp_error(inst *pp, int ec) {
+@@ -1745,7 +1745,7 @@ ss_interp_error(inst *pp, int ec) {
case ss_et_FilterOutOfPos:
return "Filter wheel out of position";
case ss_et_SendTimeout:
@@ -331,7 +331,7 @@ Index: trunk/spectro/ss.c
case ss_et_DriveError:
return "Data drive defect";
case ss_et_MeasDisabled:
-@@ -1864,7 +1864,7 @@ ss_interp_error(inst *pp, int ec) {
+@@ -1865,7 +1865,7 @@ ss_interp_error(inst *pp, int ec) {
case ss_et_BadHexEncoding:
return "Message received from instrument has bad Hex encoding";
case ss_et_RecBufferOverun:
@@ -370,7 +370,7 @@ Index: trunk/xicc/cv.c
===================================================================
--- trunk.orig/xicc/cv.c
+++ trunk/xicc/cv.c
-@@ -101,7 +101,7 @@ main(int argc, char *argv[]) {
+@@ -102,7 +102,7 @@ main(int argc, char *argv[]) {
printf("There are %d parameters:\n",np); fflush(stdout);
for (i = 0; i < np; i++) {
@@ -667,34 +667,7 @@ Index: trunk/link/collink.c
===================================================================
--- trunk.orig/link/collink.c
+++ trunk/link/collink.c
-@@ -1122,7 +1122,7 @@ void devip_devop(void *cntx, double *out
- }
- /* We've got the input profile PCS' at this point. */
-
-- /* If we're transfering the K value from the input profile to the */
-+ /* If we're transferring the K value from the input profile to the */
- /* output, copy it into locus[], which will be given to the inverse */
- /* lookup function, else the inverse lookup will generate a K using */
- /* the curve parameters. */
-@@ -1204,7 +1204,7 @@ void devip_devop(void *cntx, double *out
- if (p->verb)
- #endif
- {
-- printf("White point hack mapped %f %f %f to %f %f %f, hit withing %f\n",
-+ printf("White point hack mapped %f %f %f to %f %f %f, hit within %f\n",
- p->in.wp[0],p->in.wp[1],p->in.wp[2],pcsv[0], pcsv[1], pcsv[2],dd);
- fflush(stdout);
- }
-@@ -1254,7 +1254,7 @@ void devip_devop(void *cntx, double *out
- if (p->nhack == 2) {
- /* Ideally we would create a 4D PCSK -> PCSK gamut mapping */
- /* to smoothly and accurately cope with the changing source */
-- /* and destination gamuts acording to their degree of "K onlyness". */
-+ /* and destination gamuts according to their degree of "K onlyness". */
- /* In practice we're going to simply interpolated between */
- /* two extremes: unrestricted gamut and K only black gamut. */
- double map0[3], map1[3];
-@@ -4807,7 +4807,7 @@ main(int argc, char *argv[]) {
+@@ -4899,7 +4899,7 @@ main(int argc, char *argv[]) {
}
if (li.verb)
@@ -720,7 +693,7 @@ Index: trunk/spectro/dispsup.c
===================================================================
--- trunk.orig/spectro/dispsup.c
+++ trunk/spectro/dispsup.c
-@@ -721,7 +721,7 @@ static int disprd_read_imp(
+@@ -722,7 +722,7 @@ static int disprd_read_imp(
scb->serno = p->serno++;
scb->msec = msec_time();
@@ -729,7 +702,7 @@ Index: trunk/spectro/dispsup.c
val.XYZ[0], val.XYZ[1], val.XYZ[2]);
scb->mtype = val.mtype;
-@@ -1241,7 +1241,7 @@ int disprd_ambient(
+@@ -1242,7 +1242,7 @@ int disprd_ambient(
/* Or something is wrong with instrument capabilities */
} else {
@@ -738,7 +711,7 @@ Index: trunk/spectro/dispsup.c
return 2;
}
-@@ -2344,7 +2344,7 @@ static int config_inst_displ(disprd *p)
+@@ -2346,7 +2346,7 @@ static int config_inst_displ(disprd *p)
/* Reset key meanings */
inst_reset_uih();
@@ -751,7 +724,7 @@ Index: trunk/gamut/gammap.c
===================================================================
--- trunk.orig/gamut/gammap.c
+++ trunk/gamut/gammap.c
-@@ -859,7 +859,7 @@ gammap *new_gammap(
+@@ -861,7 +861,7 @@ gammap *new_gammap(
#endif
if (gmi->bph == gmm_clipBP) {
@@ -764,7 +737,7 @@ Index: trunk/profile/profout.c
===================================================================
--- trunk.orig/profile/profout.c
+++ trunk/profile/profout.c
-@@ -1104,7 +1104,7 @@ make_output_icc(
+@@ -1105,7 +1105,7 @@ make_output_icc(
if (iccver < icmVersion2_4) {
iccver = icmVersion2_4; /* Need 2.4.0 for Display intents */
if (verb)
@@ -790,7 +763,7 @@ Index: trunk/xicc/xspect.c
===================================================================
--- trunk.orig/xicc/xspect.c
+++ trunk/xicc/xspect.c
-@@ -4454,7 +4454,7 @@ void xspect_plot10p(xspect *sp[10], int
+@@ -4509,7 +4509,7 @@ void xspect_plotNp(xspect *sp[MXGPHS], i
/* Given an emission spectrum, set the UV output to the given level. */
/* The shape of the UV is taken from FWA1_stim, and the level is */
/* with respect to the Y of the input spectrum. */
@@ -812,7 +785,7 @@ Index: trunk/spectro/ccxxmake.c
comno = atoi(na);
if (comno < 1 || comno > 40) usage(0,"-c parameter %d out of range",comno);
-@@ -508,7 +508,7 @@ int main(int argc, char *argv[]) {
+@@ -510,7 +510,7 @@ int main(int argc, char *argv[]) {
/* Serial port flow control */
} else if (argv[fa][1] == 'W') {
fa = nfa;
@@ -821,7 +794,7 @@ Index: trunk/spectro/ccxxmake.c
if (na[0] == 'n' || na[0] == 'N')
fc = fc_None;
else if (na[0] == 'h' || na[0] == 'H')
-@@ -597,7 +597,7 @@ int main(int argc, char *argv[]) {
+@@ -599,7 +599,7 @@ int main(int argc, char *argv[]) {
strcat(outname, doccss ? ".ccss" : ".ccmx");
if (fakeseq && doccss)
@@ -830,7 +803,7 @@ Index: trunk/spectro/ccxxmake.c
printf("\n");
-@@ -813,7 +813,7 @@ int main(int argc, char *argv[]) {
+@@ -815,7 +815,7 @@ int main(int argc, char *argv[]) {
refs[i][2] = cols[i][2];
}
gotref = 1;
@@ -1298,7 +1271,7 @@ Index: trunk/xicc/mpp.c
===================================================================
--- trunk.orig/xicc/mpp.c
+++ trunk/xicc/mpp.c
-@@ -733,7 +733,7 @@ int use_fwa /* NZ to involke
+@@ -735,7 +735,7 @@ int use_fwa /* NZ to involke
error ("mpp->set_ilob, instrument doesn't have an FWA illuminent");
if (p->spc->set_fwa(p->spc, &inst, NULL, &white))
@@ -1324,7 +1297,7 @@ Index: trunk/target/ofps.c
===================================================================
--- trunk.orig/target/ofps.c
+++ trunk/target/ofps.c
-@@ -2612,7 +2612,7 @@ static int position_vtx(
+@@ -2613,7 +2613,7 @@ static int position_vtx(
if (tries > s->maxretries)
s->maxretries = tries;
#ifdef DEBUG
@@ -1333,7 +1306,7 @@ Index: trunk/target/ofps.c
printf(" oog = %f, eperr = %f, ceperr = %f\n",vv->oog,vv->eperr,vv->ceperr);
#endif
//if (tries > 10)
-@@ -2627,7 +2627,7 @@ static int position_vtx(
+@@ -2628,7 +2628,7 @@ static int position_vtx(
#ifdef DUMP_FERR /* Create .tiff of dnsq function error */
if (tries >= DUMP_FERR) {
@@ -1342,7 +1315,7 @@ Index: trunk/target/ofps.c
/* Re-run the last unsucessful dnsq, to trace the path */
pcx.debug = 1;
-@@ -6221,7 +6221,7 @@ static int ofps_findhit_vtxs(ofps *s, no
+@@ -6222,7 +6222,7 @@ static int ofps_findhit_vtxs(ofps *s, no
int hit = 0;
if (nn->ix < 0)
@@ -1351,7 +1324,7 @@ Index: trunk/target/ofps.c
#ifdef DEBUG
if (s->agrid_init == 0)
-@@ -8023,7 +8023,7 @@ ofps *s
+@@ -8024,7 +8024,7 @@ ofps *s
warning("Verify of incremental vertexes failed!");
printf("Verify of incremental vertexes failed!\n");
} else {
@@ -1360,7 +1333,7 @@ Index: trunk/target/ofps.c
}
#ifdef DUMP_STRUCTURE
dump_node_vtxs(s, 1);
-@@ -8443,7 +8443,7 @@ int nopstop /* Debug - number of opti
+@@ -8444,7 +8444,7 @@ int nopstop /* Debug - number of opti
fprintf(stderr,"Average dnsqs/position = %.2f\n",s->dnsqs/(double)s->positions);
fprintf(stderr,"Average function calls/dnsq = %.1f\n",s->funccount/(double)s->dnsqs);
fprintf(stderr,"Maximum function calls/dnsq = %d\n",s->maxfunc);
@@ -1412,6 +1385,15 @@ Index: trunk/spectro/smcube.c
p->gotcoms = 1;
+@@ -768,7 +768,7 @@ smcube_interp_error(inst *pp, int ec) {
+ case SMCUBE_INT_THREADFAILED:
+ return "Starting diffuser position thread failed";
+ case SMCUBE_INT_ILL_WRITE:
+- return "Attemp to write to factory calibration";
++ return "Attempt to write to factory calibration";
+ case SMCUBE_INT_WHITE_CALIB:
+ return "No valid white calibration";
+ case SMCUBE_INT_BLACK_CALIB:
@@ -1248,7 +1248,7 @@ smcube_get_idle_time(smcube *p, int *pit
itime = read_ORD16_be(buf + 4);
@@ -1457,7 +1439,7 @@ Index: trunk/spectro/kleink10.c
===================================================================
--- trunk.orig/spectro/kleink10.c
+++ trunk/spectro/kleink10.c
-@@ -729,7 +729,7 @@ int ix /* Klein calibration index 1
+@@ -730,7 +730,7 @@ int ix /* Klein calibration index 1
if (buf[0] != 'D' || buf[1] != '1') {
amutex_unlock(p->lock);
@@ -1466,7 +1448,7 @@ Index: trunk/spectro/kleink10.c
return inst_protocol_error;
}
-@@ -2068,7 +2068,7 @@ int *pinstmsec) { /* Return instrument r
+@@ -2077,7 +2077,7 @@ int *pinstmsec) { /* Return instrument r
break;
}
@@ -1570,7 +1552,7 @@ Index: trunk/spectro/specbos.c
/* See if it's a 1501 or 1511 */
if (p->model == 1501) {
-@@ -1669,7 +1669,7 @@ char id[CALIDLEN] /* Condition identifi
+@@ -1693,7 +1693,7 @@ char id[CALIDLEN] /* Condition identifi
if ((ev = specbos_get_n_a_cals((inst *)p, &needed, &available)) != inst_ok)
return ev;
@@ -1583,7 +1565,7 @@ Index: trunk/plot/plot.c
===================================================================
--- trunk.orig/plot/plot.c
+++ trunk/plot/plot.c
-@@ -2459,7 +2459,7 @@ static void dprintf(char *fmt, ...) {
+@@ -2521,7 +2521,7 @@ static void dprintf(char *fmt, ...) {
printf("~1 found NtQueryInformationProcess\n"); fflush(stdout);
if(NtQueryInformationProcess(GetCurrentProcess(), 0,
&pbi, sizeof(pbi), &ulSize) >= 0 && ulSize == sizeof(pbi)) {
@@ -1718,3 +1700,16 @@ Index: trunk/spectro/munki_imp.h
#define MUNKI_INT_CAL_SAVE 0x65 /* Unable to save calibration to file */
#define MUNKI_INT_CAL_RESTORE 0x66 /* Unable to restore calibration from file */
#define MUNKI_INT_CAL_TOUCH 0x67 /* Unable to touch calibration file */
+Index: trunk/spectro/spec2cie.c
+===================================================================
+--- trunk.orig/spectro/spec2cie.c
++++ trunk/spectro/spec2cie.c
+@@ -215,7 +215,7 @@ main(int argc, char *argv[])
+ calstdi = xcalstd_gmdi;
+ calstdo = xcalstd_xrdi;
+ } else {
+- //usage("Paramater after -A '%c%c' not recognized",na[0],na[1]);
++ //usage("Parameter after -A '%c%c' not recognized",na[0],na[1]);
+ usage();
+ }
+ }
diff --git a/debian/patches/0105_dispwin_segfault.patch b/debian/patches/0105_dispwin_segfault.patch
index 3ead582..d69d9d6 100644
--- a/debian/patches/0105_dispwin_segfault.patch
+++ b/debian/patches/0105_dispwin_segfault.patch
@@ -10,7 +10,7 @@ Index: trunk/spectro/dispwin.c
===================================================================
--- trunk.orig/spectro/dispwin.c
+++ trunk/spectro/dispwin.c
-@@ -6277,6 +6277,7 @@ main(int argc, char *argv[]) {
+@@ -6281,6 +6281,7 @@ main(int argc, char *argv[]) {
/* Display number */
else if (argv[fa][1] == 'd') {
diff --git a/doc/ArgyllDoc.html b/doc/ArgyllDoc.html
index 8463fcf..f346f18 100644..100755
--- a/doc/ArgyllDoc.html
+++ b/doc/ArgyllDoc.html
@@ -10,9 +10,9 @@
<title>Argyll Documentation Top</title>
</head>
<body>
- <h1> ArgyllCMS documentation index (V2.0.0)<br>
+ <h1> ArgyllCMS documentation index (V2.0.1)<br>
</h1>
- Date:&nbsp;&nbsp; 17th November 2017<br>
+ Date:&nbsp;&nbsp; 9th July 2018<br>
Author: Graeme Gill
<h2><u><a name="Intro"></a>Introduction</u></h2>
ArgyllCMS is an ICC compatible color management system, available as
@@ -35,24 +35,13 @@
general guide to using the tools for typical color management tasks
is also available. A mailing list provides support for more advanced
usage.<br>
- <p>This is Version 2.0.0, a feature and bug fix update to the last
- major releaseV1.9.2. The first public release of icclib was in
- November 1998, and of ArgyllCMS was in October 2000. Code
- development commenced in 1995. See <a href="ChangesSummary.html">Changes
-
-
-
-
-
-
-
-
-
-
-
- Summary</a> for an overview of changes since the last release.
- Changes between revisions is detailed in the <b>log.txt</b> file
- that accompanies the source code. </p>
+ <p>This is Version 2.0.1, a bug fix update to the last major release
+ V2.0.0. The first public release of icclib was in November 1998,
+ and of ArgyllCMS was in October 2000. Code development commenced
+ in 1995. See <a href="ChangesSummary.html">Changes Summary</a>
+ for an overview of changes since the last release. Changes between
+ revisions is detailed in the <b>log.txt</b> file that accompanies
+ the source code. </p>
<p>The latest source code is available from <a
href="http://www.argyllcms.com/#Downloads">here</a>.<br>
</p>
@@ -153,6 +142,12 @@
+
+
+
+
+
+
discussion</a> of what color management is, and why we need it,
together with a brief overview of the ICC profile format.<br>
@@ -175,13 +170,13 @@
9) Apple OS X 10.3 PPC using GCC<br>
10) Apple OS X 10.4, 10.5, 10.6 Intel using GCC<br>
11) Apple OS X10.7 Intel using&nbsp; Clang<br>
+ 12) Apple OS X10.12 Intel using Clang<br>
<br>
Additionally it is also known to run on:<br>
<br>
&nbsp;MSWindows 2000, Vista &amp; Windows 7 - 32 bit.<br>
&nbsp;MSWindows Vista 64bit, Windows 7, 8, 8.1, 10 - 64 bit.<br>
- <p>but may well compile and run correctly in many more than this,
- including OS X 10.8, 10.9, 10.10 and beyond.<br>
+ <p>but may well compile and run correctly in many more than this.<br>
</p>
This is a <span style="font-weight: bold;">command line terminal</span>
only environment. Those unfamiliar with command line environments
@@ -283,6 +278,12 @@
+
+
+
+
+
+
- Tele-Spectro-Radiometer<br>
&nbsp;&nbsp;&nbsp; <a href="instruments.html#spectraval">spectraval
@@ -306,6 +307,12 @@
+
+
+
+
+
+
&nbsp;&nbsp; - Tele-Spectro-Radiometer<br>
<br>
@@ -399,6 +406,12 @@
+
+
+
+
+
+
- Tele-Spectro-Radiometer<br>
<br>
@@ -469,6 +482,12 @@
+
+
+
+
+
+
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
@@ -607,6 +626,12 @@
+
+
+
+
+
+
- "swipe" type reflective spectrometer, that can be used untethered.<br>
&nbsp;&nbsp;&nbsp; <a href="instruments.html#DTP22">DTP22 Digital
@@ -739,6 +764,12 @@
+
+
+
+
+
+
- spot type reflective spectrometer.<br>
&nbsp;&nbsp;&nbsp; <a href="instruments.html#DTP41">DTP41</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -870,6 +901,12 @@
+
+
+
+
+
+
- spot and strip reading reflective spectrometer.<br>
&nbsp;&nbsp;&nbsp; <a href="instruments.html#DTP41">DTP41T</a>
@@ -1003,6 +1040,12 @@
+
+
+
+
+
+
- spot and strip reading reflective/transmissive spectrometer.<br>
&nbsp;&nbsp;&nbsp; <a href="instruments.html#dtp51">DTP51</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -1134,6 +1177,12 @@
+
+
+
+
+
+
- strip reading reflective colorimeter.<br>
&nbsp;&nbsp;&nbsp; <a href="instruments.html#DTP92">DTP92</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -1265,6 +1314,12 @@
+
+
+
+
+
+
- CRT display colorimeter.<br>
&nbsp;&nbsp;&nbsp; <a href="instruments.html#DTP94">DTP94</a> <font
@@ -1272,14 +1327,13 @@
colorimeter.<br>
&nbsp;&nbsp;&nbsp; <a href="instruments.html#ColorMunki"><span
style="text-decoration: underline;">ColorMunki</span></a> Design
- or Photo&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -
- spot and "swipe" reflective/emissive spectrometer (UV cut only).<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-
-
-
- The <b>i1Studio</b> version of this instrument is also reported to
- work.<br>
+ or Photo or i1Studio<br>
+ &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - spot and "swipe"
+ reflective/emissive spectrometer (UV cut only).<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
@@ -1308,8 +1362,8 @@
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
- &nbsp; &nbsp; &nbsp;&nbsp; Quato Silver Haze 3 OEM and HP
- DreamColor&nbsp; i1d3 are also reported to work.]<br>
+ &nbsp; &nbsp; &nbsp;&nbsp; Quato Silver Haze 3 OEM,&nbsp; HP
+ DreamColor &amp; Wacom i1d3 are also reported to work.]<br>
&nbsp; &nbsp; <a href="instruments.html#i1p2">Eye-One Pro2</a>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp; - spot and
@@ -1469,6 +1523,12 @@
+
+
+
+
+
+
- display colorimeter. (Treated as a Eye-One Display 2)<br>
&nbsp;&nbsp;&nbsp; <a href="instruments.html#i1d">CalMAN X2</a>
@@ -1601,6 +1661,12 @@
+
+
+
+
+
+
- display colorimeter. (Treated as a Eye-One Display 2)<br>
&nbsp;&nbsp;&nbsp; <a href="instruments.html#Huey">Huey</a> &nbsp;
@@ -1742,6 +1808,12 @@
+
+
+
+
+
+
[The Sequel Chroma 4 &amp; 5, and Sencore ColorPro V, IV &amp; III
also work.]<br>
@@ -1876,6 +1948,12 @@
+
+
+
+
+
+
- see <a href="instruments.html#i1d">Eye-One Display</a><br>
<br>
@@ -2014,6 +2092,12 @@
+
+
+
+
+
+
[The Spyder 1 has also been reported as working, but this has not
been confirmed.]<br>
@@ -2165,6 +2249,12 @@
+
+
+
+
+
+
- display colorimeter</span><br>
&nbsp;&nbsp;&nbsp; <a href="instruments.html#ColorHug">ColorHug</a>
@@ -2188,6 +2278,12 @@
+
+
+
+
+
+
- display colorimeter<br>
&nbsp;&nbsp;&nbsp; <a href="instruments.html#SMCube">Palette/SwatchMate
@@ -2228,6 +2324,12 @@
+
+
+
+
+
+
Cube</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -2248,6 +2350,12 @@
+
+
+
+
+
+
- reflective colorimeter<br>
<span style="font-weight: bold;"></span><span class="titre"><br>
@@ -2349,6 +2457,12 @@
+
+
+
+
+
+
GNU</span> license <span style="font-weight: bold;">prohibits</span>
extending these tools<span style="font-weight: bold;"></span>
@@ -2534,6 +2648,12 @@
+
+
+
+
+
+
the jcnf library in <span style="font-weight: bold;">jcnf</span>/,
@@ -2663,6 +2783,12 @@
+
+
+
+
+
+
the files <span style="font-weight: bold;">spectro/xdg_bds.*</span>,
<span style="font-weight: bold;">spectro/aglob.*</span> and the
@@ -2887,6 +3013,12 @@ calibration
+
+
+
+
+
+
and profiling is <a href="http://displaycal.net/">DisplayCAL</a> by
Florian Höch. For print profiling, you might like to take a look at
@@ -2919,10 +3051,18 @@ calibration
+
+
+
+
+
+
Little Argyll GUI</a> by Russell Cottrell, and for cameras or
scanners, <a href="http://www.dohm.com.au/coca/">CoCa</a> by Andrew
- Stawowczyk Long.<br>
+ Stawowczyk Long. Another GUI worth looking at is <a
+ href="http://www.coloris-app.fr/">Coloris</a>, by Rémi and Lionel
+ Wetteren.<br>
<br>
Others can be found with a suitable <a
href="http://www.google.com/search?hl=en&amp;source=hp&amp;q=argyllcms+GUI&amp;aq=f&amp;aqi=g1&amp;aql=&amp;oq=">search</a>.<br>
@@ -3061,6 +3201,12 @@ href="http://www.google.com/search?hl=en&amp;source=hp&amp;q=argyllcms+GUI&amp;a
+
+
+
+
+
+
-? </b>(or some other unrecognized flag, if the "?" character is
treated specially in your shell, i.e. try "--" on OS X zsh).<br>
@@ -3207,6 +3353,12 @@ href="http://www.google.com/search?hl=en&amp;source=hp&amp;q=argyllcms+GUI&amp;a
+
+
+
+
+
+
Verbose mode<br>
&nbsp;&nbsp; -d
@@ -3339,6 +3491,12 @@ href="http://www.google.com/search?hl=en&amp;source=hp&amp;q=argyllcms+GUI&amp;a
+
+
+
+
+
+
Choose a depth 0-4<br>
&nbsp;&nbsp; -r
@@ -3471,6 +3629,12 @@ href="http://www.google.com/search?hl=en&amp;source=hp&amp;q=argyllcms+GUI&amp;a
+
+
+
+
+
+
Use a random depth<br>
&nbsp;&nbsp; -f
@@ -3606,6 +3770,12 @@ href="http://www.google.com/search?hl=en&amp;source=hp&amp;q=argyllcms+GUI&amp;a
+
+
+
+
+
+
Manual<br>
&nbsp;&nbsp; infile
@@ -3738,6 +3908,12 @@ href="http://www.google.com/search?hl=en&amp;source=hp&amp;q=argyllcms+GUI&amp;a
+
+
+
+
+
+
Input file<br>
&nbsp;&nbsp; outfile
@@ -4021,6 +4197,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span><big>Generate a profiling test target values .ti1 file. </big><br
style="font-family: monospace;">
@@ -4154,6 +4336,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
film recorder TIFF files from Argyll .ti1 file. </big><br
style="font-family: monospace;">
@@ -4287,6 +4475,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
a PS, EPS or TIFF file containing test patch values, ready for
printing.</big></small>
@@ -4422,6 +4616,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
a test chart using an instrument to create a .ti3 data file.</big><span
style="font-family: monospace;"> </span><br style="font-family:
@@ -4556,6 +4756,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
and read colorimetric values from a display </big><br
style="font-family: monospace;">
@@ -4689,6 +4895,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
film colorimetric values using a SpectroScanT (Deprecated ?)</big><br
style="font-family: monospace;">
@@ -4822,6 +5034,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span><big>Convert a TIFF&nbsp; image of a test chart into .ti3
device values. <br>
@@ -4960,6 +5178,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
the reading of a device using an ICC or MPP profile. <br>
</big></small><small><a style="font-family: monospace;"
@@ -5097,6 +5321,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span><big>Convert Colorblind format CMY/RGB test chart into
Argyll .ti3 CGATS format. </big><br style="font-family:
@@ -5231,6 +5461,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
Kodak Colorflow format CMYK test chart into Argyll .ti3 CGATS
format. </big><br style="font-family: monospace;">
@@ -5364,6 +5600,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span><big>Convert Gretag/Logo/X-Rite/Barbieri or other format
RGB or CMYK test chart results into Argyll .ti3 CGATS format. </big></small><br
@@ -5436,6 +5678,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
LightSpace format RGB .bcs test chart results into Argyll
.ti3 CGATS format.</big></small></big><br>
@@ -5569,6 +5817,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span><big>Create a fake Argyll .ti3 CMY data file from a CMYK
profile, as a basis of creating a CMY to CMYK separation<br>
@@ -5632,6 +5886,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
or Merge two or more measurement data files, or average patches
within a single file.</big></small><br>
@@ -5766,6 +6026,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Create an ICC profile from the .ti3 test data. <br>
<small><a style="font-family: monospace;" href="mppprof.html">mppprof</a><span
@@ -5898,6 +6164,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Create a Model Printer Profile (MPP) from the .ti3
test data. <br>
@@ -6031,6 +6303,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Regenerate a device profiles B2A table data by
inverting the A2B table.
@@ -6165,6 +6443,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Link two device ICC profiles to create a device
link profile.
@@ -6300,6 +6584,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Color convert a TIFF or JPEG file using a sequence
of ICC device, device link, abstract profiles and calibration files.
@@ -6433,6 +6723,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
calibration curves to an ICC profile.<br>
<small><a style="font-family: monospace;" href="icclu.html">icclu&nbsp;</a><span
@@ -6565,6 +6861,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Lookup individual color values through any ICC
profile table. <br>
@@ -6698,6 +7000,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Lookup individual color values forward or inverted
though an ICC profile or CAL table. <br>
@@ -6831,6 +7139,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Lookup individual color values though an MPP
profile. Also create MPP gamut files/views.<br>
@@ -6964,6 +7278,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
a TIFF file to monochrome using an ICC device profile <br>
<h3>Color Tweaking tools<br>
@@ -7105,6 +7425,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
a gamut file or VRML file of the color gamut of an ICC profile. <br>
<small><a style="font-family: monospace;" href="tiffgamut.html">tiffgamut</a><span
@@ -7237,6 +7563,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
a gamut file or VRML file of the color gamut of a TIFF or JPEG
image. <br>
@@ -7370,6 +7702,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Convert one or more gamuts into a VRML 3D
visualization file. Compute an intersection.<br>
@@ -7505,6 +7843,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Dump the contents of an ICC profile as text. <br>
<small><a style="font-family: monospace;" href="profcheck.html">profcheck</a><span
@@ -7637,6 +7981,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
an ICC profile against .ti3 test chart data, create pruned .ti3
file.<br>
@@ -7769,6 +8119,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</small>Check ICC forward against inverse lookup. <br>
<small><a style="font-family: monospace;" href="splitti3.html">splitsti3</a><span
@@ -7900,6 +8256,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
a CGATS file (ie. a .ti3) into two parts randomly to verify
profiling. <br>
@@ -8036,6 +8398,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
an MPP profile against .ti3 test chart data. <br>
<small><a style="font-family: monospace;" href="spotread.html">spotread</a><span
@@ -8167,6 +8535,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
an instrument to read a single spot color value. <br>
<small><a style="font-family: monospace;" href="colverify.html">colverify</a><span
@@ -8242,6 +8616,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
matching of CIE in two CGATS/.ti3 files (also view differences as
VRML)<br>
@@ -8374,6 +8754,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
a synthetic input, display or output calibration (<a
href="File_Formats.html#.cal">.cal</a>)file.
@@ -8507,6 +8893,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
a Spectrometer to create a Colorimeter Correction Matrix
(CCMX)&nbsp; or a Colorimeter Calibration Spectral Set (CCSS)&nbsp;
@@ -8642,6 +9034,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
an embedded ICC profile from a TIFF or JPEG file.<br>
</small><small><a style="font-family: monospace;"
@@ -8780,6 +9178,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
or uninstall display profile, set display calibration from profile
or .cal file, test displace and dispwin access to a display.<br>
@@ -8919,6 +9323,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
Plot a spectrum (.sp, .cmf, .ccss) and calculate CCT and VCT.<br>
<small><a style="font-family: monospace;" href="spec2cie.html">spec2cie</a><span
@@ -8955,6 +9365,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
spectral .ti3 or .sp readings into CIE XYZ and D50 L*a*b* readings.
Apply FWA, plot spectrums. Convert to/from XRGA standard.<br>
@@ -9090,6 +9506,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
calibration curves to an ICC profile.<br>
<small><a style="font-family: monospace;" href="average.html">average</a><span
@@ -9222,6 +9644,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small><small><big>Average or Merge two or more
measurement data files, or average patches within a single file.</big></small><br>
@@ -9355,6 +9783,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Convert Colorblind format CMY/RGB test chart into
Argyll .ti3 CGATS format. <br>
@@ -9488,6 +9922,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Color convert a TIFF or JPEG file using a sequence
of ICC device, device link, abstract profiles and calibration files.<br>
@@ -9620,6 +10060,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
a Spectrometer to create a Colorimeter Correction Matrix
(CCMX)&nbsp; or a Colorimeter Calibration Spectral Set (CCSS)&nbsp;
@@ -9754,6 +10200,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
a test chart using an instrument to create a .ti3 data file. <br>
<small><a style="font-family: monospace;" href="collink.html">collink</a><span
@@ -9886,6 +10338,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Link two device ICC profiles to create a device
link profile. <br>
@@ -10019,6 +10477,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Create an ICC profile from the .ti3 test data.<br>
<font size="-1"><a style="font-family: monospace;"
@@ -10158,6 +10622,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
and read colorimetric values from a display <br>
<small><a style="font-family: monospace;" href="dispwin.html">dispwin</a><span
@@ -10291,6 +10761,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
or uninstall display profile, set display calibration from profile
or .cal file, test displace and dispwin access to a display.<br>
@@ -10425,6 +10901,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
an embedded ICC profile from a TIFF or JPEG file.<br>
</small><small><a style="font-family: monospace;"
@@ -10562,6 +11044,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Create a fake Argyll .ti3 CMY data file from a CMYK
profile, as a basis of creating a CMY to CMYK separation <br>
@@ -10695,6 +11183,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
the reading of a device using an ICC or MPP profile. <br>
<small><a style="font-family: monospace;" href="filmread.html">filmread</a><span
@@ -10827,6 +11321,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
film colorimetric values using a SpectroScanT (Deprecated ?)<br>
<small><a style="font-family: monospace;" href="filmtarg.html">filmtarg</a><span
@@ -10959,6 +11459,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
film recorder TIFF files from Argyll .ti1 file. <br>
<small><a style="font-family: monospace;" href="greytiff.html">greytiff</a><span
@@ -11091,6 +11597,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
a TIFF file to monochrome using an ICC device profile <small><a
style="font-family: monospace;" href="oeminst.html"></a></small><br>
@@ -11224,6 +11736,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Dump the contents of an ICC profile as text. <br>
<small><a style="font-family: monospace;" href="iccgamut.html">iccgamut</a><span
@@ -11356,6 +11874,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
a gamut file or VRML file of the color gamut of an ICC profile. <br>
<small><a style="font-family: monospace;" href="icclu.html">icclu&nbsp;</a><span
@@ -11488,6 +12012,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Lookup individual color values through any ICC
profile table. <br>
@@ -11620,6 +12150,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
an instrument to measure an illuminant spectrum, and estimate its UV
content.<br>
@@ -11756,6 +12292,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
Kodak Colorflow format CMYK test chart into Argyll .ti3 CGATS
format. <br>
@@ -11793,6 +12335,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
LightSpace format RGB .bcs test chart results into Argyll
.ti3 CGATS format.</big></small></big></small><br>
@@ -11926,6 +12474,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
an MPP profile against .ti3 test chart data. <br>
<small><a style="font-family: monospace;" href="mpplu.html">mpplu</a><span
@@ -12058,6 +12612,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Lookup individual color values though an MPP
profile. Also create MPP gamut files/views. <br>
@@ -12191,6 +12751,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Create a Model Printer Profile (MPP) from the .ti3
test data. <br>
@@ -12328,6 +12894,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
a printer calibration .cal file from a .ti3 data file<small><big>.</big></small><br>
<small><a style="font-family: monospace;" href="printtarg.html">printtarg</a><span
@@ -12460,6 +13032,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
a PS, EPS or TIFF file containing test patch values, ready for
printing.</big></small><br>
@@ -12593,6 +13171,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
an ICC profile against .ti3 test chart data, create pruned .ti3
file.<br>
@@ -12731,6 +13315,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Regenerate a device profiles B2A table data by
inverting the A2B table. <br>
@@ -12864,6 +13454,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Convert a TIFF&nbsp; image of a test chart into
.ti3 device values. <br>
@@ -12998,6 +13594,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
spectral .ti3 or .sp readings into CIE XYZ and D50 L*a*b* readings.
Apply FWA, plot spectrums. Convert to/from XRGA standard.<br>
@@ -13132,6 +13734,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
Plot a spectrum (.sp, .cmf, .ccss) and calculate CCT and VCT.<br>
<small><a style="font-family: monospace;" href="splitti3.html">splitsti3</a><span
@@ -13263,6 +13871,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
a CGATS file (ie. a .ti3) into two parts randomly to verify
profiling. <br>
@@ -13395,6 +14009,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
an instrument to read a single spot color value. <small><a
style="font-family: monospace;" href="oeminst.html"></a></small><br>
@@ -13527,6 +14147,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
a synthetic input, display or output calibration (<a
href="File_Formats.html#.cal">.cal</a>)file.<br>
@@ -13660,6 +14286,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
the reading of a device using a synthetic device model. </big></small><br>
<small><a style="font-family: monospace;" href="targen.html">targen</a><span
@@ -13792,6 +14424,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Generate a profiling test target values .ti1 file.
<br>
@@ -13925,6 +14563,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
a gamut file or VRML file of the color gamut of a TIFF or JPEG
image. <br>
@@ -14062,6 +14706,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small><small><big>Convert Gretag/Logo/X-Rite/Barbieri or
other format RGB or CMYK test chart results into Argyll .ti3
@@ -14196,6 +14846,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
one or more gamuts into a VRML 3D visualization file. Compute an
intersection.<br>
@@ -14329,6 +14985,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
</span></small>Lookup individual color values forward or inverted
though an ICC profile or CAL table. <br>
@@ -14489,6 +15151,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
Device test values <br>
<a href="File_Formats.html#.ti2">.ti2</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -14620,6 +15288,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
Device test values &amp; chart layout <br>
<a href="File_Formats.html#.ti3">.ti3</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -14751,6 +15425,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
Device test values &amp; CIE tristimulus/spectral results&nbsp; <a
href="ti3_format.html">Format details.</a><br>
@@ -14886,6 +15566,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
Test chart recognition template. <a href="cht_format.html">Format
details.</a> <br>
@@ -15018,6 +15704,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
3D gamut surface description <br>
<a href="File_Formats.html#.sp">.sp</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -15149,6 +15841,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
Illuminant spectral description <br>
<a href="File_Formats.html#.cmf">.cmf</a>
@@ -15288,6 +15986,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
Standard text based data exchange format <br>
<a href="File_Formats.html#ICC">ICC</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -15419,6 +16123,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
International Color Consortium profile format <br>
<a href="File_Formats.html#MPP">MPP</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -15550,6 +16260,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
Model device profile format <br>
<a href="File_Formats.html#TIFF">TIFF</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -15681,6 +16397,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
Tag Image File Format raster files. <br>
<a href="File_Formats.html#JPEG">JPEG</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -15812,6 +16534,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
Joint Photographic Experts Group, JPEG File Interchange Format
raster files. <br>
@@ -15948,6 +16676,12 @@ href="http://www.google.com/search?hl=en&amp;q=windows+command+prompt+tutorial">
+
+
+
+
+
+
Virtual Reality Modelling Language 3D file format. <br>
<a href="File_Formats.html#X3D">X3D</a>
diff --git a/doc/ChangesSummary.html b/doc/ChangesSummary.html
index 354437d..1327552 100644..100755
--- a/doc/ChangesSummary.html
+++ b/doc/ChangesSummary.html
@@ -1,1155 +1,1184 @@
-<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html;
- charset=windows-1252">
- <meta name="author" content="Graeme Gill">
- <meta name="description" content="Root of Argyll CMS documentation">
- <meta name="GENERATOR" content="Mozilla/4.73 [en] (WinNT; I)
- [Netscape]">
- <meta name="Author" content="Graeme Gill">
- <meta name="Description" content="Summary of changes for the most
- recent release.">
- <title>Argyll CMS changes since last release</title>
- </head>
- <body>
- <h1> Summary of Argyll CMS Changes since last release</h1>
- <h3>For a <span style="text-decoration: underline;">complete</span>
- and more detailed list of changes, please see the log.txt file.</h3>
- <h1>[V1.9.2 -&gt; V2.0.0] 17th November 2017</h1>
- <ul>
- <li>Added support for "pm" viewing condition (Print evaluation
- with partial Mid-tone adaptation), and associated m: viewing
- condition parameter. This is intended to address certain
- situations involving the use of papers containing FWA/OBE
- brighteners when viewed in an environment that has a very
- noticeably warmer white point than the paper itself under the
- illuminant.</li>
- <li>Added support for the X-Rite i1Studio instrument. Note that
- you may have to un-install and re-install the system drivers on
- MSWindows, or update the udev 55-Argyll.rules file on Linux.<span
- style="font-weight: bold;"></span></li>
- <li>Slight improvement to i1d3 accuracy, by rounding the frequency
- mode measurements up by 0.5.</li>
- <li>Returned input profile forced Absolute Colorimetric option
- with -ua flag, after the -u option was changed in V1.5.0.<br>
- </li>
- <li>Try and fix problem in triggering calibration when
- ARGYLL_NOT_INTERACTIVE is set.</li>
- <li>Improve compatibility of txt2ti3, and added -D option to mark
- output as Display but not Normalized to white.</li>
- <li>Modified collink to disable Video encoded in/out sync level
- preservation.</li>
- <li>Added support for custom Observer by using a .cmf file as an
- argument to all tools taking an observer parameter.</li>
- <li>Added support for proposed CIE 2012 2 degree &amp; 10 degree
- observers, based on the CIE (2006) 2-deg LMS cone fundamentals.</li>
- <li>Fix problem with dispwin -E option not being shown in usage,
- and only being applied when a calibration file is used.</li>
- <li>Added spotread -u option to display XYZ amd CIE 1976 Yuv
- values.</li>
- <li>Added XRGA conversion support to spec2cie, as well as better
- support in chartread and txt2ti3 for tracking XRGA standard and
- polarization filter use.</li>
- <li>Fix bug in spec2cie processing emissive .sp files.</li>
- <li>Fix problem with i1d3 running direct USB (i.e. Not via HID) on
- MSWin.</li>
- <li>Fixed bug in render/timage -p.</li>
- <li>Changed spotread ambient readings (CCT, CRI, TLCI) to show CCT
- delta E in 1960 Duv units and others in Delta E 2000.</li>
- <li>Added ARGYLL_UNTWIST_GAMUT_SURFACE environment variable, that
- enables extra gamut clip surface processing that may improve the
- smoothness of device links and B2A tables for poorly behaved
- devices.</li>
- <li>Fixed bug introduced in new colorimetric nearest clipping code
- in rspl/rev.c in V1.9.0 that caused colprof using some ink limit
- settings (such as -L0) to crash.</li>
- <li>Fixed bug introduced in new colorimetric nearest clipping code
- in rspl/rev.c in V1.9.0 that caused some (mainly XYZ clut)
- profiles to clip badly, causing banding.</li>
- <li>Improved dispcal -R VideoLUT depth measurement algorithm
- robustness.</li>
- <li>Worked around latest OS X super slow opening serial port
- problem (1.5 seconds to open a port!)</li>
- <li>Added ColorCheckerHalfPassport.cht file.</li>
- <li>Fixed bug in ChromeCast mDNS parsing that caused problems with
- some devices with long names being detected.</li>
- <li>Now ignoring Chromecast-Audio and (.ca flags &amp; 1) == 0
- devices, and showing the friendly chromecast name if available.</li>
- <li>Wait longer to find more Chromecasts, even if we've found one.</li>
- <li>Fixed colprof bug when handling Display L*a*b* .ti3 data.</li>
- <li>Added Wacom i1d3 support.</li>
- <li>Changed dispwin to by default ignore Gnome colord, and use its
- native ucmm for storage of display profiles, since colord
- support for ArgyllCMS has proven unreliable. This can be
- re-enabled by setting the ARGYLL_USE_COLORD environment variable
- (i.e. to "true").</li>
- <li>Change X11 root window _ICC_PROFILE_xxx atom setting for
- Xrandr case to now match the Xinerama order, so that
- ICC_PROFILE_xxx atoms match, irrespective of which extension
- applications are using. This improves conformance to "ICC
- Profiles in X Specification 0.2".</li>
- <li>Improved ucmm install/load/delete to better respect
- systemlocal/user scopes, as well as eliminating need for profile
- name on delete when ucmm is used.</li>
- <li>Improve fast serial port scan to better detect Lumagen
- Radiance without upsetting it.</li>
- <li>Added ARGYLL_EXCLUDE_SERIAL_SCAN environment variable, to
- allow suppression of fast serial port scan of sensitive devices.<br>
- </li>
- </ul>
- <h1>[V1.9.1 -&gt; V1.9.2] 17th October 2016</h1>
- <ul>
- <li>Added CMYKOGB and CMYKRGB 7 channel ink preset, and made
- targen more flexible in matching pre-conditioning profiles to
- targen ink selection.<br>
- </li>
- <li>Fix oeminst for OS X save location.</li>
- <li>Fix oeminst for OS X Spyder 4 CD calibration file location.</li>
- </ul>
- <h1>[V1.8.3 -&gt; V1.9.1] 28th September 2016</h1>
- <ul>
- <li>Improved robustness of ChromeCast discovery, and added some
- minimal diagnostics.<br>
- </li>
- <li>Improved robustness of targen ofps patch generation when using
- less well behaved pre-conditioning profiles.<br>
- </li>
- <li>Fixed oeminst so that it locates cdrom's in Linuxes latest
- mount point of /run/media/$USER/.<br>
- </li>
- <li>Fixed bug in i1pro2 driver, in which strip calibration would
- fail if instrument had been first calibrated with
- ARGYLL_DISABLE_I1PRO2_DRIVER set, and then calibrated with
- ARGYLL_DISABLE_I1PRO2_DRIVER unset.<br>
- </li>
- <li>Added option to icclib to write Output profiles using 'chad'
- tag if the ARGYLL_CREATE_DISPLAY_PROFILE_WITH_CHAD&nbsp;
- environment variable is set. This is not recommended for normal
- use, but may assist compatibility with other systems.</li>
- <li>Added JETI spectraval support, including Bluetooth access.</li>
- <li>Added support for the Klein K10 connecting via a serial port.</li>
- <li>Fixed bug in Colormunki Smile driver that causes crash on
- Ubuntu 16.04.1 LTS.</li>
- <li>Modified "lp" intent to greatly reduce eliminate
- Helmholtz-Kohlrausch appearance modelling.<br>
- </li>
- <li>Fixed problem with targen -g, in that the corresponding XYZ
- values had double the power applied, rather than none. This was
- causing problems with printtarg spacer colors.<br>
- </li>
- <li>Extensive re-write of colorimetric nearest clipping code in
- rspl/rev.c to restore precision that was lost in the speedups
- made in V1.0.0. The nnrev setup now takes a lot longer with
- &nbsp; high resolution CMYK profiles though. This corrects a
- "green becoming too yellow" problem for mapping from ProPhoto
- space with some RGB devices.</li>
- <li>Change dispwin to properly set X11 DirectColor and take
- account of TrueColor Colormap.&nbsp; This fixes problem with
- NVidia linux driver 364.12 exposing a VideoLUT depth that is
- different from the frame buffer depth.</li>
- <li>Change icclib to automatically repair icmTextDescription
- strings that have an allocation that is longer than their size.</li>
- <li>Added i1Pro Lamp Drift test and fix functions to spotread (-Y
- l|L options).</li>
- <li>Change colprof so that -s -S will accept general compression
- percentage as an alternative to a source colorspace/image gamut.</li>
- <li>Added optional conversion from native Gretag-MacBeth &amp;
- X-Rite reflective calibration standards to/from XRGA.</li>
- <li>Changed OS X GUI support code so as not to switch to "interact
- with the Dock" mode until actual GUI element is to be displayed.
- This prevents batch commands with optional GUI elements from
- blocking normal GUI interactions.</li>
- <li>Re-jigged OS X UI code to use the main thread to avoid window
- creation timing issues and a warning backtrace on OS X 10.11.</li>
- <li>Added CMP_Digital_Target-7.cht</li>
- <li>Fix spec2cie to cope with .ti3 files that are missing device
- values, so that it can process a wider range of input CIE
- reference files.</li>
- <li>Changed implementation of ARGYLL_NOT_INTERACTIVE on MSWin to
- make it more reliable when operated progromatically.</li>
- <li>Fixed chartread so that if you are reading patch by patch, the
- location strings can be arbitrary (i.e. they don't have to
- conform to an alpha/num strip/patch pattern.)</li>
- <li>Added support for Sencore ColorPro V, IV &amp; III
- colorimeters (based on Sequel Chroma colorimeter.).<br>
- </li>
- </ul>
- <h1>[V1.8.2 -&gt; V1.8.3] 26th October 2015</h1>
- <ul>
- <li>Added SpyderCheckr24 scaning .cht and .cie files.</li>
- <li>Fixed USB problem with i1pro (Rev B &amp; D ?), where
- communications would occasionally break down on fast systems.<br>
- </li>
- <li>Added another fixed display intergration time to i1pro
- non-adaptive emission mode to cope with higher brightness
- displays.</li>
- <li>Added workaround for i1d3 Rev. B status code 0x83 on very low
- light measurement</li>
- <li>Fixed minor bug in i1d3.c that truncated serial number string.
- (Thanks to Mikael Sterner).</li>
- <li>Fixed bug in Klein K10 driver - adaptive measurement wasn't
- properly using all the extra measurements.</li>
- <li>Improved Klein K10 driver to be more robust when lights off
- command returns bogus error codes, or causes a cascade of bogus
- measurement errors.<br>
- </li>
- <li>Added workaround for OS X 10.9+ "App Nap" problem.</li>
- <li>Added maximum sensor frequency check for Spyder &amp; i1d3
- drivers, so that erronious readings due to excessive brightness
- can't be missed.</li>
- <li>Changed chartread so that it doesn't warn of a possible wrong
- strip being read, nor allows bi-directional strip reading, if
- "printtarg -r" was used. A warning will be issued if "printtarg
- -r" was used, and "chartread -B" wasn't used.<br>
- </li>
- <li>Fixed collink for eeColor Full range RGB to use output curve
- ("second" 1D curves) to compensate for cLUT being wired for 1.0
- output from 1.0 input.<br>
- </li>
- <li>Added "lp" gamut mapping intent :- Luminance Preserving
- Perceptual, for Photographers concerned with maintaining tonal
- variations.</li>
- <li>Fixed bugs in image specific gamut mapping that were degrading
- the accuracy of the result.</li>
- <li>Re-wrote gamut smoothing code, and re-tuned it to behave
- similarly to the V1.8.2 release.</li>
- <li>Changed default viewing condition glare to 5%, to smooth out
- shadow tone curve.</li>
- <li>Reduced the level of Helmholtz-Kohlrausch effect in CIECAM02
- implementation in the light of visual experiments.</li>
- </ul>
- <h1>[V1.8.1 -&gt; V1.8.2] 7th September 2015</h1>
- <ul>
- <li>Fixed endless loop bug in alternate calibration selectors
- code.</li>
- </ul>
- <h1>[V1.8.0 -&gt; V1.8.1] 4th September 2015</h1>
- <ul>
- <li>Fixed bug in "spec2cie -n" wrong field indexes were being
- used.</li>
- <li>Fixed colorimeter calibration selectors to add in alternate
- selectors if the letters are free.</li>
- </ul>
- <h1>[V1.7.0 -&gt; V1.8.0] 20th August 2015</h1>
- <ul>
- <li>Added support for the Image Engineering EX1 spectroradiometer.</li>
- <li>Added support for the SwatchMate Cube reflective colorimeter,
- with improved accuracy.</li>
- <li>Added Added Television Lighting Consistency Index (EBU
- TLCI-2012 Qa)&nbsp; to spotread and specplot output.</li>
- <li>Added R9 value to CRI value in spotread and specplot output.</li>
- <li>Added workaround for JETI specbos having been calibrated by a
- 3rd party, and its calibrated range being out of sync with its
- claimed range.<br>
- </li>
- <li>Added support for "EMISINPUT" type .ti3 file.</li>
- <li>Build using OpenSSL rather than axTLS if it is built on Linux.</li>
- <li>Fixed stack space problem in OS X UI programs by expanding
- main thread proxy to have 8MB instead of the default 512K.</li>
- <li>Updated built in libtiff to V4.0.4beta.</li>
- <li>Changed CGATS format to not emit unknown keyword declaration
- ("KEYWORD") by default.</li>
- <li>Added inst_calc_cond_mask to inst.h to allow for flags in
- calibration conditions. A consequence of this is that calc needs
- to be masked with this when comparing against a specific
- condition, and the inst_calc_optional_flag should be cleared if
- it is set, before callint inst-&gt;calibrate() if the user wants
- to proceed with a particular calibration.</li>
- <li>Fixed bug with dispcal -e N</li>
- <li>Fixed bug in xicclu -fg and -kp</li>
- <li>Added dispcal -x x option to allow reading a chart and
- manually entering the XYZ values.</li>
- <li>Fix spyder4 &amp; 5 bug where some display types were set as
- refresh when they shouldn't be.</li>
- <li>Fix collink "Warning :- RGB black hack trigger more than
- once!" when -b is used with input video encoding (-e).</li>
- <li>Changed colprof so that the default ICC description is the
- base filename rather than the whole file path.</li>
- <li>Fix technology type and display type selector
- "uniqueification" bug&nbsp; that shows up in "ccxxmake -??".</li>
- <li>Add OEM field to ccmx and ccss files to mark files that have
- been installed from OEM disk, so that custom ccmx &amp; ccss
- files can be given suggested selector letter priority (+
- ref/CRT.ccss).</li>
- <li>Tweak CGATS write format to avoid scientific notation until
- the numbers are bigger and smaller (i.e until e6 and e-6 are
- needed).<br>
- </li>
- </ul>
- <h1>[V1.6.3 -&gt; V1.7.0] 1st May 2015</h1>
- <ul>
- <li>Improved gamut mapping to reduce unnecessary changes to less
- saturated colors&nbsp; such as skin tones.</li>
- <li>Add support for DataColor Spyder 5.</li>
- <li>Add support for ColorHug2 colorimeter.</li>
- <li>Add support for Klein K10-A colorimeter.</li>
- <li>Added Google ChromeCast as a test patch generator for Video
- displays.</li>
- <li>Added ls2ti3 tool to convert LightSpace .bcs files to .ti3.</li>
- <li>Added IRIDAS .cube 3DLut format support to collink.</li>
- <li>Add X3D and X3DOM support as an alternative to VRML, and make
- X3DOM the default.</li>
- <li>Add better cross compatibility with non-Argyll ICC profiles
- using ArgyllCMS 'arts' tag to mark 'wtpt' Absolute Colorimetric
- chromaticity transform, as well as implement proper absolute
- colorimetric intent for Display profiles use the 'chad' tag.
- Note that the standard ICC profiles provided by ArgyllCMS in the
- ref directory (such as sRGB etc.) now include an 'arts' tag.</li>
- <li>Ignore any patches that have zero values for creating Display
- profiles, unless they are for device zero. </li>
- <li>Fix various instrument communications problems for JETI
- specbos, DTP20, DTP92 &amp; DTP94.</li>
- <li>Fix gestaltSystemVersion warning on OS X 10.10.</li>
- <li>Fix very major bug in illumread. It wasn't actually working at
- all since V1.4.0.</li>
- <li>Added collink -I[gG][:p.p]:x.x options that allows an output
- offset gamma curve be targetted instead of BT1886.</li>
- <li>Added dispcal and collink -b black point hack. This forces the
- input zero to map to the output zero for well behaved displays,
- reducing dependence on the instrument accuracy for a very dark
- black point.</li>
- <li>Added preset list of display techologies to select from in
- ccxxmake.</li>
- <li>Added a -P prune option to profcheck, that creates a .ti3 file
- pruned of any patches that have a delta E fit error greater than
- a threshold. This may be of use in eliminating bad reading
- values from a measurement set.</li>
- <li>Added histogram plot option -h to both profcheck and verify.</li>
- <li>Added a dispread &amp; fakeread -Z option to set the number of
- bits to quantize the test values to. </li>
- <li>Fixed bug in targen - the -V dark emphasis wasn't being
- applied to OFPS generated points.</li>
- <li>Make sure that if an instrument display reading is interrupted
- by a forced calibration, that the user is asked to place it back
- on the display before resuming the measurements.</li>
- </ul>
- <h1>[V1.6.2 -&gt; V1.6.3] 26th January 2014</h1>
- <ul>
- <li>Added ProPhoto.icm and ProPhotoLin.icm to ref profiles.</li>
- <li>Fix bug in xicclu -py conversion.</li>
- <li>Added code to minimize ICC rounding error on matrix profile
- white point accuracy. Re-generated all reference profiles with
- this change.</li>
- <li>Changed i1d3 driver to completely ignore any EEPROM checksum
- errors for non "A-01" rev. instruments.</li>
- <li>Made transplot handle RGB-&gt;RGB device link.</li>
- <li>Removed colprof -y option. Use "profcheck -v2" instead, as it
- is more developed.</li>
- <li>Fixed bug in dispcal - it was not using the final measurement
- pass to update the calibration curves.</li>
- <li>Fixed bug in spotread, dispcal &amp; dispread for CCSS capable
- instruments where refresh display types was being ignored if a
- custom observer was used, and/or the custom observer as being
- ignored, and/or a&nbsp; CCMX was being ignored. Changed instlib
- semantics for inst_opt_set_ccss_obs :- this is now set
- immediately, and applied also to any subsequent set_disptype()
- or col_cal_spec_set().</li>
- <li>Renamed verify to colverify to avoid clash with MSWin program
- of the same name. Made it print the patch location for -v2 if it
- is present in the file.</li>
- <li>Changed targen to ensure that -V and -p options effects are
- reflected in the resulting expected CIE values of the .ti1 file.</li>
- <li>Changed targen so that -V parameter also affects single
- channel, grey wedge, grid &amp; body centered grid point
- distribution.</li>
- <li>Changed colprof to deal with variable grid distribution in a
- more neuanced way, to reduce overshoot artifacts when the -V
- parameter is used.</li>
- <li>Changed colprof to used a power_like function for the grid
- distribution shape from the -V parameter, so as to avoid issues
- with a power curve infinte slope near zero.</li>
- <li>Changed colprof to used a scaled down value of the targen -V
- parameter as the default for its -V parameter. Documentation now
- recommends more moderate values for -V.</li>
- <li>Added a special case to collink for RGB video input encoding
- to (attempt) to fine tune the black point to compensate for it
- (probably) not falling on a cLUT grid point. &amp; out encoding</li>
- <li>Tweaked dispcal to try and improve accuracy of black point
- calibration.</li>
- <li>Switch dispread to use NoClamp readings, so that average black
- point value is not biased.</li>
- <li>Fixed bug introduced into 1.6.2 oeminst that prevents .ccss
- files being installed.<br>
- </li>
- </ul>
- <h1>[V1.6.1 -&gt; V1.6.2] 18th November 2013</h1>
- <ul>
- <li> Added "dark region emphasis" -V parameter to targen and
- colprof,&nbsp; in an attempt to improve the accuracy of display
- profiles intended for use with video. This should improve the
- subsequent black point accuracy of the profile.</li>
- <li>Fixed bug and tweaked dispcal black point optimization to err
- on the black side. Added -v3 for even more debugging
- information.</li>
- <li>Changed i1d3 driver to be more forgiving of EEProm checksum
- calculation, so that it works with the latest release "A-02"
- rev.&nbsp; i1 display pro &amp; colormunki display instruments,
- as well as improving its robustness in the face of errors.</li>
- <li>Fixed race condition bug in OS X HID driver. This fixes
- occassional problem with i1d3, and also solves problem with the
- ColorHug on OS X. </li>
- <li>Fixed problem with TV encoded output and dispread -E -k/-K.</li>
- <li>Fixed minor bug in DE94 in icclib.</li>
- <li>Fixed major bug in illumread - result was being corrupted.</li>
- <li>Fixed "edges don't match" bug in printarg when -iCM -h -s/-S
- used.</li>
- <li>Fix bug in -H flag in ccxxmake, chartread, dispcal, dispread,
- illumread &amp; spotread so that it works once again.</li>
- <li> <br>
- </li>
- </ul>
- <h1>[V1.6.0 -&gt; V1.6.1] 30th September 2013</h1>
- <ul>
- <li>Fix bug in "average -m"<br>
- </li>
- <li>Fix oeminst to work with a wider range of i1d3 install files.</li>
- <li>Fix ColorMunki reflective measurement accuracy, particularly
- for reflective readings. This has been poor since V1.5</li>
- <li>Fix bug in using DTP94 on Apple OS X introduced in V1.5</li>
- <li>Fix MadVR connect code to look for appropriate 32 bit or 64
- bit .dll.</li>
- <li>Improve MSWin system driver installation by creating valid
- ArgyllCMS.cat file to match ArgyllCMS.inf. This eliminates the
- need to "Disable Driver Signature Enforcement", as well as
- allowing installation on MSWin&nbsp; 8.1.<br>
- </li>
- </ul>
- <h1>[V1.5.1 -&gt; V1.6.0] 16th August 2013</h1>
- <ul>
- <li>Added support for <b>JETI</b> specbos 1211 and 1201 (Thanks
- to JETI for their support!)</li>
- <li>Added Video profiling &amp; 3dLut creation support for eeColor
- and MadVR. See video section in tutorial for pointers to
- relevant changes to tools. This includes support for MadTPG +
- various Video standard ICC profiles + verification workflow.<br>
- </li>
- <li>Linux profile installation will use <b>colord</b> if
- libcolordcompat.so is present on system.</li>
- <li>Fix <b>ColorHug</b> driver so that it is backwards compatible
- with FW 1.1.8</li>
- <li>Made sure that MSWin test colors are not color managed. This
- may affect Vista, Win7 and Win8.</li>
- <li>Changed spectro/dispwin.c so that null transform color
- matching is used for displaying test patches on OS X &gt;= 10.6.
- This should fix calibrating/profiling secondary displays on &gt;
- OS X 10.6. Note that the 32 bit 10.4 binary will still have
- problems on &gt; OS X 10.6.</li>
- <li>Changed <b>instlib API</b> ambient XYZ and spectral units to
- Lux. In previous versions of instlib they were Lux/pi.</li>
- <li>For those instruments that support it, made ambient readings
- honor refresh mode measurements, to improve repeatability when
- measuring regularly flickering light sources. (specbos, i1d3,
- i1disp).</li>
- <li>Changed spotread -ew mode to be Bradford chromatic transform
- rather than XYZ scaling, to better match Argyll ICC abs. vs.
- rel.</li>
- <li>Added support to xicclu to lookup colors though CAL files,
- both forward and backwards. Will also plot CAL file contents
- using -g.</li>
- <li>Added -Y R:rate option to spotread, dispcal, dispread &amp;
- ccxxmake to allow setting a chosen display refresh rate. This
- can be used with the Colormunki display, as well as situations
- in which refresh rate measurement is not reliable.</li>
- <li>By default printtarg will create PS and EPS files with a CUPS
- job ticket to disable color management. Use the -U flag to
- disable this.</li>
- <li>Added display update delay calibration support to i1pro and
- ColorMunki (just like i1disp3), to improve measurement times.</li>
- <li>Changed dispcal &amp; dispread so that they wait up to 0.5
- seconds when reading dark patches after light ones to allow for
- display fall time. Added&nbsp; patch order optimization for
- display patch sets in targen to minimize the extra time.</li>
- <li>Changed dispwin daemon loader mode option from -E to -X. Added
- -E option to encode test patch colors in Video 16-235 range.</li>
- <li>Changed dispcal verify option from -E to -z. Added -E option
- to encode test patch colors in Video 16-235 range.</li>
- <li>Added -E option to to dispread to encode test patch colors in
- Video 16-235 range.</li>
- <li>Changed CIECAM02 Flare model to distinguish between Flare from
- the image itself, and Glare from ambient light. This allows
- scaling Glare with ambient automatically. Changed enumerated
- viewing conditions for new Flare/Glare settings, changed all to
- Flareless to improve dark image behavior, while retaining Glare
- modelling. Tweaked brightness and ambient values.</li>
- <li>Improved i1pro hi-res mode to improve accuracy.</li>
- <li>Added Body Centered Cubic grid option to targen.</li>
- <li>Added -Yn flag to dispcal and dispread, which skips asking the
- user to place the instrument on the measuring spot.</li>
- <li>Improve robustness of i1d3 display update measurement code.</li>
- <li>Added support for applying calibration curves in collink.</li>
- <li>Changed spotread so that it won't fall back to emissive spot
- mode if an ambient reading is requested.</li>
- <li>Turned off B2A table clip map smoothing, as it seems to
- introduce reversals for some data sets, and provides little
- benefit.</li>
- <li>Fixed crash in ucmm/ucmm.c when loading certain profiles using
- dispwin (thanks to Torok Edwin).</li>
- <li>Fixed gamut mapping intent "rl" to really use relative L*a*b*</li>
- <li>Fix bug in cicam02 in V1.5.0 that causes some mapping problems
- in the red for collink -ir or -ila.&nbsp;</li>
- <li>Changed cctiff so that it does lossless JPEG copy when there
- is no color transformation. This makes it more useful for
- embedding a profile.</li>
- <li>Fix xicclu so that it works with device links.</li>
- <li>Fixed bug in shaper/matrix profile curves that caused random
- bumpy black behaviour (shaper curve optimization local minimum
- problem).</li>
- <li>Don't add colorant tag to .tiff files in cctiff unless it is a
- non-standard space, as Photoshop will barf on such files.</li>
- <li>Fix bug with Spyder not being able to break out of dispcal
- adjustment loop.</li>
- <li>Fix bug in xicc/xicclu, -K flag not being recognised.</li>
- <li>Fix bug in xicc/xmatrix.c introduced in V1.5 that prevents
- matrix only profiles from being created.</li>
- <li>libusb 1.0 is now deprecated in favor of native USB drivers.<br>
- </li>
- </ul>
- <h1>[V1.5.0 -&gt; V1.5.1] 8th March 2013</h1>
- <ul>
- <li>Fix spectro/instlib.ksh and standalone instlib build.</li>
- <li>Turned off debug plot on using FWA.</li>
- <li>Changed link $(LINKFLAGS) location in link command line
- Jambase to get latest gcc working.</li>
- <li>Fixed new bug in matrix display profile creation that causes
- an inaccurate relative white point. This causes Photoshop to
- barf on the profiles.</li>
- <li>Added -m option to printcal.</li>
- <li>Fix bug in webwin that causes crash.<br>
- </li>
- </ul>
- <h1>[V1.4.0 -&gt; V1.5.0] 1st March 2013</h1>
- <ul>
- <li>Increased ease of selecting ISO 13655:2009 M0, M1 and M2
- measurements using FWA comensation using any spectrometer that
- can take non-UV filtered measurements. M0, M1 or M2 can now be
- selected directly using the -f flag. [ArgyllCMS has been
- supporting ISO 13655 M0, M1 &amp; M2 well before the standard
- was created, thanks to its FWA compensation feature.]<br>
- </li>
- <li>Increased stability of i1d3 refresh display measurements by
- increasing integration time, and tweaking crossover from
- frequency to period measurement.</li>
- <li>Added i1pro Rev E (i1pro2) feature support. Uses RevE
- measurement mode, and does wavelength calibration. Uses RevE
- (internal) stray light reduction, and black level temperature
- compensation. The only Rev E feature not currently supported is
- U.V. measurement, which would improve the accuracy of FWA
- compensation. Rev E driver can be disabled and the legacy driver
- mode used by setting the ARGYLL_DISABLE_I1PRO2_DRIVER
- environment variable.</li>
- <li>Changed i1pro adaptive mode to avoid high gain mode, so as to
- give more consistent and longer integration times for low light
- levels.</li>
- <li>Changed ColorMunki adaptive mode to avoid high gain mode, so
- as to give more consistent and longer integration times for low
- levels. Added black level temperature compensation.</li>
- <li>Added spotread interactive function 'f' to read out the
- calibrate display refresh rate for instruments that have a
- refresh display mode, as well as an 'F' function that measures
- the refresh rate for instruments that support a refresh rate
- measurement function (colorimeters &amp; spectrometers).</li>
- <li>The Display Type selection option -y in dispcal, dispread,
- chartread, spotread &amp; ccxxmake now lists installed CCSS and
- CCMX files as a selection, rather than using the -X parameter.
- CCMX and CCSS files now have extra fields to indicate the
- refresh mode, an optional list of default UI selection
- characters, and (for CCMX files) the base display type they
- apply over (CB-n).<br>
- </li>
- <li>Tweaked CIECAM02 to improve behavior for extreme blue colors,
- so that the hue doesn't swing too far towards the cyan. This
- helps in the clipping behavior from colorspaces such as
- ProPhotoRGB.</li>
- <li>Made the input profile cLUT extra neutral axis extrapolation
- points the default for colprof -u and non -u profiles. Changed
- -u algorithm to work similarly to -U scale :- it sets the scale
- automatically. Relative colorimetric is therefore hue matched to
- the white reference patch, Removed colprof -un, as it seems
- unnecessary. Added colprof -uc, which clips cLUT colors over Y =
- 1 to white.</li>
- <li>The spyd2en, spyd4en and i1d3ccss tools have been combined
- into, and replaced by a single oeminst tool.</li>
- <li>Fix problem with dispwin/dispcal/dispread -dweb and the latest
- Safari browser.</li>
- <li>Changed to a single ArgyllCMS.inf file for MSWin USB driver
- installation. This eases installation of more than a single type
- of instrument. Tested on MS Windows 8 and updated installation
- instructions.</li>
- <li>Dropped libusb for USB access, using native USB access
- instead. MSWin uses the libusb-win32 kernel driver. Moved the
- usb setup files from libusb1 to a new directory, usb.</li>
- <li>Added scanin support for ColorCheckerPassort.</li>
- <li>Updated OS X code to compile on 10.6 and 10.7 and (presumably)
- 10.8 (64 bit compatible API used when compiling on those
- platforms, including Cocoa for the test patch window).<br>
- </li>
- <li>Changed udev file usb/55-Argyll.rules to eliminate the test
- for /lib/udev/udev-acl as a condition of using ACL_MANAGE, since
- I'm informed that it is deprecated in recent distribution
- releases (but who can tell, given the churn in the udev API).</li>
- <li>Deprecated -V flag (adaptive mode) in dispcal, dispread and
- ccxxmake, since this is now the default. Flag will be ignored
- with a warning. Added -ZA flag instead, to select non-adaptive
- integration time mode.</li>
- <li>spotread -d flag is deprecated, and is now a synonym for the
- -e flag, since it defaults to adaptive mode. Added -ZA flag
- instead, to select non-adaptive integration time mode. Also
- added -Zr and -ZR flags to allow testing of the refresh mode
- overrides.</li>
- <li>Migrated ArgyllCMS specific application runtime files (such as
- instrument blobs, calibration state &amp; calibration files) to
- an "ArgyllCMS" sub-directory rather than the generic "color"
- directory. On OS X also moved data files to below the
- "Application Support" sub directory. The old locations will be
- used as a fallback.<br>
- </li>
- <li>Added support for Quato Silver Haze 3 OEM i1d3<br>
- </li>
- <li>Added support for X-Rite ColorMunki Smile colorimeter.</li>
- <li>Enable the ColorHug by default, although it isn't advertised
- as supported, since it doesn't yet work reliably on OS X.
- Updated ColorHug PCI VID &amp; PID</li>
- <li>For Spyder, emit a warning rather than error if the feature
- bits are missing for calibration tables.</li>
- <li>Added automatic adjustment of patch reading delay for i1d3, so
- that a more conservative (longer) default value (200 msec) can
- be used without impacting i1d3 speed. Also added environment
- variable ARGYLL_MIN_DISPLAY_UPDATE_DELAY_MS that can set a
- different minimum update delay.</li>
- <li>Fixed a bug introduced in V1.3.6 that stops the dtp41 from
- being initialized properly.</li>
- <li>Improved black level readings derived from spectral values by
- allowing them to be -ve. <br>
- </li>
- <li>The instlib API has been modified quite extensively to make it
- more self contained and flexible, although the basic
- architecture remains the same.<br>
- </li>
- </ul>
- <h1>[V1.3.7 -&gt; V1.4.0] 20th April 2012</h1>
- <ul>
- <li>Modified spectro/ccxxmake so that a colorimeter can be used as
- a reference to make ccmx files if two .ti3 files are used. Added
- ref/ccxx.ti1 as convenient way of creating ccmx .ti3 files.<br>
- </li>
- <li>Added dither/screening support for 8 bit output of render, and
- then made it available in target/printtarg.<br>
- </li>
- <li>Added JPEG file support to imdi/cctiff, xicc/tiffgamut and
- xicc/extracticc. ICC profiles embedded in JPEG files can now be
- used anywhere a TIFF file with embedded ICC profile can be used
- as a source of an ICC profile.<br>
- </li>
- <li>Fixed memory leaks in usbio.c, xdg_bds.c &amp; conv.c</li>
- <li>Fixed double memory free bug in icc/icc.c when iccdump'ing a
- profile that has a duplicate tag.</li>
- <li>Changed license of xicc/ccmx.[ch] to GPL2+.<br>
- </li>
- <li>Made display calibration and profile making deal with displays
- without hardware calibration support (VideoLUT support) more
- graceful. Added tutorial section covering this.<br>
- </li>
- <li>Added option to dispwin/dispcal/dispread/ccxxmake to redirect
- the test patches to a web browser via a local web server. This
- augments Argyll's existing local and remote display capability.<br>
- </li>
- <li>Fixed bug in spectro/i1d3.c which results in NAN if a low
- level readings drops to zero at a particular time. Improved
- refresh rate calibration accuracy. Fixed bugs in adaptive
- measurement logic that caused a channel to be pre-measured when
- it shouldn't. This seems to noticeably improve repeatability on
- refresh displays.<br>
- </li>
- <li>Fixed bug in ucmm/jcnf where it was failing to locate the
- correct profile for a display.<br>
- </li>
- <li>Fix bugs in ColorMunki Transmissive measurement mode
- calibration.<br>
- </li>
- </ul>
- <h1>[V1.3.6 -&gt; V1.3.7] 26th March 2012</h1>
- <ul>
- <li>Fix regression in Spyder support - ccmx files were not being
- handled (bug introduced in 1.3.6).</li>
- <li>Fix packaging problem - Spyder4 MSWin .inf file was missing.</li>
- <li>Change dispwin so that it will install a profile when there is
- no access to the display VideoLUT if the profile has no vcgt.<br>
- </li>
- </ul>
- <h1>[V1.3.5 -&gt; V1.3.6] 19th March 2012<br>
- </h1>
- <ul>
- <li>Added Spyder4 support. Note the need for spyd4en for access to
- a full range of Manufacturers calibrations. The Spyder4 can use
- .ccss calibration files too. Speeded up all Spyder instrument
- readings on brighter colors.</li>
- <li>Experimental ColorHug support is compiled in, but is disabled
- unless the environment variable "ENABLE_COLORHUG" is set. The
- ColorHug currently doesn't seem to work reliably across all
- platforms ArgyllCMS supports.<br>
- </li>
- <li>Changed and expanded display selection (-y flag) to be
- instrument specific. This is to support the Spyder4 and
- ColorHug, and adds a refresh display selection to the i1d3.</li>
- <li>Tweaked i1d3 integration times and added accurate refresh
- period calibration to the refresh display mode. Refresh display
- measurement times are double non-refresh displays. Improved i1d3
- period measurement logic to improve measurement speed and
- accuracy for dark colors.</li>
- <li>Changed i1disp measurement logic to try and make it more
- robust against light to dark changes during a reading. This may
- make it slightly less precise for LCD displays on bright colors
- (equivalent now to Refresh display precision).<br>
- </li>
- <li>Added a -V option to spotread to allow tracking reading
- consistency.</li>
- <li>Changed ccxxmake to create default .ccss with just&nbsp; RGBW,
- and not to weight W. This may give better matching. Made
- corresponding change to CCMX, giving the white patch 1/4
- weighting of sum of all other patches.</li>
- <li>Fixed applycal so that it applies calibration to both A2B and
- B2A tables, to preserve softproofing.</li>
- <li>Fixed timeout in SpectroScanT reference transmission
- measurement. (Someone kindly donated me a SpectroScanT to test
- with!)</li>
- <li>Made DTP94 driver ignore with a warning any
- NEEDS_OFFSET_DRIFT_CAL_ERR after a full reset. It seems that
- occasionally a few instruments do this, and X-Rite don't appear
- to be prepared to treat this as an instrument fault.</li>
- <li>Added support for Datacolor SpyderCheckr (Thanks to Jos
- Pereira).</li>
- <li>Improved the ability of spyd2en to cope with slightly
- different setup.exe formats.</li>
- <li>Add support for NEC SpectraSensor Pro version of the i1d3.<br>
- </li>
- </ul>
- <h1>[V1.3.4 -&gt; V1.3.5] 24th October 2011</h1>
- <ul>
- <li>Fix bug (crash) that affects ColorMunki design/photo display
- measurement. This also stops it restoring a calibration (-N
- flag).</li>
- <li>Add support for the OEM version of the i1d3.</li>
- <li>Fix bug that stopped ccxxmake being able to make ccmx's.</li>
- <li>Tweak gamut mapping to improve dark area mapping,
- non-monotonic profile inversion, and contrast preservation to
- small gamut.</li>
- <li>Kill i1ProfileTray.exe process if unable to open i1d3 on
- MSWin.</li>
- <li>Fix DTP20 chart printing - TID was sometimes incomplete. This
- shows up on a 4x6 chart.<br>
- </li>
- </ul>
- <h1>[V1.3.3 -&gt; V1.3.4] 31st August 2011</h1>
- <ul>
- <li>Added support for the X-Rite i1 Display Pro and ColorMunki
- Display colorimeters. As part of this, added support for CCSS
- calibration files for the instruments and added CCSS support to
- ccxxmake (renamed from ccmxmake). Provide new tool i1d3ccss to
- translating and installing CCSS files as well as the
- manufacturers calibration files for these instruments. Added
- non-default observer support for these instruments too.</li>
- <li>Fix gamut code to ignore setting primary/secondary cusps that
- are unlikely to be true. This avoids buggy gamut mapping
- behavior for gamuts that are very small and odd shaped.</li>
- <li>Changed Linux USB code to avoid doing a
- set_configuration&nbsp; if possible, since the USB driver does
- this by default. This then avoids triggering a bug in the
- Spyder2, which allows it to work on Linux version without the
- reset_ep fix, and may also allow the Spyder to work better with
- USB hubs.</li>
- <li>Change printtarg for DTP20 to allow for variable patch size.</li>
- <li>Changed dummy display matrix table to have channels rotated
- rather than R &amp; G swapped, to make it more obvious.</li>
- <li>Added option to colprof to allow setting the default profile
- rendering intent.</li>
- <li>Enhanced spectro/fakeread so that it will process a .ti3 file
- that has been renamed to .ti1.</li>
- <li>Fix bug in matrix input profile white point selection, + add
- in slight neutral bias code used in clut profiles.</li>
- <li>New profcheck -I wasn't working - fix option parsing.</li>
- </ul>
- <h1>[V1.3.2 -&gt; V1.3.3] 13th May 2011</h1>
- <ul>
- </ul>
- <ul>
- <li>Fixed compiler dependant bug in Eye-One pro and (possibly)
- Munki high res. spectral wavelength calculation.</li>
- <li>Add support for install variables DESTDIR and PREFIX in
- Jamtop. These can be set on the command line using "jam -s"</li>
- <li>Added targen -N parameter to allow adjustment of neutral axis
- patch density emphasis, as well as increasing the default. This
- should improve the result without needing to add explicit grey
- test patches.</li>
- <li>Added spectro/instlib.ksh script to assemble all the files
- needed for a standalone instrument library. Changed licence to
- GPLv2 for the files included in the instlib.zip file that is
- thus created. See spectro/instlib.txt for more details.</li>
- <li>Fix Jambase so that recent MingW compilers don't need extra
- .dll's</li>
- <li>Change Linux serial code to test ports using O_NONBLOCK</li>
- <li>Modify xspect &amp; illumread to improve realism of UV
- spectrum estimation.</li>
- <li>Fixed profile/txt2ti3 so that a sample name that looks like an
- integer is treated as text. (Fixes problem with latest
- ProfileMaker file).</li>
- <li>Added LCh option to spotread.</li>
- <li>Fixed numerical issue in scanin/scanrd.c, where large input
- rasters would cause fitting to fail.</li>
- <li>Modified colprof input chart white patch detection to slightly
- favour patches that are close to D50 neutral.</li>
- <li>Increase the default XYZ PCS A2B profile default smoothness.</li>
- <li>Improved cLUT input -u black &amp; white&nbsp; point
- extrapolation.</li>
- <li>Improved black point determination for devices that have
- extremely narrow gamuts doe to the use of custom inks.</li>
- <li>Added -Z option to colprof, to allow setting ICC attribute
- flags.</li>
- <li>Fix CIECAM02 to better match forward and backwards, to fix
- perceptual table white point.</li>
- <li>Add code to override X-Rite's new OS X drivers for ColorMunki
- and EyeOne. Note new installation instructions
- &lt;http://www.argyllcms.com/doc/Installing_OSX.html&gt;.</li>
- <li>Added -R flag to colprof, which restricts the range of the
- white, black for better compatibility with other programs.</li>
- <li>Fixed typo bug that prevented flash measurement mode from
- working.</li>
- <li>Replaced spectro/average with a new version that is more
- general.</li>
- <li>Fixed bug in printcal not working with spectral only files.</li>
- <li>Added extra verbose output to printcal in which it computes an
- ideal power-like value to apply to the test chart values in
- targen.</li>
- <li>Modify the way that XYZ cLUT B2A tables are indexed, so that
- the white point is at the top corner of the grid.This should
- solve Photoshop CS4/CS5 complaining that XYZ LUT profiles are
- 'defective'.</li>
- <li>Added option in xicc/xicclu to plot an arbitrary slice.</li>
- <li>Expand the number of i1 Display OEM devices that can be used.</li>
- <li>Made some changes to help compile on FreeBSD.</li>
- <li>Added another intent, "pa", Perceptual Appearance, which is
- the same as perceptual except that the grey axes are not forced
- into alignment, allowing the appearance parameters to have full
- affect, including altering the chromatic mapping.</li>
- <li>Fixed bug in txt2ti3 - it wasn't creating an iRGB colorspace
- file for output device RGB files, causing warnings warnings and
- failures when mixed with other iRGB tool sequences. </li>
- <li>Added pathological case fix for target/ofps where the ink
- limit == di-2. </li>
- <li>targen was failing to proceed when fixed points happened to be
- numerically just over the total ink limit.</li>
- <li>Added more navigation options for chartread patch by patch
- mode.</li>
- <li>&nbsp;Fixed bug in "chartread -r -H" that caused resume of
- i1Pro high res to fail with "The resumed spectral type seems to
- have changed".</li>
- <li>Modified profcheck so that it prints patch location if it is
- present in the .ti3 file.</li>
- <li>Changed dispcal and dispread -K option to -J. Added -K option
- to dispcal as an alternate way of profiling a calibrated
- display, and also added a -K option to dispcal. </li>
- <li>Increased ColorMunki emissive auto scaling target "over"
- margin from 5% to 10% to allow more room for instrument drift
- during measurement.</li>
- <li>&nbsp;Fix bug in winusb + i1Display, where dark CRT
- measurements timeout.</li>
- </ul>
- <h1>[V1.3.1 -&gt; V1.3.2] 4th November 2010<br>
- </h1>
- <ul>
- <li>Turn off debugging that was accidentally left on in FWA code.
- Add gcc 3.3 PPC optimizer bug workaround to FWA code in
- xicc/xspect.c</li>
- <li>Change shaper/matrix profile back to using power curve as 0th
- order shape. Improve it with input &amp; output offsets and
- straight segment at zero. Make cLUT input -u black &amp; white
- point extrapolation use pure shaper curves with special tweaks.</li>
- <li>Increase dispcal native white target weighting from 10 to 50
- to encourage white to be device 1.0,1.0,1.0 more strongly.</li>
- </ul>
- <h1>[V1.3.0 -&gt; V1.3.1] 26th October 2010<br>
- </h1>
- <ul>
- <li>Fixed MSWIN Vista/Win7 problem where having Task Manager
- running would stop display test window updating. Also fixed plot
- library to avoid the same problem.</li>
- <li>Swapped dispwin -E and -D flags, to make -D debug consistent
- throughout tools.</li>
- <li>Changed the ARGYLL_NOT_INTERACTIVE mode so that all return and
- line feed characters are ignored, so that they can be used
- freely to flush stdin without triggering anything.</li>
- <li>Fixed endless loop problem with chartread -r -p on fully read
- chart.</li>
- <li>Added -S option to chartread, that suppresses wrong strip and
- unexpected value warnings.</li>
- <li>Fix dispcal and spotread so that color temperature takes into
- account any non-standard observer (ie. the color temperature is
- the closest point on the spectrum locus as determined by the
- chosen observers interpretation of the Plancian or daylight
- spectrum.)</li>
- <li>Fix bug in libusb1 triggered on systems that support bulk
- continuation (Linux)</li>
- <li>Added 1964_10c observer to spectro/dispcal, to better allow
- comparison to the default numbers.</li>
- <li>Added recognition for Huey built into Lenovo W series Laptops.</li>
- <li>Fixed chartread/dispsup/spotread etc. so that -N isn't fatal
- if the instrument doesn't support it.</li>
- <li>Fixed dispcal to disable black &amp; white drift tracking
- during interactive adjustment.</li>
- <li>Added -s option to ccmxmake to allow the number of test
- patches to be set.</li>
- </ul>
- <h1>[V1.2.0 -&gt; V1.3.0] 8th September 2010<br>
- </h1>
- <ul>
- <li>Added option to <span style="font-weight: bold;">dispcal</span>
- and dispread that attempts to counteract instrument black drift
- and display white drift (-I option). This may help with
- instruments that haven't properly acclimatised to the
- measurement location, and LCD displays that also take some time
- to stabilise. The is a short discussion <a
- href="Scenarios.html#PM6">here</a>.<br>
- </li>
- <li>Added option to <span style="font-weight: bold;">dispcal</span>
- to allow specifying a non 1931 2 degree observer if a
- spectrometer is being used.<br>
- </li>
- <li>Added new utility spectro/<span style="font-weight: bold;">ccmxmake</span>,
- which makes Colorimeter Correction Matrices for a particular
- Colorimeter + Display combination, using a Spectrometer as a
- reference. The resulting <span style="font-weight: bold;">.ccmx</span>
- file can then be used with <span style="font-weight: bold;">spotread/dispcal/dispread</span>
- (-X option) to improve the&nbsp; accuracy of the colorimeter on
- that particular display. See a discussion <a
- href="WideGamutColmters.html">here</a> and <a
- href="Scenarios.html#PM6">here</a>.<br>
- </li>
- <li>Fixed bug in spotread's handling of emissive measurements. If
- the XYZ was computed from spectral, it was using a D50 white
- instead of no white reference.</li>
- <li>Fixed bug in i1pro normal resolution wavelength calibration,
- introduced in V1.2.0.<br>
- </li>
- <li>Changed libusb V1.0 name to libusb-1.0A, so as not to clash
- with any official but different libusb V1.0 installation. [This
- may necessitate re-installing device drivers on MSWin.]</li>
- <li>Added support for HP DreamColor version of the i1 display.<br>
- </li>
- <li>Fix problem with ARGYLL_NOT_INTERACTIVE - reading from
- instruments was not actually possible, because polling for input
- was disabled.</li>
- <li>Adjust ColorMunki dark threshold to reduce misread reports.
- Add inconsistent data to debug output. Fix bug in adaptive mode
- - the integration time was sometimes&nbsp; too short. Set
- adaptive emissive target at 95% to allow a little more margin to
- saturation.<br>
- </li>
- <li>Fix problem with ColorMunki reporting erroneous inconsistent
- measurement errors. This shows up on display calibration.</li>
- <li>Fix some minor compiler warnings.</li>
- <li>Added direction indicators to xy values in dispcal
- interactive&nbsp; monitor adjustments. </li>
- <li>Fix bug in CIECAM02 viewing condition settings :- the
- enumerated conditions after "mt" are displaced by 1. (ie. "mt"
- is really "pc", "mb" is "mt", "md" is "mb" etc.) Added option
- -c:sn for auto surround from the Lv parameter (-c:l).</li>
- <li>Add option to illumread to average several readings. Fixed bug
- in the way illumread displays available instruments.<br>
- </li>
- </ul>
- <h1>[V1.1.1 -&gt; V1.2.0] 30 July 2010<br>
- </h1>
- <ul>
- <li>Re-worked gamut mapping to improve perceptual intent
- saturation levels, as well as improve highlight and shadow
- contrast. Added fine tuning to improve both smoothness and the
- precision with which the source is mapped to the destination.</li>
- <li>Added illumread, which allows measuring an illuminant and
- estimating its UV content, for better accuracy with FWA
- compensation.</li>
- <li>Use a modified/forked version of libusb V1.0, that supports
- Win2K (libusb0.sys) back end by default. Supports 64 but MSWin
- using a combination of WinUSB.sys and ptlibusb0.sys. [ The HCFR
- does not work on Win 64 bit though, due to its buggy USB
- implementation. ] NOTE that the included version of Libusb V1
- has been carefully tested with all supported instruments on all
- supported platforms,&nbsp; and includes many bug fixes needed
- for correct functioning. While bug fixes have been fed upstream,
- not all have been adopted. In particular there is a nasty race
- condition that has not, and may never be fixed upstream, as well
- as missing critical functionality (clearep()).<br>
- </li>
- <li>Modified colprof -p to allow different abstract profiles to be
- applied for each intent.</li>
- <li>Added -I option (imitation) to printcal, so that an existing
- devices response can be set as a target.</li>
- <li>Increase target/ofps.c vertex intersection retries from 10 to
- 40 to give it a better chance of working with difficult
- profiles.</li>
- <li>Fixed bug in plot that shows up on XP+, where the window isn't
- dismissed by the first keystroke, but only after it has been
- moved or resized.</li>
- <li>Changed CMYK black point to be natural, rather than the
- darkest point in the same direction and K only. This may wreck K
- only to black point matching, but it will stop printers with
- funny colored K ink from messing up the black point.</li>
- <li>Make Lacie Blue Eye colorimeter appear as an i1display.</li>
- <li>Improved i1pro matching to Original Manufacturers Driver (see
- doc/i1proDriver.html).</li>
- <li>Improved i1pro/ColorMunki patch recognition for better
- uniformity.</li>
- <li>Fixed bug in ColorMunki driver scan mode calibration when
- instrument is more sensitive than usual.</li>
- <li>Added EV calculation to spotread -a<br>
- </li>
- </ul>
- <h1>[V1.1.0 -&gt; V1.1.1] 21 February 2010<br>
- </h1>
- <ul>
- <li>Renamed the following tools:<br>
- &nbsp;&nbsp;&nbsp; cb2cgats&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&gt;
- cb2ti3<br>
- &nbsp;&nbsp;&nbsp; kodak2cgats -&gt; kodak2ti3<br>
- &nbsp;&nbsp;&nbsp; logo2cgats&nbsp;&nbsp;&nbsp; -&gt; txt2ti3<br>
- &nbsp;&nbsp;&nbsp; splitcgats&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
- -&gt; splitti3<br>
- &nbsp;&nbsp;&nbsp;
- mpprof&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&gt;
- mppprof<br>
- </li>
- <li>Modified black curve to make sure that smoothed curve meets
- target level at boundaries.</li>
- <li>Added -M option to printtarg, for the case where the TIFF file
- is to include the margin.</li>
- <li>Fixed several build bugs in imdi code related to 64 bits.</li>
- <li>Fixed profile/colprof -u so that it is applied to matrix
- profiles too</li>
- <li>Changed tiffgamut to use one pass gamut hull finding and
- modified the smoothing so as to end up with a more closely
- wrapped volume.</li>
- <li>Fixed bug in input matrix profiles introduced by the XYZ cLUT
- display matrix profile change, where the correct white and black
- point weren't being written.</li>
- <li>Added matrix only/linear algorithm option to profile/colprof,
- for raw camera profiling.</li>
- <li>Modified libusb/55-Argyll.rules for better compatibility with
- systems that have ACL installed but no ConsoleKit. Also set
- ID_VENDOR and ID_MODEL using. usb-db.</li>
- <li>Modified target/targen to cope better with case where adding
- nodes fails to determine vertex positions a lot of the time,
- causing extreme slowdown.</li>
- <li>Fixed colprof so that the per channel input curves for XYZ PCS
- B2A tables are actually scaled correctly.</li>
- <li>Changed link/collink to apply Y to L* curve if the input or
- output space is XYZ. Fixed the Y to L* scaling to make sure it
- only apples to XYZ space, and that the L* non-linearisation
- still applies to Y like device spaces.</li>
- <li>Modified scanin so that it ignores any alpha channels in the
- input .tiff file.</li>
- <li>Changed printcal so that it will create .AMP file with more
- than 4 channels. Also fixed up plotting to plot up to 10
- channels.</li>
- <li>Changed dispcal and dispread so that a request for projector
- mode falls back to display mode if the instrument doesn't
- support a projector mode.</li>
- <li>Updated ref/CMP_Digital_Target-3.cht as it seems that the
- reference chart has columns labelled "2A - 2D" rather than the
- "AA - AD" that is actually printed on the chart...</li>
- <li>Altered xpsect FWA code to reduce overshoot artefacts due to
- filtering.<br>
- </li>
- </ul>
- <h1>[V1.0.4 -&gt; V1.1.0] 17th January 2010<br>
- </h1>
- <ul>
- <li>Spyder3 and ColorMunki Design, Photo and Create instrument
- support.</li>
- <li>Added a complete printer calibration system. This can work
- either with a print system that supports per channel print
- calibration curves, or purely using ICC profiling mechanisms.</li>
- <li>Default targen (OFPS) test point distribution has been
- re-written to generate test points on the gamut surface, refine
- the point locations when using a guide profile, and use a better
- error estimate model to determine the test point locations. <br>
- </li>
- <li>Changed chartread strip reading mode to allow navigating about
- the strips, saving a partially read chart, and resuming a
- partially read chart.<br>
- </li>
- <li>Improved and re-tuned gamut mapping. This is noticeably
- smoother and better retains source image detail.</li>
- <li>Re-tuned the cLUT profile creation smoothness vs. accuracy.</li>
- <li>Fixed viewgam so that the number of gamuts that can be viewed
- is unlimited. Also added error when computing intersecting
- volume if the two gamuts are incompatible.</li>
- <li>Improved CMYK black generation control and smoothness near the
- black point.</li>
- <li>Improved collink special black and colorant handling so that
- the gamut mapping is consistent&nbsp; with the special black and
- colorant mapping</li>
- <li>Changed profile/colprof to generate matrix tags for Display
- XYZ PCS cLUT profiles, to improve compatibility with other CMMs.<br>
- By default (-ax) the matrix tags will be a dummy transform that
- swaps red and green, while using -aX will create real matrix
- tags.</li>
- <li>Added -V option to dispcal and dispread to allow use of i1pro
- adaptive mode to give better low level consistency.</li>
- <li>Changed dispcal to default to -f 1.0 (assume black is all
- output offset) to make it work in more sympathy to a typical
- display response. Also changed default gamma to 2.4 for OS X
- 10.6 systems.<br>
- </li>
- <li>Improved X11 XRandR CRTC detection.</li>
- <li>Added spotread option to save spectral reading of an
- illuminant to a .sp file.</li>
- <li>Added Color Rendering Index (Ra) to spotread measurement
- results.</li>
- <li>Added i1pro &amp; ColorMunki flash measurement
- support.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
- </li>
- <li>Improve reliability of detecting backwards read i1pro/Munki
- strips.</li>
- <li>Fixed bug in i1pro driver that subtly affected accuracy.</li>
- <li>Modified xicc/cam02 to clip the blue to avoid crazy behavior
- outside the spectrum locus.</li>
- <li>Simplified the Linux installation instructions, particularly
- with regard to USB and serial permissions.</li>
- <li>Added working MSWindows 64 bit libusb drivers, which will work
- on Vista 64 and MSWindows 7 64 bit. Because of Microsoft's
- driver signing requirements though, they won't be usable unless
- a driver code signing workaround is used.</li>
- <li>Changed printtarg so that the TIFF output has the paper margin
- subtracted from it. This is so that the resulting TIFF can be
- placed on that sized paper without clipping or scaling. Set the
- margin to zero to get a TIFF that exactly fits into the
- specified paper size</li>
- </ul>
- <h1>[V1.0.3 -&gt; V1.0.4] 30th June 2009<br>
- </h1>
- <ul>
- <li>Modify icc/icclib to protect against integer overflow
- exploits, and fixes to minor bugs. Bump icclib version to 2.11
- to reflect this.<br>
- </li>
- <li>Fix bug in spectro/hidio.c that can cause a crash (bus error)
- on OS X for any program that accesses the instruments.</li>
- <li>Fix bug in xicc/xfit.c where too little memory was being
- allocated.<br>
- </li>
- </ul>
- <h1>[V1.0.2 -&gt; V1.0.3] 3rd September 2008<br>
- </h1>
- <ul>
- <li>Added multi-TIFF and popularity filtering to <span
- style="font-weight: bold;">tiffgamut</span>.<br>
- </li>
- <li>Modified gamut mapping in <span style="font-weight: bold;">colprof</span>
- and <span style="font-weight: bold;">collink</span> to be
- consistent, and have higher perceptual intent saturation.<br>
- </li>
- <li>Fixed timeout problem with the Eye-One Display colorimeter.<br>
- </li>
- <li>Fix segmentation fault in <span style="font-weight: bold;">dispread</span>.</li>
+<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html;
+ charset=windows-1252">
+ <meta name="author" content="Graeme Gill">
+ <meta name="description" content="Root of Argyll CMS documentation">
+ <meta name="GENERATOR" content="Mozilla/4.73 [en] (WinNT; I)
+ [Netscape]">
+ <meta name="Author" content="Graeme Gill">
+ <meta name="Description" content="Summary of changes for the most
+ recent release.">
+ <title>Argyll CMS changes since last release</title>
+ </head>
+ <body>
+ <h1> Summary of Argyll CMS Changes since last release</h1>
+ <h3>For a <span style="text-decoration: underline;">complete</span>
+ and more detailed list of changes, please see the log.txt file.</h3>
+ <h1>[V2.0.0 -&gt; V2.0.1] 9th July 2018</h1>
+ <ul>
+ <li>Increased maximum render channels to 16<br>
+ </li>
+ <li>Added -O option to collink to allow creating a link purely
+ from calibration file.</li>
+ <li>Fixed JETI specbos &amp; specval timeout when in averaging
+ mode and dark measurement.</li>
+ <li>Changed JETI specval 1511 driver to ignore REMOTE command
+ error with newer firmware.</li>
+ <li>Changed Klein K10 serial parameters in attempt to prevent
+ serial lock up on MSWindows.</li>
+ <li>Made a failure of the conf:maxtin command with a JETI 1201 a
+ soft error, to allow for old firmware versions.</li>
+ <li>Change colorhug Linux driver to reset on close. This may
+ overcome a problem re-starting the driver.</li>
+ <li>Fixed i1Pro driver to cope with stripped down OEM i1Pro2 that
+ is missing one piece of calibration information.</li>
+ <li>Fixed display calibration selection to allow for more than 62
+ entries. This is to fix problem using Klein K10 that has a lot
+ of saved calibrations.</li>
+ <li>Changed spec2cie to add extra informational L*a*b* output
+ fields, if a non D50 illuminant (-i option) is used.</li>
+ <li>Added -w parameter to spotread, to use the -i parameter
+ illuminant for L*a*b* calculation.</li>
+ <li>Fixed bug in spec2cie - XRGA conversion wasn't saving spectrum
+ out.<br>
+ </li>
+ </ul>
+ <h1>[V1.9.2 -&gt; V2.0.0] 17th November 2017</h1>
+ <ul>
+ <li>Added support for "pm" viewing condition (Print evaluation
+ with partial Mid-tone adaptation), and associated m: viewing
+ condition parameter. This is intended to address certain
+ situations involving the use of papers containing FWA/OBE
+ brighteners when viewed in an environment that has a very
+ noticeably warmer white point than the paper itself under the
+ illuminant.</li>
+ <li>Added support for the X-Rite i1Studio instrument. Note that
+ you may have to un-install and re-install the system drivers on
+ MSWindows, or update the udev 55-Argyll.rules file on Linux.<span
+ style="font-weight: bold;"></span></li>
+ <li>Slight improvement to i1d3 accuracy, by rounding the frequency
+ mode measurements up by 0.5.</li>
+ <li>Returned input profile forced Absolute Colorimetric option
+ with -ua flag, after the -u option was changed in V1.5.0.<br>
+ </li>
+ <li>Try and fix problem in triggering calibration when
+ ARGYLL_NOT_INTERACTIVE is set.</li>
+ <li>Improve compatibility of txt2ti3, and added -D option to mark
+ output as Display but not Normalized to white.</li>
+ <li>Modified collink to disable Video encoded in/out sync level
+ preservation.</li>
+ <li>Added support for custom Observer by using a .cmf file as an
+ argument to all tools taking an observer parameter.</li>
+ <li>Added support for proposed CIE 2012 2 degree &amp; 10 degree
+ observers, based on the CIE (2006) 2-deg LMS cone fundamentals.</li>
+ <li>Fix problem with dispwin -E option not being shown in usage,
+ and only being applied when a calibration file is used.</li>
+ <li>Added spotread -u option to display XYZ amd CIE 1976 Yuv
+ values.</li>
+ <li>Added XRGA conversion support to spec2cie, as well as better
+ support in chartread and txt2ti3 for tracking XRGA standard and
+ polarization filter use.</li>
+ <li>Fix bug in spec2cie processing emissive .sp files.</li>
+ <li>Fix problem with i1d3 running direct USB (i.e. Not via HID) on
+ MSWin.</li>
+ <li>Fixed bug in render/timage -p.</li>
+ <li>Changed spotread ambient readings (CCT, CRI, TLCI) to show CCT
+ delta E in 1960 Duv units and others in Delta E 2000.</li>
+ <li>Added ARGYLL_UNTWIST_GAMUT_SURFACE environment variable, that
+ enables extra gamut clip surface processing that may improve the
+ smoothness of device links and B2A tables for poorly behaved
+ devices.</li>
+ <li>Fixed bug introduced in new colorimetric nearest clipping code
+ in rspl/rev.c in V1.9.0 that caused colprof using some ink limit
+ settings (such as -L0) to crash.</li>
+ <li>Fixed bug introduced in new colorimetric nearest clipping code
+ in rspl/rev.c in V1.9.0 that caused some (mainly XYZ clut)
+ profiles to clip badly, causing banding.</li>
+ <li>Improved dispcal -R VideoLUT depth measurement algorithm
+ robustness.</li>
+ <li>Worked around latest OS X super slow opening serial port
+ problem (1.5 seconds to open a port!)</li>
+ <li>Added ColorCheckerHalfPassport.cht file.</li>
+ <li>Fixed bug in ChromeCast mDNS parsing that caused problems with
+ some devices with long names being detected.</li>
+ <li>Now ignoring Chromecast-Audio and (.ca flags &amp; 1) == 0
+ devices, and showing the friendly chromecast name if available.</li>
+ <li>Wait longer to find more Chromecasts, even if we've found one.</li>
+ <li>Fixed colprof bug when handling Display L*a*b* .ti3 data.</li>
+ <li>Added Wacom i1d3 support.</li>
+ <li>Changed dispwin to by default ignore Gnome colord, and use its
+ native ucmm for storage of display profiles, since colord
+ support for ArgyllCMS has proven unreliable. This can be
+ re-enabled by setting the ARGYLL_USE_COLORD environment variable
+ (i.e. to "true").</li>
+ <li>Change X11 root window _ICC_PROFILE_xxx atom setting for
+ Xrandr case to now match the Xinerama order, so that
+ ICC_PROFILE_xxx atoms match, irrespective of which extension
+ applications are using. This improves conformance to "ICC
+ Profiles in X Specification 0.2".</li>
+ <li>Improved ucmm install/load/delete to better respect
+ systemlocal/user scopes, as well as eliminating need for profile
+ name on delete when ucmm is used.</li>
+ <li>Improve fast serial port scan to better detect Lumagen
+ Radiance without upsetting it.</li>
+ <li>Added ARGYLL_EXCLUDE_SERIAL_SCAN environment variable, to
+ allow suppression of fast serial port scan of sensitive devices.<br>
+ </li>
+ </ul>
+ <h1>[V1.9.1 -&gt; V1.9.2] 17th October 2016</h1>
+ <ul>
+ <li>Added CMYKOGB and CMYKRGB 7 channel ink preset, and made
+ targen more flexible in matching pre-conditioning profiles to
+ targen ink selection.<br>
+ </li>
+ <li>Fix oeminst for OS X save location.</li>
+ <li>Fix oeminst for OS X Spyder 4 CD calibration file location.</li>
+ </ul>
+ <h1>[V1.8.3 -&gt; V1.9.1] 28th September 2016</h1>
+ <ul>
+ <li>Improved robustness of ChromeCast discovery, and added some
+ minimal diagnostics.<br>
+ </li>
+ <li>Improved robustness of targen ofps patch generation when using
+ less well behaved pre-conditioning profiles.<br>
+ </li>
+ <li>Fixed oeminst so that it locates cdrom's in Linuxes latest
+ mount point of /run/media/$USER/.<br>
+ </li>
+ <li>Fixed bug in i1pro2 driver, in which strip calibration would
+ fail if instrument had been first calibrated with
+ ARGYLL_DISABLE_I1PRO2_DRIVER set, and then calibrated with
+ ARGYLL_DISABLE_I1PRO2_DRIVER unset.<br>
+ </li>
+ <li>Added option to icclib to write Output profiles using 'chad'
+ tag if the ARGYLL_CREATE_DISPLAY_PROFILE_WITH_CHAD&nbsp;
+ environment variable is set. This is not recommended for normal
+ use, but may assist compatibility with other systems.</li>
+ <li>Added JETI spectraval support, including Bluetooth access.</li>
+ <li>Added support for the Klein K10 connecting via a serial port.</li>
+ <li>Fixed bug in Colormunki Smile driver that causes crash on
+ Ubuntu 16.04.1 LTS.</li>
+ <li>Modified "lp" intent to greatly reduce eliminate
+ Helmholtz-Kohlrausch appearance modelling.<br>
+ </li>
+ <li>Fixed problem with targen -g, in that the corresponding XYZ
+ values had double the power applied, rather than none. This was
+ causing problems with printtarg spacer colors.<br>
+ </li>
+ <li>Extensive re-write of colorimetric nearest clipping code in
+ rspl/rev.c to restore precision that was lost in the speedups
+ made in V1.0.0. The nnrev setup now takes a lot longer with
+ &nbsp; high resolution CMYK profiles though. This corrects a
+ "green becoming too yellow" problem for mapping from ProPhoto
+ space with some RGB devices.</li>
+ <li>Change dispwin to properly set X11 DirectColor and take
+ account of TrueColor Colormap.&nbsp; This fixes problem with
+ NVidia linux driver 364.12 exposing a VideoLUT depth that is
+ different from the frame buffer depth.</li>
+ <li>Change icclib to automatically repair icmTextDescription
+ strings that have an allocation that is longer than their size.</li>
+ <li>Added i1Pro Lamp Drift test and fix functions to spotread (-Y
+ l|L options).</li>
+ <li>Change colprof so that -s -S will accept general compression
+ percentage as an alternative to a source colorspace/image gamut.</li>
+ <li>Added optional conversion from native Gretag-MacBeth &amp;
+ X-Rite reflective calibration standards to/from XRGA.</li>
+ <li>Changed OS X GUI support code so as not to switch to "interact
+ with the Dock" mode until actual GUI element is to be displayed.
+ This prevents batch commands with optional GUI elements from
+ blocking normal GUI interactions.</li>
+ <li>Re-jigged OS X UI code to use the main thread to avoid window
+ creation timing issues and a warning backtrace on OS X 10.11.</li>
+ <li>Added CMP_Digital_Target-7.cht</li>
+ <li>Fix spec2cie to cope with .ti3 files that are missing device
+ values, so that it can process a wider range of input CIE
+ reference files.</li>
+ <li>Changed implementation of ARGYLL_NOT_INTERACTIVE on MSWin to
+ make it more reliable when operated progromatically.</li>
+ <li>Fixed chartread so that if you are reading patch by patch, the
+ location strings can be arbitrary (i.e. they don't have to
+ conform to an alpha/num strip/patch pattern.)</li>
+ <li>Added support for Sencore ColorPro V, IV &amp; III
+ colorimeters (based on Sequel Chroma colorimeter.).<br>
+ </li>
+ </ul>
+ <h1>[V1.8.2 -&gt; V1.8.3] 26th October 2015</h1>
+ <ul>
+ <li>Added SpyderCheckr24 scaning .cht and .cie files.</li>
+ <li>Fixed USB problem with i1pro (Rev B &amp; D ?), where
+ communications would occasionally break down on fast systems.<br>
+ </li>
+ <li>Added another fixed display intergration time to i1pro
+ non-adaptive emission mode to cope with higher brightness
+ displays.</li>
+ <li>Added workaround for i1d3 Rev. B status code 0x83 on very low
+ light measurement</li>
+ <li>Fixed minor bug in i1d3.c that truncated serial number string.
+ (Thanks to Mikael Sterner).</li>
+ <li>Fixed bug in Klein K10 driver - adaptive measurement wasn't
+ properly using all the extra measurements.</li>
+ <li>Improved Klein K10 driver to be more robust when lights off
+ command returns bogus error codes, or causes a cascade of bogus
+ measurement errors.<br>
+ </li>
+ <li>Added workaround for OS X 10.9+ "App Nap" problem.</li>
+ <li>Added maximum sensor frequency check for Spyder &amp; i1d3
+ drivers, so that erronious readings due to excessive brightness
+ can't be missed.</li>
+ <li>Changed chartread so that it doesn't warn of a possible wrong
+ strip being read, nor allows bi-directional strip reading, if
+ "printtarg -r" was used. A warning will be issued if "printtarg
+ -r" was used, and "chartread -B" wasn't used.<br>
+ </li>
+ <li>Fixed collink for eeColor Full range RGB to use output curve
+ ("second" 1D curves) to compensate for cLUT being wired for 1.0
+ output from 1.0 input.<br>
+ </li>
+ <li>Added "lp" gamut mapping intent :- Luminance Preserving
+ Perceptual, for Photographers concerned with maintaining tonal
+ variations.</li>
+ <li>Fixed bugs in image specific gamut mapping that were degrading
+ the accuracy of the result.</li>
+ <li>Re-wrote gamut smoothing code, and re-tuned it to behave
+ similarly to the V1.8.2 release.</li>
+ <li>Changed default viewing condition glare to 5%, to smooth out
+ shadow tone curve.</li>
+ <li>Reduced the level of Helmholtz-Kohlrausch effect in CIECAM02
+ implementation in the light of visual experiments.</li>
+ </ul>
+ <h1>[V1.8.1 -&gt; V1.8.2] 7th September 2015</h1>
+ <ul>
+ <li>Fixed endless loop bug in alternate calibration selectors
+ code.</li>
+ </ul>
+ <h1>[V1.8.0 -&gt; V1.8.1] 4th September 2015</h1>
+ <ul>
+ <li>Fixed bug in "spec2cie -n" wrong field indexes were being
+ used.</li>
+ <li>Fixed colorimeter calibration selectors to add in alternate
+ selectors if the letters are free.</li>
+ </ul>
+ <h1>[V1.7.0 -&gt; V1.8.0] 20th August 2015</h1>
+ <ul>
+ <li>Added support for the Image Engineering EX1 spectroradiometer.</li>
+ <li>Added support for the SwatchMate Cube reflective colorimeter,
+ with improved accuracy.</li>
+ <li>Added Added Television Lighting Consistency Index (EBU
+ TLCI-2012 Qa)&nbsp; to spotread and specplot output.</li>
+ <li>Added R9 value to CRI value in spotread and specplot output.</li>
+ <li>Added workaround for JETI specbos having been calibrated by a
+ 3rd party, and its calibrated range being out of sync with its
+ claimed range.<br>
+ </li>
+ <li>Added support for "EMISINPUT" type .ti3 file.</li>
+ <li>Build using OpenSSL rather than axTLS if it is built on Linux.</li>
+ <li>Fixed stack space problem in OS X UI programs by expanding
+ main thread proxy to have 8MB instead of the default 512K.</li>
+ <li>Updated built in libtiff to V4.0.4beta.</li>
+ <li>Changed CGATS format to not emit unknown keyword declaration
+ ("KEYWORD") by default.</li>
+ <li>Added inst_calc_cond_mask to inst.h to allow for flags in
+ calibration conditions. A consequence of this is that calc needs
+ to be masked with this when comparing against a specific
+ condition, and the inst_calc_optional_flag should be cleared if
+ it is set, before callint inst-&gt;calibrate() if the user wants
+ to proceed with a particular calibration.</li>
+ <li>Fixed bug with dispcal -e N</li>
+ <li>Fixed bug in xicclu -fg and -kp</li>
+ <li>Added dispcal -x x option to allow reading a chart and
+ manually entering the XYZ values.</li>
+ <li>Fix spyder4 &amp; 5 bug where some display types were set as
+ refresh when they shouldn't be.</li>
+ <li>Fix collink "Warning :- RGB black hack trigger more than
+ once!" when -b is used with input video encoding (-e).</li>
+ <li>Changed colprof so that the default ICC description is the
+ base filename rather than the whole file path.</li>
+ <li>Fix technology type and display type selector
+ "uniqueification" bug&nbsp; that shows up in "ccxxmake -??".</li>
+ <li>Add OEM field to ccmx and ccss files to mark files that have
+ been installed from OEM disk, so that custom ccmx &amp; ccss
+ files can be given suggested selector letter priority (+
+ ref/CRT.ccss).</li>
+ <li>Tweak CGATS write format to avoid scientific notation until
+ the numbers are bigger and smaller (i.e until e6 and e-6 are
+ needed).<br>
+ </li>
+ </ul>
+ <h1>[V1.6.3 -&gt; V1.7.0] 1st May 2015</h1>
+ <ul>
+ <li>Improved gamut mapping to reduce unnecessary changes to less
+ saturated colors&nbsp; such as skin tones.</li>
+ <li>Add support for DataColor Spyder 5.</li>
+ <li>Add support for ColorHug2 colorimeter.</li>
+ <li>Add support for Klein K10-A colorimeter.</li>
+ <li>Added Google ChromeCast as a test patch generator for Video
+ displays.</li>
+ <li>Added ls2ti3 tool to convert LightSpace .bcs files to .ti3.</li>
+ <li>Added IRIDAS .cube 3DLut format support to collink.</li>
+ <li>Add X3D and X3DOM support as an alternative to VRML, and make
+ X3DOM the default.</li>
+ <li>Add better cross compatibility with non-Argyll ICC profiles
+ using ArgyllCMS 'arts' tag to mark 'wtpt' Absolute Colorimetric
+ chromaticity transform, as well as implement proper absolute
+ colorimetric intent for Display profiles use the 'chad' tag.
+ Note that the standard ICC profiles provided by ArgyllCMS in the
+ ref directory (such as sRGB etc.) now include an 'arts' tag.</li>
+ <li>Ignore any patches that have zero values for creating Display
+ profiles, unless they are for device zero. </li>
+ <li>Fix various instrument communications problems for JETI
+ specbos, DTP20, DTP92 &amp; DTP94.</li>
+ <li>Fix gestaltSystemVersion warning on OS X 10.10.</li>
+ <li>Fix very major bug in illumread. It wasn't actually working at
+ all since V1.4.0.</li>
+ <li>Added collink -I[gG][:p.p]:x.x options that allows an output
+ offset gamma curve be targetted instead of BT1886.</li>
+ <li>Added dispcal and collink -b black point hack. This forces the
+ input zero to map to the output zero for well behaved displays,
+ reducing dependence on the instrument accuracy for a very dark
+ black point.</li>
+ <li>Added preset list of display techologies to select from in
+ ccxxmake.</li>
+ <li>Added a -P prune option to profcheck, that creates a .ti3 file
+ pruned of any patches that have a delta E fit error greater than
+ a threshold. This may be of use in eliminating bad reading
+ values from a measurement set.</li>
+ <li>Added histogram plot option -h to both profcheck and verify.</li>
+ <li>Added a dispread &amp; fakeread -Z option to set the number of
+ bits to quantize the test values to. </li>
+ <li>Fixed bug in targen - the -V dark emphasis wasn't being
+ applied to OFPS generated points.</li>
+ <li>Make sure that if an instrument display reading is interrupted
+ by a forced calibration, that the user is asked to place it back
+ on the display before resuming the measurements.</li>
+ </ul>
+ <h1>[V1.6.2 -&gt; V1.6.3] 26th January 2014</h1>
+ <ul>
+ <li>Added ProPhoto.icm and ProPhotoLin.icm to ref profiles.</li>
+ <li>Fix bug in xicclu -py conversion.</li>
+ <li>Added code to minimize ICC rounding error on matrix profile
+ white point accuracy. Re-generated all reference profiles with
+ this change.</li>
+ <li>Changed i1d3 driver to completely ignore any EEPROM checksum
+ errors for non "A-01" rev. instruments.</li>
+ <li>Made transplot handle RGB-&gt;RGB device link.</li>
+ <li>Removed colprof -y option. Use "profcheck -v2" instead, as it
+ is more developed.</li>
+ <li>Fixed bug in dispcal - it was not using the final measurement
+ pass to update the calibration curves.</li>
+ <li>Fixed bug in spotread, dispcal &amp; dispread for CCSS capable
+ instruments where refresh display types was being ignored if a
+ custom observer was used, and/or the custom observer as being
+ ignored, and/or a&nbsp; CCMX was being ignored. Changed instlib
+ semantics for inst_opt_set_ccss_obs :- this is now set
+ immediately, and applied also to any subsequent set_disptype()
+ or col_cal_spec_set().</li>
+ <li>Renamed verify to colverify to avoid clash with MSWin program
+ of the same name. Made it print the patch location for -v2 if it
+ is present in the file.</li>
+ <li>Changed targen to ensure that -V and -p options effects are
+ reflected in the resulting expected CIE values of the .ti1 file.</li>
+ <li>Changed targen so that -V parameter also affects single
+ channel, grey wedge, grid &amp; body centered grid point
+ distribution.</li>
+ <li>Changed colprof to deal with variable grid distribution in a
+ more neuanced way, to reduce overshoot artifacts when the -V
+ parameter is used.</li>
+ <li>Changed colprof to used a power_like function for the grid
+ distribution shape from the -V parameter, so as to avoid issues
+ with a power curve infinte slope near zero.</li>
+ <li>Changed colprof to used a scaled down value of the targen -V
+ parameter as the default for its -V parameter. Documentation now
+ recommends more moderate values for -V.</li>
+ <li>Added a special case to collink for RGB video input encoding
+ to (attempt) to fine tune the black point to compensate for it
+ (probably) not falling on a cLUT grid point. &amp; out encoding</li>
+ <li>Tweaked dispcal to try and improve accuracy of black point
+ calibration.</li>
+ <li>Switch dispread to use NoClamp readings, so that average black
+ point value is not biased.</li>
+ <li>Fixed bug introduced into 1.6.2 oeminst that prevents .ccss
+ files being installed.<br>
+ </li>
+ </ul>
+ <h1>[V1.6.1 -&gt; V1.6.2] 18th November 2013</h1>
+ <ul>
+ <li> Added "dark region emphasis" -V parameter to targen and
+ colprof,&nbsp; in an attempt to improve the accuracy of display
+ profiles intended for use with video. This should improve the
+ subsequent black point accuracy of the profile.</li>
+ <li>Fixed bug and tweaked dispcal black point optimization to err
+ on the black side. Added -v3 for even more debugging
+ information.</li>
+ <li>Changed i1d3 driver to be more forgiving of EEProm checksum
+ calculation, so that it works with the latest release "A-02"
+ rev.&nbsp; i1 display pro &amp; colormunki display instruments,
+ as well as improving its robustness in the face of errors.</li>
+ <li>Fixed race condition bug in OS X HID driver. This fixes
+ occassional problem with i1d3, and also solves problem with the
+ ColorHug on OS X. </li>
+ <li>Fixed problem with TV encoded output and dispread -E -k/-K.</li>
+ <li>Fixed minor bug in DE94 in icclib.</li>
+ <li>Fixed major bug in illumread - result was being corrupted.</li>
+ <li>Fixed "edges don't match" bug in printarg when -iCM -h -s/-S
+ used.</li>
+ <li>Fix bug in -H flag in ccxxmake, chartread, dispcal, dispread,
+ illumread &amp; spotread so that it works once again.</li>
+ <li> <br>
+ </li>
+ </ul>
+ <h1>[V1.6.0 -&gt; V1.6.1] 30th September 2013</h1>
+ <ul>
+ <li>Fix bug in "average -m"<br>
+ </li>
+ <li>Fix oeminst to work with a wider range of i1d3 install files.</li>
+ <li>Fix ColorMunki reflective measurement accuracy, particularly
+ for reflective readings. This has been poor since V1.5</li>
+ <li>Fix bug in using DTP94 on Apple OS X introduced in V1.5</li>
+ <li>Fix MadVR connect code to look for appropriate 32 bit or 64
+ bit .dll.</li>
+ <li>Improve MSWin system driver installation by creating valid
+ ArgyllCMS.cat file to match ArgyllCMS.inf. This eliminates the
+ need to "Disable Driver Signature Enforcement", as well as
+ allowing installation on MSWin&nbsp; 8.1.<br>
+ </li>
+ </ul>
+ <h1>[V1.5.1 -&gt; V1.6.0] 16th August 2013</h1>
+ <ul>
+ <li>Added support for <b>JETI</b> specbos 1211 and 1201 (Thanks
+ to JETI for their support!)</li>
+ <li>Added Video profiling &amp; 3dLut creation support for eeColor
+ and MadVR. See video section in tutorial for pointers to
+ relevant changes to tools. This includes support for MadTPG +
+ various Video standard ICC profiles + verification workflow.<br>
+ </li>
+ <li>Linux profile installation will use <b>colord</b> if
+ libcolordcompat.so is present on system.</li>
+ <li>Fix <b>ColorHug</b> driver so that it is backwards compatible
+ with FW 1.1.8</li>
+ <li>Made sure that MSWin test colors are not color managed. This
+ may affect Vista, Win7 and Win8.</li>
+ <li>Changed spectro/dispwin.c so that null transform color
+ matching is used for displaying test patches on OS X &gt;= 10.6.
+ This should fix calibrating/profiling secondary displays on &gt;
+ OS X 10.6. Note that the 32 bit 10.4 binary will still have
+ problems on &gt; OS X 10.6.</li>
+ <li>Changed <b>instlib API</b> ambient XYZ and spectral units to
+ Lux. In previous versions of instlib they were Lux/pi.</li>
+ <li>For those instruments that support it, made ambient readings
+ honor refresh mode measurements, to improve repeatability when
+ measuring regularly flickering light sources. (specbos, i1d3,
+ i1disp).</li>
+ <li>Changed spotread -ew mode to be Bradford chromatic transform
+ rather than XYZ scaling, to better match Argyll ICC abs. vs.
+ rel.</li>
+ <li>Added support to xicclu to lookup colors though CAL files,
+ both forward and backwards. Will also plot CAL file contents
+ using -g.</li>
+ <li>Added -Y R:rate option to spotread, dispcal, dispread &amp;
+ ccxxmake to allow setting a chosen display refresh rate. This
+ can be used with the Colormunki display, as well as situations
+ in which refresh rate measurement is not reliable.</li>
+ <li>By default printtarg will create PS and EPS files with a CUPS
+ job ticket to disable color management. Use the -U flag to
+ disable this.</li>
+ <li>Added display update delay calibration support to i1pro and
+ ColorMunki (just like i1disp3), to improve measurement times.</li>
+ <li>Changed dispcal &amp; dispread so that they wait up to 0.5
+ seconds when reading dark patches after light ones to allow for
+ display fall time. Added&nbsp; patch order optimization for
+ display patch sets in targen to minimize the extra time.</li>
+ <li>Changed dispwin daemon loader mode option from -E to -X. Added
+ -E option to encode test patch colors in Video 16-235 range.</li>
+ <li>Changed dispcal verify option from -E to -z. Added -E option
+ to encode test patch colors in Video 16-235 range.</li>
+ <li>Added -E option to to dispread to encode test patch colors in
+ Video 16-235 range.</li>
+ <li>Changed CIECAM02 Flare model to distinguish between Flare from
+ the image itself, and Glare from ambient light. This allows
+ scaling Glare with ambient automatically. Changed enumerated
+ viewing conditions for new Flare/Glare settings, changed all to
+ Flareless to improve dark image behavior, while retaining Glare
+ modelling. Tweaked brightness and ambient values.</li>
+ <li>Improved i1pro hi-res mode to improve accuracy.</li>
+ <li>Added Body Centered Cubic grid option to targen.</li>
+ <li>Added -Yn flag to dispcal and dispread, which skips asking the
+ user to place the instrument on the measuring spot.</li>
+ <li>Improve robustness of i1d3 display update measurement code.</li>
+ <li>Added support for applying calibration curves in collink.</li>
+ <li>Changed spotread so that it won't fall back to emissive spot
+ mode if an ambient reading is requested.</li>
+ <li>Turned off B2A table clip map smoothing, as it seems to
+ introduce reversals for some data sets, and provides little
+ benefit.</li>
+ <li>Fixed crash in ucmm/ucmm.c when loading certain profiles using
+ dispwin (thanks to Torok Edwin).</li>
+ <li>Fixed gamut mapping intent "rl" to really use relative L*a*b*</li>
+ <li>Fix bug in cicam02 in V1.5.0 that causes some mapping problems
+ in the red for collink -ir or -ila.&nbsp;</li>
+ <li>Changed cctiff so that it does lossless JPEG copy when there
+ is no color transformation. This makes it more useful for
+ embedding a profile.</li>
+ <li>Fix xicclu so that it works with device links.</li>
+ <li>Fixed bug in shaper/matrix profile curves that caused random
+ bumpy black behaviour (shaper curve optimization local minimum
+ problem).</li>
+ <li>Don't add colorant tag to .tiff files in cctiff unless it is a
+ non-standard space, as Photoshop will barf on such files.</li>
+ <li>Fix bug with Spyder not being able to break out of dispcal
+ adjustment loop.</li>
+ <li>Fix bug in xicc/xicclu, -K flag not being recognised.</li>
+ <li>Fix bug in xicc/xmatrix.c introduced in V1.5 that prevents
+ matrix only profiles from being created.</li>
+ <li>libusb 1.0 is now deprecated in favor of native USB drivers.<br>
+ </li>
+ </ul>
+ <h1>[V1.5.0 -&gt; V1.5.1] 8th March 2013</h1>
+ <ul>
+ <li>Fix spectro/instlib.ksh and standalone instlib build.</li>
+ <li>Turned off debug plot on using FWA.</li>
+ <li>Changed link $(LINKFLAGS) location in link command line
+ Jambase to get latest gcc working.</li>
+ <li>Fixed new bug in matrix display profile creation that causes
+ an inaccurate relative white point. This causes Photoshop to
+ barf on the profiles.</li>
+ <li>Added -m option to printcal.</li>
+ <li>Fix bug in webwin that causes crash.<br>
+ </li>
+ </ul>
+ <h1>[V1.4.0 -&gt; V1.5.0] 1st March 2013</h1>
+ <ul>
+ <li>Increased ease of selecting ISO 13655:2009 M0, M1 and M2
+ measurements using FWA comensation using any spectrometer that
+ can take non-UV filtered measurements. M0, M1 or M2 can now be
+ selected directly using the -f flag. [ArgyllCMS has been
+ supporting ISO 13655 M0, M1 &amp; M2 well before the standard
+ was created, thanks to its FWA compensation feature.]<br>
+ </li>
+ <li>Increased stability of i1d3 refresh display measurements by
+ increasing integration time, and tweaking crossover from
+ frequency to period measurement.</li>
+ <li>Added i1pro Rev E (i1pro2) feature support. Uses RevE
+ measurement mode, and does wavelength calibration. Uses RevE
+ (internal) stray light reduction, and black level temperature
+ compensation. The only Rev E feature not currently supported is
+ U.V. measurement, which would improve the accuracy of FWA
+ compensation. Rev E driver can be disabled and the legacy driver
+ mode used by setting the ARGYLL_DISABLE_I1PRO2_DRIVER
+ environment variable.</li>
+ <li>Changed i1pro adaptive mode to avoid high gain mode, so as to
+ give more consistent and longer integration times for low light
+ levels.</li>
+ <li>Changed ColorMunki adaptive mode to avoid high gain mode, so
+ as to give more consistent and longer integration times for low
+ levels. Added black level temperature compensation.</li>
+ <li>Added spotread interactive function 'f' to read out the
+ calibrate display refresh rate for instruments that have a
+ refresh display mode, as well as an 'F' function that measures
+ the refresh rate for instruments that support a refresh rate
+ measurement function (colorimeters &amp; spectrometers).</li>
+ <li>The Display Type selection option -y in dispcal, dispread,
+ chartread, spotread &amp; ccxxmake now lists installed CCSS and
+ CCMX files as a selection, rather than using the -X parameter.
+ CCMX and CCSS files now have extra fields to indicate the
+ refresh mode, an optional list of default UI selection
+ characters, and (for CCMX files) the base display type they
+ apply over (CB-n).<br>
+ </li>
+ <li>Tweaked CIECAM02 to improve behavior for extreme blue colors,
+ so that the hue doesn't swing too far towards the cyan. This
+ helps in the clipping behavior from colorspaces such as
+ ProPhotoRGB.</li>
+ <li>Made the input profile cLUT extra neutral axis extrapolation
+ points the default for colprof -u and non -u profiles. Changed
+ -u algorithm to work similarly to -U scale :- it sets the scale
+ automatically. Relative colorimetric is therefore hue matched to
+ the white reference patch, Removed colprof -un, as it seems
+ unnecessary. Added colprof -uc, which clips cLUT colors over Y =
+ 1 to white.</li>
+ <li>The spyd2en, spyd4en and i1d3ccss tools have been combined
+ into, and replaced by a single oeminst tool.</li>
+ <li>Fix problem with dispwin/dispcal/dispread -dweb and the latest
+ Safari browser.</li>
+ <li>Changed to a single ArgyllCMS.inf file for MSWin USB driver
+ installation. This eases installation of more than a single type
+ of instrument. Tested on MS Windows 8 and updated installation
+ instructions.</li>
+ <li>Dropped libusb for USB access, using native USB access
+ instead. MSWin uses the libusb-win32 kernel driver. Moved the
+ usb setup files from libusb1 to a new directory, usb.</li>
+ <li>Added scanin support for ColorCheckerPassort.</li>
+ <li>Updated OS X code to compile on 10.6 and 10.7 and (presumably)
+ 10.8 (64 bit compatible API used when compiling on those
+ platforms, including Cocoa for the test patch window).<br>
+ </li>
+ <li>Changed udev file usb/55-Argyll.rules to eliminate the test
+ for /lib/udev/udev-acl as a condition of using ACL_MANAGE, since
+ I'm informed that it is deprecated in recent distribution
+ releases (but who can tell, given the churn in the udev API).</li>
+ <li>Deprecated -V flag (adaptive mode) in dispcal, dispread and
+ ccxxmake, since this is now the default. Flag will be ignored
+ with a warning. Added -ZA flag instead, to select non-adaptive
+ integration time mode.</li>
+ <li>spotread -d flag is deprecated, and is now a synonym for the
+ -e flag, since it defaults to adaptive mode. Added -ZA flag
+ instead, to select non-adaptive integration time mode. Also
+ added -Zr and -ZR flags to allow testing of the refresh mode
+ overrides.</li>
+ <li>Migrated ArgyllCMS specific application runtime files (such as
+ instrument blobs, calibration state &amp; calibration files) to
+ an "ArgyllCMS" sub-directory rather than the generic "color"
+ directory. On OS X also moved data files to below the
+ "Application Support" sub directory. The old locations will be
+ used as a fallback.<br>
+ </li>
+ <li>Added support for Quato Silver Haze 3 OEM i1d3<br>
+ </li>
+ <li>Added support for X-Rite ColorMunki Smile colorimeter.</li>
+ <li>Enable the ColorHug by default, although it isn't advertised
+ as supported, since it doesn't yet work reliably on OS X.
+ Updated ColorHug PCI VID &amp; PID</li>
+ <li>For Spyder, emit a warning rather than error if the feature
+ bits are missing for calibration tables.</li>
+ <li>Added automatic adjustment of patch reading delay for i1d3, so
+ that a more conservative (longer) default value (200 msec) can
+ be used without impacting i1d3 speed. Also added environment
+ variable ARGYLL_MIN_DISPLAY_UPDATE_DELAY_MS that can set a
+ different minimum update delay.</li>
+ <li>Fixed a bug introduced in V1.3.6 that stops the dtp41 from
+ being initialized properly.</li>
+ <li>Improved black level readings derived from spectral values by
+ allowing them to be -ve. <br>
+ </li>
+ <li>The instlib API has been modified quite extensively to make it
+ more self contained and flexible, although the basic
+ architecture remains the same.<br>
+ </li>
+ </ul>
+ <h1>[V1.3.7 -&gt; V1.4.0] 20th April 2012</h1>
+ <ul>
+ <li>Modified spectro/ccxxmake so that a colorimeter can be used as
+ a reference to make ccmx files if two .ti3 files are used. Added
+ ref/ccxx.ti1 as convenient way of creating ccmx .ti3 files.<br>
+ </li>
+ <li>Added dither/screening support for 8 bit output of render, and
+ then made it available in target/printtarg.<br>
+ </li>
+ <li>Added JPEG file support to imdi/cctiff, xicc/tiffgamut and
+ xicc/extracticc. ICC profiles embedded in JPEG files can now be
+ used anywhere a TIFF file with embedded ICC profile can be used
+ as a source of an ICC profile.<br>
+ </li>
+ <li>Fixed memory leaks in usbio.c, xdg_bds.c &amp; conv.c</li>
+ <li>Fixed double memory free bug in icc/icc.c when iccdump'ing a
+ profile that has a duplicate tag.</li>
+ <li>Changed license of xicc/ccmx.[ch] to GPL2+.<br>
+ </li>
+ <li>Made display calibration and profile making deal with displays
+ without hardware calibration support (VideoLUT support) more
+ graceful. Added tutorial section covering this.<br>
+ </li>
+ <li>Added option to dispwin/dispcal/dispread/ccxxmake to redirect
+ the test patches to a web browser via a local web server. This
+ augments Argyll's existing local and remote display capability.<br>
+ </li>
+ <li>Fixed bug in spectro/i1d3.c which results in NAN if a low
+ level readings drops to zero at a particular time. Improved
+ refresh rate calibration accuracy. Fixed bugs in adaptive
+ measurement logic that caused a channel to be pre-measured when
+ it shouldn't. This seems to noticeably improve repeatability on
+ refresh displays.<br>
+ </li>
+ <li>Fixed bug in ucmm/jcnf where it was failing to locate the
+ correct profile for a display.<br>
+ </li>
+ <li>Fix bugs in ColorMunki Transmissive measurement mode
+ calibration.<br>
+ </li>
+ </ul>
+ <h1>[V1.3.6 -&gt; V1.3.7] 26th March 2012</h1>
+ <ul>
+ <li>Fix regression in Spyder support - ccmx files were not being
+ handled (bug introduced in 1.3.6).</li>
+ <li>Fix packaging problem - Spyder4 MSWin .inf file was missing.</li>
+ <li>Change dispwin so that it will install a profile when there is
+ no access to the display VideoLUT if the profile has no vcgt.<br>
+ </li>
+ </ul>
+ <h1>[V1.3.5 -&gt; V1.3.6] 19th March 2012<br>
+ </h1>
+ <ul>
+ <li>Added Spyder4 support. Note the need for spyd4en for access to
+ a full range of Manufacturers calibrations. The Spyder4 can use
+ .ccss calibration files too. Speeded up all Spyder instrument
+ readings on brighter colors.</li>
+ <li>Experimental ColorHug support is compiled in, but is disabled
+ unless the environment variable "ENABLE_COLORHUG" is set. The
+ ColorHug currently doesn't seem to work reliably across all
+ platforms ArgyllCMS supports.<br>
+ </li>
+ <li>Changed and expanded display selection (-y flag) to be
+ instrument specific. This is to support the Spyder4 and
+ ColorHug, and adds a refresh display selection to the i1d3.</li>
+ <li>Tweaked i1d3 integration times and added accurate refresh
+ period calibration to the refresh display mode. Refresh display
+ measurement times are double non-refresh displays. Improved i1d3
+ period measurement logic to improve measurement speed and
+ accuracy for dark colors.</li>
+ <li>Changed i1disp measurement logic to try and make it more
+ robust against light to dark changes during a reading. This may
+ make it slightly less precise for LCD displays on bright colors
+ (equivalent now to Refresh display precision).<br>
+ </li>
+ <li>Added a -V option to spotread to allow tracking reading
+ consistency.</li>
+ <li>Changed ccxxmake to create default .ccss with just&nbsp; RGBW,
+ and not to weight W. This may give better matching. Made
+ corresponding change to CCMX, giving the white patch 1/4
+ weighting of sum of all other patches.</li>
+ <li>Fixed applycal so that it applies calibration to both A2B and
+ B2A tables, to preserve softproofing.</li>
+ <li>Fixed timeout in SpectroScanT reference transmission
+ measurement. (Someone kindly donated me a SpectroScanT to test
+ with!)</li>
+ <li>Made DTP94 driver ignore with a warning any
+ NEEDS_OFFSET_DRIFT_CAL_ERR after a full reset. It seems that
+ occasionally a few instruments do this, and X-Rite don't appear
+ to be prepared to treat this as an instrument fault.</li>
+ <li>Added support for Datacolor SpyderCheckr (Thanks to Jos
+ Pereira).</li>
+ <li>Improved the ability of spyd2en to cope with slightly
+ different setup.exe formats.</li>
+ <li>Add support for NEC SpectraSensor Pro version of the i1d3.<br>
+ </li>
+ </ul>
+ <h1>[V1.3.4 -&gt; V1.3.5] 24th October 2011</h1>
+ <ul>
+ <li>Fix bug (crash) that affects ColorMunki design/photo display
+ measurement. This also stops it restoring a calibration (-N
+ flag).</li>
+ <li>Add support for the OEM version of the i1d3.</li>
+ <li>Fix bug that stopped ccxxmake being able to make ccmx's.</li>
+ <li>Tweak gamut mapping to improve dark area mapping,
+ non-monotonic profile inversion, and contrast preservation to
+ small gamut.</li>
+ <li>Kill i1ProfileTray.exe process if unable to open i1d3 on
+ MSWin.</li>
+ <li>Fix DTP20 chart printing - TID was sometimes incomplete. This
+ shows up on a 4x6 chart.<br>
+ </li>
+ </ul>
+ <h1>[V1.3.3 -&gt; V1.3.4] 31st August 2011</h1>
+ <ul>
+ <li>Added support for the X-Rite i1 Display Pro and ColorMunki
+ Display colorimeters. As part of this, added support for CCSS
+ calibration files for the instruments and added CCSS support to
+ ccxxmake (renamed from ccmxmake). Provide new tool i1d3ccss to
+ translating and installing CCSS files as well as the
+ manufacturers calibration files for these instruments. Added
+ non-default observer support for these instruments too.</li>
+ <li>Fix gamut code to ignore setting primary/secondary cusps that
+ are unlikely to be true. This avoids buggy gamut mapping
+ behavior for gamuts that are very small and odd shaped.</li>
+ <li>Changed Linux USB code to avoid doing a
+ set_configuration&nbsp; if possible, since the USB driver does
+ this by default. This then avoids triggering a bug in the
+ Spyder2, which allows it to work on Linux version without the
+ reset_ep fix, and may also allow the Spyder to work better with
+ USB hubs.</li>
+ <li>Change printtarg for DTP20 to allow for variable patch size.</li>
+ <li>Changed dummy display matrix table to have channels rotated
+ rather than R &amp; G swapped, to make it more obvious.</li>
+ <li>Added option to colprof to allow setting the default profile
+ rendering intent.</li>
+ <li>Enhanced spectro/fakeread so that it will process a .ti3 file
+ that has been renamed to .ti1.</li>
+ <li>Fix bug in matrix input profile white point selection, + add
+ in slight neutral bias code used in clut profiles.</li>
+ <li>New profcheck -I wasn't working - fix option parsing.</li>
+ </ul>
+ <h1>[V1.3.2 -&gt; V1.3.3] 13th May 2011</h1>
+ <ul>
+ </ul>
+ <ul>
+ <li>Fixed compiler dependant bug in Eye-One pro and (possibly)
+ Munki high res. spectral wavelength calculation.</li>
+ <li>Add support for install variables DESTDIR and PREFIX in
+ Jamtop. These can be set on the command line using "jam -s"</li>
+ <li>Added targen -N parameter to allow adjustment of neutral axis
+ patch density emphasis, as well as increasing the default. This
+ should improve the result without needing to add explicit grey
+ test patches.</li>
+ <li>Added spectro/instlib.ksh script to assemble all the files
+ needed for a standalone instrument library. Changed licence to
+ GPLv2 for the files included in the instlib.zip file that is
+ thus created. See spectro/instlib.txt for more details.</li>
+ <li>Fix Jambase so that recent MingW compilers don't need extra
+ .dll's</li>
+ <li>Change Linux serial code to test ports using O_NONBLOCK</li>
+ <li>Modify xspect &amp; illumread to improve realism of UV
+ spectrum estimation.</li>
+ <li>Fixed profile/txt2ti3 so that a sample name that looks like an
+ integer is treated as text. (Fixes problem with latest
+ ProfileMaker file).</li>
+ <li>Added LCh option to spotread.</li>
+ <li>Fixed numerical issue in scanin/scanrd.c, where large input
+ rasters would cause fitting to fail.</li>
+ <li>Modified colprof input chart white patch detection to slightly
+ favour patches that are close to D50 neutral.</li>
+ <li>Increase the default XYZ PCS A2B profile default smoothness.</li>
+ <li>Improved cLUT input -u black &amp; white&nbsp; point
+ extrapolation.</li>
+ <li>Improved black point determination for devices that have
+ extremely narrow gamuts doe to the use of custom inks.</li>
+ <li>Added -Z option to colprof, to allow setting ICC attribute
+ flags.</li>
+ <li>Fix CIECAM02 to better match forward and backwards, to fix
+ perceptual table white point.</li>
+ <li>Add code to override X-Rite's new OS X drivers for ColorMunki
+ and EyeOne. Note new installation instructions
+ &lt;http://www.argyllcms.com/doc/Installing_OSX.html&gt;.</li>
+ <li>Added -R flag to colprof, which restricts the range of the
+ white, black for better compatibility with other programs.</li>
+ <li>Fixed typo bug that prevented flash measurement mode from
+ working.</li>
+ <li>Replaced spectro/average with a new version that is more
+ general.</li>
+ <li>Fixed bug in printcal not working with spectral only files.</li>
+ <li>Added extra verbose output to printcal in which it computes an
+ ideal power-like value to apply to the test chart values in
+ targen.</li>
+ <li>Modify the way that XYZ cLUT B2A tables are indexed, so that
+ the white point is at the top corner of the grid.This should
+ solve Photoshop CS4/CS5 complaining that XYZ LUT profiles are
+ 'defective'.</li>
+ <li>Added option in xicc/xicclu to plot an arbitrary slice.</li>
+ <li>Expand the number of i1 Display OEM devices that can be used.</li>
+ <li>Made some changes to help compile on FreeBSD.</li>
+ <li>Added another intent, "pa", Perceptual Appearance, which is
+ the same as perceptual except that the grey axes are not forced
+ into alignment, allowing the appearance parameters to have full
+ affect, including altering the chromatic mapping.</li>
+ <li>Fixed bug in txt2ti3 - it wasn't creating an iRGB colorspace
+ file for output device RGB files, causing warnings warnings and
+ failures when mixed with other iRGB tool sequences. </li>
+ <li>Added pathological case fix for target/ofps where the ink
+ limit == di-2. </li>
+ <li>targen was failing to proceed when fixed points happened to be
+ numerically just over the total ink limit.</li>
+ <li>Added more navigation options for chartread patch by patch
+ mode.</li>
+ <li>&nbsp;Fixed bug in "chartread -r -H" that caused resume of
+ i1Pro high res to fail with "The resumed spectral type seems to
+ have changed".</li>
+ <li>Modified profcheck so that it prints patch location if it is
+ present in the .ti3 file.</li>
+ <li>Changed dispcal and dispread -K option to -J. Added -K option
+ to dispcal as an alternate way of profiling a calibrated
+ display, and also added a -K option to dispcal. </li>
+ <li>Increased ColorMunki emissive auto scaling target "over"
+ margin from 5% to 10% to allow more room for instrument drift
+ during measurement.</li>
+ <li>&nbsp;Fix bug in winusb + i1Display, where dark CRT
+ measurements timeout.</li>
+ </ul>
+ <h1>[V1.3.1 -&gt; V1.3.2] 4th November 2010<br>
+ </h1>
+ <ul>
+ <li>Turn off debugging that was accidentally left on in FWA code.
+ Add gcc 3.3 PPC optimizer bug workaround to FWA code in
+ xicc/xspect.c</li>
+ <li>Change shaper/matrix profile back to using power curve as 0th
+ order shape. Improve it with input &amp; output offsets and
+ straight segment at zero. Make cLUT input -u black &amp; white
+ point extrapolation use pure shaper curves with special tweaks.</li>
+ <li>Increase dispcal native white target weighting from 10 to 50
+ to encourage white to be device 1.0,1.0,1.0 more strongly.</li>
+ </ul>
+ <h1>[V1.3.0 -&gt; V1.3.1] 26th October 2010<br>
+ </h1>
+ <ul>
+ <li>Fixed MSWIN Vista/Win7 problem where having Task Manager
+ running would stop display test window updating. Also fixed plot
+ library to avoid the same problem.</li>
+ <li>Swapped dispwin -E and -D flags, to make -D debug consistent
+ throughout tools.</li>
+ <li>Changed the ARGYLL_NOT_INTERACTIVE mode so that all return and
+ line feed characters are ignored, so that they can be used
+ freely to flush stdin without triggering anything.</li>
+ <li>Fixed endless loop problem with chartread -r -p on fully read
+ chart.</li>
+ <li>Added -S option to chartread, that suppresses wrong strip and
+ unexpected value warnings.</li>
+ <li>Fix dispcal and spotread so that color temperature takes into
+ account any non-standard observer (ie. the color temperature is
+ the closest point on the spectrum locus as determined by the
+ chosen observers interpretation of the Plancian or daylight
+ spectrum.)</li>
+ <li>Fix bug in libusb1 triggered on systems that support bulk
+ continuation (Linux)</li>
+ <li>Added 1964_10c observer to spectro/dispcal, to better allow
+ comparison to the default numbers.</li>
+ <li>Added recognition for Huey built into Lenovo W series Laptops.</li>
+ <li>Fixed chartread/dispsup/spotread etc. so that -N isn't fatal
+ if the instrument doesn't support it.</li>
+ <li>Fixed dispcal to disable black &amp; white drift tracking
+ during interactive adjustment.</li>
+ <li>Added -s option to ccmxmake to allow the number of test
+ patches to be set.</li>
+ </ul>
+ <h1>[V1.2.0 -&gt; V1.3.0] 8th September 2010<br>
+ </h1>
+ <ul>
+ <li>Added option to <span style="font-weight: bold;">dispcal</span>
+ and dispread that attempts to counteract instrument black drift
+ and display white drift (-I option). This may help with
+ instruments that haven't properly acclimatised to the
+ measurement location, and LCD displays that also take some time
+ to stabilise. The is a short discussion <a
+ href="Scenarios.html#PM6">here</a>.<br>
+ </li>
+ <li>Added option to <span style="font-weight: bold;">dispcal</span>
+ to allow specifying a non 1931 2 degree observer if a
+ spectrometer is being used.<br>
+ </li>
+ <li>Added new utility spectro/<span style="font-weight: bold;">ccmxmake</span>,
+ which makes Colorimeter Correction Matrices for a particular
+ Colorimeter + Display combination, using a Spectrometer as a
+ reference. The resulting <span style="font-weight: bold;">.ccmx</span>
+ file can then be used with <span style="font-weight: bold;">spotread/dispcal/dispread</span>
+ (-X option) to improve the&nbsp; accuracy of the colorimeter on
+ that particular display. See a discussion <a
+ href="WideGamutColmters.html">here</a> and <a
+ href="Scenarios.html#PM6">here</a>.<br>
+ </li>
+ <li>Fixed bug in spotread's handling of emissive measurements. If
+ the XYZ was computed from spectral, it was using a D50 white
+ instead of no white reference.</li>
+ <li>Fixed bug in i1pro normal resolution wavelength calibration,
+ introduced in V1.2.0.<br>
+ </li>
+ <li>Changed libusb V1.0 name to libusb-1.0A, so as not to clash
+ with any official but different libusb V1.0 installation. [This
+ may necessitate re-installing device drivers on MSWin.]</li>
+ <li>Added support for HP DreamColor version of the i1 display.<br>
+ </li>
+ <li>Fix problem with ARGYLL_NOT_INTERACTIVE - reading from
+ instruments was not actually possible, because polling for input
+ was disabled.</li>
+ <li>Adjust ColorMunki dark threshold to reduce misread reports.
+ Add inconsistent data to debug output. Fix bug in adaptive mode
+ - the integration time was sometimes&nbsp; too short. Set
+ adaptive emissive target at 95% to allow a little more margin to
+ saturation.<br>
+ </li>
+ <li>Fix problem with ColorMunki reporting erroneous inconsistent
+ measurement errors. This shows up on display calibration.</li>
+ <li>Fix some minor compiler warnings.</li>
+ <li>Added direction indicators to xy values in dispcal
+ interactive&nbsp; monitor adjustments. </li>
+ <li>Fix bug in CIECAM02 viewing condition settings :- the
+ enumerated conditions after "mt" are displaced by 1. (ie. "mt"
+ is really "pc", "mb" is "mt", "md" is "mb" etc.) Added option
+ -c:sn for auto surround from the Lv parameter (-c:l).</li>
+ <li>Add option to illumread to average several readings. Fixed bug
+ in the way illumread displays available instruments.<br>
+ </li>
+ </ul>
+ <h1>[V1.1.1 -&gt; V1.2.0] 30 July 2010<br>
+ </h1>
+ <ul>
+ <li>Re-worked gamut mapping to improve perceptual intent
+ saturation levels, as well as improve highlight and shadow
+ contrast. Added fine tuning to improve both smoothness and the
+ precision with which the source is mapped to the destination.</li>
+ <li>Added illumread, which allows measuring an illuminant and
+ estimating its UV content, for better accuracy with FWA
+ compensation.</li>
+ <li>Use a modified/forked version of libusb V1.0, that supports
+ Win2K (libusb0.sys) back end by default. Supports 64 but MSWin
+ using a combination of WinUSB.sys and ptlibusb0.sys. [ The HCFR
+ does not work on Win 64 bit though, due to its buggy USB
+ implementation. ] NOTE that the included version of Libusb V1
+ has been carefully tested with all supported instruments on all
+ supported platforms,&nbsp; and includes many bug fixes needed
+ for correct functioning. While bug fixes have been fed upstream,
+ not all have been adopted. In particular there is a nasty race
+ condition that has not, and may never be fixed upstream, as well
+ as missing critical functionality (clearep()).<br>
+ </li>
+ <li>Modified colprof -p to allow different abstract profiles to be
+ applied for each intent.</li>
+ <li>Added -I option (imitation) to printcal, so that an existing
+ devices response can be set as a target.</li>
+ <li>Increase target/ofps.c vertex intersection retries from 10 to
+ 40 to give it a better chance of working with difficult
+ profiles.</li>
+ <li>Fixed bug in plot that shows up on XP+, where the window isn't
+ dismissed by the first keystroke, but only after it has been
+ moved or resized.</li>
+ <li>Changed CMYK black point to be natural, rather than the
+ darkest point in the same direction and K only. This may wreck K
+ only to black point matching, but it will stop printers with
+ funny colored K ink from messing up the black point.</li>
+ <li>Make Lacie Blue Eye colorimeter appear as an i1display.</li>
+ <li>Improved i1pro matching to Original Manufacturers Driver (see
+ doc/i1proDriver.html).</li>
+ <li>Improved i1pro/ColorMunki patch recognition for better
+ uniformity.</li>
+ <li>Fixed bug in ColorMunki driver scan mode calibration when
+ instrument is more sensitive than usual.</li>
+ <li>Added EV calculation to spotread -a<br>
+ </li>
+ </ul>
+ <h1>[V1.1.0 -&gt; V1.1.1] 21 February 2010<br>
+ </h1>
+ <ul>
+ <li>Renamed the following tools:<br>
+ &nbsp;&nbsp;&nbsp; cb2cgats&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&gt;
+ cb2ti3<br>
+ &nbsp;&nbsp;&nbsp; kodak2cgats -&gt; kodak2ti3<br>
+ &nbsp;&nbsp;&nbsp; logo2cgats&nbsp;&nbsp;&nbsp; -&gt; txt2ti3<br>
+ &nbsp;&nbsp;&nbsp; splitcgats&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ -&gt; splitti3<br>
+ &nbsp;&nbsp;&nbsp;
+ mpprof&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&gt;
+ mppprof<br>
+ </li>
+ <li>Modified black curve to make sure that smoothed curve meets
+ target level at boundaries.</li>
+ <li>Added -M option to printtarg, for the case where the TIFF file
+ is to include the margin.</li>
+ <li>Fixed several build bugs in imdi code related to 64 bits.</li>
+ <li>Fixed profile/colprof -u so that it is applied to matrix
+ profiles too</li>
+ <li>Changed tiffgamut to use one pass gamut hull finding and
+ modified the smoothing so as to end up with a more closely
+ wrapped volume.</li>
+ <li>Fixed bug in input matrix profiles introduced by the XYZ cLUT
+ display matrix profile change, where the correct white and black
+ point weren't being written.</li>
+ <li>Added matrix only/linear algorithm option to profile/colprof,
+ for raw camera profiling.</li>
+ <li>Modified libusb/55-Argyll.rules for better compatibility with
+ systems that have ACL installed but no ConsoleKit. Also set
+ ID_VENDOR and ID_MODEL using. usb-db.</li>
+ <li>Modified target/targen to cope better with case where adding
+ nodes fails to determine vertex positions a lot of the time,
+ causing extreme slowdown.</li>
+ <li>Fixed colprof so that the per channel input curves for XYZ PCS
+ B2A tables are actually scaled correctly.</li>
+ <li>Changed link/collink to apply Y to L* curve if the input or
+ output space is XYZ. Fixed the Y to L* scaling to make sure it
+ only apples to XYZ space, and that the L* non-linearisation
+ still applies to Y like device spaces.</li>
+ <li>Modified scanin so that it ignores any alpha channels in the
+ input .tiff file.</li>
+ <li>Changed printcal so that it will create .AMP file with more
+ than 4 channels. Also fixed up plotting to plot up to 10
+ channels.</li>
+ <li>Changed dispcal and dispread so that a request for projector
+ mode falls back to display mode if the instrument doesn't
+ support a projector mode.</li>
+ <li>Updated ref/CMP_Digital_Target-3.cht as it seems that the
+ reference chart has columns labelled "2A - 2D" rather than the
+ "AA - AD" that is actually printed on the chart...</li>
+ <li>Altered xpsect FWA code to reduce overshoot artefacts due to
+ filtering.<br>
+ </li>
+ </ul>
+ <h1>[V1.0.4 -&gt; V1.1.0] 17th January 2010<br>
+ </h1>
+ <ul>
+ <li>Spyder3 and ColorMunki Design, Photo and Create instrument
+ support.</li>
+ <li>Added a complete printer calibration system. This can work
+ either with a print system that supports per channel print
+ calibration curves, or purely using ICC profiling mechanisms.</li>
+ <li>Default targen (OFPS) test point distribution has been
+ re-written to generate test points on the gamut surface, refine
+ the point locations when using a guide profile, and use a better
+ error estimate model to determine the test point locations. <br>
+ </li>
+ <li>Changed chartread strip reading mode to allow navigating about
+ the strips, saving a partially read chart, and resuming a
+ partially read chart.<br>
+ </li>
+ <li>Improved and re-tuned gamut mapping. This is noticeably
+ smoother and better retains source image detail.</li>
+ <li>Re-tuned the cLUT profile creation smoothness vs. accuracy.</li>
+ <li>Fixed viewgam so that the number of gamuts that can be viewed
+ is unlimited. Also added error when computing intersecting
+ volume if the two gamuts are incompatible.</li>
+ <li>Improved CMYK black generation control and smoothness near the
+ black point.</li>
+ <li>Improved collink special black and colorant handling so that
+ the gamut mapping is consistent&nbsp; with the special black and
+ colorant mapping</li>
+ <li>Changed profile/colprof to generate matrix tags for Display
+ XYZ PCS cLUT profiles, to improve compatibility with other CMMs.<br>
+ By default (-ax) the matrix tags will be a dummy transform that
+ swaps red and green, while using -aX will create real matrix
+ tags.</li>
+ <li>Added -V option to dispcal and dispread to allow use of i1pro
+ adaptive mode to give better low level consistency.</li>
+ <li>Changed dispcal to default to -f 1.0 (assume black is all
+ output offset) to make it work in more sympathy to a typical
+ display response. Also changed default gamma to 2.4 for OS X
+ 10.6 systems.<br>
+ </li>
+ <li>Improved X11 XRandR CRTC detection.</li>
+ <li>Added spotread option to save spectral reading of an
+ illuminant to a .sp file.</li>
+ <li>Added Color Rendering Index (Ra) to spotread measurement
+ results.</li>
+ <li>Added i1pro &amp; ColorMunki flash measurement
+ support.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
+ </li>
+ <li>Improve reliability of detecting backwards read i1pro/Munki
+ strips.</li>
+ <li>Fixed bug in i1pro driver that subtly affected accuracy.</li>
+ <li>Modified xicc/cam02 to clip the blue to avoid crazy behavior
+ outside the spectrum locus.</li>
+ <li>Simplified the Linux installation instructions, particularly
+ with regard to USB and serial permissions.</li>
+ <li>Added working MSWindows 64 bit libusb drivers, which will work
+ on Vista 64 and MSWindows 7 64 bit. Because of Microsoft's
+ driver signing requirements though, they won't be usable unless
+ a driver code signing workaround is used.</li>
+ <li>Changed printtarg so that the TIFF output has the paper margin
+ subtracted from it. This is so that the resulting TIFF can be
+ placed on that sized paper without clipping or scaling. Set the
+ margin to zero to get a TIFF that exactly fits into the
+ specified paper size</li>
+ </ul>
+ <h1>[V1.0.3 -&gt; V1.0.4] 30th June 2009<br>
+ </h1>
+ <ul>
+ <li>Modify icc/icclib to protect against integer overflow
+ exploits, and fixes to minor bugs. Bump icclib version to 2.11
+ to reflect this.<br>
+ </li>
+ <li>Fix bug in spectro/hidio.c that can cause a crash (bus error)
+ on OS X for any program that accesses the instruments.</li>
+ <li>Fix bug in xicc/xfit.c where too little memory was being
+ allocated.<br>
+ </li>
+ </ul>
+ <h1>[V1.0.2 -&gt; V1.0.3] 3rd September 2008<br>
+ </h1>
+ <ul>
+ <li>Added multi-TIFF and popularity filtering to <span
+ style="font-weight: bold;">tiffgamut</span>.<br>
+ </li>
+ <li>Modified gamut mapping in <span style="font-weight: bold;">colprof</span>
+ and <span style="font-weight: bold;">collink</span> to be
+ consistent, and have higher perceptual intent saturation.<br>
+ </li>
+ <li>Fixed timeout problem with the Eye-One Display colorimeter.<br>
+ </li>
+ <li>Fix segmentation fault in <span style="font-weight: bold;">dispread</span>.</li>
<li>Fix out of memory error in <span style="font-weight: bold;">colprof
@@ -1205,20 +1234,23 @@
-
- </span>for systems with &gt; 3Gig Ram.</li>
- <li>Add support for the Eye-One Monitor spectrometer.</li>
- <li>Added -L option to <span style="font-weight: bold;">printtarg</span>
- to suppress the i1pro target holder clip margin.<br>
- </li>
- <li>Fixed bug in <span style="font-weight: bold;">dispcal</span>
- when using -a with -t<br>
- </li>
- </ul>
- <h1>[V1.0.1 -&gt; V1.0.2] 19th August 2008<br>
- </h1>
- Various bug fixes, the main ones being:<br>
- <ul>
+
+
+
+
+ </span>for systems with &gt; 3Gig Ram.</li>
+ <li>Add support for the Eye-One Monitor spectrometer.</li>
+ <li>Added -L option to <span style="font-weight: bold;">printtarg</span>
+ to suppress the i1pro target holder clip margin.<br>
+ </li>
+ <li>Fixed bug in <span style="font-weight: bold;">dispcal</span>
+ when using -a with -t<br>
+ </li>
+ </ul>
+ <h1>[V1.0.1 -&gt; V1.0.2] 19th August 2008<br>
+ </h1>
+ Various bug fixes, the main ones being:<br>
+ <ul>
<li>Fixed some <span style="font-weight: bold;">colprof </span>performance
@@ -1262,74 +1294,77 @@
-
- and memory usage issues.</li>
- <li>Fixed issues with Eye-One Pro Rev B timeouts.</li>
- <li>Added new option to collink -fk, that forces 000K input to K
- only output.</li>
- <li>Added device target value quantization option to <span
- style="font-weight: bold;">printtarg</span>, as well as making
- it default for TIFF output files.put files.</li>
- <li>Fixed leak that was affecting <span style="font-weight:
- bold;">printtarg</span>.<br>
- </li>
- </ul>
- <h1>[V0.70 Beta 8 -&gt; V1.0.0] 1st July 2008<br>
- </h1>
- <br>
- Apart from numerous bug fixes and many minor feature additions and
- improvements, the main changes to this version compared to the
- previous one are:<br>
- <ul>
- <li>Speedup in profile and device link generation (inversion
- code), and better memory usage.<br>
- </li>
- <li>Support for embedded profiles in TIFF files.</li>
- <li>Support for installing and uninstalling and loading of display
- profiles for all operating systems, and a micro CMM system for
- X11/Linux<br>
- </li>
- <li>Improved display calibration and profiling, including ambient
- light adjustment.</li>
- <li>X11 XRandR 1.2 support added.</li>
- <li>Raster test charts now supported, as well as PS and EPS.<br>
- </li>
- <li>Guidance for installing on a wider range of systems.</li>
- <li>Fixed luminance and ambient calibration issues with various
- instruments.</li>
- <li>Renamed "profile" to "colprof", and "icclink" to "collink" to
- avoid clashes that have arisen with other executable names.</li>
- <li>Streamlined source code build system, for much easier
- building.<br>
- </li>
- <li>Installation archives now include a top directory, and
- gzip/tar format for OS X and Linux.</li>
- <li>Added B2A table to input device LUT profiles by default.<br>
- </li>
- </ul>
- As usual, a more detailed description of all changes is in the <b>log.txt</b>
- file that accompanies the source code.
- <h1>[V0.60 -&gt; V0.70 Beta 8]15th January 2008<br>
- </h1>
- <ul>
- <li>Added quick display ICC profile creation as part of
- calibration.</li>
- <li>Added support for the Huey, Spyder 2, DTP20, Eye-One Pro,
- DTP22/Digital Swatchbook, Eye-One Display 1 and 2 instruments.</li>
- <li>Changed to GPL Version 3 license.</li>
- <li>Countless other bug fixes and feature enhancements.<br>
- </li>
- </ul>
- <br>
- <br>
- <br>
- <p><br>
- &nbsp; <br>
- &nbsp; <br>
- &nbsp; <br>
- &nbsp; <br>
- &nbsp; <br>
- &nbsp; </p>
- <br>
- </body>
-</html>
+
+
+
+
+ and memory usage issues.</li>
+ <li>Fixed issues with Eye-One Pro Rev B timeouts.</li>
+ <li>Added new option to collink -fk, that forces 000K input to K
+ only output.</li>
+ <li>Added device target value quantization option to <span
+ style="font-weight: bold;">printtarg</span>, as well as making
+ it default for TIFF output files.put files.</li>
+ <li>Fixed leak that was affecting <span style="font-weight:
+ bold;">printtarg</span>.<br>
+ </li>
+ </ul>
+ <h1>[V0.70 Beta 8 -&gt; V1.0.0] 1st July 2008<br>
+ </h1>
+ <br>
+ Apart from numerous bug fixes and many minor feature additions and
+ improvements, the main changes to this version compared to the
+ previous one are:<br>
+ <ul>
+ <li>Speedup in profile and device link generation (inversion
+ code), and better memory usage.<br>
+ </li>
+ <li>Support for embedded profiles in TIFF files.</li>
+ <li>Support for installing and uninstalling and loading of display
+ profiles for all operating systems, and a micro CMM system for
+ X11/Linux<br>
+ </li>
+ <li>Improved display calibration and profiling, including ambient
+ light adjustment.</li>
+ <li>X11 XRandR 1.2 support added.</li>
+ <li>Raster test charts now supported, as well as PS and EPS.<br>
+ </li>
+ <li>Guidance for installing on a wider range of systems.</li>
+ <li>Fixed luminance and ambient calibration issues with various
+ instruments.</li>
+ <li>Renamed "profile" to "colprof", and "icclink" to "collink" to
+ avoid clashes that have arisen with other executable names.</li>
+ <li>Streamlined source code build system, for much easier
+ building.<br>
+ </li>
+ <li>Installation archives now include a top directory, and
+ gzip/tar format for OS X and Linux.</li>
+ <li>Added B2A table to input device LUT profiles by default.<br>
+ </li>
+ </ul>
+ As usual, a more detailed description of all changes is in the <b>log.txt</b>
+ file that accompanies the source code.
+ <h1>[V0.60 -&gt; V0.70 Beta 8]15th January 2008<br>
+ </h1>
+ <ul>
+ <li>Added quick display ICC profile creation as part of
+ calibration.</li>
+ <li>Added support for the Huey, Spyder 2, DTP20, Eye-One Pro,
+ DTP22/Digital Swatchbook, Eye-One Display 1 and 2 instruments.</li>
+ <li>Changed to GPL Version 3 license.</li>
+ <li>Countless other bug fixes and feature enhancements.<br>
+ </li>
+ </ul>
+ <br>
+ <br>
+ <br>
+ <p><br>
+ &nbsp; <br>
+ &nbsp; <br>
+ &nbsp; <br>
+ &nbsp; <br>
+ &nbsp; <br>
+ &nbsp; </p>
+ <br>
+ </body>
+</html>
diff --git a/doc/XRGA.html b/doc/XRGA.html
index 778b8bd..d0ce315 100755
--- a/doc/XRGA.html
+++ b/doc/XRGA.html
@@ -28,15 +28,16 @@ href="https://www.xrite.com/documents/literature/en/L7-462_XRGA_WhitePaper_en.pd
+
+
is possible</a> between these different standards. While such a
conversion is not perfect, it reduces the discontinuities between
old instrument families and current X-Rite instruments.<br>
<br>
By default, Argyll will use the native calibration of Gretag-Macbeth
and X-Rite instruments. These are summarized here:<br>
- <br>
&nbsp; <br>
- <table border="0" cellpadding="2" cellspacing="2">
+ <table cellspacing="2" cellpadding="2" border="0">
<tbody>
<tr>
<td valign="top"><a href="instruments.html#DTP20">DTP20
@@ -76,7 +77,8 @@ href="https://www.xrite.com/documents/literature/en/L7-462_XRGA_WhitePaper_en.pd
<tr>
<td valign="top"><a href="instruments.html#ColorMunki"><span
style="text-decoration: underline;">ColorMunki</span></a>
- Design or Photo</td>
+ Design, Photo or i1Studio<br>
+ </td>
<td valign="top">XRGA<br>
</td>
</tr>
@@ -137,5 +139,21 @@ href="https://www.xrite.com/documents/literature/en/L7-462_XRGA_WhitePaper_en.pd
You can also convert from one standard to the other using <a
href="spec2cie.html#A">spec2cie</a>.<br>
<br>
+ For informational purposes, the native calibration of some other
+ Gretag-Macbeth and X-Rite instruments are:<br>
+ <br>
+ <table cellspacing="2" cellpadding="2" border="0">
+ <tbody>
+ <tr>
+ <td valign="top">HP Z printer Sensor&nbsp; <br>
+ </td>
+ <td valign="top">GMDI<br>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <br>
+ <br>
+ <br>
</body>
</html>
diff --git a/doc/collink.html b/doc/collink.html
index b746c5d..fbb1aaa 100755
--- a/doc/collink.html
+++ b/doc/collink.html
@@ -18,6 +18,9 @@
inverting the forward profile,&nbsp; to allow black ink regeneration
or to retain the source black characteristic from the source
profile.<br>
+ <br>
+ <small>The <a href="#O">-O</a> option allows creation of a device
+ link that contains just per channel calibration curves.</small>
<h3>Usage Summary</h3>
<span style="font-family: monospace;">collink [-options] <span
style="font-style: italic;">srcprofile dstprofile linkedprofile</span></span><br
@@ -66,6 +69,7 @@
+
Verbose<br>
</span><span style="font-family: monospace;">&nbsp;</span><a
style="font-family: monospace;" href="#A">-A "manufacturer"</a><span
@@ -134,6 +138,7 @@ existing
+
profile, rather than link (Debug option)</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;</span><a
@@ -187,6 +192,7 @@ clut
+
res. set by -q</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;</span><a
style="font-family: monospace;" href="#n">-n</a><span
@@ -234,6 +240,7 @@ preserve
+
device curves in result</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;</span><a
style="font-family: monospace;" href="#f">-f</a><span
@@ -305,13 +312,14 @@ Include
+
abstract profile in link</span><br>
<span style="font-family: monospace;"><span style="font-family:
monospace;">&nbsp;</span><a style="font-family: monospace;"
href="#a">-a file.cal</a><span style="font-family: monospace;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Apply calibration curves</span>
to link output and append linear<br>
- &nbsp;<a href="H">-H file.cal</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ &nbsp;<a href="#H">-H file.cal</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -329,8 +337,11 @@ Include
- Append calibration curves to 3dlut<br style="font-family:
- monospace;">
+
+ Append calibration curves to 3dlut<br>
+ &nbsp;<a href="#O">-O file.cal</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ Use just calibration curves as link and append linear<br
+ style="font-family: monospace;">
</span> <span style="font-family: monospace;">&nbsp;</span><a
style="font-family: monospace;" href="#s">-s</a><span
style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -377,6 +388,7 @@ Mode
+
(default)</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;</span><a
style="font-family: monospace;" href="#g">-g [src.gam]</a><span
@@ -428,6 +440,7 @@ Gamut
+
Mapping Mode using inverse outprofile A2B [optional source gamut]</span><br
style="font-family: monospace;">
<br style="font-family: monospace;">
@@ -483,6 +496,7 @@ s
+
= saturation, a = absolute colorimetric</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;</span><a
@@ -535,6 +549,7 @@ s
+
= saturation, a = absolute colorimetric</span><br
style="font-family: monospace;">
<br style="font-family: monospace;">
@@ -590,6 +605,7 @@ a
+
Absolute Colorimetric (in Jab) [ICC Absolute Colorimetric]<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
aw
@@ -635,6 +651,7 @@ aw
+
Absolute Colorimetric (in Jab) with scaling to fit white point<br
style="font-family: monospace;">
</span><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -681,6 +698,7 @@ aa
+
Absolute Appearance</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
r
@@ -726,6 +744,7 @@ r
+
White Point Matched Appearance [ICC Relative Colorimetric]</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -772,6 +791,7 @@ la
+
Luminance matched Appearance</span><br style="font-family:
monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -818,6 +838,7 @@ p
+
Perceptual (Preferred) [ICC Perceptual]<br>
</span><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pa
@@ -862,11 +883,13 @@ pa
+
- Perceptual Appearance</span><br>
<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+
lp - Luminance Preserving Perceptual</tt><br style="font-family:
monospace;">
<span style="font-family: monospace;"></span><span
@@ -914,6 +937,7 @@ ms
+
Saturation</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
s
@@ -959,6 +983,7 @@ s
+
Enhanced Saturation [ICC Saturation]</span><br style="font-family:
monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -1005,6 +1030,7 @@ al
+
Absolute Colorimetric (Lab)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -1043,6 +1069,7 @@ al
+
rl - White Point Matched Colorimetric (Lab)</span><span
style="font-family: monospace;"></span><br style="font-family:
monospace;">
@@ -1063,6 +1090,7 @@ al
+
Use RGB-&gt;RGB forced black point hack<br style="font-family:
monospace;">
</span> <span style="font-family: monospace;">&nbsp;</span><a
@@ -1113,6 +1141,7 @@ either
+
an enumerated choice, or a parameter</span><br style="font-family:
monospace;">
<span style="font-family: monospace;">&nbsp;</span><a
@@ -1164,14 +1193,17 @@ either
+
an enumerated choice, or a parameter:value change<br>
&nbsp;</span><tt>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </tt><tt><tt>pc
+
- Critical print evaluation environment (ISO-3664 P1)</tt><tt><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+
</tt>pp - Practical Reflection Print (ISO-3664 P2)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
&nbsp; pe - Print evaluation environment (CIE 116-1995)<br>
@@ -1225,6 +1257,7 @@ either
+
mb - Monitor in bright work environment</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; &nbsp;
@@ -1289,6 +1322,7 @@ n
+
= auto, a = average, m = dim, d = dark,</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -1335,6 +1369,7 @@ n
+
c = transparency (default average)</span><br style="font-family:
monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -1381,6 +1416,7 @@ Adapted
+
white point as XYZ (default media white)</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -1427,6 +1463,7 @@ Adapted
+
white point as x, y</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
a:adaptation&nbsp;
@@ -1472,6 +1509,7 @@ Adaptatation
+
luminance in cd.m^2 (default 50.0)</span><br style="font-family:
monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -1519,6 +1557,7 @@ Background
+
of image luminance (default 20)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; l:imagewhite&nbsp;
Image white in cd.m^2 if surround = auto (default 250)</span><br
@@ -1569,9 +1608,11 @@ light
+
% of image luminance (default 0)<br>
</span>&nbsp;</span><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+
g:glare&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Glare light % of
ambient (default 5)</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -1605,6 +1646,7 @@ light
+
g:X:Y:Z&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Glare color as XYZ
(default media white)</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -1638,6 +1680,7 @@ light
+
g:x:y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Glare color
as x, y</span><br style="font-family: monospace;">
<tt><span style="font-family: monospace;"><tt><span
@@ -1649,11 +1692,13 @@ light
+
m:mtaf&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mid-tone
partial adaptation factor (default 0.0)</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+
m:X:Y:Z&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mid-tone
Adaptation white as XYZ (default D50)</span><br
style="font-family: monospace;">
@@ -1707,6 +1752,7 @@ source
+
total ink limit, 0 - 400% (estimate by default)</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;</span><a
@@ -1755,6 +1801,7 @@ source
+
total ink limit, 0 - 100% (estimate by default)</span><br
style="font-family: monospace;">
<br style="font-family: monospace;">
@@ -1810,6 +1857,7 @@ t
+
= transfer K from source to destination, e = retain K of
destination B2A table</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -1856,6 +1904,7 @@ z
+
= zero K, h = 0.5 K, x = maximum K, r = ramp K (default)</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;</span><a
@@ -1905,6 +1954,7 @@ p
+
= black level generation curve parameters</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;</span><a
@@ -1955,6 +2005,7 @@ q
+
= transfer source K to dual curve limits</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;</span><a
@@ -2008,6 +2059,7 @@ destination
+
total ink limit, 0 - 400% (estimate by default)</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;</span><a
@@ -2056,6 +2108,7 @@ destination
+
total ink limit, 0 - 100% (estimate by default)<br>
&nbsp;<a href="#3">-3 flag</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -2093,6 +2146,7 @@ destination
+
Create "3DLut" output file as well as devlink<br>
&nbsp;&nbsp;&nbsp;&nbsp;
e&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -2131,6 +2185,7 @@ destination
+
eeColor .txt file</span><br>
<tt>&nbsp;&nbsp;&nbsp;&nbsp;
m&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -2157,11 +2212,13 @@ destination
+
MadVR .3dlut&nbsp;&nbsp; file<br>
&nbsp;&nbsp;&nbsp;&nbsp;
c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+
IRIDAS .cube file<br>
</tt> <tt>&nbsp;<a href="#Ib">-I B</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -2177,6 +2234,7 @@ destination
+
Use BT.1886 source EOTF with technical gamma 2.4</tt><tt><br>
</tt><tt>&nbsp;<a href="#Ib">-I b:g.g</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Use
@@ -2227,6 +2285,7 @@ destination
+
Video encode input as:<br>
&nbsp;<a href="#E">-E flag</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -2264,6 +2323,7 @@ destination
+
Video encode output as:</span><span style="font-family:
monospace;"><span style="font-family: monospace;"><br>
&nbsp;&nbsp;&nbsp;&nbsp;
@@ -2292,6 +2352,7 @@ destination
+
normal RGB 0..1 levels (default)<br>
&nbsp;&nbsp;&nbsp;&nbsp;
t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -2319,6 +2380,7 @@ destination
+
RGB (16-235)/255 "TV" levels</span></span><br>
<span style="font-family: monospace;"><span style="font-family:
monospace;"><span style="font-family: monospace;"><span
@@ -2348,6 +2410,7 @@ destination
+
RGB (16-235)/255 "TV" levels, clip WTW [Input Only]</span></span><br>
&nbsp;&nbsp;&nbsp;&nbsp;
6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -2375,6 +2438,7 @@ destination
+
Rec601 YCbCr SD (16-235,240)/255 "TV" levels<br>
&nbsp;&nbsp;&nbsp;&nbsp;
7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -2402,6 +2466,7 @@ destination
+
Rec709 1125/60Hz YCbCr HD (16-235,240)/255 "TV" levels<br>
&nbsp;&nbsp;&nbsp;&nbsp;
5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -2429,6 +2494,7 @@ destination
+
Rec709 1250/50Hz YCbCr HD (16-235,240)/255 "TV" levels<br>
&nbsp;&nbsp;&nbsp;&nbsp;
2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -2456,6 +2522,7 @@ destination
+
Rec2020 YCbCr UHD (16-235,240)/255 "TV" levels<br>
&nbsp;&nbsp;&nbsp;&nbsp;
C&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -2483,6 +2550,7 @@ destination
+
Rec2020 Constant Luminance YCbCr UHD (16-235,240)/255 "TV"
levels<br>
&nbsp;&nbsp;&nbsp;&nbsp;
@@ -2511,6 +2579,7 @@ destination
+
xvYCC Rec601 YCbCr Rec709 Prims. SD (16-235,240)/255 "TV" levels<br>
&nbsp;&nbsp;&nbsp;&nbsp;
X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -2538,6 +2607,7 @@ destination
+
xvYCC Rec709 YCbCr Rec709 Prims. HD (16-235,240)/255 "TV" levels<br>
</span>&nbsp;</span>&nbsp; <span style="font-family: monospace;"><a
href="#P">-P</a>
@@ -2585,6 +2655,7 @@ gamut
+
gammap_p.x3d.html and gammap_s.x3d.html diagostics</span><br>
<span style="font-family: monospace;"></span><span
style="font-family: monospace;">&nbsp;<span
@@ -2635,6 +2706,7 @@ ICC
+
profile. A </span><span style="font-family: monospace;">TIFF or
JPEG file with embedded profile may be used here.</span><br
style="font-family: monospace;">
@@ -2686,6 +2758,7 @@ ICC
+
profile. </span><span style="font-family: monospace;">A </span><span
style="font-family: monospace;">TIFF or JPEG file with embedded
profile may be used here.</span><br style="font-family:
@@ -2797,6 +2870,7 @@ ICC
+
&nbsp;Override clut res. set by <b>-q</b><br>
<br>
This sets the basic quality of the resulting link, by choosing the
@@ -2895,6 +2969,13 @@ ICC
3dLut is used by MadVR v0.86.9 or latter. By default no calibration
curves are appended to a MadVR 3dLut.<br>
<br>
+ <a name="O"></a> The <b>-O</b> parameter causes calibration curves
+ in the supplied file to be use to creat the link. ICC profiles are
+ not expectedt or used. This option allows a device link to be used
+ to apply just per channel calibraion curves. Note that many normal
+ options will be ignored or may cause unexpected results when used
+ with this option.<br>
+ <br>
The basic linking style is chosen by using the <b>-s</b> (default),
<b>-g</b> or <b>-G</b> flags. The three behaviors are:<br>
<br>
@@ -2996,6 +3077,7 @@ ICC
+
&nbsp;<b>p</b> = perceptual, <b>r</b> = relative colorimetric,<br>
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <b>s</b>
@@ -3270,6 +3352,7 @@ ICC
+
&nbsp; &nbsp;_______&nbsp; enle<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -3315,6 +3398,7 @@ ICC
+
&nbsp; &nbsp;/<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
|&nbsp;&nbsp;&nbsp;&nbsp;
@@ -3360,6 +3444,7 @@ ICC
+
&nbsp; /<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -3405,6 +3490,7 @@ ICC
+
&nbsp;/<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -3450,6 +3536,7 @@ ICC
+
/<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
stle&nbsp; | ------/<br>
@@ -3501,6 +3588,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
Black<br>
<br>
</tt>For minimum sensitivity of printed output to the lighting
@@ -3704,6 +3792,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
</b>Full output offset with effective gamma of 2.2<b><br>
</b><b></b><b>-I B</b><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -3719,6 +3808,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
</b>Full input offset (BT.1886 like) with technical gamma of 2.4.
This exactly implements the BT.1886 specification.<b><br>
</b><b>-I G</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -3735,6 +3825,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
Full output offset with technical gamma of 2.2<br>
<br>
<b>-I b</b><b>:2.3</b><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -3751,6 +3842,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
</b>Full input offset (BT.1886 like) with effective gamma of 2.3<b>
<br>
</b><b> -I g:2.3</b><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -3767,6 +3859,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
</b>Full output offset with effective gamma of 2.3<b><br>
</b><b> -I B:2.35</b><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -3782,6 +3875,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
</b>Full input offset (BT.1886 like) with technical gamma of 2.35<br>
<b> -I G:2.35</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -3797,6 +3891,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
Full output offset with technical gamma of 2.35<br>
<br>
<b>-I b</b><b>:0.4:2.3</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -3815,6 +3910,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
Same as above.<b><br>
</b><b> -I B:0.4:2.35</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 60% input
offset, 40% output offset with technical gamma of 2.35 <b><br>
@@ -3838,6 +3934,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
T
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -3864,6 +3961,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
RGB (16-235)/255 "TV" levels, clip WTW
[Input Only]<br>
</span></small></span></small></span></small></span></small>&nbsp;&nbsp;&nbsp;&nbsp;
@@ -3874,6 +3972,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
x&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -3899,6 +3998,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
xvYCC Rec601 YCbCr Rec709 Prims. SD (16-235,240)/255 "TV"
levels<br>
&nbsp;&nbsp;&nbsp;&nbsp;
@@ -3927,6 +4027,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
xvYCC Rec709 YCbCr Rec709 Prims. HD (16-235,240)/255 "TV"
levels</span></small></span></small><br>
<br>
@@ -3977,6 +4078,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
normal RGB 0..1 full range levels (default)<br>
&nbsp;&nbsp;&nbsp;&nbsp;
t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -4004,6 +4106,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
RGB (16-235)/255 "TV" levels</span></small></span></small><small><span
style="font-family: monospace;"><small><span style="font-family:
monospace;"></span></small></span></small><br>
@@ -4017,6 +4120,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -4042,6 +4146,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
Rec601 YCbCr SD (16-235,240)/255 "TV" levels<br>
&nbsp;&nbsp;&nbsp;&nbsp;
7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -4069,6 +4174,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
Rec709 1125/60Hz YCbCr HD (16-235,240)/255 "TV" levels<br>
&nbsp;&nbsp;&nbsp;&nbsp;
5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -4096,6 +4202,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
Rec709 1250/50Hz YCbCr HD (16-235,240)/255 "TV" levels<br>
&nbsp;&nbsp;&nbsp;&nbsp;
2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -4123,6 +4230,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
Rec2020 YCbCr UHD (16-235,240)/255 "TV" levels<br>
&nbsp;&nbsp;&nbsp;&nbsp;
C&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -4150,6 +4258,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
Rec2020 Constant Luminance YCbCr UHD (16-235,240)/255 "TV"
levels</span></small></span></small><br>
<small><span style="font-family: monospace;"><small><span
@@ -4165,15 +4274,17 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
<a href="File_Formats.html#X3DOM">X3DOM</a> plots to be created that
illustrate the gamut mapping generated.<br>
<br>
- <a name="p1"></a>The <i><b>inprofile</b></i> argument specifies the
- source profile. This is the color space/device we are attempting to
- emulate in the overall conversion. A <small>TIFF or JPEG file with
- embedded profile may be used here.</small><br>
+ <a name="p1"></a>The <i><b>srcprofile</b></i> argument specifies
+ the source profile. This is the color space/device we are attempting
+ to emulate in the overall conversion. A <small>TIFF or JPEG file
+ with embedded profile may be used here. This argument must be
+ omitted if the <a href="#O">-O</a> option is used.</small><br>
<br>
- <a name="p2"></a>The<i><b> outprofile</b></i> argument specifies the
+ <a name="p2"></a>The<i><b> dstprofile</b></i> argument specifies the
destination profile. This is the device we are actually displaying
on or printing to. A <small>TIFF or JPEG file with embedded profile
- may be used here.</small><br>
+ may be used here. </small><small>This argument must be omitted if
+ the <a href="#O">-O</a> option is used.</small><br>
<br>
<a name="p3"></a>The <i><b>linkedprofile</b></i> argument specifies
the resulting device link profile. This profile will contain the
@@ -4221,6 +4332,7 @@ White&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb
+
Usage Scenarios</a> page.<br>
<h3>Discussion</h3>
The viewing condition parameter <b>m:</b> is a hack, intended to
diff --git a/doc/instruments.html b/doc/instruments.html
index 283755a..eea6fc5 100755
--- a/doc/instruments.html
+++ b/doc/instruments.html
@@ -64,6 +64,9 @@
+
+
+
- Tele-Spectro-Radiometer<br>
&nbsp;&nbsp;&nbsp; <a href="#spectraval">spectraval 1511&amp; 1501</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -75,6 +78,9 @@
+
+
+
&nbsp;&nbsp; - Tele-Spectro-Radiometer<br>
<br>
@@ -150,6 +156,9 @@
+
+
+
- Tele-Spectro-Radiometer<br>
<br>
@@ -227,6 +236,9 @@
+
+
+
- "swipe" type reflective spectrometer, that can be used untethered.<br>
&nbsp;&nbsp;&nbsp; <a href="#DTP22">DTP22 Digital Swatchbook</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -292,6 +304,9 @@
+
+
+
- spot type reflective spectrometer.<br>
&nbsp;&nbsp;&nbsp; <a href="#DTP41">DTP41</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -357,6 +372,9 @@
+
+
+
- spot and strip reading reflective spectrometer.<br>
&nbsp;&nbsp;&nbsp; <a href="#DTP41">DTP41T</a> &nbsp; &nbsp; &nbsp;
@@ -424,6 +442,9 @@
+
+
+
- spot and strip reading reflective/transmissive spectrometer.<br>
&nbsp;&nbsp;&nbsp; <a href="#dtp51">DTP51</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -489,6 +510,9 @@
+
+
+
- strip reading reflective colorimeter.<br>
&nbsp;&nbsp;&nbsp; <a href="#DTP92">DTP92</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -554,6 +578,9 @@
+
+
+
- CRT display colorimeter.<br>
&nbsp;&nbsp;&nbsp; <a href="#DTP94">DTP94</a> <font size="-1">"Optix
@@ -619,6 +646,9 @@
+
+
+
XR"</font> or "Optix XR2" or "Optix Pro"- display colorimeter.<br>
<a href="#ColorMunki"><span style="text-decoration: underline;"></span></a>&nbsp;&nbsp;&nbsp;
@@ -684,15 +714,22 @@
+
+
+
<a href="#ColorMunki"><span style="text-decoration: underline;">ColorMunki</span></a>
- Design or Photo&nbsp;
+ Design or Photo or i1Studio<br>
+ &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
+ &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - spot and "swipe"
reflective/emissive spectrometer (UV cut only).<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-
- - The i1 Studio version of this instrument is also reported to work.<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+
+
+
[ The OEM&nbsp; XEROX PhaserMeter is also reported to work. ] <br>
&nbsp;&nbsp;&nbsp; <a href="#i1d"><span style="text-decoration:
@@ -715,8 +752,8 @@
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
- &nbsp; &nbsp; &nbsp;&nbsp; Quato Silver Haze 3 OEM and HP
- DreamColor&nbsp; i1d3 are also reported to work.]<br>
+ &nbsp; &nbsp; &nbsp;&nbsp; Quato Silver Haze 3 OEM, HP DreamColor
+ &amp; Wacom i1d3 are also reported to work.]<br>
&nbsp; &nbsp; <a href="instruments.html#i1p2">Eye-One Pro2</a>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp; - spot and
@@ -809,6 +846,9 @@
+
+
+
- display colorimeter. (Treated as a Eye-One Display 2)<br>
&nbsp;&nbsp;&nbsp; <a href="#i1d">CalMAN X2</a>
@@ -875,6 +915,9 @@
+
+
+
- display colorimeter. (Treated as a Eye-One Display 2)<br>
&nbsp;&nbsp;&nbsp; <a href="#Huey">Huey</a> &nbsp; &nbsp; &nbsp;
@@ -950,6 +993,9 @@
+
+
+
[The Sequel Chroma 4 &amp; 5, and Sencore ColorPro V, IV &amp; III
also work.]<br>
@@ -1018,6 +1064,9 @@
+
+
+
- see <a href="#i1d">Eye-One Display</a><br>
<br>
@@ -1090,6 +1139,9 @@
+
+
+
[The Spyder 1 also seems to work.]<br>
&nbsp;&nbsp;&nbsp;&nbsp; <a href="#spyd3">Spyder 3</a> &nbsp;
@@ -1174,6 +1226,9 @@
+
+
+
- display colorimeter<br>
</span>&nbsp;&nbsp;&nbsp; <a href="#ColorHug">ColorHug</a> &amp;
@@ -1231,6 +1286,9 @@
+
+
+
- display colorimeter<span class="titre"></span><br>
&nbsp;&nbsp;&nbsp; <a href="#SMCube">Palette/SwatchMate Cube</a>
@@ -1573,6 +1631,9 @@
+
+
+
type</span> selection parameter. Depending on the instrument, this
may combine two related functions: 1) Changing the measurement mode
@@ -1743,6 +1804,9 @@
+
+
+
instructions</a>.<br>
<br>
@@ -1784,6 +1848,9 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e
+
+
+
Engineering EX1</a> is a currently available instruments. This is
a high resolution spectrometer intended for the measurement of light
@@ -1828,6 +1895,9 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e
+
+
+
<a href="http://www.kleininstruments.com/">Klein Instruments</a>&nbsp;
@@ -1858,6 +1928,9 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e
+
+
+
is a currently available instrument. It is noted for it's speed,
high precision, and ability to measure to very low light
@@ -1925,6 +1998,9 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e
There are some OEM versions of this instrument around too, and
the&nbsp;<a href="http://www.office.xerox.com/latest/78XDS-03U.PDF">XEROX
+
+
+
PhaserMeter</a> instruments (part of the Xerox PhaserMatch 5.0
package) are also reported to work.<br>
@@ -1974,8 +2050,7 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e
<br>
<b>Native Calibration Standard:</b><br>
<br>
- Reflection measurements are natively X-Rite <a
- href="http://www.xrite.com/xrite-graphic-arts-standard">XRGA</a>.<br>
+ Reflection measurements are natively X-Rite <a href="XRGA.html">XRGA</a>.<br>
<span style="font-weight: bold;"></span><br>
<span style="font-weight: bold;"><span style="font-weight: bold;"></span></span><span
style="font-weight: bold;"></span><br>
@@ -2230,6 +2305,9 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e
+
+
+
CRT display&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; A Cathode Ray
Tube display, that is of the Refresh type [Default, CB2].<br>
@@ -2315,6 +2393,9 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e
+
+
+
LCD display&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; A Liquid
Crystal Display, that is of the Non-Refresh type [default, CB1].<br>
@@ -2381,6 +2462,9 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e
+
+
+
CRT display&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; A Cathode Ray
Tube display, that is of the Refresh type [CB2].<br>
@@ -2463,6 +2547,9 @@ Gretag
+
+
+
MacBeth (Now X-Rite) is a discontinued instrument. It is often
available second hand. If buying it second hand, make sure it comes
@@ -2520,6 +2607,9 @@ Gretag
+
+
+
Eye-One Pro Rev E) from&nbsp;<a
href="http://www.kleininstruments.com/"></a> <a
@@ -2539,6 +2629,9 @@ href="http://www.xrite.com/categories/calibration-profiling/i1basic-pro-2">i1
+
+
+
Basic Pro 2</a>.<br>
<br>
@@ -2555,6 +2648,9 @@ href="http://www.xrite.com/categories/calibration-profiling/i1basic-pro-2">i1
+
+
+
Pro reflective/emissive spectrometer</a><span style="font-weight:
bold;"> </span>below for details on the operation of this type of
@@ -2562,8 +2658,7 @@ href="http://www.xrite.com/categories/calibration-profiling/i1basic-pro-2">i1
<br>
<b>Native Calibration Standard:</b><br>
<br>
- Reflection measurements are natively X-Rite <a
- href="http://www.xrite.com/xrite-graphic-arts-standard">XRGA</a>.<span
+ Reflection measurements are natively X-Rite <a href="XRGA.html">XRGA</a>.<span
style="font-weight: bold;"></span><br>
<br>
<hr style="width: 100%; height: 2px;"><br>
@@ -2632,9 +2727,7 @@ href="http://www.xrite.com/categories/calibration-profiling/i1basic-pro-2">i1
<br>
Reflection measurements are natively historical Gretag MacBeth
standard (GMDI) for RevA-D,<br>
- and&nbsp; natively X-Rite <a
- href="http://www.xrite.com/xrite-graphic-arts-standard">XRGA</a>
- for Rev E.<br>
+ and&nbsp; natively X-Rite <a href="XRGA.html">XRGA</a> for Rev E.<br>
<br>
<span style="font-weight: bold;">Special features:</span><br>
<br>
@@ -2785,6 +2878,9 @@ href="http://www.xrite.com/categories/calibration-profiling/i1basic-pro-2">i1
+
+
+
Smile</span> are:<br>
<br>
@@ -2838,6 +2934,9 @@ href="http://www.xrite.com/categories/calibration-profiling/i1basic-pro-2">i1
+
+
+
LCD with LED back-light&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A Liquid Crystal display that uses
@@ -2908,6 +3007,9 @@ href="http://www.xrite.com/categories/calibration-profiling/i1basic-pro-2">i1
+
+
+
LCD display&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; A Liquid
Crystal Display, that is of the Non-Refresh type. [Default, CB1]<br>
@@ -2974,6 +3076,9 @@ href="http://www.xrite.com/categories/calibration-profiling/i1basic-pro-2">i1
+
+
+
CRT display&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A
Cathode Ray Tube display, that is of the Refresh type. [CB2]<br>
@@ -3025,7 +3130,7 @@ href="http://xritephoto.com/ph_product_overview.aspx?id=1454&amp;catid=109">pack
href="http://www.spectracal.com/">SpectraCal OEM i1Display</a>, <a
href="http://www.chromapure.com/">ChromaPure</a>, <a
href="http://www.necdisplay.com/p/sensors/mdsvsensor3">NEC
- SpectraSensor Pro</a> and <a
+ SpectraSensor Pro</a>, <a
href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
@@ -3062,8 +3167,14 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
+
+ DreamColor</a> and <a
+href="https://us-store.wacom.com/Catalog/Accessories/wacom-color-manager">Wacom
- DreamColor</a> instruments are also reported to work. They will
+ Color Manager</a> instruments are also reported to work. They will
appear as a be a the same as the i1Display Pro.<br>
<span style="font-weight: bold;">[Note</span> that if you have an
OEM version of this instrument, it's worth checking if they come
@@ -3148,6 +3259,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
Pro</b> are discontinued instruments. They may still be available
as old stock, or second hand. <br>
@@ -3219,6 +3333,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
LCD display&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; A Liquid
Crystal Display, that is of the Non-Refresh type. [Default, CB1]<br>
@@ -3285,6 +3402,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
CRT display&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; A Cathode Ray
Tube display, that is of the Refresh type. [CB2]<br>
@@ -3376,6 +3496,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
CRT display&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; A Cathode Ray
Tube display, that is of the Refresh type.<br>
@@ -3442,6 +3565,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
LCD display&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; A Liquid
Crystal Display or alternate Calibration, that is of the Non-Refresh
@@ -3542,6 +3668,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
LCD display&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; A Liquid Crystal
Display, that is of the Non-Refresh type. [Default, CB1]<br>
@@ -3608,6 +3737,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
CRT display&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; A Cathode Ray
Tube display, that is of the Refresh type. [CB2]<br>
@@ -3799,6 +3931,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
- normal gamut Liquid Crystal Display with standard Cold Cathode
Fluorescent Lamp backlight.<br>
@@ -3874,6 +4009,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; Wide Gamut LCD, RGB LED
Backlight - wide gamut Liquid Crystal Display with RGB LED
@@ -3944,6 +4082,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
- normal gamut Liquid Crystal Display with alternative Cold Cathode
Fluorescent Lamp backlight (Laptop ?)<br>
@@ -4083,6 +4224,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
- normal gamut Liquid Crystal Display with standard Cold Cathode
Fluorescent Lamp backlight.<br>
@@ -4158,6 +4302,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; Wide Gamut LCD, RGB LED
Backlight - wide gamut Liquid Crystal Display with RGB LED
@@ -4228,6 +4375,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
- normal gamut Liquid Crystal Display with alternative Cold Cathode
Fluorescent Lamp backlight (Laptop ?)<br>
@@ -4308,6 +4458,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
HCFR Probe</span> is a kit instrument from <span
style="font-weight: bold;"></span> <a
@@ -4392,6 +4545,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
LCD display&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; A Liquid
Crystal Display [Default].<br>
@@ -4458,6 +4614,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
CRT display&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; A Cathode Ray
Tube display.<br>
@@ -4524,6 +4683,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
LCD, CCFL Backlight [Default]<br>
&nbsp;&nbsp; <b>c</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -4560,6 +4722,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
CRT display<br>
&nbsp;&nbsp; <b>p</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -4596,6 +4761,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
Projector<br>
&nbsp;&nbsp; <b>e</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -4631,6 +4799,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
LCD, White LED Backlight<br>
&nbsp;&nbsp; <b>F</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -4667,6 +4838,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
Factory matrix (For Calibration) [CB1]<br>
&nbsp;&nbsp;<b> R</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -4703,6 +4877,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
Raw Reading (For Factory matrix Calibration) [CB2]<br>
<br>
@@ -4726,6 +4903,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
Cube<br>
<br>
@@ -4767,6 +4947,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
Matt surfaces [Default]<br>
&nbsp;&nbsp; <b>g</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -4803,6 +4986,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
Gloss surfaces<br>
&nbsp;&nbsp; <b>N</b>
@@ -4828,6 +5014,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP
+
+
+
Native Calibration<br>
<br>
diff --git a/doc/profcheck.html b/doc/profcheck.html
index 0676c14..6dfa27d 100755
--- a/doc/profcheck.html
+++ b/doc/profcheck.html
@@ -33,6 +33,7 @@ Show
+
CIE94 delta E values</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;-k
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -49,6 +50,7 @@ create
+
X3DOM visualization (iccprofile.x3d.html)</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;-x&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -62,6 +64,7 @@ Use
+
X3DOM axes<br>
&nbsp;-m&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Make
@@ -74,6 +77,7 @@ X3DOM
+
lines a minimum of 0.5<br style="font-family: monospace;">
</span><span style="font-family: monospace;">&nbsp;-e&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Color
@@ -86,11 +90,13 @@ vectors
+
acording to delta E<br>
&nbsp;-s&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+
Sort output by delta E<br>
&nbsp;-h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -100,6 +106,7 @@ vectors
+
Plot a histogram of delta E's<br>
&nbsp;-P
de&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -118,6 +125,7 @@ Specify
+
a device value to sort against</span><br style="font-family:
monospace;">
<span style="font-family: monospace;">&nbsp;-p&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -131,6 +139,7 @@ Sort
+
device value by PCS/Lab target</span><br style="font-family:
monospace;">
&nbsp; <span style="font-family: monospace;">-f
@@ -145,6 +154,7 @@ Sort
+
M0, M1, M2, A, C, D50 (def.), D50M2, D65, F5, F8, F10 or
file.sp]<br>
&nbsp;-i illum&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Choose
@@ -159,6 +169,7 @@ Sort
+
A, C, D50 (def.), D50M2, D65, F5, F8, F10 or file.sp</span><span
style="font-family: monospace;"></span><br style="font-family:
monospace;">
@@ -175,11 +186,13 @@ Sort
+
1931_2 </span></small><small><span style="font-family:
monospace;">(def.)</span></small><small><span
style="font-family: monospace;">, 1964_10, </span></small><small><span
style="font-family: monospace;"><tt><small>2012_2, 2012_10, </small></tt>S&amp;B
+
1955_2, shaw, J&amp;V 1978_2</span></small><small><span
style="font-family: monospace;"> or file.cmf<br>
&nbsp;-I intent&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r = relative
@@ -217,6 +230,7 @@ Sort
Device values </i><b>-&gt;</b><i> Profile PCS values </i><b>should
+
be</b><i> .ti3 PCS values</i><br>
<br>
The <b>-c</b> option causes the differences between the test values
@@ -264,7 +278,7 @@ Sort
is appropriate if a profcheck -h on the resulting profile no longer
has a long tail. <b>Note</b> that using this procedure will be of
no benefit if the tail is due to an inherently poor fit of the
- profile to the data rather than reading innacuracy, even if it makes
+ profile to the data rather than reading inaccuracy, even if it makes
the fit appear to be better.<br>
<br>
<b>NOTE</b> that the pruning does not take any special care as to
diff --git a/doc/spec2cie.html b/doc/spec2cie.html
index d973289..4554531 100755
--- a/doc/spec2cie.html
+++ b/doc/spec2cie.html
@@ -22,6 +22,7 @@
+
<span style="font-weight: bold;">EMISINPUT</span> (See the <a
href="ti3_format.html">description of the .ti3 format</a>. This
would have to be done manually, as no ArgyllCMS tools generate such
@@ -38,12 +39,14 @@
+
output.[ti3|sp]<br>
&nbsp;</span></small></tt><tt><small>-v
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+
Verbose mode<br>
&nbsp;<a href="A">-A NN|AX|AG|XA|XG|GA|GX</a>&nbsp;&nbsp; XRGA
conversion (default NN)<br>
@@ -58,10 +61,12 @@
+
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+
Override actual instrument illuminant in .ti3 or .sp file:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
@@ -70,6 +75,7 @@
+
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; (only used in conjunction
with <span style="font-weight: bold;">-f</span>)<br>
</small></small></tt><tt><small><small>&nbsp;<a href="#f">-f [<i>illum</i>]</a>
@@ -77,23 +83,27 @@
+
Use Fluorescent Whitening Agent compensation [simulated inst.
illum.:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+
&nbsp; &nbsp; &nbsp; &nbsp; M0, M1, M2, A, C, D50 (def.),
D50M2, D65, F5, F8, F10 or file.sp]<br>
</small></small></tt><tt><small><small><small>&nbsp;<a href="#i">-i
+
<i>illum</i></a>&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+
Choose illuminant for computation of CIE XYZ from spectral
data &amp; FWA:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -110,10 +120,12 @@
+
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+
&nbsp; Choose CIE Observer for spectral data:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;
@@ -121,10 +133,12 @@
+
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; 1931_2 </small></tt><tt><small>
(def.)</small></tt><tt><small>, 1964_10, </small></tt><tt><small><tt><small>2012_2,
+
2012_10, </small></tt>S&amp;B 1955_2, shaw, J&amp;V 1978_2
or file.cmf<br>
&nbsp;<a href="#p">-n</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -140,6 +154,7 @@ output
+
spectral values<br>
</small></tt><tt><small>&nbsp;<a href="#p">-p</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -148,6 +163,7 @@ output
+
Plot each values spectrum</small></tt><tt><br>
</tt><tt> </tt><tt><small>&nbsp;<span style="font-style: italic;">input.[ti3|sp]</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -239,6 +255,7 @@ output
+
<a href="colprof.html#f">colprof -f</a> for a fuller explanation. <br>
<br>
<a name="i"></a>The <b>-i</b> parameter allows specifying a
@@ -281,6 +298,13 @@ output
should generally be linked with other profiles that have the same
illuminant and observer.<br>
<br>
+ If a non D50 illuminant is used, then an extra set of L*a*b* output
+ fields will be created in the resulting CGATS file, containing
+ values relative to the illuminant white point. These will be
+ labelled XXXLAB_L etc, where XXX is the name of the illuminant.
+ These are informational only, and are not used by any ArgyllCMS
+ tools.<br>
+ <br>
<a name="o"></a> The <b>-o</b> flag allows specifying a tristimulus
observer, and is used to compute PCS (Profile Connection Space)
tristimulus values. The following choices are available:<br>
diff --git a/doc/spotread.html b/doc/spotread.html
index 143b61e..6f09669 100755
--- a/doc/spotread.html
+++ b/doc/spotread.html
@@ -61,6 +61,7 @@
+
&nbsp; &nbsp; &nbsp; Verbose mode</span><br style="font-family:
monospace;">
<span style="font-family: monospace;"></span><span
@@ -108,6 +109,7 @@
+
&nbsp; &nbsp; &nbsp; Print spectrum for each reading.</span></small><br
style="font-family: monospace;">
<small><span style="font-family: monospace;"></span><span
@@ -160,6 +162,7 @@
+
Set COM port, 1..4 (default 1)</span><span style="font-family:
monospace;"></span><span style="font-family: monospace;"><br
style="font-family: monospace;">
@@ -206,6 +209,7 @@
+
&nbsp; &nbsp; &nbsp; Use transmission measurement mode</span><br
style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;</span><a style="
@@ -252,6 +256,7 @@
+
Use emissive measurement mode (absolute results)<br>
</span></small><small><span style="font-family: monospace;">&nbsp;</span><a
style=" font-family: monospace;" href="#eb">-eb</a><span
@@ -297,6 +302,7 @@
+
Use display white brightness relative measurement mode<br>
</span></small><small><span style="font-family: monospace;">&nbsp;</span><a
style=" font-family: monospace;" href="#ew">-ew</a><span
@@ -325,6 +331,7 @@
+
Use display white point relative chromatically adjusted mode<br>
</span></small><small><span style="font-family: monospace;">&nbsp;</span><a
style=" font-family: monospace;" href="#p">-p</a><span
@@ -370,6 +377,7 @@
+
Use telephoto measurement mode (absolute results)<br>
</span></small><small><span style="font-family: monospace;">&nbsp;</span><a
style=" font-family: monospace;" href="#pb">-pb</a><span
@@ -415,6 +423,7 @@
+
Use </span></small><small><span style="font-family: monospace;">projector</span></small><small><span
style="font-family: monospace;"> white brightness relative
measurement mode<br>
@@ -462,6 +471,7 @@
+
Use </span></small><small><span style="font-family: monospace;">projector</span></small><small><span
style="font-family: monospace;"> </span></small><small><span
style="font-family: monospace;">white point relative
@@ -510,6 +520,7 @@
+
Use ambient measurement mode (absolute results)<br>
&nbsp;<a href="#f">-f</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -552,6 +563,7 @@
+
Use ambient flash measurement mode (absolute results)<br>
</span></small><font size="-1"><span style="font-family:
monospace;">&nbsp;<a href="#y">-y X</a>
@@ -596,6 +608,7 @@
+
Display type - instrument specific list to choose from.</span></font><br>
<small><span style="font-family: monospace;">&nbsp;</span><a
style="font-family: monospace;" href="spotread.html#I">-I illum</a><span
@@ -638,6 +651,7 @@ M0,
+
M1, M2, A, D50 (def.), D50M2, D65, F5, F8, F10 or file.sp</span></small><br
style="font-family: monospace;">
<small><span style="font-family: monospace;"></span><span
@@ -697,6 +711,7 @@ D50
+
D50M2, D65, F5, F8, F10 or file.sp</span><br style="font-family:
monospace;">
<span style="font-family: monospace;">&nbsp;</span><a style="
@@ -746,12 +761,14 @@ D50
+
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; </span></small><small><span
style="font-family: monospace;">1931_2 </span></small><small><span
style="font-family: monospace;"> (def.)</span></small><small><span
style="font-family: monospace;">, 1964_10, </span></small><small><span
style="font-family: monospace;"><tt><small>2012_2, 2012_10, </small></tt>S&amp;B
+
1955_2, shaw, J&amp;V 1978_2</span></small><small><span
style="font-family: monospace;"></span></small><font size="-1"><span
style="font-family: monospace;"> or file.cmf<br>
@@ -796,6 +813,7 @@ D50
+
Set filter configuration:<br>
&nbsp;&nbsp;
n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -839,6 +857,7 @@ D50
+
None<br>
&nbsp;&nbsp;
p&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -882,6 +901,7 @@ D50
+
Polarising filter<br>
&nbsp;&nbsp;
6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -925,6 +945,7 @@ D50
+
D65<br>
&nbsp;&nbsp;
u&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -968,6 +989,7 @@ D50
+
U.V. Cut<br>
&nbsp;<a href="#E">-E extrafilterfile</a>&nbsp;&nbsp;&nbsp;
Apply extra filter compensation file<br>
@@ -984,7 +1006,10 @@ D50
+
XRGA conversion (default N)<br>
+ &nbsp;<a href="#w">-w</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ Use -i param. illuminant for comuting L*a*b*<br>
</span></font><font size="-1"><span style="font-family:
monospace;">&nbsp;<a href="#x">-x</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -1028,6 +1053,7 @@ D50
+
Display Yxy instead of Lab<br>
</span></font><font size="-1"><span style="font-family:
monospace;">&nbsp;<a href="#h">-h</a>
@@ -1072,6 +1098,7 @@ D50
+
Display LCh instead of Lab</span></font><br>
<font size="-1"><span style="font-family: monospace;"><font
size="-1"><span style="font-family: monospace;">&nbsp;<a
@@ -1117,6 +1144,7 @@ D50
+
Display Luv instead of Lab</span></font><br>
</span></font> <font size="-1"><span style="font-family:
monospace;">&nbsp;<a href="#V">-V</a>
@@ -1161,6 +1189,7 @@ D50
+
Show running average and std. devation from ref.</span></font><br>
<font size="-1"><span style="font-family: monospace;">&nbsp;<a
href="#T">-T</a>
@@ -1205,6 +1234,7 @@ D50
+
Display correlated color temperatures, CRI and TLCI<br>
</span></font><font size="-1"><span style="font-family:
monospace;">&nbsp;<a href="#N">-N</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -1248,6 +1278,7 @@ D50
+
Disable initial calibration of instrument if possible</span></font><br>
<font size="-1"><span style="font-family: monospace;">&nbsp;<a
href="spotread.html#O">-O</a>
@@ -1292,6 +1323,7 @@ D50
+
Do one cal. or measure and exit</span></font><br>
<font size="-1"><span style="font-family: monospace;">&nbsp;</span><a
style="font-family: monospace;" href="#H">-H</a><span
@@ -1311,6 +1343,7 @@ D50
+
Preset reference to spectrum<br>
&nbsp;</span></font><font size="-1"><span style="font-family:
monospace;"><a href="#X1">-X file.ccmx</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -1354,6 +1387,7 @@ D50
+
Apply Colorimeter Correction Matrix</span></font><br>
<span style="font-family: monospace;">&nbsp;<a href="#X2">-X
file.ccss</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -1402,6 +1436,7 @@ Samples
+
for calibration</span><br>
<font size="-1"><span style="font-family: monospace;">&nbsp;</span><a
style=" font-family: monospace;" href="#Yrn">-<font size="-1">Y</font>
@@ -1439,6 +1474,7 @@ Samples
+
&nbsp;&nbsp;&nbsp;&nbsp; Override refresh, non-refresh display
mode</span></font><br>
<tt>&nbsp;<a href="#YR">-Y R:<i>rate</i></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -1466,6 +1502,7 @@ Samples
+
Override measured refresh rate with rate Hz</tt><br>
<font size="-1"><span style="font-family: monospace;">&nbsp;</span><a
style=" font-family: monospace;" href="#YA">-<font size="-1">Y </font>A</a><span
@@ -1485,6 +1522,7 @@ Samples
+
Save white tile ref. spectrum to file</tt><br>
<tt>&nbsp;<a href="#YL">-Y L</a> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; Test for i1Pro Lamp
@@ -1539,6 +1577,7 @@ none,
+
h = HW, x = Xon/Xoff</span></font><br>
<small><span style="font-family: monospace;">&nbsp;</span><a style="
font-family: monospace;" href="#D">-D [level]</a><span
@@ -1587,6 +1626,7 @@ none,
+
Optional file to save reading results<br style="font-family:
monospace;">
</span></font><small><span style="font-family: monospace;"></span><span
@@ -1659,6 +1699,7 @@ none,
+
&nbsp;&nbsp; <br>
</td>
</tr>
@@ -1759,6 +1800,7 @@ none,
+
If the instrument does not support ambient mode, emissive mode will
be used instead. An adaptive integration time will be used in
devices that support it. <br>
@@ -1807,6 +1849,7 @@ none,
+
intending to use standard <b>M0</b>, <b>M1</b> or <b>M2</b>
conditions, then use just the <b>-I</b> option and not the&nbsp; <b>-i</b>
option. See <a href="colprof.html#f">colprof -f</a> for a fuller
@@ -1877,9 +1920,9 @@ none,
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; The <b>G</b> argument sets
the calibration to GMDI.<br>
<br>
- <a name="x"></a>The <b>-x</b> option causes the reading to be
- displayed as XYZ and Yxy values, rather than the default XYZ and
- L*a*b*<br>
+ <a name="w"></a>The <b>-w</b> option causes the L*a*b* reading to
+ converted using the <a href="#i">-i</a> parameter white point,
+ rather than the default of D50.<br>
<br>
<a name="h"></a>The <b>-h</b> option causes the reading to be
displayed as XYZ and LCh values, rather than the default XYZ and
@@ -1997,6 +2040,7 @@ none,
+
<b>-Y n</b> options overrides the refresh display mode set by the <a
href="#y">-y display type selection</a>, with <b>-Y</b><span
style="font-weight: bold;"> r</span> forcing refresh display mode,
diff --git a/gamut/gammap.c b/gamut/gammap.c
index 2fd00a3..ff949e8 100755
--- a/gamut/gammap.c
+++ b/gamut/gammap.c
@@ -155,6 +155,7 @@ struct {
#include <fcntl.h>
#include <string.h>
#include <math.h>
+#include "aconfig.h"
#include "icc.h"
#include "numlib.h"
#include "xicc.h"
@@ -165,6 +166,7 @@ struct {
#include "vrml.h"
#ifdef PLOT_LMAP
#include "plot.h"
+#include "ui.h"
#endif
/* Callback context for enhancing the saturation of the clut values */
diff --git a/h/aconfig.h b/h/aconfig.h
index dde4e69..6251893 100755
--- a/h/aconfig.h
+++ b/h/aconfig.h
@@ -7,7 +7,7 @@
/*
* Author: Graeme W. Gill
*
- * Copyright 2006 - 2017, Graeme W. Gill
+ * Copyright 2006 - 2018, Graeme W. Gill
* All rights reserved.
*
* This material is licenced under the GNU GENERAL PUBLIC LICENSE Version 2 or later :-
@@ -24,8 +24,8 @@
/* major number = 8 bits */
#ifndef USE_NG_VERSION
-# define ARGYLL_VERSION 0x02000
-# define ARGYLL_VERSION_STR "2.0.0"
+# define ARGYLL_VERSION 0x02001
+# define ARGYLL_VERSION_STR "2.0.1"
#else
# define ARGYLL_VERSION NG_VERSION
# define ARGYLL_VERSION_STR "NG_VERSION_STR"
@@ -54,6 +54,9 @@
# endif
#endif
+/* Maximum number of graphs supported by plot */
+#define MXGPHS 12
+
/* Maximum file path length */
#define MAXNAMEL 1024
diff --git a/h/counters.h b/h/counters.h
index 7e48e03..f84b6a2 100755
--- a/h/counters.h
+++ b/h/counters.h
@@ -160,7 +160,7 @@
/* ------------------------------------------------------- */
/* Macros combination counter */
/* Declare the counter name nn, combinations out of total */
-/* mxdi should be set to maximum combinations */
+/* mxdi should be set to maximum combinations. */
/* e.g. if there are 8 objects, and we want all combinations */
/* of 4 out of the 8, we would use: COMBO(nn, 4, 4, 8) */
@@ -209,7 +209,7 @@
} \
}
-/* After increment, expression is TRUE if counter is done */
+/* After init or increment, expression is TRUE if counter is done */
#define CB_DONE(nn) \
(nn##_e >= nn##_cmb)
@@ -272,7 +272,7 @@
} \
}
-/* After increment, expression is TRUE if counter is done */
+/* After init or increment, expression is TRUE if counter is done */
#define XCB_DONE(nn) \
CB_DONE(nn)
diff --git a/icc/Jamfile b/icc/Jamfile
index 4bedbba..21b9dcb 100755
--- a/icc/Jamfile
+++ b/icc/Jamfile
@@ -41,7 +41,7 @@ MainsFromSources icctest.c lutest.c iccdump.c icclu.c iccrw.c ;
# This is an example program for making a matrix display profile
MainsFromSources mkDispProf.c ;
-#MainsFromSources t.c ;
+#MainsFromSources t2.c ;
if $(BUILD_JUNK) {
diff --git a/icc/icc.c b/icc/icc.c
index de8c539..9c49081 100755
--- a/icc/icc.c
+++ b/icc/icc.c
@@ -13560,7 +13560,7 @@ void icmClamp3(double out[3], double in[3]) {
out[i] = in[i] < 0.0 ? 0.0 : in[i];
}
-/* Invert a 3 vector */
+/* Invert (negate) a 3 vector */
void icmInv3(double out[3], double in[3]) {
int i;
for (i = 0; i < 3; i++)
@@ -13858,7 +13858,7 @@ double in[3][3]
*/
det = icmDet3x3(in);
- if ( fabs(det) < ICM_SMALL_NUMBER)
+ if (fabs(det) < ICM_SMALL_NUMBER)
return 1;
/* calculate the adjoint matrix */
@@ -13871,6 +13871,23 @@ double in[3][3]
return 0;
}
+/* Invert a 2x2 transform matrix. Return 1 if error. */
+int icmInverse2x2(double out[2][2], double in[2][2]) {
+ double det = det2x2(in[0][0], in[0][1], in[1][0], in[1][1]);
+
+ if (fabs(det) < ICM_SMALL_NUMBER)
+ return 1;
+
+ det = 1.0/det;
+
+ out[0][0] = det * in[1][1];
+ out[0][1] = det * -in[0][1];
+ out[1][0] = det * -in[1][0];
+ out[1][1] = det * in[0][0];
+
+ return 0;
+}
+
/* - - - - - - - - - - - - - - - - - - - - - - - - */
/* Transpose a 3x3 matrix */
void icmTranspose3x3(double out[3][3], double in[3][3]) {
@@ -14006,17 +14023,6 @@ int icmNormalize3(double out[3], double in[3], double len) {
return 0;
}
-/* Compute the norm (length) of a vector define by two points */
-double icmNorm22(double in1[2], double in0[2]) {
- int j;
- double rv;
- for (rv = 0.0, j = 0; j < 2; j++) {
- double tt = in1[j] - in0[j];
- rv += tt * tt;
- }
- return sqrt(rv);
-}
-
/* Compute the norm (length) squared of a vector define by two points */
double icmNorm33sq(double in1[3], double in0[3]) {
int j;
@@ -14232,143 +14238,6 @@ double icmClip4marg(double out[4], double in[4]) {
/* - - - - - - - - - - - - - - - - - - - - - - - - */
-/*
-
- mat in out
-
-[ ] [] []
-[ ] [] []
-[ ] * [] => []
-[ ] [] []
-[ ] [] []
-
- */
-
-/* Multiply 5 array by 5x5 transform matrix */
-void icmMulBy5x5(double out[5], double mat[5][5], double in[5]) {
- int i, j;
- double tt[5];
-
- for (i = 0; i < 5; i++) {
- tt[i] = 0.0;
- for (j = 0; j < 5; j++)
- tt[i] += mat[i][j] * in[j];
- }
-
- for (i = 0; i < 5; i++)
- out[i] = tt[i];
-}
-
-/* Transpose a 5x5 matrix */
-void icmTranspose5x5(double out[5][5], double in[5][5]) {
- int i, j;
- if (out != in) {
- for (i = 0; i < 5; i++)
- for (j = 0; j < 5; j++)
- out[i][j] = in[j][i];
- } else {
- double tt[5][5];
- for (i = 0; i < 5; i++)
- for (j = 0; j < 5; j++)
- tt[i][j] = in[j][i];
- for (i = 0; i < 5; i++)
- for (j = 0; j < 5; j++)
- out[i][j] = tt[i][j];
- }
-}
-
-/* Clip a vector to the range 0.0 .. 1.0 */
-/* and return any clipping margine */
-double icmClip5marg(double out[5], double in[5]) {
- int j;
- double tt, marg = 0.0;
- for (j = 0; j < 5; j++) {
- out[j] = in[j];
- if (out[j] < 0.0) {
- tt = 0.0 - out[j];
- out[j] = 0.0;
- if (tt > marg)
- marg = tt;
- } else if (out[j] > 1.0) {
- tt = out[j] - 1.0;
- out[j] = 1.0;
- if (tt > marg)
- marg = tt;
- }
- }
- return marg;
-}
-
-
-/* Multiply 6 array by 6x6 transform matrix */
-void icmMulBy6x6(double out[6], double mat[6][6], double in[6]) {
- int i, j;
- double tt[6];
-
- for (i = 0; i < 6; i++) {
- tt[i] = 0.0;
- for (j = 0; j < 6; j++)
- tt[i] += mat[i][j] * in[j];
- }
-
- for (i = 0; i < 6; i++)
- out[i] = tt[i];
-}
-
-/* Transpose a 6x6 matrix */
-void icmTranspose6x6(double out[6][6], double in[6][6]) {
- int i, j;
- if (out != in) {
- for (i = 0; i < 6; i++)
- for (j = 0; j < 6; j++)
- out[i][j] = in[j][i];
- } else {
- double tt[6][6];
- for (i = 0; i < 6; i++)
- for (j = 0; j < 6; j++)
- tt[i][j] = in[j][i];
- for (i = 0; i < 6; i++)
- for (j = 0; j < 6; j++)
- out[i][j] = tt[i][j];
- }
-}
-
-/* Clip a vector to the range 0.0 .. 1.0 */
-/* and return any clipping margine */
-double icmClip6marg(double out[6], double in[6]) {
- int j;
- double tt, marg = 0.0;
- for (j = 0; j < 6; j++) {
- out[j] = in[j];
- if (out[j] < 0.0) {
- tt = 0.0 - out[j];
- out[j] = 0.0;
- if (tt > marg)
- marg = tt;
- } else if (out[j] > 1.0) {
- tt = out[j] - 1.0;
- out[j] = 1.0;
- if (tt > marg)
- marg = tt;
- }
- }
- return marg;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - */
-/* Multiply 2 array by 2x2 transform matrix */
-void icmMulBy2x2(double out[2], double mat[2][2], double in[2]) {
- double tt[2];
-
- tt[0] = mat[0][0] * in[0] + mat[0][1] * in[1];
- tt[1] = mat[1][0] * in[0] + mat[1][1] * in[1];
-
- out[0] = tt[0];
- out[1] = tt[1];
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - */
-
/* Copy a 3x4 transform matrix */
void icmCpy3x4(double dst[3][4], double src[3][4]) {
int i, j;
@@ -14638,6 +14507,52 @@ double icmPlaneDist3(double eq[4], double p[3]) {
}
/* - - - - - - - - - - - - - - - - - - - - - - - - */
+
+/* Compute the norm (length) of a vector define by two points */
+double icmNorm22(double in1[2], double in0[2]) {
+ int j;
+ double rv;
+ for (rv = 0.0, j = 0; j < 2; j++) {
+ double tt = in1[j] - in0[j];
+ rv += tt * tt;
+ }
+ return sqrt(rv);
+}
+
+/* Compute the norm (length) squared of of a vector defined by two points */
+double icmNorm22sq(double in1[2], double in0[2]) {
+ int j;
+ double rv;
+ for (rv = 0.0, j = 0; j < 2; j++) {
+ double tt = in1[j] - in0[j];
+ rv += tt * tt;
+ }
+ return rv;
+}
+
+/* Multiply 2 array by 2x2 transform matrix */
+void icmMulBy2x2(double out[2], double mat[2][2], double in[2]) {
+ double tt[2];
+
+ tt[0] = mat[0][0] * in[0] + mat[0][1] * in[1];
+ tt[1] = mat[1][0] * in[0] + mat[1][1] * in[1];
+
+ out[0] = tt[0];
+ out[1] = tt[1];
+}
+
+/* Compute the dot product of two 2 vectors */
+double icmDot2(double in1[2], double in2[2]) {
+ return in1[0] * in2[0] + in1[1] * in2[1];
+}
+
+/* Compute the dot product of two 2 vectors defined by 4 points */
+/* 1->2 and 3->4 */
+double icmDot22(double in1[2], double in2[2], double in3[2], double in4[2]) {
+ return (in2[0] - in1[0]) * (in4[0] - in3[0])
+ + (in2[1] - in1[1]) * (in4[1] - in3[1]);
+}
+
/* Given 2 2D points, compute a plane equation (implicit line equation). */
/* The normal will be right handed given the order of the points */
/* The plane equation will be the 2 normal components and the constant. */
@@ -14769,7 +14684,7 @@ int icmLineIntersect2(double res[2], double p1[2], double p2[2], double p3[2], d
}
/* Given two finite 2D lines define by 4 points, compute their paramaterized intersection. */
-/* aprm may be NULL */
+/* aprm may be NULL. Param is prop. from p1 -> p2, p3 -> p4 */
/* Return 2 if there is no intersection (lines are parallel) */
/* Return 1 lines do not cross within their length */
int icmParmLineIntersect2(double res[2], double aprm[2], double p1[2], double p2[2], double p3[2], double p4[2]) {
@@ -14803,6 +14718,23 @@ int icmParmLineIntersect2(double res[2], double aprm[2], double p1[2], double p2
return 0;
}
+/* Compute a blend between in0 and in1 */
+void icmBlend2(double out[2], double in0[2], double in1[2], double bf) {
+ out[0] = (1.0 - bf) * in0[0] + bf * in1[0];
+ out[1] = (1.0 - bf) * in0[1] + bf * in1[1];
+}
+
+/* Scale a 2 vector by the given ratio */
+void icmScale2(double out[2], double in[2], double rat) {
+ out[0] = in[0] * rat;
+ out[1] = in[1] * rat;
+}
+
+/* Scale a 2 vector by the given ratio and add it */
+void icmScaleAdd2(double out[3], double in2[2], double in1[2], double rat) {
+ out[0] = in2[0] + in1[0] * rat;
+ out[1] = in2[1] + in1[1] * rat;
+}
/* - - - - - - - - - - - - - - - - - - - - - - - - */
/* CIE Y (range 0 .. 1) to perceptual CIE 1976 L* (range 0 .. 100) */
@@ -14893,12 +14825,14 @@ icmLab2XYZ(icmXYZNumber *w, double *out, double *in) {
* This is a modern update to L*a*b*, based on IPT space.
*
* Differences to L*a*b* and IPT:
- * Using inverse CIE 2012 2degree LMS to XYZ matrix instead of Hunt-Pointer-Estevez
+ * Using inverse CIE 2012 2degree LMS to XYZ matrix instead of Hunt-Pointer-Estevez.
* Von Kries chromatic adapation in LMS space.
* Using L* compression rather than IPT pure 0.43 power.
* Tweaked LMS' to IPT matrix to account for change in XYZ to LMS matrix.
* Output scaled to L*a*b* type ranges, to maintain 1 JND scale.
- * (Watch out - L* value is not a non-linear Y value though!).
+ * (Watch out - L* value is not a non-linear Y value though!
+ * - Interesting that Dolby force L to be just dependent on Y
+ * by making L = 0.5 L | 0.5 M in ICtCp space).
*/
/* CIE XYZ to perceptual Lpt */
diff --git a/icc/icc.h b/icc/icc.h
index 1e2caf8..75b7736 100755
--- a/icc/icc.h
+++ b/icc/icc.h
@@ -1784,6 +1784,12 @@ extern ICCLIB_API unsigned int icmCSSig2chanNames( icColorSpaceSignature sig, ch
/* Copy a 2 vector */
#define icmCpy2(d_ary, s_ary) ((d_ary)[0] = (s_ary)[0], (d_ary)[1] = (s_ary)[1])
+#define icmAdd2(d_ary, s1_ary, s2_ary) ((d_ary)[0] = (s1_ary)[0] + (s2_ary)[0], \
+ (d_ary)[1] = (s1_ary)[1] + (s2_ary)[1])
+
+#define icmSub2(d_ary, s1_ary, s2_ary) ((d_ary)[0] = (s1_ary)[0] - (s2_ary)[0], \
+ (d_ary)[1] = (s1_ary)[1] - (s2_ary)[1])
+
/* Copy a 3 vector */
#define icmCpy3(d_ary, s_ary) ((d_ary)[0] = (s_ary)[0], (d_ary)[1] = (s_ary)[1], \
(d_ary)[2] = (s_ary)[2])
@@ -1792,10 +1798,12 @@ extern ICCLIB_API unsigned int icmCSSig2chanNames( icColorSpaceSignature sig, ch
#define icmCpy4(d_ary, s_ary) ((d_ary)[0] = (s_ary)[0], (d_ary)[1] = (s_ary)[1], \
(d_ary)[2] = (s_ary)[2], (d_ary)[3] = (s_ary)[3])
+/* - - - - - - - - - - - - - - */
+
/* Clamp a 3 vector to be +ve */
void icmClamp3(double out[3], double in[3]);
-/* Invert a 3 vector */
+/* Invert (negate) a 3 vector */
void icmInv3(double out[3], double in[3]);
/* Add two 3 vectors */
@@ -1832,8 +1840,6 @@ double icmDot3(double in1[3], double in2[3]);
/* Compute the cross product of two 3D vectors, out = in1 x in2 */
void icmCross3(double out[3], double in1[3], double in2[3]);
-#define icmNorm2(i) sqrt((i)[0] * (i)[0] + (i)[1] * (i)[1])
-
/* Compute the norm squared (length squared) of a 3 vector */
double icmNorm3sq(double in[3]);
@@ -1869,9 +1875,6 @@ double icmClip3marg(double out[3], double in[3]);
/* Normalise a 3 vector to the given length. Return nz if not normalisable */
int icmNormalize3(double out[3], double in[3], double len);
-/* Compute the norm (length) of of a vector defined by two points */
-double icmNorm22(double in1[2], double in0[2]);
-
/* Compute the norm squared (length squared) of a vector defined by two points */
double icmNorm33sq(double in1[3], double in0[3]);
@@ -1983,30 +1986,24 @@ double icmClip4marg(double out[4], double in[4]);
/* - - - - - - - - - - - - - - - - - - - - - - - */
-/* Multiply 5 vector by 5x5 transform matrix */
-/* Organization is mat[out][in] */
-void icmMulBy5x5(double out[5], double mat[5][5], double in[5]);
+#define icmNorm2(i) sqrt((i)[0] * (i)[0] + (i)[1] * (i)[1])
-/* Transpose a 5x5 matrix */
-void icmTranspose5x5(double out[5][5], double in[5][5]);
-
-/* Clip a vector to the range 0.0 .. 1.0 */
-/* and return any clipping margine */
-double icmClip5marg(double out[5], double in[5]);
+#define icmNorm2sq(i) ((i)[0] * (i)[0] + (i)[1] * (i)[1])
+/* Compute the norm (length) of of a vector defined by two points */
+double icmNorm22(double in1[2], double in0[2]);
-/* Multiply 6 vector by 6x6 transform matrix */
-/* Organization is mat[out][in] */
-void icmMulBy6x6(double out[6], double mat[6][6], double in[6]);
+/* Compute the norm (length) squared of of a vector defined by two points */
+double icmNorm22sq(double in1[2], double in0[2]);
-/* Transpose a 6x6 matrix */
-void icmTranspose6x6(double out[6][6], double in[6][6]);
+/* Compute the dot product of two 2 vectors */
+double icmDot2(double in1[2], double in2[2]);
-/* Clip a vector to the range 0.0 .. 1.0 */
-/* and return any clipping margine */
-double icmClip6marg(double out[6], double in[6]);
+#define ICMDOT2(o, i, j) ((o) = (i)[0] * (j)[0] + (i)[1] * (j)[1])
-/* - - - - - - - - - - - - - - - - - - - - - - - */
+/* Compute the dot product of two 2 vectors defined by 4 points */
+/* 1->2 and 3->4 */
+double icmDot22(double in1[2], double in2[2], double in3[2], double in4[2]);
/* Given 2 2D points, compute a plane equation. */
/* The normal will be right handed given the order of the points */
@@ -2038,13 +2035,26 @@ int icmLinePointClosest2(double cp[2], double *pa,
int icmLineIntersect2(double res[2], double p1[2], double p2[2], double p3[2], double p4[2]);
/* Given two finite 2D lines define by 4 points, compute their paramaterized intersection. */
-/* aprm may be NULL */
-/* Return nz if there is no intersection (lines are parallel or do not cross in length) */
+/* aprm may be NULL. Param is prop. from p1 -> p2, p3 -> p4 */
+/* Return 2 if there is no intersection (lines are parallel) */
+/* Return 1 lines do not cross within their length */
int icmParmLineIntersect2(double ares[2], double aprm[2], double p1[2], double p2[2], double p3[2], double p4[2]);
+/* Invert a 2x2 transform matrix. Return 1 if error. */
+int icmInverse2x2(double out[2][2], double in[2][2]);
+
/* Multiply 2 array by 2x2 transform matrix */
void icmMulBy2x2(double out[2], double mat[2][2], double in[2]);
+/* Compute a blend between in0 and in1 */
+void icmBlend2(double out[2], double in0[2], double in1[2], double bf);
+
+/* Scale a 2 vector by the given ratio */
+void icmScale2(double out[2], double in[2], double rat);
+
+/* Scale a 2 vector by the given ratio and add it */
+void icmScaleAdd2(double out[2], double in2[3], double in1[2], double rat);
+
/* - - - - - - - - - - - - - - */
/* Simple macro to transfer an array to an XYZ number */
diff --git a/link/collink.c b/link/collink.c
index 798bc14..3172f2b 100755
--- a/link/collink.c
+++ b/link/collink.c
@@ -181,6 +181,18 @@
#include "gammap.h"
#include "vrml.h"
+/* flag usage:
+
+ 0123456789
+ .
+
+ abcdefghijklmnopqrstuvwxyz
+ ....... . .. ....... ..
+
+ ABCDEFGHIJKLMNOPQRSTUVWXYZ
+ . ....... . . .. .. .
+*/
+
void usage(char *diag, ...) {
int i;
fprintf(stderr,"Link ICC profiles, Version %s\n",ARGYLL_VERSION_STR);
@@ -211,6 +223,7 @@ void usage(char *diag, ...) {
fprintf(stderr," -p absprof Include abstract profile in link\n");
fprintf(stderr," -a file.cal Apply calibration curves to link output and append linear\n");
fprintf(stderr," -H file.cal Append calibration curves to 3dlut\n");
+ fprintf(stderr," -O file.cal Use just calibration curves as link and append linear\n");
fprintf(stderr," -s Simple Mode (default)\n");
fprintf(stderr," -g [src.gam] Gamut Mapping Mode [optional source image gamut]\n");
fprintf(stderr," -G [src.gam] Gamut Mapping Mode using inverse outprofile A2B\n");
@@ -219,7 +232,7 @@ void usage(char *diag, ...) {
fprintf(stderr," s = saturation, a = absolute colorimetric\n");
fprintf(stderr," -o out_intent p = perceptual, r = relative colorimetric,\n");
fprintf(stderr," s = saturation, a = absolute colorimetric\n");
- fprintf(stderr," Gamut Mapping Mode Options:\n");
+ fprintf(stderr," Gamut Mapping Mode Options:\n");
fprintf(stderr," -i intent set linking intent from the following choice:\n");
for (i = 0; ; i++) {
icxGMappingIntent gmi;
@@ -382,6 +395,8 @@ struct _clink {
/* 2 = set MadVR cal1 to cal */
xcal *cal; /* Calibration to apply, NULL if none */
+ int calonly; /* calibration curve only - no ICC profile linking */
+
/* (We current assume that xyzscale can't be used with gmi) */
double xyzscale; /* < 1.0 if Y is to be scaled in destination XYZ space */
double swxyz[3]; /* Source white point in XYZ */
@@ -1057,559 +1072,568 @@ void devip_devop(void *cntx, double *out, double *in) {
#endif
}
- /* Do DevIn' -> PCS */
- switch(p->in.alg) {
- case icmMonoFwdType: {
- icxLuMono *lu = (icxLuMono *)p->in.luo; /* Safe to coerce */
+ if (p->calonly) {
- if (p->in.nocurve) { /* No explicit curve, so do implicit here */
- rv |= lu->fwd_curve(lu, pcsv, win);
- rv |= lu->fwd_map(lu, pcsv, pcsv);
- } else {
- rv |= lu->fwd_map(lu, pcsv, win);
+ vect_cpy(out, win, p->cal->devchan);
+
+ } else {
+
+ /* Do DevIn' -> PCS */
+ switch(p->in.alg) {
+ case icmMonoFwdType: {
+ icxLuMono *lu = (icxLuMono *)p->in.luo; /* Safe to coerce */
+
+ if (p->in.nocurve) { /* No explicit curve, so do implicit here */
+ rv |= lu->fwd_curve(lu, pcsv, win);
+ rv |= lu->fwd_map(lu, pcsv, pcsv);
+ } else {
+ rv |= lu->fwd_map(lu, pcsv, win);
+ }
+ rv |= lu->fwd_abs(lu, pcsv, pcsv);
+ break;
}
- rv |= lu->fwd_abs(lu, pcsv, pcsv);
- break;
- }
- case icmMatrixFwdType: {
- icxLuMatrix *lu = (icxLuMatrix *)p->in.luo; /* Safe to coerce */
- icmLuMatrix *plu = (icmLuMatrix *)lu->plu; /* Safe to coerce */
+ case icmMatrixFwdType: {
+ icxLuMatrix *lu = (icxLuMatrix *)p->in.luo; /* Safe to coerce */
+ icmLuMatrix *plu = (icmLuMatrix *)lu->plu; /* Safe to coerce */
- if (p->in.nocurve) { /* No explicit curve, so do implicit here */
+ if (p->in.nocurve) { /* No explicit curve, so do implicit here */
- if (p->in.tvenc == 8 || p->in.tvenc == 9) { /* xvYCC */
- if (p->in.bt1886)
- bt1886_fwd_curve(&p->in.bt, pcsv, win);
- else
- xvYCC_fwd_curve(pcsv, win); /* Allow for overrange values */
- xvYCC_fwd_matrix(pcsv, pcsv); /* Rec709 primaries */
+ if (p->in.tvenc == 8 || p->in.tvenc == 9) { /* xvYCC */
+ if (p->in.bt1886)
+ bt1886_fwd_curve(&p->in.bt, pcsv, win);
+ else
+ xvYCC_fwd_curve(pcsv, win); /* Allow for overrange values */
+ xvYCC_fwd_matrix(pcsv, pcsv); /* Rec709 primaries */
+ } else {
+ if (p->in.bt1886)
+ bt1886_fwd_curve(&p->in.bt, pcsv, win);
+ else
+ rv |= lu->fwd_curve(lu, pcsv, win);
+ rv |= lu->fwd_matrix(lu, pcsv, pcsv);
+ }
} else {
- if (p->in.bt1886)
- bt1886_fwd_curve(&p->in.bt, pcsv, win);
+ if (p->in.tvenc == 8 || p->in.tvenc == 9) /* xvYCC */
+ xvYCC_fwd_matrix(pcsv, pcsv); /* Rec709 primaries */
else
- rv |= lu->fwd_curve(lu, pcsv, win);
- rv |= lu->fwd_matrix(lu, pcsv, pcsv);
+ rv |= lu->fwd_matrix(lu, pcsv, win);
}
- } else {
- if (p->in.tvenc == 8 || p->in.tvenc == 9) /* xvYCC */
- xvYCC_fwd_matrix(pcsv, pcsv); /* Rec709 primaries */
- else
- rv |= lu->fwd_matrix(lu, pcsv, win);
- }
#ifdef DEBUG
- DEBUGCND printf("After matrix PCS' XYZ %s Lab %s\n",icmPdv(p->in.chan, pcsv), icmPLab(pcsv));
+ DEBUGCND printf("After matrix PCS' XYZ %s Lab %s\n",icmPdv(p->in.chan, pcsv), icmPLab(pcsv));
#endif
- if (p->in.bt1886) {
- bt1886_wp_adjust(&p->in.bt, pcsv, pcsv);
+ if (p->in.bt1886) {
+ bt1886_wp_adjust(&p->in.bt, pcsv, pcsv);
#ifdef DEBUG
- DEBUGCND printf("After bt1886 PCS' XYZ %s Lab %s\n",icmPdv(p->in.chan, pcsv), icmPLab(pcsv));
+ DEBUGCND printf("After bt1886 PCS' XYZ %s Lab %s\n",icmPdv(p->in.chan, pcsv), icmPLab(pcsv));
#endif
- }
+ }
- rv |= lu->fwd_abs(lu, pcsv, pcsv);
+ rv |= lu->fwd_abs(lu, pcsv, pcsv);
- break;
- }
- case icmLutType: {
- icxLuLut *lu = (icxLuLut *)p->in.luo; /* Safe to coerce */
- if (p->in.nocurve) { /* No explicit curve, so we've got Dev */
- /* Since not PCS, in_abs and matrix cannot be valid, */
- /* so input curve on own is ok to use. */
- rv |= lu->input(lu, pcsv, win); /* Dev -> Dev' */
- rv |= lu->clut(lu, pcsv, pcsv); /* Dev' -> PCS' */
- } else { /* We've got Dev' */
- rv |= lu->clut(lu, pcsv, win); /* Dev' -> PCS' */
+ break;
}
- /* We've got the input profile PCS' at this point. */
+ case icmLutType: {
+ icxLuLut *lu = (icxLuLut *)p->in.luo; /* Safe to coerce */
+ if (p->in.nocurve) { /* No explicit curve, so we've got Dev */
+ /* Since not PCS, in_abs and matrix cannot be valid, */
+ /* so input curve on own is ok to use. */
+ rv |= lu->input(lu, pcsv, win); /* Dev -> Dev' */
+ rv |= lu->clut(lu, pcsv, pcsv); /* Dev' -> PCS' */
+ } else { /* We've got Dev' */
+ rv |= lu->clut(lu, pcsv, win); /* Dev' -> PCS' */
+ }
+ /* We've got the input profile PCS' at this point. */
- /* If we're transfering the K value from the input profile to the */
- /* output, copy it into locus[], which will be given to the inverse */
- /* lookup function, else the inverse lookup will generate a K using */
- /* the curve parameters. */
+ /* If we're transfering the K value from the input profile to the */
+ /* output, copy it into locus[], which will be given to the inverse */
+ /* lookup function, else the inverse lookup will generate a K using */
+ /* the curve parameters. */
//printf("~1 out.inking = %d\n",p->out.inking);
- if (p->out.inking == 0 || p->out.inking == 6) {
- if (p->out.locus) {
- /* Converts PCS' to K locus proportion */
- lu->clut_locus(lu, locus, pcsv, win); /* Compute possible locus values */
+ if (p->out.inking == 0 || p->out.inking == 6) {
+ if (p->out.locus) {
+ /* Converts PCS' to K locus proportion */
+ lu->clut_locus(lu, locus, pcsv, win); /* Compute possible locus values */
//printf("~1 looked up locus value\n");
- } else {
- for (i = 0; i < p->in.chan; i++) /* Target is K input value */
- locus[i] = win[i];
- /* Convert K' to K value ready for aux target */
- if (!p->in.nocurve) { /* we have an input curve, so convert Dev' -> Dev */
- lu->inv_input(lu, locus, locus);
- }
+ } else {
+ for (i = 0; i < p->in.chan; i++) /* Target is K input value */
+ locus[i] = win[i];
+ /* Convert K' to K value ready for aux target */
+ if (!p->in.nocurve) { /* we have an input curve, so convert Dev' -> Dev */
+ lu->inv_input(lu, locus, locus);
+ }
//printf("~1 copied win to locus\n");
- }
+ }
#ifdef DEBUG
- DEBUGCND printf("Got possible K %s of %f %f %f %f\n",p->out.locus ? "locus" : "value", locus[0],locus[1],locus[2],locus[3]);
+ DEBUGCND printf("Got possible K %s of %f %f %f %f\n",p->out.locus ? "locus" : "value", locus[0],locus[1],locus[2],locus[3]);
#endif
+ }
+ rv |= lu->output(lu, pcsv, pcsv); /* PCS' -> */
+ rv |= lu->out_abs(lu, pcsv, pcsv); /* PCS */
+ break;
}
- rv |= lu->output(lu, pcsv, pcsv); /* PCS' -> */
- rv |= lu->out_abs(lu, pcsv, pcsv); /* PCS */
- break;
+ default:
+ error("Unexpected algorithm type %d in devip of devip_devop()",p->in.alg);
}
- default:
- error("Unexpected algorithm type %d in devip of devip_devop()",p->in.alg);
- }
- /* At this point, the PCS is:
- *
- * If not gamut mapped:
- * Lab in the intent selected for the source profile
- * If gamut mapped:
- * either
- * Absolute Lab
- * or
- * Jab derived from absolute XYZ via the in/out viewing conditions
+ /* At this point, the PCS is:
+ *
+ * If not gamut mapped:
+ * Lab in the intent selected for the source profile
+ * If gamut mapped:
+ * either
+ * Absolute Lab
+ * or
+ * Jab derived from absolute XYZ via the in/out viewing conditions
*
* and locus[] contains any auxiliar target values if the
- * auxiliary is not being created by a rule applied to the PCS.
- */
+ * auxiliary is not being created by a rule applied to the PCS.
+ */
- /*
- * The order to do this intermediate processing is hard to figure out,
- * as is the interaction between such elements. How should the
- * abstract profile be properly handled ?
- * what should we do if the wphack/rgbbkhack is on and Y scaling is on ?
- */
+ /*
+ * The order to do this intermediate processing is hard to figure out,
+ * as is the interaction between such elements. How should the
+ * abstract profile be properly handled ?
+ * what should we do if the wphack/rgbbkhack is on and Y scaling is on ?
+ */
#ifdef DEBUG
- DEBUGCND printf("PCS before map %f %f %f\n",pcsv[0], pcsv[1], pcsv[2]);
+ DEBUGCND printf("PCS before map %f %f %f\n",pcsv[0], pcsv[1], pcsv[2]);
#endif
- if (p->wphack) {
- int e;
- double dd = 0.0;
- for (e = 0; e < 3; e++) { /* Does this match the input white point ? */
- double tt;
- tt = pcsv[e] - p->in.wp[e];
- dd += tt * tt;
- }
- dd = sqrt(dd);
-
- if (dd < 1.0) { /* Triggered withing 1 delta E */
- if (clip == 0) /* Don't count zero's white caused by video input clipping */
- p->wphacked++;
- wptrig = 1;
- if (p->wphack == 2) {
- for (e = 0; e < 3; e++) /* Map input white to given white */
- pcsv[e] = p->hwp[e];
- } else {
- for (e = 0; e < 3; e++) /* Map input white to output white */
- pcsv[e] = p->out.wp[e];
+ if (p->wphack) {
+ int e;
+ double dd = 0.0;
+ for (e = 0; e < 3; e++) { /* Does this match the input white point ? */
+ double tt;
+ tt = pcsv[e] - p->in.wp[e];
+ dd += tt * tt;
}
+ dd = sqrt(dd);
+
+ if (dd < 1.0) { /* Triggered withing 1 delta E */
+ if (clip == 0) /* Don't count zero's white caused by video input clipping */
+ p->wphacked++;
+ wptrig = 1;
+ if (p->wphack == 2) {
+ for (e = 0; e < 3; e++) /* Map input white to given white */
+ pcsv[e] = p->hwp[e];
+ } else {
+ for (e = 0; e < 3; e++) /* Map input white to output white */
+ pcsv[e] = p->out.wp[e];
+ }
#ifndef DEBUG
- if (p->verb)
+ if (p->verb)
#endif
- {
- printf("White point hack mapped %f %f %f to %f %f %f, hit withing %f\n",
+ {
+ printf("White point hack mapped %f %f %f to %f %f %f, hit withing %f\n",
p->in.wp[0],p->in.wp[1],p->in.wp[2],pcsv[0], pcsv[1], pcsv[2],dd);
- fflush(stdout);
+ fflush(stdout);
+ }
}
}
- }
- /* Do luminence scaling if requested */
- if (wptrig == 0 && p->xyzscale < 1.0) {
- double xyz[3];
+ /* Do luminence scaling if requested */
+ if (wptrig == 0 && p->xyzscale < 1.0) {
+ double xyz[3];
//printf("~1 got xyzscale = %f\n",p->xyzscale);
//printf("PCS %f %f %f\n",pcsv[0], pcsv[1], pcsv[2]);
- /* Convert our PCS to XYZ */
- if (p->pcsor == icxSigJabData) {
- /* We're being bad in delving inside the xluo, but we'll fix it latter */
- p->out.luo->cam->cam_to_XYZ(p->out.luo->cam, xyz, pcsv);
- } else
- error("Internal :- not setup to handle Y scaling and non-Jab PCS");
+ /* Convert our PCS to XYZ */
+ if (p->pcsor == icxSigJabData) {
+ /* We're being bad in delving inside the xluo, but we'll fix it latter */
+ p->out.luo->cam->cam_to_XYZ(p->out.luo->cam, xyz, pcsv);
+ } else
+ error("Internal :- not setup to handle Y scaling and non-Jab PCS");
//printf("XYZ %f %f %f\n",xyz[0], xyz[1], xyz[2]);
- /* Scale it */
- xyz[0] *= p->xyzscale;
- xyz[1] *= p->xyzscale;
- xyz[2] *= p->xyzscale;
+ /* Scale it */
+ xyz[0] *= p->xyzscale;
+ xyz[1] *= p->xyzscale;
+ xyz[2] *= p->xyzscale;
//printf("scaled XYZ %f %f %f\n",xyz[0], xyz[1], xyz[2]);
- /* Convert back to PCS */
- if (p->pcsor == icxSigJabData) {
- /* We're being bad in delving inside the xluo, but we'll fix it latter */
- p->out.luo->cam->XYZ_to_cam(p->out.luo->cam, pcsv, xyz);
- } else
- error("Internal :- not setup to handle Y scaling and non-Jab PCS");
+ /* Convert back to PCS */
+ if (p->pcsor == icxSigJabData) {
+ /* We're being bad in delving inside the xluo, but we'll fix it latter */
+ p->out.luo->cam->XYZ_to_cam(p->out.luo->cam, pcsv, xyz);
+ } else
+ error("Internal :- not setup to handle Y scaling and non-Jab PCS");
//printf("scaled PCS %f %f %f\n",pcsv[0], pcsv[1], pcsv[2]);
#ifdef DEBUG
- DEBUGCND printf("PCS after Y scale %f %f %f\n",pcsv[0], pcsv[1], pcsv[2]);
+ DEBUGCND printf("PCS after Y scale %f %f %f\n",pcsv[0], pcsv[1], pcsv[2]);
#endif
- }
+ }
- /* Do gamut mapping */
- if (wptrig == 0 && p->mode > 0 && p->gmi.usemap) {
- /* We've used pcsor to ensure PCS space is appropriate */
-
- /* Doing XXXK -> XXXK */
- if (p->nhack == 2) {
- /* Ideally we would create a 4D PCSK -> PCSK gamut mapping */
- /* to smoothly and accurately cope with the changing source */
- /* and destination gamuts acording to their degree of "K onlyness". */
- /* In practice we're going to simply interpolated between */
- /* two extremes: unrestricted gamut and K only black gamut. */
- double map0[3], map1[3];
-
- /* Compute blend of normal gamut map and Konly to Konly gamut map */
- {
- p->map->domap(p->map, map0, pcsv);
- p->Kmap->domap(p->Kmap, map1, pcsv);
- icmBlend3(pcsvm, map0, map1, konlyness);
- }
+ /* Do gamut mapping */
+ if (wptrig == 0 && p->mode > 0 && p->gmi.usemap) {
+ /* We've used pcsor to ensure PCS space is appropriate */
+
+ /* Doing XXXK -> XXXK */
+ if (p->nhack == 2) {
+ /* Ideally we would create a 4D PCSK -> PCSK gamut mapping */
+ /* to smoothly and accurately cope with the changing source */
+ /* and destination gamuts acording to their degree of "K onlyness". */
+ /* In practice we're going to simply interpolated between */
+ /* two extremes: unrestricted gamut and K only black gamut. */
+ double map0[3], map1[3];
+
+ /* Compute blend of normal gamut map and Konly to Konly gamut map */
+ {
+ p->map->domap(p->map, map0, pcsv);
+ p->Kmap->domap(p->Kmap, map1, pcsv);
+ icmBlend3(pcsvm, map0, map1, konlyness);
+ }
#ifdef DEBUG
- DEBUGCND printf("PCS after map0 %f %f %f map1 %f %f %f\n", map0[0], map0[1], map0[2], map1[0], map1[1], map1[2]);
+ DEBUGCND printf("PCS after map0 %f %f %f map1 %f %f %f\n", map0[0], map0[1], map0[2], map1[0], map1[1], map1[2]);
#endif
- /* Normal gamut mapping */
- } else {
- {
- p->map->domap(p->map, pcsvm, pcsv);
+ /* Normal gamut mapping */
+ } else {
+ {
+ p->map->domap(p->map, pcsvm, pcsv);
+ }
}
- }
#ifdef DEBUG
- DEBUGCND printf("PCS after map %f %f %f\n",pcsvm[0], pcsvm[1], pcsvm[2]);
+ DEBUGCND printf("PCS after map %f %f %f\n",pcsvm[0], pcsvm[1], pcsvm[2]);
#endif
- } else {
- pcsvm[0] = pcsv[0];
- pcsvm[1] = pcsv[1];
- pcsvm[2] = pcsv[2];
- }
+ } else {
+ pcsvm[0] = pcsv[0];
+ pcsvm[1] = pcsv[1];
+ pcsvm[2] = pcsv[2];
+ }
- /* Gamut mapped PCS value is now in pcsvm[] */
-
- /* Abstract profile transform, PCS -> PCS */
- /* pcsor -> abstract -> pcsor conversion */
- /* We're applying any abstract profile after gamut mapping, */
- /* on the assumption is primarily being used to "correct" the */
- /* output device. Ideally the gamut mapping should take the change */
- /* the abstract profile has on the output device into account, but */
- /* currently we're not doing this... */
- if (wptrig == 0 && p->abs_luo != NULL) {
- /* Abstract profile is either absolute or relative. */
- /* We need to convert the current PCS into something compatible. */
- /* This is more ugly than it really should be, so we're ignoring it. */
- /* We should really run the source through the abstract profile before */
- /* creating the gamut mapping, to be able to use abstract with gamut */
- /* mapping properly. */
- p->abs_luo->lookup(p->abs_luo, pcsvm, pcsvm);
+ /* Gamut mapped PCS value is now in pcsvm[] */
+
+ /* Abstract profile transform, PCS -> PCS */
+ /* pcsor -> abstract -> pcsor conversion */
+ /* We're applying any abstract profile after gamut mapping, */
+ /* on the assumption is primarily being used to "correct" the */
+ /* output device. Ideally the gamut mapping should take the change */
+ /* the abstract profile has on the output device into account, but */
+ /* currently we're not doing this... */
+ if (wptrig == 0 && p->abs_luo != NULL) {
+ /* Abstract profile is either absolute or relative. */
+ /* We need to convert the current PCS into something compatible. */
+ /* This is more ugly than it really should be, so we're ignoring it. */
+ /* We should really run the source through the abstract profile before */
+ /* creating the gamut mapping, to be able to use abstract with gamut */
+ /* mapping properly. */
+ p->abs_luo->lookup(p->abs_luo, pcsvm, pcsvm);
#ifdef DEBUG
- DEBUGCND printf("PCS after abstract %f %f %f\n",pcsvm[0], pcsvm[1], pcsvm[2]);
+ DEBUGCND printf("PCS after abstract %f %f %f\n",pcsvm[0], pcsvm[1], pcsvm[2]);
#endif
- }
+ }
- /* If we're using the existing B2A inking to determine K, */
- /* lookup the output profiles K value for this PCS */
- if (p->mode >= 2 && p->out.inking == 7) {
- double tdevv[MAX_CHAN];
+ /* If we're using the existing B2A inking to determine K, */
+ /* lookup the output profiles K value for this PCS */
+ if (p->mode >= 2 && p->out.inking == 7) {
+ double tdevv[MAX_CHAN];
//printf("~1 dealing with out.inking = %d\n",p->out.inking);
- if (p->out.alg != icmLutType || p->out.c->header->colorSpace != icSigCmykData)
- error ("Attempting to use non-CMYK output profile to determine K inking");
+ if (p->out.alg != icmLutType || p->out.c->header->colorSpace != icSigCmykData)
+ error ("Attempting to use non-CMYK output profile to determine K inking");
- /* Lookup PCS in B2A of output profile to get target K value */
+ /* Lookup PCS in B2A of output profile to get target K value */
//printf("~1 looking up pcs %f %f %f in B2A\n", pcsvm[0], pcsvm[1], pcsvm[2]);
- p->out.b2aluo->lookup(p->out.b2aluo, tdevv, pcsvm);
+ p->out.b2aluo->lookup(p->out.b2aluo, tdevv, pcsvm);
//printf("~1 resulting dev %f %f %f %f\n", tdevv[0], tdevv[1], tdevv[2], tdevv[3]);
- if (p->out.locus) {
- double tpcsv[MAX_CHAN];
- icxLuLut *lu = (icxLuLut *)p->out.luo; /* Safe to coerce */
+ if (p->out.locus) {
+ double tpcsv[MAX_CHAN];
+ icxLuLut *lu = (icxLuLut *)p->out.luo; /* Safe to coerce */
- /* Convert PCS to PCS' ready for locus lookup */
- lu->in_abs(lu, tpcsv, pcsvm);
- lu->matrix(lu, tpcsv, tpcsv);
- lu->input(lu, tpcsv, tpcsv);
- lu->clut_locus(lu, locus, tpcsv, tdevv); /* Compute locus values */
- } else {
- for (i = 0; i < p->out.chan; i++) /* Target is K value */
- locus[i] = tdevv[i];
- }
+ /* Convert PCS to PCS' ready for locus lookup */
+ lu->in_abs(lu, tpcsv, pcsvm);
+ lu->matrix(lu, tpcsv, tpcsv);
+ lu->input(lu, tpcsv, tpcsv);
+ lu->clut_locus(lu, locus, tpcsv, tdevv); /* Compute locus values */
+ } else {
+ for (i = 0; i < p->out.chan; i++) /* Target is K value */
+ locus[i] = tdevv[i];
+ }
#ifdef DEBUG
- DEBUGCND printf("Got possible K %s of %f %f %f %f\n",p->out.locus ? "locus" : "value", locus[0],locus[1],locus[2],locus[3]);
+ DEBUGCND printf("Got possible K %s of %f %f %f %f\n",p->out.locus ? "locus" : "value", locus[0],locus[1],locus[2],locus[3]);
#endif
- }
+ }
- /* Do PCS -> DevOut' */
- if (p->nhack == 3 /* All to K only */
- || ntrig /* Neutral or K only to K only hack has triggered */
- || cmytrig /* 100% CMY rough hack has triggered */
- || rgbbktrig) { /* RGB black inpu thas triggered */
-
- if (p->nhack == 3 || ntrig) { /* Neutral to K only hack has triggered */
- co pp;
- pp.p[0] = pcsvm[0]; /* Input L value */
- p->pcs2k->interp(p->pcs2k, &pp); /* L -> K' */
- if (pp.v[0] < 0.0) /* rspl might have extrapolated */
- pp.v[0] = 0.0;
- else if (pp.v[0] > 1.0)
- pp.v[0] = 1.0;
- out[0] = out[1] = out[2] = 0.0; /* We know output is CMYK' */
- out[3] = pp.v[0];
+ /* Do PCS -> DevOut' */
+ if (p->nhack == 3 /* All to K only */
+ || ntrig /* Neutral or K only to K only hack has triggered */
+ || cmytrig /* 100% CMY rough hack has triggered */
+ || rgbbktrig) { /* RGB black inpu thas triggered */
+
+ if (p->nhack == 3 || ntrig) { /* Neutral to K only hack has triggered */
+ co pp;
+ pp.p[0] = pcsvm[0]; /* Input L value */
+ p->pcs2k->interp(p->pcs2k, &pp); /* L -> K' */
+ if (pp.v[0] < 0.0) /* rspl might have extrapolated */
+ pp.v[0] = 0.0;
+ else if (pp.v[0] > 1.0)
+ pp.v[0] = 1.0;
+ out[0] = out[1] = out[2] = 0.0; /* We know output is CMYK' */
+ out[3] = pp.v[0];
#ifndef DEBUG
- if (p->verb)
+ if (p->verb)
#endif
- if (ntrig) {
- printf("Neutral hack mapped %s to 0 0 0 %f\n", icmPdv(p->in.chan,win), out[3]);
- fflush(stdout);
- }
- } else if (cmytrig) { /* 100% CMY rough hack has triggered */
- if (cmytrig & 1) {
- out[0] = 1.0;
- out[1] = out[2] = out[3] = 0.0;
- }
- if (cmytrig & 2) {
- out[1] = 1.0;
- out[0] = out[2] = out[3] = 0.0;
- }
- if (cmytrig & 4) {
- out[2] = 1.0;
- out[0] = out[1] = out[3] = 0.0;
- }
+ if (ntrig) {
+ printf("Neutral hack mapped %s to 0 0 0 %f\n", icmPdv(p->in.chan,win), out[3]);
+ fflush(stdout);
+ }
+ } else if (cmytrig) { /* 100% CMY rough hack has triggered */
+ if (cmytrig & 1) {
+ out[0] = 1.0;
+ out[1] = out[2] = out[3] = 0.0;
+ }
+ if (cmytrig & 2) {
+ out[1] = 1.0;
+ out[0] = out[2] = out[3] = 0.0;
+ }
+ if (cmytrig & 4) {
+ out[2] = 1.0;
+ out[0] = out[1] = out[3] = 0.0;
+ }
#ifndef DEBUG
- if (p->verb)
+ if (p->verb)
#endif
- if (cmytrig != 0) {
- if (p->in.chan == 4)
- printf("CMY hack mapped %s to %s\n",icmPdv(p->in.chan, win), icmPdv(p->out.chan, out));
- fflush(stdout);
+ if (cmytrig != 0) {
+ if (p->in.chan == 4)
+ printf("CMY hack mapped %s to %s\n",icmPdv(p->in.chan, win), icmPdv(p->out.chan, out));
+ fflush(stdout);
+ }
+ } else if (rgbbktrig) {
+ out[0] = out[1] = out[2] = 0.0;
}
- } else if (rgbbktrig) {
- out[0] = out[1] = out[2] = 0.0;
- }
#ifdef DEBUG
- DEBUGCND printf("DevOut' after hack trigger %s\n\n",icmPdv(p->out.chan, out));
+ DEBUGCND printf("DevOut' after hack trigger %s\n\n",icmPdv(p->out.chan, out));
#endif
- } else { /* Various hacks haven't triggered */
+ } else { /* Various hacks haven't triggered */
- switch(p->out.alg) {
- case icmMonoBwdType: {
- icxLuMono *lu = (icxLuMono *)p->out.luo; /* Safe to coerce */
+ switch(p->out.alg) {
+ case icmMonoBwdType: {
+ icxLuMono *lu = (icxLuMono *)p->out.luo; /* Safe to coerce */
- rv |= lu->bwd_abs(lu, pcsvm, pcsvm);
- rv |= lu->bwd_map(lu, out, pcsvm);
- if (p->out.nocurve) { /* No explicit curve, so do implicit here */
- rv |= lu->bwd_curve(lu, out, out);
- }
- break;
- }
- case icmMatrixBwdType: {
- icxLuMatrix *lu = (icxLuMatrix *)p->out.luo; /* Safe to coerce */
-
- rv |= lu->bwd_abs(lu, pcsvm, pcsvm);
- rv |= lu->bwd_matrix(lu, out, pcsvm);
- if (p->out.nocurve) { /* No explicit curve, so do implicit here */
- rv |= lu->bwd_curve(lu, out, out);
+ rv |= lu->bwd_abs(lu, pcsvm, pcsvm);
+ rv |= lu->bwd_map(lu, out, pcsvm);
+ if (p->out.nocurve) { /* No explicit curve, so do implicit here */
+ rv |= lu->bwd_curve(lu, out, out);
+ }
+ break;
}
- break;
- }
- case icmLutType: {
- icxLuLut *lu = (icxLuLut *)p->out.luo; /* Safe to coerce */
+ case icmMatrixBwdType: {
+ icxLuMatrix *lu = (icxLuMatrix *)p->out.luo; /* Safe to coerce */
- if (p->mode < 2) { /* Using B2A table */
- rv |= lu->in_abs(lu, pcsvm, pcsvm);
- rv |= lu->matrix(lu, pcsvm, pcsvm);
- rv |= lu->input(lu, pcsvm, pcsvm);
- rv |= lu->clut(lu, out, pcsvm);
+ rv |= lu->bwd_abs(lu, pcsvm, pcsvm);
+ rv |= lu->bwd_matrix(lu, out, pcsvm);
if (p->out.nocurve) { /* No explicit curve, so do implicit here */
- rv |= lu->output(lu, out, out);
+ rv |= lu->bwd_curve(lu, out, out);
}
+ break;
+ }
+ case icmLutType: {
+ icxLuLut *lu = (icxLuLut *)p->out.luo; /* Safe to coerce */
- } else { /* Use inverse A2B table */
- int i;
+ if (p->mode < 2) { /* Using B2A table */
+ rv |= lu->in_abs(lu, pcsvm, pcsvm);
+ rv |= lu->matrix(lu, pcsvm, pcsvm);
+ rv |= lu->input(lu, pcsvm, pcsvm);
+ rv |= lu->clut(lu, out, pcsvm);
+ if (p->out.nocurve) { /* No explicit curve, so do implicit here */
+ rv |= lu->output(lu, out, out);
+ }
+
+ } else { /* Use inverse A2B table */
+ int i;
#ifdef USE_MERGE_CLUT_OPT
# pragma message("!!!!!!!!!!!! USE_MERGE_CLUT_OPT turned on !!!!!!!!!")
- /* Because we have used the ICX_MERGE_CLUT flag, we don't need */
- /* to call inv_out_abs() and inv_output() */
+ /* Because we have used the ICX_MERGE_CLUT flag, we don't need */
+ /* to call inv_out_abs() and inv_output() */
#else
- rv |= lu->inv_out_abs(lu, pcsvm, pcsvm);
- rv |= lu->inv_output(lu, pcsvm, pcsvm);
+ rv |= lu->inv_out_abs(lu, pcsvm, pcsvm);
+ rv |= lu->inv_output(lu, pcsvm, pcsvm);
#endif
#ifdef DEBUG
- DEBUGCND printf("Calling inv_clut with K aux targets %f %f %f %f and pcsvm %f %f %f %f\n",
- locus[0],locus[1],locus[2],locus[3],pcsvm[0],pcsvm[1],pcsvm[2],pcsvm[3]);
+ DEBUGCND printf("Calling inv_clut with K aux targets %f %f %f %f and pcsvm %f %f %f %f\n",
+ locus[0],locus[1],locus[2],locus[3],pcsvm[0],pcsvm[1],pcsvm[2],pcsvm[3]);
#endif
- /* locus[] contains possible K target or locus value, */
- /* so copy it to out[] so that inv_clut will use it. */
- for (i = 0; i < p->out.chan; i++)
- out[i] = locus[i];
+ /* locus[] contains possible K target or locus value, */
+ /* so copy it to out[] so that inv_clut will use it. */
+ for (i = 0; i < p->out.chan; i++)
+ out[i] = locus[i];
- rv |= lu->inv_clut(lu, out, pcsvm);
+ rv |= lu->inv_clut(lu, out, pcsvm);
#ifdef DEBUG
- DEBUGCND printf("Got result %f %f %f %f\n", out[0],out[1],out[2],out[3]);
+ DEBUGCND printf("Got result %f %f %f %f\n", out[0],out[1],out[2],out[3]);
#endif
-
- if (p->out.nocurve) { /* No explicit curve, so do implicit here */
- rv |= lu->inv_input(lu, out, out);
+
+ if (p->out.nocurve) { /* No explicit curve, so do implicit here */
+ rv |= lu->inv_input(lu, out, out);
+ }
}
+ break;
}
- break;
- }
- default:
- error("Unexpected algorithm type %d in devop of devip_devop()",p->out.alg);
- }
- if (rv >= 2)
- error("icc lookup failed: %d, %s",p->in.c->errc,p->in.c->err);
+ default:
+ error("Unexpected algorithm type %d in devop of devip_devop()",p->out.alg);
+ }
+ if (rv >= 2)
+ error("icc lookup failed: %d, %s",p->in.c->errc,p->in.c->err);
#ifdef DEBUG
- DEBUGCND printf("DevOut' after PCS->Dev %s\n\n",icmPdv(p->out.chan, out));
+ DEBUGCND printf("DevOut' after PCS->Dev %s\n\n",icmPdv(p->out.chan, out));
#endif
- }
+ }
- if (p->cal != NULL && p->addcal == 1 && p->out.nocurve) {
- p->cal->interp(p->cal, out, out);
+ /* Apply calibration curve */
+ if (p->cal != NULL && p->addcal == 1 && p->out.nocurve) {
+ p->cal->interp(p->cal, out, out);
#ifdef DEBUG
- DEBUGCND printf("DevOut' after cal curve %s\n\n",icmPdv(p->out.chan, out));
+ DEBUGCND printf("DevOut' after cal curve %s\n\n",icmPdv(p->out.chan, out));
#endif
- }
-
- /* Video encode */
- if (p->out.nocurve && p->out.tvenc != 0) {
- for (i = 0; i < p->out.chan; i++) {
- if (out[i] < 0.0)
- out[i] = 0.0;
- else if (out[i] > 1.0)
- out[i] = 1.0;
- }
- if (p->out.tvenc == 1) { /* Video 16-235 range */
- icmRGB_2_VidRGB(out, out);
- } else if (p->out.tvenc == 3) { /* Rec601 YCbCr */
- icmRec601_RGBd_2_YPbPr(out, out);
- icmRecXXX_YPbPr_2_YCbCr(out, out);
- } else if (p->out.tvenc == 4) { /* Rec709 1150/60/2:1 YCbCr */
- icmRec709_RGBd_2_YPbPr(out, out);
- icmRecXXX_YPbPr_2_YCbCr(out, out);
- } else if (p->out.tvenc == 5) { /* Rec709 1250/50/2:1 YCbCr */
- icmRec709_50_RGBd_2_YPbPr(out, out);
- icmRecXXX_YPbPr_2_YCbCr(out, out);
- } else if (p->out.tvenc == 6) { /* Rec2020 Non-constant Luminance YCbCr encoding */
- icmRec2020_NCL_RGBd_2_YPbPr(out, out);
- icmRecXXX_YPbPr_2_YCbCr(out, out);
- } else if (p->out.tvenc == 7) { /* Rec2020 Constant Luminance YCbCr encoding */
- icmRec2020_CL_RGBd_2_YPbPr(out, out);
- icmRecXXX_YPbPr_2_YCbCr(out, out);
}
+ /* Video encode */
+ if (p->out.nocurve && p->out.tvenc != 0) {
+ for (i = 0; i < p->out.chan; i++) {
+ if (out[i] < 0.0)
+ out[i] = 0.0;
+ else if (out[i] > 1.0)
+ out[i] = 1.0;
+ }
+ if (p->out.tvenc == 1) { /* Video 16-235 range */
+ icmRGB_2_VidRGB(out, out);
+ } else if (p->out.tvenc == 3) { /* Rec601 YCbCr */
+ icmRec601_RGBd_2_YPbPr(out, out);
+ icmRecXXX_YPbPr_2_YCbCr(out, out);
+ } else if (p->out.tvenc == 4) { /* Rec709 1150/60/2:1 YCbCr */
+ icmRec709_RGBd_2_YPbPr(out, out);
+ icmRecXXX_YPbPr_2_YCbCr(out, out);
+ } else if (p->out.tvenc == 5) { /* Rec709 1250/50/2:1 YCbCr */
+ icmRec709_50_RGBd_2_YPbPr(out, out);
+ icmRecXXX_YPbPr_2_YCbCr(out, out);
+ } else if (p->out.tvenc == 6) { /* Rec2020 Non-constant Luminance YCbCr encoding */
+ icmRec2020_NCL_RGBd_2_YPbPr(out, out);
+ icmRecXXX_YPbPr_2_YCbCr(out, out);
+ } else if (p->out.tvenc == 7) { /* Rec2020 Constant Luminance YCbCr encoding */
+ icmRec2020_CL_RGBd_2_YPbPr(out, out);
+ icmRecXXX_YPbPr_2_YCbCr(out, out);
+ }
+
#ifdef NEVER
- else if (p->out.tvenc == 8) { /* SD xvYCC with Rec601 YCbCr encoding */
- icmRec601_RGBd_2_YPbPr(out, out);
- icmRecXXX_YPbPr_2_YCbCr(out, out);
- } else if (p->out.tvenc == 9) { /* HD xvYCC with Rec709 YCbCr encoding */
- icmRec709_RGBd_2_YPbPr(out, out);
- icmRecXXX_YPbPr_2_YCbCr(out, out);
- }
+ else if (p->out.tvenc == 8) { /* SD xvYCC with Rec601 YCbCr encoding */
+ icmRec601_RGBd_2_YPbPr(out, out);
+ icmRecXXX_YPbPr_2_YCbCr(out, out);
+ } else if (p->out.tvenc == 9) { /* HD xvYCC with Rec709 YCbCr encoding */
+ icmRec709_RGBd_2_YPbPr(out, out);
+ icmRecXXX_YPbPr_2_YCbCr(out, out);
+ }
#endif /* NEVER */
#ifdef DEBUG
- DEBUGCND printf("DevOut' after TVenc %s\n",icmPdv(p->out.chan, out));
+ DEBUGCND printf("DevOut' after TVenc %s\n",icmPdv(p->out.chan, out));
#endif
- }
+ }
- if (clip && p->out.nocurve && p->out.tvenc != 0) {
+ if (clip && p->out.nocurve && p->out.tvenc != 0) {
- /* For RGB encoding, unscale +ve clip to preserve hue */
- if (p->out.tvenc == 1) { /* RGB Video 16-235 range */
+ /* For RGB encoding, unscale +ve clip to preserve hue */
+ if (p->out.tvenc == 1) { /* RGB Video 16-235 range */
- if (!p->in.tvclip && scale > 1.0) { /* We got +ve clipping */
+ if (!p->in.tvclip && scale > 1.0) { /* We got +ve clipping */
- /* Re-scale all non-black values */
- for (i = 0; i < 3; i++) {
- if (out[i] > (16.0/255.0))
- out[i] = (out[i] - 16.0/255.0) * scale + 16.0/255.0;
+ /* Re-scale all non-black values */
+ for (i = 0; i < 3; i++) {
+ if (out[i] > (16.0/255.0))
+ out[i] = (out[i] - 16.0/255.0) * scale + 16.0/255.0;
+ }
}
- }
- /* Deal with -ve clipping and sync */
- for (i = 0; i < 3; i++) {
- if (clip & (1 << i)) {
+ /* Deal with -ve clipping and sync */
+ for (i = 0; i < 3; i++) {
+ if (clip & (1 << i)) {
- if (full[i] == 0.0) { /* Only extrapolate in black direction */
- double ifull = 1.0 - full[i]; /* Opposite limit to full */
+ if (full[i] == 0.0) { /* Only extrapolate in black direction */
+ double ifull = 1.0 - full[i]; /* Opposite limit to full */
+
+ /* Do simple extrapolation (Not perfect though) */
+ out[i] = ifull + (out[i] - ifull) * (uci[i] - ifull)/(cin[i] - ifull);
+ }
- /* Do simple extrapolation (Not perfect though) */
- out[i] = ifull + (out[i] - ifull) * (uci[i] - ifull)/(cin[i] - ifull);
- }
-
- /* Clip or pass sync through */
- if (out[i] < 0.0 || out[i] > 1.0 /* clip */
+ /* Clip or pass sync through */
+ if (out[i] < 0.0 || out[i] > 1.0 /* clip */
#ifdef PRESERVE_SYNC
- || fabs(uci[i] - full[i]) < 1e-6 /* or input is at sync level */
+ || fabs(uci[i] - full[i]) < 1e-6 /* or input is at sync level */
#endif
- )
- out[i] = full[i];
+ )
+ out[i] = full[i];
+ }
}
- }
- /* For YCrCb, do simple linear extrapolation of out of range input. */
- /* (Note we should really change this to preserve hue instead !) */
- } else {
- for (i = 0; i < 3; i++) {
- if (clip & (1 << i)) {
- double ifull = 1.0 - full[i]; /* Opposite limit to full */
-
- /* Do simple extrapolation (Not perfect though) */
- out[i] = ifull + (out[i] - ifull) * (uci[i] - ifull)/(cin[i] - ifull);
-
- if (out[i] < 0.0 || out[i] > 1.0 /* clip */
+ /* For YCrCb, do simple linear extrapolation of out of range input. */
+ /* (Note we should really change this to preserve hue instead !) */
+ } else {
+ for (i = 0; i < 3; i++) {
+ if (clip & (1 << i)) {
+ double ifull = 1.0 - full[i]; /* Opposite limit to full */
+
+ /* Do simple extrapolation (Not perfect though) */
+ out[i] = ifull + (out[i] - ifull) * (uci[i] - ifull)/(cin[i] - ifull);
+
+ if (out[i] < 0.0 || out[i] > 1.0 /* clip */
#ifdef PRESERVE_SYNC
- || fabs(uci[i] - full[i]) < 1e-6 /* or input is at sync level */
+ || fabs(uci[i] - full[i]) < 1e-6 /* or input is at sync level */
#endif
- )
- out[i] = full[i];
+ )
+ out[i] = full[i];
+ }
}
}
- }
#ifdef DEBUG
- DEBUGCND printf("DevOut' after TVenc un-clip %s\n",icmPdv(p->out.chan, out));
+ DEBUGCND printf("DevOut' after TVenc un-clip %s\n",icmPdv(p->out.chan, out));
#endif
- }
+ }
- /* For eeColor and Full range RGB, make sure that the cLUT output maps to 1.0 */
- /* The output curve will correct this, irrespective of out.nocurve */
- if (p->tdlut == 1) { /* eeColor encoded input */
- /* ~~ it's not clear if this re-scaling would help with other */
- /* encodings like xvYCC ? */
- if (p->out.tvenc == 0) { /* Full range RGB */
- for (i = 0; i < 3; i++) {
- out[i] /= p->coscale[i];
- if (out[i] > 1.0)
- out[i] = 1.0;
- }
+ /* For eeColor and Full range RGB, make sure that the cLUT output maps to 1.0 */
+ /* The output curve will correct this, irrespective of out.nocurve */
+ if (p->tdlut == 1) { /* eeColor encoded input */
+ /* ~~ it's not clear if this re-scaling would help with other */
+ /* encodings like xvYCC ? */
+ if (p->out.tvenc == 0) { /* Full range RGB */
+ for (i = 0; i < 3; i++) {
+ out[i] /= p->coscale[i];
+ if (out[i] > 1.0)
+ out[i] = 1.0;
+ }
#ifdef DEBUG
- DEBUGCND printf("DevOut' after eeColor de-scale %s\n\n",icmPdv(p->out.chan, out));
+ DEBUGCND printf("DevOut' after eeColor de-scale %s\n\n",icmPdv(p->out.chan, out));
#endif
+ }
}
- }
- /* lcurve is incompatible with coscale and tvenc ?? */
- if (p->out.lcurve) { /* Apply Y to L* to make output perceptual */
+ /* lcurve is incompatible with coscale and tvenc ?? */
+ if (p->out.lcurve) { /* Apply Y to L* to make output perceptual */
#ifdef DEBUG
- DEBUGCND printf("DevOut' before y2l_curve %s\n\n",icmPdv(p->out.chan, out));
+ DEBUGCND printf("DevOut' before y2l_curve %s\n\n",icmPdv(p->out.chan, out));
#endif
- y2l_curve(out, out, p->out.lcurve == 2);
- }
+ y2l_curve(out, out, p->out.lcurve == 2);
+ }
#ifdef DEBUG
- DEBUGCND printf("DevIn'->DevOut' ret %s\n\n",icmPdv(p->out.chan, out));
+ DEBUGCND printf("DevIn'->DevOut' ret %s\n\n",icmPdv(p->out.chan, out));
#endif
+ } /* Not calonly */
+
if (p->verb) { /* Output percent intervals */
int pc;
p->count++;
@@ -1694,6 +1718,7 @@ void devop_devo(void *cntx, double *out, double *in) {
#ifdef DEBUG
DEBUGCND printf("After output curve %s\n",icmPdv(p->out.chan, out));
#endif
+
/* Apply calibration curve */
if (p->cal != NULL && p->addcal == 1) {
p->cal->interp(p->cal, out, out);
@@ -1711,7 +1736,15 @@ void devop_devo(void *cntx, double *out, double *in) {
DEBUGCND printf("After Video encode %s\n",icmPdv(p->out.chan, out));
}
#endif
+
+ /* Apply calibration curve */
+ } else if (p->calonly && p->cal != NULL && p->addcal == 1) {
+ p->cal->interp(p->cal, out, out);
+#ifdef DEBUG
+ DEBUGCND printf("After calibration curve %s\n",icmPdv(p->out.chan, out));
+#endif
}
+
#ifdef DEBUG
DEBUGCND printf("DevOut'->DevOut ret %s\n",icmPdv(p->out.chan, out));
#endif
@@ -1841,13 +1874,13 @@ int write_cube_3DLut(clink *li, icc *icc, char *fname);
int
main(int argc, char *argv[]) {
int fa, nfa, mfa; /* argument we're looking at */
- char in_name[MAXNAMEL+1];
+ char in_name[MAXNAMEL+1] = "\000";
char sgam_name[MAXNAMEL+1] = "\000"; /* Source gamut name */
char abs_name[MAXNAMEL+1] = "\000"; /* Abstract profile name */
char cal_name[MAXNAMEL+1] = "\000"; /* Calibration filename */
- char out_name[MAXNAMEL+1];
- char link_name[MAXNAMEL+1];
- char tdlut_name[MAXNAMEL+1];
+ char out_name[MAXNAMEL+1] = "\000";
+ char link_name[MAXNAMEL+1] = "\000";
+ char tdlut_name[MAXNAMEL+1] = "\000";
int verify = 0; /* Do verify pass */
int outinkset = 0; /* The user specfied an output inking */
int intentset = 0; /* The user specified an intent */
@@ -1855,6 +1888,7 @@ main(int argc, char *argv[]) {
int modeset = 0; /* The gamut mapping mode was set by the user */
int addcal = 0; /* 1 = Incorporate cal. curves in 3dLUT and set linear MadVR cal1 */
/* 2 = Set 3dLut MadVR cal1 to calibration curves */
+ int calonly = 0; /* calibration curve only - no ICC profile linking */
int rv = 0;
icxViewCond ivc, ovc; /* Viewing Condition Overrides for in and out profiles */
int ivc_e = -1, ovc_e = -1; /* Enumerated viewing condition */
@@ -1946,7 +1980,7 @@ main(int argc, char *argv[]) {
/* Process the arguments */
mfa = 3; /* Minimum final arguments */
- for(fa = 1;fa < argc;fa++) {
+ for (fa = 1; fa < argc; fa++) {
nfa = fa; /* skip to nfa if next argument is used */
if (argv[fa][0] == '-') { /* Look for any flags */
@@ -2100,10 +2134,23 @@ main(int argc, char *argv[]) {
/* Calibration curves */
else if (argv[fa][1] == 'a'
+ || argv[fa][1] == 'O'
|| argv[fa][1] == 'H') {
addcal = 1;
if (argv[fa][1] == 'H')
addcal = 2;
+ if (argv[fa][1] == 'O') {
+ calonly = 1;
+
+ /* Hmm. Make on the fly change to mfa... */
+ mfa = 1;
+ if (na == NULL && (fa+1+mfa) < argc) {
+ if (argv[fa+1][0] != '-') {
+ nfa = fa + 1;
+ na = argv[nfa]; /* next is seperate non-flag argument */
+ }
+ }
+ }
if (na == NULL) usage("Expected calibration filename after -%c",argv[fa][1]);
fa = nfa;
strncpy(cal_name,na,MAXNAMEL); cal_name[MAXNAMEL] = '\000';
@@ -2577,12 +2624,21 @@ main(int argc, char *argv[]) {
}
#endif
- if (fa >= argc || argv[fa][0] == '-') usage("Missing input profile");
- strncpy(in_name,argv[fa++],MAXNAMEL); in_name[MAXNAMEL] = '\000';
+ /* Is this a link created just from a calibration file ? */
+ if (calonly) { /* yes */
+ li.calonly = calonly;
- if (fa >= argc || argv[fa][0] == '-') usage("Missing output profile");
- strncpy(out_name,argv[fa++],MAXNAMEL); out_name[MAXNAMEL] = '\000';
+ /* no */
+ } else {
+ /* Get the ICC source & destination profile names */
+ if (fa >= argc || argv[fa][0] == '-') usage("Missing input profile");
+ strncpy(in_name,argv[fa++],MAXNAMEL); in_name[MAXNAMEL] = '\000';
+
+ if (fa >= argc || argv[fa][0] == '-') usage("Missing output profile");
+ strncpy(out_name,argv[fa++],MAXNAMEL); out_name[MAXNAMEL] = '\000';
+ }
+ /* Get the resulting link profile name */
if (fa >= argc || argv[fa][0] == '-') usage("Missing result profile");
strncpy(link_name,argv[fa++],MAXNAMEL); link_name[MAXNAMEL] = '\000';
@@ -2910,68 +2966,6 @@ main(int argc, char *argv[]) {
usage("Can't use 'white point hack' and Luminence scaling intent together");
/* - - - - - - - - - - - - - - - - - - - */
- /* Open up the input device profile for reading, and read header etc. */
- if ((li.in.c = read_embedded_icc(in_name)) == NULL)
- error ("Can't open file '%s'",in_name);
- li.in.h = li.in.c->header;
-
- /* Check that it is a suitable device input icc */
- if (li.in.h->deviceClass != icSigInputClass
- && li.in.h->deviceClass != icSigDisplayClass
- && li.in.h->deviceClass != icSigOutputClass
- && li.in.h->deviceClass != icSigColorSpaceClass) /* For sRGB etc. */
- error("Input profile '%s' isn't a device profile",in_name);
-
- /* Wrap with an expanded icc */
- if ((li.in.x = new_xicc(li.in.c)) == NULL)
- error ("Creation of input profile xicc failed");
-
- /* Set the default ink limits if not set on command line */
- icxDefaultLimits(li.in.x, &li.in.ink.tlimit, li.in.ink.tlimit, &li.in.ink.klimit, li.in.ink.klimit);
-
- if (li.verb) {
- if (li.in.ink.tlimit >= 0.0)
- printf("Input total ink limit assumed is %3.0f%%\n",100.0 * li.in.ink.tlimit);
- if (li.in.ink.klimit >= 0.0)
- printf("Input black ink limit assumed is %3.0f%%\n",100.0 * li.in.ink.klimit);
- }
-
- /* - - - - - - - - - - - - - - - - - - - */
- /* Open up the abstract profile if requested */
- if (abs_name[0] != '\000') {
- if ((li.abs_fp = new_icmFileStd_name(abs_name,"r")) == NULL)
- error ("Can't open abstract profile file '%s'",abs_name);
-
- if ((li.abs_icc = new_icc()) == NULL)
- error ("Creation of Abstract profile ICC object failed");
-
- /* Read header etc. */
- if ((rv = li.abs_icc->read(li.abs_icc,li.abs_fp,0)) != 0)
- error ("%d, %s",rv,li.abs_icc->err);
-
- if (li.abs_icc->header->deviceClass != icSigAbstractClass)
- error("Abstract profile isn't an abstract profile");
-
- /* Take intended abstract intent from profile itself */
- if ((li.abs_intent = li.abs_icc->header->renderingIntent) != icAbsoluteColorimetric)
- li.abs_intent = icRelativeColorimetric;
-
- /* Wrap with an expanded icc */
- if ((li.abs_xicc = new_xicc(li.abs_icc)) == NULL)
- error ("Creation of abstract profile xicc failed");
- }
- /* - - - - - - - - - - - - - - - - - - - */
- /* Open up the output device output profile for reading, and read header etc. */
- if ((li.out.c = read_embedded_icc(out_name)) == NULL)
- error ("Can't open file '%s'",out_name);
- li.out.h = li.out.c->header;
-
- if (li.out.h->deviceClass != icSigInputClass
- && li.out.h->deviceClass != icSigDisplayClass
- && li.out.h->deviceClass != icSigOutputClass
- && li.out.h->deviceClass != icSigColorSpaceClass) /* For sRGB etc. */
- error("Output profile isn't a device profile");
-
/* Grab the calibration if requested */
if (addcal) {
if ((li.cal = new_xcal()) == NULL)
@@ -2986,194 +2980,261 @@ main(int argc, char *argv[]) {
/* and we don't currently have a way of detecting this */
}
- /* Wrap with an expanded icc */
- if ((li.out.x = new_xicc(li.out.c)) == NULL)
- error ("Creation of output profile xicc failed");
+ if (!calonly) {
- /* Set the default ink limits if not set on command line */
- icxDefaultLimits(li.out.x, &li.out.ink.tlimit, li.out.ink.tlimit, &li.out.ink.klimit, li.out.ink.klimit);
+ /* Open up the input device profile for reading, and read header etc. */
+ if ((li.in.c = read_embedded_icc(in_name)) == NULL)
+ error ("Can't open file '%s'",in_name);
+ li.in.h = li.in.c->header;
- if (li.verb) {
- if (li.out.ink.tlimit >= 0.0)
- printf("Output total ink limit assumed is %3.0f%%\n",100.0 * li.out.ink.tlimit);
- if (li.out.ink.klimit >= 0.0)
- printf("Output black ink limit assumed is %3.0f%%\n",100.0 * li.out.ink.klimit);
- }
+ /* Check that it is a suitable device input icc */
+ if (li.in.h->deviceClass != icSigInputClass
+ && li.in.h->deviceClass != icSigDisplayClass
+ && li.in.h->deviceClass != icSigOutputClass
+ && li.in.h->deviceClass != icSigColorSpaceClass) /* For sRGB etc. */
+ error("Input profile '%s' isn't a device profile",in_name);
- /* deal with output black generation. */
- /* Ink limits will have been set in option parsing */
+ /* Wrap with an expanded icc */
+ if ((li.in.x = new_xicc(li.in.c)) == NULL)
+ error ("Creation of input profile xicc failed");
- switch (li.out.inking) {
- case 0: /* Use input profile K level or locus */
- /* Sanity check */
- if (li.in.h->colorSpace != li.out.h->colorSpace)
- error("Can't transfer black ink in & out unless the same colorspaces");
- li.out.ink.k_rule = li.out.locus ? icxKlocus : icxKvalue; /* Given as aux parameter in PCS -> Device */
- break;
- case 7: /* Use output profile K level or locus */
- li.out.ink.k_rule = li.out.locus ? icxKlocus : icxKvalue; /* Given as aux parameter in PCS -> Device */
- break;
- case 1: /* Minimum K */
- li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k;
- li.out.ink.c.Kstle = 0.0;
- li.out.ink.c.Kstpo = 0.0;
- li.out.ink.c.Kenpo = 1.0;
- li.out.ink.c.Kenle = 0.0;
- li.out.ink.c.Kshap = 1.0;
- break;
- case 2: /* 0.5 K */
- li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k;
- li.out.ink.c.Kstle = 0.5;
- li.out.ink.c.Kstpo = 0.0;
- li.out.ink.c.Kenpo = 1.0;
- li.out.ink.c.Kenle = 0.5;
- li.out.ink.c.Kshap = 1.0;
- break;
- case 3: /* Maximum K */
- li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k;
- li.out.ink.c.Kstle = 1.0;
- li.out.ink.c.Kstpo = 0.0;
- li.out.ink.c.Kenpo = 1.0;
- li.out.ink.c.Kenle = 1.0;
- li.out.ink.c.Kshap = 1.0;
- break;
- case 4: /* Ramp K */
- li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k;
- li.out.ink.c.Kstle = 0.0;
- li.out.ink.c.Kstpo = 0.0;
- li.out.ink.c.Kenpo = 1.0;
- li.out.ink.c.Kenle = 1.0;
- li.out.ink.c.Kshap = 1.0;
- break;
- case 5: /* Curve */
- li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k;
- break; /* Other params already set by options */
- case 6: /* Use input profile K locus + dual curve limits */
- /* Sanity check */
- if (li.in.h->colorSpace != li.out.h->colorSpace)
- error("Can't transfer black ink in & out unless the same colorspaces");
- li.out.ink.k_rule = li.out.locus ? icxKl5l : icxKl5lk; /* Aux param in PCS -> Device */
- break; /* Other params already set by options */
- }
+ /* Set the default ink limits if not set on command line */
+ icxDefaultLimits(li.in.x, &li.in.ink.tlimit, li.in.ink.tlimit, &li.in.ink.klimit, li.in.ink.klimit);
- for (i = 0; i < 2; i++) {
- xicc *x;
- icxViewCond *v, *vc;
- int es;
- int *set;
-
- if (i == 0) {
- v = &ivc; /* Override parameters */
- vc = &li.in.vc; /* Target parameters */
- set = &li.in.vc_set;
- es = ivc_e;
- x = li.in.x; /* xicc */
- } else {
- v = &ovc; /* Override parameters */
- vc = &li.out.vc; /* Target parameters */
- set = &li.out.vc_set;
- es = ovc_e;
- x = li.out.x; /* xicc */
- }
-
- /* Set the default viewing conditions */
- xicc_enum_viewcond(x, vc, -1, NULL, 0, NULL);
-
- /* Override the default viewing conditions. */
- /* (?? Could move this code into xicc_enum_viewcond() as an option ??) */
- /* First any enumerated selection */
- if (es != -1) {
- if (xicc_enum_viewcond(x, vc, es, NULL, 0, NULL) == -999)
- error ("%d, %s",x->errc, x->err);
- *set = 1;
- }
- /* Then any individual paramaters */
- if (v->Ev >= 0) {
- vc->Ev = v->Ev;
- *set = 1;
- }
- if (v->Wxyz[0] >= 0.0 && v->Wxyz[1] > 0.0 && v->Wxyz[2] >= 0.0) {
- /* Normalise XYZ to current media white */
- vc->Wxyz[0] = v->Wxyz[0]/v->Wxyz[1] * vc->Wxyz[1];
- vc->Wxyz[2] = v->Wxyz[2]/v->Wxyz[1] * vc->Wxyz[1];
- *set = 1;
- }
- if (v->Wxyz[0] >= 0.0 && v->Wxyz[1] >= 0.0 && v->Wxyz[2] < 0.0) {
- /* Convert Yxy to XYZ */
- double x = v->Wxyz[0];
- double y = v->Wxyz[1]; /* If Y == 1.0, then X+Y+Z = 1/y */
- double z = 1.0 - x - y;
- vc->Wxyz[0] = x/y * vc->Wxyz[1];
- vc->Wxyz[2] = z/y * vc->Wxyz[1];
- *set = 1;
- }
- if (v->La >= 0.0) {
- vc->La = v->La;
- *set = 1;
- }
- if (v->Yb >= 0.0) {
- vc->Yb = v->Yb;
- *set = 1;
- }
- if (v->Lv >= 0.0) {
- vc->Lv = v->Lv;
- *set = 1;
- }
- if (v->Yf >= 0.0) {
- vc->Yf = v->Yf;
- *set = 1;
- }
- if (v->Yg >= 0.0) {
- vc->Yg = v->Yg;
- *set = 1;
- }
- if (v->Gxyz[0] >= 0.0 && v->Gxyz[1] > 0.0 && v->Gxyz[2] >= 0.0) {
- /* Normalise XYZ to current media white */
- vc->Gxyz[0] = v->Gxyz[0]/v->Gxyz[1] * vc->Gxyz[1];
- vc->Gxyz[2] = v->Gxyz[2]/v->Gxyz[1] * vc->Gxyz[1];
- *set = 1;
- }
- if (v->Gxyz[0] >= 0.0 && v->Gxyz[1] >= 0.0 && v->Gxyz[2] < 0.0) {
- /* Convert Yxy to XYZ */
- double x = v->Gxyz[0];
- double y = v->Gxyz[1]; /* If Y == 1.0, then X+Y+Z = 1/y */
- double z = 1.0 - x - y;
- vc->Gxyz[0] = x/y * vc->Gxyz[1];
- vc->Gxyz[2] = z/y * vc->Gxyz[1];
- *set = 1;
+ if (li.verb) {
+ if (li.in.ink.tlimit >= 0.0)
+ printf("Input total ink limit assumed is %3.0f%%\n",100.0 * li.in.ink.tlimit);
+ if (li.in.ink.klimit >= 0.0)
+ printf("Input black ink limit assumed is %3.0f%%\n",100.0 * li.in.ink.klimit);
}
- if (v->hkscale >= 0.0) {
- vc->hkscale = v->hkscale;
- *set = 1;
+ /* - - - - - - - - - - - - - - - - - - - */
+ /* Open up the abstract profile if requested */
+ if (abs_name[0] != '\000') {
+ if ((li.abs_fp = new_icmFileStd_name(abs_name,"r")) == NULL)
+ error ("Can't open abstract profile file '%s'",abs_name);
+
+ if ((li.abs_icc = new_icc()) == NULL)
+ error ("Creation of Abstract profile ICC object failed");
+
+ /* Read header etc. */
+ if ((rv = li.abs_icc->read(li.abs_icc,li.abs_fp,0)) != 0)
+ error ("%d, %s",rv,li.abs_icc->err);
+
+ if (li.abs_icc->header->deviceClass != icSigAbstractClass)
+ error("Abstract profile isn't an abstract profile");
+
+ /* Take intended abstract intent from profile itself */
+ if ((li.abs_intent = li.abs_icc->header->renderingIntent) != icAbsoluteColorimetric)
+ li.abs_intent = icRelativeColorimetric;
+
+ /* Wrap with an expanded icc */
+ if ((li.abs_xicc = new_xicc(li.abs_icc)) == NULL)
+ error ("Creation of abstract profile xicc failed");
}
- if (v->mtaf >= 0.0) {
- vc->mtaf = v->mtaf;
- *set = 1;
+ /* - - - - - - - - - - - - - - - - - - - */
+ /* Open up the output device output profile for reading, and read header etc. */
+ if ((li.out.c = read_embedded_icc(out_name)) == NULL)
+ error ("Can't open file '%s'",out_name);
+ li.out.h = li.out.c->header;
+
+ if (li.out.h->deviceClass != icSigInputClass
+ && li.out.h->deviceClass != icSigDisplayClass
+ && li.out.h->deviceClass != icSigOutputClass
+ && li.out.h->deviceClass != icSigColorSpaceClass) /* For sRGB etc. */
+ error("Output profile isn't a device profile");
+
+ /* Wrap with an expanded icc */
+ if ((li.out.x = new_xicc(li.out.c)) == NULL)
+ error ("Creation of output profile xicc failed");
+
+ /* Set the default ink limits if not set on command line */
+ icxDefaultLimits(li.out.x, &li.out.ink.tlimit, li.out.ink.tlimit, &li.out.ink.klimit, li.out.ink.klimit);
+
+ if (li.verb) {
+ if (li.out.ink.tlimit >= 0.0)
+ printf("Output total ink limit assumed is %3.0f%%\n",100.0 * li.out.ink.tlimit);
+ if (li.out.ink.klimit >= 0.0)
+ printf("Output black ink limit assumed is %3.0f%%\n",100.0 * li.out.ink.klimit);
}
- if (v->Wxyz2[0] >= 0.0 && v->Wxyz2[1] > 0.0 && v->Wxyz2[2] >= 0.0) {
- /* Normalise XYZ */
- vc->Wxyz2[0] = v->Wxyz2[0]/v->Wxyz2[1] * vc->Wxyz2[1];
- vc->Wxyz2[2] = v->Wxyz2[2]/v->Wxyz2[1] * vc->Wxyz2[1];
- *set = 1;
+
+ /* deal with output black generation. */
+ /* Ink limits will have been set in option parsing */
+
+ switch (li.out.inking) {
+ case 0: /* Use input profile K level or locus */
+ /* Sanity check */
+ if (li.in.h->colorSpace != li.out.h->colorSpace)
+ error("Can't transfer black ink in & out unless the same colorspaces");
+ li.out.ink.k_rule = li.out.locus ? icxKlocus : icxKvalue; /* Given as aux parameter in PCS -> Device */
+ break;
+ case 7: /* Use output profile K level or locus */
+ li.out.ink.k_rule = li.out.locus ? icxKlocus : icxKvalue; /* Given as aux parameter in PCS -> Device */
+ break;
+ case 1: /* Minimum K */
+ li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k;
+ li.out.ink.c.Kstle = 0.0;
+ li.out.ink.c.Kstpo = 0.0;
+ li.out.ink.c.Kenpo = 1.0;
+ li.out.ink.c.Kenle = 0.0;
+ li.out.ink.c.Kshap = 1.0;
+ break;
+ case 2: /* 0.5 K */
+ li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k;
+ li.out.ink.c.Kstle = 0.5;
+ li.out.ink.c.Kstpo = 0.0;
+ li.out.ink.c.Kenpo = 1.0;
+ li.out.ink.c.Kenle = 0.5;
+ li.out.ink.c.Kshap = 1.0;
+ break;
+ case 3: /* Maximum K */
+ li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k;
+ li.out.ink.c.Kstle = 1.0;
+ li.out.ink.c.Kstpo = 0.0;
+ li.out.ink.c.Kenpo = 1.0;
+ li.out.ink.c.Kenle = 1.0;
+ li.out.ink.c.Kshap = 1.0;
+ break;
+ case 4: /* Ramp K */
+ li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k;
+ li.out.ink.c.Kstle = 0.0;
+ li.out.ink.c.Kstpo = 0.0;
+ li.out.ink.c.Kenpo = 1.0;
+ li.out.ink.c.Kenle = 1.0;
+ li.out.ink.c.Kshap = 1.0;
+ break;
+ case 5: /* Curve */
+ li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k;
+ break; /* Other params already set by options */
+ case 6: /* Use input profile K locus + dual curve limits */
+ /* Sanity check */
+ if (li.in.h->colorSpace != li.out.h->colorSpace)
+ error("Can't transfer black ink in & out unless the same colorspaces");
+ li.out.ink.k_rule = li.out.locus ? icxKl5l : icxKl5lk; /* Aux param in PCS -> Device */
+ break; /* Other params already set by options */
}
- if (v->Wxyz2[0] >= 0.0 && v->Wxyz2[1] >= 0.0 && v->Wxyz2[2] < 0.0) {
- /* Convert Yxy to XYZ */
- double x = v->Wxyz2[0];
- double y = v->Wxyz2[1]; /* If Y == 1.0, then X+Y+Z = 1/y */
- double z = 1.0 - x - y;
- vc->Wxyz2[0] = x/y * vc->Wxyz2[1];
- vc->Wxyz2[2] = z/y * vc->Wxyz2[1];
- *set = 1;
+
+ /* Deal with source & dest viewing conditions */
+ for (i = 0; i < 2; i++) {
+ xicc *x;
+ icxViewCond *v, *vc;
+ int es;
+ int *set;
+
+ if (i == 0) {
+ v = &ivc; /* Override parameters */
+ vc = &li.in.vc; /* Target parameters */
+ set = &li.in.vc_set;
+ es = ivc_e;
+ x = li.in.x; /* xicc */
+ } else {
+ v = &ovc; /* Override parameters */
+ vc = &li.out.vc; /* Target parameters */
+ set = &li.out.vc_set;
+ es = ovc_e;
+ x = li.out.x; /* xicc */
+ }
+
+ /* Set the default viewing conditions */
+ xicc_enum_viewcond(x, vc, -1, NULL, 0, NULL);
+
+ /* Override the default viewing conditions. */
+ /* (?? Could move this code into xicc_enum_viewcond() as an option ??) */
+ /* First any enumerated selection */
+ if (es != -1) {
+ if (xicc_enum_viewcond(x, vc, es, NULL, 0, NULL) == -999)
+ error ("%d, %s",x->errc, x->err);
+ *set = 1;
+ }
+ /* Then any individual paramaters */
+ if (v->Ev >= 0) {
+ vc->Ev = v->Ev;
+ *set = 1;
+ }
+ if (v->Wxyz[0] >= 0.0 && v->Wxyz[1] > 0.0 && v->Wxyz[2] >= 0.0) {
+ /* Normalise XYZ to current media white */
+ vc->Wxyz[0] = v->Wxyz[0]/v->Wxyz[1] * vc->Wxyz[1];
+ vc->Wxyz[2] = v->Wxyz[2]/v->Wxyz[1] * vc->Wxyz[1];
+ *set = 1;
+ }
+ if (v->Wxyz[0] >= 0.0 && v->Wxyz[1] >= 0.0 && v->Wxyz[2] < 0.0) {
+ /* Convert Yxy to XYZ */
+ double x = v->Wxyz[0];
+ double y = v->Wxyz[1]; /* If Y == 1.0, then X+Y+Z = 1/y */
+ double z = 1.0 - x - y;
+ vc->Wxyz[0] = x/y * vc->Wxyz[1];
+ vc->Wxyz[2] = z/y * vc->Wxyz[1];
+ *set = 1;
+ }
+ if (v->La >= 0.0) {
+ vc->La = v->La;
+ *set = 1;
+ }
+ if (v->Yb >= 0.0) {
+ vc->Yb = v->Yb;
+ *set = 1;
+ }
+ if (v->Lv >= 0.0) {
+ vc->Lv = v->Lv;
+ *set = 1;
+ }
+ if (v->Yf >= 0.0) {
+ vc->Yf = v->Yf;
+ *set = 1;
+ }
+ if (v->Yg >= 0.0) {
+ vc->Yg = v->Yg;
+ *set = 1;
+ }
+ if (v->Gxyz[0] >= 0.0 && v->Gxyz[1] > 0.0 && v->Gxyz[2] >= 0.0) {
+ /* Normalise XYZ to current media white */
+ vc->Gxyz[0] = v->Gxyz[0]/v->Gxyz[1] * vc->Gxyz[1];
+ vc->Gxyz[2] = v->Gxyz[2]/v->Gxyz[1] * vc->Gxyz[1];
+ *set = 1;
+ }
+ if (v->Gxyz[0] >= 0.0 && v->Gxyz[1] >= 0.0 && v->Gxyz[2] < 0.0) {
+ /* Convert Yxy to XYZ */
+ double x = v->Gxyz[0];
+ double y = v->Gxyz[1]; /* If Y == 1.0, then X+Y+Z = 1/y */
+ double z = 1.0 - x - y;
+ vc->Gxyz[0] = x/y * vc->Gxyz[1];
+ vc->Gxyz[2] = z/y * vc->Gxyz[1];
+ *set = 1;
+ }
+
+ if (v->hkscale >= 0.0) {
+ vc->hkscale = v->hkscale;
+ *set = 1;
+ }
+ if (v->mtaf >= 0.0) {
+ vc->mtaf = v->mtaf;
+ *set = 1;
+ }
+ if (v->Wxyz2[0] >= 0.0 && v->Wxyz2[1] > 0.0 && v->Wxyz2[2] >= 0.0) {
+ /* Normalise XYZ */
+ vc->Wxyz2[0] = v->Wxyz2[0]/v->Wxyz2[1] * vc->Wxyz2[1];
+ vc->Wxyz2[2] = v->Wxyz2[2]/v->Wxyz2[1] * vc->Wxyz2[1];
+ *set = 1;
+ }
+ if (v->Wxyz2[0] >= 0.0 && v->Wxyz2[1] >= 0.0 && v->Wxyz2[2] < 0.0) {
+ /* Convert Yxy to XYZ */
+ double x = v->Wxyz2[0];
+ double y = v->Wxyz2[1]; /* If Y == 1.0, then X+Y+Z = 1/y */
+ double z = 1.0 - x - y;
+ vc->Wxyz2[0] = x/y * vc->Wxyz2[1];
+ vc->Wxyz2[2] = z/y * vc->Wxyz2[1];
+ *set = 1;
+ }
}
- }
+
+ } /* Not calonly */
if (li.verb)
printf("Configured options\n");
/* - - - - - - - - - - - - - - - - - - - */
/* Setup the profile color lookup information */
- {
+ if (!calonly) {
icmLuAlgType oalg; /* Native output algorithm */
icColorSpaceSignature natpcs; /* Underlying native output PCS */
int flb = 0, fl = 0; /* luobj flags */
@@ -3542,9 +3603,23 @@ main(int argc, char *argv[]) {
}
/* - - - - - - - - - - - - - - - - - - - */
- /* Sanity checking */
+ if (calonly) { /* Fudge the in & out settings */
+ li.in.csp = li.cal->colspace;
+ li.in.chan = li.cal->devchan;
+ li.in.nocurve = 1;
+ li.in.lcurve = 0;
+ li.in.bt1886 = 0;
- if (li.cal != NULL) {
+ li.out.csp = li.cal->colspace;
+ li.out.chan = li.cal->devchan;
+ li.out.nocurve = 1;
+ li.out.lcurve = 0;
+ li.out.bt1886 = 0;
+
+ li.mode = 0; /* Simple mode */
+
+ /* Sanity checking */
+ } else if (li.cal != NULL) {
if (li.cal->colspace != li.out.csp) {
error("Calibration space %s doesn't match output profile %s",
icm2str(icmColorSpaceSignature, li.cal->colspace),
@@ -3905,12 +3980,14 @@ main(int argc, char *argv[]) {
if (li.in.tvenc >= 3) {
wh->colorSpace = icSigYCbCrData; /* Use YCbCr encoding */
} else {
- wh->colorSpace = li.in.h->colorSpace; /* Input profile device space */
+// wh->colorSpace = li.in.h->colorSpace; /* Input profile device space */
+ wh->colorSpace = li.in.csp; /* Input profile device space */
}
if (li.out.tvenc >= 3) {
wh->pcs = icSigYCbCrData; /* Use YCbCr encoding */
} else {
- wh->pcs = li.out.h->colorSpace; /* Output profile device space */
+// wh->pcs = li.out.h->colorSpace; /* Output profile device space */
+ wh->pcs = li.out.csp; /* Output profile device space */
}
if (li.mode > 0) {
wh->renderingIntent = li.gmi.icci; /* Closest ICC intent */
@@ -4009,8 +4086,21 @@ main(int argc, char *argv[]) {
wo->allocate((icmBase *)wo);/* Allocate space */
strcpy(wo->desc, dst); /* Copy the string in */
}
+
/* ProfileSequenceDescTag: */
- {
+ if (li.calonly) { /* Fake one up */
+ unsigned int i;
+ icmProfileSequenceDesc *wo;
+ if ((wo = (icmProfileSequenceDesc *)wr_icc->add_tag(
+ wr_icc, icSigProfileSequenceDescTag, icSigProfileSequenceDescType)) == NULL)
+ return 1;
+
+ wo->count = 2; /* Number of descriptions in sequence */
+ if (wo->allocate((icmBase *)wo) != 0) /* Allocate space for all the DescStructures */
+ error("allocate failed: %d, %s",wr_icc->errc,wr_icc->err);
+
+ /* Real one */
+ } else {
unsigned int i;
icmProfileSequenceDesc *wo;
if ((wo = (icmProfileSequenceDesc *)wr_icc->add_tag(
@@ -4107,7 +4197,7 @@ main(int argc, char *argv[]) {
}
}
/* ColorantTable: */
- {
+ if (!li.calonly) {
int i;
unsigned int j;
int repclip = 0;
@@ -4560,8 +4650,10 @@ main(int argc, char *argv[]) {
#endif /* USE_APXLS */
0,
&li, /* Context */
- li.in.h->colorSpace, /* Input color space */
- li.out.h->colorSpace, /* Output color space */
+// li.in.h->colorSpace, /* Input color space */
+ li.in.csp, /* Input color space */
+// li.out.h->colorSpace, /* Output color space */
+ li.out.csp, /* Output color space */
devi_devip, /* Input transfer tables devi->devi' */
NULL, NULL, /* Use default input colorspace range */
devip_devop, /* devi' -> devo' transfer function */
@@ -4840,15 +4932,21 @@ main(int argc, char *argv[]) {
li.cal->del(li.cal);
}
- li.in.luo->del(li.in.luo);
- li.in.x->del(li.in.x);
- li.in.c->del(li.in.c);
+ if (li.in.luo != NULL)
+ li.in.luo->del(li.in.luo);
+ if (li.in.x != NULL)
+ li.in.x->del(li.in.x);
+ if (li.in.c != NULL)
+ li.in.c->del(li.in.c);
if (li.out.b2aluo != NULL)
li.out.b2aluo->del(li.out.b2aluo);
- li.out.luo->del(li.out.luo);
- li.out.x->del(li.out.x);
- li.out.c->del(li.out.c);
+ if (li.out.luo != NULL)
+ li.out.luo->del(li.out.luo);
+ if (li.out.x != NULL)
+ li.out.x->del(li.out.x);
+ if (li.out.c != NULL)
+ li.out.c->del(li.out.c);
return 0;
}
diff --git a/log.txt b/log.txt
index 16a181c..9a77d82 100755
--- a/log.txt
+++ b/log.txt
@@ -2,11 +2,49 @@
Argyll CMS change log
=====================
-Version 2.1.0 Beta
--------------
+Not included yet:
+----------------
* Started adding comms for Lumagen Radiance detection.
+Version 2.0.1 9th July 2018
+-------------
+
+* Increased maximum render channels to 16
+
+* Added -O option to collink to allow creating a link
+ purely from calibration file.
+
+* Fixed JETI specbos & specval timeout when in averaging mode
+ and dark measurement.
+
+* Changed JETI specval 1511 driver to ignore REMOTE command
+ error with newer firmware.
+
+* Changed Klein K10 serial parameters in attempt to prevent
+ serial lock up on MSWindows.
+
+* Made a failure of the conf:maxtin command with a JETI 1201
+ a soft error, to allow for old firmware versions.
+
+* Change colorhug Linux driver to reset on close. This may overcome
+ a problem re-starting the driver.
+
+* Fixed i1Pro driver to cope with stripped down OEM i1Pro2 that is missing
+ one piece of calibration information.
+
+* Fixed display calibration selection to allow for more
+ than 62 entries. This is to fix problem using Klein K10
+ that has a lot of saved calibrations.
+
+* Changed spec2cie to add extra informational L*a*b* output fields, if
+ a non D50 illuminant (-i option) is used.
+
+* Added -w parameter to spotread, to use the -i parameter illuminant
+ for L*a*b* calculation.
+
+* Fixed bug in spec2cie - XRGA conversion wasn't saving spectrum out.
+
Version 2.0.0 17th November 2017
-------------
diff --git a/makepackagebin.sh b/makepackagebin.sh
index 2688bf4..192e89a 100755
--- a/makepackagebin.sh
+++ b/makepackagebin.sh
@@ -177,11 +177,18 @@ if [ X$USETAR = "Xtrue" ] ; then
fi
# tar -xzf to extract
# tar -tzf to list
+ # to update a file:
+ # gzip -d archive.tgz
+ # tar -uf application.tar file
+ # gzip application.tar
+ # mv application.tar.gz application.tgz
+ # or "tgzupdate.sh application"
# Should we use "COPYFILE_DISABLE=1 tar .." on OS X ??
else
zip -9 -r $PACKAGE $TOPDIR
# unzip to extract
# unzip -l to list
+ # zip archive.zip file to update
fi
rm -rf $TOPDIR
echo "Done GNU Argyll binary distribution $PACKAGE"
diff --git a/namedc/namedc.c b/namedc/namedc.c
index 2fc7796..7f8967f 100755
--- a/namedc/namedc.c
+++ b/namedc/namedc.c
@@ -710,7 +710,7 @@ static int read_cxf(namedc *p, const char *filename, int options) {
else if (strcmp(name, "FieldOfView_10_Degree") == 0)
p->obs = icxOT_CIE_1964_10;
else {
- a1logd(p->log, 2, "read_cxf: Illuminant '%s' unrecognised\n",name);
+ a1logd(p->log, 2, "read_cxf: Observer '%s' unrecognised\n",name);
p->obs = icxOT_CIE_1931_2;
}
}
@@ -784,7 +784,7 @@ static int read_cxf(namedc *p, const char *filename, int options) {
else if (strcmp(name, "10_Degree") == 0)
p->obs = icxOT_CIE_1964_10;
else {
- a1logd(p->log, 2, "read_cxf: Illuminant '%s' unrecognised\n",name);
+ a1logd(p->log, 2, "read_cxf: Observer '%s' unrecognised\n",name);
p->obs = icxOT_CIE_1931_2;
}
}
@@ -1087,7 +1087,7 @@ int match(struct _namedc *p, double *de, double *pLab, xspect *rspect, int deTyp
if (rspect != NULL) {
if (p->sp2cie == NULL) {
- if ((p->sp2cie = new_xsp2cie(p->ill, NULL, p->obs, NULL, icSigLabData, 0)) == NULL) {
+ if ((p->sp2cie = new_xsp2cie(p->ill, 0.0, NULL, p->obs, NULL, icSigLabData, 0)) == NULL) {
snprintf(p->err, NAMEDC_ERRL, "creating spetral conversion failed");
a1logd(p->log, 1, "match: %s\n",p->err);
return -1;
@@ -1109,7 +1109,7 @@ int match(struct _namedc *p, double *de, double *pLab, xspect *rspect, int deTyp
xsp2cie *tt;
xspect ts;
// Get the XYZ of the given white point for the illuminant and observer
- if ((tt = new_xsp2cie(p->ill, NULL, p->obs, NULL, icSigXYZData, 0)) == NULL) {
+ if ((tt = new_xsp2cie(p->ill, 0.0, NULL, p->obs, NULL, icSigXYZData, 0)) == NULL) {
snprintf(p->err, NAMEDC_ERRL, "creating spetral conversion failed");
a1logd(p->log, 1, "match: %s\n",p->err);
return -1;
diff --git a/numlib/Jamfile b/numlib/Jamfile
index 2d5edaf..e2a06fd 100755
--- a/numlib/Jamfile
+++ b/numlib/Jamfile
@@ -20,13 +20,13 @@ Headers = numlib.h libui.h ;
HDRS = ../h ;
# Numeric library
-Library libnum.lib : numsup.c dnsq.c powell.c dhsx.c varmet.c ludecomp.c svd.c zbrent.c rand.c sobol.c aatree.c quadprog.c ;
+Library libnum.lib : numsup.c dnsq.c powell.c dhsx.c varmet.c ludecomp.c svd.c zbrent.c rand.c sobol.c aatree.c quadprog.c gnewt.c roots.c ;
# Link all utilities with libnum
LINKLIBS = libnum ;
# All test programs are made from a single source file
-MainsFromSources dnsqtest.c tpowell.c tdhsx.c LUtest.c svdtest.c zbrenttest.c soboltest.c qptest.c ;
+MainsFromSources dnsqtest.c tpowell.c tconjgrad.c tdhsx.c LUtest.c svdtest.c zbrenttest.c soboltest.c qptest.c ;
# Compile .c as .m
if $(OS) = MACOSX {
diff --git a/numlib/afiles b/numlib/afiles
index b2138b2..e427b7d 100755
--- a/numlib/afiles
+++ b/numlib/afiles
@@ -4,6 +4,8 @@ afiles
Jamfile
dnsq.c
dnsq.h
+gnewt.c
+gnewt.h
dnsqtest.c
numlib.h
numsup.c
@@ -11,6 +13,7 @@ numsup.h
powell.h
powell.c
tpowell.c
+tconjgrad.c
varmet.h
varmet.c
dhsx.h
@@ -35,5 +38,7 @@ aatree.c
quadprog.h
quadprog.c
qptest.c
+roots.h
+roots.c
ui.h
ui.c
diff --git a/numlib/dhsx.c b/numlib/dhsx.c
index e9da0eb..aa9f462 100755
--- a/numlib/dhsx.c
+++ b/numlib/dhsx.c
@@ -20,7 +20,7 @@
#undef DEBUG
-int dhsx_debug = 1;
+int dhsx_debug = 0;
static void simplexinit(int di, double *cp, double **p, double *r, double sv, int ii);
static double trypoint(int di,double *cp, double **p, double *y, int hix, double hpfac,
@@ -92,9 +92,15 @@ void *fdata /* Data needed by function */
lox = i;
}
tryy = (*funk)(fdata, cp); /* Value at initial point */
+#ifdef DEBUG
+ if (dhsx_debug) printf(" initial point %s = %e\n",debPdv(di,cp),tryy);
+#endif /* DEBUG */
/* If our initial point is better than any of the simplex verticies */
if (y[lox] > tryy) {
+#ifdef DEBUG
+ if (dhsx_debug) printf(" initial point is better than surrounding simplex\n");
+#endif /* DEBUG */
/* Move all the verticies to match moving lox to cp */
for (i = 0; i < nsp; i++) {
if (i == lox)
@@ -263,6 +269,9 @@ void *fdata /* Data needed by function */
for (j = 0; j < di; j++)
cp[j] = p[lox][j];
}
+#ifdef DEBUG
+ else if (dhsx_debug) printf("C point val %f is best\n",tryy);
+#endif
free_dvector(y2, 0, nsp-1);
free_dmatrix(p2, 0, nsp-1, 0, di-1);
free_dvector(y, 0, nsp-1);
diff --git a/numlib/dhsx.h b/numlib/dhsx.h
index 78cdb10..8a4e1ff 100755
--- a/numlib/dhsx.h
+++ b/numlib/dhsx.h
@@ -14,9 +14,9 @@
/* return 0 on sucess, 1 on failure due to excessive itterations */
/* Result will be in cp */
int dhsx(
- double *rv, /* If not NULL, return the residual error */
- int di, /* Dimentionality */
- double *cp, /* Initial starting point, return minimum */
+ double *rv, /* If not NULL, return the residual error */
+ int di, /* Dimentionality */
+ double *cp, /* Initial starting point, return minimum */
double *s, /* Size of initial search area */
double ftol, /* Finishing tollerance of error change */
double athr, /* Absolute return value threshold. (Set high to not use) */
diff --git a/numlib/dnsq.c b/numlib/dnsq.c
index 75f00a8..31bebe4 100755
--- a/numlib/dnsq.c
+++ b/numlib/dnsq.c
@@ -112,6 +112,7 @@ int dnsqe(
info = 4;
if (info == 0)
warning("dnsqe: invalid input parameter.");
+
return info;
} /* dnsqe */
diff --git a/numlib/dnsq.h b/numlib/dnsq.h
index e06e562..28dd5de 100755
--- a/numlib/dnsq.h
+++ b/numlib/dnsq.h
@@ -84,7 +84,8 @@ int dnsq_jac( /* Return < 0 on abort */
);
#define M_LARGE 1.79e+308
-#define M_DIVER 2.22e-15
+#define M_DIVER 2.22e-15 /* Machine precision (10 x IEEE double) */
+#define M_SQRT_DIVER 4.71e-8 /* sqrt(M_DIVER) */
/* Simplified dnsq() */
int dnsqe(
diff --git a/numlib/dnsqtest.c b/numlib/dnsqtest.c
index 3f02819..f05bed4 100755
--- a/numlib/dnsqtest.c
+++ b/numlib/dnsqtest.c
@@ -74,7 +74,7 @@ int main(void)
/* Unless high precision solutions are required, */
/* this is the recommended setting. */
- tol = sqrt(M_DIVER);
+ tol = M_SQRT_DIVER;
info = dnsqe(NULL, fcn, NULL, n, x, ss, fvec, tol, tol, 0, nprint);
fnorm = denorm(n, fvec);
diff --git a/numlib/gnewt.c b/numlib/gnewt.c
new file mode 100755
index 0000000..c95cec7
--- /dev/null
+++ b/numlib/gnewt.c
@@ -0,0 +1,413 @@
+
+/*
+ * Copyright 2018 Graeme Gill
+ * All rights reserved.
+ *
+ * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
+ * see the License.txt file for licencing details.
+ */
+
+#include "numsup.h"
+#include "ludecomp.h"
+#include "gnewt.h" /* Public interface definitions */
+
+#undef DEBUG
+
+#ifdef DEBUG
+# define DBG(xx) printf xx;
+#else
+# define DBG(xx)
+#endif
+
+
+#define TOLX 1.0e-7 /* Convergence criterion on delx */
+#define STPMX 100.0 /* Maximum step multiplier */
+
+static void apxjac(int n, double *x, double *fvec, double **df, void *fdata,
+ void (*fcn)(void *fdata, int n, double *x, double *fvec));
+
+static int linesearch(int n, double *xold, double fold, double *delf, double *delx,
+ double *x, double *fvec, double *fp, double maxstep, void *fdata,
+ void (*fcn)(void *fdata, int n, double *x, double *f), int *pfit, int maxjac, int it);
+
+#define FMAX(A, B) ((A) > (B) ? (A) : (B))
+
+int gnewt(
+ void *fdata, /* Opaque pointer to pass to fcn() and jac() */
+ void (*fcn)(void *fdata, int n, double *x, double *fvec),
+ /* Pointer to function we are solving */
+ void (*jac)(void *fdata, int n, double *x, double **fjac),
+ /* Function to compute jacobian */
+ int n, /* Number of functions and variables */
+ double x[], /* Initial solution estimate, returns final solution */
+ double rfvec[], /* Optionaly return soln. function values */
+ double xtol, /* Desired tollerance of root */
+ double ftol, /* Desired tollerance of the solution */
+ int maxfcn, /* Maximum number of function itterations */
+ int maxjac /* Maximum number of jacobian itterations */
+) {
+ int i, j, it, fit, jit, *pivx, _pivx[10];
+ double f, fold; /* half magnitide squared of fvec[] */
+ double *delf, _delf[10]; /* del f where f = 0.5 F.F */
+ double *fvec, _fvec[10]; /* F(x) */
+ double **fjac, *_fjac[11], __fjac[10 * 10];
+ double *xold, _xold[10];
+ double bigfx, bigx, maxstep;
+ double *delx, _delx[10]; /* Full step delta x */
+ double sum;
+ int rv = 0;
+
+#ifdef DEBUG
+ double *fvec_check;
+ double **fjac_check;
+#endif
+
+ DBG(("gnewt:\n"))
+
+ fit = jit = 0;
+
+ /* Do local vector/array allocations */
+ if (n <= 10) {
+ pivx = _pivx;
+ if (rfvec == NULL) {
+ fvec = _fvec;
+ } else
+ fvec = rfvec;
+ _fjac[0] = __fjac;
+ fjac = _fjac+1; /* dmatrix_reset() will setup fjac */
+ xold = _xold;
+ delf = _delf;
+ delx = _delx;
+ } else {
+ pivx = ivector(0, n-1); /* LU decomp. pivod record */
+ if (rfvec == NULL) {
+ fvec = dvector(0, n-1); /* Function value */
+ } else
+ fvec = rfvec;
+ fjac = dmatrix(0, n-1, 0, n-1); /* Jacobian matrix */
+ xold = dvector(0, n-1); /* Previous value of x[] */
+ delf = dvector(0, n-1); /* del f */
+ delx = dvector(0, n-1); /* Full step delta x */
+ }
+#ifdef DEBUG
+ fvec_check = dvector(0, n-1);
+ fjac_check = dmatrix(0, n-1, 0, n-1);
+#endif
+
+ /* Initial function value */
+ fcn(fdata, n, x, fvec);
+ fit++;
+
+ DBG((" x %s\n",debPdv(n,x)))
+ DBG((" fvec %s\n",debPdv(n,fvec)))
+
+ /* Compute half magnitide squared of function value at x */
+ for (sum = 0.0, i = 0; i < n; i++)
+ sum += fvec[i] * fvec[i];
+ f = 0.5 * sum;
+ DBG((" f %f\n",f))
+
+ /* test for initial value being a root */
+ for (bigfx = 0.0, i = 0; i < n; i++) {
+ double tt = fabs(fvec[i]);
+ if (tt > bigfx)
+ bigfx = tt;
+ }
+ if (bigfx < (0.01 * ftol)) {
+ goto done;
+ }
+
+ /* Compute line search x maximum step size */
+ for (sum = 0.0, i = 0 ; i < n; i++)
+ sum += x[i] * x[i];
+ maxstep = STPMX * FMAX(sqrt(sum), (double)n);
+ DBG((" maxstep %f\n",maxstep))
+
+ /* Until we are done */
+ for (it = 0; fit < maxfcn && jit < maxjac; it++) {
+ double rip;
+
+ DBG((" fit %d jit %d\n",fit,jit))
+
+ /* Compute Jacobian matrix */
+ if (jac != NULL) {
+ /* lu_decomp may have swapped rows - so fix it */
+ dmatrix_reset(fjac, 0, n-1, 0, n-1);
+ jac(fdata, n, x, fjac); /* User function */
+ } else {
+ apxjac(n, x, fvec, fjac, fdata, fcn); /* Numerical aproximation */
+ }
+ jit++;
+
+#ifdef DEBUG
+ copy_dmatrix(fjac_check, fjac, 0, n-1, 0, n-1);
+
+ DBG((" fjac = \n"))
+ for (i = 0; i < n; i++)
+ DBG((" %d: %s\n",i,debPdv(n, fjac[i])))
+ DBG(("\n"))
+#endif
+
+ /* Compute del f for the line search. */
+ for (i = 0; i < n; i++) {
+ for (sum = 0.0, j = 0; j < n; j++)
+ sum += fjac[j][i] * fvec[j]; /* Hmm. df/dx . f */
+ delf[i] = sum;
+ }
+
+ /* Save current values of x and f to be able to monitor progres */
+ for (i = 0; i < n; i++)
+ xold[i] = x[i];
+ fold = f;
+
+ /* Desired delta f to make F(x) == 0 */
+ for (i = 0; i < n; i++)
+ delx[i] = -fvec[i];
+ DBG((" -fvec %s\n",debPdv(n,delx)))
+
+ /* Solve for delta x using Jacobian and desired delta f */
+ if (lu_decomp(fjac, n, pivx, &rip)) {
+ rv = 2;
+ goto done;
+ }
+ lu_backsub(fjac, n, pivx, delx);
+ DBG((" delx %s\n",debPdv(n,delx)))
+
+#ifdef DEBUG
+ matrix_vect_mult(fvec_check, n, fjac_check, n, n, delx, n);
+ DBG((" check -fvec : %s\n\n",debPdv(n,fvec_check)))
+#endif
+
+ if ((rv = linesearch(n, xold, fold, delf, delx, x, fvec, &f, maxstep, fdata, fcn,
+ &fit, maxfcn, it)) != 0) {
+ if (rv != 1) { /* Not run out of itterations error */
+ DBG((" linesearch failed with %d\n",rv))
+ goto done;
+ }
+ }
+
+ DBG((" after linesearch:\n"))
+ DBG((" x %s\n",debPdv(n,x)))
+ DBG((" fvec %s\n",debPdv(n,fvec)))
+
+ /* See if f() has converged */
+ for (bigfx = 0.0, i = 0; i < n; i++) {
+ if (fabs(fvec[i]) > bigfx)
+ bigfx = fabs(fvec[i]);
+ }
+ DBG((" bigfx %f ftol %f\n",bigfx,ftol))
+ if (bigfx < ftol) {
+ goto done;
+ }
+
+ /* Could check for zero gradient problem here... */
+
+ /* See if x[] has converged */
+ for (bigx = 0.0, i = 0; i < n; i++) {
+ double tt = (fabs(x[i] - xold[i]))/FMAX(fabs(x[i]), 1.0);
+ if (tt > bigx)
+ bigx = tt;
+ }
+ DBG((" bigx %f xtol %f\n",bigx,xtol))
+ if (bigx < xtol)
+ goto done;
+ }
+
+ rv = 1;
+
+ done:;
+
+ if (n > 10) {
+ if (fvec != rfvec)
+ free_dvector(fvec, 0, n-1);
+ free_dvector(xold, 0, n-1);
+ free_dvector(delx, 0, n-1);
+ free_dvector(delf, 0, n-1);
+ free_dmatrix(fjac, 0, n-1, 0, n-1);
+ free_ivector(pivx, 0, n-1);
+ }
+#ifdef DEBUG
+ free_dvector(fvec_check,0, n-1);
+ free_dmatrix(fjac_check,0, n-1, 0, n-1);
+#endif
+
+ return rv;
+}
+
+/* - - - - - - - - */
+
+#define ALF 1.0e-4 /* Ensures sufficient decrease in function value. */
+
+/* Search for a step size that makes progress */
+/* Return nz on error */
+static int linesearch(
+ int n,
+ double *xold,
+ double fold,
+ double *delf, /* del f */
+ double *delx, /* full step delta x[] */
+ double *x, /* in/out current x[] */
+ double *fvec, /* return fvec at x[] */
+ double *fp, /* in/out f value */
+ double maxstep, /* maximum x step */
+ void *fdata, /* Context for fcn */
+ void (*fcn)(void *fdata, int n, double *x, double *f),
+ int *pfit, /* Inc number of itts */
+ int maxfcn, /* Max function its */
+ int it /* Caller iteration count */
+) {
+ int i;
+ double f = *fp, f2;
+ double lmda1, lmda2, min_lmda;
+ double sum, slope, bigx;
+
+ DBG(("linesearch:\n"))
+
+ /* Comute magnitude of step */
+ for (sum = 0.0, i = 0; i < n; i++)
+ sum += delx[i] * delx[i];
+ sum = sqrt(sum);
+
+ /* re-scale if step is too big */
+ if (sum > maxstep) {
+ for (i = 0; i < n; i++)
+ delx[i] *= maxstep/sum;
+ }
+
+ for (slope = 0.0, i = 0; i < n; i++)
+ slope += delf[i] * delx[i];
+ if (slope >= 0.0) {
+ DBG((" slope %f >= 0.0\n",slope))
+ return 3;
+ }
+
+ bigx = 0.0;
+ for (i = 0;i < n; i++) {
+ double tt = fabs(delx[i])/FMAX(fabs(xold[i]), 1.0);
+ if (tt > bigx)
+ bigx = tt;
+ }
+ min_lmda = TOLX/bigx;
+
+ /* Try full Newton step first */
+ lmda1 = 1.0;
+
+ DBG((" lmda1 %f min_lmda %f\n",lmda1, min_lmda))
+
+ /* Top of loop */
+ for (; *pfit < maxfcn; it++) {
+ double tmp_lmda;
+
+ DBG((" lmda1 %f\n",lmda1))
+
+ /* Take step */
+ for (i = 0;i < n;i++)
+ x[i] = xold[i] + lmda1 * delx[i];
+
+ /* Compute f = 0.5 F.F at x */
+ fcn(fdata, n, x, fvec);
+ (*pfit)++;
+ DBG((" x %s\n",debPdv(n,x)))
+ DBG((" fvec %s\n",debPdv(n,fvec)))
+ for (sum = 0.0, i = 0; i < n; i++)
+ sum += fvec[i] * fvec[i];
+ f = 0.5 * sum;
+
+//if (it == 0) printf(" linesearch: At 1st full step f %f -> %f\n", *fp, f);
+
+ /* Convergence on delx. */
+ if (lmda1 < min_lmda) {
+
+ for (i = 0; i < n; i++)
+ x[i] = xold[i];
+ return 0;
+
+ } else if (f <= fold + ALF * lmda1 * slope) {
+ *fp = f;
+ return 0; /* Sufficient function decrease */
+
+ } else { /* Backtrack. */
+ if (lmda1 == 1.0) /* First time */
+ tmp_lmda = -slope/(2.0 * (f - fold-slope));
+
+ else { /* Subsequent backtracks */
+ double c, d, e;
+ double a, b, rhs1, rhs2;
+
+ rhs1 = f - fold - slope * lmda1;
+ rhs2 = f2 - fold - slope * lmda2;
+ c = rhs1/(lmda1 * lmda1);
+ d = rhs2/(lmda2 * lmda2);
+ e = lmda1 - lmda2;
+ a = (c - d)/e;
+ b = (-lmda2 * c + lmda1 * d)/e;
+ if (a == 0.0)
+ tmp_lmda = -slope/(2.0 * b);
+ else {
+ double disc = b * b - 3.0 * a * slope;
+
+ if (disc < 0.0)
+ tmp_lmda = 0.5 * lmda1;
+ else if (b <= 0.0)
+ tmp_lmda = (-b + sqrt(disc))/(3.0 * a);
+ else
+ tmp_lmda = -slope/(b + sqrt(disc));
+ }
+ if (tmp_lmda > 0.5 * lmda1)
+ tmp_lmda = 0.5 * lmda1;
+ }
+ }
+ lmda2 = lmda1;
+ lmda1 = FMAX(tmp_lmda, lmda1 * 0.1);
+ f2 = f;
+ }
+
+ *fp = f;
+
+ return 1;
+}
+
+/* - - - - - - - - */
+
+/* Compute forward difference as aprox. Jacobian matrix */
+
+#define JEPS 1.0e-8 /* Aprox. sqrt of machine precision */
+
+static void apxjac(
+ int n, /* Dimensions */
+ double *x, /* Location x to compute Jacobian */
+ double *fvec, /* Function value at x */
+ double **df, /* Return Jacobian */
+ void *fdata, /* fcn() context */
+ void (*fcn)(void *fdata, int n, double *x, double *fvec)
+) {
+ int i, j;
+ double h, temp, *f, _f[10];
+
+ if (n <= 10)
+ f = _f;
+ else
+ f = dvector(0, n);
+
+ for (j = 0; j < n; j++) {
+ temp = x[j];
+
+ h = JEPS * fabs(temp);
+ if (h == 0.0)
+ h = JEPS;
+ x[j] = temp + h; /* Add delta */
+ h = x[j] - temp; /* Actual delta with fp precision limits */
+
+ fcn(fdata, n, x, f);
+
+ x[j] = temp; /* Restore value */
+
+ for (i = 0; i < n; i++)
+ df[i][j] = (f[i] - fvec[i])/h;
+ }
+
+ if (f != _f)
+ free_dvector(f, 0, n-1);
+}
+
+
diff --git a/numlib/gnewt.h b/numlib/gnewt.h
new file mode 100755
index 0000000..322d511
--- /dev/null
+++ b/numlib/gnewt.h
@@ -0,0 +1,59 @@
+#ifndef GNEWT_H
+#define GNEWT_H
+
+/* Global newton non-linear equation solver */
+
+/*
+ * Copyright 2018 Graeme W. Gill
+ * All rights reserved.
+ *
+ * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
+ * see the License.txt file for licencing details.
+ */
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*
+
+ return values:
+
+ 0 Success
+
+ 1 Ran out of itterations
+
+ 2 Inverting Jacobian failed
+
+ */
+
+int gnewt(
+ void *fdata, /* Opaque pointer to pass to fcn() and jac() */
+ void (*fcn)(void *fdata, int n, double *x, double *fvec),
+ /* Pointer to function we are solving */
+ void (*jac)(void *fdata, int n, double *x, double **fjac),
+ /* Function to compute jacobian */
+ int n, /* Number of functions and variables */
+ double x[], /* Initial solution estimate, returns final solution */
+ double rfvec[], /* Optionaly return soln. function values */
+ double xtol, /* Desired tollerance of root */
+ double ftol, /* Desired tollerance of the solution */
+ int maxfcn, /* Maximum number of function itterations */
+ int maxjac /* Maximum number of jacobian itterations */
+);
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* GNEWT_H */
+
+
+
+
+
+
+
+
+
+
diff --git a/numlib/ludecomp.c b/numlib/ludecomp.c
index b756bfe..06fc6a8 100755
--- a/numlib/ludecomp.c
+++ b/numlib/ludecomp.c
@@ -163,6 +163,7 @@ int n /* Dimensionality */
/* Decompose the square matrix A[][] into lower and upper triangles */
/* NOTE that it returns transposed inverse by normal convention. */
+/* NOTE that rows get swaped by swapping matrix pointers! */
/* Use sym_matrix_trans() to fix this. */
/* Return 1 if the matrix is singular. */
int
@@ -260,14 +261,14 @@ double *rip /* Row interchange parity, +/- 1.0, used for determinant */
return 0;
}
-/* Solve a set of simultaneous equations from the */
+/* Solve a set of simultaneous equations A.x = b from the */
/* LU decomposition, by back substitution. */
void
lu_backsub(
double **a, /* A[][] LU decomposed matrix */
int n, /* Dimensionality */
int *pivx, /* Pivoting row permutations record */
-double *b /* Input B[] vecor, return X[] */
+double *b /* Input B[] vector, return X[] */
) {
int i, j;
int nvi; /* When >= 0, indicates non-vanishing B[] index */
@@ -441,15 +442,13 @@ int n /* Dimensionality */
}
/* Pseudo-Invert matrix A using lu decomposition */
-/* NOTE that it returns transposed inverse by normal convention. */
-/* Use matrix_trans() to fix this, or use matrix_trans_mult(). */
/* Return 1 if the matrix is singular, 0 if OK */
int
lu_psinvert(
double **out, /* Output[0..N-1][0..M-1] */
double **in, /* Input[0..M-1][0..N-1] input matrix */
-int m, /* Rows */
-int n /* Columns */
+int m, /* In Rows */
+int n /* In Columns */
) {
int rv = 0;
double **tr; /* Transpose */
@@ -490,13 +489,73 @@ int n /* Columns */
}
free_dmatrix(sq, 0, m-1, 0, m-1);
}
-
free_dmatrix(tr, 0, n-1, 0, m-1);
return rv;
}
+/* ----------------------------------------------------------------- */
+
+// ~~~ Hmm. Need to verify this code is correct...
+
+/* Use Cholesky decomposition on a symetric positive-definite matrix. */
+/* Only the upper triangle of the matrix A is accessed. */
+/* L returns the decomposition */
+/* Return nz if A is not positive-definite */
+int llt_decomp(double **L, double **A, int n) {
+ int i, j, k;
+ double sum;
+
+ /* Scan though upper triangle */
+ for (i = 0; i < n; i++) {
+
+ for (j = i; j < n; j++) {
+
+ sum = A[i][j];
+ for (k = i-1; k >= 0; k--) {
+ sum -= A[i][k] * A[j][k];
+ }
+
+ if (i != j) {
+ L[j][i] = sum/L[i][i];
+ } else {
+ if (sum <= 0.0)
+ return 1;
+ L[i][i] = sqrt(sum);
+ }
+ }
+ }
+ return 0;
+}
+
+/* Solve a set of simultaneous equations A.x = b from the */
+/* LLt decomposition, by back substitution. */
+void llt_backsub(
+double **L, /* A[][] LLt decomposition in lower triangle */
+int n, /* Dimensionality */
+double *b, /* Input B[] */
+double *x /* Return X[] (may be same as B[]) */
+) {
+ int i, k;
+ double sum;
+
+ /* Solve L.y = b, storing y in x. */
+ for (i = 0; i < n; i++) {
+ sum = b[i];
+ for (k = i-1; k >= 0; k--)
+ sum -= L[i][k] * x[k];
+ x[i] = sum/L[i][i];
+ }
+
+ /* Solve Lt.x = y */
+ for (i = n; i >= 0; i--) {
+ sum = x[i];
+ for (k = i+1 ; k < n; k++)
+ sum -= L[k][i] * x[k];
+ x[i] = sum/L[i][i];
+ }
+}
diff --git a/numlib/ludecomp.h b/numlib/ludecomp.h
index 1075a5b..3f92ef8 100755
--- a/numlib/ludecomp.h
+++ b/numlib/ludecomp.h
@@ -38,6 +38,7 @@ int n /* Dimensionality */
);
/* Decompose the square matrix A[][] into lower and upper triangles */
+/* NOTE that rows get swaped by swapping matrix pointers! */
/* Return 1 if the matrix is singular. */
int
lu_decomp(
@@ -89,17 +90,34 @@ int n /* Dimensionality */
);
/* Pseudo-Invert matrix A using lu decomposition */
-/* NOTE that it returns transposed inverse by normal convention. */
-/* Use matrix_trans() to fix this, or use matrix_trans_mult(). */
/* Return 1 if the matrix is singular, 0 if OK */
int
lu_psinvert(
double **out, /* Output[0..N-1][0..M-1] */
double **in, /* Input[0..M-1][0..N-1] input matrix */
-int m, /* Rows */
-int n /* Columns */
+int m, /* In Rows */
+int n /* In Columns */
);
+/* - - - - - - - - - - - - - - - - - - - */
+
+/* Use Cholesky decomposition on a symetric positive-definite matrix. */
+/* Only the upper triangle of the matrix A is accessed. */
+/* L returns the decomposition */
+/* Return nz if A is not positive-definite */
+int llt_decomp(double **L, double **A, int n);
+
+
+/* Solve a set of simultaneous equations A.x = b from the */
+/* LLt decomposition, by back substitution. */
+void llt_backsub(
+double **L, /* A[][] LLt decomposition in lower triangle */
+int n, /* Dimensionality */
+double *b, /* Input B[] */
+double *x /* Return X[] (may be same as B[]) */
+);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/numlib/numlib.h b/numlib/numlib.h
index 430ce7a..28ec9ab 100755
--- a/numlib/numlib.h
+++ b/numlib/numlib.h
@@ -6,6 +6,7 @@
#include "numsup.h" /* Support routines, macros */
#include "dnsq.h" /* Non-linear equation solver */
+#include "gnewt.h" /* Global Newton non-linear equation solver */
#include "powell.h" /* Powell multi dimentional minimiser */
#include "dhsx.h" /* Downhill simplex multi dimentional minimiser */
#include "varmet.h" /* Variable Metric multi dimentional minimiser */
@@ -16,5 +17,6 @@
#include "sobol.h" /* Sub-random vector generators */
#include "aatree.h" /* Anderson balanced binary tree */
#include "quadprog.h" /* Quadradic Programming solution */
+#include "roots.h" /* Quadratic, Cubic and Quartic root solving */
#endif /* NUMLIB_H */
diff --git a/numlib/numsup.c b/numlib/numsup.c
index eab81ed..ce76337 100755
--- a/numlib/numsup.c
+++ b/numlib/numsup.c
@@ -1080,6 +1080,29 @@ int nch
free((char *)(m+nrl-1));
}
+/* In case rows have been swapped, reset the pointers */
+void dmatrix_reset(
+double **m,
+int nrl, /* Row low index */
+int nrh, /* Row high index */
+int ncl, /* Col low index */
+int nch /* Col high index */
+) {
+ int i;
+ int cols;
+
+ if (nrh < nrl) /* Prevent failure for 0 dimension */
+ nrh = nrl;
+ if (nch < ncl)
+ nch = ncl;
+
+ cols = nch - ncl + 1;
+
+ m[nrl] = m[nrl-1] - ncl; /* Set first row address, offset to ncl */
+ for(i = nrl+1; i <= nrh; i++) /* Set subsequent row addresses */
+ m[i] = m[i-1] + cols;
+}
+
/* --------------------- */
/* 2D diagonal half matrix vector malloc/free */
/* A half matrix must have equal rows and columns, */
@@ -1854,19 +1877,61 @@ int matrix_vect_mult(
return 0;
}
+/* Multiply a 0 based transposed matrix by a vector */
+/* d may be same as v */
+int matrix_trans_vect_mult(
+ double *d, int nd,
+ double **m, int nr, int nc,
+ double *v, int nv
+) {
+ int i, j;
+ double *_v = v, vv[20];
+
+ if (d == v) {
+ if (nv <= 20) {
+ _v = vv;
+ } else {
+ _v = dvector(0, nv-1);
+ }
+ for (j = 0; j < nv; j++)
+ _v[j] = v[j];
+ }
+
+ /* Input vector must match matrix columns */
+ if (nv != nr)
+ return 1;
+
+ /* Output vector must match matrix rows */
+ if (nd != nc)
+ return 1;
+
+ for (i = 0; i < nd; i++) {
+ d[i] = 0.0;
+ for (j = 0; j < nv; j++)
+ d[i] += m[j][i] * _v[j];
+ }
+
+ if (_v != v && _v != vv)
+ free_dvector(_v, 0, nv-1);
+
+ return 0;
+}
+
/* Set zero based dvector */
void vect_set(double *d, double v, int len) {
- int i;
- for (i = 0; i < len; i++)
- d[i] = v;
+ if (v == 0.0)
+ memset((char *)d, 0, len * sizeof(double));
+ else {
+ int i;
+ for (i = 0; i < len; i++)
+ d[i] = v;
+ }
}
/* Copy zero based dvector */
void vect_cpy(double *d, double *s, int len) {
- int i;
- for (i = 0; i < len; i++)
- d[i] = s[i];
+ memmove((char *)d, (char *)s, len * sizeof(double));
}
@@ -1900,6 +1965,35 @@ void vect_sub(
d[i] -= v[i];
}
+/* Scale a vector, */
+/* d may be same as v */
+void vect_scale(double *d, double *s, double scale, int len) {
+ int i;
+
+ for (i = 0; i < len; i++)
+ d[i] = s[i] * scale;
+}
+
+/* Take dot product of two vectors */
+double vect_dot(double *s1, double *s2, int len) {
+ int i;
+ double rv = 0.0;
+ for (i = 0; i < len; i++)
+ rv += s1[i] * s2[i];
+ return rv;
+}
+
+/* Return the vectors magnitude */
+double vect_mag(double *s, int len) {
+ int i;
+ double rv = 0.0;
+
+ for (i = 0; i < len; i++)
+ rv += s[i] * s[i];
+
+ return sqrt(rv);
+}
+
/* - - - - - - - - - - - - - - - - - - - - - - */
@@ -2019,6 +2113,85 @@ void adump_svector(a1log *log, char *id, char *pfx, short *a, int nc) {
a1logd(g_log, 0, "\n");
}
+/* ============================================================================ */
+/* C matrix support */
+
+/* Clip a vector to the range 0.0 .. 1.0 */
+/* and return any clipping margine */
+double vect_ClipNmarg(int n, double *out, double *in) {
+ int j;
+ double tt, marg = 0.0;
+ for (j = 0; j < n; j++) {
+ out[j] = in[j];
+ if (out[j] < 0.0) {
+ tt = 0.0 - out[j];
+ out[j] = 0.0;
+ if (tt > marg)
+ marg = tt;
+ } else if (out[j] > 1.0) {
+ tt = out[j] - 1.0;
+ out[j] = 1.0;
+ if (tt > marg)
+ marg = tt;
+ }
+ }
+ return marg;
+}
+
+/*
+
+ mat in out
+
+[ ] [] []
+[ ] [] []
+[ ] * [] => []
+[ ] [] []
+[ ] [] []
+
+ */
+
+/* Multiply N vector by NxN transform matrix */
+/* Organization is mat[out][in] */
+void vect_MulByNxN(int n, double *out, double *mat, double *in) {
+ int i, j;
+ double _tt[20], *tt = _tt;
+
+ if (n > 20)
+ tt = dvector(0, n-1);
+
+ for (i = 0; i < n; i++) {
+ tt[i] = 0.0;
+ for (j = 0; j < n; j++)
+ tt[i] += mat[i * n + j] * in[j];
+ }
+
+ for (i = 0; i < n; i++)
+ out[i] = tt[i];
+
+ if (n > 20)
+ free_dvector(tt, 0, n-1);
+}
+
+/* Transpose an NxN matrix */
+void matrix_TransposeNxN(int n, double *out, double *in) {
+ int i, j;
+
+ if (in != out) {
+ for (i = 0; i < n; i++)
+ for (j = 0; j < n; j++)
+ out[i * n + j] = in[j * n + i];
+ } else {
+ for (i = 0; i < n; i++) {
+ for (j = i+1; j < n; j++) {
+ double tt;
+ tt = out[i * n + j];
+ out[i * n + j] = out[j * n + i];
+ out[j * n + i] = tt;
+ }
+ }
+ }
+}
+
/* Print C double matrix to g_log debug */
/* id identifies matrix */
/* pfx used at start of each line */
@@ -2694,9 +2867,9 @@ char *debPiv(int di, int *p) {
return buf[ix];
}
-/* Print a double color vector to a string. */
+/* Print a double color vector to a string with format. */
/* Returned static buffer is re-used every 5 calls. */
-char *debPdv(int di, double *p) {
+char *debPdvf(int di, char *fmt, double *p) {
static char buf[5][DEB_MAX_CHAN * 100];
static int ix = 0;
int e;
@@ -2705,6 +2878,9 @@ char *debPdv(int di, double *p) {
if (p == NULL)
return "(null)";
+ if (fmt == NULL)
+ fmt = "%.8f";
+
if (++ix >= 5)
ix = 0;
bp = buf[ix];
@@ -2715,11 +2891,17 @@ char *debPdv(int di, double *p) {
for (e = 0; e < di; e++) {
if (e > 0)
*bp++ = ' ';
- sprintf(bp, "%.8f", p[e]); bp += strlen(bp);
+ sprintf(bp, fmt, p[e]); bp += strlen(bp);
}
return buf[ix];
}
+/* Print a double color vector to a string. */
+/* Returned static buffer is re-used every 5 calls. */
+char *debPdv(int di, double *p) {
+ return debPdvf(di, NULL, p);
+}
+
/* Print a float color vector to a string. */
/* Returned static buffer is re-used every 5 calls. */
char *debPfv(int di, float *p) {
diff --git a/numlib/numsup.h b/numlib/numsup.h
index 86ad6a8..972d5b3 100755
--- a/numlib/numsup.h
+++ b/numlib/numsup.h
@@ -411,6 +411,7 @@ void free_dvector(double *v,int nl,int nh);
double **dmatrix(int nrl, int nrh, int ncl, int nch);
double **dmatrixz(int nrl, int nrh, int ncl, int nch);
void free_dmatrix(double **m, int nrl, int nrh, int ncl, int nch);
+void dmatrix_reset(double **m, int nrl, int nrh, int ncl, int nch);
double **dhmatrix(int nrl, int nrh, int ncl, int nch);
double **dhmatrixz(int nrl, int nrh, int ncl, int nch);
@@ -486,6 +487,14 @@ int matrix_vect_mult(
double *v, int nv
);
+/* Multiply a 0 based transposed matrix by a vector */
+/* d may be same as v */
+int matrix_trans_vect_mult(
+ double *d, int nd,
+ double **m, int nr, int nc,
+ double *v, int nv
+);
+
/* Set zero based dvector */
void vect_set(double *d, double v, int len);
@@ -498,16 +507,21 @@ void vect_neg(double *d, double *s, int len);
/* Add two vectors, d += v */
/* d may be same as v */
-void vect_add(
- double *d, double *v, int len
-);
+void vect_add(double *d, double *v, int len);
/* Subtract two vectors, d -= v */
/* d may be same as v */
-void vect_sub(
- double *d, double *v, int len
-);
+void vect_sub(double *d, double *v, int len);
+
+/* Scale a vector, */
+/* d may be same as v */
+void vect_scale(double *d, double *s, double scale, int len);
+
+/* Take dot product of two vectors */
+double vect_dot(double *s1, double *s2, int len);
+/* Return the vectors magnitude */
+double vect_mag(double *s, int len);
/* Diagnostics */
/* id identifies matrix/vector */
@@ -524,6 +538,20 @@ void adump_fvector(a1log *log, char *id, char *pfx, float *a, int nc);
void adump_ivector(a1log *log, char *id, char *pfx, int *a, int nc);
void adump_svector(a1log *log, char *id, char *pfx, short *a, int nc);
+/* ===================================================== */
+/* C matrix support */
+
+/* Clip a vector to the range 0.0 .. 1.0 */
+/* and return any clipping margine */
+double vect_ClipNmarg(int n, double *out, double *in);
+
+/* Multiply N vector by NxN transform matrix */
+/* Organization is mat[out][in] */
+void vect_MulByNxN(int n, double *out, double *mat, double *in);
+
+/* Transpose an NxN matrix */
+void matrix_TransposeNxN(int n, double *out, double *in);
+
/* Dump C type matrix */
void adump_C_dmatrix(a1log *log, char *id, char *pfx, double *a, int nr, int nc);
@@ -631,10 +659,15 @@ char *debPiv(int di, int *p);
/* Returned static buffer is re-used every 5 calls. */
char *debPdv(int di, double *p);
+/* Print a double vector to a string with format. */
+/* Returned static buffer is re-used every 5 calls. */
+char *debPdvf(int di, char *fmt, double *p);
+
/* Print a float vector to a string. */
/* Returned static buffer is re-used every 5 calls. */
char *debPfv(int di, float *p);
+
/*******************************************/
/* Numerical diagnostics */
diff --git a/numlib/powell.c b/numlib/powell.c
index 47acc15..7fb57a7 100755
--- a/numlib/powell.c
+++ b/numlib/powell.c
@@ -40,8 +40,10 @@
#include "numsup.h"
#include "powell.h"
-#undef SLOPE_SANITY_CHECK /* exermental */
-#undef ABSTOL /* Make tollerance absolute */
+#undef SLOPE_SANITY_CHECK /* [und] expermental */
+#undef ABSTOL /* [und] Make tollerance absolute */
+#undef USE_LINMIND /* [und] Use limind for conjgrad (typically slower) */
+
/* Some debugging printfs (not comprehensive): */
#undef PDEBUG /* Powell debug */
#undef CDEBUG /* Conjgrad debug */
@@ -71,6 +73,7 @@
# define LDBG(xxx)
#endif
+/* -------------------------------------- */
/* Standard interface for powell function */
/* return 0 on sucess, 1 on failure due to excessive itterions */
/* Result will be in cp */
@@ -91,10 +94,10 @@ void (*prog)(void *pdata, int perc), /* Optional progress percentage callback *
void *pdata /* Opaque data needed by prog() */
) {
int i;
- double **dmtx; /* Direction vector */
- double *spt; /* Sarting point before exploring all the directions */
- double *xpt; /* Extrapolated point */
- double *svec; /* Search vector */
+ double **dmtx, *_dmtx[10], __dmtx[10 * 10] = { 0.0 }; /* Direction vector */
+ double *spt, _spt[10]; /* Sarting point before exploring all the directions */
+ double *xpt, _xpt[10]; /* Extrapolated point */
+ double *svec, _svec[10]; /* Search vector */
int iter;
double retv; /* Returned function value at p */
double stopth; /* Current stop threshold */
@@ -102,10 +105,20 @@ void *pdata /* Opaque data needed by prog() */
double curdel; /* Current change in function value */
int pc = 0; /* Percentage complete */
- dmtx = dmatrixz(0, di-1, 0, di-1); /* Zero filled */
- spt = dvector(0,di-1);
- xpt = dvector(0,di-1);
- svec = dvector(0,di-1);
+ if (di <= 10) {
+ int j;
+ for (j = i = 0; i < di; i++, j += di)
+ _dmtx[i] = __dmtx + j;
+ dmtx = _dmtx;
+ spt = _spt;
+ xpt = _xpt;
+ svec = _svec;
+ } else {
+ dmtx = dmatrixz(0, di-1, 0, di-1); /* Zero filled */
+ spt = dvector(0, di-1);
+ xpt = dvector(0, di-1);
+ svec = dvector(0, di-1);
+ }
/* Create initial direction matrix by */
/* placing search start on diagonal */
@@ -213,11 +226,14 @@ void *pdata /* Opaque data needed by prog() */
}
//printf("~1 iters = %d\n",iter);
+
/* Free up all the temporary vectors and matrix */
- free_dvector(svec,0,di-1);
- free_dvector(xpt,0,di-1);
- free_dvector(spt,0,di-1);
- free_dmatrix(dmtx, 0, di-1, 0, di-1);
+ if (di > 10) {
+ free_dvector(svec, 0, di-1);
+ free_dvector(xpt, 0, di-1);
+ free_dvector(spt, 0, di-1);
+ free_dmatrix(dmtx, 0, di-1, 0, di-1);
+ }
if (prog != NULL) /* Report final progress */
prog(pdata, 100);
@@ -232,12 +248,323 @@ void *pdata /* Opaque data needed by prog() */
return 1; /* Failed due to execessive itterations */
}
+/* - - - - - - - - - - - - - - - - - */
+
+#define POWELL_GOLD 1.618034
+#define POWELL_CGOLD 0.3819660
+#define POWELL_MAXIT 100
+
+/* Line bracketing and minimisation routine. */
+/* Return value at minimum. */
+double linmin(
+double cp[], /* Start point, and returned value */
+double xi[], /* Search vector */
+int di, /* Dimensionality */
+#ifdef ABSTOL
+double ftol, /* Absolute tolerance to stop on */
+#else
+double ftol, /* Relative tolerance to stop on */
+#endif
+double (*func)(void *fdata, double tp[]), /* Error function to evaluate */
+void *fdata) /* Opaque data for func() */
+{
+ int i;
+ double ax, xx, bx; /* Search vector multipliers */
+ double af, xf, bf; /* Function values at those points */
+ double *xt, _xt[10]; /* Trial point */
+
+ if (di <= 10)
+ xt = _xt;
+ else
+ xt = dvector(0, di-1); /* Vector for trial point */
+
+ /* -------------------------- */
+ /* First bracket the solution */
+
+ LDBG((" linmin: Bracketing solution\n"))
+
+ /* The line is measured as startpoint + offset * search vector. */
+ /* (Search isn't symetric, but it seems to depend on cp being */
+ /* best current solution ?) */
+ ax = 0.0;
+ for (i = 0; i < di; i++)
+ xt[i] = cp[i] + ax * xi[i];
+ af = (*func)(fdata, xt);
+
+ /* xx being vector offset 0.618 */
+ xx = 1.0/POWELL_GOLD;
+ for (i = 0; i < di; i++)
+ xt[i] = cp[i] + xx * xi[i];
+ xf = (*func)(fdata, xt);
+
+ LDBG((" linmin: Initial points a:%f:%f -> b:%f:%f\n",ax,af,xx,xf))
+
+ /* Fix it so that we are decreasing from point a -> x */
+ if (xf > af) {
+ double tt;
+ tt = ax; ax = xx; xx = tt;
+ tt = af; af = xf; xf = tt;
+ }
+ LDBG((" linmin: Ordered Initial points a:%f:%f -> b:%f:%f\n",ax,af,xx,xf))
+
+ bx = xx + POWELL_GOLD * (xx-ax); /* Guess b beyond a -> x */
+ for (i = 0; i < di; i++)
+ xt[i] = cp[i] + bx * xi[i];
+ bf = (*func)(fdata, xt);
+
+ LDBG((" linmin: Initial bracket a:%f:%f x:%f:%f b:%f:%f\n",ax,af,xx,xf,bx,bf))
+
+#ifdef SLOPE_SANITY_CHECK
+ /* If we're not seeing a slope indicitive of progress */
+ /* of order ftol, give up straight away */
+ if (2000.0 * fabs(xf - bf) <= ftol * (fabs(xf) + fabs(bf))
+ && 2000.0 * fabs(af - xf) <= ftol * (fabs(af) + fabs(xf))) {
+ LDBG((" linmin: giving up because slope is too shallow\n"))
+ if (xt != _xt)
+ free_dvector(xt,0,di-1);
+
+ if (bf < xf) {
+ xf = bf;
+ xx = bx;
+ }
+ goto done;
+ }
+#endif /* SLOPE_SANITY_CHECK */
+
+ /* While not bracketed */
+ while (xf > bf) {
+ double ulim, ux, uf;
+ double tt, r, q;
+
+ LDBG((" linmin: Not bracketed because xf %f > bf %f\n",xf, bf))
+ LDBG((" ax = %f, xx = %f, bx = %f\n",ax,xx,bx))
+
+ /* Compute ux by parabolic interpolation from a, x & b */
+ q = (xx - bx) * (xf - af);
+ r = (xx - ax) * (xf - bf);
+ tt = q - r;
+ if (tt >= 0.0 && tt < 1e-20) /* If +ve too small */
+ tt = 1e-20;
+ else if (tt <= 0.0 && tt > -1e-20) /* If -ve too small */
+ tt = -1e-20;
+ ux = xx - ((xx - bx) * q - (xx - ax) * r) / (2.0 * tt);
+ ulim = xx + 100.0 * (bx - xx); /* Extrapolation limit */
+
+//printf("~1 ux = %f, ulim = %f\n",ux,ulim);
+ if ((xx - ux) * (ux - bx) > 0.0) { /* u is between x and b */
+
+ for (i = 0; i < di; i++) /* Evaluate u */
+ xt[i] = cp[i] + ux * xi[i];
+ uf = (*func)(fdata, xt);
+
+//printf("~1 u is between x and b, uf = %f\n",uf);
+
+ if (uf < bf) { /* Minimum is between x and b */
+//printf("~1 min is between x and b\n");
+ ax = xx; af = xf;
+ xx = ux; xf = uf;
+ break;
+ } else if (uf > xf) { /* Minimum is between a and u */
+//printf("~1 min is between a and u\n");
+ bx = ux; bf = uf;
+ break;
+ }
+
+ /* Parabolic fit didn't work, look further out in direction of b */
+ ux = bx + POWELL_GOLD * (bx-xx);
+//printf("~1 parabolic fit didn't work,look further in direction of b (%f)\n",ux);
+
+ } else if ((bx - ux) * (ux - ulim) > 0.0) { /* u is between b and limit */
+ for (i = 0; i < di; i++) /* Evaluate u */
+ xt[i] = cp[i] + ux * xi[i];
+ uf = (*func)(fdata, xt);
+
+//printf("~1 u is between b and limit uf = %f\n",uf);
+ if (uf > bf) { /* Minimum is between x and u */
+//printf("~1 min is between x and uf\n");
+ ax = xx; af = xf;
+ xx = bx; xf = bf;
+ bx = ux; bf = uf;
+ break;
+ }
+ xx = bx; xf = bf; /* Continue looking */
+ bx = ux; bf = uf;
+ ux = bx + POWELL_GOLD * (bx - xx); /* Test beyond b */
+//printf("~1 continue looking beyond b (%f)\n",ux);
+
+ } else if ((ux - ulim) * (ulim - bx) >= 0.0) { /* u is beyond limit */
+ ux = ulim;
+//printf("~1 use limit\n");
+ } else { /* u is to left side of x ? */
+ ux = bx + POWELL_GOLD * (bx-xx);
+//printf("~1 look gold beyond b (%f)\n",ux);
+ }
+ /* Evaluate u, and move into place at b */
+ for (i = 0; i < di; i++)
+ xt[i] = cp[i] + ux * xi[i];
+ uf = (*func)(fdata, xt);
+//printf("~1 lookup ux %f value uf = %f\n",ux,uf);
+ ax = xx; af = xf;
+ xx = bx; xf = bf;
+ bx = ux; bf = uf;
+//printf("~1 move along to the right (a<-x, x<-b, b-<u)\n");
+ }
+ LDBG((" linmin: Got bracket a:%f:%f x:%f:%f b:%f:%f\n",ax,af,xx,xf,bx,bf))
+ /* Got bracketed minimum between a -> x -> b */
+//printf("~1 got bracketed minimum at %f (%f), %f (%f), %f (%f)\n",ax,af,xx,xf,bx,bf);
+
+ /* --------------------------------------- */
+ /* Now use brent minimiser bewteen a and b */
+ {
+ /* a and b bracket solution */
+ /* x is best function value so far */
+ /* w is second best function value so far */
+ /* v is previous second best, or third best */
+ /* u is most recently tested point */
+ double wx, vx, ux; /* Search vector multipliers */
+ double wf, vf = 0.0, uf; /* Function values at those points */
+ int iter;
+ double de = 0.0; /* Distance moved on previous step */
+ double e = 0.0; /* Distance moved on 2nd previous step */
+
+ /* Make sure a and b are in ascending order */
+ if (ax > bx) {
+ double tt;
+ tt = ax; ax = bx; bx = tt;
+ tt = af; af = bf; bf = tt;
+ }
+
+ wx = vx = xx; /* Initial values of other center points */
+ wf = xf = xf;
+
+ for (iter = 1; iter <= POWELL_MAXIT; iter++) {
+ double mx = 0.5 * (ax + bx); /* m is center of bracket values */
+#ifdef ABSTOL
+ double tol1 = ftol; /* Absolute tollerance */
+#else
+ double tol1 = ftol * fabs(xx) + 1e-10;
+#endif
+ double tol2 = 2.0 * tol1;
+
+ LDBG((" linmin it %d: Got bracket a:%f:%f x:%f:%f b:%f:%f\n",iter,ax,af,xx,xf,bx,bf))
+
+ /* See if we're done */
+//printf("~1 linmin check %f <= %f\n",fabs(xx - mx), tol2 - 0.5 * (bx - ax));
+ if (fabs(xx - mx) <= (tol2 - 0.5 * (bx - ax))) {
+ LDBG((" linmin: We're done because %e <= %e\n",fabs(xx - mx), tol2 - 0.5 * (bx - ax)))
+ break;
+ }
+
+ LDBG((" linmin: e %e tol2 %e\n",e,tol1))
+
+ if (fabs(e) > tol1) { /* Do a trial parabolic fit */
+ double te, p, q, r;
+ r = (xx-wx) * (xf-vf);
+ q = (xx-vx) * (xf-wf);
+ p = (xx-vx) * q - (xx-wx) * r;
+ q = 2.0 * (q - r);
+ if (q > 0.0)
+ p = -p;
+ else
+ q = -q;
+ te = e; /* Save previous e value */
+ e = de; /* Previous steps distance moved */
+
+ LDBG((" linmin: Trial parabolic fit\n" ))
+
+ if (fabs(p) >= fabs(0.5 * q * te) || p <= q * (ax-xx) || p >= q * (bx-xx)) {
+ /* Give up on the parabolic fit, and use the golden section search */
+ e = ((xx >= mx) ? ax-xx : bx-xx); /* Override previous distance moved */
+ de = POWELL_CGOLD * e;
+ LDBG((" linmin: Moving to golden section search\n" ))
+ } else { /* Use parabolic fit */
+ de = p/q; /* Change in xb */
+ ux = xx + de; /* Trial point according to parabolic fit */
+ if ((ux - ax) < tol2 || (bx - ux) < tol2) {
+ if ((mx - xx) > 0.0) /* Don't use parabolic, use tol1 */
+ de = tol1; /* tol1 is +ve */
+ else
+ de = -tol1;
+ }
+ LDBG((" linmin: Using parabolic fit\n" ))
+ }
+ } else { /* Keep using the golden section search */
+ e = ((xx >= mx) ? ax-xx : bx-xx); /* Override previous distance moved */
+ de = POWELL_CGOLD * e;
+ LDBG((" linmin: Continuing golden section search\n" ))
+ }
+
+ if (fabs(de) >= tol1) { /* If de moves as much as tol1 would */
+ ux = xx + de; /* use it */
+ LDBG((" linmin: ux = %f = xx %f + de %f\n",ux,xx,de))
+ } else { /* else move by tol1 in direction de */
+ if (de > 0.0) {
+ ux = xx + tol1;
+ LDBG((" linmin: ux = %f = xx %f + tol1 %e\n",ux,xx,tol1))
+ } else {
+ ux = xx - tol1;
+ LDBG((" linmin: ux = %f = xx %f - tol1 %f\n",ux,xx,tol1))
+ }
+ }
+
+ /* Evaluate function */
+ for (i = 0; i < di; i++)
+ xt[i] = cp[i] + ux * xi[i];
+ uf = (*func)(fdata, xt);
+
+ if (uf <= xf) { /* Found new best solution */
+ LDBG((" linmin: found new best solution at %f val %f\n",ux,uf))
+ if (ux >= xx) {
+ ax = xx; af = xf; /* New lower bracket */
+ } else {
+ bx = xx; bf = xf; /* New upper bracket */
+ }
+ vx = wx; vf = wf; /* New previous 2nd best solution */
+ wx = xx; wf = xf; /* New 2nd best solution from previous best */
+ xx = ux; xf = uf; /* New best solution from latest */
+ } else { /* Found a worse solution */
+ LDBG((" linmin: found new worse solution at %f val %f\n",ux,uf))
+ LDBG((" linmin: current best at %f val %f\n",xx,xf))
+ if (ux < xx) {
+ ax = ux; af = uf; /* New lower bracket */
+ } else {
+ bx = ux; bf = uf; /* New upper bracket */
+ }
+ if (uf <= wf || wx == xx) { /* New 2nd best solution, or equal best */
+ vx = wx; vf = wf; /* New previous 2nd best solution */
+ wx = ux; wf = uf; /* New 2nd best from latest */
+ } else if (uf <= vf || vx == xx || vx == wx) { /* New 3rd best, or equal 1st & 2nd */
+ vx = ux; vf = uf; /* New previous 2nd best from latest */
+ }
+ }
+ }
+ /* !!! should do something if iter > POWELL_MAXIT !!!! */
+ /* Solution is at xx, xf */
+ }
+
+ done:;
+
+ /* Compute solution vector at xx */
+ LDBG((" linmin: computing soln from best at %f val %f\n",xx,xf))
+ for (i = 0; i < di; i++)
+ cp[i] += xx * xi[i];
+
+ if (xt != _xt)
+ free_dvector(xt,0,di-1);
+//printf("~~~ line minimizer returning %e\n",xf);
+ return xf;
+}
+
+#undef POWELL_GOLD
+#undef POWELL_CGOLD
+#undef POWELL_MAXIT
+
/* -------------------------------------- */
-/* Conjugate Gradient optimiser */
+/* Conjugate Gradient optimiser using partial derivatives. */
/* return 0 on sucess, 1 on failure due to excessive itterions */
/* Result will be in cp */
/* Note that we could use gradient in line minimiser, */
-/* but haven't bothered yet. */
+/* but this seems to be slower, so we don't use it. */
int conjgrad(
double *rv, /* If not NULL, return the residual error */
int di, /* Dimentionality */
@@ -250,79 +577,93 @@ double ftol, /* Relative tollerance of error change to stop on */
#endif
int maxit, /* Maximum iterations allowed */
double (*func)(void *fdata, double tp[]), /* Error function to evaluate */
-double (*dfunc)(void *fdata, double dp[], double tp[]), /* Gradient function to evaluate */
+double (*dfunc)(void *fdata, double dp[], double tp[]), /* Gradient & function to evaluate */
+ /* dfunc() should return DFUNC_NRV if it doesn't return function value */
void *fdata, /* Opaque data needed by function */
void (*prog)(void *pdata, int perc), /* Optional progress percentage callback */
void *pdata /* Opaque data needed by prog() */
) {
int i, iter;
- double *svec; /* Search vector */
- double *gvec; /* G direction vector */
- double *hvec; /* H direction vector */
+ double *svec, _svec[10]; /* Search vector */
+ double *ssvec, _ssvec[10]; /* s[] scaled search vector */
+ double *gvec, _gvec[10]; /* G direction vector */
+ double *hvec, _hvec[10]; /* H direction vector */
double retv; /* Returned function value at p */
double stopth; /* Current stop threshold */
double startdel = -1.0; /* Initial change in function value */
double curdel; /* Current change in function value */
- double svec_sca; /* initial svec scale factor */
+ double brat; /* svec to s[] ratio */
+ double svec_sca; /* svec scale factor */
int pc = 0; /* Percentage complete */
- svec = dvector(0,di-1);
- gvec = dvector(0,di-1);
- hvec = dvector(0,di-1);
+ if (di <= 10) {
+ svec = _svec;
+ ssvec = _ssvec;
+ gvec = _gvec;
+ hvec = _hvec;
+ } else {
+ svec = dvector(0, di-1);
+ ssvec = dvector(0, di-1);
+ gvec = dvector(0, di-1);
+ hvec = dvector(0, di-1);
+ }
+
+ CDBG(("conjgrad with di %d\n", di))
if (prog != NULL) /* Report initial progress */
prog(pdata, pc);
- /* Initial gradient function evaluation */
+ /* Initial function and gradient evaluation */
retv = (*dfunc)(fdata, svec, cp);
-
- /* svec[] seems to be large after this. */
- /* Rescale it to conform to maximum of s[] */
- for (svec_sca = 0.0, i = 0; i < di; i++) {
- if (fabs(svec[i]) > svec_sca)
- svec_sca = fabs(svec[i]);
+ if (retv == DFUNC_NRV)
+ retv = (*func)(fdata, cp);
+
+ /* svec[] seems to be large after this. Compute scaled version that */
+ /* has maximum of s[] so that line search is guided by the search radius. */
+ for (brat = 0.0, i = 0; i < di; i++) {
+ double rat = fabs(svec[i]) / fabs(s[i]);
+ if (rat > brat)
+ brat = rat;
}
- /* set scale so largest <= 1 */
- if (svec_sca < 1e-12)
- svec_sca = 1.0;
- else
- svec_sca = 1.0/svec_sca;
-
- CDBG((" initial dir = %s\n", debPdv(di,svec)));
- CDBG((" initial retv = %f\n",retv));
+ svec_sca = 1.0/brat;
/* Initial vector setup */
for (i = 0; i < di; i++) {
- gvec[i] = hvec[i] = -svec[i]; /* Inverse gradient */
- svec[i] = s[i] * -svec[i] * svec_sca; /* Scale the search vector */
+ svec[i] = gvec[i] = hvec[i] = -svec[i]; /* Inverse gradient */
+ ssvec[i] = svec[i] * svec_sca; /* Scale the search vector to s[] size */
}
- CDBG(("Initial svec = %s\n", debPdv(di,svec)));
+
+ CDBG((" initial dir = %s\n", debPdv(di, ssvec)));
+ CDBG((" initial retv = %f\n",retv));
/* Itterate untill we converge on a solution, or give up. */
for (iter = 1; iter < maxit; iter++) {
double gamden, gamnum, gam;
double pretv; /* Previous function return value */
- CDBG(("conjrad: about to do linmin\n"))
+ CDBG(("conjrad it %d: about to do linmind\n",iter))
pretv = retv;
- retv = linmin(cp, svec, di, ftol, func, fdata);
+#ifdef USE_LINMIND
+ retv = linmind(cp, ssvec, di, ftol, func, dfunc, fdata);
+#else
+ retv = linmin(cp, ssvec, di, ftol, func, fdata);
+#endif
#ifdef ABSTOL
stopth = ftol; /* Absolute tollerance */
#else
- stopth = ftol * 0.5 * (fabs(pretv) + fabs(retv) + DBL_EPSILON); // Old code
+ stopth = ftol * 0.5 * (fabs(pretv) + fabs(retv) + DBL_EPSILON);
#endif
curdel = fabs(pretv - retv);
CDBG((" this retv = %f, pretv = %f, curdel = %f\n",retv,pretv,curdel));
if (startdel < 0.0) {
startdel = curdel;
- } else {
+ } else if (prog != NULL) { /* Update percentage */
int tt;
tt = (int)(100.0 * pow((log(curdel) - log(startdel))/(log(stopth) - log(startdel)), 4.0) + 0.5);
if (tt > pc && tt < 100) {
pc = tt;
- if (prog != NULL) /* Report initial progress */
- prog(pdata, pc);
+ prog(pdata, pc); /* Report initial progress */
}
}
@@ -336,7 +677,7 @@ void *pdata /* Opaque data needed by prog() */
CDBG(("conjrad: recomputing direction\n"))
(*dfunc)(fdata, svec, cp); /* (Don't use retv as it wrecks stop test) */
- CDBG((" pderiv = %s\n", debPdv(di,svec)));
+ CDBG((" pderiv = %s\n", debPdv(di, svec)));
/* Compute gamma */
for (gamnum = gamden = 0.0, i = 0; i < di; i++) {
@@ -360,25 +701,26 @@ void *pdata /* Opaque data needed by prog() */
svec[i] = hvec[i] = gvec[i] + gam * hvec[i];
}
- /* svec[] seems to be large after this. */
- /* Rescale it to conform to maximum of s[] */
- for (svec_sca = 0.0, i = 0; i < di; i++) {
- if (fabs(svec[i]) > svec_sca)
- svec_sca = fabs(svec[i]);
+ /* svec[] seems to be large after this. Compute scaled version that */
+ /* has maximum of s[] so that line search is guided by the search radius. */
+ for (brat = 0.0, i = 0; i < di; i++) {
+ double rat = fabs(svec[i]) / fabs(s[i]);
+ if (rat > brat)
+ brat = rat;
}
- /* set scale so largest <= 1 */
- if (svec_sca < 1e-12)
- svec_sca = 1.0;
- else
- svec_sca = 1.0/svec_sca;
+ svec_sca = 1.0/brat;
for (i = 0; i < di; i++)
- svec[i] = svec[i] * s[i] * svec_sca;
- CDBG((" svec = %s\n", debPdv(di,svec)));
+ ssvec[i] = svec[i] * svec_sca;
+
+ CDBG((" ssvec = %s\n", debPdv(di,ssvec)));
}
/* Free up all the temporary vectors and matrix */
- free_dvector(hvec,0,di-1);
- free_dvector(gvec,0,di-1);
- free_dvector(svec,0,di-1);
+ if (di > 10) {
+ free_dvector(hvec, 0, di-1);
+ free_dvector(gvec, 0, di-1);
+ free_dvector(ssvec, 0, di-1);
+ free_dvector(svec, 0, di-1);
+ }
if (prog != NULL) /* Report final progress */
prog(pdata, 100);
@@ -394,14 +736,15 @@ void *pdata /* Opaque data needed by prog() */
return 1; /* Failed due to execessive itterations */
}
-/*------------------------------*/
#define POWELL_GOLD 1.618034
-#define POWELL_CGOLD 0.3819660
#define POWELL_MAXIT 100
-/* Line bracketing and minimisation routine. */
+/* Line bracketing and minimisation routine using derivatives */
+/* This is not used, because it typically makes it slower */
+/* - it may take less itterations, but each itteration uses */
+/* a func() and dfunc() call, at least doubling itter overhead. */
/* Return value at minimum. */
-double linmin(
+double linmind(
double cp[], /* Start point, and returned value */
double xi[], /* Search vector */
int di, /* Dimensionality */
@@ -410,23 +753,29 @@ double ftol, /* Absolute tolerance to stop on */
#else
double ftol, /* Relative tolerance to stop on */
#endif
-double (*func)(void *fdata, double tp[]), /* Error function to evaluate */
+double (*func)(void *fdata, double tp[]), /* Error function to evaluate */
+double (*dfunc)(void *fdata, double dp[], double tp[]), /* Gradient function to evaluate */
+ /* dfunc() should return DFUNC_NRV if it doesn't return function value */
void *fdata) /* Opaque data for func() */
{
int i;
double ax, xx, bx; /* Search vector multipliers */
double af, xf, bf; /* Function values at those points */
- double *xt, XT[10]; /* Trial point */
+ double *xt, _xt[10]; /* Trial point */
+ double *df, _df[10]; /* Derivative vector */
- if (di <= 10)
- xt = XT;
- else
+ if (di <= 10) {
+ xt = _xt;
+ df = _df;
+ } else {
xt = dvector(0, di-1); /* Vector for trial point */
+ df = dvector(0, di-1); /* Vector for trial point */
+ }
/* -------------------------- */
/* First bracket the solution */
- LDBG(("linmin: Bracketing solution\n"))
+ LDBG((" linmind: Bracketing solution\n"))
/* The line is measured as startpoint + offset * search vector. */
/* (Search isn't symetric, but it seems to depend on cp being */
@@ -442,7 +791,7 @@ void *fdata) /* Opaque data for func() */
xt[i] = cp[i] + xx * xi[i];
xf = (*func)(fdata, xt);
- LDBG(("linmin: Initial points a:%f:%f -> b:%f:%f\n",ax,af,xx,xf))
+ LDBG((" linmind: Initial points a:%f:%f -> b:%f:%f\n",ax,af,xx,xf))
/* Fix it so that we are decreasing from point a -> x */
if (xf > af) {
@@ -450,33 +799,31 @@ void *fdata) /* Opaque data for func() */
tt = ax; ax = xx; xx = tt;
tt = af; af = xf; xf = tt;
}
- LDBG(("linmin: Ordered Initial points a:%f:%f -> b:%f:%f\n",ax,af,xx,xf))
+ LDBG((" linmind: Ordered Initial points a:%f:%f -> b:%f:%f\n",ax,af,xx,xf))
bx = xx + POWELL_GOLD * (xx-ax); /* Guess b beyond a -> x */
for (i = 0; i < di; i++)
xt[i] = cp[i] + bx * xi[i];
bf = (*func)(fdata, xt);
- LDBG(("linmin: Initial bracket a:%f:%f x:%f:%f b:%f:%f\n",ax,af,xx,xf,bx,bf))
+ LDBG((" linmind: Initial bracket a:%f:%f x:%f:%f b:%f:%f\n",ax,af,xx,xf,bx,bf))
#ifdef SLOPE_SANITY_CHECK
/* If we're not seeing a slope indicitive of progress */
/* of order ftol, give up straight away */
if (2000.0 * fabs(xf - bf) <= ftol * (fabs(xf) + fabs(bf))
&& 2000.0 * fabs(af - xf) <= ftol * (fabs(af) + fabs(xf))) {
- LDBG(("linmin: giving up because slope is too shallow\n"))
- if (xt != XT)
- free_dvector(xt,0,di-1);
+ LDBG((" linmind: giving up because slope is too shallow\n"))
+ if (di > 10) {
+ free_dvector(df, 0, di-1);
+ free_dvector(xt, 0, di-1);
+ }
if (bf < xf) {
xf = bf;
xx = bx;
}
-
- /* Compute solution vector */
- for (i = 0; i < di; i++)
- cp[i] += xx * xi[i];
- return xf;
+ goto done;
}
#endif /* SLOPE_SANITY_CHECK */
@@ -485,8 +832,7 @@ void *fdata) /* Opaque data for func() */
double ulim, ux, uf;
double tt, r, q;
-// LDBG(("linmin: Not bracketed a:%f:%f x:%f%f b:%f:%f\n",ax,af,xx,xf,bx,bf))
- LDBG(("linmin: Not bracketed because xf %f > bf %f\n",xf, bf))
+ LDBG((" linmind: Not bracketed because xf %f > bf %f\n",xf, bf))
LDBG((" ax = %f, xx = %f, bx = %f\n",ax,xx,bx))
/* Compute ux by parabolic interpolation from a, x & b */
@@ -559,7 +905,7 @@ void *fdata) /* Opaque data for func() */
bx = ux; bf = uf;
//printf("~1 move along to the right (a<-x, x<-b, b-<u)\n");
}
- LDBG(("linmin: Got bracket a:%f:%f x:%f:%f b:%f:%f\n",ax,af,xx,xf,bx,bf))
+ LDBG((" linmind: Got bracket a:%f:%f x:%f:%f b:%f:%f\n",ax,af,xx,xf,bx,bf))
/* Got bracketed minimum between a -> x -> b */
//printf("~1 got bracketed minimum at %f (%f), %f (%f), %f (%f)\n",ax,af,xx,xf,bx,bf);
@@ -571,8 +917,10 @@ void *fdata) /* Opaque data for func() */
/* w is second best function value so far */
/* v is previous second best, or third best */
/* u is most recently tested point */
+
double wx, vx, ux; /* Search vector multipliers */
double wf, vf = 0.0, uf; /* Function values at those points */
+ double xd, wd, vd, ud; /* Derivative values at those points */
int iter;
double de = 0.0; /* Distance moved on previous step */
double e = 0.0; /* Distance moved on 2nd previous step */
@@ -587,6 +935,16 @@ void *fdata) /* Opaque data for func() */
wx = vx = xx; /* Initial values of other center points */
wf = xf = xf;
+ /* Lookup derivative at x (we already have xf from bracketing) */
+ for (i = 0; i < di; i++)
+ xt[i] = cp[i] + xx * xi[i];
+ (*dfunc)(fdata, df, xt);
+ for (xd = 0.0, i = 0; i < di; i++)
+ xd += xi[i] * df[i];
+ wd = ud = xd;
+
+ LDBG((" linmind: xx %f, deriv. xd %f\n",xx,xd))
+
for (iter = 1; iter <= POWELL_MAXIT; iter++) {
double mx = 0.5 * (ax + bx); /* m is center of bracket values */
#ifdef ABSTOL
@@ -596,113 +954,169 @@ void *fdata) /* Opaque data for func() */
#endif
double tol2 = 2.0 * tol1;
- LDBG(("linmin: Got bracket a:%f:%f x:%f:%f b:%f:%f\n",ax,af,xx,xf,bx,bf))
+ LDBG((" linmind it %d: Got bracket a:%f:%f x:%f:%f b:%f:%f\n",iter, ax,af,xx,xf,bx,bf))
/* See if we're done */
-//printf("~1 linmin check %f <= %f\n",fabs(xx - mx), tol2 - 0.5 * (bx - ax));
if (fabs(xx - mx) <= (tol2 - 0.5 * (bx - ax))) {
- LDBG(("linmin: We're done because %f <= %f\n",fabs(xx - mx), tol2 - 0.5 * (bx - ax)))
+ LDBG((" linmind: We're done because %e <= %e\n",fabs(xx - mx), tol2 - 0.5 * (bx - ax)))
break;
}
- if (fabs(e) > tol1) { /* Do a trial parabolic fit */
- double te, p, q, r;
- r = (xx-wx) * (xf-vf);
- q = (xx-vx) * (xf-wf);
- p = (xx-vx) * q - (xx-wx) * r;
- q = 2.0 * (q - r);
- if (q > 0.0)
- p = -p;
- else
- q = -q;
+ LDBG((" linmind: e %f tol2 %f\n",e,tol1))
+
+ if (fabs(e) > tol1) { /* Do a trial secant fit */
+ double te;
+ double dx1, dx2; /* Secant extrapolation points */
+ double ux1, ux2;
+ int ch1, ch2;
+
+ LDBG((" linmind: Doing trial secant fit\n" ))
+
+ dx2 = dx1 = 2.0 * (bx - ax); /* Default to values out of the ax..bx bracket */
+
+ /* Extrapolated points from last two points (secant method) */
+ if (wd != xd)
+ dx1 = (wx - xx) * xd/(xd - wd);
+ if (vd != xd)
+ dx2 = (vx - xx) * xd/(xd - vd);
+
+ ux1 = xx + dx1;
+ ux2 = xx + dx2;
+
+ /* Check which one is reasonable */
+ ch1 = (ax - ux1) * (ux1 - bx) > 0.0 && xd * dx1 < 0.0;
+ ch2 = (ax - ux2) * (ux2 - bx) > 0.0 && xd * dx2 < 0.0;
+
+ LDBG((" linmind: Doing dx1 %f dx2 %f ux1 %f ux2 %f ch1 %d ch2 %d\n",dx1,dx2,ux1,ux2,ch1,ch2))
+
te = e; /* Save previous e value */
e = de; /* Previous steps distance moved */
- LDBG(("linmin: Trial parabolic fit\n" ))
+ if (!ch1 && !ch2)
+ goto bisect;
- if (fabs(p) >= fabs(0.5 * q * te) || p <= q * (ax-xx) || p >= q * (bx-xx)) {
- /* Give up on the parabolic fit, and use the golden section search */
- e = ((xx >= mx) ? ax-xx : bx-xx); /* Override previous distance moved */
- de = POWELL_CGOLD * e;
- LDBG(("linmin: Moving to golden section search\n" ))
- } else { /* Use parabolic fit */
- de = p/q; /* Change in xb */
- ux = xx + de; /* Trial point according to parabolic fit */
- if ((ux - ax) < tol2 || (bx - ux) < tol2) {
- if ((mx - xx) > 0.0) /* Don't use parabolic, use tol1 */
- de = tol1; /* tol1 is +ve */
- else
- de = -tol1;
- }
- LDBG(("linmin: Using parabolic fit\n" ))
+ /* Use smallest or the one that's valid */
+ if (ch1 && ch2)
+ de = fabs(dx1) < fabs(dx2) ? dx1 : dx2;
+ if (ch1)
+ de = dx1;
+ else if (ch2)
+ de = dx2;
+
+ LDBG((" linmind: set de %f\n",de))
+
+ if (fabs(de) > fabs(0.5 * te)) {
+ LDBG((" linmind: abs(de) %f > abs(te/2 = %f)\n",fabs(de),fabs(0.5 * te)))
+ goto bisect;
}
- } else { /* Keep using the golden section search */
- e = ((xx >= mx) ? ax-xx : bx-xx); /* Override previous distance moved */
- de = POWELL_CGOLD * e;
- LDBG(("linmin: Continuing golden section search\n" ))
+
+ ux = xx + de;
+
+ if ((ux - ax) < tol2 || (bx - ux) < tol2) {
+ if ((mx - xx) < 0.0)
+ de = -fabs(tol1);
+ else
+ de = fabs(tol1);
+ LDBG((" linmind: Set de to tol1 %f\n",de))
+ }
+#ifdef LDEBUG
+ else {
+ LDBG((" linmind: Using secant fit de %f\n",de))
+ }
+#endif
+
+ /* else bisect picking side using sign of derivative */
+ } else {
+ bisect:
+ e = (xd >= 0.0 ? ax - xx : bx -xx);
+ de = 0.5 * e;
+ LDBG((" linmind: Continuing bisection search de %f\n",de))
}
- if (fabs(de) >= tol1) { /* If de moves as much as tol1 would */
+ if (fabs(de) >= tol1) { /* If de moves as much as tol1 or more */
ux = xx + de; /* use it */
- LDBG(("linmin: ux = %f = xx %f + de %f\n",ux,xx,de))
+
+ /* Evaluate function */
+ for (i = 0; i < di; i++)
+ xt[i] = cp[i] + ux * xi[i];
+ uf = (*func)(fdata, xt);
+
+ LDBG((" linmind: ux = %f = xx %f + de %f, uf %f\n",ux,xx,de,uf))
+
} else { /* else move by tol1 in direction de */
if (de > 0.0) {
ux = xx + tol1;
- LDBG(("linmin: ux = %f = xx %f + tol1 %f\n",ux,xx,tol1))
+ LDBG((" linmind: ux = %f = xx %f + tol1 %f\n",ux,xx,tol1))
} else {
ux = xx - tol1;
- LDBG(("linmin: ux = %f = xx %f - tol1 %f\n",ux,xx,tol1))
+ LDBG((" linmind: ux = %f = xx %f - tol1 %f\n",ux,xx,tol1))
+ }
+ /* Evaluate function */
+ for (i = 0; i < di; i++)
+ xt[i] = cp[i] + ux * xi[i];
+ uf = (*func)(fdata, xt);
+
+ LDBG((" linmind: uf %f\n",uf))
+
+ if (uf > xf) { /* If tol1 step downhill takes us uphill, we're done */
+ goto done;
}
}
- /* Evaluate function */
- for (i = 0; i < di; i++)
- xt[i] = cp[i] + ux * xi[i];
- uf = (*func)(fdata, xt);
+ /* Evaluate derivative at trial point */
+ (*dfunc)(fdata, df, xt);
+ for (ud = 0.0, i = 0; i < di; i++)
+ ud += xi[i] * df[i];
+
+ LDBG((" linmind: ux %f, deriv. ud %f\n",ux,ud))
+ /* Houskeeping: */
if (uf <= xf) { /* Found new best solution */
- LDBG(("linmin: found new best solution at %f val %f\n",ux,uf))
+ LDBG((" linmind: found new best solution at %f val %f dval %f\n",ux,uf,ud))
if (ux >= xx) {
- ax = xx; af = xf; /* New lower bracket */
+ ax = xx; af = xf; /* New lower bracket */
} else {
bx = xx; bf = xf; /* New upper bracket */
}
- vx = wx; vf = wf; /* New previous 2nd best solution */
- wx = xx; wf = xf; /* New 2nd best solution from previous best */
- xx = ux; xf = uf; /* New best solution from latest */
- } else { /* Found a worse solution */
- LDBG(("linmin: found new worse solution at %f val %f\n",ux,uf))
- LDBG(("linmin: current best at %f val %f\n",xx,xf))
+ vx = wx; vf = wf; vd = wd; /* New previous 2nd best solution */
+ wx = xx; wf = xf; wd = xd; /* New 2nd best solution from previous best */
+ xx = ux; xf = uf; xd = ud; /* New best solution from latest */
+
+ } else { /* Found a worse solution */
+ LDBG((" linmind: found new worse solution at %f val %f dval %f\n",ux,uf,ud))
+ LDBG((" linmind: current best at %f val %f dval %f\n",xx,xf,xd))
if (ux < xx) {
ax = ux; af = uf; /* New lower bracket */
} else {
bx = ux; bf = uf; /* New upper bracket */
}
if (uf <= wf || wx == xx) { /* New 2nd best solution, or equal best */
- vx = wx; vf = wf; /* New previous 2nd best solution */
- wx = ux; wf = uf; /* New 2nd best from latest */
+ vx = wx; vf = wf; vd = wd; /* New previous 2nd best solution */
+ wx = ux; wf = uf; wd = ud; /* New 2nd best from latest */
} else if (uf <= vf || vx == xx || vx == wx) { /* New 3rd best, or equal 1st & 2nd */
- vx = ux; vf = uf; /* New previous 2nd best from latest */
+ vx = ux; vf = uf; vd = ud; /* New previous 2nd best from latest */
}
}
- }
- /* !!! should do something if iter > POWELL_MAXIT !!!! */
+ } /* Next itter */
+
+ /* !!! should do something if iter > POWELL_MAXIT ??? */
/* Solution is at xx, xf */
+ done:;
+ if (di > 10) {
+ free_dvector(df, 0, di-1);
+ free_dvector(xt, 0, di-1);
+ }
/* Compute solution vector */
- LDBG(("linmin: computing soln from best at %f val %f\n",xx,xf))
+ LDBG((" linmind: computing soln from best at %f val %f dval %f\n",xx,xf,xd))
for (i = 0; i < di; i++)
cp[i] += xx * xi[i];
- }
- if (xt != XT)
- free_dvector(xt,0,di-1);
-//printf("~~~ line minimizer returning %e\n",xf);
+ } /* Minimizer context */
+
return xf;
}
#undef POWELL_GOLD
-#undef POWELL_CGOLD
#undef POWELL_MAXIT
-/**************************************************/
diff --git a/numlib/powell.h b/numlib/powell.h
index 4b86573..642cb65 100755
--- a/numlib/powell.h
+++ b/numlib/powell.h
@@ -15,6 +15,8 @@
extern "C" {
#endif
+#define DFUNC_NRV 1e100
+
/* Standard interface for powell function */
/* return 0 on sucess, 1 on failure due to excessive itterations */
/* Result will be in cp */
@@ -32,7 +34,7 @@ void (*prog)(void *pdata, int perc), /* Optional progress percentage callback *
void *pdata /* Opaque data needed by prog() */
);
-/* Conjugate Gradient optimiser */
+/* Conjugate Gradient optimiser using partial derivatives. */
/* return 0 on sucess, 1 on failure due to excessive itterations */
/* Result will be in cp */
int conjgrad(
@@ -43,7 +45,8 @@ double s[], /* Size of initial search area */
double ftol, /* Tollerance of error change to stop on */
int maxit, /* Maximum iterations allowed */
double (*func)(void *fdata, double tp[]), /* Error function to evaluate */
-double (*dfunc)(void *fdata, double dp[], double tp[]), /* Gradient function to evaluate */
+double (*dfunc)(void *fdata, double dp[], double tp[]), /* Gradient & function to evaluate */
+ /* dfunc() should return DFUNC_NRV if it doesn't return function value */
void *fdata, /* Opaque data needed by function */
void (*prog)(void *pdata, int perc), /* Optional progress percentage callback */
void *pdata /* Opaque data needed by prog() */
@@ -69,6 +72,22 @@ double (*func)(void *fdata, double tp[]), /* Error function to evaluate */
void *fdata /* Opaque data for func() */
);
+/* Line bracketing and minimisation routine using derivatives. */
+/* Return value at minimum. */
+double linmind(
+double cp[], /* Start point, and returned value */
+double xi[], /* Search vector */
+int di, /* Dimensionality */
+#ifdef ABSTOL
+double ftol, /* Absolute tolerance to stop on */
+#else
+double ftol, /* Relative tolerance to stop on */
+#endif
+double (*func)(void *fdata, double tp[]), /* Error function to evaluate */
+double (*dfunc)(void *fdata, double dp[], double tp[]), /* Gradient & function to evaluate */
+void *fdata /* Opaque data for func() */
+);
+
#ifdef __cplusplus
}
#endif
diff --git a/numlib/quadprog.c b/numlib/quadprog.c
index 847601f..4e94cec 100755
--- a/numlib/quadprog.c
+++ b/numlib/quadprog.c
@@ -233,7 +233,7 @@ double quadprog( /* Return solution cost, QP_INFEASIBLE if infeasible/error */
/* and compute the current solution value */
f_value = 0.5 * scalar_product(g0, x, n);
#ifdef TRACE_SOLVER
- printf("Unconstrained solution: %f",f_value);
+ printf("Unconstrained solution: f_value %f\n",f_value);
print_vector("x", x, n);
#endif
@@ -314,9 +314,11 @@ l1: iter++;
#endif
if (fabs(psi) <= m * DBL_EPSILON * c1 * c2* 100.0) {
- /* numerically there are not infeasibilities anymore */
+ /* numerically there are no infeasibilities anymore */
+#ifdef TRACE_SOLVER
+ printf("numerically there are no infeasibilities anymore\n");
+#endif
q = iq;
-
goto done;
}
@@ -338,8 +340,10 @@ l2: /* Step 2: check for feasibility and determine a new S-pair */
}
}
if (ss >= 0.0) {
+#ifdef TRACE_SOLVER
+ printf(" ss %f >= 0.0\n",ss);
+#endif
q = iq;
-
goto done;
}
@@ -398,7 +402,7 @@ l2a:
/* the step is chosen as the minimum of t1 and t2 */
t = FMIN(t1, t2);
#ifdef TRACE_SOLVER
- printf("Step sizes: %f (t1 = %f, t2 = %f\n",t,t1,t2);
+ printf("Step size: %e (t1 = %e, t2 = %e\n",t,t1,t2);
#endif
/* Step 2c: determine new S-pair and take step: */
@@ -407,6 +411,9 @@ l2a:
if (t >= QP_INFEASIBLE) {
/* QPP is infeasible */
// FIXME: unbounded to raise
+#ifdef TRACE_SOLVER
+ printf(" QPP is infeasible\n");
+#endif
q = iq;
f_value = QP_INFEASIBLE;
goto done;
@@ -449,18 +456,21 @@ l2a:
if (fabs(t - t2) < DBL_EPSILON) {
#ifdef TRACE_SOLVER
- printf("Full step has taken %f\n",t);
+ printf("Full step has been taken %f\n",t);
print_vector("x", x, n);
#endif
- /* full step has taken */
- /* add constraint ip to the active set*/
+ /* full step has been taken */
+ /* Add constraint ip to the active set*/
if (!add_constraint(R, J, d, &iq, &R_norm, n)) {
+#ifdef TRACE_SOLVER
+ printf("add_constraint failed - removing constraint ant step\n",t);
+#endif
iaexcl[ip] = 0;
delete_constraint(R, J, A, u, n, p, &iq, ip);
#ifdef TRACE_SOLVER
print_matrix("R", R, n, n);
print_ivector("A", A, iq);
- print_ivector("iai", iai, iq); // ?? iq size of m+p ?
+ print_ivector("iai", iai, m+p);
#endif
for (i = 0; i < m; i++)
iai[i] = i;
@@ -477,7 +487,7 @@ l2a:
#ifdef TRACE_SOLVER
print_matrix("R", R, n, n);
print_ivector("A", A, iq);
- print_ivector("iai", iai, iq); // ?? iq size of m+p ?
+ print_ivector("iai", iai, m + p);
#endif
goto l1;
}
@@ -532,6 +542,11 @@ l2a:
free_svector(iaexcl, 0, m + p-1);
}
+#ifdef TRACE_SOLVER
+ printf("Returning f_value %e\n",f_value);
+ print_vector("Returning x", x, n);
+#endif
+
return f_value;
}
diff --git a/numlib/quadprog.h b/numlib/quadprog.h
index 7d28ec8..d091b75 100755
--- a/numlib/quadprog.h
+++ b/numlib/quadprog.h
@@ -25,20 +25,20 @@ The problem is in the form:
min 0.5 * x G x + g0 x
s.t.
- CE^T x + ce0 = 0
- CI^T x + ci0 >= 0
+ CE^t x + ce0 = 0
+ CI^t x + ci0 >= 0
The matrix and vectors dimensions are as follows:
- G: n * n
- g0: n
+ G: n * n
+ g0: n
- CE: n * p
- ce0: p
+ CE: n * p
+ ce0: p
- CI: n * m
- ci0: m
+ CI: n * m
+ ci0: m
- x: n
+ x: n
References: D. Goldfarb, A. Idnani. A numerically stable dual method for solving
strictly convex quadratic programs. Mathematical Programming 27 (1983) pp. 1-33.
diff --git a/numlib/rand.c b/numlib/rand.c
index 9e58de3..e2fdfdf 100755
--- a/numlib/rand.c
+++ b/numlib/rand.c
@@ -39,12 +39,18 @@ double ranno(void) {
return rand32_th(NULL, 0) / 4294967295.0;
}
-/* Return a random double in the range min to max */
+/* Return a uniform random double in the range min to max */
double
d_rand(double min, double max) {
return d_rand_th(NULL, min, max);
}
+/* Return a squared distribution random double in the range min to max */
+double
+d2_rand(double min, double max) {
+ return d2_rand_th(NULL, min, max);
+}
+
/* Return a random integer in the range min to max inclusive */
int
i_rand(int min, int max) {
@@ -81,6 +87,7 @@ unsigned int seed /* Optional seed. Non-zero re-initialized with that seed */
p = &g_rand;
if (seed != 0) {
+//printf("~1 rand 0x%x seed 0x%x\n",p,seed);
p->pvs_inited = 0;
p->ran = seed;
}
@@ -98,21 +105,29 @@ unsigned int seed /* Optional seed. Non-zero re-initialized with that seed */
p->last = p->pvs[i]; /* Value generated */
p->pvs[i] = p->ran = PSRAND32(p->ran); /* New value */
+//printf("~1 rand 0x%x ret 0x%x\n",p,p->last-1);
return p->last-1;
}
/* return a random number between 0.0 and 1.0 */
/* based on rand32 */
double ranno_th(rand_state *p) {
- return rand32_th(NULL, 0) / 4294967295.0;
+ return rand32_th(p, 0) / 4294967295.0;
}
-/* Return a random double in the range min to max */
+/* Return a uniform random double in the range min to max */
double
d_rand_th(rand_state *p, double min, double max) {
return min + (max - min) * ranno_th(p);
}
+/* Return a squared distribution random double in the range min to max */
+double
+d2_rand_th(rand_state *p, double min, double max) {
+ double val = ranno_th(p);
+ return min + (max - min) * val * val;
+}
+
/* Return a random integer in the range min to max inclusive */
int
i_rand_th(rand_state *p, int min, int max) {
diff --git a/numlib/rand.h b/numlib/rand.h
index e190fcd..0339b24 100755
--- a/numlib/rand.h
+++ b/numlib/rand.h
@@ -24,9 +24,12 @@ unsigned int seed); /* Optional seed. Non-zero re-initialized with that seed *
/* Return a random integer in the range min to max inclusive */
int i_rand(int min, int max);
-/* Return a random double in the range min to max inclusive */
+/* Return a uniform random double in the range min to max inclusive */
double d_rand(double min, double max);
+/* Return a squared distribution random double in the range min to max inclusive */
+double d2_rand(double min, double max);
+
/* Return a random floating point number with a gausian/normal */
/* distribution, centered about 0.0, with standard deviation 1.0 */
/* and an average deviation of 0.564 */
@@ -61,9 +64,12 @@ unsigned int seed); /* Optional seed. Non-zero re-initialized with that seed *
/* Return a random integer in the range min to max inclusive */
int i_rand_th(rand_state *p, int min, int max);
-/* Return a random double in the range min to max inclusive */
+/* Return a uniform random double in the range min to max inclusive */
double d_rand_th(rand_state *p, double min, double max);
+/* Return a squared distribution random double in the range min to max inclusive */
+double d2_rand_th(rand_state *p, double min, double max);
+
/* Return a random floating point number with a gausian/normal */
/* distribution, centered about 0.0, with standard deviation 1.0 */
/* and an average deviation of 0.564 */
diff --git a/numlib/roots.c b/numlib/roots.c
new file mode 100755
index 0000000..04e1526
--- /dev/null
+++ b/numlib/roots.c
@@ -0,0 +1,217 @@
+
+/*
+ * Roots3And4.c
+ *
+ * Utility functions to find cubic and quartic roots.
+ *
+ * Coefficients are passed like this:
+ *
+ * c[0] + c[1]*x + c[2]*x^2 + c[3]*x^3 + c[4]*x^4 = 0
+ *
+ * The functions return the number of non-complex roots and
+ * put the values into the s array.
+ *
+ * Author: Jochen Schwarze (schwarze@isa.de)
+ *
+ * Jan 26, 1990 Version for Graphics Gems
+ * Oct 11, 1990 Fixed sign problem for negative q's in SolveQuartic
+ * (reported by Mark Podlipec),
+ * Old-style function definitions,
+ * IsZero() as a macro
+ * Nov 23, 1990 Some systems do not declare acos() and cbrt() in
+ * <math.h>, though the functions exist in the library.
+ * If large coefficients are used, EQN_EPS should be
+ * reduced considerably (e.g. to 1E-30), results will be
+ * correct but multiple roots might be reported more
+ * than once.
+ * Apr 18, 2018 Reformat for inclusing in ArgyllCMS - GWG
+ *
+ * The authors and the publisher hold no copyright restrictions
+ * on any of these files; this source code is public domain, and
+ * is freely available to the entire computer graphics community
+ * for study, use, and modification. We do request that the
+ * comment at the top of each file, identifying the original
+ * author and its original publication in the book Graphics
+ * Gems, be retained in all programs that use these files.
+ *
+ */
+
+#include <math.h>
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+/* epsilon surrounding for near zero values */
+#define EQN_EPS 1e-9
+#define IsZero(x) ((x) > -EQN_EPS && (x) < EQN_EPS)
+
+#define CBRT(x) ((x) > 0.0 ? pow((double)(x), 1.0/3.0) : \
+ ((x) < 0.0 ? -pow((double)-(x), 1.0/3.0) : 0.0))
+
+int SolveQuadric(double c[3], double s[2]) {
+ double p, q, D;
+
+ /* normal form: x^2 + px + q = 0 */
+ p = c[1] / (2 * c[2]);
+ q = c[0] / c[2];
+
+ D = p * p - q;
+
+ if (IsZero(D)) {
+ s[ 0 ] = - p;
+ return 1;
+ } else if (D < 0) {
+ return 0;
+ } else /* if (D > 0) */ {
+ double sqrt_D = sqrt(D);
+
+ s[0] = sqrt_D - p;
+ s[1] = - sqrt_D - p;
+ return 2;
+ }
+}
+
+
+int SolveCubic(double c[4], double s[3]) {
+ int i, num;
+ double sub;
+ double A, B, C;
+ double sq_A, p, q;
+ double cb_p, D;
+
+ /* normal form: x^3 + Ax^2 + Bx + C = 0 */
+ A = c[2] / c[3];
+ B = c[1] / c[3];
+ C = c[0] / c[3];
+
+ /* substitute x = y - A/3 to eliminate quadric term: */
+ /* x^3 +px + q = 0 */
+ sq_A = A * A;
+ p = 1.0/3 * (-1.0/3 * sq_A + B);
+ q = 1.0/2 * (2.0/27 * A * sq_A - 1.0/3 * A * B + C);
+
+ /* use Cardano's formula */
+ cb_p = p * p * p;
+ D = q * q + cb_p;
+
+ if (IsZero(D)) {
+ if (IsZero(q)) { /* one triple solution */
+ s[0] = 0.0;
+ num = 1;
+ } else { /* one single and one double solution */
+ double u = CBRT(-q);
+ s[0] = 2.0 * u;
+ s[1] = - u;
+ num = 2;
+ }
+ } else if (D < 0) { /* Casus irreducibilis: three real solutions */
+ double phi = 1.0/3 * acos(-q / sqrt(-cb_p));
+ double t = 2 * sqrt(-p);
+
+ s[0] = t * cos(phi);
+ s[1] = -t * cos(phi + M_PI / 3.0);
+ s[2] = -t * cos(phi - M_PI / 3.0);
+ num = 3;
+ } else { /* one real solution */
+ double sqrt_D = sqrt(D);
+ double u = CBRT(sqrt_D - q);
+ double v = -CBRT(sqrt_D + q);
+
+ s[0] = u + v;
+ num = 1;
+ }
+
+ /* resubstitute */
+ sub = 1.0/3.0 * A;
+
+ for (i = 0; i < num; i++)
+ s[i] -= sub;
+
+ return num;
+}
+
+
+int SolveQuartic(double c[5], double s[4]) {
+ double coeffs[4];
+ double z, u, v, sub;
+ double A, B, C, D;
+ double sq_A, p, q, r;
+ int i, num;
+
+ /* normal form: x^4 + Ax^3 + Bx^2 + Cx + D = 0 */
+ A = c[3] / c[4];
+ B = c[2] / c[4];
+ C = c[1] / c[4];
+ D = c[0] / c[4];
+
+ /* substitute x = y - A/4 to eliminate cubic term:
+ x^4 + px^2 + qx + r = 0 */
+ sq_A = A * A;
+ p = - 3.0/8 * sq_A + B;
+ q = 1.0/8 * sq_A * A - 1.0/2 * A * B + C;
+ r = - 3.0/256*sq_A*sq_A + 1.0/16*sq_A*B - 1.0/4*A*C + D;
+
+ if (IsZero(r)) {
+ /* no absolute term: y(y^3 + py + q) = 0 */
+
+ coeffs[0] = q;
+ coeffs[1] = p;
+ coeffs[2] = 0;
+ coeffs[3] = 1.0;
+
+ num = SolveCubic(coeffs, s);
+
+ s[num++] = 0;
+ } else {
+ /* solve the resolvent cubic ... */
+ coeffs[0] = 1.0/2.0 * r * p - 1.0/8.0 * q * q;
+ coeffs[1] = - r;
+ coeffs[2] = - 1.0/2.0 * p;
+ coeffs[3] = 1.0;
+
+ (void) SolveCubic(coeffs, s);
+
+ /* ... and take the one real solution ... */
+ z = s[0];
+
+ /* ... to build two quadric equations */
+ u = z * z - r;
+ v = 2 * z - p;
+
+ if (IsZero(u))
+ u = 0;
+ else if (u > 0)
+ u = sqrt(u);
+ else
+ return 0;
+
+ if (IsZero(v))
+ v = 0;
+ else if (v > 0)
+ v = sqrt(v);
+ else
+ return 0;
+
+ coeffs[0] = z - u;
+ coeffs[1] = q < 0 ? -v : v;
+ coeffs[2] = 1.0;
+
+ num = SolveQuadric(coeffs, s);
+
+ coeffs[0]= z + u;
+ coeffs[1] = q < 0 ? v : -v;
+ coeffs[2] = 1.0;
+
+ num += SolveQuadric(coeffs, s + num);
+ }
+
+ /* resubstitute */
+ sub = 1.0/4.0 * A;
+
+ for (i = 0; i < num; i++)
+ s[i] -= sub;
+
+ return num;
+}
+
+
diff --git a/numlib/roots.h b/numlib/roots.h
new file mode 100755
index 0000000..e14b72d
--- /dev/null
+++ b/numlib/roots.h
@@ -0,0 +1,23 @@
+
+/*
+ * Roots3And4.c
+ *
+ * Utility functions to find cubic and quartic roots,
+ * coefficients are passed like this:
+ *
+ * c[0] + c[1]*x + c[2]*x^2 + c[3]*x^3 + c[4]*x^4 = 0
+ *
+ * The functions return the number of non-complex roots and
+ * put the values into the s array.
+ *
+ * Author: Jochen Schwarze (schwarze@isa.de)
+ * (From Graphics Gems I)
+ */
+
+int SolveQuadric(double c[3], double s[2]);
+
+int SolveCubic(double c[4], double s[3]);
+
+int SolveQuartic(double c[5], double s[4]);
+
+
diff --git a/numlib/tconjgrad.c b/numlib/tconjgrad.c
new file mode 100755
index 0000000..aa98871
--- /dev/null
+++ b/numlib/tconjgrad.c
@@ -0,0 +1,162 @@
+/* Code to test the conjgrad minimiser */
+/*
+ * Copyright 1999, 2018 Graeme W. Gill
+ * All rights reserved.
+ *
+ * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
+ * see the License.txt file for licencing details.
+ */
+
+#include <stdio.h>
+#include "numlib.h"
+
+/* Final approximate solution: */
+
+double expect[9] = {
+ -0.5706545E+00,
+ -0.6816283E+00,
+ -0.7017325E+00,
+ -0.7042129E+00,
+ -0.7013690E+00,
+ -0.6918656E+00,
+ -0.6657920E+00,
+ -0.5960342E+00,
+ -0.4164121E+00 };
+
+double fcn( /* Return function value */
+ void *fdata, /* Opaque data pointer */
+ double tp[] /* Multivriate input value */
+);
+
+static double dfcn(
+ void *fdata,
+ double dp[],
+ double tp[]
+);
+
+#define N 9
+
+static void progress(void *pdata, int perc) {
+ printf("%c% 3d%%",cr_char,perc);
+ if (perc == 100)
+ printf("\n");
+ fflush(stdout);
+}
+
+int main(void)
+{
+ double cp[N]; /* Function input values */
+ double s[N]; /* Search area */
+ double err;
+ int j;
+ int nprint = 0; /* Itteration debugging print = off */
+ int rc;
+
+ error_program = "tpowell"; /* Set global error reporting string */
+ check_if_not_interactive();
+
+ /* The following starting values provide a rough solution. */
+ for (j = 0; j < N; j++) {
+ cp[j] = -1.f;
+ s[j] = 0.9;
+ }
+
+ nprint = 0;
+
+ /* Set tol to the square root of the machine precision. */
+ /* Unless high precision solutions are required, */
+ /* this is the recommended setting. */
+
+ rc = conjgrad(
+ &err,
+ N, /* Dimentionality */
+ cp, /* Initial starting point */
+ s, /* Size of initial search area */
+ 0.00000001, /* Tollerance of error change to stop on */
+ 1000, /* Maximum iterations allowed */
+ fcn, /* Error function to evaluate */
+ dfcn, /* Partial derivative function */
+ NULL, /* Opaque data needed by function */
+ progress, /* Progress callback */
+ NULL /* Context for callback */
+ );
+
+
+ fprintf(stdout,"Status = %d, final approximate solution err = %f:\n",rc,err);
+ for (j = 0; j < N; j++) {
+ fprintf(stdout,"cp[%d] = %e, expect %e\n",j,cp[j],expect[j]);
+ }
+
+ return 0;
+} /* main() */
+
+/* Function being minimized */
+double fcn( /* Return function value */
+void *fdata, /* Opaque data pointer */
+double tp[] /* Multivriate input value */
+) {
+ double err, tt;
+ double temp, temp1, temp2;
+ int k;
+
+ /* Function Body */
+ err = 0.0;
+ for (k = 0; k < N; ++k) {
+ temp = (3.0 - 2.0 * tp[k]) * tp[k];
+ temp1 = 0.0;
+ if (k != 0) {
+ temp1 = tp[k-1];
+ }
+ temp2 = 0.0;
+ if (k != ((N)-1))
+ temp2 = tp[k+1];
+ tt = temp - temp1 - 2.0 * temp2 + 1.0;
+ err += tt * tt;
+ }
+ err = sqrt(err);
+//printf("Returning %16.14f\n",err);
+ return err;
+}
+
+
+/* Compute aprox. forward difference */
+
+#define JEPS 1.0e-8 /* Aprox. sqrt of machine precision */
+
+static double dfcn(
+void *fdata,
+double dp[],
+double tp[]
+) {
+ int i;
+ double d, h, temp;
+
+ d = fcn(fdata, tp);
+
+ for (i = 0; i < N; i++) {
+ temp = tp[i];
+
+ h = JEPS * fabs(temp);
+ if (h == 0.0)
+ h = JEPS;
+ tp[i] = temp + h; /* Add delta */
+ h = tp[i] - temp; /* Actual delta with fp precision limits */
+
+ dp[i] = (fcn(fdata, tp) - d)/h;
+
+ tp[i] = temp; /* Restore value */
+ }
+
+ return DFUNC_NRV;
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plot/plot.c b/plot/plot.c
index be4d1cf..d0cf081 100755
--- a/plot/plot.c
+++ b/plot/plot.c
@@ -35,6 +35,7 @@
#include <unistd.h>
#endif
#include <math.h>
+#include "aconfig.h"
#include "numlib.h"
#include "plot.h"
//#ifdef STANDALONE_TEST
@@ -54,14 +55,12 @@
#define DEFWHEIGHT 500
/* Graph order is Black = Y1, Red = Y2, Green = Y3, Blue = Y4, Yellow = Y5, Purple = Y6 */
-/* Brown = Y7, Orange = Y8, Grey = Y9, Magenta = Y10 */
+/* Brown = Y7, Orange = Y8, Grey = Y9, Magenta = Y10, Lime = Y11, Pink = Y12 */
double nicenum(double x, int round);
-#define MXGPHS 10 /* Number of graphs with common X axis */
-
/* Colors of the graphs */
-static int gcolors[MXGPHS][3] = {
+int plot_colors[MXGPHS][3] = {
{ 0, 0, 0}, /* Black */
{ 210, 30, 0}, /* Red */
{ 0, 200, 90}, /* Green */
@@ -71,7 +70,9 @@ static int gcolors[MXGPHS][3] = {
{ 136, 86, 68}, /* Brown */
{ 248, 95, 0}, /* Orange */
{ 160, 160, 160}, /* Grey */
- { 220, 30, 220} /* Magenta */
+ { 220, 30, 220}, /* Magenta */
+ { 112, 255, 161}, /* Lime */
+ { 255, 191, 80} /* Pink */
};
/* Information defining plot */
@@ -90,6 +91,7 @@ struct _plot_info {
double *x1, *x2;
double *yy[MXGPHS]; /* y1 - y10 */
+ plot_col *ncols;
char **ntext;
int n;
@@ -123,7 +125,7 @@ static int do_plot_imp(
double ratio, /* Aspect ratio of window, X/Y, 1.0 = nominal */
int dowait, /* > 0 wait for user to hit space key, < 0 delat dowait seconds. */
double *x1, double *x2,
- double *yy[MXGPHS], char **ntext,
+ double *yy[MXGPHS], plot_col *ncols, char **ntext,
int n,
double *x7, double *y7, plot_col *mcols, char **mtext,
int m,
@@ -184,7 +186,7 @@ int n) {
return do_plot_imp(PLOTF_NONE,
xmin, xmax, ymin, ymax, 1.0, 1,
- x, NULL, yy, NULL, n,
+ x, NULL, yy, NULL, NULL, n,
NULL, NULL, NULL, NULL, 0,
NULL, NULL, NULL, NULL, NULL, 0);
}
@@ -256,7 +258,7 @@ int m) {
return do_plot_imp(PLOTF_NONE,
xmin, xmax, ymin, ymax, 1.0, 1,
- x, NULL, yy, NULL, n,
+ x, NULL, yy, NULL, NULL, n,
x4, y4, NULL, NULL, m ,
NULL, NULL, NULL, NULL, NULL, 0);
}
@@ -331,7 +333,7 @@ double ratio
return do_plot_imp(PLOTF_NONE,
xmin, xmax, ymin, ymax, ratio, dowait,
- x, NULL, yy, NULL, n,
+ x, NULL, yy, NULL, NULL, n,
NULL, NULL, NULL, NULL, 0,
NULL, NULL, NULL, NULL, NULL, 0);
}
@@ -393,7 +395,7 @@ int n) { /* Number of values */
return do_plot_imp(PLOTF_NONE,
xmin, xmax, ymin, ymax, 1.0, 1,
- x, NULL, yy, NULL, n,
+ x, NULL, yy, NULL, NULL, n,
NULL, NULL, NULL, NULL, n ,
NULL, NULL, NULL, NULL, NULL, 0);
}
@@ -472,49 +474,26 @@ int m) {
return do_plot_imp(PLOTF_NONE,
xmin, xmax, ymin, ymax, 1.0, 1,
- x, NULL, yy, NULL, n,
+ x, NULL, yy, NULL, NULL, n,
xp, yp, NULL, NULL, m,
NULL, NULL, NULL, NULL, NULL, 0);
}
/* Public routines */
-/* Plot up to 10 graphs. Wait for a key */
-/* return 0 on success, -1 on error */
-/* If n is -ve, reverse the X axis */
+/* Plot up to 12 graphs + optional crosses */
int
-do_plot10(
-double *x, /* X coord */
-double *y1, /* Black */
-double *y2, /* Red */
-double *y3, /* Green */
-double *y4, /* Blue */
-double *y5, /* Yellow */
-double *y6, /* Purple */
-double *y7, /* Brown */
-double *y8, /* Orange */
-double *y9, /* Grey */
-double *y10,/* White */
-int n, /* Number of values */
-int zero /* Flag - make sure zero is in y range */
+do_plotNpwz(
+double *x, /* X coord */
+double **yy, /* Y values, NULL for none */
+int n, /* Number of values, -ve for reverse X axis */
+double *xp, double *yp, /* And crosses */
+int m, /* Number of crosses */
+int dowait, /* == 0 no wait, > 0, wait for user key, < 0 wait for secs */
+int zero /* Flag - nz, make sure zero is in y range */
) {
int i, j;
double xmin, xmax, ymin, ymax;
int nn = abs(n);
- double *yy[MXGPHS];
-
- for (j = 0; j < MXGPHS; j++)
- yy[j] = NULL;
-
- yy[0] = y1;
- yy[1] = y2;
- yy[2] = y3;
- yy[3] = y4;
- yy[4] = y5;
- yy[5] = y6;
- yy[6] = y7;
- yy[7] = y8;
- yy[8] = y9;
- yy[9] = y10;
/* Determine min and max dimensions of plot */
xmin = ymin = 1e6;
@@ -536,9 +515,24 @@ int zero /* Flag - make sure zero is in y range */
}
}
+ for (i = 0; i < m; i++) {
+ if (xp != NULL) {
+ if (xmin > xp[i])
+ xmin = xp[i];
+ if (xmax < xp[i])
+ xmax = xp[i];
+ }
+ if (yp != NULL) {
+ if (ymin > yp[i])
+ ymin = yp[i];
+ if (ymax < yp[i])
+ ymax = yp[i];
+ }
+ }
+
if (zero && ymin > 0.0)
ymin = 0.0;
-
+
/* Work out scale factors */
if ((xmax - xmin) == 0.0)
xmax += 0.5, xmin -= 0.5;
@@ -546,9 +540,9 @@ int zero /* Flag - make sure zero is in y range */
ymax += 0.5, ymin -= 0.5;
return do_plot_imp(PLOTF_NONE,
- xmin, xmax, ymin, ymax, 1.0, 1,
- x, NULL, yy, NULL, n,
- NULL, NULL, NULL, NULL, n ,
+ xmin, xmax, ymin, ymax, 1.0, dowait,
+ x, NULL, yy, NULL, NULL, n,
+ xp, yp, NULL, NULL, m,
NULL, NULL, NULL, NULL, NULL, 0);
}
@@ -558,8 +552,9 @@ int zero /* Flag - make sure zero is in y range */
/* if dowait < 0, wait for no seconds */
/* return 0 on success, -1 on error */
/* If n is -ve, reverse the X axis */
+/* If zero, ensure Y goes to zero */
int
-do_plot10pw(
+do_plot10pwz(
double *x, /* X coord */
double *y1, /* Black */
double *y2, /* Red */
@@ -571,13 +566,13 @@ double *y7, /* Brown */
double *y8, /* Orange */
double *y9, /* Grey */
double *y10,/* White */
-int n, /* Number of values */
+int n, /* Number of values, -ve for reverse X axis */
double *xp, double *yp, /* And crosses */
-int m,
-int dowait) {
- int i, j;
- double xmin, xmax, ymin, ymax;
- int nn = abs(n);
+int m, /* Number of crosses */
+int dowait, /* == 0 no wait, > 0, wait for user key, < 0 wait for secs */
+int zero /* Flag - nz, make sure zero is in y range */
+) {
+ int j;
double *yy[MXGPHS];
for (j = 0; j < MXGPHS; j++)
@@ -594,52 +589,54 @@ int dowait) {
yy[8] = y9;
yy[9] = y10;
- /* Determine min and max dimensions of plot */
- xmin = ymin = 1e6;
- xmax = ymax = -1e6;
-
- for (i = 0; i < n; i++) {
- if (xmin > x[i])
- xmin = x[i];
- if (xmax < x[i])
- xmax = x[i];
-
- for (j = 0; j < MXGPHS; j++) {
- if (yy[j] != NULL) {
- if (ymin > yy[j][i])
- ymin = yy[j][i];
- if (ymax < yy[j][i])
- ymax = yy[j][i];
- }
- }
- }
-
- for (i = 0; i < m; i++) {
- if (xp != NULL) {
- if (xmin > xp[i])
- xmin = xp[i];
- if (xmax < xp[i])
- xmax = xp[i];
- }
- if (yp != NULL) {
- if (ymin > yp[i])
- ymin = yp[i];
- if (ymax < yp[i])
- ymax = yp[i];
- }
- }
+ return do_plotNpwz(x, yy, n, xp, yp, m, dowait, zero);
+}
- /* Work out scale factors */
- if ((xmax - xmin) == 0.0)
- xmax += 0.5, xmin -= 0.5;
- if ((ymax - ymin) == 0.0)
- ymax += 0.5, ymin -= 0.5;
+/* Plot up to 10 graphs. Wait for a key */
+/* return 0 on success, -1 on error */
+/* If n is -ve, reverse the X axis */
+int
+do_plot10(
+double *x, /* X coord */
+double *y1, /* Black */
+double *y2, /* Red */
+double *y3, /* Green */
+double *y4, /* Blue */
+double *y5, /* Yellow */
+double *y6, /* Purple */
+double *y7, /* Brown */
+double *y8, /* Orange */
+double *y9, /* Grey */
+double *y10,/* White */
+int n, /* Number of values */
+int zero /* Flag - make sure zero is in y range */
+) {
+ return do_plot10pwz(x, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, n, NULL, NULL, 0, 1, zero);
+}
- return do_plot_imp(PLOTF_NONE,
- xmin, xmax, ymin, ymax, 1.0, dowait,
- x, NULL, yy, NULL, n,
- xp, yp, NULL, NULL, m,
- NULL, NULL, NULL, NULL, NULL, 0);
+/* Plot up to 10 graphs + optional crosses */
+/* if dowait > 0, wait for user key */
+/* if dowait < 0, wait for no seconds */
+/* return 0 on success, -1 on error */
+/* If n is -ve, reverse the X axis */
+int
+do_plot10pw(
+double *x, /* X coord */
+double *y1, /* Black */
+double *y2, /* Red */
+double *y3, /* Green */
+double *y4, /* Blue */
+double *y5, /* Yellow */
+double *y6, /* Purple */
+double *y7, /* Brown */
+double *y8, /* Orange */
+double *y9, /* Grey */
+double *y10,/* White */
+int n, /* Number of values */
+double *xp, double *yp, /* And crosses */
+int m,
+int dowait) {
+ return do_plot10pwz(x, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, n, xp, yp, m, dowait, 0);
}
/* Plot up to 10 graphs + optional crosses. Wait for a key */
@@ -661,7 +658,7 @@ double *y10,/* White */
int n, /* Number of values */
double *xp, double *yp, /* And crosses */
int m) {
- return do_plot10pw(x, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, n, xp, yp, m, 1);
+ return do_plot10pwz(x, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, n, xp, yp, m, 1, 0);
}
@@ -695,7 +692,7 @@ int m /* Number of points */
return do_plot_imp(PLOTF_VECCROSSES,
xmin, xmax, ymin, ymax, 1.0, dowait,
- x1, x2, yy, NULL, n,
+ x1, x2, yy, NULL, NULL, n,
x3, y3, mcols, mtext, m,
NULL, NULL, NULL, NULL, NULL, 0);
}
@@ -737,7 +734,54 @@ int o /* Number of vectors */
return do_plot_imp(PLOTF_VECCROSSES,
xmin, xmax, ymin, ymax, 1.0, dowait,
- x1, x2, yy, ntext, n,
+ x1, x2, yy, NULL, ntext, n,
+ x3, y3, mcols, mtext, m,
+ x4, y4, x5, y5, ocols, o);
+}
+
+/* Plot a bunch of colored vectors + points + optional colored points & notation */
+/* + optional colored vectors */
+/* return 0 on success, -1 on error */
+/* Vectors are x1, y1 to x2, y2 with color ncols and annotated 'X' at x2, y2, */
+/* Colored annotated Crosss at x3, y3. */
+/* Colored vector from x4, y4 to x5, y5 */
+int do_plot_vec3(
+double xmin,
+double xmax,
+double ymin,
+double ymax,
+double *x1, /* n vector start */
+double *y1,
+double *x2, /* vector end and diagonal cross */
+double *y2,
+plot_col *ncols,/* Vector and cross colors */
+char **ntext, /* text annotation at cross */
+int n, /* Number of vectors */
+int dowait,
+double *x3, /* m extra crosses */
+double *y3,
+plot_col *mcols,/* cross colors */
+char **mtext, /* text annotation at cross */
+int m, /* Number of crosses */
+double *x4, /* o vector start */
+double *y4,
+double *x5, /* o vector end */
+double *y5,
+plot_col *ocols,/* Vector colors */
+int o /* Number of vectors */
+) {
+ int j;
+ double *yy[MXGPHS];
+
+ for (j = 0; j < MXGPHS; j++)
+ yy[j] = NULL;
+
+ yy[0] = y1;
+ yy[1] = y2;
+
+ return do_plot_imp(PLOTF_VECCROSSES,
+ xmin, xmax, ymin, ymax, 1.0, dowait,
+ x1, x2, yy, ncols, ntext, n,
x3, y3, mcols, mtext, m,
x4, y4, x5, y5, ocols, o);
}
@@ -836,7 +880,7 @@ DWORD WINAPI plot_message_thread(LPVOID lpParameter) {
/* Hybrid Graph uses x1 : y1, y2, y3, y4, y5, y6 for up to 6 graph curves + */
/* optional diagonal crosses at x7, y7 in yellow (x2 == NULL). */
/* Vector uses x1, y1 to x2, y2 as a vector with a (optional) diagonal cross at x2, y2 */
-/* all in black with annotation ntext at the cross, */
+/* all in black or ncols with annotation ntext at the cross, */
/* plus a (optiona) diagonal cross at x7, y7 in yellow. The color for x7, y7 can be */
/* overidden by an array of colors mcols, plus optional label text mtext. (x2 != NULL) */
/* n = number of points/vectors. -ve for reversed X axis */
@@ -848,7 +892,7 @@ static int do_plot_imp(
double ratio, /* Aspect ratio of window, X/Y */
int dowait, /* > 0 wait for user to hit space key, < 0 delat dowait seconds. */
double *x1, double *x2,
- double *yy[MXGPHS], char **ntext,
+ double *yy[MXGPHS], plot_col *ncols, char **ntext,
int n,
double *x7, double *y7, plot_col *mcols, char **mtext,
int m,
@@ -883,11 +927,12 @@ static int do_plot_imp(
if (x2 == NULL)
pd.graph = 1; /* 6 graphs + points */
else
- pd.graph = 0;
+ pd.graph = 0; /* vectors + optional crosses */
pd.x1 = x1;
pd.x2 = x2;
for (j = 0; j < MXGPHS; j++)
pd.yy[j] = yy[j];
+ pd.ncols = ncols;
pd.ntext = ntext;
pd.n = abs(n);
@@ -1105,25 +1150,13 @@ plot_info *p
DeleteObject(pen);
if (p->graph) { /* Up to MXGPHS graphs + crosses */
- int gcolors[MXGPHS][3] = {
- { 0, 0, 0}, /* Black */
- { 210, 30, 0}, /* Red */
- { 0, 200, 90}, /* Green */
- { 0, 10, 255}, /* Blue */
- { 200, 200, 0}, /* Yellow */
- { 220, 0, 255}, /* Purple */
- { 136, 86, 68}, /* Brown */
- { 248, 95, 0}, /* Orange */
- { 160, 160, 160}, /* Grey */
- { 220, 220, 220} /* White */
- };
for (j = MXGPHS-1; j >= 0; j--) {
double *yp = p->yy[j];
if (yp == NULL)
continue;
- pen = CreatePen(PS_SOLID,ILTHICK,RGB(gcolors[j][0],gcolors[j][1],gcolors[j][2]));
+ pen = CreatePen(PS_SOLID,ILTHICK,RGB(plot_colors[j][0],plot_colors[j][1],plot_colors[j][2]));
SelectObject(hdc,pen);
lx = (int)((p->x1[0] - p->mnx) * p->scx + 0.5);
@@ -1149,8 +1182,9 @@ plot_info *p
} else { /* Vectors with cross */
- pen = CreatePen(PS_SOLID,ILTHICK,RGB(0,0,0));
- SelectObject(hdc,pen);
+ /* Default is black */
+ pen = CreatePen(PS_SOLID,ILTHICK, RGB(0,0,0));
+ SelectObject(hdc, pen);
if (p->ntext != NULL) {
HFONT fon;
@@ -1170,6 +1204,20 @@ plot_info *p
for (i = 0; i < p->n; i++) {
int cx,cy;
+ if (p->ncols != NULL) {
+ int rgb[3];
+
+ for (j = 0; j < 3; j++)
+ rgb[j] = (int)(p->ncols[i].rgb[j] * 255.0 + 0.5);
+
+ DeleteObject(pen);
+ pen = CreatePen(PS_SOLID,ILTHICK,RGB(rgb[0],rgb[1],rgb[2]));
+ SelectObject(hdc,pen);
+
+ if (p->mtext != NULL)
+ SetTextColor(hdc, RGB(rgb[0],rgb[1],rgb[2]));
+ }
+
lx = (int)((p->x1[i] - p->mnx) * p->scx + 0.5);
ly = (int)((p->yy[0][i] - p->mny) * p->scy + 0.5);
@@ -1450,7 +1498,7 @@ static void create_my_win(void *cntx) {
/* Hybrid Graph uses x1 : y1, y2, y3, y4, y5, y6 for up to 6 graph curves + */
/* optional diagonal crosses at x7, y7 in yellow (x2 == NULL). */
/* Vector uses x1, y1 to x2, y2 as a vector with a (optional) diagonal cross at x2, y2 */
-/* all in black with annotation ntext at the cross, */
+/* all in black or ncols with annotation ntext at the cross, */
/* plus a (optiona) diagonal cross at x7, y7 in yellow. The color for x7, y7 can be */
/* overidden by an array of colors mcols, plus optional label text mtext. (x2 != NULL) */
/* n = number of points/vectors. -ve for reversed X axis */
@@ -1462,7 +1510,7 @@ static int do_plot_imp(
double ratio, /* Aspect ratio of window, X/Y */
int dowait, /* > 0 wait for user to hit space key, < 0 delat dowait seconds. */
double *x1, double *x2,
- double *yy[MXGPHS], char **ntext,
+ double *yy[MXGPHS], plot_col *ncols, char **ntext,
int n,
double *x7, double *y7, plot_col *mcols, char **mtext,
int m,
@@ -1504,6 +1552,7 @@ static int do_plot_imp(
pd.x2 = x2;
for (j = 0; j < MXGPHS; j++)
pd.yy[j] = yy[j];
+ pd.ncols = ncols;
pd.ntext = ntext;
pd.n = abs(n);
@@ -1761,26 +1810,15 @@ static void DoPlot(NSRect *rect, plot_info *pdp) {
[path setLineDash: NULL count: 0 phase: 0.0 ];
if (pdp->graph) { /* Up to 6 graphs */
- int gcolors[MXGPHS][3] = {
- { 0, 0, 0}, /* Black */
- { 210, 30, 0}, /* Red */
- { 0, 200, 90}, /* Green */
- { 0, 10, 255}, /* Blue */
- { 200, 200, 0}, /* Yellow */
- { 220, 0, 255}, /* Purple */
- { 136, 86, 68}, /* Brown */
- { 248, 95, 0}, /* Orange */
- { 160, 160, 160}, /* Grey */
- { 220, 220, 220} /* White */
- };
for (j = MXGPHS-1; j >= 0; j--) {
double *yp = pdp->yy[j];
if (yp == NULL)
continue;
- [[NSColor colorWithCalibratedRed: gcolors[j][0]/255.0
- green: gcolors[j][1]/255.0
- blue: gcolors[j][2]/255.0
+
+ [[NSColor colorWithCalibratedRed: plot_colors[j][0]/255.0
+ green: plot_colors[j][1]/255.0
+ blue: plot_colors[j][2]/255.0
alpha: 1.0] setStroke];
if (pdp->n > 0) {
@@ -1804,6 +1842,7 @@ static void DoPlot(NSRect *rect, plot_info *pdp) {
}
} else { /* Vectors */
+
[[NSColor colorWithCalibratedRed: 0.0
green: 0.0
blue: 0.0
@@ -1817,6 +1856,20 @@ static void DoPlot(NSRect *rect, plot_info *pdp) {
for (i = 0; i < pdp->n; i++) {
int cx,cy;
+ if (pdp->ncols != NULL) {
+ [[NSColor colorWithCalibratedRed: pdp->ncols[i].rgb[0]/255.0
+ green: pdp->ncols[i].rgb[1]/255.0
+ blue: pdp->ncols[i].rgb[2]/255.0
+ alpha: 1.0] setStroke];
+
+ if (pdp->ntext != NULL) {
+ tcol = [NSColor colorWithCalibratedRed: pdp->ncols[i].rgb[0]/255.0
+ green: pdp->ncols[i].rgb[1]/255.0
+ blue: pdp->ncols[i].rgb[2]/255.0
+ alpha: 1.0];
+ }
+ }
+
lx = (int)((pdp->x1[i] - pdp->mnx) * pdp->scx + 0.5);
ly = (int)((pdp->yy[0][i] - pdp->mny) * pdp->scy + 0.5);
@@ -1924,7 +1977,7 @@ void DoPlot(Display *mydisplay, Window mywindow, GC mygc, plot_info *pdp);
/* Hybrid Graph uses x1 : y1, y2, y3, y4, y5, y6 for up to 6 graph curves + */
/* optional diagonal crosses at x7, y7 in yellow (x2 == NULL). */
/* Vector uses x1, y1 to x2, y2 as a vector with a (optional) diagonal cross at x2, y2 */
-/* all in black with annotation ntext at the cross, */
+/* all in black or ncols with annotation ntext at the cross, */
/* plus a (optiona) diagonal cross at x7, y7 in yellow. The color for x7, y7 can be */
/* overidden by an array of colors mcols, plus optional label text mtext. (x2 != NULL) */
/* n = number of points/vectors. -ve for reversed X axis */
@@ -1936,7 +1989,7 @@ static int do_plot_imp(
double ratio, /* Aspect ratio of window, X/Y */
int dowait, /* > 0 wait for user to hit space key, < 0 delat dowait seconds. */
double *x1, double *x2,
- double *yy[MXGPHS], char **ntext,
+ double *yy[MXGPHS], plot_col *ncols, char **ntext,
int n,
double *x7, double *y7, plot_col *mcols, char **mtext,
int m,
@@ -1977,6 +2030,7 @@ static int do_plot_imp(
pd.x2 = x2;
for (j = 0; j < MXGPHS; j++)
pd.yy[j] = yy[j];
+ pd.ncols = ncols;
pd.ntext = ntext;
pd.n = abs(n);
@@ -2225,9 +2279,9 @@ plot_info *pdp
if (yp == NULL)
continue;
- col.red = gcolors[j][0] * 256;
- col.green = gcolors[j][1] * 256;
- col.blue = gcolors[j][2] * 256;
+ col.red = plot_colors[j][0] * 256;
+ col.green = plot_colors[j][1] * 256;
+ col.blue = plot_colors[j][2] * 256;
XAllocColor(mydisplay, mycmap, &col);
XSetForeground(mydisplay,mygc, col.pixel);
XSetLineAttributes(mydisplay, mygc, ILTHICK, LineSolid, CapButt, JoinBevel);
@@ -2252,7 +2306,6 @@ plot_info *pdp
} else { /* Vectors */
- col.red = col.green = col.blue = 0 * 256;
XAllocColor(mydisplay, mycmap, &col);
XSetForeground(mydisplay,mygc, col.pixel);
XSetLineAttributes(mydisplay, mygc, ILTHICK, LineSolid, CapButt, JoinBevel);
@@ -2260,6 +2313,15 @@ plot_info *pdp
for (i = 0; i < pdp->n; i++) {
int cx,cy;
+ if (pdp->ncols != NULL) {
+ col.red = (int)(pdp->ncols[i].rgb[0] * 65535.0 + 0.5);
+ col.green = (int)(pdp->ncols[i].rgb[1] * 65535.0 + 0.5);
+ col.blue = (int)(pdp->ncols[i].rgb[2] * 65535.0 + 0.5);
+ XAllocColor(mydisplay, mycmap, &col);
+ XSetForeground(mydisplay,mygc, col.pixel);
+ XSetLineAttributes(mydisplay, mygc, ILTHICK, LineSolid, CapButt, JoinBevel);
+ }
+
lx = (int)((pdp->x1[i] - pdp->mnx) * pdp->scx + 0.5);
ly = (int)((pdp->yy[0][i] - pdp->mny) * pdp->scy + 0.5);
diff --git a/plot/plot.h b/plot/plot.h
index 8e3db5e..b586903 100755
--- a/plot/plot.h
+++ b/plot/plot.h
@@ -11,6 +11,10 @@
* see the License.txt file for licencing details.
*/
+/* MXGPHS is defined in aconfig.h */
+
+extern int plot_colors[MXGPHS][3];
+
/* Graph order is Black = Y1, Red = Y2, Green = Y3, Blue = Y4, Yellow = Y5, Purple = Y6 */
/* Brown = Y7, Orange = Y8, Grey = Y9, White = Y10 */
@@ -78,6 +82,20 @@ int do_plot10pw(double *x, double *y1, double *y2, double *y3, double *y4, doubl
double *y7, double *y8, double *y9, double *y10,
int n, double *xp, double *yp, int m, int dowait);
+/* Plot up to 10 graphs + optional crosses */
+/* if dowait > 0, wait for user key */
+/* if dowait < 0, wait for no seconds */
+/* return 0 on success, -1 on error */
+/* If n is -ve, reverse the X axis */
+/* if dozero flag, make sure y range covers zero */
+int do_plot10pwz(double *x, double *y1, double *y2, double *y3, double *y4, double *y5, double *y6,
+ double *y7, double *y8, double *y9, double *y10,
+ int n, double *xp, double *yp, int m, int dowait, int zero);
+
+/* Public routines */
+/* Plot up to MXGPHS (12) graphs + optional crosses */
+int do_plotNpwz(double *x, double **yy, int n, double *xp, double *yp, int m, int dowait, int zero);
+
/* Plot a bunch of vectors + points + optional colored points & notation */
/* return 0 on success, -1 on error */
/* Vectors are x1, y1 to x2, y2 with 'X' at x2, y2, */
@@ -99,5 +117,17 @@ int do_plot_vec2(double xmin, double xmax, double ymin, double ymax,
double *x3, double *y3, plot_col *mcols, char **mtext, int m,
double *x4, double *y4, double *x5, double *y5, plot_col *ocols, int o);
+/* Plot a bunch of colored vectors + points + optional colored points & notation */
+/* + optional colored vectors */
+/* return 0 on success, -1 on error */
+/* Vectors are x1, y1 to x2, y2 with color ncols and annotated 'X' at x2, y2, */
+/* Colored annotated Crosss at x3, y3. */
+/* Colored vector from x4, y4 to x5, y5 */
+int do_plot_vec3(double xmin, double xmax, double ymin, double ymax,
+ double *x1, double *y1, double *x2, double *y2, plot_col *ncols, char **ntext, int n,
+ int dowait,
+ double *x3, double *y3, plot_col *mcols, char **mtext, int m,
+ double *x4, double *y4, double *x5, double *y5, plot_col *ocols, int o);
+
#define PLOT_H
#endif /* PLOT_H */
diff --git a/profile/colverify.c b/profile/colverify.c
index d7100a3..de99c15 100755
--- a/profile/colverify.c
+++ b/profile/colverify.c
@@ -759,7 +759,7 @@ int main(int argc, char *argv[])
if (l_observ == icxOT_none)
l_observ = icxOT_CIE_1931_2;
- if ((sp2cie = new_xsp2cie(l_illum, l_illum == icxIT_none ? NULL : &cust_illum,
+ if ((sp2cie = new_xsp2cie(l_illum, 0.0, l_illum == icxIT_none ? NULL : &cust_illum,
l_observ, custObserver, icSigXYZData, icxClamp)) == NULL)
error("Creation of spectral conversion object failed");
diff --git a/profile/mppcheck.c b/profile/mppcheck.c
index 6615a84..07ecc16 100755
--- a/profile/mppcheck.c
+++ b/profile/mppcheck.c
@@ -502,7 +502,7 @@ int main(int argc, char *argv[])
xsp2cie *sc;
xspect sp;
- if ((sc = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL)
+ if ((sc = new_xsp2cie(icxIT_D50, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL)
error("Failed to create xsp2cie object");
/* Set standard D50 viewer & illum. */
diff --git a/profile/mppprof.c b/profile/mppprof.c
index 41fe2fc..ace8c97 100755
--- a/profile/mppprof.c
+++ b/profile/mppprof.c
@@ -693,13 +693,13 @@ make_output_mpp(
xspect sp;
if (isDisplay) {
- if ((sc = new_xsp2cie(icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL)
+ if ((sc = new_xsp2cie(icxIT_none, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL)
error("Failed to create xsp2cie object");
p->set_ilob(p, icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, 0);
} else {
/* Set standard D50 viewer & illum. */
- if ((sc = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL)
+ if ((sc = new_xsp2cie(icxIT_D50, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL)
error("Failed to create xsp2cie object");
p->set_ilob(p, icxIT_D50, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, 0);
@@ -865,13 +865,13 @@ make_output_mpp(
if (isDisplay) {
/* Set emissive viewer. */
- if ((sc = new_xsp2cie(icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL)
+ if ((sc = new_xsp2cie(icxIT_none, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL)
error("Failed to create xsp2cie object");
/* (mpp will ignore illuminant for display anyway ??) */
p2->set_ilob(p2, icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, 0);
} else {
/* Set standard D50 viewer & illum. */
- if ((sc = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL)
+ if ((sc = new_xsp2cie(icxIT_D50, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL)
error("Failed to create xsp2cie object");
p2->set_ilob(p2, icxIT_D50, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, 0);
}
diff --git a/profile/printcal.c b/profile/printcal.c
index 9bbcb41..cee9ed9 100755
--- a/profile/printcal.c
+++ b/profile/printcal.c
@@ -1105,7 +1105,7 @@ int main(int argc, char *argv[]) {
}
/* Create a spectral conversion object to XYZ */
- if ((sp2cie = new_xsp2cie(illum, &cust_illum, observ, NULL, icSigXYZData, icxClamp)) == NULL)
+ if ((sp2cie = new_xsp2cie(illum, 0.0, &cust_illum, observ, NULL, icSigXYZData, icxClamp)) == NULL)
error("Creation of spectral conversion object failed");
/* To add FWA comp. would have to locate/create spectral white here, */
diff --git a/profile/profcheck.c b/profile/profcheck.c
index 62d39bd..ae00dc0 100755
--- a/profile/profcheck.c
+++ b/profile/profcheck.c
@@ -781,7 +781,7 @@ int main(int argc, char *argv[])
}
/* Create a spectral conversion object */
- if ((sp2cie = new_xsp2cie(illum, illum == icxIT_none ? NULL : &cust_illum,
+ if ((sp2cie = new_xsp2cie(illum, 0.0, illum == icxIT_none ? NULL : &cust_illum,
obType, custObserver, icSigLabData, icxClamp)) == NULL)
error("Creation of spectral conversion object failed");
@@ -945,7 +945,7 @@ int main(int argc, char *argv[])
/* Open up the file for reading */
if ((rd_fp = new_icmFileStd_name(iccname,"r")) == NULL)
- error("Write: Can't open file '%s'",iccname);
+ error("Read: Can't open file '%s'",iccname);
if ((rd_icco = new_icc()) == NULL)
error("Read: Creation of ICC object failed");
diff --git a/profile/profin.c b/profile/profin.c
index 92317bb..d20b47a 100755
--- a/profile/profin.c
+++ b/profile/profin.c
@@ -37,6 +37,7 @@
#define verbo stdout
#include <stdio.h>
+#include "aconfig.h"
#include "counters.h"
#include "numlib.h"
#include "icc.h"
@@ -786,7 +787,7 @@ make_input_icc(
illum = icxIT_none;
cust_illum = NULL;
}
- if ((sp2cie = new_xsp2cie(illum, cust_illum, obType, custObserver,
+ if ((sp2cie = new_xsp2cie(illum, 0.0, cust_illum, obType, custObserver,
wantLab ? icSigLabData : icSigXYZData, icxClamp)) == NULL)
error("Creation of spectral conversion object failed");
diff --git a/profile/profout.c b/profile/profout.c
index 47726f1..fe6be0a 100755
--- a/profile/profout.c
+++ b/profile/profout.c
@@ -89,6 +89,7 @@
#define FILTER_MAX_RAD 0.1 /* [0.1] Filtering maximum radius in grid */
#include <stdio.h>
+#include "aconfig.h"
#include "numlib.h"
#include "icc.h"
#include "cgats.h"
@@ -1798,7 +1799,7 @@ make_output_icc(
}
/* Create a spectral conversion object */
- if ((sp2cie = new_xsp2cie(illum, cust_illum, obType, custObserver,
+ if ((sp2cie = new_xsp2cie(illum, 0.0, cust_illum, obType, custObserver,
wantLab ? icSigLabData : icSigXYZData, icxClamp)) == NULL)
error("Creation of spectral conversion object failed");
diff --git a/ref/linear.cal b/ref/linear.cal
index 1dafbde..4555f15 100755
--- a/ref/linear.cal
+++ b/ref/linear.cal
@@ -2,7 +2,7 @@ CAL
DESCRIPTOR "Argyll Device Calibration Curves"
ORIGINATOR "Argyll synthcal"
-CREATED "Fri Nov 17 01:11:11 2017"
+CREATED "Thu Jul 05 04:49:42 2018"
DEVICE_CLASS "DISPLAY"
COLOR_REP "RGB"
diff --git a/ref/strange.cal b/ref/strange.cal
index b31bbed..f620429 100755
--- a/ref/strange.cal
+++ b/ref/strange.cal
@@ -2,7 +2,7 @@ CAL
DESCRIPTOR "Argyll Device Calibration Curves"
ORIGINATOR "Argyll synthcal"
-CREATED "Fri Nov 17 01:11:11 2017"
+CREATED "Thu Jul 05 04:49:42 2018"
DEVICE_CLASS "DISPLAY"
COLOR_REP "RGB"
diff --git a/render/render.h b/render/render.h
index 26b7028..5104ebd 100755
--- a/render/render.h
+++ b/render/render.h
@@ -26,7 +26,7 @@
/* the bottom left corner. */
/* Device color values range from 0.0 to 1.0 */
-#define MXCH2D 8 /* Maximum color channels */
+#define MXCH2D 16 /* Maximum color channels */
#define TOTC2D (MXCH2D+1) /* Maximum total components */
#define PRIX2D (MXCH2D) /* Index of primitive kept with color value */
diff --git a/rspl/Jamfile b/rspl/Jamfile
index 6f80f9f..d007562 100644
--- a/rspl/Jamfile
+++ b/rspl/Jamfile
@@ -69,7 +69,7 @@ if ( $(HOME) = "D:\\usr\\graeme" && $(PWD) = "/src/argyll/rspl" )
Main lchw_solve : lchw_solve.c : : : ../h ../numlib ../icc ../plot : : ../plot/libplot ../icc/libicc ../numlib/libui ../numlib/libnum ;
Main lchw_deriv : lchw_deriv.c : : : ../h ../numlib ../icc ../plot : : ../plot/libplot ../icc/libicc ../numlib/libui ../numlib/libnum ;
Main lchw_2deriv : lchw_2deriv.c : : : ../h ../numlib ../icc ../plot : : ../plot/libplot ../icc/libicc ../numlib/libui ../numlib/libnum ;
- Main crossv : crossv.c : : : ../numlib ../plot : : ../plot/libplot ../numlib/libui ../numlib/libnum ;
+ Main crossv : crossv.c : : : ../h ../numlib ../plot : : ../plot/libplot ../numlib/libui ../numlib/libnum ;
}
if $(BUILD_JUNK) {
diff --git a/rspl/smtmpp.c b/rspl/smtmpp.c
index 1264d4b..baa01b7 100755
--- a/rspl/smtmpp.c
+++ b/rspl/smtmpp.c
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <fcntl.h>
#include <math.h>
+#include "aconfig.h"
#include "rspl.h"
#include "numlib.h"
#include "xicc.h"
diff --git a/rspl/smtnd.c b/rspl/smtnd.c
index 355d20b..b4eeab9 100755
--- a/rspl/smtnd.c
+++ b/rspl/smtnd.c
@@ -23,6 +23,7 @@
#include <stdio.h>
#include <fcntl.h>
#include <math.h>
+#include "aconfig.h"
#include "rspl.h"
#include "numlib.h"
#include "xicc.h" /* For mpp support */
diff --git a/rspl/t2d.c b/rspl/t2d.c
index e3f304c..6c1f742 100755
--- a/rspl/t2d.c
+++ b/rspl/t2d.c
@@ -19,6 +19,7 @@
#include <stdlib.h>
#include <fcntl.h>
#include <math.h>
+#include "aconfig.h"
#include "rspl.h"
#include "tiffio.h"
#include "plot.h"
diff --git a/rspl/t2ddf.c b/rspl/t2ddf.c
index 115d5f5..926968f 100755
--- a/rspl/t2ddf.c
+++ b/rspl/t2ddf.c
@@ -19,6 +19,7 @@
#include <stdlib.h>
#include <fcntl.h>
#include <math.h>
+#include "aconfig.h"
#include "rspl.h"
#include "tiffio.h"
#include "plot.h"
diff --git a/rspl/t3d.c b/rspl/t3d.c
index c526669..d3a77b0 100755
--- a/rspl/t3d.c
+++ b/rspl/t3d.c
@@ -19,6 +19,7 @@
#include <stdlib.h>
#include <fcntl.h>
#include <math.h>
+#include "aconfig.h"
#include "rspl.h"
#include "tiffio.h"
#include "plot.h"
diff --git a/rspl/t3ddf.c b/rspl/t3ddf.c
index 4a43f0d..65b0678 100755
--- a/rspl/t3ddf.c
+++ b/rspl/t3ddf.c
@@ -19,6 +19,7 @@
#include <stdlib.h>
#include <fcntl.h>
#include <math.h>
+#include "aconfig.h"
#include "rspl.h"
#include "tiffio.h"
#include "plot.h"
diff --git a/spectro/ccxxmake.c b/spectro/ccxxmake.c
index 4d8c057..a982107 100755
--- a/spectro/ccxxmake.c
+++ b/spectro/ccxxmake.c
@@ -228,8 +228,8 @@ int main(int argc, char *argv[]) {
int comno = COMPORT; /* COM port used */
flow_control fc = fc_nc; /* Default flow control */
int highres = 0; /* High res mode if available */
- int dtype = 0; /* Display kind, 0 = default, 1 = CRT, 2 = LCD, etc */
- int sdtype = -1; /* Spectro display kind, -1 = use dtype */
+ int ditype = 0; /* Display kind selector, 0 = default */
+ int sditype = -1; /* Spectro display kind, -1 = use ditype */
int refrmode = -1; /* Refresh mode */
double refrate = 0.0; /* 0.0 = default, > 0.0 = override refresh rate */
int cbid = 0; /* Calibration base display mode ID */
@@ -411,7 +411,9 @@ int main(int argc, char *argv[]) {
} else if (argv[fa][1] == 'y') {
fa = nfa;
if (na == NULL) usage(0,"Parameter expected after -y");
- dtype = na[0];
+ ditype = na[0];
+ if (ditype == '_' && na[1] != '\000')
+ ditype = ditype << 8 | na[1];
/* For ccss, set a default */
if (na[0] == 'r') {
@@ -424,7 +426,7 @@ int main(int argc, char *argv[]) {
} else if (argv[fa][1] == 'z') {
fa = nfa;
if (na == NULL) usage(0,"Parameter expected after -z");
- sdtype = na[0];
+ sditype = na[0];
/* Test patch offset and size */
} else if (argv[fa][1] == 'P') {
@@ -884,7 +886,7 @@ int main(int argc, char *argv[]) {
}
/* Create a spectral conversion object */
- if ((sp2cie = new_xsp2cie(icxIT_none, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL)
+ if ((sp2cie = new_xsp2cie(icxIT_none, 0.0, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL)
error("Creation of spectral conversion object failed");
for (i = 0; i < npat; i++) {
@@ -1260,7 +1262,7 @@ int main(int argc, char *argv[]) {
/* Should we use current cal rather than native ??? */
if ((dr = new_disprd(&errc, icmps->get_path(icmps, comno),
- fc, dtype, sdtype, 1, tele, nadaptive,
+ fc, ditype, sditype, 1, tele, nadaptive,
noinitcal, 0, highres, refrate, 3, NULL, NULL,
NULL, 0, disp, 0, fullscreen,
override, webdisp, ccid,
@@ -1318,7 +1320,7 @@ int main(int argc, char *argv[]) {
if (spec) {
/* Create a spectral conversion object */
- if ((sp2cie = new_xsp2cie(icxIT_none, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL)
+ if ((sp2cie = new_xsp2cie(icxIT_none, 0.0, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL)
error("Creation of spectral conversion object failed");
}
for (i = 0; i < npat; i++) { /* For all grid points */
diff --git a/spectro/chartread.c b/spectro/chartread.c
index 6a9db39..14ee129 100755
--- a/spectro/chartread.c
+++ b/spectro/chartread.c
@@ -256,7 +256,7 @@ int trans, /* Use transmission mode */
int emis, /* Use emissive mode */
int displ, /* 1 = Use display emissive mode, 2 = display bright rel. */
/* 3 = display white rel. */
-int dtype, /* Display type selection charater */
+int ditype, /* Display type selection charater */
inst_opt_filter fe, /* Optional filter */
xcalstd scalstd, /* X-Rite calibration standard to set */
xcalstd *ucalstd, /* X-Rite calibration standard actually used */
@@ -398,11 +398,11 @@ a1log *log /* verb, debug & error log */
}
/* Set display type or calibration mode */
- if (dtype != 0) {
+ if (ditype != 0) {
if (cap2 & inst2_disptype) {
int ix;
- if ((ix = inst_get_disptype_index(it, dtype, 0)) < 0) {
+ if ((ix = inst_get_disptype_index(it, ditype, 0)) < 0) {
printf("Setting display type ix %d failed\n",ix);
it->del(it);
return -1;
@@ -2188,7 +2188,7 @@ int main(int argc, char *argv[]) {
int emis = 0; /* Use emissive mode */
int displ = 0; /* 1 = Use display emissive mode, 2 = display bright rel. */
/* 3 = display white rel. */
- int dtype = 0; /* Display type selection charater */
+ int ditype = 0; /* Display type selection charater(s) */
inst_opt_filter fe = inst_opt_filter_unknown;
int pbypatch = 0; /* Read patch by patch */
int disbidi = 0; /* Disable bi-directional strip recognition */
@@ -2383,7 +2383,10 @@ int main(int argc, char *argv[]) {
} else if (argv[fa][1] == 'y') {
fa = nfa;
if (na == NULL) usage();
- dtype = na[0];
+ ditype = na[0];
+ if (ditype == '_' && na[1] != '\000')
+ ditype = ditype << 8 | na[1];
+
/* Request patch by patch measurement */
} else if (argv[fa][1] == 'p') {
@@ -2998,7 +3001,7 @@ int main(int argc, char *argv[]) {
/* Read all of the strips in */
if (read_strips(itype, scols, &atype, npat, totpa, stipa, pis, paix,
saix, ixord, rstart, rand, hex, ipath, fc, plen, glen, tlen,
- trans, emis, displ, dtype, fe, scalstd, &ucalstd, nocal, disbidi, highres,
+ trans, emis, displ, ditype, fe, scalstd, &ucalstd, nocal, disbidi, highres,
ccxxname, obType, custObserver,
scan_tol, pbypatch, xtern, spectral, uvmode, accurate_expd,
emit_warnings, doplot, g_log) == 0) {
diff --git a/spectro/colorhug.c b/spectro/colorhug.c
index aa8ba21..e09362c 100755
--- a/spectro/colorhug.c
+++ b/spectro/colorhug.c
@@ -435,6 +435,7 @@ static inst_code
colorhug_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
int se;
colorhug *p = (colorhug *) pp;
+ icomuflags usbflags = icomuf_none;
a1logd(p->log, 2, "colorhug_init_coms: About to init coms\n");
@@ -444,7 +445,7 @@ colorhug_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
a1logd(p->log, 3, "colorhug_init_coms: About to init HID\n");
/* Set config, interface */
- if ((se = p->icom->set_hid_port(p->icom, icomuf_none, 0, NULL)) != ICOM_OK) {
+ if ((se = p->icom->set_hid_port(p->icom, usbflags, 0, NULL)) != ICOM_OK) {
a1logd(p->log, 1, "colorhug_init_coms: set_hid_port failed ICOM err 0x%x\n",se);
return colorhug_interp_code((inst *)p, icoms2colorhug_err(se));
}
@@ -453,9 +454,16 @@ colorhug_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
a1logd(p->log, 3, "colorhug_init_coms: About to init USB\n");
+#if defined(UNIX_X11)
+ usbflags |= icomuf_detach;
+ /* Some Linux drivers can't open the device a second time, so */
+ /* use the reset on close workaround. */
+ usbflags |= icomuf_reset_before_close;
+#endif
+
/* Set config, interface, write end point, read end point */
// ~~ does Linux need icomuf_reset_before_close ? Why ?
- if ((se = p->icom->set_usb_port(p->icom, 1, 0x00, 0x00, icomuf_detach, 0, NULL))
+ if ((se = p->icom->set_usb_port(p->icom, 1, 0x00, 0x00, usbflags, 0, NULL))
!= ICOM_OK) {
a1logd(p->log, 1, "colorhug_init_coms: set_usb_port failed ICOM err 0x%x\n",se);
return colorhug_interp_code((inst *)p, icoms2colorhug_err(se));
diff --git a/spectro/conv.c b/spectro/conv.c
index a728566..92556ec 100755
--- a/spectro/conv.c
+++ b/spectro/conv.c
@@ -697,6 +697,9 @@ static int delayed_beep(void *pp) {
# endif
#else /* UNIX */
/* Linux is pretty lame in this regard... */
+ /* Maybe we could write an 8Khz 8 bit sample to /dev/dsp, or /dev/audio ? */
+ /* The ALSA system is the modern way for audio output. */
+ /* Also check out what sox does: <http://sox.sourceforge.net/> */
fprintf(stdout, "\a"); fflush(stdout);
#endif
return 0;
diff --git a/spectro/dispcal.c b/spectro/dispcal.c
index a4798af..10f333b 100755
--- a/spectro/dispcal.c
+++ b/spectro/dispcal.c
@@ -1684,7 +1684,7 @@ int main(int argc, char *argv[]) {
icompaths *icmps = NULL;
icompath *ipath = NULL;
flow_control fc = fc_nc; /* Default flow control */
- int dtype = 0; /* Display type selection charater */
+ int ditype = 0; /* Display type selection charater(s) */
int tele = 0; /* nz if telephoto mode */
int nocal = 0; /* Disable auto calibration */
int noplace = 0; /* Disable initial user placement check */
@@ -2121,7 +2121,9 @@ int main(int argc, char *argv[]) {
} else if (argv[fa][1] == 'y') {
fa = nfa;
if (na == NULL) usage(0,"Parameter expected after -y");
- dtype = na[0];
+ ditype = na[0];
+ if (ditype == '_' && na[1] != '\000')
+ ditype = ditype << 8 | na[1];
/* Daylight color temperature */
} else if (argv[fa][1] == 't' || argv[fa][1] == 'T') {
@@ -2342,7 +2344,7 @@ int main(int argc, char *argv[]) {
}
if (docalib) {
- if ((rv = disprd_calibration(ipath, fc, dtype, -1, 0, tele, nadaptive, nocal, disp,
+ if ((rv = disprd_calibration(ipath, fc, ditype, -1, 0, tele, nadaptive, nocal, disp,
webdisp, ccid,
#ifdef NT
madvrdisp,
@@ -2384,7 +2386,7 @@ int main(int argc, char *argv[]) {
native = 0; /* But measure current calibrated & CM response for verify or report calibrated */
/* Get ready to do some readings */
- if ((dr = new_disprd(&errc, ipath, fc, dtype, -1, 0, tele, nadaptive, nocal, noplace,
+ if ((dr = new_disprd(&errc, ipath, fc, ditype, -1, 0, tele, nadaptive, nocal, noplace,
highres, refrate, native, &noramdac, &nocm, NULL, 0,
disp, out_tvenc, fullscreen, override, webdisp, ccid,
#ifdef NT
@@ -2677,14 +2679,15 @@ int main(int argc, char *argv[]) {
/* Read in the setup, user and model values */
- if (dtype == 0) { /* If the use hasn't set anything */
+ if (ditype == 0) { /* If the use hasn't set anything */
if ((fi = icg->find_kword(icg, 0, "DEVICE_TYPE")) >= 0) {
if (strcmp(icg->t[0].kdata[fi], "CRT") == 0)
- dtype = 'c';
+ ditype = 'c';
else if (strcmp(icg->t[0].kdata[fi], "LCD") == 0)
- dtype = 'l';
- else
- dtype = icg->t[0].kdata[fi][0];
+ ditype = 'l';
+ else {
+ ditype = icg->t[0].kdata[fi][0]; // Hmm. not handling '_' ...
+ }
}
}
//printf("~1 dealt with device type\n");
@@ -3024,8 +3027,8 @@ int main(int argc, char *argv[]) {
if (out_tvenc)
printf("Using TV encoding range of (16-235)/255\n");
- if (dtype > 0)
- printf("Display type is '%c'\n",dtype);
+ if (ditype > 0)
+ printf("Display type is '%s'\n",inst_distr(ditype));
if (doupdate) {
if (x.nat)
@@ -5269,8 +5272,11 @@ int main(int argc, char *argv[]) {
ocg->add_kword(ocg, 0, "TV_OUTPUT_ENCODING",out_tvenc ? "YES" : "NO", NULL);
/* Put the target parameters in the CGATS file too */
- if (dtype != 0) {
- sprintf(buf,"%c",dtype);
+ if (ditype != 0) {
+ if ((ditype & ~0xff) != 0)
+ sprintf(buf,"%c%c",((ditype >> 8) & 0xff), ditype & 0xff);
+ else
+ sprintf(buf,"%c",ditype);
ocg->add_kword(ocg, 0, "DEVICE_TYPE", buf, NULL);
}
diff --git a/spectro/dispread.c b/spectro/dispread.c
index 5e332cc..baa042e 100755
--- a/spectro/dispread.c
+++ b/spectro/dispread.c
@@ -242,7 +242,7 @@ int main(int argc, char *argv[]) {
int nadaptive = 0; /* Use non-adaptive mode if available */
int bdrift = 0; /* Flag, nz for black drift compensation */
int wdrift = 0; /* Flag, nz for white drift compensation */
- int dtype = 0; /* Display type selection charater */
+ int ditype = 0; /* Display type selection charater(s) */
int tele = 0; /* NZ if telephoto mode */
int noautocal = 0; /* Disable auto calibration */
int noplace = 0; /* Disable user instrument placement */
@@ -426,7 +426,9 @@ int main(int argc, char *argv[]) {
} else if (argv[fa][1] == 'y') {
fa = nfa;
if (na == NULL) usage(0,"Parameter expected after -y");
- dtype = na[0];
+ ditype = na[0];
+ if (ditype == '_' && na[1] != '\000')
+ ditype = ditype << 8 | na[1];
/* Calibration file */
} else if (argv[fa][1] == 'k'
@@ -701,7 +703,7 @@ int main(int argc, char *argv[]) {
}
if (docalib) {
- if ((rv = disprd_calibration(ipath, fc, dtype, -1, 0, tele, nadaptive, noautocal,
+ if ((rv = disprd_calibration(ipath, fc, ditype, -1, 0, tele, nadaptive, noautocal,
disp, webdisp, ccid,
#ifdef NT
madvrdisp,
@@ -919,7 +921,7 @@ int main(int argc, char *argv[]) {
cal[0][0] = -1.0; /* Not used */
}
- if ((dr = new_disprd(&errc, ipath, fc, dtype, -1, 0, tele, nadaptive, noautocal, noplace,
+ if ((dr = new_disprd(&errc, ipath, fc, ditype, -1, 0, tele, nadaptive, noautocal, noplace,
highres, refrate, native, &noramdac, &nocm, cal, ncal, disp,
out_tvenc, fullscreen, override, webdisp, ccid,
#ifdef NT
diff --git a/spectro/dispsup.c b/spectro/dispsup.c
index 21e847f..bbb4151 100755
--- a/spectro/dispsup.c
+++ b/spectro/dispsup.c
@@ -205,9 +205,9 @@ inst_code setup_display_calibrate(
int disprd_calibration(
icompath *ipath, /* Instrument path to open, &icomFakeDevice == fake */
flow_control fc, /* Serial flow control */
-int dtype, /* Display type selection character */
-int sdtype, /* Spectro dtype, use dtype if -1 */
-int docbid, /* NZ to only allow cbid dtypes */
+int ditype, /* Display type selection character(s) */
+int sditype, /* Spectro ditype, use ditype if -1 */
+int docbid, /* NZ to only allow cbid ditypes */
int tele, /* NZ for tele mode, falls back to spot mode */
int nadaptive, /* NZ for non-adaptive mode */
int noinitcal, /* NZ to disable initial instrument calibration */
@@ -326,16 +326,17 @@ a1log *log /* Verb, debug & error log */
p->capabilities(p, &cap, &cap2, &cap3);
/* If this is a spectral instrument, and a different */
- /* spectral inst. dtype is supplied, then use it */
- if (IMODETST(cap, inst_mode_spectral) && sdtype >= 0)
- dtype = sdtype;
+ /* spectral inst. ditype is supplied, then use it */
+ if (IMODETST(cap, inst_mode_spectral) && sditype >= 0)
+ ditype = sditype;
/* Set the display type or calibration mode */
- if (dtype != 0) { /* Given selection character */
+ if (ditype != 0) { /* Given selection character */
if (cap2 & inst2_disptype) {
int ix;
- if ((ix = inst_get_disptype_index(p, dtype, docbid)) < 0) {
- a1logd(log,1,"Display type selection '%c' is not valid for instrument\n",dtype);
+ if ((ix = inst_get_disptype_index(p, ditype, docbid)) < 0) {
+ a1logd(log,1,"Display type selection '%s' is not valid for instrument\n",
+ inst_distr(ditype));
p->del(p);
return -1;
}
@@ -2156,7 +2157,7 @@ static int config_inst_displ(disprd *p) {
inst2_capability cap2;
inst3_capability cap3;
inst_mode mode = 0;
- int dtype = p->dtype;
+ int ditype = p->ditype;
int rv;
p->it->capabilities(p->it, &cap, &cap2, &cap3);
@@ -2229,16 +2230,17 @@ static int config_inst_displ(disprd *p) {
}
/* If this is a spectral instrument, and a different */
- /* spectral inst. dtype is supplied, then use it */
- if (IMODETST(cap, inst_mode_spectral) && p->sdtype >= 0)
- dtype = p->sdtype;
+ /* spectral inst. ditype is supplied, then use it */
+ if (IMODETST(cap, inst_mode_spectral) && p->sditype >= 0)
+ ditype = p->sditype;
/* Set the display type or calibration mode */
- if (dtype != 0) {
+ if (ditype != 0) {
if (cap2 & inst2_disptype) {
int ix;
- if ((ix = inst_get_disptype_index(p->it, dtype, p->docbid)) < 0) {
- a1logd(p->log,1,"Display type selection '%c' is not valid for instrument\n",dtype);
+ if ((ix = inst_get_disptype_index(p->it, ditype, p->docbid)) < 0) {
+ a1logd(p->log,1,"Display type selection '%s' is not valid for instrument\n",
+ inst_distr(ditype));
if (p->docbid)
return 16;
return 15;
@@ -2356,9 +2358,9 @@ disprd *new_disprd(
int *errc, /* Error code. May be NULL (could use log for this instead?) */
icompath *ipath, /* Instrument path to open, &icomFakeDevice == fake */
flow_control fc, /* Flow control */
-int dtype, /* Display type selection character */
-int sdtype, /* Spectro dtype, use dtype if -1 */
-int docbid, /* NZ to only allow cbid dtypes */
+int ditype, /* Display type selection character(s) */
+int sditype, /* Spectro ditype, use ditype if -1 */
+int docbid, /* NZ to only allow cbid ditypes */
int tele, /* NZ for tele mode. Falls back to display mode */
int nadaptive, /* NZ for non-adaptive mode */
int noinitcal, /* No initial instrument calibration */
@@ -2436,8 +2438,8 @@ a1log *log /* Verb, debug & error log */
p->custObserver = custObserver;
p->bdrift = bdrift;
p->wdrift = wdrift;
- p->dtype = dtype;
- p->sdtype = sdtype;
+ p->ditype = ditype;
+ p->sditype = sditype;
p->docbid = docbid;
p->refrmode = -1; /* Unknown */
p->cbid = 0; /* Unknown */
@@ -2568,7 +2570,7 @@ a1log *log /* Verb, debug & error log */
/* Create a spectral conversion object if needed */
if (p->spectral && p->obType != icxOT_none) {
- if ((p->sp2cie = new_xsp2cie(icxIT_none, NULL, p->obType, custObserver, icSigXYZData, icxNoClamp))
+ if ((p->sp2cie = new_xsp2cie(icxIT_none, 0.0, NULL, p->obType, custObserver, icSigXYZData, icxNoClamp))
== NULL) {
a1logd(log,1,"new_disprd failed because creation of spectral conversion object failed\n");
p->del(p);
diff --git a/spectro/dispsup.h b/spectro/dispsup.h
index 07a66e2..3687979 100755
--- a/spectro/dispsup.h
+++ b/spectro/dispsup.h
@@ -49,9 +49,9 @@ inst_code setup_display_calibrate(
int disprd_calibration(
icompath *ipath, /* Instrument path to open, &icomFakeDevice == fake */
flow_control fc, /* Serial flow control */
-int dtype, /* Display type, 0 = unknown, 1 = CRT, 2 = LCD */
-int sdtype, /* Spectro dtype, use dtype if -1 */
-int docbid, /* NZ to only allow cbid dtypes */
+int ditype, /* Display type selection character(s) */
+int sditype, /* Spectro ditype, use ditype if -1 */
+int docbid, /* NZ to only allow cbid ditypes */
int tele, /* NZ for tele mode */
int nadaptive, /* NZ for non-adaptive mode */
int noinitcal, /* NZ to disable initial instrument calibration */
@@ -116,9 +116,9 @@ struct _disprd {
baud_rate br;
flow_control fc;
inst *it; /* Instrument */
- int dtype; /* Display type, 0 = unknown, 1 = CRT, 2 = LCD */
- int sdtype; /* Spectro dtype */
- int docbid; /* NZ to only allow cbid dtypes */
+ int ditype; /* Display type selection character(s) */
+ int sditype; /* Spectro ditype */
+ int docbid; /* NZ to only allow cbid ditypes */
int refrmode; /* Refresh display mode, -1 if unknow, 0 = if no, 1 if yes */
int cbid; /* The current Calibration Base display mode ID, 0 if unknown */
int tele; /* NZ for tele mode */
@@ -229,9 +229,9 @@ disprd *new_disprd(
int *errc, /* Error code. May be NULL */
icompath *ipath, /* Instrument path to open, &icomFakeDevice == fake */
flow_control fc, /* Serial flow control */
-int dtype, /* Display type, 0 = unknown, 1 = CRT, 2 = LCD */
-int sdtype, /* Spectro dtype, use dtype if -1 */
-int docbid, /* NZ to only allow cbid dtypes */
+int ditype, /* Display type selection character(s) */
+int sditype, /* Spectro ditype, use ditype if -1 */
+int docbid, /* NZ to only allow cbid ditypes */
int tele, /* NZ for tele mode */
int nadaptive, /* NZ for non-adaptive mode */
int noinitcal, /* No initial instrument calibration */
diff --git a/spectro/disptechs.c b/spectro/disptechs.c
index bade777..dc38480 100755
--- a/spectro/disptechs.c
+++ b/spectro/disptechs.c
@@ -330,7 +330,7 @@ static disptech_info disptech_info_array[] = {
};
-static int unknown_ix = -1;
+static int unknown_ix = -1; /* Set to actual index by find_unknown() */
static void find_unknown() {
int i;
diff --git a/spectro/dispwin.c b/spectro/dispwin.c
index 7761db1..9261592 100755
--- a/spectro/dispwin.c
+++ b/spectro/dispwin.c
@@ -1754,6 +1754,8 @@ static char *cur_profile(dispwin *p) {
/* Return a CMProfileRef/ColorSyncProfileRef for the */
/* displays profile. Return NULL on error */
+/* Could use CGDisplayCopyColorSpace() instead of */
+/* cur_profile_url/ColorSyncProfileCreateWithURL for 10.5 + ? */
static void *cur_colorsync_ref(dispwin *p) {
void *cspr = NULL;
@@ -3853,6 +3855,8 @@ static void create_my_win(void *cntx) {
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
/* Get the ColorSync profile for this display */
+ /* Could use CGDisplayCopyColorSpace() instead of */
+ /* cur_colorsync_ref() code for 10.5 + ? */
if ((cspr = cur_colorsync_ref(p)) == NULL) {
debugr2((errout,"cur_colorsync_ref failed\n"));
diff --git a/spectro/ex1.c b/spectro/ex1.c
index 929af3d..ee417dd 100755
--- a/spectro/ex1.c
+++ b/spectro/ex1.c
@@ -382,7 +382,7 @@ ex1_init_inst(inst *pp) {
}
#endif /* NEVER */
- p->conv = new_xsp2cie(icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, icxNoClamp);
+ p->conv = new_xsp2cie(icxIT_none, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, icxNoClamp);
if (p->conv == NULL)
return EX1_INT_CIECONVFAIL;
diff --git a/spectro/i1d3.c b/spectro/i1d3.c
index 7e5c396..c822324 100755
--- a/spectro/i1d3.c
+++ b/spectro/i1d3.c
@@ -2205,7 +2205,7 @@ i1d3_comp_calmat(
sampRGB = dmatrix(0, nsamp-1, 0, 3-1);
/* Compute XYZ of the sample array */
- if ((conv = new_xsp2cie(icxIT_none, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL)
+ if ((conv = new_xsp2cie(icxIT_none, 0.0, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL)
return i1d3_interp_code((inst *)p, I1D3_INT_CIECONVFAIL);
for (i = 0; i < nsamp; i++) {
conv->convert(conv, sampXYZ[i], &samples[i]);
@@ -2213,7 +2213,7 @@ i1d3_comp_calmat(
conv->del(conv);
/* Compute sensor RGB of the sample array */
- if ((conv = new_xsp2cie(icxIT_none, NULL, icxOT_custom, RGBcmfs, icSigXYZData, icxClamp)) == NULL) {
+ if ((conv = new_xsp2cie(icxIT_none, 0.0, NULL, icxOT_custom, RGBcmfs, icSigXYZData, icxClamp)) == NULL) {
free_dmatrix(sampXYZ, 0, nsamp-1, 0, 3-1);
free_dmatrix(sampRGB, 0, nsamp-1, 0, 3-1);
return i1d3_interp_code((inst *)p, I1D3_INT_CIECONVFAIL);
@@ -2880,7 +2880,7 @@ double mtx[3][3]
i1d3 *p = (i1d3 *)pp;
inst_code ev = inst_ok;
- a1logd(p->log, 4, "i1d3_col_cor_mat%s\n",mtx == NULL ? " (noop)": "");
+ a1logd(p->log, 4, "i1d3_col_cor_mat%s dtech %d cbid %d\n",mtx == NULL ? " (noop)": "",dtech,cbid);
if (!p->gotcoms)
return inst_no_coms;
diff --git a/spectro/i1d3.h b/spectro/i1d3.h
index 6152a00..c8f72df 100755
--- a/spectro/i1d3.h
+++ b/spectro/i1d3.h
@@ -81,16 +81,20 @@
/* Sub-type of instrument */
typedef enum {
- i1d3_disppro = 0, /* i1 DisplayPro */
- i1d3_munkdisp = 1, /* ColorMunki Display */
- i1d3_oem = 2, /* Generic OEM */
- 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_wacom_dc = 7 /* Wacom DC */
+ i1d3_disppro = 0, /* i1 DisplayPro */
+ i1d3_munkdisp = 1, /* ColorMunki Display */
+ i1d3_oem = 2, /* Generic OEM */
+ 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_wacom_dc = 7, /* Wacom DC */
} i1d3_dtype;
+/* Generic OEM aliases:
+ i1d3_viewsonic_xri1
+*/
+
/* Measurement mode */
typedef enum {
i1d3_adaptive = 0, /* Frequency over fixed period then adaptive period measurement (def) */
diff --git a/spectro/i1pro_imp.c b/spectro/i1pro_imp.c
index 03f0a0d..cd870fa 100755
--- a/spectro/i1pro_imp.c
+++ b/spectro/i1pro_imp.c
@@ -582,25 +582,33 @@ i1pro_code i1pro_imp_init(i1pro *p) {
/* Information about the instrument */
- if ((ip = m->data->get_ints(m->data, &count, key_serno)) == NULL || count < 1)
+ if ((ip = m->data->get_ints(m->data, &count, key_serno)) == NULL || count < 1) {
+ a1logd(p->log,7,"Missing key_serno\n");
return I1PRO_HW_CALIBINFO;
+ }
m->serno = ip[0];
a1logd(p->log,2,"Serial number = %d\n",m->serno);
sprintf(m->sserno,"%ud",m->serno);
- if ((ip = m->data->get_ints(m->data, &count, key_dom)) == NULL || count < 1)
+ if ((ip = m->data->get_ints(m->data, &count, key_dom)) == NULL || count < 1) {
+ a1logd(p->log,7,"Missing key_dom\n");
return I1PRO_HW_CALIBINFO;
+ }
m->dom = ip[0];
a1logd(p->log,2, "Date of manufactur = %d-%d-%d\n",
m->dom/1000000, (m->dom/10000) % 100, m->dom % 10000);
- if ((ip = m->data->get_ints(m->data, &count, key_cpldrev)) == NULL || count < 1)
+ if ((ip = m->data->get_ints(m->data, &count, key_cpldrev)) == NULL || count < 1) {
+ a1logd(p->log,7,"Missing key_cpldrev\n");
return I1PRO_HW_CALIBINFO;
+ }
m->cpldrev = ip[0];
a1logd(p->log,2,"CPLD rev = %d\n",m->cpldrev);
- if ((ip = m->data->get_ints(m->data, &count, key_capabilities)) == NULL || count < 1)
+ if ((ip = m->data->get_ints(m->data, &count, key_capabilities)) == NULL || count < 1) {
+ a1logd(p->log,7,"Missing key_capabilities\n");
return I1PRO_HW_CALIBINFO;
+ }
m->capabilities = ip[0];
if (m->capabilities & 0x6000) /* Has ambient */
m->capabilities2 |= I1PRO_CAP2_AMBIENT; /* Mimic in capabilities2 */
@@ -608,8 +616,10 @@ i1pro_code i1pro_imp_init(i1pro *p) {
if (m->capabilities & 0x6000)
a1logd(p->log,2," Can read ambient\n");
- if ((ip = m->data->get_ints(m->data, &count, key_physfilt)) == NULL || count < 1)
+ if ((ip = m->data->get_ints(m->data, &count, key_physfilt)) == NULL || count < 1) {
+ a1logd(p->log,7,"Missing key_physfilt\n");
return I1PRO_HW_CALIBINFO;
+ }
m->physfilt = ip[0];
if (m->physfilt == 0x82)
m->capabilities2 |= I1PRO_CAP2_UV_FILT; /* Mimic in cap 2 */
@@ -639,10 +649,14 @@ i1pro_code i1pro_imp_init(i1pro *p) {
if (m->nsen > NSEN_MAX) /* Static allocation assumed */
return I1PRO_HW_UNEX_SPECPARMS;
}
- if (m->data->get_ints(m->data, &m->nwav[0], key_mtx_index) == 0)
+ if (m->data->get_ints(m->data, &m->nwav[0], key_mtx_index) == 0) {
+ a1logd(p->log,7,"Missing key_mtx_index\n");
return I1PRO_HW_CALIBINFO;
- if (m->nwav[0] != 36)
+ }
+ if (m->nwav[0] != 36) {
+ a1logd(p->log,7,"key_mtx_index != 36 elements\n");
return I1PRO_HW_CALIBINFO;
+ }
m->wl_short[0] = 380.0; /* Normal res. range */
m->wl_long[0] = 730.0;
@@ -651,18 +665,24 @@ i1pro_code i1pro_imp_init(i1pro *p) {
m->wl_long[1] = HIGHRES_LONG;
m->nwav[1] = (int)((m->wl_long[1]-m->wl_short[1])/HIGHRES_WIDTH + 0.5) + 1;
- if ((dp = m->data->get_doubles(m->data, &count, key_hg_factor)) == NULL || count < 1)
+ if ((dp = m->data->get_doubles(m->data, &count, key_hg_factor)) == NULL || count < 1) {
+ a1logd(p->log,7,"Missing key_hg_factor\n");
return I1PRO_HW_CALIBINFO;
+ }
m->highgain = dp[0];
a1logd(p->log,2,"High gain = %.10f\n",m->highgain);
if ((m->lin0 = m->data->get_doubles(m->data, &m->nlin0, key_ng_lin)) == NULL
- || m->nlin0 < 1)
+ || m->nlin0 < 1) {
+ a1logd(p->log,7,"Missing key_ng_lin\n");
return I1PRO_HW_CALIBINFO;
+ }
if ((m->lin1 = m->data->get_doubles(m->data, &m->nlin1, key_hg_lin)) == NULL
- || m->nlin1 < 1)
+ || m->nlin1 < 1) {
+ a1logd(p->log,7,"Missing key_hg_lin\n");
return I1PRO_HW_CALIBINFO;
+ }
if (p->log->debug >= 2) {
char oline[200] = { '\000' }, *bp = oline;
@@ -681,8 +701,10 @@ i1pro_code i1pro_imp_init(i1pro *p) {
a1logd(p->log,2,oline);
}
- if ((dp = m->data->get_doubles(m->data, &count, key_min_int_time)) == NULL || count < 1)
+ if ((dp = m->data->get_doubles(m->data, &count, key_min_int_time)) == NULL || count < 1) {
+ a1logd(p->log,7,"Missing key_min_int_time\n");
return I1PRO_HW_CALIBINFO;
+ }
m->min_int_time = dp[0];
/* And then override it */
@@ -695,62 +717,84 @@ i1pro_code i1pro_imp_init(i1pro *p) {
m->min_int_time = 0.00884; /* == 1 sub clock */
}
- if ((dp = m->data->get_doubles(m->data, &count, key_max_int_time)) == NULL || count < 1)
+ if ((dp = m->data->get_doubles(m->data, &count, key_max_int_time)) == NULL || count < 1) {
+ a1logd(p->log,7,"Missing key_max_int_time\n");
return I1PRO_HW_CALIBINFO;
+ }
m->max_int_time = dp[0];
if ((m->mtx_o.index = m->data->get_ints(m->data, &count, key_mtx_index)) == NULL
- || count != m->nwav[0])
+ || count != m->nwav[0]) {
+ a1logd(p->log,7,"Missing key_mtx_index\n");
return I1PRO_HW_CALIBINFO;
+ }
if ((m->mtx_o.nocoef = m->data->get_ints(m->data, &count, key_mtx_nocoef)) == NULL
- || count != m->nwav[0])
+ || count != m->nwav[0]) {
+ a1logd(p->log,7,"Missing key_mtx_nocoef\n");
return I1PRO_HW_CALIBINFO;
+ }
for (xcount = i = 0; i < m->nwav[0]; i++) /* Count number expected in matrix coeffs */
xcount += m->mtx_o.nocoef[i];
if ((m->mtx_o.coef = m->data->get_doubles(m->data, &count, key_mtx_coef)) == NULL
- || count != xcount)
+ || count != xcount) {
+ a1logd(p->log,7,"Missing key_mtx_coef\n");
return I1PRO_HW_CALIBINFO;
+ }
if ((m->white_ref[0] = m->data->get_doubles(m->data, &count, key_white_ref)) == NULL
- || count != m->nwav[0]) {
- if (p->dtype != instI1Monitor)
+ || count != m->nwav[0]) {
+ if (p->dtype != instI1Monitor) {
+ a1logd(p->log,7,"Missing key_white_ref\n");
return I1PRO_HW_CALIBINFO;
+ }
m->white_ref[0] = NULL;
}
if ((m->emis_coef[0] = m->data->get_doubles(m->data, &count, key_emis_coef)) == NULL
- || count != m->nwav[0])
+ || count != m->nwav[0]) {
+ a1logd(p->log,7,"Missing key_emis_coef\n");
return I1PRO_HW_CALIBINFO;
+ }
if ((m->amb_coef[0] = m->data->get_doubles(m->data, &count, key_amb_coef)) == NULL
- || count != m->nwav[0]) {
+ || count != m->nwav[0]) {
if (p->dtype != instI1Monitor
- && m->capabilities & 0x6000) /* Expect ambient calibration */
+ && m->capabilities & 0x6000) { /* Expect ambient calibration */
+ a1logd(p->log,7,"Missing key_amb_coef\n");
return I1PRO_HW_CALIBINFO;
+ }
m->amb_coef[0] = NULL;
}
/* Default to original EEProm raw to wav filters values*/
m->mtx[0][0] = m->mtx_o; /* Std res reflective */
m->mtx[0][1] = m->mtx_o; /* Std res emissive */
- if ((ip = m->data->get_ints(m->data, &count, key_sens_target)) == NULL || count < 1)
+ if ((ip = m->data->get_ints(m->data, &count, key_sens_target)) == NULL || count < 1) {
+ a1logd(p->log,7,"Missing key_sens_target\n");
return I1PRO_HW_CALIBINFO;
+ }
m->sens_target = ip[0];
- if ((ip = m->data->get_ints(m->data, &count, key_sens_dark)) == NULL || count < 1)
+ if ((ip = m->data->get_ints(m->data, &count, key_sens_dark)) == NULL || count < 1) {
+ a1logd(p->log,7,"Missing key_sens_dark\n");
return I1PRO_HW_CALIBINFO;
+ }
m->sens_dark = ip[0];
- if ((ip = m->data->get_ints(m->data, &count, key_ng_sens_sat)) == NULL || count < 1)
+ if ((ip = m->data->get_ints(m->data, &count, key_ng_sens_sat)) == NULL || count < 1) {
+ a1logd(p->log,7,"Missing key_ng_sens_sat\n");
return I1PRO_HW_CALIBINFO;
+ }
m->sens_sat0 = ip[0];
- if ((ip = m->data->get_ints(m->data, &count, key_hg_sens_sat)) == NULL || count < 1)
+ if ((ip = m->data->get_ints(m->data, &count, key_hg_sens_sat)) == NULL || count < 1) {
+ a1logd(p->log,7,"Missing key_hg_sens_sat\n");
return I1PRO_HW_CALIBINFO;
+ }
m->sens_sat1 = ip[0];
a1logd(p->log,2,"sens_target %d, sens_dark %d, sens_sat0 %d, sens_sat1 %d\n",
@@ -809,8 +853,10 @@ i1pro_code i1pro_imp_init(i1pro *p) {
/* Capability bits */
if ((ip = m->data->get_ints(m->data, &count, key2_capabilities)) == NULL
- || count != 1)
+ || count != 1) {
+ a1logd(p->log,7,"Missing key2_capabilities\n");
return I1PRO_HW_CALIBINFO;
+ }
m->capabilities2 = *ip;
if (p->log->debug >= 2) {
a1logd(p->log,2,"Capabilities2 flag = 0x%x\n",m->capabilities2);
@@ -831,64 +877,94 @@ i1pro_code i1pro_imp_init(i1pro *p) {
if (m->capabilities2 & I1PRO_CAP2_WL_LED) {
/* wavelength LED calibration integration time (0.56660) */
if ((dp = m->data->get_doubles(m->data, &count, key2_wlcal_intt)) == NULL
- || count != 1)
+ || count != 1) {
+ a1logd(p->log,7,"Missing key2_wlcal_intt\n");
return I1PRO_HW_CALIBINFO;
+ }
m->wl_cal_inttime = *dp;
/* Wavelength calibration minimum level */
if ((ip = m->data->get_ints(m->data, &count, key2_wlcal_minlev)) == NULL
- || count != 1)
+ || count != 1) {
+ a1logd(p->log,7,"Missing key2_wlcal_minlev\n");
return I1PRO_HW_CALIBINFO;
+ }
/* Normalize it to 1.0 seconds (ie. 500/0.56660) */
m->wl_cal_min_level = (double)(*ip) / m->wl_cal_inttime;
/* wavelength LED measurement expected FWHM in nm */
if ((dp = m->data->get_doubles(m->data, &count, key2_wlcal_fwhm)) == NULL
- || count != 1)
+ || count != 1) {
+ a1logd(p->log,7,"Missing key2_wlcal_fwhm\n");
return I1PRO_HW_CALIBINFO;
+ }
m->wl_cal_fwhm = *dp;
/* wavelength LED measurement FWHM tollerance in nm */
if ((dp = m->data->get_doubles(m->data, &count, key2_wlcal_fwhm_tol)) == NULL
- || count != 1)
+ || count != 1) {
+ a1logd(p->log,7,"Missing key2_wlcal_fwhm_tol\n");
return I1PRO_HW_CALIBINFO;
+ }
m->wl_cal_fwhm_tol = *dp;
/* wavelength LED reference spectrum */
- if ((m->wl_led_spec = m->data->get_doubles(m->data, &m->wl_led_count, key2_wlcal_spec)) == NULL)
+ if ((m->wl_led_spec = m->data->get_doubles(m->data, &m->wl_led_count,
+ key2_wlcal_spec)) == NULL) {
+ a1logd(p->log,7,"Missing key2_wlcal_spec\n");
return I1PRO_HW_CALIBINFO;
+ }
/* wavelength LED spectraum reference offset */
if ((ip = m->data->get_ints(m->data, &count, key2_wlcal_ooff)) == NULL
- || count != 1)
+ || count != 1) {
+ a1logd(p->log,7,"Missing key2_wlcal_ooff\n");
return I1PRO_HW_CALIBINFO;
+ }
m->wl_led_ref_off = *ip;
/* Hmm. this is odd, but it doesn't work correctly otherwise... */
m->wl_led_ref_off--;
/* wavelength calibration maximum error */
if ((dp = m->data->get_doubles(m->data, &count, key2_wlcal_max)) == NULL
- || count != 1)
+ || count != 1) {
+ a1logd(p->log,7,"Missing key2_wlcal_max\n");
return I1PRO_HW_CALIBINFO;
+ }
m->wl_err_max = *dp;
}
- /* CCD bin to wavelength polinomial */
- if ((m->wlpoly1 = m->data->get_doubles(m->data, &count, key2_wlpoly_1)) == NULL || count != 4)
+ /* CCD bin to wavelength polinomial (Emission) */
+ if ((m->wlpoly2 = m->data->get_doubles(m->data, &count, key2_wlpoly_2)) == NULL
+ || count != 4) {
+ a1logd(p->log,7,"Missing key2_wlpoly_2\n");
return I1PRO_HW_CALIBINFO;
+ }
- if ((m->wlpoly2 = m->data->get_doubles(m->data, &count, key2_wlpoly_2)) == NULL || count != 4)
- return I1PRO_HW_CALIBINFO;
+ /* CCD bin to wavelength polinomial (Reflection) */
+ if ((m->wlpoly1 = m->data->get_doubles(m->data, &count, key2_wlpoly_1)) == NULL || count != 4) {
+ /* Hmm. no key2_wlpoly_1. This seems to be the case for */
+ /* some stripped down OEM instruments. Use key2_wlpoly_2 instead */
+ if ((m->wlpoly2 = m->data->get_doubles(m->data, &count, key2_wlpoly_2)) == NULL
+ || count != 4) {
+ a1logd(p->log,7,"Missing key2_wlpoly_1 and key2_wlpoly_2\n");
+ return I1PRO_HW_CALIBINFO;
+ }
+ }
/* Stray light compensation. Note that 16 bit numbers are signed. */
if ((sip = m->data->get_shorts(m->data, &count, key2_straylight)) == NULL
- || count != (36 * 36))
+ || count != (36 * 36)) {
+ a1logd(p->log,7,"Missing key2_straylight\n");
return I1PRO_HW_CALIBINFO;
+ }
/* stray light scale factor */
if ((dp = m->data->get_doubles(m->data, &count, key2_straylight_scale)) == NULL
- || count != 1)
+ || count != 1) {
+ a1logd(p->log,7,"Missing key2_straylight_scale\n");
return I1PRO_HW_CALIBINFO;
+ }
/* Convert from ints to floats */
m->straylight[0] = dmatrixz(0, 35, 0, 35);
@@ -1060,6 +1136,7 @@ i1pro_code i1pro_imp_init(i1pro *p) {
s->scan = 1;
s->adaptive = 1;
s->inttime = m->min_int_time; /* Maximize scan rate */
+ /* (see i1pro_imp_calibrate() too) */
s->dark_int_time = s->inttime;
if (m->fwrev >= 301) /* (We're not using scan targoscale though) */
s->targoscale = 0.25;
@@ -1127,6 +1204,7 @@ i1pro_code i1pro_imp_init(i1pro *p) {
s->scan = 1;
s->adaptive = 1; /* ???? */
s->inttime = m->min_int_time; /* Maximize scan rate */
+ /* (see i1pro_imp_calibrate() too) */
s->lamptime = 0.0;
s->dark_int_time = s->inttime;
if (m->fwrev >= 301)
@@ -1223,6 +1301,7 @@ i1pro_code i1pro_imp_init(i1pro *p) {
s->scan = 1;
s->adaptive = 0;
s->inttime = m->min_int_time; /* Maximize scan rate */
+ /* (see i1pro_imp_calibrate() too) */
s->dark_int_time = s->inttime;
if (m->fwrev >= 301) /* (We're not using scan targoscale though) */
s->targoscale = 0.25;
@@ -10175,9 +10254,9 @@ i1pro_code i1pro_conv2XYZ(
double sms; /* Weighting */
if (s->emiss)
- conv = new_xsp2cie(icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, (icxClamping)clamp);
+ conv = new_xsp2cie(icxIT_none, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, (icxClamping)clamp);
else
- conv = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, (icxClamping)clamp);
+ conv = new_xsp2cie(icxIT_D50, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, (icxClamping)clamp);
if (conv == NULL)
return I1PRO_INT_CIECONVFAIL;
@@ -10325,16 +10404,16 @@ i1pro_code i1pro_check_white_reference1(
/* And check them against tolerance for the illuminant. */
if (m->physfilt == 0x82) { /* UV filter */
- a1logd(p->log,2,"Checking white reference (UV): 0.0 < avg01 %f < 0.05, 1.2 < avg2227 %f < 1.76\n",avg01,avg2227);
- if (0.0 < avg01 && avg01 < 0.05
- && 1.2 < avg2227 && avg2227 < 1.76) {
+ a1logd(p->log,2,"Checking white reference (UV): 0.0 <= avg01 %f <= 0.05, 1.2 <= avg2227 %f <= 1.76\n",avg01,avg2227);
+ if (0.0 <= avg01 && avg01 <= 0.05
+ && 1.2 <= avg2227 && avg2227 <= 1.76) {
return I1PRO_OK;
}
} else { /* No filter */
- a1logd(p->log,2,"Checking white reference: 0.11 < avg01 %f < 0.22, 1.35 < avg2227 %f < 1.6\n",avg01,avg2227);
- if (0.11 < avg01 && avg01 < 0.22
- && 1.35 < avg2227 && avg2227 < 1.6) {
+ a1logd(p->log,2,"Checking white reference: 0.11 <= avg01 %f <= 0.22, 1.35 <= avg2227 %f <= 1.6\n",avg01,avg2227);
+ if (0.11 <= avg01 && avg01 <= 0.22
+ && 1.35 <= avg2227 && avg2227 <= 1.6) {
return I1PRO_OK;
}
}
diff --git a/spectro/i1pro_imp.h b/spectro/i1pro_imp.h
index 582cc98..00cf52d 100755
--- a/spectro/i1pro_imp.h
+++ b/spectro/i1pro_imp.h
@@ -248,7 +248,7 @@ struct _i1proimp {
/* 0x81 == emission only ?? */
/* 0x82 == UV filter */
int capabilities2; /* Rev E capabilities - set #defines above */
- /* Also set for RevA-D */
+ /* Also set for RevA-D to simplify capability testing */
/* Underlying calibration information */
int nsen; /* Raw + extra sample bands read = 128 for i1pro, 136 for Rev E */
@@ -1290,14 +1290,45 @@ typedef enum {
key2_wlcal_max = 0x2f46, /* double, wavelength calibration error limit, ie. 5.0 */
- key2_wlpoly_1 = 0x2f62, /* double[4], CCD bin to wavelength polinomial #1 (normal) */
- key2_wlpoly_2 = 0x2f63, /* double[4], CCD bin to wavelength polinomial #2 ??? */
+ key2_wlpoly_1 = 0x2f62, /* double[4], CCD bin to wavelength polinomial #1 (reflective ?) */
+ key2_wlpoly_2 = 0x2f63, /* double[4], CCD bin to wavelength polinomial #2 (emissive ?) */
key2_straylight = 0x2f58, /* int16[36][6] signed stray light values */
key2_straylight_scale = 0x2f59 /* double stray light scale factor */
} i1key;
+/*
+
+Missing keys for Stripped down OEM i1pro2 (Capabilities2 flag = 0x30)
+i.e. missing Ambient, WL Led, UV Led, Zebra ruller,
+ has indicator Leds, UV filter.
+
+Table entry 34 is Key 0x0bba, type 3 addr 0x1c4c, size 4 Unkn
+
+Table entry 5 is Key 0x2eea, type 3 addr 0x2218, size 4 Unkn
+Table entry 6 is Key 0x2eeb, type 3 addr 0x221c, size 4 key2_sens_target
+Table entry 9 is Key 0x2ef5, type 4 addr 0x2228, size 4 Unkn
+Table entry 10 is Key 0x2ef6, type 4 addr 0x222c, size 4 Unkn
+Table entry 11 is Key 0x2ef9, type 4 addr 0x2230, size 4 key2_uvcal_intt
+Table entry 12 is Key 0x2efa, type 4 addr 0x2234, size 4 key2_wlcal_intt
+Table entry 13 is Key 0x2efe, type 3 addr 0x2238, size 4 key2_wlcal_minlev
+Table entry 14 is Key 0x2eff, type 3 addr 0x223c, size 4 Unkn
+Table entry 21 is Key 0x2f44, type 4 addr 0x2258, size 200 key2_wlcal_spec
+Table entry 22 is Key 0x2f45, type 3 addr 0x2320, size 4 key2_wlcal_ooff
+Table entry 23 is Key 0x2f46, type 4 addr 0x2324, size 4 key2_wlcal_max
+Table entry 24 is Key 0x2f4e, type 4 addr 0x2328, size 4 key2_wlcal_fwhm
+Table entry 25 is Key 0x2f4f, type 4 addr 0x232c, size 4 key2_wlcal_fwhm_tol
+Table entry 26 is Key 0x2f50, type 4 addr 0x2330, size 4 Unkn
+Table entry 29 is Key 0x2f62, type 4 addr 0x2d58, size 16 key2_wlpoly_1
+Table entry 31 is Key 0x2f6c, type 4 addr 0x2d78, size 8 Unkn
+Table entry 32 is Key 0x2f6d, type 4 addr 0x2d80, size 4 Unkn
+Table entry 33 is Key 0x2f6e, type 4 addr 0x2d84, size 4 Unkn
+Table entry 34 is Key 0x2f76, type 4 addr 0x2d88, size 72 Unkn
+Table entry 35 is Key 0x2f77, type 4 addr 0x2dd0, size 72 Unkn
+
+*/
+
/* Data type */
typedef enum {
diff --git a/spectro/icoms.c b/spectro/icoms.c
index 875f3b6..08ddd92 100755
--- a/spectro/icoms.c
+++ b/spectro/icoms.c
@@ -760,8 +760,12 @@ int frbw /* nz to Flush Read Before Write */
int debug = p->log->debug;
int bread;
+ p->ser_clearerr(p);
+
if (debug < 8)
p->log->debug = 0;
+ /* (Could use tcflush() or ioctl(TCFLSH) on *nix, */
+ /* except these don't work on USB serial ports!) */
for (;;) {
bread = 0;
p->read(p, tbuf, 500, &bread, NULL, 500, 0.02);
@@ -813,6 +817,11 @@ double tout /* Timeout for write and then read (i.e. max = 2 x tout) */
return icoms_write_read_ex(p, wbuf, nwch, rbuf, bsize, bread, tc, ntc, tout, 0);
}
+/* Default NOP implementation - Serial open or set_methods may override */
+static void icoms_ser_clearerr(icoms *p) {
+ return;
+}
+
/* Optional callback to client from device */
/* Default implementation is a NOOP */
static int icoms_interrupt(icoms *p,
@@ -907,6 +916,7 @@ icoms *new_icoms(
p->read = NULL;
p->write_read = icoms_write_read;
p->write_read_ex = icoms_write_read_ex;
+ p->ser_clearerr = icoms_ser_clearerr; /* Default NOP implementation */
p->interrupt = icoms_interrupt;
p->del = icoms_del;
diff --git a/spectro/icoms.h b/spectro/icoms.h
index 4e18b62..74af2ee 100755
--- a/spectro/icoms.h
+++ b/spectro/icoms.h
@@ -515,6 +515,9 @@ struct _icoms {
double tout, /* Timeout in seconds */
int frbw); /* nz to Flush Read Before Write */
+ /* For serial device, clear any errors */
+ void (*ser_clearerr)(struct _icoms *p);
+
/* For a USB device, do a control message */
/* return icom error */
int (*usb_control)(struct _icoms *p,
diff --git a/spectro/icoms_nt.c b/spectro/icoms_nt.c
index 39ff6f0..7ac074b 100755
--- a/spectro/icoms_nt.c
+++ b/spectro/icoms_nt.c
@@ -163,6 +163,16 @@ void serial_close_port(icoms *p) {
}
}
+/* Clear any serial errors */
+static void nt_ser_clearerr(icoms *p) {
+ DWORD errs;
+
+ if (!ClearCommError(p->phandle, &errs,NULL))
+ error("nt_ser_clearerr: failed, and Clear error failed");
+
+ return;
+}
+
/* -------------------------------------------------------------------- */
#ifndef CBR_230400
@@ -428,6 +438,7 @@ int delayms) { /* Delay after open in msec */
p->write = icoms_ser_write;
p->read = icoms_ser_read;
+ p->ser_clearerr = nt_ser_clearerr;
}
a1logd(p->log, 8, "icoms_set_ser_port: port characteristics set ok\n");
diff --git a/spectro/illumread.c b/spectro/illumread.c
index 28ecbca..aee546c 100755
--- a/spectro/illumread.c
+++ b/spectro/illumread.c
@@ -1063,14 +1063,14 @@ int main(int argc, char *argv[])
bf.r_sp = &r_sp;
bf.p_sp = &p_sp;
- if ((bf.pap = new_xsp2cie(icxIT_custom, &i_sp, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL)
+ if ((bf.pap = new_xsp2cie(icxIT_custom, 0.0, &i_sp, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL)
error("new_xsp2cie pap failed");
if (bf.pap->set_fwa(bf.pap, &insp, NULL, &p_sp) != 0)
error ("Setting FWA compensation failed");
/* Setup the equal energy to Lab conversion */
- if ((bf.ref = new_xsp2cie(icxIT_E, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL)
+ if ((bf.ref = new_xsp2cie(icxIT_E, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL)
error("new_xsp2cie ref failed");
/* Estimate an initial gain match */
@@ -1154,7 +1154,7 @@ int main(int argc, char *argv[])
xspect cpdsp; /* FWA corrected calculated daylight paper reflectance */
/* Setup the referencec comversion */
- if ((cf.ref = new_xsp2cie(icxIT_E, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL)
+ if ((cf.ref = new_xsp2cie(icxIT_E, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL)
error("new_xsp2cie ref failed");
cf.ill = bf.ill;
diff --git a/spectro/inst.c b/spectro/inst.c
index 07ace6e..7f1368a 100755
--- a/spectro/inst.c
+++ b/spectro/inst.c
@@ -41,11 +41,11 @@
#ifndef SALONEINSTLIB
#include "copyright.h"
#include "aconfig.h"
+#include "rand.h"
#else
#include "sa_config.h"
#endif /* !SALONEINSTLIB */
#include "numsup.h"
-#include "rand.h"
#include "cgats.h"
#include "xspect.h"
#include "conv.h"
@@ -881,6 +881,12 @@ static inst_disptypesel *expand_dlist(inst_disptypesel *list, int nlist, int *na
than any aliases that come after it, and the
aliases as more important than the fallback list,
so we need to do three passes through all the selections.
+
+ If we run out of single letter selectors (i.e. K10),
+ then we switch to the two letter prefixed selector "_X".
+
+ NOTE that we assume that we cannot exaust the single letter
+ selectors via hard coded, ccmx or ccss calibrations.
*/
/* Create the display type list */
@@ -892,8 +898,8 @@ int doccss, /* Add installed ccss files */
int doccmx /* Add matching installed ccmx files */
) {
inst_disptypesel *list = NULL;
- int i, j, k, nlist = 0, nalist = 0;
- char usels[256]; /* Used selectors */
+ int i, j, k, k2, nlist = 0, nalist = 0;
+ char usels[256]; /* Used selectors 1 */
static char *asels = "123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
int fail = 0;
@@ -902,8 +908,9 @@ int doccmx /* Add matching installed ccmx files */
*pdtlist = NULL;
*pndtlist = 0;
- for (i = 0; i < 256; i++)
- usels[i] = ((char)-1);
+ for (j = 0; j < 256; j++)
+ usels[j] = ((char)-1);
+ k2 = 0; /* Single letter selector */
k = 0; /* Next selector index */
/* First create a list of calibrations and their desired selectors: */
@@ -1031,26 +1038,42 @@ int doccmx /* Add matching installed ccmx files */
/* Set remaining from fallback */
for (i = 0; i < nlist; i++) {
- disptechs_set_sel(2, i, list[i].sel, list[i].isel, usels, &k, asels);
- if (list[i].sel[0] == '\000')
- fail = 1;
+ if (k2 == 0) { /* Single letter selector */
+ disptechs_set_sel(2, i, list[i].sel, list[i].isel, usels, &k, asels);
+ if (list[i].sel[0] == '\000') { /* Switch to two letter */
+ for (j = 0; j < 256; j++)
+ usels[j] = ((char)-1);
+ k2 = 1; /* Two letter selector */
+ k = 0; /* Next selector index */
+ }
+ }
+ if (k2 == 1) { /* Two letter selector */
+ list[i].sel[0] = '_';
+ disptechs_set_sel(2, i, &list[i].sel[1], list[i].isel, usels, &k, asels);
+ if (list[i].sel[0] == '\000') { /* Ran out of two letter selectors! */
+ fail = 1;
+ break;
+ }
+ }
}
/* Any calibrations that failed to find a character will be left as a nul string */
/* Add alternate selectors if they are free. */
- for (;;) {
- int more = 0;
- for (i = 0; i < nlist; i++) {
- /* Add unused secondaries */
- disptechs_set_sel(3, i, list[i].sel, list[i].isel, usels, &k, asels);
-
- if (list[i].isel[0] != '\000') { /* Still more secondaries available */
- more = 1;
+ if (k2 == 0) { /* If not run out of 1 letter selectors */
+ for (;;) {
+ int more = 0;
+ for (i = 0; i < nlist; i++) {
+ /* Add unused secondaries */
+ disptechs_set_sel(3, i, list[i].sel, list[i].isel, usels, &k, asels);
+
+ if (list[i].isel[0] != '\000') { /* Still more secondaries available */
+ more = 1;
+ }
}
+ if (!more)
+ break;
}
- if (!more)
- break;
}
if (pndtlist != NULL)
diff --git a/spectro/inst.h b/spectro/inst.h
index 04e02d6..601f7b3 100755
--- a/spectro/inst.h
+++ b/spectro/inst.h
@@ -43,8 +43,8 @@
and agreed to support.
*/
-#include "dev.h" /* Base device class */
#include "insttypes.h" /* libinst Includes this functionality */
+#include "dev.h" /* Base device class */
#include "disptechs.h" /* libinst Includes this functionality */
#include "icoms.h" /* libinst Includes this functionality */
#include "conv.h"
@@ -69,6 +69,10 @@
#ifdef NEVER /* Declared in xicc/xspect.h */
+// ~~~ should add absorbance mode -
+// i.e. modified transmissive mode where units are
+// log10(incident/transmitted) = Beer-Lambert Law
+
/* Type of measurement result */
typedef enum { /* XYZ units, Spectral units */
inst_mrt_none = 0, /* Not set */
diff --git a/spectro/instappsup.c b/spectro/instappsup.c
index 6c3dd68..0cb5798 100755
--- a/spectro/instappsup.c
+++ b/spectro/instappsup.c
@@ -479,6 +479,7 @@ inst2_capability inst_show_disptype_options(FILE *fp, char *oline, icompaths *ic
if (docbib && sels[j].cbid == 0)
continue; /* Skip non cbid type */
+ /* Break up selector chars/pairs with '|' */
m = pstart;
for (k = 0; k < (INST_DTYPE_SEL_LEN-1); k++) {
if (sels[j].sel[k] == '\000')
@@ -486,6 +487,8 @@ inst2_capability inst_show_disptype_options(FILE *fp, char *oline, icompaths *ic
if (m > pstart)
buf[m++] = '|';
buf[m++] = sels[j].sel[k];
+ if (sels[j].sel[k] == '_')
+ buf[m++] = sels[j].sel[++k];
}
while (m < (olen+1)) /* Indent it by 1 */
buf[m++] = ' ';
@@ -534,8 +537,9 @@ inst2_capability inst_show_disptype_options(FILE *fp, char *oline, icompaths *ic
/* A helper function to turn a -y flag into a selection index */
/* If docbib is nz, then only allow base calibration display types */
+/* c will be 16 bits ('_' + 'X') if a 2 char selector */
/* Return -1 on error */
-int inst_get_disptype_index(inst *it, int c, int docbib) {
+int inst_get_disptype_index(inst *it, int ditype, int docbib) {
inst2_capability cap;
int j, k;
@@ -555,7 +559,14 @@ int inst_get_disptype_index(inst *it, int c, int docbib) {
for (k = 0; k < (INST_DTYPE_SEL_LEN-1); k++) {
if (sels[j].sel[k] == '\000')
break;
- if (sels[j].sel[k] == c) {
+ if (sels[j].sel[k] == '_') { /* 2 char selector */
+ k++;
+ if (sels[j].sel[k-1] == (0xff & (ditype >> 8))
+ && sels[j].sel[k] == (0xff & ditype)) {
+ return j;
+ }
+ }
+ if (sels[j].sel[k] == ditype) {
return j;
}
}
@@ -564,6 +575,21 @@ int inst_get_disptype_index(inst *it, int c, int docbib) {
return -1;
}
+/* Return a static string of the ditype flag char(s) */
+char *inst_distr(int ditype) {
+ static char buf[5];
+
+ if ((ditype >> 8) & 0xff) {
+ buf[0] = (ditype >> 8) & 0xff;
+ buf[1] = ditype & 0xff;
+ buf[2] = '\000';
+ } else {
+ buf[0] = ditype;
+ buf[1] = '\000';
+ }
+
+ return buf;
+}
/* ================================================================= */
diff --git a/spectro/instappsup.h b/spectro/instappsup.h
index 8da4325..c5b95fc 100755
--- a/spectro/instappsup.h
+++ b/spectro/instappsup.h
@@ -91,7 +91,10 @@ inst2_capability inst_show_disptype_options(FILE *fp, char *oline, icompaths *ic
/* A helper function to turn a -y flag into a list index */
/* If docbib is nz, then only allow base calibration display types */
/* Return 0 on error */
-int inst_get_disptype_index(inst *it, int c, int docbib);
+int inst_get_disptype_index(inst *it, int ditype, int docbib);
+
+/* Return a static string of the ditype flag char(s) */
+char *inst_distr(int ditype);
#ifdef __cplusplus
}
diff --git a/spectro/instlib.ksh b/spectro/instlib.ksh
index 8b0303f..47243e4 100755
--- a/spectro/instlib.ksh
+++ b/spectro/instlib.ksh
@@ -57,6 +57,7 @@ SPECTRO_FILES="
hidio.h
hidio.c
icoms.h
+ dev.h
inst.h
inst.c
insttypes.c
diff --git a/spectro/kleink10.c b/spectro/kleink10.c
index d169156..6b057ff 100755
--- a/spectro/kleink10.c
+++ b/spectro/kleink10.c
@@ -2,7 +2,7 @@
/*
* Argyll Color Correction System
*
- * JETI kleink10 1211/1201 related functions
+ * Klein K10 related functions
*
* Author: Graeme W. Gill
* Date: 29/4/2014
@@ -68,6 +68,7 @@
#undef PLOT_REFRESH /* [und] Plot refresh rate measurement info */
#undef PLOT_UPDELAY /* [und] Plot update delay measurement info */
+#undef TEST_FAKE_CALIBS /* Fake having a full calibration set (98 calibs) */
#undef TEST_BAUD_CHANGE /* Torture test baud rate change on non high speed K10 */
static inst_disptypesel k10_disptypesel[98];
@@ -216,7 +217,7 @@ int nd /* nz to disable debug messages */
strncpy((char *)cmd, (char *)in, 2);
cmd[2] = '\000';
- if ((se = p->icom->write_read(p->icom, in, 0, out, bsize, &bread, NULL, nchar, to))
+ if ((se = p->icom->write_read_ex(p->icom, in, 0, out, bsize, &bread, NULL, nchar, to, 1))
!= ICOM_OK) {
rv = icoms2k10_err(se);
@@ -331,7 +332,7 @@ struct _kleink10 *p,
baud_rate br
) {
int se, rv = K10_OK;
- if ((se = p->icom->set_ser_port(p->icom, fc_HardwareDTR, br, parity_none,
+ if ((se = p->icom->set_ser_port(p->icom, fc_None, br, parity_none,
stop_1, length_8)) != ICOM_OK) {
rv = icoms2k10_err(se);
} else {
@@ -388,7 +389,7 @@ k10_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
}
a1logd(p->log, 5, "k10_init_coms: Trying %s baud, %d msec to go\n",
baud_rate_to_str(brt[i]), etime- msec_time());
- if ((se = p->icom->set_ser_port(p->icom, fc_HardwareDTR, brt[i], parity_none,
+ if ((se = p->icom->set_ser_port(p->icom, fc_None, brt[i], parity_none,
stop_1, length_8)) != ICOM_OK) {
amutex_unlock(p->lock);
a1logd(p->log, 5, "k10_init_coms: set_ser_port failed with 0x%x\n",se);
@@ -872,8 +873,16 @@ kleink10 *p) {
name[j] = buf[i + j];
if (((unsigned char *)name)[0] == 0xff) {
+#ifdef TEST_FAKE_CALIBS
+ #pragma message("!!!!!!!!!!!!!!! Klein K10 TEST_FULL_CALIB set !!!!!!!!!!!!!!!!!!!")
+ sprintf(name, "Fake_%d",ix);
+#else
+ //printf("Cal %d is 0xff - skipping\n",ix);
continue;
+#endif
}
+
+ /* Remove trailing spaces */
for (j = 19; j >= 0; j--) {
if (name[j] != ' ') {
name[j+1] = '\000';
@@ -881,7 +890,7 @@ kleink10 *p) {
}
}
-// printf("Adding Cal %d is '%s'\n",ix,name);
+ // printf("Adding Cal %d is '%s'\n",ix,name);
/* Add it to the list */
memset((void *)&k10_disptypesel[n], 0, sizeof(inst_disptypesel));
@@ -974,7 +983,7 @@ int usefast /* If nz use fast rate is possible */
#ifdef HIGH_SPEED
/* This isn't reliable, because there is no way to ensure that */
/* the T1 command has been sent before we change the baud rate, */
- /* anf if we wait too long will will loose the measurements. */
+ /* and if we wait too long we will loose the measurements. */
if (usefast && strcmp(p->firm_ver, "v01.09fh") > 0) {
isnew = 1; /* We can use faster T1 command */
rate = 384;
diff --git a/spectro/munki_imp.c b/spectro/munki_imp.c
index d8690e8..f95140b 100755
--- a/spectro/munki_imp.c
+++ b/spectro/munki_imp.c
@@ -7886,9 +7886,9 @@ munki_code munki_conv2XYZ(
double sms; /* Weighting */
if (s->emiss)
- conv = new_xsp2cie(icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, (icxClamping)clamp);
+ conv = new_xsp2cie(icxIT_none, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, (icxClamping)clamp);
else
- conv = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, (icxClamping)clamp);
+ conv = new_xsp2cie(icxIT_D50, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, (icxClamping)clamp);
if (conv == NULL)
return MUNKI_INT_CIECONVFAIL;
diff --git a/spectro/sa_conv.h b/spectro/sa_conv.h
index 0f7e635..0d4718d 100755
--- a/spectro/sa_conv.h
+++ b/spectro/sa_conv.h
@@ -191,6 +191,10 @@ void sa_Yxy2XYZ(double *out, double *in);
#define icmLab2XYZ sa_Lab2XYZ
#define icmYxy2XYZ sa_Yxy2XYZ
+/* Lpt isn't used by instlib, so dummy it out */
+#define icmXYZ2Lpt sa_XYZ2Lab
+#define icmLpt2XYZ sa_Lab2XYZ
+
/* A helper object that computes MD5 checksums */
struct _sa_MD5 {
/* Private: */
diff --git a/spectro/spec2cie.c b/spectro/spec2cie.c
index 6c56e67..fd40c51 100755
--- a/spectro/spec2cie.c
+++ b/spectro/spec2cie.c
@@ -53,7 +53,7 @@
This is intended for conversion of reflective measurements to XYZ -
there is no illuminant for emissive values.
- L*a*b* is always D50.
+ L*a*b* is always D50, since it is intended for ICC profile construction.
*/
@@ -133,10 +133,10 @@ main(int argc, char *argv[])
int ci, mi, yi, ki; /* Indexes of device values */
int fwacomp = 0; /* FWA compensation */
int doplot = 0; /* Plot each patches spectrum */
- char* illum_str = "D50";
icxIllumeType tillum = icxIT_none; /* Target/simulated instrument illuminant, if set. */
xspect cust_tillum, *tillump = NULL; /* Custom target/simulated illumination spectrum */
/* if tillum == icxIT_custom */
+ char* illum_str = "D50";
icxIllumeType illum = icxIT_none; /* CIE calc. illuminant spectrum, and FWA inst. */
/* illuminant if tillum not set. */
xspect cust_illum; /* Custom CIE illumination spectrum if illum == icxIT_custom */
@@ -149,6 +149,8 @@ main(int argc, char *argv[])
icxObserverType obType = icxOT_none;
xspect custObserver[3]; /* Custom observer CMF's */
+ icmXYZNumber ill_wp_XYZ; /* if ill_wp != NULL, same as ill_wp */
+
int npat; /* Number of patches */
int ti; /* Field index */
char *kw;
@@ -654,10 +656,11 @@ main(int argc, char *argv[])
int Xi, Yi, Zi, Li, ai, bi; /* CGATS indexes for each field */
int spi[XSPECT_MAX_BANDS]; /* CGATS indexes for each wavelength */
int oXi, oYi, oZi, oLi, oai, obi; /* CGATS indexes for each ouput field */
+ int oL2i, oa2i, ob2i; /* For illuminant wp L*a*b* output */
xsp2cie *sp2cie; /* Spectral conversion object */
xspect sp;
double XYZ[3];
- double Lab[3];
+ double Lab[3], Lab2[3];
char buf[100];
/* These are only set if fwa is needed */
xspect rmwsp; /* Raw medium white spectrum */
@@ -710,6 +713,17 @@ main(int argc, char *argv[])
}
+ /* If CIE calculation illuminant is not standard, compute it's white point */
+ if (illum != icxIT_D50 && illum != icxIT_none) {
+ ill_wp = _ill_wp;
+
+ /* 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");
+
+ icmAry2XYZ(ill_wp_XYZ, ill_wp);
+ }
+
/* copy fields to output file (except spectral if nospec) */
for (i = 0; i < icg->t[0].nfields; i++) {
@@ -758,27 +772,51 @@ main(int argc, char *argv[])
oai = ai;
obi = bi;
- /* allocate elements */
+ /* If non-standard illuminant is being used, add extra LAB fields */
+ /* to show illuminant relative values (Not used for profiling!) */
+ if (ill_wp != NULL) {
+ char buf[50] = { '\000' }, *cp;
- if ((elems = (cgats_set_elem *)
- calloc(ocg->t[0].nfields, sizeof(cgats_set_elem))) == NULL)
- {
- error("Out of memory");
- }
+ strncpy(buf, illum_str, 40);
- /* If CIE calculation illuminant is not standard, compute it's white point */
- if (illum != icxIT_D50 && illum != icxIT_none) {
- ill_wp = _ill_wp;
+ /* Replace spaces */
+ for (cp = buf; *cp != '\000'; cp++) {
+ if (*cp == ' ')
+ *cp = '_';
+ }
+ /* Remove extension */
+ for (; cp >= buf; cp--) {
+ if (*cp == '.') {
+ *cp = '\000';
+ break;
+ }
+ }
+ strcat(buf, "LAB");
+ cp = buf + strlen(buf);
+ cp[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");
+ cp[1] = 'L';
+ if ((oL2i = ocg->add_field(ocg, 0, buf, r_t)) < 0)
+ error ("Cannot add field to table");
+
+ cp[1] = 'A';
+ if ((oa2i = ocg->add_field(ocg, 0, buf, r_t)) < 0)
+ error ("Cannot add field to table");
+
+ cp[1] = 'B';
+ if ((ob2i = ocg->add_field(ocg, 0, buf, r_t)) < 0)
+ error ("Cannot add field to table");
+ }
+
+ /* allocate elements */
+ if ((elems = (cgats_set_elem *)
+ calloc(ocg->t[0].nfields, sizeof(cgats_set_elem))) == NULL) {
+ error("Out of memory");
}
/* Create a spectral conversion object */
- if ((sp2cie = new_xsp2cie(illum, &cust_illum, obType, custObserver,
- icSigXYZData, icxClamp)) == NULL)
- {
+ if ((sp2cie = new_xsp2cie(illum, 0.0, &cust_illum, obType, custObserver,
+ icSigXYZData, icxClamp)) == NULL) {
error ("Creation of spectral conversion object failed");
}
@@ -921,14 +959,15 @@ main(int argc, char *argv[])
ocg->add_kword(ocg, 0, "ILLUMINANT_WHITE_POINT_XYZ",buf, NULL);
}
- /* Transform patches from spectral to CIE */
+ /* Transform patches from spectral to CIE, */
+ /* after correcting the spectrum for possible XRGA and FWA. */
for (i = 0; i < npat; i++) {
- xspect corr_sp;
/* copy all input colums to output (except spectral if nospec) */
for (jj = j = 0; j < icg->t[0].nfields; j++) {
if (nospec) {
+
/* See if this is a spectral field */
for (k = 0; nospec && k < sp.spec_n; k++) {
if (spi[k] == j)
@@ -963,39 +1002,27 @@ main(int argc, char *argv[])
}
/* Read the spectral values for this patch */
- for (j = 0; j < sp.spec_n; j++) {
+ 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);
+ /* Convert it to CIE space */
if (fwacomp) {
- corr_sp = sp; /* Copy spectrum */
-
- /* Convert it to CIE space */
- sp2cie->sconvert (sp2cie, &corr_sp, XYZ, &sp);
-
- /* Write the corrected spectral values for this patch */
- if (nospec == 0) {
- for (j = 0; j < sp.spec_n; j++) {
- elems[spi[j]].d = sp.spec[j] = corr_sp.spec[j];
- }
- }
+ sp2cie->sconvert(sp2cie, &sp, XYZ, &sp);
+ } else {
+ sp2cie->convert(sp2cie, XYZ, &sp);
}
- /* No FWA comp */
- else {
- /* Convert it to CIE space */
- sp2cie->convert (sp2cie, XYZ, &sp);
+ /* Standard pseudo-absolute D50 ICC Lab */
+ icmXYZ2Lab(&icmD50, Lab, XYZ);
+ /* Illuminant relative Lab */
+ if (ill_wp != NULL) {
+ icmXYZ2Lab(&ill_wp_XYZ, Lab2, XYZ);
}
- /* Could use sp2cie->get_cie_il() to get CIE white point */
- /* if we wanted to return L*a*b* relative to that. */
- /* We would have to mark that in the .ti3 though. */
- /* This won't work for emmisive though, since get_cie_il() will return 'E' */
- icmXYZ2Lab(&icmD50, Lab, XYZ);
-
#ifdef ALLOW_PLOT
if (doplot) {
int ii;
@@ -1018,14 +1045,28 @@ main(int argc, char *argv[])
do_plot(xx,y1,NULL,NULL,ii);
}
#endif
+ /* Write the corrected spectral values for this patch */
+ if (nospec == 0
+ && (calstdo != xcalstd_none || fwacomp)) {
+ for (j = 0; j < sp.spec_n; j++) {
+ elems[spi[j]].d = sp.spec[j];
+ }
+ }
+
elems[oXi].d = XYZ[0] * 100.0;
elems[oYi].d = XYZ[1] * 100.0;
elems[oZi].d = XYZ[2] * 100.0;
-
+
elems[oLi].d = Lab[0];
elems[oai].d = Lab[1];
elems[obi].d = Lab[2];
+ if (ill_wp != NULL) {
+ elems[oL2i].d = Lab2[0];
+ elems[oa2i].d = Lab2[1];
+ elems[ob2i].d = Lab2[2];
+ }
+
ocg->add_setarr(ocg, 0, elems);
}
diff --git a/spectro/specbos.c b/spectro/specbos.c
index 136fb34..6d2d5c0 100755
--- a/spectro/specbos.c
+++ b/spectro/specbos.c
@@ -383,11 +383,9 @@ specbos_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
if (dispen) {
p->model = 1511;
- /* Set remote mode */
+ /* Set remote mode (for old firmare) */
if ((ev = specbos_command(p, "*REMOTE 1\r", buf, MAX_MES_SIZE, 1.0)) != inst_ok) {
- amutex_unlock(p->lock);
- a1logd(p->log, 2, "specbos_init_coms: failed to set remote mode\n");
- return inst_protocol_error;
+ a1logd(p->log, 2, "specbos_init_coms: remote command failed (newer firmware ?)\n");
}
}
@@ -579,6 +577,9 @@ specbos_init_inst(inst *pp) {
}
}
+ /* Set target maximum measure time (no averaging) */
+ /* (We will then setup instrument to compy with this target) */
+ /* 3.6 is the assumed maximum fixed overhead */
p->measto = 20.0; /* Set default. Specbos default is 60.0 */
if (p->model == 1211)
@@ -624,10 +625,11 @@ specbos_init_inst(inst *pp) {
return ev;
}
#else /* Bound auto by no. averages (better - limit maxint to 1.0) */
- double dmaxtint = 1.0; /* Recommended maximum */
+ double dmaxtint = 1.0; /* Recommended maximum is 1.0 */
int maxtint;
int maxaver; /* Maximum averages for auto int time */
+ /* Set the max integration time to 1.0 seconds: */
maxtint = (int)(dmaxtint * 1000.0+0.5);
if (maxtint < 1000 || maxtint > 64999) {
@@ -638,23 +640,24 @@ specbos_init_inst(inst *pp) {
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;
}
+ /* Then compute the maximum number of measurements to meet measto: */
+
/* 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;
}
+ a1logd(p->log, 6, "specbos_init_inst: set maxaver %d\n",maxaver);
+
/* 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) {
@@ -679,16 +682,25 @@ specbos_init_inst(inst *pp) {
warning("specbos: assert, maxtint %d out of range",maxtin);
if (maxtin < 1000)
maxtin = 1000;
- else if (maxtin > 64999)
- maxtin = 64999;
+ else if (maxtin > 60000) /* 60 secs according to auxiliary doco. */
+ maxtin = 60000;
}
- /* Set maximum integration time */
- /* (1201 *para:maxtint doesn't work !!) */
+ /* Set maximum integration time that auto will use */
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;
+ /* 1201 Firmware V1.8.3 and earlier doesn't support maxtin. */
+ /* Ignore error with a warning. */
+ if (p->model == 1201) {
+ if (!p->maxtin_warn)
+ warning("specbos: conf:maxtin %d command failed (Old Firmware ?)",maxtin);
+ p->maxtin_warn = 1;
+
+ /* Fatal error otherwise */
+ } else {
+ amutex_unlock(p->lock);
+ return ev;
+ }
}
#ifdef NEVER /* Use default */
@@ -972,6 +984,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
int user_trig = 0;
int pos = -1;
inst_code rv = inst_protocol_error;
+ double measto = p->measto;
if (!p->gotcoms)
return inst_no_coms;
@@ -1062,10 +1075,21 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
if ((rv = set_average(p, p->noaverage, 0)) != inst_ok)
return rv;
+ /* Adjust timeout to account for averaging */
+ /* (Allow extra 1 sec fudge factor per average) */
+ if (p->noaverage > 1) {
+ measto = p->noaverage * (p->measto - 3.6 + 1.0) + 3.6;
+ a1logd(p->log, 6, " Adjusted measto to %f for noaver %d\n",measto,p->noaverage);
+ }
+
/* Set to average 10 readings for transmission */
} else if ((p->mode & inst_mode_illum_mask) == inst_mode_transmission) {
if ((rv = set_average(p, DEFAULT_TRANS_NAV, 0)) != inst_ok)
return rv;
+
+ measto = DEFAULT_TRANS_NAV * (p->measto - 3.6 + 1.0) + 3.6;
+ a1logd(p->log, 6, " Adjusted measto to %f for noaver %d\n",measto,DEFAULT_TRANS_NAV);
+
/* Or default 1 otherwise */
} else {
if ((rv = set_average(p, DEFAULT_NAV, 0)) != inst_ok)
@@ -1080,12 +1104,12 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
}
}
- /* Trigger a measurement */
+ /* Trigger a measurement (Allow 10 second timeout margine) */
/* (Note that ESC will abort it) */
if (p->model == 1501 || p->model == 1511)
- ec = specbos_fcommand(p, "*meas:refer\r", buf, MAX_MES_SIZE, p->measto + 10.0 , 1, tmeas, 0);
+ ec = specbos_fcommand(p, "*meas:refer\r", buf, MAX_MES_SIZE, measto + 10.0 , 1, tmeas, 0);
else
- ec = specbos_fcommand(p, "*init\r", buf, MAX_MES_SIZE, p->measto + 10.0 , 1, tmeas, 0);
+ ec = specbos_fcommand(p, "*init\r", buf, MAX_MES_SIZE, measto + 10.0 , 1, tmeas, 0);
// Test out bug workaround
// if (!p->badCal) ec = SPECBOS_EXCEED_CAL_WL;
@@ -1118,9 +1142,9 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
/* Try command again */
if (p->model == 1501 || p->model == 1511)
- ec = specbos_fcommand(p, "*meas:refer\r", buf, MAX_MES_SIZE, p->measto + 10.0 , 1, tmeas, 0);
+ ec = specbos_fcommand(p, "*meas:refer\r", buf, MAX_MES_SIZE, measto + 10.0 , 1, tmeas, 0);
else
- ec = specbos_fcommand(p, "*init\r", buf, MAX_MES_SIZE, p->measto + 10.0 , 1, tmeas, 0);
+ ec = specbos_fcommand(p, "*init\r", buf, MAX_MES_SIZE, measto + 10.0 , 1, tmeas, 0);
}
/* Restore single reading if transmission */
@@ -1405,7 +1429,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
/* Convert to XYZ */
if (p->conv == NULL) {
- p->conv = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData,
+ p->conv = new_xsp2cie(icxIT_D50, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData,
icxNoClamp);
if (p->conv == NULL) {
a1logd(p->log, 1, "specbos_read_sample: Emulated transmission new_xsp2cie() failed");
diff --git a/spectro/specbos.h b/spectro/specbos.h
index ef6fc2f..4ef4a88 100755
--- a/spectro/specbos.h
+++ b/spectro/specbos.h
@@ -150,7 +150,7 @@ struct _specbos {
inst_opt_type trig; /* Reading trigger mode */
- double measto; /* Expected measurement timeout value */
+ double measto; /* Measurement maximum time target value */
int nbands; /* Number of spectral bands */
double wl_short;
double wl_long;
@@ -169,6 +169,8 @@ struct _specbos {
int dpos; /* Diffuser position, 0 = emissive, 1 = ambient */
int laser; /* Target laser state, nz = on */
+ int maxtin_warn; /* NZ if conf:maxtin failure warning has been given */
+
}; typedef struct _specbos specbos;
/* Constructor */
diff --git a/spectro/spotread.c b/spectro/spotread.c
index 16f6f2d..1b4189b 100755
--- a/spectro/spotread.c
+++ b/spectro/spotread.c
@@ -21,6 +21,8 @@
/* TTBD
*
+ * Add option to automatically read continuously, until stopped. (A bit like -O)
+
* Make -V average the spectrum too (if present), and allow it to
* be saved to a .sp file.
*
@@ -45,19 +47,19 @@
#include <time.h>
#include <string.h>
#ifndef SALONEINSTLIB
-#include "copyright.h"
-#include "aconfig.h"
-#include "numlib.h"
-#include "cgats.h"
-#include "xicc.h"
-#include "conv.h"
-#include "plot.h"
-#include "ui.h"
+# include "copyright.h"
+# include "aconfig.h"
+# include "numlib.h"
+# include "cgats.h"
+# include "xicc.h"
+# include "conv.h"
+# include "plot.h"
+# include "ui.h"
#else /* SALONEINSTLIB */
-#include "sa_config.h"
-#include "numsup.h"
-#include "xspect.h"
-#include "conv.h"
+# include "sa_config.h"
+# include "numsup.h"
+# include "xspect.h"
+# include "conv.h"
#endif /* SALONEINSTLIB */
#include "inst.h"
#include "icoms.h"
@@ -252,7 +254,7 @@ static inst_code uicallback(void *cntx, inst_ui_purp purp) {
ABCDEFGHIJKLMNOPQRSTUVWXYZ
upper ... . . .. . .. ...
- lower . .... .. . .. . ..
+ lower . .... .. . .. ....
*/
@@ -332,6 +334,9 @@ usage(char *diag, ...) {
fprintf(stderr," u U.V. Cut\n");
fprintf(stderr," -E extrafilterfile Apply extra filter compensation file\n");
fprintf(stderr," -A N|A|X|G XRGA conversion (default N)\n");
+#ifndef SALONEINSTLIB
+ fprintf(stderr," -w Use -i param. illuminant for comuting L*a*b*\n");
+#endif
fprintf(stderr," -x Display Yxy instead of Lab\n");
fprintf(stderr," -h Display LCh instead of Lab\n");
#ifndef SALONEINSTLIB
@@ -413,7 +418,7 @@ int main(int argc, char *argv[]) {
icompaths *icmps = NULL;
int comport = COMPORT; /* COM port used */
icompath *ipath = NULL;
- int dtype = 0; /* Display type selection charater */
+ int ditype = 0; /* Display type selection character(s) */
inst_mode cap = inst_mode_none; /* Instrument mode capabilities */
inst2_capability cap2 = inst2_none; /* Instrument capabilities 2 */
inst3_capability cap3 = inst3_none; /* Instrument capabilities 3 */
@@ -430,7 +435,10 @@ int main(int argc, char *argv[]) {
int illum_set = 0; /* User asked for custom illuminant spectrum */
icxIllumeType illum = icxIT_D50; /* Spectral defaults */
xspect cust_illum; /* Custom illumination spectrum */
- icxObserverType obType = icxOT_default;
+ int labwpillum = 0; /* nz to use illum WP for L*a*b* conversion */
+ icmXYZNumber labwp = { icmD50_100.X, icmD50_100.Y, icmD50_100.Z }; /* Lab conversion wp */
+ char labwpname[100] = "D50"; /* Name of Lab conversion wp */
+ icxObserverType obType = icxOT_default; /* Default is 1931_2 */
xspect custObserver[3]; /* If obType = icxOT_custom */
xspect sp; /* Last spectrum read */
xspect rsp; /* Reference spectrum */
@@ -519,7 +527,9 @@ int main(int argc, char *argv[]) {
} else if (argv[fa][1] == 'y') {
fa = nfa;
if (na == NULL) usage("Paramater expected following -y");
- dtype = na[0];
+ ditype = na[0];
+ if (ditype == '_' && na[1] != '\000')
+ ditype = ditype << 8 | na[1];
#ifndef SALONEINSTLIB
/* Simulated instrument illumination (FWA) */
@@ -620,6 +630,12 @@ int main(int argc, char *argv[]) {
usage("Unrecognised illuminant '%s'",na);
#endif /* SALONEINSTLIB */
+#ifndef SALONEINSTLIB
+ /* Use -i illuminant for L*a*b* conversion */
+ } else if (argv[fa][1] == 'w') {
+ labwpillum = 1;
+#endif /* !SALONEINSTLIB */
+
/* Spectral Observer type */
} else if (argv[fa][1] == 'Q') {
fa = nfa;
@@ -901,11 +917,29 @@ int main(int argc, char *argv[]) {
}
/* Check for some user mistakes */
-
- if ((tillum_set || illum_set) && emiss)
+ if ((tillum_set || illum_set) && emiss )
warning("-I or -i parameter makes no sense with emissive or ambient measurement!");
+ if (illum_set && labwpillum && emiss) {
+ warning("-w for emissive is ignored!");
+ labwpillum = 0;
+ }
+
/* - - - - - - - - - - - - - - - - - - - */
+ /* Setup Lab conversion wp if not D50 */
+ if (illum_set && labwpillum && !emiss) {
+ double xyz[3];
+
+ strcpy(labwpname, standardIlluminant_name(illum, 0.0));
+
+ if (icx_ill_sp2XYZ(xyz, obType, custObserver, illum, 0.0, &cust_illum, 0))
+ error("Looking up W.P. of illuminant failed");
+
+ icmScale3(xyz, xyz, 100.0);
+ icmAry2XYZ(labwp, xyz);
+
+ }
+
if ((icmps = new_icompaths(g_log)) == NULL)
error("Finding instrument paths failed");
if ((ipath = icmps->get_path(icmps, comport)) == NULL)
@@ -1204,12 +1238,12 @@ int main(int argc, char *argv[]) {
}
/* Set displaytype or calibration mode */
- if (dtype != 0) {
+ if (ditype != 0) {
if (cap2 & inst2_disptype) {
int ix;
- if ((ix = inst_get_disptype_index(it, dtype, 0)) < 0) {
+ if ((ix = inst_get_disptype_index(it, ditype, 0)) < 0) {
it->del(it);
- usage("Failed to locate display type matching '%c'",dtype);
+ usage("Failed to locate display type matching '%s'",inst_distr(ditype));
}
if ((rv = it->set_disptype(it, ix)) != inst_ok) {
@@ -1547,7 +1581,7 @@ int main(int argc, char *argv[]) {
illum = icxIT_none;
/* Create a spectral conversion object */
- if ((sp2cie = new_xsp2cie(illum, &cust_illum, obType, custObserver, icSigXYZData,
+ if ((sp2cie = new_xsp2cie(illum, 0.0, &cust_illum, obType, custObserver, icSigXYZData,
refstats ? icxNoClamp : icxClamp)) == NULL)
error("Creation of spectral conversion object failed");
@@ -1593,9 +1627,9 @@ int main(int argc, char *argv[]) {
for (j = 0; j < 3; j++)
rXYZ[j] *= 100.0; /* 0..100 scale */
}
- icmXYZ2Lab(&icmD50_100, rLab, rXYZ);
+ icmXYZ2Lab(&labwp, rLab, rXYZ);
if (verb)
- printf("Preset ref. XYZ %f %f %f, Lab %f %f %f\n", rXYZ[0], rXYZ[1], rXYZ[2], rLab[0], rLab[1], rLab[2]);
+ printf("Preset ref. XYZ %f %f %f, %s Lab %f %f %f\n", rXYZ[0], rXYZ[1], rXYZ[2], labwpname, rLab[0], rLab[1], rLab[2]);
}
#endif
@@ -2315,7 +2349,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,
+ if ((sp2cief[fidx] = new_xsp2cie(illum, 0.0, &cust_illum, obType,
custObserver, icSigXYZData, refstats ? icxNoClamp : icxClamp)) == NULL)
error("Creation of spectral conversion object failed");
}
@@ -2520,8 +2554,8 @@ int main(int argc, char *argv[]) {
vdt_sn = -1.0;
}
- /* Compute D50 Lab from XYZ */
- icmXYZ2Lab(&icmD50_100, Lab, XYZ);
+ /* Compute D50 (or other) Lab from XYZ */
+ icmXYZ2Lab(&labwp, Lab, XYZ);
/* Compute Yxy from XYZ */
icmXYZ2Yxy(Yxy, XYZ);
@@ -2529,7 +2563,7 @@ int main(int argc, char *argv[]) {
/* Compute LCh from Lab */
icmLab2LCh(LCh, Lab);
- /* Compute D50 Yuv from XYZ */
+ /* Compute Yuv from XYZ */
icmXYZ21976UCS(Yuv, XYZ);
#else /* SALONEINSTLIB */
@@ -2547,8 +2581,8 @@ int main(int argc, char *argv[]) {
if (wXYZ[0] < 0.0) { /* If we haven't save a white ref. yet */
if (XYZ[1] < 10.0)
error ("White of XYZ %f %f %f doesn't seem reasonable",XYZ[0], XYZ[1], XYZ[2]);
- printf("\n Making result XYZ: %f %f %f, D50 Lab: %f %f %f white reference.\n",
- XYZ[0], XYZ[1], XYZ[2], Lab[0], Lab[1], Lab[2]);
+ printf("\n Making result XYZ: %f %f %f, %s Lab: %f %f %f white reference.\n",
+ XYZ[0], XYZ[1], XYZ[2], labwpname, Lab[0], Lab[1], Lab[2]);
wXYZ[0] = XYZ[0];
wXYZ[1] = XYZ[1];
wXYZ[2] = XYZ[2];
@@ -2576,7 +2610,7 @@ int main(int argc, char *argv[]) {
}
/* recompute Lab */
- icmXYZ2Lab(&icmD50_100, Lab, XYZ);
+ icmXYZ2Lab(&labwp, Lab, XYZ);
/* recompute Yxy from XYZ */
icmXYZ2Yxy(Yxy, XYZ);
@@ -2625,8 +2659,8 @@ int main(int argc, char *argv[]) {
#endif
} else {
/* Print out the XYZ and Lab */
- printf("\n Result is XYZ: %f %f %f, D50 Lab: %f %f %f\n",
- XYZ[0], XYZ[1], XYZ[2], Lab[0], Lab[1], Lab[2]);
+ printf("\n Result is XYZ: %f %f %f, %s Lab: %f %f %f\n",
+ XYZ[0], XYZ[1], XYZ[2], labwpname, Lab[0], Lab[1], Lab[2]);
}
}
diff --git a/spectro/spyd2.c b/spectro/spyd2.c
index 28051f3..539c2c0 100755
--- a/spectro/spyd2.c
+++ b/spectro/spyd2.c
@@ -2146,7 +2146,7 @@ spyd4_comp_calmat(
}
/* Compute XYZ of the real sample array. */
- if ((conv = new_xsp2cie(icxIT_none, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL)
+ if ((conv = new_xsp2cie(icxIT_none, 0.0, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL)
return spyd2_interp_code((inst *)p, SPYD2_INT_CIECONVFAIL);
sampXYZ = dmatrix(0, nasamp-1, 0, 3-1);
for (i = 0; i < nsamp; i++) {
diff --git a/spectro/ss.c b/spectro/ss.c
index 4f95fdb..7e67fbe 100755
--- a/spectro/ss.c
+++ b/spectro/ss.c
@@ -54,10 +54,11 @@
You should be able to use the table enter key anywhere the user
is asked to hit a key.
- The corner positioning could be smarter.
+ The corner positioning could be smarter (i.e. move to the anticipated corned
+ automatically).
The SpectroscanT transmission cal. merely reminds the user (via verbose)
- that it is assuming the correct apatture, rather than given them
+ that it is assuming the correct apature, rather than given them
a chance to change it.
*/
diff --git a/spectro/ss_imp.c b/spectro/ss_imp.c
index 0de14ea..bfe7e25 100755
--- a/spectro/ss_imp.c
+++ b/spectro/ss_imp.c
@@ -1497,8 +1497,8 @@ ss_tmt tm /* Table mode (Reflectance/Transmission) */
inst_code ss_do_SetDeviceOnline(ss *p) {
#ifdef EMSST
if (p->tmode != 0)
- *((char *)0) = 55;
-// return inst_unsupported;
+// *((char *)0) = 55; // Trigger backtrace
+ return inst_unsupported;
#endif
ss_add_ssreq(p, ss_SetDeviceOnline);
ss_command(p, DF_TMO);
@@ -1514,7 +1514,8 @@ inst_code ss_do_SetDeviceOnline(ss *p) {
inst_code ss_do_SetDeviceOffline(ss *p) {
#ifdef EMSST
if (p->tmode != 0)
- *((char *)0) = 55;
+// *((char *)0) = 55; // Trigger backtrace
+ return inst_unsupported;
#endif
ss_add_ssreq(p, ss_SetDeviceOffline);
ss_command(p, DF_TMO);
@@ -1559,7 +1560,8 @@ double y /* Y coord in mm, 0-230.0, accurate to 0.1mm */
) {
#ifdef EMSST
if (p->tmode != 0)
- *((char *)0) = 55;
+// *((char *)0) = 55; // Trigger backtrace
+ return inst_unsupported;
#endif
ss_add_ssreq(p, ss_MoveAbsolut);
ss_add_1(p, r);
@@ -1581,7 +1583,8 @@ double y /* Y distance in mm, 0-230.0, accurate to 0.1mm */
) {
#ifdef EMSST
if (p->tmode != 0)
- *((char *)0) = 55;
+// *((char *)0) = 55; // Trigger backtrace
+ return inst_unsupported;
#endif
ss_add_ssreq(p, ss_MoveRelative);
ss_add_2(p, (int)(x * 10 + 0.5));
@@ -1600,7 +1603,8 @@ ss *p
) {
#ifdef EMSST
if (p->tmode != 0)
- *((char *)0) = 55;
+// *((char *)0) = 55; // Trigger backtrace
+ return inst_unsupported;
#endif
ss_add_ssreq(p, ss_MoveHome);
ss_command(p, MV_TMO);
@@ -1617,7 +1621,8 @@ ss *p
) {
#ifdef EMSST
if (p->tmode != 0)
- *((char *)0) = 55;
+// *((char *)0) = 55; // Trigger backtrace
+ return inst_unsupported;
#endif
ss_add_ssreq(p, ss_MoveUp);
ss_command(p, MV_TMO);
@@ -1634,7 +1639,8 @@ ss *p
) {
#ifdef EMSST
if (p->tmode != 0)
- *((char *)0) = 55;
+// *((char *)0) = 55; // Trigger backtrace
+ return inst_unsupported;
#endif
ss_add_ssreq(p, ss_MoveDown);
ss_command(p, MV_TMO);
@@ -1656,7 +1662,8 @@ ss_zkt *zk /* Return the Z coordinate (Up/Down) */
) {
#ifdef EMSST
if (p->tmode != 0)
- *((char *)0) = 55;
+// *((char *)0) = 55; // Trigger backtrace
+ return inst_unsupported;
#endif
ss_add_ssreq(p, ss_OutputActualPosition);
ss_add_1(p, r);
@@ -1680,7 +1687,8 @@ ss_wrpt wrp /* White Reference Position (Tile1/Tile2) */
) {
#ifdef EMSST
if (p->tmode != 0)
- *((char *)0) = 55;
+// *((char *)0) = 55; // Trigger backtrace
+ return inst_unsupported;
#endif
ss_add_ssreq(p, ss_MoveToWhiteRefPos);
ss_add_1(p, wrp);
@@ -1749,7 +1757,8 @@ ss_llt ll /* Transmission light level (Off/Surround/Low) */
if (p->tmode != 0)
return inst_ok;
else
- *((char *)0) = 55;
+// *((char *)0) = 55; // Trigger backtrace
+ return inst_unsupported;
#endif
ss_add_ssreq(p, ss_SetLightLevel);
ss_add_1(p, ll);
@@ -1775,7 +1784,8 @@ double y /* Y coord in mm, 0-230.0, accurate to 0.1mm */
p->sby = y;
return inst_ok;
} else {
- *((char *)0) = 55;
+// *((char *)0) = 55; // Trigger backtrace
+ return inst_unsupported;
}
#endif
ss_add_ssreq(p, ss_SetTransmStandbyPos);
diff --git a/spectro/vtpglut.c b/spectro/vtpglut.c
index 2308466..b558bf4 100755
--- a/spectro/vtpglut.c
+++ b/spectro/vtpglut.c
@@ -14,6 +14,16 @@
* see the License2.txt file for licencing details.
*/
+/*
+ TTBD:
+
+ Note that there is some support for HW 3dLUTs in X11 xrandr
+ in a patch for xf86-videeo-amdgpu drmmode_display.c
+ submitted on 3 May 2018.
+ See <https://lists.freedesktop.org/archives/amd-gfx/2018-May/022007.html>
+
+*/
+
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
diff --git a/spectro/xrga.c b/spectro/xrga.c
index 7318fce..d481b6a 100755
--- a/spectro/xrga.c
+++ b/spectro/xrga.c
@@ -160,23 +160,20 @@ void xspec_convert_xrga(xspect *dst, xspect *srcp, xcalpol pol, xcalstd dsp, xca
xspect tmp, *src = srcp;
/* If no conversion and no copy needed */
- if ((ssp == xcalstd_native || dsp == xcalstd_native || dsp == ssp)
- && dst == src)
+ if (!XCALSTD_NEEDED(ssp, dsp) && dst == src)
return;
- /* If no conversion needed */
- if (ssp == xcalstd_native || dsp == xcalstd_native || dsp == ssp) {
+ /* If no conversion needed */
+ if (!XCALSTD_NEEDED(ssp, dsp)) {
*dst = *src; /* Struct copy */
return;
}
- /* If the dest is the same as the src, make a temporary copy */
+ /* If the dest is the same as the src, make a temporary copy, */
+ /* since convert_xrga() needs them to be distinct */
if (dst == src) {
tmp = *src; /* Struct copy */
src = &tmp;
-
- } else {
- XSPECT_COPY_INFO(dst, src); /* Copy parameters */
}
eq = &xrga_equations[pol][ssp][dsp];
@@ -210,7 +207,7 @@ void ipatch_convert_xrga(ipatch *vals, int nvals,
/* Re-compute XYZ */
if (vals[i].XYZ_v) {
if (conv == NULL) {
- conv = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2,
+ conv = new_xsp2cie(icxIT_D50, 0.0, NULL, icxOT_CIE_1931_2,
NULL, icSigXYZData, (icxClamping)clamp);
}
conv->convert(conv, vals[i].XYZ, &vals[i].sp);
diff --git a/target/ofps.c b/target/ofps.c
index 54a0ea1..d965097 100755
--- a/target/ofps.c
+++ b/target/ofps.c
@@ -128,6 +128,7 @@
#if defined(__IBMC__)
#include <float.h>
#endif
+#include "aconfig.h"
#include "numlib.h"
#include "sort.h"
#include "counters.h"
diff --git a/target/prand.c b/target/prand.c
index 7ce5760..7040373 100755
--- a/target/prand.c
+++ b/target/prand.c
@@ -26,6 +26,7 @@
#if defined(__IBMC__)
#include <float.h>
#endif
+#include "aconfig.h"
#include "numlib.h"
#include "sort.h"
#include "icc.h"
diff --git a/target/targen.c b/target/targen.c
index 96cda6c..ee12243 100755
--- a/target/targen.c
+++ b/target/targen.c
@@ -18,6 +18,8 @@
/* TTBD:
+ Should add option to create just surface test patches.
+
Should add an option to generate grey and near grey
or other PCS based pattern test points based on the previous profile.
How about an option to read in an CGATS file containing
diff --git a/tweak/refine.c b/tweak/refine.c
index c9e16bd..6415874 100755
--- a/tweak/refine.c
+++ b/tweak/refine.c
@@ -671,7 +671,7 @@ main(int argc, char *argv[]) {
}
/* Create a spectral conversion object */
- if ((sp2cie = new_xsp2cie(illum, illum == icxIT_none ? NULL : &cust_illum,
+ if ((sp2cie = new_xsp2cie(illum, 0.0, illum == icxIT_none ? NULL : &cust_illum,
obType, custObserver, icSigLabData, icxClamp)) == NULL)
error("Creation of spectral conversion object failed");
diff --git a/usb/ArgyllCMS.cat b/usb/ArgyllCMS.cat
index d905b40..e0a2d35 100755
--- a/usb/ArgyllCMS.cat
+++ b/usb/ArgyllCMS.cat
Binary files differ
diff --git a/usb/ArgyllCMS_x64.cat b/usb/ArgyllCMS_x64.cat
index f734475..e3c213f 100755
--- a/usb/ArgyllCMS_x64.cat
+++ b/usb/ArgyllCMS_x64.cat
Binary files differ
diff --git a/xicc/bt1886.c b/xicc/bt1886.c
index ddd6066..2dad1a6 100755
--- a/xicc/bt1886.c
+++ b/xicc/bt1886.c
@@ -12,7 +12,7 @@
*
*/
-/* BT.1886 stype input offset transfer curve, */
+/* BT.1886 type input offset transfer curve, */
/* + general gamma + input + output offset curve support. */
#include <sys/types.h>
diff --git a/xicc/bt1886.h b/xicc/bt1886.h
index f14efdc..b0399c9 100755
--- a/xicc/bt1886.h
+++ b/xicc/bt1886.h
@@ -14,10 +14,9 @@
*
*/
-/* BT.1886 stype input offset transfer curve, */
+/* BT.1886 type input offset transfer curve, */
/* + general gamma + input + output offset curve support. */
-
typedef struct {
icmXYZNumber w; /* White point for Lab conversion */
double ingo; /* input Y offset for bt1886 */
diff --git a/xicc/ccmx.c b/xicc/ccmx.c
index 7206f31..7a004d9 100755
--- a/xicc/ccmx.c
+++ b/xicc/ccmx.c
@@ -278,13 +278,6 @@ cgats *icg /* input cgats structure */
}
if ((ti = icg->find_kword(icg, 0, "OEM")) >= 0) {
- if ((p->ref = strdup(icg->t[0].kdata[ti])) == NULL) {
- sprintf(p->err, "read_ccmx: malloc failed");
- return 2;
- }
- }
-
- if ((ti = icg->find_kword(icg, 0, "OEM")) >= 0) {
if (stricmp(icg->t[0].kdata[ti], "YES") == 0)
p->oem = 1;
else if (stricmp(icg->t[0].kdata[ti], "NO") == 0)
diff --git a/xicc/ccss.c b/xicc/ccss.c
index aae278e..b561b7b 100755
--- a/xicc/ccss.c
+++ b/xicc/ccss.c
@@ -29,12 +29,14 @@
#include <math.h>
#include <sys/types.h>
#include <time.h>
+# include "aconfig.h"
#ifndef SALONEINSTLIB
-#include "numlib.h"
-#include "icc.h"
+# include "numlib.h"
+# include "icc.h"
+# include "plot.h" /* For debugging */
#else
-#include "numsup.h"
-#include "sa_conv.h"
+# include "numsup.h"
+# include "sa_conv.h"
#endif
#include "cgats.h"
#include "xspect.h"
diff --git a/xicc/ccttest.c b/xicc/ccttest.c
index f7f4363..d9c480b 100755
--- a/xicc/ccttest.c
+++ b/xicc/ccttest.c
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <math.h>
+#include "aconfig.h"
#include "cgats.h"
#include "xspect.h"
#include "numlib.h"
diff --git a/xicc/cgatsplot.c b/xicc/cgatsplot.c
index bb598fc..a3315dd 100755
--- a/xicc/cgatsplot.c
+++ b/xicc/cgatsplot.c
@@ -20,6 +20,7 @@
#include <fcntl.h>
#include <string.h>
#include <math.h>
+#include "aconfig.h"
#include "numlib.h"
#include "icc.h"
#include "cgats.h"
diff --git a/xicc/cv.c b/xicc/cv.c
index 7cd7927..a61ef96 100755
--- a/xicc/cv.c
+++ b/xicc/cv.c
@@ -16,6 +16,7 @@
#include <stdlib.h>
#include <math.h>
#include <numlib.h>
+#include "aconfig.h"
#include "plot.h"
#include "ui.h"
diff --git a/xicc/cvtest.c b/xicc/cvtest.c
index a9fa59f..3520933 100755
--- a/xicc/cvtest.c
+++ b/xicc/cvtest.c
@@ -25,6 +25,7 @@
#if defined(__IBMC__) && defined(_M_IX86)
#include <float.h>
#endif
+#include "aconfig.h"
#include "numlib.h"
#include "plot.h"
#include "ui.h"
diff --git a/xicc/mpp.c b/xicc/mpp.c
index 86b6c30..4164021 100755
--- a/xicc/mpp.c
+++ b/xicc/mpp.c
@@ -113,6 +113,7 @@
#if defined(__IBMC__) && defined(_M_IX86)
#include <float.h>
#endif
+#include "aconfig.h"
#include "numlib.h"
#include "cgats.h"
#include "icc.h"
@@ -123,8 +124,9 @@
#include "gamut.h"
#include "mpp.h"
#ifdef DOPLOT
-#include "plot.h"
-#endif /* DOPLOT */
+# include "plot.h"
+# include "ui.h"
+#endif
/* Forward declarations */
static double bandval(mpp *p, int band, double *dev);
@@ -715,7 +717,7 @@ int use_fwa /* NZ to involke FWA. */
custIllum = NULL;
}
- if ((p->spc = new_xsp2cie(ilType, custIllum, obType, custObserver, rcs, 1)) == NULL)
+ if ((p->spc = new_xsp2cie(ilType, 0.0, custIllum, obType, custObserver, rcs, 1)) == NULL)
error("mpp->set_ilob, new_xsp2cie failed");
if (use_fwa) {
diff --git a/xicc/mpplu.c b/xicc/mpplu.c
index ecc67b0..bcf09bf 100755
--- a/xicc/mpplu.c
+++ b/xicc/mpplu.c
@@ -23,6 +23,7 @@
#include <fcntl.h>
#include <string.h>
#include <math.h>
+#include "aconfig.h"
#include "numlib.h"
#include "xicc.h"
#include "counters.h"
diff --git a/xicc/specplot.c b/xicc/specplot.c
index de819ed..ead2066 100755
--- a/xicc/specplot.c
+++ b/xicc/specplot.c
@@ -21,6 +21,7 @@
#include <stdio.h>
#include <math.h>
+#include "aconfig.h"
#include "cgats.h"
#include "xspect.h"
#include "numlib.h"
diff --git a/xicc/specsubsamp.c b/xicc/specsubsamp.c
index 1d6bbde..616b7ad 100755
--- a/xicc/specsubsamp.c
+++ b/xicc/specsubsamp.c
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <math.h>
+#include "aconfig.h"
#include "cgats.h"
#include "xspect.h"
#include "numlib.h"
diff --git a/xicc/spectest.c b/xicc/spectest.c
index 0bcc716..86c95a8 100755
--- a/xicc/spectest.c
+++ b/xicc/spectest.c
@@ -29,12 +29,13 @@
#include <stdio.h>
#include <math.h>
+#include "aconfig.h"
+#include "numlib.h"
#include "cgats.h"
#include "xspect.h"
-#include "numlib.h"
#ifdef DOPLOT
-#include "plot.h"
-#include "ui.h"
+# include "plot.h"
+# include "ui.h"
#endif
@@ -631,11 +632,11 @@ main(void) {
standardIlluminant(&sill, matilum[m][ss].ill, 0); /* Instrument */
/* Create two conversions for the target/check illuminant */
- if ((pcon = new_xsp2cie(icxIT_custom, &pill, icxOT_Shaw_Fairchild_2,
+ if ((pcon = new_xsp2cie(icxIT_custom, 0.0, &pill, icxOT_Shaw_Fairchild_2,
NULL, icSigLabData, 1)) == NULL)
error ("Creating conversion failed");
- if ((scon = new_xsp2cie(icxIT_custom, &pill, icxOT_Shaw_Fairchild_2,
+ if ((scon = new_xsp2cie(icxIT_custom, 0.0, &pill, icxOT_Shaw_Fairchild_2,
NULL, icSigLabData, 1)) == NULL)
error ("Creating conversion failed");
diff --git a/xicc/spectest2.c b/xicc/spectest2.c
index a1c338d..81832a4 100755
--- a/xicc/spectest2.c
+++ b/xicc/spectest2.c
@@ -25,14 +25,15 @@
#include <stdio.h>
#include <math.h>
+#include "aconfig.h"
#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
//#include "inst.h"
#include "numlib.h"
#ifdef DOPLOT
-#include "plot.h"
-#include "ui.h"
+# include "plot.h"
+# include "ui.h"
#endif
@@ -237,7 +238,7 @@ main(void) {
printf("Material %d\n", m+1);
/* Create two conversions for the target/check illuminant */
- if ((con = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2,
+ if ((con = new_xsp2cie(icxIT_D50, 0.0, NULL, icxOT_CIE_1931_2,
NULL, icSigLabData, 1)) == NULL)
error ("Creating conversion failed");
diff --git a/xicc/transplot.c b/xicc/transplot.c
index 6473e2b..aa4a1ff 100755
--- a/xicc/transplot.c
+++ b/xicc/transplot.c
@@ -25,6 +25,7 @@
#include <fcntl.h>
#include <string.h>
#include <math.h>
+#include "aconfig.h"
#include "icc.h"
#include "numlib.h"
#include "plot.h"
diff --git a/xicc/xcal.c b/xicc/xcal.c
index 4a5b37e..c1639d6 100755
--- a/xicc/xcal.c
+++ b/xicc/xcal.c
@@ -33,6 +33,7 @@
#include "copyright.h"
#include "aconfig.h"
#include "numlib.h"
+#include "plot.h"
#include "xicc.h"
#else
#include "sa_config.h"
diff --git a/xicc/xdgb.c b/xicc/xdgb.c
index 80914b8..fd5d90d 100755
--- a/xicc/xdgb.c
+++ b/xicc/xdgb.c
@@ -33,8 +33,8 @@
#include "numlib.h"
#include "icc.h"
#include "rspl.h"
-#include "xicc.h"
#include "plot.h"
+#include "xicc.h"
#include "xdgb.h"
#include "sort.h"
diff --git a/xicc/xfit.c b/xicc/xfit.c
index b5a8694..a4cfee6 100755
--- a/xicc/xfit.c
+++ b/xicc/xfit.c
@@ -74,8 +74,8 @@
#include "numlib.h"
#include "icc.h"
#include "rspl.h"
-#include "xicc.h"
#include "plot.h"
+#include "xicc.h"
#include "xfit.h"
#include "sort.h"
diff --git a/xicc/xicc.c b/xicc/xicc.c
index eef469d..e0be01a 100755
--- a/xicc/xicc.c
+++ b/xicc/xicc.c
@@ -37,6 +37,7 @@
#if defined(__IBMC__) && defined(_M_IX86)
#include <float.h>
#endif
+#include "aconfig.h"
#include "numlib.h"
#include "counters.h"
#include "plot.h"
diff --git a/xicc/xicclu.c b/xicc/xicclu.c
index 6bbb62a..e95e188 100755
--- a/xicc/xicclu.c
+++ b/xicc/xicclu.c
@@ -34,8 +34,8 @@
#include "copyright.h"
#include "aconfig.h"
#include "numlib.h"
-#include "xicc.h"
#include "plot.h"
+#include "xicc.h"
#include "ui.h"
#undef SPTEST /* [und] Test (flawed) rspl gamut surface code */
diff --git a/xicc/xlutfix.c b/xicc/xlutfix.c
index a0c0e4e..5492280 100755
--- a/xicc/xlutfix.c
+++ b/xicc/xlutfix.c
@@ -132,8 +132,9 @@
*/
-#include "icc.h"
+#include "aconfig.h"
#include "numlib.h"
+#include "icc.h"
#include "xicc.h"
/* NOTE:- that we only implement support for CMYK output here !!! */
diff --git a/xicc/xspect.c b/xicc/xspect.c
index b77f322..fff4d46 100755
--- a/xicc/xspect.c
+++ b/xicc/xspect.c
@@ -30,14 +30,16 @@
#include <time.h>
#include <string.h>
#include <math.h>
+# include "aconfig.h"
#ifndef SALONEINSTLIB
# include "numlib.h"
-# include "cgats.h"
-# include "plot.h" /* For debugging */
+# include "plot.h" /* For debugging */
+# include "ui.h"
#else
# include "numsup.h"
# include "sa_conv.h"
#endif
+#include "cgats.h"
#include "conv.h"
#include "xspect.h"
@@ -614,7 +616,6 @@ static xspect il_F8 = {
};
-
/* CIE F10 */
/* Fluorescent, Narrow band 5000K, CRI 81 */
static xspect il_F10 = {
@@ -749,6 +750,61 @@ double temp /* Optional temperature in degrees kelvin, for Dtemp and Ptemp *
return 1;
}
+/* Return a string describing the standard illuminant */
+/* (Returns static buffer for temp based) */
+char *standardIlluminant_name(
+icxIllumeType ilType, /* Type of illuminant */
+double temp /* Optional temperature in degrees kelvin, For Dtemp and Ptemp */
+) {
+ static char buf[50];
+ switch (ilType) {
+ case icxIT_none:
+ return "None";
+ case icxIT_custom:
+ return "Custom";
+ case icxIT_A:
+ return "A";
+ case icxIT_C:
+ return 0;
+ case icxIT_default:
+ case icxIT_D50:
+ return 0;
+ case icxIT_D50M2:
+ return 0;
+ case icxIT_D55:
+ return "D55";
+ case icxIT_D65:
+ return "D65";
+ case icxIT_D75:
+ return "D75";
+ case icxIT_E:
+ return "E";
+#ifndef SALONEINSTLIB
+ case icxIT_F5:
+ return "F5";
+ case icxIT_F8:
+ return "F8";
+ case icxIT_F10:
+ return "F10";
+ case icxIT_Spectrocam:
+ return "Spectrocam";
+#endif
+ case icxIT_ODtemp:
+ sprintf(buf, "OD%d",(int)(temp+0.5));
+ return buf;
+ case icxIT_Dtemp:
+ sprintf(buf, "D%d",(int)(temp+0.5));
+ return buf;
+ case icxIT_OPtemp:
+ sprintf(buf, "OP%d",(int)(temp+0.5));
+ return buf;
+ case icxIT_Ptemp:
+ sprintf(buf, "P%d",(int)(temp+0.5));
+ return buf;
+ }
+ return "Unknown";
+}
+
/* ------------- */
/* Observer Data */
@@ -3514,6 +3570,8 @@ static xspect FWA1_emit = {
#endif /* STOCKFWA */
+#endif /* !SALONEINSTLIB */
+
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Return a string describing the inst_meas_type */
char *meas_type2str(inst_meas_type mt) {
@@ -3901,7 +3959,6 @@ int read_cmf(xspect sp[3], char *fname) {
}
/* ------------- */
-#endif /* !SALONEINSTLIB */
/* Get a raw 3rd order polinomial interpolated spectrum value. */
@@ -4353,15 +4410,15 @@ void xspect_plot(xspect *sp1, xspect *sp2, xspect *sp3) {
xspect_plot_w(sp1, sp2, sp3, 1);
}
-/* Plot up to 10 spectra in an array */
-void xspect_plot10(xspect *sp, int n) {
+/* Plot up to 12 spectra in an array, and wait for key */
+void xspect_plotN(xspect *sp, int n) {
double xx[XSPECT_MAX_BANDS];
- double *yp[10];
- double yy[10][XSPECT_MAX_BANDS];
+ double *yp[MXGPHS];
+ double yy[MXGPHS][XSPECT_MAX_BANDS];
double wl, wlshort, wllong;
int i, j;
- for (i = 0; i < 10; i++)
+ for (i = 0; i < MXGPHS; i++)
yp[i] = NULL;
if (sp == NULL)
@@ -4370,7 +4427,7 @@ void xspect_plot10(xspect *sp, int n) {
wlshort = sp->spec_wl_short;
wllong = sp->spec_wl_long;
- for (i = 0; i < n; i++) {
+ for (i = 0; i < n && i < MXGPHS; i++) {
if (sp[i].spec_wl_short < wlshort)
wlshort = sp[i].spec_wl_short;
if (sp[i].spec_wl_long > wllong)
@@ -4386,24 +4443,23 @@ void xspect_plot10(xspect *sp, int n) {
gcc_bug_fix(j);
#endif
xx[j] = wl;
- for (i = 0; i < n; i++) {
+ for (i = 0; i < n && i < MXGPHS; i++) {
yp[i] = yy[i];
yy[i][j] = value_xspect(&sp[i], wl);
}
}
- do_plot10(xx, yp[0], yp[1], yp[2], yp[3], yp[4],
- yp[5], yp[6], yp[7], yp[8], yp[9], j, 0);
+ do_plotNpwz(xx, yp, j, NULL, NULL, 0, 1, 0);
}
-/* Plot up to 10 spectra pointed to by an array */
-void xspect_plot10p_w(xspect *sp[10], int n, int wait) {
+/* Plot up to 12 spectra pointed to by an array, with optional wait */
+void xspect_plotNp_w(xspect *sp[MXGPHS], int n, int wait) {
double xx[XSPECT_MAX_BANDS];
- double *yp[10];
- double yy[10][XSPECT_MAX_BANDS];
+ double *yp[MXGPHS];
+ double yy[MXGPHS][XSPECT_MAX_BANDS];
double wl, wlshort, wllong;
int i, j;
- for (i = 0; i < 10; i++)
+ for (i = 0; i < MXGPHS; i++)
yp[i] = NULL;
if (sp == NULL)
@@ -4412,7 +4468,7 @@ void xspect_plot10p_w(xspect *sp[10], int n, int wait) {
wlshort = 1e6;
wllong = -1e6;
- for (i = 0; i < n; i++) {
+ for (i = 0; i < n && i < MXGPHS; i++) {
if (sp[i] == NULL)
continue;
if (sp[i]->spec_wl_short < wlshort)
@@ -4433,20 +4489,19 @@ void xspect_plot10p_w(xspect *sp[10], int n, int wait) {
gcc_bug_fix(j);
#endif
xx[j] = wl;
- for (i = 0; i < n; i++) {
+ for (i = 0; i < n && i < MXGPHS; i++) {
if (sp[i] == NULL)
continue;
yp[i] = yy[i];
yy[i][j] = value_xspect(sp[i], wl);
}
}
- do_plot10pw(xx, yp[0], yp[1], yp[2], yp[3], yp[4],
- yp[5], yp[6], yp[7], yp[8], yp[9], j, NULL, NULL, 0, wait);
+ do_plotNpwz(xx, yp, j, NULL, NULL, 0, wait, 0);
}
/* Plot up to 10 spectra pointed to by an array * wait for a key */
-void xspect_plot10p(xspect *sp[10], int n) {
- xspect_plot10p_w(sp, n, 1);
+void xspect_plotNp(xspect *sp[MXGPHS], int n) {
+ xspect_plotNp_w(sp, n, 1);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
@@ -5084,7 +5139,7 @@ double *FWAc) {
/* rather than integrated if they are not at 1nm spacing. */
static void xsp2cie_fwa_sconvert(
xsp2cie *p, /* this */
-xspect *sout, /* Return corrected input spectrum (may be NULL, or same as imput) */
+xspect *sout, /* Return corrected input spectrum (may be NULL, or same as input) */
double *out, /* Return XYZ or D50 Lab value (may be NULL) */
xspect *in /* Spectrum to be converted */
) {
@@ -5605,13 +5660,13 @@ xspect *in /* Colorant reflectance to be applied */
/* rather than integrated if they are not at 1nm spacing. */
static void xsp2cie_photo2rad(
xsp2cie *p, /* this */
-double *routp, /* Return total lumens */
-double *poutp, /* Return total mW */
+double *loutp, /* Return total lumens (photometric) */
+double *mwoutp, /* Return total mW (radiometric) */
xspect *sout, /* Return input spectrum converted to lm/nm */
xspect *in /* Spectrum to be converted */
) {
- double rscale = 0.0;
- double rout, pout;
+ double lscale = 0.0;
+ double lout, mwout;
double ww;
/* Compute the Y value (normalised to 1.0) */
@@ -5623,40 +5678,41 @@ xspect *in /* Spectrum to be converted */
/* ANSI CGATS.5-1993 spec. If illumninant or material spectra */
/* values are truncated at the extremes, then the last valid values */
/* are used, also consistent with CIE and ANSI CGATS recommendations. */
- rout = 0.0;
- pout = 0.0;
+ /* Also intergate the radiometric total. */
+ lout = 0.0;
+ mwout = 0.0;
for (ww = p->spec_wl_short; ww <= p->spec_wl_long; ww += p->spec_bw) {
double I = 1.0, O, S;
if (!p->isemis)
getval_xspec(&p->illuminant, &I, ww);
getval_xspec(&p->observer[1], &O, ww);
getval_xspec(in, &S, ww);
- rscale += I * O; /* Integrate Y illuminant * observer values */
- rout += I * O * S;
- pout += S;
+ lscale += I * O; /* Integrate Y illuminant * observer values */
+ lout += I * O * S;
+ mwout += S;
}
if (p->isemis) {
- // Hmm. Should we really make rscale += O for this case and then
- // rscale = 0.683002/rscale ??
- rscale = 0.683002; /* Convert from mW/m^2 to Lumens/m^2 */
+ // Hmm. Should we really make lscale += O for this case and then
+ // lscale = 0.683002/lscale ??
+ lscale = 0.683002; /* Convert from mW/m^2 to Lumens/m^2 */
/* (== 683 Luments/Watt/m^2) */
} else {
- rscale *= p->spec_bw; /* Scale for integration interval */
- rscale = 1.0/rscale;
+ lscale *= p->spec_bw; /* Scale for integration interval */
+ lscale = 1.0/lscale;
}
/* Scale for illuminant/observer normalisation of Y */
- rout *= rscale;
+ lout *= lscale;
#ifdef CLAMP_XYZ
- if (p->clamp && rout < 0.0)
- rout = 0.0; /* Just to be sure we don't get silly values */
+ if (p->clamp && lout < 0.0)
+ lout = 0.0; /* Just to be sure we don't get silly values */
#endif /* CLAMP_XYZ */
- if (routp != NULL)
- *routp = rout;
+ if (loutp != NULL)
+ *loutp = lout;
- pout *= p->spec_bw; /* Scale for integration interval */
- if (poutp != NULL)
- *poutp = pout;
+ mwout *= p->spec_bw; /* Scale for integration interval */
+ if (mwoutp != NULL)
+ *mwoutp = mwout;
/* Compute phometric output spectrum. For reflective/transmissive, this is */
/* the illuminant times the reflectivity/transmissitivity times Y weighting, */
@@ -5675,7 +5731,7 @@ xspect *in /* Spectrum to be converted */
getval_xspec(&p->illuminant, &I, ww);
getval_xspec(&p->observer[1], &O, ww);
getval_xspec(in, &S, ww);
- sout->spec[i] = rscale * I * O * S;
+ sout->spec[i] = lscale * I * O * S;
}
}
}
@@ -5787,6 +5843,7 @@ xsp2cie *p
/* Create and return a new spectral conversion object */
xsp2cie *new_xsp2cie(
icxIllumeType ilType, /* Illuminant */
+double temp, /* Optional temperature in degrees kelvin, if ilType = Dtemp etc. */
xspect *custIllum, /* Custom illuminant if ilType == icxIT_custom */
icxObserverType obType, /* Observer */
xspect custObserver[3], /* Custom observer if obType == icxOT_custom */
@@ -5801,119 +5858,38 @@ icxClamping clamp /* NZ to clamp XYZ/Lab to be +ve */
return NULL;
p->isemis = 0;
- switch (ilType) {
- case icxIT_none:
- p->illuminant = il_none; /* Emissive */
- p->isemis = 1;
- break;
- case icxIT_custom:
- p->illuminant = *custIllum; /* Struct copy */
- break;
- case icxIT_A:
- p->illuminant = il_A;
- break;
- case icxIT_C:
- p->illuminant = il_C;
- break;
- case icxIT_default:
- case icxIT_D50:
- p->illuminant = il_D50;
- break;
- case icxIT_D50M2:
- if (il_D50M2.spec_n == 0)
- uv_filter(&il_D50M2, &il_D50);
- p->illuminant = il_D50M2;
- break;
- case icxIT_D55:
- daylight_il(&p->illuminant, 5500.0);
- break;
- case icxIT_D65:
- p->illuminant = il_D65;
- break;
- case icxIT_D75:
- daylight_il(&p->illuminant, 7500.0);
- case icxIT_E:
- p->illuminant = il_none;
- break;
-#ifndef SALONEINSTLIB
- case icxIT_F5:
- p->illuminant = il_F5;
- break;
- case icxIT_F8:
- p->illuminant = il_F8;
- break;
- case icxIT_F10:
- p->illuminant = il_F10;
- break;
- case icxIT_Spectrocam:
- p->illuminant = il_Spectrocam;
- break;
-#endif /* !SALONEINSTLIB */
- default:
+
+ if (ilType == icxIT_custom) {
+ p->illuminant = *custIllum;
+
+ } else if (ilType == icxIT_none) {
+ p->isemis = 1;
+ p->illuminant = il_none; /* Not used */
+
+ } else {
+ if (standardIlluminant(&p->illuminant, ilType, temp) != 0) {
DBGF((DBGA,"new_xsp2cie() unrecognised illuminant 0x%x\n",ilType));
free(p);
return NULL;
+ }
}
- /* Do 3 structure copies to record observer sensitivity curves */
- switch (obType) {
- case icxOT_custom:
- p->observer[0] = custObserver[0];
- p->observer[1] = custObserver[1];
- p->observer[2] = custObserver[2];
- break;
- case icxOT_default:
- case icxOT_CIE_1931_2:
- p->observer[0] = ob_CIE_1931_2[0];
- p->observer[1] = ob_CIE_1931_2[1];
- p->observer[2] = ob_CIE_1931_2[2];
- break;
- case icxOT_CIE_1964_10:
- p->observer[0] = ob_CIE_1964_10[0];
- p->observer[1] = ob_CIE_1964_10[1];
- p->observer[2] = ob_CIE_1964_10[2];
- break;
- case icxOT_CIE_2012_2:
- p->observer[0] = ob_CIE_2012_2[0];
- p->observer[1] = ob_CIE_2012_2[1];
- p->observer[2] = ob_CIE_2012_2[2];
- break;
- case icxOT_CIE_2012_10:
- p->observer[0] = ob_CIE_2012_10[0];
- p->observer[1] = ob_CIE_2012_10[1];
- p->observer[2] = ob_CIE_2012_10[2];
- break;
-#ifndef SALONEINSTLIB
- case icxOT_Stiles_Burch_2:
- p->observer[0] = ob_Stiles_Burch_2[0];
- p->observer[1] = ob_Stiles_Burch_2[1];
- p->observer[2] = ob_Stiles_Burch_2[2];
- break;
- case icxOT_Judd_Voss_2:
- p->observer[0] = ob_Judd_Voss_2[0];
- p->observer[1] = ob_Judd_Voss_2[1];
- p->observer[2] = ob_Judd_Voss_2[2];
- break;
- case icxOT_CIE_1964_10c:
- p->observer[0] = ob_CIE_1964_10c[0];
- p->observer[1] = ob_CIE_1964_10c[1];
- p->observer[2] = ob_CIE_1964_10c[2];
- break;
- case icxOT_Shaw_Fairchild_2:
- p->observer[0] = ob_Shaw_Fairchild_2[0];
- p->observer[1] = ob_Shaw_Fairchild_2[1];
- p->observer[2] = ob_Shaw_Fairchild_2[2];
- break;
- case icxOT_EBU_2012:
- p->observer[0] = ob_EBU_2012[0];
- p->observer[1] = ob_EBU_2012[1];
- p->observer[2] = ob_EBU_2012[2];
- break;
-#endif /* !SALONEINSTLIB */
- default:
+ /* Get copies of the 3 observer curves */
+ if (obType == icxOT_custom) {
+ p->observer[0] = custObserver[0];
+ p->observer[1] = custObserver[1];
+ p->observer[2] = custObserver[2];
+ } else {
+ xspect *sp3[3];
+
+ if (standardObserver(sp3, obType)) {
DBGF((DBGA,"new_xsp2cie() unrecognised observer type 0x%x\n",obType));
free(p);
return NULL;
+ }
+ p->observer[0] = *sp3[0];
+ p->observer[1] = *sp3[1];
+ p->observer[2] = *sp3[2];
}
if (rcs == icSigXYZData)
@@ -8166,15 +8142,9 @@ double ct, /* Input temperature in degrees K */
xspect *custIllum, /* Optional custom illuminant */
xspect *sp /* Spectrum to be converted */
) {
- xspect ill; /* Xspect to fill in */
xsp2cie *conv; /* Means of converting spectrum to XYZ */
- if (ilType == icxIT_custom)
- ill = *custIllum;
- else if (standardIlluminant(&ill, ilType, ct) != 0)
- return 1;
-
- if ((conv = new_xsp2cie(icxIT_custom, &ill, obType, custObserver, icSigXYZData, 1)) == NULL)
+ if ((conv = new_xsp2cie(ilType, ct, custIllum, obType, custObserver, icSigXYZData, 1)) == NULL)
return 1;
conv->convert(conv, xyz, sp);
@@ -8208,7 +8178,7 @@ int abs /* If nz return absolute value in cd/m^2 or Lux */
else if (standardIlluminant(&sp, ilType, ct) != 0)
return 1;
- if ((conv = new_xsp2cie(icxIT_none, NULL, obType, custObserver, icSigXYZData, 1)) == NULL)
+ if ((conv = new_xsp2cie(icxIT_none, 0.0, NULL, obType, custObserver, icSigXYZData, 1)) == NULL)
return 1;
conv->convert(conv, xyz, &sp);
@@ -8381,7 +8351,7 @@ int viscct /* nz to use visual CIEDE2000, 0 to use CCT CIE 1960 UCS. */
return -1.0;
x.ilType = ilType;
- if ((x.conv = new_xsp2cie(icxIT_none, NULL, obType, custObserver, icSigXYZData, 1)) == NULL)
+ if ((x.conv = new_xsp2cie(icxIT_none, 0.0, NULL, obType, custObserver, icSigXYZData, 1)) == NULL)
return -1;
if (xyz == NULL) {
@@ -8496,7 +8466,7 @@ xspect *sample /* Illuminant sample to compute CRI of */
//DBGF((DBGA,"icx_CIE1995_CRI called\n"));
- if ((tocie = new_xsp2cie(icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, 1)) == NULL)
+ if ((tocie = new_xsp2cie(icxIT_none, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, 1)) == NULL)
return -1.0;
/* Compute the XYZ of the sample */
@@ -8561,7 +8531,7 @@ if (dc > 0.0054) DBGF((DBGA,"CRI is invalid\n"));
}
/* Check out the delta E for each reflective sample */
- if ((tocie = new_xsp2cie(icxIT_custom, &wts, icxOT_CIE_1931_2, NULL, icSigXYZData, 1)) == NULL) {
+ if ((tocie = new_xsp2cie(icxIT_custom, 0.0, &wts, icxOT_CIE_1931_2, NULL, icSigXYZData, 1)) == NULL) {
sample->norm = sampnorm; /* Restore this */
return -1.0;
}
@@ -8575,7 +8545,7 @@ if (dc > 0.0054) DBGF((DBGA,"CRI is invalid\n"));
}
tocie->del(tocie);
- if ((tocie = new_xsp2cie(icxIT_custom, sample, icxOT_CIE_1931_2, NULL, icSigXYZData, 1)) == NULL) {
+ if ((tocie = new_xsp2cie(icxIT_custom, 0.0, sample, icxOT_CIE_1931_2, NULL, icSigXYZData, 1)) == NULL) {
sample->norm = sampnorm; /* Restore this */
return -1.0;
}
@@ -8720,7 +8690,7 @@ xspect *sample /* Illuminant sample to compute TLCI of */
//DBGF((DBGA,"icx_EBU2012_TLCI called\n"));
/* Create spectral to XYZ for UCS space delta */
- if ((tocie = new_xsp2cie(icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, 1)) == NULL) {
+ if ((tocie = new_xsp2cie(icxIT_none, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, 1)) == NULL) {
//DBGF((DBGA,"Ref new_xsp2cie failed\n"));
return -1.0;
}
@@ -8822,12 +8792,12 @@ if (dc > 0.0054) DBGF((DBGA,"TLCI is invalid\n"));
/* Note that xsp2cie will normalise the values such that the "Y" value */
/* (actually G here) to be 1.0 for the perfect diffusor for the given illuminant, */
/* but that the white balancing scaling would do this anyway. */
- if ((reftoRGB = new_xsp2cie(icxIT_custom, &wts, icxOT_EBU_2012, NULL, icSigXYZData, 1)) == NULL) {
+ if ((reftoRGB = new_xsp2cie(icxIT_custom, 0.0, &wts, icxOT_EBU_2012, NULL, icSigXYZData, 1)) == NULL) {
//DBGF((DBGA,"new_xsp2cie for ref failed\n"));
sample->norm = sampnorm; /* Restore this */
return -1.0;
}
- if ((satoRGB = new_xsp2cie(icxIT_custom, sample, icxOT_EBU_2012, NULL, icSigXYZData, 1)) == NULL) {
+ if ((satoRGB = new_xsp2cie(icxIT_custom, 0.0, sample, icxOT_EBU_2012, NULL, icSigXYZData, 1)) == NULL) {
//DBGF((DBGA,"new_xsp2cie for samp failed\n"));
sample->norm = sampnorm; /* Restore this */
reftoRGB->del(reftoRGB);
diff --git a/xicc/xspect.h b/xicc/xspect.h
index b42a961..76b8b89 100755
--- a/xicc/xspect.h
+++ b/xicc/xspect.h
@@ -178,14 +178,14 @@ void xspect_plot_w(xspect *sp1, xspect *sp2, xspect *sp3, int wait);
/* Plot up to 3 spectra & wait for key */
void xspect_plot(xspect *sp1, xspect *sp2, xspect *sp3);
-/* Plot up to 10 spectra in an array */
-void xspect_plot10(xspect *sp, int n);
+/* Plot up to 12 spectra in an array */
+void xspect_plotN(xspect *sp, int n);
-/* Plot up to 10 spectra pointed to by an array & wait for key */
-void xspect_plot10p(xspect *sp[10], int n);
+/* Plot up to 12 spectra pointed to by an array & wait for key */
+void xspect_plotNp(xspect *sp[MXGPHS], int n);
-/* Plot up to 10 spectra pointed to by an array */
-void xspect_plot10p_w(xspect *sp[10], int n, int wait);
+/* Plot up to 12 spectra pointed to by an array */
+void xspect_plotNp_w(xspect *sp[MXGPHS], int n, int wait);
#endif /* !SALONEINSTLIB*/
@@ -226,6 +226,12 @@ xspect *sp, /* Xspect to fill in */
icxIllumeType ilType, /* Type of illuminant */
double temp); /* Optional temperature in degrees kelvin, For Dtemp and Ptemp */
+/* Return a string describing the standard illuminant */
+/* (Returns static buffer for temp based) */
+char *standardIlluminant_name(
+icxIllumeType ilType, /* Type of illuminant */
+double temp); /* Optional temperature in degrees kelvin, For Dtemp and Ptemp */
+
/* Given an emission spectrum, set the UV output to the given level. */
/* The shape of the UV is taken from FWA1_stim, and the level is */
/* with respect to the average of the input spectrum. */
@@ -326,7 +332,7 @@ struct _xsp2cie {
/* Convert and also return (possibly corrected) reflectance spectrum */
/* Spectrum will be same wlength range and readings as input spectrum */
- /* Note that the returned XYZ is 0..1 range for reflectanc. */
+ /* Note that the returned XYZ is 0..1 range for reflectance. */
/* Emissive spectral values are assumed to be in mW/nm, and sampled */
/* rather than integrated if they are not at 1nm spacing. */
void (*sconvert) (struct _xsp2cie *p, /* this */
@@ -397,6 +403,7 @@ struct _xsp2cie {
xsp2cie *new_xsp2cie(
icxIllumeType ilType, /* Observer Illuminant to use */
+ double temp, /* Optional temp. in degrees kelvin, if ilType = Dtemp etc */
xspect *custIllum, /* Custom illuminant if ilType == icxIT_custom */
icxObserverType obType, /* Observer */
@@ -491,9 +498,6 @@ xspect *custIllum, /* Optional custom illuminant */
xspect *sp /* Spectrum to be converted */
);
-/* ------------------------------------------------- */
-/* Color temperature and CRI */
-
/* Given an illuminant definition and an observer model, return */
/* the normalised XYZ value for that spectrum. */
/* Return 0 on sucess, 1 on error */
@@ -509,6 +513,9 @@ int abs /* If nz return absolute value in cd/m^2 or Lux */
/* else return Y = 1 normalised value */
);
+/* ------------------------------------------------- */
+/* Color temperature and CRI */
+
/* Given a choice of temperature dependent illuminant (icxIT_[O]Dtemp or icxIT_[O]Ptemp), */
/* return the closest correlated color temperature to the given spectrum or XYZ. */
/* An observer type can be chosen for interpretting the spectrum of the input and */