From c6739b6427261ac2682a9fca3b23c98df0dc9f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Fri, 6 Nov 2015 07:40:42 +0100 Subject: New upstream release --- Jamtop | 3 +- Readme.txt | 4 +- ccast/axTLS/tls1.c | 2 + ccast/ccmdns.c | 3 +- ccast/ccpacket.c | 2 +- ccast/dpat.c | 2 +- ccast/filt.c | 1 + debian/changelog | 6 + debian/patches/series | 2 +- doc/ArgyllDoc.html | 2506 ++++++++++-------- doc/ChangesSummary.html | 46 + doc/File_Formats.html | 2 +- doc/Installing_OSX.html | 590 ++--- doc/Scenarios.html | 5779 +++++++++++++++++++++--------------------- doc/SpyderChecker24.jpg | Bin 0 -> 7270 bytes doc/afiles | 1 + doc/chartread.html | 51 +- doc/collink.html | 208 +- doc/colprof.html | 107 +- doc/dispcal.html | 2836 ++++++++++----------- doc/dispread.html | 1304 +++++----- doc/dispwin.html | 914 +++---- doc/fakeread.html | 2 +- doc/iccgamut.html | 4 +- doc/illumread.html | 554 ++-- doc/instruments.html | 3548 +++++++++++++------------- doc/targen.html | 10 +- doc/tiffgamut.html | 26 +- doc/viewgam.html | 2 +- doc/xicclu.html | 2 +- gamut/gammap.c | 667 ++--- gamut/gamut.c | 682 ++--- gamut/gamut.h | 25 +- gamut/maptest.c | 3 +- gamut/nearsmth.c | 1803 ++++++++----- gamut/nearsmth.h | 48 +- gamut/smthtest.c | 35 +- h/aconfig.h | 27 +- icc/icc.c | 53 +- icc/icc.h | 3 + link/collink.c | 223 +- link/monoplot.c | 30 +- log.txt | 53 + makepackagebin.sh | 5 +- namedc/namedc.c | 4 +- numlib/Jamfile | 4 + numlib/numsup.c | 310 ++- numlib/numsup.h | 19 + numlib/ui.c | 21 +- plot/plot.c | 7 +- plot/vrml.c | 2 +- profile/colprof.c | 2 +- profile/colverify.c | 2 +- profile/profcheck.c | 2 +- profile/profout.c | 16 +- ref/ColorCheckerPassport.cht | 102 +- ref/SpyderChecker24.cht | 59 + ref/SpyderChecker24.cie | 38 + ref/afiles | 2 + ref/linear.cal | 2 +- ref/strange.cal | 2 +- rspl/gam.c | 46 + scanin/Jamfile | 3 +- scanin/SpyderChecker24.cht | 59 + scanin/SpyderChecker24.cie | 38 + scanin/afiles | 2 + spectro/aglob.c | 1 + spectro/ccxxmake.c | 5 +- spectro/chartread.c | 19 +- spectro/colorhug.c | 1 + spectro/conv.c | 9 + spectro/dispwin.c | 7 +- spectro/dtp20.c | 5 +- spectro/dtp22.c | 3 +- spectro/dtp41.c | 5 +- spectro/dtp51.c | 3 +- spectro/dtp92.c | 3 +- spectro/ex1.c | 11 +- spectro/hcfr.c | 1 + spectro/huey.c | 5 +- spectro/i1d3.c | 58 +- spectro/i1d3.h | 1 + spectro/i1disp.c | 3 +- spectro/i1pro.c | 3 +- spectro/i1pro_imp.c | 123 +- spectro/i1pro_imp.h | 8 +- spectro/inst.c | 18 + spectro/inst.h | 4 + spectro/instappsup.c | 2 +- spectro/kleink10.c | 114 +- spectro/linear.cal | 272 ++ spectro/munki.c | 3 +- spectro/rspec.c | 4 +- spectro/rspec.h | 6 +- spectro/smcube.c | 13 +- spectro/spec2cie.c | 2 +- spectro/specbos.c | 1 + spectro/spyd2.c | 30 +- spectro/spyd2.h | 1 + spectro/ss.c | 3 +- spectro/strange.cal | 272 ++ spectro/usbio.c | 4 +- spectro/usbio_nt.c | 2 +- target/ifarp.c | 4 +- target/ifarp.h | 5 +- target/printtarg.c | 14 +- target/targen.c | 2 +- usb/ArgyllCMS.cat | Bin 3551 -> 3551 bytes usb/ArgyllCMS.inf | 458 ++-- usb/ArgyllCMS.inf.d | 78 +- usb/ArgyllCMS.inf.t | 224 +- usb/ArgyllCMS_x64.cat | Bin 3535 -> 3535 bytes xicc/bt1886.c | 2 +- xicc/cam02.c | 28 +- xicc/iccgamut.c | 2 +- xicc/tiffgamut.c | 2 +- xicc/tiffgmts.c | 4 +- xicc/xicc.c | 90 +- xicc/xicc.h | 3 + xicc/xicclu.c | 2 +- yajl/afiles | 2 - 121 files changed, 13861 insertions(+), 11000 deletions(-) create mode 100644 doc/SpyderChecker24.jpg create mode 100644 ref/SpyderChecker24.cht create mode 100644 ref/SpyderChecker24.cie create mode 100644 scanin/SpyderChecker24.cht create mode 100644 scanin/SpyderChecker24.cie create mode 100644 spectro/linear.cal create mode 100644 spectro/strange.cal diff --git a/Jamtop b/Jamtop index 141abd2..6864931 100644 --- a/Jamtop +++ b/Jamtop @@ -60,7 +60,7 @@ if $(USE_LIBUSB) = true { } # For testing CCast -DEFINES += CCTEST_PATTERN ; +#DEFINES += CCTEST_PATTERN ; # Information for compiling and linking GUI programs @@ -170,6 +170,7 @@ rule CheckForLibrary { # See if we have a system TIFF, JPEG, PNG or ZLIB library. # Note this generates: $(TIFFLIB) $(TIFFINC) $(JPEGLIB) $(JPEGINC) $(PNGLIB) # $(PNGINC) $(ZLIBLIB) $(ZINC) +# !!!!! Add to makepackagebin.sh -sBUILTIN_XXX=true !!!!! CheckForLibrary "TIFF" ; CheckForLibrary "JPEG" ; CheckForLibrary "PNG" ; diff --git a/Readme.txt b/Readme.txt index 3bb253a..1550f1b 100644 --- a/Readme.txt +++ b/Readme.txt @@ -2,7 +2,7 @@ Argyll CMS README file - Version 1.8.2 -------------------------------------- -Date: 7th September 2015 +Date: 26th October 2015 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 1.8.2, a bug fix update to V1.8.1. +This is Version 1.8.3, a bug fix update to V1.8.2. 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/ccast/axTLS/tls1.c b/ccast/axTLS/tls1.c index b635263..d8ce892 100644 --- a/ccast/axTLS/tls1.c +++ b/ccast/axTLS/tls1.c @@ -309,6 +309,8 @@ EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data) return ret; } +int basic_readi(SSL *ssl, uint8_t **in_data); + /* * Internal read the SSL connection used for setup */ diff --git a/ccast/ccmdns.c b/ccast/ccmdns.c index 0ba3318..76ae4d1 100644 --- a/ccast/ccmdns.c +++ b/ccast/ccmdns.c @@ -75,6 +75,7 @@ #else #include "numsup.h" #endif +#include "conv.h" #include "ccmdns.h" #undef DEBUG @@ -223,7 +224,7 @@ static int init_send_mDNS(SOCKET *psock) { // If we're doing a one-shot, we shouldn't transmit from port 5353, */ // but ChromCast won't see the packet if we don't. */ - /* We cant send from port 5353 if someone else is using it, */ + /* We can't send from port 5353 if someone else is using it, */ /* so set the SO_REUSEADDR option (which is enough for MSWin), */ /* and SO_REUSEPORT for OS X and Linux */ { diff --git a/ccast/ccpacket.c b/ccast/ccpacket.c index 97e28d7..2efc11f 100644 --- a/ccast/ccpacket.c +++ b/ccast/ccpacket.c @@ -231,7 +231,7 @@ static ccpacket_err connect_ccpacket_imp( } /* Connect */ - if (rv = (connect(p->sock, (struct sockaddr *)&server, sizeof(server))) != 0) { + if ((rv = (connect(p->sock, (struct sockaddr *)&server, sizeof(server)))) != 0) { DBG((g_log,0, "TCP connect IP '%s' port %d failed with %d, errno %d\n",p->dip, p->dport,rv,ERRNO)) return ccpacket_connect; } diff --git a/ccast/dpat.c b/ccast/dpat.c index 106c52a..a8792fe 100644 --- a/ccast/dpat.c +++ b/ccast/dpat.c @@ -440,7 +440,7 @@ double get_ccast_dith(double ipat[DISIZE][DISIZE][3], double val[3]) { if (vv) { printf("There are %d unique surrounders:\n",nsur); for (n = 0; n < nsur; n++) { - printf("sur %f %f %f\n",ressur[n][0], ressur[n][1], ressur[n][2], ressur[n][3]); + printf("sur %f %f %f\n",ressur[n][0], ressur[n][1], ressur[n][2]); } } #endif diff --git a/ccast/filt.c b/ccast/filt.c index ab075ae..65cf7bd 100644 --- a/ccast/filt.c +++ b/ccast/filt.c @@ -33,6 +33,7 @@ #include "ccpacket.h" #include "ccmes.h" #include "yajl.h" +#include "ccast.h" #define DO_WEIGHTING #define SUM_CONSTRAINT diff --git a/debian/changelog b/debian/changelog index b8f6ba4..c8bf772 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +argyll (1.8.3+repack-1) UNRELEASED; urgency=medium + + * + + -- Jörg Frings-Fürst Fri, 06 Nov 2015 07:19:48 +0100 + argyll (1.8.2+repack-1) unstable; urgency=medium * New upstream release. diff --git a/debian/patches/series b/debian/patches/series index 8f5d038..4856c86 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,5 +1,5 @@ 110_dispwin_segfault.patch -100_spelling.patch +#100_spelling.patch 15_jam.patch 20_hurd_PATH_MAX.patch #120_usb-db_new.patch diff --git a/doc/ArgyllDoc.html b/doc/ArgyllDoc.html index 6dda431..a2b2ed5 100644 --- a/doc/ArgyllDoc.html +++ b/doc/ArgyllDoc.html @@ -1,63 +1,63 @@ - - - - - - - - Argyll Documentation Top - - -

Argyll CMS documentation index (V1.8.2)
-

- Date:   7th September 2015
- Author: Graeme Gill -

Introduction

- ArgyllCMS is an ICC compatible color management system, available as - Open Source. It supports accurate ICC profile creation for scanners, - cameras and film recorders, and calibration and profiling of - displays and RGB & CMYK printers. Device Link can be created - with a wide variety of advanced options, including specialized Video - calibration standards  and 3dLuts. Spectral sample data is - supported, allowing a selection of illuminants observer types, and - paper fluorescent whitener additive compensation. Profiles can also - incorporate source specific gamut mappings for perceptual and - saturation intents. Gamut mapping and profile linking uses the - CIECAM02 appearance model, a unique gamut mapping algorithm, and a - wide selection of rendering intents. It also includes code for the - fastest portable 8 bit raster color conversion engine available - anywhere, as well as support for fast, fully accurate 16 bit - conversion. Device color gamuts can also be viewed and compared with - a modern Web browser using X3DOM . Comprehensive documentation is - 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 1.8.2, a bug fix update to V1.8.1. 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 between revisions is - detailed in the log.txt file that accompanies the source - code.

-

The latest source code is available from here.
-

-

Please - note that instruments are being driven by ArgyllCMS drivers, - and that any problems or queries regarding instrument
- operation
should - first be directed to the Argyll's author(s) or the Argyll - mailing list, and not to any other party.

-

-

An Introduction to Color - Management

-

A great introduction for non technical people is Steve Upton's The - Color of Toast.
-

+ + + + + + + + Argyll Documentation Top + + +

Argyll CMS documentation index (V1.8.3)
+

+ Date:   26th October 2015
+ Author: Graeme Gill +

Introduction

+ ArgyllCMS is an ICC compatible color management system, available as + Open Source. It supports accurate ICC profile creation for scanners, + cameras and film recorders, and calibration and profiling of + displays and RGB & CMYK printers. Device Link can be created + with a wide variety of advanced options, including specialized Video + calibration standards  and 3dLuts. Spectral sample data is + supported, allowing a selection of illuminants observer types, and + paper fluorescent whitener additive compensation. Profiles can also + incorporate source specific gamut mappings for perceptual and + saturation intents. Gamut mapping and profile linking uses the + CIECAM02 appearance model, a unique gamut mapping algorithm, and a + wide selection of rendering intents. It also includes code for the + fastest portable 8 bit raster color conversion engine available + anywhere, as well as support for fast, fully accurate 16 bit + conversion. Device color gamuts can also be viewed and compared with + a modern Web browser using X3DOM . Comprehensive documentation is + 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 1.8.3, a bug fix update to V1.8.2. 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 between revisions is + detailed in the log.txt file that accompanies the source + code.

+

The latest source code is available from here.
+

+

Please + note that instruments are being driven by ArgyllCMS drivers, + and that any problems or queries regarding instrument
+ operation
should + first be directed to the Argyll's author(s) or the Argyll + mailing list, and not to any other party.

+

+

An Introduction to Color + Management

+

A great introduction for non technical people is Steve Upton's The + Color of Toast.
+

I present here a more technical but concise @@ -106,52 +106,54 @@ - - discussion of what color management is, and why we need it, - together with a brief overview of the ICC profile format.
-
-

Operating Environments

-

-

Argyll is known to compile and run in at least the following - environments:

- 1) MSWindows XP system using Microsoft VC++ 6.0 compiler
- 2) MSWindows XP system using Microsoft VC++ 8.0 Express compiler + - Platform SDK Feb. 2003
- 3) MSWindows XP system using Microsoft VC++ 9.0 Express compiler + - Platform SDK Feb. 2003
- 4) MSWindows XP system using Microsoft VC++ 10.0 Express compiler + - Platform SDK Feb. 2003
- 5) MSWindows XP system using Microsoft VC++ 11.0 Express compiler
- 6) MSWindows XP system using the MingW port of the GCC compiler
- 7) Linux on Fedora Core 8, 32 bit using gcc
- 8) Linux on Fedora Core 8, 64 bit using gcc
- 9) Apple OS X 10.3 PPC using GCC
- 10) Apple OS X 10.4, 10.5, 10.6 Intel using GCC
- 11) Apple OS X10.7 Intel using  Clang
-
- Additionally it is also known to run on:
-
-  MSWindows 2000, Vista & Windows 7 32 bit.
-  MSWindows Vista 64bit, Windows 7, 8, 8.1 64 bit.
-  Linux Ubuntu 7.10
-  Linux Kubuntu 7.10
-  Linux Mandriva 2008.0
-  Linux OpenSuSE 10.3
-  Linux Whitebox 4.2/2
-

but may well compile and run correctly in many more than this, - including OS X 10.8, 10.8 and 10.10.

- This is a command line terminal - only environment. Those unfamiliar with command line environments - should consult an appropriate tutorial for their environment if they - are interested in using this software. See the listing of tutorials below.
-
- The following color measuring instruments are directly supported:
-
- JETI:
-
-     specbos 1211 + + + + discussion of what color management is, and why we need it, + together with a brief overview of the ICC profile format.
+
+

Operating Environments

+

+

Argyll is known to compile and run in at least the following + environments:

+ 1) MSWindows XP system using Microsoft VC++ 6.0 compiler
+ 2) MSWindows XP system using Microsoft VC++ 8.0 Express compiler + + Platform SDK Feb. 2003
+ 3) MSWindows XP system using Microsoft VC++ 9.0 Express compiler + + Platform SDK Feb. 2003
+ 4) MSWindows XP system using Microsoft VC++ 10.0 Express compiler + + Platform SDK Feb. 2003
+ 5) MSWindows XP system using Microsoft VC++ 11.0 Express compiler
+ 6) MSWindows XP system using the MingW port of the GCC compiler
+ 7) Linux on Fedora Core 8, 32 bit using gcc
+ 8) Linux on Fedora Core 8, 64 bit using gcc
+ 9) Apple OS X 10.3 PPC using GCC
+ 10) Apple OS X 10.4, 10.5, 10.6 Intel using GCC
+ 11) Apple OS X10.7 Intel using  Clang
+
+ Additionally it is also known to run on:
+
+  MSWindows 2000, Vista & Windows 7 32 bit.
+  MSWindows Vista 64bit, Windows 7, 8, 8.1 64 bit.
+  Linux Ubuntu 7.10
+  Linux Kubuntu 7.10
+  Linux Mandriva 2008.0
+  Linux OpenSuSE 10.3
+  Linux Whitebox 4.2/2
+

but may well compile and run correctly in many more than this, + including OS X 10.8, 10.9 and 10.10 & MSWin 10.

+ This is a command line terminal + only environment. Those unfamiliar with command line environments + should consult an appropriate tutorial for their environment if they + are interested in using this software. See the listing of tutorials below.
+
+ The following color measuring instruments are directly supported:
+
+ JETI:
+
+     specbos 1211 & 1201                    @@ -205,11 +207,13 @@ - - - Tele-Spectro-Radiometer
-
- Image Engineering:
-
+ + + + - Tele-Spectro-Radiometer
+
+ Image Engineering:
+
    EX1                                               @@ -263,11 +267,13 @@ - - - Tele-Spectro-Radiometer
-
- Klein:
-
+ + + + - Tele-Spectro-Radiometer
+
+ Klein:
+
    K10-A   @@ -298,14 +304,16 @@ - -             -             -             -     - Display Colorimeter. Reported also to work with - the K-1, K-8 and  K-10.
-
- X-Rite:
+ + + +             +             +             +     - Display Colorimeter. Reported also to work with + the K-1, K-8 and  K-10.
+
+ X-Rite:
    DTP20 "Pulse"                              @@ -401,9 +409,11 @@ - - - "swipe" type reflective spectrometer, that can be used untethered.
-     DTP22 Digital + + + + - "swipe" type reflective spectrometer, that can be used untethered.
+    
DTP22 Digital Swatchbook            @@ -498,8 +508,10 @@ - - - spot type reflective spectrometer.
+ + + + - spot type reflective spectrometer.
    DTP41                                         @@ -594,10 +606,12 @@ - - - spot and strip reading reflective spectrometer.
-     DTP41T -                  + + + + - spot and strip reading reflective spectrometer.
+     DTP41T +                                       @@ -692,8 +706,10 @@ - - - spot and strip reading reflective/transmissive spectrometer.
+ + + + - spot and strip reading reflective/transmissive spectrometer.
    DTP51                                         @@ -788,8 +804,10 @@ - - - strip reading reflective colorimeter.
+ + + + - strip reading reflective colorimeter.
    DTP92                                         @@ -884,69 +902,71 @@ - - - CRT display colorimeter.
-     DTP94 "Optix XR" or "Optix XR2" or "Optix Pro"- display - colorimeter.
-     ColorMunki Design - or Photo           - - spot and "swipe" reflective/emissive spectrometer (UV cut only).
-     ColorMunki Create - or Smile   -          - display - colorimeter. (Similar to an Eye-One Display 2)
-     Lenovo W -                   -                   - - built in laptop Huey display colorimeter.
-     Eye-One Display - 3                 -         - Xrite i1 DisplayPro and ColorMunki - Display
-             -             -             -             -           [ The OEM - i1Display Pro, NEC SpectraSensor Pro,
-                   -                   -                   -        Quato Silver Haze 3 OEM and HP - DreamColor  i1d3 are also reported to work.]
-     Eye-One Pro2 -                   -              - spot and - "swipe" reflective/emissive spectrometer.
-
- Gretag-Macbeth (now X-Rite):
-     Spectrolino   -                   -               - spot - reflective/emissive spectrometer.
-     SpectroScan   -                   -             - spot - reflective/emissive, XY table reflective spectrometer  .
-     SpectroScanT   -                   -           - spot - reflective/emissive/transmissive, XY table reflective spectrometer.
-     Eye-One Pro "EFI - ES-1000"           - spot and "swipe" - reflective/emissive spectrometer.
-     Eye-One Monitor -                   -         - spot and "swipe" emissive - spectrometer.
-     Eye-One Display 1 - or 2  or LT        - - display colorimeter.
-     HP DreamColor or - APS  + + + + - CRT display colorimeter.
+     DTP94 "Optix XR" or "Optix XR2" or "Optix Pro"- display + colorimeter.
+     ColorMunki Design + or Photo           - + spot and "swipe" reflective/emissive spectrometer (UV cut only).
+     ColorMunki Create + or Smile   +          - display + colorimeter. (Similar to an Eye-One Display 2)
+     Lenovo W +                   +                   - + built in laptop Huey display colorimeter.
+     Eye-One Display + 3                 +         - Xrite i1 DisplayPro and ColorMunki + Display
+             +             +             +             +           [ The OEM + i1Display Pro, NEC SpectraSensor Pro,
+                   +                   +                   +        Quato Silver Haze 3 OEM and HP + DreamColor  i1d3 are also reported to work.]
+     Eye-One Pro2 +                   +              - spot and + "swipe" reflective/emissive spectrometer.
+
+ Gretag-Macbeth (now X-Rite):
+     Spectrolino   +                   +               - spot + reflective/emissive spectrometer.
+     SpectroScan   +                   +             - spot + reflective/emissive, XY table reflective spectrometer  .
+     SpectroScanT   +                   +           - spot + reflective/emissive/transmissive, XY table reflective spectrometer.
+     Eye-One Pro "EFI + ES-1000"           - spot and "swipe" + reflective/emissive spectrometer.
+     Eye-One Monitor +                   +         - spot and "swipe" emissive + spectrometer.
+     Eye-One Display 1 + or 2  or LT        - + display colorimeter.
+     HP DreamColor or + APS                  @@ -1041,9 +1061,11 @@ - - - display colorimeter. (Treated as a Eye-One Display 2)
-     CalMAN X2 + + + + - display colorimeter. (Treated as a Eye-One Display 2)
+     CalMAN X2                                  @@ -1138,18 +1160,20 @@ - - - display colorimeter. (Treated as a Eye-One Display 2)
-     Huey   -                   -                 -        - display colorimeter.
-
- Sequel imaging (Now X-Rite):
-      MonacoOPTIX -                   -           - display - colorimeter (Treated as an Eye-One Display 1)
+ + + + - display colorimeter. (Treated as a Eye-One Display 2)
+     Huey   +                   +                 +        - display colorimeter.
+
+ Sequel imaging (Now X-Rite):
+      MonacoOPTIX +                   +           - display + colorimeter (Treated as an Eye-One Display 1)
                                                           @@ -1244,10 +1268,12 @@ - - [The Sequel Chroma 4 may also work.]
-
- Lacie Blue + + + + [The Sequel Chroma 4 may also work.]
+
+ Lacie Blue Eye:                                  @@ -1342,15 +1368,17 @@ - - - see Eye-One Display
-
- DataColor ColorVision:
-      Spyder 2 -                    -            -        - display colorimeter (Note - that the user must supply firmware)
+ + + + - see Eye-One Display
+
+ DataColor ColorVision:
+      Spyder 2 +                    +            +        - display colorimeter (Note + that the user must supply firmware)
                                                          @@ -1445,28 +1473,30 @@ - - [The Spyder 1 has also been reported as working, but this has not - been confirmed.]
-      Spyder 3 -                    -            -        - display colorimeter.
-      Spyder 4 -                    -            -        - display colorimeter (Note - that the user must supply calibration - data)
-      Spyder 5 -                    -            -        - display colorimeter (Note - that the user must supply calibration - data)
-
- Other:
-     +      Spyder 3 +                    +            +        - display colorimeter.
+      Spyder 4 +                    +            +        - display colorimeter (Note + that the user must supply calibration + data)
+      Spyder 5 +                    +            +        - display colorimeter (Note + that the user must supply calibration + data)
+
+ Other:
+     Colorimètre HCFR                         @@ -1561,8 +1591,10 @@ - - - display colorimeter
+ + + + - display colorimeter

    ColorHug                                        @@ -1642,53 +1674,57 @@ - - - display colorimeter
+ + + + - display colorimeter
    Palette/SwatchMate - - Cube         - - reflective colorimeter
-
- See
Operation of particular - instruments for more instrument specific detail.
-
- Other instruments can be supported indirectly, since patch result - files created by other packages can be imported into Argyll.
-
- Please note the installation instructions - for each platform - they contain important information for getting - your instruments working.
-

If you've decided to buy a color instrument because Argyll - supports it, please let the dealer and manufacturer know that "You bought it because Argyll CMS - supports it" - thanks.
-

-

Please note that instruments are - being driven by ArgyllCMS drivers, and that any problems or - queries regarding instrument
- operation
should be - directed to the Argyll's author(s) or the Argyll mailing list, - and not to any other - party.

-

There is a list of contributed ccmx (Colorimeter Correction - Matrix) files for some display/colorimeter combinations.

-

Copyright and Licensing:
-

-

Most of the source code and provided executable files are - copyrighted works, licensed under the Affero GNU Version 3 license, and therefore they - (or works derived from them) can't be copied, sold or made - available to users interacting with them remotely through a - computer network, without providing the source code. Nothing other - than your agreement and compliance with the Affero GNU License - grants you permission to use, modify or distribute ArgyllCMS - source code, executables or its derivative works. You could be - sued for copyright infringement if you use or distribute ArgyllCMS + + + + Cube         - + reflective colorimeter
+
+ See
Operation of particular + instruments for more instrument specific detail.
+
+ Other instruments can be supported indirectly, since patch result + files created by other packages can be imported into Argyll.
+
+ Please note the installation instructions + for each platform - they contain important information for getting + your instruments working.
+

If you've decided to buy a color instrument because Argyll + supports it, please let the dealer and manufacturer know that "You bought it because Argyll CMS + supports it" - thanks.
+

+

Please note that instruments are + being driven by ArgyllCMS drivers, and that any problems or + queries regarding instrument
+ operation
should be + directed to the Argyll's author(s) or the Argyll mailing list, + and not to any other + party.

+

There is a list of contributed ccmx (Colorimeter Correction + Matrix) files for some display/colorimeter combinations.

+

Copyright, Licensing & Trade Mark:
+

+

Most of the source code and provided executable files are + copyrighted works, licensed under the Affero GNU Version 3 license, and therefore they + (or works derived from them) can't be copied, sold or made + available to users interacting with them remotely through a + computer network, without providing the source code. Nothing other + than your agreement and compliance with the Affero GNU License + grants you permission to use, modify or distribute ArgyllCMS + source code, executables or its derivative works. You could be + sued for copyright infringement if you use or distribute ArgyllCMS without a valid license. The Affero @@ -1710,62 +1746,64 @@ - - GNU license prohibits - extending these tools - (i.e. by combining them with other programs or scripts that make - use of, depend on, or work with the ArgyllCMS code) and - distributing them, unless all the elements of the extensions are - also made available under a GPL compatible license. It is - permissible to provide ArgyllCMS tools with other non GPL - components if the elements of the package are not related, such - that the packaging is mere aggregation. For all the gory details, - please read the accompanying license.

- Note that unlike many commercial ICC profiling tools, the profiles - created using ArgyllCMS, are not subject to any claims or - restrictions of ArgyllCMS's author(s), but are assumed to be the - copyright property of the person who gathers the characterization - data, and causes the profiles to be created. -

The ArgyllCMS is Copyright 1995 - 2015 Graeme W. Gill, and is - made available under the terms of the Affero GNU General Public - License Version 3, as detailed in the License.txt - file. Documentation is licensed under the terms of the GNU Free - Documentation License, Version 1.3. The author asserts his moral - rights over this material in relationship to the attribution and - integrity of these works. In particular, if these works are - modified in a way that materially changes their functionality, - then the modified works should be renamed in a way that clearly - distinguishes them from "Argyll" or "ArgyllCMS" so that the - effects of such changes do not reflect on the original works - integrity or the original authors reputation. A subset of files - (those that are related to the color instrument drivers, and are - collected together into the instlib.zip archive by the - spectro/instlib.ksh script + xicc/ccmx.h and xicc/ccmx.c) are - licensed under the General Public License Version 2 or later, as - detailed in the License2.txt file.
-

-

Portions of the ColorHug instrument library - (spectro/colorhug.[ch]) are Copyright 2011, Richard Hughes, and is - licensed under the General Public License Version 2 or later, as - detailed in the License2.txt file.

-

The tool spectro/spec2cie.c is Copyright 2005 Gerhard Fuernkranz, - and is made available under the terms of the GNU General Public - License Version 2 or later, and is licensed here under the Version - 3 license, as detailed in the License3.txt - file.
-

-

The Win32 USB library libusb-win32 kernel drivers are included in - this distribution in the usb/driver and usb/bin directories, and - are copyright Stephan Meyer and Travis Robinson, and are licensed - under the GNU Version 2 or later (the drivers, services, - installer). See  usb/driver/License.txt, - libusbw/COPYING_LGPL.txt and libusbw/COPYING_GPL.txt for details. - Additional terms noted on the website - are "This license combination explicitly allows the use of this - library in commercial, non-Open-Source applications."
-

-

The icc library in icc/, + + + + GNU license prohibits + extending these tools + (i.e. by combining them with other programs or scripts that make + use of, depend on, or work with the ArgyllCMS code) and + distributing them, unless all the elements of the extensions are + also made available under a GPL compatible license. It is + permissible to provide ArgyllCMS tools with other non GPL + components if the elements of the package are not related, such + that the packaging is mere aggregation. For all the gory details, + please read the accompanying license.

+ Note that unlike many commercial ICC profiling tools, the profiles + created using ArgyllCMS, are not subject to any claims or + restrictions of ArgyllCMS's author(s), but are assumed to be the + copyright property of the person who gathers the characterization + data, and causes the profiles to be created. +

The ArgyllCMS is Copyright 1995 - 2015 Graeme W. Gill, and is + made available under the terms of the Affero GNU General Public + License Version 3, as detailed in the License.txt + file. Documentation is licensed under the terms of the GNU Free + Documentation License, Version 1.3. The author asserts his moral + rights over this material in relationship to the attribution and + integrity of these works. In particular, if these works are + modified in a way that materially changes their functionality, + then the modified works should be renamed in a way that clearly + distinguishes them from "Argyll" or "ArgyllCMS" so that the + effects of such changes do not reflect on the original works + integrity or the original authors reputation. A subset of files + (those that are related to the color instrument drivers, and are + collected together into the instlib.zip archive by the + spectro/instlib.ksh script + xicc/ccmx.h and xicc/ccmx.c) are + licensed under the General Public License Version 2 or later, as + detailed in the License2.txt file.
+

+

Portions of the ColorHug instrument library + (spectro/colorhug.[ch]) are Copyright 2011, Richard Hughes, and is + licensed under the General Public License Version 2 or later, as + detailed in the License2.txt file.

+

The tool spectro/spec2cie.c is Copyright 2005 Gerhard Fuernkranz, + and is made available under the terms of the GNU General Public + License Version 2 or later, and is licensed here under the Version + 3 license, as detailed in the License3.txt + file.
+

+

The Win32 USB library libusb-win32 kernel drivers are included in + this distribution in the usb/driver and usb/bin directories, and + are copyright Stephan Meyer and Travis Robinson, and are licensed + under the GNU Version 2 or later (the drivers, services, + installer). See  usb/driver/License.txt, + libusbw/COPYING_LGPL.txt and libusbw/COPYING_GPL.txt for details. + Additional terms noted on the website + are "This license combination explicitly allows the use of this + library in commercial, non-Open-Source applications."
+

+

The icc library in icc/, the CGATS library in cgats/, @@ -1860,7 +1898,9 @@ - + + + the jcnf library in jcnf/, @@ -1954,84 +1994,94 @@ - - the files spectro/xdg_bds.*, - spectro/aglob.* and the - ucmm library in ucmm/ are - Copyright 1995 - 2015 Graeme W. Gill, and available according to - the "MIT" license granted in the icc/License.txt and - cgats/License.txt files, and the licenses at the top of - ucmm/ucmm.c and jcnf/jcnf.c.
-

-

The yajl library in jcnf/yajl - is Copyright (c) 2007-2014, Lloyd Hilaiel <me@lloyd.io> and - is used under an ISC License granted in the yajl/COPYING files. - The yajl library has been repackaged and modified slightly to adds - some features and for packaging and build convenience.
-

-

The TIFF library included in this distribution for convenience, - has its own copyright and license detailed in tiff/COPYRIGHT (an - "MIT"/"BSD" like license).
-

-

The Independent JPEG Group's JPEG library included in this - distribution for convenience, has its own copyright and license - detailed in jpg/README (an "MIT"/"BSD" like license). Executables - that include JPEG format support are based in part on the work of - the Independent JPEG Group.

-

xicc/iccjpeg.h and xicc/iccjpeg.c are from lcms and they are Copyright - (c) 1998-2010 Marti Maria Saguer and is licensed under an - "MIT"/"BSD" like license. See the top of the iccjpeg.c file for - the detailed copyright and licensing conditions.
-

-

The mongoose web server software is Copyright (c) 2004-2011 - Sergey Lyubka, and is licensed under an "MIT" license.
-

-

The axTLS library is Copyright (c) 2008, Cameron Rich, and the - license is detailed in ccast/axTLS/LICENSE file (an "MIT"/"BSD" - like license).
- It is not used for any security sensitive purpose, but is used - purely to communicate with the ChromeCast.
-

-

The X3DOM x3dom.css and - x3dom.js files are Copyright (C) 2009 X3DOM and licensed dual - "MIT" and "GPL" license. See plot/X3DOM_LICENSE.txt.
-

-

What sort of project is this ? (re: - contributions)
-

- This is essentially my private project, that I've made available - under GNU licensing conditions. Because I license my code under - other licenses as well, there is a limit to what I will accept in - the way of code contributions back into this project. For me to - accept contributions into the distribution, it either has to a - non-core (side) project, or has to be offered to me with copyright - conditions that are compatible with my other uses (i.e.. a "BSD" - like license, or assigning or licensing the copyright to me), or has - to be so trivial (say a one line bug fix), that it can't be the - subject of copyright.
-
- Of course there is nothing to stop someone setting up a real free - software, community project based on the GNU licensed code made - available here, that would be able to take GNU licensed - contributions from everyone and would essentially be a "fork" of - this code base.
-
-

Compiling

- How to build the software from the - source if you want to.
- Note that you don't need to - do this if you are using one of the binary installations.
-

Installing

- Important notes on installing the binary - software on various platforms.
-
-

Graphic - User Interfaces
-

- ArgyllCMS does not directly support a graphic user interface, but - several people have written GUI + + + + the files spectro/xdg_bds.*, + spectro/aglob.* and the + ucmm library in ucmm/ are + Copyright 1995 - 2015 Graeme W. Gill, and available according to + the "MIT" license granted in the icc/License.txt and + cgats/License.txt files, and the licenses at the top of + ucmm/ucmm.c and jcnf/jcnf.c.
+

+

The yajl library in jcnf/yajl + is Copyright (c) 2007-2014, Lloyd Hilaiel <me@lloyd.io> and + is used under an ISC License granted in the yajl/COPYING files. + The yajl library has been repackaged and modified slightly to adds + some features and for packaging and build convenience.
+

+

The TIFF library included in this distribution for convenience, + has its own copyright and license detailed in tiff/COPYRIGHT (an + "MIT"/"BSD" like license).
+

+

The Independent JPEG Group's JPEG library included in this + distribution for convenience, has its own copyright and license + detailed in jpg/README (an "MIT"/"BSD" like license). Executables + that include JPEG format support are based in part on the work of + the Independent JPEG Group.

+

xicc/iccjpeg.h and xicc/iccjpeg.c are from lcms and they are Copyright + (c) 1998-2010 Marti Maria Saguer and is licensed under an + "MIT"/"BSD" like license. See the top of the iccjpeg.c file for + the detailed copyright and licensing conditions.
+

+

The mongoose web server software is Copyright (c) 2004-2011 + Sergey Lyubka, and is licensed under an "MIT" license.
+

+

The axTLS library is Copyright (c) 2008, Cameron Rich, and the + license is detailed in ccast/axTLS/LICENSE file (an "MIT"/"BSD" + like license).
+ It is not used for any security sensitive purpose, but is used + purely to communicate with the ChromeCast.
+

+

The X3DOM x3dom.css and + x3dom.js files are Copyright (C) 2009 X3DOM and licensed dual + "MIT" and "GPL" license. See plot/X3DOM_LICENSE.txt.
+

+

"ArgyllCMS" is a trade mark. It is permissible to refer to + copies or derivatives of this software as being the same as + ArgyllCMS if they are materially  unchanged, and retain all + the functionality provided by the software made available at + www.argyllcms.com. Modified versions of this software that are + materially changed or have missing functionality must be clearly + marked as such, so as not to to be confused with ArgyllCMS.
+

+

What sort of project is this ? (re: + contributions)
+

+ This is essentially my private project, that I've made available + under GNU licensing conditions. Because I license my code under + other licenses as well, there is a limit to what I will accept in + the way of code contributions back into this project. For me to + accept contributions into the distribution, it either has to a + non-core (side) project, or has to be offered to me with copyright + conditions that are compatible with my other uses (i.e.. a "BSD" + like license, or assigning or licensing the copyright to me), or has + to be so trivial (say a one line bug fix), that it can't be the + subject of copyright.
+
+ Of course there is nothing to stop someone setting up a real free + software, community project based on the GNU licensed code made + available here, that would be able to take GNU licensed + contributions from everyone and would essentially be a "fork" of + this code base.
+
+

Compiling

+ How to build the software from the + source if you want to.
+ Note that you don't need to + do this if you are using one of the binary installations.
+

Installing

+ Important notes on installing the binary + software on various platforms.
+
+

Graphic + User Interfaces
+

+ ArgyllCMS does not directly support a graphic user interface, but + several people have written GUI based front ends for it. A popular front end that @@ -2131,18 +2181,20 @@ calibration - - and profiling is dispcalGUI - by Florian Höch. Others can be found with a suitable search.
-

Main - Tools and the command line
-

- These are all command line ("DOS" shell) tools, and each tool - require appropriate options to be set, followed by filename - arguments. Sometimes the filenames will have to include the usual - extensions, sometimes they are implicit. To get a brief listing of - the possible arguments and usage + + + + and profiling is dispcalGUI + by Florian Höch. Others can be found with a suitable search.
+

Main + Tools and the command line
+

+ These are all command line ("DOS" shell) tools, and each tool + require appropriate options to be set, followed by filename + arguments. Sometimes the filenames will have to include the usual + extensions, sometimes they are implicit. To get a brief listing of + the possible arguments and usage of any of the tools, run it with just an "-?" argument, i.e. targen @@ -2235,23 +2287,25 @@ href="http://www.google.com/search?hl=en&source=hp&q=argyllcms+GUI&a - - -? (or some other unrecognized flag, if the "?" character is - treated specially in your shell, i.e. try "--" on OS X zsh).
-
- Note that in general the arguments consist of possible flags or - options followed by file name arguments. All arguments need to be - separated by whitespace.  (If you need to specify a string with - embedded white space, double quote the string). A flag consists of a - dash attached to a single letter, the letter identifying the flag, - and is usually case sensitive. An option is a flag that has an - associated parameter or parameters. The parameter can be separated - from the flag by white space, or may come directly after the flag. - So if a tool has a usage that looks like this:
-
-   tool -?
-   usage: tool [options] infile outfile
-    + + + + -? (or some other unrecognized flag, if the "?" character is + treated specially in your shell, i.e. try "--" on OS X zsh).
+
+ Note that in general the arguments consist of possible flags or + options followed by file name arguments. All arguments need to be + separated by whitespace.  (If you need to specify a string with + embedded white space, double quote the string). A flag consists of a + dash attached to a single letter, the letter identifying the flag, + and is usually case sensitive. An option is a flag that has an + associated parameter or parameters. The parameter can be separated + from the flag by white space, or may come directly after the flag. + So if a tool has a usage that looks like this:
+
+   tool -?
+   usage: tool [options] infile outfile
+    -v                   @@ -2346,9 +2400,11 @@ href="http://www.google.com/search?hl=en&source=hp&q=argyllcms+GUI&a - - Verbose mode
-    -d + + + + Verbose mode
+    -d n                @@ -2443,9 +2499,11 @@ href="http://www.google.com/search?hl=en&source=hp&q=argyllcms+GUI&a - - Choose a depth 0-4
-    -r + + + + Choose a depth 0-4
+    -r                   @@ -2540,12 +2598,14 @@ href="http://www.google.com/search?hl=en&source=hp&q=argyllcms+GUI&a - - Use a random depth
-    -f - [nn]            - Use full range. nn optional range 0 - 100.
-    -M + + + + Use a random depth
+    -f + [nn]            + Use full range. nn optional range 0 - 100.
+    -M                  @@ -2640,9 +2700,11 @@ href="http://www.google.com/search?hl=en&source=hp&q=argyllcms+GUI&a - - Manual
-    infile + + + + Manual
+    infile                @@ -2737,160 +2799,162 @@ href="http://www.google.com/search?hl=en&source=hp&q=argyllcms+GUI&a - - Input file
-    outfile -             - Output file
-
- then there are  5 flags/options, and two filename arguments. - Notice that square braces [] denote optional items. The first - flag/option is a flag. The second is an option that has a numerical - argument in the range 0 to 4. The third is a flag. the fourth is an - option with an optional argument. The fourth is a flag.  The - flags and options can generally be in any order, but must be before - the file name arguments. (For a few special tools you actually - specify a sequence of flags and files where the flags apply just to - the following file.) So example invocations may look like:
-
-   tool -v testin testout
-   tool -d3 -M testin1 testout2
-   tool -f infile outfile
-   tool -f 45 infile outfile
-   tool -d 3 -f67 infile outfile
-

In order to make use of the tools, it is necessary to keep track - of where various files are, and what they are called. There are - many possible ways of doing this. One way is to put each source - profile and all its associated files (test charts, spectrometer - values etc.) in one set of directories for each source profile - type. Similarly the device profiles could be stored in a hierarchy - of directories ordered by device type, media, resolution, device - mode etc. Naturally you will want to set your $PATH so that you - can run the tools from whichever directory you are in, as well as - specify any necessary directory paths for file arguments so that - the tools are able to open them.
-

-

Note that there are two ways the Argyll tools deal with filename - extensions. In one you supply the extension (ie. you supply the - whole file name), so the extension is up to you. In the other - (used where one name is used for input and output files, or where - there are multiple output files), the program adds the extension. - In the documentation this should be indicated by calling it a - "base name".
-

-

For more information on using a command - line environments, consult an appropriate tutorial:

-

MS Windows :
-    <http://www.bleepingcomputer.com/tutorials/tutorial76.html>
-    <http://www.pcstats.com/articleview.cfm?articleid=1723&page=1>
-    <http://www.voidspace.org.uk/python/articles/command_line.shtml>
-
-     To find more: <http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial>
-
- OS X:
-     <http://www.osxfaq.com/Tutorials/LearningCenter/>
-     <http://www.atomiclearning.com/macosxterminalx.shtml>
-     <http://www.oreillynet.com/pub/a/mac/2001/12/14/terminal_one.html>
-
-     To find more: <http://www.google.com/search?hl=en&q=OS+X+shell+tutorial>
-
- Linux:
-     <http://www.linuxcommand.org/index.php>
-     <http://www.tuxfiles.org/linuxhelp/shell.html>
-     <http://www.ee.surrey.ac.uk/Teaching/Unix/>
-
-     To find more: <http://www.google.com/search?q=linux+command+line+shell+tutorial>

-


- Note that since OS X is - based on UNIX, there is much in common between the OS X and Linux - command line environments, and many of the UNIX tutorials may be - useful:
-

-

    <http://www.rain.org/~mkummel/unix.html>
-
-

-

Tutorial: Typical usage scenarios - and examples

- A guided tour of the major tools, - applied to typical CMS jobs, such as calibrating displays, creating - device profiles, calibrating printers, linking profiles, and - converting color spaces of raster files.
-
- Although it is is a couple of years old now, this tutorial - may also be of interest.
-  
-

Topical - Discussions

- Discussions about particular topics:
-
- About Fluorescent Whitening Agent compensation
-
- Operation of particular instruments
-
- About ICC profiles and Gamut Mapping
-
- About display monitor settings and - targets
-
- About display "Gamma"
-
- What's the difference between Calibration - and Characterization ?
-
- Why doesn't my Colorimeter work - well on my Wide Gamut display ?
-
- My blacks get crushed on my - display - why ? How do I fix it ?
-
- How can I have confidence in the i1pro - Driver ?
-
- Does the i1pro High Resolution mode - improve accuracy ?
-
- Evaluating input targets
-
- ArgyllCMS's Absolute to media - Relative Transform Space matrix ('arts') ICC tag
-
-

Flow - diagram of Major Tools:

-
-           Thumbnail of Flow Diagram
-
-

Main Tools by - category:

-

Calibrating devices
-

- dispcal -       Adjust, - calibrate and profile a display.
-
printcal      Create a - printer calibration .cal file from a .ti3 data file.
-

Creating test targets for profiling or print calibration
-

- targen +    outfile +             + Output file
+
+ then there are  5 flags/options, and two filename arguments. + Notice that square braces [] denote optional items. The first + flag/option is a flag. The second is an option that has a numerical + argument in the range 0 to 4. The third is a flag. the fourth is an + option with an optional argument. The fourth is a flag.  The + flags and options can generally be in any order, but must be before + the file name arguments. (For a few special tools you actually + specify a sequence of flags and files where the flags apply just to + the following file.) So example invocations may look like:
+
+   tool -v testin testout
+   tool -d3 -M testin1 testout2
+   tool -f infile outfile
+   tool -f 45 infile outfile
+   tool -d 3 -f67 infile outfile
+

In order to make use of the tools, it is necessary to keep track + of where various files are, and what they are called. There are + many possible ways of doing this. One way is to put each source + profile and all its associated files (test charts, spectrometer + values etc.) in one set of directories for each source profile + type. Similarly the device profiles could be stored in a hierarchy + of directories ordered by device type, media, resolution, device + mode etc. Naturally you will want to set your $PATH so that you + can run the tools from whichever directory you are in, as well as + specify any necessary directory paths for file arguments so that + the tools are able to open them.
+

+

Note that there are two ways the Argyll tools deal with filename + extensions. In one you supply the extension (ie. you supply the + whole file name), so the extension is up to you. In the other + (used where one name is used for input and output files, or where + there are multiple output files), the program adds the extension. + In the documentation this should be indicated by calling it a + "base name".
+

+

For more information on using a command + line environments, consult an appropriate tutorial:

+

MS Windows :
+    <http://www.bleepingcomputer.com/tutorials/tutorial76.html>
+    <http://www.pcstats.com/articleview.cfm?articleid=1723&page=1>
+    <http://www.voidspace.org.uk/python/articles/command_line.shtml>
+
+     To find more: <http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial>
+
+ OS X:
+     <http://www.osxfaq.com/Tutorials/LearningCenter/>
+     <http://www.atomiclearning.com/macosxterminalx.shtml>
+     <http://www.oreillynet.com/pub/a/mac/2001/12/14/terminal_one.html>
+
+     To find more: <http://www.google.com/search?hl=en&q=OS+X+shell+tutorial>
+
+ Linux:
+     <http://www.linuxcommand.org/index.php>
+     <http://www.tuxfiles.org/linuxhelp/shell.html>
+     <http://www.ee.surrey.ac.uk/Teaching/Unix/>
+
+     To find more: <http://www.google.com/search?q=linux+command+line+shell+tutorial>

+


+ Note that since OS X is + based on UNIX, there is much in common between the OS X and Linux + command line environments, and many of the UNIX tutorials may be + useful:
+

+

    <http://www.rain.org/~mkummel/unix.html>
+
+

+

Tutorial: Typical usage scenarios + and examples

+ A guided tour of the major tools, + applied to typical CMS jobs, such as calibrating displays, creating + device profiles, calibrating printers, linking profiles, and + converting color spaces of raster files.
+
+ Although it is is a couple of years old now, this tutorial + may also be of interest.
+  
+

Topical + Discussions

+ Discussions about particular topics:
+
+ About Fluorescent Whitening Agent compensation
+
+ Operation of particular instruments
+
+ About ICC profiles and Gamut Mapping
+
+ About display monitor settings and + targets
+
+ About display "Gamma"
+
+ What's the difference between Calibration + and Characterization ?
+
+ Why doesn't my Colorimeter work + well on my Wide Gamut display ?
+
+ My blacks get crushed on my + display - why ? How do I fix it ?
+
+ How can I have confidence in the i1pro + Driver ?
+
+ Does the i1pro High Resolution mode + improve accuracy ?
+
+ Evaluating input targets
+
+ ArgyllCMS's Absolute to media + Relative Transform Space matrix ('arts') ICC tag
+
+

Flow + diagram of Major Tools:

+
+           Thumbnail of Flow Diagram
+
+

Main Tools by + category:

+

Calibrating devices
+

+ dispcal +       Adjust, + calibrate and profile a display.
+
printcal      Create a + printer calibration .cal file from a .ti3 data file.
+

Creating test targets for profiling or print calibration
+

+ targen        @@ -2985,10 +3049,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Generate a profiling test target values .ti1 file.
- filmtargGenerate a profiling test target values .ti1 file.
+ filmtarg      Create @@ -3083,10 +3149,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - film recorder TIFF files from Argyll .ti1 file.
- printtarg
+ printtarg     Create @@ -3181,12 +3249,14 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - a PS, EPS or TIFF file containing test patch values, ready for - printing.
-

Obtaining test results for profiling or print calibration
-

- chartread +

Obtaining test results for profiling or print calibration
+

+ chartread     Read @@ -3281,11 +3351,13 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - a test chart using an instrument to create a .ti3 data file.
- dispread
+ dispread      Test @@ -3380,10 +3452,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - and read colorimetric values from a display
- filmread
+ filmread      Read @@ -3478,10 +3552,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - film colorimetric values using a SpectroScanT (Deprecated ?)
- scanin
+ scanin        @@ -3576,15 +3652,17 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Convert a TIFF  image of a test chart into .ti3 - device values.
-
illumread     Use an - instrument to measure an illuminant spectrum, and estimate its UV - content.
- fakereadConvert a TIFF  image of a test chart into .ti3 + device values.
+
illumread     Use an + instrument to measure an illuminant spectrum, and estimate its UV + content.
+ fakeread      Fake @@ -3679,14 +3757,16 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - the reading of a device using an ICC or MPP profile.
-
synthread     Fake the - reading of a device using a synthetic device model.
- cb2ti3 + synthread     Fake the + reading of a device using a synthetic device model.
+ cb2ti3        @@ -3781,11 +3861,13 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Convert Colorblind format CMY/RGB test chart into - Argyll .ti3 CGATS format.
- kodak2ti3Convert Colorblind format CMY/RGB test chart into + Argyll .ti3 CGATS format.
+ kodak2ti3     Convert @@ -3880,10 +3962,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Kodak Colorflow format CMYK test chart into Argyll .ti3 CGATS - format.
- txt2ti3
+ txt2ti3       @@ -3978,12 +4062,14 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Convert Gretag/Logo/X-Rite/Barbieri or other format - RGB or CMYK test chart results into Argyll .ti3 CGATS format.

- ls2ti3 + ls2ti3        Convert @@ -4015,10 +4101,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - LightSpace format RGB .bcs test chart results into Argyll - .ti3 CGATS format.
- fakeCMY

+ fakeCMY       @@ -4113,11 +4201,13 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Create a fake Argyll .ti3 CMY data file from a CMYK - profile, as a basis of creating a CMY to CMYK separation
-
averageaverage       Average @@ -4141,11 +4231,13 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - or Merge two or more measurement data files, or average patches - within a single file.
-

Creating Device Profiles

- colprof
+

Creating Device Profiles

+ colprof       @@ -4240,9 +4332,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Create an ICC profile from the .ti3 test data.
- mppprofCreate an ICC profile from the .ti3 test data.
+ mppprof       @@ -4337,10 +4431,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Create a Model Printer Profile (MPP) from the .ti3 - test data.
- revfixCreate a Model Printer Profile (MPP) from the .ti3 + test data.
+ revfix        @@ -4435,11 +4531,13 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Regenerate a device profiles B2A table data by - inverting the A2B table. -

Creating Device Link Profiles

- collinkRegenerate a device profiles B2A table data by + inverting the A2B table. +

Creating Device Link Profiles

+ collink       @@ -4534,12 +4632,14 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Link two device ICC profiles to create a device - link profile. -

Converting colors or applying print calibration
-

- cctiffLink two device ICC profiles to create a device + link profile. +

Converting colors or applying print calibration
+

+ cctiff        @@ -4634,11 +4734,13 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Color convert a TIFF or JPEG file using a sequence - of ICC device, device link, abstract profiles and calibration files. -
- applycalColor convert a TIFF or JPEG file using a sequence + of ICC device, device link, abstract profiles and calibration files. +
+ applycal      Apply @@ -4732,9 +4834,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - calibration curves to an ICC profile.
- icclu  + icclu         @@ -4829,10 +4933,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Lookup individual color values through any ICC - profile table.
- xiccluLookup individual color values through any ICC + profile table.
+ xicclu        @@ -4927,10 +5033,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Lookup individual color values forward or inverted - though an ICC profile or CAL table.
- mppluLookup individual color values forward or inverted + though an ICC profile or CAL table.
+ mpplu         @@ -5025,10 +5133,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Lookup individual color values though an MPP - profile. Also create MPP gamut files/views.
- greytiffLookup individual color values though an MPP + profile. Also create MPP gamut files/views.
+ greytiff      Convert @@ -5123,18 +5233,20 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - a TIFF file to monochrome using an ICC device profile
-

Color Tweaking tools
-

- refine -        Creates an - abstract profile from two chart readings, useful for refining - proofing profiles.
-
-

Creating gamut views

- iccgamut +

Color Tweaking tools
+

+ refine +        Creates an + abstract profile from two chart readings, useful for refining + proofing profiles.
+
+

Creating gamut views

+ iccgamut      Create @@ -5229,9 +5341,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - a gamut file or VRML file of the color gamut of an ICC profile.
- tiffgamut + tiffgamut     Create @@ -5326,10 +5440,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - a gamut file or VRML file of the color gamut of a TIFF or JPEG - image.
- viewgam + viewgam       @@ -5424,12 +5540,14 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Convert one or more gamuts into a VRML 3D - visualization file. Compute an intersection.
-

Diagnostic and test tools
-

- iccdumpConvert one or more gamuts into a VRML 3D + visualization file. Compute an intersection.
+

Diagnostic and test tools
+

+ iccdump       @@ -5524,9 +5642,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Dump the contents of an ICC profile as text.
- profcheckDump the contents of an ICC profile as text.
+ profcheck     Check @@ -5621,9 +5741,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - an ICC profile against .ti3 test chart data, create pruned .ti3 - file.
+ + + + an ICC profile against .ti3 test chart data, create pruned .ti3 + file.
invprofcheck  @@ -5718,9 +5840,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Check ICC forward against inverse lookup.
- splitsti3Check ICC forward against inverse lookup.
+ splitsti3     Split @@ -5814,13 +5938,15 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - a CGATS file (ie. a .ti3) into two parts randomly to verify - profiling.
- timage -        Create TIFF test - images.
- mppcheck + timage +        Create TIFF test + images.
+ mppcheck      Check @@ -5915,9 +6041,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - an MPP profile against .ti3 test chart data.
- spotread + spotread      Use @@ -6011,9 +6139,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - an instrument to read a single spot color value.
- colverify + colverify     Verify @@ -6051,10 +6181,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - matching of CIE in two CGATS/.ti3 files (also view differences as - VRML)
- synthcal + synthcal      Create @@ -6148,11 +6280,13 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - a synthetic input, display or output calibration (.cal)file. -

Other Tools

- ccxxmake.cal)file. +

Other Tools

+ ccxxmake      Use @@ -6246,12 +6380,14 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - a Spectrometer to create a Colorimeter Correction Matrix - (CCMX)  or a Colorimeter Calibration Spectral Set (CCSS)  - for a particular display.
- extracticc + extracticc    Extract @@ -6346,15 +6482,17 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - an embedded ICC profile from a TIFF or JPEG file.
-
extractttag   Extract a text tag (ie. CGATS - .ti3 data or CAL) from an ICC profile.
- dispwin + extractttag   Extract a text tag (ie. CGATS + .ti3 data or CAL) from an ICC profile.
+ dispwin       Install @@ -6449,16 +6587,18 @@ href="http://www.google.com/search?hl=en&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.
- oeminst       - Install Instrument manufacturers files for the - Spyder 2, EDR or CCSS calibration files for i1d3 or Spyder 4 or - 5,  CCMX files for colorimeters.
- specplot     + oeminst       + Install Instrument manufacturers files for the + Spyder 2, EDR or CCSS calibration files for i1d3 or Spyder 4 or + 5,  CCMX files for colorimeters.
+ specplot       @@ -6553,10 +6693,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Plot a spectrum (.sp, .cmf, .ccss) and calculate CCT and VCT.
- spec2cie      + spec2cie      Convert @@ -6651,13 +6793,15 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - reflective spectral .ti3 readings into CIE XYZ and D50 L*a*b* - readings. Apply FWA, plot spectrums.
-   -

Main Tools - Alphabetic Listing:

- applycal +   +

Main Tools + Alphabetic Listing:

+ applycal      Apply @@ -6751,9 +6895,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - calibration curves to an ICC profile.
- average + average       @@ -6848,10 +6994,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Average or Merge two or more - measurement data files, or average patches within a single file.
- cb2ti3Average or Merge two or more + measurement data files, or average patches within a single file.
+ cb2ti3        @@ -6946,10 +7094,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Convert Colorblind format CMY/RGB test chart into - Argyll .ti3 CGATS format.
- cctiffConvert Colorblind format CMY/RGB test chart into + Argyll .ti3 CGATS format.
+ cctiff        @@ -7044,10 +7194,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Color convert a TIFF or JPEG file using a sequence - of ICC device, device link, abstract profiles and calibration files.
- ccxxmakeColor convert a TIFF or JPEG file using a sequence + of ICC device, device link, abstract profiles and calibration files.
+ ccxxmake      Use @@ -7141,11 +7293,13 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - a Spectrometer to create a Colorimeter Correction Matrix - (CCMX)  or a Colorimeter Calibration Spectral Set (CCSS)  - for a particular display.
- chartread + chartread     Read @@ -7240,9 +7394,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - a test chart using an instrument to create a .ti3 data file.
- collink + collink       @@ -7337,10 +7493,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Link two device ICC profiles to create a device - link profile.
- colprofLink two device ICC profiles to create a device + link profile.
+ colprof       @@ -7435,10 +7593,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Create an ICC profile from the .ti3 test data.
- colverify
Create an ICC profile from the .ti3 test data.
+ colverify     Verify @@ -7533,13 +7693,15 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - matching of CIE in two CGATS/.ti3 files (also view differences as - VRML)
- dispcal -       Adjust, calibrate and - profile a display.
- dispread + dispcal +       Adjust, calibrate and + profile a display.
+ dispread      Test @@ -7634,10 +7796,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - and read colorimetric values from a display
- dispwin + dispwin       Install @@ -7732,11 +7896,13 @@ href="http://www.google.com/search?hl=en&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.
- extracticc + extracticc    Extract @@ -7831,14 +7997,16 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - an embedded ICC profile from a TIFF or JPEG file.
-
extractttag   Extract a text tag (ie. CGATS - .ti3 data or CAL) from an ICC profile.
- fakeCMY + extractttag   Extract a text tag (ie. CGATS + .ti3 data or CAL) from an ICC profile.
+ fakeCMY       @@ -7933,10 +8101,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Create a fake Argyll .ti3 CMY data file from a CMYK - profile, as a basis of creating a CMY to CMYK separation
- fakereadCreate a fake Argyll .ti3 CMY data file from a CMYK + profile, as a basis of creating a CMY to CMYK separation
+ fakeread      Fake @@ -8031,9 +8201,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - the reading of a device using an ICC or MPP profile.
- filmread + filmread      Read @@ -8128,9 +8300,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - film colorimetric values using a SpectroScanT (Deprecated ?)
- filmtarg + filmtarg      Create @@ -8225,9 +8399,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - film recorder TIFF files from Argyll .ti1 file.
- greytiff + greytiff      Convert @@ -8322,10 +8498,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - a TIFF file to monochrome using an ICC device profile
- iccdump
+ iccdump       @@ -8420,9 +8598,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Dump the contents of an ICC profile as text.
- iccgamutDump the contents of an ICC profile as text.
+ iccgamut      Create @@ -8517,9 +8697,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - a gamut file or VRML file of the color gamut of an ICC profile.
- icclu  + icclu         @@ -8614,10 +8796,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Lookup individual color values through any ICC - profile table.
- illumreadLookup individual color values through any ICC + profile table.
+ illumread     Use @@ -8711,13 +8895,15 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - an instrument to measure an illuminant spectrum, and estimate its UV - content.
- invprofcheck  Check ICC - forward against inverse lookup.
- kodak2ti3 + invprofcheck  Check ICC + forward against inverse lookup.
+ kodak2ti3     Convert @@ -8812,11 +8998,13 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Kodak Colorflow format CMYK test chart into Argyll .ti3 CGATS - format.
- ls2ti3 + ls2ti3        @@ -8911,10 +9099,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Convert LightSpace format RGB .bcs test chart - results into Argyll .ti3 CGATS format.
- mppcheckConvert LightSpace format RGB .bcs test chart + results into Argyll .ti3 CGATS format.

+ mppcheck      Check @@ -9009,9 +9199,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - an MPP profile against .ti3 test chart data.
- mpplu + mpplu         @@ -9106,10 +9298,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Lookup individual color values though an MPP - profile. Also create MPP gamut files/views.
- mppprofLookup individual color values though an MPP + profile. Also create MPP gamut files/views.
+ mppprof       @@ -9204,15 +9398,17 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Create a Model Printer Profile (MPP) from the .ti3 - test data.
- oeminst       - Install Instrument manufacturers files for the - Spyder 2, EDR or CCSS calibration files for i1d3 or Spyder 4 or - 5,  CCMX files for colorimeters.
- printcalCreate a Model Printer Profile (MPP) from the .ti3 + test data.
+ oeminst       + Install Instrument manufacturers files for the + Spyder 2, EDR or CCSS calibration files for i1d3 or Spyder 4 or + 5,  CCMX files for colorimeters.
+ printcal      Create @@ -9306,9 +9502,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - a printer calibration .cal file from a .ti3 data file.
- printtarg.
+ printtarg     Create @@ -9403,10 +9601,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - a PS, EPS or TIFF file containing test patch values, ready for - printing.
- profcheck
+ profcheck     Check @@ -9501,15 +9701,17 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - an ICC profile against .ti3 test chart data, create pruned .ti3 - file.
- refine -        Creates an - abstract profile from two chart readings, useful for refining - proofing profiles.
- revfix + refine +        Creates an + abstract profile from two chart readings, useful for refining + proofing profiles.
+ revfix        @@ -9604,10 +9806,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Regenerate a device profiles B2A table data by - inverting the A2B table.
- scaninRegenerate a device profiles B2A table data by + inverting the A2B table.
+ scanin        @@ -9702,11 +9906,13 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Convert a TIFF  image of a test chart into - .ti3 device values.
- spec2cie      Convert a TIFF  image of a test chart into + .ti3 device values.
+ spec2cie      Convert @@ -9801,11 +10007,13 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - reflective spectral .ti3 readings into CIE XYZ and D50 L*a*b* - readings. Apply FWA, plot spectrums.
- specplot     + specplot       @@ -9900,9 +10108,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Plot a spectrum (.sp, .cmf, .ccss) and calculate CCT and VCT.
- splitsti3 + splitsti3     Split @@ -9996,10 +10206,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - a CGATS file (ie. a .ti3) into two parts randomly to verify - profiling.
- spotread + spotread      Use @@ -10093,10 +10305,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - an instrument to read a single spot color value.
- synthcal
+ synthcal      Create @@ -10190,10 +10404,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - a synthetic input, display or output calibration (.cal)file.
- synthread.cal)file.
+ synthread     Fake @@ -10288,9 +10504,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - the reading of a device using a synthetic device model.
- targen
+ targen        @@ -10385,10 +10603,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Generate a profiling test target values .ti1 file. -
- tiffgamutGenerate a profiling test target values .ti1 file. +
+ tiffgamut     Create @@ -10483,14 +10703,16 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - a gamut file or VRML file of the color gamut of a TIFF or JPEG - image.
- timage -        Create TIFF - test images.
- txt2ti3 + timage +        Create TIFF + test images.
+ txt2ti3       @@ -10585,12 +10807,14 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Convert Gretag/Logo/X-Rite/Barbieri or - other format RGB or CMYK test chart results into Argyll .ti3 - CGATS format.
- viewgamviewgam       Convert @@ -10684,10 +10908,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - one or more gamuts into a VRML 3D visualization file. Compute an - intersection.
- xicclu + xicclu        @@ -10782,37 +11008,39 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Lookup individual color values forward or inverted - though an ICC profile or CAL table.
-
-

Environment Variables
-

- Performance/memory tuning hints, plus - tweaks for scipting.
-

Performance Tuning
-

- Performance hints.
-

Overview

- Overview of the software and its aims and functionality.
-

Limitations

- Limitations of the current functionality.
-

Organization

- How directories are organized, what they contain. -

Source

- Any detailed documentation on how the software works, or what - algorithms it is based on. (Very incomplete.) -

Minor Tools

- A very brief description of minor tools and test harnesses.
-
-
-

File - formats that Argyll uses

- Argyll uses a number of file formats for its operation, some that - are external standards, and some that are unique to Argyll.
-
+ + + +
Lookup individual color values forward or inverted + though an ICC profile or CAL table.
+
+

Environment Variables
+

+ Performance/memory tuning hints, plus + tweaks for scipting.
+

Performance Tuning
+

+ Performance hints.
+

Overview

+ Overview of the software and its aims and functionality.
+

Limitations

+ Limitations of the current functionality.
+

Organization

+ How directories are organized, what they contain. +

Source

+ Any detailed documentation on how the software works, or what + algorithms it is based on. (Very incomplete.) +

Minor Tools

+ A very brief description of minor tools and test harnesses.
+
+
+

File + formats that Argyll uses

+ Argyll uses a number of file formats for its operation, some that + are external standards, and some that are unique to Argyll.
+
.ti1            @@ -10907,8 +11135,10 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Device test values
+ + + + Device test values
.ti2            @@ -11003,8 +11233,10 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Device test values & chart layout
+ + + + Device test values & chart layout
.ti3            @@ -11099,12 +11331,14 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Device test values & CIE tristimulus/spectral results  Format details.
- .cal -            Device - calibration information. Format details.
+ + + + Device test values & CIE tristimulus/spectral results  Format details.
+ .cal +            Device + calibration information. Format details.
.cht           @@ -11199,9 +11433,11 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Test chart recognition template. Format - details.
+ + + + Test chart recognition template. Format + details.
.gam         @@ -11296,8 +11532,10 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - 3D gamut surface description
+ + + + 3D gamut surface description
.sp            @@ -11392,16 +11630,18 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Illuminant spectral description
- .cmf -          Color Matching - Functions
- .ccmx -        Colorimeter Correction Matrix
- .ccss -         Colorimeter Calibration - Spectral Set
+ + + + Illuminant spectral description
+ .cmf +          Color Matching + Functions
+ .ccmx +        Colorimeter Correction Matrix
+ .ccss +         Colorimeter Calibration + Spectral Set
CGATS      @@ -11496,8 +11736,10 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Standard text based data exchange format
+ + + + Standard text based data exchange format
ICC           @@ -11592,8 +11834,10 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - International Color Consortium profile format
+ + + + International Color Consortium profile format
MPP          @@ -11688,8 +11932,10 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Model device profile format
+ + + + Model device profile format
TIFF         @@ -11784,8 +12030,10 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Tag Image File Format raster files.
+ + + + Tag Image File Format raster files.
JPEG         @@ -11880,13 +12128,15 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Joint Photographic Experts Group, JPEG File Interchange Format - raster files.
- ucmm   -     Unix micro Color Management Module convention and - configuration file format and Profile Locations.
+ + + + Joint Photographic Experts Group, JPEG File Interchange Format + raster files.
+ ucmm   +     Unix micro Color Management Module convention and + configuration file format and Profile Locations.
VRML       @@ -11981,43 +12231,45 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> - - Virtual Reality Modelling Language 3D file format.
- X3D -           Open - standards file format to represent 3D scenes using XML.
- X3DOM     - Open-source framework and runtime for 3D graphics on the Web.
-
-   -

Errors, Corrections and Omissions:

- If you notice any errors, corrections needed or omissions in - the current documentation, please contact the author.
-  
-  
- - + + + + Virtual Reality Modelling Language 3D file format.
+ X3D +           Open + standards file format to represent 3D scenes using XML.
+ X3DOM     + Open-source framework and runtime for 3D graphics on the Web.
+
+   +

Errors, Corrections and Omissions:

+ If you notice any errors, corrections needed or omissions in + the current documentation, please contact the author.
+  
+  
+ + diff --git a/doc/ChangesSummary.html b/doc/ChangesSummary.html index 9bf9dca..fb586e3 100644 --- a/doc/ChangesSummary.html +++ b/doc/ChangesSummary.html @@ -16,6 +16,50 @@

Summary of Argyll CMS Changes since last release

For a complete and more detailed list of changes, please see the log.txt file.

+

[V1.8.2 -> V1.8.3] 26th October 2015

+
    +
  • Added SpyderCheckr24 scaning .cht and .cie files.
  • +
  • Fixed USB problem with i1pro (Rev B & D ?), where + communications would occasionally break down on fast systems.
    +
  • +
  • Added another fixed display intergration time to i1pro + non-adaptive emission mode to cope with higher brightness + displays.
  • +
  • Added workaround for i1d3 Rev. B status code 0x83 on very low + light measurement
  • +
  • Fixed minor bug in i1d3.c that truncated serial number string. + (Thanks to Mikael Sterner).
  • +
  • Fixed bug in Klein K10 driver - adaptive measurement wasn't + properly using all the extra measurements.
  • +
  • Improved Klein K10 driver to be more robust when lights off + command returns bogus error codes, or causes a cascade of bogus + measurement errors.
    +
  • +
  • Added workaround for OS X 10.9+ "App Nap" problem.
  • +
  • Added maximum sensor frequency check for Spyder & i1d3 + drivers, so that erronious readings due to excessive brightness + can't be missed.
  • +
  • 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.
    +
  • +
  • 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.
    +
  • +
  • Added "lp" gamut mapping intent :- Luminance Preserving + Perceptual, for Photographers concerned with maintaining tonal + variations.
  • +
  • Fixed bugs in image specific gamut mapping that were degrading + the accuracy of the result.
  • +
  • Re-wrote gamut smoothing code, and re-tuned it to behave + similarly to the V1.8.2 release.
  • +
  • Changed default viewing condition glare to 5%, to smooth out + shadow tone curve.
  • +
  • Reduced the level of Helmholtz-Kohlrausch effect in CIECAM02 + implementation in the light of visual experiments.
  • +

[V1.8.1 -> V1.8.2] 7th September 2015

  • Fixed endless loop bug in alternate calibration selectors @@ -984,6 +1028,7 @@ + for systems with > 3Gig Ram.
  • @@ -1024,6 +1069,7 @@ + and memory usage issues. diff --git a/doc/File_Formats.html b/doc/File_Formats.html index 70a196a..ae59dd2 100644 --- a/doc/File_Formats.html +++ b/doc/File_Formats.html @@ -99,7 +99,7 @@ spectral samples.

    .cmf

    Color Matching Functions. This is an ASCII text, CGATS, + href="File_Formats.html#CGATS">CGATS, Argyll specific format, used to hold three spectral response curves that define a tristimulus observer. The format is the same as a .sp file. diff --git a/doc/Installing_OSX.html b/doc/Installing_OSX.html index fb01e4a..76aa98a 100644 --- a/doc/Installing_OSX.html +++ b/doc/Installing_OSX.html @@ -1,116 +1,116 @@ - - - - - - - Argyll Installation on Apple OS X - - -

    Installing the software on Apple OS X
    -

    -
    - You will need to unpack the downloaded file in such a way that the - files it contains end up in the location you have chosen to hold its - contents.
    -
    - If you want to install it system wide, then you probably want to - unpack it in the /Applications folder, so that it ends up in - the /Applications/Argyll_VX.X.X folder.
    - Another option is just to install it somewhere under your $HOME - folder, such as $HOME/Argyll_VX.X.X - or $HOME/bin/Argyll_VX.X.X, - depending on how you like to organize your applications and utility - programs. ($HOME is the shell symbolic name for your home folder, - typically /Users/username. Another abbreviation for it is the - ~ character.)
    -
    - You can unpack it by control-click on the downloaded file and “Open - With” BOMArchiveHelper or Archive Utility. Drag the resulting folder - to where you want it, e.g. into /Applications, $HOME - or $HOME/bin.
    -
    - Alternatively you can unpack it on the command line using  the - command tar -zxf archivename.tgz, which will - create a folder Argyll_VX.X.X - in your current folder, where X.X.X is the version number, and the - executables will be in Argyll_VX.X.X/bin - sub-folder.
    -
    - Open a Terminal shell. This will be in - Applications->Utilities->Terminal (Dragging it to the dock is - a good idea to make it more accessible).
    -
    - You should configure your $PATH environment variable to give the - shell access to the executable from your command line environment - without having to spell out the whole path every time, by editing - your .profile file, which - will be in your $HOME folder. You can open a graphical editor on - this file by using the open command:
    -
    -   open $HOME/.profile
    -
    - or alternatively, use some other text editor that you are familiar - with.
    -
    - Add a line similar to the following line to your .profile file:
    -
    -   PATH=$PATH:/Applications/Argyll_VX.X.X/bin
    -
    - where "/Applications/Argyll_VX.X.X/bin" is the path to the folder - that contains the ArgyllCMS executables.
    - Save your changes and exit the editor.
    -
    - If you want further guidance in setting up and using a command line - environment, then please consult an appropriate tutorial, e.g. <ShellIntro>.
    -
    - The .tgz file also contains several useful reference files (such as - scanner chart recognition templates, sample illumination spectrum - etc.) in the ref sub-folder, as well as all the current - documentation in a doc sub-folder.
    -
    - For most devices there is nothing special to do. Plug in and go. - Some devices may not work without some extra help though:
    -

    X-Rite ColorMunki

    - Some version of X-Rite's ColorMunki drivers released between 2009 - and 2011 install an X-Rite daemon that runs as root and grabs the - device, preventing any other programs (such as Argyll) from opening - them. Latter versions seem to be more cooperative, and don't suffer - from this problem. There are three ways of working around this - problem:
    -
    - 1) Turn off the X-Rite service for the ColorMunki. See <http://www.xrite.com/product_overview.aspx?ID=1161&Action=support&SupportID=4980>.
    -
    - 2) Run all Argyll programs that need to access the instrument as - root. For instance:
    -
    -     sudo spotread
    -
    - and then you will be asked for the root password.
    - While these methods will work, they are inconvenient.
    -
    - 3) Alter the X-Rite drivers Daeomon so that it runs under your user - account.
    -
    - To do this you need to edit the script that controls the X-Rite - Daemon.
    -
    -     cd ~
    -     whoami
    -     cp - /Library/LaunchDaemons/com.xrite.device.colormunki.plist temp.plist
    -     open temp.plist
    -
    - and add one child below the root:
    -
    + + + + + + + Argyll Installation on Apple OS X + + +

    Installing the software on Apple OS X
    +

    +
    + You will need to unpack the downloaded file in such a way that the + files it contains end up in the location you have chosen to hold its + contents.
    +
    + If you want to install it system wide, then you probably want to + unpack it in the /Applications folder, so that it ends up in + the /Applications/Argyll_VX.X.X folder.
    + Another option is just to install it somewhere under your $HOME + folder, such as $HOME/Argyll_VX.X.X + or $HOME/bin/Argyll_VX.X.X, + depending on how you like to organize your applications and utility + programs. ($HOME is the shell symbolic name for your home folder, + typically /Users/username. Another abbreviation for it is the + ~ character.)
    +
    + You can unpack it by control-click on the downloaded file and “Open + With” BOMArchiveHelper or Archive Utility. Drag the resulting folder + to where you want it, e.g. into /Applications, $HOME + or $HOME/bin.
    +
    + Alternatively you can unpack it on the command line using  the + command tar -zxf archivename.tgz, which will + create a folder Argyll_VX.X.X + in your current folder, where X.X.X is the version number, and the + executables will be in Argyll_VX.X.X/bin + sub-folder.
    +
    + Open a Terminal shell. This will be in + Applications->Utilities->Terminal (Dragging it to the dock is + a good idea to make it more accessible).
    +
    + You should configure your $PATH environment variable to give the + shell access to the executable from your command line environment + without having to spell out the whole path every time, by editing + your .profile file, which + will be in your $HOME folder. You can open a graphical editor on + this file by using the open command:
    +
    +   open $HOME/.profile
    +
    + or alternatively, use some other text editor that you are familiar + with.
    +
    + Add a line similar to the following line to your .profile file:
    +
    +   PATH=$PATH:/Applications/Argyll_VX.X.X/bin
    +
    + where "/Applications/Argyll_VX.X.X/bin" is the path to the folder + that contains the ArgyllCMS executables.
    + Save your changes and exit the editor.
    +
    + If you want further guidance in setting up and using a command line + environment, then please consult an appropriate tutorial, e.g. <ShellIntro>.
    +
    + The .tgz file also contains several useful reference files (such as + scanner chart recognition templates, sample illumination spectrum + etc.) in the ref sub-folder, as well as all the current + documentation in a doc sub-folder.
    +
    + For most devices there is nothing special to do. Plug in and go. + Some devices may not work without some extra help though:
    +

    X-Rite ColorMunki

    + Some version of X-Rite's ColorMunki drivers released between 2009 + and 2011 install an X-Rite daemon that runs as root and grabs the + device, preventing any other programs (such as Argyll) from opening + them. Latter versions seem to be more cooperative, and don't suffer + from this problem. There are three ways of working around this + problem:
    +
    + 1) Turn off the X-Rite service for the ColorMunki. See <http://www.xrite.com/product_overview.aspx?ID=1161&Action=support&SupportID=4980>.
    +
    + 2) Run all Argyll programs that need to access the instrument as + root. For instance:
    +
    +     sudo spotread
    +
    + and then you will be asked for the root password.
    + While these methods will work, they are inconvenient.
    +
    + 3) Alter the X-Rite drivers Daeomon so that it runs under your user + account.
    +
    + To do this you need to edit the script that controls the X-Rite + Daemon.
    +
    +     cd ~
    +     whoami
    +     cp + /Library/LaunchDaemons/com.xrite.device.colormunki.plist temp.plist
    +     open temp.plist
    +
    + and add one child below the root:
    +
        Item                             Type                    @@ -121,10 +121,10 @@ Type            &nbs - - Value           -
    -     UserName   + + Value           +
    +     UserName                     string                   @@ -135,63 +135,63 @@ string            &n - - myusername
    -
    - where "myusername" is your username shown by whoami, and save the - file. You then need to copy the modified file back:
    -
    -     sudo cp temp.plist - /Library/LaunchDaemons/com.xrite.device.colormunki.plist
    -
    - You will then need to restart the machine for this change to take - effect, or invoke the following commands:
    -
    -    sudo launchctl unload - /Library/LaunchDaemons/com.xrite.device.colormunki.plist
    -    sudo launchctl load - /Library/LaunchDaemons/com.xrite.device.colormunki.plist
    -
    - NOTE that after running - Argyll tools, you may have to turn the X-Rite service off then on - again, or disconnect and reconnect the instrument.
    -
    -

    X-Rite EyeOne Pro
    -

    - Some version of X-Rite's EyeOne Pro drivers drivers released between - 2009 and 2011 install an X-Rite daemon that runs as root and grabs - the device, preventing any other programs (such as Argyll) from - opening them. Latter versions seem to be more cooperative, and don't - suffer from this problem. There are three ways of working around - this problem:
    -
    - 1) Turn off the X-Rite service for the EyeOne Pro. See <http://www.xrite.com/product_overview.aspx?ID=1161&Action=support&SupportID=4980>.
    -
    - 2) Run all Argyll programs that need to access the instrument as - root. For instance:
    -
    -     sudo spotread
    -
    - and then you will be asked for the root password.
    - While these methods will work, they are inconvenient.
    -
    - 3) Alter the X-Rite drivers Daemon so that it runs under your user - account.
    -
    - To do this you need to edit the script that controls the X-Rite - Daemon.
    -
    -     cd ~
    -     whoami
    -     cp - /Library/LaunchDaemons/com.xrite.device.i1.plist temp.plist
    -     open temp.plist
    -
    - and add one child below the root:
    -
    + + myusername
    +
    + where "myusername" is your username shown by whoami, and save the + file. You then need to copy the modified file back:
    +
    +     sudo cp temp.plist + /Library/LaunchDaemons/com.xrite.device.colormunki.plist
    +
    + You will then need to restart the machine for this change to take + effect, or invoke the following commands:
    +
    +    sudo launchctl unload + /Library/LaunchDaemons/com.xrite.device.colormunki.plist
    +    sudo launchctl load + /Library/LaunchDaemons/com.xrite.device.colormunki.plist
    +
    + NOTE that after running + Argyll tools, you may have to turn the X-Rite service off then on + again, or disconnect and reconnect the instrument.
    +
    +

    X-Rite EyeOne Pro
    +

    + Some version of X-Rite's EyeOne Pro drivers drivers released between + 2009 and 2011 install an X-Rite daemon that runs as root and grabs + the device, preventing any other programs (such as Argyll) from + opening them. Latter versions seem to be more cooperative, and don't + suffer from this problem. There are three ways of working around + this problem:
    +
    + 1) Turn off the X-Rite service for the EyeOne Pro. See <http://www.xrite.com/product_overview.aspx?ID=1161&Action=support&SupportID=4980>.
    +
    + 2) Run all Argyll programs that need to access the instrument as + root. For instance:
    +
    +     sudo spotread
    +
    + and then you will be asked for the root password.
    + While these methods will work, they are inconvenient.
    +
    + 3) Alter the X-Rite drivers Daemon so that it runs under your user + account.
    +
    + To do this you need to edit the script that controls the X-Rite + Daemon.
    +
    +     cd ~
    +     whoami
    +     cp + /Library/LaunchDaemons/com.xrite.device.i1.plist temp.plist
    +     open temp.plist
    +
    + and add one child below the root:
    +
        Item                             Type                    @@ -202,10 +202,10 @@ Type            &nbs - - Value           -
    -     UserName   + + Value           +
    +     UserName                     string                   @@ -216,27 +216,27 @@ string            &n - - myusername
    -
    - where "myusername" is your username shown by whoami, and save the - file. You then need to copy the modified file back:
    -
    -     sudo cp temp.plist - /Library/LaunchDaemons/com.xrite.device.i1.plist
    -
    - You will then need to restart the machine for this change to take - effect, or invoke the following commands:
    -
    -    sudo launchctl unload - /Library/LaunchDaemons/com.xrite.device.i1.plist
    -    sudo launchctl load - /Library/LaunchDaemons/com.xrite.device.i1.plist
    -
    - NOTE that after running - Argyll tools, you may have to turn the X-Rite service off then on - again, or disconnect and reconnect the instrument.
    -
    + + myusername
    +
    + where "myusername" is your username shown by whoami, and save the + file. You then need to copy the modified file back:
    +
    +     sudo cp temp.plist + /Library/LaunchDaemons/com.xrite.device.i1.plist
    +
    + You will then need to restart the machine for this change to take + effect, or invoke the following commands:
    +
    +    sudo launchctl unload + /Library/LaunchDaemons/com.xrite.device.i1.plist
    +    sudo launchctl load + /Library/LaunchDaemons/com.xrite.device.i1.plist
    +
    + NOTE that after running + Argyll tools, you may have to turn the X-Rite service off then on + again, or disconnect and reconnect the instrument.
    +

    JETI specbos @@ -247,69 +247,69 @@ specbos - - 1201 and 1211 and Klein K10A
    -

    -
    - If you are using the JETI specbos 1211 and 1201, - or the Klein K10A then you may need to install the FTDI Virtual COM - Port Drivers (VCP), if they are not already on your system.
    -
    -

    HCFR Colorimeter

    - The default OS X class drivers will grab this device, preventing - Argyll from accessing it. To overcome this, you need to install a - codeless kernel extension if you wish to use the HCFR colorimeter, - that prevents this from happening. From the command line you need to - create a folder called Argyll.kext somewhere convenient, and then - place in it one file called Info.plist, containing the following:
    -
    -     ----------------- cut here ---------------------
    -    <?xml version="1.0" encoding="UTF-8"?>
    -    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST - 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    -    <plist version="1.0">
    -    <dict>
    -        - <key>CFBundleDevelopmentRegion</key> - <string>English</string>
    -        - <key>CFBundleGetInfoString</key> <string>Libusb - USB device Shield</string>
    -        - <key>CFBundleIdentifier</key> - <string>com.libusb.USB_Shield</string>
    -        - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string>
    -        <key>CFBundleName</key> - <string>Libusb USB device Shield</string>
    -        - <key>CFBundlePackageType</key> - <string>KEXT</string>
    -        <key>CFBundleSignature</key> - <string>????</string>
    -        <key>CFBundleVersion</key> - <string>6.0</string>
    -        - <key>IOKitPersonalities</key>
    -        <dict>
    -            - <key>HCFR</key>
    -            <dict>
    -                - <key>CFBundleIdentifier</key> - <string>com.apple.driver.AppleUSBComposite</string>
    -             -    <key>IOClass</key> - <string>AppleUSBComposite</string>
    -              -   <key>IOProviderClass</key> - <string>IOUSBDevice</string>
    -             -    <key>idVendor</key> - <integer>1243</integer>
    + + 1201 and 1211 and Klein K10A
    + +
    + If you are using the JETI specbos 1211 and 1201, + or the Klein K10A then you may need to install the FTDI Virtual COM + Port Drivers (VCP), if they are not already on your system.
    +
    +

    HCFR Colorimeter

    + The default OS X class drivers will grab this device, preventing + Argyll from accessing it. To overcome this, you need to install a + codeless kernel extension if you wish to use the HCFR colorimeter, + that prevents this from happening. From the command line you need to + create a folder called Argyll.kext somewhere convenient, and then + place in it one file called Info.plist, containing the following:
    +
    +     ----------------- cut here ---------------------
    +    <?xml version="1.0" encoding="UTF-8"?>
    +    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST + 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    +    <plist version="1.0">
    +    <dict>
    +        + <key>CFBundleDevelopmentRegion</key> + <string>English</string>
    +        + <key>CFBundleGetInfoString</key> <string>Libusb + USB device Shield</string>
    +        + <key>CFBundleIdentifier</key> + <string>com.libusb.USB_Shield</string>
    +        + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string>
    +        <key>CFBundleName</key> + <string>Libusb USB device Shield</string>
    +        + <key>CFBundlePackageType</key> + <string>KEXT</string>
    +        <key>CFBundleSignature</key> + <string>????</string>
    +        <key>CFBundleVersion</key> + <string>6.0</string>
    +        + <key>IOKitPersonalities</key>
    +        <dict>
    +            + <key>HCFR</key>
    +            <dict>
    +                + <key>CFBundleIdentifier</key> + <string>com.apple.driver.AppleUSBComposite</string>
    +             +    <key>IOClass</key> + <string>AppleUSBComposite</string>
    +              +   <key>IOProviderClass</key> + <string>IOUSBDevice</string>
    +             +    <key>idVendor</key> + <integer>1243</integer>
                 @@ -319,36 +319,36 @@ specbos - -   <key>idProduct</key> - <integer>91</integer>
    -            - </dict>
    -        </dict>
    -        - <key>OSBundleCompatibleVersion</key> - <string>1.8</string>
    -        <key>OSBundleLibraries</key>
    -        <dict>
    -            - <key>com.apple.kernel.iokit</key> - <string>6.0</string>
    -        </dict>
    -    </dict>
    -    </plist>
    -     ----------------- cut here ---------------------
    -
    - (You can also copy this from the source installation in - usb/Argyll.kext)
    -
    - You then need to install it by using:
    -
    -   sudo cp -R Argyll.kext /System/Library/Extensions
    -
    - supplying the appropriate root password when prompted.
    - Reboot the system to activate the extension.
    -
    -


    -

    - - + +   <key>idProduct</key> + <integer>91</integer>
    +            + </dict>
    +        </dict>
    +        + <key>OSBundleCompatibleVersion</key> + <string>1.8</string>
    +        <key>OSBundleLibraries</key>
    +        <dict>
    +            + <key>com.apple.kernel.iokit</key> + <string>6.0</string>
    +        </dict>
    +    </dict>
    +    </plist>
    +     ----------------- cut here ---------------------
    +
    + (You can also copy this from the source installation in + usb/Argyll.kext)
    +
    + You then need to install it by using:
    +
    +   sudo cp -R Argyll.kext /System/Library/Extensions
    +
    + supplying the appropriate root password when prompted.
    + Reboot the system to activate the extension.
    +
    +


    +

    + + diff --git a/doc/Scenarios.html b/doc/Scenarios.html index 8cd45c9..c8bb154 100644 --- a/doc/Scenarios.html +++ b/doc/Scenarios.html @@ -1,134 +1,134 @@ - - - - Argyll Usage Scenarios - - - -

    Typical usage Scenarios and Examples

    - Choose a task from the list below. For more details on alternative - options, follow the links to the individual tools being used.
    -
    - Note that by default it is assumed that ICC profile have the file - extension .icm, but that on - Apple OS X and Unix/Linux platforms, the .icc extension is expected and should be used.
    -

    Profiling Displays

    -

        Checking you can access your - display
    -

    -

        Adjusting and Calibrating a - displays

    -

        Adjusting, calibrating and - profiling in one step
    -

    -

        Creating display test values

    -

        Taking readings from a - display

    -

        Creating a display profile

    -

        Installing a display profile

    -

        Expert tips when measuring displays

    -

        Calibrating and profiling a display that doesn't - have VideoLUT access.

    -


    - Profiling Scanners and other input devices such as - cameras
    -

    -

        Types of test charts

    -

        Taking readings from a - scanner

    -

        Creating a scanner profile

    -


    - Profiling Printers

    -

        Creating a print profile - test chart

    -

        Printing a - print profile test chart

    -

        Reading a print test chart - using an instrument

    -

        Reading a print test chart - using a scanner

    -

    -

        Creating a printer profile
    -

    -

        Choosing a black generation - curve

    -
    -

    Calibrating Printers

    -

        Calibrated - print workflows

    -

        Creating a - print calibration test chart

    -

    -

        Creating a - printer calibration
    -

    -

        Using a printer - calibration

    -

        How profile ink limits are - handled when calibration is being used
    -

    -

    Linking Profiles

    -

        Image dependent gamut - mapping using device links
    -

    -

        Soft Proofing Link
    -

    -

    Transforming colorspaces of raster files

    -

    -

    Creating Video Calibration 3DLuts

    -

    Verifying Video Calibration 3DLuts

    -
    -

    -

    Profiling Displays

    - Argyll supports adjusting, calibrating and profiling of displays - using one of a number of instruments - see instruments for a current list.  - Adjustment and calibration are prior steps to profiling, in which - the display is adjusted using it's screen controls,  and then - per channel lookup tables are created to make it meet a well behaved - response of the desired type. The  process following that of - creating a display profile is then similar to that of all other - output devices :- first a set of device colorspace test values needs - to be created to exercise the display, then these values need to be - displayed, while taking measurements of the resulting colors using - the instrument. Finally, the device value/measured color values need - to be converted into an ICC profile.
    -
    -

    Checking you can access your display
    -

    - You might first want to check that you are accessing and can - calibrate your display. You can do this using the dispwin - tool. If you just run dispwin it will create a test - window and run through a series of test colors before checking that - the VideoLUT can be accessed by the display. If you invoke the usage - for dispwin (by giving it - an unrecognized option, e.g. -?) - then it will show a list of available displays next to the -d - flag. Make sure that you are accessing the display you intend to - calibrate and profile, and that the VideoLUT is effective (the -r flag can be used to just run - the VideoLUT test). You can also try clearing the VideoLUTs using - the -c flag, and loading a - deliberately strange looking calibration strange.cal that is provided in the Argyll ref directory.
    -
    - Note that calibrating and/or profiling remote displays is possible using X11 or a web - browser (see -d option of - dispcal and dispread), or by using some external program to send - test colors to a display (see -C - and -M options of dispcal + + + + Argyll Usage Scenarios + + + +

    Typical usage Scenarios and Examples

    + Choose a task from the list below. For more details on alternative + options, follow the links to the individual tools being used.
    +
    + Note that by default it is assumed that ICC profile have the file + extension .icm, but that on + Apple OS X and Unix/Linux platforms, the .icc extension is expected and should be used.
    +

    Profiling Displays

    +

        Checking you can access your + display
    +

    +

        Adjusting and Calibrating a + displays

    +

        Adjusting, calibrating and + profiling in one step
    +

    +

        Creating display test values

    +

        Taking readings from a + display

    +

        Creating a display profile

    +

        Installing a display profile

    +

        Expert tips when measuring displays

    +

        Calibrating and profiling a display that doesn't + have VideoLUT access.

    +


    + Profiling Scanners and other input devices such as + cameras
    +

    +

        Types of test charts

    +

        Taking readings from a + scanner

    +

        Creating a scanner profile

    +


    + Profiling Printers

    +

        Creating a print profile + test chart

    +

        Printing a + print profile test chart

    +

        Reading a print test chart + using an instrument

    +

        Reading a print test chart + using a scanner

    +

    +

        Creating a printer profile
    +

    +

        Choosing a black generation + curve

    +
    +

    Calibrating Printers

    +

        Calibrated + print workflows

    +

        Creating a + print calibration test chart

    +

    +

        Creating a + printer calibration
    +

    +

        Using a printer + calibration

    +

        How profile ink limits are + handled when calibration is being used
    +

    +

    Linking Profiles

    +

        Image dependent gamut + mapping using device links
    +

    +

        Soft Proofing Link
    +

    +

    Transforming colorspaces of raster files

    +

    +

    Creating Video Calibration 3DLuts

    +

    Verifying Video Calibration 3DLuts

    +
    +

    +

    Profiling Displays

    + Argyll supports adjusting, calibrating and profiling of displays + using one of a number of instruments - see instruments for a current list.  + Adjustment and calibration are prior steps to profiling, in which + the display is adjusted using it's screen controls,  and then + per channel lookup tables are created to make it meet a well behaved + response of the desired type. The  process following that of + creating a display profile is then similar to that of all other + output devices :- first a set of device colorspace test values needs + to be created to exercise the display, then these values need to be + displayed, while taking measurements of the resulting colors using + the instrument. Finally, the device value/measured color values need + to be converted into an ICC profile.
    +
    +

    Checking you can access your display
    +

    + You might first want to check that you are accessing and can + calibrate your display. You can do this using the dispwin + tool. If you just run dispwin it will create a test + window and run through a series of test colors before checking that + the VideoLUT can be accessed by the display. If you invoke the usage + for dispwin (by giving it + an unrecognized option, e.g. -?) + then it will show a list of available displays next to the -d + flag. Make sure that you are accessing the display you intend to + calibrate and profile, and that the VideoLUT is effective (the -r flag can be used to just run + the VideoLUT test). You can also try clearing the VideoLUTs using + the -c flag, and loading a + deliberately strange looking calibration strange.cal that is provided in the Argyll ref directory.
    +
    + Note that calibrating and/or profiling remote displays is possible using X11 or a web + browser (see -d option of + dispcal and dispread), or by using some external program to send + test colors to a display (see -C + and -M options of dispcal and dispread), but you may want to refer to Calibrating @@ -181,27 +181,29 @@ - - and profiling a display that doesn't have VideoLUT access.
    -
    -

    Adjusting and Calibrating Displays

    - Please read What's the difference between - Calibration and Characterization ? if you are unclear as to - the difference .
    -
    - The first step is to decide what the target should be for adjustment - and calibration. This boils down to three things: The desired - brightness, the desired white point, and the desired response curve. - The native brightness and white points of a display may be different - to the desired characteristics for some purposes. For instance, for - graphic arts use, it might be desirable to run with a warmer white - point of about 5000 degrees Kelvin, rather than the default display - white point of 6500 to 9000 Kelvin. Some LCD displays are too bright - to compare to printed material under available lighting, so it might - be desirable to reduce the maximum brightness.
    -
    - You can run dispcal -r to check on how - your display is currently set up. (you may have to run this as .
    +
    +

    Adjusting and Calibrating Displays

    + Please read What's the difference between + Calibration and Characterization ? if you are unclear as to + the difference .
    +
    + The first step is to decide what the target should be for adjustment + and calibration. This boils down to three things: The desired + brightness, the desired white point, and the desired response curve. + The native brightness and white points of a display may be different + to the desired characteristics for some purposes. For instance, for + graphic arts use, it might be desirable to run with a warmer white + point of about 5000 degrees Kelvin, rather than the default display + white point of 6500 to 9000 Kelvin. Some LCD displays are too bright + to compare to printed material under available lighting, so it might + be desirable to reduce the maximum brightness.
    +
    + You can run dispcal -r to check on how + your display is currently set up. (you may have to run this as dispcal -yl @@ -260,332 +262,334 @@ - - -r for an LCD display, or dispcal -yc -r for a - CRT display with most of the colorimeter instruments. If so, this - will apply to all of the following examples.)
    -
    - Once this is done, dispcal can be run to - guide you through the display adjustments, and then calibrate it. By - default, the brightness and white point will be kept the same as the - devices natural brightness and white point. The default response - curve is a gamma of 2.4, except for Apple OS X systems prior to 10.6 - where a gamma of 1.8 is the default. 2.4 is close to that of  - many monitors, and close to that of the sRGB colorspace.
    -
    - A typical calibration that leaves the brightness and white point - alone, might be:
    -
    - dispcal -v TargetA
    -
    - which will result in a "TargetA.cal" calibration file, that can then - be used during the profiling stage.
    -
    - If the absolutely native response of the display is desired during - profiling, then calibration should be skipped, and the linear.cal - file from the "ref" directory used instead as the argument to the -k - flag of dispread.
    -
    - Dispcal will display a test window in the middle of the - screen, and issue a series of instructions about placing the - instrument on the display. You may need to make sure that the - display cursor is not in the test window, and it may also be - necessary to disable any screensaver and powersavers before starting - the process, although both dispcal - and dispread will attempt - to do this for you. It's also highly desirable on CRT's, to clear - your screen of any white or bright background images or windows - (running your shell window with white text on a black background - helps a lot here.), or at least keep any bright areas away from the - test window, and be careful not to change anything on the display - while the readings are taken. Lots of bright images or windows can - affect the ability to measure the black point accurately, and - changing images on the display can cause inconsistency in the - readings,  and leading to poor results. LCD displays seem to be less - influenced by what else is on the screen.
    -
    - If dispcal is run without - arguments, it will provide a usage screen. The -c parameter allows selecting a - communication port for an instrument, or selecting the instrument - you want to use,  and the -d option allows selecting - a target display on a multi-display system. On some multi-monitor - systems, it may not be possible to independently calibrate and - profile each display if they appear as one single screen to the - operating system, or if it is not possible to set separate video - lookup tables for each display. You can change the position and size - of the test window using the -P parameter. You can - determine how best to arrange the test window, as well as whether - each display has separate video lookup capability, by experimenting - with the dispwin tool.
    -
    - For a more detailed discussion on interactively adjusting the - display controls using dispcal, - see dispcal-adjustment. Once - you have adjusted and calibrated your display, you can move on to - the next step.
    -
    - When you have calibrated and profiled your display, you can keep it - calibrated using the dispcal -u - option.
    -
    -

    Adjusting, calibrating and profiling in one - step.

    - If a simple matrix/shaper display profile is all that is desired, dispcal can be used to do this, - permitting display adjustment, calibration and profiling all in one - operation. This is done by using the dispcal -o - flag:
    -
    - dispcal -v - -o TargetA
    -
    - This will create both a TargetA.cal file, but also a TargetA.icm - file. See -o and -O for other variations.
    -
    - For more flexibility in creating a display profile, the separate - steps of creating characterization test values using targen, reading them from the - display using dispread, and - then creating a profile using colprof - are used. The following steps illustrate this:
    -

    Profiling in several steps: Creating display - test values

    - If the dispcal has not been - used to create a display profile at the same time as adjustment and - calibration, then it can be used to create a suitable set of - calibration curves as the first step, or the calibration step can be - omitted, and the display cansimply be profiled.
    -
    - The first step in profiling any output device, is to create a set of - device colorspace test values. The important parameters needed are: -
    -
      -
    • What colorspace does the device use ?
    • -
    • How many test patches do I want to use ?
    • -
    • What information do I already have about how the device - behaves ?
    • -
    - For a display device,  the colorspace will be RGB. The number - of test patches will depend somewhat on what quality profile you - want to make, what type of profile you want to make, and how long - you are prepared to wait when testing the display.
    - At a minimum, a few hundred values are needed. A matrix/shaper type - of profile can get by with fewer test values, while a LUT based - profile will give better results if more test values are used. A - typical number might be 200-600 or so values, while 1000-2000 is not - an unreasonable number for a high quality characterization of a - display.
    -
    - To assist the choice of test patch values, it can help to have a - rough idea of how the device behaves. This could be in the form of - an ICC profile of a similar device, or a lower quality, or previous - profile for that particular device. If one were going to make a very - high quality LUT based profile, then it might be worthwhile to make - up a smaller, preliminary shaper/matrix profile using a few hundred - test points, before embarking on testing the device with several - thousand.
    -
    - Lets say that we ultimately want to make a profile for the device - "DisplayA", the simplest approach is to make a set of test values - that is independent of the characteristics of the particular device:
    -
    - targen -v -  -d3 -f500 - DisplayA
    -
    - If there is a preliminary or previous profile called "OldDisplay" - available, and we want to try creating a "pre-conditioned" set of - test values that will more efficiently sample the device response, - then the following would achieve this:
    -
    -
    targen -v -  -d3 -f500 - -cOldDisplay.icm DisplayA
    -
    - The output of targen will be the file DisplayA.ti1, - containing the device space test values, as well as expected CIE - values used for chart recognition purposes.
    -
    -

    Profiling in several steps: Taking readings - from a display

    - First it is necessary to connect your measurement instrument to your - computer, and check which communication port it is connected to. In - the following example, it is assumed that the instrument is - connected to the default port 1, which is either the first USB - instrument found, or serial port found. Invoking dispread so as to - display the usage information (by using a flag -? or --) will list - the identified serial and USB ports, and their labels.
    -
    - dispread -v - DisplayA
    -
    - If we created a calibration for the display using dispcal, then we will want to use this - when we take the display readings (e.g. TargetA.cal from the - calibration example)..
    -
    - dispread -v - -k TargetA.cal DisplayA
    -
    - dispread will display a test window in the middle of the - screen, and issue a series of instructions about placing the - instrument on the display. You may need to make sure that the - display cursor is not in the test window, and it may also be - necessary to disable any screensaver before starting the process. - Exactly the same facilities are provided to select alternate - displays using the -d - parameter, and an alternate location and size for the test window - using the -P parameter as - with dispcal.
    -

    Profiling in several steps: Creating a display - profile

    - There are two basic choices of profile type for a display, a - shaper/matrix profile, or a LUT based profile. They have different - tradeoffs. A shaper/matrix profile will work well on a well behaved - display, that is one that behaves in an additive color manner, will - give very smooth looking results, and needs fewer test points to - create. A LUT based profile on the other hand, will model any - display behaviour more accurately, and can accommodate gamut mapping - and different intent tables. Often it can show some unevenness and - contouring in the results though.
    -
    - To create a matrix/shaper profile, the following suffices:
    -
    - colprof -v - -D"Display A" -qm - -as DisplayA
    -
    - For a LUT based profile, where gamut mapping is desired, then a - source profile will need to be provided to define the source gamut. - For instance, if the display profile was likely to be linked to a - CMYK printing source profile, say "swop.icm" or "fogra39l.icm", then - the following would suffice:
    -
    - colprof -v - -D"Display A" -qm - -S - fogra39l.icm -cpp -dmt DisplayA
    -
    - Make sure you check the delta E report at the end of the profile - creation, to see if the sample data and profile is behaving - reasonably.
    - If a calibration file was used with dispread, - then it will be converted to a vcgt tag in the profile, so that the - operating system or other system color tools load the lookup curves - into the display hardware, when the profile is used.
    -

    Installing a display profile

    - dispwin provides a convenient way of - installing a profile as the default system profile for the chosen - display:
    -
    - dispwin -I - DisplayA.icm
    -
    - This also sets the display to the calibration contained in the - profile. If you want to try out a calibration before installing the - profile, using dispwin without the -I - option will load a calibration (ICC profile or .cal file) into the - current display.
    -
    - Some systems will automatically set the display to the calibration - contained in the installed profile (ie. OS X), while on other - systems (ie. MSWindows and Linux/X11) it is necessary to use some - tool to do this. On MSWindows XP you could install the - optional  Microsoft Color Control Panel Applet for Windows XP - available for download from Microsoft to do this, but NOTE however that it seems to - have a bug, in that it - sometimes associates the profiles with the wrong monitor entry. Other - display calibration tools will often install a similar tool, so - beware of there being multiple, competing programs. [ Commonly these - will be in your Start->Programs->Startup folder. ]
    - On Microsoft Vista, you need to use dispwin -L or some other tool to - load the installed profiles calibration at startup.
    -
    - To use dispwin to load the installed profiles calibration to the - display, use
    -
    - dispwin -L
    -
    - As per usual, you can select the appropriate display using the -d flag.
    -
    - This can be automated on MSWindows and X11/Linux by adding this - command to an appropriate startup script.
    - More system specific details, including how to create such startup - scripts are here.
    -
    - If you are using Microsoft Vista, - there is a known bug in - Vista that resets the calibration every time a fade-in effect is - executed, which happens if you lock and unlock the computer, resume - from sleep or hibernate, or User Access Control is activated. Using - dispwin -L - may not restore the calibration, because Vista filters out setting - (what it thinks) is a calibration that is already loaded. Use dispwin -c -L - as a workaround, as this will first clear the calibration, then - re-load the current calibration.
    -
    - On X11/Linux systems, you could try adding dispwin - -L to your ~/.config/autostart file, so that your window - manager automatically sets calibration when it starts. If you are - running XRandR 1.2, you might consider running the experimental dispwin -E in the background, as in its - "daemon" mode it will update the profile and calibration in response - to any changes in the the connected display.
    -
    -

    Expert tips when measuring displays:
    -

    - Sometimes it can be difficult to get good quality, consistent and - visually relevant readings from displays, due to various practical - considerations with regard to instruments and the displays - themselves. Argyll's tools have some extra options that may assist - in overcoming these problems.
    -
    - If you are using an Eye-One Pro or ColorMunki spectrometer, then you - may wish to use the high resolution - spectral mode (-H). - This may be better at capturing the often narrow wavelength peaks - that are typical of display primary colors.
    -
    - All instruments depend on silicon sensors, and such sensors generate - a temperature dependant level of noise ("dark noise") that is - factored out of the measurements by a dark or black instrument - calibration. The spectrometers in particular need this calibration - before commencing each set of measurements. Often an instrument will - warm up as it sits on a display, and this warming up can cause the - dark noise to increase, leading to inaccuracies in dark patch - measurements. The longer the measurement takes, the worse this - problem is likely to be. One way of addressing this is to - "acclimatise" the instrument before commencing measurements by - placing it on the screen in a powered up state, and leaving it for - some time. (Some people leave it for up to an hour to acclimatise.). - Another approach is to try and compensate - for dark calibration changes (-Ib) - by doing on the fly calibrations during the measurements, based on - the assumption that the black level of the display itself won't - change significantly.
    -
    - Some displays take a long time to settle down and stabilise. The is - often the case with LCD (Liquid Crystal) displays that use - fluorescent back lights, and these sorts of displays can change in - brightness significantly with changes in temperature. One way of - addressing this is to make sure that the display is given adequate - time to warm up before measurements. Another approach is to try and + + + + -r
    for an LCD display, or dispcal -yc -r for a + CRT display with most of the colorimeter instruments. If so, this + will apply to all of the following examples.)
    +
    + Once this is done, dispcal can be run to + guide you through the display adjustments, and then calibrate it. By + default, the brightness and white point will be kept the same as the + devices natural brightness and white point. The default response + curve is a gamma of 2.4, except for Apple OS X systems prior to 10.6 + where a gamma of 1.8 is the default. 2.4 is close to that of  + many monitors, and close to that of the sRGB colorspace.
    +
    + A typical calibration that leaves the brightness and white point + alone, might be:
    +
    + dispcal -v TargetA
    +
    + which will result in a "TargetA.cal" calibration file, that can then + be used during the profiling stage.
    +
    + If the absolutely native response of the display is desired during + profiling, then calibration should be skipped, and the linear.cal + file from the "ref" directory used instead as the argument to the -k + flag of dispread.
    +
    + Dispcal will display a test window in the middle of the + screen, and issue a series of instructions about placing the + instrument on the display. You may need to make sure that the + display cursor is not in the test window, and it may also be + necessary to disable any screensaver and powersavers before starting + the process, although both dispcal + and dispread will attempt + to do this for you. It's also highly desirable on CRT's, to clear + your screen of any white or bright background images or windows + (running your shell window with white text on a black background + helps a lot here.), or at least keep any bright areas away from the + test window, and be careful not to change anything on the display + while the readings are taken. Lots of bright images or windows can + affect the ability to measure the black point accurately, and + changing images on the display can cause inconsistency in the + readings,  and leading to poor results. LCD displays seem to be less + influenced by what else is on the screen.
    +
    + If dispcal is run without + arguments, it will provide a usage screen. The -c parameter allows selecting a + communication port for an instrument, or selecting the instrument + you want to use,  and the -d option allows selecting + a target display on a multi-display system. On some multi-monitor + systems, it may not be possible to independently calibrate and + profile each display if they appear as one single screen to the + operating system, or if it is not possible to set separate video + lookup tables for each display. You can change the position and size + of the test window using the -P parameter. You can + determine how best to arrange the test window, as well as whether + each display has separate video lookup capability, by experimenting + with the dispwin tool.
    +
    + For a more detailed discussion on interactively adjusting the + display controls using dispcal, + see dispcal-adjustment. Once + you have adjusted and calibrated your display, you can move on to + the next step.
    +
    + When you have calibrated and profiled your display, you can keep it + calibrated using the dispcal -u + option.
    +
    +

    Adjusting, calibrating and profiling in one + step.

    + If a simple matrix/shaper display profile is all that is desired, dispcal can be used to do this, + permitting display adjustment, calibration and profiling all in one + operation. This is done by using the dispcal -o + flag:
    +
    + dispcal -v + -o TargetA
    +
    + This will create both a TargetA.cal file, but also a TargetA.icm + file. See -o and -O for other variations.
    +
    + For more flexibility in creating a display profile, the separate + steps of creating characterization test values using targen, reading them from the + display using dispread, and + then creating a profile using colprof + are used. The following steps illustrate this:
    +

    Profiling in several steps: Creating display + test values

    + If the dispcal has not been + used to create a display profile at the same time as adjustment and + calibration, then it can be used to create a suitable set of + calibration curves as the first step, or the calibration step can be + omitted, and the display cansimply be profiled.
    +
    + The first step in profiling any output device, is to create a set of + device colorspace test values. The important parameters needed are: +
    +
      +
    • What colorspace does the device use ?
    • +
    • How many test patches do I want to use ?
    • +
    • What information do I already have about how the device + behaves ?
    • +
    + For a display device,  the colorspace will be RGB. The number + of test patches will depend somewhat on what quality profile you + want to make, what type of profile you want to make, and how long + you are prepared to wait when testing the display.
    + At a minimum, a few hundred values are needed. A matrix/shaper type + of profile can get by with fewer test values, while a LUT based + profile will give better results if more test values are used. A + typical number might be 200-600 or so values, while 1000-2000 is not + an unreasonable number for a high quality characterization of a + display.
    +
    + To assist the choice of test patch values, it can help to have a + rough idea of how the device behaves. This could be in the form of + an ICC profile of a similar device, or a lower quality, or previous + profile for that particular device. If one were going to make a very + high quality LUT based profile, then it might be worthwhile to make + up a smaller, preliminary shaper/matrix profile using a few hundred + test points, before embarking on testing the device with several + thousand.
    +
    + Lets say that we ultimately want to make a profile for the device + "DisplayA", the simplest approach is to make a set of test values + that is independent of the characteristics of the particular device:
    +
    + targen -v +  -d3 -f500 + DisplayA
    +
    + If there is a preliminary or previous profile called "OldDisplay" + available, and we want to try creating a "pre-conditioned" set of + test values that will more efficiently sample the device response, + then the following would achieve this:
    +
    +
    targen -v +  -d3 -f500 + -cOldDisplay.icm DisplayA
    +
    + The output of targen will be the file DisplayA.ti1, + containing the device space test values, as well as expected CIE + values used for chart recognition purposes.
    +
    +

    Profiling in several steps: Taking readings + from a display

    + First it is necessary to connect your measurement instrument to your + computer, and check which communication port it is connected to. In + the following example, it is assumed that the instrument is + connected to the default port 1, which is either the first USB + instrument found, or serial port found. Invoking dispread so as to + display the usage information (by using a flag -? or --) will list + the identified serial and USB ports, and their labels.
    +
    + dispread -v + DisplayA
    +
    + If we created a calibration for the display using dispcal, then we will want to use this + when we take the display readings (e.g. TargetA.cal from the + calibration example)..
    +
    + dispread -v + -k TargetA.cal DisplayA
    +
    + dispread will display a test window in the middle of the + screen, and issue a series of instructions about placing the + instrument on the display. You may need to make sure that the + display cursor is not in the test window, and it may also be + necessary to disable any screensaver before starting the process. + Exactly the same facilities are provided to select alternate + displays using the -d + parameter, and an alternate location and size for the test window + using the -P parameter as + with dispcal.
    +

    Profiling in several steps: Creating a display + profile

    + There are two basic choices of profile type for a display, a + shaper/matrix profile, or a LUT based profile. They have different + tradeoffs. A shaper/matrix profile will work well on a well behaved + display, that is one that behaves in an additive color manner, will + give very smooth looking results, and needs fewer test points to + create. A LUT based profile on the other hand, will model any + display behaviour more accurately, and can accommodate gamut mapping + and different intent tables. Often it can show some unevenness and + contouring in the results though.
    +
    + To create a matrix/shaper profile, the following suffices:
    +
    + colprof -v + -D"Display A" -qm + -as DisplayA
    +
    + For a LUT based profile, where gamut mapping is desired, then a + source profile will need to be provided to define the source gamut. + For instance, if the display profile was likely to be linked to a + CMYK printing source profile, say "swop.icm" or "fogra39l.icm", then + the following would suffice:
    +
    + colprof -v + -D"Display A" -qm + -S + fogra39l.icm -cpp -dmt DisplayA
    +
    + Make sure you check the delta E report at the end of the profile + creation, to see if the sample data and profile is behaving + reasonably.
    + If a calibration file was used with dispread, + then it will be converted to a vcgt tag in the profile, so that the + operating system or other system color tools load the lookup curves + into the display hardware, when the profile is used.
    +

    Installing a display profile

    + dispwin provides a convenient way of + installing a profile as the default system profile for the chosen + display:
    +
    + dispwin -I + DisplayA.icm
    +
    + This also sets the display to the calibration contained in the + profile. If you want to try out a calibration before installing the + profile, using dispwin without the -I + option will load a calibration (ICC profile or .cal file) into the + current display.
    +
    + Some systems will automatically set the display to the calibration + contained in the installed profile (ie. OS X), while on other + systems (ie. MSWindows and Linux/X11) it is necessary to use some + tool to do this. On MSWindows XP you could install the + optional  Microsoft Color Control Panel Applet for Windows XP + available for download from Microsoft to do this, but NOTE however that it seems to + have a bug, in that it + sometimes associates the profiles with the wrong monitor entry. Other + display calibration tools will often install a similar tool, so + beware of there being multiple, competing programs. [ Commonly these + will be in your Start->Programs->Startup folder. ]
    + On Microsoft Vista, you need to use dispwin -L or some other tool to + load the installed profiles calibration at startup.
    +
    + To use dispwin to load the installed profiles calibration to the + display, use
    +
    + dispwin -L
    +
    + As per usual, you can select the appropriate display using the -d flag.
    +
    + This can be automated on MSWindows and X11/Linux by adding this + command to an appropriate startup script.
    + More system specific details, including how to create such startup + scripts are here.
    +
    + If you are using Microsoft Vista, + there is a known bug in + Vista that resets the calibration every time a fade-in effect is + executed, which happens if you lock and unlock the computer, resume + from sleep or hibernate, or User Access Control is activated. Using + dispwin -L + may not restore the calibration, because Vista filters out setting + (what it thinks) is a calibration that is already loaded. Use dispwin -c -L + as a workaround, as this will first clear the calibration, then + re-load the current calibration.
    +
    + On X11/Linux systems, you could try adding dispwin + -L to your ~/.config/autostart file, so that your window + manager automatically sets calibration when it starts. If you are + running XRandR 1.2, you might consider running the experimental dispwin -E in the background, as in its + "daemon" mode it will update the profile and calibration in response + to any changes in the the connected display.
    +
    +

    Expert tips when measuring displays:
    +

    + Sometimes it can be difficult to get good quality, consistent and + visually relevant readings from displays, due to various practical + considerations with regard to instruments and the displays + themselves. Argyll's tools have some extra options that may assist + in overcoming these problems.
    +
    + If you are using an Eye-One Pro or ColorMunki spectrometer, then you + may wish to use the high resolution + spectral mode (-H). + This may be better at capturing the often narrow wavelength peaks + that are typical of display primary colors.
    +
    + All instruments depend on silicon sensors, and such sensors generate + a temperature dependant level of noise ("dark noise") that is + factored out of the measurements by a dark or black instrument + calibration. The spectrometers in particular need this calibration + before commencing each set of measurements. Often an instrument will + warm up as it sits on a display, and this warming up can cause the + dark noise to increase, leading to inaccuracies in dark patch + measurements. The longer the measurement takes, the worse this + problem is likely to be. One way of addressing this is to + "acclimatise" the instrument before commencing measurements by + placing it on the screen in a powered up state, and leaving it for + some time. (Some people leave it for up to an hour to acclimatise.). + Another approach is to try and compensate + for dark calibration changes (-Ib) + by doing on the fly calibrations during the measurements, based on + the assumption that the black level of the display itself won't + change significantly.
    +
    + Some displays take a long time to settle down and stabilise. The is + often the case with LCD (Liquid Crystal) displays that use + fluorescent back lights, and these sorts of displays can change in + brightness significantly with changes in temperature. One way of + addressing this is to make sure that the display is given adequate + time to warm up before measurements. Another approach is to try and compensate for display white level  @@ -643,21 +647,23 @@ - - (-Iw) changes by doing on - the fly calibrations during the measurements. Instrument black level - drift and display white level drift can be combined (-Ibw).
    -
    - Colorimeter instruments make use of physical color filters that - approximate the standard observer spectral sensitivity curves. - Because these filters are not perfectly accurate, the manufacturer - calibrates the instrument for typical displays, which is why you - have to make a selection between CRT (Cathode Ray Tube) and LCD - (Liquid Crystal Display) modes. If you are measuring a display that - has primary colorants that differ significantly from those typical - displays,  (ie. you have a Wide Gamut Display), then you may - get disappointing results with a Colorimeter. One way of addressing + + + + (-Iw) changes by doing on + the fly calibrations during the measurements. Instrument black level + drift and display white level drift can be combined (-Ibw).
    +
    + Colorimeter instruments make use of physical color filters that + approximate the standard observer spectral sensitivity curves. + Because these filters are not perfectly accurate, the manufacturer + calibrates the instrument for typical displays, which is why you + have to make a selection between CRT (Cathode Ray Tube) and LCD + (Liquid Crystal Display) modes. If you are measuring a display that + has primary colorants that differ significantly from those typical + displays,  (ie. you have a Wide Gamut Display), then you may + get disappointing results with a Colorimeter. One way of addressing this problem is to use a Colorimeter @@ -714,118 +720,120 @@ - - Correction Matrix. These are specific to a particular - Colorimeter and Display make and model combination, although a - matrix for a different but similar type of display may give better - results than none at all. A list of contributed ccmx files is here.
    -
    -

    Calibrating and profiling a display that - doesn't have VideoLUT access.

    -

    In some situation there is no access to a displays VideoLUT - hardware, and this hardware is what is usually used to implement - display calibration. This could be because the display is being - accessed via a web server, or because the driver or windowing - system doesn't support VideoLUT access.
    -

    -

    There are two basic options in this situation:
    -

    -

      1) Don't attempt to calibrate, just profile the display.
    -   2) Calibrate, but incorporate the calibration in some other - way in the workflow.
    -

    -

    The first case requires nothing special - just skip calibration - (see the previous section Profiling in several - steps: Creating display test values).

    -

    In the second case, there are three choices:
    -

    -

     2a) Use dispcal to create a calibration and a quick profile - that incorporates the calibration into the profile.
    -  2b) Use dispcal to create the calibration, then dispread and - colprof to create a profile, and then incorporate the calibration - into the profile using applycal.
    -  2c) Use dispcal to create the calibration, then dispread and - colprof to create a profile, and then apply the calibration after - the profile in a cctiff workflow.
    -

    -

    The first case requires nothing special, use dispcal in a normal - fashioned with the -o - option to generate a quick profile.The profile created will not contain a 'vcgt' - tag, but instead will have the calibration curves incorporated - into the profile itself. If calibration parameters are chosen that - change the displays white point or brightness, then this will - result in a slightly unusual profile that has a white point that - does not correspond with device R=G=B=1.0. Some systems may not - cope properly with this type of profile, and a general shift in - white point through such a profile can create an odd looking - display if it is applied to images but not to other elements on - the display say as GUI decoration elements or other application - windows.
    -

    -

    In the second case, the calibration file created using dispcal - should be provided to dispread using the -K flag:
    -

    -

    dispread -v - -K TargetA.cal DisplayA

    -

    Create the profile as - usual using colprof. but note that colprof will ignore the - calibration, and that no 'vcgt' tag will be added to the profile.
    - You can then use applycal to combine - the calibration into the profile. Note that the resulting profile - will be slightly unusual, since the profile is not made completely - consistent with the effects of the calibration, and the device - R=G=B=1.0 probably not longer corresponds with the PCS white or - the white point.
    -

    - In the third case, the same procedure as above is used to create a - profile, but the calibration is applied in a raster transformation - workflow explicitly, e.g.:
    -
    -     cctiff SourceProfile.icm DisplayA.icm DisplayA.cal - infile.tif outfile.tif
    - or
    -     cctiff SourceProfile.icm DisplayA.icm DisplayA.cal - infile.jpg outfile.jpg
    -
    -
    -

    Profiling Scanners and other input devices - such as cameras
    -

    - Because a scanner or camera is an input device, it is necessary to - go about profiling it in quite a different way to an output device. - To profile it, a test chart is needed to exercise the input device - response, to which the CIE values for each test patch is known. - Generally standard reflection or transparency test charts are used - for this purpose.
    -

    Types of test charts

    - The most common and popular test chart for scanner profiling is the - IT8.7/2 chart. This is a standard format chart generally reproduced - on photographic film, containing about 264 test patches.
    - An accessible and affordable source of such targets is Wolf Faust a - www.coloraid.de.
    - Another source is LaserSoft www.silverfast.com.
    - The Kodak Q-60 Color Input Target is also a typical example:
    -
    - Kodak Q60 chart image
    -
    - A very simple chart that is widely available is the Macbeth - ColorChecker chart, although it contains only 24 patches and - therefore is probably not ideal for creating profiles:
    - ColorChecker 24 patch
    -
    - Other popular charts are the X-Rite/GretagMacbeth ColorChecker DC + + + + Correction Matrix. These are specific to a particular + Colorimeter and Display make and model combination, although a + matrix for a different but similar type of display may give better + results than none at all. A list of contributed ccmx files is here.
    +
    +

    Calibrating and profiling a display that + doesn't have VideoLUT access.

    +

    In some situation there is no access to a displays VideoLUT + hardware, and this hardware is what is usually used to implement + display calibration. This could be because the display is being + accessed via a web server, or because the driver or windowing + system doesn't support VideoLUT access.
    +

    +

    There are two basic options in this situation:
    +

    +

      1) Don't attempt to calibrate, just profile the display.
    +   2) Calibrate, but incorporate the calibration in some other + way in the workflow.
    +

    +

    The first case requires nothing special - just skip calibration + (see the previous section Profiling in several + steps: Creating display test values).

    +

    In the second case, there are three choices:
    +

    +

     2a) Use dispcal to create a calibration and a quick profile + that incorporates the calibration into the profile.
    +  2b) Use dispcal to create the calibration, then dispread and + colprof to create a profile, and then incorporate the calibration + into the profile using applycal.
    +  2c) Use dispcal to create the calibration, then dispread and + colprof to create a profile, and then apply the calibration after + the profile in a cctiff workflow.
    +

    +

    The first case requires nothing special, use dispcal in a normal + fashioned with the -o + option to generate a quick profile.The profile created will not contain a 'vcgt' + tag, but instead will have the calibration curves incorporated + into the profile itself. If calibration parameters are chosen that + change the displays white point or brightness, then this will + result in a slightly unusual profile that has a white point that + does not correspond with device R=G=B=1.0. Some systems may not + cope properly with this type of profile, and a general shift in + white point through such a profile can create an odd looking + display if it is applied to images but not to other elements on + the display say as GUI decoration elements or other application + windows.
    +

    +

    In the second case, the calibration file created using dispcal + should be provided to dispread using the -K flag:
    +

    +

    dispread -v + -K TargetA.cal DisplayA

    +

    Create the profile as + usual using colprof. but note that colprof will ignore the + calibration, and that no 'vcgt' tag will be added to the profile.
    + You can then use applycal to combine + the calibration into the profile. Note that the resulting profile + will be slightly unusual, since the profile is not made completely + consistent with the effects of the calibration, and the device + R=G=B=1.0 probably not longer corresponds with the PCS white or + the white point.
    +

    + In the third case, the same procedure as above is used to create a + profile, but the calibration is applied in a raster transformation + workflow explicitly, e.g.:
    +
    +     cctiff SourceProfile.icm DisplayA.icm DisplayA.cal + infile.tif outfile.tif
    + or
    +     cctiff SourceProfile.icm DisplayA.icm DisplayA.cal + infile.jpg outfile.jpg
    +
    +
    +

    Profiling Scanners and other input devices + such as cameras
    +

    + Because a scanner or camera is an input device, it is necessary to + go about profiling it in quite a different way to an output device. + To profile it, a test chart is needed to exercise the input device + response, to which the CIE values for each test patch is known. + Generally standard reflection or transparency test charts are used + for this purpose.
    +

    Types of test charts

    + The most common and popular test chart for scanner profiling is the + IT8.7/2 chart. This is a standard format chart generally reproduced + on photographic film, containing about 264 test patches.
    + An accessible and affordable source of such targets is Wolf Faust a + www.coloraid.de.
    + Another source is LaserSoft www.silverfast.com.
    + The Kodak Q-60 Color Input Target is also a typical example:
    +
    + Kodak Q60 chart image
    +
    + A very simple chart that is widely available is the Macbeth + ColorChecker chart, although it contains only 24 patches and + therefore is probably not ideal for creating profiles:
    + ColorChecker 24 patch
    +
    + Other popular charts are the X-Rite/GretagMacbeth ColorChecker DC and ColorChecker @@ -883,18 +891,20 @@ - - SG charts:
    -
    - GretagMacbeth ColorChecker DC chart ColorChecker SG
    -
    - The GretagMacbeth Eye-One Pro Scan Target 1.4 can also be used:
    -
    - Eye-One Scan Target 1.4
    -
    + + + + SG charts:
    +
    + GretagMacbeth ColorChecker DC chart ColorChecker SG
    +
    + The GretagMacbeth Eye-One Pro Scan Target 1.4 can also be used:
    +
    + Eye-One Scan Target 1.4
    +
    Also supported is the HutchColor @@ -952,23 +962,25 @@ - - HCT :
    -
    - HutchColor HCT
    -
    -
    - and Christophe - Métairie's Digital TargeT 003 and Christophe - Métairie's Digital Target - 4 :
    -
    - CMP_DT_003  CMP_Digital_Target-4
    -
    + + + + HCT :
    +
    + HutchColor HCT
    +
    +
    + and Christophe + Métairie's Digital TargeT 003 and Christophe + Métairie's Digital Target - 4 :
    +
    + CMP_DT_003  CMP_Digital_Target-4
    +
    and the LaserSoft @@ -1026,20 +1038,28 @@ - - Imaging DCPro Target:
    -
    - LaserSoft DCPro
-      Target
    -
    - The Datacolor SpyderCheckr:
    -
    - Datacolor
-      SpyderCheckr
    -
    - One of the QPcard's:
    - :
    +
    + LaserSoft DCPro
+      Target
    +
    + The Datacolor
    SpyderCheckr:
    +
    + Datacolor
+      SpyderCheckr
    +
    + The Datacolor SpyderCheckr24:
    +
    + SpyderCheckr24
    +
    + One of the QPcard's:
    + QPcard @@ -1091,8 +1111,10 @@ - - 201:            :            QPcard @@ -1144,87 +1166,89 @@ href="http://www.qpcard.com/en_b2c/color-reference-cards/instant-camera-raw-prof - - 202:
    -
    - QPCard201        -             QPcard202
    -
    -

    Taking readings from a scanner or camera
    -

    - The test chart you are using needs to be placed on the scanner, and - the scanner needs to be configured to a suitable state, and restored - to that same state when used subsequently with the resulting - profile. For a camera, the chart needs to be lit in a controlled and - even manner using the light source that will be used for subsequent - photographs, and should be shot so as to minimise any geometric - distortion, although the scanin -p flag - may be used to compensate for some degree of distortion. As with any - color profiling task, it is important to setup a known and - repeatable image processing flow, to ensure that the resulting - profile will be usable.
    -
    - The chart should be captured and saved to a TIFF format file. I will - assume the resulting file is called scanner.tif. The raster file - need only be roughly cropped so as to contain the test chart - (including the charts edges).
    -
    - The second step is to extract the RGB values from the scanner.tif - file, and match then to the reference CIE values. To locate the - patch values in the scan, the scanin tool needs to be given - a template .cht file that - describes the features of the chart, and how the test patches are - labeled. Also needed is a file containing the CIE values for each of - the patches in the chart, which is typically supplied with the - chart, available from the manufacturers web site, or has been - measured using a spectrometer.
    -
    -
    For an IT8.7/2 chart, this is the ref/it8.cht file - supplied with Argyll, and  the manufacturer will will supply - an individual or batch average file along with the chart - containing this information, or downloadable from their web site. - For instance, Kodak Q60 target reference files are here.
    - NOTE that the reference file for the IT8.7/2 chart supplied with Monaco EZcolor can be - obtained by unzipping the .mrf file. (You may have to make a copy - of the file with a .zip extension to do this.)
    -
    - For the ColorChecker 24 patch chart, the ref/ColorChecker.cht file - should be used, and there is also a ref/ColorChecker.cie file provided that is based - on the manufacturers reference values for the chart. You can also - create your own reference file using an instrument and chartread, - making use of the chart reference file ref/ColorChecker.ti2:
    -    chartread -n - ColorChecker.ti2
    - Note that due to the small number of patches, a profile created - from such a chart is not likely to be very detailed.
    -
    - For the ColorChecker DC chart, the ref/ColorCheckerDC.cht file should be used, and - there will be a ColorCheckerDC reference file supplied by - X-Rite/GretagMacbeth with the chart.
    -
    - The ColorChecker SG is relatively expensive, but is preferred by - many people because (like the ColorChecker and ColorCheckerDC) its - colors are composed of multiple different pigments, giving it - reflective spectra that are more representative of the real world, - unlike many other charts that are created out of combination of 3 - or 4 colorants.
    - A limited CIE reference file is available from X-Rite here, - but it is not in the usual CGATS format. To convert it to a CIE - reference file useful for scanin, - you will need to edit the X-Rite file using a plain text editor, - first deleting everything before the line starting with "A1" and + + + + 202:
    +
    + QPCard201        +             QPcard202
    +
    +

    Taking readings from a scanner or camera
    +

    + The test chart you are using needs to be placed on the scanner, and + the scanner needs to be configured to a suitable state, and restored + to that same state when used subsequently with the resulting + profile. For a camera, the chart needs to be lit in a controlled and + even manner using the light source that will be used for subsequent + photographs, and should be shot so as to minimise any geometric + distortion, although the scanin -p flag + may be used to compensate for some degree of distortion. As with any + color profiling task, it is important to setup a known and + repeatable image processing flow, to ensure that the resulting + profile will be usable.
    +
    + The chart should be captured and saved to a TIFF format file. I will + assume the resulting file is called scanner.tif. The raster file + need only be roughly cropped so as to contain the test chart + (including the charts edges).
    +
    + The second step is to extract the RGB values from the scanner.tif + file, and match then to the reference CIE values. To locate the + patch values in the scan, the scanin tool needs to be given + a template .cht file that + describes the features of the chart, and how the test patches are + labeled. Also needed is a file containing the CIE values for each of + the patches in the chart, which is typically supplied with the + chart, available from the manufacturers web site, or has been + measured using a spectrometer.
    +
    +
    For an IT8.7/2 chart, this is the ref/it8.cht file + supplied with Argyll, and  the manufacturer will will supply + an individual or batch average file along with the chart + containing this information, or downloadable from their web site. + For instance, Kodak Q60 target reference files are here.
    + NOTE that the reference file for the IT8.7/2 chart supplied with Monaco EZcolor can be + obtained by unzipping the .mrf file. (You may have to make a copy + of the file with a .zip extension to do this.)
    +
    + For the ColorChecker 24 patch chart, the ref/ColorChecker.cht file + should be used, and there is also a ref/ColorChecker.cie file provided that is based + on the manufacturers reference values for the chart. You can also + create your own reference file using an instrument and chartread, + making use of the chart reference file ref/ColorChecker.ti2:
    +    chartread -n + ColorChecker.ti2
    + Note that due to the small number of patches, a profile created + from such a chart is not likely to be very detailed.
    +
    + For the ColorChecker DC chart, the ref/ColorCheckerDC.cht file should be used, and + there will be a ColorCheckerDC reference file supplied by + X-Rite/GretagMacbeth with the chart.
    +
    + The ColorChecker SG is relatively expensive, but is preferred by + many people because (like the ColorChecker and ColorCheckerDC) its + colors are composed of multiple different pigments, giving it + reflective spectra that are more representative of the real world, + unlike many other charts that are created out of combination of 3 + or 4 colorants.
    + A limited CIE reference file is available from X-Rite here, + but it is not in the usual CGATS format. To convert it to a CIE + reference file useful for scanin, + you will need to edit the X-Rite file using a plain text editor, + first deleting everything before the line starting with "A1" and everything after "N10", then prepending this @@ -1281,83 +1305,95 @@ href="http://www.xrite.com/documents/apps/public/digital_colorchecker_sg_l_a_b.t - - header, and appending this footer, - making sure there are no blank lines inserted in the process. - There are reports that X-Rite have experimented with different ink - formulations for certain patches, so the above reference may not - be as accurate as desired, and it is preferable to measure your - own chart using a spectrometer, if you have the capability.
    - If you do happen to have access to a more comprehensive instrument - measurement of the ColorChecker SG, or you have measured it - yourself using a color instrument,
    - then you may - need to convert the reference information from spectral ColorCheckerSG.txt file to CIE - value ColorCheckerSG.cie - reference file, follow the following steps:
    -      txt2ti3 - ColorCheckerSG.txt ColorCheckerSG
    -      spec2cie - ColorCheckerSG.ti3 ColorCheckerSG.cie
    -
    - For the Eye-One Pro Scan Target 1.4 chart, the ref/i1_RGB_Scan_1.4.cht - file should be used, and as there is no reference file - accompanying this chart, the chart needs to be read with an - instrument (usually the Eye-One Pro). This can be done using - chartread,  making use of the chart reference file ref/i1_RGB_Scan_1.4.ti2:
    -     chartread -n - i1_RGB_Scan_1.4
    - and then rename the resulting i1_RGB_Scan_1.4.ti3 - file to i1_RGB_Scan_1.4.cie
    -
    - For the HutchColor HCT chart, the ref/Hutchcolor.cht - file should be used, and the reference .txt file downloaded from the HutchColor website.
    -
    - For the Christophe Métairie's Digital TargeT 003 chart with 285 - patches, the ref/CMP_DT_003.cht - file should be used, and the cie reference files come with the chart.
    -
    - For the Christophe Métairie's Digital Target-4 chart with 570 - patches, the ref/CMP_Digital_Target-4.cht - file should be used, and the cie reference files come with the chart.
    -
    - For the LaserSoft DCPro chart, the ref/LaserSoftDCPro.cht file should be used, and - reference .txt file - downloaded from the Silverfast - website.
    -
    - For the Datacolor SpyderCheckr, the ref/SpyderChecker.cht file should be used, and a - reference ref/SpyderChecker.cie - file made from measuring a sample chart is also available. - Alternately you could create your own reference file by - transcribing the values - on the Datacolor website.
    -
    - For the QPCard 201, the ref/QPcard_201.cht - file should be used, and a reference ref/QPcard_201.cie file made from measuring a - sample chart is also available.
    -
    - For the QPCard 202, the ref/QPcard_202.cht - file should be used, and a reference ref/QPcard_202.cie file made from measuring a - sample chart is also available.
    -
    -
    - For any other type of chart, a chart recognition template file will - need to be created (this is beyond the scope of the current + + + + header, and appending this footer, + making sure there are no blank lines inserted in the process. + There are reports that X-Rite have experimented with different ink + formulations for certain patches, so the above reference may not + be as accurate as desired, and it is preferable to measure your + own chart using a spectrometer, if you have the capability.
    + If you do happen to have access to a more comprehensive instrument + measurement of the ColorChecker SG, or you have measured it + yourself using a color instrument,
    + then you may + need to convert the reference information from spectral ColorCheckerSG.txt file to CIE + value ColorCheckerSG.cie + reference file, follow the following steps:
    +      txt2ti3 + ColorCheckerSG.txt ColorCheckerSG
    +      spec2cie + ColorCheckerSG.ti3 ColorCheckerSG.cie
    +
    + For the Eye-One Pro Scan Target 1.4 chart, the ref/i1_RGB_Scan_1.4.cht + file should be used, and as there is no reference file + accompanying this chart, the chart needs to be read with an + instrument (usually the Eye-One Pro). This can be done using + chartread,  making use of the chart reference file ref/i1_RGB_Scan_1.4.ti2:
    +     chartread -n + i1_RGB_Scan_1.4
    + and then rename the resulting i1_RGB_Scan_1.4.ti3 + file to i1_RGB_Scan_1.4.cie
    +
    + For the HutchColor HCT chart, the ref/Hutchcolor.cht + file should be used, and the reference .txt file downloaded from the HutchColor website.
    +
    + For the Christophe Métairie's Digital TargeT 003 chart with 285 + patches, the ref/CMP_DT_003.cht + file should be used, and the cie reference files come with the chart.
    +
    + For the Christophe Métairie's Digital Target-4 chart with 570 + patches, the ref/CMP_Digital_Target-4.cht + file should be used, and the cie reference files come with the chart.
    +
    + For the LaserSoft DCPro chart, the ref/LaserSoftDCPro.cht file should be used, and + reference .txt file + downloaded from the Silverfast + website.
    +
    + For the Datacolor SpyderCheckr, the ref/SpyderChecker.cht file should be used, and a + reference ref/SpyderChecker.cie + file made from measuring a sample chart is also available. + Alternately you could create your own reference file by + transcribing the values + on the Datacolor website.
    +
    + For the Datacolor SpyderCheckr, the ref/SpyderChecker24.cht file should be used, and a + reference ref/SpyderChecker24.cie + + file made from measuring a sample chart is also available. + Alternately you could create your own reference file by + transcribing the values + on the Datacolor website.
    +
    + For the QPCard 201, the ref/QPcard_201.cht + file should be used, and a reference ref/QPcard_201.cie file made from measuring a + sample chart is also available.
    +
    + For the QPCard 202, the ref/QPcard_202.cht + file should be used, and a reference ref/QPcard_202.cie file made from measuring a + sample chart is also available.
    +
    +
    + For any other type of chart, a chart recognition template file will + need to be created (this is beyond the scope of the current documentation, although see  the .cht_format @@ -1414,403 +1450,405 @@ href="http://www.xrite.com/documents/apps/public/digital_colorchecker_sg_l_a_b.t - - documentation).
    -
    - To create the scanner .ti3 file, run the scanin tool as - follows (assuming an IT8 chart is being used):
    -
    - scanin -v scanner.tif It8.cht It8ref.txt
    -
    - "It8ref.txt" or "It8ref.cie" is assumed to be the name of the CIE - reference file supplied by the chart manufacturer. The resulting - file will be named "scanner.ti3".
    -
    - scanin will process 16 bit - per component .tiff files, which (if the scanner is capable of - creating such files),  may improve the quality of the profile. -
    -
    - If you have any doubts about the correctness of the chart - recognition, or the subsequent profile's delta E report is unusual, - then use the scanin diagnostic flags -dipn - and examine the diag.tif - diagnostic file, to make sure that the patches are identified and - aligned correctly. If you have problems getting good automatic - alignment, then consider doing a manual alignment by locating the - fiducial marks on your scan, and feeding them into scanin -F parameters. The fiducial marks should - be listed in a clockwise direction starting at the top left.
    -

    Creating a scanner or camera input profile

    - Similar to a display profile, an input profile can be either a - shaper/matrix or LUT based profile. Well behaved input devices will - probably give the best results with a shaper/matrix profile, and - this may also be the best choice if your test chart has a small or - unevenly distributed set of test patchs (ie. the IT8.7.2). If a - shaper/matrix profile is a poor fit, consider using a LUT type - profile.
    -
    - When creating a LUT type profile, there is the choice of XYZ or - L*a*b* PCS (Device independent, Profile Connection Space). Often for - input devices, it is better to choose the XYZ PCS, as this may be a - better fit given that input devices are usually close to being - linearly additive in behaviour.
    -
    - If the purpose of the input profile is to use it as a substitute for - a colorimeter, then the -u flag should be used to avoid - clipping values above the white point. Unless the shaper/matrix type - profile is a very good fit, it is probably advisable to use a LUT - type profile in this situation.
    -
    - To create a matrix/shaper profile, the following suffices:
    -
    - colprof -v - -D"Scanner A" - -qm -as scanner
    -
    - For an XYZ PCS LUT based profile then the following would be used:
    -
    - colprof -v - -D"Scanner A" -qm - -ax scanner
    -
    - For the purposes of a poor mans colorimeter, the following would - generally be used:
    -
    - colprof -v - -D"Scanner A" -qm - -ax -u scanner
    -
    - Make sure you check the delta E report at the end of the profile - creation, to see if the sample data and profile is behaving - reasonably. Depending on the type of device, and the consistency of - the readings, average errors of 5 or less, and maximum errors of 15 - or less would normally be expected. If errors are grossly higher - than this, then this is an indication that something is seriously - wrong with the device measurement, or profile creation.
    -
    - If profiling a camera in RAW mode, then there may be some - advantage in creating a pure matrix only profile, in which it is - assumed that the camera response is completely linear. This may - reduce extrapolation artefacts. If setting the white point will be - done in some application, then it may also be an advantage to use - the -u flag and avoid - setting the white point to that of the profile chart:
    -
    - colprof -v - -D"Camera" -qm - -am -u scanner
    -
    -
    -
    -

    Profiling Printers
    -

    - The overall process is to create a set of device measurement target - values, print them out, measure them, and then create an ICC profile - from the measurements. If the printer is an RGB based printer, then - the process is only slightly more complicated than profiling a - display. If the printer is CMYK based, then some additional - parameters are required to set the total ink limit (TAC) and -  black generation curve.
    -

    Creating a print profile test chart

    - The first step in profiling any output device, is to create a set of - device colorspace test values. The important parameters needed are:
    -
      -
    • What colorspace does the device use ?
    • -
    • How many test patches do I want to use/what paper size do I - want to use ?
    • -
    • What instrument am I going to use to read the patches ?
      -
    • -
    • If it is a CMYK device, what is the total ink limit ?
      -
    • -
    • What information do I already have about how the device - behaves ?
    • -
    - Most printers running through simple drivers will appear as if they - are RGB devices. In fact there is no such thing as a real RGB - printer, since printers use white media and the colorant must - subtract from the light reflected on it to create color, but the - printer itself turns the incoming RGB into the native print - colorspace, so for this reason we will tell targen to use the "Print - RGB" colorspace, so that it knows that it's really a subtractive - media. Other drivers will drive a printer more directly, and will - expect a CMYK profile. [Currently Argyll is not capable of creating - an ICC profile for devices with more colorants than CMYK. When this - capability is introduced, it will by creating an additional - separation profile which then allows the printer to be treated as a - CMY or CMYK printer.] One way of telling what sort of profile is - expected for your device is to examine an existing profile for that - device using iccdump.
    -
    - The number of test patches will depend somewhat on what quality - profile you want to make, how well behaved the printer is, as well - as the effort needed to read the number of test values. Generally it - is convenient to fill a certain paper size with the maximum number - of test values that will fit.
    -
    - At a minimum, for an "RGB" device, a few hundred values are needed - (400-1000). For high quality CMYK profiles, 1000-3000 is not an - unreasonable number of patches.
    -
    - To assist the determination of test patch values, it can help to - have a rough idea of how the device behaves, so that the device test - point locations can be pre-conditioned. This could be in the form of - an ICC profile of a similar device, or a lower quality, or previous - profile for that particular device. If one were going to make a very - high quality Lut based profile, then it might be worthwhile to make - up a smaller, preliminary shaper/matrix profile using a few hundred - test points, before embarking on testing the device with several - thousand.
    -
    - The documentation for the targen tool - lists a table - of paper sizes and number of  patches for typical situations.
    -
    - For a CMYK device, a total ink limit usually needs to be specified. - Sometimes a device will have a maximum total ink limit set by its - manufacturer or operator, and some CMYK systems (such as chemical - proofing systems) don't have any limit. Typical printing devices - such as Xerographic printers, inkjet printers and printing presses - will have a limit. The exact procedure for determining an ink limit - is outside the scope of this document, but one way of going about - this might be to generate some small (say a few hundred patches) - with targen & pritntarg with different total ink limits, and - printing them out, making the ink limit as large as possible without - striking problems that are caused by too much ink.
    -
    - Generally one wants to use the maximum possible amount of ink to - maximize the gamut available on the device. For most CMYK devices, - an ink limit between 200 and 400 is usual, but and ink limit of 250% - or over is generally desirable for reasonably dense blacks and dark - saturated colors. And ink limit of less than 200% will begin to - compromise the fully saturated gamut, as secondary colors (ie - combinations of any two primary colorants) will not be able to reach - full strength.
    -
    - Once an ink limit is used in printing the characterization test - chart for a device, it becomes a critical parameter in knowing what - the characterized gamut of the device is. If after printing the test - chart, a greater ink limit were to be used, the the software would - effectively be extrapolating the device behaviour at total ink - levels beyond that used in the test chart, leading to inaccuracies.
    -
    - Generally in Argyll, the ink limit is established when creating the - test chart values, and then carried through the profile making - process automatically. Once the profile has been made however, the - ink limit is no longer recorded, and you, the user, will have to - keep track of it if the ICC profile is used in any program than - needs to know the usable gamut of the device.
    -
    -
    - Lets consider two devices in our examples, "PrinterA" which is an - "RGB" device, and "PrinterB" which is CMYK, and has a target ink - limit of 250%.
    -
    - The simplest approach is to make a set of test values that is - independent of the characteristics of the particular device:
    -
    - targen -v -  -d2 -f1053 - PrinterA
    -
    - targen -v -  -d4 -l260 - -f1053 PrinterB
    -
    - The number of patches chosen here happens to be right for an A4 - paper size being read using a Spectroscan instrument. See the table in  the targen documentation for some other - suggested numbers.
    -
    - If there is a preliminary or previous profile called "OldPrinterA" - available, and we want to try creating a "pre-conditioned" set of - test values that will more efficiently sample the device response, - then the following would achieve this:
    -

    - targen -v -  -d2 -f1053 - -c OldPrinterA PrinterA
    -
    - targen -v -  -d4 -l260 - -f1053 -c - OldPrinterB PrinterB
    -
    -
    - The output of targen will be the file PrinterA.ti1 and - PrinterB.ti1 respectively, containing the device space test values, - as well as expected CIE values used for chart recognition purposes.
    -
    -

    Printing a print profile test chart
    -
    -

    - The next step is turn the test values in to a PostScript or TIFF - raster test file that can printed on the device. The basic - information that needs to be supplied is the type of instrument that - will be used to read the patches, as well as the paper size it is to - be formatted for.
    -
    - For an X-Rite DTP41, the following would be typical:
    -
    - printtarg -v - -i41 -pA4 - PrinterA
    -  
    - For a Gretag Eye-One Pro, the following would be typical:
    -
    - printtarg -v - -ii1 -pA4 - PrinterA
    -
    - For using with a scanner as a colorimeter, the Gretag Spectroscan - layout is suitable, but the -s flag - should be used so as to generate a layout suitable for scan - recognition, as well as generating the scan recognition template - files. (You probably want to use less patches with targen, when using the printtarg -s flag, e.g. 1026 - patches for an A4R page, etc.) The following would be typical:
    -
    - printtarg -v - -s -iSS - -pA4R PrinterA
    -
    - printtarg
    reads the PrinterA.ti1 file, creates a - PrinterA.ti2 file containing the layout information as well as the - device values and expected CIE values, as well as a PrinterA.ps file - containing the test chart. If the -s - flag is used, one or more PrinterA.cht files is created to allow the - scanin program to recognize the chart.
    -
    - To create TIFF raster files rather than PostScript, use the -t - flag.
    -
    - GSview is a good program to - use to check what the PostScript file will look like, without - actually printing it out. You could also use Photoshop or ImageMagick for this purpose.
    -
    - The last step is to print the chart out.
    -
    - Using a suitable PostScript or raster file printing program, - downloader, print the chart. If you are not using a TIFF test chart, - and you do not have a PostScript capable printer, then an - interpreter like GhostScript or even Photoshop could be used to - rasterize the file into something that can be printed. Note that it - is important that the PostScript interpreter or TIFF printing - application and printer configuration is setup for a device - profiling run, and that any sort of color conversion of color - correction be turned off so that the device values in the PostScript - or TIFF file are sent directly to the device. If the device has a - calibration system, then it would be usual to have setup and - calibrated the device before starting the profiling run, and to - apply calibration to the chart values. If Photoshop was to be used, - then either the chart needs to be a single page, or separate .eps or - .tiff files for each page should be used, so that they can be - converted and printed one at a time (see the -e and -t - flags).
    -
    -

    Reading a print test chart using an instrument

    - Once the test chart has been printed, the color of the patches needs - to be read using a suitable instrument.
    -
    - Several different instruments are currently supported, some that - need to be used patch by patch, some read a strip at a time, and - some read a sheet at a time. See instruments - for a current list.
    -
    - The instrument needs to be connected to your computer before running - the chartread command. Both serial - port and USB connected Instruments are supported. A serial port to - USB adapter might have to be used if your computer doesn't have any - serial ports, and you have a serial interface connected instrument.
    -
    - If you run chartread so as to print - out its usage message (ie. by using a -? or -- - flags), then it will list any identified serial ports or USB - connected instruments, and their corresponding number for the -c option. By default, chartread will try to connect to the - first available USB instrument, or an instrument on the first serial - port.
    -
    - The only arguments required is to specify the basename of the .ti2 - file. If a non-default serial port is to be used, then the -c option would also be - specified.
    -
    -  e.g. for a Spectroscan on the second port:
    -
    - chartread -c2 - PrinterA
    -
    - For a DTP41 to the default serial port:
    -
    - chartread - PrinterA
    -
    - chartread will interactively - prompt you through the process of reading each sheet or strip. See chartread for more details on the - responses for each type of instrument. Continue with Creating a printer profile.
    -
    -

    Reading a print test chart using a scanner or - camera
    -

    -
    - Argyll supports using a scanner or even a camera as a substitute for - a colorimeter. While a scanner or camera is no replacement for a - color measurement instrument, it may give acceptable results in some - situations, and may give better results than a generic profile for a - printing device.
    -
    - The main limitation of the scanner-as-colorimeter approach are:
    -
    - * The scanner dynamic range and/or precision may not match the - printers or what is required for a good profile.
    - * The spectral interaction of the scanner test chart and printer - test chart with the scanner spectral response can cause color - errors.
    - * Spectral differences caused by different black amounts in the - print test chart can cause color errors.
    - * The scanner reference chart gamut may be much smaller than the - printers gamut, making the scanner profile too inaccurate to be - useful.
    -
    - As well as some of the above, a camera may not be suitable if it - automatically adjusts exposure or white point when taking a picture, - and this behavior cannot be disabled.
    -
    - The end result is often a profile that has a noticeable color cast, - compared to a profile created using a colorimeter or spectrometer.
    -
    -
    - It is assumed that you have created a scanner or camera profile - following the procedure - outline above. For best possible results it is advisable to both - profile the scanner or camera, and use it in scanning the printed - test chart, in as "raw" mode as possible (i.e. using 16 bits per - component images, if the scanner or camera is capable of doing so; - not setting white or black points, using a fixed exposure etc.). It - is generally advisable to create a LUT type input profile, and use - the -u - flag to avoid clipping scanned value whiter than the input - calibration chart.
    -
    - Scan or photograph your printer chart (or charts) on the scanner or + + + + documentation).
    +
    + To create the scanner .ti3 file, run the scanin tool as + follows (assuming an IT8 chart is being used):
    +
    + scanin -v scanner.tif It8.cht It8ref.txt
    +
    + "It8ref.txt" or "It8ref.cie" is assumed to be the name of the CIE + reference file supplied by the chart manufacturer. The resulting + file will be named "scanner.ti3".
    +
    + scanin will process 16 bit + per component .tiff files, which (if the scanner is capable of + creating such files),  may improve the quality of the profile. +
    +
    + If you have any doubts about the correctness of the chart + recognition, or the subsequent profile's delta E report is unusual, + then use the scanin diagnostic flags -dipn + and examine the diag.tif + diagnostic file, to make sure that the patches are identified and + aligned correctly. If you have problems getting good automatic + alignment, then consider doing a manual alignment by locating the + fiducial marks on your scan, and feeding them into scanin -F parameters. The fiducial marks should + be listed in a clockwise direction starting at the top left.
    +

    Creating a scanner or camera input profile

    + Similar to a display profile, an input profile can be either a + shaper/matrix or LUT based profile. Well behaved input devices will + probably give the best results with a shaper/matrix profile, and + this may also be the best choice if your test chart has a small or + unevenly distributed set of test patchs (ie. the IT8.7.2). If a + shaper/matrix profile is a poor fit, consider using a LUT type + profile.
    +
    + When creating a LUT type profile, there is the choice of XYZ or + L*a*b* PCS (Device independent, Profile Connection Space). Often for + input devices, it is better to choose the XYZ PCS, as this may be a + better fit given that input devices are usually close to being + linearly additive in behaviour.
    +
    + If the purpose of the input profile is to use it as a substitute for + a colorimeter, then the -u flag should be used to avoid + clipping values above the white point. Unless the shaper/matrix type + profile is a very good fit, it is probably advisable to use a LUT + type profile in this situation.
    +
    + To create a matrix/shaper profile, the following suffices:
    +
    + colprof -v + -D"Scanner A" + -qm -as scanner
    +
    + For an XYZ PCS LUT based profile then the following would be used:
    +
    + colprof -v + -D"Scanner A" -qm + -ax scanner
    +
    + For the purposes of a poor mans colorimeter, the following would + generally be used:
    +
    + colprof -v + -D"Scanner A" -qm + -ax -u scanner
    +
    + Make sure you check the delta E report at the end of the profile + creation, to see if the sample data and profile is behaving + reasonably. Depending on the type of device, and the consistency of + the readings, average errors of 5 or less, and maximum errors of 15 + or less would normally be expected. If errors are grossly higher + than this, then this is an indication that something is seriously + wrong with the device measurement, or profile creation.
    +
    + If profiling a camera in RAW mode, then there may be some + advantage in creating a pure matrix only profile, in which it is + assumed that the camera response is completely linear. This may + reduce extrapolation artefacts. If setting the white point will be + done in some application, then it may also be an advantage to use + the -u flag and avoid + setting the white point to that of the profile chart:
    +
    + colprof -v + -D"Camera" -qm + -am -u scanner
    +
    +
    +
    +

    Profiling Printers
    +

    + The overall process is to create a set of device measurement target + values, print them out, measure them, and then create an ICC profile + from the measurements. If the printer is an RGB based printer, then + the process is only slightly more complicated than profiling a + display. If the printer is CMYK based, then some additional + parameters are required to set the total ink limit (TAC) and +  black generation curve.
    +

    Creating a print profile test chart

    + The first step in profiling any output device, is to create a set of + device colorspace test values. The important parameters needed are:
    +
      +
    • What colorspace does the device use ?
    • +
    • How many test patches do I want to use/what paper size do I + want to use ?
    • +
    • What instrument am I going to use to read the patches ?
      +
    • +
    • If it is a CMYK device, what is the total ink limit ?
      +
    • +
    • What information do I already have about how the device + behaves ?
    • +
    + Most printers running through simple drivers will appear as if they + are RGB devices. In fact there is no such thing as a real RGB + printer, since printers use white media and the colorant must + subtract from the light reflected on it to create color, but the + printer itself turns the incoming RGB into the native print + colorspace, so for this reason we will tell targen to use the "Print + RGB" colorspace, so that it knows that it's really a subtractive + media. Other drivers will drive a printer more directly, and will + expect a CMYK profile. [Currently Argyll is not capable of creating + an ICC profile for devices with more colorants than CMYK. When this + capability is introduced, it will by creating an additional + separation profile which then allows the printer to be treated as a + CMY or CMYK printer.] One way of telling what sort of profile is + expected for your device is to examine an existing profile for that + device using iccdump.
    +
    + The number of test patches will depend somewhat on what quality + profile you want to make, how well behaved the printer is, as well + as the effort needed to read the number of test values. Generally it + is convenient to fill a certain paper size with the maximum number + of test values that will fit.
    +
    + At a minimum, for an "RGB" device, a few hundred values are needed + (400-1000). For high quality CMYK profiles, 1000-3000 is not an + unreasonable number of patches.
    +
    + To assist the determination of test patch values, it can help to + have a rough idea of how the device behaves, so that the device test + point locations can be pre-conditioned. This could be in the form of + an ICC profile of a similar device, or a lower quality, or previous + profile for that particular device. If one were going to make a very + high quality Lut based profile, then it might be worthwhile to make + up a smaller, preliminary shaper/matrix profile using a few hundred + test points, before embarking on testing the device with several + thousand.
    +
    + The documentation for the targen tool + lists a table + of paper sizes and number of  patches for typical situations.
    +
    + For a CMYK device, a total ink limit usually needs to be specified. + Sometimes a device will have a maximum total ink limit set by its + manufacturer or operator, and some CMYK systems (such as chemical + proofing systems) don't have any limit. Typical printing devices + such as Xerographic printers, inkjet printers and printing presses + will have a limit. The exact procedure for determining an ink limit + is outside the scope of this document, but one way of going about + this might be to generate some small (say a few hundred patches) + with targen & pritntarg with different total ink limits, and + printing them out, making the ink limit as large as possible without + striking problems that are caused by too much ink.
    +
    + Generally one wants to use the maximum possible amount of ink to + maximize the gamut available on the device. For most CMYK devices, + an ink limit between 200 and 400 is usual, but and ink limit of 250% + or over is generally desirable for reasonably dense blacks and dark + saturated colors. And ink limit of less than 200% will begin to + compromise the fully saturated gamut, as secondary colors (ie + combinations of any two primary colorants) will not be able to reach + full strength.
    +
    + Once an ink limit is used in printing the characterization test + chart for a device, it becomes a critical parameter in knowing what + the characterized gamut of the device is. If after printing the test + chart, a greater ink limit were to be used, the the software would + effectively be extrapolating the device behaviour at total ink + levels beyond that used in the test chart, leading to inaccuracies.
    +
    + Generally in Argyll, the ink limit is established when creating the + test chart values, and then carried through the profile making + process automatically. Once the profile has been made however, the + ink limit is no longer recorded, and you, the user, will have to + keep track of it if the ICC profile is used in any program than + needs to know the usable gamut of the device.
    +
    +
    + Lets consider two devices in our examples, "PrinterA" which is an + "RGB" device, and "PrinterB" which is CMYK, and has a target ink + limit of 250%.
    +
    + The simplest approach is to make a set of test values that is + independent of the characteristics of the particular device:
    +
    + targen -v +  -d2 -f1053 + PrinterA
    +
    + targen -v +  -d4 -l260 + -f1053 PrinterB
    +
    + The number of patches chosen here happens to be right for an A4 + paper size being read using a Spectroscan instrument. See the table in  the targen documentation for some other + suggested numbers.
    +
    + If there is a preliminary or previous profile called "OldPrinterA" + available, and we want to try creating a "pre-conditioned" set of + test values that will more efficiently sample the device response, + then the following would achieve this:
    +

    + targen -v +  -d2 -f1053 + -c OldPrinterA PrinterA
    +
    + targen -v +  -d4 -l260 + -f1053 -c + OldPrinterB PrinterB
    +
    +
    + The output of targen will be the file PrinterA.ti1 and + PrinterB.ti1 respectively, containing the device space test values, + as well as expected CIE values used for chart recognition purposes.
    +
    +

    Printing a print profile test chart
    +
    +

    + The next step is turn the test values in to a PostScript or TIFF + raster test file that can printed on the device. The basic + information that needs to be supplied is the type of instrument that + will be used to read the patches, as well as the paper size it is to + be formatted for.
    +
    + For an X-Rite DTP41, the following would be typical:
    +
    + printtarg -v + -i41 -pA4 + PrinterA
    +  
    + For a Gretag Eye-One Pro, the following would be typical:
    +
    + printtarg -v + -ii1 -pA4 + PrinterA
    +
    + For using with a scanner as a colorimeter, the Gretag Spectroscan + layout is suitable, but the -s flag + should be used so as to generate a layout suitable for scan + recognition, as well as generating the scan recognition template + files. (You probably want to use less patches with targen, when using the printtarg -s flag, e.g. 1026 + patches for an A4R page, etc.) The following would be typical:
    +
    + printtarg -v + -s -iSS + -pA4R PrinterA
    +
    + printtarg
    reads the PrinterA.ti1 file, creates a + PrinterA.ti2 file containing the layout information as well as the + device values and expected CIE values, as well as a PrinterA.ps file + containing the test chart. If the -s + flag is used, one or more PrinterA.cht files is created to allow the + scanin program to recognize the chart.
    +
    + To create TIFF raster files rather than PostScript, use the -t + flag.
    +
    + GSview is a good program to + use to check what the PostScript file will look like, without + actually printing it out. You could also use Photoshop or ImageMagick for this purpose.
    +
    + The last step is to print the chart out.
    +
    + Using a suitable PostScript or raster file printing program, + downloader, print the chart. If you are not using a TIFF test chart, + and you do not have a PostScript capable printer, then an + interpreter like GhostScript or even Photoshop could be used to + rasterize the file into something that can be printed. Note that it + is important that the PostScript interpreter or TIFF printing + application and printer configuration is setup for a device + profiling run, and that any sort of color conversion of color + correction be turned off so that the device values in the PostScript + or TIFF file are sent directly to the device. If the device has a + calibration system, then it would be usual to have setup and + calibrated the device before starting the profiling run, and to + apply calibration to the chart values. If Photoshop was to be used, + then either the chart needs to be a single page, or separate .eps or + .tiff files for each page should be used, so that they can be + converted and printed one at a time (see the -e and -t + flags).
    +
    +

    Reading a print test chart using an instrument

    + Once the test chart has been printed, the color of the patches needs + to be read using a suitable instrument.
    +
    + Several different instruments are currently supported, some that + need to be used patch by patch, some read a strip at a time, and + some read a sheet at a time. See instruments + for a current list.
    +
    + The instrument needs to be connected to your computer before running + the chartread command. Both serial + port and USB connected Instruments are supported. A serial port to + USB adapter might have to be used if your computer doesn't have any + serial ports, and you have a serial interface connected instrument.
    +
    + If you run chartread so as to print + out its usage message (ie. by using a -? or -- + flags), then it will list any identified serial ports or USB + connected instruments, and their corresponding number for the -c option. By default, chartread will try to connect to the + first available USB instrument, or an instrument on the first serial + port.
    +
    + The only arguments required is to specify the basename of the .ti2 + file. If a non-default serial port is to be used, then the -c option would also be + specified.
    +
    +  e.g. for a Spectroscan on the second port:
    +
    + chartread -c2 + PrinterA
    +
    + For a DTP41 to the default serial port:
    +
    + chartread + PrinterA
    +
    + chartread will interactively + prompt you through the process of reading each sheet or strip. See chartread for more details on the + responses for each type of instrument. Continue with Creating a printer profile.
    +
    +

    Reading a print test chart using a scanner or + camera
    +

    +
    + Argyll supports using a scanner or even a camera as a substitute for + a colorimeter. While a scanner or camera is no replacement for a + color measurement instrument, it may give acceptable results in some + situations, and may give better results than a generic profile for a + printing device.
    +
    + The main limitation of the scanner-as-colorimeter approach are:
    +
    + * The scanner dynamic range and/or precision may not match the + printers or what is required for a good profile.
    + * The spectral interaction of the scanner test chart and printer + test chart with the scanner spectral response can cause color + errors.
    + * Spectral differences caused by different black amounts in the + print test chart can cause color errors.
    + * The scanner reference chart gamut may be much smaller than the + printers gamut, making the scanner profile too inaccurate to be + useful.
    +
    + As well as some of the above, a camera may not be suitable if it + automatically adjusts exposure or white point when taking a picture, + and this behavior cannot be disabled.
    +
    + The end result is often a profile that has a noticeable color cast, + compared to a profile created using a colorimeter or spectrometer.
    +
    +
    + It is assumed that you have created a scanner or camera profile + following the procedure + outline above. For best possible results it is advisable to both + profile the scanner or camera, and use it in scanning the printed + test chart, in as "raw" mode as possible (i.e. using 16 bits per + component images, if the scanner or camera is capable of doing so; + not setting white or black points, using a fixed exposure etc.). It + is generally advisable to create a LUT type input profile, and use + the -u + flag to avoid clipping scanned value whiter than the input + calibration chart.
    +
    + Scan or photograph your printer chart (or charts) on the scanner or camera previously profiled. The @@ -1868,98 +1906,100 @@ href="http://www.xrite.com/documents/apps/public/digital_colorchecker_sg_l_a_b.t - - scanner or camera must be configured and used exactly the same - as it was when it was profiled.
    -
    - I will assume the resulting scan/photo input file is called PrinterB.tif (or PrinterB1.tif, PrinterB2.tif etc. in the case - of multiple charts). As with profiling the scanner or camera, the - raster file need only be roughly cropped so as to contain the test - chart.
    -
    - The scanner recognition files created when printtarg was run is assumed to - be called PrinterB.cht. - Using the scanner profile created previously (assumed to be called scanner.icm), the printer test - chart scan patches are converted to CIE values using the scanin tool:
    -
    - scanin -v -c PrinterB.tif - PrinterB.cht scanner.icm PrinterB
    -
    - If there were multiple test chart pages, the results would be - accumulated page by page using the -ca - option, ie., if there were 3 pages:
    -
    - scanin -v -c PrinterB1.tif - PrinterB1.cht scanner.icm PrinterB
    - scanin -v -ca PrinterB2.tif - PrinterB2.cht scanner.icm PrinterB
    - scanin -v -ca PrinterB3.tif - PrinterB3.cht scanner.icm PrinterB
    -
    - Now that the PrinterB.ti3 - data has been obtained, the profile continue in the next section - with Creating a printer profile.
    -
    - If you have any doubts about the correctness of the chart - recognition, or the subsequent profile's delta E report is unusual, - then use the scanin diagnostic flags -dipn - and examine the diag.tif - diagnostic file.
    -

    Creating a printer profile
    -

    - Creating an RGB based printing profile is very similar to creating a - display device profile. For a CMYK printer, some additional - information is needed to set the black generation.
    -
    - Where the resulting profile will be used conventionally (ie. using collink -s, - or cctiff or most other "dumb" CMMs) it - is important to specify that gamut mapping should be computed for - the output (B2A) perceptual and saturation tables. This is done by - specifying a device profile as the parameter to the colprof -S - flag. When you intend to create a "general use" profile, it can be a - good technique to specify the source gamut as the opposite type of - profile to that being created, i.e. if a printer profile is being - created, specify a display profile (e.g. sRGB) as the source gamut. - If a display profile is being created, then specify a printer - profile as the source (e.g. Figra, SWOP etc.).  When linking to - the profile you have created this way as the output profile, then - use perceptual intent if the source is the opposite type, and - relative colorimetric if it is the same type.
    -
    - "Opposite type of profile" refers to the native gamut of the device, - and what its fundamental nature is, additive or subtractive. An - emissive display will have additive primaries (R, G & B), while - a reflective print, will have subtractive primaries (C, M, Y & - possibly others), irrespective of what colorspace the printer is - driven in (a printer might present an RGB interface, but internally - this will be converted to CMY, and it will have a CMY type of - gamut).  Because of the complimentary nature of additive and - subtractive device primary colorants, these types of devices have - the most different gamuts, and hence need the most gamut mapping to - convert from one colorspace to the other.
    -
    - If you are creating a profile for a specific purpose, intending to - link it to a specific input profile, then you will get the best - results by specifying that source profile as the source gamut.
    -
    - If a profile is only going to be used as an input profile, or is - going to be used with a "smart" CMM (e.g. collink + + + + scanner or camera must be configured and used exactly the same + as it was when it was profiled.
    +
    + I will assume the resulting scan/photo input file is called PrinterB.tif (or PrinterB1.tif, PrinterB2.tif etc. in the case + of multiple charts). As with profiling the scanner or camera, the + raster file need only be roughly cropped so as to contain the test + chart.
    +
    + The scanner recognition files created when printtarg was run is assumed to + be called PrinterB.cht. + Using the scanner profile created previously (assumed to be called scanner.icm), the printer test + chart scan patches are converted to CIE values using the scanin tool:
    +
    + scanin -v -c PrinterB.tif + PrinterB.cht scanner.icm PrinterB
    +
    + If there were multiple test chart pages, the results would be + accumulated page by page using the -ca + option, ie., if there were 3 pages:
    +
    + scanin -v -c PrinterB1.tif + PrinterB1.cht scanner.icm PrinterB
    + scanin -v -ca PrinterB2.tif + PrinterB2.cht scanner.icm PrinterB
    + scanin -v -ca PrinterB3.tif + PrinterB3.cht scanner.icm PrinterB
    +
    + Now that the PrinterB.ti3 + data has been obtained, the profile continue in the next section + with Creating a printer profile.
    +
    + If you have any doubts about the correctness of the chart + recognition, or the subsequent profile's delta E report is unusual, + then use the scanin diagnostic flags -dipn + and examine the diag.tif + diagnostic file.
    +

    Creating a printer profile
    +

    + Creating an RGB based printing profile is very similar to creating a + display device profile. For a CMYK printer, some additional + information is needed to set the black generation.
    +
    + Where the resulting profile will be used conventionally (ie. using collink -s, + or cctiff or most other "dumb" CMMs) it + is important to specify that gamut mapping should be computed for + the output (B2A) perceptual and saturation tables. This is done by + specifying a device profile as the parameter to the colprof -S + flag. When you intend to create a "general use" profile, it can be a + good technique to specify the source gamut as the opposite type of + profile to that being created, i.e. if a printer profile is being + created, specify a display profile (e.g. sRGB) as the source gamut. + If a display profile is being created, then specify a printer + profile as the source (e.g. Figra, SWOP etc.).  When linking to + the profile you have created this way as the output profile, then + use perceptual intent if the source is the opposite type, and + relative colorimetric if it is the same type.
    +
    + "Opposite type of profile" refers to the native gamut of the device, + and what its fundamental nature is, additive or subtractive. An + emissive display will have additive primaries (R, G & B), while + a reflective print, will have subtractive primaries (C, M, Y & + possibly others), irrespective of what colorspace the printer is + driven in (a printer might present an RGB interface, but internally + this will be converted to CMY, and it will have a CMY type of + gamut).  Because of the complimentary nature of additive and + subtractive device primary colorants, these types of devices have + the most different gamuts, and hence need the most gamut mapping to + convert from one colorspace to the other.
    +
    + If you are creating a profile for a specific purpose, intending to + link it to a specific input profile, then you will get the best + results by specifying that source profile as the source gamut.
    +
    + If a profile is only going to be used as an input profile, or is + going to be used with a "smart" CMM (e.g. collink -g or -G), then @@ -2018,83 +2058,85 @@ then - - it can save considerable processing time and space if the -b flag is - used, and the -S flag not used.
    -
    - For an RGB printer intended to print RGB originals, the following - might be a typical profile usage:
    -
    - colprof -v - -D"Printer A" -qm - -S sRGB.icm - -cmt -dpp - PrinterA
    -
    - or if you intent to print from Fogra, SWOP or other standard CMYK - style originals:
    -
    - colprof -v - -D"Printer A" -qm - -S - fogra39l.icm -cmt -dpp PrinterA
    -
    - If you know what colorspace your originals are in, use that as the - argument to -S.
    -
    - If your viewing environment for the display and print doesn't match - the ones implied by the -cmt and -dpp options, leave them out, and - evaluate what, if any appearance transformation is appropriate for - your environment at a later stage.
    -
    - Make sure you check the delta E report at the end of the profile - creation, to see if the sample data and profile is behaving - reasonably. Depending on the type of device, and the consistency of - the readings, average errors of 5 or less, and maximum errors of 15 - or less would normally be expected. If errors are grossly higher - than this, then this is an indication that something is seriously - wrong with the device measurement, or profile creation. -

    Choosing a black generation curve (and other - CMYK printer options)
    -

    - For a CMYK printer, it would be normal to specify the type of black - generation, either as something simple, or as a specific curve. The - documentation  in colprof for the - details of the options.
    -
    - Note
    that making a good choice of black generation curve - can affect things such as: how robust neutrals are given printer - drift or changes in viewing lighting, how visible screening is, and - how smooth looking the B2A conversion is.
    -
    - For instance, maximizing the level of K will mean that the neutral - colors are composed of greater amounts of Black ink, and black ink - retains its neutral appearance irrespective of printer behavior or - the spectrum of the illuminant used to view the print. On the other - hand, output which is dominantly from one of the color channels will - tend to emphasize the screening pattern and any unevenness (banding - etc.) of that channel, and the black channel in particular has the - highest visibility. So in practice, some balance between the levels - of the four channels is probably best, with more K if the screening - is fine and a robust neutral balance is important, or less K if the - screening is more visible and neutral balance is less critical. The - levels of K at the edges of the gamut of the device will be fixed by - the nature of the ink combinations that maximize the gamut (ie. - typically zero ink for light chromatic colors, some combination for - dark colors, and a high level of black for very dark near neutrals), - and it is also usually important to set a curve that smoothly - transitions to the K values at the gamut edges. Dramatic changes in - K imply equally dramatic changes in CMY, and these abrupt - transitions will reveal the limited precision and detail that can be - captured in a lookup table based profile, often resulting in a - "bumpy" looking output.
    -
    - If you want to experiment with the various black generation - parameters, then it might be a good idea to create a preliminary - profile (using -ql -b -no, +
    + For an RGB printer intended to print RGB originals, the following + might be a typical profile usage:
    +
    +
    colprof -v + -D"Printer A" -qm + -S sRGB.icm + -cmt -dpp + PrinterA
    +
    + or if you intent to print from Fogra, SWOP or other standard CMYK + style originals:
    +
    + colprof -v + -D"Printer A" -qm + -S + fogra39l.icm -cmt -dpp PrinterA
    +
    + If you know what colorspace your originals are in, use that as the + argument to -S.
    +
    + If your viewing environment for the display and print doesn't match + the ones implied by the -cmt and -dpp options, leave them out, and + evaluate what, if any appearance transformation is appropriate for + your environment at a later stage.
    +
    + Make sure you check the delta E report at the end of the profile + creation, to see if the sample data and profile is behaving + reasonably. Depending on the type of device, and the consistency of + the readings, average errors of 5 or less, and maximum errors of 15 + or less would normally be expected. If errors are grossly higher + than this, then this is an indication that something is seriously + wrong with the device measurement, or profile creation. +

    Choosing a black generation curve (and other + CMYK printer options)
    +

    + For a CMYK printer, it would be normal to specify the type of black + generation, either as something simple, or as a specific curve. The + documentation  in colprof for the + details of the options.
    +
    + Note
    that making a good choice of black generation curve + can affect things such as: how robust neutrals are given printer + drift or changes in viewing lighting, how visible screening is, and + how smooth looking the B2A conversion is.
    +
    + For instance, maximizing the level of K will mean that the neutral + colors are composed of greater amounts of Black ink, and black ink + retains its neutral appearance irrespective of printer behavior or + the spectrum of the illuminant used to view the print. On the other + hand, output which is dominantly from one of the color channels will + tend to emphasize the screening pattern and any unevenness (banding + etc.) of that channel, and the black channel in particular has the + highest visibility. So in practice, some balance between the levels + of the four channels is probably best, with more K if the screening + is fine and a robust neutral balance is important, or less K if the + screening is more visible and neutral balance is less critical. The + levels of K at the edges of the gamut of the device will be fixed by + the nature of the ink combinations that maximize the gamut (ie. + typically zero ink for light chromatic colors, some combination for + dark colors, and a high level of black for very dark near neutrals), + and it is also usually important to set a curve that smoothly + transitions to the K values at the gamut edges. Dramatic changes in + K imply equally dramatic changes in CMY, and these abrupt + transitions will reveal the limited precision and detail that can be + captured in a lookup table based profile, often resulting in a + "bumpy" looking output.
    +
    + If you want to experiment with the various black generation + parameters, then it might be a good idea to create a preliminary + profile (using -ql -b -no, -ni and no -S), @@ -2151,407 +2193,409 @@ then - - and then used xicclu to explore the - effect of the parameters.
    -
    - For instance, say we have our CMYK .ti3 file PrinterB.ti3. First we make a - preliminary profile called PrinterBt:
    -
    - copy PrinterB.ti3 PrinterBt.ti3      (Use - "cp" on Linux or OSX of course.)
    - colprof -v - -qm -b -cmt -dpp - PrinterBt
    -
    - Then see what the minimum black level down the neutral axis can be. - Note that we need to also set any ink limits we've decided on as - well (coloprof defaulting to 10% less than the value recorded in the - .ti3 file). In this example the test chart has a 300% total ink - limit, and we've decided to use 290%:
    -
    - xicclu -g -kz -l290 -fif -ir PrinterBt.icm
    -
    - Which might be a graph something like this:
    -
    - Graph of CMYK neutral axis with minimum K
    -
    - Note  how the minimum black is zero up to 93% of the - white->black L* curve, and then jumps up to 87%. This is because - we've reached the total ink limit, and K then has to be substituted - for CMY, to keep the total under the total ink limit.
    -
    - Then let's see what the maximum black level down the neutral axis - can be:
    -
    - xicclu -g -kx -l290 -fif -ir PrinterBt.icm
    -
    - Which might be a graph something like this:
    -
    - Graph of CMYK neutral axis with maximum K
    -
    - Note how the CMY values are fairly low up to 93% of the - white->black L* curve (the low levels of CMY are helping set the - neutral color), and then they jump up. This is because we've reach - the point where black on it's own, isn't as dark as the color that - can be achieved using CMY and K. Because the K has a dominant effect - on the hue of the black, the levels of CMY are often fairly volatile - in this region.
    -
    - Any K curve we specify must lie between the black curves of the - above two graphs.
    -
    - Let's say we'd like to chose a moderate black curve, one that aims - for about equal levels of CMY and K. We should also aim for it to be - fairly smooth, since this will minimize visual artefacts caused by - the limited fidelity that profile LUT tables are able to represent - inside the profile.
    -
    - -k parameters
    -
    -
    - For minimum discontinuities we should aim for the curve to finish at - the point it has to reach to satisfy the total ink limit at 87% - curve and 93% black. For a first try we can simply set a straight - line to that point:
    -
    - xicclu -g -kp 0 0 .93 .87 1.0 -l290 -fif -ir PrinterBt.icm
    -
    - Graph of CMYK neutral axis with kp 0 0 1.0 1.0 1.0 -l290
    -
    - The black "curve" hits the 93%/87% mark well, but is a bit too far - above CMY, so we'll try making the black curve concave:
    -
    - xicclu -g -kp 0 0 .93 .87 - 0.65 -l290 -fif -ir PrinterBt.icm
    -
    - Graph of CMYK neutral axis with -kp 0 .05 1 .9 1 -l290
    -
    - This looks just about perfect, so the the curve parameters can now - be used to generate our real profile:
    -
    - colprof -v - -D"Printer B" -qm - -kp 0 0 .93 - .87 0.65 -S sRGB.icm -cmt - -dpp PrinterB
    -
    - and the resulting B2A table black curve can be checked using xicclu:
    -
    - xicclu -g -fb -ir PrinterB.icm
    -
    - sadsadas
    -
    -
    -

    - Examples of other inkings:
    -
    -
    A smoothed zero black inking:
    -
    - xicclu -g -kp 0 .7 .93 .87 - 1.0 -l290 -fif -ir PrinterBt.icm
    -
    - sadsadas
    -
    - A low black inking:
    -
    - xicclu -g -kp 0 0 .93 .87 - 0.15 -l290 -fif -ir PrinterBt.icm
    -
    - sadsadas
    -
    -
    - A high black inking:
    -
    - xicclu -g -kp 0 0 .93 .87 - 1.2 -l290 -fif -ir PrinterBt.icm
    -
    - sadsadas
    -
    - -

    Overriding the ink limit
    -

    - Normally the total ink limit will be read from the PrinterB.ti3 file, and will be - set at a level 10% lower than the number used in creating the test - chart values using targen -l. If you - want to override this with a lower limit, then use the -l flag.
    -
    - colprof -v - -D"Printer B" -qm - -S sRGB.icm - -cmt -dpp - -kr -l290 - PrinterB
    -
    - Make sure you check the delta E report at the end of the profile - creation, to see if the profile is behaving reasonably.
    -
    - One way of checking that your ink limit is not too high, is to use "xicc -fif -ia" to check, by - setting different ink limits using the -l option, feeding Lab = 0 0 0 into it, and checking - the resulting  black point. Starting with the ink limit used - with targen for the test - chart, reduce it until the black point starts to be affected. If it - is immediately affected by any reduction in the ink limit, then the - black point may be improved by increasing the ink limit used to - generate the test chart and then re-print and re-measuring it, - assuming other aspects such as wetness, smudging, spreading or - drying time are not an issue.
    -
    -

    -

    Calibrating Printers
    -

    - Profiling creates a - description of how a device behaves, while calibration on the other hand is - intended to change - how a device behaves. Argyll has the ability to create per-channel - device space calibration curves for print devices, that can then be - used to improve the behavior of of the device, making a subsequent - profile fit the device more easily and also allow day to day - correction of device drift without resorting to a full re-profile.
    -
    - NOTE: Because calibration - adds yet another layer to the way color is processed, it is - recommended that it not be attempted until the normal profiling - workflow is established, understood and verified.
    -

    Calibrated print workflows

    - There are two main workflows that printer calibration curves can be - applied to:
    -
    - Workflow with native calibration - capability:
    -
    - Firstly the printer itself may have the capability of using per - channel calibration curves. In this situation, the calibration - process will be largely independent of profiling. Firstly the - printer is configured to have both its color management and - calibration disabled (the latter perhaps achieved by loading linear - calibration curves), and a print calibration test chart that - consists of per channel color wedges is printed. The calibration - chart is read and the resulting .ti3 file converted into calibration - curves by processing it using printcal. - The calibration is then installed into the printer. Subsequent - profiling will be performed on the calibrated printer (ie. the profile test chart - will have the calibration curves applied to it by the printer, and - the resulting ICC profile will represent the behavior of the - calibrated printer.)
    -
    - Workflow without native calibration - capability:
    -
    - The second workflow is one in which the printer has no calibration - capability itself. In this situation, the calibration process will - have to be applied using the ICC color management tools, so careful - coordination with profiling is needed. Firstly the printer is - configured to have its color management disabled, and a print - calibration test chart that consists of per channel color wedges is - printed. The calibration chart is converted into calibration curves - by reading it and then processing the resultant .ti3 using printcal,. During the subsequent - profiling, the - calibration curves will need to be applied to the profile test chart - in the process of using printtarg. - Once the the profile has been created, then in subsequent printing - the calibration curves will need to be applied to an image being - printed either explicitly when using cctiff to apply color profiles and calibration, OR by creating a version of the - profile that has had the calibration curves incorporated into it - using the applycal tool. - The latter is useful when some CMM (color management module) other - than cctiff is being used.
    -
    - Once calibration aim targets for a particular device and mode - (screening, paper etc.) have been established, then the printer can - be re-calibrated at any time to bring its per channel behavior back - into line if it drifts, and the new calibration curves can be - installed into the printer, or re-incorporated into the profile. -   -

    Creating a print calibration test chart

    - The first step is to create a print calibration test chart. Since - calibration only creates per-channel curves, only single channel - step wedges are required for the chart. The main choice is the - number of steps in each wedge. For simple fast calibrations perhaps - as few as 20 steps per channel may be enough, but for a better - quality of calibration something like 50 or more steps would be a - better choice.
    -
    - Let's consider two devices in our examples, "PrinterA" which is an - "RGB" printer device, and "PrinterB" which is CMYK. In fact there is - no such thing as a real RGB printer, since printers use white media - and the colorant must subtract from the light reflected on it to - create color, but the printer itself turns the incoming RGB into the - native print colorspace, so for this reason we are careful to tell - targen to use the "Print RGB" colorspace, so that it knows to create - step wedges from media white to full colorant values.
    -
    - For instance, to create a 50 steps per channel calibration test - chart for our RGB and CMYK devices, the following would be - sufficient:
    -
    - targen -v -  -d2 -s50 - -e3 -f0 PrinterA_c
    -
    - targen -v -  -d4 -s50 - -e4 -f0 PrinterB_c
    -
    - For an outline of how to then print and read the resulting test - chart, see  Printing a print - profile test chart, and Reading - a print test chart using an instrument. Note that the printer - must be in an un-profiled and un-calibrated mode when doing this - print. Having done this, there will be a PrinterA.ti3 or - PrinterB.ti3 file containing the step wedge calibration chart - readings.
    -
    - NOTE that if you are - calibrating a raw printer driver, and there is considerable dot - gain, then you may want to use the -p - parameter to adjust the test chart point distribution to spread them - more evenly in perceptual space, giving more accurate control over - the calibration. Typically this will be a value greater than one for - a device that has dot gain, e.g. values of 1.5, 2.0 or 2.5 might be - good places to start. You can do a preliminary calibration and use - the verbose output of printcal to recommend a suitable value for -p.
    -

    Creating a printer calibration
    -

    - The printcal tool turns a calibration - chart .ti3 file into a .cal file. It has three main - operating modes:- Initial calibration, Re-Calibration, and - Verification. (A fourth mode, "Imitation" is very like Initial - Calibration, but is used for establishing a calibration target that - a similar printer can attempt to imitate.)
    -
    - The distinction between Initial Calibration and Re-Calibration is - that in the initial calibration we establish the "aim points" or - response we want out of the printer after calibration. There are - three basic parameters to set this for each channel: Maximum level, - minimum level, and curve shape.
    -
    - By default the maximum level will be set using a heuristic which - attempts to pick the point when there is diminishing returns for - applying more colorant. This can be overridden using the -x# percent option, where # represents the choice of - channel this will be applied to. The parameter is the percentage of - device maximum.
    -
    - The minimum level defaults to 0, but can be overridden using the -n# deltaE option. A minimum of - 0 means that zero colorant will correspond to the natural media - color, but it may be desirable to set a non-pure media color using - calibration for the purposes of emulating some other media. The - parameter is in Delta E units.
    -
    - The curve shape defaults to being perceptually uniform, which means - that even steps of calibrated device value result in perceptually - even color steps. In some situations it may be desirable to alter - this curve (for instance when non color managed output needs to be - sent to the calibrated printer), and a simple curve shape target can - be set using the -t# percent - parameter. This affects the output value at 50% input value, and - represents the percentage of perceptual output. By default it is 50% - perceptual output for 50% device input.
    -
    - Once a device has been calibrated, it can be re-calibrated to the - same aim target.
    -
    - Verification uses a calibration test chart printed through the - calibration, and compares the achieved response to the aim target.
    -
    - The simplest possible way of creating the PrinterA.cal file is:
    -
    -   printcal -i PrinterA_c
    -
    - For more detailed information, you can add the -v and -p flags:
    -
    -   printcal -v -p -i PrinterB_c
    -
    - (You will need to select the plot window and hit a key to advance - past each plot).
    -
    - For re-calibration, the name of the previous calibration file will - need to be supplied, and a new calibration
    - file will be created:
    -
    -   printcal -v -p -r PrinterB_c_old - PrinterB_c_new
    -
    - Various aim points are normally set automatically by printcal, but these can be - overridden using the -x, -n and -t - options. e.g. say we wanted to set the maximum ink for Cyan to 80% - and Black to 95%, we might use:
    -
    -   printcal -v -p -i -xc 80 - -xk 95 PrinterB_c
    -
    - -

    Using a printer calibration

    - The resulting calibration curves can be used with the following - other Argyll tools:
    -
    + + + + and then used xicclu to explore the + effect of the parameters.
    +
    + For instance, say we have our CMYK .ti3 file PrinterB.ti3. First we make a + preliminary profile called PrinterBt:
    +
    + copy PrinterB.ti3 PrinterBt.ti3      (Use + "cp" on Linux or OSX of course.)
    + colprof -v + -qm -b -cmt -dpp + PrinterBt
    +
    + Then see what the minimum black level down the neutral axis can be. + Note that we need to also set any ink limits we've decided on as + well (coloprof defaulting to 10% less than the value recorded in the + .ti3 file). In this example the test chart has a 300% total ink + limit, and we've decided to use 290%:
    +
    + xicclu -g -kz -l290 -fif -ir PrinterBt.icm
    +
    + Which might be a graph something like this:
    +
    + Graph of CMYK neutral axis with minimum K
    +
    + Note  how the minimum black is zero up to 93% of the + white->black L* curve, and then jumps up to 87%. This is because + we've reached the total ink limit, and K then has to be substituted + for CMY, to keep the total under the total ink limit.
    +
    + Then let's see what the maximum black level down the neutral axis + can be:
    +
    + xicclu -g -kx -l290 -fif -ir PrinterBt.icm
    +
    + Which might be a graph something like this:
    +
    + Graph of CMYK neutral axis with maximum K
    +
    + Note how the CMY values are fairly low up to 93% of the + white->black L* curve (the low levels of CMY are helping set the + neutral color), and then they jump up. This is because we've reach + the point where black on it's own, isn't as dark as the color that + can be achieved using CMY and K. Because the K has a dominant effect + on the hue of the black, the levels of CMY are often fairly volatile + in this region.
    +
    + Any K curve we specify must lie between the black curves of the + above two graphs.
    +
    + Let's say we'd like to chose a moderate black curve, one that aims + for about equal levels of CMY and K. We should also aim for it to be + fairly smooth, since this will minimize visual artefacts caused by + the limited fidelity that profile LUT tables are able to represent + inside the profile.
    +
    + -k parameters
    +
    +
    + For minimum discontinuities we should aim for the curve to finish at + the point it has to reach to satisfy the total ink limit at 87% + curve and 93% black. For a first try we can simply set a straight + line to that point:
    +
    + xicclu -g -kp 0 0 .93 .87 1.0 -l290 -fif -ir PrinterBt.icm
    +
    + Graph of CMYK neutral axis with kp 0 0 1.0 1.0 1.0 -l290
    +
    + The black "curve" hits the 93%/87% mark well, but is a bit too far + above CMY, so we'll try making the black curve concave:
    +
    + xicclu -g -kp 0 0 .93 .87 + 0.65 -l290 -fif -ir PrinterBt.icm
    +
    + Graph of CMYK neutral axis with -kp 0 .05 1 .9 1 -l290
    +
    + This looks just about perfect, so the the curve parameters can now + be used to generate our real profile:
    +
    + colprof -v + -D"Printer B" -qm + -kp 0 0 .93 + .87 0.65 -S sRGB.icm -cmt + -dpp PrinterB
    +
    + and the resulting B2A table black curve can be checked using xicclu:
    +
    + xicclu -g -fb -ir PrinterB.icm
    +
    + sadsadas
    +
    +
    +

    + Examples of other inkings:
    +
    +
    A smoothed zero black inking:
    +
    + xicclu -g -kp 0 .7 .93 .87 + 1.0 -l290 -fif -ir PrinterBt.icm
    +
    + sadsadas
    +
    + A low black inking:
    +
    + xicclu -g -kp 0 0 .93 .87 + 0.15 -l290 -fif -ir PrinterBt.icm
    +
    + sadsadas
    +
    +
    + A high black inking:
    +
    + xicclu -g -kp 0 0 .93 .87 + 1.2 -l290 -fif -ir PrinterBt.icm
    +
    + sadsadas
    +
    + +

    Overriding the ink limit
    +

    + Normally the total ink limit will be read from the PrinterB.ti3 file, and will be + set at a level 10% lower than the number used in creating the test + chart values using targen -l. If you + want to override this with a lower limit, then use the -l flag.
    +
    + colprof -v + -D"Printer B" -qm + -S sRGB.icm + -cmt -dpp + -kr -l290 + PrinterB
    +
    + Make sure you check the delta E report at the end of the profile + creation, to see if the profile is behaving reasonably.
    +
    + One way of checking that your ink limit is not too high, is to use "xicc -fif -ia" to check, by + setting different ink limits using the -l option, feeding Lab = 0 0 0 into it, and checking + the resulting  black point. Starting with the ink limit used + with targen for the test + chart, reduce it until the black point starts to be affected. If it + is immediately affected by any reduction in the ink limit, then the + black point may be improved by increasing the ink limit used to + generate the test chart and then re-print and re-measuring it, + assuming other aspects such as wetness, smudging, spreading or + drying time are not an issue.
    +
    +

    +

    Calibrating Printers
    +

    + Profiling creates a + description of how a device behaves, while calibration on the other hand is + intended to change + how a device behaves. Argyll has the ability to create per-channel + device space calibration curves for print devices, that can then be + used to improve the behavior of of the device, making a subsequent + profile fit the device more easily and also allow day to day + correction of device drift without resorting to a full re-profile.
    +
    + NOTE: Because calibration + adds yet another layer to the way color is processed, it is + recommended that it not be attempted until the normal profiling + workflow is established, understood and verified.
    +

    Calibrated print workflows

    + There are two main workflows that printer calibration curves can be + applied to:
    +
    + Workflow with native calibration + capability:
    +
    + Firstly the printer itself may have the capability of using per + channel calibration curves. In this situation, the calibration + process will be largely independent of profiling. Firstly the + printer is configured to have both its color management and + calibration disabled (the latter perhaps achieved by loading linear + calibration curves), and a print calibration test chart that + consists of per channel color wedges is printed. The calibration + chart is read and the resulting .ti3 file converted into calibration + curves by processing it using printcal. + The calibration is then installed into the printer. Subsequent + profiling will be performed on the calibrated printer (ie. the profile test chart + will have the calibration curves applied to it by the printer, and + the resulting ICC profile will represent the behavior of the + calibrated printer.)
    +
    + Workflow without native calibration + capability:
    +
    + The second workflow is one in which the printer has no calibration + capability itself. In this situation, the calibration process will + have to be applied using the ICC color management tools, so careful + coordination with profiling is needed. Firstly the printer is + configured to have its color management disabled, and a print + calibration test chart that consists of per channel color wedges is + printed. The calibration chart is converted into calibration curves + by reading it and then processing the resultant .ti3 using printcal,. During the subsequent + profiling, the + calibration curves will need to be applied to the profile test chart + in the process of using printtarg. + Once the the profile has been created, then in subsequent printing + the calibration curves will need to be applied to an image being + printed either explicitly when using cctiff to apply color profiles and calibration, OR by creating a version of the + profile that has had the calibration curves incorporated into it + using the applycal tool. + The latter is useful when some CMM (color management module) other + than cctiff is being used.
    +
    + Once calibration aim targets for a particular device and mode + (screening, paper etc.) have been established, then the printer can + be re-calibrated at any time to bring its per channel behavior back + into line if it drifts, and the new calibration curves can be + installed into the printer, or re-incorporated into the profile. +   +

    Creating a print calibration test chart

    + The first step is to create a print calibration test chart. Since + calibration only creates per-channel curves, only single channel + step wedges are required for the chart. The main choice is the + number of steps in each wedge. For simple fast calibrations perhaps + as few as 20 steps per channel may be enough, but for a better + quality of calibration something like 50 or more steps would be a + better choice.
    +
    + Let's consider two devices in our examples, "PrinterA" which is an + "RGB" printer device, and "PrinterB" which is CMYK. In fact there is + no such thing as a real RGB printer, since printers use white media + and the colorant must subtract from the light reflected on it to + create color, but the printer itself turns the incoming RGB into the + native print colorspace, so for this reason we are careful to tell + targen to use the "Print RGB" colorspace, so that it knows to create + step wedges from media white to full colorant values.
    +
    + For instance, to create a 50 steps per channel calibration test + chart for our RGB and CMYK devices, the following would be + sufficient:
    +
    + targen -v +  -d2 -s50 + -e3 -f0 PrinterA_c
    +
    + targen -v +  -d4 -s50 + -e4 -f0 PrinterB_c
    +
    + For an outline of how to then print and read the resulting test + chart, see  Printing a print + profile test chart, and Reading + a print test chart using an instrument. Note that the printer + must be in an un-profiled and un-calibrated mode when doing this + print. Having done this, there will be a PrinterA.ti3 or + PrinterB.ti3 file containing the step wedge calibration chart + readings.
    +
    + NOTE that if you are + calibrating a raw printer driver, and there is considerable dot + gain, then you may want to use the -p + parameter to adjust the test chart point distribution to spread them + more evenly in perceptual space, giving more accurate control over + the calibration. Typically this will be a value greater than one for + a device that has dot gain, e.g. values of 1.5, 2.0 or 2.5 might be + good places to start. You can do a preliminary calibration and use + the verbose output of printcal to recommend a suitable value for -p.
    +

    Creating a printer calibration
    +

    + The printcal tool turns a calibration + chart .ti3 file into a .cal file. It has three main + operating modes:- Initial calibration, Re-Calibration, and + Verification. (A fourth mode, "Imitation" is very like Initial + Calibration, but is used for establishing a calibration target that + a similar printer can attempt to imitate.)
    +
    + The distinction between Initial Calibration and Re-Calibration is + that in the initial calibration we establish the "aim points" or + response we want out of the printer after calibration. There are + three basic parameters to set this for each channel: Maximum level, + minimum level, and curve shape.
    +
    + By default the maximum level will be set using a heuristic which + attempts to pick the point when there is diminishing returns for + applying more colorant. This can be overridden using the -x# percent option, where # represents the choice of + channel this will be applied to. The parameter is the percentage of + device maximum.
    +
    + The minimum level defaults to 0, but can be overridden using the -n# deltaE option. A minimum of + 0 means that zero colorant will correspond to the natural media + color, but it may be desirable to set a non-pure media color using + calibration for the purposes of emulating some other media. The + parameter is in Delta E units.
    +
    + The curve shape defaults to being perceptually uniform, which means + that even steps of calibrated device value result in perceptually + even color steps. In some situations it may be desirable to alter + this curve (for instance when non color managed output needs to be + sent to the calibrated printer), and a simple curve shape target can + be set using the -t# percent + parameter. This affects the output value at 50% input value, and + represents the percentage of perceptual output. By default it is 50% + perceptual output for 50% device input.
    +
    + Once a device has been calibrated, it can be re-calibrated to the + same aim target.
    +
    + Verification uses a calibration test chart printed through the + calibration, and compares the achieved response to the aim target.
    +
    + The simplest possible way of creating the PrinterA.cal file is:
    +
    +   printcal -i PrinterA_c
    +
    + For more detailed information, you can add the -v and -p flags:
    +
    +   printcal -v -p -i PrinterB_c
    +
    + (You will need to select the plot window and hit a key to advance + past each plot).
    +
    + For re-calibration, the name of the previous calibration file will + need to be supplied, and a new calibration
    + file will be created:
    +
    +   printcal -v -p -r PrinterB_c_old + PrinterB_c_new
    +
    + Various aim points are normally set automatically by printcal, but these can be + overridden using the -x, -n and -t + options. e.g. say we wanted to set the maximum ink for Cyan to 80% + and Black to 95%, we might use:
    +
    +   printcal -v -p -i -xc 80 + -xk 95 PrinterB_c
    +
    + +

    Using a printer calibration

    + The resulting calibration curves can be used with the following + other Argyll tools:
    +
        printtarg     To apply @@ -2617,8 +2661,10 @@ chart, - - and/or to have it included in .ti3 file.
    + + + + and/or to have it included in .ti3 file.
        cctiff         To apply @@ -2684,8 +2730,10 @@ an - - image file.
    + + + + image file.
        applycal     @@ -2743,8 +2791,10 @@ an - - To incorporate calibration into an ICC profile.
    + + + + To incorporate calibration into an ICC profile.
        chartread   To override @@ -2810,396 +2860,405 @@ a - - profile chart.
    -
    -
    - In a workflow with native - calibration capability, the calibration curves would be used with - printarg during subsequent profiling - so that any ink limit calculations will reflect final device values, - while not otherwise using the calibration within the ICC workflow:
    -
    -     printtarg -v -ii1 - -pA4 -I - PrinterA_c.cal PrinterA
    -
    - This will cause the .ti2 and resulting .ti3 and ICC profiles to - contain the calibration curves, allowing all the tools to be able to - compute final device value ink limits. The calibration curves must - also of course be installed into the printer. The means to do this - is currently outside the scope of Argyll (ie. either the print - system needs to be able to understand Argyll CAL format files, or - some tool will be needed to convert Argyll CAL files into the - printer calibration format).
    -
    -
    - In a workflow without - native calibration capability, the calibration curves would be used - with printarg to apply - the calibration to the test patch samples during subsequent profiling, as well as embedding - it in the resulting .ti3 to allow all the tools to be able to - compute final device value ink limits:
    -
    -     printtarg -v -ii1 - -pA4 -K - PrinterA_c.cal PrinterA
    -
    - To apply calibration to an ICC profile, so that a calibration - unaware CMM can be used:
    -
    -     applycal PrinterA.cal PrinterA.icm PrinterA_cal.icm
    -
    - To apply color management and calibration to a raster image:
    -
    -     cctiff - Source.icm PrinterA.icm PrinterA_c.cal - infile.tif outfile.tif
    -
    - or
    -
    -     cctiff - Source.icm PrinterA_c.icm - infile.tif outfile.tif
    -
    - [ Note that cctiff will also process JPEG raster images. ]
    -
    - Another useful tool is synthcal, that - allows creating linear or synthetic calibration files for disabling - calibration or testing.
    - Similarly, fakeread also supports - applying calibration curves and embedding them in the resulting .ti3 - file
    -
    - If you want to create a pre-conditioning profile for use with targen -c, then use the PrinterA.icm - profile, NOT PrinterA_c.icm that has calibration curves - applied.
    -

    How profile ink limits are handled when - calibration is being used.

    - Even though the profiling process is carried out on top of the - linearized device, and the profiling is generally unaware of the - underlying non-linearized device values, an exception is made in the - calculation of ink limits during profiling. This is made possible by - including the calibration curves in the profile charts .ti2 and - subsequent .ti3 file and resulting ICC profile 'targ' text tag, by way of the printtarg -I or -K options. This is done on the assumption that the - physical quantity of ink is what's important in setting the ink - limit, and that the underlying non-linearized device values - represent such a physical quantity.
    -
    -
    -
    -

    Linking Profiles

    - Two device profiles can be linked together to create a device link - profile, than encapsulates a particular device to device transform. - Often this step is not necessary, as many systems and tools will - link two device profiles "on the fly", but creating a device link - profile gives you the option of using "smart CMM" techniques, such - as true gamut mapping, improved inverse transform accuracy, tailored - black generation and ink limiting.
    -
    - The overall process is to link the input space and output space - profiles using collink, creating a - device to device link profile. The device to device link profile can - then be used by cctiff (or other ICC device profile capable tools), - to color correct a raster files.
    -
    - Three examples will be given here, showing the three different modes - than collink supports.
    -
    - In simple mode, the two profiles are - linked together in a similar fashion to other CMMs simply using the forward - and backwards color transforms defined by the profiles. Any gamut - mapping is determined by the content of the tables within the two - profiles, together with the particular intent chosen. Typically the - same intent will be used for both the source and destination - profile:
    -
    - collink -v - -qm -s -ip -op - SouceProfile.icm DestinationProfile.icm Source2Destination.icm
    -
    -
    - In gamut mapping mode, the - pre-computed intent mappings inside the profiles are not used, but - instead the gamut mapping between source and destination is tailored - to the specific gamuts of the two profiles, and the intent parameter - supplied to collink. - Additionally, source and destination viewing conditions should be - provided, to allow the color appearance space conversion to work as - intended. The colorimetric B2A table in the destination profile is - used, and this will determine any black generation and ink limiting:
    -
    - collink -v - -qm -g -ip -cmt - -dpp MonitorSouceProfile.icm - DestinationProfile.icm Source2Destination.icm
    -
    - [ If your viewing environment for the display and print doesn't - match the ones implied by the -cmt and - -dpp options, leave them out, and - evaluate what, if any appearance transformation is appropriate for - your environment at a later stage. ]
    -
    - In inverse output table gamut mapping mode, - the pre-computed intent mappings inside the profiles are not used, - but instead the gamut mapping between source and destination is - tailored to the specific gamuts of the two profiles, and the intent - parameter supplied to collink. - In addition, the B2A table is not - used in the destination profile, but the A2B table is instead - inverted, leading to improved transform accuracy, and in CMYK - devices, allowing the ink limiting and black generation parameters - to be set:
    -
    - For a CLUT table based RGB printer destination profile, the - following would be appropriate:
    -
    - collink -v - -qm -G -ip -cmt - -dpp MonitorSouceProfile.icm - RGBDestinationProfile.icm Source2Destination.icm
    -
    - For a CMYK profile, the total ink limit needs to be specified (a - typical value being 10% less than the value used in creating the - device test chart), and the type of black generation also needs to - be specified:
    -
    - collink -v - -qm -G -ip -cmt - -dpp -l250 - -kr MonitorSouceProfile.icm - CMYKDestinationProfile.icm Source2Destination.icm
    -
    - Note that you should set the source (-c) - and destination (-d) viewing conditions - for the type of device the profile represents, and the conditions - under which it will be viewed.
    -
    -

    Image dependent gamut mapping using device - links
    -

    - When images are stored in large gamut colorspaces (such as. L*a*b* - or ProPhoto, etc.), then using the colorspace gamut as the source - gamut for gamut mapping is generally a bad idea, as it leads to - overly compressed and dull images. The correct approach is to use a - source gamut that represents the gamut of the images themselves. - This can be created using tiffgamut, and an example workflow is as - follows:
    -
    - tiffgamut -f80 -pj -cmt ProPhoto.icm - image.tif
    -
    - collink -v - -qh -G image.gam -ip - -cmt -dpp - ProPhoto.icm RGBDestinationProfile.icm - Source2Destination.icm
    -
    - cctiff Source2Destination.icm - image.tif printfile.tif
    -
    - The printfile.tif is then send to the printer without color - management, (i.e. in the same way the printer characterization test - chart was printed), since it is in the printers native colorspace.
    -
    - You can adjust how conservatively the image gamut is preserved using - the tiffgamut -f parameter. Omitting it or using a larger value (up - to 100) preserves the color gradations of even the lesser used - colors, at the cost of compressing the gamut more.
    - Using a smaller value will preserve the saturation of the most - popular colors, at the cost of not preserving the color gradations - of less popular colors.
    -
    - You can create a gamut that covers a set of source images by - providing more than one image file name to tiffgamut. This may be - more efficient for a group of related images, and ensures that - colors are transformed in exactly the same way for all of the - images.
    -
    - The arguments to collink should be appropriate for the output device - type - see the collink examples in the above section.
    -

    Soft Proofing Link

    - Often it is desirable to get an idea what a particular devices - output will look like using a different device. Typically this might - be trying to evaluate print output using a display. Often it is - sufficient to use an absolute or relative colorimetric transform - from the print device space to the display space, but while these - provide a colorimetric preview of the result, they do not take into - account the subjective appearance differences due to the different - device conditions. It can therefore be useful to create a soft proof - appearance transform using collink:
    -
    - collink -v - -qm -G -ila -cpp - -dmt -t250 CMYKDestinationProfile.icm - MonitorProfile.icm SoftProof.icm
    -
    - We use the Luminance matched appearance intent, to preserve the - subjective apperance of the target device, which takes into account - the viewing conditions and assumes adaptation to the differences in - the luminence range, but otherwise not attempting to compress or - change the gamut.
    -
    - If your viewing environment for the display and print doesn't match - the ones implied by the -cpp and -dmt options, then either leave them out - or substitute values that do match your environment.
    -   -

    -

    Transforming colorspaces of raster files

    - Although a device profile or device link profile may be useful with - other programs and systems, Argyll provides the tool cctiff for directly applying a device to - device transform to a TIFF or - JPEG raster file. The cctiff - tool is capable of linking an arbitrary sequence of device profiles, - device links, abstract profiles and calibration curves. Each device - profile can be preceded by the -i - option to indicate the intent that should be used. Both 8 and 16 bit - per component files can be handled, and up to 8 color channels. The - color transform is optimized to perform the overall transformation - rapidly.
    -
    - If a device link is to be used, the following is a typical example:
    -
    - cctiff Source2Destination.icm - infile.tif outfile.tif
    - or
    - cctiff Source2Destination.icm - infile.jpg outfile.jpg
    -
    -
    -
    If a source and destination profile are to be used, the - following would be a typical example:
    -
    - cctiff  -ip - SourceProfile.icm -ip DestinationProfile.icm - infile.tif outfile.tif
    - or
    - cctiff  -ip - SourceProfile.icm -ip DestinationProfile.icm - infile.jpg outfile.jpg
    -
    -
    -

    -

    Creating Video Calibration 3DLuts

    - Video calibration typically involves trying to make your actual - display device emulate an ideal video display, one which matches - what your Video media was intended to be displayed on. An ICC device - link embodies the machinery to do exactly this, to take device - values in the target source colorspace and transform them into an - actual output device colorspace. In the Video and Film industries a - very similar, but less sophisticated means of doing this is to use - 3DLuts, which come in a multitude of different format. ICC device - links have the advantage of being a superset of 3dLuts, encapsulated - in a standard file format.
    -
    - To facilitate Video calibration of certain Video systems, ArgyllCMS - supports some 3DLut output options as part of collink.
    -
    - What follows here is an outline of how to create Video calibration - 3DLuts using ArgyllCMS. First comes a general discussion of various - aspects of video device links/3dLuts, and followed with some - specific advice regarding the systems that ArgyllCMS supports. Last - is some recommended scenarios for verifying the quality of Video - calibration achieved.
    -
    1) How to display test patches.
    -
    - Argyll's normal test patch display will be used by default, as long - as any video encoding range considerations are dealt with (see - Signal encoding below).
    -
    - An alternative when working with MadVR V 0.86.9 or latter, is to use - the madTPG to display the patches in which case the MadVR video - encoding range setting will operate. This can give some quality - benefits due to MadVR's use of dithering. To display patches using + + + + profile chart.
    +
    +
    + In a workflow with native + calibration capability, the calibration curves would be used with + printarg during subsequent profiling + so that any ink limit calculations will reflect final device values, + while not otherwise using the calibration within the ICC workflow:
    +
    +     printtarg -v -ii1 + -pA4 -I + PrinterA_c.cal PrinterA
    +
    + This will cause the .ti2 and resulting .ti3 and ICC profiles to + contain the calibration curves, allowing all the tools to be able to + compute final device value ink limits. The calibration curves must + also of course be installed into the printer. The means to do this + is currently outside the scope of Argyll (ie. either the print + system needs to be able to understand Argyll CAL format files, or + some tool will be needed to convert Argyll CAL files into the + printer calibration format).
    +
    +
    + In a workflow without + native calibration capability, the calibration curves would be used + with printarg to apply + the calibration to the test patch samples during subsequent profiling, as well as embedding + it in the resulting .ti3 to allow all the tools to be able to + compute final device value ink limits:
    +
    +     printtarg -v -ii1 + -pA4 -K + PrinterA_c.cal PrinterA
    +
    + To apply calibration to an ICC profile, so that a calibration + unaware CMM can be used:
    +
    +     applycal PrinterA.cal PrinterA.icm PrinterA_cal.icm
    +
    + To apply color management and calibration to a raster image:
    +
    +     cctiff + Source.icm PrinterA.icm PrinterA_c.cal + infile.tif outfile.tif
    +
    + or
    +
    +     cctiff + Source.icm PrinterA_c.icm + infile.tif outfile.tif
    +
    + [ Note that cctiff will also process JPEG raster images. ]
    +
    + Another useful tool is synthcal, that + allows creating linear or synthetic calibration files for disabling + calibration or testing.
    + Similarly, fakeread also supports + applying calibration curves and embedding them in the resulting .ti3 + file
    +
    + If you want to create a pre-conditioning profile for use with targen -c, then use the PrinterA.icm + profile, NOT PrinterA_c.icm that has calibration curves + applied.
    +

    How profile ink limits are handled when + calibration is being used.

    + Even though the profiling process is carried out on top of the + linearized device, and the profiling is generally unaware of the + underlying non-linearized device values, an exception is made in the + calculation of ink limits during profiling. This is made possible by + including the calibration curves in the profile charts .ti2 and + subsequent .ti3 file and resulting ICC profile 'targ' text tag, by way of the printtarg -I or -K options. This is done on the assumption that the + physical quantity of ink is what's important in setting the ink + limit, and that the underlying non-linearized device values + represent such a physical quantity.
    +
    +
    +
    +

    Linking Profiles

    + Two device profiles can be linked together to create a device link + profile, than encapsulates a particular device to device transform. + Often this step is not necessary, as many systems and tools will + link two device profiles "on the fly", but creating a device link + profile gives you the option of using "smart CMM" techniques, such + as true gamut mapping, improved inverse transform accuracy, tailored + black generation and ink limiting.
    +
    + The overall process is to link the input space and output space + profiles using collink, creating a + device to device link profile. The device to device link profile can + then be used by cctiff (or other ICC device profile capable tools), + to color correct a raster files.
    +
    + Three examples will be given here, showing the three different modes + than collink supports.
    +
    + In simple mode, the two profiles are + linked together in a similar fashion to other CMMs simply using the forward + and backwards color transforms defined by the profiles. Any gamut + mapping is determined by the content of the tables within the two + profiles, together with the particular intent chosen. Typically the + same intent will be used for both the source and destination + profile:
    +
    + collink -v + -qm -s -ip -op + SouceProfile.icm DestinationProfile.icm Source2Destination.icm
    +
    +
    + In gamut mapping mode, the + pre-computed intent mappings inside the profiles are not used, but + instead the gamut mapping between source and destination is tailored + to the specific gamuts of the two profiles, and the intent parameter + supplied to collink. + Additionally, source and destination viewing conditions should be + provided, to allow the color appearance space conversion to work as + intended. The colorimetric B2A table in the destination profile is + used, and this will determine any black generation and ink limiting:
    +
    + collink -v + -qm -g -ip -cmt + -dpp MonitorSouceProfile.icm + DestinationProfile.icm Source2Destination.icm
    +
    + [ If your viewing environment for the display and print doesn't + match the ones implied by the -cmt and + -dpp options, leave them out, and + evaluate what, if any appearance transformation is appropriate for + your environment at a later stage. ]
    +
    + In inverse output table gamut mapping mode, + the pre-computed intent mappings inside the profiles are not used, + but instead the gamut mapping between source and destination is + tailored to the specific gamuts of the two profiles, and the intent + parameter supplied to collink. + In addition, the B2A table is not + used in the destination profile, but the A2B table is instead + inverted, leading to improved transform accuracy, and in CMYK + devices, allowing the ink limiting and black generation parameters + to be set:
    +
    + For a CLUT table based RGB printer destination profile, the + following would be appropriate:
    +
    + collink -v + -qm -G -ip -cmt + -dpp MonitorSouceProfile.icm + RGBDestinationProfile.icm Source2Destination.icm
    +
    + For a CMYK profile, the total ink limit needs to be specified (a + typical value being 10% less than the value used in creating the + device test chart), and the type of black generation also needs to + be specified:
    +
    + collink -v + -qm -G -ip -cmt + -dpp -l250 + -kr MonitorSouceProfile.icm + CMYKDestinationProfile.icm Source2Destination.icm
    +
    + Note that you should set the source (-c) + and destination (-d) viewing conditions + for the type of device the profile represents, and the conditions + under which it will be viewed.
    +
    +

    Image dependent gamut mapping using device + links
    +

    + When images are stored in large gamut colorspaces (such as. L*a*b*, + ProPhoto, scRGB etc.), then using the colorspace gamut as the source + gamut for gamut mapping is generally a bad idea, as it leads to + overly compressed and dull images. The correct approach is to use a + source gamut that represents the gamut of the images themselves. + This can be created using tiffgamut, and an example workflow is as + follows:
    +
    + tiffgamut -f80 -pj -cmt ProPhoto.icm + image.tif
    +
    + collink -v + -qh -G image.gam -ip + -cmt -dpp + ProPhoto.icm RGBDestinationProfile.icm + Source2Destination.icm
    +
    + cctiff Source2Destination.icm + image.tif printfile.tif
    +
    + The printfile.tif is then send to the printer without color + management, (i.e. in the same way the printer characterization test + chart was printed), since it is in the printers native colorspace.
    +
    + You can adjust how conservatively the image gamut is preserved using + the tiffgamut -f parameter. Omitting it or using a larger value (up + to 100) preserves the color gradations of even the lesser used + colors, at the cost of compressing the gamut more.
    + Using a smaller value will preserve the saturation of the most + popular colors, at the cost of not preserving the color gradations + of less popular colors.
    +
    + You can create a gamut that covers a set of source images by + providing more than one image file name to tiffgamut. This may be + more efficient for a group of related images, and ensures that + colors are transformed in exactly the same way for all of the + images.
    +
    + An alternative generating a gamut for a specific set of images, is + to use a general smaller gamut definition (i.e. the sRGB profile), + or a gamut that represents the typical range of colors you wish to + preserve.
    +
    + The arguments to collink should be appropriate for the output device + type - see the collink examples in the above section.
    +

    Soft Proofing Link

    + Often it is desirable to get an idea what a particular devices + output will look like using a different device. Typically this might + be trying to evaluate print output using a display. Often it is + sufficient to use an absolute or relative colorimetric transform + from the print device space to the display space, but while these + provide a colorimetric preview of the result, they do not take into + account the subjective appearance differences due to the different + device conditions. It can therefore be useful to create a soft proof + appearance transform using collink:
    +
    + collink -v + -qm -G -ila -cpp + -dmt -t250 CMYKDestinationProfile.icm + MonitorProfile.icm SoftProof.icm
    +
    + We use the Luminance matched appearance intent, to preserve the + subjective apperance of the target device, which takes into account + the viewing conditions and assumes adaptation to the differences in + the luminence range, but otherwise not attempting to compress or + change the gamut.
    +
    + If your viewing environment for the display and print doesn't match + the ones implied by the -cpp and -dmt options, then either leave them out + or substitute values that do match your environment.
    +   +

    +

    Transforming colorspaces of raster files

    + Although a device profile or device link profile may be useful with + other programs and systems, Argyll provides the tool cctiff for directly applying a device to + device transform to a TIFF or + JPEG raster file. The cctiff + tool is capable of linking an arbitrary sequence of device profiles, + device links, abstract profiles and calibration curves. Each device + profile can be preceded by the -i + option to indicate the intent that should be used. Both 8 and 16 bit + per component files can be handled, and up to 8 color channels. The + color transform is optimized to perform the overall transformation + rapidly.
    +
    + If a device link is to be used, the following is a typical example:
    +
    + cctiff Source2Destination.icm + infile.tif outfile.tif
    + or
    + cctiff Source2Destination.icm + infile.jpg outfile.jpg
    +
    +
    +
    If a source and destination profile are to be used, the + following would be a typical example:
    +
    + cctiff  -ip + SourceProfile.icm -ip DestinationProfile.icm + infile.tif outfile.tif
    + or
    + cctiff  -ip + SourceProfile.icm -ip DestinationProfile.icm + infile.jpg outfile.jpg
    +
    +
    +

    +

    Creating Video Calibration 3DLuts

    + Video calibration typically involves trying to make your actual + display device emulate an ideal video display, one which matches + what your Video media was intended to be displayed on. An ICC device + link embodies the machinery to do exactly this, to take device + values in the target source colorspace and transform them into an + actual output device colorspace. In the Video and Film industries a + very similar, but less sophisticated means of doing this is to use + 3DLuts, which come in a multitude of different format. ICC device + links have the advantage of being a superset of 3dLuts, encapsulated + in a standard file format.
    +
    + To facilitate Video calibration of certain Video systems, ArgyllCMS + supports some 3DLut output options as part of collink.
    +
    + What follows here is an outline of how to create Video calibration + 3DLuts using ArgyllCMS. First comes a general discussion of various + aspects of video device links/3dLuts, and followed with some + specific advice regarding the systems that ArgyllCMS supports. Last + is some recommended scenarios for verifying the quality of Video + calibration achieved.
    +
    1) How to display test patches.
    +
    + Argyll's normal test patch display will be used by default, as long + as any video encoding range considerations are dealt with (see + Signal encoding below).
    +
    + An alternative when working with MadVR V 0.86.9 or latter, is to use + the madTPG to display the patches in which case the MadVR video + encoding range setting will operate. This can give some quality + benefits due to MadVR's use of dithering. To display patches using MadVR rather than Argyll, start madTPG and then use the option "-d - - madvr" in dispcal, dispread and dispwin. Leave the MadTPG - "VideoLUT" and "3dluts" buttons in their default  (enabled) - state, as the various tools will automatically take care of - disabling the 3dLut and/or calibration curves as needed.
    -
    - Another option is to use a ChromeCast - using the option "-dcc" in dispcal, dispread and dispwin. - Note that the ChromeCast as a test patch source is probably the - least accurate of your choices, since it up-samples the test - patch and transforms from RGB to YCC and back, but should be - accurate within ± 1 bit. You may have to modify any firewall to - permit port 8081 to be accessed on your machine if it falls back to - the Default receiver (see installation - instructions for your platform). -
    2) White point calibration & neutral axis calibration.
    - A Device Link is capable of embodying all aspects of the - calibration, including correcting the white point and neutral axis - behavior of the output device, but making such a Link just from two - ICC profile requires the use of Absolute Colorimetric intent during - linking, and this reduces flexibility. In addition, a typical ICC - device profile may not capture the neutral axis behavior quite as - well as an explicit calibration, since it doesn't sample the - displays neutral axis behaviour in quite as much detail. It is often - desirable therefore, to calibrate the display device so as to have - the specific white point desired so that one of the white point - relative linking intents can be used, and to improve the displays - general neutral axis behavior so that subsequent profiling works to - best advantage. In summary, there are basically 4 options in - handling white point & neutral axis calibration:
    -
      -
    • Don't bother correcting the white point. Most displays are - close to the typical D65 target, and our eyes adapt to the white - automatically unless it is very far from the daylight locus or - we have something else to refer to. If this approach is taken, - then display profiling and linking can ignore calibration, and - one of the non Absolute Colorimetric intents (such as Relative - Colorimetric) is chosen during profile linking. It is wise to - make sure that the video card VideoLUTs are set to some known - state (ie. linear using "dispwin -c" , or set by a an installed - ICC display profile) though.
      -
    • -
    • Calibrate the white point and linearise the neutral axis using - the display controls. Many TV's have internal calibration - controls that allow setting the white point, and possibly the - neutral axis response. Either a dedicated Video calibration + + + + madvr" in dispcal, dispread and dispwin. Leave the MadTPG + "VideoLUT" and "3dluts" buttons in their default  (enabled) + state, as the various tools will automatically take care of + disabling the 3dLut and/or calibration curves as needed.
      +
      + Another option is to use a ChromeCast + using the option "-dcc" in dispcal, dispread and dispwin. + Note that the ChromeCast as a test patch source is probably the + least accurate of your choices, since it up-samples the test + patch and transforms from RGB to YCC and back, but should be + accurate within ± 1 bit. You may have to modify any firewall to + permit port 8081 to be accessed on your machine if it falls back to + the Default receiver (see installation + instructions for your platform). +
      2) White point calibration & neutral axis calibration.
      + A Device Link is capable of embodying all aspects of the + calibration, including correcting the white point and neutral axis + behavior of the output device, but making such a Link just from two + ICC profile requires the use of Absolute Colorimetric intent during + linking, and this reduces flexibility. In addition, a typical ICC + device profile may not capture the neutral axis behavior quite as + well as an explicit calibration, since it doesn't sample the + displays neutral axis behaviour in quite as much detail. It is often + desirable therefore, to calibrate the display device so as to have + the specific white point desired so that one of the white point + relative linking intents can be used, and to improve the displays + general neutral axis behavior so that subsequent profiling works to + best advantage. In summary, there are basically 4 options in + handling white point & neutral axis calibration:
      +
        +
      • Don't bother correcting the white point. Most displays are + close to the typical D65 target, and our eyes adapt to the white + automatically unless it is very far from the daylight locus or + we have something else to refer to. If this approach is taken, + then display profiling and linking can ignore calibration, and + one of the non Absolute Colorimetric intents (such as Relative + Colorimetric) is chosen during profile linking. It is wise to + make sure that the video card VideoLUTs are set to some known + state (ie. linear using "dispwin -c" , or set by a an installed + ICC display profile) though.
        +
      • +
      • Calibrate the white point and linearise the neutral axis using + the display controls. Many TV's have internal calibration + controls that allow setting the white point, and possibly the + neutral axis response. Either a dedicated Video calibration package could be used, or ArgyllCMS dispcal's @@ -3215,28 +3274,30 @@ a - - interactive adjustment mode can be used to set the white point. - Note that while adjusting the neutral axis for neutrality may - help, the Device Link will override the transfer curve - characteristic of the calibrated display, so aiming for a - transfer curve approximately the same as the target and - reasonably perceptually linear is all that is required. If this - approach is taken, then display profiling and linking can ignore - calibration, and one of the non Absolute Colorimetric intents is - chosen during profile linking. It is wise to make sure that the - video card VideoLUTs are set to some known state  though.
      • -
      • [Recommended] Calibrate the white point and neutral - axis using ArgyllCMS dispcal. Since - the Device Link will override the calibrated transfer curve - characteristic of the display, there there may be no point in - doing much more than a medium calibration, and choosing a - standard that has a straight segment from black, such as L*a*b*, - sRGB, Rec709 or SMPTE240 curve. The exact shape of the - calibration curve is not critically important, as the profiling - and 3dLut will set the final response. If this approach is - taken, then the resulting calibration file should be provided to - dispread as the -k parameter or +
      • [Recommended] Calibrate the white point and neutral + axis using ArgyllCMS dispcal. Since + the Device Link will override the calibrated transfer curve + characteristic of the display, there there may be no point in + doing much more than a medium calibration, and choosing a + standard that has a straight segment from black, such as L*a*b*, + sRGB, Rec709 or SMPTE240 curve. The exact shape of the + calibration curve is not critically important, as the profiling + and 3dLut will set the final response. If this approach is + taken, then the resulting calibration file should be provided to + dispread as the -k parameter or -K parameter.  See also below Choice @@ -3249,476 +3310,478 @@ a - - of where to apply display per channel calibration curves.
      • -
      • Choose one of the Absolute Colorimetric intents in collink - (ie. -i aw). This greatly reduces flexibility, and may not be - quite as accurate as an explicit calibration.
      • -
      - If an explicit calibration is used, then it is a good idea to add - some test points down the neutral axis when profiling (targen -g parameter).
      -
      - 3) Choice of where to apply display per channel calibration - curves
      -
      - If calibration curves are going to be used, then it needs to be - decided where they will be applied in the video processing chain. - There are two options:
      -
      - a) Install the calibration curves in the playback system. On - a PC the display, this can be done by loading the calibration curves - into the Video Card temporarily using "dispwin calibration.cal", or - installing the ICC profile into the system persistently using - something like "dispwin -I profile.icm",
      - or when using MadVR 0.86.9 or latter by creating a 3dLut with - appended calibration curves using -H - display.cal.
      -
      - b) The calibration can be incorporated into the Device - Link/3dLUT by providing it to collink as the -a display.cal. This is the only option - if the video display path does not have some separate facility to - handle calibration curves. Note that if the playback system has - graphic card VideoLUTs then they will have to be set to a defined - consistent state such as linear. When using MadVR 0.86.9 or latter - this will be done automatically since the -a option will append a - linear set of calibration curves to the 3dLut.
      -
      - The choice is dictated by a number of considerations:
      -
        -
      • Does the video playback path have a facility for installing - the calibration curves ? If playing back system is a PC, then - typically the Graphics Card supports 1D VideoLUTs, thereby - making a) a possible choice.
        -
      • -
      • Does the video playback always play back through the - Video Card VideoLUTs ? Some systems do not apply VIdeoLUTs to - things like overlay plane rendering. If not, then you need to - choose b), but also make sure that if it does use the Video Card - VideoLUTs in some situations, that they are set to linear (ie. - dispcal -c). One way of determining when the VideoLUTs get used - or not is to load a distinct calibration such as "strange.cal" - provided in the ref folder, and check visually if it is - affecting the video or not, ie. "dispcal strange.cal". Note that - using MadVR 0.86.9 or latter in combination with a 3dLut with - appended calibration curves will apply the calibration even with - overlay plane rendering.
        -
      • -
      • Do you want/need other applications to share the calibration - curves or profile or not ? If you do, then it is desirable to - choose a).
      • -
      • Quality considerations. VideoLUTs may or may not be of greater - depth than the standard 8 bit per color component frame buffer. - If they are, and the video path passes that extra depth through - to the display, and the display is capable of using that extra - depth, then a) may be a desirable choice from a quality point of - view. You can get some idea whether this is the case by running - "dispcal -R". If the VideoLUT depth is not better than 8 bits, - then it may be more desirable to choose b), since renders like - MadVR can use dithering to give better than 8 bits precision in - the video playback.
        -
      • -
      -
      4) Output device calibration and profiling.
      - Output device profiling should basically follow the guide above in Adjusting and Calibrating a displays and Profiling Displays. The assumption is that either - you are calibrating/profiling your computer display for video, or - your TV is connected to the computer you are creating - calibrations/profiles on, and that the connection between the PC and - TV display is such that full range RGB signals are being used, or - that the Video card has automatically or manually been configured to - scale full range RGB values to Video levels for the TV. If the - latter is not possible, then use the -E options on dispcal and - dispread. (See Signal encoding bellow for more details on - this). It may also improve the accuracy of the display profile if - you use the dispread -Z option to - quantize the test values to the precision of the display - system.  Don't use the -E options on dispcal and dispread, nor - the -Z option on dispread if you are using MadVR to display test - patches using the "-d madvr" option.
      -
      - Once the profile has been created, it is possible to then use the - resulting Device Link/3DLut with signal encoding other than full - range or Video level RGB.
      -
      5) Target colorspace
      -
      - In practical terms, there are five common Video and Digital Cinema - encoding colorspaces.
      -
      - For Standard Definition:
      -
      -     EBU 3213 or "PAL 576i" primaries.
      -
      -     SMPTE RP 145 or "NTSC 480i" primaries.
      -
      - For High Definition:
      -
      -     Rec 709 primaries.
      -
      - For Ultra High Defintion
      -
      -     Rec 2020 primaries.
      -
      - For Digital Cinema
      -
      -     SMPTE-431-2  or "DCI-P3"
      -
      - PAL and NTSC have historically had poorly specified transfer curve - encodings, and the Rec 709 HDTV encoding curve is the modern recommendation, - but the overall interpretation of Video sources may in fact be - partly determined by the expected standard Video display device - characteristics (see Viewing conditions adjustment and gamut - mapping below for more details).
      -
      - To enable targeting these colorspaces, ArgyllCMS provides 5 ICC - profiles in the ref directory to use as source - colorspaces:   
      -
      -     EBU3213_PAL.icm
      -
      -     SMPTE_RP145_NTSC.icm
      -
      -     Rec709.icm
      -
      -     Rec2020.icm
      -
      -     SMPTE431_P3.icm
      -
      6) Signal encoding
      - Typical PC display output uses full range RGB signals (0 .. 255 in 8 - bit parlance), while typical Video encoding allows some head & - footroom for overshoot and sync of digitized analog signals, and - typically uses a 16..235 range in 8 bits. In many cases Video is - encoded as luma and color difference signals YCbCr (loosely known as - YUV as well), and this also uses a restricted range 16..235 for Y, - and 16..240 for Cb and Cr in 8 bit encoding. The extended gamut - xvYCC encoding uses 16..235 for Y, and 1..254 for Cb and Cr.
      -
      - The signal encoding comes into play in two situations: 1) - Calibrating and profiling the display, and 2) Using the resulting - Device Link/3DLut.
      - The encoding may need to be different in these two situations, - either because different video source devices are being used for - calibration/profiling and for video playback, or because the video - playback system uses the Device Link/3DLut at a point in its - processing pipeline that requires a specific encoding.
      -
      - For calibration & profiling, the display will be driven by a - computer system so that dispcal and dispread can be used. By default - these programs expect to output full range RGB signals, and it is - assumed that either the display accepts full range signals, or that - the graphics card or connection path has been setup to convert the - full range values into Video range signals automatically or - manually. If this is not the case, then both dispcal and dispread - have a -E option that will modify them to output Video range RGB - values.
      -
      - If MadVR is the target of the calibration and profiling, then there - is an option to use it to display the calibration and profiling test - patches (-d madvr). In this case, MadVR should be configured - appropriately for full range or Video range encoding, and the -E - flag should not be used with dispcal or dispread, since - MadVR will be taking care of such conversions.
      -
      - If a calibration file was created using dispcal -E, then using it in - dispread will automatically trigger Video level RGB signals during - profiling. Any time such a Video level calibration is loaded into - the Graphics card VideoLUTs using dispwin, or the calibration curve - is converted to a 'vcgt' tag in a profile, the curve will also - convert full range RGB to Video range RGB. This should be kept in - mind so that if video playback is being performed with the - calibration curves installed in the Graphics card VideoLUTs, that - full range is converted only once to Video range (ie. In this - situation MadVR output should be set to full range if being played - back through the calibration curves in hardware, but only if dispcal - -E has been used). On the other hand, if the calibration curves are - incorporated into the DeviceLink/3dLUT, then the conversion to Video - levels has to be done somewhere else in the pipeline, such as using - MadVR video level output, or by the graphics card, etc.
      -
      - When creating the Device Link/3dLut, it is often necessary to - specify one of the video encodings so that it fits in to the - processing pipeline correctly. For instance the eeColor needs to - have input and output encoding that suits the HDMI signals passing - through it, typically Video Range RGB. MadVR needs Video Level RGB - to match the values being passed through the 3dLut at that point.
      -
      - There are several version of YCbCr encoding supported as well, even - though neither the eeColor nor the current version of MadVR need or - can use them at present.
      -
      7) Black point mapping
      -

      Video encoding assumes that the black displayed on a device is a - perfect black (zero light). No real device has a perfect black, - and if a colorimetric intent is used then certain image values - near black will get clipped to the display black point, loosing - shadow detail. To avoid this, some sort of black point mapping is - usually desirable. There are two mechanisms available in collink: - a) Custom EOTF with input and/or output black point mapping, or b) - using one of the smart gamut mapping intents that does black point - mapping (e.g. la, p, pa, ms or s).
      -

      -
      8) Viewing conditions adjustment and gamut mapping
      -

      -

      In historical TV systems, there is a viewing conditions - adjustment being made between the bright studio conditions that TV - is filmed in, and the typical dim viewing environment that people - view it in. This is created by the difference between the encoding - response curve gamma of about 2.0, and a typical CRT response - curve gamma of 2.4.
      -

      -

      In theory Rec709 defines the video encoding, but it seems in - practice that much video material is adjusted to look as intended - when displayed on a reference monitor having a display gamma of - somewhere between 2.2 and 2.4, viewed in a dim viewing - environment. The modern standard covering the display EOTF - (Electro-Optical Transfer Curve) is BT.1886, - which defines a pure power 2.4 curve with an input offset and - scale applied to account for the black point offset while - retaining dark shadow tonality. So another means of making the - viewing adjustment is to use the BT.1886-like EOTF for Rec709 - encoded material. Collink supports this using the -I b, and allows some control over the - degree of viewing conditions adjustment by overriding the BT.1886 - gamma  using the -I b:g.g - parameter. This is the recommended approach to start with, - since it gives good results with a single parameter.
      -

      -

      The addition of a second optional parameter -I b:p.p:g.g - allows control over the degree of black point offset accounted for - as an output offset, as opposed to input offset Once the effective - gamma value has been chosen to suite the viewing conditions and - set the overall contrast for mid greys, increasing the proportion - of black offset accounted for in the output of the curve is a way - of reducing the deep shadow detail, if it is being overly - emphasized.

      -

      An alternate approach to making this adjustment is to take - advantage of the viewing conditions adjustment using the CIECAM02 - model available in collink. Some control over the degree of - viewing conditions adjustment is possible by varying the viewing - condition parameters.

      -

      A third alternative is to combine the two approaches. The source - is defined as Rec709 primaries with a BT.1886-like EOTF display in - dim viewing conditions, and then CIECAM02 is used to adjust for - the actual display viewing conditions. Once again, control over - the degree of viewing conditions adjustment is possible by varying - the viewing condition parameters
      -

      -


      -

      -

      9) Correcting for any black point inaccuracy in the display - profile
      -

      -

      Some video display devices have particularly good black points, - and any slight raising of the black due to innacuracies in the - display profile near black can be objectionable. As well as using - the targen -V flag to improve - accuracy near black during profiling, if the display is known to - be well behaved (ie. that it's darkest black is actually at RGB - value 0,0,0), then the collink -b - flag can be used, to force the source RGB 0,0,0 to map to the - display 0,0,0.
      -

      -
      Putting it all together:
      - In this example we choose to create a display calibration first - using dispcal, and create a simple matrix profile as well:
      -
      -   dispcal -v -o -qm -k0 -w 0.3127,0.3290 -gs -o TVmtx.icm - TV
      -
      - We are targeting a D65 white point (-w 0.3127,0.3290) and - an sRGB response curve.
      -
      - If you are using the madTPG you would use:
      -
      -   dispcal -v -d madvr -o -qm -k0 -w 0.3127,0.3290 -gs -o - TVmtx.icm TV
      -
      - Then we need to create a display patch test set. We can use the - simple matrix to pre-condition the test patches, as this helps - distribute them where they will be of most benefit. If have - previously profiled your display, you should use that previous - profile, or if you decided not to do a dispcal, then the Rec709.icm - should be used as a substitute. Some per channel and a moderate - number of full spread patches is used here - more will increase - profiling accuracy, a smaller number will speed it up. Since the - video or film material is typically viewed in a darkened viewing - environment, and often uses a range of maximum brightnesses in - different scenes, the device behavior in the dark regions of its - response are often of great importance, and using the targen -V parameter can help improve the - accuracy in this region at the expense of slightly lower accuracy in - lighter regions.
      -
      -   targen -v -d3 -s30 -g100 -f1000 -cTVmtx.icm -V1.8 TV
      -
      - The display can then be measured:
      -
      -   dispread -v -k -Z8 TV.cal TV
      -
      - or using madTPG:
      -
      -  dispread -v -d madvr -K TV.cal TV
      -
      - and then a cLUT type ICC profile created. Since we will be using - collink smart linking, we minimize the B2A table size. We use the - default colprof -V parameter carried through from targen:
      -
      -   colprof -v -qh -bl TV
      -
      - Make sure you check the delta E report at the end of the profile - creation, to see if the sample data and profile is behaving - reasonably. Depending on the type of device, and the consistency of - the readings, average errors of 5 or less, and maximum errors of 15 - or less would normally be expected. If errors are grossly higher - than this, then this is an indication that something is seriously - wrong with the device measurement, or profile creation.
      -
      - If you would like to use the display ICC profile for general color - managed applications, then you would compute a more complete - profile:
      -
      -   colprof -v -qh TV
      -
      - The recommended approach then is to create a Device Link that uses a - BT.1886 black point and viewing conditions adjustment, say one of - the following:
      -
      -   collink -v -Ib:2.4 -b -G -ir Rec709.icm TV.icm - HD.icm   # dark conditions
      -
        collink -v -Ib     -b -G -ir - Rec709.icm TV.icm HD.icm   # dim conditions - good - default
      -
        collink -v -Ib:2.1 -b -G -ir Rec709.icm TV.icm - HD.icm   # mid to dim conditions
      -
        collink -v -Ib:2.0 -b -G -ir Rec709.icm TV.icm - HD.icm   # mid to light conditions
      -
      - or you could do it using pure CIECAM02 adjustment and a black point - mapping:
      -
      -   collink -v -ctv -dmd -da:1 -G -ila Rec709.icm TV.icm - HD.icm  # very dark conditions
      -
        collink -v -ctv -dmd -da:3 -G -ila Rec709.icm - TV.icm HD.icm  # dim conditions
      -
        collink -v -ctv -dmd -da:7 -G -ila Rec709.icm - TV.icm HD.icm  # mid to dim conditions - good default
      -
        collink -v -ctv -dmd -da:15 -G -ila Rec709.icm - TV.icm HD.icm # mid conditions
      -
      - or using both to model a reference video display system that is - adapted to your viewing conditions:
      -
      -
        collink -v -Ib -c md -dmd -da:5  -G -ila - Rec709.icm TV.icm HD.icm # very dark conditions
      -
        collink -v -Ib -c md -dmd -da:10 -G -ila Rec709.icm - TV.icm HD.icm  # dim conditions
      -
        collink -v -Ib -c md -dmd -da:18 -G -ila Rec709.icm - TV.icm HD.icm  # mid to dark conditions
      -
        collink -v -Ib -c md -dmd -da:30 -G -ila Rec709.icm - TV.icm HD.icm   # mid to dark conditions
      -
      - None of the above examples incorporate the calibration curves, so it - is assumed that the calibration curves would be installed so that - the Video Card applies calibration, ie:
      -
      -     dispwin TV.cal
      -
      - or the simple matrix profile installed:
      -
      -     dispwin -I TVmtx.icm
      -
      - or a the more complete display profile could be installed:
      -
      -   dispwin -I TV.icm
      -
      - See also here for information on how - to make sure the calibration is loaded on each system start. If not, - then you will want to incorporate the calibration in the Device - Link/3dlut by using collink "-a TV.cal".
      -
      - If the video path needs Video Level RGB encoding but does not - provide a means to do this, then you will want to include the -E - flag in the dispcal and dispread command lines above.
      -
      - Below are specific recommendation for the eeColor and MadVR that - include the flags to create the .3dlut and encode the input and - output values appropriately, but only illustrate using the - recommended BT.1886 black point and viewing conditions adjustments, - rather than illustrating CIECAM02 etc. use.
      -
      - For faster exploration of different collink option, you could omit - the "colprof -bl" option, and use collink "-g" instead of "-G", - since this
      - will greatly speed up collink. Once you are happy with the link - details, you can then generate a higher quality link/3dLut using - "collink -G ..".
      -
      - You can also increase the precision of the device profile by - increasing the number of test patches measured (ie. up to a few - thousand, depending on how long you are prepared to wait for the - measurement to complete, and how stable your display and instrument - are).
      -
      - Alternatives to relative colorimetric rendering ("-i r") or - luminance matched appearance ("-i la") used in the examples above - and below, are, perceptual ("-i p") which will ensure that the - source gamut is compressed rather than clipped by the display, or - even a saturation rendering ("-i ms"), which will expand the gamut - of the source to the full range of the output.
      -
      -
      - eeColor
      -
      - For PC use, where the encoding is full range RGB:
      -
      -   collink -v -3e -Ib -b -G -ir -a TV.cal Rec709.icm TV.icm - HD.icm
      -
      - For correct operation both the 3DLut HD.txt and the per channel - input curves HD-first1dred.txt, HD-first1dgreen.txt and - HD-first1dblue.txt. the latter by copying them over the default - input curve files uploaded by the TruVue application.
      -
      - See <http://www.avsforum.com/t/1464890/eecolor-processor-argyllcms> - for some more details.
      -
      - Where the eeColor is connected from a Video source using HDMI, it - will probably be processing TV RGB levels, or YCbCr encoded signals - that it converts to/from RGB internally, so
      -
      -   collink -v -3e -et -Et -Ib -b -G -ir -a TV.cal - Rec709.icm TV.icm HD.icm
      -
      - in this case just the HD.txt file needs installing on the eeColor, - but make sure that the original linear "first1*.txt files are - re-installed, or install the ones generated by collink, which will - be linear for -e t mode.
      -
      - MadVR
      -
      - MadVR 0.86.9 or latter has a number of features to support accurate - profiling and calibration, and is the recommended version to - use.  It converts from the media colorspace to the 3dLut input - space automatically with the type of source being played, but has - configuration for to 5 3dLuts, each one optimized for a particular - source color space. The advantage of building and installing several - 3dLuts is that unnecessary gamut clipping can be avoided.
      -
      - If you are just building one 3dLut then Rec709 source is a good one - to pick.
      -
      - If you want to share the VideoLUT calibration curves between your - normal desktop and MadVR, then it is recommended that you install - the display ICC profile and use the -H option:
      -
      -     collink -v -3m -et -Et -Ib -b -G -ir -H - TV.cal Rec709.icm TV.icm HD.icm
      -

      + + + + of where to apply display per channel calibration curves.
    • +
    • Choose one of the Absolute Colorimetric intents in collink + (ie. -i aw). This greatly reduces flexibility, and may not be + quite as accurate as an explicit calibration.
    • +
    + If an explicit calibration is used, then it is a good idea to add + some test points down the neutral axis when profiling (targen -g parameter).
    +
    + 3) Choice of where to apply display per channel calibration + curves
    +
    + If calibration curves are going to be used, then it needs to be + decided where they will be applied in the video processing chain. + There are two options:
    +
    + a) Install the calibration curves in the playback system. On + a PC the display, this can be done by loading the calibration curves + into the Video Card temporarily using "dispwin calibration.cal", or + installing the ICC profile into the system persistently using + something like "dispwin -I profile.icm",
    + or when using MadVR 0.86.9 or latter by creating a 3dLut with + appended calibration curves using -H + display.cal.
    +
    + b) The calibration can be incorporated into the Device + Link/3dLUT by providing it to collink as the -a display.cal. This is the only option + if the video display path does not have some separate facility to + handle calibration curves. Note that if the playback system has + graphic card VideoLUTs then they will have to be set to a defined + consistent state such as linear. When using MadVR 0.86.9 or latter + this will be done automatically since the -a option will append a + linear set of calibration curves to the 3dLut.
    +
    + The choice is dictated by a number of considerations:
    +
      +
    • Does the video playback path have a facility for installing + the calibration curves ? If playing back system is a PC, then + typically the Graphics Card supports 1D VideoLUTs, thereby + making a) a possible choice.
      +
    • +
    • Does the video playback always play back through the + Video Card VideoLUTs ? Some systems do not apply VIdeoLUTs to + things like overlay plane rendering. If not, then you need to + choose b), but also make sure that if it does use the Video Card + VideoLUTs in some situations, that they are set to linear (ie. + dispcal -c). One way of determining when the VideoLUTs get used + or not is to load a distinct calibration such as "strange.cal" + provided in the ref folder, and check visually if it is + affecting the video or not, ie. "dispcal strange.cal". Note that + using MadVR 0.86.9 or latter in combination with a 3dLut with + appended calibration curves will apply the calibration even with + overlay plane rendering.
      +
    • +
    • Do you want/need other applications to share the calibration + curves or profile or not ? If you do, then it is desirable to + choose a).
    • +
    • Quality considerations. VideoLUTs may or may not be of greater + depth than the standard 8 bit per color component frame buffer. + If they are, and the video path passes that extra depth through + to the display, and the display is capable of using that extra + depth, then a) may be a desirable choice from a quality point of + view. You can get some idea whether this is the case by running + "dispcal -R". If the VideoLUT depth is not better than 8 bits, + then it may be more desirable to choose b), since renders like + MadVR can use dithering to give better than 8 bits precision in + the video playback.
      +
    • +
    +
    4) Output device calibration and profiling.
    + Output device profiling should basically follow the guide above in Adjusting and Calibrating a displays and Profiling Displays. The assumption is that either + you are calibrating/profiling your computer display for video, or + your TV is connected to the computer you are creating + calibrations/profiles on, and that the connection between the PC and + TV display is such that full range RGB signals are being used, or + that the Video card has automatically or manually been configured to + scale full range RGB values to Video levels for the TV. If the + latter is not possible, then use the -E options on dispcal and + dispread. (See Signal encoding bellow for more details on + this). It may also improve the accuracy of the display profile if + you use the dispread -Z option to + quantize the test values to the precision of the display + system.  Don't use the -E options on dispcal and dispread, nor + the -Z option on dispread if you are using MadVR to display test + patches using the "-d madvr" option.
    +
    + Once the profile has been created, it is possible to then use the + resulting Device Link/3DLut with signal encoding other than full + range or Video level RGB.
    +
    5) Target colorspace
    +
    + In practical terms, there are five common Video and Digital Cinema + encoding colorspaces.
    +
    + For Standard Definition:
    +
    +     EBU 3213 or "PAL 576i" primaries.
    +
    +     SMPTE RP 145 or "NTSC 480i" primaries.
    +
    + For High Definition:
    +
    +     Rec 709 primaries.
    +
    + For Ultra High Defintion
    +
    +     Rec 2020 primaries.
    +
    + For Digital Cinema
    +
    +     SMPTE-431-2  or "DCI-P3"
    +
    + PAL and NTSC have historically had poorly specified transfer curve + encodings, and the Rec 709 HDTV encoding curve is the modern recommendation, + but the overall interpretation of Video sources may in fact be + partly determined by the expected standard Video display device + characteristics (see Viewing conditions adjustment and gamut + mapping below for more details).
    +
    + To enable targeting these colorspaces, ArgyllCMS provides 5 ICC + profiles in the ref directory to use as source + colorspaces:   
    +
    +     EBU3213_PAL.icm
    +
    +     SMPTE_RP145_NTSC.icm
    +
    +     Rec709.icm
    +
    +     Rec2020.icm
    +
    +     SMPTE431_P3.icm
    +
    6) Signal encoding
    + Typical PC display output uses full range RGB signals (0 .. 255 in 8 + bit parlance), while typical Video encoding allows some head & + footroom for overshoot and sync of digitized analog signals, and + typically uses a 16..235 range in 8 bits. In many cases Video is + encoded as luma and color difference signals YCbCr (loosely known as + YUV as well), and this also uses a restricted range 16..235 for Y, + and 16..240 for Cb and Cr in 8 bit encoding. The extended gamut + xvYCC encoding uses 16..235 for Y, and 1..254 for Cb and Cr.
    +
    + The signal encoding comes into play in two situations: 1) + Calibrating and profiling the display, and 2) Using the resulting + Device Link/3DLut.
    + The encoding may need to be different in these two situations, + either because different video source devices are being used for + calibration/profiling and for video playback, or because the video + playback system uses the Device Link/3DLut at a point in its + processing pipeline that requires a specific encoding.
    +
    + For calibration & profiling, the display will be driven by a + computer system so that dispcal and dispread can be used. By default + these programs expect to output full range RGB signals, and it is + assumed that either the display accepts full range signals, or that + the graphics card or connection path has been setup to convert the + full range values into Video range signals automatically or + manually. If this is not the case, then both dispcal and dispread + have a -E option that will modify them to output Video range RGB + values.
    +
    + If MadVR is the target of the calibration and profiling, then there + is an option to use it to display the calibration and profiling test + patches (-d madvr). In this case, MadVR should be configured + appropriately for full range or Video range encoding, and the -E + flag should not be used with dispcal or dispread, since + MadVR will be taking care of such conversions.
    +
    + If a calibration file was created using dispcal -E, then using it in + dispread will automatically trigger Video level RGB signals during + profiling. Any time such a Video level calibration is loaded into + the Graphics card VideoLUTs using dispwin, or the calibration curve + is converted to a 'vcgt' tag in a profile, the curve will also + convert full range RGB to Video range RGB. This should be kept in + mind so that if video playback is being performed with the + calibration curves installed in the Graphics card VideoLUTs, that + full range is converted only once to Video range (ie. In this + situation MadVR output should be set to full range if being played + back through the calibration curves in hardware, but only if dispcal + -E has been used). On the other hand, if the calibration curves are + incorporated into the DeviceLink/3dLUT, then the conversion to Video + levels has to be done somewhere else in the pipeline, such as using + MadVR video level output, or by the graphics card, etc.
    +
    + When creating the Device Link/3dLut, it is often necessary to + specify one of the video encodings so that it fits in to the + processing pipeline correctly. For instance the eeColor needs to + have input and output encoding that suits the HDMI signals passing + through it, typically Video Range RGB. MadVR needs Video Level RGB + to match the values being passed through the 3dLut at that point.
    +
    + There are several version of YCbCr encoding supported as well, even + though neither the eeColor nor the current version of MadVR need or + can use them at present.
    +
    7) Black point mapping
    +

    Video encoding assumes that the black displayed on a device is a + perfect black (zero light). No real device has a perfect black, + and if a colorimetric intent is used then certain image values + near black will get clipped to the display black point, loosing + shadow detail. To avoid this, some sort of black point mapping is + usually desirable. There are two mechanisms available in collink: + a) Custom EOTF with input and/or output black point mapping, or b) + using one of the smart gamut mapping intents that does black point + mapping (e.g. la, p, pa, ms or s).
    +

    +
    8) Viewing conditions adjustment and gamut mapping
    +

    +

    In historical TV systems, there is a viewing conditions + adjustment being made between the bright studio conditions that TV + is filmed in, and the typical dim viewing environment that people + view it in. This is created by the difference between the encoding + response curve gamma of about 2.0, and a typical CRT response + curve gamma of 2.4.
    +

    +

    In theory Rec709 defines the video encoding, but it seems in + practice that much video material is adjusted to look as intended + when displayed on a reference monitor having a display gamma of + somewhere between 2.2 and 2.4, viewed in a dim viewing + environment. The modern standard covering the display EOTF + (Electro-Optical Transfer Curve) is BT.1886, + which defines a pure power 2.4 curve with an input offset and + scale applied to account for the black point offset while + retaining dark shadow tonality. So another means of making the + viewing adjustment is to use the BT.1886-like EOTF for Rec709 + encoded material. Collink supports this using the -I b, and allows some control over the + degree of viewing conditions adjustment by overriding the BT.1886 + gamma  using the -I b:g.g + parameter. This is the recommended approach to start with, + since it gives good results with a single parameter.
    +

    +

    The addition of a second optional parameter -I b:p.p:g.g + allows control over the degree of black point offset accounted for + as an output offset, as opposed to input offset Once the effective + gamma value has been chosen to suite the viewing conditions and + set the overall contrast for mid greys, increasing the proportion + of black offset accounted for in the output of the curve is a way + of reducing the deep shadow detail, if it is being overly + emphasized.

    +

    An alternate approach to making this adjustment is to take + advantage of the viewing conditions adjustment using the CIECAM02 + model available in collink. Some control over the degree of + viewing conditions adjustment is possible by varying the viewing + condition parameters.

    +

    A third alternative is to combine the two approaches. The source + is defined as Rec709 primaries with a BT.1886-like EOTF display in + dim viewing conditions, and then CIECAM02 is used to adjust for + the actual display viewing conditions. Once again, control over + the degree of viewing conditions adjustment is possible by varying + the viewing condition parameters
    +

    +


    +

    +

    9) Correcting for any black point inaccuracy in the display + profile
    +

    +

    Some video display devices have particularly good black points, + and any slight raising of the black due to innacuracies in the + display profile near black can be objectionable. As well as using + the targen -V flag to improve + accuracy near black during profiling, if the display is known to + be well behaved (ie. that it's darkest black is actually at RGB + value 0,0,0), then the collink -b + flag can be used, to force the source RGB 0,0,0 to map to the + display 0,0,0.
    +

    +
    Putting it all together:
    + In this example we choose to create a display calibration first + using dispcal, and create a simple matrix profile as well:
    +
    +   dispcal -v -o -qm -k0 -w 0.3127,0.3290 -gs -o TVmtx.icm + TV
    +
    + We are targeting a D65 white point (-w 0.3127,0.3290) and + an sRGB response curve.
    +
    + If you are using the madTPG you would use:
    +
    +   dispcal -v -d madvr -o -qm -k0 -w 0.3127,0.3290 -gs -o + TVmtx.icm TV
    +
    + Then we need to create a display patch test set. We can use the + simple matrix to pre-condition the test patches, as this helps + distribute them where they will be of most benefit. If have + previously profiled your display, you should use that previous + profile, or if you decided not to do a dispcal, then the Rec709.icm + should be used as a substitute. Some per channel and a moderate + number of full spread patches is used here - more will increase + profiling accuracy, a smaller number will speed it up. Since the + video or film material is typically viewed in a darkened viewing + environment, and often uses a range of maximum brightnesses in + different scenes, the device behavior in the dark regions of its + response are often of great importance, and using the targen -V parameter can help improve the + accuracy in this region at the expense of slightly lower accuracy in + lighter regions.
    +
    +   targen -v -d3 -s30 -g100 -f1000 -cTVmtx.icm -V1.8 TV
    +
    + The display can then be measured:
    +
    +   dispread -v -k -Z8 TV.cal TV
    +
    + or using madTPG:
    +
    +  dispread -v -d madvr -K TV.cal TV
    +
    + and then a cLUT type ICC profile created. Since we will be using + collink smart linking, we minimize the B2A table size. We use the + default colprof -V parameter carried through from targen:
    +
    +   colprof -v -qh -bl TV
    +
    + Make sure you check the delta E report at the end of the profile + creation, to see if the sample data and profile is behaving + reasonably. Depending on the type of device, and the consistency of + the readings, average errors of 5 or less, and maximum errors of 15 + or less would normally be expected. If errors are grossly higher + than this, then this is an indication that something is seriously + wrong with the device measurement, or profile creation.
    +
    + If you would like to use the display ICC profile for general color + managed applications, then you would compute a more complete + profile:
    +
    +   colprof -v -qh TV
    +
    + The recommended approach then is to create a Device Link that uses a + BT.1886 black point and viewing conditions adjustment, say one of + the following:
    +
    +   collink -v -Ib:2.4 -b -G -ir Rec709.icm TV.icm + HD.icm   # dark conditions
    +
      collink -v -Ib     -b -G -ir + Rec709.icm TV.icm HD.icm   # dim conditions - good + default
    +
      collink -v -Ib:2.1 -b -G -ir Rec709.icm TV.icm + HD.icm   # mid to dim conditions
    +
      collink -v -Ib:2.0 -b -G -ir Rec709.icm TV.icm + HD.icm   # mid to light conditions
    +
    + or you could do it using pure CIECAM02 adjustment and a black point + mapping:
    +
    +   collink -v -ctv -dmd -da:1 -G -ila Rec709.icm TV.icm + HD.icm  # very dark conditions
    +
      collink -v -ctv -dmd -da:3 -G -ila Rec709.icm + TV.icm HD.icm  # dim conditions
    +
      collink -v -ctv -dmd -da:7 -G -ila Rec709.icm + TV.icm HD.icm  # mid to dim conditions - good default
    +
      collink -v -ctv -dmd -da:15 -G -ila Rec709.icm + TV.icm HD.icm # mid conditions
    +
    + or using both to model a reference video display system that is + adapted to your viewing conditions:
    +
    +
      collink -v -Ib -c md -dmd -da:5  -G -ila + Rec709.icm TV.icm HD.icm # very dark conditions
    +
      collink -v -Ib -c md -dmd -da:10 -G -ila Rec709.icm + TV.icm HD.icm  # dim conditions
    +
      collink -v -Ib -c md -dmd -da:18 -G -ila Rec709.icm + TV.icm HD.icm  # mid to dark conditions
    +
      collink -v -Ib -c md -dmd -da:30 -G -ila Rec709.icm + TV.icm HD.icm   # mid to dark conditions
    +
    + None of the above examples incorporate the calibration curves, so it + is assumed that the calibration curves would be installed so that + the Video Card applies calibration, ie:
    +
    +     dispwin TV.cal
    +
    + or the simple matrix profile installed:
    +
    +     dispwin -I TVmtx.icm
    +
    + or a the more complete display profile could be installed:
    +
    +   dispwin -I TV.icm
    +
    + See also here for information on how + to make sure the calibration is loaded on each system start. If not, + then you will want to incorporate the calibration in the Device + Link/3dlut by using collink "-a TV.cal".
    +
    + If the video path needs Video Level RGB encoding but does not + provide a means to do this, then you will want to include the -E + flag in the dispcal and dispread command lines above.
    +
    + Below are specific recommendation for the eeColor and MadVR that + include the flags to create the .3dlut and encode the input and + output values appropriately, but only illustrate using the + recommended BT.1886 black point and viewing conditions adjustments, + rather than illustrating CIECAM02 etc. use.
    +
    + For faster exploration of different collink option, you could omit + the "colprof -bl" option, and use collink "-g" instead of "-G", + since this
    + will greatly speed up collink. Once you are happy with the link + details, you can then generate a higher quality link/3dLut using + "collink -G ..".
    +
    + You can also increase the precision of the device profile by + increasing the number of test patches measured (ie. up to a few + thousand, depending on how long you are prepared to wait for the + measurement to complete, and how stable your display and instrument + are).
    +
    + Alternatives to relative colorimetric rendering ("-i r") or + luminance matched appearance ("-i la") used in the examples above + and below, are, perceptual ("-i p") which will ensure that the + source gamut is compressed rather than clipped by the display, or + even a saturation rendering ("-i ms"), which will expand the gamut + of the source to the full range of the output.
    +
    +
    + eeColor
    +
    + For PC use, where the encoding is full range RGB:
    +
    +   collink -v -3e -Ib -b -G -ir -a TV.cal Rec709.icm TV.icm + HD.icm
    +
    + For correct operation both the 3DLut HD.txt and the per channel + input curves HD-first1dred.txt, HD-first1dgreen.txt and + HD-first1dblue.txt. the latter by copying them over the default + input curve files uploaded by the TruVue application.
    +
    + See <http://www.avsforum.com/t/1464890/eecolor-processor-argyllcms> + for some more details.
    +
    + Where the eeColor is connected from a Video source using HDMI, it + will probably be processing TV RGB levels, or YCbCr encoded signals + that it converts to/from RGB internally, so
    +
    +   collink -v -3e -et -Et -Ib -b -G -ir -a TV.cal + Rec709.icm TV.icm HD.icm
    +
    + in this case just the HD.txt file needs installing on the eeColor, + but make sure that the original linear "first1*.txt files are + re-installed, or install the ones generated by collink, which will + be linear for -e t mode.
    +
    + MadVR
    +
    + MadVR 0.86.9 or latter has a number of features to support accurate + profiling and calibration, and is the recommended version to + use.  It converts from the media colorspace to the 3dLut input + space automatically with the type of source being played, but has + configuration for to 5 3dLuts, each one optimized for a particular + source color space. The advantage of building and installing several + 3dLuts is that unnecessary gamut clipping can be avoided.
    +
    + If you are just building one 3dLut then Rec709 source is a good one + to pick.
    +
    + If you want to share the VideoLUT calibration curves between your + normal desktop and MadVR, then it is recommended that you install + the display ICC profile and use the -H option:
    +
    +     collink -v -3m -et -Et -Ib -b -G -ir -H + TV.cal Rec709.icm TV.icm HD.icm
    +

        collink -v -3m -et -Et -Ib -b -G -ir -H @@ -3742,9 +3805,11 @@ a - - TV.cal EBU3213_PAL.icm TV.icm SD_PAL.icm
    -

    + + + + TV.cal
    EBU3213_PAL.icm TV.icm SD_PAL.icm

    +

        collink -v -3m -et -Et -Ib -b -G -ir -H @@ -3768,16 +3833,18 @@ a - - TV.cal SMPTE_RP145_NTSC.icm TV.icm SD_NTSC.icm
    -
    - For best quality it is better to let MadVR apply the calibration - curves using dithering, and allow it to set the graphics card to - linear by using the -a option:
    -
    -     collink -v -3m -et -Et -Ib -b -G -ir -a - TV.cal Rec709.icm TV.icm HD.icm
    -

    + + + + TV.cal
    SMPTE_RP145_NTSC.icm TV.icm SD_NTSC.icm
    +
    + For best quality it is better to let MadVR apply the calibration + curves using dithering, and allow it to set the graphics card to + linear by using the -a option:
    +
    +     collink -v -3m -et -Et -Ib -b -G -ir -a + TV.cal Rec709.icm TV.icm HD.icm
    +

        collink -v -3m -et -Et -Ib -b -G -ir -a @@ -3801,9 +3868,11 @@ a - - TV.cal EBU3213_PAL.icm TV.icm SD_PAL.icm
    -

    + + + + TV.cal
    EBU3213_PAL.icm TV.icm SD_PAL.icm
    +

        collink -v -3m -et -Et -Ib -b -G -ir -a @@ -3827,182 +3896,184 @@ a - - TV.cal SMPTE_RP145_NTSC.icm TV.icm SD_NTSC.icm
    -
    - the consequence though is that the appearance of other application - will shift when MadVR is using the 3dLut and loading the calibration - curves.
    -
    - The 3dLut can be used by opening the MadVR settings dialog, - selecting "calibration" and then selecting "calibrate this display - by using an external 3DLUT file", and then using the file dialog to - use it.
    -
    - If neither the -a no -H options are used, then no calibration curves - will be appended to the 3dLut, and MadVR will not change the - VideoLUTs when that 3dLut is in use. It is then up to you to manage - the graphics card VideoLUTs in some other fashion.
    -
    -
    -

    -

    Verifying Video Calibration

    -

    Often it is desirable to verify the results of a video - calibration and profile, and the following gives an outline of how - to use ArgyllCMS tools to do this. It is only possible to expect - perfect verification if a colorimetric intent was used during - linking - currently it's not possible to exactly verify a - perceptual or CIECAM02 viewing condition adjusted link.
    -
    -

    -

    The first step is to create a set of test points. This is - essentially the same as creating a set of test points for the - purposes of profiling, although it is best not to create exactly - the same set, so as to explore the colorspace at different - locatioins. For the purposes here, we'll actually create a regular - grid test set, since this makes it easier to visualize the - results, although a less regular set would probably be better for - numerical evaluation:
    -

    -

      targen -v -d3 -e1 -m6 -f0 -W verify
    -

    -

    We make sure there is at least one white patch usin g -e1, a 20% - increment grid using -m6, no full spread patches, and create an - X3DOM 3d visualization of the point set using the -W flag. It is - good to take a look at the verifyd.x3d.html file using a Web - browser. You may want to create several test sets that look at - particular aspects, ie. neutral axis response, pure colorant - responses, etc.
    -

    -

    Next we create a reference file by simulating the expected - response of the perfect video display system. Assuming the collink - options were "-et -Et -Ib -G -ir Rec709.icm TV.icm HD.icm" then we - would:
    -

    -

      copy verify.ti1 ref.ti1
    -   fakeread -v -b -Z8 TV.icm Rec709.icm ref
    -

    -

    You should adjust the parameters as necessary, so that the - reference matches the link options. For instance, if your link - options included "-I b:0.2:2.15" then the equivalent fakeread - option "-b 0.2:2.15:TV.icm" should be used, etc.
    -

    -
    -

    A sanity check we can make at this point is to see what the - expected result of the profiling & calibration will be, by - simulating the reproduction of this test set:
    -

    -

      copy verify.ti1 checkA.ti1
    -   fakeread -v -et -Z8 -p HD.icm -Et TV.icm checkA
    -

    -

    If you used collink -a, then the calibration incorporated in the - device link needs to be undone to match what the display profile - expects:

    -

      fakeread -v -et -Z8 -p HD.icm -Et -K TV.cal TV.icm - checkA

    -

    and then you can verify:
    -

    -

      colverify -v -n -w -x ref.ti3 checkA.ti3
    -

    -

    If you have targeted some other white point rather than video D65 - for the display, then use the -N flag instead of -n to align the - white points. [ Note that there can be some small discrepancies in - this case in some parts of the color space if a CIECAM02 linking - intent was used, due to the slightly different chromatic - adaptation algorithm it uses compared to the one used by verify to - match the white points.]
    -

    -

      verify -v -N -w -x ref.ti3 checkA.ti3
    -

    -

    This will give a numerical report of the delta E's, and also - generate an X3DOM plot of the errors in L*a*b* space. The - important thing is to take a look at the checkA.x3d.html file, to - see if gamut clipping is occurring - this is the case if the large - error vectors are on the sides or top of the gamut. Note that the - perfect cube device space values become a rather distorted cube - like shape in the perceptual L*a*b* space. If the vectors are - small in the bulk of the space, then this indicates that the link - is likely to be doing the right thing in making the display - emulate the video colorspace with a BT.1886 like black point - adjustment. You could also check just the in gamut test points - using:
    -

    -

      verify -v -N -w -x -L TV.icm ref.ti3 - checkA.ti3
    -
    -

    -
    -

    You can explicitly compare the gamuts of your video space and - your display using the gamut tools:
    -

    -

      iccgamut -ff -ia Rec709
    -
      iccgamut -ff -ia TV.icm
    -
      viewgam -i Rec709.gam TV.gam gamuts
    -

    -

    and look at the gamuts.x3d.html file, as well as taking notice of - % of the video volume that the display intersects. The X3DOM solid - volume will be the video gamut, while the wire frame is the - display gamut. If you are not targetting D65 with your display, - you should use iccgamut -ir instead of -ia, so as - to align the white points.
    -

    -
    -

    The main verification check is to actually measure the display - response and compare it against the reference. Make sure the - display is setup as you would for video playback and then use - dispread:
    -

    -

      copy verify.ti1 checkB.ti1
    -
      dispread -v -Z8 checkB
    -

    -

    You would add any other options needed (such as -y etc.) - to set your instrument up properly. If you are using madTPG, then - configure madVR to use the 3dLut you want to measure as the - default, and also use the dispread -V flag to make sure that the - 3dLut is being used for the measurements: [Note that if the - version of MadVR you are using does not have radio buttons in its - calibration setup to indicate a default 3dLut, then the 3dLut - under test should be the only one set - all others should be - blank. ]
    -

    -

      dispread -v -d madvr -V checkB
    -

    -

    Verify the same way as above:
    -

    -

      verify -v -n -w -x ref.ti3 checkB.ti3
    -

    -

    If your display does not cover the full gamut of your video - source, the errors are probably dominated by out of gamut colors. - You can verify just the in gamut test values by asking verify to - skip them, and this will give a better notion of the actual device - link and calibration accuracy:
    -

    -

      verify -v -n -w -x -L TV.icm ref.ti3 - checkB.ti3

    -


    -

    -

     
    -

    -


    -
    -

    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - - + + + + TV.cal SMPTE_RP145_NTSC.icm TV.icm SD_NTSC.icm
    +
    + the consequence though is that the appearance of other application + will shift when MadVR is using the 3dLut and loading the calibration + curves.
    +
    + The 3dLut can be used by opening the MadVR settings dialog, + selecting "calibration" and then selecting "calibrate this display + by using an external 3DLUT file", and then using the file dialog to + use it.
    +
    + If neither the -a no -H options are used, then no calibration curves + will be appended to the 3dLut, and MadVR will not change the + VideoLUTs when that 3dLut is in use. It is then up to you to manage + the graphics card VideoLUTs in some other fashion.
    +
    +
    +

    +

    Verifying Video Calibration

    +

    Often it is desirable to verify the results of a video + calibration and profile, and the following gives an outline of how + to use ArgyllCMS tools to do this. It is only possible to expect + perfect verification if a colorimetric intent was used during + linking - currently it's not possible to exactly verify a + perceptual or CIECAM02 viewing condition adjusted link.
    +
    +

    +

    The first step is to create a set of test points. This is + essentially the same as creating a set of test points for the + purposes of profiling, although it is best not to create exactly + the same set, so as to explore the colorspace at different + locatioins. For the purposes here, we'll actually create a regular + grid test set, since this makes it easier to visualize the + results, although a less regular set would probably be better for + numerical evaluation:
    +

    +

      targen -v -d3 -e1 -m6 -f0 -W verify
    +

    +

    We make sure there is at least one white patch usin g -e1, a 20% + increment grid using -m6, no full spread patches, and create an + X3DOM 3d visualization of the point set using the -W flag. It is + good to take a look at the verifyd.x3d.html file using a Web + browser. You may want to create several test sets that look at + particular aspects, ie. neutral axis response, pure colorant + responses, etc.
    +

    +

    Next we create a reference file by simulating the expected + response of the perfect video display system. Assuming the collink + options were "-et -Et -Ib -G -ir Rec709.icm TV.icm HD.icm" then we + would:
    +

    +

      copy verify.ti1 ref.ti1
    +   fakeread -v -b -Z8 TV.icm Rec709.icm ref
    +

    +

    You should adjust the parameters as necessary, so that the + reference matches the link options. For instance, if your link + options included "-I b:0.2:2.15" then the equivalent fakeread + option "-b 0.2:2.15:TV.icm" should be used, etc.
    +

    +
    +

    A sanity check we can make at this point is to see what the + expected result of the profiling & calibration will be, by + simulating the reproduction of this test set:
    +

    +

      copy verify.ti1 checkA.ti1
    +   fakeread -v -et -Z8 -p HD.icm -Et TV.icm checkA
    +

    +

    If you used collink -a, then the calibration incorporated in the + device link needs to be undone to match what the display profile + expects:

    +

      fakeread -v -et -Z8 -p HD.icm -Et -K TV.cal TV.icm + checkA

    +

    and then you can verify:
    +

    +

      colverify -v -n -w -x ref.ti3 checkA.ti3
    +

    +

    If you have targeted some other white point rather than video D65 + for the display, then use the -N flag instead of -n to align the + white points. [ Note that there can be some small discrepancies in + this case in some parts of the color space if a CIECAM02 linking + intent was used, due to the slightly different chromatic + adaptation algorithm it uses compared to the one used by verify to + match the white points.]
    +

    +

      verify -v -N -w -x ref.ti3 checkA.ti3
    +

    +

    This will give a numerical report of the delta E's, and also + generate an X3DOM plot of the errors in L*a*b* space. The + important thing is to take a look at the checkA.x3d.html file, to + see if gamut clipping is occurring - this is the case if the large + error vectors are on the sides or top of the gamut. Note that the + perfect cube device space values become a rather distorted cube + like shape in the perceptual L*a*b* space. If the vectors are + small in the bulk of the space, then this indicates that the link + is likely to be doing the right thing in making the display + emulate the video colorspace with a BT.1886 like black point + adjustment. You could also check just the in gamut test points + using:
    +

    +

      verify -v -N -w -x -L TV.icm ref.ti3 + checkA.ti3
    +
    +

    +
    +

    You can explicitly compare the gamuts of your video space and + your display using the gamut tools:
    +

    +

      iccgamut -ff -ia Rec709
    +
      iccgamut -ff -ia TV.icm
    +
      viewgam -i Rec709.gam TV.gam gamuts
    +

    +

    and look at the gamuts.x3d.html file, as well as taking notice of + % of the video volume that the display intersects. The X3DOM solid + volume will be the video gamut, while the wire frame is the + display gamut. If you are not targetting D65 with your display, + you should use iccgamut -ir instead of -ia, so as + to align the white points.
    +

    +
    +

    The main verification check is to actually measure the display + response and compare it against the reference. Make sure the + display is setup as you would for video playback and then use + dispread:
    +

    +

      copy verify.ti1 checkB.ti1
    +
      dispread -v -Z8 checkB
    +

    +

    You would add any other options needed (such as -y etc.) + to set your instrument up properly. If you are using madTPG, then + configure madVR to use the 3dLut you want to measure as the + default, and also use the dispread -V flag to make sure that the + 3dLut is being used for the measurements: [Note that if the + version of MadVR you are using does not have radio buttons in its + calibration setup to indicate a default 3dLut, then the 3dLut + under test should be the only one set - all others should be + blank. ]
    +

    +

      dispread -v -d madvr -V checkB
    +

    +

    Verify the same way as above:
    +

    +

      verify -v -n -w -x ref.ti3 checkB.ti3
    +

    +

    If your display does not cover the full gamut of your video + source, the errors are probably dominated by out of gamut colors. + You can verify just the in gamut test values by asking verify to + skip them, and this will give a better notion of the actual device + link and calibration accuracy:
    +

    +

      verify -v -n -w -x -L TV.icm ref.ti3 + checkB.ti3

    +


    +

    +

     
    +

    +


    +
    +

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + diff --git a/doc/SpyderChecker24.jpg b/doc/SpyderChecker24.jpg new file mode 100644 index 0000000..022eb11 Binary files /dev/null and b/doc/SpyderChecker24.jpg differ diff --git a/doc/afiles b/doc/afiles index 88f7406..a73a8ba 100644 --- a/doc/afiles +++ b/doc/afiles @@ -146,6 +146,7 @@ CMP_DT_003.jpg CMP_Digital_Target-4.jpg colorchecker.jpg SpyderChecker.jpg +SpyderChecker24.jpg LSDC.jpg QPcard201.jpg QPcard202.jpg diff --git a/doc/chartread.html b/doc/chartread.html index 4d5b005..e9dddaf 100644 --- a/doc/chartread.html +++ b/doc/chartread.html @@ -27,6 +27,7 @@ Verbose + mode
     -c listno
     -d
    @@ -62,6 +65,7 @@ measurement + Display type - instrument specific list to choose from.

     -e  -p
      -x [lx]            Take - manually entered - values, either L*a*b* (-xl) or XYZ (-xx).

     -n
     -l  -I file.cal        Override @@ -127,30 +135,35 @@ partly + Set filter configuration:
      n                  + None
      p                  + Polarising filter
      6                  + D65
      u                  + U.V. Cut

     
     
    -X file.ccss          @@ -188,6 +202,7 @@ Samples + for calibration
     -Q observ1931_2 (def.)  -S                 @@ -224,6 +241,7 @@ strip + & unexpected value warnings
     -W n|h|x           @@ -231,6 +249,7 @@ Override + serial port flow control: n = none, h = HW, x = Xon/Xoff
    .ti2]/output[chartread + -I parameter allows overriding the .ti2 calibration curves placed in the resulting .ti3 file with the actual calibration that was used for that particular print.
    @@ -415,12 +436,15 @@ Override strip instruments (i.e.. Eye-One Pro, Color Munki) when used with Argyll will automatically recognize a strip when read in the reverse direction by matching the patch readings against their expected - values. If the randomized patch layout has not been used, or the - expected values are not known accurately enough, this may cause - erroneous reverse recognition, so the -B flag - allows this to be turned off, forcing strips to only be read in the - forward direction.
    + values. If the expected values are not known accurately enough, this + may cause erroneous reverse recognition, so the -B + flag allows this to be turned off, forcing strips to only be read in + the forward direction. (Note that the DTP20 always allows + bi-directional strip reading.) If the randomized patch layout has + not been used, then  bi-directional strip recognition will + automatically turned off, and a warning issued if the -B flag is not + used.

    The -H option turns on high resolution spectral mode, if the instrument @@ -443,10 +467,8 @@ Override colorimeters that rely on sensor spectral sensitivity calibration information (ie. the X-Rite i1d3, or the DataColor Spyder4 & - Spyder 5).This - can - improve - a colorimeters accuracy for a particular type of display.
    + Spyder 5).This can improve a colorimeters accuracy for a + particular type of display.

    The -T ratio argument modifies the patch consistency tolerance threshold for some @@ -482,7 +504,10 @@ Override advisable to also use the -B flag if warnings are turned off, since many warnings indicate that the expected values are not to be relied on. With warnings - suppressed, greater care must be taken to read the correct strip.
    + suppressed, greater care must be taken to read the correct strip. If + the randomized patch layout has not been used, then "wrong strip" + warnings will automatically be suppressed, and bi-directional strip + recognition turned off.

    The -W n|h|x parameter overrides the default serial communications flow control diff --git a/doc/collink.html b/doc/collink.html index 0bb3e77..dc67463 100644 --- a/doc/collink.html +++ b/doc/collink.html @@ -58,6 +58,8 @@ + + @@ -122,6 +124,8 @@ existing + + @@ -170,6 +174,8 @@ clut + + @@ -212,6 +218,8 @@ preserve + + @@ -279,6 +287,8 @@ Include + + @@ -302,6 +312,8 @@ Include + + Append calibration curves to 3dlut
     

                 @@ -819,6 +855,8 @@ ms + + @@ -859,6 +897,8 @@ s + + @@ -900,6 +940,8 @@ al + + @@ -933,6 +975,8 @@ al + + @@ -951,6 +995,8 @@ al + + Use RGB->RGB forced black point hack
     
              g:glare       Glare light % of - ambient (default 1)
    + ambient (default 5)
              @@ -1512,6 +1582,8 @@ light + + @@ -1540,6 +1612,8 @@ light + + @@ -1583,6 +1657,8 @@ source + + @@ -1626,6 +1702,8 @@ source + + @@ -1676,6 +1754,8 @@ t + + @@ -1717,6 +1797,8 @@ z + + @@ -1761,6 +1843,8 @@ p + + @@ -1806,6 +1890,8 @@ q + + @@ -1854,6 +1940,8 @@ destination + + @@ -1897,6 +1985,8 @@ destination + + @@ -1929,6 +2019,8 @@ destination + + @@ -1962,6 +2054,8 @@ destination + + @@ -1986,6 +2080,8 @@ destination + + MadVR .3dlut   file
     
    -I B               @@ -1996,6 +2092,8 @@ destination + + Use BT.1886 source EOTF with technical gamma 2.4
     -I b:g.g           Use @@ -2007,7 +2105,7 @@ destination monospace;">

     -I + href="collink.html#Ib">-I g:g.g           Use effective gamma g.g source EOTF with all output black @@ -2040,6 +2138,8 @@ destination + + @@ -2072,6 +2172,8 @@ destination + + @@ -2098,6 +2200,8 @@ destination + + normal RGB 0..1 levels (default)
         @@ -2120,6 +2224,8 @@ destination + + RGB (16-235)/255 "TV" levels

         + + T                @@ -2147,6 +2255,8 @@ destination + + RGB (16-235)/255 "TV" levels, clip WTW [Input Only]
         @@ -2169,6 +2279,8 @@ destination + + Rec601 YCbCr SD (16-235,240)/255 "TV" levels
         @@ -2191,6 +2303,8 @@ destination + + Rec709 1125/60Hz YCbCr HD (16-235,240)/255 "TV" levels
         @@ -2213,6 +2327,8 @@ destination + + Rec709 1250/50Hz YCbCr HD (16-235,240)/255 "TV" levels
         @@ -2235,6 +2351,8 @@ destination + + Rec2020 YCbCr UHD (16-235,240)/255 "TV" levels
         @@ -2257,6 +2375,8 @@ destination + + Rec2020 Constant Luminance YCbCr UHD (16-235,240)/255 "TV" levels
    @@ -2280,6 +2400,8 @@ destination + + xvYCC Rec601 YCbCr Rec709 Prims. SD (16-235,240)/255 "TV" levels
    @@ -2303,6 +2425,8 @@ destination + + xvYCC Rec709 YCbCr Rec709 Prims. HD (16-235,240)/255 "TV" levels
    @@ -2344,6 +2468,8 @@ gamut + + @@ -2389,6 +2515,8 @@ ICC + + @@ -2426,6 +2554,8 @@ ICC + + @@ -2471,6 +2601,8 @@ ICC + + @@ -2577,6 +2709,8 @@ ICC + + @@ -2765,6 +2899,8 @@ ICC + + @@ -2858,6 +2994,16 @@ ICC destination, allowing the apperance parameters to alter the chromatic mapping.

    + The  lp + intent, Luminance Preserving Perceptual Appearance uses + compression to make the source gamut fit within the destination + gamut, but very heavily weights the preservation of the Luminance + value of the source, which will compromise the preservation of + saturation. No contrast enhancement is used if the dynamic range + is reduced. This intent may be of use where preserving the tonal + distinctions in images is more important than maintaining overall + colorfulness or contrast.
    +
    The ms intent, Saturation, uses 3 Dimensional compression and expansion to try and @@ -3024,6 +3170,8 @@ ICC + + @@ -3064,6 +3212,8 @@ ICC + + @@ -3104,6 +3254,8 @@ ICC + + @@ -3144,6 +3296,8 @@ ICC + + @@ -3184,6 +3338,8 @@ ICC + + @@ -3230,6 +3386,8 @@ White            &nb + + @@ -3431,6 +3589,8 @@ White            &nb + + Full output offset with effective gamma of 2.2
    -I B                  @@ -3441,6 +3601,8 @@ White            &nb + + Full input offset (BT.1886 like) with technical gamma of 2.4. This exactly implements the BT.1886 specification.
    -I G                  @@ -3452,6 +3614,8 @@ White            &nb + + Full output offset with technical gamma of 2.2

    -I b:2.3             @@ -3463,6 +3627,8 @@ White            &nb + + Full input offset (BT.1886 like) with effective gamma of 2.3
    -I g:2.3             @@ -3474,6 +3640,8 @@ White            &nb + + Full output offset with effective gamma of 2.3
    -I B:2.35           @@ -3484,6 +3652,8 @@ White            &nb + + Full input offset (BT.1886 like) with technical gamma of 2.35
    -I G:2.35           @@ -3494,6 +3664,8 @@ White            &nb + + Full output offset with technical gamma of 2.35

    -I b:0.4:2.3        @@ -3507,6 +3679,8 @@ White            &nb + + Same as above.
    -I B:0.4:2.35      60% input offset, 40% output offset with technical gamma of 2.35
    @@ -3525,6 +3699,8 @@ White            &nb style="font-family: monospace;">     + + T                @@ -3545,12 +3721,16 @@ White            &nb + + RGB (16-235)/255 "TV" levels, clip WTW [Input Only]
         + + x                @@ -3570,6 +3750,8 @@ White            &nb + + xvYCC Rec601 YCbCr Rec709 Prims. SD (16-235,240)/255 "TV" levels
    @@ -3593,6 +3775,8 @@ White            &nb + + xvYCC Rec709 YCbCr Rec709 Prims. HD (16-235,240)/255 "TV" levels
    @@ -3638,6 +3822,8 @@ White            &nb + + normal RGB 0..1 full range levels (default)
         @@ -3660,6 +3846,8 @@ White            &nb + + RGB (16-235)/255 "TV" levels     + + 6                @@ -3688,6 +3878,8 @@ White            &nb + + Rec601 YCbCr SD (16-235,240)/255 "TV" levels
         @@ -3710,6 +3902,8 @@ White            &nb + + Rec709 1125/60Hz YCbCr HD (16-235,240)/255 "TV" levels
         @@ -3732,6 +3926,8 @@ White            &nb + + Rec709 1250/50Hz YCbCr HD (16-235,240)/255 "TV" levels
         @@ -3754,6 +3950,8 @@ White            &nb + + Rec2020 YCbCr UHD (16-235,240)/255 "TV" levels
         @@ -3776,6 +3974,8 @@ White            &nb + + Rec2020 Constant Luminance YCbCr UHD (16-235,240)/255 "TV" levels

    @@ -3834,6 +4034,8 @@ White            &nb + + diff --git a/doc/colprof.html b/doc/colprof.html index b3b6df2..755226b 100644 --- a/doc/colprof.html +++ b/doc/colprof.html @@ -43,6 +43,8 @@ + + @@ -79,6 +81,8 @@ + + @@ -120,6 +124,8 @@ + + @@ -157,6 +163,8 @@ + + @@ -208,6 +216,8 @@ x + + @@ -252,6 +262,8 @@ White + + @@ -296,6 +308,8 @@ Wh + + @@ -340,6 +354,8 @@ Wh + + @@ -383,6 +399,8 @@ Black + + @@ -427,6 +445,8 @@ concave, + + @@ -451,6 +471,8 @@ concave, + + @@ -502,6 +524,8 @@ cLUT + + @@ -545,6 +569,8 @@ s + + @@ -589,6 +615,8 @@ S + + @@ -618,6 +646,8 @@ S + + @@ -664,6 +694,8 @@ and + + @@ -675,6 +707,8 @@ and + + Display Black Point override hack
     -V demphasis       @@ -689,6 +723,8 @@ and + + Degree of dark region cLUT grid emphasis 1.0-3.0 (default 1.00 = none)
     -f [illum] @@ -713,6 +749,8 @@ and + + @@ -737,6 +775,8 @@ and + + @@ -771,6 +811,8 @@ D50M2, + + @@ -806,6 +848,8 @@ D50M2, + + @@ -853,6 +897,8 @@ for + + @@ -886,6 +932,8 @@ for + + @@ -920,6 +968,8 @@ for + + @@ -954,6 +1004,8 @@ for + + @@ -996,6 +1048,8 @@ for + + @@ -1049,7 +1103,12 @@ for - pa - Perceptual Appearance
    + + + pa - Perceptual Appearance

    +                  + + lp - Luminance Preserving Perceptual
            @@ -1079,6 +1138,8 @@ for + + @@ -1107,6 +1168,8 @@ for + + rl - White Point Matched Colorimetric (Lab)
     -c viewcond        @@ -1138,6 +1201,8 @@ for + + @@ -1172,6 +1237,8 @@ for + + @@ -1205,6 +1272,8 @@ for + + @@ -1239,6 +1308,8 @@ for + + @@ -1272,6 +1343,8 @@ for + + @@ -1305,6 +1378,8 @@ for + + @@ -1367,6 +1442,8 @@ for + + @@ -1416,8 +1493,10 @@ for + + g:glare       Glare light % of - ambient (default 1)
                   @@ -1460,6 +1539,8 @@ for + + @@ -1494,6 +1575,8 @@ Override + + @@ -1648,6 +1731,8 @@ the + + @@ -1682,6 +1767,8 @@ the + + @@ -1751,6 +1838,8 @@ the + + @@ -1785,6 +1874,8 @@ the + + @@ -1818,6 +1909,8 @@ the + + @@ -1851,6 +1944,8 @@ the + + @@ -1884,6 +1979,8 @@ the + + @@ -1925,6 +2022,8 @@ White            &nb + + @@ -2006,7 +2105,7 @@ White            &nb point for input devices by avoiding clipping of values above the white point that can occur in L*a*b* based cLUT input profiles. A disadvantage of this type of profile is that it can be a lot less robust if given - a test patch set that is sparse, or too evenly spaced. By default + a test patch set that is sparse, or too unevenly spaced. By default cLUT XYZ PCS Display profiles will also have a set of dummy matrix tags included in them, for better compatibility with other systems. The dummy matrix deliberately interchanges Red, Green and Blue @@ -2182,6 +2281,8 @@ White            &nb + + diff --git a/doc/dispcal.html b/doc/dispcal.html index ff96ff2..d66caf5 100644 --- a/doc/dispcal.html +++ b/doc/dispcal.html @@ -1,28 +1,28 @@ - - - - dispcal - - - - -

    spectro/dispcal

    -

    Summary

    - Given calibration target information [white point, maximum - brightness, and response curve ("gamma")], display a series of test - patches on the display, and using the colorimetric values read, - create a calibration lookup tables that make the display meet the - desired target. The type of instrument is determined by the - communication port selected. Emission and display measurement - instruments are supported.
    -

    Usage

    - dispcal - [-options] inoutfile
    -  -v [n] + + + + dispcal + + + + +

    spectro/dispcal

    +

    Summary

    + Given calibration target information [white point, maximum + brightness, and response curve ("gamma")], display a series of test + patches on the display, and using the colorimetric values read, + create a calibration lookup tables that make the display meet the + desired target. The type of instrument is determined by the + communication port selected. Emission and display measurement + instruments are supported.
    +

    Usage

    + dispcal + [-options] inoutfile
    +  -v [n]               @@ -70,18 +70,18 @@ - - Verbose mode
    -
     -display displayname [X11 only] Choose X11 display - name
    -
     -d n[,m] -             - [X11 only]Choose the display from the following list (default - 1),
    + + Verbose mode
    +
     -display displayname [X11 only] Choose X11 display + name
    +
     -d n[,m] +             + [X11 only]Choose the display from the following list (default + 1),
                          and optionally @@ -137,9 +137,9 @@ for - - VideoLUT access.

    -  
    +  
    -d n                 Choose the @@ -195,8 +195,8 @@ list - - 1)

    + + 1)

     -dweb[:port]         @@ -243,9 +243,9 @@ list - - Display via a web server at port (default 8080)
    -  -dmadvr + + Display via a web server at port (default 8080)
    +  -dmadvr              @@ -276,8 +276,8 @@ list - - [MSWin] Display via MadVR Video Renderer
    + + [MSWin] Display via MadVR Video Renderer
     -dcc[:n]             @@ -288,13 +288,13 @@ list - - Display via n'th ChromeCast (default 1, ? for list)
    -   +   -c @@ -342,37 +342,37 @@ list - - listno     -        Set communication port from - the following list (default 1)
    -
     -r -              -      Report on the calibrated display then - exit
    -
     -R -              -      Report on the uncalibrated display then - exit
    -  -m -              -      Skip adjustment of the monitor - controls
    -   -o [profile.icm]     Create - fast matrix/shaper profile [different filename to outfile.icm]
    + + listno     +        Set communication port from + the following list (default 1)
    +
     -r +              +      Report on the calibrated display then + exit
    +
     -R +              +      Report on the uncalibrated display then + exit
    +  -m +              +      Skip adjustment of the monitor + controls
    +   -o [profile.icm]     Create + fast matrix/shaper profile [different filename to outfile.icm]
     -O description       @@ -420,8 +420,8 @@ list - - Fast ICC Profile Description string (Default "outfile")
    + + Fast ICC Profile Description string (Default "outfile")
     -u                   Update previous @@ -477,12 +477,12 @@ ICC - - profile VideoLUTs

    -  -q [lmh]
    +  -q [lmh]             @@ -530,8 +530,8 @@ ICC - - Quality - Low, Medium (def), High
    + + Quality - Low, Medium (def), High
     -p                   @@ -568,10 +568,10 @@ ICC - - Use telephoto mode (ie. for a projector) (if available)
    -  
    -y X + + Use telephoto mode (ie. for a projector) (if available)
    +  
    -y X                 @@ -619,12 +619,12 @@ ICC - - Display type - instrument specific list to choose from.
    -
     -t [temp]

    +
     -t [temp]            White Daylight @@ -680,10 +680,10 @@ in - - deg. K (deflt.)
    -
      +  -T [temp]            White Black @@ -739,11 +739,11 @@ temperaturee - - in deg. K
    -  -w x,y
    +  -w x,y               @@ -791,11 +791,11 @@ temperaturee - - Set the target white point as chromaticity coordinates
    -  -b bright
    +  -b bright            @@ -843,11 +843,11 @@ temperaturee - - Set the target white brightness in cd/m^2
    -  -g gamma
    +  -g gamma             @@ -895,9 +895,9 @@ temperaturee - - Set the target response curve gamma (Def. 2.4)
    + + Set the target response curve gamma (Def. 2.4)

                          @@ -945,9 +945,9 @@ temperaturee - - Use "-gl" for L*a*b* curve
    + + Use "-gl" for L*a*b* curve

                   @@ -995,8 +995,8 @@ temperaturee - -        Use "-gs" for sRGB curve
    + +        Use "-gs" for sRGB curve
                          Use "-g709" @@ -1052,8 +1052,8 @@ use - - -a as well!)
    + + -a as well!)
                          @@ -1101,9 +1101,9 @@ use - - Use "-g240" for SMPTE 240M curve
    (should use -a as well!)
    + + Use "-g240" for SMPTE 240M curve
    (should use -a as well!)
                          @@ -1151,7 +1151,7 @@ use - + Use "-G2.4 -f0" for BT.1886                                           @@ -1192,13 +1192,13 @@ use - -
    -  -G gamma -             - Set the target response curve actual technical gamma
    + +
    +  -G gamma +             + Set the target response curve actual technical gamma
     -f [degree]          Amount of @@ -1254,8 +1254,8 @@ output - - offset (default all output offset)
    + + offset (default all output offset)
     -a ambient           @@ -1303,17 +1303,17 @@ output - - Use viewing condition adjustment for ambient in Lux
    -
     -k factor -            - Amount to try and correct black point hue. Default 1.0, LCD - default 0.0
    -
     -A rate -              - Rate of blending from neutral to black point. Default 4.0
    + + Use viewing condition adjustment for ambient in Lux
    +
     -k factor +            + Amount to try and correct black point hue. Default 1.0, LCD + default 0.0
    +
     -A rate +              + Rate of blending from neutral to black point. Default 4.0
     -b                   @@ -1322,10 +1322,10 @@ output - - Use forced black point hack
    -
      +
     -B bkbright          @@ -1373,12 +1373,12 @@ output - - Set the target black brightness in cd/m^2
    -  -e [n]
    +  -e [n]               @@ -1426,12 +1426,12 @@ output - - Run n verify passes on final curves
    -
     -z + + Run n verify passes on final curves
    +
     -z                   @@ -1479,13 +1479,13 @@ output - - Run only verify pass on installed calibration curves
    -  -P - ho,vo,ss[,vs]     Position test window - and scale it
    + + Run only verify pass on installed calibration curves

    +  -P + ho,vo,ss[,vs]     Position test window + and scale it
                          ho,vi: 0.0 @@ -1541,8 +1541,8 @@ center, - - = right/bottom etc.
    + + = right/bottom etc.
                          ss: 0.5 @@ -1598,9 +1598,9 @@ normal, - - = double etc.
    -
                          @@ -1635,10 +1635,10 @@ normal, - - ss,vs: = optional horizontal, vertical scale.
    -  -F + + ss,vs: = optional horizontal, vertical scale.
    +  -F                   @@ -1686,11 +1686,11 @@ normal, - - Fill whole screen with black background
    -  -E + + Fill whole screen with black background
    +  -E                   @@ -1717,13 +1717,13 @@ normal, - - Video - encode output as (16-235)/255 "TV" levels
    -  -nVideo + encode output as (16-235)/255 "TV" levels
    +  -n                   [X11 @@ -1779,14 +1779,14 @@ on - - test window
    -
     -J -              -      Run instrument calibration first
    -
     -J +              +      Run instrument calibration first
    +
     -N                   @@ -1834,18 +1834,18 @@ on - - Disable initial calibration of instrument if possible
    -  -H -              -      Use high resolution spectrum mode (if - available)
    -

    -  

    +  
    -H +              +      Use high resolution spectrum mode (if + available)
    +

    +  
    -X file.ccmx         @@ -1893,9 +1893,9 @@ on - - Apply Colorimeter Correction Matrix
    -  -X + + Apply Colorimeter Correction Matrix

    +  
    -X file.ccss          Use Colorimeter @@ -1946,14 +1946,14 @@ Calibration - - Spectral Samples for calibration
    -
     -Q observ        -     Choose CIE Observer for spectrometer or CCSS - colorimeter data:
    + + Spectral Samples for calibration
    +
     -Q observ        +     Choose CIE Observer for spectrometer or CCSS + colorimeter data:
                @@ -2001,11 +2001,11 @@ Calibration - -           1931_2
    (def.), 1964_10, S&B 1955_2, shaw, - J&V 1978_2, 1964_10c
    + +           1931_2
    (def.), 1964_10, S&B 1955_2, shaw, + J&V 1978_2, 1964_10c
     -I b|w               @@ -2053,8 +2053,8 @@ Calibration - - Drift compensation, Black: -Ib, White: -Iw, Both: -Ibw

    + + Drift compensation, Black: -Ib, White: -Iw, Both: -Ibw

     -Y @@ -2071,7 +2071,7 @@ Calibration - + R:rate            @@ -2088,36 +2088,36 @@ Calibration - - Override measured refresh rate with rate Hz
    -
     
    -Y A -             -     Use non-adaptive integration time mode (if - available).
    -  -Y - p -             -     Don't wait for the instrument to be placed on - the display
    -  -C "command" -         Invoke shell - "command" each time a color is set
    -  -M "command" -         Invoke shell - "command" each time a color is measured
    -   +
     -Y A +             +     Use non-adaptive integration time mode (if + available).
    +  -Y + p +             +     Don't wait for the instrument to be placed on + the display
    +  -C "command" +         Invoke shell + "command" each time a color is set
    +  -M "command" +         Invoke shell + "command" each time a color is measured
    +  -W n|h|x             Override serial @@ -2173,12 +2173,12 @@ none, - - h = HW, x = Xon/Xoff
    -  -D [level]
    +  -D [level]           @@ -2226,12 +2226,12 @@ none, - - Print debug diagnostics to stderr
    -  inoutfile
    +  inoutfile            @@ -2279,79 +2279,79 @@ none, - - Base name for created - or updated .cal  and .icm output files
    -
    -

    Comments
    -

    - This is the tool is used for adjusting and calibrating a display to - reach specified target behaviour, and optionally profiling it.  - For best results on a CRT, you should run this against a neutral - grey desktop background, and avoid having any bright images or - windows on the screen at the time you run dispcal. You could also - use the -B option to black - the whole screen out, although this will make it impossible to - control dispcal unless you have more than one display.
    -
    - The -v flag reports progress information, - as well as other statistics about the progress of calibration. A - numerical argument greater than 1 gives greater verbosity. 2 will - give per step adjustment and repeat information, while 3 will give - even greater technical detail.
    -
    - When running on a UNIX based system that used - the X11 Windowing System, dispcal will by default use the - $DISPLAY environment variable to determine which local or remote - display and screen to read from. This can be overridden by supplying - an X11 display name to the -display - option. Note that if Xinerama is active, you can't select the screen - using $DISPLAY or -display, you have to select it using the -d parameter.
    -
    - By default the main display will be the location of - the test window. If the system has more than one display or screen, - an alternate display/screen can be selected with the -d parameter. If you invoke dispcal so as to display the - usage information (i.e. "dispcal -?" or "dispcal --"), then the - discovered displays/screens will be listed. Multiple displays may - not be listed, if they appear as a single display to the operating - system (ie. the multi-display support is hidden in the video card - driver). On UNIX based system that used the X11 Windowing System, - the -d parameter will - override the screen specified by the $DISPLAY or parameter.
    -
    - Note that if VideoLUTs for a - display are not accessible (i.e. no hardware calibration - capability), dispcal will - will issue a warning, but continue creating a calibration based on - the display "as-is" rather than its native response. See the -o flag for an explanation of the - implications of having no access to the VideoLUTs.
    -
    - On X11 the inability to access VideoLUTs could be because you are - trying to access a remote display, and the remote display doesn't - support the XF86VidMode extension, or perhaps you are running - multiple monitors using NVidia TwinView, or MergedFB, and trying to - access anything other than the primary monitor. TwinView and - MergedFB don't properly support the XF86VidMode extension for - multiple displays. You can use dispwin -r - to test whether the VideoLUTs are accessible for a particular - display. See also below, on how to select a different display for - VideoLUT access. Also note that dispcal will fail if the Visual - depth doesn't match the VideoLUT depth. Typically the VideoLUTs have - 256 entries per color component, so the Visual generally needs to be - 24 bits, 8 bits per color component.
    -
    - Because of the difficulty cause by TwinView and - MergedFB in X11 based systems, you can optionally specify a separate - display number after the display that is going to be used to present - test patches, for accessing the VideoLUT hardware. This must be + + Base name for created + or updated
    .cal  and .icm output files
    +
    +

    Comments
    +

    + This is the tool is used for adjusting and calibrating a display to + reach specified target behaviour, and optionally profiling it.  + For best results on a CRT, you should run this against a neutral + grey desktop background, and avoid having any bright images or + windows on the screen at the time you run dispcal. You could also + use the -B option to black + the whole screen out, although this will make it impossible to + control dispcal unless you have more than one display.
    +
    + The -v flag reports progress information, + as well as other statistics about the progress of calibration. A + numerical argument greater than 1 gives greater verbosity. 2 will + give per step adjustment and repeat information, while 3 will give + even greater technical detail.
    +
    + When running on a UNIX based system that used + the X11 Windowing System, dispcal will by default use the + $DISPLAY environment variable to determine which local or remote + display and screen to read from. This can be overridden by supplying + an X11 display name to the -display + option. Note that if Xinerama is active, you can't select the screen + using $DISPLAY or -display, you have to select it using the -d parameter.
    +
    + By default the main display will be the location of + the test window. If the system has more than one display or screen, + an alternate display/screen can be selected with the -d parameter. If you invoke dispcal so as to display the + usage information (i.e. "dispcal -?" or "dispcal --"), then the + discovered displays/screens will be listed. Multiple displays may + not be listed, if they appear as a single display to the operating + system (ie. the multi-display support is hidden in the video card + driver). On UNIX based system that used the X11 Windowing System, + the -d parameter will + override the screen specified by the $DISPLAY or parameter.
    +
    + Note that if VideoLUTs for a + display are not accessible (i.e. no hardware calibration + capability), dispcal will + will issue a warning, but continue creating a calibration based on + the display "as-is" rather than its native response. See the -o flag for an explanation of the + implications of having no access to the VideoLUTs.
    +
    + On X11 the inability to access VideoLUTs could be because you are + trying to access a remote display, and the remote display doesn't + support the XF86VidMode extension, or perhaps you are running + multiple monitors using NVidia TwinView, or MergedFB, and trying to + access anything other than the primary monitor. TwinView and + MergedFB don't properly support the XF86VidMode extension for + multiple displays. You can use dispwin -r + to test whether the VideoLUTs are accessible for a particular + display. See also below, on how to select a different display for + VideoLUT access. Also note that dispcal will fail if the Visual + depth doesn't match the VideoLUT depth. Typically the VideoLUTs have + 256 entries per color component, so the Visual generally needs to be + 24 bits, 8 bits per color component.
    +
    + Because of the difficulty cause by TwinView and + MergedFB in X11 based systems, you can optionally specify a separate + display number after the display that is going to be used to present + test patches, for accessing the VideoLUT hardware. This must be specified as a single string, e.g. -d @@ -2399,273 +2399,273 @@ none, - - 1,2 . Some experimentation may be needed using dispwin on such systems, to discover what - screen has access to the VideoLUT hardware, and which screens the - test patches appear on. You may be able to calibrate one screen, and - then share the calibration with another screen. Profiling can be - done independently to calibration on each screen.
    -
    - -dweb or - -dweb:port starts a - standalone web server on your machine, which then allows a local or - remote web browser to display the the color test patches. By default - port 8080 is used, but this - can be overridden by appending a : - and the port number i.e. -dweb:8001. - The URL will be http:// - then name of the machine or its I.P. address followed by a colon and - the port number - e.g something like http://192.168.0.1:8080. If you use the verbose - option (-v) then a likely - URL will be printed once the server is started, or you could run ipconfig (MSWin) or /sbin/ifconfig (Linux or OS X) - and identify an internet address for your machine that way. JavaScript - needs to be enabled in your web browser for this to work. You may - have to modify any firewall to permit port 8080 to be accessed on - your machine.
    -
    - Note that if you use this method of displaying test patches, that - there is no access to the display VideoLUTs and that the colors will - be displayed with 8 bit per component precision, and any - screen-saver or power-saver will not be disabled. You will also be - at the mercy of any color management applied by the web browser, and - may have to carefully review and configure such color management. - See the -o flag for an explanation of the - implications of having no access to the VideoLUTs.
    -
    - -dmadvr - [MSWin only] causes test patches to be displayed using the MadVR - video renderer. Note that will have to start MadTPG before - running dispcal, and that while you can adjust the "Test Pattern - Configuration" controls, you should not normally alter the - "Existing Calibration" controls, as dispcal will set these - appropriately.
    -
    - -dcc or -dcc:no - causes test patches to be displayed using and available ChromeCast to - your TV. Use -dcc:? to display a list of ChromeCasts on your - local network. Note that the ChromeCast as a test patch source is - probably the least accurate of your choices, since it - up-samples the test patch and transforms from RGB to YCC and back, - but should be accurate within ± 1 bit. You may have to modify any - firewall to permit port 8081 to be accessed on your machine if it + + 1,2 . Some experimentation may be needed using dispwin on such systems, to discover what + screen has access to the VideoLUT hardware, and which screens the + test patches appear on. You may be able to calibrate one screen, and + then share the calibration with another screen. Profiling can be + done independently to calibration on each screen.
    +
    + -dweb or + -dweb:port starts a + standalone web server on your machine, which then allows a local or + remote web browser to display the the color test patches. By default + port 8080 is used, but this + can be overridden by appending a : + and the port number i.e. -dweb:8001. + The URL will be http:// + then name of the machine or its I.P. address followed by a colon and + the port number - e.g something like http://192.168.0.1:8080. If you use the verbose + option (-v) then a likely + URL will be printed once the server is started, or you could run ipconfig (MSWin) or /sbin/ifconfig (Linux or OS X) + and identify an internet address for your machine that way. JavaScript + needs to be enabled in your web browser for this to work. You may + have to modify any firewall to permit port 8080 to be accessed on + your machine.
    +
    + Note that if you use this method of displaying test patches, that + there is no access to the display VideoLUTs and that the colors will + be displayed with 8 bit per component precision, and any + screen-saver or power-saver will not be disabled. You will also be + at the mercy of any color management applied by the web browser, and + may have to carefully review and configure such color management. + See the -o flag for an explanation of the + implications of having no access to the VideoLUTs.
    +
    + -dmadvr + [MSWin only] causes test patches to be displayed using the MadVR + video renderer. Note that will have to start MadTPG before + running dispcal, and that while you can adjust the "Test Pattern + Configuration" controls, you should not normally alter the + "Existing Calibration" controls, as dispcal will set these + appropriately.
    +
    + -dcc or -dcc:no + causes test patches to be displayed using and available ChromeCast to + your TV. Use -dcc:? to display a list of ChromeCasts on your + local network. Note that the ChromeCast as a test patch source is + probably the least accurate of your choices, since it + up-samples the test patch and transforms from RGB to YCC and back, + but should be accurate within ± 1 bit. You may have to modify any + firewall to permit port 8081 to be accessed on your machine if it falls back to the Default receiver (see installation - - instructions for your platform).
    -
    - -c The - instrument is assumed to communicate through a USB or serial - communication port, and the port can be selected with the -c - option, if the instrument is not connected to the first port. If you - invoke dispcal so as to - display the usage information (i.e. "dispcal -?" or "dispcal --"), - then the discovered USB and serial ports will be listed. On - UNIX/Linux, a list of all possible serial ports are shown, but not - all of them may actually be present on your system.
    -
    - The -r and - -R flags - perform a quick measurement of current display behaviour, reports - and then exits. If the -r - flag is used the measurement are taken using the currently loaded - calibration (Video LUT) curves, and in the case of MadVR renderer - test patch display the Color Management 3dLut. If -R is use, then the uncalibrated - ("raw" or "native") behaviour is measured (ie. no VideoLut or CM). - Reported are:
    -
    -     Black Brightness in cd/m^2
    -     White Brightness in cd/m^2
    -     The approximate Gamma
    -     The white point x,y chromaticity co-ordinates
    -     The correlated color temperature in Kelvin, and - the CIEDE200 to the Black Body locus.
    -     The correlated Daylight temperature in Kelvin, - and the CIEDE200 to the Daylight locus.
    -     The visual color temperature in Kelvin, and the - CIEDE200 to the Black Body locus.
    -     The visual Daylight temperature in Kelvin, and - the CIEDE200 to the Daylight locus.
    -     The visual color temperature in Kelvin
    - (for -R "raw":)
    -     The apparent VideoLUT entry number of significant - bits.
    -
    - Note that the correlated color temperature is the temperature of a - black body radiator that has the closest color to the white point - measured using the traditional CIE 1960 UCS space color difference - formula. The correlated daylight temperature is a similar thing, - except the CIE daylight locus is used. The visual color temperature - values are calculated similarly to the correlated color - temperatures, but using the modern CIEDE2000 color difference - formula to calculate a better visual approximation to the closest - temperature to the displays white point. There will be no difference - between the UCS and CIEDE2000 temperatures if the display white - point actually lies on the particular locus.
    -
    - The -m - option skips the usual process of adjusting the display monitor - contrast, brightness and white point controls, and skips straight to - calibration.
    -
    - -o [profile.icm] Normally dispcal creates just a - calibration file, which can then be used for subsequent - characterization using dispread and - profiling using colprof. If the -o flag is used, dispcal will also create a - shaper/matrix profile. By default it will create a profile named inoutfile.icm, but a differently - named file can be created or updated by specifying the name after - the -o flag. If the -u flag is used with -o, then the ICC profile vcgt calibration curves will be - updated.
    -
    - Note that if VideoLUT access is not possible for the display, that - hardware calibration is not possible. dispcal will create - calibration curves anyway with a warning, and if a profile is - created, it will not contain a 'vcgt' tag, but instead will have the - calibration curves incorporated into the profile itself. If - calibration parameters are chosen that change the displays white - point or brightness, then this will result in a slightly unusual - profile that has a white point that does not correspond with - R=G=B=1.0. Some systems may not cope properly with this type of - profile. See the tutorial for a - further explanation.
    -
    - The -O parameter allows setting of the - shaper/matrix profile description tag. The parameter should be a - string that describes the device and profile. With most command line - shells, it will be necessary to enclose the parameter with double - quotes, so that spaces and other special characters are included in - the parameter, and not mistaken for the start of another flag, or as - a final command line parameter. Many programs that deal with ICC - profiles use the description tag to identify a profile, rather than - the profile filename, so using a descriptive string is important in - being able to find a profile. By default, the profile file name will - be used as the description.
    -
    - -u Normally - dispcal creates a new - calibration file and optional profile, based on the requested - targets and the response of the display. This can take a fair amount - of time, particularly if a high quality level has been selected, so - to speed up the process of keeping a display in calibration the -u flag can be used. This uses - the same calibration targets as the previous calibration but does a - smaller number of refinement passes, enough to improve the accuracy - of the calibration to account for drift in the device. If the -o flag is used as well, then - the ICC profile will have - its vcgt tag updated with the new calibration. This keeps the - profile up to date with the display. Normally dispcal -u will use the same - quality level that was specified in the previous calibration, but - this can be overridden using the -q - flag. Any options that attempt to change the calibration target (ie. - white point, brightness, gamma etc.) will be ignored. Adjustment of - the display monitor controls is skipped. A profile cannot be updated - if the display does not support hardware calibration (no VideoLUT - access).
    -
    -   Quality - Low, Medium (def), High. The -q flag determines how much time - and effort to go to in calibrating the display. The higher the - quality, the more test readings will be done, the more refinement - passes will be done, the tighter will be the accuracy tolerance, and - the more detailed will be the calibration of the display. The result - will ultimately be limited by the accuracy of the instrument, the - repeatability of the display and instrument, and the resolution of - the Video Lookup table entries and Digital or Analogue output - (RAMDAC).
    -
    - The -p flag - allows measuring in telephoto mode, using instruments that support - this mode, e.g. the ColorMunki. Telephoto mode is one for taking - emissive measurements from a distance (ie. telespectometer, - tele-colorimeter) mode, and typically would be used for measuring - projector type displays. If a device does not support a specific - telephoto mode, then the normal emissive mode may be suitable for - measuring projectors.
    -
    -   The -y - flag allows setting the Display Type. The selection typically - determines two aspects of of the instrument operation: 1) It may set the measuring mode - to suite refresh or non-refresh displays. - Typically only LCD (Liquid Crystal) displays have a non-refresh - nature. 2) It may select an - instrument calibration matrix suitable for a particular display - type. The selections available depends on the type and model of - instrument, and a list of the options for the discovered instruments - will be shown in the usage - information. For more details on what particular instruments support - and how this works, see Operation of - particular instruments. 3) Any installed CCSS files - (if applicable), or CCMX files. These files are typically created - using ccxxmake, and installed using oeminst. The default and Base Calibration - types will be indicated in the usage.
    -
    - -t Set the target white point - locus to the equivalent of a Daylight spectrum of the given - temperature in degrees Kelvin. By default the white point target - will be the native white of the display, and it's color temperature - and delta E to the daylight spectrum locus will be shown during - monitor adjustment, and adjustments will be recommended to put the - display white point directly on the Daylight locus. If a Daylight - color temperature is given as an argument to -t, then this will become the - target of the adjustment, and the recommended adjustments will be - those needed to make the monitor white point meet the target. - Typical  values might be 5000 for matching printed output, or - 6500, which gives a brighter, bluer look. A white point temperature - different to that native to the display may limit the maximum - brightness possible.
    -
    - -T  Same functionality as - the -t option, except the - white point locus will be the Black Body, or Planckian locus, rather - than the Daylight locus. While these two white point loci are quite - close, they are subtly different. If a temperature is given as an - argument, this will become the Black Body target temperature during - adjustment.
    -
    - -w  An - alternative to specifying a  white point target in Daylight or - Black Body degrees Kevin, is to specify it in chromaticity - co-ordinates. This allows the white point to be a color other than - one on the Daylight or Black Body. Note that the x,y numbers must be - specified as a single string (no space between the numbers and the - comma).
    -
    - -b  Set - the target brightness of white in cd/m^2. If this number cannot be - reached, the brightest output possible is chosen, consistent with - matching the white point target. Note that many of the instruments - are not particularly accurate when assessing the absolute display - brightness in cd/m^2. NOTE - that some LCD screens behave a little strangely near their absolute - white point, and may therefore exhibit odd behavior at values just - below white. It may be advisable in such cases to set a brightness - slightly less than the maximum such a display is capable of.
    -
    + + instructions for your platform).
    +
    + -c The + instrument is assumed to communicate through a USB or serial + communication port, and the port can be selected with the -c + option, if the instrument is not connected to the first port. If you + invoke dispcal so as to + display the usage information (i.e. "dispcal -?" or "dispcal --"), + then the discovered USB and serial ports will be listed. On + UNIX/Linux, a list of all possible serial ports are shown, but not + all of them may actually be present on your system.
    +
    + The -r and + -R flags + perform a quick measurement of current display behaviour, reports + and then exits. If the -r + flag is used the measurement are taken using the currently loaded + calibration (Video LUT) curves, and in the case of MadVR renderer + test patch display the Color Management 3dLut. If -R is use, then the uncalibrated + ("raw" or "native") behaviour is measured (ie. no VideoLut or CM). + Reported are:
    +
    +     Black Brightness in cd/m^2
    +     White Brightness in cd/m^2
    +     The approximate Gamma
    +     The white point x,y chromaticity co-ordinates
    +     The correlated color temperature in Kelvin, and + the CIEDE200 to the Black Body locus.
    +     The correlated Daylight temperature in Kelvin, + and the CIEDE200 to the Daylight locus.
    +     The visual color temperature in Kelvin, and the + CIEDE200 to the Black Body locus.
    +     The visual Daylight temperature in Kelvin, and + the CIEDE200 to the Daylight locus.
    +     The visual color temperature in Kelvin
    + (for -R "raw":)
    +     The apparent VideoLUT entry number of significant + bits.
    +
    + Note that the correlated color temperature is the temperature of a + black body radiator that has the closest color to the white point + measured using the traditional CIE 1960 UCS space color difference + formula. The correlated daylight temperature is a similar thing, + except the CIE daylight locus is used. The visual color temperature + values are calculated similarly to the correlated color + temperatures, but using the modern CIEDE2000 color difference + formula to calculate a better visual approximation to the closest + temperature to the displays white point. There will be no difference + between the UCS and CIEDE2000 temperatures if the display white + point actually lies on the particular locus.
    +
    + The -m + option skips the usual process of adjusting the display monitor + contrast, brightness and white point controls, and skips straight to + calibration.
    +
    + -o [profile.icm] Normally dispcal creates just a + calibration file, which can then be used for subsequent + characterization using dispread and + profiling using colprof. If the -o flag is used, dispcal will also create a + shaper/matrix profile. By default it will create a profile named inoutfile.icm, but a differently + named file can be created or updated by specifying the name after + the -o flag. If the -u flag is used with -o, then the ICC profile vcgt calibration curves will be + updated.
    +
    + Note that if VideoLUT access is not possible for the display, that + hardware calibration is not possible. dispcal will create + calibration curves anyway with a warning, and if a profile is + created, it will not contain a 'vcgt' tag, but instead will have the + calibration curves incorporated into the profile itself. If + calibration parameters are chosen that change the displays white + point or brightness, then this will result in a slightly unusual + profile that has a white point that does not correspond with + R=G=B=1.0. Some systems may not cope properly with this type of + profile. See the tutorial for a + further explanation.
    +
    + The -O parameter allows setting of the + shaper/matrix profile description tag. The parameter should be a + string that describes the device and profile. With most command line + shells, it will be necessary to enclose the parameter with double + quotes, so that spaces and other special characters are included in + the parameter, and not mistaken for the start of another flag, or as + a final command line parameter. Many programs that deal with ICC + profiles use the description tag to identify a profile, rather than + the profile filename, so using a descriptive string is important in + being able to find a profile. By default, the profile file name will + be used as the description.
    +
    + -u Normally + dispcal creates a new + calibration file and optional profile, based on the requested + targets and the response of the display. This can take a fair amount + of time, particularly if a high quality level has been selected, so + to speed up the process of keeping a display in calibration the -u flag can be used. This uses + the same calibration targets as the previous calibration but does a + smaller number of refinement passes, enough to improve the accuracy + of the calibration to account for drift in the device. If the -o flag is used as well, then + the ICC profile will have + its vcgt tag updated with the new calibration. This keeps the + profile up to date with the display. Normally dispcal -u will use the same + quality level that was specified in the previous calibration, but + this can be overridden using the -q + flag. Any options that attempt to change the calibration target (ie. + white point, brightness, gamma etc.) will be ignored. Adjustment of + the display monitor controls is skipped. A profile cannot be updated + if the display does not support hardware calibration (no VideoLUT + access).
    +
    +   Quality - Low, Medium (def), High. The -q flag determines how much time + and effort to go to in calibrating the display. The higher the + quality, the more test readings will be done, the more refinement + passes will be done, the tighter will be the accuracy tolerance, and + the more detailed will be the calibration of the display. The result + will ultimately be limited by the accuracy of the instrument, the + repeatability of the display and instrument, and the resolution of + the Video Lookup table entries and Digital or Analogue output + (RAMDAC).
    +
    + The -p flag + allows measuring in telephoto mode, using instruments that support + this mode, e.g. the ColorMunki. Telephoto mode is one for taking + emissive measurements from a distance (ie. telespectometer, + tele-colorimeter) mode, and typically would be used for measuring + projector type displays. If a device does not support a specific + telephoto mode, then the normal emissive mode may be suitable for + measuring projectors.
    +
    +   The -y + flag allows setting the Display Type. The selection typically + determines two aspects of of the instrument operation: 1) It may set the measuring mode + to suite refresh or non-refresh displays. + Typically only LCD (Liquid Crystal) displays have a non-refresh + nature. 2) It may select an + instrument calibration matrix suitable for a particular display + type. The selections available depends on the type and model of + instrument, and a list of the options for the discovered instruments + will be shown in the usage + information. For more details on what particular instruments support + and how this works, see Operation of + particular instruments. 3) Any installed CCSS files + (if applicable), or CCMX files. These files are typically created + using ccxxmake, and installed using oeminst. The default and Base Calibration + types will be indicated in the usage.
    +
    + -t Set the target white point + locus to the equivalent of a Daylight spectrum of the given + temperature in degrees Kelvin. By default the white point target + will be the native white of the display, and it's color temperature + and delta E to the daylight spectrum locus will be shown during + monitor adjustment, and adjustments will be recommended to put the + display white point directly on the Daylight locus. If a Daylight + color temperature is given as an argument to -t, then this will become the + target of the adjustment, and the recommended adjustments will be + those needed to make the monitor white point meet the target. + Typical  values might be 5000 for matching printed output, or + 6500, which gives a brighter, bluer look. A white point temperature + different to that native to the display may limit the maximum + brightness possible.
    +
    + -T  Same functionality as + the -t option, except the + white point locus will be the Black Body, or Planckian locus, rather + than the Daylight locus. While these two white point loci are quite + close, they are subtly different. If a temperature is given as an + argument, this will become the Black Body target temperature during + adjustment.
    +
    + -w  An + alternative to specifying a  white point target in Daylight or + Black Body degrees Kevin, is to specify it in chromaticity + co-ordinates. This allows the white point to be a color other than + one on the Daylight or Black Body. Note that the x,y numbers must be + specified as a single string (no space between the numbers and the + comma).
    +
    + -b  Set + the target brightness of white in cd/m^2. If this number cannot be + reached, the brightest output possible is chosen, consistent with + matching the white point target. Note that many of the instruments + are not particularly accurate when assessing the absolute display + brightness in cd/m^2. NOTE + that some LCD screens behave a little strangely near their absolute + white point, and may therefore exhibit odd behavior at values just + below white. It may be advisable in such cases to set a brightness + slightly less than the maximum such a display is capable of.
    +
    -g gamma  Set @@ -2714,14 +2714,14 @@ Set - - the target response curve gamma. This is normally an exponential - curve (output = input ^gamma), and defaults to 2.4 on MSWindows and - Macintosh OS X 10.6 or latter and Linux/Unix (which is typical of a - CRT type displays real response), and 1.8 on a Macintosh (prior to - OS X 10.6). Four pre-defined curves can be used as well: the sRGB - colorspace response curve, which is an exponent curve with a - straight segment at the dark end and an overall response of + + the target response curve gamma. This is normally an exponential + curve (output = input ^gamma), and defaults to 2.4 on MSWindows and + Macintosh OS X 10.6 or latter and Linux/Unix (which is typical of a + CRT type displays real response), and 1.8 on a Macintosh (prior to + OS X 10.6). Four pre-defined curves can be used as well: the sRGB + colorspace response curve, which is an exponent curve with a + straight segment at the dark end and an overall response of approximately gamma 2.2 (-gs), the @@ -2770,65 +2770,65 @@ the - - L* curve, which is the response of the CIE L*a*b* perceptual - colorspace (-gl). the REC - 709 video standard response curve (-g709) - and the SMPTE 240M video standard response curve (-g240)
    -
    - Note that a real display - can't reproduce any of these ideal curves, since it will have a - non-zero black point, whereas all the ideal curves assume zero light - at zero input. In the case of a gamma curve target, dispcal uses an - actual technical power curve shape that aims for the same relative - output at 50% input as the ideal gamma power curve. To allow for the - non-zero black level of a real display, by default dispcal will offset the target - curve values so that zero input gives the actual black level of the - display (output offset). This ensures that the target curve better - corresponds to the typical natural behavior of displays, but it may - not be the most visually even progression from display minimum, but - this behavior can be changed using the -f option (see below).
    -
    - Also note that many color - spaces are encoded with, and labelled as having a gamma of - approximately 2.2 (ie. sRGB, - REC 709, SMPTE 240M, Macintosh OS X 10.6), but are actually intended - to be displayed on a display with a typical CRT gamma of 2.4 viewed in a darkened - environment. This is because this 2.2 - gamma is a source gamma encoding in bright viewing conditions such - as a television studio, while typical display viewing conditions are - quite dark by comparison, and a contrast expansion of (approx.) - gamma 1.1 is desirable to make the images look as intended. So if - you are displaying images encoded to the sRGB standard, or - displaying video through the calibration, just setting the gamma - curve to sRGB or REC 709 (respectively) is probably not what you want! What you - probably want to do, is to set the gamma curve to about gamma 2.4, - so that the contrast range is expanded appropriately, or alternatively - use sRGB or REC 709 or a gamm of 2.2 but also use the -a - parameter to specify the actual ambient viewing conditions, so that - dispcal can make an - appropriate contrast enhancement. If your instrument is capable of - measuring ambient light levels, then you can do so during the - interactive display control adjustment. See - <http://www.color.org/sRGB.xalter> for details of how sRGB is - intended to be used.
    -
    - It is hard to know whether Apple Macintosh computers prior to OS X - 10.6 should also have such an adjustment, since it is not really - possible to know whether colors labelled as being in such a - colorspace are actually encoded in that gamma with the expectation - that they will be displayed on a display with that actual response, - or whether they are intended to be displayed on a display that - contrast expands by a power 1.1.  Both situations might be the - case, depending on how source material is created!
    -
    + + L* curve, which is the response of the CIE L*a*b* perceptual + colorspace (-gl). the REC + 709 video standard response curve (-g709) + and the SMPTE 240M video standard response curve (-g240)
    +
    + Note that a real display + can't reproduce any of these ideal curves, since it will have a + non-zero black point, whereas all the ideal curves assume zero light + at zero input. In the case of a gamma curve target, dispcal uses an + actual technical power curve shape that aims for the same relative + output at 50% input as the ideal gamma power curve. To allow for the + non-zero black level of a real display, by default dispcal will offset the target + curve values so that zero input gives the actual black level of the + display (output offset). This ensures that the target curve better + corresponds to the typical natural behavior of displays, but it may + not be the most visually even progression from display minimum, but + this behavior can be changed using the -f option (see below).
    +
    + Also note that many color + spaces are encoded with, and labelled as having a gamma of + approximately 2.2 (ie. sRGB, + REC 709, SMPTE 240M, Macintosh OS X 10.6), but are actually intended + to be displayed on a display with a typical CRT gamma of 2.4 viewed in a darkened + environment. This is because this 2.2 + gamma is a source gamma encoding in bright viewing conditions such + as a television studio, while typical display viewing conditions are + quite dark by comparison, and a contrast expansion of (approx.) + gamma 1.1 is desirable to make the images look as intended. So if + you are displaying images encoded to the sRGB standard, or + displaying video through the calibration, just setting the gamma + curve to sRGB or REC 709 (respectively) is probably not what you want! What you + probably want to do, is to set the gamma curve to about gamma 2.4, + so that the contrast range is expanded appropriately, or alternatively + use sRGB or REC 709 or a gamm of 2.2 but also use the -a + parameter to specify the actual ambient viewing conditions, so that + dispcal can make an + appropriate contrast enhancement. If your instrument is capable of + measuring ambient light levels, then you can do so during the + interactive display control adjustment. See + <http://www.color.org/sRGB.xalter> for details of how sRGB is + intended to be used.
    +
    + It is hard to know whether Apple Macintosh computers prior to OS X + 10.6 should also have such an adjustment, since it is not really + possible to know whether colors labelled as being in such a + colorspace are actually encoded in that gamma with the expectation + that they will be displayed on a display with that actual response, + or whether they are intended to be displayed on a display that + contrast expands by a power 1.1.  Both situations might be the + case, depending on how source material is created!
    +
    -G gamma  As @@ -2877,99 +2877,99 @@ As - - explained above, the gamma value provided to the -g option is used to set and - actual response curve that makes an allowance for the non-zero black - of the actual display, and will have the same relative output at 50% - input as the ideal gamma power curve, and so best matches typical - expectations. The -G option - is an alternative that allows the actual - power to be specified instead, meaning that when combined with the - displays non-zero black value, the response at 50% input will - probably not match that of the ideal power curve with that gamma - value.
    -
    - -f [degree]: - As explained in for the -g - and -G options, real - displays do not have a zero black response, while all the target - response curves do, so this has to be allowed for in some way. The - default way of handling this (equivalent to -f 1.0)  is to - allow for this at the output of the ideal response curve, by - offsetting and scaling the output values. This defined a curve that will match the responses - that many other systems provide and may be a better match to the - natural response of the display, but will give a less visually even - response from black. The - other alternative is to offset and scale the input values into the - ideal response curve so that zero input gives the actual non-zero - display response. This ensures the most visually even progression - from display minimum, but might be hard to achieve since it is - different to the naturally response of a display. A subtlety is to - provide a split between how much of the offset is accounted for as - input to the ideal response curve, and how much is accounted for at - the output, and this can be done by providing a parameter -f degree, where the degree is - 0.0 accounts for it all as input offset, and 1.0 accounts for all of - it as output offset. If -f - is used without a specified degree, a degree of 0.0 is assumed, the - opposite of the default. Note - that using all input offset (degree == 0.0) is equivalent to the use - of the BT.1886 transfer - function.
    -
    - -a ambient: - As explained for the -g - parameter, often colors are encoded in a situation with viewing - conditions that are quite different to the viewing conditions of a - typical display, with the expectation that this difference in - viewing conditions will be allowed for in the way the display is - calibrated. The -a option - is a way of doing this. By default dispcal - will not make any allowances for viewing conditions, but will - calibrate to the specified response curve, but if the -a option is used, or the - ambient level is measured during the interactive display controls - portion of the calibration, an appropriate viewing conditions - adjustment will be performed. For a gamma value or sRGB, the - original viewing conditions will be assumed to be that of the sRGB - standard viewing conditions, while for REC 709 and SMPTE 240M they - will be assumed to be television studio viewing conditions. By - specifying or measuring the ambient lighting for your display, a - viewing conditions adjustment based on the CIECAM02 color appearance - model will be made for the brightness of  your display and the - contrast it makes with your ambient light levels.
    -
    - -k factor: - Normally this will be set automatically, based on the measured black - level of the display. A -k - factor of 1.0 will make all colors down the neutral axis (R=G=B) - have the same hue as the chosen white point. Near the black point, - red, green or blue can only be added, not subtracted from zero, so - the process of making the near black colors have the desired hue, - will lighten them to some - extent. For a device with a good contrast ratio or a black point - that has nearly the same hue as the white, this should not affect - the contrast ratio too severely. If the device contrast ratio is not - so good, and the native black hue is noticeably different to that of - the chosen white point (which is often the case for LCD type displays, or CRT type displays with one - channel which has a poor level of black), this could have a - noticeably detrimental effect on an already limited contrast ratio, - and result in a black that is not as good as it can be, and a lower - -k factor should be used. -k values can range between 0.0 - (no correction of black) to 1.0 (full correction of black). If less - than full correction is chosen, then the resulting calibration - curves will have the target white point down most of the curve, but - will then blend over to the native or compromise black point that is - blacker, but not of the right hue. The rate of this blend can be - controlled with the -A - parameter (see below). For applications where maximum contrast ratio - is important (such as Video), use -k0.
    -
    + + explained above, the gamma value provided to the -g option is used to set and + actual response curve that makes an allowance for the non-zero black + of the actual display, and will have the same relative output at 50% + input as the ideal gamma power curve, and so best matches typical + expectations. The -G option + is an alternative that allows the actual + power to be specified instead, meaning that when combined with the + displays non-zero black value, the response at 50% input will + probably not match that of the ideal power curve with that gamma + value.
    +
    + -f [degree]: + As explained in for the -g + and -G options, real + displays do not have a zero black response, while all the target + response curves do, so this has to be allowed for in some way. The + default way of handling this (equivalent to -f 1.0)  is to + allow for this at the output of the ideal response curve, by + offsetting and scaling the output values. This defined a curve that will match the responses + that many other systems provide and may be a better match to the + natural response of the display, but will give a less visually even + response from black. The + other alternative is to offset and scale the input values into the + ideal response curve so that zero input gives the actual non-zero + display response. This ensures the most visually even progression + from display minimum, but might be hard to achieve since it is + different to the naturally response of a display. A subtlety is to + provide a split between how much of the offset is accounted for as + input to the ideal response curve, and how much is accounted for at + the output, and this can be done by providing a parameter -f degree, where the degree is + 0.0 accounts for it all as input offset, and 1.0 accounts for all of + it as output offset. If -f + is used without a specified degree, a degree of 0.0 is assumed, the + opposite of the default. Note + that using all input offset (degree == 0.0) is equivalent to the use + of the BT.1886 transfer + function.
    +
    + -a ambient: + As explained for the -g + parameter, often colors are encoded in a situation with viewing + conditions that are quite different to the viewing conditions of a + typical display, with the expectation that this difference in + viewing conditions will be allowed for in the way the display is + calibrated. The -a option + is a way of doing this. By default dispcal + will not make any allowances for viewing conditions, but will + calibrate to the specified response curve, but if the -a option is used, or the + ambient level is measured during the interactive display controls + portion of the calibration, an appropriate viewing conditions + adjustment will be performed. For a gamma value or sRGB, the + original viewing conditions will be assumed to be that of the sRGB + standard viewing conditions, while for REC 709 and SMPTE 240M they + will be assumed to be television studio viewing conditions. By + specifying or measuring the ambient lighting for your display, a + viewing conditions adjustment based on the CIECAM02 color appearance + model will be made for the brightness of  your display and the + contrast it makes with your ambient light levels.
    +
    + -k factor: + Normally this will be set automatically, based on the measured black + level of the display. A -k + factor of 1.0 will make all colors down the neutral axis (R=G=B) + have the same hue as the chosen white point. Near the black point, + red, green or blue can only be added, not subtracted from zero, so + the process of making the near black colors have the desired hue, + will lighten them to some + extent. For a device with a good contrast ratio or a black point + that has nearly the same hue as the white, this should not affect + the contrast ratio too severely. If the device contrast ratio is not + so good, and the native black hue is noticeably different to that of + the chosen white point (which is often the case for LCD type displays, or CRT type displays with one + channel which has a poor level of black), this could have a + noticeably detrimental effect on an already limited contrast ratio, + and result in a black that is not as good as it can be, and a lower + -k factor should be used. -k values can range between 0.0 + (no correction of black) to 1.0 (full correction of black). If less + than full correction is chosen, then the resulting calibration + curves will have the target white point down most of the curve, but + will then blend over to the native or compromise black point that is + blacker, but not of the right hue. The rate of this blend can be + controlled with the -A + parameter (see below). For applications where maximum contrast ratio + is important (such as Video), use -k0.
    +
    -A rate:  If @@ -3018,641 +3018,641 @@ If - - the black point is not being set completely to the same hue as the - white point (ie. because the -k - factor is less than 1.0), then the resulting calibration curves will - have the target white point down most of the curve, but will then - blend over to the native or compromise black point that is blacker, - but not of the right hue. The rate of this blend can be controlled - with the -A parameter. The - default value 4.0, which results in a target that switches from the - white point target to the black, moderately close to the black - point. While this typically gives a good visual result with the - target neutral hue being maintained to the point where the crossover - to the black hue is not visible, it may be asking too much of some - displays (typically LCD type displays), and there may be some visual - effects due to inconsistent color with viewing angle. For this - situation a smaller value may give a better visual result (e.g. try - values of 3.0 or 2.0. A value of 1.0 will set a pure linear blend - from white point to black point). If there is too much coloration - near black, try a larger value, e.g. 6.0 or 8.0.
    -
    - The -b flag forces source 0,0,0 to map - to destination 0,0,0. This may be useful with displays that have a - very dark black point, and with an instrument is unable to measure - it precisely, and where it is known in some other way that the - display is very well behaved from black (i.e. that it has no - "dead zone" above zero device input). Using this option with a - display that is not well behaved, may result in a loss of - shadow detail. This will override any -k factor.
    -
    - -B  Set - the target brightness of black in cd/m^2 (i.e. the absolute Y - value). Setting too high a value may give strange results as it - interacts with trying to achieve the target "advertised" gamma curve - shape. You could try using -f 1 if this causes a problem.
    -
    - -e [n] Run n verify passes on the final - curves. This is an extra set of instrument readings, that can be - used to estimate how well the device will match the targets with the - computed calibration curves. Note that the usefulness of the - verification is sometimes limited by the repeatability of the device - & instrument readings. This is often evident for CRT displays, - which (due to their refresh rate) flicker. More than one - verification pass can be done by providing the parameter n, and by then comparing the - successive verifications, some idea of the repeatability can be - ascertained. The verification uses a fixed number of semi-random - test values to test the calibration.
    -
    - -z Run - verify pass on the display as it is currently setup (currently - installed LUT curves). This will use the usual input parameters to - establish the expected (target) characteristic. Note that if the initial - calibration was modified due to it being out of gamut of the - display, verify will show the resulting discrepancy. You can use dispwin to load a .cal file into the display - before running dispcal -z. - Note that if you set an Ambient light level interactively during the - calibration, you need to enter the same number that was measured and - set using the -a parameter - for verify.
    -
    - The -P - parameter allows you to position and size the test patch window. By - default it is places in the center of the screen, and sized - appropriately for the type of instrument, or 10% of the width of the - display if the display size is unknown.. The ho and vo values govern the horizontal - and vertical offset respectively. A value of 0.0 positions the - window to the far left or top of the screen, a value of 0.5 - positions it in the center of the screen (the default), and 1.0 - positions it to the far right or bottom of the screen. If three - parameters are provided, then the ss - parameter is a scale factor for the test window size. A value of 0.5 - for instance, would produce a half sized window. A value of 2.0 will - produce a double size window. If four parameters are provided, then - the last two set independent horizontal and vertical scaling - factors. Note that the ho,vo,ss or ho,vo,hs,vs numbers must be - specified as a single string (no space between the numbers and the - comma). For example, to create a double sized test window at the top - right of the screen, use -P 1,0,2 - . To create a window twice as wide as high: -P 1,0,2,1.
    -
    - The -F - flag causes the while screen behind the test window to be masked - with black. This can aid black accuracy when measuring CRT displays - or projectors.
    -
    - The -E - flag causes the display test values to be scaled to the Video RGB - encoding range of (16-235)/255. This also modifies the resulting - calibration curve behavior downstream of dispcal. If a calibration - curve created using -E gets installed or converted to an ICC profile - 'vcgt' tag in the process of creating a profile in dispcal or - colprof, the incoming full range values will first have the - calibration curve applied and then be scaled to the Video encoding - range (16-235)/255.
    -
    - -n When - running on a UNIX based system that used the X11 Windowing System, dispcal - normally selects the override redirect so that the test window will - appear above any other windows on the display. On some systems this - can interfere with window manager operation, and the -n - option turns this behaviour off.
    -
    - The -J - option runs through the black and sensor relative calibration - routines for the Xrite DTP92 and DTP94 instruments, the black level - calibration for the Eye-One Display 1, and a CRT frequency - calibration for the Eye-One Display 2. For the black calibration the - instrument should be placed on an opaque, black surface, and any - stray light should be avoided by placing something opaque over the - instrument. If a Spectrolino is being used, then a white and black - calibration will always be performed before the instrument can be - placed on the display, unless the -N - flag is used. Generally it is not necessary to do a calibration - every time an instrument is used, just now and again. There is also - no point in doing  a CRT frequency calibration, as this will be - done automatically at the commencement of patch reading, and will be - lost between runs.
    -
    - -N Any - instrument that requires regular calibration will ask for - calibration on initial start-up. Sometimes this can be awkward if - the instrument is being mounted in some sort of measuring jig, or - annoying if several sets of readings are being taken in quick - succession. The -N - suppresses this initial calibration if a valid and not timed out - previous calibration is recorded in the instrument or on the host - computer. It is advisable to only use this option on the second and - subsequent measurements in a single session.
    -
    - The -H - option turns on high resolution spectral mode, if the instrument - supports it, such as the Eye-One Pro. See Operation of particular instruments - for more details. This may give better accuracy for display - measurements.
    -
    - The -X file.ccmx option reads - a Colorimeter Correction Matrix - from the given file, and applies it to the colorimeter instruments - readings. This can improve a colorimeters accuracy for a particular - type of display. A list of contributed ccmx files is here.
    -
    - The -X file.ccss option reads - a Colorimeter Calibration - Spectral Sample from the given file, and uses it to set the - colorimeter instruments calibration. This will only work with - colorimeters that rely on sensor spectral sensitivity calibration - information (ie. the X-Rite i1d3, - or the DataColor Spyder4 & - Spyder 5).This can improve a colorimeters accuracy for a - particular type of display.
    -
    - The -Q flag allows specifying a tristimulus - observer, and is used to compute PCS (Profile Connection Space) - tristimulus values from spectral readings or using a colorimeter - that has CCSS capability. The following choices are available:
    -   1931_2 selects the standard CIE 1931 2 degree - observer. The default.
    -   1964_10 selects the standard CIE 1964 10 degree - observer.
    -   1955_2 selects the Stiles and Birch 1955 2 degree - observer
    -   1978_2 selects the Judd and Voss 1978 2 degree - observer
    -   shaw selects the Shaw and Fairchild 1997 2 degree - observer
    -   1964_10c selects a version of the CIE 1964 10 degree - observer that has been adjusted using a 3x3 matrix to better agree - with the 1931 2 degree observer.
    -
    - NOTE that if you select - anything other than the default 1931 2 degree observer, that the Y - values will not be cd/m^2, due to the Y curve not being the CIE 1924 - photopic V(λ) luminosity function.
    -
    - The -I b|w options invoke - instrument black level, and display white level compensation - (respectively). Instrument black level drift compensation attempts - to combat instrument black calibration drift by using a display - black test patch as a reference. If an instrument is not - acclimatised sufficiently to the measurement conditions, changes in - temperature can affect the black readings. Display white level drift - compensation attempts to combat changes in display brightness as it - warms up by measuring a white patch every so often, and using it to - normalise all the other readings. If just instrument black drift - compensation is needed, use -Ib. - If just display white level compensation is needed, use -Iw. If both are needed, use -Ibw or -Iwb.
    -
    - The -Y R:rate - options overrides calibration of the instrument refresh rate. This - may be useful if the instrument supports this function and the - refresh rate cannot be accurately calibrated from the display - itself.
    -
    - The -Y A - option uses a non-adaptive integration time emission measurement - mode, if the instrument supports it, such as the Eye-One Pro, - ColorMunki, i1d3 and K10. By default an adaptive integration time - measurement mode will be used for emission measurements, but some - instruments support a fixed integration time mode that can be used - with display devices. This may give faster measurement times, but - may also give less accurate low level readings.
    -
    - The -Y p - option skips asking the user to place the instrument on the display. - Normally a grey patch is displayed, and then the user is asked to - confirm that the instrument is in place, so that readings can - commence. This flag disables that check. This may be useful in - automating certain operations.
    -
    - The -C "command" option allows a - method of relaying each test value to some other display than that - on the system running dispcal (for instance, a photo frame, PDA - screen etc.), by causing the given command to be invoked to the - shell, with six arguments. The first three arguments are the RGB - test color as integers in the range 0 to 255, the second three - parameters are the RGB test color as floating point numbers in the - range 0.0 to 1.0. The script or tool should relay the given color to - the screen in some manner (e.g. by generating a raster file of the - given color and sending it to the display being profiled), before - returning. Note that a test window will also be created on the - system running dispread.
    -
    - The -M "command" option allows a - method of gathering each test value from some external source, such - as an instrument that is not directly supported by Argyll. The given - command is involked to the shell, with six arguments. The first - three arguments are the RGB test color as integers in the range 0 to - 255, the second three parameters are the RGB test color as floating - point numbers in the range 0.0 to 1.0. The script or tool should - create a file called "command.meas" - that contains the XYZ values for the given RGB (or measured from the - test window) in cd/m^2 as three numbers separated by spaces, before - returning. If the command returns a non-zero return value, dispcal - will abort. Note that a test window will also be created on the - system running dispcal.
    -
    - The -W n|h|x - parameter overrides the default serial communications flow control - setting. The value n turns - all flow control off, h - sets hardware handshaking, and x - sets Xon/Xoff handshaking. This commend may be useful in workaround - serial communications issues with some systems and cables.
    -
    - The -D flag causes communications and other - instrument diagnostics to be printed to stdout. A level can be set - between 1 .. 9, that may give progressively more verbose - information, depending on the instrument. This can be useful in - tracking down why an instrument can't connect.
    -
    - inoutfile - The final parameter on the command line is the base filename for the - .cal file and the optional ICC - profile. Normally this will be created (or an existing file will be - overwritten). If the -u - flag is used, then these files will be updated. If a different ICC - profile name needs to be specified, do so as an argument to the -o flag.
    -
    - NOTE that on an X11 system, - if the environment variable ARGYLL_IGNORE_XRANDR1_2 - is set (ie. set it to "yes"), then the presence of the XRandR 1.2 - extension will be ignored, and other extensions such as Xinerama and - XF86VidMode extension will be used. This may be a way to work around - buggy XRandR 1.2 implementations.
    -
    -
    -

    Discussion and guide to display control - adjustment:

    -
    - The adjustment of the display controls (brightness, contrast, R, G - & B channel controls etc.) is very dependent on the particular - monitor. Different types and brands of monitors will have different - controls, or controls that operate in different ways. Some displays - have almost no user controls, and so you may well be best skipping - display adjustment, and going straight to calibration.
    -
    - Almost all LCD displays lack a real contrast control. Those that do present such a - control generally fake it by adjusting the video signal. For this - reason it is usually best to set an LCD's contrast control at its neutral setting (ie. the - setting at which it doesn't change the video signal). Unfortunately, - it can be hard to know what this neutral setting is. On some - displays it is 50%, others 75%. If the LCD display has a "reset to - factory defaults" mode, then try using this first, as a way of - setting the contrast - control to neutral. The LCD brightness - control generally adjusts the level of backlighting the display - gets, which affects the maximum brightness, and also tends to raise - or lower the black level in proportion, without changing the - displays response curve shape or overall contrast ratio. If your LCD - display has a backlight - control as well as a brightness - control, then the brightness control is also probably being faked, - and you are probably better off setting it to it's neutral setting, - and using the backlight - control in place of brightness - in the following adjustments.
    -
    - Some high end displays have the ability to mimic various standard - colorspaces such as sRGB or AdobeRGB. You could choose to calibrate - and profile the display in such an emulation mode, although you - probably don't want to fight the emulations white point and gamma. - To get the best out of such a display you really want to choose it's - "Native Gamut" setting, whatever that is called. Note that some - people have reported bad experiences in trying to use "6-axis custom - controls" on displays such as the Dell U2410, so attempting to use - such a mode should be approached with caution. Ideally such a mode - should be used to give just the underlying native display response, - but the settings to achieve this may be very difficult to determine, - and/or it may not be possible, depending on how such a mode distorts - the RGB signals.
    -
    - On CRT based displays, the brightness - control generally adjusts the black level of the display (sometimes - called the offset), and as - a side effect, tends to change the maximum brightness too. A CRT contrast control generally - adjusts the maximum brightness (sometimes called gain) without affecting the - black level a great deal. On a CRT both the brightness and contrast controls will tend to - affect the shape or gamma of the display response curve.
    -
    - Many displays have some sort of color temperature adjustment. This - may be in the form of some pre-set color temperatures, or in the - form of individual Red, Green and Blue channel gain adjustments. - Some CRT displays also have R, G & B channel offset adjustments - that will affect the color temperatures near black, as well as - affect the individual channels curve shape. The color temperature - adjustment will generally affect the maximum brightness, and may - also affect the black level and the shape of the display response - curves.
    -
    - Some special (expensive) LCD displays may have a white point - adjustment that changes the color of the backlight. If you do not - have one of these types of LCD displays, then attempting to change - the white point of the display (even if it appears to have a "white point selection" or R/G/B "gain" controls") may not be a good idea, as once - again these controls are probably being faked by manipulating the - signal levels. Even if you do manage to change the white point - significantly, it may do things like change the mid tone color too - dramatically, or create a display response that is hard to correct - with calibration, or results in side effects such as quantization - (banding) or other undesirable effects. You may have to try out - various controls (and your aim points for the display calibration), - to decide what is reasonable to attempt on an LCD display.
    -
    - Due to the variety of controls as well as the interaction between - them, it can be an iterative process to arrive at a good monitor - set-up, before proceeding on to calibrating and profiling a display. - For this reason, dispcal - offers a menu of adjustment modes, so that the user can - interactively and iteratively adjust the display controls to meet - the desired targets.
    -
    -   1) Black level (CRT: Brightness)
    -   2) White point (Color temperature, R,G,B, Gain/Contrast)
    -   3) White level (CRT: Gain/Contrast, LCD: - Brightness/Backlight)
    -   4) Black point (R,G,B, Offset/Brightness)
    -   5) Check all
    -   6) Measure and set ambient for viewing condition adjustment
    -   7) Continue on to calibration
    -   8) Exit
    -
    - There are four basic adjustment modes. Normally one would proceed - through them in the order above, then perhaps repeat the first - adjustment, before checking the overall settings. The White point - and White level modes operate slightly differently, depending on - whether a white target point has been set using the -t -T or -w options, and on whether a - brightness target has been set using the -b option.
    -
    -
    - The first mode lets you adjust the black level of a CRT display. - Given the current white level, it calculates a value that should - produce a 1% display brightness if the black level is set correctly. - After doing some initial measurements, it will show the target - brightness value (in cd/m^2) on one line, and then underneath it - will show continuously updated readings from the display. The left - most character will switch from '\' to '/' or back again each time a - reading is updated. Some instruments can be quite slow in measuring - dark colors, and it's best to wait for a reading update before - changing the controls more than once. Underneath the target value is - displayed the current reading, and to the right of this is a '+', - '-' or '=' symbol, which gives a hint as to which way to adjust the - brightness control to improve the match to the target.
    -
    -   Adjust CRT brightness to get target level. - Press space when done.
    -      Target - 0.60
    -   / Current 0.68  - -

    -
    - Once happy with the adjustment, press space to go back to the menu.
    -
    -
    - The second mode lets you adjust the color of the white point of the - display. If a target white point has been set, it will show the - target brightness value (in cd/m^2) on one line, together with the - target chromaticity co-ordinates for the white point, and then - underneath it will show continuously updated readings from the - display. The left most character will switch from '\' to '/' or back - again each time a reading is updated. Underneath the target - brightness value is displayed the current reading, and then the - current chromaticity co-ordinate values. To the right of this is the - current delta E of the white point from the target, and further to - the right are hints '+', '-' or '='  as to which direction to - adjust the individual Red, Green and Blue gain settings to move the - white point in the direction of the target, and reduce the delta E. - If the symbol is doubled, then this channel will have the greatest - effect. If you do not have individual channel gain controls, then - try choosing amongst color temperature pre-sets, to find one with - the lowest delta E. Depending on the stability of the display, the - coarseness of the controls, and the repeatability of the instrument, - you may not be able to get a perfectly zero delta E.
    -
    -    Adjust R,G & B gain to get - target x,y. Press space when done.
    -      Target B 60.00, x 0.3451, y 0.3516
    -   / Current B 60.05, x 0.3426, y 0.3506  DE  - 1.4  R+  G+  B--

    -
    - If you did not set a white point target, then the information shown - is a little different - it will show the initial white point value, - as well as the color temperature, and the CIEDE2000 of the white - point to either the Daylight or Black Body locus (depending on - whether the -T flag was - set). The constantly updated values show the same thing, and the - Red, Green and Blue control hints show the direction to adjust the - controls to place the white point on the locus. The control that - will have the most direct effect on the color temperature will be - the Blue, while the Green will most directly move the white point - towards or away from the locus, thereby reducing the delta E of the - white point to the locus (but there is interaction).
    -
    - Adjust R,G & B gain to desired white point. - Press space when done.
    -   Initial B 47.25, x - 0.3417, y 0.3456, CDT 5113 DE  6.9
    - \ Current B 47.38, x 0.3420, - y 0.3460  CDT 5104 DE  6.7  R-- G+  B-

    -
    -  The brightness value is just there as a guide to what effect - the adjustment is having on the overall brightness. Usually the - white level brightness is adjusted using the next adjustment mode. - Once happy with the adjustment, press space to go back to the menu.
    -
    -
    - The third mode lets you adjust the brightness of white on the - display. If you set a target brightness using the -b - parameter, it will show the target brightness value (in cd/m^2) on - one line, and then underneath it will show continuously updated - readings from the display. The left most character will switch from - '\' to '/' or back again each time a reading is updated. Underneath - the target value is displayed the current reading, and to the right - of this is a '+', '-' or '=' symbol, which gives a hint as to which - way to adjust the CRT contrast or LCD brightness control to improve - the match to the target.
    -
    -    Adjust CRT Contrast or LCD - Brightness to get target level. Press space when done.
    -      Target 60.00
    -   / Current 59.96  +

    -
    - If you did not set a brightness target, it will show the initial - brightness as the target, and the current brightness, which you can - then set any way you want:
    -
    - Adjust CRT Contrast or LCD Brightness to desired - level. Press space when done.
    -   Initial 47.32
    - / Current 47.54

    -
    - Once happy with the adjustment, press space to go back to the menu.
    -
    -
    - The fourth mode lets you adjust the color of the black point of the - display, if the display has Red, Green and Blue channel offset - controls. It will show the target 1% brightness value (in cd/m^2) on - one line, together with the target chromaticity co-ordinates for the - black point, and then underneath it will show continuously updated - readings from the display. The left most character will switch from - '\' to '/' or back again each time a reading is updated. Underneath - the target brightness value is displayed the current reading, and - then the current chromaticity co-ordinate values. To the right of - this is the current delta E of the black point from the target, and - further to the right are hints '+', '-' or '='  as to which - direction to adjust the individual Red, Green and Blue offset - settings to move the black point in the right direction. If the - symbol is doubled, then this channel will have the greatest effect. -
    -
    -   Adjust R,G & B offsets to get target x,y. - Press space when done.
    -      Target B 0.60, x 0.3451, y 0.3516
    -   \ Current B 0.62, x 0.2782, y 0.2331  DE  - 10.3  R+  G++ B-

    -
    - The 1%  brightness value is just there as a guide to what - effect the adjustment is having on the 1% brightness level. The - combined channel offsets may have an effect on this in combination - with the CRT brightness control. Press space to go back to the menu.
    -
    -
    - The fifth selection checks on the overall settings.  If targets - have been set, it will be like:
    -
    -   Target Brightness = 50.00, Current = 47.44, - error = -5.1%
    -   Target 50% Level  = 10.32, Current =  8.10, - error = -4.4%
    -   Target Near Black =  0.47, Current =  0.68, - error =  0.4%
    -   Target white = x 0.3458, y 0.3586, Current = x 0.3420, y - 0.3454, error =  7.55 DE
    -   Target black = x 0.3458, y 0.3586, Current = x 0.2908, y - 0.2270, error = 29.69 DE

    -
    - or if no targets are set:
    -
    -   Current Brightness = 46.28
    -   Target 50% - Level  = 10.07, Current =  7.52, error = -5.5%
    -   Target Near Black - =  0.46, Current =  0.46, error = -0.0%
    -   Current white = x - 0.3439, y 0.3466, VCT 5098K DE  3.0
    -   Target black = x - 0.3439, y 0.3466, Current = x 0.3093, y 0.2165, error = 30.30 DE

    -
    - and will then go back to the menu.
    -
    - The sixth selection 6) - allows the reading of you ambient lighting conditions if your - instrument supports such a mode. Doing so will enable the -a option to compensate for your - viewing conditions in the subsequent calibration. See -a.
    -
    - Once  you're happy with the display set-up, you can either - proceed on to the rest of the calibration by selecting 7), or exit and re-start by - selecting 8). You might - want to re-start if you want to change the calibration targets.
    -
    -
    -

    Other caveats:

    - NOTE that some LCD screens - behave a little strangely near their absolute white point, and may - therefore exhibit odd behavior at values just below white. It may be - advisable in such cases to set a brightness slightly less than the - maximum such a display is capable of.
    -
    - The program attempts to stop any screensaver or powersaver from - interfering with the measurements, but this may not be effective on - some systems, so it may be necessary to manually disable the - screensaver and/or powersaver before commencing the calibration with - a large number of patches.
    -
    - The calibration tables produced maintain the maximum level of - precision available on a system. If the display has VideoLUTs - available (Video Lookup Tables that the frame buffer values pass - through on their way to the display) and thier outputs are better - than 8 bits per component, then the resulting curves can reflect - this, although few current operating systems and/or display cards - actually support better than 8 bit per component output.
    -
    - If calibration curves are created for a display in which VideoLUTs - are not available, then the resulting calibration file will be - marked to indicate this, and a subsequent profile created with the - calibration will not have the calibration converted to the 'vcgt' - tag, since such a tag can't be loaded into the displays VideoLUTs.
    -
    - If communications break down with a USB connected instrument, you - may have to unplug it, and plug it in again to recover operation.
    -
    - Some systems (Apple OS X in particular) have a special set of user - interface controls ("Universal Access") that allows altering the - display in ways designed to assist visually impaired users, by - increasing contrast etc. This will interfere badly with any attempts - to calibrate or profile such a system, and must be turned off in - order to do so. Note that certain magic keyboard sequences can turn - this on by accident.
    -
    -
    -
    -
    -
    - - + + the black point is not being set completely to the same hue as the + white point (ie. because the -k + factor is less than 1.0), then the resulting calibration curves will + have the target white point down most of the curve, but will then + blend over to the native or compromise black point that is blacker, + but not of the right hue. The rate of this blend can be controlled + with the -A parameter. The + default value 4.0, which results in a target that switches from the + white point target to the black, moderately close to the black + point. While this typically gives a good visual result with the + target neutral hue being maintained to the point where the crossover + to the black hue is not visible, it may be asking too much of some + displays (typically LCD type displays), and there may be some visual + effects due to inconsistent color with viewing angle. For this + situation a smaller value may give a better visual result (e.g. try + values of 3.0 or 2.0. A value of 1.0 will set a pure linear blend + from white point to black point). If there is too much coloration + near black, try a larger value, e.g. 6.0 or 8.0.
    +
    + The -b flag forces source 0,0,0 to map + to destination 0,0,0. This may be useful with displays that have a + very dark black point, and with an instrument is unable to measure + it precisely, and where it is known in some other way that the + display is very well behaved from black (i.e. that it has no + "dead zone" above zero device input). Using this option with a + display that is not well behaved, may result in a loss of + shadow detail. This will override any -k factor.
    +
    + -B  Set + the target brightness of black in cd/m^2 (i.e. the absolute Y + value). Setting too high a value may give strange results as it + interacts with trying to achieve the target "advertised" gamma curve + shape. You could try using -f 1 if this causes a problem.
    +
    + -e [n] Run n verify passes on the final + curves. This is an extra set of instrument readings, that can be + used to estimate how well the device will match the targets with the + computed calibration curves. Note that the usefulness of the + verification is sometimes limited by the repeatability of the device + & instrument readings. This is often evident for CRT displays, + which (due to their refresh rate) flicker. More than one + verification pass can be done by providing the parameter n, and by then comparing the + successive verifications, some idea of the repeatability can be + ascertained. The verification uses a fixed number of semi-random + test values to test the calibration.
    +
    + -z Run + verify pass on the display as it is currently setup (currently + installed LUT curves). This will use the usual input parameters to + establish the expected (target) characteristic. Note that if the initial + calibration was modified due to it being out of gamut of the + display, verify will show the resulting discrepancy. You can use dispwin to load a .cal file into the display + before running dispcal -z. + Note that if you set an Ambient light level interactively during the + calibration, you need to enter the same number that was measured and + set using the -a parameter + for verify.
    +
    + The -P + parameter allows you to position and size the test patch window. By + default it is places in the center of the screen, and sized + appropriately for the type of instrument, or 10% of the width of the + display if the display size is unknown.. The ho and vo values govern the horizontal + and vertical offset respectively. A value of 0.0 positions the + window to the far left or top of the screen, a value of 0.5 + positions it in the center of the screen (the default), and 1.0 + positions it to the far right or bottom of the screen. If three + parameters are provided, then the ss + parameter is a scale factor for the test window size. A value of 0.5 + for instance, would produce a half sized window. A value of 2.0 will + produce a double size window. If four parameters are provided, then + the last two set independent horizontal and vertical scaling + factors. Note that the ho,vo,ss or ho,vo,hs,vs numbers must be + specified as a single string (no space between the numbers and the + comma). For example, to create a double sized test window at the top + right of the screen, use -P 1,0,2 + . To create a window twice as wide as high: -P 1,0,2,1.
    +
    + The -F + flag causes the while screen behind the test window to be masked + with black. This can aid black accuracy when measuring CRT displays + or projectors.
    +
    + The -E + flag causes the display test values to be scaled to the Video RGB + encoding range of (16-235)/255. This also modifies the resulting + calibration curve behavior downstream of dispcal. If a calibration + curve created using -E gets installed or converted to an ICC profile + 'vcgt' tag in the process of creating a profile in dispcal or + colprof, the incoming full range values will first have the + calibration curve applied and then be scaled to the Video encoding + range (16-235)/255.
    +
    + -n When + running on a UNIX based system that used the X11 Windowing System, dispcal + normally selects the override redirect so that the test window will + appear above any other windows on the display. On some systems this + can interfere with window manager operation, and the -n + option turns this behaviour off.
    +
    + The -J + option runs through the black and sensor relative calibration + routines for the Xrite DTP92 and DTP94 instruments, the black level + calibration for the Eye-One Display 1, and a CRT frequency + calibration for the Eye-One Display 2. For the black calibration the + instrument should be placed on an opaque, black surface, and any + stray light should be avoided by placing something opaque over the + instrument. If a Spectrolino is being used, then a white and black + calibration will always be performed before the instrument can be + placed on the display, unless the -N + flag is used. Generally it is not necessary to do a calibration + every time an instrument is used, just now and again. There is also + no point in doing  a CRT frequency calibration, as this will be + done automatically at the commencement of patch reading, and will be + lost between runs.
    +
    + -N Any + instrument that requires regular calibration will ask for + calibration on initial start-up. Sometimes this can be awkward if + the instrument is being mounted in some sort of measuring jig, or + annoying if several sets of readings are being taken in quick + succession. The -N + suppresses this initial calibration if a valid and not timed out + previous calibration is recorded in the instrument or on the host + computer. It is advisable to only use this option on the second and + subsequent measurements in a single session.
    +
    + The -H + option turns on high resolution spectral mode, if the instrument + supports it, such as the Eye-One Pro. See Operation of particular instruments + for more details. This may give better accuracy for display + measurements.
    +
    + The -X file.ccmx option reads + a Colorimeter Correction Matrix + from the given file, and applies it to the colorimeter instruments + readings. This can improve a colorimeters accuracy for a particular + type of display. A list of contributed ccmx files is here.
    +
    + The -X file.ccss option reads + a Colorimeter Calibration + Spectral Sample from the given file, and uses it to set the + colorimeter instruments calibration. This will only work with + colorimeters that rely on sensor spectral sensitivity calibration + information (ie. the X-Rite i1d3, + or the DataColor Spyder4 & + Spyder 5).This can improve a colorimeters accuracy for a + particular type of display.
    +
    + The -Q flag allows specifying a tristimulus + observer, and is used to compute PCS (Profile Connection Space) + tristimulus values from spectral readings or using a colorimeter + that has CCSS capability. The following choices are available:
    +   1931_2 selects the standard CIE 1931 2 degree + observer. The default.
    +   1964_10 selects the standard CIE 1964 10 degree + observer.
    +   1955_2 selects the Stiles and Birch 1955 2 degree + observer
    +   1978_2 selects the Judd and Voss 1978 2 degree + observer
    +   shaw selects the Shaw and Fairchild 1997 2 degree + observer
    +   1964_10c selects a version of the CIE 1964 10 degree + observer that has been adjusted using a 3x3 matrix to better agree + with the 1931 2 degree observer.
    +
    + NOTE that if you select + anything other than the default 1931 2 degree observer, that the Y + values will not be cd/m^2, due to the Y curve not being the CIE 1924 + photopic V(λ) luminosity function.
    +
    + The -I b|w options invoke + instrument black level, and display white level compensation + (respectively). Instrument black level drift compensation attempts + to combat instrument black calibration drift by using a display + black test patch as a reference. If an instrument is not + acclimatised sufficiently to the measurement conditions, changes in + temperature can affect the black readings. Display white level drift + compensation attempts to combat changes in display brightness as it + warms up by measuring a white patch every so often, and using it to + normalise all the other readings. If just instrument black drift + compensation is needed, use -Ib. + If just display white level compensation is needed, use -Iw. If both are needed, use -Ibw or -Iwb.
    +
    + The -Y R:rate + options overrides calibration of the instrument refresh rate. This + may be useful if the instrument supports this function and the + refresh rate cannot be accurately calibrated from the display + itself.
    +
    + The -Y A + option uses a non-adaptive integration time emission measurement + mode, if the instrument supports it, such as the Eye-One Pro, + ColorMunki, i1d3 and K10. By default an adaptive integration time + measurement mode will be used for emission measurements, but some + instruments support a fixed integration time mode that can be used + with display devices. This may give faster measurement times, but + may also give less accurate low level readings.
    +
    + The -Y p + option skips asking the user to place the instrument on the display. + Normally a grey patch is displayed, and then the user is asked to + confirm that the instrument is in place, so that readings can + commence. This flag disables that check. This may be useful in + automating certain operations.
    +
    + The -C "command" option allows a + method of relaying each test value to some other display than that + on the system running dispcal (for instance, a photo frame, PDA + screen etc.), by causing the given command to be invoked to the + shell, with six arguments. The first three arguments are the RGB + test color as integers in the range 0 to 255, the second three + parameters are the RGB test color as floating point numbers in the + range 0.0 to 1.0. The script or tool should relay the given color to + the screen in some manner (e.g. by generating a raster file of the + given color and sending it to the display being profiled), before + returning. Note that a test window will also be created on the + system running dispread.
    +
    + The -M "command" option allows a + method of gathering each test value from some external source, such + as an instrument that is not directly supported by Argyll. The given + command is involked to the shell, with six arguments. The first + three arguments are the RGB test color as integers in the range 0 to + 255, the second three parameters are the RGB test color as floating + point numbers in the range 0.0 to 1.0. The script or tool should + create a file called "command.meas" + that contains the XYZ values for the given RGB (or measured from the + test window) in cd/m^2 as three numbers separated by spaces, before + returning. If the command returns a non-zero return value, dispcal + will abort. Note that a test window will also be created on the + system running dispcal.
    +
    + The -W n|h|x + parameter overrides the default serial communications flow control + setting. The value n turns + all flow control off, h + sets hardware handshaking, and x + sets Xon/Xoff handshaking. This commend may be useful in workaround + serial communications issues with some systems and cables.
    +
    + The -D flag causes communications and other + instrument diagnostics to be printed to stdout. A level can be set + between 1 .. 9, that may give progressively more verbose + information, depending on the instrument. This can be useful in + tracking down why an instrument can't connect.
    +
    + inoutfile + The final parameter on the command line is the base filename for the + .cal file and the optional ICC + profile. Normally this will be created (or an existing file will be + overwritten). If the -u + flag is used, then these files will be updated. If a different ICC + profile name needs to be specified, do so as an argument to the -o flag.
    +
    + NOTE that on an X11 system, + if the environment variable ARGYLL_IGNORE_XRANDR1_2 + is set (ie. set it to "yes"), then the presence of the XRandR 1.2 + extension will be ignored, and other extensions such as Xinerama and + XF86VidMode extension will be used. This may be a way to work around + buggy XRandR 1.2 implementations.
    +
    +
    +

    Discussion and guide to display control + adjustment:

    +
    + The adjustment of the display controls (brightness, contrast, R, G + & B channel controls etc.) is very dependent on the particular + monitor. Different types and brands of monitors will have different + controls, or controls that operate in different ways. Some displays + have almost no user controls, and so you may well be best skipping + display adjustment, and going straight to calibration.
    +
    + Almost all LCD displays lack a real contrast control. Those that do present such a + control generally fake it by adjusting the video signal. For this + reason it is usually best to set an LCD's contrast control at its neutral setting (ie. the + setting at which it doesn't change the video signal). Unfortunately, + it can be hard to know what this neutral setting is. On some + displays it is 50%, others 75%. If the LCD display has a "reset to + factory defaults" mode, then try using this first, as a way of + setting the contrast + control to neutral. The LCD brightness + control generally adjusts the level of backlighting the display + gets, which affects the maximum brightness, and also tends to raise + or lower the black level in proportion, without changing the + displays response curve shape or overall contrast ratio. If your LCD + display has a backlight + control as well as a brightness + control, then the brightness control is also probably being faked, + and you are probably better off setting it to it's neutral setting, + and using the backlight + control in place of brightness + in the following adjustments.
    +
    + Some high end displays have the ability to mimic various standard + colorspaces such as sRGB or AdobeRGB. You could choose to calibrate + and profile the display in such an emulation mode, although you + probably don't want to fight the emulations white point and gamma. + To get the best out of such a display you really want to choose it's + "Native Gamut" setting, whatever that is called. Note that some + people have reported bad experiences in trying to use "6-axis custom + controls" on displays such as the Dell U2410, so attempting to use + such a mode should be approached with caution. Ideally such a mode + should be used to give just the underlying native display response, + but the settings to achieve this may be very difficult to determine, + and/or it may not be possible, depending on how such a mode distorts + the RGB signals.
    +
    + On CRT based displays, the brightness + control generally adjusts the black level of the display (sometimes + called the offset), and as + a side effect, tends to change the maximum brightness too. A CRT contrast control generally + adjusts the maximum brightness (sometimes called gain) without affecting the + black level a great deal. On a CRT both the brightness and contrast controls will tend to + affect the shape or gamma of the display response curve.
    +
    + Many displays have some sort of color temperature adjustment. This + may be in the form of some pre-set color temperatures, or in the + form of individual Red, Green and Blue channel gain adjustments. + Some CRT displays also have R, G & B channel offset adjustments + that will affect the color temperatures near black, as well as + affect the individual channels curve shape. The color temperature + adjustment will generally affect the maximum brightness, and may + also affect the black level and the shape of the display response + curves.
    +
    + Some special (expensive) LCD displays may have a white point + adjustment that changes the color of the backlight. If you do not + have one of these types of LCD displays, then attempting to change + the white point of the display (even if it appears to have a "white point selection" or R/G/B "gain" controls") may not be a good idea, as once + again these controls are probably being faked by manipulating the + signal levels. Even if you do manage to change the white point + significantly, it may do things like change the mid tone color too + dramatically, or create a display response that is hard to correct + with calibration, or results in side effects such as quantization + (banding) or other undesirable effects. You may have to try out + various controls (and your aim points for the display calibration), + to decide what is reasonable to attempt on an LCD display.
    +
    + Due to the variety of controls as well as the interaction between + them, it can be an iterative process to arrive at a good monitor + set-up, before proceeding on to calibrating and profiling a display. + For this reason, dispcal + offers a menu of adjustment modes, so that the user can + interactively and iteratively adjust the display controls to meet + the desired targets.
    +
    +   1) Black level (CRT: Brightness)
    +   2) White point (Color temperature, R,G,B, Gain/Contrast)
    +   3) White level (CRT: Gain/Contrast, LCD: + Brightness/Backlight)
    +   4) Black point (R,G,B, Offset/Brightness)
    +   5) Check all
    +   6) Measure and set ambient for viewing condition adjustment
    +   7) Continue on to calibration
    +   8) Exit
    +
    + There are four basic adjustment modes. Normally one would proceed + through them in the order above, then perhaps repeat the first + adjustment, before checking the overall settings. The White point + and White level modes operate slightly differently, depending on + whether a white target point has been set using the -t -T or -w options, and on whether a + brightness target has been set using the -b option.
    +
    +
    + The first mode lets you adjust the black level of a CRT display. + Given the current white level, it calculates a value that should + produce a 1% display brightness if the black level is set correctly. + After doing some initial measurements, it will show the target + brightness value (in cd/m^2) on one line, and then underneath it + will show continuously updated readings from the display. The left + most character will switch from '\' to '/' or back again each time a + reading is updated. Some instruments can be quite slow in measuring + dark colors, and it's best to wait for a reading update before + changing the controls more than once. Underneath the target value is + displayed the current reading, and to the right of this is a '+', + '-' or '=' symbol, which gives a hint as to which way to adjust the + brightness control to improve the match to the target.
    +
    +   Adjust CRT brightness to get target level. + Press space when done.
    +      Target + 0.60
    +   / Current 0.68  + -

    +
    + Once happy with the adjustment, press space to go back to the menu.
    +
    +
    + The second mode lets you adjust the color of the white point of the + display. If a target white point has been set, it will show the + target brightness value (in cd/m^2) on one line, together with the + target chromaticity co-ordinates for the white point, and then + underneath it will show continuously updated readings from the + display. The left most character will switch from '\' to '/' or back + again each time a reading is updated. Underneath the target + brightness value is displayed the current reading, and then the + current chromaticity co-ordinate values. To the right of this is the + current delta E of the white point from the target, and further to + the right are hints '+', '-' or '='  as to which direction to + adjust the individual Red, Green and Blue gain settings to move the + white point in the direction of the target, and reduce the delta E. + If the symbol is doubled, then this channel will have the greatest + effect. If you do not have individual channel gain controls, then + try choosing amongst color temperature pre-sets, to find one with + the lowest delta E. Depending on the stability of the display, the + coarseness of the controls, and the repeatability of the instrument, + you may not be able to get a perfectly zero delta E.
    +
    +    Adjust R,G & B gain to get + target x,y. Press space when done.
    +      Target B 60.00, x 0.3451, y 0.3516
    +   / Current B 60.05, x 0.3426, y 0.3506  DE  + 1.4  R+  G+  B--

    +
    + If you did not set a white point target, then the information shown + is a little different - it will show the initial white point value, + as well as the color temperature, and the CIEDE2000 of the white + point to either the Daylight or Black Body locus (depending on + whether the -T flag was + set). The constantly updated values show the same thing, and the + Red, Green and Blue control hints show the direction to adjust the + controls to place the white point on the locus. The control that + will have the most direct effect on the color temperature will be + the Blue, while the Green will most directly move the white point + towards or away from the locus, thereby reducing the delta E of the + white point to the locus (but there is interaction).
    +
    + Adjust R,G & B gain to desired white point. + Press space when done.
    +   Initial B 47.25, x + 0.3417, y 0.3456, CDT 5113 DE  6.9
    + \ Current B 47.38, x 0.3420, + y 0.3460  CDT 5104 DE  6.7  R-- G+  B-

    +
    +  The brightness value is just there as a guide to what effect + the adjustment is having on the overall brightness. Usually the + white level brightness is adjusted using the next adjustment mode. + Once happy with the adjustment, press space to go back to the menu.
    +
    +
    + The third mode lets you adjust the brightness of white on the + display. If you set a target brightness using the -b + parameter, it will show the target brightness value (in cd/m^2) on + one line, and then underneath it will show continuously updated + readings from the display. The left most character will switch from + '\' to '/' or back again each time a reading is updated. Underneath + the target value is displayed the current reading, and to the right + of this is a '+', '-' or '=' symbol, which gives a hint as to which + way to adjust the CRT contrast or LCD brightness control to improve + the match to the target.
    +
    +    Adjust CRT Contrast or LCD + Brightness to get target level. Press space when done.
    +      Target 60.00
    +   / Current 59.96  +

    +
    + If you did not set a brightness target, it will show the initial + brightness as the target, and the current brightness, which you can + then set any way you want:
    +
    + Adjust CRT Contrast or LCD Brightness to desired + level. Press space when done.
    +   Initial 47.32
    + / Current 47.54

    +
    + Once happy with the adjustment, press space to go back to the menu.
    +
    +
    + The fourth mode lets you adjust the color of the black point of the + display, if the display has Red, Green and Blue channel offset + controls. It will show the target 1% brightness value (in cd/m^2) on + one line, together with the target chromaticity co-ordinates for the + black point, and then underneath it will show continuously updated + readings from the display. The left most character will switch from + '\' to '/' or back again each time a reading is updated. Underneath + the target brightness value is displayed the current reading, and + then the current chromaticity co-ordinate values. To the right of + this is the current delta E of the black point from the target, and + further to the right are hints '+', '-' or '='  as to which + direction to adjust the individual Red, Green and Blue offset + settings to move the black point in the right direction. If the + symbol is doubled, then this channel will have the greatest effect. +
    +
    +   Adjust R,G & B offsets to get target x,y. + Press space when done.
    +      Target B 0.60, x 0.3451, y 0.3516
    +   \ Current B 0.62, x 0.2782, y 0.2331  DE  + 10.3  R+  G++ B-

    +
    + The 1%  brightness value is just there as a guide to what + effect the adjustment is having on the 1% brightness level. The + combined channel offsets may have an effect on this in combination + with the CRT brightness control. Press space to go back to the menu.
    +
    +
    + The fifth selection checks on the overall settings.  If targets + have been set, it will be like:
    +
    +   Target Brightness = 50.00, Current = 47.44, + error = -5.1%
    +   Target 50% Level  = 10.32, Current =  8.10, + error = -4.4%
    +   Target Near Black =  0.47, Current =  0.68, + error =  0.4%
    +   Target white = x 0.3458, y 0.3586, Current = x 0.3420, y + 0.3454, error =  7.55 DE
    +   Target black = x 0.3458, y 0.3586, Current = x 0.2908, y + 0.2270, error = 29.69 DE

    +
    + or if no targets are set:
    +
    +   Current Brightness = 46.28
    +   Target 50% + Level  = 10.07, Current =  7.52, error = -5.5%
    +   Target Near Black + =  0.46, Current =  0.46, error = -0.0%
    +   Current white = x + 0.3439, y 0.3466, VCT 5098K DE  3.0
    +   Target black = x + 0.3439, y 0.3466, Current = x 0.3093, y 0.2165, error = 30.30 DE

    +
    + and will then go back to the menu.
    +
    + The sixth selection 6) + allows the reading of you ambient lighting conditions if your + instrument supports such a mode. Doing so will enable the -a option to compensate for your + viewing conditions in the subsequent calibration. See -a.
    +
    + Once  you're happy with the display set-up, you can either + proceed on to the rest of the calibration by selecting 7), or exit and re-start by + selecting 8). You might + want to re-start if you want to change the calibration targets.
    +
    +
    +

    Other caveats:

    + NOTE that some LCD screens + behave a little strangely near their absolute white point, and may + therefore exhibit odd behavior at values just below white. It may be + advisable in such cases to set a brightness slightly less than the + maximum such a display is capable of.
    +
    + The program attempts to stop any screensaver or powersaver from + interfering with the measurements, but this may not be effective on + some systems, so it may be necessary to manually disable the + screensaver and/or powersaver before commencing the calibration with + a large number of patches.
    +
    + The calibration tables produced maintain the maximum level of + precision available on a system. If the display has VideoLUTs + available (Video Lookup Tables that the frame buffer values pass + through on their way to the display) and thier outputs are better + than 8 bits per component, then the resulting curves can reflect + this, although few current operating systems and/or display cards + actually support better than 8 bit per component output.
    +
    + If calibration curves are created for a display in which VideoLUTs + are not available, then the resulting calibration file will be + marked to indicate this, and a subsequent profile created with the + calibration will not have the calibration converted to the 'vcgt' + tag, since such a tag can't be loaded into the displays VideoLUTs.
    +
    + If communications break down with a USB connected instrument, you + may have to unplug it, and plug it in again to recover operation.
    +
    + Some systems (Apple OS X in particular) have a special set of user + interface controls ("Universal Access") that allows altering the + display in ways designed to assist visually impaired users, by + increasing contrast etc. This will interfere badly with any attempts + to calibrate or profile such a system, and must be turned off in + order to do so. Note that certain magic keyboard sequences can turn + this on by accident.
    +
    +
    +
    +
    +
    + + diff --git a/doc/dispread.html b/doc/dispread.html index f7fe551..52a38c2 100644 --- a/doc/dispread.html +++ b/doc/dispread.html @@ -1,25 +1,25 @@ - - - - dispread - - - - -

    spectro/dispread 

    -

    Summary

    - Display test patches on a monitor, read the colorimetric value - result with the colorimeter, and create the chart readings file. The - type of instrument is determined by the communication port selected. - Emission and display measurement instruments are supported.
    -
    - If you want to read a display manually rather than automatically, - see chartread and the -d option.
    -

    Usage

    - dispread [-options] - inoutfile
    + + + + dispread + + + + +

    spectro/dispread 

    +

    Summary

    + Display test patches on a monitor, read the colorimetric value + result with the colorimeter, and create the chart readings file. The + type of instrument is determined by the communication port selected. + Emission and display measurement instruments are supported.
    +
    + If you want to read a display manually rather than automatically, + see chartread and the -d option.
    +

    Usage

    + dispread [-options] + inoutfile
     -v              @@ -54,17 +54,17 @@ - -      Verbose mode
    -  
    -display displayname [X11 only] Choose X11 display - name
    -
     -d n[,m] -             - [X11 only]Choose the display from the following list (default - 1),
    + +      Verbose mode
    +  
    -display displayname [X11 only] Choose X11 display + name
    +
     -d n[,m] +             + [X11 only]Choose the display from the following list (default + 1),
                          and optionally @@ -106,9 +106,9 @@ m - - for VideoLUT access.

    -  
    +  
    -d n                 Choose the @@ -150,8 +150,8 @@ list - - (default 1)
    + + (default 1)

     -dweb[:port]         @@ -188,9 +188,9 @@ list - - Display via a web server at port (default 8080)
    -  -dmadvr + + Display via a web server at port (default 8080)
    +  -dmadvr              @@ -214,22 +214,22 @@ list - - [MSWin] Display via MadVR Video Renderer
    + + [MSWin] Display via MadVR Video Renderer
     -dcc[:n]             - - Display via n'th ChromeCast (default 1, ? for list)
    -  -c listno -            Set - communication port from the following list (default 1)
    -
     -c listno +            Set + communication port from the following list (default 1)
    +
     -p                   @@ -264,10 +264,10 @@ list - - Use telephoto mode (ie. for a projector) (if available)
    -   -y X + + Use telephoto mode (ie. for a projector) (if available)
    +   -y X                 Display @@ -304,10 +304,10 @@ Display - - type - instrument specific list to choose from.
    -  -k + + type - instrument specific list to choose from.

    +  -
    k file.cal          @@ -342,10 +342,10 @@ Display - - Load calibration file into display while reading
    -
     -K + + Load calibration file into display while reading
    +
     -K file.cal          Apply @@ -381,8 +381,8 @@ Apply - - calibration file to test values while reading
    + + calibration file to test values while reading

     -V                   @@ -398,8 +398,8 @@ Apply - - [MSWin] Enable MadVR color management (3dLut)
    + + [MSWin] Enable MadVR color management (3dLut)

     -s              @@ -434,12 +434,12 @@ Apply - -      Save spectral information (default don't - save)
    -
     -P ho,vo,ss[,vs]     Position - test window and scale it
    + +      Save spectral information (default don't + save)
    +  -P ho,vo,ss[,vs]     Position + test window and scale it
                          ho,vi: 0.0 @@ -481,8 +481,8 @@ center, - - 1.0 = right/bottom etc.
    + + 1.0 = right/bottom etc.
                          ss: 0.5 @@ -524,8 +524,8 @@ normal, - - 2.0 = double etc.
    + + 2.0 = double etc.
                          @@ -553,10 +553,10 @@ normal, - - ss,vs: = optional horizontal, vertical scale.
    -  -F + + ss,vs: = optional horizontal, vertical scale.
    +  -F                   @@ -591,10 +591,10 @@ normal, - - Fill whole screen with black background
    -  -E + + Fill whole screen with black background
    +  -E                   @@ -614,11 +614,11 @@ normal, - - Video - encode output as (16-235)/255 "TV" levels
    -  -Z + + Video + encode output as (16-235)/255 "TV" levels
    +  
    -Z nbits             @@ -638,7 +638,7 @@ normal, - + Quantize test values @@ -658,9 +658,9 @@ fit - - in nbits
    -  
    +  -n                   [X11 @@ -702,9 +702,9 @@ redirect - - on test window
    -
     -J + + on test window
    +
     -J              @@ -739,9 +739,9 @@ redirect - -      Run calibration first
    -  
    +  
    -N                   @@ -776,17 +776,17 @@ redirect - - Disable initial calibration of instrument if possible
    -
     -H -              -      Use high resolution spectrum mode (if - available)
    -  -w + + Disable initial calibration of instrument if possible
    +
     -H +              +      Use high resolution spectrum mode (if + available)
    +  -w                   Disable normalisation @@ -828,9 +828,9 @@ Y - - 100

    -  
    +  
    -X file.ccmx         @@ -865,9 +865,9 @@ Y - - Apply Colorimeter Correction Matrix
    -  -X + + Apply Colorimeter Correction Matrix

    +  
    -X file.ccss          Use Colorimeter @@ -905,14 +905,14 @@ Calibration - - Spectral Samples for calibration
    -
     -Q observ        -     Choose CIE Observer for spectrometer or CCSS - colorimeter data:
    + + Spectral Samples for calibration
    +
     -Q observ        +     Choose CIE Observer for spectrometer or CCSS + colorimeter data:
                @@ -947,12 +947,12 @@ Calibration - -           1931_2
    (def.), 1964_10, S&B 1955_2, shaw, - J&V 1978_2, 1964_10c
    -  (def.), 1964_10, S&B 1955_2, shaw, + J&V 1978_2, 1964_10c
    +  
    -I b|w               Drift compensation, @@ -994,8 +994,8 @@ Both: - - -Ibw
    + + -Ibw

     -Y @@ -1008,7 +1008,7 @@ Both: - + R:rate             @@ -1021,12 +1021,12 @@ Both: - - Override measured refresh rate with rate Hz
    -
     
    -Y A + + Override measured refresh rate with rate Hz
    +  
    -Y A                 @@ -1052,31 +1052,31 @@ Both: - - Use non-adaptive integration time mode (if available).
    -  -Y - p -             -     Don't wait for the instrument to be placed on - the display
    -  -C "command" -         Invoke shell - "command" each time a color is set
    -
     -M "command" -         Invoke shell - "command" each time a color is measured
    -   -x x

    +  -Y + p +             +     Don't wait for the instrument to be placed on + the display
    +  -C "command" +         Invoke shell + "command" each time a color is set
    +
     -M "command" +         Invoke shell + "command" each time a color is measured
    +   -x x                 -Take - manually entered - XYZ values
    -  

    +  
    -W n|h|x             Override serial @@ -1118,11 +1118,11 @@ n - - none, h = HW, x = Xon/Xoff
    -  -D [level] -           Print debug - diagnostics to stderr
    + + none, h = HW, x = Xon/Xoff

    +  -D [level] +           Print debug + diagnostics to stderr
     inoutfile            @@ -1157,73 +1157,73 @@ n - - Base name for input[.ti1]/output[.ti3] file.
    -

    - Examples
    -
    - dispread -c1 -i92 mycrt
    -

    Comments
    -

    - This is the tool for exercising a display, in order to measure its - color characteristics. The device test colors are defined by the - outfile.ti1 file, while the resulting device+colorimetric and - optional spectral readings are stored in the outfile.ti3 file. - Display calibration curves can be applied during the measurements, - and the curves included in the resulting .ti3 data file using the -kflag. See dispcal for information on how  to - calibrate the display before profiling it. For best results, you - should run this against a neutral grey desktop background, and avoid - having any bright images or windows on the screen at the time you - run it.
    -
    - The -v flag reports progress information.
    -
    - -display: - When running on a UNIX based system that used the X11 Windowing - System, dispread will by default use the $DISPLAY - environment variable to determine which display and screen to read - from. This can be overridden by supplying an X11 display name to the - -display option. Note that - if Xinerama is active, you can't select the screen using $DISPLAY or - -display, you have to select it using the -d parameter.
    -
    - -d: By - default the main display will be the location of the test window. If - the system has more than one display or screen, an alternate - display/screen can be selected with the -d parameter. If you invoke dispread so as to display the - usage information (i.e. "dispread -?" or "dispread --"), then the - discovered displays/screens will be listed. Multiple displays may - not be listed, if they appear as a single display to the operating - system (ie. the multi-display support is hidden in the video card - driver). On UNIX based system that used the X11 Windowing System, - the -d parameter will - override the screen specified by the $DISPLAY or -display parameter.
    -
    - On X11 the inability to access VideoLUTs could be because you are - trying to access a remote display, and the remote display doesn't - support the XF86VidMode extension, or perhaps you are running - multiple monitors using NVidia TwinView, or MergedFB, and trying to - access anything other than the primary monitor. TwinView and - MergedFB don't properly support the XF86VidMode extension for - multiple displays. You can use dispwin -r - to test whether the VideoLUTs are accessible for a particular - display. See also below, on how to select a different display for - VideoLUT access. Also note that dispcal will fail if the Visual - depth doesn't match the VideoLUT depth. Typically the VideoLUTs have - 256 entries per color component, so the Visual generally needs to be - 24 bits, 8 bits per color component.
    -
    - Because of the difficulty cause by TwinView and - MergedFB in X11 based systems, you can optionally specify a separate - display number after the display that is going to be used to present - test patches, for accessing the VideoLUT hardware. This must be + + Base name for input[.ti1]/output[.ti3] file.
    +
    + Examples
    +
    + dispread -c1 -i92 mycrt
    +

    Comments
    +

    + This is the tool for exercising a display, in order to measure its + color characteristics. The device test colors are defined by the + outfile.ti1 file, while the resulting device+colorimetric and + optional spectral readings are stored in the outfile.ti3 file. + Display calibration curves can be applied during the measurements, + and the curves included in the resulting .ti3 data file using the -kflag. See dispcal for information on how  to + calibrate the display before profiling it. For best results, you + should run this against a neutral grey desktop background, and avoid + having any bright images or windows on the screen at the time you + run it.
    +
    + The -v flag reports progress information.
    +
    + -display: + When running on a UNIX based system that used the X11 Windowing + System, dispread will by default use the $DISPLAY + environment variable to determine which display and screen to read + from. This can be overridden by supplying an X11 display name to the + -display option. Note that + if Xinerama is active, you can't select the screen using $DISPLAY or + -display, you have to select it using the -d parameter.
    +
    + -d: By + default the main display will be the location of the test window. If + the system has more than one display or screen, an alternate + display/screen can be selected with the -d parameter. If you invoke dispread so as to display the + usage information (i.e. "dispread -?" or "dispread --"), then the + discovered displays/screens will be listed. Multiple displays may + not be listed, if they appear as a single display to the operating + system (ie. the multi-display support is hidden in the video card + driver). On UNIX based system that used the X11 Windowing System, + the -d parameter will + override the screen specified by the $DISPLAY or -display parameter.
    +
    + On X11 the inability to access VideoLUTs could be because you are + trying to access a remote display, and the remote display doesn't + support the XF86VidMode extension, or perhaps you are running + multiple monitors using NVidia TwinView, or MergedFB, and trying to + access anything other than the primary monitor. TwinView and + MergedFB don't properly support the XF86VidMode extension for + multiple displays. You can use dispwin -r + to test whether the VideoLUTs are accessible for a particular + display. See also below, on how to select a different display for + VideoLUT access. Also note that dispcal will fail if the Visual + depth doesn't match the VideoLUT depth. Typically the VideoLUTs have + 256 entries per color component, so the Visual generally needs to be + 24 bits, 8 bits per color component.
    +
    + Because of the difficulty cause by TwinView and + MergedFB in X11 based systems, you can optionally specify a separate + display number after the display that is going to be used to present + test patches, for accessing the VideoLUT hardware. This must be specified as a single string, e.g. -d @@ -1258,423 +1258,423 @@ n - - 1,2 . Some experimentation may be needed using dispwin on such systems, to discover what - screen has access to the VideoLUT hardware, and which screens the - test patches appear on. You may be able to calibrate one screen, and - then share the calibration with another screen. Profiling can be - done independently to calibration.
    -
    - -dweb or - -dweb:port starts a - standalone web server on your machine, which then allows a local or - remote web browser to display the the color test patches. By default - port 8080 is used, but this - can be overridden by appending a : - and the port number i.e. -dweb:8001. - The URL will be http:// - then name of the machine or its I.P. address followed by a colon and - the port number - e.g something like http://192.168.0.1:8080. If you use the verbose - option (-v) then a likely - URL will be printed once the server is started, or you could run ipconfig (MSWin) or /sbin/ifconfig (Linux or OS X) - and identify an internet address for your machine that way. - JavaScript needs to be enabled in your web browser for this to - work. You may have to modify any firewall to permit port 8080 to be - accessed on your machine.
    -
    - Note that if you use this method of displaying test patches, that - there is no access to the display VideoLUTs and that the colors will - be displayed with 8 bit per component precision, and any - screen-saver or power-saver will not be disabled. You will also be - at the mercy of any color management applied by the web browser, and - may have to carefully review and configure such color management. - See the -o flag for an explanation of - the implications of having no access to the VideoLUTs.
    -
    - -dmadvr - [MSWin only] causes test patches to be displayed using the MadVR - video renderer. Note that will have to start MadTPG before - running dispread, and that while you can adjust the "Test Pattern - Configuration" controls, you should not normally alter the - "Existing Calibration" controls, as dispread will set these - appropriately. See also -V flag.
    -
    - -dcc or -dcc:no - causes test patches to be displayed using and available ChromeCast to - your TV. Use -dcc:? to display a list of ChromeCasts on your - local network. Note that the ChromeCast as a test patch source is - probably the least accurate of your choices, since it - up-samples the test patch and transforms from RGB to YCC and back, - but should be accurate within ± 1 bit. You may have to modify any - firewall to permit port 8081 to be accessed on your machine if it + + 1,2 . Some experimentation may be needed using dispwin on such systems, to discover what + screen has access to the VideoLUT hardware, and which screens the + test patches appear on. You may be able to calibrate one screen, and + then share the calibration with another screen. Profiling can be + done independently to calibration.
    +
    + -dweb or + -dweb:port starts a + standalone web server on your machine, which then allows a local or + remote web browser to display the the color test patches. By default + port 8080 is used, but this + can be overridden by appending a : + and the port number i.e. -dweb:8001. + The URL will be http:// + then name of the machine or its I.P. address followed by a colon and + the port number - e.g something like http://192.168.0.1:8080. If you use the verbose + option (-v) then a likely + URL will be printed once the server is started, or you could run ipconfig (MSWin) or /sbin/ifconfig (Linux or OS X) + and identify an internet address for your machine that way. + JavaScript needs to be enabled in your web browser for this to + work. You may have to modify any firewall to permit port 8080 to be + accessed on your machine.
    +
    + Note that if you use this method of displaying test patches, that + there is no access to the display VideoLUTs and that the colors will + be displayed with 8 bit per component precision, and any + screen-saver or power-saver will not be disabled. You will also be + at the mercy of any color management applied by the web browser, and + may have to carefully review and configure such color management. + See the -o flag for an explanation of + the implications of having no access to the VideoLUTs.
    +
    + -dmadvr + [MSWin only] causes test patches to be displayed using the MadVR + video renderer. Note that will have to start MadTPG before + running dispread, and that while you can adjust the "Test Pattern + Configuration" controls, you should not normally alter the + "Existing Calibration" controls, as dispread will set these + appropriately. See also -V flag.
    +
    + -dcc or -dcc:no + causes test patches to be displayed using and available ChromeCast to + your TV. Use -dcc:? to display a list of ChromeCasts on your + local network. Note that the ChromeCast as a test patch source is + probably the least accurate of your choices, since it + up-samples the test patch and transforms from RGB to YCC and back, + but should be accurate within ± 1 bit. You may have to modify any + firewall to permit port 8081 to be accessed on your machine if it falls back to the Default receiver (see installation - - instructions for your platform).
    -
    - -c: The - instrument is assumed to communicate through a USB or serial - communication port, and the port can be selected with the -c - option, if the instrument is not connected to the first port. If you - invoke dispread so as to - display the usage information (i.e. "dispread -?" or "dispread --"), - then the discovered USB and serial ports will be listed. On - UNIX/Linux, a list of all possible serial ports are shown, but not - all of them may actually be present on your system.
    -
    - The -p flag - allows measuring in telephoto mode, using instruments that support - this mode, e.g. the ColorMunki. Telephoto mode is one for taking - emissive measurements from a distance (ie. telespectometer, - tele-colorimeter) mode, and typically would be used for measuring - projector type displays. If a device does not support a specific - telephoto mode, then the normal emissive mode may be suitable for - measuring projectors.
    -
    - The -y flag - allows setting the Display Type. The selection typically determines - two aspects of of the instrument operation: 1) It may set the measuring mode - to suite refresh or non-refresh displays. - Typically only LCD (Liquid Crystal) displays have a non-refresh - nature. 2) It may select an - instrument calibration matrix suitable for a particular display - type. The selections available depends on the type and model of - instrument, and a list of the options for the discovered instruments - will be shown in the usage - information. For more details on what particular instruments support - and how this works, see Operation of - particular instruments. 3) Any installed CCSS files - (if applicable), or CCMX files. These files are typically created - using ccxxmake, and installed using oeminst. The default and Base Calibration - types will be indicated in the usage.
    -
    - -s: By - default only the colorimetric information (XYZ value) will be saved, - but for instruments that support spectral readings (such as the - Gretag Spectrolino), the -s option will save the spectral - readings to the .ti3 file as well.
    -
    - -k: If a - display video lookup table calibration .cal file is provided, it will - be loaded into the display VideoLUTs - while the measurements are being taken, thereby being applied to the - measurement values, and the calibration will also included in the - resulting .ti3 data file, so that colprof - can include it as a vcgt - tag in the resulting profile. This is the normal way to profile a calibrated display. The - calibration file has usually been created using dispcal. If the calibration file indicates - that the displays VideoLUTs are not accessible, or if they prove not - to be accessible, then dispread will switch to -K mode (see below). If a - calibration file is not supplied using -k or -K, - then the display will be measured in whatever calibration state it - is in, and no calibration information is saved to the resulting .ti3 - file.
    - If the calibration file provided created using video range encoding - (dispcal -E), then the -E option in dispread will be - triggered automatically.
    - NOTE that the calibration is - loaded into the display hardware just before the instrument starts - measurement, after the test window first appears.
    -
    - -K: If a - display video lookup table calibration .cal file is provided, it will - be applied to the test values for each measurement, and also - included in the resulting .ti3 data file, so that colprof can include it as a vcgt tag in the resulting - profile. This is NOT - normally the best way to profile a calibrated display, since the - frame buffer may have lower precision than the VideoLUTs output - values. This is the way calibration should be applied if MadVR is - being used to display the test patches. If a calibration file is not - supplied using -k or -K, then the display will be - measured in whatever calibration state it is in, and no calibration - information is saved to the resulting .ti3 file.
    - If the calibration file provided created using video range encoding - (dispcal -E), then the -E option in dispread will be - triggered automatically.
    -
    - -V: [MSWin] If using MadVR to display test - patches, then enable Color Managenent (3dLut). This would be used - for verification measurement.
    -
    - The -P - parameter allows you to position and size the test patch window. By - default it is places in the center of the screen, and sized - appropriately for the type of instrument, or 10% of the width of the - display if the display size is unknown. The ho and vo values govern the horizontal - and vertical offset respectively. A value of 0.0 positions the - window to the far left or top of the screen, a value of 0.5 - positions it in the center of the screen (the default), and 1.0 - positions it to the far right or bottom of the screen. If three - parameters are provided, then the ss - parameter is a scale factor for the test window size. A value of 0.5 - for instance, would produce a half sized window. A value of 2.0 will - produce a double size window. If four parameters are provided, then - the last two set independent horizontal and vertical scaling - factors. Note that the ho,vo,ss or ho,vo,hs,vs numbers must be - specified as a single string (no space between the numbers and the - comma). For example, to create a double sized test window at the top - right of the screen, use -P 1,0,2 - . To create a window twice as wide as high: -P 1,0,2,1.
    -
    - The -F - flag causes the while screen behind the test window to be masked - with black. This can aid black accuracy when measuring CRT displays - or projectors.
    -
    - The -E - flag causes the test values to be scaled to the Video RGB encoding - range of 16/255 to 235/255. If the calibration file provided using - the -k or -K flag was created using video range - encoding, then this option will be triggered automatically. This - will also set quantization of 8 bits (see -Z flag below). If your - video connection is better than 8 bits (ie. 10 or 12 bits), then you - may wish to raise this default.
    -
    - -Z nbits Normally the target device values - are floating point numbers that may get rounded and quantized in the - process of printing them or reproducing them on the display device. - If some of this quantization can be accounted for, it may improve - the accuracy of the resulting profile, and the Q parameter allows this - quantization to be specified. The parameter is the number of binary - digits (bits) that the device values should be quantized to. An idea - of the number of bits of precision that makes its way to your - display can be obtained by using dispcal - -R If Video encoding is selected (see -E flag above), then 8 - bits is selected by default. On systems using an VGA connection or - Display Port with a graphics card with VideoLUT entries with greater - than 8 bits depth, or if using the MadVR rendered with dithering, - then a higher bit depth is typically possible.
    -
    - -n: When - running on a UNIX based system that used the X11 Windowing System, dispread - normally selects the override redirect so that the test window will - appear above any other windows on the display. On some systems this - can interfere with window manager operation, and the -n - option turns this behaviour off.
    -
    - The -J - option runs through the black and sensor relative calibration - routines for the Xrite DTP92 and DTP94 instrument, the black level - calibration for the Eye-One Display 1, and a CRT frequency - calibration for the Eye-One Display 2. For the black calibration the - instrument should be placed on an opaque, black surface, and any - stray light should be avoided by placing something opaque over the - instrument. If a Spectrolino is being used, then a white and black - calibration will always be performed before the instrument can be - placed on the display, unless the -N flag is used. - Generally it is not necessary to do a calibration every time an - instrument is used, just now and again. There is no point in - doing  a CRT frequency calibration, as this will be done - automatically at the commencement of patch reading.
    -
    - -N Any - instrument that requires regular calibration will ask for - calibration on initial start-up. Sometimes this can be awkward if - the instrument is being mounted in some sort of measuring jig, or - annoying if several sets of readings are being taken in quick - succession. The -N - suppresses this initial calibration if a valid and not timed out - previous calibration is recorded in the instrument or on the host - computer. It is advisable to only use this option on the second and - subsequent measurements in a single session.
    -
    - The -H - option turns on high resolution spectral mode, if the instrument - supports it. See Operation of particular - instruments for more details. This may give better accuracy - for display measurements.
    -
    - The -w flag disables the normalisation of - the white patch value to 100.0, resulting in values that are in - cd/m^2. This is mainly for diagnostic purposes.
    -
    - The -X file.ccmx option reads - a Colorimeter Correction Matrix - from the given file, and applies it to the colorimeter instruments - readings. This can improve a colorimeters accuracy for a particular - type of display. A list of contributed ccmx files is here.
    -
    - The -X file.ccss option reads - a Colorimeter Calibration - Spectral Sample from the given file, and uses it to set the - colorimeter instruments calibration. This will only work with - colorimeters that rely on sensor spectral sensitivity calibration - information (ie. the X-Rite i1d3, - or the DataColor Spyder4 & - Spyder 5).This can improve a colorimeters accuracy for a - particular type of display.
    -
    - The -Q flag allows specifying a tristimulus - observer, and is used to compute PCS (Profile Connection Space) - tristimulus values from spectral readings or using a colorimeter - that has CCSS capability. The following choices are available:
    -   1931_2 selects the standard CIE 1931 2 degree - observer. The default.
    -   1964_10 selects the standard CIE 1964 10 degree - observer.
    -   1955_2 selects the Stiles and Birch 1955 2 degree - observer
    -   1978_2 selects the Judd and Voss 1978 2 degree - observer
    -   shaw selects the Shaw and Fairchild 1997 2 degree - observer
    -   1964_10c selects a version of the CIE 1964 10 degree - observer that has been adjusted using a 3x3 matrix to better agree - with the 1931 2 degree observer.
    -
    - NOTE that if you select - anything other than the default 1931 2 degree observer, that the Y - values will not be cd/m^2, due to the Y curve not being the CIE 1924 - photopic V(λ) luminosity function.
    -
    - The -I b|w options invoke - instrument black level, and display white level compensation - (respectively). Instrument black level drift compensation attempts - to combat instrument black calibration drift by using a display - black test patch as a reference. If an instrument is not - acclimatised sufficiently to the measurement conditions, changes in - temperature can affect the black readings. Display white level drift - compensation attempts to combat changes in display brightness as it - warms up by measuring a white patch every so often, and using it to - normalise all the other readings. If just instrument black drift - compensation is needed, use -Ib. - If just display white level compensation is needed, use -Iw. If both are needed, use -Ibw or -Iwb.
    -
    - The -Y R:rate - options overrides calibration of the instrument refresh rate. This - may be useful if the instrument supports this function and the - refresh rate cannot be accurately calibrated from the display - itself.
    -  
    -
    The -Y A - option uses a non-adaptive integration time emission measurement - mode, if the instrument supports it, such as the Eye-One Pro, - ColorMunki, i1d3 and K10. By default an adaptive integration time - measurement mode will be used for emission measurements, but some - instruments support a fixed integration time mode that can be used - with display devices. This may give faster measurement times, but - may also give less accurate low level readings.
    -
    - The -Y p - option skips asking the user to place the instrument on the display. - Normally a grey patch is displayed, and then the user is asked to - confirm that the instrument is in place, so that readings can - commence. This flag disables that check. This may be useful in - automating certain operations.
    -
    -
    The -C - "command" option allows a - method of relaying each test value to some other display than that - on the system running dispread (for instance, a photo frame, PDA - screen etc.), by causing the given command to be invoked to the - shell, with six arguments. The first three arguments are the RGB - test color as integers in the range 0 to 255, the second three - parameters are the RGB test color as floating point numbers in the - range 0.0 to 1.0. The script or tool should relay the given color to - the screen in some manner (e.g. by generating a raster file of the - given color and sending it to the display being profiled), before - returning. Note that a test window will also be created on the - system running dispread.
    -
    - The -M "command" option allows a - method of gathering each test value from some external source, such - as an instrument that is not directly supported by Argyll. The given - command is involked to the shell, with six arguments. The first - three arguments are the RGB test color as integers in the range 0 to - 255, the second three parameters are the RGB test color as floating - point numbers in the range 0.0 to 1.0. The script or tool should - create a file called "command.meas" - that contains the XYZ values for the given RGB (or measured from the - test window) in cd/m^2 as three numbers separated by spaces, before - returning. If the command returns a non-zero return value, dispread - will abort. Note that a test window will also be created on the - system running dispread.
    -
    - The -x flag causes dispread to expect - values to be manually entered for each reading, rather than using an - instrument to do the measurements.  This mode is ideal if your - instrument is not supported by Argyll. XYZ values should be entered. - It is possible to navigate about the test values being measured, so - as to do them in any order, as well as re-do values, in case of any - mistakes.
    -
    - The -W n|h|x - parameter overrides the default serial communications flow control - setting. The value n turns - all flow control off, h - sets hardware handshaking, and x - sets Xon/Xoff handshaking. This commend may be useful in workaround - serial communications issues with some systems and cables.
    -
    - The -D flag causes communications and other - instrument diagnostics to be printed to stdout. A level can be set - between 1 .. 9, that may give progressively more verbose - information, depending on the instrument. This can be useful in - tracking down why an instrument can't connect.
    -
    - The final parameter on the command line is the - base filename for the .ti1 - input file, and the .ti3 - output file. dispread will add the .ti1 and .ti3 extensions - automatically.
    -
    - NOTE that on an X11 system, - if the environment variable ARGYLL_IGNORE_XRANDR1_2 - is set (ie. set it to "yes"), then the presence of the XRandR 1.2 - extension will be ignored, and other extensions such as Xinerama and - XF86VidMode extension will be used. This may be a way to work around - buggy XRandR 1.2 implementations.
    -
    -

    - If a large number of patches is being read, the screensaver on many - systems can interfere with the operation of dispread. It is - therefore advisable in these cases to manually turn off the - screensaver before commencing the measurements.
    -
    - If communications break down with a USB connected instrument, you - may have to unplug it, and plug it in again to recover.
    -
    - Some systems (Apple OSX in particular) have a special set of user - interface controls ("Universal Access") that allows altering the - display in ways designed to assist visually impaired users, by - increasing contrast etc. This will interfere badly with any attempts - to calibrate or profile such a system, and must be turned off in - order to do so. Note that certain magic keyboard sequences can turn - this on by accident.
    -
    -
    -
    - - + + instructions for your platform).
    +
    + -c: The + instrument is assumed to communicate through a USB or serial + communication port, and the port can be selected with the -c + option, if the instrument is not connected to the first port. If you + invoke dispread so as to + display the usage information (i.e. "dispread -?" or "dispread --"), + then the discovered USB and serial ports will be listed. On + UNIX/Linux, a list of all possible serial ports are shown, but not + all of them may actually be present on your system.
    +
    + The -p flag + allows measuring in telephoto mode, using instruments that support + this mode, e.g. the ColorMunki. Telephoto mode is one for taking + emissive measurements from a distance (ie. telespectometer, + tele-colorimeter) mode, and typically would be used for measuring + projector type displays. If a device does not support a specific + telephoto mode, then the normal emissive mode may be suitable for + measuring projectors.
    +
    + The -y flag + allows setting the Display Type. The selection typically determines + two aspects of of the instrument operation: 1) It may set the measuring mode + to suite refresh or non-refresh displays. + Typically only LCD (Liquid Crystal) displays have a non-refresh + nature. 2) It may select an + instrument calibration matrix suitable for a particular display + type. The selections available depends on the type and model of + instrument, and a list of the options for the discovered instruments + will be shown in the usage + information. For more details on what particular instruments support + and how this works, see Operation of + particular instruments. 3) Any installed CCSS files + (if applicable), or CCMX files. These files are typically created + using ccxxmake, and installed using oeminst. The default and Base Calibration + types will be indicated in the usage.
    +
    + -s: By + default only the colorimetric information (XYZ value) will be saved, + but for instruments that support spectral readings (such as the + Gretag Spectrolino), the -s option will save the spectral + readings to the .ti3 file as well.
    +
    + -k: If a + display video lookup table calibration .cal file is provided, it will + be loaded into the display VideoLUTs + while the measurements are being taken, thereby being applied to the + measurement values, and the calibration will also included in the + resulting .ti3 data file, so that colprof + can include it as a vcgt + tag in the resulting profile. This is the normal way to profile a calibrated display. The + calibration file has usually been created using dispcal. If the calibration file indicates + that the displays VideoLUTs are not accessible, or if they prove not + to be accessible, then dispread will switch to -K mode (see below). If a + calibration file is not supplied using -k or -K, + then the display will be measured in whatever calibration state it + is in, and no calibration information is saved to the resulting .ti3 + file.
    + If the calibration file provided created using video range encoding + (dispcal -E), then the -E option in dispread will be + triggered automatically.
    + NOTE that the calibration is + loaded into the display hardware just before the instrument starts + measurement, after the test window first appears.
    +
    + -K: If a + display video lookup table calibration .cal file is provided, it will + be applied to the test values for each measurement, and also + included in the resulting .ti3 data file, so that colprof can include it as a vcgt tag in the resulting + profile. This is NOT + normally the best way to profile a calibrated display, since the + frame buffer may have lower precision than the VideoLUTs output + values. This is the way calibration should be applied if MadVR is + being used to display the test patches. If a calibration file is not + supplied using -k or -K, then the display will be + measured in whatever calibration state it is in, and no calibration + information is saved to the resulting .ti3 file.
    + If the calibration file provided created using video range encoding + (dispcal -E), then the -E option in dispread will be + triggered automatically.
    +
    + -V: [MSWin] If using MadVR to display test + patches, then enable Color Managenent (3dLut). This would be used + for verification measurement.
    +
    + The -P + parameter allows you to position and size the test patch window. By + default it is places in the center of the screen, and sized + appropriately for the type of instrument, or 10% of the width of the + display if the display size is unknown. The ho and vo values govern the horizontal + and vertical offset respectively. A value of 0.0 positions the + window to the far left or top of the screen, a value of 0.5 + positions it in the center of the screen (the default), and 1.0 + positions it to the far right or bottom of the screen. If three + parameters are provided, then the ss + parameter is a scale factor for the test window size. A value of 0.5 + for instance, would produce a half sized window. A value of 2.0 will + produce a double size window. If four parameters are provided, then + the last two set independent horizontal and vertical scaling + factors. Note that the ho,vo,ss or ho,vo,hs,vs numbers must be + specified as a single string (no space between the numbers and the + comma). For example, to create a double sized test window at the top + right of the screen, use -P 1,0,2 + . To create a window twice as wide as high: -P 1,0,2,1.
    +
    + The -F + flag causes the while screen behind the test window to be masked + with black. This can aid black accuracy when measuring CRT displays + or projectors.
    +
    + The -E + flag causes the test values to be scaled to the Video RGB encoding + range of 16/255 to 235/255. If the calibration file provided using + the -k or -K flag was created using video range + encoding, then this option will be triggered automatically. This + will also set quantization of 8 bits (see -Z flag below). If your + video connection is better than 8 bits (ie. 10 or 12 bits), then you + may wish to raise this default.
    +
    + -Z nbits Normally the target device values + are floating point numbers that may get rounded and quantized in the + process of printing them or reproducing them on the display device. + If some of this quantization can be accounted for, it may improve + the accuracy of the resulting profile, and the Q parameter allows this + quantization to be specified. The parameter is the number of binary + digits (bits) that the device values should be quantized to. An idea + of the number of bits of precision that makes its way to your + display can be obtained by using dispcal + -R If Video encoding is selected (see -E flag above), then 8 + bits is selected by default. On systems using an VGA connection or + Display Port with a graphics card with VideoLUT entries with greater + than 8 bits depth, or if using the MadVR rendered with dithering, + then a higher bit depth is typically possible.
    +
    + -n: When + running on a UNIX based system that used the X11 Windowing System, dispread + normally selects the override redirect so that the test window will + appear above any other windows on the display. On some systems this + can interfere with window manager operation, and the -n + option turns this behaviour off.
    +
    + The -J + option runs through the black and sensor relative calibration + routines for the Xrite DTP92 and DTP94 instrument, the black level + calibration for the Eye-One Display 1, and a CRT frequency + calibration for the Eye-One Display 2. For the black calibration the + instrument should be placed on an opaque, black surface, and any + stray light should be avoided by placing something opaque over the + instrument. If a Spectrolino is being used, then a white and black + calibration will always be performed before the instrument can be + placed on the display, unless the -N flag is used. + Generally it is not necessary to do a calibration every time an + instrument is used, just now and again. There is no point in + doing  a CRT frequency calibration, as this will be done + automatically at the commencement of patch reading.
    +
    + -N Any + instrument that requires regular calibration will ask for + calibration on initial start-up. Sometimes this can be awkward if + the instrument is being mounted in some sort of measuring jig, or + annoying if several sets of readings are being taken in quick + succession. The -N + suppresses this initial calibration if a valid and not timed out + previous calibration is recorded in the instrument or on the host + computer. It is advisable to only use this option on the second and + subsequent measurements in a single session.
    +
    + The -H + option turns on high resolution spectral mode, if the instrument + supports it. See Operation of particular + instruments for more details. This may give better accuracy + for display measurements.
    +
    + The -w flag disables the normalisation of + the white patch value to 100.0, resulting in values that are in + cd/m^2. This is mainly for diagnostic purposes.
    +
    + The -X file.ccmx option reads + a Colorimeter Correction Matrix + from the given file, and applies it to the colorimeter instruments + readings. This can improve a colorimeters accuracy for a particular + type of display. A list of contributed ccmx files is here.
    +
    + The -X file.ccss option reads + a Colorimeter Calibration + Spectral Sample from the given file, and uses it to set the + colorimeter instruments calibration. This will only work with + colorimeters that rely on sensor spectral sensitivity calibration + information (ie. the X-Rite i1d3, + or the DataColor Spyder4 & + Spyder 5).This can improve a colorimeters accuracy for a + particular type of display.
    +
    + The -Q flag allows specifying a tristimulus + observer, and is used to compute PCS (Profile Connection Space) + tristimulus values from spectral readings or using a colorimeter + that has CCSS capability. The following choices are available:
    +   1931_2 selects the standard CIE 1931 2 degree + observer. The default.
    +   1964_10 selects the standard CIE 1964 10 degree + observer.
    +   1955_2 selects the Stiles and Birch 1955 2 degree + observer
    +   1978_2 selects the Judd and Voss 1978 2 degree + observer
    +   shaw selects the Shaw and Fairchild 1997 2 degree + observer
    +   1964_10c selects a version of the CIE 1964 10 degree + observer that has been adjusted using a 3x3 matrix to better agree + with the 1931 2 degree observer.
    +
    + NOTE that if you select + anything other than the default 1931 2 degree observer, that the Y + values will not be cd/m^2, due to the Y curve not being the CIE 1924 + photopic V(λ) luminosity function.
    +
    + The -I b|w options invoke + instrument black level, and display white level compensation + (respectively). Instrument black level drift compensation attempts + to combat instrument black calibration drift by using a display + black test patch as a reference. If an instrument is not + acclimatised sufficiently to the measurement conditions, changes in + temperature can affect the black readings. Display white level drift + compensation attempts to combat changes in display brightness as it + warms up by measuring a white patch every so often, and using it to + normalise all the other readings. If just instrument black drift + compensation is needed, use -Ib. + If just display white level compensation is needed, use -Iw. If both are needed, use -Ibw or -Iwb.
    +
    + The -Y R:rate + options overrides calibration of the instrument refresh rate. This + may be useful if the instrument supports this function and the + refresh rate cannot be accurately calibrated from the display + itself.
    +  
    +
    The -Y A + option uses a non-adaptive integration time emission measurement + mode, if the instrument supports it, such as the Eye-One Pro, + ColorMunki, i1d3 and K10. By default an adaptive integration time + measurement mode will be used for emission measurements, but some + instruments support a fixed integration time mode that can be used + with display devices. This may give faster measurement times, but + may also give less accurate low level readings.
    +
    + The -Y p + option skips asking the user to place the instrument on the display. + Normally a grey patch is displayed, and then the user is asked to + confirm that the instrument is in place, so that readings can + commence. This flag disables that check. This may be useful in + automating certain operations.
    +
    +
    The -C + "command" option allows a + method of relaying each test value to some other display than that + on the system running dispread (for instance, a photo frame, PDA + screen etc.), by causing the given command to be invoked to the + shell, with six arguments. The first three arguments are the RGB + test color as integers in the range 0 to 255, the second three + parameters are the RGB test color as floating point numbers in the + range 0.0 to 1.0. The script or tool should relay the given color to + the screen in some manner (e.g. by generating a raster file of the + given color and sending it to the display being profiled), before + returning. Note that a test window will also be created on the + system running dispread.
    +
    + The -M "command" option allows a + method of gathering each test value from some external source, such + as an instrument that is not directly supported by Argyll. The given + command is involked to the shell, with six arguments. The first + three arguments are the RGB test color as integers in the range 0 to + 255, the second three parameters are the RGB test color as floating + point numbers in the range 0.0 to 1.0. The script or tool should + create a file called "command.meas" + that contains the XYZ values for the given RGB (or measured from the + test window) in cd/m^2 as three numbers separated by spaces, before + returning. If the command returns a non-zero return value, dispread + will abort. Note that a test window will also be created on the + system running dispread.
    +
    + The -x flag causes dispread to expect + values to be manually entered for each reading, rather than using an + instrument to do the measurements.  This mode is ideal if your + instrument is not supported by Argyll. XYZ values should be entered. + It is possible to navigate about the test values being measured, so + as to do them in any order, as well as re-do values, in case of any + mistakes.
    +
    + The -W n|h|x + parameter overrides the default serial communications flow control + setting. The value n turns + all flow control off, h + sets hardware handshaking, and x + sets Xon/Xoff handshaking. This commend may be useful in workaround + serial communications issues with some systems and cables.
    +
    + The -D flag causes communications and other + instrument diagnostics to be printed to stdout. A level can be set + between 1 .. 9, that may give progressively more verbose + information, depending on the instrument. This can be useful in + tracking down why an instrument can't connect.
    +
    + The final parameter on the command line is the + base filename for the .ti1 + input file, and the .ti3 + output file. dispread will add the .ti1 and .ti3 extensions + automatically.
    +
    + NOTE that on an X11 system, + if the environment variable ARGYLL_IGNORE_XRANDR1_2 + is set (ie. set it to "yes"), then the presence of the XRandR 1.2 + extension will be ignored, and other extensions such as Xinerama and + XF86VidMode extension will be used. This may be a way to work around + buggy XRandR 1.2 implementations.
    +
    +

    + If a large number of patches is being read, the screensaver on many + systems can interfere with the operation of dispread. It is + therefore advisable in these cases to manually turn off the + screensaver before commencing the measurements.
    +
    + If communications break down with a USB connected instrument, you + may have to unplug it, and plug it in again to recover.
    +
    + Some systems (Apple OSX in particular) have a special set of user + interface controls ("Universal Access") that allows altering the + display in ways designed to assist visually impaired users, by + increasing contrast etc. This will interfere badly with any attempts + to calibrate or profile such a system, and must be turned off in + order to do so. Note that certain magic keyboard sequences can turn + this on by accident.
    +
    +
    +
    + + diff --git a/doc/dispwin.html b/doc/dispwin.html index 05db989..dac6b8e 100644 --- a/doc/dispwin.html +++ b/doc/dispwin.html @@ -1,38 +1,38 @@ - - - - dispwin - - - - -

    spectro/dispwin

    -

    Summary

    - This tool has several different but related functions. When given as - a file argument an ICC profile containing vcgt "gamma" curves, or an - Argyll video calibration .cal file, it will load that calibration - into the chosen display. It can also install or uninstall a profile - in the system for the chosen display, or set the display calibration - to that in the currently installed system profile. By default it - displays a test window the same as that used by dispcal and - dispread, to test this functionality. It can also be used to test - the ability to load video card LUT curves to each display, and to - test how the console Bell will sound when used with some instruments - (ie. Eye-One Pro).
    -
    - [Note that in OS X 10.7 Lion, changes to the default system profile - permissions mean that you can't set a calibration persistently when - the default system profile is being used, unless you run as root - (ie. use sudo). Note that you do not - need to run as root to install a user profile (-Su, the default - install type.)]
    -

    Usage

    - dispwin - [options] [calfile]
    -  -v + + + dispwin + + + + +

    spectro/dispwin

    +

    Summary

    + This tool has several different but related functions. When given as + a file argument an ICC profile containing vcgt "gamma" curves, or an + Argyll video calibration .cal file, it will load that calibration + into the chosen display. It can also install or uninstall a profile + in the system for the chosen display, or set the display calibration + to that in the currently installed system profile. By default it + displays a test window the same as that used by dispcal and + dispread, to test this functionality. It can also be used to test + the ability to load video card LUT curves to each display, and to + test how the console Bell will sound when used with some instruments + (ie. Eye-One Pro).
    +
    + [Note that in OS X 10.7 Lion, changes to the default system profile + permissions mean that you can't set a calibration persistently when + the default system profile is being used, unless you run as root + (ie. use sudo). Note that you do not + need to run as root to install a user profile (-Su, the default + install type.)]
    +

    Usage

    + dispwin + [options] [calfile]
    +  -v                   Verbose @@ -51,18 +51,18 @@ Verbose - - mode
    -
     -display displayname [X11 only] Choose X11 display name
    -
     -d n[,m] -             - [X11 only] Choose the - display from the following list (default 1),
    + + mode
    +
     -display displayname [X11 only] Choose X11 display name
    +
     -d n[,m] +             + [X11 only] Choose the + display from the following list (default 1),
                          and optionally @@ -81,9 +81,9 @@ optionally - - choose a different display m for Video LUT access.
    -
     -d n                 [Not X11] @@ -102,9 +102,9 @@ X11] - - Choose the display from the following list (default 1)
    -
      +
     -dweb[:port]         @@ -119,22 +119,22 @@ X11] - - Display via a web server at port (default 8080)
    -  -dmadvr -              - [MSWin] Display via MadVR Video Renderer
    + + Display via a web server at port (default 8080)
    +  -dmadvr +              + [MSWin] Display via MadVR Video Renderer
     -dcc[:n]             - - Display via n'th ChromeCast (default 1, ? for - list)
    -  -P - ho,vo,ss[,vs]     Position test window - and scale it
    + + Display via n'th ChromeCast (default 1, ? for + list)
    +  -P + ho,vo,ss[,vs]     Position test window + and scale it
                          ho,vi: 0.0 @@ -153,9 +153,9 @@ ho,vi: - - = left/top, 0.5 = center, 1.0 = right/bottom etc.
    + + = left/top, 0.5 = center, 1.0 = right/bottom etc.
                          ss: 0.5 @@ -174,8 +174,8 @@ ss: - - = half, 1.0 = normal, 2.0 = double etc.
    + + = half, 1.0 = normal, 2.0 = double etc.
                          @@ -188,10 +188,10 @@ ss: - - ss,vs: = optional horizontal, vertical scale.
    -  
    -F + + ss,vs: = optional horizontal, vertical scale.
    +  
    -F                   Fill whole @@ -210,10 +210,10 @@ whole - - screen with black background
    -  -E + + screen with black background
    +  -E                   @@ -221,25 +221,25 @@ whole - - Video - encode output as (16-235)/255 "TV" levels
    -  -i -              -      Run forever with random values
    -  -G filename -          Display RGB - colors from CGATS file
    -  
    -m -              -      Manually step through colors
    -  Video + encode output as (16-235)/255 "TV" levels
    +  
    -i +              +      Run forever with random values
    +  -G filename +          Display RGB + colors from CGATS file
    +  
    -m +              +      Manually step through colors
    +  -r                   Test just @@ -258,10 +258,10 @@ just - - video LUT loading & Beeps
    -
     -n + + video LUT loading & Beeps
    +
     -n                   Test native @@ -280,8 +280,8 @@ native - - display values (rather than through Video LUT  and C.M.)
    + + display values (rather than through Video LUT  and C.M.)
     -s filename.cal      Save the @@ -300,10 +300,10 @@ the - - currently loaded Video LUT to 'filename'
    -
     -c + + currently loaded Video LUT to 'filename'
    +
     -c                   Load a @@ -322,11 +322,11 @@ a - - linear display calibration (clear calibration)
    -
     -V + + linear display calibration (clear calibration)
    +
     -V                   Verify that @@ -345,10 +345,10 @@ that - - calfile/profile cal. is currently loaded in LUT
    -
     -I + + calfile/profile cal. is currently loaded in LUT
    +
     -I                   @@ -365,11 +365,11 @@ that - - Install profile for display and use it's calibration
    -
     -U + + Install profile for display and use it's calibration
    +
     -U                   @@ -386,9 +386,9 @@ that - - Un-install profile for display
    + +
    Un-install profile for display
     -S d                 Specify the @@ -407,8 +407,8 @@ the - - install/uninstall scope for OS X [nlu] or Vista [lu]
    + + install/uninstall scope for OS X [nlu] or Vista [lu]
                          d is @@ -427,11 +427,11 @@ is - - one of: n = network, l = local system, u = user (default)
    -
     -L + + one of: n = network, l = local system, u = user (default)
    +
     -L                   @@ -448,11 +448,11 @@ is - - Load installed profiles cal. into Video LUT
    -
     -X + + Load installed profiles cal. into Video LUT
    +
     -X                   @@ -469,11 +469,11 @@ is - - [X11 only] Run in daemon - loader mode for given X11 server
    -
     X11 only] Run in daemon + loader mode for given X11 server
    +
     -D [level]           Print debug @@ -492,14 +492,14 @@ debug - - diagnostics to stderr
    -  
    calfile
    +  
    calfile              Load display @@ -518,60 +518,60 @@ display - - calibration (.cal or .icm) into - LUT, and exit.
    -
    -

    Comments
    -

    - The -v flag makes the program more - verbose..
    -
    - display: - When running on a UNIX based system that used the X11 Windowing - System, dispwin will by default use the $DISPLAY environment - variable to determine which display and screen to read from. This - can be overridden by supplying an X11 display name to the -display option. Note that if - Xinerama is active, you can't select the screen using $DISPLAY or - -display, you have to select it using the -d parameter.
    -
    - -d: By - default the location of the test window will be the main display. If - the system has more than one display or screen, an alternate - display/screen can be selected with the -d parameter. If you invoke dispwin so as to display the - usage information (i.e. "dispcal -?" or "dispcal --"), then the - discovered displays/screens will be listed. Multiple displays may - not be listed if they appear as a single display to the operating - system (ie. the multi-display support is hidden in the video card - driver). On UNIX based system that used the X11 Windowing System, - the -d parameter will - override the screen specified by the $DISPLAY or -display parameter.
    -
    - Note that if VideoLUTs for a - display are not accessible (i.e. no hardware calibration - capability), dispwin will - will issue a warning or fail when it attempts to access them.
    -
    - On X11 the inability to access VideoLUTs could be because you are - trying to access a remote display, and the remote display doesn't - support the XF86VidMode extension, or perhaps you are running - multiple monitors using NVidia TwinView, or MergedFB, and trying to - access anything other than the primary monitor. TwinView and - MergedFB don't properly support the XF86VidMode extension for - multiple displays. You can use dispwin -r - to test whether the VideoLUTs are accessible for a particular - display. See also below, on how to select a different display for - VideoLUT access. Also note that dispcal will fail if the Visual - depth doesn't match the VideoLUT depth. Typically the VideoLUTs have - 256 entries per color component, so the Visual generally needs to be - 24 bits, 8 bits per color component.
    -
    + + calibration (.cal or .icm) into + LUT, and exit.

    +
    +

    Comments
    +

    + The -v flag makes the program more + verbose..
    +
    + display: + When running on a UNIX based system that used the X11 Windowing + System, dispwin will by default use the $DISPLAY environment + variable to determine which display and screen to read from. This + can be overridden by supplying an X11 display name to the -display option. Note that if + Xinerama is active, you can't select the screen using $DISPLAY or + -display, you have to select it using the -d parameter.
    +
    + -d: By + default the location of the test window will be the main display. If + the system has more than one display or screen, an alternate + display/screen can be selected with the -d parameter. If you invoke dispwin so as to display the + usage information (i.e. "dispcal -?" or "dispcal --"), then the + discovered displays/screens will be listed. Multiple displays may + not be listed if they appear as a single display to the operating + system (ie. the multi-display support is hidden in the video card + driver). On UNIX based system that used the X11 Windowing System, + the -d parameter will + override the screen specified by the $DISPLAY or -display parameter.
    +
    + Note that if VideoLUTs for a + display are not accessible (i.e. no hardware calibration + capability), dispwin will + will issue a warning or fail when it attempts to access them.
    +
    + On X11 the inability to access VideoLUTs could be because you are + trying to access a remote display, and the remote display doesn't + support the XF86VidMode extension, or perhaps you are running + multiple monitors using NVidia TwinView, or MergedFB, and trying to + access anything other than the primary monitor. TwinView and + MergedFB don't properly support the XF86VidMode extension for + multiple displays. You can use dispwin -r + to test whether the VideoLUTs are accessible for a particular + display. See also below, on how to select a different display for + VideoLUT access. Also note that dispcal will fail if the Visual + depth doesn't match the VideoLUT depth. Typically the VideoLUTs have + 256 entries per color component, so the Visual generally needs to be + 24 bits, 8 bits per color component.
    +
    -d n[,m]Because of the @@ -590,257 +590,257 @@ the - - difficulty cause by TwinView and MergedFB in X11 based systems, you - can optionally specify a separate display number after the display - that is going to be used to present test patches, for accessing the - VideoLUT hardware. This must be specified as a single string, e.g. -d 1,2 . Some experimentation - may be needed on such systems, to discover what screen has access to - the VideoLUT hardware, and which screens the test patches appear on. - You may be able to calibrate one screen, and then share the - calibration with another screen. Profiling can be done independently - to calibration.
    -
    - -dweb or - -dweb:port starts a - standalone web server on your machine, which then allows a local or - remote web browser to display the the color test patches. By default - port 8080 is used, but this - can be overridden by appending a : - and the port number i.e. -dweb:8001. - The URL will be http:// - then name of the machine or its I.P. address followed by a colon and - the port number - e.g something like http://192.168.0.1:8080. If you use the verbose - option (-v) then a likely - URL will be printed once the server is started, or you could run ipconfig (MSWin) or /sbin/ifconfig (Linux or OS X) - and identify an internet address for your machine that way. JavaScript - needs to be enabled in your web browser for this to work. You may - have to modify any firewall to permit port 8080 to be accessed on - your machine.
    -
    - Note that if you use this method of accessing a display, that there - is no access to the display Video Lookup tables, and that any - operation that depends on accessing the VideoLUTs will either - generate a warning or fail.
    -
    - -dmadvr - [MSWin only] causes test patches to be displayed using the MadVR - video renderer. Note that will have to start MadTPG before - running dispread, and that while you can adjust the "Test Pattern - Configuration" controls, you should not normally alter the - "Existing Calibration" controls, as dispread will set these - appropriately. See -n flag.
    -
    - -dcc or -dcc:no - causes test patches to be displayed using and available ChromeCast to - your TV. Use -dcc:? to display a list of ChromeCasts on your - local network. Note that the ChromeCast as a test patch source is - probably the least accurate of your choices, since it - up-samples the test patch and transforms from RGB to YCC and back, - but should be accurate within ± 1 bit. You may have to modify any - firewall to permit port 8081 to be accessed on your machine if it + + difficulty cause by TwinView and MergedFB in X11 based systems, you + can optionally specify a separate display number after the display + that is going to be used to present test patches, for accessing the + VideoLUT hardware. This must be specified as a single string, e.g. -d 1,2 . Some experimentation + may be needed on such systems, to discover what screen has access to + the VideoLUT hardware, and which screens the test patches appear on. + You may be able to calibrate one screen, and then share the + calibration with another screen. Profiling can be done independently + to calibration.
    +
    + -dweb or + -dweb:port starts a + standalone web server on your machine, which then allows a local or + remote web browser to display the the color test patches. By default + port 8080 is used, but this + can be overridden by appending a : + and the port number i.e. -dweb:8001. + The URL will be http:// + then name of the machine or its I.P. address followed by a colon and + the port number - e.g something like http://192.168.0.1:8080. If you use the verbose + option (-v) then a likely + URL will be printed once the server is started, or you could run ipconfig (MSWin) or /sbin/ifconfig (Linux or OS X) + and identify an internet address for your machine that way. JavaScript + needs to be enabled in your web browser for this to work. You may + have to modify any firewall to permit port 8080 to be accessed on + your machine.
    +
    + Note that if you use this method of accessing a display, that there + is no access to the display Video Lookup tables, and that any + operation that depends on accessing the VideoLUTs will either + generate a warning or fail.
    +
    + -dmadvr + [MSWin only] causes test patches to be displayed using the MadVR + video renderer. Note that will have to start MadTPG before + running dispread, and that while you can adjust the "Test Pattern + Configuration" controls, you should not normally alter the + "Existing Calibration" controls, as dispread will set these + appropriately. See -n flag.
    +
    + -dcc or -dcc:no + causes test patches to be displayed using and available ChromeCast to + your TV. Use -dcc:? to display a list of ChromeCasts on your + local network. Note that the ChromeCast as a test patch source is + probably the least accurate of your choices, since it + up-samples the test patch and transforms from RGB to YCC and back, + but should be accurate within ± 1 bit. You may have to modify any + firewall to permit port 8081 to be accessed on your machine if it falls back to the Default receiver (see installation - - instructions for your platform).
    -
    - The -P - parameter allows you to position and size the test patch window. By - default it is places in the center of the screen, and sized - appropriately for the type of instrument, or 10% of the width of the - display if the display size is unknown.. The ho and vo values govern the horizontal - and vertical offset respectively. A value of 0.0 positions the - window to the far left or top of the screen, a value of 0.5 - positions it in the center of the screen (the default), and 1.0 - positions it to the far right or bottom of the screen. If three - parameters are provided, then the ss - parameter is a scale factor for the test window size. A value of 0.5 - for instance, would produce a half sized window. A value of 2.0 will - produce a double size window. If four parameters are provided, then - the last two set independent horizontal and vertical scaling - factors. Note that the ho,vo,ss or ho,vo,hs,vs numbers must be - specified as a single string (no space between the numbers and the - comma). For example, to create a double sized test window at the top - right of the screen, use -P 1,0,2 - . To create a window twice as wide as high: -P 1,0,2,1.
    -
    - The -F - flag causes the while screen behind the test window to be masked - with black. This can aid black accuracy when measuring CRT displays - or projectors.
    -
    - The -E - flag causes the test values to be scaled to the Video RGB encoding - range of 16/255 to 235/255. Note that this is not applicable if the - MadVR render is being used to display patches, as MadVR should be - configured for Video encoding instead.
    -
    - By default dispwin will put - a test window on the selected display, and display some test colors, - before darkening  then brightening the screen by loading video - LUT values, test the bell sounds, then restore the original values - and exit.
    -
    - If the -i - flag is set, then dispwin - will display the preset sequence, then random test colors forever.
    -
    - If the -G - parameter is set, then dispwin - will display the sequence of RGB color in the supplied CGATS file, - e.g. a .ti1 file. Typically this might the used with the -m option to manually measure a - set of test patches.
    -
    - If the -m - flag is set, then dispwin - will display the preset sequence then exits, but advances manually - after each return key.
    -
    - If the -r - flag is set, then dispwin - will test just the loading of video LUT values by first darkening, - then lightening the screen, before exiting.
    -
    - If the -n - flag is set, then dispwin - will display the colors directly on the display, rather than having - the color values translated through the currently loaded Video LUTs. - In the case of using the MadVR renderer to display the patches, any - 3dLut will also be disabled.
    -
    - If a -s filename.cal option is - used, then rather than displaying a test window, dispwin will save the currently - loaded calibration curves to the given calibration file. Note that - other functions such as clearing or loading a calibration can be - performed after this action.
    -
    - If a -c - flag is used, then rather than displaying a test window, dispwin will load the selected - display with a linear set of Video LUT curves, effectively clearing - the calibration, and will then exit. Note that other functions such - as loading a calibration can be performed after this action.
    -
    - If a -V - flag is used, then rather than loading the calibration specified as - the final argument, the currently loaded calibration will be - verified as being the same as the given calibration file. If this is - combined with the -L flag, the currently - loaded calibration will be verified as being the same as the - installed system profile for the display.
    -
    - -I: The ICC - profile specified as the final argument will be installed as the - default operating system profile for the chosen display, and the - display calibration will be set to the calibration tag ('vcgt' tag, - if any) in that profile.. On MSWindows and OS X this means that the - profile will be copied to the appropriate color profile directory - and registered with the operating system. For Linux X11 systems, the - profile will be installed using the ucmm - convention, and the X11 _ICC_PROFILE property in the root window, - and also the the XrandR 1.2 X11 _ICC_PROFILE output property on - systems that are running XrandR 1.2 or later. The latter is - following this convention - for allowing applications to locate the display profile for a - particular X11 display, and expands it to accomodate XrandR 1.2. - Note that for X11 systems, the properties are not persistent, and - will need to be loaded each time the X11 server is started (see the - -L flag). To make sure that the profile calbration - 'vcgt' tag gets loaded into the Graphics Card at system start, - please read the guide here.
    -
    - -U: The ICC - profile specified as the final argument will be un-installed as the - default operating system profile for the chosen display. The display - calibration will remain unchanged.
    -
    - -S d: Some - systems have more than one profile scope that an installed profile - will apply to, and this parameter allows overriding the default user - scope. On OS X, there is a choice of three scopes: n: for network scope, if people - are sharing profiles over a network, l: local system scope, which installs the profile - for all users of a system, and the default u, which covers just the user - installing the profile. On Linux or Microsoft Vista, just the local - system l and user u scope are available. Note that - you may need to run dispwin with elevated privileges(sudo) to be - able to successfully use network or local system scope. This option - also applies to uninstalling a profile. Note that to install a user - profile for the root account, you will have to login as root (sudo - will not achieve this).
    -
    - -L: This - option fetches the current installed system profile for the chosen - display, and sets the display to the calibration tag ('vcgt' tag, if - any) in the profile. This is a convenient way of initializing the - display on system startup from the installed display profile, if the - system doesn't not do this automatically .
    -
    - -X: Daemon - mode (experimental). When running on a UNIX based system that used - the X11 Windowing System, this option runs dispwin in a "daemon" - mode where it monitors the given X11 server, waiting for any changes - in monitors that may require loading a matching ICC profile (ie. - such as re-configuring, plugging in a different monitor etc.)  - This only works if XRandR 1.2 is available on the server. By default - dispwin runs silently, and will not terminate. If the -v option is given, it will emit - messages to stdout to show what it is doing. When it is first - invoked, it will load the installed profiles of all the screens of - the given X11 server.
    -
    - The -D flag causes diagnostics to be printed - to stdout. A level can be set between 1 .. 9, that may give - progressively more verbose information. This can be useful in - tracking down why an operation fails.
    -
    - The final optional parameter on the command line - is the name of an ICC profile that contains a Video LUT vcgt tag, or an Argyll .cal format display calibration. If - this parameter is provided, then the selected display will be loaded - with the given calibration. If the -V - flag was given, then it is verified that this calibration is the - currently loaded one.  This may be useful in initializing a - system to the current calibration on system startup, although a - better way may be to install the profile (-I option), and then just use -L. Note that the vcgt tag - interpretation within Argyll is consistent with that of the - originators of the tag. Other ICC profile vcgt implementations may - not be so consistent.
    -
    - NOTE that on an X11 system, - if the environment variable ARGYLL_IGNORE_XRANDR1_2 - is set (ie. set it to "yes"), then the presence of the XRandR 1.2 - extension will be ignored, and other extensions such as Xinerama and - XF86VidMode extension will be used. This may be a way to work around - buggy XRandR 1.2 implementations.
    -
    - NOTE
    on MSWin systems that you will have to disable any - other calibration installer program if you want to be able to - control calibration using dispwin. Note also that there are other - programs that will interfere with calibration loading, such as - igfxpers.exe that gets installed with nVidia "Optimus" technology.
    -
    -
    -
    -
    - - + + instructions for your platform).
    +
    + The -P + parameter allows you to position and size the test patch window. By + default it is places in the center of the screen, and sized + appropriately for the type of instrument, or 10% of the width of the + display if the display size is unknown.. The ho and vo values govern the horizontal + and vertical offset respectively. A value of 0.0 positions the + window to the far left or top of the screen, a value of 0.5 + positions it in the center of the screen (the default), and 1.0 + positions it to the far right or bottom of the screen. If three + parameters are provided, then the ss + parameter is a scale factor for the test window size. A value of 0.5 + for instance, would produce a half sized window. A value of 2.0 will + produce a double size window. If four parameters are provided, then + the last two set independent horizontal and vertical scaling + factors. Note that the ho,vo,ss or ho,vo,hs,vs numbers must be + specified as a single string (no space between the numbers and the + comma). For example, to create a double sized test window at the top + right of the screen, use -P 1,0,2 + . To create a window twice as wide as high: -P 1,0,2,1.
    +
    + The -F + flag causes the while screen behind the test window to be masked + with black. This can aid black accuracy when measuring CRT displays + or projectors.
    +
    + The -E + flag causes the test values to be scaled to the Video RGB encoding + range of 16/255 to 235/255. Note that this is not applicable if the + MadVR render is being used to display patches, as MadVR should be + configured for Video encoding instead.
    +
    + By default dispwin will put + a test window on the selected display, and display some test colors, + before darkening  then brightening the screen by loading video + LUT values, test the bell sounds, then restore the original values + and exit.
    +
    + If the -i + flag is set, then dispwin + will display the preset sequence, then random test colors forever.
    +
    + If the -G + parameter is set, then dispwin + will display the sequence of RGB color in the supplied CGATS file, + e.g. a .ti1 file. Typically this might the used with the -m option to manually measure a + set of test patches.
    +
    + If the -m + flag is set, then dispwin + will display the preset sequence then exits, but advances manually + after each return key.
    +
    + If the -r + flag is set, then dispwin + will test just the loading of video LUT values by first darkening, + then lightening the screen, before exiting.
    +
    + If the -n + flag is set, then dispwin + will display the colors directly on the display, rather than having + the color values translated through the currently loaded Video LUTs. + In the case of using the MadVR renderer to display the patches, any + 3dLut will also be disabled.
    +
    + If a -s filename.cal option is + used, then rather than displaying a test window, dispwin will save the currently + loaded calibration curves to the given calibration file. Note that + other functions such as clearing or loading a calibration can be + performed after this action.
    +
    + If a -c + flag is used, then rather than displaying a test window, dispwin will load the selected + display with a linear set of Video LUT curves, effectively clearing + the calibration, and will then exit. Note that other functions such + as loading a calibration can be performed after this action.
    +
    + If a -V + flag is used, then rather than loading the calibration specified as + the final argument, the currently loaded calibration will be + verified as being the same as the given calibration file. If this is + combined with the -L flag, the currently + loaded calibration will be verified as being the same as the + installed system profile for the display.
    +
    + -I: The ICC + profile specified as the final argument will be installed as the + default operating system profile for the chosen display, and the + display calibration will be set to the calibration tag ('vcgt' tag, + if any) in that profile.. On MSWindows and OS X this means that the + profile will be copied to the appropriate color profile directory + and registered with the operating system. For Linux X11 systems, the + profile will be installed using the ucmm + convention, and the X11 _ICC_PROFILE property in the root window, + and also the the XrandR 1.2 X11 _ICC_PROFILE output property on + systems that are running XrandR 1.2 or later. The latter is + following this convention + for allowing applications to locate the display profile for a + particular X11 display, and expands it to accomodate XrandR 1.2. + Note that for X11 systems, the properties are not persistent, and + will need to be loaded each time the X11 server is started (see the + -L flag). To make sure that the profile calbration + 'vcgt' tag gets loaded into the Graphics Card at system start, + please read the guide here.
    +
    + -U: The ICC + profile specified as the final argument will be un-installed as the + default operating system profile for the chosen display. The display + calibration will remain unchanged.
    +
    + -S d: Some + systems have more than one profile scope that an installed profile + will apply to, and this parameter allows overriding the default user + scope. On OS X, there is a choice of three scopes: n: for network scope, if people + are sharing profiles over a network, l: local system scope, which installs the profile + for all users of a system, and the default u, which covers just the user + installing the profile. On Linux or Microsoft Vista, just the local + system l and user u scope are available. Note that + you may need to run dispwin with elevated privileges(sudo) to be + able to successfully use network or local system scope. This option + also applies to uninstalling a profile. Note that to install a user + profile for the root account, you will have to login as root (sudo + will not achieve this).
    +
    + -L: This + option fetches the current installed system profile for the chosen + display, and sets the display to the calibration tag ('vcgt' tag, if + any) in the profile. This is a convenient way of initializing the + display on system startup from the installed display profile, if the + system doesn't not do this automatically .
    +
    + -X: Daemon + mode (experimental). When running on a UNIX based system that used + the X11 Windowing System, this option runs dispwin in a "daemon" + mode where it monitors the given X11 server, waiting for any changes + in monitors that may require loading a matching ICC profile (ie. + such as re-configuring, plugging in a different monitor etc.)  + This only works if XRandR 1.2 is available on the server. By default + dispwin runs silently, and will not terminate. If the -v option is given, it will emit + messages to stdout to show what it is doing. When it is first + invoked, it will load the installed profiles of all the screens of + the given X11 server.
    +
    + The -D flag causes diagnostics to be printed + to stdout. A level can be set between 1 .. 9, that may give + progressively more verbose information. This can be useful in + tracking down why an operation fails.
    +
    + The final optional parameter on the command line + is the name of an ICC profile that contains a Video LUT vcgt tag, or an Argyll .cal format display calibration. If + this parameter is provided, then the selected display will be loaded + with the given calibration. If the -V + flag was given, then it is verified that this calibration is the + currently loaded one.  This may be useful in initializing a + system to the current calibration on system startup, although a + better way may be to install the profile (-I option), and then just use -L. Note that the vcgt tag + interpretation within Argyll is consistent with that of the + originators of the tag. Other ICC profile vcgt implementations may + not be so consistent.
    +
    + NOTE that on an X11 system, + if the environment variable ARGYLL_IGNORE_XRANDR1_2 + is set (ie. set it to "yes"), then the presence of the XRandR 1.2 + extension will be ignored, and other extensions such as Xinerama and + XF86VidMode extension will be used. This may be a way to work around + buggy XRandR 1.2 implementations.
    +
    + NOTE
    on MSWin systems that you will have to disable any + other calibration installer program if you want to be able to + control calibration using dispwin. Note also that there are other + programs that will interfere with calibration loading, such as + igfxpers.exe that gets installed with nVidia "Optimus" technology.
    +
    +
    +
    +
    + + diff --git a/doc/fakeread.html b/doc/fakeread.html index 376e971..e8c353e 100644 --- a/doc/fakeread.html +++ b/doc/fakeread.html @@ -240,7 +240,7 @@ digits (bits) that the device values should be quantized to. An idea of the number of bits of precision that makes its way to your display can be obtained by using dispcal -R If + href="dispcal.html#R">dispcal -R If Video encoding is selected (see -E flag above), then 8 bits is selected by default. On systems using an VGA connection or Display Port with a graphics card with VideoLUT entries with greater than 8 diff --git a/doc/iccgamut.html b/doc/iccgamut.html index 47df32c..ead8f7c 100644 --- a/doc/iccgamut.html +++ b/doc/iccgamut.html @@ -16,7 +16,7 @@ in Lab or CIECAM02 Jab colorspace, and can also representing the gamut as a X3DOM file.

    - See 3D Viewing + See 3D Viewing Format for switching to VRML or X3D output format.

    Usage

    @@ -235,7 +235,7 @@ f:flare               g:glare      Glare light % of ambient - (default 1)
    + (default 5)
             diff --git a/doc/illumread.html b/doc/illumread.html index 9b65b2f..3ee7aa5 100644 --- a/doc/illumread.html +++ b/doc/illumread.html @@ -1,309 +1,309 @@ - - - - illumread - - - - -

    spectro/illumread

    -

    Summary

    - Use an instrument or instruments to measure an illuminant spectrum, - including estimate its Ultra Violet content. A combination of direct - illumination readings and readings from a piece of paper having some - FWA content are used for this. (If the UV content is not needed, or - a suitable instrument is not available, then spotread should be used instead.)
    -

    Usage Summary

    - illumread [-options] - illuminant.sp
    -  -v + + + illumread + + + + +

    spectro/illumread

    +

    Summary

    + Use an instrument or instruments to measure an illuminant spectrum, + including estimate its Ultra Violet content. A combination of direct + illumination readings and readings from a piece of paper having some + FWA content are used for this. (If the UV content is not needed, or + a suitable instrument is not available, then spotread should be used instead.)
    +

    Usage Summary

    + illumread [-options] + illuminant.sp
    +  -v                - -     Verbose mode

    -  -S -              -       Plot the readings in a graph window.
    -  -c comport

    +  -S +              +       Plot the readings in a graph window.
    +  -c comport            Set - - COM port, 1..4 (default 1)

    -

    +
     -N                    Disable - - initial calibration of instrument if possible
    -  -H -              -       Use high resolution spectrum mode - (if available)
    + + initial calibration of instrument
    if possible
    +  -H +              +       Use high resolution spectrum mode + (if available)
     -Y r                  - - Set refresh measurement mode
    -
     -W n|h|x              Override - - serial port flow control: n = none, h = HW, x = Xon/Xoff
    -  -T + + serial port flow control: n = none, h = HW, x = Xon/Xoff

    +  -T                    - - Test mode - restore & save measurements to
    + + Test mode - restore & save measurements to
                            - - *_i.sp, *_r.sp, *_p.sp, *_mpir.sp, *_cpir.sp files
    -
     -D [level] -            - Print debug diagnostics to stderr
    -   +
     -D [level] +            + Print debug diagnostics to stderr
    +   illuminant.sp         File - - to save measurement to
    -

    -

    Usage Details and Discussion

    - illumread uses a suitable instrument to read an illuminant - spectrum, and uses an indirect method to estimate the Ultra Violet - content of the illuminant, so as to provide better accuracy with FWA compensation. An instrument or combination - of instruments capable of spectral measurement of both emissive - measurement and reflective measurement without a U.V. filter is - required for this.
    -
    - The -v flag causes extra information to be - printed out during chartread operation.
    -
    - The -S flag enables the plotting of the - spectral reflectance/transmittance values. You must select the plot - window and strike a key in it to continue with another measurement.
    -
    - The instrument is assumed to communicate through a - USB or serial communication port, and the initial port can be - selected with the -c option, if the instrument is not - connected to the first port. If you invoke illumread so as to display the - usage information (i.e. "illumread -?" or "illumread --"), then the - discovered USB and serial ports will be listed. On UNIX/Linux, a - list of all possible serial ports are shown, but not all of them may - actually be present on your system.
    -
    - -N Any - instrument that requires regular calibration will ask for - calibration on initial start-up. Sometimes this can be awkward if - the instrument is being mounted in some sort of measuring jig, or - annoying if several sets of readings are being taken in quick - succession. The -N - suppresses this initial calibration if a valid and not timed out - previous calibration is recorded in the instrument or on the host - computer. It is advisable to only use this option on the second and - subsequent measurements in a single session.
    -
    - The -H - option turns on high resolution spectral mode, if the instrument - supports it. See Operation of particular - instruments for more details.
    -
    - The -Y r - option turns on refresh mode measurement, if the instrument supports - it. This may improve the repeatability of measurements of - illuminants that have a repetitive flicker.
    -
    - The -W n|h|x - parameter overrides the default serial communications flow control - setting. The value n turns - all flow control off, h - sets hardware handshaking, and x - sets Xon/Xoff handshaking. This commend may be useful in workaround - serial communications issues with some systems and cables.
    -
    - The -T flag invokes the test mode. In test - mode the three measurements are saved to files illuminant_i.sp - (Illuminant spectrum), illuminant_r.sp (Illuminant - off paper spectrum), and illuminant_p.sp (Instrument - measured paper reflectance spectrum), and these will be loaded if - discovered, allowing a replay of the calculation without requiring - any measurement. In addition, two diagnostic files illuminant_mpir.sp + + to save measurement to
    +

    +

    Usage Details and Discussion

    + illumread uses a suitable instrument to read an illuminant + spectrum, and uses an indirect method to estimate the Ultra Violet + content of the illuminant, so as to provide better accuracy with FWA compensation. An instrument or combination + of instruments capable of spectral measurement of both emissive + measurement and reflective measurement without a U.V. filter is + required for this.
    +
    + The -v flag causes extra information to be + printed out during chartread operation.
    +
    + The -S flag enables the plotting of the + spectral reflectance/transmittance values. You must select the plot + window and strike a key in it to continue with another measurement.
    +
    + The instrument is assumed to communicate through a + USB or serial communication port, and the initial port can be + selected with the -c option, if the instrument is not + connected to the first port. If you invoke illumread so as to display the + usage information (i.e. "illumread -?" or "illumread --"), then the + discovered USB and serial ports will be listed. On UNIX/Linux, a + list of all possible serial ports are shown, but not all of them may + actually be present on your system.
    +
    + -N Any + instrument that requires regular calibration will ask for + calibration on initial start-up. Sometimes this can be awkward if + the instrument is being mounted in some sort of measuring jig, or + annoying if several sets of readings are being taken in quick + succession. The -N + suppresses this initial calibration if a valid and not timed out + previous calibration is recorded in the instrument or on the host + computer. It is advisable to only use this option on the second and + subsequent measurements in a single session.
    +
    + The -H + option turns on high resolution spectral mode, if the instrument + supports it. See Operation of particular + instruments for more details.
    +
    + The -Y r + option turns on refresh mode measurement, if the instrument supports + it. This may improve the repeatability of measurements of + illuminants that have a repetitive flicker.
    +
    + The -W n|h|x + parameter overrides the default serial communications flow control + setting. The value n turns + all flow control off, h + sets hardware handshaking, and x + sets Xon/Xoff handshaking. This commend may be useful in workaround + serial communications issues with some systems and cables.
    +
    + The -T flag invokes the test mode. In test + mode the three measurements are saved to files illuminant_i.sp + (Illuminant spectrum), illuminant_r.sp (Illuminant + off paper spectrum), and illuminant_p.sp (Instrument + measured paper reflectance spectrum), and these will be loaded if + discovered, allowing a replay of the calculation without requiring + any measurement. In addition, two diagnostic files illuminant_mpir.sp (Measured paper under illuminant spectrum) and illuminant_cpir.sp - - (Computed paper under illuminant spectrum) will be saved.
    -
    - The -D flag causes communications and other - instrument diagnostics to be printed to stdout. A level can be set - between 1 .. 9, that may give progressively more verbose - information, depending on the instrument. This can be useful in - tracking down why an instrument can't connect.
    -
    - The illuminant.sp is the name of the file to save the - resulting illuminant spectrum to. The format used is .sp.
    -
    -

    - Unlike the other measurement utilities, illumread doesn't connect to the instrument until it - is about to make a measurement. This allows for the possibility of - using a different instrument for each measurement.
    -
    - It will display a menu:
    -
    - Press 1 .. 6
    - 1) Measure direct illuminant
    - 2) Measure illuminant reflected from paper
    - 3) Measure paper
    - 4) Select another instrument, Currently 1 'usb:/bus4/dev2/ - (GretagMacbeth i1 Pro)'
    - 5) Compute illuminant spectrum, average result with 0 previous - readings & save it
    - 6) Compute illuminant spectrum from this reading & save result
    - 7) Exit
    -
    - There are three measurements to be made, after which the illuminant - can be computed and saved. Before each measurement, the instrument - may need calibrating.
    -
    - The first measurement needs a spectral instrument capable of reading - in an ambient or emissive mode. For instance, a Spectrolino, Eye-One - Pro or ColorMunki would be suitable instruments.
    -
    - The second measurement needs a spectral instrument capable of - reading in an projector or emissive mode. For instance, a - Spectrolino, Eye-One Pro or ColorMunki would be suitable - instruments.
    -
    - The third measurement needs a spectral instrument capable of reading - in reflective mode with UV included. For instance, a Spectrolino, - Eye-One Pro, DTP20, DTP22 or  DTP41 would be suitable - instruments, as long as they are not fitted with UV filters.
    -
    - To be able to estimate the level of Ultra Violet (UV) light in the - illuminant, a reasonable sized piece of white paper needs to be - used. The paper should have some noticeable level of FWA - (Fluorescent Whitener Additive, or Optical Brightening Agents) in - it, so that it responds to UV light. A piece of cheap copier paper - is ideal, since cheap paper is typically whitened with large amounts - of FWA. If the paper is thin (less than 160 gsm) then two or three - sheets should be used to prevent any background showing through. If - the intention is to use the illuminant spectrum for proofing to a - particular paper, then it's best to use the intended paper for this - purpose.
    -
    - The first measurement 1), - is to use either the ambient or emissive measurement mode to measure - the illumination directly.
    -
    -
    If the instrument supports an - ambient measurement capability, then it will be used. If the - insrument does not have an ambient mode, then an emissive - measurement mode can be used, although typically many illuminants - are too bright to directly point the instrument at. A work-around - is to reflect the illuminant from a spectrally flat white surface. - A good candidate for this is a piece of white, fine textured - polystyrene foam. [The suitability of a reflector can be checked - using spotread -S to - check that the reflection characteristic is close to flat.]
    -
    - Measuring AmbientMeasuring Ambient  Measuring Ambient
    -
    -
    - The second measurement 2), - is to measure the illuminant after it has reflected from the paper.
    -
    -
    This is done by placing the paper - such that it is uniformly illuminated with reasonable brightness, - and then placing the instrument so that it receives the reflected - light from the paper. This is typically achieved by placing the - instrument close to the paper at about 45º, so that it's aperture - has a clear view of the illuminated paper, but avoiding shadowing - the region that is in view.
    -
    - Measuring via
-        PaperMeasuring via Paper
    -
    -
    - The third measurement 3), - is to measure the paper directly using the instrument reflective - mode measurement.
    -
    Measuring Paper
    -
    - If a different instrument is needed, use 4) to select from the available instruments attached - to your computer.
    -
    - Once these three measurements have been made, then the illuminant - readings spectrum can be computed and save using 6), or a series of readings can - be made with each reading being averages with the previous readings - before saving it by using 5). - Note that the averaged readings will be weighted by their absolute - intensities, and that while the direct and indirect illumination - needs measuring for each reading, the same paper measurement can be - used each time.
    -
    - If plotting is enabled, a plot of the measured (black) and with - estimated UV (red) is plotted. This is followed by a plot showing - measured paper reflectance (black) and the FWA calculated paper - reflectance (red).
    -
    -
    - Illumread can then be terminated using 7).
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - - + + (Computed paper under illuminant spectrum) will be saved.
    +
    + The -D flag causes communications and other + instrument diagnostics to be printed to stdout. A level can be set + between 1 .. 9, that may give progressively more verbose + information, depending on the instrument. This can be useful in + tracking down why an instrument can't connect.
    +
    + The illuminant.sp is the name of the file to save the + resulting illuminant spectrum to. The format used is .sp.
    +
    +

    + Unlike the other measurement utilities, illumread doesn't connect to the instrument until it + is about to make a measurement. This allows for the possibility of + using a different instrument for each measurement.
    +
    + It will display a menu:
    +
    + Press 1 .. 6
    + 1) Measure direct illuminant
    + 2) Measure illuminant reflected from paper
    + 3) Measure paper
    + 4) Select another instrument, Currently 1 'usb:/bus4/dev2/ + (GretagMacbeth i1 Pro)'
    + 5) Compute illuminant spectrum, average result with 0 previous + readings & save it
    + 6) Compute illuminant spectrum from this reading & save result
    + 7) Exit
    +
    + There are three measurements to be made, after which the illuminant + can be computed and saved. Before each measurement, the instrument + may need calibrating.
    +
    + The first measurement needs a spectral instrument capable of reading + in an ambient or emissive mode. For instance, a Spectrolino, Eye-One + Pro or ColorMunki would be suitable instruments.
    +
    + The second measurement needs a spectral instrument capable of + reading in an projector or emissive mode. For instance, a + Spectrolino, Eye-One Pro or ColorMunki would be suitable + instruments.
    +
    + The third measurement needs a spectral instrument capable of reading + in reflective mode with UV included. For instance, a Spectrolino, + Eye-One Pro, DTP20, DTP22 or  DTP41 would be suitable + instruments, as long as they are not fitted with UV filters.
    +
    + To be able to estimate the level of Ultra Violet (UV) light in the + illuminant, a reasonable sized piece of white paper needs to be + used. The paper should have some noticeable level of FWA + (Fluorescent Whitener Additive, or Optical Brightening Agents) in + it, so that it responds to UV light. A piece of cheap copier paper + is ideal, since cheap paper is typically whitened with large amounts + of FWA. If the paper is thin (less than 160 gsm) then two or three + sheets should be used to prevent any background showing through. If + the intention is to use the illuminant spectrum for proofing to a + particular paper, then it's best to use the intended paper for this + purpose.
    +
    + The first measurement 1), + is to use either the ambient or emissive measurement mode to measure + the illumination directly.
    +
    +
    If the instrument supports an + ambient measurement capability, then it will be used. If the + insrument does not have an ambient mode, then an emissive + measurement mode can be used, although typically many illuminants + are too bright to directly point the instrument at. A work-around + is to reflect the illuminant from a spectrally flat white surface. + A good candidate for this is a piece of white, fine textured + polystyrene foam. [The suitability of a reflector can be checked + using spotread -S to + check that the reflection characteristic is close to flat.]
    +
    + Measuring AmbientMeasuring Ambient  Measuring Ambient
    +
    +
    + The second measurement 2), + is to measure the illuminant after it has reflected from the paper.
    +
    +
    This is done by placing the paper + such that it is uniformly illuminated with reasonable brightness, + and then placing the instrument so that it receives the reflected + light from the paper. This is typically achieved by placing the + instrument close to the paper at about 45º, so that it's aperture + has a clear view of the illuminated paper, but avoiding shadowing + the region that is in view.
    +
    + Measuring via
+        PaperMeasuring via Paper
    +
    +
    + The third measurement 3), + is to measure the paper directly using the instrument reflective + mode measurement.
    +
    Measuring Paper
    +
    + If a different instrument is needed, use 4) to select from the available instruments attached + to your computer.
    +
    + Once these three measurements have been made, then the illuminant + readings spectrum can be computed and save using 6), or a series of readings can + be made with each reading being averages with the previous readings + before saving it by using 5). + Note that the averaged readings will be weighted by their absolute + intensities, and that while the direct and indirect illumination + needs measuring for each reading, the same paper measurement can be + used each time.
    +
    + If plotting is enabled, a plot of the measured (black) and with + estimated UV (red) is plotted. This is followed by a plot showing + measured paper reflectance (black) and the FWA calculated paper + reflectance (red).
    +
    +
    + Illumread can then be terminated using 7).
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + diff --git a/doc/instruments.html b/doc/instruments.html index b493b27..1e287fc 100644 --- a/doc/instruments.html +++ b/doc/instruments.html @@ -1,28 +1,28 @@ - - - - Operation of particular instruments - - - -

    Operation of particular instruments

    - Please note that instruments are - being driven by ArgyllCMS drivers, and that any problems or - queries regarding instrument
    - operation
    should be - directed to the Argyll's author(s) or the Argyll mailing list, and - not to any other party.
    -
    - The following instruments are directly supported:
    - (Please note the installation instructions for each - platform - they contain important information for getting your - instruments working.)
    -
    - JETI:
    -
    + + + + Operation of particular instruments + + + +

    Operation of particular instruments

    + Please note that instruments are + being driven by ArgyllCMS drivers, and that any problems or + queries regarding instrument
    + operation
    should be + directed to the Argyll's author(s) or the Argyll mailing list, and + not to any other party.
    +
    + The following instruments are directly supported:
    + (Please note the installation instructions for each + platform - they contain important information for getting your + instruments working.)
    +
    + JETI:
    +
        specbos 1211 & 1201                    @@ -48,11 +48,11 @@ - - - Tele-Spectro-Radiometer
    -
    - Image Engineering:
    -
    + + - Tele-Spectro-Radiometer
    +
    + Image Engineering:
    +
        EX1                                               @@ -107,20 +107,20 @@ - - - Tele-Spectro-Radiometer
    -
    - Klein:
    -
    -     K10-A   -             -             -             -     - Display Colorimeter. Reported also to work with - the K-1, K-8 and  K-10
    -
    - X-Rite:
    -     DTP20 "Pulse"  + + - Tele-Spectro-Radiometer
    +
    + Klein:
    +
    +     K10-A   +             +             +             +     - Display Colorimeter. Reported also to work with + the K-1, K-8 and  K-10
    +
    + X-Rite:
    +     DTP20 "Pulse"                              @@ -168,8 +168,8 @@ - - - "swipe" type reflective spectrometer, that can be used untethered.
    + + - "swipe" type reflective spectrometer, that can be used untethered.
        DTP22 Digital Swatchbook            @@ -217,8 +217,8 @@ - - - spot type reflective spectrometer.
    + + - spot type reflective spectrometer.
        DTP41                                         @@ -266,10 +266,10 @@ - - - spot and strip reading reflective spectrometer.
    -     DTP41T       -            + + - spot and strip reading reflective spectrometer.
    +     DTP41T       +                                 @@ -317,8 +317,8 @@ - - - spot and strip reading reflective/transmissive spectrometer.
    + + - spot and strip reading reflective/transmissive spectrometer.
        DTP51                                         @@ -366,8 +366,8 @@ - - - strip reading reflective colorimeter.
    + + - strip reading reflective colorimeter.
        DTP92                                         @@ -415,8 +415,8 @@ - - - CRT display colorimeter.
    + + - CRT display colorimeter.
        DTP94 "Optix @@ -464,8 +464,8 @@ - - XR" or "Optix XR2" or "Optix Pro"- display colorimeter.
    + + XR"
    or "Optix XR2" or "Optix Pro"- display colorimeter.
        @@ -513,62 +513,62 @@ - - ColorMunki - Design or Photo  -          - spot and "swipe" - reflective/emissive spectrometer (UV cut only).
    -     ColorMunki Create or Smile   -          - display - colorimeter. (Similar to an Eye-One Display 2)
    -     Lenovo W     -                   -               - built in laptop - Huey display colorimeter.
    -     Eye-One Display 3   -                   -     - i1 DisplayPro and ColorMunki Display
    -             -             -             -             -           [ The OEM - i1Display Pro, NEC SpectraSensor Pro,
    -                   -                   -                   -        Quato Silver Haze 3 OEM and HP - DreamColor  i1d3 are also reported to work.]
    -     Eye-One Pro2 -                   -              - spot and - "swipe" reflective/emissive spectrometer.
    -
    - Gretag-Macbeth (now X-Rite):
    -     Spectrolino       -                   -           - spot reflective/emissive - spectrometer
    -     SpectroScan       -                   -         - spot reflective/emissive, XY table - reflective spectrometer 
    -     SpectroScanT       -                   -       - spot reflective/emissive/transmissive, XY - table reflective spectrometer
    -     Eye-One Pro "EFI ES-1000"   -         - spot and "swipe" reflective/emissive - spectrometer
    -     Eye-One Monitor -                   -         - spot and "swipe" emissive spectrometer
    -     Eye-One Display 1 or 2  or - LT        - display - colorimeter
    -     HP DreamColor or - APS  + + ColorMunki + Design or Photo  +          - spot and "swipe" + reflective/emissive spectrometer (UV cut only).
    +     ColorMunki Create or Smile   +          - display + colorimeter. (Similar to an Eye-One Display 2)
    +     Lenovo W     +                   +               - built in laptop + Huey display colorimeter.
    +     Eye-One Display 3   +                   +     - i1 DisplayPro and ColorMunki Display
    +             +             +             +             +           [ The OEM + i1Display Pro, NEC SpectraSensor Pro,
    +                   +                   +                   +        Quato Silver Haze 3 OEM and HP + DreamColor  i1d3 are also reported to work.]
    +     Eye-One Pro2 +                   +              - spot and + "swipe" reflective/emissive spectrometer.
    +
    + Gretag-Macbeth (now X-Rite):
    +     Spectrolino       +                   +           - spot reflective/emissive + spectrometer
    +     SpectroScan       +                   +         - spot reflective/emissive, XY table + reflective spectrometer 
    +     SpectroScanT       +                   +       - spot reflective/emissive/transmissive, XY + table reflective spectrometer
    +     Eye-One Pro "EFI ES-1000"   +         - spot and "swipe" reflective/emissive + spectrometer
    +     Eye-One Monitor +                   +         - spot and "swipe" emissive spectrometer
    +     Eye-One Display 1 or 2  or + LT        - display + colorimeter
    +     HP DreamColor or + APS                  @@ -616,9 +616,9 @@ - - - display colorimeter. (Treated as a Eye-One Display 2)
    -     CalMAN X2 + + - display colorimeter. (Treated as a Eye-One Display 2)
    +     CalMAN X2                                  @@ -666,18 +666,18 @@ - - - display colorimeter. (Treated as a Eye-One Display 2)
    -     Huey       -                   -             -        - display colorimeter
    -
    - Sequel imaging (Now X-Rite):
    -      MonacoOPTIX   -                    -        - display colorimeter (Treated - as an Eye-One Display 1)
    + + - display colorimeter. (Treated as a Eye-One Display 2)
    +     Huey       +                   +             +        - display colorimeter
    +
    + Sequel imaging (Now X-Rite):
    +      MonacoOPTIX   +                    +        - display colorimeter (Treated + as an Eye-One Display 1)
                                                               @@ -725,10 +725,10 @@ - - [The Sequel Chroma 4 may also work.]
    -
    - Lacie Blue + + [The Sequel Chroma 4 may also work.]
    +
    + Lacie Blue Eye:                                  @@ -776,15 +776,15 @@ - - - see Eye-One Display
    -
    - DataColor ColorVision:
    -      Spyder 2   -                    -          -        - display colorimeter (Note - that the user must supply firmware)
    + + - see Eye-One Display
    +
    + DataColor ColorVision:
    +      Spyder 2   +                    +          +        - display colorimeter (Note + that the user must supply firmware)
                                                              @@ -832,27 +832,27 @@ - - [The Spyder 1 also seems to work.]
    -      Spyder 3   -                    -          -        - display colorimeter.
    -      Spyder 4   -                    -          -        - display colorimeter (Note - that the user must supply calibration - data)
    -      Spyder 5   -                    -          -        - display colorimeter (Note - that the user must supply calibration - data)
    -
    - Other:
    -     Colorimètre + + [The Spyder 1 also seems to work.]
    +     
    Spyder 3   +                    +          +        - display colorimeter.
    +      Spyder 4   +                    +          +        - display colorimeter (Note + that the user must supply calibration + data)
    +      Spyder 5   +                    +          +        - display colorimeter (Note + that the user must supply calibration + data)
    +
    + Other:
    +     Colorimètre HCFR                        @@ -900,8 +900,8 @@ - - - display colorimeter
    + + - display colorimeter
        ColorHug                                        @@ -940,288 +940,288 @@ - - - display colorimeter
    + + - display colorimeter
        Palette/SwatchMate Cube         - - - reflective colorimeter
    -
    - Other instruments can be supported indirectly, since patch result - files created by other packages can be imported into Argyll.
    -
    - General information about:
    -
    -     Strip reading instruments
    -
        X-Y Table instruments
    -     Spot reading instruments
    -
    -
    - There is a list of contributed ccmx (Colorimeter Correction - Matrix) files.
    -
    -
    -

    Strip reading instruments

    - When used with a DT20, DTP41, DTP51, Eye-One Pro or ColorMunki - strip reading instrument, chartread will first establish - communications with the instrument, and then set it up ready to read - the strips. The strips are labeled A to ZZ, and for each strip it - will prompt:
    -
    -     About to read strip XX  :
    -
    - where XX is the strip label, and this is followed by the available - options to navigate, read the strip, or finish. Note that the normal - (forward) direction of strip reading is one that starts at the strip - label.
    -
    - For the DTP51 you should - feed the strip into the instrument, and the microswitch will trigger - the read.
    -
    - For the DTP41 you should - line the appropriate strip up in the machine, and press its button.
    -
    - For the Eye-One Pro you - should set the guide to the appropriate strip, place the instrument - ahead of the first - patch on blank paper, and then press and hold the instruments - button. When you hear a beep from the computer, you can then move - the instrument steadily over the patches, releasing the button after - the instrument is past the last patch. Moving the instrument too - fast or changing speeds may cause a mis-read, or a scan with few - samples read per patch.
    -
    - For the ColorMunki with the - default chart, the patches are the same width as the silver portion - of body (white version), or the textured portion of the body (black - version). Place aperture of the the instrument (located at its - center) in the white space ahead of the first patch, and then press - and hold the instruments button. When you hear a beep from the - computer, you can then move the instrument steadily over the - patches, releasing the button after the instrument is past the last - patch. Moving the instrument too fast or changing speeds may cause a - mis-read, or a scan with few samples read per patch. For the high density ColorMunki chart (printtarg -h), the patches are - arranged so that three rows are exactly the width of the  body - of the instrument. If you are careful you can use this to guide the - center of the instrument over each row, or you may prefer to use - something like a plastic ruler to help guide the instrument.
    -
    - Using the DTP20 or the Eye-One Pro or ColorMunki with a randomized - chart layout, the strip may be scanned from either direction. If a - randomized chart layout has not been used for the Eye-One Pro or ColorMunki, then the chart - should only be read in the one direction (use chartread -B).
    -
    - Note that you may have to check that system alert sounds are enabled - and at a suitable volume to in order to hear the beep prompt. For - the Eye-One Pro and ColorMunki, a second beep will sound after a - successfully read strip, or a double beep will sound,  - indicating a failure or warning that needs attention. See also the - note on Linux in installation.
    -
    - If the strip is read successfully there will be a single "success" - beep, and the line will be followed with:
    -
    -     Ready to read strip  XX  :
    -     Strip read OK
    -
    - If there is an error of some sort there will be a double "fail" - beep, and a message will be issued, and you will be asked whether to - abort the chart reading, or retry the
    - failed strip:
    -
    -     Ready to read strip XX  :
    -     Strip read failed due to misread (Not enough - patches)
    -
    -     Hit Esc to give up, any other key to retry:
    -
    - If you are unable to successfully read a strip after several - retries, you can skip that strip using the 'n' key, and save
    - the chart readings without that strip.
    -
    - If the strip is read successfully, but the patches values don't seem - to be what is expected, you will get a double "fail" beep  and - the following type of warning:
    -
    -     Ready to read strip  XX  :
    -     (Warning) Seem to have read strip  YY  - rather than  XX !
    -     Hit Return to use it anyway, any other key to - retry, Esc, ^C or Q to give up:
    -
    - This could be because you have accidentally read the wrong strip (a - common mistake), or it could be that the device response is so - different from what is expected that warning is erroneous, or you - may get a lot of these sorts of warnings if you are accidentally - reading the wrong chart. You may also get this sort of warning if - you are not using bi-direction reading (chartread -B), and read the - strip from the wrong end.
    - If you are absolutely sure you lined up the correct strip, then hit - return, otherwise line the appropriate strip up again, and hit some - other key (ie. space).
    - Erroneous warnings are less likely if a previous profile for a - device was given to targen - to set more accurate expectations.
    -
    - You may also see the following type of warning:
    -
    -     Ready to read strip  XX  :
    -     (Warning) Patch error YY.YYY (>35 not good, - >95 bad)
    -    There is at least one patch with an very unexpected - response!
    -     Hit Return to use it anyway, any other key to - retry, Esc, ^C or Q to give up:
    -
    - Similar to the previous warning, this indicates that while the right - strip appears to have been read, one of the patch readings is quite - different to what is expected. This may indicate an error of some - sort (ie. damaged test chart, or bad instrument positioning), or may - be erroneous if the actual device response is quite different to the - expectation. Erroneous warnings are less likely if a previous - profile for a device was given to targen - to set more accurate expectations.
    -
    - You can also navigate the next strip to be read using the 'f' key to move forward and the - 'b' keys - to move backwards. The prompt will indicate whether this strip has - already been read or not, or whether all strips have been read. You - can also use 'n' to move - forward to the next unread strip. After each successful reading it - will move forward to the next unread strip. When you are finished, - use the 'd' to indicate - that you are done. You can choose to finish before all the strips - are read, and the patches that have been read will be saved to the - .ti3 file. This is useful if you are unable to read a particular - strip successfully, or if you are unable to finish the chart in one - session, and you can later resume reading the chart by using the chartread -r flag. [You could - resume reading the chart patch by patch using the chartread -r -p if you are - unable to read a strip successfully.]
    -
    - When reading in patch by patch mode, there are a few additional - navigation options, such as F to move forward 10 - patches, B to move - backwards 10 patches, and g - to go to a specific patch.
    -
    - You can abort the whole process at any time by hitting Escape, and - the readings will not be saved.
    -
    -
    -

    X-Y Table instruments

    - When you are using an XY table type instrument, such as a Gretag SpectroScan,  chartread - will first establish communications with the instrument, and then - set it up ready to read the chart. You will be prompted for each - sheet with a message such as:
    -
    -     Please make sure that the white reference is in - slot 1, then
    -     place sheet 1 of 4 on table, then
    -     hit return to continue, Esc to give up
    -
    - After hitting return you will be prompted to line up three squares - on the sheet, one at a time:
    -
    -     Using the XY table controls, locate patch A1 with - the sight,
    -     then hit return to continue, Esc to give up
    -
    - On completing this, the instrument will commence reading each sheet.
    -
    -
    -

    Spot reading instruments

    - When used with a DT22 or SpectroLino or use the patch by - patch reading mode (chartread -p) - with the Eye-One Pro or ColorMunki - instrument, or use the external values mode (chartread -x), chartread will - first establish communications with the instrument, and then set it - up ready to read the patches. The patches are typically labeled by - column A to ZZ, and row 1-999. Each patch will prompt:
    -
    -     Ready to read patch 'XX'  :
    -
    - where XX is the patch label, and this is followed by the available - options to navigate, read the strip, or finish.
    -
    - Place the instrument on the indicated patch, and trigger a reading - using one of the available methods (typically using the instrument - switch of pressing a key).
    -
    - There should be an audible prompt on a successful or failed reading. -
    -
    - Note that you may have to check that system alert sounds are enabled - and at a suitable volume to in order to hear the beep prompt. For - the Eye-One Pro and ColorMunki, a second beep will sound after a - successfully read strip, or a double beep will sound,  - indicating a failure or warning that needs attention. See also the - note on Linux in installation.
    -
    - If the patch is read successfully, the line will be completed with:
    -
    -     Ready to read patch  XX  :
    -     Patch read OK
    -
    - If there is an error of some sort, a message will be issued, and you - will be asked whether to abort the chart reading, or retry the
    - failed patch:
    -
    -     Ready to read patch XX  : read_strip - returned 'Strip misread' (Bad reading)
    -
    -     Strip read failed due to misread
    -     Hit Esc to give up, any other key to retry:
    -
    - You can navigate the next patch to be read using the 'f' key to move forward and the - 'b' keys - to move backwards, while 'F' - and 'B' will move forward - and backwards by 10 patches. The prompt will indicate whether this - patch has already been read or not, or whether all patches have been - read. You can also use 'n' - to move forward to the next unread patch. When you are finished, use - the 'd' to indicate that - you are done. You can choose to finish before all the patches are - read, and they will be saved to the .ti3 file. This is useful if you - are unable to finish the chart in one session, and you can later resume reading the - chart by using the chartread -r - flag.
    -
    - You can abort the whole process at any time by hitting Escape, and - the readings will not be saved.
    -
    - -
    -

    Display Type
    -

    + + - reflective colorimeter
    +
    + Other instruments can be supported indirectly, since patch result + files created by other packages can be imported into Argyll.
    +
    + General information about:
    +
    +     Strip reading instruments
    +
        X-Y Table instruments
    +     Spot reading instruments
    +
    +
    + There is a list of contributed ccmx (Colorimeter Correction + Matrix) files.
    +
    +
    +

    Strip reading instruments

    + When used with a DT20, DTP41, DTP51, Eye-One Pro or ColorMunki + strip reading instrument, chartread will first establish + communications with the instrument, and then set it up ready to read + the strips. The strips are labeled A to ZZ, and for each strip it + will prompt:
    +
    +     About to read strip XX  :
    +
    + where XX is the strip label, and this is followed by the available + options to navigate, read the strip, or finish. Note that the normal + (forward) direction of strip reading is one that starts at the strip + label.
    +
    + For the DTP51 you should + feed the strip into the instrument, and the microswitch will trigger + the read.
    +
    + For the DTP41 you should + line the appropriate strip up in the machine, and press its button.
    +
    + For the Eye-One Pro you + should set the guide to the appropriate strip, place the instrument + ahead of the first + patch on blank paper, and then press and hold the instruments + button. When you hear a beep from the computer, you can then move + the instrument steadily over the patches, releasing the button after + the instrument is past the last patch. Moving the instrument too + fast or changing speeds may cause a mis-read, or a scan with few + samples read per patch.
    +
    + For the ColorMunki with the + default chart, the patches are the same width as the silver portion + of body (white version), or the textured portion of the body (black + version). Place aperture of the the instrument (located at its + center) in the white space ahead of the first patch, and then press + and hold the instruments button. When you hear a beep from the + computer, you can then move the instrument steadily over the + patches, releasing the button after the instrument is past the last + patch. Moving the instrument too fast or changing speeds may cause a + mis-read, or a scan with few samples read per patch. For the high density ColorMunki chart (printtarg -h), the patches are + arranged so that three rows are exactly the width of the  body + of the instrument. If you are careful you can use this to guide the + center of the instrument over each row, or you may prefer to use + something like a plastic ruler to help guide the instrument.
    +
    + Using the DTP20 or the Eye-One Pro or ColorMunki with a randomized + chart layout, the strip may be scanned from either direction. If a + randomized chart layout has not been used for the Eye-One Pro or ColorMunki, then the chart + should only be read in the one direction (use chartread -B).
    +
    + Note that you may have to check that system alert sounds are enabled + and at a suitable volume to in order to hear the beep prompt. For + the Eye-One Pro and ColorMunki, a second beep will sound after a + successfully read strip, or a double beep will sound,  + indicating a failure or warning that needs attention. See also the + note on Linux in installation.
    +
    + If the strip is read successfully there will be a single "success" + beep, and the line will be followed with:
    +
    +     Ready to read strip  XX  :
    +     Strip read OK
    +
    + If there is an error of some sort there will be a double "fail" + beep, and a message will be issued, and you will be asked whether to + abort the chart reading, or retry the
    + failed strip:
    +
    +     Ready to read strip XX  :
    +     Strip read failed due to misread (Not enough + patches)
    +
    +     Hit Esc to give up, any other key to retry:
    +
    + If you are unable to successfully read a strip after several + retries, you can skip that strip using the 'n' key, and save
    + the chart readings without that strip.
    +
    + If the strip is read successfully, but the patches values don't seem + to be what is expected, you will get a double "fail" beep  and + the following type of warning:
    +
    +     Ready to read strip  XX  :
    +     (Warning) Seem to have read strip  YY  + rather than  XX !
    +     Hit Return to use it anyway, any other key to + retry, Esc, ^C or Q to give up:
    +
    + This could be because you have accidentally read the wrong strip (a + common mistake), or it could be that the device response is so + different from what is expected that warning is erroneous, or you + may get a lot of these sorts of warnings if you are accidentally + reading the wrong chart. You may also get this sort of warning if + you are not using bi-direction reading (chartread -B), and read the + strip from the wrong end.
    + If you are absolutely sure you lined up the correct strip, then hit + return, otherwise line the appropriate strip up again, and hit some + other key (ie. space).
    + Erroneous warnings are less likely if a previous profile for a + device was given to targen + to set more accurate expectations.
    +
    + You may also see the following type of warning:
    +
    +     Ready to read strip  XX  :
    +     (Warning) Patch error YY.YYY (>35 not good, + >95 bad)
    +    There is at least one patch with an very unexpected + response!
    +     Hit Return to use it anyway, any other key to + retry, Esc, ^C or Q to give up:
    +
    + Similar to the previous warning, this indicates that while the right + strip appears to have been read, one of the patch readings is quite + different to what is expected. This may indicate an error of some + sort (ie. damaged test chart, or bad instrument positioning), or may + be erroneous if the actual device response is quite different to the + expectation. Erroneous warnings are less likely if a previous + profile for a device was given to targen + to set more accurate expectations.
    +
    + You can also navigate the next strip to be read using the 'f' key to move forward and the + 'b' keys + to move backwards. The prompt will indicate whether this strip has + already been read or not, or whether all strips have been read. You + can also use 'n' to move + forward to the next unread strip. After each successful reading it + will move forward to the next unread strip. When you are finished, + use the 'd' to indicate + that you are done. You can choose to finish before all the strips + are read, and the patches that have been read will be saved to the + .ti3 file. This is useful if you are unable to read a particular + strip successfully, or if you are unable to finish the chart in one + session, and you can later resume reading the chart by using the chartread -r flag. [You could + resume reading the chart patch by patch using the chartread -r -p if you are + unable to read a strip successfully.]
    +
    + When reading in patch by patch mode, there are a few additional + navigation options, such as F to move forward 10 + patches, B to move + backwards 10 patches, and g + to go to a specific patch.
    +
    + You can abort the whole process at any time by hitting Escape, and + the readings will not be saved.
    +
    +
    +

    X-Y Table instruments

    + When you are using an XY table type instrument, such as a Gretag SpectroScan,  chartread + will first establish communications with the instrument, and then + set it up ready to read the chart. You will be prompted for each + sheet with a message such as:
    +
    +     Please make sure that the white reference is in + slot 1, then
    +     place sheet 1 of 4 on table, then
    +     hit return to continue, Esc to give up
    +
    + After hitting return you will be prompted to line up three squares + on the sheet, one at a time:
    +
    +     Using the XY table controls, locate patch A1 with + the sight,
    +     then hit return to continue, Esc to give up
    +
    + On completing this, the instrument will commence reading each sheet.
    +
    +
    +

    Spot reading instruments

    + When used with a DT22 or SpectroLino or use the patch by + patch reading mode (chartread -p) + with the Eye-One Pro or ColorMunki + instrument, or use the external values mode (chartread -x), chartread will + first establish communications with the instrument, and then set it + up ready to read the patches. The patches are typically labeled by + column A to ZZ, and row 1-999. Each patch will prompt:
    +
    +     Ready to read patch 'XX'  :
    +
    + where XX is the patch label, and this is followed by the available + options to navigate, read the strip, or finish.
    +
    + Place the instrument on the indicated patch, and trigger a reading + using one of the available methods (typically using the instrument + switch of pressing a key).
    +
    + There should be an audible prompt on a successful or failed reading. +
    +
    + Note that you may have to check that system alert sounds are enabled + and at a suitable volume to in order to hear the beep prompt. For + the Eye-One Pro and ColorMunki, a second beep will sound after a + successfully read strip, or a double beep will sound,  + indicating a failure or warning that needs attention. See also the + note on Linux in installation.
    +
    + If the patch is read successfully, the line will be completed with:
    +
    +     Ready to read patch  XX  :
    +     Patch read OK
    +
    + If there is an error of some sort, a message will be issued, and you + will be asked whether to abort the chart reading, or retry the
    + failed patch:
    +
    +     Ready to read patch XX  : read_strip + returned 'Strip misread' (Bad reading)
    +
    +     Strip read failed due to misread
    +     Hit Esc to give up, any other key to retry:
    +
    + You can navigate the next patch to be read using the 'f' key to move forward and the + 'b' keys + to move backwards, while 'F' + and 'B' will move forward + and backwards by 10 patches. The prompt will indicate whether this + patch has already been read or not, or whether all patches have been + read. You can also use 'n' + to move forward to the next unread patch. When you are finished, use + the 'd' to indicate that + you are done. You can choose to finish before all the patches are + read, and they will be saved to the .ti3 file. This is useful if you + are unable to finish the chart in one session, and you can later resume reading the + chart by using the chartread -r + flag.
    +
    + You can abort the whole process at any time by hitting Escape, and + the readings will not be saved.
    +
    + +
    +

    Display Type
    +

    Many of the colorimeters have a display @@ -1264,174 +1264,174 @@ - - type selection parameter. Depending on the instrument, this - may combine two related functions: 1) Changing the measurement mode - to suite either refresh-type, or non-refresh displays, and 2) - Changing the calibration to suite a particular displays spectral - characteristics.
    -
    - A refresh type display uses a technology that presents different - portions of the image at different times, doing so at a high enough - rate that this is normally imperceptible. This time varying - characteristic can interfere with measuring a display color unless - the instrument makes allowances for it, typically by making its - measurement period a multiple of the display refresh period. Display - types that refresh are CRT - (Cathode Ray Tube), Single chip DLP (Digital Light Processing) and - Plasma displays. An example of a non-refresh - display technology is LCD (Liquid Crystal Display), although is a - few cases the back-light illumination may have a low enough - frequency flicker to benefit from the refresh mode.
    -
    - Instruments in which the display type selection only changes the - measurement mode (i.e. i1d3), will typically have some other - independent option to set the calibration type. Simpler instruments - combine the measurement mode with a calibration selections, - typically refresh+CRT and non-refresh+LCD. Some instruments are a - hybrid of both (Spyder4), where the display type can select between - generic refresh/non-refresh that can then use a .CCSS to set the - calibration type, or a combined selection of non-refresh and a - particular display type.
    -
    - See Comparison_of_display_technology - for some background on different display technologies.
    -
    -

    -

    Refresh Rate Measurement

    -

    Most of the colorimeters that have a refresh display type - selection, also have an ability to measure the refresh rate of a - display. Some of the spectrometers also have a display refresh - rate measurement capability when in an emissive measurement mode, - even though they don't use this to support a refresh display mode. - You can do a display refresh rate measurement in spotread using the 'F' key. - The particular instruments have a range of accuracy when making - this measurement. A rough guide is as follows:
    -
    -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    InstrumentTypical error in Hz.
    spectrobos 1211/1201
    -
    0.05
    -
    Klein K10-A
    -
    0.05
    -
    DTP92
    -
    0.1
    -
    i1 Display 2
    -
    0.5
    -
    Spyder 2
    -
    0.7
    -
    Spyder 3
    -
    3
    -
    Spyder 4
    -
    3
    -
    i1 Display Pro
    -
    0.05
    -
    i1 Pro Spectro.
    -
    0.05
    -
    ColorMunki Spectro.
    -
    0.05
    -
    -


    -

    -
    -

    specbos 1211 and 1201 - Tele-Spectro-Radiometer
    -

    - JETI specbos 1211 -


    -
    Availability:
    -
    -
    The specbos 1211 and 1201 from JETI  are currently - available instruments. These are reference grade instruments - capable of emissive and ambient measurements, and are often used - for monitor, projector and cinema calibration & - characterization, lighting measurement and colorimeter - calibration, amongst many other uses.
    -

    -
    -

    Image Engineering EX1
    -

    - Image Engineering EX1
    -

    - Availability:
    -
    -
    The selection parameter. Depending on the instrument, this + may combine two related functions: 1) Changing the measurement mode + to suite either refresh-type, or non-refresh displays, and 2) + Changing the calibration to suite a particular displays spectral + characteristics.
    +
    + A refresh type display uses a technology that presents different + portions of the image at different times, doing so at a high enough + rate that this is normally imperceptible. This time varying + characteristic can interfere with measuring a display color unless + the instrument makes allowances for it, typically by making its + measurement period a multiple of the display refresh period. Display + types that refresh are CRT + (Cathode Ray Tube), Single chip DLP (Digital Light Processing) and + Plasma displays. An example of a non-refresh + display technology is LCD (Liquid Crystal Display), although is a + few cases the back-light illumination may have a low enough + frequency flicker to benefit from the refresh mode.
    +
    + Instruments in which the display type selection only changes the + measurement mode (i.e. i1d3), will typically have some other + independent option to set the calibration type. Simpler instruments + combine the measurement mode with a calibration selections, + typically refresh+CRT and non-refresh+LCD. Some instruments are a + hybrid of both (Spyder4), where the display type can select between + generic refresh/non-refresh that can then use a .CCSS to set the + calibration type, or a combined selection of non-refresh and a + particular display type.
    +
    + See
    Comparison_of_display_technology + for some background on different display technologies.
    +
    +

    +

    Refresh Rate Measurement

    +

    Most of the colorimeters that have a refresh display type + selection, also have an ability to measure the refresh rate of a + display. Some of the spectrometers also have a display refresh + rate measurement capability when in an emissive measurement mode, + even though they don't use this to support a refresh display mode. + You can do a display refresh rate measurement in spotread using the 'F' key. + The particular instruments have a range of accuracy when making + this measurement. A rough guide is as follows:
    +
    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    InstrumentTypical error in Hz.
    spectrobos 1211/1201
    +
    0.05
    +
    Klein K10-A
    +
    0.05
    +
    DTP92
    +
    0.1
    +
    i1 Display 2
    +
    0.5
    +
    Spyder 2
    +
    0.7
    +
    Spyder 3
    +
    3
    +
    Spyder 4
    +
    3
    +
    i1 Display Pro
    +
    0.05
    +
    i1 Pro Spectro.
    +
    0.05
    +
    ColorMunki Spectro.
    +
    0.05
    +
    +


    +

    +
    +

    specbos 1211 and 1201 + Tele-Spectro-Radiometer
    +

    + JETI specbos 1211 +


    +
    Availability:
    +
    +
    The specbos 1211 and 1201 from JETI  are currently + available instruments. These are reference grade instruments + capable of emissive and ambient measurements, and are often used + for monitor, projector and cinema calibration & + characterization, lighting measurement and colorimeter + calibration, amongst many other uses.
    +

    +
    +

    Image Engineering EX1
    +

    + Image Engineering EX1
    +

    + Availability:
    +
    +
    The Image - - Engineering EX1 is a currently available instruments. This is - a high resolution spectrometer intended for the measurement of light - sources. -

    -


    -

    -
    -

    Klein K10-A Colorimeter
    -

    - Klein K10-A
    -


    -
    Availability:
    -
    + + Engineering EX1 is a currently available instruments. This is + a high resolution spectrometer intended for the measurement of light + sources. +

    +


    +

    +
    +

    Klein K10-A Colorimeter
    +

    + Klein K10-A
    +


    +
    Availability:
    +
    The Klein K10-A from @@ -1445,7 +1445,7 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e - + Klein Instruments  @@ -1459,277 +1459,277 @@ 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 - levels.This is a high end instruments capable of contact and tele - - emissive, and ambient measurements, and are often used for - monitor, projector and cinema calibration and characterization.
    -

    -

    Note that unlike the operation of other instruments, the Ambient - mode is purely manual - the diffuser must be fitted and then the - appropriate calibration setting chosen (Typically with "Lux" in - the name).
    -

    -

    By default, more measurements are taken and averaged together - when the light level is low. This can be disabled and a single - measurement taken per reading, to gain maximum speed by using the - -Y A flag.
    -

    -

    The K-1, K-8 and  K-10 are also - reported to work.

    -

    -
    -


    -

    -
    - ColorMunki Design or Photo reflective/emissive spectrometer
    -
    -   
    -
    -
    Availability:
    -
    -
    The ColorMunki Design or Photo from X-Rite  is currently - available in two different packages from the manufacturer. These - packages differ in what features the manufacturers software - provides, as well as cosmetic differences between the instrument - (white and black). This comparison chart - illustrates the differences. Used with Argyll, there are no - differences in operation of a ColorMunki instrument, irrespective of - which package it came with. The ColorMunki Design has the lowest - RRP, but the Photo package may be cheaper with discounting .
    -
    - Limitations & Features:
    -
    - Unlike the Eye-One Pro, the ColorMunki is only available in a U.V. - Cut (ie. "Ultra Violet filtered") model. This means that it is not - suitable for use with the  Fluorescent Whitener Additive - Compensation option in Argyll (see here for - a discussion about what FWA compensation is).
    -
    - Like the Eye-One Pro, this instrument does support the high resolution spectral mode.
    -
    - OS X and X-Rite drivers
    -
    - Please note the installation instructions.
    -
    - Tips & Tricks:
    -
    -
    In handling the instrument when about to make a reading, be - very careful not to accidentally press the switch - it is large and - easily pressed by accident. A guide of some sort (ie. a plastic - ruler) can help a lot in  keeping the instrument over a line - of  patches.
    -
    - Patch recognition:
    -
    - For the best chances of good patch recognition, the instrument - should be drawn smoothly and not too rapidly over the strip. (This - can be a little tricky due to the two small rubber feet on the - bottom of the device that aid its spot reading guide.) If there is a - misread, try slowing down slightly. Generally a higher quality set - of readings will result if slower scans are used, since there will - then be more samples averaged for each patch.
    -
    - In chartread, the -T ratio argument modifies the - patch consistency tolerance threshold for the ColorMunki. In - recognizing patches in a strip, the instrument takes multiple - readings as the strip is read, and then divide the readings up into - each patch. It then check the consistency of the multiple readings - corresponding to each patch, and reject the measurement if they are - too inconsistent. For some media (ie. a coarser screens, fabric - etc.) the default tolerance may be unreasonably tight, so the -T ratio argument can be used to - modify this criteria. To loosen the tolerance, use a number greater - than 1.0 (ie. 1.5, 2.0).
    -
    - Note that printtarg provides the -h option that allows the choice of - two different patch row widths with ColorMunki test charts. [Some - people have successfully used the i1Pro patch layout with the - ColorMunki, by making a guide to keep it over the much narrower - patchs.]
    -
    -
    -
    - -

    -
    DTP20 - "Pulse" reflective spectrometer
    -
    -

    -
    -
    Availability:
    -
    -
    The DTP20 from X-Rite was discontinued during - 2007, but may still be available from old stock or second hand.
    -
    - Special features:
    -
    - The DTP20 has a couple of - unique features that Argyll can take advantage of. One is that it - can operate un-tethered (off line). A whole chart can be read - un-tethered by first clearing any previous readings in the - instrument, then reading the chart TID strip, before reading all the - other strips. The instrument can then be connected up to chartread, which will recognize - the chart, and download all the measurements.
    - If there is no chart in the instrument when chartread connects to - it, then it will use the strip by strip tethered mode, just like the - other strip instruments. If the right number of spot readings are - present in the instrument, these will be used by chartread too.
    -
    - Un-tethered spot measurements can also be read in using  spotread, which will notice the - stored readings, and offer to print them out, or they can be - ignored, and tethered readings taken. This will clear any saved spot - readings.
    -
    - Note that tethered (on-line) - strip reading will only work if the firmware in the device is - version 1.03 or greater. You can check the firmware version by - running with the verbose option: -v
    -
    - Chart printing:
    -
    -
    Because the DTP20 measures exact distances using the - markings on its ruler, it's critical that the chart be printed out - exactly the right size. If the chart gets re-sized at all in the - process of printing it, the DTP20 is likely to fail in reading it. - If you have a problem with this, you might want to increase the page - margins using the printtarg -m - parameter, or find a printing path that preserves the test chart - size correctly.
    -
    - Operation:
    -
    -
    When reading in tethered (on-line) mode, that the instrument - takes several seconds to - download the measurements after each strip, and that the indicator - will be in "rainbow" mode while this occurs. Wait until the - indicator turns solid green again before starting to measure the - next strip.
    -
    - To reset the instrument and - clear any stored readings: press the button three times in quick - succession. The indicator will turn solid blue. Then hold the button - down until the instrument beeps and the indicator goes out. Release - the button and the indicator should flash then return to solid green - (ready).
    -
    - To calibrate the - instrument, place it on its calibration tile, then press the button - three times in quick succession.The indicator will turn solid blue. - Click the button another three times in quick succession, and the - indicator should turn yellow. Then hold the button down until the - instrument beeps and the indicator goes out. Release the button and - the instrument should flash and then turn solid green.
    -
    - If the chart is particularly small, - the patches may end up printed very close to the edge of the chart, - and therefore it may be difficult to confine your scan to the chart, - and passing
    - the instrument over the edge of the chart may prevent it reading - successfully. One way of working around this is to place the chart - on a larger piece of paper of the same type.
    -
    - The speed of scan can be - quite critical with this instrument. In particular, it doesn't work - very well if the scan is too slow. - You don't want to go too fast either, as this reduces the number of - samples per patch.
    -
    -
    - -

    -
    DTP22 - Digital Swatchbook reflective spectrometer
    -
    -
    -
    -
    Availability:
    -
    -
    The DTP22 from X-Rite is a discontinued - instrument.  It may still be available second hand. It is - capable of reading colored patches one at a time.
    -
    -
    - -

    - DTP41 reflective, DTP41T - reflective/transmissive spectrometers
    -
    -
    -
    -
    Availability:
    -
    -
    The DTP41 and DTP41T from X-Rite is a discontinued - instrument.  It may still be available second hand.
    -
    - The series II instruments (DTP41B - and DTP41TB) offer both - serial and USB connection. Note that currently only serial operation - using Argyll is possible with these instruments.
    -
    -

    - DTP51 - reflective colorimeter
    -
    -
    -
    -
    Availability:
    -
    -
    The DTP51 from X-Rite is a discontinued - instrument.  It may still be available second hand.
    -
    - Operation:
    -
    -
    The DTP51's switch is triggered by inserting a strip - into the slot.
    -
    -
    - -

    - DTP92 CRT display colorimeter
    -
    -
    -
    -
    Availability:
    -
    -
    The DTP92 from X-Rite is a discontinued - instrument.  It may still be available second hand. It will - only read CRT technology displays.
    -
    - Operation:
    -
    - The Display Selections for this instrument are:
    -
    + + is a currently available instrument. It is noted for it's speed, + high precision, and ability to measure to very low light + levels.This is a high end instruments capable of contact and tele + - emissive, and ambient measurements, and are often used for + monitor, projector and cinema calibration and characterization.
    +

    +

    Note that unlike the operation of other instruments, the Ambient + mode is purely manual - the diffuser must be fitted and then the + appropriate calibration setting chosen (Typically with "Lux" in + the name).
    +

    +

    By default, more measurements are taken and averaged together + when the light level is low. This can be disabled and a single + measurement taken per reading, to gain maximum speed by using the + -Y A flag.
    +

    +

    The K-1, K-8 and  K-10 are also + reported to work.

    +

    +
    +


    +

    +
    + ColorMunki Design or Photo reflective/emissive spectrometer
    +
    +   
    +
    +
    Availability:
    +
    +
    The ColorMunki Design or Photo from X-Rite  is currently + available in two different packages from the manufacturer. These + packages differ in what features the manufacturers software + provides, as well as cosmetic differences between the instrument + (white and black). This comparison chart + illustrates the differences. Used with Argyll, there are no + differences in operation of a ColorMunki instrument, irrespective of + which package it came with. The ColorMunki Design has the lowest + RRP, but the Photo package may be cheaper with discounting .
    +
    + Limitations & Features:
    +
    + Unlike the Eye-One Pro, the ColorMunki is only available in a U.V. + Cut (ie. "Ultra Violet filtered") model. This means that it is not + suitable for use with the  Fluorescent Whitener Additive + Compensation option in Argyll (see here for + a discussion about what FWA compensation is).
    +
    + Like the Eye-One Pro, this instrument does support the high resolution spectral mode.
    +
    + OS X and X-Rite drivers
    +
    + Please note the installation instructions.
    +
    + Tips & Tricks:
    +
    +
    In handling the instrument when about to make a reading, be + very careful not to accidentally press the switch - it is large and + easily pressed by accident. A guide of some sort (ie. a plastic + ruler) can help a lot in  keeping the instrument over a line + of  patches.
    +
    + Patch recognition:
    +
    + For the best chances of good patch recognition, the instrument + should be drawn smoothly and not too rapidly over the strip. (This + can be a little tricky due to the two small rubber feet on the + bottom of the device that aid its spot reading guide.) If there is a + misread, try slowing down slightly. Generally a higher quality set + of readings will result if slower scans are used, since there will + then be more samples averaged for each patch.
    +
    + In chartread, the -T ratio argument modifies the + patch consistency tolerance threshold for the ColorMunki. In + recognizing patches in a strip, the instrument takes multiple + readings as the strip is read, and then divide the readings up into + each patch. It then check the consistency of the multiple readings + corresponding to each patch, and reject the measurement if they are + too inconsistent. For some media (ie. a coarser screens, fabric + etc.) the default tolerance may be unreasonably tight, so the -T ratio argument can be used to + modify this criteria. To loosen the tolerance, use a number greater + than 1.0 (ie. 1.5, 2.0).
    +
    + Note that printtarg provides the -h option that allows the choice of + two different patch row widths with ColorMunki test charts. [Some + people have successfully used the i1Pro patch layout with the + ColorMunki, by making a guide to keep it over the much narrower + patchs.]
    +
    +
    +
    + +

    +
    DTP20 + "Pulse" reflective spectrometer
    +
    +

    +
    +
    Availability:
    +
    +
    The DTP20 from X-Rite was discontinued during + 2007, but may still be available from old stock or second hand.
    +
    + Special features:
    +
    + The DTP20 has a couple of + unique features that Argyll can take advantage of. One is that it + can operate un-tethered (off line). A whole chart can be read + un-tethered by first clearing any previous readings in the + instrument, then reading the chart TID strip, before reading all the + other strips. The instrument can then be connected up to chartread, which will recognize + the chart, and download all the measurements.
    + If there is no chart in the instrument when chartread connects to + it, then it will use the strip by strip tethered mode, just like the + other strip instruments. If the right number of spot readings are + present in the instrument, these will be used by chartread too.
    +
    + Un-tethered spot measurements can also be read in using  spotread, which will notice the + stored readings, and offer to print them out, or they can be + ignored, and tethered readings taken. This will clear any saved spot + readings.
    +
    + Note that tethered (on-line) + strip reading will only work if the firmware in the device is + version 1.03 or greater. You can check the firmware version by + running with the verbose option: -v
    +
    + Chart printing:
    +
    +
    Because the DTP20 measures exact distances using the + markings on its ruler, it's critical that the chart be printed out + exactly the right size. If the chart gets re-sized at all in the + process of printing it, the DTP20 is likely to fail in reading it. + If you have a problem with this, you might want to increase the page + margins using the printtarg -m + parameter, or find a printing path that preserves the test chart + size correctly.
    +
    + Operation:
    +
    +
    When reading in tethered (on-line) mode, that the instrument + takes several seconds to + download the measurements after each strip, and that the indicator + will be in "rainbow" mode while this occurs. Wait until the + indicator turns solid green again before starting to measure the + next strip.
    +
    + To reset the instrument and + clear any stored readings: press the button three times in quick + succession. The indicator will turn solid blue. Then hold the button + down until the instrument beeps and the indicator goes out. Release + the button and the indicator should flash then return to solid green + (ready).
    +
    + To calibrate the + instrument, place it on its calibration tile, then press the button + three times in quick succession.The indicator will turn solid blue. + Click the button another three times in quick succession, and the + indicator should turn yellow. Then hold the button down until the + instrument beeps and the indicator goes out. Release the button and + the instrument should flash and then turn solid green.
    +
    + If the chart is particularly small, + the patches may end up printed very close to the edge of the chart, + and therefore it may be difficult to confine your scan to the chart, + and passing
    + the instrument over the edge of the chart may prevent it reading + successfully. One way of working around this is to place the chart + on a larger piece of paper of the same type.
    +
    + The speed of scan can be + quite critical with this instrument. In particular, it doesn't work + very well if the scan is too slow. + You don't want to go too fast either, as this reduces the number of + samples per patch.
    +
    +
    + +

    +
    DTP22 + Digital Swatchbook reflective spectrometer
    +
    +
    +
    +
    Availability:
    +
    +
    The DTP22 from X-Rite is a discontinued + instrument.  It may still be available second hand. It is + capable of reading colored patches one at a time.
    +
    +
    + +

    + DTP41 reflective, DTP41T + reflective/transmissive spectrometers
    +
    +
    +
    +
    Availability:
    +
    +
    The DTP41 and DTP41T from X-Rite is a discontinued + instrument.  It may still be available second hand.
    +
    + The series II instruments (DTP41B + and DTP41TB) offer both + serial and USB connection. Note that currently only serial operation + using Argyll is possible with these instruments.
    +
    +

    + DTP51 + reflective colorimeter
    +
    +
    +
    +
    Availability:
    +
    +
    The DTP51 from X-Rite is a discontinued + instrument.  It may still be available second hand.
    +
    + Operation:
    +
    +
    The DTP51's switch is triggered by inserting a strip + into the slot.
    +
    +
    + +

    + DTP92 CRT display colorimeter
    +
    +
    +
    +
    Availability:
    +
    +
    The DTP92 from X-Rite is a discontinued + instrument.  It may still be available second hand. It will + only read CRT technology displays.
    +
    + Operation:
    +
    + The Display Selections for this instrument are:
    +
        c    @@ -1777,33 +1777,33 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e - - CRT display         A Cathode Ray - Tube display, that is of the Refresh type [Default, CB2].
    -
    -

    - DTP94, "Optix XR" or "Optix XR2" or "Optix Pro" display colorimetrers
    -
    -             -    
    -
    -
    Availability:
    -
    -
    The DTP94 from X-Rite is a discontinued - instrument, although it is still being supplied to OEMs.  It - may still be available as old stock, or second hand. It was sold as - an instrument without software as the DTP94, and packaged with - software from the manufacturer as the "Optix XR" range.
    -
    - Operation:
    -
    - The Display Selections for this instrument are:
    -
    + + CRT display         A Cathode Ray + Tube display, that is of the Refresh type [Default, CB2].
    +
    +

    + DTP94, "Optix XR" or "Optix XR2" or "Optix Pro" display colorimetrers
    +
    +             +    
    +
    +
    Availability:
    +
    +
    The DTP94 from X-Rite is a discontinued + instrument, although it is still being supplied to OEMs.  It + may still be available as old stock, or second hand. It was sold as + an instrument without software as the DTP94, and packaged with + software from the manufacturer as the "Optix XR" range.
    +
    + Operation:
    +
    + The Display Selections for this instrument are:
    +
        l     @@ -1846,9 +1846,9 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e - - LCD display         A Liquid - Crystal Display, that is of the Non-Refresh type [default, CB1].
    + + LCD display         A Liquid + Crystal Display, that is of the Non-Refresh type [default, CB1].
        c    @@ -1896,24 +1896,24 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e - - CRT display         A Cathode Ray - Tube display, that is of the Refresh type [CB2].
    -     g    - Generic    -            Generic - display [CB3]
    -   
    -
    - -

    - Spectrolino reflective/emissive spectrometer
    -
    -
    -
    -
    Availability:
    -
    + + CRT display         A Cathode Ray + Tube display, that is of the Refresh type [CB2].
    +     g    + Generic    +            Generic + display [CB3]
    +   
    +
    + +

    + Spectrolino reflective/emissive spectrometer
    +
    +
    +
    +
    Availability:
    +
    The Spectrolino from Gretag @@ -1962,226 +1962,226 @@ Gretag - - MacBeth (Now X-Rite) is a discontinued instrument. It is often - available second hand. If buying it second hand, make sure it comes - with all it's accessories, including white reference, spot reading - adapter, display reading adapters, filters (UV, polarizing, D65), - serial cable adapter and power supply.
    -
    -
    -

    - SpectroScan reflective/emissive and SpectroScanT - reflective/emissive/transmissive spectrometers
    -
    -
    -
    -
    Availability:
    -
    -
    The SpectroScan and - SpectroScanT from Gretag - MacBeth (Now X-Rite) is a discontinued instrument. It is the - combination of an X-Y table and the Spectrolino instrument. The SpectroScanT is capable of - measuring transparency. It is often available second hand. If buying - it second hand, make sure it comes with all it's accessories, - including white reference, spot reading adapter, display reading - adapters, filters (UV, polarizing, D65) and power supply.
    -
    - If measuring transparencies using a SpectroScanT, the Enter - key on the instrument may be used to trigger each reading. It will - be recognized after each previous reading has been completed.
    -
    -

    -
    - Eye-One Pro2:
    - Eye-One Pro 2
    -
    - There is support for some of the new features of the Eye-One Pro2 - (also known as the Eye-One Pro Rev E), in particular the  Rev E - measurement mode, spectrometer stray light reduction, wavelength - calibration, and improved black level tracking. This new support can - be disabled and an Eye-One Pro2 operated in legacy mode by setting - the environment variable ARGYLL_DISABLE_I1PRO2_DRIVER. See Eye-One Pro reflective/emissive - spectrometer below - for details on the operation of this type of instrument.
    -
    -

    - Eye-One Pro and - Eye-One Pro2 reflective/emissive spectrometer
    -
    -
    -
    -
    Availability:
    -
    -
    The Eye-One Pro from - X-Rite (was Gretag MacBeth) is - available in two packages from the manufacturer. These packages - differ partly in what accessories come with the instrument, but - primarily in what features the manufacturers software provides. This - comparison chart - illustrates the differences. Used with Argyll, there are no - differences in operation of an Eye-One Pro instrument, irrespective - of which package it came with. The lowest cost package is the i1 Basic - Pro.
    -
    - The EFI ES-1000 (which is a re-badged Eye-One Pro) is also reported - to work with Argyll.
    -
    - Unless you know what you're doing, and have a very specific reason - to buy an instrument fitted with a UV (Ultra Violet) filter, make - sure that you buy an instrument without the filter. A UV filtered - instrument can't deal intelligently with FWA (Fluorescent Whitener - Additive) effects in paper. (Look here for - more information about FWA compensation.) Using FWA compensation you - can make measurements using ISO 13655:2009 M0, M1 and M2 conditions. - The M2 condition emulates a UV cut instrument.
    -
    - There have been four revisions of the Eye-One Pro, Rev. A, B, D and - E (AKA Eye-One Pro2). The rev B, D and E are capable of sampling - twice as fast as the Rev. A version of the instrument, and are also - available with an ambient light reading capability.
    -
    - NOTE for those running on - older versions of Linux with a Rev. D, there was a problem with the - Linux USB stack that causes the instrument to stop working once it - has been used. The only workaround is to unplug and replug the - instrument in again, whereupon it can be used one time again. A fix - for this problem was in the  Linux 2.6.26 kernel release.
    -
    - See also How can I have confidence in - the i1pro Driver ?
    -
    - Patch recognition:
    -
    - For the best chances of good patch recognition, the instrument - should be drawn smoothly and not too rapidly over the strip. If - there is a misread, try slowing down slightly. The Rev A and B. - instruments have a slower sampling rate than the latter revision - instruments, and hence must be used a bit more slowly. Generally a - higher quality set of readings will result if slower scans are used, - since there will then be more samples averaged for each patch.
    -
    - In chartread, the -T ratio argument modifies the - patch consistency tolerance threshold for the Eye-One Pro. In - recognizing patches in a strip, the instrument takes multiple - readings as the strip is read, and then divide the readings up into - each patch. It then check the consistency of the multiple readings - corresponding to each patch, and reject the measurement if they are - too inconsistent. For some media (ie. a coarser screens, fabric - etc.) the default tolerance may be unreasonably tight, so the -T ratio argument can be used to - modify this criteria. To loosen the tolerance, use a number greater - than 1.0 (ie. 1.5, 2.0).
    -
    - Special features:
    -
    - A feature unique to Argyll when used with the Eye-One Pro, is the - high resolution spectral mode. This returns spectral measurements at - 3.333 nm spacing, rather than the default 10nm spacing, and also - extends the range of wavelengths very slightly. This high resolution - may assist in giving better accuracy for "peaky" emissive sources - such as illuminants and displays. The high resolution mode is - selected by using the -H - flag on the command line to dispcal, - dispread, chartread, and spotread. It can also be toggled - on and off within spotread - using the h key.
    -
    - Note that while finer spectral resolution will worsen the signal to - noise ratio of the individual spectral values, the signal to noise - ratio of the resulting tri-stimulus color values will be identical - to normal resolution mode, since the same overall integration is - performed.
    -
    - See Does the i1pro High Resolution mode - improve accuracy ?
    -
    - High res. and standard res. spectrum.
    -
    - C.R.T high res. and standard res. spectrum.
    -
    -

    - Eye-One Monitor - emissive spectrometer
    -
    -
    -
    -
    Availability:
    -
    -
    The Eye-One Monitor - from X-Rite (was Gretag - MacBeth) is a discontinued instrument. It was a lower cost version - of the Eye-One Pro without - reflective measurement capability. See Eye-One Pro - reflective/emissive spectrometer for details on the operation of this instrument.
    -
    -
    -

    - Eye-One Display - 1, Eye-One Display 2, Eye-One Display LT, ColorMunki Create, - ColorMunki Smile colorimeters,
    -
    - ColorMunki SmileEye-One Display 2 ColorMunki Create
    -
    - Instrument Availability:
    -
    -
    The ColorMunki Smile - colorimeter is a currently available instrument.
    - The Eye-One Display LT and - Eye-One Display 2 are - discontinued products, although they may still be available from - some retailers, second hand, and may still be shipped with some - displays as part of their calibration capability.
    - The ColorMunki Create - colorimeter is a discontinued product, although they may still be - available from some retailers or second hand,can also be used. They - will appear as an i1Display2 colorimeter.
    - The HP DreamColor - colorimeter can also be used, and will appear as an i1Display2 - colorimeter [note that it is calibrated for the DreamColor display].
    - The HP APS (Advanced - Profiling Solution) colorimeter is also reported to work, and will - appear as an i1Display2.
    - The CalMAN X2 colorimeter - is also reported to work, and will appear as an i1Display2 - colorimeter.
    - The  Lacie Blue Eye colorimeter is also reported to - work, and will appear as an i1Display2 colorimeter.
    -
    - The Eye-One Display 1 is a - discontinued instrument.
    -
    - The Eye-One Display LT came with a less expensive package with more - limited software from the manufacture.
    - The Eye-One Display 2 package came with more software - features,  but the instruments are virtually identical, and - will operate identically using Argyll.
    - The ColorMunki Create - package is another alternative, and will operate identically using - Argyll.
    -
    - Operation:
    -
    + + MacBeth (Now X-Rite) is a discontinued instrument. It is often + available second hand. If buying it second hand, make sure it comes + with all it's accessories, including white reference, spot reading + adapter, display reading adapters, filters (UV, polarizing, D65), + serial cable adapter and power supply.
    +
    +
    +

    + SpectroScan reflective/emissive and SpectroScanT + reflective/emissive/transmissive spectrometers
    +
    +
    +
    +
    Availability:
    +
    +
    The SpectroScan and + SpectroScanT from Gretag + MacBeth (Now X-Rite) is a discontinued instrument. It is the + combination of an X-Y table and the Spectrolino instrument. The SpectroScanT is capable of + measuring transparency. It is often available second hand. If buying + it second hand, make sure it comes with all it's accessories, + including white reference, spot reading adapter, display reading + adapters, filters (UV, polarizing, D65) and power supply.
    +
    + If measuring transparencies using a SpectroScanT, the Enter + key on the instrument may be used to trigger each reading. It will + be recognized after each previous reading has been completed.
    +
    +

    +
    + Eye-One Pro2:
    + Eye-One Pro 2
    +
    + There is support for some of the new features of the Eye-One Pro2 + (also known as the Eye-One Pro Rev E), in particular the  Rev E + measurement mode, spectrometer stray light reduction, wavelength + calibration, and improved black level tracking. This new support can + be disabled and an Eye-One Pro2 operated in legacy mode by setting + the environment variable ARGYLL_DISABLE_I1PRO2_DRIVER. See Eye-One Pro reflective/emissive + spectrometer below + for details on the operation of this type of instrument.
    +
    +

    + Eye-One Pro and + Eye-One Pro2 reflective/emissive spectrometer
    +
    +
    +
    +
    Availability:
    +
    +
    The Eye-One Pro from + X-Rite (was Gretag MacBeth) is + available in two packages from the manufacturer. These packages + differ partly in what accessories come with the instrument, but + primarily in what features the manufacturers software provides. This + comparison chart + illustrates the differences. Used with Argyll, there are no + differences in operation of an Eye-One Pro instrument, irrespective + of which package it came with. The lowest cost package is the i1 Basic + Pro.
    +
    + The EFI ES-1000 (which is a re-badged Eye-One Pro) is also reported + to work with Argyll.
    +
    + Unless you know what you're doing, and have a very specific reason + to buy an instrument fitted with a UV (Ultra Violet) filter, make + sure that you buy an instrument without the filter. A UV filtered + instrument can't deal intelligently with FWA (Fluorescent Whitener + Additive) effects in paper. (Look here for + more information about FWA compensation.) Using FWA compensation you + can make measurements using ISO 13655:2009 M0, M1 and M2 conditions. + The M2 condition emulates a UV cut instrument.
    +
    + There have been four revisions of the Eye-One Pro, Rev. A, B, D and + E (AKA Eye-One Pro2). The rev B, D and E are capable of sampling + twice as fast as the Rev. A version of the instrument, and are also + available with an ambient light reading capability.
    +
    + NOTE for those running on + older versions of Linux with a Rev. D, there was a problem with the + Linux USB stack that causes the instrument to stop working once it + has been used. The only workaround is to unplug and replug the + instrument in again, whereupon it can be used one time again. A fix + for this problem was in the  Linux 2.6.26 kernel release.
    +
    + See also How can I have confidence in + the i1pro Driver ?
    +
    + Patch recognition:
    +
    + For the best chances of good patch recognition, the instrument + should be drawn smoothly and not too rapidly over the strip. If + there is a misread, try slowing down slightly. The Rev A and B. + instruments have a slower sampling rate than the latter revision + instruments, and hence must be used a bit more slowly. Generally a + higher quality set of readings will result if slower scans are used, + since there will then be more samples averaged for each patch.
    +
    + In chartread, the -T ratio argument modifies the + patch consistency tolerance threshold for the Eye-One Pro. In + recognizing patches in a strip, the instrument takes multiple + readings as the strip is read, and then divide the readings up into + each patch. It then check the consistency of the multiple readings + corresponding to each patch, and reject the measurement if they are + too inconsistent. For some media (ie. a coarser screens, fabric + etc.) the default tolerance may be unreasonably tight, so the -T ratio argument can be used to + modify this criteria. To loosen the tolerance, use a number greater + than 1.0 (ie. 1.5, 2.0).
    +
    + Special features:
    +
    + A feature unique to Argyll when used with the Eye-One Pro, is the + high resolution spectral mode. This returns spectral measurements at + 3.333 nm spacing, rather than the default 10nm spacing, and also + extends the range of wavelengths very slightly. This high resolution + may assist in giving better accuracy for "peaky" emissive sources + such as illuminants and displays. The high resolution mode is + selected by using the -H + flag on the command line to dispcal, + dispread, chartread, and spotread. It can also be toggled + on and off within spotread + using the h key.
    +
    + Note that while finer spectral resolution will worsen the signal to + noise ratio of the individual spectral values, the signal to noise + ratio of the resulting tri-stimulus color values will be identical + to normal resolution mode, since the same overall integration is + performed.
    +
    + See Does the i1pro High Resolution mode + improve accuracy ?
    +
    + High res. and standard res. spectrum.
    +
    + C.R.T high res. and standard res. spectrum.
    +
    +

    + Eye-One Monitor + emissive spectrometer
    +
    +
    +
    +
    Availability:
    +
    +
    The Eye-One Monitor + from X-Rite (was Gretag + MacBeth) is a discontinued instrument. It was a lower cost version + of the Eye-One Pro without + reflective measurement capability. See Eye-One Pro + reflective/emissive spectrometer for details on the operation of this instrument.
    +
    +
    +

    + Eye-One Display + 1, Eye-One Display 2, Eye-One Display LT, ColorMunki Create, + ColorMunki Smile colorimeters,
    +
    + ColorMunki SmileEye-One Display 2 ColorMunki Create
    +
    + Instrument Availability:
    +
    +
    The ColorMunki Smile + colorimeter is a currently available instrument.
    + The Eye-One Display LT and + Eye-One Display 2 are + discontinued products, although they may still be available from + some retailers, second hand, and may still be shipped with some + displays as part of their calibration capability.
    + The ColorMunki Create + colorimeter is a discontinued product, although they may still be + available from some retailers or second hand,can also be used. They + will appear as an i1Display2 colorimeter.
    + The HP DreamColor + colorimeter can also be used, and will appear as an i1Display2 + colorimeter [note that it is calibrated for the DreamColor display].
    + The HP APS (Advanced + Profiling Solution) colorimeter is also reported to work, and will + appear as an i1Display2.
    + The CalMAN X2 colorimeter + is also reported to work, and will appear as an i1Display2 + colorimeter.
    + The  Lacie Blue Eye colorimeter is also reported to + work, and will appear as an i1Display2 colorimeter.
    +
    + The Eye-One Display 1 is a + discontinued instrument.
    +
    + The Eye-One Display LT came with a less expensive package with more + limited software from the manufacture.
    + The Eye-One Display 2 package came with more software + features,  but the instruments are virtually identical, and + will operate identically using Argyll.
    + The ColorMunki Create + package is another alternative, and will operate identically using + Argyll.
    +
    + Operation:
    +
    The Display Selections for the ColorMunki @@ -2214,13 +2214,13 @@ Gretag - - Smile are:
    -
    -     f -    LCD with CCFL back-light    -      A Liquid Crystal display that uses a Cold - Cathode Fluorescent back lighting. [Default, CB1]
    + + Smile
    are:
    +
    +     f +    LCD with CCFL back-light    +      A Liquid Crystal display that uses a Cold + Cathode Fluorescent back lighting. [Default, CB1]
        e    @@ -2251,13 +2251,13 @@ Gretag - - LCD with LED back-light    -       A Liquid Crystal display that uses - Light Emitting Diode back lighting.
    -
    - other instruments will offer:
    -
    + + LCD with LED back-light    +       A Liquid Crystal display that uses + Light Emitting Diode back lighting.
    +
    + other instruments will offer:
    +
        l     @@ -2305,9 +2305,9 @@ Gretag - - LCD display         A Liquid - Crystal Display, that is of the Non-Refresh type. [Default, CB1]
    + + LCD display         A Liquid + Crystal Display, that is of the Non-Refresh type. [Default, CB1]
        c    @@ -2355,55 +2355,55 @@ Gretag - - CRT display          A - Cathode Ray Tube display, that is of the Refresh type. [CB2]
    -
    -
    -

    -   i1 DisplayPro and ColorMunki Display colorimeters (i1 Display 3)
    -
    - i1 Display Pro ColorMunki Display
    -
    - Instrument Availability:
    -
    -
    Both instruments are currently available..
    -
    - The ColorMunki Display is a less expensive package - with more limited software from the manufacture, and takes a - noticeably longer time to make most measurements (a minimum of 1 - second), but both instruments will take longer for very dark - samples, and under these conditions the speed difference is less - significant.
    -
    - The i1Display Pro package - comes with i1Profiler, and the instrument is generally faster than - the ColorMunki Display, but other than this and the software - package, the instruments appear to be virtually identical. (Note - though that the ColorMunki Display is unable to measure the - refresh period, so is less repeatable in this mode than the - i1Display Pro).
    -
    - Both instruments are capable of using CCSS (Colorimeter Calibration Spectral - Sample) files, and this also gives the instrument the - capability of using a non-default standard observer. CCSS files can - be created using the ccxxmake tool, and - installed or translated from the .EDR files that are provided with - the instrument CD using the oeminst - utility using a spectrometer as a reference.
    -
    - There are some OEM versions of this instrument around too, and the SpectraCal OEM i1Display, ChromaPure, NEC - SpectraSensor Pro and +
    +
    +

    +
      i1 DisplayPro and ColorMunki Display colorimeters (i1 Display 3)
    +
    + i1 Display Pro ColorMunki Display
    +
    + Instrument Availability:
    +
    +
    Both instruments are currently available..
    +
    + The ColorMunki Display is a less expensive package + with more limited software from the manufacture, and takes a + noticeably longer time to make most measurements (a minimum of 1 + second), but both instruments will take longer for very dark + samples, and under these conditions the speed difference is less + significant.
    +
    + The i1Display Pro package + comes with i1Profiler, and the instrument is generally faster than + the ColorMunki Display, but other than this and the software + package, the instruments appear to be virtually identical. (Note + though that the ColorMunki Display is unable to measure the + refresh period, so is less repeatable in this mode than the + i1Display Pro).
    +
    + Both instruments are capable of using CCSS (Colorimeter Calibration Spectral + Sample) files, and this also gives the instrument the + capability of using a non-default standard observer. CCSS files can + be created using the ccxxmake tool, and + installed or translated from the .EDR files that are provided with + the instrument CD using the oeminst + utility using a spectrometer as a reference.
    +
    + There are some OEM versions of this instrument around too, and the SpectraCal OEM i1Display, ChromaPure, NEC + SpectraSensor Pro and HP @@ -2424,84 +2424,84 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - - DreamColor instruments are also reported to work. They will - appear as a be a the same as the i1Display Pro.
    - [Note that if you have an - OEM version of this instrument, it's worth checking if they come - with any extra .edr files, that can then be translated for use with - ArgyllCMS using oeminst.]
    -
    - On MSWindows, if you have installed the Manufacturers applications, - you may have to shut the i1Profiler tray application down before - Argyll can open the instrument.
    -
    - Operation:
    -
    - The Display Selections for this instrument are:
    -
    -     n     A - non-refresh type display [Default, CB1].
    -     r -     A refresh type display  - The refresh period - is measured, and the integration time adjusted appropriately. [CB2]
    -
    - With the manufacturers .edr files & reference Argyll .ccss files - installed, the following selections are:
    -
    -     n      A - non-refresh type display [Default, CB1].
    -     r -      A refresh type display  - The refresh - period is measured, and the integration time adjusted appropriately. - [CB2]
    -     c      CRT - (Hitachi CM2112MET, Diamond View 1772ie)
    -     l       LCD CCFL - IPS (CCFL AC EIZO HP with CORRECTION)
    -     L      LCD CCFL - Wide Gamut IPS (WG CCFL NEC241 271)
    -          LCD RGB - LED IPS (RGBLED HP SOYO)
    -     e      LCD White - LED IPS (WLED AC LG Samsung)
    -     p      Projector - (Marantz HP Panasonic Projectors Hybrid EDR)
    -
    - By default the integration time is adaptive, taking longer when the - light level is low. This can be disabled and a fixed integration - time used to gain maximum speed at the cost of greatly reduced low - light accuracy, by using the -Y A flag.
    -
    - Note when measuring CRT displays:
    -

    - The small magnet in the ambient light cover used to signal what - position it is in, can interfere in the operation of the CRT - display, particularly if the ambient cover is in it's natural - position at 180 degrees away from the measuring lens. One way of - minimizing this is to swing the cover down so that it touches the - display adjacent to the lens, thereby moving the magnet away from - the display surface. A more thorough but inconvenient way of - avoiding this problem is to unclip the ambient light cover and slide - it down the cable.
    -
    -

    - Huey colorimeter
    -
    -
    -
    - Availability:
    -
    -
    The Huey and Huey - Pro are discontinued instruments. They may still be available - as old stock, or second hand.
    -
    - Operation:
    -
    - The Display Selections for this instrument are:
    -
    + + DreamColor instruments are also reported to work. They will + appear as a be a the same as the i1Display Pro.
    + [Note that if you have an + OEM version of this instrument, it's worth checking if they come + with any extra .edr files, that can then be translated for use with + ArgyllCMS using oeminst.]
    +
    + On MSWindows, if you have installed the Manufacturers applications, + you may have to shut the i1Profiler tray application down before + Argyll can open the instrument.
    +
    + Operation:
    +
    + The Display Selections for this instrument are:
    +
    +     n     A + non-refresh type display [Default, CB1].
    +     r +     A refresh type display  - The refresh period + is measured, and the integration time adjusted appropriately. [CB2]
    +
    + With the manufacturers .edr files & reference Argyll .ccss files + installed, the following selections are:
    +
    +     n      A + non-refresh type display [Default, CB1].
    +     r +      A refresh type display  - The refresh + period is measured, and the integration time adjusted appropriately. + [CB2]
    +     c      CRT + (Hitachi CM2112MET, Diamond View 1772ie)
    +     l       LCD CCFL + IPS (CCFL AC EIZO HP with CORRECTION)
    +     L      LCD CCFL + Wide Gamut IPS (WG CCFL NEC241 271)
    +          LCD RGB + LED IPS (RGBLED HP SOYO)
    +     e      LCD White + LED IPS (WLED AC LG Samsung)
    +     p      Projector + (Marantz HP Panasonic Projectors Hybrid EDR)
    +
    + By default the integration time is adaptive, taking longer when the + light level is low. This can be disabled and a fixed integration + time used to gain maximum speed at the cost of greatly reduced low + light accuracy, by using the -Y A flag.
    +
    + Note when measuring CRT displays:
    +

    + The small magnet in the ambient light cover used to signal what + position it is in, can interfere in the operation of the CRT + display, particularly if the ambient cover is in it's natural + position at 180 degrees away from the measuring lens. One way of + minimizing this is to swing the cover down so that it touches the + display adjacent to the lens, thereby moving the magnet away from + the display surface. A more thorough but inconvenient way of + avoiding this problem is to unclip the ambient light cover and slide + it down the cable.
    +
    +

    + Huey colorimeter
    +
    +
    +
    + Availability:
    +
    +
    The Huey and Huey + Pro are discontinued instruments. They may still be available + as old stock, or second hand.
    +
    + Operation:
    +
    + The Display Selections for this instrument are:
    +
        l     @@ -2549,9 +2549,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - - LCD display         A Liquid - Crystal Display, that is of the Non-Refresh type. [Default, CB1]
    + + LCD display         A Liquid + Crystal Display, that is of the Non-Refresh type. [Default, CB1]
        c    @@ -2599,34 +2599,34 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - - CRT display         A Cathode Ray - Tube display, that is of the Refresh type. [CB2]
    -
    -
    -

    - MonacoOPTIX - colorimeters
    -
    - -          
    -
    - Instrument Availability:
    -

    - Availability:
    -
    -
    The MonacoOPTIX from - Monaco Soft is a discontinued instrument.  It may still be - available as old stock, or second hand. It was sold packaged with - software from the manufacturer. The Sequel Chroma 4 appears to be a - similar instrument, and both seem to operate as if they were an - Eye-One Display 1 using Argyll.
    -
    - Operation:
    -
    - The Display Selections for this instrument are:
    -
    + + CRT display         A Cathode Ray + Tube display, that is of the Refresh type. [CB2]
    +
    +
    +

    + MonacoOPTIX + colorimeters
    +
    + +          
    +
    + Instrument Availability:
    +

    + Availability:
    +
    +
    The MonacoOPTIX from + Monaco Soft is a discontinued instrument.  It may still be + available as old stock, or second hand. It was sold packaged with + software from the manufacturer. The Sequel Chroma 4 appears to be a + similar instrument, and both seem to operate as if they were an + Eye-One Display 1 using Argyll.
    +
    + Operation:
    +
    + The Display Selections for this instrument are:
    +
        c    @@ -2674,9 +2674,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - - CRT display         A Cathode Ray - Tube display, that is of the Refresh type.
    + + CRT display         A Cathode Ray + Tube display, that is of the Refresh type.
        l     @@ -2724,42 +2724,42 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - - LCD display         A Liquid - Crystal Display, that is of the Non-Refresh type.
    -
    -

    - Spyder 2 - colorimeter
    -
    -
    -
    -
    Availability:
    -
    -
    The Spyder 2 has been superseded by the - Spyder 5, but may be available second hand.
    - [The Spyder 1 has also been reported as working, but this has not - been confirmed.]
    -
    -
    Operation:
    -

    - Important Note about the - ColorVision Spyder 2 instrument support:
    -
    - This instrument cannot function without the driver software having - access to the vendor supplied PLD firmware pattern for it.
    - This firmware is not provided with Argyll, since it is not available - under a compatible license.
    -
    - The purchaser of a Spyder 2 instrument should have received a copy - of this firmware along with their instrument, and should therefore - be able to enable the Argyll driver for this instrument by using the - oeminst tool.
    -
    - The Display Selections for this instrument are:
    -
    + + LCD display         A Liquid + Crystal Display, that is of the Non-Refresh type.
    +
    +

    + Spyder 2 + colorimeter
    +
    +
    +
    +
    Availability:
    +
    +
    The Spyder 2 has been superseded by the + Spyder 5, but may be available second hand.
    + [The Spyder 1 has also been reported as working, but this has not + been confirmed.]
    +
    +
    Operation:
    +

    + Important Note about the + ColorVision Spyder 2 instrument support:
    +
    + This instrument cannot function without the driver software having + access to the vendor supplied PLD firmware pattern for it.
    + This firmware is not provided with Argyll, since it is not available + under a compatible license.
    +
    + The purchaser of a Spyder 2 instrument should have received a copy + of this firmware along with their instrument, and should therefore + be able to enable the Argyll driver for this instrument by using the + oeminst tool.
    +
    + The Display Selections for this instrument are:
    +
        l     @@ -2807,9 +2807,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - - LCD display        A Liquid Crystal - Display, that is of the Non-Refresh type. [Default, CB1]
    + + LCD display        A Liquid Crystal + Display, that is of the Non-Refresh type. [Default, CB1]
        c    @@ -2857,134 +2857,134 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - - CRT display         A Cathode Ray - Tube display, that is of the Refresh type. [CB2]
    -
    -
    - Linux USB hub problems:
    -
    -
    Note that the Spyder doesn't appear to operate at all well on - Linux if attached to a secondary USB hub. You may have such a - secondary hub built into your motherboard. If Argyll has difficulty - in reliably talking to the Spyder, try connecting it directly to the - computer rather than via a usb hub, or try using a USB port on your - computer that connects directly to a root hub. This is probably due - to a bug in the Linux EHCI driver, and a fix is due to appear in the - Linux kernel sometime after July 2011. The name of the fix is "EHCI: - fix direction handling for interrupt data toggles".
    -
    -

    - Spyder 3 - colorimeter
    -
    - Spyder3 Spyder3Express
    -
    -
    Availability:
    -
    -
    The Spyder3Elite, Spyder3Pro and Spyder3Express have being - superseded by the Spyder 5, but may still stocked by some dealers, - and may be available second hand. The Spyder3Elite and Spyder3Pro - appear to be identical hardware with different software from the - manufacturer. The Spyder3Express - lacks the ambient sensor.
    -
    - [Note that this instrument doesn't seem particularly suited to - measuring CRT displays, since it no longer seems to synchronise its - readings to a CRT refresh, and you can no longer remove the LCD - filter, reducing its sensitivity compared to the Spyder 2 in CRT - mode. The Spyder 2 or one of the other instruments may be a better - choice if you particularly need to measure CRTs or Refresh - displays.]
    -
    -
    Operation:
    -

    - The ambient light sensor can be used with the Spyder3Elite and Spyder3Pro instruments, but is - only capable of monochrome readings.
    -

    - The Display Selections for this instrument are:
    -
    -     n | l     A - non-refresh type display [Default, CB1]
    -     r | c -     A refresh type display. [CB2]
    -
    -
    -

    - Spyder 4 - colorimeter
    -
    - Spyder4
    -
    -
    Availability:
    -
    -
    The Spyder4Elite, Spyder4Pro and Spyder4Express have being - superseded by the Spyder 5, but may still stocked by some dealers, - and may be available second hand.  The Spyder4Elite and Spyder4Pro appear to be - identical hardware with different software from the manufacturer. - The Spyder4Express lacks - the ambient sensor.
    -
    -
    Operation:
    -

    - These instruments are capable of using using CCSS (Colorimeter Calibration Spectral - Sample) files, and this also gives the instrument the - capability of using a non-default standard observer. CCSS files can - be created using the ccxxmake tool - using a spectrometer as a reference.
    -
    - Important Note about the - DataColor Spyder 4 vendor display type/calibration support:
    -
    - This instrument does not have a full range of display type - calibration selections available without the vendor supplied - calibration data for it.
    - This calibration data is not provided with Argyll, since it is not - available under a compatible license.
    - You can use CCSS files as an alternative (see above), or as the - purchaser of a Spyder 4 instrument you should have received a copy - of the calibration data along with the instrument, and should - therefore be able to enable the full range of display type - selections in Argyll by using the oeminst - tool.
    -
    - The Display Selections for this instrument are:
    -
    -     n | l     -    A non-refresh type display with a generic calibration - [Default, CB1].
    -     r | c        A - refresh type display with a generic calibration.[CB2]
    -
    - The Display Selections for this instrument when the manufacturers - calibration information has been installed is:
    -
    -     n        -      A non-refresh type display with a generic - calibration [Default, CB1].
    -     r        -      A refresh type display with a generic - calibration.[CB2]
    -     f    -          LCD, CCFL + + CRT display         A Cathode Ray + Tube display, that is of the Refresh type. [CB2]
    +
    +
    + Linux USB hub problems:
    +
    +
    Note that the Spyder doesn't appear to operate at all well on + Linux if attached to a secondary USB hub. You may have such a + secondary hub built into your motherboard. If Argyll has difficulty + in reliably talking to the Spyder, try connecting it directly to the + computer rather than via a usb hub, or try using a USB port on your + computer that connects directly to a root hub. This is probably due + to a bug in the Linux EHCI driver, and a fix is due to appear in the + Linux kernel sometime after July 2011. The name of the fix is "EHCI: + fix direction handling for interrupt data toggles".
    +
    +

    + Spyder 3 + colorimeter
    +
    + Spyder3 Spyder3Express
    +
    +
    Availability:
    +
    +
    The Spyder3Elite, Spyder3Pro and Spyder3Express have being + superseded by the Spyder 5, but may still stocked by some dealers, + and may be available second hand. The Spyder3Elite and Spyder3Pro + appear to be identical hardware with different software from the + manufacturer. The Spyder3Express + lacks the ambient sensor.
    +
    + [Note that this instrument doesn't seem particularly suited to + measuring CRT displays, since it no longer seems to synchronise its + readings to a CRT refresh, and you can no longer remove the LCD + filter, reducing its sensitivity compared to the Spyder 2 in CRT + mode. The Spyder 2 or one of the other instruments may be a better + choice if you particularly need to measure CRTs or Refresh + displays.]
    +
    +
    Operation:
    +

    + The ambient light sensor can be used with the Spyder3Elite and Spyder3Pro instruments, but is + only capable of monochrome readings.
    +

    + The Display Selections for this instrument are:
    +
    +     n | l     A + non-refresh type display [Default, CB1]
    +     r | c +     A refresh type display. [CB2]
    +
    +
    +

    + Spyder 4 + colorimeter
    +
    + Spyder4
    +
    +
    Availability:
    +
    +
    The Spyder4Elite, Spyder4Pro and Spyder4Express have being + superseded by the Spyder 5, but may still stocked by some dealers, + and may be available second hand.  The Spyder4Elite and Spyder4Pro appear to be + identical hardware with different software from the manufacturer. + The Spyder4Express lacks + the ambient sensor.
    +
    +
    Operation:
    +

    + These instruments are capable of using using CCSS (Colorimeter Calibration Spectral + Sample) files, and this also gives the instrument the + capability of using a non-default standard observer. CCSS files can + be created using the ccxxmake tool + using a spectrometer as a reference.
    +
    + Important Note about the + DataColor Spyder 4 vendor display type/calibration support:
    +
    + This instrument does not have a full range of display type + calibration selections available without the vendor supplied + calibration data for it.
    + This calibration data is not provided with Argyll, since it is not + available under a compatible license.
    + You can use CCSS files as an alternative (see above), or as the + purchaser of a Spyder 4 instrument you should have received a copy + of the calibration data along with the instrument, and should + therefore be able to enable the full range of display type + selections in Argyll by using the oeminst + tool.
    +
    + The Display Selections for this instrument are:
    +
    +     n | l     +    A non-refresh type display with a generic calibration + [Default, CB1].
    +     r | c        A + refresh type display with a generic calibration.[CB2]
    +
    + The Display Selections for this instrument when the manufacturers + calibration information has been installed is:
    +
    +     n        +      A non-refresh type display with a generic + calibration [Default, CB1].
    +     r        +      A refresh type display with a generic + calibration.[CB2]
    +     f    +          LCD, CCFL Backlight                         @@ -3032,18 +3032,18 @@ 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.
    -     L  -           Wide Gamut LCD, CCFL - Backlight      - wide gamut Liquid Crystal - Display with Cold Cathode Fluorescent Lamps backlight.
    -     e -             LCD, White - LED Backlight        -           - normal - gamut Liquid Crystal Display with a White LED backlight.
    + + - normal gamut Liquid Crystal Display with standard Cold Cathode + Fluorescent Lamp backlight.
    +     L  +           Wide Gamut LCD, CCFL + Backlight      - wide gamut Liquid Crystal + Display with Cold Cathode Fluorescent Lamps backlight.
    +     e +             LCD, White + LED Backlight        +           - normal + gamut Liquid Crystal Display with a White LED backlight.
        B   @@ -3091,13 +3091,13 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - -          Wide Gamut LCD, RGB LED - Backlight - wide gamut Liquid Crystal Display with RGB LED - backlight.
    -     x -             LCD, CCFL - Type 2 + +          Wide Gamut LCD, RGB LED + Backlight - wide gamut Liquid Crystal Display with RGB LED + backlight.
    +     x +             LCD, CCFL + Type 2 Backlight              @@ -3145,90 +3145,90 @@ 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 ?)
    -
    - The ambient light sensor can be used with the Spyder4Elite and Spyder4Pro instruments, but is - only capable of monochrome readings.
    -
    -
    -

    - Spyder 5 - colorimeter
    -
    - Spyder4
    -
    -
    Availability:
    -
    -
    The Spyder5Elite, Spyder5Pro and Spyder5Express are a currently - available instruments. The Spyder5Elite - and Spyder5Pro appear to be - identical hardware with different software from the manufacturer. - The Spyder5Express lacks - the ambient sensor.
    -
    -
    Operation:
    -

    - These instruments are capable of using using CCSS (Colorimeter + + - normal gamut Liquid Crystal Display with alternative Cold Cathode + Fluorescent Lamp backlight (Laptop ?)
    +
    + The ambient light sensor can be used with the Spyder4Elite and Spyder4Pro instruments, but is + only capable of monochrome readings.
    +
    +
    +

    +
    Spyder 5 + colorimeter
    +
    + Spyder4
    +
    + Availability:
    +
    +
    The Spyder5Elite, Spyder5Pro and Spyder5Express are a currently + available instruments. The Spyder5Elite + and Spyder5Pro appear to be + identical hardware with different software from the manufacturer. + The Spyder5Express lacks + the ambient sensor.
    +
    +
    Operation:
    +

    + These instruments are capable of using using CCSS (Colorimeter - - Calibration Spectral Sample) files, and this also gives the - instrument the capability of using a non-default standard observer. - CCSS files can be created using the ccxxmake tool - using a spectrometer as a reference.
    -
    - Important Note about the - DataColor Spyder 5 vendor display type/calibration support:
    -
    - This instrument does not have a full range of display type - calibration selections available without the vendor supplied - calibration data for it.
    - This calibration data is not provided with Argyll, since it is not - available under a compatible license.
    - You can use CCSS files as an alternative (see above), or as the - purchaser of a Spyder 5 instrument you should have received a copy - of the calibration data along with the instrument or have been - directed to download it from the manufacturers website, and should - therefore be able to enable the full range of display type - selections in Argyll by using the oeminst tool.
    -
    - The Display Selections for this instrument are:
    -
    -     n | l     -    A non-refresh type display with a generic calibration - [Default, CB1].
    -     r | c        A - refresh type display with a generic calibration.[CB2]
    -
    - The Display Selections for this instrument when the manufacturers - calibration information has been installed is:
    -
    -     n        -      A non-refresh type display with a generic - calibration [Default, CB1].
    -     r        -      A refresh type display with a generic - calibration.[CB2]
    -     f    -          LCD, CCFL + + Calibration Spectral Sample) files, and this also gives the + instrument the capability of using a non-default standard observer. + CCSS files can be created using the ccxxmake tool + using a spectrometer as a reference.
    +
    + Important Note about the + DataColor Spyder 5 vendor display type/calibration support:
    +
    + This instrument does not have a full range of display type + calibration selections available without the vendor supplied + calibration data for it.
    + This calibration data is not provided with Argyll, since it is not + available under a compatible license.
    + You can use CCSS files as an alternative (see above), or as the + purchaser of a Spyder 5 instrument you should have received a copy + of the calibration data along with the instrument or have been + directed to download it from the manufacturers website, and should + therefore be able to enable the full range of display type + selections in Argyll by using the oeminst tool.
    +
    + The Display Selections for this instrument are:
    +
    +     n | l     +    A non-refresh type display with a generic calibration + [Default, CB1].
    +     r | c        A + refresh type display with a generic calibration.[CB2]
    +
    + The Display Selections for this instrument when the manufacturers + calibration information has been installed is:
    +
    +     n        +      A non-refresh type display with a generic + calibration [Default, CB1].
    +     r        +      A refresh type display with a generic + calibration.[CB2]
    +     f    +          LCD, CCFL Backlight                         @@ -3276,18 +3276,18 @@ 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.
    -     L  -           Wide Gamut LCD, CCFL - Backlight      - wide gamut Liquid Crystal - Display with Cold Cathode Fluorescent Lamps backlight.
    -     e -             LCD, White - LED Backlight        -           - normal - gamut Liquid Crystal Display with a White LED backlight.
    + + - normal gamut Liquid Crystal Display with standard Cold Cathode + Fluorescent Lamp backlight.
    +     L  +           Wide Gamut LCD, CCFL + Backlight      - wide gamut Liquid Crystal + Display with Cold Cathode Fluorescent Lamps backlight.
    +     e +             LCD, White + LED Backlight        +           - normal + gamut Liquid Crystal Display with a White LED backlight.
        B   @@ -3335,13 +3335,13 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - -          Wide Gamut LCD, RGB LED - Backlight - wide gamut Liquid Crystal Display with RGB LED - backlight.
    -     x -             LCD, CCFL - Type 2 + +          Wide Gamut LCD, RGB LED + Backlight - wide gamut Liquid Crystal Display with RGB LED + backlight.
    +     x +             LCD, CCFL + Type 2 Backlight              @@ -3389,23 +3389,23 @@ 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 ?)
    -
    - The ambient light sensor can be used with the Spyder5Elite and Spyder5Pro instruments, but is - only capable of monochrome readings.
    -
    -
    Colorimètre HCFR - colorimeter
    -
    -
    -
    -
    Availability:
    -
    + + - normal gamut Liquid Crystal Display with alternative Cold Cathode + Fluorescent Lamp backlight (Laptop ?)
    +
    + The ambient light sensor can be used with the Spyder5Elite and Spyder5Pro instruments, but is + only capable of monochrome readings.
    +
    +
    Colorimètre HCFR + colorimeter
    +
    +
    +
    +
    Availability:
    +
    The Colorimètre @@ -3453,27 +3453,27 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - - HCFR Probe is a kit instrument from HCFR. -
    -
    - OS X
    -
    - Please note the installation instructions.
    -
    - Operation:
    -
    - The accuracy of this instrument does not seem to be comparable to - the commercial instruments when used for measuring displays, - particularly in the area of measuring dark colors, and I've seen the - best results when used with a CRT display. It may well give good - results in calibrating projectors, since this was what it was - designed to do.
    -
    - The Display Selections for this instrument are:
    -
    + + HCFR Probe
    is a kit instrument from HCFR. +
    +
    + OS X
    +
    + Please note the installation instructions.
    +
    + Operation:
    +
    + The accuracy of this instrument does not seem to be comparable to + the commercial instruments when used for measuring displays, + particularly in the area of measuring dark colors, and I've seen the + best results when used with a CRT display. It may well give good + results in calibrating projectors, since this was what it was + designed to do.
    +
    + The Display Selections for this instrument are:
    +
        l     @@ -3521,9 +3521,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - - LCD display         A Liquid - Crystal Display [Default].
    + + LCD display         A Liquid + Crystal Display [Default].
        c    @@ -3571,39 +3571,39 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - - CRT display         A Cathode Ray - Tube display.
    -     R   Raw  - Reading       Raw sensor readings, - used for calibration [CB1]
    -
    -
    ColorHug
    -
    -
    -
    -
    Availability:
    -
    -
    The ColorHug - is a low cost display colorimeter instrument from Hughski.
    - ArgyllCMS will also work with the ColorHug2.
    -
    - Operation:
    -
    - Due to the nature of its sensor, the ColorHug accuracy is quite - dependent on the instrument calibration matrix. (The ColorHug2 - is much more forgiving though). A custom .CCMX will greatly assist - it's accuracy, although a workaround is to calibrate your display - using its native white point, rather than aiming for some absolute - white point such as D65.
    -
    - The Display Selections for this instrument are:
    -
    + + CRT display         A Cathode Ray + Tube display.
    +     R   Raw  + Reading       Raw sensor readings, + used for calibration [CB1]
    +
    +
    ColorHug
    +
    +
    +
    +
    Availability:
    +
    +
    The ColorHug + is a low cost display colorimeter instrument from Hughski.
    + ArgyllCMS will also work with the ColorHug2.
    +
    + Operation:
    +
    + Due to the nature of its sensor, the ColorHug accuracy is quite + dependent on the instrument calibration matrix. (The ColorHug2 + is much more forgiving though). A custom .CCMX will greatly assist + it's accuracy, although a workaround is to calibrate your display + using its native white point, rather than aiming for some absolute + white point such as D65.
    +
    + The Display Selections for this instrument are:
    +
       l                   @@ -3621,8 +3621,8 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - - LCD, CCFL Backlight [Default]
    + + LCD, CCFL Backlight [Default]
       c                  @@ -3641,8 +3641,8 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - - CRT display
    + + CRT display
       p                  @@ -3661,8 +3661,8 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - - Projector
    + + Projector
       e                  @@ -3680,8 +3680,8 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - - LCD, White LED Backlight
    + + LCD, White LED Backlight
       F                  @@ -3700,8 +3700,8 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - - Factory matrix (For Calibration) [CB1]
    + + Factory matrix (For Calibration) [CB1]
       R                 @@ -3720,40 +3720,40 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - - Raw Reading (For Factory matrix Calibration) [CB2]
    -
    -

    + + Raw Reading (For Factory matrix Calibration) [CB2]
    +
    +

    Palette/SwatchMate - - Cube
    -
    - SwatchMate Cube
    -
    -
    Availability:
    -
    -
    The Cube from Palette/SwatchMate - is a currently available entry level Colorimeter, with somewhat - limited accuracy. The ArgyllCMS driver provides two - alternative calibrations that noticably improve - this accuracy.
    -
    - The Calibration Selections for this instrument are:
    -
    -    m + + Cube
    +
    + SwatchMate Cube
    +
    + Availability:
    +
    +
    The Cube from Palette/SwatchMate + is a currently available entry level Colorimeter, with somewhat + limited accuracy. The ArgyllCMS driver provides two + alternative calibrations that noticably improve + this accuracy.
    +
    + The Calibration Selections for this instrument are:
    +
    +    m                 - - Matt surfaces [Default]
    + + Matt surfaces [Default]
       g                  @@ -3772,64 +3772,64 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP - - Gloss surfaces
    -    N + + Gloss surfaces
    +    N                 - - Native Calibration
    -
    - Operation:
    -

    - The Cube must be connected via USB for operation with ArgyllCMS, and - can be connected either by USB or using Bluetooth LE when used with - ArgyllPRO ColorMeter on - capable Android devices.
    -
    - The Cube goes to sleep fairly rapidly and must be woken up by - pressing the top of it before connecting via USB to be recognized by - ArgyllCMS, although once connected, and with an ArgyllCMS utility - running, it should stay awake.
    -
    - When connecting via Bluetooth to ColorMeter, the foreground - application will be the one that connects to it.
    -
    - The ability to measure values into its own memory and recover them - later is not supported, since it is not possible to use the - ArgyllCMS calibrations with this feature.
    -
    - Calibration:
    -
    - As well as the normal white calibration step, the ArgyllCMS driver - offers two option supplemental calibration steps that can improve - accuracy, but both require appropriate calibration conditions. You - can use spotread with the 'k' command - to trigger this calibration.
    -
    - The black calibration requires a light trap, and the easiest - way of providing this is to place the Cube in a location that is - dark (i.e. not illuminated directly by any light) and some distance - from any surface. A practical approach I have used is to place the - measuring end in a thick black sock, and hide it from direct - illumination while this calibration step is done.
    -
    - The gloss calibration requires a black glossy surface. I - have used a paint catalog gloss paint black sample square for this, - but some other completely black glossy surface of sufficient size - such as a glossy black plastic item or a smooth surface painted in - gloss black paint should also work.
    -
    -
    -
    -
    -
    -
    -
    -
    - - + + Native Calibration
    +
    + Operation:
    +

    + The Cube must be connected via USB for operation with ArgyllCMS, and + can be connected either by USB or using Bluetooth LE when used with + ArgyllPRO ColorMeter on + capable Android devices.
    +
    + The Cube goes to sleep fairly rapidly and must be woken up by + pressing the top of it before connecting via USB to be recognized by + ArgyllCMS, although once connected, and with an ArgyllCMS utility + running, it should stay awake.
    +
    + When connecting via Bluetooth to ColorMeter, the foreground + application will be the one that connects to it.
    +
    + The ability to measure values into its own memory and recover them + later is not supported, since it is not possible to use the + ArgyllCMS calibrations with this feature.
    +
    + Calibration:
    +
    + As well as the normal white calibration step, the ArgyllCMS driver + offers two option supplemental calibration steps that can improve + accuracy, but both require appropriate calibration conditions. You + can use spotread with the 'k' command + to trigger this calibration.
    +
    + The black calibration requires a light trap, and the easiest + way of providing this is to place the Cube in a location that is + dark (i.e. not illuminated directly by any light) and some distance + from any surface. A practical approach I have used is to place the + measuring end in a thick black sock, and hide it from direct + illumination while this calibration step is done.
    +
    + The gloss calibration requires a black glossy surface. I + have used a paint catalog gloss paint black sample square for this, + but some other completely black glossy surface of sufficient size + such as a glossy black plastic item or a smooth surface painted in + gloss black paint should also work.
    +
    +
    +
    +
    +
    +
    +
    +
    + + diff --git a/doc/targen.html b/doc/targen.html index 3aa1bb4..81b331b 100644 --- a/doc/targen.html +++ b/doc/targen.html @@ -1323,12 +1323,12 @@ device accuracy of measuring and modelling the lighter regions, given a fixed number of test points and profile quality/grid resolution. The parameter will also be used in an analogous way to the -p power + href="targen.html#p">-p power value in changing the distribution of -s steps, -g steps, -m steps - and -b + href="targen.html#s">-s steps, -g steps, -m steps + and -b diff --git a/doc/tiffgamut.html b/doc/tiffgamut.html index 6aea52d..9534717 100644 --- a/doc/tiffgamut.html +++ b/doc/tiffgamut.html @@ -19,7 +19,9 @@ This can be used for visualizing and comparing the gamut of an image to the colorspace it is in, or a colorspace it might get transformed into, and can also be used to create an image source gamut for use - with collink.
    + with collink, something that can be of + particular importance if your images are encoded in a large gamut + space such as L*a*b*, ProPhoto, scRGB etc.

    NOTE that if you are creating an image gamut suitable for use with the Image dependent gamut mapping using device links for an example workflow.

    - See 3D Viewing + See 3D Viewing Format for switching to VRML or X3D output format.

    Usage Summary

    tiffgamut [-v level] @@ -44,6 +46,7 @@ + Verbose
      -d sres       Surface resolution @@ -54,6 +57,7 @@ emit + X3DOM .x3d.html file as well as CGATS .gam file
     -n            @@ -62,6 +66,7 @@ Don't + add X3DOM axes or white/black point
     -k            @@ -70,6 +75,7 @@ Add + markers for prim. & sec. "cusp" points
     -f perc       Filter by popularity, perc = percent to use

    @@ -97,6 +104,7 @@ r + = reverse (priority: monochrome > matrix > lut)
     -p oride
    @@ -128,6 +137,7 @@ either + pe - Print evaluation environment (CIE 116-1995)
               @@ -135,6 +145,7 @@ either + pc - Critical print evaluation environment (ISO-3664 P1)
    @@ -147,6 +158,7 @@ either +   mb - Monitor in bright work environment
         @@ -173,6 +185,7 @@ s:surround   + n = auto, a = average, m = dim, d = dark,
                   @@ -181,6 +194,7 @@ s:surround   +      c = transparency (default average)
             @@ -189,6 +203,7 @@ w:X:Y:Z      + Adapted white point as XYZ (default media white)
             @@ -197,6 +212,7 @@ w:x:y        + Adapted white point as x, y
             @@ -205,6 +221,7 @@ a:adaptation + Adaptation luminance in cd.m^2 (default 50.0)
             @@ -213,6 +230,7 @@ b:background + Background % of image luminance (default 20)
             l:imagewhite Image white in cd.m^2 if surround = auto (default 250)

             g:glare      Glare light % of ambient - (default 1)
    + (default 5)
             g:X:Y:Z      Glare color as XYZ (default media white)
    3D Viewing Format for switching to + See 3D Viewing Format for switching to VRML or X3D output format.

    Usage

    diff --git a/doc/xicclu.html b/doc/xicclu.html index cf572fe..831977d 100644 --- a/doc/xicclu.html +++ b/doc/xicclu.html @@ -435,7 +435,7 @@ light g:glare      Glare light % of ambient - (default 1)
    + (default 2)
              g:X:Y:Z      Glare color as XYZ (default media white, Abs: D50)
    3D mapping points down the grey axis */ -#define USE_GAMKNF /* [Define] Enable 3D knee function points */ -#define USE_BOUND /* [Define] Enable grid boundary anchor points */ +#undef DUMP_GREY_AXIS_POINTS /* [Und] Dump grey axis map 3d->3d points */ #undef SHOW_NEIGBORS /* [Und] Show nearsmth neigbors in gammap.wrl */ @@ -80,6 +76,13 @@ #define XRES 100 /* [100] Res of plots */ + /* Functionality */ +#define USE_GLUMKNF /* [Define] Enable luminence knee function points else linear */ +#define USE_GREYMAP /* [Define] Enable 3D->3D mapping points down the grey axis */ +#define USE_GAMKNF /* [Define] Enable 3D knee function points */ +#define USE_BOUND /* [Define] Enable grid boundary anchor points */ + + /* The locus.ts file can contain source locus(es) that will be plotted */ /* as cones in red, with the destination plotted in white. They can */ /* be created from .tif files using xicc/tiffgmts utility. */ @@ -148,7 +151,6 @@ struct { #include #include #include -#include "counters.h" #include "icc.h" #include "numlib.h" #include "xicc.h" @@ -168,11 +170,17 @@ typedef struct { double satenh; /* Saturation engancement value */ } adjustsat; +/* Callback context for fixing 1D Lut white and black points */ +typedef struct { + double twb[2], awb[2]; /* Target and Actual black, white */ +} adjust1wb; + /* Callback context for making clut relative to white and black points */ typedef struct { double mat[3][4]; } adjustwb; +static void adjust1_wb_func(void *pp, double *out, double *in); static void inv_grey_func(void *pp, double *out, double *in); static void adjust_wb_func(void *pp, double *out, double *in); static void adjust_sat_func(void *pp, double *out, double *in); @@ -192,7 +200,7 @@ gammapweights pweights[] = { { 0.1, /* Cusp luminance alignment weighting 0 = none, 1 = full */ 0.0, /* Cusp chroma alignment weighting 0 = none, 1 = full */ - 0.3 /* Cusp hue alignment weighting 0 = none, 1 = full */ + 0.2 /* Cusp hue alignment weighting 0 = none, 1 = full */ }, 2.0, /* Alignment twist power, 0 = linear, 1 = curve, 2+ late curve */ 1.00 /* Chroma expansion 1 = none */ @@ -206,9 +214,9 @@ gammapweights pweights[] = { 1.0, /* Absolute error overall weight */ 0.8, /* Hue dominance vs l+c, 0 - 1 */ - 0.8, /* White l dominance vs, c, 0 - 1 */ - 0.5, /* Grey l dominance vs, c, 0 - 1 */ - 0.97, /* Black l dominance vs, c, 0 - 1 */ + 0.8, /* [0.8] White l dominance vs, c, 0 - 1 */ + 0.45, /* [0.45] Grey l dominance vs, c, 0 - 1 */ + 0.94, /* [0.94] Black l dominance vs, c, 0 - 1 */ 0.4, /* White l blend start radius, 0 - 1, at white = 0 */ 0.7, /* Black l blend power, linear = 1.0, enhance < 1.0 */ @@ -217,14 +225,15 @@ gammapweights pweights[] = { 10.0 /* L error extra xover threshold in DE */ }, { /* Relative vector smoothing */ - 25.0, 35.0 /* Relative Smoothing radius L* H* */ + 20.0, 30.0, /* Relative Smoothing radius L* H* */ + 0.9 /* Degree of smoothing */ }, { /* Weighting of excessive compression error, which is */ /* the src->dst vector length over the available dst depth. */ /* The depth is half the distance to the intersection of the */ /* vector to the other side of the gamut. (doesn't get triggered much ?) */ - 10.0, /* Compression depth weight */ - 10.0 /* Expansion depth weight */ + 5.0, /* [5] Compression depth weight */ + 5.0 /* [5] Expansion depth weight */ }, { 0.0 /* Fine tuning expansion weight, 0 - 1 */ @@ -261,7 +270,8 @@ gammapweights pweights[] = { -1.0 /* L error xover threshold in DE */ }, { /* Relative error preservation using smoothing */ - 20.0, 10.0 /* Relative Smoothing radius L* H* */ + 20.0, 10.0, /* Relative Smoothing radius L* H* */ + 0.5 /* Degree of smoothing */ }, { /* Weighting of excessive compression error, which is */ /* the src->dst vector length over the available dst depth. */ @@ -293,7 +303,7 @@ gammapweights pweights[] = { }, { /* Weighting of absolute error of destination from source */ -1.0, /* Absolute error overall weight */ - 0.8, /* Hue dominance vs l+c, 0 - 1 */ + -1.0, /* Hue dominance vs l+c, 0 - 1 */ -1.0, /* White l dominance vs, c, 0 - 1 */ -1.0, /* Grey l dominance vs, c, 0 - 1 */ @@ -306,7 +316,8 @@ gammapweights pweights[] = { -1.0 /* L error xover threshold in DE */ }, { /* Relative error preservation using smoothing */ - -1.0, 15.0 /* Relative Smoothing radius L* H* */ + -1.0, 15.0, /* Relative Smoothing radius L* H* */ + -1.0 /* Degree of smoothing */ }, { /* Weighting of excessive compression error, which is */ /* the src->dst vector length over the available dst depth. */ @@ -324,7 +335,61 @@ gammapweights pweights[] = { gmm_end, } }; -double psmooth = 4.0; /* [5.0] Level of RSPL smoothing for perceptual, 1 = nominal */ +double psmooth = 2.0; /* [2.0] Level of RSPL smoothing for perceptual, 1 = nominal */ + +/* Lightness Preserving Perceptual mapping weights, where preserving lightness */ +/* and hue has the highest priority, followed by smoothness and proportionality. */ +/* Chroma is basically sacrificed. */ +gammapweights lpweights[] = { + { + gmm_default, /* Non hue specific defaults */ + { /* Cusp alignment control */ + { + 0.0, /* [0.2] Cusp luminance alignment weighting 0 = none, 1 = full */ + 0.0, /* [0.0] Cusp chroma alignment weighting 0 = none, 1 = full */ + 0.0 /* [0.3] Cusp hue alignment weighting 0 = none, 1 = full */ + }, + 2.0, /* Alignment twist power, 0 = linear, 1 = curve, 2+ late curve */ + 1.00 /* Chroma expansion 1 = none */ + }, + { /* Radial weighting (currently broken - need to fix) */ + 0.0, /* Radial error overall weight, 0 + */ + 0.1, /* Radial hue dominance vs l+c, 0 - 1 */ + 1.0 /* Radial l dominance vs, c, 0 - 1 */ + }, + { /* Weighting of absolute error of destination from source */ + 1.0, /* Absolute error overall weight */ + 0.90, /* [0.9] Hue dominance vs l+c, 0 - 1 */ + + 0.98, /* White l dominance vs, c, 0 - 1 */ + 0.95, /* Grey l dominance vs, c, 0 - 1 */ + 0.99, /* Black l dominance vs, c, 0 - 1 */ + + 0.4, /* White l blend start radius, 0 - 1, at white = 0 */ + 0.7, /* Black l blend power, linear = 1.0, enhance < 1.0 */ + + 1.0, /* L error extra power with size, none = 1.0 */ + 100.0 /* L error extra xover threshold in DE */ + }, + { /* Relative vector smoothing */ + 6.0, 30.0, /* Relative Smoothing radius L* H* */ + 0.9 /* [0.9] Degree of smoothing */ + }, + { /* Weighting of excessive compression error, which is */ + /* the src->dst vector length over the available dst depth. */ + /* (This compromizes constanl L near white and black, so minimize) */ + 0.0, /* Compression depth weight */ + 0.0 /* Expansion depth weight */ + }, + { + 0.0 /* Fine tuning expansion weight, 0 - 1 */ + } + }, + { + gmm_end, + } +}; +double lpsmooth = 1.0; /* [1.0] Level of RSPL smoothing for ligtness pres perc, 1 = nominal */ /* Saturation mapping weights, where saturation has priority over smoothness */ gammapweights sweights[] = { @@ -349,24 +414,25 @@ gammapweights sweights[] = { 0.4, /* Hue dominance vs l+c, 0 - 1 */ 0.6, /* White l dominance vs, c, 0 - 1 */ - 0.4, /* Grey l dominance vs, c, 0 - 1 */ - 0.6, /* Black l dominance vs, c, 0 - 1 */ + 0.3, /* Grey l dominance vs, c, 0 - 1 */ + 0.7, /* Black l dominance vs, c, 0 - 1 */ 0.5, /* wl blend start radius, 0 - 1 */ 1.0, /* bl blend power, linear = 1.0, enhance < 1.0 */ - 1.0, /* L error extra power with size, none = 1.0 */ - 10.0 /* L error extra xover threshold in DE */ + 1.5, /* L error extra power with size, none = 1.0 */ + 20.0 /* L error extra xover threshold in DE */ }, { /* Relative vector smoothing */ - 20.0, 25.0 /* Relative Smoothing radius L* H* */ + 15.0, 20.0, /* Relative Smoothing radius L* H* */ + 0.8 /* [0.8] Degree of smoothing */ }, { /* Weighting of excessive compression error, which is */ /* the src->dst vector length over the available dst depth. */ /* The depth is half the distance to the intersection of the */ /* vector to the other side of the gamut. (doesn't get triggered much ?) */ - 10.0, /* Compression depth weight */ - 10.0 /* Expansion depth weight */ + 5.0, /* Compression depth weight */ + 5.0 /* Expansion depth weight */ }, { 0.5 /* Fine tuning expansion weight, 0 - 1 */ @@ -403,7 +469,8 @@ gammapweights sweights[] = { -1.0 /* L error xover threshold in DE */ }, { /* Relative error preservation using smoothing */ - 10.0, 15.0 /* Relative smoothing radius */ + 10.0, 15.0, /* Relative smoothing radius */ + 0.5 /* Degree of smoothing */ }, { /* Weighting of excessive compression error, which is */ /* the src->dst vector length over the available dst depth. */ @@ -420,7 +487,9 @@ gammapweights sweights[] = { gmm_end } }; -double ssmooth = 2.0; /* Level of RSPL smoothing for saturation */ +/* The cusp alignment tends to upset the vector smoothing (not exactly sure why), */ +/* so use more rspl smoothing to compensate. */ +double ssmooth = 4.0; /* [1.0] Level of RSPL smoothing for saturation */ /* * Notes: @@ -451,7 +520,7 @@ static void map_trans(void *cntx, double out[3], double in[3]); gammap *new_gammap( int verb, /* Verbose flag */ gamut *sc_gam, /* Source colorspace gamut */ - gamut *si_gam, /* Source image gamut (NULL if none) */ + gamut *isi_gam, /* Input source image gamut (NULL if none) */ gamut *d_gam, /* Destination colorspace gamut */ icxGMappingIntent *gmi, /* Gamut mapping specification */ int src_kbp, /* Use K only black point as src gamut black point */ @@ -463,9 +532,10 @@ gammap *new_gammap( double *mx, /* for rspl grid. */ char *diagname /* If non-NULL, write a gamut mapping diagnostic WRL */ ) { - gammap *s; /* This */ - gamut *scl_gam; /* Source colorspace gamut with rotation and L mapping applied */ - gamut *sil_gam; /* Source image gamut with rotation and L mapping applied */ + gammap *s; /* This */ + gamut *si_gam = NULL; /* Source image gamut (intersected with sc_gam) */ + gamut *scl_gam; /* Source colorspace gamut with rotation and L mapping applied */ + gamut *sil_gam; /* Source image gamut with rotation and L mapping applied */ double s_cs_wp[3]; /* Source colorspace white point */ double s_cs_bp[3]; /* Source colorspace black point */ @@ -491,7 +561,11 @@ gammap *new_gammap( double d_mt_wp[3]; /* Overall destination mapping white point (used for finetune) */ double d_mt_bp[3]; /* Overall destination mapping black point (used for finetune) */ - int defrgrid = 6; /* mapping range surface default anchor point resolution */ +#ifdef USE_BOUND + int surfpnts = 1; /* Add grid surface anchor points */ +#else + int surfpnts = 0; /* Don't add grid surface points */ +#endif int nres = 512; /* Neutral axis resolution */ cow lpnts[10]; /* Mapping points to create grey axis map */ int revrspl = 0; /* Reverse grey axis rspl construction */ @@ -502,12 +576,16 @@ gammap *new_gammap( #if defined(PLOT_LMAP) || defined(PLOT_GAMUTS) || defined(PLOT_3DKNEES) # pragma message("################ A gammap.c PLOT is #defined #########################") +#endif + +#ifndef USE_BOUND +# pragma message("################ gammap.c USE_BOUND not set #########################") #endif if (verb) { xicc_dump_gmi(gmi); printf("Gamut map resolution: %d\n",mapres); - if (si_gam != NULL) + if (isi_gam != NULL) printf("Image gamut supplied\n"); } @@ -522,18 +600,15 @@ gammap *new_gammap( /* Now create everything */ - /* Grab the white and black points */ + /* Grab the colorspace white and black points */ if (src_kbp) { - // ~~99 Hmm. Shouldn't this be colorspace rather than gamut ???? - if (sc_gam->getwb(sc_gam, NULL, NULL, NULL, s_cs_wp, NULL, s_cs_bp)) { -// if (sc_gam->getwb(sc_gam, s_cs_wp, NULL, s_cs_bp, NULL, NULL, NULL)) + if (sc_gam->getwb(sc_gam, s_cs_wp, NULL, s_cs_bp, NULL, NULL, NULL)) { fprintf(stderr,"gamut map: Unable to read source colorspace white and black points\n"); free(s); return NULL; } } else { - if (sc_gam->getwb(sc_gam, NULL, NULL, NULL, s_cs_wp, s_cs_bp, NULL)) { -// if (sc_gam->getwb(sc_gam, s_cs_wp, s_cs_bp, NULL, NULL, NULL, NULL)) + if (sc_gam->getwb(sc_gam, s_cs_wp, s_cs_bp, NULL, NULL, NULL, NULL)) { fprintf(stderr,"gamut map: Unable to read source colorspace white and black points\n"); free(s); return NULL; @@ -541,16 +616,40 @@ gammap *new_gammap( } /* If source space is source gamut */ - if (si_gam == NULL) { + if (isi_gam == NULL || isi_gam == sc_gam) { si_gam = sc_gam; for (j = 0; j < 3; j++) { s_ga_wp[j] = s_cs_wp[j]; s_ga_bp[j] = s_cs_bp[j]; } - /* Else have explicit sourcegamut */ + /* Else have explicit image gamut */ } else { +#ifdef VERBOSE + if (verb) { /* Check that image gamut is within colorspace */ + double scwp[3], scbp[3]; + double imwp[3], imbp[3]; + + sc_gam->getwb(sc_gam, NULL, NULL, NULL, scwp, scbp, NULL); + isi_gam->getwb(isi_gam, NULL, NULL, NULL, imwp, imbp, NULL); + + if (imwp[0] > (scwp[0] + 1e-4) + || imbp[0] < (scbp[0] - 1e-4)) { + printf("Warning: image gamut is bigger than src colorspace!\n"); + } + + } +#endif + /* Intersect it with the source colorspace gamut in case */ + /* something strange is going on. (mismatched appearance params ?) */ + if ((si_gam = new_gamut(0.0, 0, 0)) == NULL) { + fprintf(stderr,"gamut map: new_gamut failed\n"); + free(s); + return NULL; + } + si_gam->intersect(si_gam, isi_gam, sc_gam); + if (src_kbp) { if (si_gam->getwb(si_gam, NULL, NULL, NULL, s_ga_wp, NULL, s_ga_bp)) { fprintf(stderr,"gamut map: Unable to read source gamut white and black points\n"); @@ -564,42 +663,21 @@ gammap *new_gammap( return NULL; } } - - /* Guard against silliness. Image must be within colorspace */ - if (s_ga_wp[0] > s_cs_wp[0]) { - int j; - double t; -#ifdef VERBOSE - if (verb) - printf("Fixing wayward image white point\n"); -#endif - t = (s_cs_wp[0] - s_ga_bp[0])/(s_ga_wp[0] - s_ga_bp[0]); - for (j = 0; j < 3; j++) - s_ga_wp[j] = s_ga_bp[j] + t * (s_ga_wp[j] - s_ga_bp[j]); - - } - if (s_ga_bp[0] < s_cs_bp[0]) { - int j; - double t; -#ifdef VERBOSE - if (verb) - printf("Fixing wayward image black point\n"); -#endif - t = (s_cs_bp[0] - s_ga_wp[0])/(s_ga_bp[0] - s_ga_wp[0]); - for (j = 0; j < 3; j++) - s_ga_bp[j] = s_ga_wp[j] + t * (s_ga_bp[j] - s_ga_wp[j]); - } } if (dst_kbp) { if (d_gam->getwb(d_gam, NULL, NULL, NULL, d_cs_wp, NULL, d_cs_bp)) { fprintf(stderr,"gamut map: Unable to read destination white and black points\n"); + if (si_gam != sc_gam) + si_gam->del(si_gam); free(s); return NULL; } } else { if (d_gam->getwb(d_gam, NULL, NULL, NULL, d_cs_wp, d_cs_bp, NULL)) { fprintf(stderr,"gamut map: Unable to read destination white and black points\n"); + if (si_gam != sc_gam) + si_gam->del(si_gam); free(s); return NULL; } @@ -872,7 +950,7 @@ glumknf = 1.0; /* If we have a gamut (ie. image) range that is smaller than the */ /* L range of the colorspace, then use its white and black L values */ /* as the source to be compressed to the destination L range. */ - /* We expand only a colorspace range, not a gamut/image range. */ + /* We expand only a colorspace range, not an image gamut range. */ { double swL, dwL; /* Source and destination white point L */ double sbL, dbL; /* Source and destination black point L */ @@ -885,14 +963,14 @@ glumknf = 1.0; dwL = gmi->glumwexf * dr_cs_wp[0] + (1.0 - gmi->glumwexf) * sr_cs_wp[0]; } else { - if (sr_ga_wp[0] > dr_cs_wp[0]) { /* Gamut or colorspace needs compression */ + if (sr_cs_wp[0] > dr_cs_wp[0]) { /* Colorspace needs compression */ - swL = (1.0 - gmi->glumwcpf) * dr_cs_wp[0] + gmi->glumwcpf * sr_ga_wp[0]; + swL = (1.0 - gmi->glumwcpf) * dr_cs_wp[0] + gmi->glumwcpf * sr_cs_wp[0]; dwL = dr_cs_wp[0]; } else { /* Neither needed */ - swL = sr_ga_wp[0]; - dwL = sr_ga_wp[0]; + swL = sr_cs_wp[0]; + dwL = sr_cs_wp[0]; } } @@ -902,14 +980,14 @@ glumknf = 1.0; dbL = gmi->glumbexf * dr_cs_bp[0] + (1.0 - gmi->glumbexf) * sr_cs_bp[0]; } else { - if (sr_ga_bp[0] < dr_cs_bp[0]) { /* Gamut or colorspace needs compression */ + if (sr_cs_bp[0] < dr_cs_bp[0]) { /* Colorspace needs compression */ - sbL = (1.0 - gmi->glumbcpf) * dr_cs_bp[0] + gmi->glumbcpf * sr_ga_bp[0]; + sbL = (1.0 - gmi->glumbcpf) * dr_cs_bp[0] + gmi->glumbcpf * sr_cs_bp[0]; dbL = dr_cs_bp[0]; } else { /* Neither needed */ - sbL = sr_ga_bp[0]; - dbL = sr_ga_bp[0]; + sbL = sr_cs_bp[0]; + dbL = sr_cs_bp[0]; } } @@ -968,24 +1046,21 @@ glumknf = 1.0; lpnts[ngreyp].v[0] = dbL; lpnts[ngreyp++].w = 10.0; /* Must go through here */ -#ifdef USE_GLUMKNF - if (gmi->glumknf < 0.05) -#endif /* USE_GLUMKNF */ - { /* make sure curve is firmly anchored */ - lpnts[ngreyp].p[0] = 0.3 * lpnts[ngreyp-1].p[0] + 0.7 * lpnts[ngreyp-2].p[0]; - lpnts[ngreyp].v[0] = 0.3 * lpnts[ngreyp-1].v[0] + 0.7 * lpnts[ngreyp-2].v[0]; - lpnts[ngreyp++].w = 1.0; - - lpnts[ngreyp].p[0] = 0.7 * lpnts[ngreyp-2].p[0] + 0.3 * lpnts[ngreyp-3].p[0]; - lpnts[ngreyp].v[0] = 0.7 * lpnts[ngreyp-2].v[0] + 0.3 * lpnts[ngreyp-3].v[0]; - lpnts[ngreyp++].w = 1.0; - } -#ifdef USE_GLUMKNF - else { /* There is at least some weight in knee points */ - double cppos = 0.50; /* Center point ratio between black and white */ +#ifndef USE_GLUMKNF + /* make sure curve is firmly anchored */ + lpnts[ngreyp].p[0] = 0.3 * lpnts[ngreyp-1].p[0] + 0.7 * lpnts[ngreyp-2].p[0]; + lpnts[ngreyp].v[0] = 0.3 * lpnts[ngreyp-1].v[0] + 0.7 * lpnts[ngreyp-2].v[0]; + lpnts[ngreyp++].w = 1.0; + + lpnts[ngreyp].p[0] = 0.7 * lpnts[ngreyp-2].p[0] + 0.3 * lpnts[ngreyp-3].p[0]; + lpnts[ngreyp].v[0] = 0.7 * lpnts[ngreyp-2].v[0] + 0.3 * lpnts[ngreyp-3].v[0]; + lpnts[ngreyp++].w = 1.0; +#else /* USE_GLUMKNF */ + { + double cppos = 0.50; /* [0.50] Center point ratio between black and white */ double cpll, cplv; /* Center point location and value */ - double kpwpos = 0.30; /* White knee point location prop. towards center */ - double kpbpos = 0.20; /* Black knee point location prop. towards center */ + double kpwpos = 0.30; /* [0.30] White knee point location prop. towards center */ + double kpbpos = 0.15; /* [0.15] Black knee point location prop. towards center */ double kwl, kbl, kwv, kbv; /* Knee point values and locations */ double kwx, kbx; /* Knee point extra */ @@ -994,20 +1069,20 @@ glumknf = 1.0; printf("%sdbL = %f, dwL = %f\n", revrspl ? "(swapped) ": "", dbL,dwL); #endif - /* Center point location */ + /* Center point location. Make lightly weighted */ + /* center the perceptual source, to try and maintain */ + /* the absolute source grey in the output, while */ + /* still allowing some of the knee compression/expansion to creep */ + /* into the other half. */ cpll = cppos * (swL - sbL) + sbL; - // ~~?? would this be better if the output - // was scaled by dwL/swL ? cplv = cppos * (swL - sbL) + sbL; #ifdef PLOT_LMAP printf("cpll = %f, cplv = %f\n",cpll, cplv); #endif - -#ifdef NEVER /* Don't use a center point */ + /* Add weakish center point */ lpnts[ngreyp].p[0] = cpll; lpnts[ngreyp].v[0] = cplv; - lpnts[ngreyp++].w = 5.0; -#endif + lpnts[ngreyp++].w = 0.5; //printf("~1 black half diff = %f\n",dbL - sbL); //printf("~1 white half diff = %f\n",dwL - swL); @@ -1021,7 +1096,7 @@ glumknf = 1.0; // ~~ weigting of black point and white point differences kwx = 0.6 * (dbL - sbL) + 1.0 * (swL - dwL); kbx = 1.0 * (dbL - sbL) + 0.6 * (swL - dwL); - + //kwx = 0.0; //kbx = 0.0; //glumknf = 0.0; @@ -1035,7 +1110,6 @@ glumknf = 1.0; if (kbv < dbL) /* Sanity check */ kbv = dbL; - #ifdef PLOT_LMAP printf("using kbl = %f, kbv = %f\n",kbl, kbv); printf("using kwl = %f, kwv = %f\n",kwl, kwv); @@ -1045,68 +1119,110 @@ glumknf = 1.0; lpnts[ngreyp].p[0] = kwl; lpnts[ngreyp].v[0] = kwv; lpnts[ngreyp++].w = gmi->glumknf * gmi->glumknf; - + /* Emphasise points to cause black "knee" curve */ lpnts[ngreyp].p[0] = kbl; lpnts[ngreyp].v[0] = kbv; lpnts[ngreyp++].w = 1.5 * gmi->glumknf * 1.5 * gmi->glumknf; } #endif /* USE_GLUMKNF */ - } - - /* We now create the 1D rspl L map, that compresses or expands the luminence */ - /* range, independent of grey axis alignment, or gamut compression. */ - /* Because the rspl isn't symetrical when we swap X & Y, and we would */ - /* like a conversion from profile A to B to be the inverse of profile B to A */ - /* (as much as possible), we contrive here to always create a compression */ - /* RSPL, and create an inverse for it, and swap the two of them so that */ - /* the transform is correct and has an accurate inverse available. */ - { - datai il, ih; - datao ol, oh; - double avgdev[MXDO]; - int gres = 256; - /* Create a 1D rspl, that is used to */ - /* form the overall L compression mapping. */ - if ((s->grey = new_rspl(RSPL_NOFLAGS, 1, 1)) == NULL) /* Allocate 1D -> 1D */ - error("gamut: grey new_rspl failed"); - - il[0] = -1.0; /* Set possible input range */ - ih[0] = 101.0; - ol[0] = 0.0; /* Set normalisation output range */ - oh[0] = 100.0; + /* Create RSPL */ + { + datai il, ih; + datao ol, oh; + double avgdev[MXDO]; + int gres = 256; + + /* Create a 1D rspl, that is used to */ + /* form the overall L compression mapping. */ + if ((s->grey = new_rspl(RSPL_NOFLAGS, 1, 1)) == NULL) /* Allocate 1D -> 1D */ + error("gamut: grey new_rspl failed"); + + il[0] = -1.0; /* Set possible input range */ + ih[0] = 101.0; + ol[0] = 0.0; /* Set normalisation output range */ + oh[0] = 100.0; #ifdef NEVER /* Dump out the L mapping points */ - { - int i; - printf("1D rspl L mapping points:\n"); - for (i = 0; i < ngreyp; i++) - printf("%d %f -> %f (w %f)\n",i,lpnts[i].p[0],lpnts[i].v[0],lpnts[i].w); - } + { + int i; + printf("1D rspl L mapping points:\n"); + for (i = 0; i < ngreyp; i++) + printf("%d %f -> %f (w %f)\n",i,lpnts[i].p[0],lpnts[i].v[0],lpnts[i].w); + } #endif - /* Create spline from the data points, with appropriate smoothness. */ - avgdev[0] = GAMMAP_RSPLAVGDEV; - if (s->grey->fit_rspl_w(s->grey, GAMMAP_RSPLFLAGS, lpnts, ngreyp, il, ih, &gres, ol, oh, 5.0, avgdev, NULL)) { - fprintf(stderr,"Warning: Grey axis mapping is non-monotonic - may not be very smooth ?\n"); - } + /* Create spline from the data points, with appropriate smoothness. */ + avgdev[0] = GAMMAP_RSPLAVGDEV; + if (s->grey->fit_rspl_w(s->grey, GAMMAP_RSPLFLAGS, lpnts, ngreyp, il, ih, &gres, ol, oh, 5.0, avgdev, NULL)) { + fprintf(stderr,"Warning: Grey axis mapping is non-monotonic - may not be very smooth ?\n"); + } - /* Create an inverse mapping too, for reverse gamut and/or expansion. */ - il[0] = -1.0; /* Set possible input range */ - ih[0] = 101.0; - ol[0] = 0.0; /* Set normalisation output range */ - oh[0] = 100.0; + /* Fine tune the rspl, to make sure that the white and black */ + /* point mapping is precise */ + { + co cp; + adjust1wb cx; /* Adjustment context */ - if ((s->igrey = new_rspl(RSPL_NOFLAGS, 1, 1)) == NULL) /* Allocate 1D -> 1D */ - error("gamut: igrey new_rspl failed"); - - /* Create it from inverse lookups of s->grey */ - s->igrey->set_rspl(s->igrey, 0, (void *)s->grey, inv_grey_func, il, ih, &gres, ol, oh); + /* Lookup actual black & white */ + cp.p[0] = sbL; + s->grey->interp(s->grey, &cp); + cx.awb[0] = cp.v[0]; + + cp.p[0] = swL; + s->grey->interp(s->grey, &cp); + cx.awb[1] = cp.v[0]; + + /* Set target black and white */ + cx.twb[0] = dbL; + cx.twb[1] = dwL; + + /* Fine tune the 3D->3D mapping */ + s->grey->re_set_rspl( + s->grey, /* this */ + 0, /* Combination of flags */ + (void *)&cx, /* Opaque function context */ + adjust1_wb_func /* Function to set from */ + ); + +#ifdef VERBOSE + if (verb) { + printf("Before tuning, L map White/Black is %f %f, should be %f %f\n", + cx.awb[1], cx.awb[0], dwL, dbL); + + /* Lookup fine tuned black & white */ + cp.p[0] = sbL; + s->grey->interp(s->grey, &cp); + cx.awb[0] = cp.v[0]; + + cp.p[0] = swL; + s->grey->interp(s->grey, &cp); + cx.awb[1] = cp.v[0]; + + printf("After tuning, L map White/Black is %f %f, should be %f %f\n", + cx.awb[1], cx.awb[0], dwL, dbL); + } +#endif /* VERBOSE */ + } + + + /* Create an inverse mapping too, for reverse gamut and/or expansion. */ + il[0] = -1.0; /* Set possible input range */ + ih[0] = 101.0; + ol[0] = 0.0; /* Set normalisation output range */ + oh[0] = 100.0; + + if ((s->igrey = new_rspl(RSPL_NOFLAGS, 1, 1)) == NULL) /* Allocate 1D -> 1D */ + error("gamut: igrey new_rspl failed"); + + /* Create it from inverse lookups of s->grey */ + s->igrey->set_rspl(s->igrey, 0, (void *)s->grey, inv_grey_func, il, ih, &gres, ol, oh); - if (revrspl) { /* Swap to compensate for swapping of white and black points */ - rspl *tt = s->grey; - s->grey = s->igrey; - s->igrey = tt; + if (revrspl) { /* Swap to compensate for swapping of white and black points */ + rspl *tt = s->grey; + s->grey = s->igrey; + s->igrey = tt; + } } } @@ -1147,6 +1263,8 @@ glumknf = 1.0; if ((scl_gam = parttransgamut(s, sc_gam)) == NULL) { fprintf(stderr,"gamut map: parttransgamut failed\n"); + if (si_gam != sc_gam) + si_gam->del(si_gam); free(s); return NULL; } @@ -1157,6 +1275,8 @@ glumknf = 1.0; else { if ((sil_gam = parttransgamut(s, si_gam)) == NULL) { fprintf(stderr,"gamut map: parttransgamut failed\n"); + if (si_gam != sc_gam) + si_gam->del(si_gam); free(s); return NULL; } @@ -1169,7 +1289,6 @@ glumknf = 1.0; cow *gpnts = NULL; /* Mapping points to create gamut mapping */ int max_gpnts; int nspts; /* Number of source gamut surface points */ - int rgridpts; /* Number of range surface grid points */ int i, j; datai il, ih; datao ol, oh; @@ -1178,7 +1297,8 @@ glumknf = 1.0; nearsmth *nsm = NULL; /* Returned list of near smooth points */ int nnsm; /* Number of near smoothed points */ double brad = 0.0; /* Black bend radius */ - gammapweights xpweights[14], xsweights[14]; /* Explicit perceptial and sat. weights */ + gammapweights xpweights[14], xlpweights[14], xsweights[14]; + /* Explicit perceptial, lightnes pp. and sat. weights */ gammapweights xwh[14]; /* Structure holding blended weights */ double smooth = 1.0; /* Level of 3D RSPL smoothing, blend of psmooth and ssmooth */ vrml *wrl = NULL; /* Gamut mapping illustration (hulls + guide vectors) */ @@ -1193,17 +1313,9 @@ typedef struct { #endif /* PLOT_3DKNEES */ /* Get the maximum number of points that will be created */ - nspts = near_smooth_np(scl_gam, sil_gam, d_gam, xvra); + nspts = near_smooth_np(NULL, scl_gam, sil_gam, d_gam, xvra, 4, surfpnts ? mapres : 0); - rgridpts = 0; -#ifdef USE_BOUND - if (defrgrid >= 2) { - rgridpts = defrgrid * defrgrid * defrgrid - - (defrgrid -2) * (defrgrid -2) * (defrgrid -2); - } -#endif - - max_gpnts = nres + 3 * nspts + rgridpts; + max_gpnts = nres + nspts; if ((gpnts = (cow *)malloc(max_gpnts * sizeof(cow))) == NULL) { fprintf(stderr,"gamut map: Malloc of mapping setup points failed\n"); s->grey->del(s->grey); @@ -1211,6 +1323,8 @@ typedef struct { if (sil_gam != scl_gam) sil_gam->del(sil_gam); scl_gam->del(scl_gam); + if (si_gam != sc_gam) + si_gam->del(si_gam); free(s); return NULL; } @@ -1251,8 +1365,10 @@ typedef struct { /* Create source grey axis point */ t = i/(nres - 1.0); +#ifdef NEVER /* Cover L = 0.0 to 100.0 */ t = ((100.0 * t) - sl_cs_bp[0])/(sl_cs_wp[0] - sl_cs_bp[0]); +#endif for (j = 0; j < 3; j++) gpnts[ngamp].p[j] = sl_cs_bp[j] + t * (sl_cs_wp[j] - sl_cs_bp[j]); @@ -1297,7 +1413,7 @@ typedef struct { gpnts[ngamp].w = wt; //printf("~1 t = %f, blended %f %f %f\n",t, gpnts[ngamp].v[0], gpnts[ngamp].v[1],gpnts[ngamp].v[2]); -#ifdef NEVER +#ifdef DUMP_GREY_AXIS_POINTS printf("Grey axis %d maps %f %f %f -> %f %f %f wit %f\n",ngamp, gpnts[ngamp].p[0], gpnts[ngamp].p[1], gpnts[ngamp].p[2], gpnts[ngamp].v[0], gpnts[ngamp].v[1], gpnts[ngamp].v[2], @@ -1370,6 +1486,7 @@ typedef struct { /* Convert from compact to explicit hextant weightings */ if (expand_weights(xpweights, pweights) + || expand_weights(xlpweights, lpweights) || expand_weights(xsweights, sweights)) { fprintf(stderr,"gamut map: expand_weights() failed\n"); s->grey->del(s->grey); @@ -1377,13 +1494,17 @@ typedef struct { if (sil_gam != scl_gam) sil_gam->del(sil_gam); scl_gam->del(scl_gam); + if (si_gam != sc_gam) + si_gam->del(si_gam); free(s); return NULL; } - /* Create weights as blend between perceptual and saturation */ - near_xwblend(xwh, xpweights, gmi->gampwf, xsweights, gmi->gamswf); - if ((gmi->gampwf + gmi->gamswf) > 0.1) - smooth = (gmi->gampwf * psmooth) + (gmi->gamswf * ssmooth); + + /* Create weights as blend between perceptual, lightness pp. and saturation */ + near_xwblend3(xwh, xpweights, gmi->gampwf, xlpweights, gmi->gamlpwf, + xsweights, gmi->gamswf); + if ((gmi->gampwf + gmi->gamlpwf + gmi->gamswf) > 0.1) + smooth = (gmi->gampwf * psmooth) + (gmi->gamlpwf * lpsmooth) + (gmi->gamswf * ssmooth); /* Tweak gamut mappings according to extra cmy cusp flags or rel override */ if (dst_cmymap != 0 || rel_oride != 0) { @@ -1395,7 +1516,7 @@ typedef struct { nsm = near_smooth(verb, &nnsm, scl_gam, sil_gam, d_gam, src_kbp, dst_kbp, dr_cs_bp, xwh, gmi->gamcknf, gmi->gamxknf, gmi->gamcpf > 1e-6, gmi->gamexf > 1e-6, - xvra, mapres, smooth, il, ih, ol, oh); + xvra, mapres, smooth, 1.10, surfpnts, il, ih, ol, oh); if (nsm == NULL) { fprintf(stderr,"Creating smoothed near points failed\n"); s->grey->del(s->grey); @@ -1403,58 +1524,11 @@ typedef struct { if (sil_gam != scl_gam) sil_gam->del(sil_gam); scl_gam->del(scl_gam); + if (si_gam != sc_gam) + si_gam->del(si_gam); free(s); return NULL; } - /* --------------------------- */ - - /* Make sure the input range to encompasss the guide vectors. */ - for (i = 0; i < nnsm; i++) { - for (j = 0; j < 3; j++) { - if (nsm[i].sv[j] < il[j]) - il[j] = nsm[i].sv[j];; - if (nsm[i].sv[j] > ih[j]) - ih[j] = nsm[i].sv[j]; - } - } - -#ifdef NEVER - if (verb) { - fprintf(stderr,"Input bounding box:\n"); - fprintfstderr,("%f -> %f, %f -> %f, %f -> %f\n", - il[0], ih[0], il[1], ih[1], il[2], ih[2]); - } -#endif - - /* Now expand the bounding box by aprox 5% margin, but scale grid res */ - /* to match, so that the natural or given boundary still lies on the grid. */ - { - int xmapres; - double scale; - - xmapres = (int) ((mapres-1) * 0.05 + 0.5); - if (xmapres < 1) - xmapres = 1; - - scale = (double)(mapres-1 + xmapres)/(double)(mapres-1); - - for (j = 0; j < 3; j++) { - double low, high; - high = ih[j]; - low = il[j]; - ih[j] = (scale * (high - low)) + low; - il[j] = (scale * (low - high)) + high; - } - - mapres += 2 * xmapres; -#ifdef NEVER - if (verb) { - fprintf(stderr,"After incresing mapres to %d, input bounding box for 3D gamut mapping is:\n",mapres); - fprintf(stderr,"%f -> %f, %f -> %f, %f -> %f\n", - il[0], ih[0], il[1], ih[1], il[2], ih[2]); - } -#endif - } /* ---------------------------------------------------- */ /* Setup for diagnostic plot, that will have elements added */ @@ -1513,18 +1587,25 @@ typedef struct { for (i = 0; i < nnsm; i++) { double cpexf; /* The effective compression or expansion factor */ - if (nsm[i].vflag == 0) { /* Unclear whether compression or expansion */ - /* Use larger to the the two factors */ - cpexf = gmi->gamcpf > gmi->gamexf ? gmi->gamcpf : gmi->gamexf; - - } else if (nsm[i].vflag == 1) { /* Compression */ - cpexf = gmi->gamcpf; - - } else if (nsm[i].vflag == 2) { /* Expansion */ - cpexf = gmi->gamexf; + /* Grid surface point */ + if (nsm[i].uflag != 0) { + cpexf = gmi->gamcpf; /* Assume compression */ + /* Guide vector */ } else { - error("gammap: internal, unknown guide point flag"); + if (nsm[i].vflag == 0) { /* Unclear whether compression or expansion */ + /* Use larger to the the two factors */ + cpexf = gmi->gamcpf > gmi->gamexf ? gmi->gamcpf : gmi->gamexf; + + } else if (nsm[i].vflag == 1) { /* Compression */ + cpexf = gmi->gamcpf; + + } else if (nsm[i].vflag == 2) { /* Expansion */ + cpexf = gmi->gamexf; + + } else { + error("gammap: internal, unknown guide point flag"); + } } /* Compute destination value which is a blend */ @@ -1542,14 +1623,14 @@ typedef struct { gpnts[ngamp].p[j] = nsm[i].sv[j]; gpnts[ngamp].v[j] = nsm[i].div[j]; } - gpnts[ngamp++].w = 1.01; /* Main gamut surface mapping point */ - /* (Use 1.01 as a marker value) */ + gpnts[ngamp++].w = nsm[i].w1; /* 1.01 for guide vectors, less for grid surface */ + if (ngamp >= max_gpnts) error("gammap: internal, not enough space for mapping points B (%d > %d)\n",ngamp, max_gpnts); #ifdef USE_GAMKNF /* Add sub surface mapping point if available */ - if (nsm[i].vflag != 0) { /* Sub surface point is available */ + if (nsm[i].uflag == 0 && nsm[i].vflag != 0) { /* Sub surface point is available */ /* Compute destination value which is a blend */ /* between the source value and the knee adjusted destination */ @@ -1589,82 +1670,6 @@ typedef struct { if (ngamp >= max_gpnts) error("gammap: internal, not enough space for mapping points (%d > %d)\n",ngamp, max_gpnts); - /* Create preliminary gamut mapping rspl, without grid boundary values. */ - /* We use this to lookup the mapping for points on the source space gamut */ - /* that result from clipping our grid boundary points */ -#ifdef USE_BOUND - for (j = 0; j < 3; j++) { /* Set resolution for all axes */ - gres[j] = (mapres+1)/2; - avgdev[j] = GAMMAP_RSPLAVGDEV; - } - s->map = new_rspl(RSPL_NOFLAGS, 3, 3); /* Allocate 3D -> 3D */ - s->map->fit_rspl_w(s->map, GAMMAP_RSPLFLAGS, gpnts, ngamp, il, ih, gres, ol, oh, smooth, avgdev, NULL); - - /* Add input range grid surface anchor points to improve clipping behaviour. */ - if (defrgrid >= 2) { - DCOUNT(gc, 3, 3, 0, 0, defrgrid); - double cent[3]; - - sc_gam->getcent(d_gam, cent); - - DC_INIT(gc); - for (;;) { - /* If point is on the grid surface */ - if ( gc[0] == 0 || gc[0] == (defrgrid-1) - || gc[1] == 0 || gc[1] == (defrgrid-1) - || gc[2] == 0 || gc[2] == (defrgrid-1)) { - double grid2gamut, gamut2cent, ww; - co cp; - - /* Clip the point to the closest location on the source */ - /* colorspace gamut. */ - for (j = 0; j < 3; j++) - gpnts[ngamp].p[j] = il[j] + gc[j]/(defrgrid-1.0) * (ih[j] - il[j]); - sc_gam->nearest(sc_gam, cp.p, gpnts[ngamp].p); - - /* Then lookup the equivalent gamut mapped value */ - s->map->interp(s->map, &cp); - - for (j = 0; j < 3; j++) - gpnts[ngamp].v[j] = cp.v[j]; - - /* Compute the distance of the grid surface point to the to the */ - /* source colorspace gamut, as well as the distance from there */ - /* to the gamut center point. */ - for (grid2gamut = gamut2cent = 0.0, j = 0; j < 3; j++) { - double tt; - tt = gpnts[ngamp].p[j] - cp.p[j]; - grid2gamut += tt * tt; - tt = cp.p[j] - cent[j]; - gamut2cent += tt * tt; - } - grid2gamut = sqrt(grid2gamut); - gamut2cent = sqrt(gamut2cent); - - /* Make the weighting inversely related to distance, */ - /* to reduce influence on in gamut mapping shape, */ - /* while retaining some influence at the edge of the */ - /* grid. */ - ww = grid2gamut / gamut2cent; - if (ww > 1.0) - ww = 1.0; - - /* A low weight seems to be enough ? */ - /* the lower the better in terms of geting best hull mapping fidelity */ - gpnts[ngamp++].w = 0.05 * ww; - - if (ngamp >= max_gpnts) - error("gammap: internal, not enough space for mapping points E (%d > %d)\n",ngamp, max_gpnts); - } - DC_INC(gc); - if (DC_DONE(gc)) - break; - } - } -#else /* !USE_BOUND */ - printf("!!!! Warning - gammap boundary points disabled !!!!\n"); -#endif /* !USE_BOUND */ - /* --------------------------- */ /* Compute the output bounding values, and check input range hasn't changed */ for (i = 0; i < ngamp; i++) { @@ -1691,14 +1696,9 @@ typedef struct { #endif /* Create the final gamut mapping rspl. */ - /* [ The smoothing is not as useful as it should be, because */ - /* if it is increased it tends to push colors out of gamut */ - /* where they get clipped. Some cleverer scheme which makes */ - /* sure that smoothness errs on the side of more compression */ - /* is needed. - Addressed in nearsmth now ? ] */ - /* How about converting to a delta filer ? ie. */ - /* create curren filter, then create point list of delta from */ - /* smoothed value, filtering that and then un-deltering it ?? */ + /* [ How about converting to a delta filer ? ie. */ + /* create current filter, then create point list of delta from */ + /* smoothed value, filtering that and then un-deltering it ?? ] */ if (s->map != NULL) s->map->del(s->map); if (verb) @@ -1720,20 +1720,24 @@ typedef struct { /* (This isn't a good indication now that vectors have been adjusted */ /* to counteract the rspl smoothing at the edges.) */ if (verb) { - double de, avgde = 0.0, maxde = 0.0; /* DE stats */ + double de, avgde = 0.0, maxde = 0.0, num = 0.0; /* DE stats */ for (i = 0; i < nnsm; i++) { double av[3]; + if (nsm[i].uflag != 0) /* Ignore grid boundary points */ + continue; + /* Compute the mapping error */ dopartialmap2(s, av, nsm[i].sv); /* Just the rspl */ de = icmLabDE(nsm[i].div, av); avgde += de; + num++; if (de > maxde) maxde = de; } - printf("Gamut hull fit to guides: = avg %f, max %f\n",avgde/nnsm,maxde); + printf("Gamut hull fit to guides: = avg %f, max %f\n",avgde/num,maxde); } #endif /* CHECK_NEARMAP */ @@ -1830,6 +1834,10 @@ typedef struct { /* Show all neighbours */ wrl->start_line_set(wrl, 0); for (i = 0; i < nnsm; i++) { + + if (nsm[i].uflag != 0) /* Ignore grid boundary points */ + continue; + for (j = 0; j < XNNB; j++) { nearsmth *np = nsm[i].n[j]; /* Pointer to neighbor */ @@ -1865,6 +1873,8 @@ typedef struct { /* Locate the nearest source point */ for (ix = 0; ix < nnsm; ix++) { double dist = icmNorm33(pp, nsm[ix].sv); + if (nsm[i].uflag != 0) /* Ignore grid boundary points */ + continue; if (dist < bdist) { bdist = dist; bix = ix; @@ -1947,6 +1957,9 @@ typedef struct { double *ccc; double mdst[3]; + if (nsm[i].uflag != 0) /* Ignore grid boundary points */ + continue; + #if defined(SHOW_ACTUAL_VECTORS) || defined(SHOW_ACTUAL_VEC_DIFF) # ifdef SHOW_ACTUAL_VECTORS wrl->add_col_vertex(wrl, 0, nsm[i].sv, yellow); @@ -1983,6 +1996,8 @@ typedef struct { #if defined(SHOW_VECTOR_INDEXES) || defined(SHOW_SUB_PNTS) for (i = 0; i < nnsm; i++) { + if (nsm[i].uflag != 0) /* Ignore grid boundary points */ + continue; #ifdef SHOW_VECTOR_INDEXES { double cream[3] = { 0.7, 0.7, 0.5 }; @@ -2124,7 +2139,7 @@ typedef struct { icmMul3By3x4(vec, mat, vec); /* Intersect it with the source gamut */ - if (si_gam->vector_isect(si_gam, vec, cpoint, isect, + if (sil_gam->vector_isect(sil_gam, vec, cpoint, isect, NULL, NULL, NULL, NULL, NULL) == 0) { continue; } @@ -2179,7 +2194,7 @@ typedef struct { icmMul3By3x4(vec, mat, vec); /* Intersect it with the source gamut */ - if (si_gam->vector_isect(si_gam, vec, cpoint, isect, + if (sil_gam->vector_isect(sil_gam, vec, cpoint, isect, NULL, NULL, NULL, NULL, NULL) == 0) { warning("Ring %d vect %d diagnostic vector intersect failed",i,j); continue; @@ -2261,6 +2276,8 @@ typedef struct { if (sil_gam != scl_gam) sil_gam->del(sil_gam); scl_gam->del(scl_gam); + if (si_gam != sc_gam) + si_gam->del(si_gam); return s; } @@ -2451,6 +2468,20 @@ double *in /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +/* Function to pass to rspl to re-set output values, */ +/* to adjust the 1D white and black points */ +static void +adjust1_wb_func( + void *pp, /* adjust1wb structure */ + double *out, /* output value to be adjusted */ + double *in /* corresponding input value */ +) { + adjust1wb *p = (adjust1wb *)pp; + + /* Do a linear re-mapping from actual to target */ + out[0] = (out[0] - p->awb[0]) * (p->twb[1] - p->twb[0])/(p->awb[1] - p->awb[0]) + p->twb[0]; +} + /* Function to pass to rspl to invert grey curve */ static void inv_grey_func( void *cntx, diff --git a/gamut/gamut.c b/gamut/gamut.c index dd4f43b..3fc1c97 100644 --- a/gamut/gamut.c +++ b/gamut/gamut.c @@ -56,7 +56,7 @@ #define TRIANG_TOL 1e-10 /* [1e-10] Triangulation tollerance */ #define NORM_LOG_POW 0.25 /* [0.25] Normal, colorspace lopow value */ -#define RAST_LOG_POW 0.05 /* [0.05] Raster lopow value */ +#define RAST_LOG_POW 0.10 /* [0.10] Raster lopow value (is 0.05 too extreme ??) */ #undef TEST_CONVEX_HULL /* Use pure convex hull, not log hull */ @@ -156,6 +156,7 @@ static int getssvert(gamut *s, double *rad, double pos[3], double norm[3], int i static void startnexttri(gamut *s); static int getnexttri(gamut *s, int v[3]); static double volume(gamut *s); +static int write_to_vrml(gamut *s, vrml *wrl, double trans, int docusps); static int write_trans_vrml(gamut *s, char *filename, int doaxes, int docusps, void (*transform)(void *cntx, double out[3], double in[3]), void *cntx); static int write_vrml(gamut *s, char *filename, int doaxes, int docusps); @@ -174,8 +175,9 @@ static int compute_vector_isect(gamut *s, double *p1, double *p2, double *min, d static int compute_vector_isectns(gamut *s, double *p1, double *p2, gispnt *lp, int ll); static double log_scale(gamut *s, double ss); static int intersect(gamut *s, gamut *s1, gamut *s2); -static int compdstgamut(gamut *s, gamut *img, gamut *src, gamut *dst, int docomp, int doexp, - gamut *nedst, void (*cvect)(void *cntx, double *vec, double *pos), void *cntx); +static int nexpintersect(gamut *s, gamut *s1, gamut *s2); +static int expdstbysrcmdst(gamut *s, gamut *s1, gamut *s2, gamut *s3, + void (*cvect)(void *cntx, double *p2, double *p1), void *cntx); static int vect_intersect(gamut *s, double *rvp, double *ip, double *p1, double *p2, gtri *t); static void compgawb(gamut *s); @@ -656,7 +658,8 @@ int isRast /* Flag indicating Raster rather than colorspace */ s->getvert = getvert; s->volume = volume; s->intersect = intersect; - s->compdstgamut = compdstgamut; + s->nexpintersect = nexpintersect; + s->expdstbysrcmdst = expdstbysrcmdst; s->radial = radial; s->nradial = nradial; s->nearest = nearest; @@ -667,6 +670,7 @@ int isRast /* Flag indicating Raster rather than colorspace */ s->getwb = getwb; s->setcusps = setcusps; s->getcusps = getcusps; + s->write_to_vrml = write_to_vrml; s->write_vrml = write_vrml; s->write_trans_vrml = write_trans_vrml; s->write_gam = write_gam; @@ -1062,44 +1066,13 @@ double pp[3] /* rectangular coordinate of point */ } /* ------------------------------------ */ -/* Initialise this gamut with the intersection of the */ -/* the two given gamuts. Return NZ on error. */ -/* Return 1 if gamuts are not compatible */ -/* (We assume that the this gamut is currently empty) */ -static int intersect(gamut *s, gamut *sa, gamut *sb) { + +/* intersect implementation */ +/* Assumes s has been initialised. */ +static void intersect_imp(gamut *s, gamut *sa, gamut *sb) { int i, j, k; gamut *s1, *s2; - if (sa->compatible(sa, sb) == 0) - return 1; - - if IS_LIST_EMPTY(sa->tris) - triangulate(sa); - if IS_LIST_EMPTY(sb->tris) - triangulate(sb); - - s->isJab = sa->isJab; - - if (sa->isRast || sb->isRast) - s->isRast = 1; - - for (j = 0; j < 3; j++) - s->cent[j] = sa->cent[j]; - - /* Clear some flags */ - s->cswbset = 0; - s->cswbset = 0; - s->dcuspixs = 0; - - /* If either is a raster gamut, make it a raster gamut */ - if (s->isRast) - s->logpow = RAST_LOG_POW; /* Wrap the surface more closely */ - else - s->logpow = NORM_LOG_POW; - - /* Don't filter the points (gives a more accurate result ?) */ - s->nofilter = 1; - /* Add each source gamuts verticies that lie within */ /* the other gamut */ for (k = 0; k < 2; k++) { @@ -1119,6 +1092,7 @@ static int intersect(gamut *s, gamut *sa, gamut *sb) { continue; pl = s2->nradial(s2, NULL, s1->verts[i]->p); + if (pl <= (1.0 + 1e-9)) { expand_gamut(s, s1->verts[i]->p); s1->verts[i]->f &= ~GVERT_ISOS; /* s1 vert is not outside s2 */ @@ -1161,6 +1135,142 @@ static int intersect(gamut *s, gamut *sa, gamut *sb) { } END_FOR_ALL_ITEMS(tp1); } +} + +/* Initialise this gamut with the intersection of the */ +/* the two given gamuts. Return NZ on error. */ +/* Return 1 if gamuts are not compatible */ +/* (We assume that the this gamut is currently empty) */ +static int intersect(gamut *s, gamut *sa, gamut *sb) { + gamut *ss; + int j; + + if (sa->compatible(sa, sb) == 0) + return 1; + + if IS_LIST_EMPTY(sa->tris) + triangulate(sa); + if IS_LIST_EMPTY(sb->tris) + triangulate(sb); + + s->sres = sa->sres > sb->sres ? sa->sres : sb->sres; + + s->isJab = sa->isJab; + + /* Clear some flags */ + s->cswbset = 0; + s->cswbset = 0; + s->dcuspixs = 0; + + /* If either is a raster gamut, make it a raster gamut */ + if (sa->isRast || sb->isRast) + s->isRast = 1; + + if (s->isRast) { + s->logpow = RAST_LOG_POW; /* Wrap the surface more closely */ + s->no2pass = 1; /* Only do one pass */ + } else { + s->logpow = NORM_LOG_POW; /* Convex hull compression power */ + s->no2pass = 0; /* Do two passes */ + } + + for (j = 0; j < 3; j++) + s->cent[j] = sa->cent[j]; + + /* Grab white & black from whichever source has it */ + if (sb->cswbset) + ss = sb; + else if (sb->cswbset) + ss = sa; + + if (ss->cswbset) { + for (j = 0; j < 3; j++) { + s->cs_wp[j] = ss->cs_wp[j]; + s->cs_bp[j] = ss->cs_bp[j]; + s->cs_kp[j] = ss->cs_kp[j]; + } + s->cswbset = ss->cswbset; + } + + /* Don't filter the points (gives a more accurate result ?) */ + s->nofilter = 1; + + intersect_imp(s, sa, sb); + + if (sa->gawbset) { + compgawb(s); + } + + s->nofilter = 0; + + return 0; +} + +/* ------------------------------------ */ + +/* Initialise this gamut with neutral axis points from sa, */ +/* and then intersected with sb. */ +/* Return NZ on error. */ +/* Expand sb with neutral points, and then intersect */ +/* with sa. */ + +/* Return 1 if gamuts are not compatible */ +/* (We assume that the this gamut is currently empty) */ +static int nexpintersect(gamut *s, gamut *sa, gamut *sb) { + int i, j, k; + gamut *s1, *s2; + + if (sa->compatible(sa, sb) == 0) + return 1; + + if IS_LIST_EMPTY(sa->tris) + triangulate(sa); + if IS_LIST_EMPTY(sb->tris) + triangulate(sb); + + s->sres = sa->sres > sb->sres ? sa->sres : sb->sres; + + s->isJab = sa->isJab; + + /* If either is a raster gamut, make it a raster gamut */ + if (sa->isRast || sb->isRast) + s->isRast = 1; + + if (s->isRast) { + s->logpow = RAST_LOG_POW; /* Wrap the surface more closely */ + s->no2pass = 1; /* Only do one pass */ + } else { + s->logpow = NORM_LOG_POW; /* Convex hull compression power */ + s->no2pass = 0; /* Do two passes */ + } + + for (j = 0; j < 3; j++) + s->cent[j] = sa->cent[j]; + + /* Clear some flags */ + s->cswbset = 0; + s->cswbset = 0; + s->dcuspixs = 0; + + /* Don't filter the points (gives a more accurate result ?) */ + s->nofilter = 1; + + /* Number of points to generate */ + k = 10; + if (sa->nv <= 10) + k = 5; + + /* Generate points from black to white */ + for (i = 0; i < k; i++) { + double pp[3]; + double bf = i/(k-1.0); + + icmBlend3(pp, sa->cs_bp, sa->cs_wp, bf); + expand_gamut(s, pp); + } + + /* let intersect_imp to the hard work */ + intersect_imp(s, sa, sb); s->nofilter = 0; @@ -1169,49 +1279,36 @@ static int intersect(gamut *s, gamut *sa, gamut *sb) { /* ------------------------------------ */ /* - Initialise this gamut with a destination mapping gamut. - s1 is the image gamut (a possible sub-set of the src gamut) - s2 is the source gamut - s3 is the destination gamut - - if docomp: - this gamut will be set to the smaller of the img & dst gamuts - else - this gamut will be the img gamut - - if doexp - this gamut will be expanded by the amount dst is outside the src gamut. + Initialise this gamut with the image/destination gamut + expanded by the amount that dest colorspace is outside + the source colorspace gamut. The vector direction of "inwards" is that returned by the - callback function if it is supplied, or radially inwards - if it is not. + callback function as p1 -> p2 if it is supplied, or radially + inwards if it is not. p2 is a "center" point to compute depth to. Return 1 if gamuts are not compatible. - (We assume that the this gamut is currently empty) + (We assume that the _this_ gamut is currently empty) */ #define MXNIS 40 /* Maximum raw intersections handled */ -static int compdstgamut( -gamut *s, /* This */ -gamut *s1, /* Image gamut, assumed to be a subset of source gamut */ +static int expdstbysrcmdst( +gamut *s, /* Gamut to be expanded */ +gamut *s1, /* (Image) destination gamut to be expanded */ gamut *s2, /* The source space gamut */ gamut *s3, /* The destination space gamut */ -int docomp, /* Flag, nz if compression is enabled */ -int doexp, /* Flag, nz if expansion is enabled. */ -gamut *nedst, /* Optional - if doexp, then expand nedst with non-expanded dst gamut */ void (*cvect)(void *cntx, double *p2, double *p1), /* Compression direction callback */ -void *cntx /* Returns p2 which is in desired direction from given p1 */ +void *cntx /* which returns p2 which is in desired direction from given p1 */ ) { -#ifdef STATS - int tedges, edgestested, testhits; -#endif int i, j, k; gamut *ss[3]; - gispnt lp1[MXNIS], lp2[MXNIS], lp3[MXNIS]; /* Intersection lists */ int ll1, ll2, ll3; /* Returned list length */ + gispnt lp1[MXNIS], lp2[MXNIS], lp3[MXNIS]; /* Lists of intersections */ int ii, jj, kk; /* List indexes */ +//printf("\n~1 expdstbysrcmdst() called\n"); + if (s1->compatible(s1, s2) == 0 || s1->compatible(s2, s3) == 0) return 1; @@ -1226,6 +1323,14 @@ void *cntx /* Returns p2 which is in desired direction from given p1 */ s->isJab = s1->isJab; s->isRast = s1->isRast; + if (s->isRast) { + s->logpow = RAST_LOG_POW; /* Wrap the surface more closely */ + s->no2pass = 1; /* Only do one pass */ + } else { + s->logpow = NORM_LOG_POW; /* Convex hull compression power */ + s->no2pass = 0; /* Do two passes */ + } + for (j = 0; j < 3; j++) s->cent[j] = s1->cent[j]; @@ -1234,12 +1339,6 @@ void *cntx /* Returns p2 which is in desired direction from given p1 */ s->cswbset = 0; s->dcuspixs = 0; - /* If s1 is a raster gamut, make output a raster gamut */ - if (s->isRast) - s->logpow = RAST_LOG_POW; /* Wrap the surface more closely */ - else - s->logpow = NORM_LOG_POW; - /* Don't filter the points (gives a more accurate result ?) */ s->nofilter = 1; @@ -1247,26 +1346,12 @@ void *cntx /* Returns p2 which is in desired direction from given p1 */ ss[1] = s2; ss[2] = s3; -//printf("~1 compdstgamut docomp %d, doexp %d\n",docomp,doexp); - /* Reset the above/below flags */ - /* 1 = img above dst */ - /* 2 = img below dst */ - /* 4 = src above dst */ - /* 8 = src below dst */ - for (k = 0; k < 3; k++) { /* For img, src & dst */ - for (i = 0; i < ss[k]->nv; i++) { - if (!(ss[k]->verts[i]->f & GVERT_TRI)) - continue; - - ss[k]->verts[i]->as = 0; - } - } - - /* Use all the triangle vertices from the three gamuts */ + /* Use all the triangle vertices from the two/three gamuts */ /* as candidate points, because any of them might */ /* determine a surface feature. */ - for (k = 0; k < 3; k++) { /* For img, src & dst */ + for (k = 0; k < 3; k++) { + /* For each vertex */ for (i = 0; i < ss[k]->nv; i++) { double pp[3], ppv, p2[3]; double rr, r4; @@ -1276,22 +1361,39 @@ void *cntx /* Returns p2 which is in desired direction from given p1 */ icmCpy3(pp, ss[k]->verts[i]->p); /* Point in question */ + if (k == 0) { /* Seed with all points from gamut */ + expand_gamut(s, pp); /* to ensure result can't be less. */ + } + //printf("\n~1 k %d, point %d: %f %f %f\n", k,i,pp[0],pp[1],pp[2]); + + /* Get the mapping vector */ if (cvect != NULL) - cvect(cntx, p2, pp); /* Get mapping direction */ + cvect(cntx, p2, pp); /* Get mapping direction to center */ else - icmCpy3(p2, ss[k]->cent); /* Radial vector */ - icmNormalize33(p2, p2, pp, 1.0); - - /* Locate the intersecting segments for each gamut */ - ll1 = ll2 = ll3 = 0; - ll1 = s1->vector_isectns(s1, pp, p2, lp1, MXNIS); /* Image gamut */ - if (doexp) /* For dst - src expansion */ - ll2 = s2->vector_isectns(s2, pp, p2, lp2, MXNIS); /* Src gamut */ - if (docomp || doexp) /* For img ^ dst or dst - src */ - ll3 = s3->vector_isectns(s3, pp, p2, lp3, MXNIS); /* Dst gamut */ - -//printf("~1 ll1 %d, ll2 %d, ll3 %d\n",ll1,ll2,ll3); + icmCpy3(p2, ss[k]->cent); /* Radial vector to center */ + icmNormalize33(pp, pp, p2, 1.0); /* Make p2->pp length 1.0 */ + +//printf("~1 k %d, center %d: %f %f %f\n", k,i,p2[0],p2[1],p2[2]); + + /* Locate the intersecting segments for each gamut. */ + /* The returned parameter value will be >= 1.0 at and beyond the center point */ + /* and < 1.0 on the pp side. */ + /* We need intersections for all three for this to be a potential expansion point. */ + if ((ll1 = s1->vector_isectns(s1, pp, p2, lp1, MXNIS)) == 0) { /* Dest gamut */ +//printf("~1 no dst intersection\n"); + continue; + } + if ((ll2 = s2->vector_isectns(s2, pp, p2, lp2, MXNIS)) == 0) { /* Src space */ +//printf("~1 no sc intersection\n"); + continue; + } + + if ((ll3 = s3->vector_isectns(s3, pp, p2, lp3, MXNIS)) == 0) { /* Dst space */ +//printf("~1 no dc intersection\n"); + continue; + } + #ifdef NEVER printf("img segments:\n"); for (ii = 0; ii < ll1; ii++) @@ -1303,264 +1405,120 @@ void *cntx /* Returns p2 which is in desired direction from given p1 */ for (ii = 0; ii < ll3; ii++) printf("Isect %d: pv %f, dir %d, edge %d, tri %d\n",ii,lp3[ii].pv,lp3[ii].dir,lp3[ii].edge,lp3[ii].tri->n); #endif - /* Now go through each image segment */ - for (ii = 0; ii < ll1; ii += 2) { - icmCpy3(pp, lp1[ii].ip); - ppv = lp1[ii].pv; - -//printf("~1 img pnt at %f\n",lp1[ii].pv); - if (docomp) { - - /* Locate a dst segment around or below img point */ - for (kk = 0; kk < ll3; kk += 2) { - if ((lp1[kk+1].pv + 1e-8) >= ppv) - break; - } - - if (kk >= ll3) { /* No dst segments or none below */ - ss[k]->verts[i]->as |= 1; /* img above dst */ -//printf("~1 img pnt is outside dst\n"); - continue; - } else { -//printf("~1 ing %f - %f, dst %f - %f\n", lp1[ii].pv,lp1[ii+1].pv,lp3[kk].pv,lp3[kk+1].pv); - /* Use the dst point if it is smaller */ - if (ppv < lp3[kk].pv) { - icmCpy3(pp, lp3[kk].ip); - ppv = lp3[kk].pv; -//printf("~1 dst is smaller %f\n",ppv); - ss[k]->verts[i]->as |= 1; /* img above dst */ - } else { -//printf("~1 ing is smaller %f\n",ppv); - ss[k]->verts[i]->as |= 2; /* img below dst */ - } - } - } - - if (nedst != NULL) - expand_gamut(nedst, pp); - - while (doexp) { - /* Locate a src segment that ing point lies in. */ - for (jj = 0; jj < ll2; jj += 2) { - if (lp1[ii].pv >= (lp2[jj].pv - 1e-8) - && lp1[ii].pv <= (lp2[jj+1].pv + 1e-8)) - break; - } - if (jj >= ll2) { - ss[k]->verts[i]->as |= 4; /* src above dst ?? */ - break; /* No overlapping segment */ - } - - /* Locate a dst segment that src point lies in */ - for (kk = 0; kk < ll3; kk += 2) { - if (lp2[jj].pv >= (lp3[kk].pv - 1e-8) - && lp2[jj].pv <= (lp3[kk+1].pv + 1e-8)) - break; - } - if (kk >= ll2) { - ss[k]->verts[i]->as |= 4; /* src above dst ?? */ - break; /* No overlapping segment */ - } - - /* if src is outside dst, do nothing */ - if (lp3[kk].pv >= lp2[jj].pv) { - ss[k]->verts[i]->as |= 4; /* src above dst */ - break; - } - - /* Expand point by dst - src */ - icmAdd3(pp, pp, lp3[kk].ip); - icmSub3(pp, pp, lp2[jj].ip); - ss[k]->verts[i]->as |= 8; /* src below dst */ -//printf("~1 expanding point by %f - %f\nb",lp3[kk].pv,lp2[jj].pv); - break; - } + /* We're only interested in the most outside intersection of each surface */ + /* on the side of the point in question. (we're ignoring and complex */ + /* topology) */ + if (lp1[0].pv > (1.0 - 1e-8)) { +//printf("~1 dst point is on other side\n"); + continue; + } + if (lp2[0].pv > (1.0 - 1e-8)) { +//printf("~1 sc point is on other side\n"); + continue; + } + if (lp3[0].pv > (1.0 - 1e-8)) { +//printf("~1 sc point is on other side\n"); + continue; + } + + /* Make sure that sc is inside dc, */ + /* and sc is on or above dst */ + if (lp2[0].pv > (lp3[0].pv - 1e-8) + && lp2[0].pv <= (lp1[0].pv + 1e-8)) { + double ex[3], sf; + + /* Expand point by up to dst - src */ + icmSub3(ex, lp3[0].ip, lp2[0].ip); + + /* Make expansion proportional to how far dst */ + /* is to sc */ + sf = (1.0 - lp1[0].pv)/(1.0 - lp2[0].pv); + icmScale3(ex, ex, sf); + icmAdd3(pp, lp1[0].ip, ex); + +//printf("~1 expanding point by sf %f = %f %f %f\nb",sf,ex[0],ex[1],ex[2]); +//printf("~1 to %f %f %f\nb",pp[0],pp[1],pp[2]); expand_gamut(s, pp); + } else { +//printf("~1 lp2 %f <= lp3 %f || lp2 %f > lp2 %f\n",lp2[0].pv,lp3[0].pv - 1e-8, lp2[0].pv, lp1[0].pv + 1e-8); +//printf("~1 dc is inside sc or sc is inside dst\n"); } } } -#ifdef STATS - tedges = edgestested = testhits = 0; -#endif + /* Generate points along the intersection of sc and dc, map them */ + /* to the image/dest gamut, and add them as well. This is to properly define */ + /* the edges of the expansion zone. */ - /* Add any intersection points between img/dst, and src/dst */ - for (k = 0; k < 4; k++) { - int mask; - gamut *sa, *sb; - gtri *tpa, *tpb; /* Triangle pointers */ + /* For sc on dc and then dc on sc */ + for (k = 0; k < 2; k++) { + gamut *ss1, *ss2; + gtri *tp1, *tp2; /* Triangle pointers */ if (k == 0) { - if (!docomp) - continue; - mask = 3; - sa = s1; /* img */ - sb = s3; /* dst */ - } else if (k == 1) { - if (!docomp) - continue; - mask = 3; - sa = s3; /* dst */ - sb = s1; /* img */ - } else if (k == 2) { - if (!doexp) - continue; - mask = 12; - sa = s2; /* src */ - sb = s3; /* dst */ - } else if (k == 3) { - if (!doexp) - continue; - mask = 12; - sa = s3; /* dst */ - sb = s2; /* src */ + ss1 = s2; + ss2 = s3; + } else { + ss1 = s3; + ss2 = s2; } - /* Now find the edges that intersect the other gamut */ - tpa = sa->tris; - FOR_ALL_ITEMS(gtri, tpa) { + /* Find the edges that intersect the other gamut */ + tp1 = ss1->tris; + FOR_ALL_ITEMS(gtri, tp1) { /* For all ss1 triangles */ - for (j = 0; j < 3; j++) { /* For each edge */ -#ifdef STATS - tedges++; -#endif - /* If edge disposition flags aren't the same */ - if ((tpa->e[j]->v[0]->as ^ tpa->e[j]->v[1]->as) & mask - || (tpa->e[j]->v[0]->as & mask) == 3 || (tpa->e[j]->v[0]->as & mask) == 12 - || (tpa->e[j]->v[1]->as & mask) == 3 || (tpa->e[j]->v[1]->as & mask) == 12) { -#ifdef STATS - edgestested++; -#endif - /* Exhaustive search of other triangles */ - tpb = sb->tris; - FOR_ALL_ITEMS(gtri, tpb) { + for (j = 0; j < 3; j++) { /* For all edges in ss1 triangle */ + /* If edge passes through the other gamut */ + if ((tp1->e[j]->v[0]->f ^ tp1->e[j]->v[1]->f) & GVERT_ISOS) { + + /* Exhaustive search of other triangles in ss2, */ + /* to find the one that the edge intersects with. */ + tp2 = ss2->tris; + FOR_ALL_ITEMS(gtri, tp2) { double pv; double pp[3]; /* Do a min/max intersection elimination test */ for (i = 0; i < 3; i++) { - if (tpb->mix[1][i] < tpa->mix[0][i] - || tpb->mix[0][i] > tpa->mix[1][i]) + if (tp2->mix[1][i] < tp1->mix[0][i] + || tp2->mix[0][i] > tp1->mix[1][i]) break; /* min/max don't overlap */ } if (i < 3) continue; /* Skip this triangle, it can't intersect */ - if (vect_intersect(sa, &pv, pp, tpa->e[j]->v[0]->p, tpa->e[j]->v[1]->p, tpb) + if (vect_intersect(ss1, &pv, pp, tp1->e[j]->v[0]->p, tp1->e[j]->v[1]->p, tp2) && pv >= (0.0 - 1e-10) && pv <= (1.0 + 1e-10)) { - /* Process intersection point pp the same as the first loop */ - double ppv, p2[3]; - double rr, r4; -#ifdef STATS - testhits++; -#endif -//printf("\n~1 tri isxn point %f %f %f\n", pp[0],pp[1],pp[2]); - if (cvect != NULL) - cvect(cntx, p2, pp); /* Get mapping direction */ - else - icmCpy3(p2, sa->cent); /* Radial vector */ - icmNormalize33(p2, p2, pp, 1.0); - - /* Locate the intersecting segments for each gamut */ - ll1 = ll2 = ll3 = 0; - ll1 = s1->vector_isectns(s1, pp, p2, lp1, MXNIS); /* Image gamut */ - if (doexp) /* For dst - src expansion */ - ll2 = s2->vector_isectns(s2, pp, p2, lp2, MXNIS); /* Src gamut */ - if (docomp || doexp) /* For img ^ dst or dst - src */ - ll3 = s3->vector_isectns(s3, pp, p2, lp3, MXNIS); /* Dst gamut */ - -//printf("~1 ll1 %d, ll2 %d, ll3 %d\n",ll1,ll2,ll3); -#ifdef NEVER - printf("img segments:\n"); - for (ii = 0; ii < ll1; ii++) - printf("Isect %d: pv %f, dir %d, edge %d, tri %d\n",ii,lp1[ii].pv,lp1[ii].dir,lp1[ii].edge,lp1[ii].tri->n); - printf("src segments:\n"); - for (ii = 0; ii < ll2; ii++) - printf("Isect %d: pv %f, dir %d, edge %d, tri %d\n",ii,lp2[ii].pv,lp2[ii].dir,lp2[ii].edge,lp2[ii].tri->n); - printf("dst segments:\n"); - for (ii = 0; ii < ll3; ii++) - printf("Isect %d: pv %f, dir %d, edge %d, tri %d\n",ii,lp3[ii].pv,lp3[ii].dir,lp3[ii].edge,lp3[ii].tri->n); -#endif - /* Now go through each image segment */ - for (ii = 0; ii < ll1; ii += 2) { + double p2[3]; - icmCpy3(pp, lp1[ii].ip); - ppv = lp1[ii].pv; + /* Got intersection point pp. */ -//printf("~1 img pnt at %f\n",lp1[ii].pv); - if (docomp) { - - /* Locate a dst segment around or below img point */ - for (kk = 0; kk < ll3; kk += 2) { - if ((lp1[kk+1].pv + 1e-8) >= ppv) - break; - } - - if (kk >= ll3) { /* No dst segments or none below */ -//printf("~1 img pnt is outside dst\n"); - continue; - } else { -//printf("~1 ing %f - %f, dst %f - %f\n", lp1[ii].pv,lp1[ii+1].pv,lp3[kk].pv,lp3[kk+1].pv); - /* Use the dst point if it is smaller */ - if (ppv < lp3[kk].pv) { - icmCpy3(pp, lp3[kk].ip); - ppv = lp3[kk].pv; -//printf("~1 dst is smaller %f\n",ppv); - } else { -//printf("~1 ing is smaller %f\n",ppv); - } - } - } - - if (nedst != NULL) - expand_gamut(nedst, pp); - - while (doexp) { - /* Locate a src segment that ing point lies in */ - for (jj = 0; jj < ll2; jj += 2) { - if (lp1[ii].pv >= (lp2[jj].pv - 1e-8) - && lp1[ii].pv <= (lp2[jj+1].pv + 1e-8)) - break; - } - if (jj >= ll2) { - break; /* No overlapping segment */ - } - - /* Locate a dst segment that src point lies in */ - for (kk = 0; kk < ll3; kk += 2) { - if (lp2[jj].pv >= (lp3[kk].pv - 1e-8) - && lp2[jj].pv <= (lp3[kk+1].pv + 1e-8)) - break; - } - if (kk >= ll2) { - break; /* No overlapping segment */ - } - - /* if src is outside dst, do nothing */ - if (lp3[kk].pv >= lp2[jj].pv) { - break; - } - - /* Expand point by dst - src */ - icmAdd3(pp, pp, lp3[kk].ip); - icmSub3(pp, pp, lp2[jj].ip); -//printf("~1 expanding point by %f - %f\nb",lp3[kk].pv,lp2[jj].pv); - break; - } - expand_gamut(s, pp); + /* Get the mapping vector */ + if (cvect != NULL) + cvect(cntx, p2, pp); /* Get mapping direction to center */ + else + icmCpy3(p2, ss[k]->cent); /* Radial vector to center */ + icmNormalize33(pp, pp, p2, 1.0); /* Make p2->pp length 1.0 */ + + /* Locate the intersecting segments for the img/dest gamut. */ + /* The returned parameter value will be >= 1.0 at and beyond */ + /* the center point and < 1.0 on the pp side. */ + /* We're only going to bother with the most outside point */ + if ((ll1 = s1->vector_isectns(s1, pp, p2, lp1, MXNIS)) == 0 + || lp1[0].pv > (1.0 - 1e-8)) { + continue; } + + expand_gamut(s, pp); } - } END_FOR_ALL_ITEMS(tpb); + } END_FOR_ALL_ITEMS(tp2); } } - } END_FOR_ALL_ITEMS(tpa); + } END_FOR_ALL_ITEMS(tp1); } -#ifdef STATS - printf("Total edges %d, edges tested %d, edge hits %d\n", tedges, edgestested, testhits); -#endif s->nofilter = 0; return 0; @@ -3949,7 +3907,7 @@ double *nin /* Normalised center relative point */ if (fabs(denom) < 1e-9) { /* Hmm. The ray is paralell to the triangle ? */ - error("radial_point: failed to intersect radial triangle\n"); + error("radial_point: failed to intersect radial triangle, num %e, denom %e\n",num,denom); } rv = num/denom; @@ -5624,7 +5582,7 @@ int ll /* Size of list. */ return 0; /* Too few to be useful */ } - /* Now we need to turn th raw intersections into sanitized segment pairs. */ + /* Now we need to turn the raw intersections into sanitized segment pairs. */ /* Sort the intersections by parameter value */ #define HEAP_COMPARE(A,B) (A.pv < B.pv) @@ -5801,7 +5759,67 @@ int ll /* Size of list. */ #endif /* INTERSECT_DEBUG */ /* ===================================================== */ -/* Write to a VRML/X3d file */ + +/* Append gamut to an open VRML/X3d file */ +/* Return non-zero on error */ +static int write_to_vrml( + gamut *s, + vrml *wrl, + double trans, /* Transparency of gamut */ + int docusps /* Add cusps to vrml */ +) { + int i; + gtri *tp; /* Triangle pointer */ + + if IS_LIST_EMPTY(s->tris) + triangulate(s); + + if (docusps && s->cu_inited != 0) { + double ccolors[6][3] = { + { 1.0, 0.1, 0.1 }, /* Red */ + { 1.0, 1.0, 0.1 }, /* Yellow */ + { 0.1, 1.0, 0.1 }, /* Green */ + { 0.1, 1.0, 1.0 }, /* Cyan */ + { 0.1, 0.1, 1.0 }, /* Blue */ + { 1.0, 0.1, 1.0 } /* Magenta */ + }; + + for (i = 0; i < 6; i++) + wrl->add_marker(wrl, s->cusps[i], ccolors[i], 2.0); + } + + wrl->start_line_set(wrl, 0); + + /* Spit out the vertex values, in order. */ + for (i = 0; i < s->nv; i++) { + double out[3]; + + if (!(s->verts[i]->f & GVERT_TRI)) + continue; + + /* Show normal gamut surface */ + out[0] = s->verts[i]->p[0]; + out[1] = s->verts[i]->p[1]; + out[2] = s->verts[i]->p[2]; + wrl->add_vertex(wrl, 0, out); + } + + /* Add the surface triangles */ + tp = s->tris; + FOR_ALL_ITEMS(gtri, tp) { + int ix[3]; + ix[0] = tp->v[0]->tn; + ix[1] = tp->v[1]->tn; + ix[2] = tp->v[2]->tn; + wrl->add_triangle(wrl, 0, ix); + } END_FOR_ALL_ITEMS(tp); + + wrl->make_triangles_vc(wrl, 0, trans); + + return 0; +} + +/* Write gamut to a VRML/X3d file */ /* Return non-zero on error */ static int write_vrml( gamut *s, @@ -5812,7 +5830,7 @@ int docusps /* Non-zero if cusp points are to be marked */ return write_trans_vrml(s, filename, doaxes, docusps, NULL, NULL); } -/* Write to a VRML/X3d file */ +/* Write gamut to a VRML/X3d file */ /* Return non-zero on error */ static int write_trans_vrml( gamut *s, @@ -5926,7 +5944,7 @@ void *cntx ix[2] = tp->v[2]->tn; wrl->add_triangle(wrl, 0, ix); } END_FOR_ALL_ITEMS(tp); -#endif /* SHOW_BUCKETS */ +#endif /* !SHOW_BUCKETS */ { double rgb[3]; diff --git a/gamut/gamut.h b/gamut/gamut.h index 467852f..e70d898 100644 --- a/gamut/gamut.h +++ b/gamut/gamut.h @@ -36,6 +36,8 @@ #define MAXGAMN 10 /* Maximum gamut point neighbors returned */ #define NSLOTS 6 /* Number of maximum direction slots */ +struct _vrml *wrl; /* Declared in vrml.h, which may be #included after this */ + /* ------------------------------------ */ #define NODE_STRUCT \ int tag; /* Type of node, 1 = vertex, 2 = quad */ \ @@ -72,7 +74,7 @@ struct _gvert { double sp[3]; /* Point mapped to surface of unit sphere, relative to center */ double ch[3]; /* Point mapped for convex hull testing, relative to center */ - int as; /* Assert checking flag, compdstgamut flag */ + int as; /* Assert checking flag, expdstbysrcmdst flag */ }; typedef struct _gvert gvert; /* ------------------------------------ */ @@ -188,7 +190,7 @@ struct _gnn { struct _gispnt { double ip[3]; /* Intersecion Point */ double pv; /* Parameter value at intersection */ - int dir; /* Direction: 1 = into gamut, 0 = out or gamut */ + int dir; /* Direction: 1 = into gamut, 0 = out of gamut */ int edge; /* Edge: 2 = no isect, 1 = on edge, 0 = not on edge */ gtri *tri; /* Pointer to intersection triangle */ }; typedef struct _gispnt gispnt; @@ -313,17 +315,14 @@ struct _gamut { /* Initialise this gamut with the intersection of the */ /* the two given gamuts. */ -#ifdef NEVER /* Deprecated */ - int (*expandbydiff)(struct _gamut *s, struct _gamut *s1, struct _gamut *s2, struct _gamut *s3, int docomp); - /* Initialise this gamut with a gamut which is s1 expanded */ - /* (but never reduced) by the distance from s2 to s3. */ - /* If docomp != 0, make gamut trace s3 if it's smaller than s1 */ -#endif + int (*nexpintersect)(struct _gamut *s, struct _gamut *s1, struct _gamut *s2); + /* Return s1 expanded with neutral axis points */ + /* and then intersected with s2. */ - int (*compdstgamut)(struct _gamut *s, struct _gamut *img, struct _gamut *src, - struct _gamut *dst, int docomp, int doexpp, struct _gamut *nedst, - void (*cvect)(void *cntx, double *p2, double *p1), void *cntx); - /* Initialise this gamut with a destination mapping gamut. */ + int (*expdstbysrcmdst)(struct _gamut *s, + struct _gamut *dst, struct _gamut *sc, struct _gamut *dc, + void (*cvect)(void *cntx, double *p2, double *p1), void *cntx); + /* Expand dst by ((dc - sc) > 0) */ double (*radial)(struct _gamut *s, double out[3], double in[3]); /* return point on surface in same radial direction. */ @@ -384,6 +383,8 @@ struct _gamut { /* nz if no cusps available. */ /* Following return nz on error: */ + int (*write_to_vrml)(struct _gamut *s, struct _vrml *wrl, double trans, int docusps); + /* Append gamut surface to vrml. See also vrml->make_gamut_surface() etc. */ int (*write_vrml)(struct _gamut *s, char *filename, int doaxes, int docusps); /* Write to a VRML .wrl/.x3d file */ int (*write_gam)(struct _gamut *s, char *filename); /* Write to a CGATS .gam file */ diff --git a/gamut/maptest.c b/gamut/maptest.c index 3a33453..433e719 100644 --- a/gamut/maptest.c +++ b/gamut/maptest.c @@ -192,6 +192,7 @@ main(int argc, char *argv[]) { gmi.gampwf = 1.0; /* Gamut Perceptual Map weighting factor, 0.0 - 1.0 */ gmi.gamswf = 0.0; /* Gamut Saturation Map weighting factor, 0.0 - 1.0 */ } + gmi.gamlpwf = 0.0; /* Gamut Lightness preserving perceptual Map whtg. factor, 0.0 - 1.0 */ gmi.satenh = 0.0; /* Saturation enhancement factor */ gmi.desc = "mapetest"; gmi.icci = 0; @@ -205,7 +206,7 @@ main(int argc, char *argv[]) { 0, 0, /* Normal black points */ 0, /* Normal CMY cusp mapping */ 0, /* No relative weighting override */ - 17, /* rspl resolution of 17 */ + 19, /* rspl resolution of 17 */ NULL, /* No input range override */ NULL, gammapwrl /* Diagnostic plot */ diff --git a/gamut/nearsmth.c b/gamut/nearsmth.c index c0bd2be..c65704e 100644 --- a/gamut/nearsmth.c +++ b/gamut/nearsmth.c @@ -52,6 +52,7 @@ #include #include #include +#include "counters.h" #include "icc.h" #include "numlib.h" #include "rspl.h" @@ -60,12 +61,14 @@ #include "vrml.h" #undef SAVE_VRMLS /* [Und] Save various vrml's */ +#undef PLOT_SMOOTHING_CHANGE /* [Und] Dest point change due to smoothing in "dst_smvec.wrl" */ #undef PLOT_MAPPING_INFLUENCE /* [Und] Plot sci_gam colored by dominant guide influence: */ /* Absolute = red, Relative = yellow, Radial = blue, Depth = green */ #undef PLOT_AXES /* [Und] */ #undef PLOT_EVECTS /* [Und] Create VRML of error correction vectors */ #undef VERB /* [Und] [0] If <= 1, print progress headings */ /* if > 1, print information about everything */ +#undef SHOW_NEIGB /* [Und] Show the neighborhood point group in src */ #undef SHOW_NEIGB_WEIGHTS /* [Und] Show the weighting for each point of neighbours in turn */ #undef DIAG_POINTS /* [Und] Short circuite mapping and show vectors of various */ @@ -78,9 +81,8 @@ #define DARK_L 5.0 /* "dark" L/J value */ #define NEUTRAL_C 20.0 /* "neutral" C value */ #define NO_TRIALS 6 /* [6] Number of random trials */ -#define VECSMOOTHING /* [Def] Enable vector smoothing */ -#define VECADJPASSES 3 /* [3] Adjust vectors after smoothing to be on dest gamut */ -#define RSPLPASSES 4 /* [4] Number of rspl adjustment passes */ +#define VECADJPASSES 8 /* [8] Vector smoothing and adjust passes. */ +#define RSPLPASSES 4 /* [4] Number of rspl smoothing & adjustment passes */ #define RSPLSCALE 1.8 /* [1.8] Offset within gamut for rspl smoothing to aim for */ #define SHRINK 5.0 /* [5.0] Shrunk destination evect surface factor */ #define CYLIN_SUBVEC /* [Def] Make sub-vectors always cylindrical direction */ @@ -114,7 +116,7 @@ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #if defined(SAVE_VRMLS) && defined(PLOT_MAPPING_INFLUENCE) -static void create_influence_plot(nearsmth *smp, int nmpts); +static void create_influence_plot(nearsmth *smp, int nmpts, int mapres); #endif /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -194,7 +196,7 @@ double sumpow /* Sum power. 0.0 == 2.0 */ /* Compute the LCh differences squared of in1 - in2 */ /* (This is like the CIE DE94) */ -static void diffLCh( +static void diffLChsq( double out[3], double in1[3], /* Destination location */ double in2[3] /* Source location */ @@ -258,7 +260,7 @@ double dcratio, /* Depth compression ratio of mapping */ double dxratio /* Depth expansion ratio of mapping */ ) { double a_o; - double va, vr = 0.0, vl, vd, vv = 0.0; + double va, vr, vd, vv = 0.0; /* Absolute, Delta E^2 between test point and destination closest */ /* aodv is already positioned acording to the LCh weights, */ @@ -267,7 +269,7 @@ double dxratio /* Depth expansion ratio of mapping */ va = wdesq(dtp, aodv, a_o, a_o, a_o, SUM_POW); /* Radial. Delta E^2 between test point and source mapped radially to dest gamut */ - vl = wdesq(dtp, drv, w->rl.l, w->rl.c, w->rl.h, SUM_POW); + vr = wdesq(dtp, drv, w->rl.l, w->rl.c, w->rl.h, SUM_POW); /* Depth ratio error^2. */ vd = w->d.co * dcratio * dcratio @@ -276,17 +278,16 @@ double dxratio /* Depth expansion ratio of mapping */ /* Diagnostic values */ p->dbgv[0] = va; p->dbgv[1] = vr; - p->dbgv[2] = vl; - p->dbgv[3] = vd; + p->dbgv[2] = vd; - vv = va + vr + vl + vd; /* Sum of squares */ -// vv = sqrt(va) + sqrt(vr) + sqrt(vl) + sqrt(vd); /* Linear sum is better ? */ -// vv = pow(va, 0.7) + pow(vr, 0.7) + pow(vl, 0.7) + pow(vd, 0.7); /* Linear sum is better ? */ + vv = va + vr + vd; /* Sum of squares */ +// vv = sqrt(va) + sqrt(vr) + sqrt(vd); /* Linear sum is better ? */ +// vv = pow(va, 0.7) + pow(vr, 0.7) + pow(vd, 0.7); /* Linear sum is better ? */ #ifdef NEVER printf("~1 dtp %f %f %f\n", dtp[0], dtp[1], dtp[2]); printf("~1 va = %f from aodv %f %f %f, weight %f\n", va, aodv[0], aodv[1], aodv[2], a_o); - printf("~1 vl = %f from drv %f %f %f, weights %f %f %f\n", vl, drv[0], drv[1], drv[2], w->rl.l, w->rl.c, w->rl.h); + printf("~1 vr = %f from drv %f %f %f, weights %f %f %f\n", vr, drv[0], drv[1], drv[2], w->rl.l, w->rl.c, w->rl.h); printf("~1 vd = %f from d.co %f d.xo %f, weights %f %f\n", vd, w->d.co,w->d.xo,dcratio * dcratio,dxratio * dxratio); printf("~1 return vv = %f\n", vv); #endif /* NEVER */ @@ -300,12 +301,13 @@ double dxratio /* Depth expansion ratio of mapping */ /* and cusp mapping function. */ struct _smthopt { /* optimisation */ + int debug; /* debug flag */ int pass; /* Itteration round */ int ix; /* Index of point being optimized */ nearsmth *p; /* Point being optimised */ int useexp; /* Flag indicating whether expansion is permitted */ - int debug; /* debug flag */ - gamut *shgam; /* for optfunc1a */ + double *wn; /* Target of weighted nearest */ + gamut *wngam; /* for optfunc1 and optfunc1a */ /* Setup state */ int isJab; /* Flag indicating Jab rather than Lab space */ @@ -334,7 +336,7 @@ struct _smthopt { }; typedef struct _smthopt smthopt; -static void init_ce(smthopt *s, gamut *sc_gam, gamut *d_gam, int src_kbp, int dst_kbp, double d_bp[3]); +static void init_ce(smthopt *s, gamut *sc_gam, gamut *si_gam, gamut *d_gam, int src_kbp, int dst_kbp, double d_bp[3]); static void comp_ce(smthopt *s, double out[3], double in[3], gammapweights *wt); static void inv_comp_ce(smthopt *s, double out[3], double in[3], gammapweights *wt); static double comp_naxbf(smthopt *s, double in[3]); @@ -357,84 +359,97 @@ static void spow3(double *out, double *in, double ex) { } } -/* Powell optimisation function for setting minimal absolute error target point. */ -/* We get a 2D plane in the 3D space, of the destination point, */ -/* who's location we are optimizing. */ -static double optfunc1( -void *fdata, -double *_dv +/* Absolute error function, used by optfunc1() & optfunc1a() */ +static double aerrf( + nearsmth *p, + double *dv, + double *sv ) { - smthopt *s = (smthopt *)fdata; - nearsmth *p = s->p; /* Point being optimised */ - int i, j, k; - double dv[3]; /* 3D point in question */ - double ddv[3]; /* Point in question mapped to dst surface */ - double delch[3]; - double rv; /* Out of gamut, return value */ - - /* Convert from 2D to 3D. */ - dv[2] = _dv[1]; - dv[1] = _dv[0]; - dv[0] = 50.0; - icmMul3By3x4(dv, p->m3d, dv); - -//printf("~1 optfunc1 got 2D %f %f -> 3D %f %f %f\n", _dv[0], _dv[1], dv[0], dv[1], dv[2]); - p->dgam->radial(p->dgam, ddv, dv); /* Map to dst surface to check current location */ -//printf("~1 optfunc1 got %f %f %f -> surface %f %f %f\n", dv[0], dv[1], dv[2], ddv[0], ddv[1], ddv[2]); - - if (p->swap) { - /* This is actually a point on the real source gamut, so */ - /* convert to cusp mapped rotated source gamut value */ - comp_ce(s, ddv, ddv, &p->wt); -//printf("~1 after cusp rot got %f %f %f\n",ddv[0],ddv[1],ddv[2]); - } + double delch[3], rv; #ifdef NEVER /* Absolute weighted delta E between source and dest test point */ - rv = wdesq(ddv, p->sv, p->wt.ra.l, p->wt.ra.c, p->wt.ra.h, SUM_POW); + rv = wdesq(dv, sv, p->wt.ra.l, p->wt.ra.c, p->wt.ra.h, SUM_POW); #else { - double ppp = p->wt.a.lxpow; + double ppp = p->wt.a.lxpow; /* Extra power when L de is over thr */ double thr = p->wt.a.lxthr; /* Xover between normal and power */ double sumpow = SUM_POW; + double del; - diffLCh(delch, ddv, p->sv); + diffLChsq(delch, dv, sv); + del = sqrt(delch[0]); /* delta L */ if (sumpow == 0.0 || sumpow == 2.0) { /* Normal sum of squares */ #ifdef LINEAR_HUE_SUM double ll, cc, hh; - ll = p->wt.ra.l * pow(delch[0], ppp) * thr/pow(thr, ppp); + ll = p->wt.ra.l * pow(delch[0], 1.0 + (ppp - 1.0) * del/(del + thr)); cc = p->wt.ra.c * delch[1]; hh = p->wt.ra.h * delch[2]; rv = sqrt(ll + cc) + sqrt(hh); rv *= rv; #else - rv = p->wt.ra.l * pow(delch[0], ppp) * thr/pow(thr, ppp) + rv = p->wt.ra.l * pow(delch[0], 1.0 + (ppp - 1.0) * del/(del + thr)) + p->wt.ra.c * delch[1] + p->wt.ra.h * delch[2]; #endif } else { sumpow *= 0.5; - - rv = p->wt.ra.l * pow(delch[0], ppp * sumpow) * thr/pow(thr, ppp * sumpow) + rv = p->wt.ra.l * pow(delch[0], (1.0 + (ppp - 1.0) * del/(del + thr)) * sumpow) + p->wt.ra.c * pow(delch[1], sumpow) + p->wt.ra.h * pow(delch[2], sumpow); } } #endif + return rv; +} + +/* Powell optimisation function for setting minimal absolute error target point, */ +/* with a correction for swap. */ +/* We get a 2D plane in the 3D space, of the destination point, */ +/* who's location we are optimizing to wngam. */ +static double optfunc1( +void *fdata, +double *_dv +) { + smthopt *s = (smthopt *)fdata; + nearsmth *p = s->p; /* Point being optimised */ + int i, j, k; + double dv[3]; /* 3D point in question */ + double ddv[3]; /* Point in question mapped to wngam surface */ + double rv; /* Out of gamut, return value */ + + /* Convert from 2D to 3D. */ + dv[2] = _dv[1]; + dv[1] = _dv[0]; + dv[0] = 50.0; + icmMul3By3x4(dv, p->m3d, dv); + +//printf("~1 optfunc1 got 2D %f %f -> 3D %f %f %f\n", _dv[0], _dv[1], dv[0], dv[1], dv[2]); + s->wngam->radial(s->wngam, ddv, dv); /* Map to dst surface to check current location */ +//printf("~1 optfunc1 got %f %f %f -> surface %f %f %f\n", dv[0], dv[1], dv[2], ddv[0], ddv[1], ddv[2]); + + if (p->swap) { + /* This is actually a point on the real source gamut, so */ + /* convert to cusp mapped rotated source gamut value */ + comp_ce(s, ddv, ddv, &p->wt); +//printf("~1 after cusp rot got %f %f %f\n",ddv[0],ddv[1],ddv[2]); + } + + rv = aerrf(p, ddv, s->wn); if (s->debug) - printf("debug: rv = %f from %f %f %f\n",rv, ddv[0], ddv[1], ddv[2]); + printf("debug: rv = %f from %f %f %f -> %f %f %f\n",rv, s->wn[0], s->wn[1], s->wn[2], ddv[0], ddv[1], ddv[2]); -//printf("~1 sv %4.2f %4.2f %4.2f, ddv %4.2f %4.2f %4.2f\n", p->sv[0], p->sv[1], p->sv[2], ddv[0], ddv[1], ddv[2]); +//printf("~1 sv %4.2f %4.2f %4.2f, ddv %4.2f %4.2f %4.2f\n", p->wm[0], p->wm[1], p->wm[2], ddv[0], ddv[1], ddv[2]); //printf("~1 rv = %f\n",rv); return rv; } /* Powell optimisation function for setting minimal absolute error target point, */ -/* from dest gamut to shrunk destination gamut. */ +/* with no correction for swap. */ /* We get a 2D plane in the 3D space, of the destination point, */ -/* who's location we are optimizing. */ +/* who's location we are optimizing to wngam. */ static double optfunc1a( void *fdata, double *_dv @@ -443,9 +458,8 @@ double *_dv nearsmth *p = s->p; /* Point being optimised */ int i, j, k; double dv[3]; /* 3D point in question */ - double ddv[3]; /* Point in question mapped to shgam surface */ - double delch[3]; - double rv; /* Out of gamut, return value */ + double ddv[3]; /* Point in question mapped to wngam surface */ + double rv; /* Out of gamut, return value */ /* Convert from 2D to 3D. */ dv[2] = _dv[1]; @@ -453,48 +467,16 @@ double *_dv dv[0] = 50.0; icmMul3By3x4(dv, p->m3d, dv); -//printf("~1 optfunc1a got 2D %f %f -> 3D %f %f %f\n", _dv[0], _dv[1], dv[0], dv[1], dv[2]); - s->shgam->radial(s->shgam, ddv, dv); /* Map to shgam surface to check current location */ -//printf("~1 optfunc1a got %f %f %f -> surface %f %f %f\n", dv[0], dv[1], dv[2], ddv[0], ddv[1], ddv[2]); - -#ifdef NEVER - /* Absolute weighted delta E between source and dest test point */ - rv = wdesq(ddv, p->sv, p->wt.ra.l, p->wt.ra.c, p->wt.ra.h, SUM_POW); -#else - { - double ppp = p->wt.a.lxpow; - double thr = p->wt.a.lxthr; /* Xover between normal and power */ - double sumpow = SUM_POW; - - diffLCh(delch, ddv, p->dv); +//if (s->debug) printf("~1 optfunc1a got 2D %f %f -> 3D %f %f %f\n", _dv[0], _dv[1], dv[0], dv[1], dv[2]); + s->wngam->radial(s->wngam, ddv, dv); /* Map to shgam surface to check current location */ +//if (s->debug) printf("~1 optfunc1a got %f %f %f -> surface %f %f %f\n", dv[0], dv[1], dv[2], ddv[0], ddv[1], ddv[2]); - if (sumpow == 0.0 || sumpow == 2.0) { /* Normal sum of squares */ -#ifdef LINEAR_HUE_SUM - double ll, cc, hh; - ll = p->wt.ra.l * pow(delch[0], ppp) * thr/pow(thr, ppp); - cc = p->wt.ra.c * delch[1]; - hh = p->wt.ra.h * delch[2]; - rv = sqrt(ll + cc) + sqrt(hh); - rv *= rv; -#else - rv = p->wt.ra.l * pow(delch[0], ppp) * thr/pow(thr, ppp) - + p->wt.ra.c * delch[1] - + p->wt.ra.h * delch[2]; -#endif - } else { - sumpow *= 0.5; - - rv = p->wt.ra.l * pow(delch[0], ppp * sumpow) * thr/pow(thr, ppp * sumpow) - + p->wt.ra.c * pow(delch[1], sumpow) - + p->wt.ra.h * pow(delch[2], sumpow); - } - } -#endif + rv = aerrf(p, ddv, s->wn); if (s->debug) - printf("debug: rv = %f from %f %f %f\n",rv, ddv[0], ddv[1], ddv[2]); + printf("debug: rv = %f from %f %f %f -> %f %f %f\n",rv, s->wn[0], s->wn[1], s->wn[2], ddv[0], ddv[1], ddv[2]); -//printf("~1 sv %4.2f %4.2f %4.2f, ddv %4.2f %4.2f %4.2f\n", p->sv[0], p->sv[1], p->sv[2], ddv[0], ddv[1], ddv[2]); +//if (s->debug) printf("~1 sv %4.2f %4.2f %4.2f, ddv %4.2f %4.2f %4.2f\n", p->wm[0], p->wm[1], p->wm[2], ddv[0], ddv[1], ddv[2]); //printf("~1 rv = %f\n",rv); return rv; } @@ -563,7 +545,7 @@ double *dv /* 3D Location being evaluated */ } } -/* Powell optimisation function for non-relative error optimization. */ +/* Powell optimisation function for overall non-relative smoothed error optimization. */ /* We get a 2D point in the 3D space. */ static double optfunc2( void *fdata, @@ -582,8 +564,8 @@ double *_dv //printf("~1 optfunc2 got 2D %f %f -> 3D %f %f %f\n", _dv[0], _dv[1], dv[0], dv[1], dv[2]); p->dgam->radial(p->dgam, ddv, dv); /* Map to dst surface to check current location */ -//printf("~1 optfunc2 got %f %f %f -> surface %f %f %f\n", dv[0], dv[1], dv[2], ddv[0], ddv[1], ddv[2]); +//printf("~1 optfunc2 got %f %f %f -> surface %f %f %f\n", dv[0], dv[1], dv[2], ddv[0], ddv[1], ddv[2]); //printf("~1 optfunc2 sv %4.2f %4.2f %4.2f, dv %4.2f %4.2f %4.2f\n", p->sv[0], p->sv[1], p->sv[2], ddv[0], ddv[1], ddv[2]); /* Compute available depth errors p->dcratio and p->dxratio */ @@ -597,12 +579,13 @@ double *_dv printf("~1 dv = %f %f %f\n", ddv[0], ddv[1], ddv[2]); printf("~1 aodv = %f %f %f\n", p->aodv[0], p->aodv[1], p->aodv[2]); printf("~1 drv = %f %f %f\n", p->drv[0], p->drv[1], p->drv[2]); + printf("~1 va = %f, vr = %f, vd = %f\n", p->dbgv[0], p->dbgv[1], p->dbgv[2]); printf("debug:%d: rv = %f from %f %f %f\n",s->ix, rv, dv[0], dv[1], dv[2]); } //printf("~1 rv = %f from %f %f\n",rv, _dv[0], _dv[1]); - //printf("~1 rv = %f\n\n",rv); + return rv; } @@ -612,6 +595,7 @@ double *_dv static void init_ce( smthopt *s, /* Context for cusp mapping being set. */ gamut *sc_gam, /* Source colorspace gamut */ +gamut *si_gam, /* Source image gamut */ gamut *d_gam, /* Destination colorspace gamut */ int src_kbp, /* Use K only black point as src gamut black point */ int dst_kbp, /* Use K only black point as dst gamut black point */ @@ -640,9 +624,9 @@ double d_bp[3] /* Override destination target black point (may be NULL) */ /* Set some default values for src white/black/grey */ - /* Get the white and black point info */ + /* Get the colorspace white and black point info */ if (src_kbp) { - if (sc_gam->getwb(sc_gam, NULL, NULL, NULL, s->cusps[0][6], NULL, s->cusps[0][7]) != 0) { + if (sc_gam->getwb(sc_gam, s->cusps[0][6], NULL, s->cusps[0][7], NULL, NULL, NULL) != 0) { VB(("getting src wb points failed\n")); s->cusps[0][6][0] = 100.0; s->cusps[0][7][0] = 0.0; @@ -650,7 +634,7 @@ double d_bp[3] /* Override destination target black point (may be NULL) */ s->donaxis = 0; } } else { - if (sc_gam->getwb(sc_gam, NULL, NULL, NULL, s->cusps[0][6], s->cusps[0][7], NULL) != 0) { + if (sc_gam->getwb(sc_gam, s->cusps[0][6], s->cusps[0][7], NULL, NULL, NULL, NULL) != 0) { VB(("getting src wb points failed\n")); s->cusps[0][6][0] = 100.0; s->cusps[0][7][0] = 0.0; @@ -660,7 +644,7 @@ double d_bp[3] /* Override destination target black point (may be NULL) */ } if (dst_kbp) { - if (d_gam->getwb(d_gam, NULL, NULL, NULL, s->cusps[1][6], NULL, s->cusps[1][7]) != 0) { + if (d_gam->getwb(d_gam, s->cusps[1][6], NULL, s->cusps[1][7], NULL, NULL, NULL) != 0) { VB(("getting dest wb points failed\n")); s->cusps[1][6][0] = 100.0; s->cusps[1][7][0] = 0.0; @@ -668,7 +652,7 @@ double d_bp[3] /* Override destination target black point (may be NULL) */ s->donaxis = 0; } } else { - if (d_gam->getwb(d_gam, NULL, NULL, NULL, s->cusps[1][6], s->cusps[1][7], NULL) != 0) { + if (d_gam->getwb(d_gam, s->cusps[1][6], s->cusps[1][7], NULL, NULL, NULL, NULL) != 0) { VB(("getting dest wb points failed\n")); s->cusps[1][6][0] = 100.0; s->cusps[1][7][0] = 0.0; @@ -680,6 +664,21 @@ double d_bp[3] /* Override destination target black point (may be NULL) */ icmCpy3(s->cusps[1][7], d_bp); } +#ifdef NEVER + { + double iwp[3] = { -1, -1, -1}, ibp[3] = { -1, -1, -1}; + if (src_kbp) { + si_gam->getwb(si_gam, NULL, NULL, NULL, iwp, NULL, ibp); + } else { + si_gam->getwb(si_gam, NULL, NULL, NULL, iwp, ibp, NULL); + } + printf("~1 src white = %f, black = %f\n",s->cusps[0][6][0],s->cusps[0][7][0]); + printf("~1 img white = %f, black = %f\n",s->cusps[0][6][0],s->cusps[0][7][0]); + printf("~1 dst white = %f, black = %f\n",s->cusps[1][6][0],s->cusps[1][7][0]); + } + +#endif /* NEVER */ + /* Get the cusp info */ if (sc_gam->getcusps(sc_gam, s->cusps[0]) != 0 || d_gam->getcusps(d_gam, s->cusps[1]) != 0) { int isJab; @@ -1166,6 +1165,7 @@ gammapweights *src NSCOPY(r.rdl); NSCOPY(r.rdh); + NSCOPY(r.dsm); NSCOPY(d.co); NSCOPY(d.xo); @@ -1207,6 +1207,50 @@ gammapweights *src2, double wgt2 NSBLEND(r.rdl); NSBLEND(r.rdh); + NSBLEND(r.dsm); + + NSBLEND(d.co); + NSBLEND(d.xo); + + NSBLEND(f.x); +#undef NSBLEND +} + +/* Blend a three groups of individual weights into one, given three weightings */ +void near_wblend3( +gammapweights *dst, +gammapweights *src1, double wgt1, +gammapweights *src2, double wgt2, +gammapweights *src3, double wgt3 +) { + +#define NSBLEND(xxx) dst->xxx = wgt1 * src1->xxx + wgt2 * src2->xxx + wgt3 * src3->xxx + + NSBLEND(c.w.l); + NSBLEND(c.w.c); + NSBLEND(c.w.h); + NSBLEND(c.tw); + NSBLEND(c.cx); + + NSBLEND(l.o); + NSBLEND(l.h); + NSBLEND(l.l); + + NSBLEND(a.o); + NSBLEND(a.h); + NSBLEND(a.wl); + NSBLEND(a.gl); + NSBLEND(a.bl); + + NSBLEND(a.wlth); + NSBLEND(a.blpow); + + NSBLEND(a.lxpow); + NSBLEND(a.lxthr); + + NSBLEND(r.rdl); + NSBLEND(r.rdh); + NSBLEND(r.dsm); NSBLEND(d.co); NSBLEND(d.xo); @@ -1349,8 +1393,9 @@ void tweak_weights(gammapweights out[14], int dst_cmymap, int rel_oride) { } if (rel_oride == 1) { /* A high saturation "clip" like mapping */ - out[i].r.rdl = 1.0; /* No relative neighbourhood */ - out[i].r.rdh = 1.0; /* No relative neighbourhood */ + out[i].r.rdl = 1.0; /* No relative neighbourhood/smoothing */ + out[i].r.rdh = 1.0; /* No relative neighbourhood/smoothing */ + out[i].r.dsm = 0.0; /* No relative neighbourhood/smoothing */ out[i].d.co = 0.0; /* No depth weighting */ out[i].d.xo = 0.0; /* No depth weighting */ @@ -1361,7 +1406,7 @@ void tweak_weights(gammapweights out[14], int dst_cmymap, int rel_oride) { } } -/* Blend a two expanded groups of individual weights into one */ +/* Blend two expanded groups of individual weights into one */ void near_xwblend( gammapweights *dst, gammapweights *src1, double wgt1, @@ -1372,6 +1417,18 @@ gammapweights *src2, double wgt2 near_wblend(&dst[i], &src1[i], wgt1, &src2[i], wgt2); } +/* Blend three expanded groups of individual weights into one */ +void near_xwblend3( +gammapweights *dst, +gammapweights *src1, double wgt1, +gammapweights *src2, double wgt2, +gammapweights *src3, double wgt3 +) { + int i; + for (i = 0; i < 14; i++) + near_wblend3(&dst[i], &src1[i], wgt1, &src2[i], wgt2, &src3[i], wgt3); +} + /* Convert overall, hue dom & l dom to iweight */ static void comp_iweight(iweight *iw, double o, double h, double l) { double c, lc; @@ -1536,14 +1593,15 @@ void interp_xweights(gamut *gam, gammapweights *out, double pos[3], } } -/* Callback used by compdstgamut() to establish the expected compression */ -/* mapping direction. */ +/* Callback used by expdstbysrcmdst() to establish the expected compression */ +/* mapping direction. p2 should be the center point, so depth from the center */ +/* can be computed. We return a point on the neutral axis. */ static void cvect( void *cntx, /* smthopt * */ double *p2, /* Return point displaced from p1 in desired direction */ double *p1 /* Given point */ ) { - double vv, gv[3], lv[3]; + double vv, lv[3]; smthopt *s = (smthopt *)cntx; gammapweights out; @@ -1559,18 +1617,26 @@ double *p1 /* Given point */ /* Parameter along neutral axis black to white */ vv = (p1[0] - s->cusps[0][7][0])/(s->cusps[0][6][0] - s->cusps[0][7][0]); + /* lv is point at same L on neutral axis */ lv[0] = p1[0]; lv[1] = vv * (s->cusps[0][6][1] - s->cusps[0][7][1]) + s->cusps[0][7][1]; lv[2] = vv * (s->cusps[0][6][2] - s->cusps[0][7][2]) + s->cusps[0][7][2]; - icmSub3(lv, lv, p1); /* Vector */ - icmNormalize3(lv, lv, out.ra.l); - icmSub3(gv, s->cusps[0][8], p1); /* Grey vector */ - icmNormalize3(gv, gv, out.ra.c); + /* Normalise l * c weight to sum to 1.0 */ + vv = fabs(out.ra.l + out.ra.c); + if (vv < 1e-7) { /* Hmm. */ + out.ra.l = out.ra.c = 0.5; + } else { + out.ra.l /= vv; + out.ra.c /= vv; + } - icmAdd3(p2, gv, p1); - icmAdd3(p2, lv, p2); /* Combined destination */ + /* Make p2 the weighted sum of equivalent L value and grey value on */ + /* the neutral axis. */ + icmScale3(lv, lv, out.ra.l); + icmScale3(p2, s->cusps[0][8], out.ra.c); + icmAdd3(p2, p2, lv); //printf("~1 p2 %f %f %f\n", p2[0], p2[1], p2[2]); } @@ -1687,18 +1753,23 @@ double p1[3] /* Point */ /* ============================================ */ /* Return the maximum number of points that will be generated */ +/* (This isn't accurate due to manipulation of the gamuts in nearsmth!) */ int near_smooth_np( + gamut **pp_gam, /* Return gamut that was used for points */ gamut *sc_gam, /* Source colorspace gamut */ gamut *si_gam, /* Source image gamut (== sc_gam if none) */ - gamut *d_gam, /* Destination colorspace gamut */ - double xvra /* Extra vertex ratio */ + gamut *dc_gam, /* Destination colorspace gamut */ + double xvra, /* Extra vertex ratio */ + int gmult, /* Guide point multiplier, typically 4 */ + int surfgres /* surface grid point resolution, 0 for none */ ) { gamut *p_gam; /* Gamut used for points - either source colorspace or image */ int ntpts, nmpts, nspts, nipts, ndpts; + int hsurfgres = (surfgres + 1)/2; /* near_smooth uses half */ nspts = sc_gam->nverts(sc_gam); nipts = si_gam->nverts(si_gam); - ndpts = d_gam->nverts(d_gam); + ndpts = dc_gam->nverts(dc_gam); p_gam = sc_gam; /* Target number of points is max of any gamut */ @@ -1714,6 +1785,16 @@ int near_smooth_np( xvra = ntpts/(double)nspts; nmpts = p_gam->nssverts(p_gam, xvra); /* Stratified Sampling source points */ + nmpts *= gmult; /* Allow for sub-surface points etc. */ + + if (hsurfgres >= 4) { + nmpts += hsurfgres * hsurfgres * hsurfgres + - (hsurfgres -4) * (hsurfgres -4) * (hsurfgres -4); + } + + if (pp_gam != NULL) + *pp_gam = p_gam; + return nmpts; } @@ -1726,7 +1807,7 @@ int verb, /* Verbose flag */ int *npp, /* Return the actual number of points returned */ gamut *sc_gam, /* Source colorspace gamut - uses cusp info if availablle */ gamut *si_gam, /* Source image gamut (== sc_gam if none), just used for surface. */ -gamut *d_gam, /* Destination colorspace gamut */ +gamut *dc_gam, /* Destination colorspace gamut */ int src_kbp, /* Use K only black point as src gamut black point */ int dst_kbp, /* Use K only black point as dst gamut black point */ double d_bp[3], /* Override destination target black point - may be NULL */ @@ -1738,22 +1819,22 @@ int useexp, /* Flag indicating whether smoothed expanded value will be used double xvra, /* Extra number of vertexes ratio */ int mapres, /* Grid res for 3D RSPL */ double mapsmooth, /* Target smoothing for 3D RSPL */ -datai map_il, /* Preliminary rspl input range */ +double gexp, /* Grid expansion ratio, none = 1.0 */ +int surfpnts, /* Flag - add surface grid points */ +datai map_il, /* Return expanded input range */ datai map_ih, -datao map_ol, /* Preliminary rspl output range */ +datao map_ol, /* Return expanded output range */ datao map_oh ) { smthopt opts; /* optimisation and cusp mapping context */ int ix, i, j, k; - gamut *p_gam; /* Gamut used for points - either source colorspace or image */ - gamut *sci_gam; /* Intersection of src and img gamut gamut */ - gamut *di_gam; /* Modified destination gamut suitable for mapping from sci_gam. */ - /* If just compression, this is the smaller of sci_gam and d_gam. */ - /* If just expansion, this is the sci_gam expanded by d_gam - sc_gam. */ - /* If both exp & comp, then where - d_gam is outside sci_gam this is sci_gam expanded by d_gam - sc_gam - else it is the smaller of sci_gam and d_gam */ - gamut *nedi_gam;/* Same as above, but not expanded. */ + gamut *p_gam; /* Gamut used for points == either source colorspace or image */ + gamut *src_gam; /* Intersection of src and img gamut gamut */ + gamut *dst_gam; /* Modified destination gamut suitable for mapping from src_gam. */ + /* If compression, this is the intersection of src_gam and dc_gam. */ + /* If expansion, this is the src_gam expanded by dc_gam - sc_gam. */ + gamut *nedst_gam;/* Same as above, but not expanded. */ + int mxnmpts; /* Allocated number of mapping points */ int nmpts; /* Number of mapping gamut points */ nearsmth *smp; /* Absolute delta E weighting */ int pass; @@ -1762,39 +1843,21 @@ datao map_oh double codf; /* Itteration overshoot/damping factor */ double mxmv; /* Maximum a point gets moved */ int nmxmv; /* Number of maxmoves less than stopping threshold */ + int dmapres = 1; /* Change in mapres when applying gexp */ + int hmapres; /* Half mapres */ + int hdmapres; /* Half change in mapres */ + rspl *lastmap = NULL; /* Last gamut mapping map created, if any */ /* Check gamuts are compatible */ - if (sc_gam->compatible(sc_gam, d_gam) == 0 + if (sc_gam->compatible(sc_gam, dc_gam) == 0 || (si_gam != NULL && sc_gam->compatible(sc_gam, si_gam) == 0)) { fprintf(stderr,"gamut map: Gamuts aren't compatible\n"); *npp = 0; return NULL; } - { - int ntpts, nspts, nipts, ndpts; - - nspts = sc_gam->nverts(sc_gam); - nipts = si_gam->nverts(si_gam); - ndpts = d_gam->nverts(d_gam); - p_gam = sc_gam; - - /* Target number of points is max of any gamut */ - ntpts = nspts > nipts ? nspts : nipts; - ntpts = ntpts > ndpts ? ntpts : ndpts; - ntpts = (int)(ntpts * xvra + 0.5); - - /* Use image gamut if it exists */ - if (nspts < nipts || si_gam != sc_gam) { - nspts = nipts; /* Use image gamut instead */ - p_gam = si_gam; - } - xvra = ntpts/(double)nspts; - nmpts = p_gam->nssverts(p_gam, xvra); /* Stratified Sampling source points */ - - if (verb) printf("Vertex count: mult. = %f, src %d, img %d dst %d, target %d\n", - xvra,nspts,nipts,ndpts,nmpts); - } + mxnmpts = near_smooth_np(&p_gam, sc_gam, si_gam, dc_gam, xvra, 1, surfpnts ? mapres : 0); + nmpts = 0; /* Setup opts structure */ opts.useexp = useexp; /* Expansion used ? */ @@ -1805,80 +1868,106 @@ datao map_oh /* Setup source & dest neutral axis transform if white/black available. */ /* If cusps are available, also figure out the transformations */ /* needed to map source cusps to destination cusps */ - init_ce(&opts, sc_gam, d_gam, src_kbp, dst_kbp, d_bp); + init_ce(&opts, sc_gam, si_gam, dc_gam, src_kbp, dst_kbp, d_bp); /* Allocate our guide points */ - if ((smp = (nearsmth *)calloc(nmpts, sizeof(nearsmth))) == NULL) { + if ((smp = (nearsmth *)calloc(mxnmpts, sizeof(nearsmth))) == NULL) { fprintf(stderr,"gamut map: Malloc of near smooth points failed\n"); *npp = 0; return NULL; } - /* Create a source gamut surface that is the intersection of the src colorspace */ - /* and image gamut, in case (for some strange reason) the image gamut. */ - /* exceeds the source colorspace size. */ - sci_gam = sc_gam; /* Alias to source space gamut */ + /* Create a source gamut surface that is the image gamut intersected */ + /* with the source colorspace gamut, in case something strange with the */ + /* image gamut. (gammap.c may have already done this) */ + src_gam = sc_gam; /* Alias to source space gamut */ if (si_gam != sc_gam) { - if ((sci_gam = new_gamut(0.0, 0, 0)) == NULL) { + if ((src_gam = new_gamut(0.0, 0, 0)) == NULL) { fprintf(stderr,"gamut map: new_gamut failed\n"); free_nearsmth(smp, nmpts); *npp = 0; return NULL; } - sci_gam->intersect(sci_gam, sc_gam, si_gam); + src_gam->intersect(src_gam, si_gam, sc_gam); #ifdef SAVE_VRMLS { - char sci_gam_name[40] = "sci_gam"; - strcat(sci_gam_name, vrml_ext()); - printf("###### gamut/nearsmth.c: writing diagnostic sci_gam%s and di_gam%s\n",vrml_ext(),vrml_ext()); - sci_gam->write_vrml(sci_gam, sci_gam_name, 1, 0); + char src_gam_name[40] = "si_gam"; + + printf("###### gamut/nearsmth.c: writing diagnostic si_gam%s, src_gam%s\n",vrml_ext(),vrml_ext()); + + strcat(src_gam_name, vrml_ext()); + src_gam->write_vrml(si_gam, src_gam_name, 1, 0); + + strcpy(src_gam_name, "src_gam"); + strcat(src_gam_name, vrml_ext()); + src_gam->write_vrml(src_gam, src_gam_name, 1, 0); } #endif } - di_gam = sci_gam; /* Default no compress or expand */ + dst_gam = src_gam; /* Default no compress or expand */ + + /* non-expanded dst_gam for testing double back img points against: */ + nedst_gam = src_gam; /* Default same as dst_gam */ + + /* Convert dst_gam to compress and/or expand target for mapping src_gam to. */ if (usecomp || useexp) { - if ((di_gam = new_gamut(0.0, 0, 0)) == NULL) { + + if ((nedst_gam = dst_gam = new_gamut(0.0, 0, 0)) == NULL) { fprintf(stderr,"gamut map: new_gamut failed\n"); - if (si_gam != sc_gam) - sci_gam->del(sci_gam); + if (src_gam != sc_gam) + src_gam->del(src_gam); free_nearsmth(smp, nmpts); *npp = 0; return NULL; } + /* For compression only, nedst_gam and dst_gam are smaller of src_gam and dc_gam space. */ + /* Augment the dst_gam with neutral axis points in case the source gamut */ + /* has a "spike" that separates it from the neutral axis, allowing */ + /* mapping. */ + nedst_gam->nexpintersect(nedst_gam, dc_gam, src_gam); + if (useexp) { - /* Non-expand di_gam for testing double back img points against */ - if ((nedi_gam = new_gamut(0.0, 0, 0)) == NULL) { - fprintf(stderr,"gamut map: new_gamut failed\n"); - di_gam->del(di_gam); - if (si_gam != sc_gam) - sci_gam->del(sci_gam); - free_nearsmth(smp, nmpts); - *npp = 0; - return NULL; + /* No image gamut - dest colorspace is target */ + if (si_gam == sc_gam) { + dst_gam = dc_gam; /* Expanded dest is colorspace dest */ + + /* There is an image gamut, so */ + /* Expand nedst_gam to create dst_gam expanded in proportion to where */ + /* dc_gam is outside sc_gam */ + } else { + if ((dst_gam = new_gamut(0.0, 0, 0)) == NULL) { + fprintf(stderr,"gamut map: new_gamut failed\n"); + if (src_gam != sc_gam) + src_gam->del(src_gam); + free_nearsmth(smp, nmpts); + *npp = 0; + return NULL; + } + + /* Initialise this gamut with the nedst_gam expanded by ((dc_gam - sc_gam) > 0) */ + dst_gam->expdstbysrcmdst(dst_gam, nedst_gam, sc_gam, dc_gam, cvect, &opts); } - } else { - nedi_gam = di_gam; } - - /* Initialise this gamut with a destination mapping gamut. */ - /* This will be the smaller of the image and destination gamut if compressing, */ - /* and will be expanded by the (dst - src) if expanding. */ - di_gam->compdstgamut(di_gam, sci_gam, sc_gam, d_gam, usecomp, useexp, nedi_gam, - cvect, &opts); } #ifdef SAVE_VRMLS { - char di_gam_name[30] = "di_gam"; - strcat(di_gam_name, vrml_ext()); - di_gam->write_vrml(di_gam, di_gam_name, 1, 0); + char dst_gam_name[30] = "dst_gam"; + + printf("###### gamut/nearsmth.c: writing diagnostic dst_gam%s, nedst_gam%s\n",vrml_ext(),vrml_ext()); + strcat(dst_gam_name, vrml_ext()); + dst_gam->write_vrml(dst_gam, dst_gam_name, 1, 0); + + strcpy(dst_gam_name, "nedst_gam"); + strcat(dst_gam_name, vrml_ext()); + nedst_gam->write_vrml(nedst_gam, dst_gam_name, 1, 0); } #endif /* Create a list of the mapping guide points, setup for a null mapping */ VA(("Creating the mapping guide point list\n")); - for (ix = i = 0; i < nmpts; i++) { + for (ix = i = 0; i < mxnmpts; i++) { double imv[3], imr; /* Image gamut source point and radius */ double inorm[3]; /* Normal of image gamut surface at src point */ @@ -1890,12 +1979,12 @@ datao map_oh //printf("~1 got point %d out of %d\n",i+1,nmpts); if (p_gam != sc_gam) { /* If src colorspace point, map to img gamut surface */ - imr = sci_gam->radial(sci_gam, imv, imv); + imr = src_gam->radial(src_gam, imv, imv); } /* If point is within non-expanded modified destination gamut, */ - /* then it is a "double back" image point, and should be ignored. */ - if (nedi_gam->radial(nedi_gam, NULL, imv) > (imr + 1e-4)) { + /* then it is a "double back"/convex image point, and should be ignored. */ + if (nedst_gam->radial(nedst_gam, NULL, imv) > (imr + 1e-4)) { VB(("Rejecting point %d because it's inside destination\n",i)); i--; continue; @@ -1903,17 +1992,18 @@ datao map_oh /* Lookup radialy equivalent point on modified destination gamut, */ /* in case we need it for compression or expansion */ - smp[i].drr = di_gam->radial(di_gam, smp[i].drv, imv); + smp[i].drr = dst_gam->radial(dst_gam, smp[i].drv, imv); /* Default setup a null mapping of source image space point to source image point */ - smp[i].vflag = smp[i].gflag = 0; + smp[i].uflag = smp[i].vflag = smp[i].gflag = 0; smp[i].dr = smp[i].sr = smp[i]._sr = imr; smp[i].dv[0] = smp[i].sv[0] = smp[i]._sv[0] = imv[0]; smp[i].dv[1] = smp[i].sv[1] = smp[i]._sv[1] = imv[1]; smp[i].dv[2] = smp[i].sv[2] = smp[i]._sv[2] = imv[2]; - smp[i].sgam = sci_gam; - smp[i].dgam = sci_gam; - smp[i].mapres = mapres; + smp[i].w1 = 1.0; + smp[i].sgam = src_gam; + smp[i].dgam = src_gam; + smp[i].dcgam = dc_gam; VB(("In Src %d = %f %f %f\n",i,smp[i].sv[0],smp[i].sv[1],smp[i].sv[2])); @@ -1927,7 +2017,7 @@ datao map_oh double mv[3], ml; /* Radial inward mapping vector */ double dir; - icmSub3(mv, sci_gam->cent, smp[i].sv); /* Vector to center */ + icmSub3(mv, src_gam->cent, smp[i].sv); /* Vector to center */ ml = icmNorm3(mv); /* It's length */ if (ml > 0.001) { @@ -1947,6 +2037,7 @@ datao map_oh smp[i].anv[0] = smp[i].aodv[0] = smp[i].dv[0]; smp[i].anv[1] = smp[i].aodv[1] = smp[i].dv[1]; smp[i].anv[2] = smp[i].aodv[2] = smp[i].dv[2]; + smp[i].w1 = 1.01; /* Use 1.01 as marker value */ VB(("Src %d = %f %f %f\n",i,smp[i].sv[0],smp[i].sv[1],smp[i].sv[2])); VB(("Dst %d = %f %f %f\n",i,smp[i].dv[0],smp[i].dv[1],smp[i].dv[2])); @@ -1955,17 +2046,17 @@ datao map_oh *npp = nmpts; /* Don't need this anymore */ - if (nedi_gam != di_gam) - nedi_gam->del(nedi_gam); - nedi_gam = NULL; + if (nedst_gam != src_gam && nedst_gam != dst_gam) + nedst_gam->del(nedst_gam); + nedst_gam = NULL; /* If nothing to be compressed or expanded, then return */ if (usecomp == 0 && useexp == 0) { VB(("Neither compression nor expansion defined\n")); - if (si_gam != sc_gam) - sci_gam->del(sci_gam); - if (di_gam != sci_gam && di_gam != sci_gam) - di_gam->del(di_gam); + if (src_gam != sc_gam) + src_gam->del(src_gam); + if (dst_gam != src_gam && dst_gam != dc_gam) + dst_gam->del(dst_gam); return smp; } @@ -1978,6 +2069,15 @@ datao map_oh interp_xweights(opts.sgam, &smp[i].wt, smp[i]._sv, opts.xwh, &opts, 0); } + /* ~~ would be nice to eliminate the need for dst_gam that is the intersection + * of dc_gam and sc/img_gam here. Problem is determining expansion vector + * direction in a way that is consistent with the absolute error weighting. + * + * For the moment leave the current appoach of using the dst_gam that has been + * expanded in proportion to dc_gam - sc_gam in cvec() direction, since + * the absolute error weighting is use to map the sv to that surface. + */ + VA(("Setting up cusp rotated compression or expansion mappings\n")); VB(("rimv = Cusp rotated cspace/image gamut source point\n")); VB(("imv = cspace/image gamut source point\n")); @@ -2000,7 +2100,7 @@ datao map_oh /* Compute the cusp rotated version of the cspace/image points */ comp_ce(&opts, rimv, imv, &smp[i].wt); VB(("%f de, ix %d: cusp mapped %f %f %f -> %f %f %f\n", icmNorm33(rimv,imv), i, imv[0], imv[1], imv[2], rimv[0], rimv[1], rimv[2])); - rimr = icmNorm33(rimv, sci_gam->cent); + rimr = icmNorm33(rimv, src_gam->cent); /* Default setup a no compress or expand mapping of */ /* source space/image point to modified destination gamut. */ @@ -2008,8 +2108,8 @@ datao map_oh smp[i].sv[0] = rimv[0]; /* Temporary rotated src point */ smp[i].sv[1] = rimv[1]; smp[i].sv[2] = rimv[2]; - smp[i].sgam = sci_gam; - smp[i].dgam = di_gam; + smp[i].sgam = src_gam; + smp[i].dgam = dst_gam; VB(("\n")); VB(("point %d:, rimv = %f %f %f, rimr = %f\n",i,rimv[0],rimv[1],rimv[2],rimr)); @@ -2043,7 +2143,7 @@ datao map_oh double tc[3] = { 0.0, 0.0, 0.0 }; for (ix = 0; ix < nmpts; ix++) { - /* Coompute a rotation that brings the target point location to 50,0,0 */ + /* Compute a rotation that brings the target point location to 50,0,0 */ icmVecRotMat(smp[ix].m2d, smp[ix].sv, sc_gam->cent, ta, tc); /* And inverse */ @@ -2052,171 +2152,149 @@ datao map_oh } /* Figure out which neighbors of the source values to use */ - /* for the relative error calculations. */ + /* for the relative error & smoothing calculations. */ /* Locate the neighbor within the radius for this point, */ /* and weight them with a Gausian filter weight. */ /* The radius is computed on the normalised surface for this point. */ VA(("Establishing filter neighbourhoods\n")); { - double mm[3][4]; /* Tangent alignment rotation */ - double m2[2][2]; /* Additional matrix to alight a with L axis */ - double ta[3] = { 50.0, 0.0, 0.0 }; - double tc[3] = { 0.0, 0.0, 0.0 }; double avgnd = 0.0; /* Total the average number of neighbours */ int minnd = 1e6; /* Minimum number of neighbours */ for (ix = 0; ix < nmpts; ix++) { - double tt[3], rrdl, rrdh, rrdc, dd; - double msv[3], ndx[4]; /* Midpoint source value, quadrant distance */ - double pr; /* Average point radius */ + int sit; + double rr; + double rrdl, rrdh; //printf("~1 computing neigbourhood for point %d at %f %f %f\n",ix, smp[ix].sv[0], smp[ix].sv[1], smp[ix].sv[2]); - /* Compute a rotation that brings the target point location to 50,0,0 */ - icmNormalize33(tt, smp[ix].sv, smp[ix].sgam->cent, 1.0); - icmVecRotMat(mm, tt, smp[ix].sgam->cent, ta, tc); - - /* Add another rotation to orient it so that [1] corresponds */ - /* with the L direction, and [2] corresponds with the */ - /* hue direction. */ - m2[0][0] = m2[1][1] = 1.0; - m2[0][1] = m2[1][0] = 0.0; - tt[0] = smp[ix].sv[0] + 1.0; - tt[1] = smp[ix].sv[1]; - tt[2] = smp[ix].sv[2]; - icmNormalize33(tt, tt, smp[ix].sgam->cent, 1.0); - icmMul3By3x4(tt, mm, tt); - dd = tt[1] * tt[1] + tt[2] * tt[2]; - if (dd > 1e-6) { /* There is a sense of L direction */ - - /* Create the 2x2 rotation matrix */ - dd = sqrt(dd); - tt[1] /= dd; - tt[2] /= dd; - - m2[0][0] = m2[1][1] = tt[1]; - m2[0][1] = tt[2]; - m2[1][0] = -tt[2]; - } - /* Make rr inversely proportional to radius, so that */ - /* filter scope is constant delta E */ rrdl = smp[ix].wt.r.rdl; rrdh = smp[ix].wt.r.rdh; -//printf("~1 rdl %f, rdh %f\n",smp[ix].wt.r.rdl,smp[ix].wt.r.rdh); +//printf("~1 rdl %f, rdh %f\n",rrdl, rrdh); + if (rrdl < 1e-3) rrdl = 1e-3; if (rrdh < 1e-3) rrdh = 1e-3; - /* Average radius of source and destination */ - pr = 0.5 * (smp[ix]._sr + smp[ix].dr); - -//printf("~1 pr = %f from _sr %f & dr %f\n",pr,smp[ix]._sr,smp[ix].dr); - if (pr < 5.0) - pr = 5.0; - rrdl *= 50.0/pr; - rrdh *= 50.0/pr; - rrdc = 0.5 * (rrdl + rrdh); /* Chrominance radius */ - - /* Scale the filter radius by the L/C value, */ - /* so that the filters are largest at the equator, and smallest */ - /* at the white & black points. This allows the wt.a.lx wt.a.cx to work. */ - pr = smp[ix].naxbf + 0.1; /* "spherical" type weighting, 0.707 at 45 degrees */ - rrdl *= pr; - rrdh *= pr; - rrdc *= pr; -//printf("~1 at %f %f %f, rrdl = %f, rrdh = %f\n",smp[ix]._sv[0], smp[ix]._sv[1], smp[ix]._sv[2], rrdl, rrdh); - - smp[ix].nnd = 0; /* Nothing in lists */ - - /* Search for points within the gausian radius */ - for (i = 0; i < nmpts; i++) { - double x, y, z, tv[3]; - - /* compute tangent alignment rotated location */ - icmNormalize33(tt, smp[i].sv, smp[ix].sgam->cent, 1.0); - icmMul3By3x4(tv, mm, tt); - icmMulBy2x2(&tv[1], m2, &tv[1]); - - x = tv[1]/rrdl; - y = tv[2]/rrdh; - z = (tv[0] - 50.0)/rrdc; - - /* Compute normalized delta normalized tangent surface */ - dd = x * x + y * y + z * z; - - /* If we're within the direction filtering radius, */ - /* and not of the opposite hue */ - if (dd <= 1.0 && tv[0] > 0.0) { - double w; - - dd = sqrt(dd); /* Convert to radius <= 1.0 */ - - /* Add this point into the list */ - if (smp[ix].nnd >= smp[ix]._nnd) { - neighb *nd; - int _nnd; - _nnd = 5 + smp[ix]._nnd * 2; - if ((nd = (neighb *)realloc(smp[ix].nd, _nnd * sizeof(neighb))) == NULL) { - VB(("realloc of neighbs at vector %d failed\n",ix)); - if (si_gam != sc_gam) - sci_gam->del(sci_gam); - if (di_gam != sci_gam && di_gam != sci_gam) - di_gam->del(di_gam); - free_nearsmth(smp, nmpts); - *npp = 0; - return NULL; + rr = sqrt(smp[ix].sv[1] * smp[ix].sv[1] + smp[ix].sv[2] * smp[ix].sv[2]); + + if (rr < 5.0) + rr = 5.0; + rr = sqrt(rr / 50.0); + + // Scale radius aprox. by cylindrical distance ?? */ + //rrdh *= rr; + + rrdl = 1.0/rrdl; + rrdh = 1.0/rrdh; + + smp[ix].nnd = 0; + + /* Until we get a minimum number of neighbors */ + for (sit = 0; smp[ix].nnd < 8 && sit < 10; sit++) { + + smp[ix].nnd = 0; + + /* Search for points within the radius */ + for (i = 0; i < nmpts; i++) { + double tt, dd, tv; + + /* Dot of neighbor color and point */ + tv = smp[i].sv[1] * smp[ix].sv[1] + smp[i].sv[2] * smp[ix].sv[2]; + + /* Ignore if of the opposote hue */ + if (tv < 0.0) + continue; + + dd = 0.0; + tt = rrdl * (smp[i].sv[0] - smp[ix].sv[0]); + dd += tt * tt; + tt = rrdh * (smp[i].sv[1] - smp[ix].sv[1]); + dd += tt * tt; + tt = rrdh * (smp[i].sv[2] - smp[ix].sv[2]); + dd += tt * tt; + + /* If we're within the filtering radius, */ + /* and not of the opposite hue */ + if (dd <= 1.0) { + double w; + + dd = sqrt(dd); /* Convert to radius <= 1.0 */ + + /* Add this point into the list */ + if (smp[ix].nnd >= smp[ix]._nnd) { + neighb *nd; + int _nnd; + _nnd = 5 + smp[ix]._nnd * 2; + if ((nd = (neighb *)realloc(smp[ix].nd, _nnd * sizeof(neighb))) == NULL) { + VB(("realloc of neighbs at vector %d failed\n",ix)); + if (src_gam != sc_gam) + src_gam->del(src_gam); + if (dst_gam != src_gam && dst_gam != dc_gam) + dst_gam->del(dst_gam); + free_nearsmth(smp, nmpts); + *npp = 0; + return NULL; + } + smp[ix].nd = nd; + smp[ix]._nnd = _nnd; } - smp[ix].nd = nd; - smp[ix]._nnd = _nnd; - } - smp[ix].nd[smp[ix].nnd].n = &smp[i]; + smp[ix].nd[smp[ix].nnd].n = &smp[i]; - /* Box filter */ -// w = 1.0; + /* Box filter */ +// w = 1.0; - /* Triangle filter */ -// w = 1.0 - dd; + /* Triangle filter */ +// w = 1.0 - dd; -// /* Cubic spline filter */ -// w = 1.0 - dd; -// w = w * w * (3.0 - 2.0 * w); +// /* Cubic spline filter (default) */ + w = 1.0 - dd; + w = w * w * (3.0 - 2.0 * w); - /* Gaussian filter (default) */ - w = exp(-9.0 * dd/2.0); + /* Gaussian filter */ +// w = exp(-9.0 * dd/2.0); - /* Sphere filter */ -// w = sqrt(1.0 - dd * dd); + /* Sphere filter */ +// w = sqrt(1.0 - dd * dd); - /* Sinc^2 filter */ -// w = 3.1415926 * dd; -// if (w < 1e-9) -// w = 1e-9; -// w = sin(w)/w; -// w = w * w; + /* Sinc^2 filter */ +// w = 3.1415926 * dd; +// if (w < 1e-9) +// w = 1e-9; +// w = sin(w)/w; +// w = w * w; - smp[ix].nd[smp[ix].nnd].w = w; /* Will be normalized to sum to 1.0 */ + /* Save weighting */ + smp[ix].nd[smp[ix].nnd].w = w; /* Will be normalized to sum to 1.0 */ -// /* Sphere filter for depth */ -// w = sqrt(1.0 - dd * dd); +// /* Sphere filter for depth */ +// w = sqrt(1.0 - dd * dd); - /* Cubic spline filter for depth */ -// w = 1.0 - dd; -// w = w * w * (3.0 - 2.0 * w); + /* Cubic spline filter for depth (default) */ +// w = 1.0 - dd; +// w = w * w * (3.0 - 2.0 * w); - /* Gaussian filter for depth (default) */ - w = exp(-9.0 * dd/2.0); +// /* Gaussian filter for depth */ +// w = exp(-9.0 * dd/2.0); - smp[ix].nd[smp[ix].nnd].rw = w; /* Won't be normalized */ + /* Save weighting */ + smp[ix].nd[smp[ix].nnd].rw = w; /* Won't be normalized */ //printf("~1 adding %d at %f %f %f, rad %f L %f, w %f dir.\n",i, smp[i].sv[0], smp[i].sv[1], smp[i].sv[2],sqrt(dd),tv[0],smp[ix].nd[smp[ix].nnd].w); - smp[ix].nnd++; + smp[ix].nnd++; + } } + /* Increase radius in case we haven't found enough neighbors */ + rrdl /= 1.5; + rrdh /= 1.5; } + +//if (smp[ix].nnd < 8) printf("~1 point %d has %d neighbors\n",ix,smp[ix].nnd); + if (smp[ix].nnd < minnd) minnd = smp[ix].nnd; avgnd += (double)smp[ix].nnd; -//printf("~1 total of %d dir neigbours\n\n",smp[ix].nnd); - +//printf("~1 total of %d dir neigbours after try %d\n",smp[ix].nnd, sit); } avgnd /= (double)nmpts; @@ -2233,16 +2311,44 @@ datao map_oh for (j = 0; j < smp[i].nnd; j++) { smp[i].nd[j].w /= tw; } + } + } + +#ifdef SHOW_NEIGB + { + vrml *wrl = NULL; + double yellow[3] = { 1.0, 1.0, 0.0 }; + double red[3] = { 1.0, 0.0, 0.0 }; + double green[3] = { 0.0, 1.0, 0.0 }; + double magenta[3] = { 1.0, 0.0, 1.0 }; + double pp[3]; + for (i = 0; i < nmpts; i++) { + + if ((wrl = new_vrml("neigb", 1, vrml_lab)) == NULL) + error("New %s failed for '%s%s'",vrml_format(),"neigb",vrml_ext()); + for (j = 0; j < smp[i].nnd; j++) { + if (smp[i].nd[j].n == &smp[i]) + continue; + wrl->add_col_vertex(wrl, 0, smp[i].sv, yellow); + wrl->add_col_vertex(wrl, 0, smp[i].nd[j].n->sv, yellow); + } + wrl->make_lines(wrl, 0, 2); + + wrl->add_marker(wrl, smp[i].sv, red, 0.5); + + wrl->del(wrl); + printf("Waiting for input after writing 'neigb%s' for point %d:\n",vrml_ext(),i); + getchar(); } } +#endif /* SHOW_NEIGB */ #ifdef SHOW_NEIGB_WEIGHTS { vrml *wrl = NULL; double yellow[3] = { 1.0, 1.0, 0.0 }; double red[3] = { 1.0, 0.0, 0.0 }; - double green[3] = { 0.0, 1.0, 0.0 }; double pp[3]; for (i = 0; i < nmpts; i++) { @@ -2258,7 +2364,7 @@ datao map_oh } for (j = 0; j < smp[i].nnd; j++) { wrl->add_col_vertex(wrl, 0, smp[i].sgam->cent, smp[i].nd[j].n == &smp[i] ? red : yellow); - icmNormalize33(pp, smp[i].nd[j].n->_sv, smp[i].sgam->cent, smp[i].nd[j].w * 50.0/maxw); + icmNormalize33(pp, smp[i].nd[j].n->sv, smp[i].sgam->cent, smp[i].nd[j].w * 50.0/maxw); wrl->add_col_vertex(wrl, 0, pp, smp[i].nd[j].n == &smp[i] ? red : yellow); } wrl->make_lines(wrl, 0, 2); @@ -2315,6 +2421,8 @@ datao map_oh smp[i].sv[1] = smp[i].drv[1]; smp[i].sv[2] = smp[i].drv[2]; } + opts.wngam = smp[i].dgam; /* Nearest to dgam */ + opts.wn = smp[i].sv; /* minimize optfunc1 sv -> dgam */ /* Convert our start value from 3D to 2D for speed. */ icmMul3By3x4(iv, smp[i].m2d, smp[i].dv); @@ -2350,10 +2458,10 @@ datao map_oh nv[1] = iv[1] = iv[2]; powell(NULL, 2, nv, s, 0.01, 1000, optfunc1, (void *)(&opts), NULL, NULL); #endif - if (si_gam != sc_gam) - sci_gam->del(sci_gam); - if (di_gam != sci_gam && di_gam != sci_gam) - di_gam->del(di_gam); + if (src_gam != sc_gam) + src_gam->del(src_gam); + if (dst_gam != src_gam && dst_gam != dc_gam) + dst_gam->del(dst_gam); free_nearsmth(smp, nmpts); *npp = 0; return NULL; @@ -2391,14 +2499,12 @@ datao map_oh smp[i].aodv[2] = smp[i].drv[2]; } } - if (verb) { - printf("."); fflush(stdout); - } } - VA(("Locating weighted mapping vectors without smoothing:\n")); + VA(("Locating weighted mapping vectors without smoothing\n")); + /* Second pass to locate the optimized overall weighted point nrdv[], */ - /* not counting relative error. */ + /* which is a balance of absolute error, radial error, depth room weighting */ { double s[2] = { 20.0, 20.0 }; /* 2D search area */ double iv[3]; /* Initial start value */ @@ -2455,10 +2561,10 @@ datao map_oh nv[1] = iv[1] = iv[2]; powell(NULL, 2, nv, s, 0.01, 1000, optfunc2, (void *)(&opts), NULL, NULL); #endif - if (si_gam != sc_gam) - sci_gam->del(sci_gam); - if (di_gam != sci_gam && di_gam != sci_gam) - di_gam->del(di_gam); + if (src_gam != sc_gam) + src_gam->del(src_gam); + if (dst_gam != src_gam && dst_gam != dc_gam) + dst_gam->del(dst_gam); free_nearsmth(smp, nmpts); *npp = 0; return NULL; @@ -2473,37 +2579,90 @@ datao map_oh /* Remap it to the destinaton gamut surface */ smp[i].dgam->radial(smp[i].dgam, tp, tp); + icmCpy3(smp[i].dv, tp); /* Default current solution */ icmCpy3(smp[i].nrdv, tp); /* Non smoothed result */ icmCpy3(smp[i].anv, tp); /* Starting point for smoothing */ - icmCpy3(smp[i].dv, tp); /* Default current solution */ smp[i].dr = icmNorm33(smp[i].dv, smp[i].dgam->cent); //printf("~1 %d: dv %f %f %f\n", i, smp[i].dv[0], smp[i].dv[1], smp[i].dv[2]); } - if (verb) { - printf("."); fflush(stdout); + } + + /* Make sure the input and output ranges encompas the points */ + for (i = 0; i < nmpts; i++) { + for (j = 0; j < 3; j++) { + if (smp[i]._sv[j] < map_il[j]) + map_il[j] = smp[i]._sv[j];; + if (smp[i]._sv[j] > map_ih[j]) + map_ih[j] = smp[i]._sv[j]; + + if (smp[i].sv[j] < map_il[j]) + map_il[j] = smp[i].sv[j];; + if (smp[i].sv[j] > map_ih[j]) + map_ih[j] = smp[i].sv[j]; + + if (smp[i].dv[j] < map_ol[j]) + map_ol[j] = smp[i].dv[j];; + if (smp[i].dv[j] > map_oh[j]) + map_oh[j] = smp[i].dv[j]; } } -#ifdef DIAG_POINTS - /* Show just the closest vectors etc. */ - for (i = 0; i < nmpts; i++) { /* Move all the points */ -// icmCpy3(smp[i].dv, smp[i].drv); /* Radial */ - icmCpy3(smp[i].dv, smp[i].aodv); /* Nearest */ -// icmCpy3(smp[i].dv, smp[i].nrdv); /* No smoothed weighted */ -// icmCpy3(smp[i].dv, smp[i].dv); /* pre-filter smooothed */ - smp[i].dr = icmNorm33(smp[i].dv, smp[i].dgam->cent); +#ifdef NEVER + if (verb) { + printf("Input bounding box:\n"); + printf(" %f -> %f, %f -> %f, %f -> %f\n", + map_il[0], map_ih[0], map_il[1], map_ih[1], map_il[2], map_ih[2]); } -#else - /* The smoothed direction and raw depth is a single pass, */ - /* but we use multiple passes to determine the extra depth that */ - /* needs to be added so that the smoothed result lies within */ - /* the destination gamut. */ +#endif + + /* Expand the bounding box by gexp so that our surface grid points */ + /* establish the extrapolation behaviour. Ensure that boundary */ + /* lands on the new grid though. */ + { + double scale; + + dmapres = (int)(((mapres-1) - (mapres-1)/gexp)/2.0 + 0.5); + if (dmapres < 1) + dmapres = 1; + + scale = (double)(mapres-1-dmapres)/(double)(mapres-1 - 2 * dmapres); + + for (j = 0; j < 3; j++) { + double low, high; + high = map_ih[j]; + low = map_il[j]; + map_ih[j] = (scale * (high - low)) + low; + map_il[j] = (scale * (low - high)) + high; + } +#ifdef NEVER + if (verb) { + printf("After scaling up by %f, input bounding box:\n",scale); + printf(" %f -> %f, %f -> %f, %f -> %f\n", + map_il[0], map_ih[0], map_il[1], map_ih[1], map_il[2], map_ih[2]); + } +#endif + + /* Values for grid surface points */ + hmapres = (mapres+1)/2; + hdmapres = (dmapres+1)/2; + } + +#if RSPLPASSES > 0 || VECADJPASSES > 0 + + VA(("Computing fine tuning correction direction:\n")); + + /* We need inward pointing correction vectors to be able */ + /* to do clipping and fine tuning. We create a shrunken */ + /* version of the dst_gamut and a mapping based on the */ + /* weighted minimum absolute error metric, and then */ + /* create a rspl to represent that mapping. */ -#if VECADJPASSES > 0 || RSPLPASSES > 0 - /* We will need inward pointing correction vectors */ + /* This sort of clipping direction helps preserve the */ + /* mapping shape (hence smoothness), while minimizing the */ + /* loss of saturation and change in dest. mapping location. */ { - gamut *shgam; /* Shrunken di_gam */ + gamut *shgam; /* Shrunken dst_gam */ double cusps[6][3]; double wp[3], bp[3], kp[3]; double p[3], p2[3], rad; @@ -2523,14 +2682,13 @@ datao map_oh double avgdev[MXDO]; /* Create a gamut that is a shrunk version of the destination */ - - if ((shgam = new_gamut(di_gam->getsres(di_gam), di_gam->getisjab(di_gam), - di_gam->getisrast(di_gam))) == NULL) { + if ((shgam = new_gamut(dst_gam->getsres(dst_gam), dst_gam->getisjab(dst_gam), + dst_gam->getisrast(dst_gam))) == NULL) { fprintf(stderr, "new_gamut failed\n"); - if (si_gam != sc_gam) - sci_gam->del(sci_gam); - if (di_gam != sci_gam && di_gam != sci_gam) - di_gam->del(di_gam); + if (src_gam != sc_gam) + src_gam->del(src_gam); + if (dst_gam != src_gam && dst_gam != dc_gam) + dst_gam->del(dst_gam); free_nearsmth(smp, nmpts); *npp = 0; return NULL; @@ -2542,14 +2700,14 @@ datao map_oh for (i = 0;;) { double len; - if ((i = di_gam->getrawvert(di_gam, p, i)) < 0) + if ((i = dst_gam->getrawvert(dst_gam, p, i)) < 0) break; doshrink(&opts, p, p, SHRINK); shgam->expand(shgam, p); } /* Translate cusps */ - if (di_gam->getcusps(di_gam, cusps) == 0) { + if (dst_gam->getcusps(dst_gam, cusps) == 0) { shgam->setcusps(shgam, 0, NULL); for (i = 0; i < 6; i++) { doshrink(&opts, p, cusps[i], SHRINK); @@ -2558,7 +2716,7 @@ datao map_oh shgam->setcusps(shgam, 2, NULL); } /* Translate white and black points */ - if (di_gam->getwb(di_gam, wp, bp, kp, NULL, NULL, NULL) == 0) { + if (dst_gam->getwb(dst_gam, wp, bp, kp, NULL, NULL, NULL) == 0) { doshrink(&opts, wp, wp, SHRINK); doshrink(&opts, bp, bp, SHRINK); doshrink(&opts, kp, kp, SHRINK); @@ -2568,10 +2726,10 @@ datao map_oh if ((gpnts = (cow *)malloc(nmpts * sizeof(cow))) == NULL) { fprintf(stderr,"gamut map: Malloc of near smooth points failed\n"); shgam->del(shgam); - if (si_gam != sc_gam) - sci_gam->del(sci_gam); - if (di_gam != sci_gam && di_gam != sci_gam) - di_gam->del(di_gam); + if (src_gam != sc_gam) + src_gam->del(src_gam); + if (dst_gam != src_gam && dst_gam != dc_gam) + dst_gam->del(dst_gam); free_nearsmth(smp, nmpts); *npp = 0; return NULL; @@ -2579,7 +2737,7 @@ datao map_oh /* Now locate the closest points on the shrunken gamut */ /* and set them up for creating a rspl */ - opts.shgam = shgam; + opts.wngam = shgam; for (i = 0; i < nmpts; i++) { /* Move all the points */ gtri *ctri = NULL; double tmp[3]; @@ -2591,9 +2749,10 @@ datao map_oh opts.pass = 0; /* Itteration pass */ opts.ix = i; /* Point to optimise */ opts.p = &smp[i]; + opts.wn = smp[i].dv; /* minimize optfunc1a dv -> shgam */ /* Convert our start value from 3D to 2D for speed. */ - icmMul3By3x4(iv, smp[i].m2d, smp[i].dv); + icmMul3By3x4(iv, smp[i].m2d, smp[i].nrdv); nv[0] = iv[0] = iv[1]; nv[1] = iv[1] = iv[2]; @@ -2619,16 +2778,16 @@ datao map_oh #ifdef DEBUG_POWELL_FAILS /* Optimise the point with debug on */ opts.debug = 1; - icmMul3By3x4(iv, smp[i].m2d, smp[i].dv); + icmMul3By3x4(iv, smp[i].m2d, smp[i].nrdv); nv[0] = iv[0] = iv[1]; nv[1] = iv[1] = iv[2]; powell(NULL, 2, nv, s, 0.01, 1000, optfunc1a, (void *)(&opts), NULL, NULL); #endif shgam->del(shgam); /* Done with this */ - if (si_gam != sc_gam) - sci_gam->del(sci_gam); - if (di_gam != sci_gam && di_gam != sci_gam) - di_gam->del(di_gam); + if (src_gam != sc_gam) + src_gam->del(src_gam); + if (dst_gam != src_gam && dst_gam != dc_gam) + dst_gam->del(dst_gam); free_nearsmth(smp, nmpts); *npp = 0; return NULL; @@ -2644,12 +2803,11 @@ datao map_oh shgam->radial(shgam, tp, tp); /* Compute mapping vector from dst to shdst */ - icmSub3(smp[i].temp, tp, smp[i].dv); - + icmSub3(smp[i].temp, tp, smp[i].nrdv); /* In case shrunk vector is very short, add a small part */ /* of the nearest normal. */ - smp[i].dgam->nearest_tri(smp[i].dgam, NULL, smp[i].dv, &ctri); + smp[i].dgam->nearest_tri(smp[i].dgam, NULL, smp[i].nrdv, &ctri); icmScale3(tmp, ctri->pe, 0.1); /* Scale to small inwards */ icmAdd3(smp[i].temp, smp[i].temp, tmp); @@ -2657,13 +2815,12 @@ datao map_oh icmNormalize3(smp[i].temp, smp[i].temp, 1.0); /* Place it in rspl setup array */ - icmCpy3(gpnts[i].p, smp[i].dv); + icmCpy3(gpnts[i].p, smp[i].nrdv); icmCpy3(gpnts[i].v, smp[i].temp); gpnts[i].w = 1.0; } for (j = 0; j < 3; j++) { /* Set resolution for all axes */ -// gres[j] = (mapres+1)/2; /* Half resolution */ gres[j] = mapres; /* Full resolution */ avgdev[j] = GAMMAP_RSPLAVGDEV; } @@ -2672,7 +2829,6 @@ datao map_oh evectmap->fit_rspl_w(evectmap, GAMMAP_RSPLFLAGS, gpnts, nmpts, map_il, map_ih, gres, map_ol, map_oh, 1.0, avgdev, NULL); -// ~~999 #ifdef PLOT_EVECTS /* Create VRML of error correction vectors */ { vrml *wrl = NULL; @@ -2690,7 +2846,7 @@ datao map_oh printf("###### gamut/nearsmth.c: writing diagnostic evects%s\n",vrml_ext()); if ((wrl = new_vrml("evects", doaxes, vrml_lab)) == NULL) error("new_vrml failed for '%s%s'","evects",vrml_ext()); - wrl->make_gamut_surface_2(wrl, di_gam, 0.6, 0, cc); + wrl->make_gamut_surface_2(wrl, dst_gam, 0.6, 0, cc); cc[0] = -1.0; wrl->make_gamut_surface(wrl, shgam, 0.2, cc); @@ -2698,16 +2854,16 @@ datao map_oh wrl->start_line_set(wrl, 0); for (i = 0; i < nmpts; i++) { - wrl->add_col_vertex(wrl, 0, smp[i].dv, red); + wrl->add_col_vertex(wrl, 0, smp[i].nrdv, red); #ifdef NEVER /* Plot created vectors */ icmScale3(tmp, smp[i].temp, 4.0); - icmSub3(tmp, smp[i].dv, tmp); + icmSub3(tmp, smp[i].nrdv, tmp); #else /* Plot interpolated vectors */ - icmCpy3(cp.p, smp[i].dv); + icmCpy3(cp.p, smp[i].nrdv); evectmap->interp(evectmap, &cp); icmScale3(tmp, cp.v, 4.0); - icmSub3(tmp, smp[i].dv, tmp); + icmSub3(tmp, smp[i].nrdv, tmp); #endif wrl->add_col_vertex(wrl, 0, tmp, green); } @@ -2718,267 +2874,265 @@ datao map_oh shgam->del(shgam); /* Done with this */ free(gpnts); } -#endif /* VECADJPASSES > 0 || RSPLPASSES > 0 */ - -#ifdef VECSMOOTHING - VA(("Smoothing guide vectors:\n")); - - /* Compute the neighbourhood smoothed anv[] from dv[] */ - for (i = 0; i < nmpts; i++) { - double anv[3]; /* new anv[] */ - double tmp[3]; - - /* Compute filtered value */ - anv[0] = anv[1] = anv[2] = 0.0; - for (j = 0; j < smp[i].nnd; j++) { - nearsmth *np = smp[i].nd[j].n; /* Pointer to neighbor */ - double nw = smp[i].nd[j].w; /* Weight */ - double tmp[3]; - - icmSub3(tmp, smp[i].sv, np->sv); /* Vector from neighbour src to src */ - icmAdd3(tmp, tmp, np->dv); /* Neigbour dst + vector */ - icmScale3(tmp, tmp, nw); /* weight for filter */ - icmAdd3(anv, anv, tmp); /* sum filtered value */ - } - - /* Blend to un-smoothed value on neutral axis */ - icmBlend3(anv, smp[i].dv, anv, smp[i].naxbf); - - icmCpy3(smp[i].dv, anv); - icmCpy3(smp[i].anv, anv); - smp[i].rext = 0.0; /* No correction */ - } +#endif /* RSPLPASSES > 0 */ #if VECADJPASSES > 0 /* Fine tune vectors to compensate for side effects of vector smoothing */ - VA(("Fine tuning out of gamut guide vectors:\n")); - - /* Loopkup correction vectors */ - VA(("Computing fine tuning direction:\n")); - for (i = 0; i < nmpts; i++) { - co cp; - double nd, id, tmp[3]; - - icmCpy3(cp.p, smp[i].dv); - evectmap->interp(evectmap, &cp); - icmNormalize3(smp[i].evect, cp.v, 1.0); - - /* ~~99 ?? should we deal with white & black direction here ?? */ - - /* Use closest as a default */ - smp[i].dgam->nearest(smp[i].dgam, smp[i].tdst, smp[i].dv); - nd = icmNorm33(smp[i].tdst, smp[i].dv); /* Dist to nearest */ - - /* Compute intersection with dest gamut as tdst */ - if (!vintersect2(smp[i].dgam, NULL, tmp, smp[i].evect, smp[i].dv)) { - /* Got an intersection */ - id = icmNorm33(tmp, smp[i].dv); /* Dist to intersection */ - if (id <= (nd + 5.0)) /* And it seems sane */ - icmCpy3(smp[i].tdst, tmp); - } - - smp[i].rext = 0.0; - } - - VA(("Fine tuning guide vectors:\n")); - for (it = 0; it < VECADJPASSES; it++) { - double avgog = 0.0, maxog = 0.0, nog = 0.0; - double avgig = 0.0, maxig = 0.0, nig = 0.0; + /* Lookup correction vectors */ + VA(("Smoothing guide vectors:\n")); + { + int pncliped = nmpts; + double delta; - /* Filter the level of out/in gamut, and apply correction vector */ + /* Compute the source to destination neighborhood scale factors */ for (i = 0; i < nmpts; i++) { - double cvec[3], clen; - double minext = 1e80; - double maxext = -1e80; /* Max weighted depth extension */ - double dext, gain; + double tmp[3]; + double sav[3], dav[3]; /* Average center locations */ + double sdev[3], ddev[3]; /* Average devation in each direction from center */ + double scev, dcev; /* Average spherical deviation */ - minext = -20.0; + for (j = 0; j < 3; j++) + sav[j] = dav[j] = sdev[j] = ddev[j] = 0.0; + scev = dcev = 0.0; - /* Compute filtered value */ + /* Compute center average values */ for (j = 0; j < smp[i].nnd; j++) { nearsmth *np = smp[i].nd[j].n; /* Pointer to neighbor */ - double nw = smp[i].nd[j].rw; /* Weight */ - double tmpl; - - icmSub3(cvec, np->tdst, np->anv); /* Vector needed to target for neighbour */ - clen = icmDot3(smp[i].evect, cvec); /* Error in this direction */ - - tmpl = nw * (clen - minext); /* Track maximum weighted extra depth */ - if (tmpl < 0.0) - tmpl = 0.0; - if (tmpl > maxext) - maxext = tmpl; + double nw = smp[i].nd[j].w; /* Weight */ + + icmScale3(tmp, np->sv, nw); + icmAdd3(sav, sav, tmp); + icmScale3(tmp, np->dv, nw); + icmAdd3(dav, dav, tmp); } - maxext += minext; - if (it == 0) - gain = 1.2; - else - gain = 0.8; + /* Compute average deviation in each direction */ + for (j = 0; j < smp[i].nnd; j++) { + nearsmth *np = smp[i].nd[j].n; /* Pointer to neighbor */ + double nw = smp[i].nd[j].w; /* Weight */ + double tt; + + icmSub3(tmp, sav, np->sv); + icmAbs3(tmp, tmp); + icmScale3(tmp, tmp, nw); + icmAdd3(sdev, sdev, tmp); + + tt = icmNorm33(sav, np->sv); + tt *= nw; + scev += tt; + + icmSub3(tmp, dav, np->dv); + icmAbs3(tmp, tmp); + icmScale3(tmp, tmp, nw); + icmAdd3(ddev, ddev, tmp); + + tt = icmNorm33(dav, np->dv); + tt *= nw; + dcev += tt; + } - /* Accumulate correction with damping */ - smp[i].rext += gain * maxext; +//printf("~1 %d: sdev %f %f %f, scev %f\n",i,sdev[0],sdev[1],sdev[2],scev); +//printf("~1 %d: ddev %f %f %f, dcev %f\n",i,ddev[0],ddev[1],ddev[2],dcev); - /* Error for just this point */ - icmSub3(cvec, smp[i].tdst, smp[i].anv); - clen = icmDot3(smp[i].evect, cvec); + /* Try and protect against silliness */ + if (scev < 1e-3 || dcev < 1e-3) + scev = dcev = 1e-3; - /* Blend to individual correction on neutral axis */ - dext = smp[i].naxbf * smp[i].rext + (1.0 - smp[i].naxbf) * clen; + for (j = 0; j < 3; j++) { + if (sdev[j] < 1e-3 || ddev[j] < 1e-3) { + sdev[j] = scev; + ddev[j] = dcev; + } + } - /* Apply integrated correction */ - icmScale3(cvec, smp[i].evect, dext); - icmAdd3(smp[i].anv, smp[i].dv, cvec); + /* Compute scale factors */ + icmDiv3(smp[i].nscale, ddev, sdev); /* Scale = ddev/sdev */ - if (clen > 0.0) { /* Compression */ - if (clen > maxog) - maxog = clen; - avgog += clen; - nog++; +#ifdef NEVER +if (smp[i].nscale[0] > 1.5 || smp[i].nscale[0] < 0.01 + || smp[i].nscale[1] > 1.5 || smp[i].nscale[1] < 0.01 + || smp[i].nscale[2] > 1.5 || smp[i].nscale[2] < 0.01) { + printf("~1 %d: scale factors %f %f %f\n",i,smp[i].nscale[0], smp[i].nscale[1], smp[i].nscale[2]); + printf("~1 %d: from sdev %f %f %f\n",i,sdev[0], sdev[1], sdev[2]); + printf("~1 %d: from ddev %f %f %f\n",i,ddev[0], ddev[1], ddev[2]); +} +#endif /* NEVER */ - } else { /* Expansion */ - if (-clen > maxig) - maxig = -clen; - avgig += -clen; - nig++; - } } - if (verb) - printf("No og %4.0f max %f avg %f, No ig %4.0f max %f avg %f\n", - nog,maxog,nog > 1 ? avgog/nog : 0.0, nig,maxig,nig > 1 ? avgig/nig : 0.0); - } - /* Copy final results */ - for (i = 0; i < nmpts; i++) { - icmCpy3(smp[i].dv, smp[i].anv); - smp[i].dr = icmNorm33(smp[i].dv, smp[i].dgam->cent); - } + /* Itterate smoothing until we're happy */ + for (it = 0; it < VECADJPASSES; it++) { + int ncliped = 0; + double maxclipby = 0.0; + double avgclipby = 0.0; + + /* Compute the neighbourhood smoothed anv[] from dv[] */ + for (i = 0; i < nmpts; i++) { + double sav[3], dav[3]; /* Average locations */ + double tmp[3], c1[3], c2[3]; + double rdsm; + + /* Compute average values */ + sav[0] = sav[1] = sav[2] = 0.0; + dav[0] = dav[1] = dav[2] = 0.0; + for (j = 0; j < smp[i].nnd; j++) { + nearsmth *np = smp[i].nd[j].n; /* Pointer to neighbor */ + double nw = smp[i].nd[j].w; /* Weight */ + + icmScale3(tmp, np->sv, nw); /* weight for filter */ + icmAdd3(sav, sav, tmp); /* sum filtered value */ + + /* weight for filter */ + tmp[0] = nw * np->dv[0]; /* Don't itterate J */ + tmp[1] = nw * np->anv[1]; + tmp[2] = nw * np->anv[2]; + icmAdd3(dav, dav, tmp); /* sum filtered value */ + } + + /* Compute filtered value with source to dest scaling */ + icmSub3(tmp, smp[i].sv, sav); /* Vector from average to src */ + icmMul3(tmp, tmp, smp[i].nscale); /* Scale */ + icmAdd3(tmp, tmp, dav); /* average dst + vector */ - if (verb) { - double avgog = 0.0, maxog = 0.0, nog = 0.0; - double avgig = 0.0, maxig = 0.0, nig = 0.0; + rdsm = 1.0 - sqrt(smp[i].wt.r.dsm); /* To degree of blending with unchanged */ - /* Check the result */ - for (i = 0; i < nmpts; i++) { - double cvec[3], clen; - - /* Error for just this point, for stats */ - icmSub3(cvec, smp[i].tdst, smp[i].anv); - clen = icmDot3(smp[i].evect, cvec); - - if (clen > 0.0) { /* Compression */ - if (clen > maxog) - maxog = clen; - avgog += clen; - nog++; - - } else { /* Expansion */ - if (-clen > maxig) - maxig = -clen; - avgig += -clen; - nig++; + icmBlend3(tmp, tmp, smp[i].dv, rdsm); /* Less than full imprint */ + +#if VECADJPASSES > 1 + /* Clip to gamut */ + if (dc_gam->nradial(dc_gam, c1, tmp) > (1.0 + 1e-6)) { + co cp; + double cvec[3]; + + /* Lookup "shrunk gamut" cliping direction */ + icmCpy3(cp.p, tmp); + evectmap->interp(evectmap, &cp); + icmNormalize3(cvec, cp.v, 1.0); + + if (!vintersect2(dc_gam, NULL, c2, cvec, tmp)) { /* Got an intersection */ + double id; + +//printf("~1 clipped %f %f %f -> %f %f %f\n", tmp[0], tmp[1], tmp[2], c2[0], c2[1], c2[2]); + id = icmNorm33(c2, tmp); /* Dist to intersection */ + icmCpy3(tmp, c2); + + ncliped++; + if(id > maxclipby) + maxclipby = id; + avgclipby += id; + } else { +//printf("~1 rclipped %f %f %f -> %f %f %f\n", tmp[0], tmp[1], tmp[2], c1[0], c1[1], c1[2]); + icmCpy3(tmp, c1); /* Use radial clip */ + } + } +#endif + + /* Blend to un-smoothed value on neutral axis */ + icmBlend3(tmp, smp[i].dv, tmp, smp[i].naxbf); + + /* Updated value for next itteration */ + icmCpy3(smp[i].anv, tmp); + } + + if (ncliped > 0) + avgclipby /= (double)ncliped; + + delta = (pncliped - ncliped)/(double)nmpts; + + if (verb) { + printf("It %d: No clip %d/%d delta %f max by %f, avg by %f\n",it,ncliped, nmpts+1, delta, maxclipby, avgclipby); } + pncliped = ncliped; + } + + /* Copy final results */ + for (i = 0; i < nmpts; i++) { + icmCpy3(smp[i].dv, smp[i].anv); + smp[i].dr = icmNorm33(smp[i].dv, smp[i].dgam->cent); } - printf("No og %4.0f max %f avg %f, No ig %4.0f max %f avg %f\n", - nog,maxog,nog > 1 ? avgog/nog : 0.0, nig,maxig,nig > 1 ? avgig/nig : 0.0); } -#endif /* VECADJUST */ + #endif /* VECADJPASSES > 0 */ +#ifdef DIAG_POINTS + /* Show just the closest vectors etc. */ + for (i = 0; i < nmpts; i++) { /* Move all the points */ +// icmCpy3(smp[i].dv, smp[i].drv); /* Radial */ + icmCpy3(smp[i].dv, smp[i].aodv); /* Nearest */ +// icmCpy3(smp[i].dv, smp[i].nrdv); /* No smoothed weighted */ + smp[i].dr = icmNorm33(smp[i].dv, smp[i].dgam->cent); /* Vector smoothed */ + } +#else + /* The smoothed direction and raw depth is a single pass, */ + /* but we use multiple passes to determine the extra depth that */ + /* needs to be added so that the smoothed result lies within */ + /* the destination gamut. */ + #if RSPLPASSES > 0 + + VA(("Fine tuning vectors to allow for rspl smoothing:\n")); + /* We need to adjust the vectors with extra depth to compensate for */ /* for the effect of rspl smoothing. */ { cow *gpnts = NULL; /* Mapping points to create 3D -> 3D mapping */ rspl *map = NULL; /* Test map */ - datai il, ih; - datao ol, oh; int gres[MXDI]; double avgdev[MXDO]; double icgain, ixgain; /* Initial compression, expansion gain */ double fcgain, fxgain; /* Final compression, expansion gain */ - VA(("Fine tuning vectors to allow for rspl smoothing:\n")); - - for (j = 0; j < 3; j++) { /* Copy ranges */ - il[j] = map_il[j]; - ih[j] = map_ih[j]; - ol[j] = map_ol[j]; - oh[j] = map_oh[j]; - } - - /* Adjust the input ranges for guide vectors */ - for (i = 0; i < nmpts; i++) { - for (j = 0; j < 3; j++) { - if (smp[i]._sv[j] < il[j]) - il[j] = smp[i]._sv[j]; - if (smp[i]._sv[j] > ih[j]) - ih[j] = smp[i]._sv[j]; - } - } - - /* Now expand the bounding box by aprox 5% margin, but scale grid res */ - /* to match, so that the natural or given boundary still lies on the grid. */ - /* (This duplicates code in gammap applied after near_smooth() returns) */ - /* (We are assuming that our changes to the giude vectprs won't expand the ranges) */ - { - int xmapres; - double scale; - - xmapres = (int) ((mapres-1) * 0.05 + 0.5); - if (xmapres < 1) - xmapres = 1; - - scale = (double)(mapres-1 + xmapres)/(double)(mapres-1); - - for (j = 0; j < 3; j++) { - double low, high; - high = ih[j]; - low = il[j]; - ih[j] = (scale * (high - low)) + low; - il[j] = (scale * (low - high)) + high; - } - - mapres += 2 * xmapres; - } - if ((gpnts = (cow *)malloc(nmpts * sizeof(cow))) == NULL) { fprintf(stderr,"gamut map: Malloc of near smooth points failed\n"); if (evectmap != NULL) evectmap->del(evectmap); - if (si_gam != sc_gam) - sci_gam->del(sci_gam); - if (di_gam != sci_gam && di_gam != sci_gam) - di_gam->del(di_gam); + if (src_gam != sc_gam) + src_gam->del(src_gam); + if (dst_gam != src_gam && dst_gam != dc_gam) + dst_gam->del(dst_gam); free_nearsmth(smp, nmpts); *npp = 0; return NULL; } - /* Loopkup correction vectors */ - VA(("Computing fine tuning direction for vectors:\n")); + /* Lookup correction vectors */ + VA(("Computing fine tuning target for vectors:\n")); for (i = 0; i < nmpts; i++) { - co cp; double nd, id, tmp[3]; - icmCpy3(cp.p, smp[i].dv); - evectmap->interp(evectmap, &cp); - icmNormalize3(smp[i].evect, cp.v, 1.0); - - /* ~~99 ?? should we deal with white & black direction here ?? */ - - /* Use closest as a default */ - smp[i].dgam->nearest(smp[i].dgam, smp[i].tdst, smp[i].dv); - nd = icmNorm33(smp[i].tdst, smp[i].dv); /* Dist to nearest */ - - /* Compute intersection with dest gamut as tdst */ - if (!vintersect2(smp[i].dgam, NULL, tmp, smp[i].evect, smp[i].dv)) { - /* Got an intersection */ - id = icmNorm33(tmp, smp[i].dv); /* Dist to intersection */ - if (id <= (nd + 5.0)) /* And it seems sane */ - icmCpy3(smp[i].tdst, tmp); + /* If the sv and dv are within dc_gam, then this point doesn't need */ + /* to be fine tuned to make it land on the gamut surface - this point */ + /* either doesn't need gamut mapping, or is being expanded, in which */ + /* case we prioritize smoothness over exactly hitting the expansion */ + /* target */ + if (dc_gam->nradial(dc_gam, NULL, smp[i].sv) <= (1.0 + 1e-6) + && dc_gam->nradial(dc_gam, NULL, smp[i].dv) <= (1.0 + 1e-6)) { + icmCpy3(smp[i].tdst, smp[i].dv); /* Target is where we are */ + smp[i].nott = 1; + + } else { + co cp; + double evect[3]; + + /* Lookup fine tuning vector direction for current location */ + icmCpy3(cp.p, smp[i].dv); + evectmap->interp(evectmap, &cp); + icmNormalize3(evect, cp.v, 1.0); + + /* Use closest as a default */ + smp[i].dgam->nearest(smp[i].dgam, smp[i].tdst, smp[i].dv); + nd = icmNorm33(smp[i].tdst, smp[i].dv); /* Dist to nearest */ + + /* Compute intersection with dest gamut as tdst */ + if (!vintersect2(smp[i].dgam, NULL, tmp, evect, smp[i].dv)) { + /* Got an intersection */ + id = icmNorm33(tmp, smp[i].dv); /* Dist to intersection */ + if (id <= (nd + 5.0)) /* And it seems sane */ + icmCpy3(smp[i].tdst, tmp); + } + smp[i].nott = 0; } smp[i].coff[0] = smp[i].coff[1] = smp[i].coff[2] = 0.0; @@ -2996,6 +3150,8 @@ datao map_oh double avgrext = 0.0; double ovlen; + VA(("it %d: Creating rspl\n",it)); + /* Setup the rspl guide points for creating rspl */ for (i = 0; i < nmpts; i++) { icmCpy3(gpnts[i].p, smp[i]._sv); /* The orgininal src point */ @@ -3004,13 +3160,14 @@ datao map_oh } for (j = 0; j < 3; j++) { /* Set resolution for all axes */ -// gres[j] = (mapres+1)/2; /* Half resolution for speed */ gres[j] = mapres; /* Full resolution */ avgdev[j] = GAMMAP_RSPLAVGDEV; } map = new_rspl(RSPL_NOFLAGS, 3, 3); /* Allocate 3D -> 3D */ map->fit_rspl_w(map, GAMMAP_RSPLFLAGS, gpnts, nmpts, - il, ih, gres, ol, oh, mapsmooth, avgdev, NULL); + map_il, map_ih, gres, map_ol, map_oh, mapsmooth, avgdev, NULL); + + VA(("it %d: Evaluate mapping\n",it)); /* See what the source actually maps to via rspl, and how far from */ /* the target point they are. */ @@ -3022,12 +3179,20 @@ datao map_oh icmCpy3(cp.p, smp[i]._sv); map->interp(map, &cp); icmCpy3(smp[i].temp, cp.v); - + + /* Lookup fine tuning vector direction for that value. */ + /* (evect[] is then used in the local correction loop below) */ + icmCpy3(cp.p, smp[i].temp); + evectmap->interp(evectmap, &cp); + icmNormalize3(smp[i].evect, cp.v, 1.0); + /* Compute the correction needed and it's signed length */ icmSub3(cvec, smp[i].tdst, smp[i].temp); smp[i].clen = icmDot3(smp[i].evect, cvec); } + VA(("it %d: Compute correction vectors\n",it)); + /* Compute local correction */ for (i = 0; i < nmpts; i++) { double minext = 1e80; @@ -3037,6 +3202,8 @@ datao map_oh double tt; double cgain, xgain; /* This itters compression, expansion gain */ double gain; /* Gain used */ + co cp; + double evect[3]; /* See what the worst case is in the local area, and */ /* aim to lower the whole local area by enough to */ @@ -3091,6 +3258,7 @@ datao map_oh /* Keep stats of this point */ clen = smp[i].clen; + if (clen > 0.0) { if (clen > maxog) maxog = clen; @@ -3115,20 +3283,32 @@ datao map_oh gpnts[i].w = 1.0; } + if ((it+1) < RSPLPASSES || !surfpnts) + map->del(map); /* Not the last pass, or not doing grid surface points */ + else + lastmap = map; /* Let grid surface creation use this. */ + + VA(("it %d: Compute correction rspl\n",it)); + + /* Create rspl of corrections */ for (j = 0; j < 3; j++) { /* Set resolution for all axes */ -// gres[j] = (mapres+1)/2; /* Half resolution */ gres[j] = mapres; /* Full resolution */ avgdev[j] = GAMMAP_RSPLAVGDEV; } map = new_rspl(RSPL_NOFLAGS, 3, 3); /* Allocate 3D -> 3D */ map->fit_rspl_w(map, GAMMAP_RSPLFLAGS, gpnts, nmpts, - il, ih, gres, ol, oh, 2.0, avgdev, NULL); + map_il, map_ih, gres, map_ol, map_oh, 1.0, avgdev, NULL); + + VA(("it %d: Apply corrections\n",it)); /* Lookup the smoothed extension vector for each point and apply it */ for (i = 0; i < nmpts; i++) { double tt; co cp; + if (smp[i].nott) /* Don't alter points within the gamut */ + continue; + icmCpy3(cp.p, smp[i].dv); map->interp(map, &cp); #ifdef RSPLUSEPOW @@ -3143,7 +3323,7 @@ datao map_oh /* Apply accumulated offset */ icmAdd3(smp[i].anv, smp[i].dv, cp.v); } - map->del(map); + map->del(map); /* Not the last pass, or not doing grid surface points */ if (verb) printf("No og %4.0f max %f avg %f, No ig %4.0f max %f avg %f, avg rext %f\n", @@ -3174,18 +3354,15 @@ datao map_oh } #endif /* RSPLPASSES > 0 */ -#endif /* NEVER (show debug values) */ +#endif /* !DIAG_POINTS */ VA(("Smoothing passes done, doing final houskeeping\n")); - if (verb) - printf("\n"); - #if defined(SAVE_VRMLS) && defined(PLOT_MAPPING_INFLUENCE) - create_influence_plot(smp, nmpts); + create_influence_plot(smp, nmpts, mapres); #endif - VB(("Final guide points:\n")); + VA(("Restoring non cusp-rotated source points:\n")); /* Restore the actual non cusp rotated source point */ for (i = 0; i < nmpts; i++) { @@ -3236,7 +3413,7 @@ datao map_oh /* Compute actual depth of ray into destination gamut */ /* to determine if this is expansion or contraction. */ - if (di_gam->vector_isect(di_gam, smp[i].sv, smp[i].dv, + if (dst_gam->vector_isect(dst_gam, smp[i].sv, smp[i].dv, minv, maxv, &mint, &maxt, &mintri, &maxtri) != 0) { double wp[3], bp[3]; /* Gamut white and black points */ double p1, napoint[3] = { 50.0, 0.0, 0.0 }; /* Neutral axis point */ @@ -3249,7 +3426,7 @@ datao map_oh /* the guide ray. We use this as a destination direction */ /* if the sub surface ray gets very long, and to compute */ /* a sanity check on the available depth. */ - if (d_gam->getwb(d_gam, NULL, NULL, NULL, wp, dst_kbp ? NULL : bp, dst_kbp ? bp : NULL) == 0) { + if (dc_gam->getwb(dc_gam, NULL, NULL, NULL, wp, dst_kbp ? NULL : bp, dst_kbp ? bp : NULL) == 0) { if (icmLineLineClosest(napoint, NULL, &p1, NULL, bp, wp, smp[i].sv, smp[i].dv) == 0) { double nalev[3]; @@ -3295,7 +3472,7 @@ datao map_oh } #ifdef VERB else { - printf("d_gam->getwb failed\n"); + printf("dc_gam->getwb failed\n"); } #endif @@ -3444,54 +3621,345 @@ datao map_oh #ifdef SUBVEC_SMOOTHING VB(("Smoothing sub-surface guide points:\n")); + { + double maxmv = 0.0, avgmv = 0.0, acount = 0.0; - /* Smooth the sub-surface mapping points */ - /* dv2[] is duplicated in temp[], so use temp[] as the values to be filtered */ - for (i = 0; i < nmpts; i++) { - double tmp[3]; - double fdv2[3]; /* Filtered dv2[] */ - double tw; /* Total weight */ - int rc; - - if (smp[i].vflag == 0) - continue; - - /* Compute filtered value */ - tw = fdv2[0] = fdv2[1] = fdv2[2] = 0.0; - for (j = 0; j < smp[i].nnd; j++) { - nearsmth *np = smp[i].nd[j].n; /* Pointer to neighbor */ - double nw = smp[i].nd[j].w; /* Weight */ - double tmp[3]; + /* Smooth the sub-surface mapping points */ + for (i = 0; i < nmpts; i++) { + double sav[3], dav[3]; /* Average locations */ + double scr, dcr; /* Cylindrical radius */ + double scf; /* Scale factor */ + double tmp[3], de; + + if (smp[i].vflag == 0) + continue; /* Sub value not valid */ - if (np->vflag) { - icmSub3(tmp, smp[i].sv2, np->sv2); /* Vector from neighbour src to src */ - icmAdd3(tmp, tmp, np->dv2); /* Neigbour dst + vector */ + /* Compute average values */ + sav[0] = sav[1] = sav[2] = 0.0; + dav[0] = dav[1] = dav[2] = 0.0; + for (j = 0; j < smp[i].nnd; j++) { + nearsmth *np = smp[i].nd[j].n; /* Pointer to neighbor */ + double nw = smp[i].nd[j].w; /* Weight */ - icmScale3(tmp, tmp, nw); /* weight for filter */ - icmAdd3(fdv2, fdv2, tmp); /* sum filtered value */ - tw += nw; + icmScale3(tmp, np->sv2, nw); /* weight for filter */ + icmAdd3(sav, sav, tmp); /* sum filtered value */ + + icmScale3(tmp, np->dv2, nw); /* weight for filter */ + icmAdd3(dav, dav, tmp); /* sum filtered value */ } - } + + /* We want to transfer the relative location (i.e. detail) from */ + /* the source to destination, but we need to scale the features */ + /* appropriately for the mapping. */ + scr = sqrt(sav[1] * sav[1] + sav[2] * sav[2]); + dcr = sqrt(dav[1] * dav[1] + dav[2] * dav[2]); + scf = dcr/scr; + + /* Compute filtered value */ + icmSub3(tmp, smp[i].sv2, sav); /* Vector from average to src */ + tmp[1] *= scf; /* Scale */ + tmp[2] *= scf; /* Scale */ + icmAdd3(tmp, tmp, dav); /* average dst + vector */ + + de = icmNorm33(smp[i].dv2, tmp); + icmCpy3(smp[i].dv2, tmp); + + if (de > maxmv) + maxmv = de; + avgmv += de; + acount++; - if (tw > 0.0) { -//printf("~1 %d: moved %f %f %f -> %f %f %f de %f\n", i, smp[i].dv2[0], smp[i].dv2[1], smp[i].dv2[2], fdv2[0], fdv2[1], fdv2[2], icmNorm33(smp[i].dv2,fdv2)); - icmScale3(smp[i].dv2, fdv2, 1.0/tw); + VB(("Smthd Src %d = %f %f %f\n",i,smp[i].sv2[0],smp2[i].sv[1],smp2[i].sv2[2])); + VB(("Smthd Dst %d = %f %f %f\n",i,smp[i].dv2[0],smp2[i].dv[1],smp2[i].dv2[2])); } + if (acount > 0) + avgmv /= acount; + + if (verb) + printf("Sub-surface smoothing changed by max %f, average %f\n",maxmv, avgmv); + } #endif /* SUBVEC_SMOOTHING */ VB(("near_smooth is done\n")); +#ifdef PLOT_SMOOTHING_CHANGE + /* Plot change in destination point of un-smoothed to smoothed */ + { + vrml *wrl = NULL; + int doaxes = 0; + +#ifdef PLOT_AXES + doaxes = 1; +#endif + wrl = new_vrml("dst_smvec", doaxes, vrml_lab); + + /* Start of guide vector plot */ + wrl->start_line_set(wrl, 0); + + for (i = 0; i < nmpts; i++) { + double red[3] = { 1.0, 0.0, 0.0 }; + double green[3] = { 0.0, 1.0, 0.0 }; + + wrl->add_col_vertex(wrl, 0, smp[i].nrdv, red); + wrl->add_col_vertex(wrl, 0, smp[i].dv, green); + } + wrl->make_lines(wrl, 0, 2); /* Change vectors */ + +#ifndef NEVER + /* Plot un-smoothed src to dst mappings */ + wrl->start_line_set(wrl, 0); + + for (i = 0; i < nmpts; i++) { + double lblue[3] = { 0.4, 0.4, 0.8 }; + double magenta[3] = { 0.8, 0.4, 0.8 }; + + wrl->add_col_vertex(wrl, 0, smp[i].sv, lblue); + wrl->add_col_vertex(wrl, 0, smp[i].nrdv, magenta); + } + wrl->make_lines(wrl, 0, 2); /* Change vectors */ +#endif + +#ifdef NEVER + /* Plot index numbers */ + for (i = 0; i < nmpts; i++) { + double cream[3] = { 0.7, 0.7, 0.5 }; + char buf[100]; + sprintf(buf, "%d", i); + wrl->add_text(wrl, buf, smp[i].dv, cream, 0.5); + } +#endif /* NEVER */ + + /* Write transparent destination space gamut surface */ + dc_gam->write_to_vrml(dc_gam, wrl, 0.5, 0); + + /* Write file */ + wrl->del(wrl); + } +#endif /* PLOT_SMOOTHING_CHANGE */ + + /* If grid surface points are requested */ + if (surfpnts) { + DCOUNT(gc, 3, 3, 0, 0, hmapres); + double cent[3]; + + VB(("Adding grid surface points:\n")); + + /* If rspl smoothing didn't leave us a map */ + if (lastmap == NULL) { + + cow *gpnts = NULL; /* Mapping points to create 3D -> 3D mapping */ + int gres[MXDI]; + double avgdev[MXDO]; + + VB(("Creating rspl map for grid surface points\n",it)); + + if ((gpnts = (cow *)malloc(nmpts * sizeof(cow))) == NULL) { + fprintf(stderr,"gamut map: Malloc of near smooth points failed\n"); + if (evectmap != NULL) + evectmap->del(evectmap); + if (src_gam != sc_gam) + src_gam->del(src_gam); + if (dst_gam != src_gam && dst_gam != dc_gam) + dst_gam->del(dst_gam); + free_nearsmth(smp, nmpts); + *npp = 0; + return NULL; + } + + /* Setup the rspl guide points for creating rspl */ + for (i = 0; i < nmpts; i++) { + icmCpy3(gpnts[i].p, smp[i].sv); + icmCpy3(gpnts[i].v, smp[i].dv); + gpnts[i].w = 1.0; + } + + for (j = 0; j < 3; j++) { /* Set resolution for all axes */ + gres[j] = mapres; /* Full resolution */ + avgdev[j] = GAMMAP_RSPLAVGDEV; + } + lastmap = new_rspl(RSPL_NOFLAGS, 3, 3); /* Allocate 3D -> 3D */ + lastmap->fit_rspl_w(lastmap, GAMMAP_RSPLFLAGS, gpnts, nmpts, + map_il, map_ih, gres, map_ol, map_oh, mapsmooth, avgdev, NULL); + free(gpnts); + } + + sc_gam->getcent(dc_gam, cent); + + DC_INIT(gc); + for (;;) { + /* If point is in the outer two layers of grid */ + if ( gc[0] == 0 || gc[0] == hdmapres + || gc[0] == (hmapres-1) || gc[0] == (hmapres-1-hdmapres) + || gc[1] == 0 || gc[1] == hdmapres + || gc[1] == (hmapres-1) || gc[1] == (hmapres-1-hdmapres) + || gc[2] == 0 || gc[2] == hdmapres + || gc[2] == (hmapres-1) || gc[2] == (hmapres-1-hdmapres)) + + /* Only points around gamut, not on top or underneath */ +/* + if ( gc[1] == 0 || gc[1] == hdmapres + || gc[1] == (hmapres-1) || gc[1] == (hmapres-1-hdmapres) + || gc[2] == 0 || gc[2] == hdmapres + || gc[2] == (hmapres-1) || gc[2] == (hmapres-1-hdmapres)) +*/ + { + double grid2gamut, gamut2cent, ww; + co cp; + + if (nmpts >= mxnmpts) { + warning("nearsmth ran out of space for points"); + break; + } + smp[nmpts].uflag = 1; + + /* Source location */ + for (j = 0; j < 3; j++) + smp[nmpts].sv[j] = map_il[j] + gc[j]/(hmapres-1.0) * (map_ih[j] - map_il[j]); + + /* If this point is within source gamut, skip it */ + if (sc_gam->nradial(sc_gam, NULL, smp[nmpts].sv) <= (1.0 + 1e-6)) { +//printf("~1 point %d %d %d = %f %f %f is inside source gamut\n", gc[0], gc[1], gc[2], smp[nmpts].sv[0], smp[nmpts].sv[1], smp[nmpts].sv[2]); + goto next_point; + } +#ifdef NEVER + /* Clip the point to the closest location on the source */ + /* colorspace gamut. */ + sc_gam->nearest(sc_gam, cp.p, smp[nmpts].sv); +#else + /* Map grid point to weighted nearest on source space gamut */ + { + double ta[3] = { 50.0, 0.0, 0.0 }; + double tc[3] = { 0.0, 0.0, 0.0 }; + double s[2] = { 20.0, 20.0 }; /* 2D search area */ + double nv[2]; /* 2D New value */ + double tp[3]; /* Resultint value */ + double ne; /* New error */ + int notrials = NO_TRIALS; + double bnv[3]; /* Best 3d value */ + double brv; /* Best return value */ + int trial; + double mv; + + /* Determine the parameter weighting at this location */ + opts.pass = 0; /* Itteration pass */ + opts.ix = nmpts; + opts.p = &smp[nmpts]; + opts.wngam = sc_gam; /* Optimise to source colorspace gamut */ + opts.wn = smp[nmpts].sv; /* minimize optfunc1a sv -> sc_gam */ + + /* Compute weights at this point */ + interp_xweights(sc_gam, &smp[nmpts].wt, smp[nmpts].sv, opts.xwh, &opts, 0); + + /* Initial starting point */ + sc_gam->nearest(sc_gam, bnv, smp[nmpts].sv); + + /* Do several trials from different starting points to avoid */ + /* any local minima, particularly with nearest mapping. */ + brv = 1e38; + for (trial = 0; trial < notrials; trial++) { + double rv; /* Temporary */ + + /* Setup the 3D -> 2D tangent conversion and inverse for our start point */ + icmVecRotMat(smp[nmpts].m2d, bnv, sc_gam->cent, ta, tc); + icmVecRotMat(smp[nmpts].m3d, ta, tc, bnv, sc_gam->cent); + + /* Convert our start value from 3D to 2D for speed. */ + icmMul3By3x4(tp, smp[nmpts].m2d, bnv); + nv[0] = tp[1]; + nv[1] = tp[2]; + + if (trial >= 2) { + /* Use random offset to avoid local minima */ + nv[0] += d_rand(-20.0, 20.0); + nv[1] += d_rand(-20.0, 20.0); + } + + /* Optimise the point */ + if (powell(&rv, 2, nv, s, 0.01, 1000, optfunc1a, (void *)(&opts), NULL, NULL) == 0 + && rv < brv) { + brv = rv; +//printf("~1 point %d, trial %d, new best %f\n",i,trial,rv); + + /* Convert best result 2D -> 3D */ + tp[2] = nv[1]; + tp[1] = nv[0]; + tp[0] = 50.0; + icmMul3By3x4(tp, smp[nmpts].m3d, tp); + + /* Remap it to the source gamut surface */ + sc_gam->radial(sc_gam, bnv, tp); + } +//else printf("~1 powell failed with rv = %f\n",rv); + } + if (brv == 1e38) { /* We failed to get a result */ + fprintf(stderr, "multiple powells failed to get a result (4)\n"); + sc_gam->nearest(sc_gam, cp.p, smp[nmpts].sv); + + } else { + icmCpy3(cp.p, bnv); + } + } +#endif /* NEVER */ + +//printf("~1 grid %f %f %f -> src %f %f %f\n", smp[nmpts].sv[0], smp[nmpts].sv[1], smp[nmpts].sv[2], cp.p[0], cp.p[1], cp.p[2]); + + /* Then lookup the gamut mapped value */ + lastmap->interp(lastmap, &cp); + +//printf("~1 src %f %f %f -> dst %f %f %f\n", cp.p[0], cp.p[1], cp.p[2], cp.v[0], cp.v[1], cp.v[2]); + + for (j = 0; j < 3; j++) + smp[nmpts].dv[j] = cp.v[j]; + + /* Compute the distance of the grid surface point to the to the */ + /* source colorspace gamut, as well as the distance from there */ + /* to the gamut center point. */ + for (grid2gamut = gamut2cent = 0.0, j = 0; j < 3; j++) { + double tt; + tt = smp[nmpts].dv[j] - cp.p[j]; + grid2gamut += tt * tt; + tt = cp.p[j] - cent[j]; + gamut2cent += tt * tt; + } + grid2gamut = sqrt(grid2gamut); + gamut2cent = sqrt(gamut2cent); + if (gamut2cent < 0.1) + gamut2cent = 0.1; + + /* Make the weighting inversely related to distance, */ + /* to reduce influence on in gamut mapping shape, */ + /* while retaining some influence at the edge of the */ + /* grid. */ + ww = grid2gamut / gamut2cent; + if (ww > 1.0) + ww = 1.0; + + /* A low weight seems to be enough ? */ + /* The lower the better in terms of geting best hull mapping fidelity */ + smp[nmpts++].w1 = 0.1 * ww; + } + next_point:; + DC_INC(gc); + if (DC_DONE(gc)) + break; + } + *npp = nmpts; /* Update returned number of points */ + + lastmap->del(lastmap); + } + if (evectmap != NULL) evectmap->del(evectmap); #ifndef PLOT_DIGAM - if (si_gam != sc_gam) - sci_gam->del(sci_gam); - if (di_gam != sci_gam && di_gam != sci_gam) - di_gam->del(di_gam); + if (src_gam != sc_gam) + src_gam->del(src_gam); + if (dst_gam != src_gam && dst_gam != dc_gam) + dst_gam->del(dst_gam); for (i = 0; i < nmpts; i++) { smp[i].sgam = NULL; smp[i].dgam = NULL; + smp[i].dcgam = NULL; } #else /* !PLOT_DIGAM */ warning("!!!!! PLOT_DIGAM defined !!!!!"); @@ -3504,6 +3972,7 @@ datao map_oh void free_nearsmth(nearsmth *smp, int nmpts) { int i; + /* Free contents that have been used */ for (i = 0; i < nmpts; i++) { if (smp[i].nd != NULL) free(smp[i].nd); @@ -3518,7 +3987,7 @@ void free_nearsmth(nearsmth *smp, int nmpts) { /* Create a plot indicating how the source mapping has been guided by the */ /* various weighting forces. */ -static void create_influence_plot(nearsmth *smp, int nmpts) { +static void create_influence_plot(nearsmth *smp, int nmpts, int mapres) { int i, j, k; gamut *gam; int src = 0; /* 1 = src, 0 = dst gamuts */ @@ -3592,7 +4061,7 @@ static void create_influence_plot(nearsmth *smp, int nmpts) { /* Create the diagnostic color rspl */ for (j = 0; j < 3; j++) { /* Set resolution for all axes */ - gres[j] = smp->mapres; + gres[j] = mapres; avgdev[j] = 0.001; } swdiag = new_rspl(RSPL_NOFLAGS, 3, 3); /* Allocate 3D -> 3D */ diff --git a/gamut/nearsmth.h b/gamut/nearsmth.h index f826357..82afab3 100644 --- a/gamut/nearsmth.h +++ b/gamut/nearsmth.h @@ -126,10 +126,14 @@ typedef struct { struct { double rdl; /* Direction smoothing radius L* dir. (delta E radius at src point)*/ double rdh; /* Direction smoothing radius H* (delta E radius at src point)*/ + + double dsm; /* Degree of smoothing (non-linear response) */ } r; - /* depth weighting */ - /* Weighing to give to minimizing depth ratio by mapping to/from adequate dest/src depth */ + /* Depth room weighting. */ + /* Weighing to give to minimizing depth ratio by mapping to/from adequate dest/src depth. */ + /* The idea is to compromize luminance and/or hue to allow room for */ + /* preserving saturation distinction under heavy compression. */ struct { double co; /* Overall compression weighting */ double xo; /* Overall expansion weighting */ @@ -166,6 +170,7 @@ typedef struct { struct _nearsmth { /* Public: */ + int uflag; /* Use flag, 0 = normal, 1 = grid surface point */ int gflag; /* Gamut direction flag. 0 = not determinable, 1 = comp., 2 = exp. */ int vflag; /* Vector direction flag. 0 = not determinable, 1 = comp., 2 = exp. */ /* sv2, dv2, sd3 etc. are valid if vflag != 0 */ @@ -178,12 +183,13 @@ struct _nearsmth { double dv[3]; /* Output destination value */ double dr; /* Output destination value radius from center */ double div[3]; /* gam[cx]pf moderated dv[] value */ + double w1; /* guide point weight */ /* Gamut sub-surface mapping guide point (knee shape controlled by gamcknf & gamxknf) */ double sv2[3]; /* Sub-surface source value */ double dv2[3]; /* Sub-surface knee'd adjusted destination value */ double div2[3]; /* gam[cx]pf moderated dv2[] value */ - double w2; /* Sub-surface weight (fixed in nearsmth) */ + double w2; /* Sub-surface weight (set in nearsmth) */ double sd3[3]; /* Deep sub-surface source & destination value */ double w3; /* Deep sub-surface weight */ @@ -201,39 +207,43 @@ struct _nearsmth { double _sr; /* Original source radius */ double naxbf; /* Blend factor that goes to 0.0 at white & black points. */ double aodv[3]; /* Absolute error optimized destination value */ - double nrdv[3]; /* No relative weight optimized destination value */ + double nrdv[3]; /* No relative smoothed destination value */ double anv[3]; /* Average neighborhood target point (relative target) */ double tdst[3]; /* Target destination on gamut */ + int nott; /* NZ if not a point that needs to land on gamut */ double evect[3]; /* Accumulated extension vector direction */ double clen; /* Current correction length needed */ double coff[3]; /* Correction offset */ double rext; double temp[3]; /* General temporary */ - gamut *sgam; /* Source gamut sci_gam = intersection of src and img gamut gamut */ - gamut *dgam; /* Destination gamut di_gam */ + gamut *sgam; /* Source gamut src_gam = intersection of src and img gamut gamut */ + gamut *dgam; /* Intersected destination gamut dst_gam */ + gamut *dcgam; /* Destination Colorspace gamut dc_gam */ int nnd, _nnd; /* No & size of direction neighbour list */ neighb *nd; /* Allocated list of neighbours */ + double nscale[3]; /* Neighborhood scale change from sv to dv */ double dcratio; /* Depth compression ratio */ double dxratio; /* Depth expansion ratio */ - int mapres; /* Target grid res for 3D RSPL */ - int debug; - double dbgv[4]; /* Error components va, vr, vl, vd on last itteration */ + double dbgv[3]; /* Error components va, vr, vd on last itteration */ }; typedef struct _nearsmth nearsmth; /* Return the upper bound on the number of points that will be generated */ int near_smooth_np( + gamut **pp_gam, /* Return gamut that was used for points */ gamut *sc_gam, /* Source colorspace gamut */ gamut *s_gam, /* Source image gamut (== sc_gam if none) */ gamut *d_gam, /* Destination colorspace gamut */ - double xvra /* Extra vertex ratio */ + double xvra, /* Extra vertex ratio */ + int gmult, /* Guide point multiplier, typically 4 */ + int surfgres /* surface grid point resolution, 0 for none */ ); /* Return a list of points. Call free_nearsmth() after use */ @@ -253,11 +263,13 @@ nearsmth *near_smooth( int usecomp, /* Flag indicating whether smoothed compressed value will be used */ int useexp, /* Flag indicating whether smoothed expanded value will be used */ double xvra, /* Extra vertex ratio */ - int mapres, /* Target grid res for 3D RSPL */ + int mapres, /* Target grid res for 3D RSPL, (allowing for gexp) */ double mapsmooth, /* Target smoothing for 3D RSPL */ - datai map_il, /* Preliminary rspl input range */ + double gexp, /* Total grid expansion ratio, none = 1.0 */ + int surfgres, /* Surface grid point resolution, 0 for none */ + datai map_il, /* Return input range */ datai map_ih, - datao map_ol, /* Preliminary rspl output range */ + datao map_ol, /* Return output range */ datao map_oh ); @@ -267,13 +279,21 @@ void free_nearsmth(nearsmth *smp, int npp); /* Expand the compact form of weights into the explicit form. */ int expand_weights(gammapweights out[14], gammapweights *in); -/* Blend a two expanded groups of individual weights into one */ +/* Blend two expanded groups of individual weights into one */ void near_xwblend( gammapweights *dst, gammapweights *src1, double wgt1, gammapweights *src2, double wgt2 ); +/* Blend three expanded groups of individual weights into one */ +void near_xwblend3( +gammapweights *dst, +gammapweights *src1, double wgt1, +gammapweights *src2, double wgt2, +gammapweights *src3, double wgt3 +); + /* Tweak weights acording to extra cmy cusp flags or rel override */ void tweak_weights(gammapweights out[14], int dst_cmymap, int rel_oride); diff --git a/gamut/smthtest.c b/gamut/smthtest.c index c9214d3..b794ed0 100644 --- a/gamut/smthtest.c +++ b/gamut/smthtest.c @@ -47,37 +47,44 @@ gammapweights weights[] = { { /* Cusp alignment control */ { 0.1, /* Cusp luminance alignment weighting 0 = none, 1 = full */ - 0.1, /* Cusp chroma alignment weighting 0 = none, 1 = full */ - 0.2 /* Cusp hue alignment weighting 0 = none, 1 = full */ + 0.0, /* Cusp chroma alignment weighting 0 = none, 1 = full */ + 0.3 /* Cusp hue alignment weighting 0 = none, 1 = full */ }, + 2.0, /* Alignment twist power, 0 = linear, 1 = curve, 2+ late curve */ 1.00 /* Chroma expansion 1 = none */ }, - { /* Radial weighting */ + { /* Radial weighting (currently broken - need to fix) */ 0.0, /* Radial error overall weight, 0 + */ 0.5, /* Radial hue dominance vs l+c, 0 - 1 */ 0.5 /* Radial l dominance vs, c, 0 - 1 */ }, { /* Weighting of absolute error of destination from source */ 1.0, /* Absolute error overall weight */ - 0.5, /* Hue dominance vs l+c, 0 - 1 */ + 0.8, /* Hue dominance vs l+c, 0 - 1 */ - 0.9, /* Light l dominance vs, c, 0 - 1 */ - 0.9, /* Medium l dominance vs, c, 0 - 1 */ - 0.9, /* Dark l dominance vs, c, 0 - 1 */ + 0.8, /* White l dominance vs, c, 0 - 1 */ + 0.5, /* Grey l dominance vs, c, 0 - 1 */ + 0.93, /* Black l dominance vs, c, 0 - 1 */ - 0.5, /* l/c dominance breakpoint, 0 - 1 */ - 0.0, /* l dominance exageration, 0+ */ - 0.0 /* c dominance exageration, 0+ */ + 0.4, /* White l blend start radius, 0 - 1, at white = 0 */ + 0.7, /* Black l blend power, linear = 1.0, enhance < 1.0 */ + + 1.5, /* L error extra power with size, none = 1.0 */ + 10.0 /* L error extra xover threshold in DE */ }, { /* Relative vector smoothing */ - 30.0, 20.0 /* Relative Smoothing radius L* H* */ + 20.0, 30.0, /* Relative Smoothing radius L* H* */ + 0.9 /* Degree of smoothing */ }, { /* Weighting of excessive compression error, which is */ /* the src->dst vector length over the available dst depth. */ /* The depth is half the distance to the intersection of the */ /* vector to the other side of the gamut. (doesn't get triggered much ?) */ - 100.0, /* Compression depth weight */ - 100.0 /* Expansion depth weight */ + 5.0, /* Compression depth weight */ + 5.0 /* Expansion depth weight */ + }, + { + 0.0 /* Fine tuning expansion weight, 0 - 1 */ } } }; @@ -210,7 +217,7 @@ main(int argc, char *argv[]) { /* Create the near point mapping */ nsm = near_smooth(verb, &nnsm, gin, gin, gout, 0, 0, NULL, xweights, - 0.1, 0.1, 1, 1, 2.0, 17, 10.0, il, ih, ol, oh); + 0.1, 0.1, 1, 1, 2.0, 19, 2.0, 1.20, 5, il, ih, ol, oh); if (nsm == NULL) error("Creating smoothed near points failed"); diff --git a/h/aconfig.h b/h/aconfig.h index 4b24c82..50275ea 100644 --- a/h/aconfig.h +++ b/h/aconfig.h @@ -9,8 +9,31 @@ /* minor number = 8 bits */ /* major number = 8 bits */ -#define ARGYLL_VERSION 0x01082 -#define ARGYLL_VERSION_STR "1.8.2" +#define ARGYLL_VERSION 0x01083 +#define ARGYLL_VERSION_STR "1.8.3" + +#if defined(NT) +# if defined(_WIN64) +# define ARGYLL_BUILD_STR "MSWin 64 bit" +# else +# define ARGYLL_BUILD_STR "MSWin 32 bit" +# endif +#endif +#if defined(UNIX) +# if defined(__APPLE__) +# if defined(__LP64__) +# define ARGYLL_BUILD_STR "OS X 64 bit" +# else +# define ARGYLL_BUILD_STR "OS X 32 bit" +# endif +# else +# if defined(__LP64__) +# define ARGYLL_BUILD_STR "Linux 64 bit" +# else +# define ARGYLL_BUILD_STR "Linux 32 bit" +# endif +# endif +#endif /* Maximum file path length */ #define MAXNAMEL 1024 diff --git a/icc/icc.c b/icc/icc.c index 92611c3..d5b72ce 100644 --- a/icc/icc.c +++ b/icc/icc.c @@ -13401,6 +13401,13 @@ void icmMul3(double out[3], double in1[3], double in2[3]) { out[2] = in1[2] * in2[2]; } +/* Take absolute of a 3 vector */ +void icmAbs3(double out[3], double in[3]) { + out[0] = fabs(in[0]); + out[1] = fabs(in[1]); + out[2] = fabs(in[2]); +} + /* - - - - - - - - - - - - - - - - - - - - - - - - */ /* Set a 3x3 matrix to unity */ @@ -13837,6 +13844,11 @@ void icmRotMat(double m[3][3], double s[3], double t[3]) { /* If the two input vectors are close to being parallel, */ /* then h will be close to zero. */ if (fabs(h) < 1e-12) { + + /* Make sure scale is the correct sign */ + if (s[0] * t[0] + s[1] * t[1] + s[2] * t[2] < 0.0) + tl = -tl; + m[0][0] = tl/sl; m[0][1] = 0.0; m[0][2] = 0.0; @@ -13860,6 +13872,19 @@ void icmRotMat(double m[3][3], double s[3], double t[3]) { m[2][1] = tl/sl * (h * v[1] * v[2] + v[0]); m[2][2] = tl/sl * (e + h * v[2] * v[2]); } + +#ifdef NEVER /* Check result */ + { + double tt[3]; + + icmMulBy3x3(tt, m, s); + + if (icmLabDEsq(t, tt) > 1e-4) { + printf("icmRotMat error t, is %f %f %f\n",tt[0],tt[1],tt[2]); + printf(" should be %f %f %f\n",t[0],t[1],t[2]); + } + } +#endif /* NEVER */ } /* - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -13908,9 +13933,9 @@ void icmMul3By3x4(double out[3], double mat[3][4], double in[3]) { /* "Real-Time Rendering". */ /* s0 -> s1 is source vector, t0 -> t1 is target vector. */ /* Usage of icmRotMat: */ -/* t[0] == mat[0][0] * s[0] + mat[0][1] * s[1] + mat[0][2] * s[2] + mat[0][3]; */ -/* t[1] == mat[1][0] * s[0] + mat[1][1] * s[1] + mat[1][2] * s[2] + mat[1][3]; */ -/* t[2] == mat[2][0] * s[0] + mat[2][1] * s[1] + mat[2][2] * s[2] + mat[2][3]; */ +/* t[0] = mat[0][0] * s[0] + mat[0][1] * s[1] + mat[0][2] * s[2] + mat[0][3]; */ +/* t[1] = mat[1][0] * s[0] + mat[1][1] * s[1] + mat[1][2] * s[2] + mat[1][3]; */ +/* t[2] = mat[2][0] * s[0] + mat[2][1] * s[1] + mat[2][2] * s[2] + mat[2][3]; */ /* i.e. use icmMul3By3x4 */ void icmVecRotMat(double m[3][4], double s1[3], double s0[3], double t1[3], double t0[3]) { int i, j; @@ -13939,6 +13964,26 @@ void icmVecRotMat(double m[3][4], double s1[3], double s0[3], double t1[3], doub m[j][i] = 0.0; } } + +#ifdef NEVER /* Check result */ + { + double tt0[3], tt1[3]; + + icmMul3By3x4(tt0, m, s0); + + if (icmLabDEsq(t0, tt0) > 1e-4) { + printf("icmVecRotMat error t0, is %f %f %f\n",tt0[0],tt0[1],tt0[2]); + printf(" should be %f %f %f\n",t0[0],t0[1],t0[2]); + } + + icmMul3By3x4(tt1, m, s1); + + if (icmLabDEsq(t1, tt1) > 1e-4) { + printf("icmVecRotMat error t1, is %f %f %f\n",tt1[0],tt1[1],tt1[2]); + printf(" should be %f %f %f\n",t1[0],t1[1],t1[2]); + } + } +#endif /* NEVER */ } /* - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -15314,6 +15359,8 @@ int icmClipXYZ(double out[3], double in[3]) { /* --------------------------------------------------------------- */ /* Some video specific functions */ +/* Should add ST.2048 log functions */ + /* Convert Lut table index/value to YPbPr */ /* (Same as Lut_Lut2YPbPr() ) */ void icmLut2YPbPr(double *out, double *in) { diff --git a/icc/icc.h b/icc/icc.h index 4eba0ec..36ec73a 100644 --- a/icc/icc.h +++ b/icc/icc.h @@ -1754,6 +1754,9 @@ void icmMul3(double out[3], double in1[3], double in2[3]); #define ICMMUL3(o, i, j) ((o)[0] = (i)[0] * (j)[0], (o)[1] = (i)[1] * (j)[1], (o)[2] = (i)[2] * (j)[2]) +/* Take absolute of a 3 vector */ +void icmAbs3(double out[3], double in[3]); + /* Compute the dot product of two 3 vectors */ double icmDot3(double in1[3], double in2[3]); diff --git a/link/collink.c b/link/collink.c index 7d04838..597cd1d 100644 --- a/link/collink.c +++ b/link/collink.c @@ -130,7 +130,7 @@ External cLUTs that are implemented using integer logic (ie, in HW, such as the eeColor) may choose to cope - with this probem in a different way, i.e. by + with this problem in a different way, i.e. by scaling against a value above the largest valid device encoding. For instance, cLUTs of resolution 65 would be normalised to 65 rather than the usual 64, @@ -246,7 +246,7 @@ void usage(char *diag, ...) { fprintf(stderr," b:background Background %% of image luminance (default 20)\n"); fprintf(stderr," l:imagewhite Image white in cd.m^2 if surround = auto (default 250)\n"); fprintf(stderr," f:flare Flare light %% of image luminance (default 0)\n"); - fprintf(stderr," g:glare Flare light %% of ambient (default 1)\n"); + fprintf(stderr," g:glare Flare light %% of ambient (default %d)\n",XICC_DEFAULT_GLARE); fprintf(stderr," g:X:Y:Z Flare color as XYZ (default media white, Abs: D50)\n"); fprintf(stderr," g:x:y Flare color as x, y\n"); fprintf(stderr," -t tlimit set source total ink limit, 0 - 400%% (estimate by default)\n"); @@ -309,10 +309,12 @@ struct _profinfo { icmLuAlgType alg; /* Type of lookup algorithm */ icColorSpaceSignature csp; /* Colorspace */ int chan; /* Channels */ - int nocurve; /* NZ to not use device curve in per channel curve */ + int nocurve; /* NZ to not use ICC device curve and tvenc in per channel curve */ int lcurve; /* 1 to apply a Y like to L* curve for XYZ Matrix profiles */ /* 2 to apply a Y to L* curve for XYZ space */ - int tvenc; /* 0 = full range RGB, 1 = RGB Video Level encoding, */ + /* lcurve is applied irrespective of nocurve, and is */ + /* incompatible with tvenc ? */ + int tvenc; /* 0 = Full range RGB, */ /* 1 = RGB Video Level encoding, */ /* 3 = Rec601 YCbCr encoding, */ /* 4 = Rec709 1150/60/2:1 YCbCr encoding */ @@ -326,8 +328,8 @@ struct _profinfo { int bt1886; /* 1 to apply input gamma curve using effective gamma */ /* 2 to apply input gamma curve using technical gamma */ double outoprop; /* Proportion of black output offset, 0.0 .. 1.0. 0.0 == BT.1886 */ - double egamma; /* effective gamma to ain for */ - double tgamma; /* technical gamma to ain for */ + double egamma; /* effective gamma to aim for */ + double tgamma; /* technical gamma to aim for */ bt1886_info bt; /* BT.1886 adjustment info */ double rgb_bk[3]; /* Linear light input RGB black to bend to */ double wp[3]; /* Lab/Jab white point for profile used by wphack & xyzscale */ @@ -348,6 +350,7 @@ struct _clink { int dst_cmymap; /* masks C = 1, M = 2, Y = 4 to force 100% cusp map */ int tdlut; /* nz = 3DLut output, 1 = eeColor format, 2 = MadVR format */ /* 3 = .cube format */ + double coscale[3]; /* eeColor cLUT output de-scale/"second" 1D lut scale */ icColorSpaceSignature pcsor; /* PCS to use between in & out profiles */ @@ -368,8 +371,8 @@ struct _clink { xicc *abs_xicc; icxLuBase *abs_luo; /* NULL if none */ - int addcal; /* 1 = apply cal to 3dLut and set linear cal1 */ - /* 2 = set cal1 to cal */ + int addcal; /* 1 = apply cal to 3dLut and set linear MadVR cal1 */ + /* 2 = set MadVR cal1 to cal */ xcal *cal; /* Calibration to apply, NULL if none */ /* (We current assume that xyzscale can't be used with gmi) */ @@ -628,10 +631,8 @@ static void xvYCC_fwd_matrix(double *out, double *in) { } /* ======================================================= */ -/* cLUT Input value tweaks to make Video emcoded black land on */ -/* 65 res grid nodes. This should help 33 and 17 res cLUTs too*/ - -/* This also makes the cLUT nodes line up with the eeColor cLUT nodes. */ +/* cLUT Input value tweaks to make Video encoded black land on */ +/* 65 res grid nodes, which should help 33 and 17 res cLUTs too*/ static void VidRGB_to_cLUT65(double out[3], double in[3]) { int i; @@ -744,7 +745,7 @@ void devi_devip(void *cntx, double *out, double *in) { for (i = 0; i < p->in.chan; i++) out[i] = in[i]; - if (!p->in.nocurve) { /* Using profile per channel curves */ + if (!p->in.nocurve) { /* Using ICC profile per channel curves & tvenc */ /* Video decode */ if (p->in.tvenc == 1) { /* Video 16-235 range */ @@ -753,7 +754,7 @@ void devi_devip(void *cntx, double *out, double *in) { icmVidRGB_2_RGB(out, out); } else if (p->in.tvenc >= 3) { /* YCbCr */ - error("Can't use input curves with YCbCr input encoding"); + error("Can't use input curves with YCbCr or other input encoding"); } #ifdef DEBUG @@ -800,25 +801,11 @@ void devi_devip(void *cntx, double *out, double *in) { #endif } - /* eeColor cLUT is fake 65^3 - only 64^3 is usable. This affects */ - /* full range and xvYCC RGB, so map inputs to cLUT to only use 64^3 */ - if (p->tdlut == 1) { - if (p->in.tvenc == 0) { /* Full range */ - for (i = 0; i < p->in.chan; i++) - out[i] = out[i] * (p->clutres-2.0)/(p->clutres-1.0); - - /* This isn't actually usable, because the eeColor does its own YCbCr conversion */ - } else if (p->in.tvenc == 8 || p->in.tvenc == 9) { /* xvYCC */ - out[0] = out[0]; - out[1] = (out[1] * (p->clutres-3.0) + 1.0)/(p->clutres-1.0); /* Keep symetrical */ - out[2] = (out[2] * (p->clutres-3.0) + 1.0)/(p->clutres-1.0); - } - } - - /* For video encoding, adjust index value vert slightly, */ + /* For video encoding, adjust index value very slightly, */ /* to align black with grid node. (We assume that the 3DLut HW */ /* is doing this when there are no input & output curves for 2DLuts) */ if (p->in.tvenc != 0 + && p->tdlut != 1 /* Not eeColor - it doesn't have an input curve */ && (p->clutres == 65 || p->clutres == 33 || p->clutres == 17)) { @@ -880,24 +867,10 @@ void devip_devop(void *cntx, double *out, double *in) { for (i = 0; i < p->in.chan; i++) win[i] = oin[i] = in[i]; - /* eeColor cLUT is fake 65^3 - only 64^3 is usable. This affects */ - /* full range and xvYCC RGB, so un-map inputs to cLUT to only use 64^3 */ - if (p->tdlut == 1) { - if (p->in.tvenc == 0) { - for (i = 0; i < p->in.chan; i++) - win[i] = win[i] * (p->clutres-1.0)/(p->clutres-2.0); - - /* This isn't actually usable, because the eeColor does its own YCbCr conversion */ - } else if (p->in.tvenc == 8 || p->in.tvenc == 9) { /* xvYCC */ - win[0] = win[0]; - win[1] = (win[1] * (p->clutres-1.0) - 1.0)/(p->clutres-3.0); - win[2] = (win[2] * (p->clutres-1.0) - 1.0)/(p->clutres-3.0); - } - } - /* For video encoding, adjust index value to align black with */ /* grid node */ if (p->in.tvenc != 0 + && p->tdlut != 1 /* Not eeColor - it doesn't have an input curve */ && (p->clutres == 65 || p->clutres == 33 || p->clutres == 17)) { @@ -920,7 +893,7 @@ void devip_devop(void *cntx, double *out, double *in) { #endif } - if (p->in.nocurve) { /* Not using profile per channel curves */ + if (p->in.nocurve) { /* Not using profile per channel tvenc curves */ /* Video encoding decode and input clipping */ scale = 1.0; if (p->in.tvenc == 1) { /* Video 16-235 range */ @@ -1066,7 +1039,7 @@ void devip_devop(void *cntx, double *out, double *in) { } } - if (p->in.lcurve) { /* Apply L* to Y */ + if (p->in.lcurve) { /* Apply L* to Y to undo input curve */ l2y_curve(win, win, p->in.lcurve == 2); #ifdef DEBUG DEBUGCND printf("win[] set to L* value %s\n",icmPdv(p->in.chan, win)); @@ -1406,6 +1379,9 @@ void devip_devop(void *cntx, double *out, double *in) { } 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)); +#endif } else { /* Various hacks haven't triggered */ switch(p->out.alg) { @@ -1479,27 +1455,20 @@ void devip_devop(void *cntx, double *out, double *in) { } if (rv >= 2) error("icc lookup failed: %d, %s",p->in.c->errc,p->in.c->err); - } - - if (p->cal != NULL && p->addcal == 1 && p->out.nocurve) { #ifdef DEBUG - DEBUGCND printf("DevOut' before cal curve %s\n\n",icmPdv(p->out.chan, out)); + DEBUGCND printf("DevOut' after PCS->Dev %s\n\n",icmPdv(p->out.chan, out)); #endif - p->cal->interp(p->cal, out, out); } - if (p->out.lcurve) { /* Apply Y to L* */ + if (p->cal != NULL && p->addcal == 1 && p->out.nocurve) { + p->cal->interp(p->cal, out, out); #ifdef DEBUG - DEBUGCND printf("DevOut' before y2l_curve %s\n\n",icmPdv(p->out.chan, out)); + DEBUGCND printf("DevOut' after cal curve %s\n\n",icmPdv(p->out.chan, out)); #endif - y2l_curve(out, out, p->out.lcurve == 2); } /* Video encode */ - if (p->out.nocurve && p->out.tvenc) { -#ifdef DEBUG - DEBUGCND printf("DevOut' before TVenc %s\n",icmPdv(p->out.chan, out)); -#endif + 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; @@ -1540,7 +1509,7 @@ void devip_devop(void *cntx, double *out, double *in) { #endif } - if (clip && p->out.nocurve && p->out.tvenc) { + 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 */ @@ -1588,6 +1557,34 @@ void devip_devop(void *cntx, double *out, double *in) { } } } +#ifdef DEBUG + 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; + } +#ifdef DEBUG + 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 */ +#ifdef DEBUG + DEBUGCND printf("DevOut' before y2l_curve %s\n\n",icmPdv(p->out.chan, out)); +#endif + y2l_curve(out, out, p->out.lcurve == 2); } #ifdef DEBUG @@ -1630,7 +1627,20 @@ void devop_devo(void *cntx, double *out, double *in) { #endif } - if (!p->out.nocurve) { /* Using per channel output curves */ + /* For eeColor and Full range RGB, unmap the cLUT output maps from 1.0 */ + 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]; +#ifdef DEBUG + DEBUGCND printf("DevOut after eeColor re-scale %s\n\n",icmPdv(p->out.chan, out)); +#endif + } + } + + if (!p->out.nocurve) { /* Using ICC per channel output curves and tvenc */ /* Apply output curve */ switch(p->out.alg) { @@ -1680,10 +1690,9 @@ void devop_devo(void *cntx, double *out, double *in) { } #ifdef DEBUG if (p->out.tvenc != 0) { - DEBUGCND printf("After Video encode %s\n",icmPdv(p->out.chan, out)); + DEBUGCND printf("After Video encode %s\n",icmPdv(p->out.chan, out)); } #endif - } #ifdef DEBUG DEBUGCND printf("DevOut'->DevOut ret %s\n",icmPdv(p->out.chan, out)); @@ -1826,8 +1835,8 @@ main(int argc, char *argv[]) { int intentset = 0; /* The user specified an intent */ int vcset = 0; /* Viewing conditions were set by user */ int modeset = 0; /* The gamut mapping mode was set by the user */ - int addcal = 0; /* 1 = Incorporate cal. curves in 3dLUT and set linear cal1 */ - /* 2 = Set 3dLut cal1 to calibration curves */ + int addcal = 0; /* 1 = Incorporate cal. curves in 3dLUT and set linear MadVR cal1 */ + /* 2 = Set 3dLut MadVR cal1 to calibration curves */ int rv = 0; icxViewCond ivc, ovc; /* Viewing Condition Overrides for in and out profiles */ int ivc_e = -1, ovc_e = -1; /* Enumerated viewing condition */ @@ -3549,23 +3558,23 @@ main(int argc, char *argv[]) { printf("Creating Gamut Mapping\n"); /* Gamut mapping will extend given grid res to encompas */ - /* source gamut by a margin. */ + /* source gamut by a margin. This allows for grid expansion beyond src gamut of 1.20 */ if (li.quality == 3) { /* Ultra High */ sgres = 7.0; dgres = 7.0; - mapres = 41; + mapres = 49; } else if (li.quality == 2) { /* High */ sgres = 8.0; dgres = 8.0; - mapres = 33; + mapres = 39; } else if (li.quality == 1) { /* Medium */ sgres = 10.0; dgres = 10.0; - mapres = 25; + mapres = 29; } else { /* Low quality */ sgres = 12.0; dgres = 12.0; - mapres = 17; + mapres = 19; } /* Creat the source colorspace gamut surface */ @@ -3762,7 +3771,7 @@ main(int argc, char *argv[]) { if (li.verb) { printf("Gamma curve target out black rel XYZ = %f %f %f, Lab %f %f %f\n", - bp[0],bp[1],bp[2], li.in.bt.outL, li.in.bt.tab[1], li.in.bt.tab[2]); + bp[0],bp[1],bp[2], li.in.bt.outL, li.in.bt.tab[0], li.in.bt.tab[1]); printf("Proportion of black output offset = %f%s\n", li.in.outoprop, li.in.outoprop == 0.0 ? " (BT.1886)" : ""); printf("Gamma Y input offset = %f\n", li.in.bt.ingo); @@ -4326,6 +4335,33 @@ main(int argc, char *argv[]) { } } + /* The eeColor hard wires 1.0 input to 1.0 output in its cLUT, */ + /* so de-scale the cLUT to match this, and re-scale in the */ + /* output 1D lut */ + + li.coscale[0] = li.coscale[1] = li.coscale[2] = 1.0; /* Default - do nothing */ + if (li.tdlut == 1) { /* eeColor encoded input */ + double inout[3] = { 1.0, 1.0, 1.0 }; + + /* ~~ it's not clear if this re-scaling would help with other */ + /* encodings like xvYCC ? */ + if (li.out.tvenc == 0) { /* Full range RGB */ + int verb = li.verb; + li.verb = 0; + devip_devop((void *)&li, inout, inout); + li.verb = verb; + if (inout[0] < 0.1 + || inout[1] < 0.1 + || inout[2] < 0.1) { + error("Link output for white is unexpected! (%f %f %f)\n",inout[0],inout[1],inout[2]); + } + icmCpy3(li.coscale, inout); + if (li.verb) + printf("De-scaling/scaling eeColor output by %f %f %f\n", + li.coscale[0], li.coscale[1], li.coscale[2]); + } + } + /* Link Lut = AToB0 */ if ((wo = (icmLut *)wr_icc->add_tag( @@ -4422,7 +4458,6 @@ main(int argc, char *argv[]) { if (li.map != NULL) li.map->dbg = 0; - } #endif /* NEVER */ @@ -4751,7 +4786,8 @@ main(int argc, char *argv[]) { /* ===================================================================== */ -/* Tweak for eeColor input and output value encodings */ +/* Tweak for eeColor input and output value encodings, to compensate */ +/* for assumption that it maps the FP range 1.0 to 64 * 2^(bits -6). */ static void VidRGB_to_eeColor(double out[3], double in[3]) { int i; @@ -4766,7 +4802,9 @@ static void eeColor_to_VidRGB(double out[3], double in[3]) { } -/* Write a eeColor 1DLut input LUT files */ +/* Write a eeColor 1DLut "first/gamma" LUT files. */ +/* eeColor applies these after the cLUT and before its 3x3 matrix. */ +/* This can't help us, so create a unity lookup/ */ /* Return nz on error */ int write_eeColor1DinputLuts(clink *li, char *tdlut_name) { char fname[MAXNAMEL+1+20], *xl; @@ -4793,23 +4831,7 @@ int write_eeColor1DinputLuts(clink *li, char *tdlut_name) { for (i = 0; i < 1024; i++) { for (k = 0; k < 3; k++) in[k] = i/(1024-1.0); - - /* Full range -> 64/65 scaled */ - /* or Video -> cLUT65 index */ - devi_devip((void *)li, out, in); - - if (li->in.tvenc == 1) { /* Video 16-235 range */ - cLUT65_to_VidRGB(out, out); - - /* eeColor doesn't actually do YCrCb explicitly, but put this here for completeness */ - } else if (li->in.tvenc == 3 /* Rec601 YCbCr */ - || li->in.tvenc == 4 /* Rec709 1150/60/2:1 YCbCr */ - || li->in.tvenc == 5 /* Rec709 1250/50/2:1 YCbCr */ - || li->in.tvenc == 6 /* Rec2020 Non-constant Luminance YCbCr encoding */ - || li->in.tvenc == 7) { /* Rec2020 Constant Luminance YCbCr encoding */ - cLUT65_to_YCrCb(out, out); - } - + icmCpy3(out,in); fp->gprintf(fp,"%.6f\n",out[j]); } @@ -4850,13 +4872,14 @@ int write_eeColor3DLut(icc *icc, clink *li, char *fname) { double oin[3], in[3], out[3]; /* Our assumption is that the eeColor maps the FP range 1.0 - to 64 * 2^(bits -6). This is sligghtly too much for + to 64 * 2^(bits -6). This is slightly too much for full range (PC), but exactly lines the black point - up on the 4th grid node for any video encodig bit depth, + up on the 4th grid node for any video encoding bit depth, and results in input values being the same as output - values for the null transform + values for the null transform. + (We haven't confirmed this assumtion by experiment.) */ - /* There are two sets of RGB values. One is (suposedly) + /* There are two sets of cLUT RGB values. One is (suposedly) the "calibrated white point" and one "the native white point", but experiments don't give any indications that the first three entries are capable of affecting the result in any way @@ -4864,7 +4887,7 @@ int write_eeColor3DLut(icc *icc, clink *li, char *fname) { */ /* The eeColor wires the 65'th node to 1.0, and we can skip */ - /* creating it */ + /* creating it. We de-scale in clut() and re-scale in devop_devo() to compensate. */ if (gc[0] == 64 || gc[1] == 64 || gc[2] == 64) goto next; @@ -4894,7 +4917,7 @@ int write_eeColor3DLut(icc *icc, clink *li, char *fname) { || li->in.tvenc == 4 /* Rec709 1150/60/2:1 YCbCr */ || li->in.tvenc == 5 /* Rec709 1250/50/2:1 YCbCr */ || li->in.tvenc == 6 /* Rec2020 Non-constant Luminance YCbCr encoding */ - || li->in.tvenc == 7) { /* Rec2020 Constant Luminance YCbCr encoding */ + || li->in.tvenc == 7) { /* Rec2020 Constant Luminance YCbCr encoding */ YCrCb_to_cLUT65(in, in); } } @@ -4923,7 +4946,7 @@ int write_eeColor3DLut(icc *icc, clink *li, char *fname) { return 0; } -/* Write a eeColor 1DLut output LUT files */ +/* Write a eeColor 1DLut "second/linearization" LUT files. */ /* Return nz on error */ int write_eeColor1DoutputLuts(clink *li, char *tdlut_name) { char fname[MAXNAMEL+1+20], *xl; @@ -4950,7 +4973,7 @@ int write_eeColor1DoutputLuts(clink *li, char *tdlut_name) { for (i = 0; i < 8192; i++) { for (k = 0; k < 3; k++) in[k] = i/(8192-1.0); - devop_devo((void *)li, out, in); + devop_devo((void *)li, out, in); /* Apply possible output re-scaling */ fp->gprintf(fp,"%.6f\n",out[j]); } @@ -5122,7 +5145,7 @@ int write_MadVR_3DLut(clink *li, icc *icc, char *fname) { } } - /* Append a cal1 table to the 3dlut. */ + /* Append a MadVR cal1 table to the 3dlut. */ /* This can be used to ensure that the Graphics Card VideoLuts */ /* are correctly setup to match what the 3dLut is expecting. */ diff --git a/link/monoplot.c b/link/monoplot.c index adcc532..2af1aac 100644 --- a/link/monoplot.c +++ b/link/monoplot.c @@ -26,14 +26,13 @@ #include #include "copyright.h" #include "aconfig.h" +#include "numsup.h" #include "icc.h" #include "plot.h" #include "ui.h" #define PRES 100 -void error(char *fmt, ...), warning(char *fmt, ...); - /* ---------------------------------------- */ void usage(void) { @@ -203,30 +202,3 @@ main( return 0; } -/* ------------------------------------------------ */ -/* Basic printf type error() and warning() routines */ - -void -error(char *fmt, ...) -{ - va_list args; - - fprintf(stderr,"monoplot: Error - "); - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - fprintf(stderr, "\n"); - exit (-1); -} - -void -warning(char *fmt, ...) -{ - va_list args; - - fprintf(stderr,"monoplot: Warning - "); - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - fprintf(stderr, "\n"); -} diff --git a/log.txt b/log.txt index 3c6d45f..e94a676 100644 --- a/log.txt +++ b/log.txt @@ -2,6 +2,59 @@ Argyll CMS change log ===================== +Version 1.8.3 +------------- + +* Added SpyderCheckr24 scaning .cht and .cie files. + +* Fixed USB problem with i1pro (Rev B & D ?), where + communications would occasionally break down on + fast systems. + +* Added another fixed display intergration time to i1pro + non-adaptive emission mode to cope with higher brightness displays. + +* Added workaround for i1d3 Rev. B status code 0x83 on very low light measurement. + +* Fixed minor bug in i1d3.c that truncated serial number string. + (Thanks to Mikael Sterner). + +* Fixed bug in Klein K10 driver - adaptive measurement + wasn't properly using all the extra measurements. + +* Improved Klein K10 driver to be more robust when lights off + command returns bogus error codes, or causes a cascade of + bogus measurement errors. + +* Added workaround for OS X 10.9+ "App Nap" problem. + +* Added maximum sensor frequency check for Spyder & i1d3 drivers, so that + erronious readings due to excessive brightness can't be missed. + +* 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. + +* 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. + +* Added "lp" gamut mapping intent :- Luminance Preserving Perceptual, + for Photographers concerned with maintaining tonal variations. + +* Fixed bugs in image specific gamut mapping that were degrading + the accuracy of the result. + +* Re-wrote gamut smoothing code, and re-tuned it to behave similarly + to the V1.8.2 release. + +* Changed default viewing condition glare to 5%, to smooth out + shadow tone curve. + +* Reduced the level of Helmholtz-Kohlrausch effect in CIECAM02 + implementation in the light of visual experiments. + Version 1.8.2 ------------- diff --git a/makepackagebin.sh b/makepackagebin.sh index 1b8db28..2b846ba 100644 --- a/makepackagebin.sh +++ b/makepackagebin.sh @@ -1,6 +1,8 @@ #!/bin/sh echo "Script to invoke Jam and then package the binary release." +# Must use this rather than "jam -q" to ensure builtin libraries are used. + # Typical environment variables: # (NOTE some systems don't export these ENV vars. by default !!!) # @@ -51,7 +53,7 @@ rm -f bin/*.exe bin/*.dll rm -f ref/*.sp ref/*.cht ref/*.ti2 # Make sure it's built and installed -if ! jam -q -fJambase -j${NUMBER_OF_PROCESSORS:-2} -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true install ; then +if ! jam -q -fJambase -j${NUMBER_OF_PROCESSORS:-2} -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true install ; then echo "Build failed!" exit 1 fi @@ -161,6 +163,7 @@ if [ X$USETAR = "Xtrue" ] ; then tar -czvf $PACKAGE $TOPDIR # tar -xzf to extract # tar -tzf to list + # Should we use "COPYFILE_DISABLE=1 tar .." on OS X ?? else zip -9 -r $PACKAGE $TOPDIR # unzip to extract diff --git a/namedc/namedc.c b/namedc/namedc.c index 6dcfce8..2fc7796 100644 --- a/namedc/namedc.c +++ b/namedc/namedc.c @@ -796,8 +796,8 @@ static int read_cxf(namedc *p, const char *filename, int options) { } if (!found_io) { - p->ill = icIlluminantD50; - p->obs = icStdObs1931TwoDegrees; + p->ill = icxIT_D50; + p->obs = icxOT_CIE_1931_2; a1logd(p->log, 2, "read_cxf: failed to locate ColorSpecification - assuming D50 2 degree observer\n"); } diff --git a/numlib/Jamfile b/numlib/Jamfile index 87c3c78..1053612 100644 --- a/numlib/Jamfile +++ b/numlib/Jamfile @@ -17,6 +17,8 @@ Headers = numlib.h libui.h ; #InstallFile $(DESTDIR)$(PREFIX)/h : $(Headers) ; #InstallLib $(DESTDIR)$(PREFIX)/lib : $(Libraries) ; +HDRS = ../h ; + # Numeric library Library libnum.lib : numsup.c dnsq.c powell.c dhsx.c ludecomp.c svd.c zbrent.c rand.c sobol.c aatree.c ; @@ -33,3 +35,5 @@ if $(OS) = MACOSX { # UI setup library Library libui.lib : ui.c ; + + diff --git a/numlib/numsup.c b/numlib/numsup.c index 43f6e73..c08ed99 100644 --- a/numlib/numsup.c +++ b/numlib/numsup.c @@ -17,6 +17,7 @@ #include #include #include +#include #if defined (NT) #define WIN32_LEAN_AND_MEAN #include @@ -24,8 +25,14 @@ #ifdef UNIX #include #include +#include #include #endif +#ifndef SALONEINSTLIB +#include "aconfig.h" +#else +#include "sa_config.h" +#endif #define NUMSUP_C #include "numsup.h" @@ -220,22 +227,138 @@ void check_if_not_interactive() { /* It's values can be overridden to redirect these messages. */ /******************************************************************/ +static void va_loge(a1log *p, char *fmt, ...); + #ifdef NT + +/* Get a string describing the MWin operating system */ + +typedef struct { + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + WCHAR szCSDVersion[128]; + WORD wServicePackMajor; + WORD wServicePackMinor; + WORD wSuiteMask; + BYTE wProductType; + BYTE wReserved; +} osversioninfoexw; + +#define VER_NT_DOMAIN_CONTROLLER 0x0000002 +#define VER_NT_SERVER 0x0000003 +#define VER_NT_WORKSTATION 0x0000001 + +static char *get_sys_info() { + static char sysinfo[100] = { "Unknown" }; + LONG (WINAPI *pfnRtlGetVersion)(osversioninfoexw*); + + *(FARPROC *)&pfnRtlGetVersion + = GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlGetVersion"); + if (pfnRtlGetVersion != NULL) { + osversioninfoexw ver = { 0 }; + ver.dwOSVersionInfoSize = sizeof(ver); + + if (pfnRtlGetVersion(&ver) == 0) { + if (ver.dwMajorVersion > 6 || (ver.dwMajorVersion == 6 && ver.dwMinorVersion > 3)) { + if (ver.wProductType == VER_NT_WORKSTATION) + sprintf(sysinfo,"Windows V%d.%d SP %d", + ver.dwMajorVersion,ver.dwMinorVersion, + ver.wServicePackMajor); + else + sprintf(sysinfo,"Windows Server 2016 V%d.%d SP %d", + ver.dwMajorVersion,ver.dwMinorVersion, + ver.wServicePackMajor); + + } else if (ver.dwMajorVersion == 6 && ver.dwMinorVersion == 3) { + if (ver.wProductType == VER_NT_WORKSTATION) + sprintf(sysinfo,"Windows V8.1 SP %d", + ver.wServicePackMajor); + else + sprintf(sysinfo,"Windows Server 2012 R2 SP %d", + ver.wServicePackMajor); + + } else if (ver.dwMajorVersion == 6 && ver.dwMinorVersion == 2) { + if (ver.wProductType == VER_NT_WORKSTATION) + sprintf(sysinfo,"Windows V8 SP %d", + ver.wServicePackMajor); + else + sprintf(sysinfo,"Windows Server SP %d", + ver.wServicePackMajor); + + } else if (ver.dwMajorVersion == 6 && ver.dwMinorVersion == 1) { + if (ver.wProductType == VER_NT_WORKSTATION) + sprintf(sysinfo,"Windows V7 SP %d", + ver.wServicePackMajor); + else + sprintf(sysinfo,"Windows Server 2008 R2 SP %d", + ver.wServicePackMajor); + + } else if (ver.dwMajorVersion == 6 && ver.dwMinorVersion == 0) { + if (ver.wProductType == VER_NT_WORKSTATION) + sprintf(sysinfo,"Windows Vista SP %d", + ver.wServicePackMajor); + else + sprintf(sysinfo,"Windows Server 2008 SP %d", + ver.wServicePackMajor); + + } else if (ver.dwMajorVersion == 5 && ver.dwMinorVersion == 2) { + // Actually could be Server 2003, Home Server, Server 2003 R2 + sprintf(sysinfo,"Windows XP Pro64 SP %d", + ver.wServicePackMajor); + + } else if (ver.dwMajorVersion == 5 && ver.dwMinorVersion == 1) { + sprintf(sysinfo,"Windows XP SP %d", + ver.wServicePackMajor); + + } else if (ver.dwMajorVersion == 5 && ver.dwMinorVersion == 0) { + sprintf(sysinfo,"Windows XP SP %d", + ver.wServicePackMajor); + + } else { + sprintf(sysinfo,"Windows Maj %d Min %d SP %d", + ver.dwMajorVersion,ver.dwMinorVersion, + ver.wServicePackMajor); + } + } + } + return sysinfo; +} + + # define A1LOG_LOCK(log) \ if (g_log_init == 0) { \ InitializeCriticalSection(&log->lock); \ + EnterCriticalSection(&log->lock); \ g_log_init = 1; \ - } \ - EnterCriticalSection(&log->lock) + va_loge(log, "Argyll 'V%s' Build '%s' System '%s'\n",ARGYLL_VERSION_STR,ARGYLL_BUILD_STR, get_sys_info()); \ + } else { \ + EnterCriticalSection(&log->lock); \ + } # define A1LOG_UNLOCK(log) LeaveCriticalSection(&log->lock) #endif #ifdef UNIX + +static char *get_sys_info() { + static char sysinfo[200] = { "Unknown" }; + struct utsname ver; + + if (uname(&ver) == 0) + sprintf(sysinfo,"%s %s %s %s",ver.sysname, ver.version, ver.release, ver.machine); + return sysinfo; +} + # define A1LOG_LOCK(log) \ if (g_log_init == 0) { \ pthread_mutex_init(&log->lock, NULL); \ + pthread_mutex_lock(&log->lock); \ g_log_init = 1; \ - } \ - pthread_mutex_lock(&log->lock) + va_loge(log, "Argyll 'V%s' Build '%s' System '%s'\n",ARGYLL_VERSION_STR,ARGYLL_BUILD_STR, get_sys_info()); \ + } else { \ + pthread_mutex_lock(&log->lock); \ + } # define A1LOG_UNLOCK(log) pthread_mutex_unlock(&log->lock) #endif @@ -257,6 +380,14 @@ static void a1_default_de_log(void *cntx, a1log *p, char *fmt, va_list args) { #define a1_default_e_log a1_default_de_log +/* Call log->loge() with variags */ +static void va_loge(a1log *p, char *fmt, ...) { + va_list args; + va_start(args, fmt); + p->loge(p->cntx, p, fmt, args); + va_end(args); +} + /* Global log */ a1log default_log = { 1, /* Refcount of 1 because this is not allocated or free'd */ @@ -597,6 +728,177 @@ size_t nsize return ptr; } +/******************************************************************/ +/* OS X App Nap fixes */ +/******************************************************************/ + +#if defined(__APPLE__) + +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 +# include +# include +#else +# include +#endif +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 +# include +#endif + +/* + OS X 10.9+ App Nap problems bug: + + + + NSProcessInfo variables: + + + + typedef enum : uint64_t { NSActivityIdleDisplaySleepDisabled = (1ULL << 40), + NSActivityIdleSystemSleepDisabled = (1ULL << 20), + NSActivitySuddenTerminationDisabled = (1ULL << 14), + NSActivityAutomaticTerminationDisabled = (1ULL << 15), + NSActivityUserInitiated = (0x00FFFFFFULL | NSActivityIdleSystemSleepDisabled ), + NSActivityUserInitiatedAllowingIdleSystemSleep = + (NSActivityUserInitiated & ~NSActivityIdleSystemSleepDisabled ), + NSActivityBackground = 0x000000FFULL, + NSActivityLatencyCritical = 0xFF00000000ULL, + } NSActivityOptions; + + See : + + @property (strong) id activity; + + if ([[NSProcessInfo processInfo] respondsToSelector:@selector(beginActivityWithOptions:reason:)]) { + self.activity = [[NSProcessInfo processInfo] beginActivityWithOptions:0x00FFFFFF reason:@"receiving OSC messages"]; +} + + + + NSProcessInfo = interface(NSObject)['{B96935F6-3809-4A49-AD4F-CBBAB0F2C961}'] + function beginActivityWithOptions(options: NSActivityOptions; reason: NSString): NSObject; cdecl; + + + +*/ + +static int osx_userinitiated_cnt = 0; +static id osx_userinitiated_activity = nil; + +/* Tell App Nap that this is user initiated */ +void osx_userinitiated_start() { + Class pic; /* Process info class */ + SEL pis; /* Process info selector */ + SEL bawo; /* Begin Activity With Options selector */ + id pi; /* Process info */ + id str; + + if (osx_userinitiated_cnt++ != 0) + return; + + a1logd(g_log, 7, "OS X - User Initiated Activity start\n"); + + /* We have to be conservative to avoid triggering an exception when run on older OS X */ + if ((pic = (Class)objc_getClass("NSProcessInfo")) == nil) { + return; + } + + if (class_getClassMethod(pic, (pis = sel_getUid("processInfo"))) == NULL) { + return; + } + + if (class_getInstanceMethod(pic, (bawo = sel_getUid("beginActivityWithOptions:reason:"))) == NULL) { + a1logd(g_log, 7, "OS X - beginActivityWithOptions not supported\n"); + return; + } + + /* Get the process instance */ + if ((pi = objc_msgSend((id)pic, pis)) == nil) { + return; + } + + /* Create a reason string */ + str = objc_msgSend(objc_getClass("NSString"), sel_getUid("alloc")); + str = objc_msgSend(str, sel_getUid("initWithUTF8String:"), "ArgyllCMS"); + + /* Start activity that tells App Nap to mind its own business. */ + /* NSActivityUserInitiatedAllowingIdleSystemSleep */ + osx_userinitiated_activity = objc_msgSend(pi, bawo, 0x00FFFFFFULL, str); +} + +/* Done with user initiated */ +void osx_userinitiated_end() { + if (osx_userinitiated_cnt > 0) { + osx_userinitiated_cnt--; + if (osx_userinitiated_cnt == 0 && osx_userinitiated_activity != nil) { + a1logd(g_log, 7, "OS X - User Initiated Activity end"); + objc_msgSend( + objc_msgSend(objc_getClass("NSProcessInfo"), sel_getUid("processInfo")), + sel_getUid("endActivity:"), osx_userinitiated_activity); + osx_userinitiated_activity = nil; + } + } +} + +static int osx_latencycritical_cnt = 0; +static id osx_latencycritical_activity = nil; + +/* Tell App Nap that this is latency critical */ +void osx_latencycritical_start() { + Class pic; /* Process info class */ + SEL pis; /* Process info selector */ + SEL bawo; /* Begin Activity With Options selector */ + id pi; /* Process info */ + id str; + + if (osx_latencycritical_cnt++ != 0) + return; + + a1logd(g_log, 7, "OS X - Latency Critical Activity start\n"); + + /* We have to be conservative to avoid triggering an exception when run on older OS X */ + if ((pic = (Class)objc_getClass("NSProcessInfo")) == nil) { + return; + } + + if (class_getClassMethod(pic, (pis = sel_getUid("processInfo"))) == NULL) { + return; + } + + if (class_getInstanceMethod(pic, (bawo = sel_getUid("beginActivityWithOptions:reason:"))) == NULL) { + a1logd(g_log, 7, "OS X - beginActivityWithOptions not supported\n"); + return; + } + + /* Get the process instance */ + if ((pi = objc_msgSend((id)pic, pis)) == nil) { + return; + } + + /* Create a reason string */ + str = objc_msgSend(objc_getClass("NSString"), sel_getUid("alloc")); + str = objc_msgSend(str, sel_getUid("initWithUTF8String:"), "Measuring Color"); + + /* Start activity that tells App Nap to mind its own business. */ + /* NSActivityUserInitiatedAllowingIdleSystemSleep | NSActivityLatencyCritical */ + osx_latencycritical_activity = objc_msgSend(pi, bawo, 0x00FFFFFFULL | 0xFF00000000ULL, str); +} + +/* Done with latency critical */ +void osx_latencycritical_end() { + if (osx_latencycritical_cnt > 0) { + osx_latencycritical_cnt--; + if (osx_latencycritical_cnt == 0 && osx_latencycritical_activity != nil) { + a1logd(g_log, 7, "OS X - Latency Critical Activity end"); + objc_msgSend( + objc_msgSend(objc_getClass("NSProcessInfo"), sel_getUid("processInfo")), + sel_getUid("endActivity:"), osx_latencycritical_activity); + osx_latencycritical_activity = nil; + } + } +} + +#endif /* __APPLE__ */ + /******************************************************************/ /* Numerical Recipes Vector/Matrix Support functions */ /******************************************************************/ diff --git a/numlib/numsup.h b/numlib/numsup.h index a284809..366763d 100644 --- a/numlib/numsup.h +++ b/numlib/numsup.h @@ -350,6 +350,24 @@ size_t nsize /* =========================================================== */ +#if defined(__APPLE__) + +/* Tell App Nap that this is user initiated */ +void osx_userinitiated_start(); + +/* Done with user initiated */ +void osx_userinitiated_end(); + +/* Tell App Nap that this is latency critical */ +void osx_latencycritical_start(); + +/* Done with latency critical */ +void osx_latencycritical_end(); + +#endif /* __APPLE__ */ + +/* =========================================================== */ + /* Numerical recipes vector/matrix support functions */ /* Note that the index arguments are the inclusive low and high values */ @@ -504,6 +522,7 @@ void write_INR64_le(ORD8 *p, INR64 d); #ifndef isNan #define isNan(x) ((x) != (x)) #define isFinite(x) ((x) == 0.0 || (x) * 1.0000001 != (x)) +#define isNFinite(x) ((x) != 0.0 && (x) * 1.0000001 == (x)) #endif diff --git a/numlib/ui.c b/numlib/ui.c index 31fd3b6..a3cdbe8 100644 --- a/numlib/ui.c +++ b/numlib/ui.c @@ -12,7 +12,8 @@ * see the License.txt file for licencing details. * * Typically we need to set things up and then call the - * "normal" main, called "uimain" in ArgyllCMS utils. + * "normal" main, called "uimain" in ArgyllCMS utils, + * created by ui.h #defining main to uimain. */ #ifdef UNIX @@ -48,6 +49,14 @@ # include # include +/* (Duplicate declaration from numsup.h) */ + +/* Tell App Nap that this is user initiated */ +void osx_userinitiated_start(); + +/* Done with user initiated */ +void osx_userinitiated_end(); + /* This is a mechanism to force libui to link */ int ui_initialized = 0; @@ -57,6 +66,9 @@ static char **g_argv; pthread_t ui_thid = 0; /* Thread ID of main thread running io run loop */ pthread_t ui_main_thid = 0; /* Thread ID of thread running application main() */ +extern int uimain(int argc, char *argv[]); + +/* Thread that calls the real application main() */ static void *callMain(void *p) { int rv; @@ -64,8 +76,13 @@ static void *callMain(void *p) { NSAutoreleasePool *tpool = [NSAutoreleasePool new]; + /* Turn App Nap off */ + osx_userinitiated_start(); + rv = uimain(g_argc, g_argv); + osx_userinitiated_end(); + [tpool release]; exit(rv); @@ -204,6 +221,8 @@ int ui_initialized = 0; //# pragma comment( linker, "/subsystem:windows /ENTRY:mainCRTStartup" ) //# pragma comment( linker, "/subsystem:windows /ENTRY:WinMainCRTStartup" ) +extern int uimain(int argc, char *argv[]); + APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, diff --git a/plot/plot.c b/plot/plot.c index 948cb64..e3cd5bf 100644 --- a/plot/plot.c +++ b/plot/plot.c @@ -1529,7 +1529,12 @@ static int do_plot_imp( nanosleep(&ts, NULL); } } else if (dowait < 0) { - Sleep(-dowait * 1000); + struct timespec ts; + int msec = -dowait * 1000; + + ts.tv_sec = msec / 1000; + ts.tv_nsec = (msec % 1000) * 1000000; + nanosleep(&ts, NULL); } if (tpool != nil) diff --git a/plot/vrml.c b/plot/vrml.c index 5b3f9a1..0121c53 100644 --- a/plot/vrml.c +++ b/plot/vrml.c @@ -877,7 +877,7 @@ double cc[3] /* Surface color, cc == NULL or cc[0] < 0.0 */ fprintf(s->fp," >\n"); /* Hack to workaround bugs in x3dom trasparency */ if (s->fmt == fmt_x3dom && trans > 0.0) - fprintf(s->fp," \n", trans); + fprintf(s->fp," \n"); fprintf(s->fp," \n"); fprintf(s->fp," \n"); } diff --git a/profile/colprof.c b/profile/colprof.c index ced168b..7309dc4 100644 --- a/profile/colprof.c +++ b/profile/colprof.c @@ -956,7 +956,7 @@ int main(int argc, char *argv[]) { if (illum == icxIT_none) illum = icxIT_D50; - if (observ = icxOT_none) + if (observ == icxOT_none) observ = icxOT_CIE_1931_2; /* See if CIE is actually available - some sources of .TI3 don't provide it */ diff --git a/profile/colverify.c b/profile/colverify.c index 40165a0..1ab3f64 100644 --- a/profile/colverify.c +++ b/profile/colverify.c @@ -707,7 +707,7 @@ int main(int argc, char *argv[]) } /* Set default */ - if (l_observ = icxOT_none) + if (l_observ == icxOT_none) l_observ = icxOT_CIE_1931_2; if ((sp2cie = new_xsp2cie(l_illum, l_illum == icxIT_none ? NULL : &cust_illum, diff --git a/profile/profcheck.c b/profile/profcheck.c index 8c2fc60..e3f1bec 100644 --- a/profile/profcheck.c +++ b/profile/profcheck.c @@ -446,7 +446,7 @@ int main(int argc, char *argv[]) if (illum == icxIT_none) illum = icxIT_D50; - if (observ = icxOT_none) + if (observ == icxOT_none) observ = icxOT_CIE_1931_2; /* See if CIE is actually available - some sources of .TI3 don't provide it */ diff --git a/profile/profout.c b/profile/profout.c index 1a6f4ae..4ad62aa 100644 --- a/profile/profout.c +++ b/profile/profout.c @@ -2276,22 +2276,22 @@ make_output_icc( printf("Creating Gamut Mapping\n"); /* Gamut mapping will extend given grid res to encompas */ - /* source gamut by a margin. */ - if (oquality == 3) { /* Ultra High */ - gres = 8.0; - mapres = 41; + /* source gamut by a margin of 1.20. */ + if (oquality == 3) { /* Ultra High */ + gres = 7.0; + mapres = 49; } else if (oquality == 2) { /* High */ gres = 8.0; - mapres = 33; + mapres = 39; } else if (oquality == 1) { /* Medium */ gres = 10.0; - mapres = 25; + mapres = 29; } else if (oquality == 0) { /* Low quality */ gres = 12.0; - mapres = 17; + mapres = 19; } else { /* Extremely low */ gres = 14.0; - mapres = 9; + mapres = 11; } /* We could lift this restriction by allowing for separate */ diff --git a/ref/ColorCheckerPassport.cht b/ref/ColorCheckerPassport.cht index 758cad7..5378c2f 100644 --- a/ref/ColorCheckerPassport.cht +++ b/ref/ColorCheckerPassport.cht @@ -69,54 +69,54 @@ YLIST 38 105.7 1.0 1.0 112.4 1.0 1.0 -EXPECTED XYZ -SAT1 31.444334 19.286094 6.888559 -SAT2 56.064662 44.030373 6.427599 -SAT3 67.324242 67.447159 7.468562 -SAT4 15.570651 29.465796 11.20434 -SAT5 21.619963 29.778971 41.25516 -SAT6 17.456572 19.372800 46.61877 -SAT7 24.114288 18.910816 30.96444 -SAT8 30.360635 18.858573 16.93814 -WBP1 55.603171 57.729295 46.42132 -WBP2 57.049606 60.324512 49.89966 -WBP3 53.811668 58.177050 49.42470 -WBP4 52.378305 57.343255 49.64556 -WBP5 52.469763 58.680177 51.97625 -WBL1 59.661034 59.332741 48.55177 -WBL2 59.041480 59.368909 48.29234 -WBL3 55.920447 58.052670 47.03935 -WBL4 55.083575 58.526581 51.10275 -WBL5 53.892264 58.200472 53.59833 -NEU1 3.151107 3.263644 2.737095 -NEU2 3.610326 3.768524 3.225077 -NEU3 4.585675 4.814770 4.063276 -NEU4 5.242110 5.523981 4.582603 -NEU5 44.365128 46.364955 37.75652 -NEU6 55.836099 58.281967 47.53593 -NEU7 70.627230 73.603361 59.69403 -NEU8 88.638466 92.368156 71.51666 -A1 11.411919 10.072672 5.112897 -A2 38.118655 34.074205 18.53409 -A3 16.687521 18.224488 25.41503 -A4 11.119565 13.272712 5.165291 -A5 23.995041 23.022599 32.25695 -A6 29.864887 41.242607 33.61720 -B1 40.774497 30.980646 4.853984 -B2 12.786912 11.654674 29.31582 -B3 29.900282 19.631992 10.31426 -B4 8.854344 6.750602 10.88177 -B5 35.445183 44.094908 8.863355 -B6 49.113465 43.647237 6.214123 -C1 6.659992 5.799339 20.11315 -C2 15.407588 23.700772 7.772715 -C3 21.254733 12.710445 3.970060 -C4 58.616280 59.203678 6.871706 -C5 31.444170 20.458848 23.34756 -C6 13.290512 19.046913 29.20373 -D1 87.016740 90.636247 69.99650 -D2 57.632418 59.860806 48.52846 -D3 35.434916 36.927843 30.23039 -D4 18.558911 19.319142 15.73822 -D5 8.770657 9.165214 7.636996 -D6 3.216922 3.320339 2.732945 +EXPECTED XYZ 50 + SAT1 31.444334 19.286094 6.888559 + SAT2 56.064662 44.030373 6.427599 + SAT3 67.324242 67.447159 7.468562 + SAT4 15.570651 29.465796 11.20434 + SAT5 21.619963 29.778971 41.25516 + SAT6 17.456572 19.372800 46.61877 + SAT7 24.114288 18.910816 30.96444 + SAT8 30.360635 18.858573 16.93814 + WBP1 55.603171 57.729295 46.42132 + WBP2 57.049606 60.324512 49.89966 + WBP3 53.811668 58.177050 49.42470 + WBP4 52.378305 57.343255 49.64556 + WBP5 52.469763 58.680177 51.97625 + WBL1 59.661034 59.332741 48.55177 + WBL2 59.041480 59.368909 48.29234 + WBL3 55.920447 58.052670 47.03935 + WBL4 55.083575 58.526581 51.10275 + WBL5 53.892264 58.200472 53.59833 + NEU1 3.151107 3.263644 2.737095 + NEU2 3.610326 3.768524 3.225077 + NEU3 4.585675 4.814770 4.063276 + NEU4 5.242110 5.523981 4.582603 + NEU5 44.365128 46.364955 37.75652 + NEU6 55.836099 58.281967 47.53593 + NEU7 70.627230 73.603361 59.69403 + NEU8 88.638466 92.368156 71.51666 + A1 11.411919 10.072672 5.112897 + A2 38.118655 34.074205 18.53409 + A3 16.687521 18.224488 25.41503 + A4 11.119565 13.272712 5.165291 + A5 23.995041 23.022599 32.25695 + A6 29.864887 41.242607 33.61720 + B1 40.774497 30.980646 4.853984 + B2 12.786912 11.654674 29.31582 + B3 29.900282 19.631992 10.31426 + B4 8.854344 6.750602 10.88177 + B5 35.445183 44.094908 8.863355 + B6 49.113465 43.647237 6.214123 + C1 6.659992 5.799339 20.11315 + C2 15.407588 23.700772 7.772715 + C3 21.254733 12.710445 3.970060 + C4 58.616280 59.203678 6.871706 + C5 31.444170 20.458848 23.34756 + C6 13.290512 19.046913 29.20373 + D1 87.016740 90.636247 69.99650 + D2 57.632418 59.860806 48.52846 + D3 35.434916 36.927843 30.23039 + D4 18.558911 19.319142 15.73822 + D5 8.770657 9.165214 7.636996 + D6 3.216922 3.320339 2.732945 diff --git a/ref/SpyderChecker24.cht b/ref/SpyderChecker24.cht new file mode 100644 index 0000000..a67bbf6 --- /dev/null +++ b/ref/SpyderChecker24.cht @@ -0,0 +1,59 @@ +BOXES 25 + F _ _ 11 11 405.5 11 405.5 609.5 11 609.5 + D ALL ALL _ _ 415 619 0 0 0 0 + X A D 1 6 88.5 88.5 11 11 102 102 + + +BOX_SHRINK 8.0 + +REF_ROTATION 0.0 + +XLIST 8 + 11.0 1.0 1.0 + 99.5 1.0 1.0 + 113.0 1.0 1.0 + 201.5 1.0 1.0 + 215.0 1.0 1.0 + 303.5 1.0 1.0 + 317.0 1.0 1.0 + 405.5 1.0 1.0 + +YLIST 12 + 11.0 1.0 1.0 + 99.5 1.0 1.0 + 113.0 1.0 1.0 + 201.5 1.0 1.0 + 215.0 1.0 1.0 + 303.5 1.0 1.0 + 317.0 1.0 1.0 + 405.5 1.0 1.0 + 419.0 1.0 1.0 + 507.5 1.0 1.0 + 521.0 1.0 1.0 + 609.5 1.0 1.0 + +EXPECTED XYZ 24 + A1 85.00 89.31 96.33 + A2 54.09 56.94 61.35 + A3 32.55 34.33 36.79 + A4 17.72 18.68 20.09 + A5 7.89 8.30 8.87 + A6 2.65 2.78 3.12 + B1 12.84 18.14 36.39 + B2 28.20 18.34 29.84 + B3 57.08 61.01 8.56 + B4 19.63 11.29 4.87 + B5 13.70 22.39 9.24 + B6 7.32 5.35 26.41 + C1 35.76 28.16 5.45 + C2 12.71 11.07 36.60 + C3 27.74 18.51 13.48 + C4 9.34 6.93 16.38 + C5 33.22 43.77 10.98 + C6 46.49 42.42 7.53 + D1 30.35 42.13 42.95 + D2 24.45 23.05 44.34 + D3 9.73 12.51 6.59 + D4 17.28 18.47 34.69 + D5 36.71 34.18 24.66 + D6 10.43 9.32 6.27 diff --git a/ref/SpyderChecker24.cie b/ref/SpyderChecker24.cie new file mode 100644 index 0000000..49bdf61 --- /dev/null +++ b/ref/SpyderChecker24.cie @@ -0,0 +1,38 @@ +IT8.7/2 +ORIGINATOR "Jose Pereira" +DESCRIPTOR "Datacolor SpyderCheckr (D65)" +CREATED "dec, 19. 2011" +MANUFACTURER "DataColor" + +NUMBER_OF_FIELDS 7 +BEGIN_DATA_FORMAT +SAMPLE_ID XYZ_X XYZ_Y XYZ_Z +END_DATA_FORMAT + +NUMBER_OF_SETS 24 +BEGIN_DATA +A1 85.00 89.31 96.33 +A2 54.09 56.94 61.35 +A3 32.55 34.33 36.79 +A4 17.72 18.68 20.09 +A5 7.89 8.30 8.87 +A6 2.65 2.78 3.12 +B1 12.84 18.14 36.39 +B2 28.20 18.34 29.84 +B3 57.08 61.01 8.56 +B4 19.63 11.29 4.87 +B5 13.70 22.39 9.24 +B6 7.32 5.35 26.41 +C1 35.76 28.16 5.45 +C2 12.71 11.07 36.60 +C3 27.74 18.51 13.48 +C4 9.34 6.93 16.38 +C5 33.22 43.77 10.98 +C6 46.49 42.42 7.53 +D1 30.35 42.13 42.95 +D2 24.45 23.05 44.34 +D3 9.73 12.51 6.59 +D4 17.28 18.47 34.69 +D5 36.71 34.18 24.66 +D6 10.43 9.32 6.27 +END_DATA diff --git a/ref/afiles b/ref/afiles index 360448a..bd8a2f1 100644 --- a/ref/afiles +++ b/ref/afiles @@ -28,6 +28,8 @@ ColorCheckerPassport.cht ColorCheckerPassport.cie SpyderChecker.cht SpyderChecker.cie +SpyderChecker24.cht +SpyderChecker24.cie ECI2002.ti2 ECI2002R.ti2 FograStrip2.ti1 diff --git a/ref/linear.cal b/ref/linear.cal index b686edc..9c88605 100644 --- a/ref/linear.cal +++ b/ref/linear.cal @@ -2,7 +2,7 @@ CAL DESCRIPTOR "Argyll Device Calibration Curves" ORIGINATOR "Argyll synthcal" -CREATED "Thu Jun 04 09:27:53 2015" +CREATED "Mon Oct 26 01:10:48 2015" DEVICE_CLASS "DISPLAY" COLOR_REP "RGB" diff --git a/ref/strange.cal b/ref/strange.cal index 6757f3b..5f2e94d 100644 --- a/ref/strange.cal +++ b/ref/strange.cal @@ -2,7 +2,7 @@ CAL DESCRIPTOR "Argyll Device Calibration Curves" ORIGINATOR "Argyll synthcal" -CREATED "Thu Jun 04 09:27:53 2015" +CREATED "Mon Oct 26 01:10:48 2015" DEVICE_CLASS "DISPLAY" COLOR_REP "RGB" diff --git a/rspl/gam.c b/rspl/gam.c index e46780f..0765e05 100644 --- a/rspl/gam.c +++ b/rspl/gam.c @@ -18,6 +18,52 @@ * Latest simplex/linear equation version. */ +/* + + This probably needs re-writing, since (I think) it doesn't take gamut + self intersection into account. Outline would be: + + Have a spactial cache structure that contains list of potentialy + intersecting triangles for any point. Create this incrementally. + Each triangle can be replaced by a list of fragment triangles + sharing the same plane. + + i.e. + + triangle planes + triangles + edges + vertexes + + Initialization: + + Locate extreme vertex + Locate triangle that uses that vertex that is most elevated + in that direction as initial surface. + Intersect that triangle with all other triangles nearby, and + retain the fragment that has that vertex. + List of open edges is initial triangle edges. + Track outward and inward faces of all triangles in open surface. + + Basic loop: + + While edge list is non-empty { + Locate adjacent triangle that is not part of surface that + is most accutely angled to outside face. + + Intersect that triangle with all other triangles using cache structure, + hanging on to all resulting fragments that are part of that edge. + + Add those fragments to the open surface. + + } + + Each intersection adds new nodes, and splits a triangle into + about 8 smaller triangles. Trick is to avoid slivers and + numerical issues with triangles. +*/ + + /* TTBD: Add ouutput curve lookup callback support. diff --git a/scanin/Jamfile b/scanin/Jamfile index 7a1ab7a..2cb05fb 100644 --- a/scanin/Jamfile +++ b/scanin/Jamfile @@ -13,7 +13,8 @@ Samples = it8.cht ColorChecker.cht ColorChecker.cie ColorCheckerDC.cht ColorChec ColorCheckerPassport.cht ColorCheckerPassport.cie QPcard_201.cht QPcard_201.cie QPcard_202.cht QPcard_202.cie CMP_DT_003.cht CMP_Digital_Target-4.cht CMP_Digital_Target-4.ti2 CMP_Digital_Target-4.cie - LaserSoftDCPro.cht SpyderChecker.cht SpyderChecker.cie ; + LaserSoftDCPro.cht SpyderChecker.cht SpyderChecker.cie + SpyderChecker24.cht SpyderChecker24.cie ; #Install InstallBin $(DESTDIR)$(PREFIX)/bin : $(Executables) ; diff --git a/scanin/SpyderChecker24.cht b/scanin/SpyderChecker24.cht new file mode 100644 index 0000000..a67bbf6 --- /dev/null +++ b/scanin/SpyderChecker24.cht @@ -0,0 +1,59 @@ +BOXES 25 + F _ _ 11 11 405.5 11 405.5 609.5 11 609.5 + D ALL ALL _ _ 415 619 0 0 0 0 + X A D 1 6 88.5 88.5 11 11 102 102 + + +BOX_SHRINK 8.0 + +REF_ROTATION 0.0 + +XLIST 8 + 11.0 1.0 1.0 + 99.5 1.0 1.0 + 113.0 1.0 1.0 + 201.5 1.0 1.0 + 215.0 1.0 1.0 + 303.5 1.0 1.0 + 317.0 1.0 1.0 + 405.5 1.0 1.0 + +YLIST 12 + 11.0 1.0 1.0 + 99.5 1.0 1.0 + 113.0 1.0 1.0 + 201.5 1.0 1.0 + 215.0 1.0 1.0 + 303.5 1.0 1.0 + 317.0 1.0 1.0 + 405.5 1.0 1.0 + 419.0 1.0 1.0 + 507.5 1.0 1.0 + 521.0 1.0 1.0 + 609.5 1.0 1.0 + +EXPECTED XYZ 24 + A1 85.00 89.31 96.33 + A2 54.09 56.94 61.35 + A3 32.55 34.33 36.79 + A4 17.72 18.68 20.09 + A5 7.89 8.30 8.87 + A6 2.65 2.78 3.12 + B1 12.84 18.14 36.39 + B2 28.20 18.34 29.84 + B3 57.08 61.01 8.56 + B4 19.63 11.29 4.87 + B5 13.70 22.39 9.24 + B6 7.32 5.35 26.41 + C1 35.76 28.16 5.45 + C2 12.71 11.07 36.60 + C3 27.74 18.51 13.48 + C4 9.34 6.93 16.38 + C5 33.22 43.77 10.98 + C6 46.49 42.42 7.53 + D1 30.35 42.13 42.95 + D2 24.45 23.05 44.34 + D3 9.73 12.51 6.59 + D4 17.28 18.47 34.69 + D5 36.71 34.18 24.66 + D6 10.43 9.32 6.27 diff --git a/scanin/SpyderChecker24.cie b/scanin/SpyderChecker24.cie new file mode 100644 index 0000000..49bdf61 --- /dev/null +++ b/scanin/SpyderChecker24.cie @@ -0,0 +1,38 @@ +IT8.7/2 +ORIGINATOR "Jose Pereira" +DESCRIPTOR "Datacolor SpyderCheckr (D65)" +CREATED "dec, 19. 2011" +MANUFACTURER "DataColor" + +NUMBER_OF_FIELDS 7 +BEGIN_DATA_FORMAT +SAMPLE_ID XYZ_X XYZ_Y XYZ_Z +END_DATA_FORMAT + +NUMBER_OF_SETS 24 +BEGIN_DATA +A1 85.00 89.31 96.33 +A2 54.09 56.94 61.35 +A3 32.55 34.33 36.79 +A4 17.72 18.68 20.09 +A5 7.89 8.30 8.87 +A6 2.65 2.78 3.12 +B1 12.84 18.14 36.39 +B2 28.20 18.34 29.84 +B3 57.08 61.01 8.56 +B4 19.63 11.29 4.87 +B5 13.70 22.39 9.24 +B6 7.32 5.35 26.41 +C1 35.76 28.16 5.45 +C2 12.71 11.07 36.60 +C3 27.74 18.51 13.48 +C4 9.34 6.93 16.38 +C5 33.22 43.77 10.98 +C6 46.49 42.42 7.53 +D1 30.35 42.13 42.95 +D2 24.45 23.05 44.34 +D3 9.73 12.51 6.59 +D4 17.28 18.47 34.69 +D5 36.71 34.18 24.66 +D6 10.43 9.32 6.27 +END_DATA diff --git a/scanin/afiles b/scanin/afiles index 399961c..90097e6 100644 --- a/scanin/afiles +++ b/scanin/afiles @@ -28,3 +28,5 @@ CMP_Digital_Target-4.cie LaserSoftDCPro.cht SpyderChecker.cht SpyderChecker.cie +SpyderChecker24.cht +SpyderChecker24.cie diff --git a/spectro/aglob.c b/spectro/aglob.c index 2ba37d5..dbf9157 100644 --- a/spectro/aglob.c +++ b/spectro/aglob.c @@ -42,6 +42,7 @@ # include #endif +#include #include #include #include diff --git a/spectro/ccxxmake.c b/spectro/ccxxmake.c index 4202c67..418affc 100644 --- a/spectro/ccxxmake.c +++ b/spectro/ccxxmake.c @@ -27,6 +27,9 @@ /* TTBD: + Would be nice to have a way of not changing the target + instruments absolute calibration. + Would be nice to have a veryify option that produces a fit report of a matrix vs. the input files. @@ -34,7 +37,7 @@ (See post from umberto.guidali@tiscali.it) Would be nice to be able to use an i1D3 to correct other instruments, - or an i1D3 created .ti3 as the reference. + or an i1D3 created .ti3 as the reference. (can do this with .ti3 files). Would be nice to have an option of providing two ICC profiles, instead of using .ti3 files (?? How well would it work though ?) diff --git a/spectro/chartread.c b/spectro/chartread.c index 0fc7646..9cf6c22 100644 --- a/spectro/chartread.c +++ b/spectro/chartread.c @@ -198,6 +198,7 @@ alphix *paix, /* Pass (row) index generators */ alphix *saix, /* Step (patch) index generators */ int ixord, /* Index order, 0 = pass then step */ int rstart, /* Random start/chart id */ +int rand, /* Random order used - can do auto strip ID & Bi-Dir */ int hex, /* Hexagon test patches */ icompath *ipath, /* Instrument path to open */ flow_control fc, /* flow control */ @@ -1389,7 +1390,7 @@ a1log *log /* verb, debug & error log */ int xbdir; /* Expected pass overall pass direction */ double xwerror = 0.0; /* Expected pass worst error in best strip */ - if (disbidi == 0 && (cap2 & inst2_bidi_scan)) + if (rand && disbidi == 0 && (cap2 & inst2_bidi_scan)) dirrg = 2; /* Enable bi-directional strip recognition */ /* DTP51 has a nasty habit of misaligning test squares by +/- 1 */ @@ -1463,7 +1464,7 @@ a1log *log /* verb, debug & error log */ } } } - if (emit_warnings != 0 && boroi != oroi) { /* Looks like the wrong strip */ + if (emit_warnings != 0 && rand && boroi != oroi) { /* Looks like the wrong strip */ char *mm = NULL; mm = paix->aix(paix, boroi); #ifdef DEBUG @@ -2110,6 +2111,7 @@ int main(int argc, char *argv[]) { alphix *paix, *saix; /* Pass and Step index generators */ int ixord = 0; /* Index order, 0 = pass then step */ int rstart = 0; /* Random start/chart id */ + int rand = 0; /* Random patch order, - can use auto strip ID and Bi-Di */ int hex = 0; /* Hexagon pattern layout */ time_t clk = time(0); struct tm *tsp = localtime(&clk); @@ -2472,10 +2474,13 @@ int main(int argc, char *argv[]) { ixord = 1; } - if ((ti = icg->find_kword(icg, 0, "RANDOM_START")) >= 0) + if ((ti = icg->find_kword(icg, 0, "RANDOM_START")) >= 0) { rstart = atoi(icg->t[0].kdata[ti]); - else if ((ti = icg->find_kword(icg, 0, "CHART_ID")) >= 0) + rand = 1; + } else if ((ti = icg->find_kword(icg, 0, "CHART_ID")) >= 0) { rstart = atoi(icg->t[0].kdata[ti]); + rand = 0; + } if ((ti = icg->find_kword(icg, 0, "HEXAGON_PATCHES")) >= 0) hex = 1; @@ -2503,6 +2508,10 @@ int main(int argc, char *argv[]) { tlen = atof(icg->t[0].kdata[ti]); } + if (itype != instDTP20 && !rand && disbidi == 0) { + warning("Can't do bi-directional strip recognition without randomize patch locations"); + } + if (verb) { printf("Steps in each Pass = %d\n",stipa); printf("Passes in each Strip = "); @@ -2838,7 +2847,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, hex, ipath, fc, plen, glen, tlen, + saix, ixord, rstart, rand, hex, ipath, fc, plen, glen, tlen, trans, emis, displ, dtype, fe, nocal, disbidi, highres, ccxxname, obType, scan_tol, pbypatch, xtern, spectral, uvmode, accurate_expd, emit_warnings, g_log) == 0) { diff --git a/spectro/colorhug.c b/spectro/colorhug.c index 1b2a56d..7397314 100644 --- a/spectro/colorhug.c +++ b/spectro/colorhug.c @@ -825,6 +825,7 @@ colorhug_del(inst *pp) { if (p->icom != NULL) p->icom->del(p->icom); inst_del_disptype_list(p->dtlist, p->ndtlist); + p->vdel(pp); free(p); } } diff --git a/spectro/conv.c b/spectro/conv.c index 1a8c78b..94023db 100644 --- a/spectro/conv.c +++ b/spectro/conv.c @@ -68,6 +68,7 @@ //#include #include #include +#include #include #include #include @@ -263,12 +264,14 @@ static int beep_msec; /* Delayed beep handler */ static int delayed_beep(void *pp) { msec_sleep(beep_delay); + a1logd(g_log,8, "msec_beep activate\n"); Beep(beep_freq, beep_msec); return 0; } /* Activate the system beeper */ void msec_beep(int delay, int freq, int msec) { + a1logd(g_log,8, "msec_beep %d msec\n",msec); if (delay > 0) { if (beep_thread != NULL) beep_thread->del(beep_thread); @@ -278,6 +281,7 @@ void msec_beep(int delay, int freq, int msec) { if ((beep_thread = new_athread(delayed_beep, NULL)) == NULL) a1logw(g_log, "msec_beep: Delayed beep failed to create thread\n"); } else { + a1logd(g_log,8, "msec_beep activate\n"); Beep(freq, msec); } } @@ -549,6 +553,8 @@ void empty_con_chars(void) { } /* Sleep for the given number of msec */ +/* (Note that OS X 10.9+ App Nap can wreck this, unless */ +/* it is turned off.) */ void msec_sleep(unsigned int msec) { #ifdef NEVER if (msec > 1000) { @@ -779,6 +785,7 @@ static int beep_msec; /* Delayed beep handler */ static int delayed_beep(void *pp) { msec_sleep(beep_delay); + a1logd(g_log,8, "msec_beep activate\n"); #ifdef __APPLE__ # if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 AudioServicesPlayAlertSound(kUserPreferredAlert); @@ -794,6 +801,7 @@ static int delayed_beep(void *pp) { /* Activate the system beeper */ void msec_beep(int delay, int freq, int msec) { + a1logd(g_log,8, "msec_beep %d msec\n",msec); if (delay > 0) { if (beep_thread != NULL) beep_thread->del(beep_thread); @@ -803,6 +811,7 @@ void msec_beep(int delay, int freq, int msec) { if ((beep_thread = new_athread(delayed_beep, NULL)) == NULL) a1logw(g_log, "msec_beep: Delayed beep failed to create thread\n"); } else { + a1logd(g_log,8, "msec_beep activate\n"); #ifdef __APPLE__ # if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 AudioServicesPlayAlertSound(kUserPreferredAlert); diff --git a/spectro/dispwin.c b/spectro/dispwin.c index 69536f3..fffbaee 100644 --- a/spectro/dispwin.c +++ b/spectro/dispwin.c @@ -3624,6 +3624,9 @@ static void create_my_win(NSRect rect, osx_cntx_t *cx) { [cx->view setCntx:(void *)cx]; [cx->window setContentView: cx->view]; + /* Moves the window to the front of the screen list within its level, */ + /* and show the window (i.e. make it "key") */ + /* Trigger crash on OS X 10.11 El Capitan ? */ [cx->window makeKeyAndOrderFront: nil]; /* Use a null color transform to ensure device values */ @@ -6451,7 +6454,7 @@ main(int argc, char *argv[]) { /* Try darkening it */ for (j = 0; j < 3; j++) { for (i = 0; i < dw->r->nent; i++) { - dw->r->v[j][i] = pow(dw->or->v[j][i], 2.0); + dw->r->v[j][i] = pow(dw->or->v[j][i], 1.6); } } printf("Darkening screen\n"); @@ -6464,7 +6467,7 @@ main(int argc, char *argv[]) { /* Try lightening it */ for (j = 0; j < 3; j++) { for (i = 0; i < dw->r->nent; i++) { - dw->r->v[j][i] = pow(dw->or->v[j][i], 0.5); + dw->r->v[j][i] = pow(dw->or->v[j][i], 0.625); } } printf("Lightening screen\n"); diff --git a/spectro/dtp20.c b/spectro/dtp20.c index a504803..6af2484 100644 --- a/spectro/dtp20.c +++ b/spectro/dtp20.c @@ -217,7 +217,7 @@ double top) { /* Timout in seconds */ } /* Establish communications with a DTP20 */ -/* Return DTP_COMS_FAIL on failure to establish communications */ +/* Return DTP20_COMS_FAIL on failure to establish communications */ static inst_code dtp20_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { dtp20 *p = (dtp20 *)pp; @@ -1402,7 +1402,8 @@ dtp20_del(inst *pp) { dtp20 *p = (dtp20 *)pp; if (p->icom != NULL) p->icom->del(p->icom); - free (p); + p->vdel(pp); + free(p); } /* Set the instrument capabilities */ diff --git a/spectro/dtp22.c b/spectro/dtp22.c index d332ffc..2cb3634 100644 --- a/spectro/dtp22.c +++ b/spectro/dtp22.c @@ -164,7 +164,7 @@ dtp22_command(dtp22 *p, char *in, char *out, int bsize, double to) { /* Establish communications with a DTP22 */ /* If it's a serial port, use the baud rate given, and timeout in to secs */ -/* Return DTP_COMS_FAIL on failure to establish communications */ +/* Return DTP22_COMS_FAIL on failure to establish communications */ static inst_code dtp22_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { dtp22 *p = (dtp22 *) pp; @@ -930,6 +930,7 @@ dtp22_del(inst *pp) { dtp22 *p = (dtp22 *)pp; if (p->icom != NULL) p->icom->del(p->icom); + p->vdel(pp); free(p); } diff --git a/spectro/dtp41.c b/spectro/dtp41.c index 5c3361c..44ac6c6 100644 --- a/spectro/dtp41.c +++ b/spectro/dtp41.c @@ -145,7 +145,7 @@ dtp41_command(dtp41 *p, char *in, char *out, int bsize, double to) { /* Establish communications with a DTP41 */ /* Use the baud rate given, and timeout in to secs */ -/* Return DTP_COMS_FAIL on failure to establish communications */ +/* Return DTP41_COMS_FAIL on failure to establish communications */ static inst_code dtp41_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { dtp41 *p = (dtp41 *)pp; @@ -1085,7 +1085,8 @@ dtp41_del(inst *pp) { dtp41 *p = (dtp41 *)pp; if (p->icom != NULL) p->icom->del(p->icom); - free (p); + p->vdel(pp); + free(p); } /* Interogate the device to discover its capabilities */ diff --git a/spectro/dtp51.c b/spectro/dtp51.c index cfd1265..ab1999d 100644 --- a/spectro/dtp51.c +++ b/spectro/dtp51.c @@ -180,7 +180,7 @@ double to) { /* Timout in seconts */ /* Establish communications with a DTP51 */ /* Use the baud rate given, and timeout in to secs */ -/* Return DTP_COMS_FAIL on failure to establish communications */ +/* Return DTP51_COMS_FAIL on failure to establish communications */ static inst_code dtp51_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { dtp51 *p = (dtp51 *)pp; @@ -787,6 +787,7 @@ dtp51_del(inst *pp) { dtp51 *p = (dtp51 *)pp; if (p->icom != NULL) p->icom->del(p->icom); + p->vdel(pp); free(p); } diff --git a/spectro/dtp92.c b/spectro/dtp92.c index 1ed9bc1..3b6dacd 100644 --- a/spectro/dtp92.c +++ b/spectro/dtp92.c @@ -169,7 +169,7 @@ dtp92_command(dtp92 *p, char *in, char *out, int bsize, double to) { /* Establish communications with a DTP92 */ /* If it's a serial port, use the baud rate given, and timeout in to secs */ -/* Return DTP_COMS_FAIL on failure to establish communications */ +/* Return DTP92_COMS_FAIL on failure to establish communications */ static inst_code dtp92_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { dtp92 *p = (dtp92 *) pp; @@ -1023,6 +1023,7 @@ dtp92_del(inst *pp) { if (p->icom != NULL) p->icom->del(p->icom); inst_del_disptype_list(p->dtlist, p->ndtlist); + p->vdel(pp); free(p); } diff --git a/spectro/ex1.c b/spectro/ex1.c index 93d0a31..b336cbc 100644 --- a/spectro/ex1.c +++ b/spectro/ex1.c @@ -147,6 +147,10 @@ static int ex1_set_boxcar(ex1 *p, int nobox); static int ex1_measure(ex1 *p, double *raw); +static int ex1_save_calibration(ex1 *p); +static int ex1_restore_calibration(ex1 *p); +static int ex1_touch_calibration(ex1 *p); + /* ----------------------------------------------------------------- */ /* Establish communications with a ex1 */ @@ -1038,6 +1042,7 @@ ex1_del(inst *pp) { if (p->conv != NULL) p->conv->del(p->conv); + p->vdel(pp); free(p); } } @@ -1234,7 +1239,7 @@ extern ex1 *new_ex1(icoms *icom, instType itype) { /* =============================================================================== */ /* Calibration info save/restore */ -int ex1_save_calibration(ex1 *p) { +static int ex1_save_calibration(ex1 *p) { int ev = EX1_OK; int i; char fname[100]; /* Name */ @@ -1280,7 +1285,7 @@ int ex1_save_calibration(ex1 *p) { } /* Restore the all modes calibration from the local system */ -int ex1_restore_calibration(ex1 *p) { +static int ex1_restore_calibration(ex1 *p) { int ev = EX1_OK; int i, j; char fname[100]; /* Name */ @@ -1353,7 +1358,7 @@ int ex1_restore_calibration(ex1 *p) { return ev; } -int ex1_touch_calibration(ex1 *p) { +static int ex1_touch_calibration(ex1 *p) { int ev = EX1_OK; char fname[100]; /* Name */ int rv; diff --git a/spectro/hcfr.c b/spectro/hcfr.c index d0a8261..a6c457e 100644 --- a/spectro/hcfr.c +++ b/spectro/hcfr.c @@ -637,6 +637,7 @@ hcfr_del(inst *pp) { if (p->icom != NULL) p->icom->del(p->icom); inst_del_disptype_list(p->dtlist, p->ndtlist); + p->vdel(pp); free(p); } diff --git a/spectro/huey.c b/spectro/huey.c index 79f8089..b09ed2c 100644 --- a/spectro/huey.c +++ b/spectro/huey.c @@ -159,7 +159,7 @@ static char *inst_desc(int cc) { /* The Huey is set up as an HID device, which can ease the need */ /* for providing a kernel driver on MSWindows systems, */ /* but it doesn't seem to actually be used as an HID device. */ -/* We allow for communicating via libusb, or an HID driver. */ +/* We allow for communicating via usbio, or an HID driver. */ static inst_code huey_command( huey *p, /* huey object */ @@ -1026,7 +1026,7 @@ static inst_code set_default_disp_type(huey *p); /* Establish communications with a HUEY */ /* If it's a serial port, use the baud rate given, and timeout in to secs */ -/* Return DTP_COMS_FAIL on failure to establish communications */ +/* Return HUEY_COMS_FAIL on failure to establish communications */ static inst_code huey_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { huey *p = (huey *) pp; @@ -1400,6 +1400,7 @@ huey_del(inst *pp) { if (p->icom != NULL) p->icom->del(p->icom); inst_del_disptype_list(p->dtlist, p->ndtlist); + p->vdel(pp); free(p); } diff --git a/spectro/i1d3.c b/spectro/i1d3.c index 689f328..df7d3f0 100644 --- a/spectro/i1d3.c +++ b/spectro/i1d3.c @@ -34,6 +34,10 @@ and agreed to support. */ +/* TTBD: + +*/ + #include #include #include @@ -70,6 +74,8 @@ #define I1D3_MEAS_TIMEOUT 40.0 /* Longest reading timeout in seconds */ /* Typically 20.0 is the maximum needed. */ +#define I1D3_SAT_FREQ 100000.0 /* L2F sensor frequency limit */ + static inst_code i1d3_interp_code(inst *pp, int ec); static inst_code i1d3_check_unlock(i1d3 *p); @@ -105,6 +111,12 @@ static int icoms2i1d3_err(int se, int torc) { /* and byte 1 is the sub code for command 0x00 . The response is byte 0 */ /* error code, byte 1 echoing the major command number. */ /* Major code 00 works when locked ? */ +/* Response codes: + + 00 OK + 83 After pulse count measure in low light. Means ??? + + */ typedef enum { i1d3_getinfo = 0x0000, /* Product name + Firmware version + Firmware Date string */ i1d3_status = 0x0001, /* status number ?? */ @@ -174,7 +186,7 @@ static char *inst_desc(i1Disp3CC cc) { /* The i1d3 is set up as an HID device, which can ease the need */ /* for providing a kernel driver on MSWindows systems, */ /* but it doesn't seem to actually be used as an HID device. */ -/* We allow for communicating via libusb, or an HID driver. */ +/* We allow for communicating via usbio, or an HID driver. */ static inst_code i1d3_command( i1d3 *p, /* i1d3 object */ @@ -265,6 +277,21 @@ i1d3_command( rv = i1d3_interp_code((inst *)p, I1D3_BAD_RD_LENGTH); } + /* Hmm. Not sure about this bug workaround. Is this a rev B thing ? */ + /* May get status 0x83 on i1d3_measure2 when there are no transitions ? */ + /* If so, ignore the error. */ + if (rv == inst_ok && cc == i1d3_measure2 && recv[1] == 0x02 && recv[0] == 0x83) { + int i; + for (i = 2; i < 14; i++) { + if (recv[i] != 0) + break; + } + if (i >= 14) { /* returned all zero's */ + if (!nd) a1logd(p->log, 1, "i1d3_command: ignoring status byte = 0x%x\n",recv[0]); + recv[0] = 0x00; /* Fudge OK status */ + } + } + /* The first byte returned seems to be a command result error code. */ if (rv == inst_ok && recv[0] != 0x00) { if (!nd) a1logd(p->log, 1, "i1d3_command: status byte != 00 = 0x%x\n",recv[0]); @@ -756,7 +783,7 @@ static inst_code i1d3_freq_measure( i1d3 *p, /* Object */ double *inttime, /* Integration time in seconds. (Return clock rounded) */ - double rgb[3] /* Return the RGB values */ + double rgb[3] /* Return the RGB count values */ ) { int intclks; unsigned char todev[64]; @@ -1568,6 +1595,11 @@ i1d3_take_emis_measurement( } a1logd(p->log,3,"Got %f %f %f raw, %f %f %f Hz\n",rmeas[0],rmeas[1],rmeas[2],rgb[0],rgb[1],rgb[2]); + + for (i = 0; i < 3; i++) { + if (rgb[i] > I1D3_SAT_FREQ) + return i1d3_interp_code((inst *)p, I1D3_TOOBRIGHT); + } } /* If some period measurement will be done */ @@ -1863,6 +1895,11 @@ i1d3_take_emis_measurement( a1logd(p->log,3,"Got %f %f %f raw, %f %f %f Hz after re-measure\n",rmeas[0],rmeas[1],rmeas[2],rgb[0],rgb[1],rgb[2]); + for (i = 0; i < 3; i++) { + if (rgb[i] > I1D3_SAT_FREQ) + return i1d3_interp_code((inst *)p, I1D3_TOOBRIGHT); + } + } else { /* Use period measurement of the target number of edges */ /* (Note that if the patch isn't constant and drops compared to */ @@ -1907,6 +1944,11 @@ i1d3_take_emis_measurement( } a1logd(p->log,3,"Cooked RGB = %f %f %f\n",rgb[0],rgb[1],rgb[2]); + + for (i = 0; i < 3; i++) { + if (rgb[i] > I1D3_SAT_FREQ) + return i1d3_interp_code((inst *)p, I1D3_TOOBRIGHT); + } return inst_ok; } @@ -1983,7 +2025,7 @@ static inst_code i1d3_decode_intEE( p->serial_no[20] = '\000'; strncpy(p->vers_no, (char *)buf + 0x2C, 10); - p->serial_no[10] = '\000'; + p->vers_no[10] = '\000'; /* Read the black level offset */ for (i = 0; i < 3; i++) { @@ -2395,7 +2437,7 @@ i1d3_set_cal(i1d3 *p) { /* ------------------------------------------------------------------------ */ /* Establish communications with a I1D3 */ -/* Return DTP_COMS_FAIL on failure to establish communications */ +/* Return I1D3_COMS_FAIL on failure to establish communications */ static inst_code i1d3_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { i1d3 *p = (i1d3 *) pp; @@ -3287,6 +3329,9 @@ i1d3_interp_error(inst *pp, int ec) { case I1D3_INT_THREADFAILED: return "Starting diffuser position thread failed"; + case I1D3_TOOBRIGHT: + return "Too bright to read accuractly"; + case I1D3_NO_COMS: return "Communications hasn't been established";; case I1D3_NOT_INITED: @@ -3355,11 +3400,13 @@ i1d3_interp_code(inst *pp, int ec) { case I1D3_BAD_EX_CHSUM: return inst_hardware_fail | ec; + case I1D3_TOOBRIGHT: + return inst_misread | ec; + /* Unused: inst_notify inst_warning inst_unknown_model - inst_misread inst_nonesaved inst_nochmatch inst_needs_cal @@ -3411,6 +3458,7 @@ i1d3_del(inst *pp) { if (p->samples != NULL) free(p->samples); amutex_del(p->lock); + p->vdel(pp); free(p); } } diff --git a/spectro/i1d3.h b/spectro/i1d3.h index 47f3858..bb239df 100644 --- a/spectro/i1d3.h +++ b/spectro/i1d3.h @@ -63,6 +63,7 @@ #define I1D3_BAD_RET_STAT 0x13 #define I1D3_BAD_RET_CMD 0x14 #define I1D3_NOT_INITED 0x15 +#define I1D3_TOOBRIGHT 0x16 /* Internal errors */ #define I1D3_BAD_MEM_ADDRESS 0x20 diff --git a/spectro/i1disp.c b/spectro/i1disp.c index 437e1fa..489c6cd 100644 --- a/spectro/i1disp.c +++ b/spectro/i1disp.c @@ -1737,7 +1737,7 @@ i1disp_compute_factors( /* Establish communications with a I1DISP */ /* If it's a serial port, use the baud rate given, and timeout in to secs */ -/* Return DTP_COMS_FAIL on failure to establish communications */ +/* Return I1DISP_COMS_FAIL on failure to establish communications */ static inst_code i1disp_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { i1disp *p = (i1disp *) pp; @@ -2240,6 +2240,7 @@ i1disp_del(inst *pp) { if (p->icom != NULL) p->icom->del(p->icom); inst_del_disptype_list(p->dtlist, p->ndtlist); + p->vdel(pp); free(p); } diff --git a/spectro/i1pro.c b/spectro/i1pro.c index 96335cc..816aee5 100644 --- a/spectro/i1pro.c +++ b/spectro/i1pro.c @@ -79,7 +79,7 @@ static inst_code i1pro_interp_code(i1pro *p, i1pro_code ec); /* Establish communications with a I1DISP */ /* If it's a serial port, use the baud rate given, and timeout in to secs */ -/* Return DTP_COMS_FAIL on failure to establish communications */ +/* Return I1PRO_COMS_FAIL on failure to establish communications */ static inst_code i1pro_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { i1pro *p = (i1pro *) pp; @@ -806,6 +806,7 @@ i1pro_del(inst *pp) { del_i1proimp(p); if (p->icom != NULL) p->icom->del(p->icom); + p->vdel(pp); free(p); } diff --git a/spectro/i1pro_imp.c b/spectro/i1pro_imp.c index 0b6fc69..8577f8c 100644 --- a/spectro/i1pro_imp.c +++ b/spectro/i1pro_imp.c @@ -149,6 +149,8 @@ /* Should be good up to 275 cd/m^2 */ #define DISP_INTT3 0.3 /* High brightness display spot mode seconds per reading, */ /* Should be good up to 700 cd/m^2 */ +#define DISP_INTT4 0.1 /* Very high brightness display spot mode seconds per reading, */ + /* Should be good up to 2000 cd/m^2 ? */ #define ADARKINT_MAX 2.0 /* Max cal time for adaptive dark cal */ #define ADARKINT_MAX2 4.0 /* Max cal time for adaptive dark cal Rev E or no high gain */ @@ -398,6 +400,7 @@ void del_i1proimp(i1pro *p) { free_dvector(s->dark_data, -1, m->nraw-1); free_dvector(s->dark_data2, -1, m->nraw-1); free_dvector(s->dark_data3, -1, m->nraw-1); + free_dvector(s->dark_data4, -1, m->nraw-1); free_dvector(s->white_data, -1, m->nraw-1); free_dmatrix(s->idark_data, 0, 3, -1, m->nraw-1); @@ -958,6 +961,7 @@ i1pro_code i1pro_imp_init(i1pro *p) { s->dark_data = dvectorz(-1, m->nraw-1); s->dark_data2 = dvectorz(-1, m->nraw-1); s->dark_data3 = dvectorz(-1, m->nraw-1); + s->dark_data4 = dvectorz(-1, m->nraw-1); s->cal_valid = 0; /* Scale cal invalid */ s->cal_factor[0] = dvectorz(0, m->nwav[0]-1); @@ -972,6 +976,7 @@ i1pro_code i1pro_imp_init(i1pro *p) { s->dark_int_time = DISP_INTT; /* 2.0 */ s->dark_int_time2 = DISP_INTT2; /* 0.8 */ s->dark_int_time3 = DISP_INTT3; /* 0.3 */ + s->dark_int_time4 = DISP_INTT4; /* 0.1 */ s->idark_int_time[0] = s->idark_int_time[2] = m->min_int_time; if (p->itype == instI1Pro2) { @@ -1057,12 +1062,14 @@ i1pro_code i1pro_imp_init(i1pro *p) { s->dark_int_time = s->inttime; s->dark_int_time2 = DISP_INTT2; /* Alternate disp integration time (ie. 0.8) */ s->dark_int_time3 = DISP_INTT3; /* Alternate disp integration time (ie. 0.3) */ + s->dark_int_time4 = DISP_INTT4; /* Alternate disp integration time (ie. 0.1) */ s->dadaptime = 0.0; s->wadaptime = 0.10; s->dcaltime = DISP_INTT; /* ie. determines number of measurements */ s->dcaltime2 = DISP_INTT2 * 2; /* Make it 1.6 seconds (ie, 2 x 0.8 seconds) */ s->dcaltime3 = DISP_INTT3 * 3; /* Make it 0.9 seconds (ie, 3 x 0.3 seconds) */ + s->dcaltime4 = DISP_INTT4 * 3; /* Make it 0.3 seconds (ie, 3 x 0.1 seconds) */ s->wcaltime = 0.0; s->dreadtime = 0.0; s->wreadtime = DISP_INTT; @@ -1620,10 +1627,10 @@ i1pro_code i1pro_imp_calibrate( || (s->emiss && !s->adaptive && !s->scan) || (s->trans && !s->adaptive))) { int stm; - int usesdct23 = 0; /* Is a mode that uses dcaltime2 & 3 */ + int usesdct234 = 0; /* Is a mode that uses dcaltime2, 3 & 4 */ if (s->emiss && !s->adaptive && !s->scan) - usesdct23 = 1; + usesdct234 = 1; nummeas = i1pro_comp_nummeas(p, s->dcaltime, s->inttime); @@ -1637,7 +1644,7 @@ i1pro_code i1pro_imp_calibrate( a1logd(p->log,2,"Execution time of dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm); /* Special display mode alternate integration time black measurement */ - if (usesdct23) { + if (usesdct234) { nummeas = i1pro_comp_nummeas(p, s->dcaltime2, s->dark_int_time2); a1logd(p->log,2,"Doing 2nd initial black calibration with dcaltime2 %f, dark_int_time2 %f, nummeas %d, gainmode %d\n", s->dcaltime2, s->dark_int_time2, nummeas, s->gainmode); stm = msec_time(); @@ -1658,6 +1665,17 @@ i1pro_code i1pro_imp_calibrate( return ev; } a1logd(p->log,2,"Execution time of 3rd dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm); + + nummeas = i1pro_comp_nummeas(p, s->dcaltime4, s->dark_int_time4); + a1logd(p->log,2,"Doing 4th initial black calibration with dcaltime4 %f, dark_int_time4 %f, nummeas %d, gainmode %d\n", s->dcaltime4, s->dark_int_time4, nummeas, s->gainmode); + nummeas = i1pro_comp_nummeas(p, s->dcaltime4, s->dark_int_time4); + stm = msec_time(); + if ((ev = i1pro_dark_measure(p, s->dark_data4, + nummeas, &s->dark_int_time4, s->gainmode)) != I1PRO_OK) { + m->mmode = mmode; /* Restore actual mode */ + return ev; + } + a1logd(p->log,2,"Execution time of 4rd dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm); } s->dark_valid = 1; s->want_dcalib = 0; @@ -1686,13 +1704,15 @@ i1pro_code i1pro_imp_calibrate( ss->dark_gain_mode = s->dark_gain_mode; for (k = -1; k < m->nraw; k++) ss->dark_data[k] = s->dark_data[k]; - /* If this is a mode with dark_data2/3, tranfer it too */ - if (usesdct23 && ss->emiss && !ss->adaptive && !ss->scan) { + /* If this is a mode with dark_data2/3/4, tranfer it too */ + if (usesdct234 && ss->emiss && !ss->adaptive && !ss->scan) { ss->dark_int_time2 = s->dark_int_time2; - ss->dark_int_time3 = s->dark_int_time2; + ss->dark_int_time3 = s->dark_int_time3; + ss->dark_int_time4 = s->dark_int_time4; for (k = -1; k < m->nraw; k++) { ss->dark_data2[k] = s->dark_data2[k]; ss->dark_data3[k] = s->dark_data3[k]; + ss->dark_data4[k] = s->dark_data4[k]; } } } @@ -2276,6 +2296,9 @@ i1pro_code i1pro_imp_calibrate( } else if (s->dispswap == 2) { tv = s->inttime; s->inttime = s->dark_int_time3; s->dark_int_time3 = tv; tt = s->dark_data; s->dark_data = s->dark_data3; s->dark_data3 = tt; + } else if (s->dispswap == 3) { + tv = s->inttime; s->inttime = s->dark_int_time4; s->dark_int_time4 = tv; + tt = s->dark_data; s->dark_data = s->dark_data4; s->dark_data4 = tt; } s->dispswap = 0; @@ -2284,30 +2307,43 @@ i1pro_code i1pro_imp_calibrate( nummeas = i1pro_comp_nummeas(p, s->wreadtime, s->inttime); ev = i1pro_whitemeasure(p, NULL, NULL, data , &scale, nummeas, &s->inttime, s->gainmode, s->targoscale, 0); - /* Switch to the alternate if things are too bright */ - /* We do this simply by swapping the alternate values in. */ if (ev == I1PRO_RD_SENSORSATURATED || scale < 1.0) { - a1logd(p->log,2,"Switching to alternate display integration time %f seconds\n",s->dark_int_time2); + a1logd(p->log,2,"Switching to 2nd display integration time %f seconds\n",s->dark_int_time2); + /* swap in 2nd display integration time */ tv = s->inttime; s->inttime = s->dark_int_time2; s->dark_int_time2 = tv; tt = s->dark_data; s->dark_data = s->dark_data2; s->dark_data2 = tt; s->dispswap = 1; /* Do another measurement of the full display white, and if it's close to */ - /* saturation, switch to the 3rd alternate display integration time */ + /* saturation, switch to the 3rd display integration time */ nummeas = i1pro_comp_nummeas(p, s->wreadtime, s->inttime); ev = i1pro_whitemeasure(p, NULL, NULL, data , &scale, nummeas, &s->inttime, s->gainmode, s->targoscale, 0); - /* Switch to the 3rd alternate if things are too bright */ - /* We do this simply by swapping the alternate values in. */ if (ev == I1PRO_RD_SENSORSATURATED || scale < 1.0) { - a1logd(p->log,2,"Switching to 3rd alternate display integration time %f seconds\n",s->dark_int_time3); + a1logd(p->log,2,"Switching to 3rd display integration time %f seconds\n",s->dark_int_time3); /* Undo previous swap */ tv = s->inttime; s->inttime = s->dark_int_time2; s->dark_int_time2 = tv; tt = s->dark_data; s->dark_data = s->dark_data2; s->dark_data2 = tt; - /* swap in 2nd alternate */ + /* swap in 3rd time */ tv = s->inttime; s->inttime = s->dark_int_time3; s->dark_int_time3 = tv; tt = s->dark_data; s->dark_data = s->dark_data3; s->dark_data3 = tt; s->dispswap = 2; + + /* Do another measurement of the full display white, and if it's close to */ + /* saturation, switch to the 4th display integration time */ + nummeas = i1pro_comp_nummeas(p, s->wreadtime, s->inttime); + ev = i1pro_whitemeasure(p, NULL, NULL, data , &scale, nummeas, + &s->inttime, s->gainmode, s->targoscale, 0); + if (ev == I1PRO_RD_SENSORSATURATED || scale < 1.0) { + a1logd(p->log,2,"Switching to 4th display integration time %f seconds\n",s->dark_int_time3); + /* Undo previous swap */ + tv = s->inttime; s->inttime = s->dark_int_time3; s->dark_int_time3 = tv; + tt = s->dark_data; s->dark_data = s->dark_data3; s->dark_data3 = tt; + /* swap in 4th time */ + tv = s->inttime; s->inttime = s->dark_int_time4; s->dark_int_time4 = tv; + tt = s->dark_data; s->dark_data = s->dark_data4; s->dark_data4 = tt; + s->dispswap = 3; + } } } free_dvector(data, -1, m->nraw-1); @@ -2947,16 +2983,16 @@ i1pro_code i1pro_imp_measure( /* and try again. */ if (s->emiss && !s->scan && !s->adaptive && ev == I1PRO_RD_SENSORSATURATED - && s->dispswap < 2) { + && s->dispswap < 3) { double *tt, tv; if (s->dispswap == 0) { - a1logd(p->log,2,"Switching to alternate display integration time %f seconds\n",s->dark_int_time2); + a1logd(p->log,2,"Switching to 2nd display integration time %f seconds\n",s->dark_int_time2); tv = s->inttime; s->inttime = s->dark_int_time2; s->dark_int_time2 = tv; tt = s->dark_data; s->dark_data = s->dark_data2; s->dark_data2 = tt; s->dispswap = 1; } else if (s->dispswap == 1) { - a1logd(p->log,2,"Switching to 2nd alternate display integration time %f seconds\n",s->dark_int_time3); + a1logd(p->log,2,"Switching to 3rd display integration time %f seconds\n",s->dark_int_time3); /* Undo first swap */ tv = s->inttime; s->inttime = s->dark_int_time2; s->dark_int_time2 = tv; tt = s->dark_data; s->dark_data = s->dark_data2; s->dark_data2 = tt; @@ -2964,6 +3000,15 @@ i1pro_code i1pro_imp_measure( tv = s->inttime; s->inttime = s->dark_int_time3; s->dark_int_time3 = tv; tt = s->dark_data; s->dark_data = s->dark_data3; s->dark_data3 = tt; s->dispswap = 2; + } else if (s->dispswap == 2) { + a1logd(p->log,2,"Switching to 4th display integration time %f seconds\n",s->dark_int_time4); + /* Undo 2nd swap */ + tv = s->inttime; s->inttime = s->dark_int_time3; s->dark_int_time3 = tv; + tt = s->dark_data; s->dark_data = s->dark_data3; s->dark_data3 = tt; + /* Do 3rd swap */ + tv = s->inttime; s->inttime = s->dark_int_time4; s->dark_int_time4 = tv; + tt = s->dark_data; s->dark_data = s->dark_data4; s->dark_data4 = tt; + s->dispswap = 3; } /* Recompute number of measurements and realloc measurement buffer */ free(mbuf); @@ -4145,6 +4190,8 @@ i1pro_code i1pro_save_calibration(i1pro *p) { write_doubles(&x, fp, s->dark_data2-1, m->nraw+1); write_doubles(&x, fp, &s->dark_int_time3, 1); write_doubles(&x, fp, s->dark_data3-1, m->nraw+1); + write_doubles(&x, fp, &s->dark_int_time4, 1); + write_doubles(&x, fp, s->dark_data4-1, m->nraw+1); write_ints(&x, fp, &s->dark_gain_mode, 1); if (!s->emiss) { @@ -4288,7 +4335,10 @@ i1pro_code i1pro_restore_calibration(i1pro *p) { read_doubles(&x, fp, &dd, 1); for (j = -1; j < m->nraw; j++) read_doubles(&x, fp, &dd, 1); - read_doubles(&x, fp, &dd, 1); + read_doubles(&x, fp, &dd, 1); /* dark_data3 */ + for (j = -1; j < m->nraw; j++) + read_doubles(&x, fp, &dd, 1); + read_doubles(&x, fp, &dd, 1); /* dark_data4 */ for (j = -1; j < m->nraw; j++) read_doubles(&x, fp, &dd, 1); read_ints(&x, fp, &di, 1); @@ -4338,6 +4388,7 @@ i1pro_code i1pro_restore_calibration(i1pro *p) { ts.dark_data = dvectorz(-1, m->nraw-1); ts.dark_data2 = dvectorz(-1, m->nraw-1); ts.dark_data3 = dvectorz(-1, m->nraw-1); + ts.dark_data4 = dvectorz(-1, m->nraw-1); ts.cal_factor[0] = dvectorz(0, m->nwav[0]-1); ts.cal_factor[1] = dvectorz(0, m->nwav[1]-1); ts.white_data = dvectorz(-1, m->nraw-1); @@ -4384,6 +4435,8 @@ i1pro_code i1pro_restore_calibration(i1pro *p) { read_doubles(&x, fp, ts.dark_data2-1, m->nraw+1); read_doubles(&x, fp, &ts.dark_int_time3, 1); read_doubles(&x, fp, ts.dark_data3-1, m->nraw+1); + read_doubles(&x, fp, &ts.dark_int_time4, 1); + read_doubles(&x, fp, ts.dark_data4-1, m->nraw+1); read_ints(&x, fp, &ts.dark_gain_mode, 1); if (!ts.emiss) { @@ -4419,6 +4472,7 @@ i1pro_code i1pro_restore_calibration(i1pro *p) { && (s->adaptive || fabs(s->dark_int_time - ts.dark_int_time) < 0.01) && (s->adaptive || fabs(s->dark_int_time2 - ts.dark_int_time2) < 0.01) && (s->adaptive || fabs(s->dark_int_time3 - ts.dark_int_time3) < 0.01) + && (s->adaptive || fabs(s->dark_int_time4 - ts.dark_int_time4) < 0.01) && (!s->adaptive || fabs(s->idark_int_time[0] - ts.idark_int_time[0]) < 0.01) && (!s->adaptive || fabs(s->idark_int_time[1] - ts.idark_int_time[1]) < 0.01) && (!s->adaptive || fabs(s->idark_int_time[2] - ts.idark_int_time[2]) < 0.01) @@ -4451,6 +4505,9 @@ i1pro_code i1pro_restore_calibration(i1pro *p) { s->dark_int_time3 = ts.dark_int_time3; for (j = -1; j < m->nraw; j++) s->dark_data3[j] = ts.dark_data3[j]; + s->dark_int_time4 = ts.dark_int_time4; + for (j = -1; j < m->nraw; j++) + s->dark_data4[j] = ts.dark_data4[j]; s->dark_gain_mode = ts.dark_gain_mode; if (!ts.emiss) { s->cal_valid = ts.cal_valid; @@ -4480,7 +4537,7 @@ i1pro_code i1pro_restore_calibration(i1pro *p) { a1logd(p->log,2,"emis = %d : %d, trans = %d : %d, ref = %d : %d\n",s->emiss,ts.emiss,s->trans,ts.trans,s->reflective,ts.reflective); a1logd(p->log,2,"scan = %d : %d, flash = %d : %d, ambi = %d : %d, adapt = %d : %d\n",s->scan,ts.scan,s->flash,ts.flash,s->ambient,ts.ambient,s->adaptive,ts.adaptive); a1logd(p->log,2,"inttime = %f : %f\n",s->inttime,ts.inttime); - a1logd(p->log,2,"darkit1 = %f : %f, 2 = %f : %f, 3 = %f : %f\n",s->dark_int_time,ts.dark_int_time,s->dark_int_time2,ts.dark_int_time2,s->dark_int_time3,ts.dark_int_time3); + a1logd(p->log,2,"darkit1 = %f : %f, 2 = %f : %f, 3 = %f : %f, 4 = %f : %f\n",s->dark_int_time,ts.dark_int_time,s->dark_int_time2,ts.dark_int_time2,s->dark_int_time3,ts.dark_int_time3,s->dark_int_time4,ts.dark_int_time4); a1logd(p->log,2,"idarkit0 = %f : %f, 1 = %f : %f, 2 = %f : %f, 3 = %f : %f\n",s->idark_int_time[0],ts.idark_int_time[0],s->idark_int_time[1],ts.idark_int_time[1],s->idark_int_time[2],ts.idark_int_time[2],s->idark_int_time[3],ts.idark_int_time[3]); } } @@ -4489,6 +4546,7 @@ i1pro_code i1pro_restore_calibration(i1pro *p) { free_dvector(ts.dark_data, -1, m->nraw-1); free_dvector(ts.dark_data2, -1, m->nraw-1); free_dvector(ts.dark_data3, -1, m->nraw-1); + free_dvector(ts.dark_data4, -1, m->nraw-1); free_dvector(ts.white_data, -1, m->nraw-1); free_dmatrix(ts.idark_data, 0, 3, -1, m->nraw-1); @@ -4549,6 +4607,8 @@ i1pro_establish_high_power(i1pro *p) { if ((ev = i1pro_getmisc(p, &m->fwrev, NULL, &m->maxpve, NULL, &m->powmode)) != I1PRO_OK) return ev; + a1logd(p->log,2,"CPLD rev = %d\n",m->cpldrev); + if (m->powmode != 8) { /* In high power mode */ if ((ev = i1pro_reset(p, 0x1f)) != I1PRO_OK) return ev; @@ -10724,14 +10784,14 @@ i1pro_readEEProm( 0xC4, 0, 0, pbuf, len, 2.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_readEEProm: read failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_readEEProm: read failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } /* Now read the bytes */ se = p->icom->usb_read(p->icom, NULL, 0x82, buf, size, &rwbytes, 5.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_readEEProm: read failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_readEEProm: read failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } @@ -10812,7 +10872,7 @@ i1pro_writeEEProm( 0xC3, 0, 0, pbuf, len, 2.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,2,"i1pro_writeEEProm: write failed with ICOM err 0x%x\n",se); + a1logd(p->log,2,"i1pro_writeEEProm: write failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } @@ -10820,7 +10880,7 @@ i1pro_writeEEProm( se = p->icom->usb_write(p->icom, NULL, 0x03, buf, size, &rwbytes, 5.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_writeEEProm: failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_writeEEProm: failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } @@ -10837,7 +10897,7 @@ i1pro_writeEEProm( se = p->icom->usb_write(p->icom, NULL, 0x03, pbuf, 1, &rwbytes, 5.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_writeEEProm: write failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_writeEEProm: write failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } @@ -10889,7 +10949,7 @@ i1pro_getmisc( 0xC9, 0, 0, pbuf, 8, 2.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_getmisc: failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_getmisc: failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } @@ -10937,7 +10997,7 @@ i1pro_getmeasparams( 0xC2, 0, 0, pbuf, 8, 2.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_getmeasparams: failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_getmeasparams: failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } @@ -11002,7 +11062,7 @@ i1pro_setmeasparams( 0xC1, 0, 0, pbuf, 8, 2.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_setmeasparams: failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_setmeasparams: failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } @@ -11318,10 +11378,13 @@ i1pro_setmcmode( 0xCF, 0, 0, pbuf, 1, 2.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_setmcmode: failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_setmcmode: failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } + /* Hmm. Give the instrument a little time to reconfigure itself. */ + msec_sleep(10); + a1logd(p->log,2,"i1pro_setmcmode: done, ICOM err 0x%x (%d msec)\n", se, msec_time()-stime); return rv; @@ -11358,7 +11421,7 @@ i1pro_getmcmode( 0xD1, 0, 0, pbuf, 6, 2.0); if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_getmcmode: failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_getmcmode: failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } @@ -11403,7 +11466,7 @@ i1pro_code i1pro_waitfor_switch(i1pro *p, double top) { } if ((rv = icoms2i1pro_err(se)) != I1PRO_OK) { - a1logd(p->log,1,"i1pro_waitfor_switch: failed with ICOM err 0x%x\n",se); + a1logd(p->log,1,"i1pro_waitfor_switch: failed with ICOM err 0x%x (%d msec)\n",se, msec_time()-stime); return rv; } diff --git a/spectro/i1pro_imp.h b/spectro/i1pro_imp.h index 6bf8de4..5a2cef2 100644 --- a/spectro/i1pro_imp.h +++ b/spectro/i1pro_imp.h @@ -127,6 +127,7 @@ struct _i1pro_state { /* Display mode calibration state (emmis && !scan && !adaptive) */ int dispswap; /* 0 = default time, 1 = dark_int_time2, 2 = dark_int_time3 */ + /* 3 = dark_int_time4 */ double done_dintsel; /* A display integration time selection has been done */ time_t diseldate; /* Date/time of last display integration time selection */ double dcaltime2; /* Target dark calibration time - sets number of readings */ @@ -135,6 +136,9 @@ struct _i1pro_state { double dcaltime3; /* Target dark calibration time - sets number of readings */ double dark_int_time3; /* Integration time used for dark data 3 */ double *dark_data3; /* [-1 nraw] of dark level to subtract for dark_int_time3. */ + double dcaltime4; /* Target dark calibration time - sets number of readings */ + double dark_int_time4; /* Integration time used for dark data 4 */ + double *dark_data4; /* [-1 nraw] of dark level to subtract for dark_int_time4. */ }; typedef struct _i1pro_state i1pro_state; @@ -200,8 +204,8 @@ struct _i1proimp { /* Values read from GetMisc() */ int fwrev; /* int - Firmware revision number, from getmisc() */ /* Used for internal switching ?? */ - /* 101 = Rev A, 202 = Rev A update, 302 = Rev B, 502 = Rev D */ - /* 629 = Rev E (i1pro2) */ + /* 101 = Rev A, 202 = Rev A update, 302 = Rev B, */ + /* 502, 505, 631 = Rev D, 629 = Rev E (i1pro2) */ int cpldrev; /* int - CPLD revision number in EEProm */ /* Not used internaly ???? */ diff --git a/spectro/inst.c b/spectro/inst.c index 949e34f..8976669 100644 --- a/spectro/inst.c +++ b/spectro/inst.c @@ -581,6 +581,18 @@ static inst_config config_enum(inst *p, int ec) { } /* ---------------------------------------------- */ + +/* Delete things set/done by new_inst() */ +static inst_code virtual_del(inst *p) { + +#if defined(__APPLE__) + osx_latencycritical_end(); +#endif + + return inst_ok; +} + + /* Virtual constructor. */ /* Return NULL for unknown instrument, */ /* or serial instrument if nocoms == 0. */ @@ -702,6 +714,8 @@ void *cntx /* Context for callback */ return NULL; } + p->vdel = virtual_del; + /* Add default methods if constructor did not supply them */ if (p->init_coms == NULL) p->init_coms = init_coms; @@ -785,6 +799,10 @@ void *cntx /* Context for callback */ /* Set the provided user interaction callback */ p->set_uicallback(p, uicallback, cntx); +#if defined(__APPLE__) + osx_latencycritical_start(); +#endif + return p; } diff --git a/spectro/inst.h b/spectro/inst.h index d47f7ea..736a879 100644 --- a/spectro/inst.h +++ b/spectro/inst.h @@ -643,6 +643,10 @@ typedef enum { void (*eventcallback)(void *cntx, inst_event_type event); \ void *event_cntx; /* Event callback function */ \ \ + /* Virtual delete. Cleans up things done by new_inst(). */ \ + inst_code (*vdel)( \ + struct _inst *p); \ + \ /* Establish communications at the indicated baud rate. */ \ /* (Serial parameters are ignored for USB instrument) */ \ /* Timout in to seconds, and return non-zero error code */ \ diff --git a/spectro/instappsup.c b/spectro/instappsup.c index 0762bbe..d2ce7ff 100644 --- a/spectro/instappsup.c +++ b/spectro/instappsup.c @@ -401,7 +401,7 @@ inst_code inst_handle_calibrate( printf("\n"); /* If optional calib. and user wants to skip it */ /* Loop back to calibrate() with inst_calc_optional_flag still set */ - if ((calc & inst_calc_optional_flag) != 0 && ch == 's' || ch == 'S') { + if ((calc & inst_calc_optional_flag) != 0 && (ch == 's' || ch == 'S')) { printf("Skipped\n"); goto oloop; } diff --git a/spectro/kleink10.c b/spectro/kleink10.c index 461cb28..9599972 100644 --- a/spectro/kleink10.c +++ b/spectro/kleink10.c @@ -62,7 +62,7 @@ #undef HIGH_SPEED /* [und] Use high speed flicker measure for refresh rate etc. */ #define AUTO_AVERAGE /* [def] Automatically average more readings for low light */ -#define RETRY_RANGE_ERROR 3 /* [3] Retry range error readings 3 times */ +#define RETRY_RANGE_ERROR 4 /* [4] Retry range error readings 4 times */ #undef PLOT_REFRESH /* [und] Plot refresh rate measurement info */ #undef PLOT_UPDELAY /* [und] Plot update delay measurement info */ @@ -81,6 +81,7 @@ static inst_code k10_read_flicker_samples(kleink10 *p, double duration, double * /* Decode a K10 error letter */ static int decodeK10err(char c) { +//printf("~1 decoding error code 0x%x\n",c); if (c == '0') { return K10_OK; } else if (c == 'B') { @@ -125,28 +126,34 @@ extract_ec(char *s, int *nlength, int bread) { if (*p == '>') break; } - if (p < s) + if (p < s) { +//printf("p %d < s %d ? %d\n", p, s, p < s); return K10_BAD_RETVAL; + } //printf("trailing is at %d '%s'\n",p - s, p); /* Find the leading '<' */ for (f = p-1; f >= (p-MAXECHARS-1) && f >= s; f--) { if (*f == '<') break; + /* Turns out the error code may be non-text */ +#ifdef NEVER if ((*f < '0' || *f > '9') && (*f < 'a' || *f > 'z') && (*f < 'A' || *f > 'Z')) return K10_BAD_RETVAL; +#endif /* NEVER */ } if (f < s || f < (p-MAXECHARS-1) || (p-f) <= 1) { -//printf("f < s ? %d, f < (p-MAXECHARS-1) ? %d, (p-f) <= 1 ? %d\n", -//f < s, f < (p-10), (p-f) <= 1); +//printf("f < s ? %d, f < (p-MAXECHARS-1) ? %d, (p-f) <= 1 ? %d\n", f < s, f < (p-10), (p-f) <= 1); return K10_BAD_RETVAL; } //printf("leading is at %d '%s'\n",f - s, f); - if (p-f-1 <= 0) + if (p-f-1 <= 0) { +//printf("p-f-1 %d <= 0 ? %d\n", p-f-1, p-f-1 <= 0); return K10_BAD_RETVAL; + } strncpy(tt, f+1, p-f-1); tt[p-f-1] = '\000'; @@ -155,7 +162,7 @@ extract_ec(char *s, int *nlength, int bread) { /* Interpret the error character(s) */ /* It's not clear if more than one error can be returned. */ /* We are only looking at the first character - we should */ - /* really prioritize them id more than one can occur. */ + /* really prioritize them if more than one can occur. */ for (p = tt; *p != '\000'; p++) { rv = decodeK10err(*p); break; @@ -467,7 +474,15 @@ k10_init_inst(inst *pp) { amutex_lock(p->lock); /* Make sure the target lights are off */ - if ((ev = k10_command(p, "L0\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 1.0)) != inst_ok) { + if ((ev = k10_command(p, "L0\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 1.0)) != inst_ok + /* Strangely the L0/1 command mat return irrelevant error codes... */ + && (ev & inst_imask) != K10_UNKNOWN + && (ev & inst_imask) != K10_BLACK_EXCESS + && (ev & inst_imask) != K10_BLACK_OVERDRIVE + && (ev & inst_imask) != K10_BLACK_ZERO + && (ev & inst_imask) != K10_OVER_HIGH_RANGE + && (ev & inst_imask) != K10_TOP_OVER_RANGE + && (ev & inst_imask) != K10_BOT_UNDER_RANGE) { amutex_unlock(p->lock); return ev; } @@ -510,14 +525,20 @@ k10_init_inst(inst *pp) { if (p->log->verb) { char *model = "Unknown"; switch (p->model) { + case k10_k1: + model = "K-1"; + break; + case k10_k8: + model = "K-8"; + break; case k10_k10: - model = "K10"; + model = "K-10"; break; case k10_k10a: - model = "K10-A"; + model = "K-10A"; break; case k10_kv10a: - model = "KV10-A"; + model = "KV-10A"; break; } a1logv(p->log, 1, " Model: '%s'\n",model); @@ -886,7 +907,7 @@ kleink10 *p) { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -static abort_flicker(kleink10 *p, int isnew, double *retbuf) { +static void abort_flicker(kleink10 *p, int isnew, double *retbuf) { char buf[MAX_MES_SIZE]; int bread; @@ -976,7 +997,15 @@ int usefast /* If nz use fast rate is possible */ /* Make sure the target lights are off */ if (p->lights) { int se; - if ((ev = k10_command(p, "L0\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 0.5)) != inst_ok) { + if ((ev = k10_command(p, "L0\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 0.5)) != inst_ok + /* Strangely the L0/1 command mat return irrelevant error codes... */ + && (ev & inst_imask) != K10_UNKNOWN + && (ev & inst_imask) != K10_BLACK_EXCESS + && (ev & inst_imask) != K10_BLACK_OVERDRIVE + && (ev & inst_imask) != K10_BLACK_ZERO + && (ev & inst_imask) != K10_OVER_HIGH_RANGE + && (ev & inst_imask) != K10_TOP_OVER_RANGE + && (ev & inst_imask) != K10_BOT_UNDER_RANGE) { amutex_unlock(p->lock); free(retbuf); a1logd(p->log, 1, "k10_read_flicker: L0 failed\n"); @@ -1182,9 +1211,9 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */ int user_trig = 0; int bsize; inst_code rv = inst_protocol_error; - int range[3]; /* Range for RGB sensor values */ - int i, tries,ntav = 1; /* Number of readings to average */ - double v, vv, XYZ[3]; + int range[3]; /* Range for RGB sensor values */ + int i, tries, ntav = 1; /* Number of readings to average */ + double v, vv; if (!p->gotcoms) return inst_no_coms; @@ -1230,7 +1259,15 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */ /* Make sure the target lights are off */ if (p->lights) { - if ((rv = k10_command(p, "L0\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 1.0)) != inst_ok) { + if ((rv = k10_command(p, "L0\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 1.0)) != inst_ok + /* Strangely the L0/1 command mat return irrelevant error codes... */ + && (rv & inst_imask) != K10_UNKNOWN + && (rv & inst_imask) != K10_BLACK_EXCESS + && (rv & inst_imask) != K10_BLACK_OVERDRIVE + && (rv & inst_imask) != K10_BLACK_ZERO + && (rv & inst_imask) != K10_OVER_HIGH_RANGE + && (rv & inst_imask) != K10_TOP_OVER_RANGE + && (rv & inst_imask) != K10_BOT_UNDER_RANGE) { amutex_unlock(p->lock); a1logd(p->log, 1, "k10_read_sample: L0 failed\n"); return rv; @@ -1256,7 +1293,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */ if (rv == inst_ok || ( (rv & inst_imask) != K10_TOP_OVER_RANGE && (rv & inst_imask) != K10_BOT_UNDER_RANGE)) - break; + break; } if (rv == inst_ok) @@ -1273,7 +1310,6 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */ if (val->XYZ[2] > v) v = val->XYZ[2]; - ntav = 1; #ifdef AUTO_AVERAGE if (!IMODETST(p->mode, inst_mode_emis_nonadaptive)) { /* Decide how many extra readings to average into result. */ @@ -1292,13 +1328,26 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */ vv = 1.0 - (v - thr[2]) / (thr[3] - thr[2]); vv = vv * vv * vv; ntav = (int)(vv * (nav[2] - nav[3]) + nav[3] + 0.5); - } + } /* else default 1 */ } #endif + /* Measure extras up to ntav */ for (i = 1; i < ntav; i++) { - if ((rv = k10_command(p, "N5\r", buf, MAX_MES_SIZE, &bsize, 15, ec_ec, 2.0)) != inst_ok) + double XYZ[3]; + + for (tries = 0; tries < RETRY_RANGE_ERROR; tries++) { + rv = k10_command(p, "N5\r", buf, MAX_MES_SIZE, &bsize, 15, ec_ec, 2.0); + if (rv == inst_ok + || ( (rv & inst_imask) != K10_TOP_OVER_RANGE + && (rv & inst_imask) != K10_BOT_UNDER_RANGE)) + break; + } + + if (rv != inst_ok) { // An error, or retry failed break; + } + if ((rv = decodeN5(p, XYZ, range, buf, bsize)) != inst_ok) break; @@ -1321,10 +1370,6 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */ amutex_unlock(p->lock); - if ((rv = decodeN5(p, val->XYZ, range, buf, bsize)) != inst_ok) { - return rv; - } - /* Apply the calibration correction matrix */ icmMulBy3x3(val->XYZ, p->ccmat, val->XYZ); @@ -2396,6 +2441,7 @@ k10_del(inst *pp) { if (p->icom != NULL) p->icom->del(p->icom); amutex_del(p->lock); + p->vdel(pp); free(p); } } @@ -2741,14 +2787,30 @@ k10_get_set_opt(inst *pp, inst_opt_type m, ...) } if (state == 1) { /* Turn on */ - if ((ev = k10_command(p, "L1\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 0.5)) != inst_ok) { + if ((ev = k10_command(p, "L1\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 0.5)) != inst_ok + /* Strangely the L0/1 command mat return irrelevant error codes... */ + && (ev & inst_imask) != K10_UNKNOWN + && (ev & inst_imask) != K10_BLACK_EXCESS + && (ev & inst_imask) != K10_BLACK_OVERDRIVE + && (ev & inst_imask) != K10_BLACK_ZERO + && (ev & inst_imask) != K10_OVER_HIGH_RANGE + && (ev & inst_imask) != K10_TOP_OVER_RANGE + && (ev & inst_imask) != K10_BOT_UNDER_RANGE) { amutex_unlock(p->lock); a1logd(p->log, 1, "k10_get_set_opt: L1 failed\n"); return ev; } p->lights = 1; } else if (state == 0) { /* Turn off */ - if ((ev = k10_command(p, "L0\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 0.5)) != inst_ok) { + if ((ev = k10_command(p, "L0\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 0.5)) != inst_ok + /* Strangely the L0/1 command mat return irrelevant error codes... */ + && (ev & inst_imask) != K10_UNKNOWN + && (ev & inst_imask) != K10_BLACK_EXCESS + && (ev & inst_imask) != K10_BLACK_OVERDRIVE + && (ev & inst_imask) != K10_BLACK_ZERO + && (ev & inst_imask) != K10_OVER_HIGH_RANGE + && (ev & inst_imask) != K10_TOP_OVER_RANGE + && (ev & inst_imask) != K10_BOT_UNDER_RANGE) { amutex_unlock(p->lock); a1logd(p->log, 1, "k10_get_set_opt: L0 failed\n"); return ev; diff --git a/spectro/linear.cal b/spectro/linear.cal new file mode 100644 index 0000000..9c88605 --- /dev/null +++ b/spectro/linear.cal @@ -0,0 +1,272 @@ +CAL + +DESCRIPTOR "Argyll Device Calibration Curves" +ORIGINATOR "Argyll synthcal" +CREATED "Mon Oct 26 01:10:48 2015" +DEVICE_CLASS "DISPLAY" +COLOR_REP "RGB" + +NUMBER_OF_FIELDS 4 +BEGIN_DATA_FORMAT +RGB_I RGB_R RGB_G RGB_B +END_DATA_FORMAT + +NUMBER_OF_SETS 256 +BEGIN_DATA +0.00000 0.00000 0.00000 0.00000 +0.00392157 0.00392157 0.00392157 0.00392157 +0.00784314 0.00784314 0.00784314 0.00784314 +0.0117647 0.0117647 0.0117647 0.0117647 +0.0156863 0.0156863 0.0156863 0.0156863 +0.0196078 0.0196078 0.0196078 0.0196078 +0.0235294 0.0235294 0.0235294 0.0235294 +0.0274510 0.0274510 0.0274510 0.0274510 +0.0313725 0.0313725 0.0313725 0.0313725 +0.0352941 0.0352941 0.0352941 0.0352941 +0.0392157 0.0392157 0.0392157 0.0392157 +0.0431373 0.0431373 0.0431373 0.0431373 +0.0470588 0.0470588 0.0470588 0.0470588 +0.0509804 0.0509804 0.0509804 0.0509804 +0.0549020 0.0549020 0.0549020 0.0549020 +0.0588235 0.0588235 0.0588235 0.0588235 +0.0627451 0.0627451 0.0627451 0.0627451 +0.0666667 0.0666667 0.0666667 0.0666667 +0.0705882 0.0705882 0.0705882 0.0705882 +0.0745098 0.0745098 0.0745098 0.0745098 +0.0784314 0.0784314 0.0784314 0.0784314 +0.0823529 0.0823529 0.0823529 0.0823529 +0.0862745 0.0862745 0.0862745 0.0862745 +0.0901961 0.0901961 0.0901961 0.0901961 +0.0941176 0.0941176 0.0941176 0.0941176 +0.0980392 0.0980392 0.0980392 0.0980392 +0.101961 0.101961 0.101961 0.101961 +0.105882 0.105882 0.105882 0.105882 +0.109804 0.109804 0.109804 0.109804 +0.113725 0.113725 0.113725 0.113725 +0.117647 0.117647 0.117647 0.117647 +0.121569 0.121569 0.121569 0.121569 +0.125490 0.125490 0.125490 0.125490 +0.129412 0.129412 0.129412 0.129412 +0.133333 0.133333 0.133333 0.133333 +0.137255 0.137255 0.137255 0.137255 +0.141176 0.141176 0.141176 0.141176 +0.145098 0.145098 0.145098 0.145098 +0.149020 0.149020 0.149020 0.149020 +0.152941 0.152941 0.152941 0.152941 +0.156863 0.156863 0.156863 0.156863 +0.160784 0.160784 0.160784 0.160784 +0.164706 0.164706 0.164706 0.164706 +0.168627 0.168627 0.168627 0.168627 +0.172549 0.172549 0.172549 0.172549 +0.176471 0.176471 0.176471 0.176471 +0.180392 0.180392 0.180392 0.180392 +0.184314 0.184314 0.184314 0.184314 +0.188235 0.188235 0.188235 0.188235 +0.192157 0.192157 0.192157 0.192157 +0.196078 0.196078 0.196078 0.196078 +0.200000 0.200000 0.200000 0.200000 +0.203922 0.203922 0.203922 0.203922 +0.207843 0.207843 0.207843 0.207843 +0.211765 0.211765 0.211765 0.211765 +0.215686 0.215686 0.215686 0.215686 +0.219608 0.219608 0.219608 0.219608 +0.223529 0.223529 0.223529 0.223529 +0.227451 0.227451 0.227451 0.227451 +0.231373 0.231373 0.231373 0.231373 +0.235294 0.235294 0.235294 0.235294 +0.239216 0.239216 0.239216 0.239216 +0.243137 0.243137 0.243137 0.243137 +0.247059 0.247059 0.247059 0.247059 +0.250980 0.250980 0.250980 0.250980 +0.254902 0.254902 0.254902 0.254902 +0.258824 0.258824 0.258824 0.258824 +0.262745 0.262745 0.262745 0.262745 +0.266667 0.266667 0.266667 0.266667 +0.270588 0.270588 0.270588 0.270588 +0.274510 0.274510 0.274510 0.274510 +0.278431 0.278431 0.278431 0.278431 +0.282353 0.282353 0.282353 0.282353 +0.286275 0.286275 0.286275 0.286275 +0.290196 0.290196 0.290196 0.290196 +0.294118 0.294118 0.294118 0.294118 +0.298039 0.298039 0.298039 0.298039 +0.301961 0.301961 0.301961 0.301961 +0.305882 0.305882 0.305882 0.305882 +0.309804 0.309804 0.309804 0.309804 +0.313725 0.313725 0.313725 0.313725 +0.317647 0.317647 0.317647 0.317647 +0.321569 0.321569 0.321569 0.321569 +0.325490 0.325490 0.325490 0.325490 +0.329412 0.329412 0.329412 0.329412 +0.333333 0.333333 0.333333 0.333333 +0.337255 0.337255 0.337255 0.337255 +0.341176 0.341176 0.341176 0.341176 +0.345098 0.345098 0.345098 0.345098 +0.349020 0.349020 0.349020 0.349020 +0.352941 0.352941 0.352941 0.352941 +0.356863 0.356863 0.356863 0.356863 +0.360784 0.360784 0.360784 0.360784 +0.364706 0.364706 0.364706 0.364706 +0.368627 0.368627 0.368627 0.368627 +0.372549 0.372549 0.372549 0.372549 +0.376471 0.376471 0.376471 0.376471 +0.380392 0.380392 0.380392 0.380392 +0.384314 0.384314 0.384314 0.384314 +0.388235 0.388235 0.388235 0.388235 +0.392157 0.392157 0.392157 0.392157 +0.396078 0.396078 0.396078 0.396078 +0.400000 0.400000 0.400000 0.400000 +0.403922 0.403922 0.403922 0.403922 +0.407843 0.407843 0.407843 0.407843 +0.411765 0.411765 0.411765 0.411765 +0.415686 0.415686 0.415686 0.415686 +0.419608 0.419608 0.419608 0.419608 +0.423529 0.423529 0.423529 0.423529 +0.427451 0.427451 0.427451 0.427451 +0.431373 0.431373 0.431373 0.431373 +0.435294 0.435294 0.435294 0.435294 +0.439216 0.439216 0.439216 0.439216 +0.443137 0.443137 0.443137 0.443137 +0.447059 0.447059 0.447059 0.447059 +0.450980 0.450980 0.450980 0.450980 +0.454902 0.454902 0.454902 0.454902 +0.458824 0.458824 0.458824 0.458824 +0.462745 0.462745 0.462745 0.462745 +0.466667 0.466667 0.466667 0.466667 +0.470588 0.470588 0.470588 0.470588 +0.474510 0.474510 0.474510 0.474510 +0.478431 0.478431 0.478431 0.478431 +0.482353 0.482353 0.482353 0.482353 +0.486275 0.486275 0.486275 0.486275 +0.490196 0.490196 0.490196 0.490196 +0.494118 0.494118 0.494118 0.494118 +0.498039 0.498039 0.498039 0.498039 +0.501961 0.501961 0.501961 0.501961 +0.505882 0.505882 0.505882 0.505882 +0.509804 0.509804 0.509804 0.509804 +0.513725 0.513725 0.513725 0.513725 +0.517647 0.517647 0.517647 0.517647 +0.521569 0.521569 0.521569 0.521569 +0.525490 0.525490 0.525490 0.525490 +0.529412 0.529412 0.529412 0.529412 +0.533333 0.533333 0.533333 0.533333 +0.537255 0.537255 0.537255 0.537255 +0.541176 0.541176 0.541176 0.541176 +0.545098 0.545098 0.545098 0.545098 +0.549020 0.549020 0.549020 0.549020 +0.552941 0.552941 0.552941 0.552941 +0.556863 0.556863 0.556863 0.556863 +0.560784 0.560784 0.560784 0.560784 +0.564706 0.564706 0.564706 0.564706 +0.568627 0.568627 0.568627 0.568627 +0.572549 0.572549 0.572549 0.572549 +0.576471 0.576471 0.576471 0.576471 +0.580392 0.580392 0.580392 0.580392 +0.584314 0.584314 0.584314 0.584314 +0.588235 0.588235 0.588235 0.588235 +0.592157 0.592157 0.592157 0.592157 +0.596078 0.596078 0.596078 0.596078 +0.600000 0.600000 0.600000 0.600000 +0.603922 0.603922 0.603922 0.603922 +0.607843 0.607843 0.607843 0.607843 +0.611765 0.611765 0.611765 0.611765 +0.615686 0.615686 0.615686 0.615686 +0.619608 0.619608 0.619608 0.619608 +0.623529 0.623529 0.623529 0.623529 +0.627451 0.627451 0.627451 0.627451 +0.631373 0.631373 0.631373 0.631373 +0.635294 0.635294 0.635294 0.635294 +0.639216 0.639216 0.639216 0.639216 +0.643137 0.643137 0.643137 0.643137 +0.647059 0.647059 0.647059 0.647059 +0.650980 0.650980 0.650980 0.650980 +0.654902 0.654902 0.654902 0.654902 +0.658824 0.658824 0.658824 0.658824 +0.662745 0.662745 0.662745 0.662745 +0.666667 0.666667 0.666667 0.666667 +0.670588 0.670588 0.670588 0.670588 +0.674510 0.674510 0.674510 0.674510 +0.678431 0.678431 0.678431 0.678431 +0.682353 0.682353 0.682353 0.682353 +0.686275 0.686275 0.686275 0.686275 +0.690196 0.690196 0.690196 0.690196 +0.694118 0.694118 0.694118 0.694118 +0.698039 0.698039 0.698039 0.698039 +0.701961 0.701961 0.701961 0.701961 +0.705882 0.705882 0.705882 0.705882 +0.709804 0.709804 0.709804 0.709804 +0.713725 0.713725 0.713725 0.713725 +0.717647 0.717647 0.717647 0.717647 +0.721569 0.721569 0.721569 0.721569 +0.725490 0.725490 0.725490 0.725490 +0.729412 0.729412 0.729412 0.729412 +0.733333 0.733333 0.733333 0.733333 +0.737255 0.737255 0.737255 0.737255 +0.741176 0.741176 0.741176 0.741176 +0.745098 0.745098 0.745098 0.745098 +0.749020 0.749020 0.749020 0.749020 +0.752941 0.752941 0.752941 0.752941 +0.756863 0.756863 0.756863 0.756863 +0.760784 0.760784 0.760784 0.760784 +0.764706 0.764706 0.764706 0.764706 +0.768627 0.768627 0.768627 0.768627 +0.772549 0.772549 0.772549 0.772549 +0.776471 0.776471 0.776471 0.776471 +0.780392 0.780392 0.780392 0.780392 +0.784314 0.784314 0.784314 0.784314 +0.788235 0.788235 0.788235 0.788235 +0.792157 0.792157 0.792157 0.792157 +0.796078 0.796078 0.796078 0.796078 +0.800000 0.800000 0.800000 0.800000 +0.803922 0.803922 0.803922 0.803922 +0.807843 0.807843 0.807843 0.807843 +0.811765 0.811765 0.811765 0.811765 +0.815686 0.815686 0.815686 0.815686 +0.819608 0.819608 0.819608 0.819608 +0.823529 0.823529 0.823529 0.823529 +0.827451 0.827451 0.827451 0.827451 +0.831373 0.831373 0.831373 0.831373 +0.835294 0.835294 0.835294 0.835294 +0.839216 0.839216 0.839216 0.839216 +0.843137 0.843137 0.843137 0.843137 +0.847059 0.847059 0.847059 0.847059 +0.850980 0.850980 0.850980 0.850980 +0.854902 0.854902 0.854902 0.854902 +0.858824 0.858824 0.858824 0.858824 +0.862745 0.862745 0.862745 0.862745 +0.866667 0.866667 0.866667 0.866667 +0.870588 0.870588 0.870588 0.870588 +0.874510 0.874510 0.874510 0.874510 +0.878431 0.878431 0.878431 0.878431 +0.882353 0.882353 0.882353 0.882353 +0.886275 0.886275 0.886275 0.886275 +0.890196 0.890196 0.890196 0.890196 +0.894118 0.894118 0.894118 0.894118 +0.898039 0.898039 0.898039 0.898039 +0.901961 0.901961 0.901961 0.901961 +0.905882 0.905882 0.905882 0.905882 +0.909804 0.909804 0.909804 0.909804 +0.913725 0.913725 0.913725 0.913725 +0.917647 0.917647 0.917647 0.917647 +0.921569 0.921569 0.921569 0.921569 +0.925490 0.925490 0.925490 0.925490 +0.929412 0.929412 0.929412 0.929412 +0.933333 0.933333 0.933333 0.933333 +0.937255 0.937255 0.937255 0.937255 +0.941176 0.941176 0.941176 0.941176 +0.945098 0.945098 0.945098 0.945098 +0.949020 0.949020 0.949020 0.949020 +0.952941 0.952941 0.952941 0.952941 +0.956863 0.956863 0.956863 0.956863 +0.960784 0.960784 0.960784 0.960784 +0.964706 0.964706 0.964706 0.964706 +0.968627 0.968627 0.968627 0.968627 +0.972549 0.972549 0.972549 0.972549 +0.976471 0.976471 0.976471 0.976471 +0.980392 0.980392 0.980392 0.980392 +0.984314 0.984314 0.984314 0.984314 +0.988235 0.988235 0.988235 0.988235 +0.992157 0.992157 0.992157 0.992157 +0.996078 0.996078 0.996078 0.996078 +1.000000 1.000000 1.000000 1.000000 +END_DATA diff --git a/spectro/munki.c b/spectro/munki.c index 57f5ce8..df54cd9 100644 --- a/spectro/munki.c +++ b/spectro/munki.c @@ -66,7 +66,7 @@ static inst_code munki_interp_code(munki *p, munki_code ec); /* Establish communications with a Munki */ /* If it's a serial port, use the baud rate given, and timeout in to secs */ -/* Return DTP_COMS_FAIL on failure to establish communications */ +/* Return MUNKI_COMS_FAIL on failure to establish communications */ static inst_code munki_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { munki *p = (munki *) pp; @@ -937,6 +937,7 @@ munki_del(inst *pp) { del_munkiimp(p); if (p->icom != NULL) p->icom->del(p->icom); + p->vdel(pp); free(p); } diff --git a/spectro/rspec.c b/spectro/rspec.c index 49d725b..e0e0194 100644 --- a/spectro/rspec.c +++ b/spectro/rspec.c @@ -43,6 +43,7 @@ #include "sa_config.h" #include "numsup.h" #endif /* !SALONEINSTLIB */ +#include "plot.h" #include "xspect.h" #include "insttypes.h" #include "conv.h" @@ -152,9 +153,6 @@ double rspec_raw2nm(rspec_inf *inf, double rix) { if (inf->nwlcal == 0) error("rspec_raw2nm: nwlcal == 0"); -// ~~~~9999 test fudge -// rix += 15; - /* Compute polinomial */ for (wl = inf->wlcal[inf->nwlcal-1], k = inf->nwlcal-2; k >= 0; k--) wl = wl * rix + inf->wlcal[k]; diff --git a/spectro/rspec.h b/spectro/rspec.h index bc5d427..0cbee58 100644 --- a/spectro/rspec.h +++ b/spectro/rspec.h @@ -33,12 +33,12 @@ /* - - - - - - - - - - - - - */ /* Collection of raw samples */ typedef enum { - rspec_sensor, /* Includes shielded/temperaturee values */ + rspec_sensor, /* Includes shielded/temperature values */ rspec_raw, /* Potential light values */ rspec_wav /* Valid wavelength values */ } rspec_type; -/* The order the state is changed in is device workflow dependent */ +/* The order the state is changed in, is device workflow dependent */ typedef enum { rspec_none = 0x0000, /* No processing */ rspec_shld = 0x0002, /* Shielded cell corrected */ @@ -136,7 +136,7 @@ struct _rspec_inf { /* Completely clear an rspec_inf. */ void clear_rspec_inf(rspec_inf *inf); -/* Completely free contesnt of rspec_inf. */ +/* Completely free contents of rspec_inf. */ void free_rspec_inf(rspec_inf *inf); /* return the number of samples for the given spectral type */ diff --git a/spectro/smcube.c b/spectro/smcube.c index 1618447..8a788ec 100644 --- a/spectro/smcube.c +++ b/spectro/smcube.c @@ -140,6 +140,12 @@ static inst_code smcube_measure(smcube *p, double *XYZ); static void cube_rgb2XYZ(double *xyz, double *irgb); +int static smcube_save_calibration(smcube *p); +int static smcube_touch_calibration(smcube *p); +int static smcube_restore_calibration(smcube *p); + +/* ------------------------------------------------- */ + /* Do a full command/response echange with the smcube */ /* (This level is not multi-thread safe) */ /* Return the smcube error code. */ @@ -849,6 +855,7 @@ smcube_del(inst *pp) { if (p->icom != NULL) p->icom->del(p->icom); amutex_del(p->lock); + p->vdel(pp); free(p); } } @@ -2009,7 +2016,7 @@ static void cube_rgb2XYZ(double *xyz, double *irgb) { /* The cube doesn't have an easily accessible serial number :-( */ /* So if you have more than one, you'll be sharing the same calibration !! */ -int smcube_save_calibration(smcube *p) { +int static smcube_save_calibration(smcube *p) { int ev = SMCUBE_OK; int i; char fname[100]; /* Name */ @@ -2067,7 +2074,7 @@ int smcube_save_calibration(smcube *p) { } /* Restore the all modes calibration from the local system */ -int smcube_restore_calibration(smcube *p) { +int static smcube_restore_calibration(smcube *p) { int ev = SMCUBE_OK; int i, j; char fname[100]; /* Name */ @@ -2169,7 +2176,7 @@ int smcube_restore_calibration(smcube *p) { return ev; } -int smcube_touch_calibration(smcube *p) { +int static smcube_touch_calibration(smcube *p) { int ev = SMCUBE_OK; char fname[100]; /* Name */ int rv; diff --git a/spectro/spec2cie.c b/spectro/spec2cie.c index aa91ebb..322ab05 100644 --- a/spectro/spec2cie.c +++ b/spectro/spec2cie.c @@ -389,7 +389,7 @@ main(int argc, char *argv[]) if (illum == icxIT_none) illum = icxIT_D50; - if (observ = icxOT_none) + if (observ == icxOT_none) observ = icxOT_CIE_1931_2; /* Figure out what sort of device it is */ diff --git a/spectro/specbos.c b/spectro/specbos.c index e819c06..491fe97 100644 --- a/spectro/specbos.c +++ b/spectro/specbos.c @@ -1434,6 +1434,7 @@ specbos_del(inst *pp) { if (p->icom != NULL) p->icom->del(p->icom); amutex_del(p->lock); + p->vdel(pp); free(p); } } diff --git a/spectro/spyd2.c b/spectro/spyd2.c index b546f6b..6833e89 100644 --- a/spectro/spyd2.c +++ b/spectro/spyd2.c @@ -642,12 +642,13 @@ spyd2_GetReading_ll( int value; int index; int flag; - int nords, retr; + int retr; unsigned char buf1[8]; /* send bytes */ unsigned char buf2[9 * 8]; /* return bytes read */ int rvals[3][8]; /* Raw values */ int _maxtcnt = 0; /* Maximum transition count */ int _mintcnt = 0x7fffffff; /* Minumum transition count */ + double maxfreq = 0.0; /* Maximum sensor frequency found */ int i, j, k; a1logd(p->log, 3, "spyd2_GetReading_ll: clocks = %d, minfc = %d, maxfc = %d\n",*clocks,*minfclks,*maxfclks); @@ -691,7 +692,7 @@ spyd2_GetReading_ll( } /* The Spyder comms seems especially flakey... */ - for (retr = 0, nords = 1; ; retr++, nords++) { + for (retr = 0; ; retr++) { //int start = msec_time(); @@ -888,13 +889,14 @@ spyd2_GetReading_ll( } else { /* We discard 0'th L2F transion to give transitions */ /* over the time period. */ if (sensv != NULL) - sensv[k] = ((double)transcnt - 1.0) * (double)CLKRATE - / ((double)nords * (double)intclks); + sensv[k] = ((double)transcnt - 1.0) * (double)CLKRATE / (double)intclks; if (transcnt > _maxtcnt) _maxtcnt = transcnt; if (transcnt < _mintcnt) _mintcnt = transcnt; } + if (sensv != NULL && sensv[k] > maxfreq) + maxfreq = sensv[k]; if (p->log->debug >= 4 && sensv != NULL) a1logd(p->log, 4, "%d: initial senv %f from transcnt %d and intclls %d\n", k,sensv[k],transcnt,intclks); @@ -967,6 +969,8 @@ spyd2_GetReading_ll( if (transcnt < _mintcnt) _mintcnt = transcnt; } + if (sensv != NULL && (8.125 * sensv[k]) > maxfreq) + maxfreq = 8.125 * sensv[k]; if (p->log->debug >= 4 && sensv != NULL) a1logd(p->log, 4, "%d: initial senv %f from transcnt %d and intclls %d\n", k,sensv[k],transcnt,intclks); @@ -978,6 +982,16 @@ spyd2_GetReading_ll( if (mintcnt != NULL) *mintcnt = _mintcnt; + if (p->log->debug >= 4 && sensv != NULL) + a1logd(p->log, 4, "Maximum sensor frequency = %f\n",maxfreq); + + /* Problem is that the HW starts loosing count above a certain */ + /* frequency, so we depend on one less bright sensor acting as a canary, */ + /* so we can't make the threshold too low. */ + if (maxfreq > 500000.0) { + return spyd2_interp_code((inst *)p, SPYD2_TOOBRIGHT); + } + return rv; } @@ -2843,7 +2857,7 @@ spyd4_load_cal(spyd2 *p) { /* Establish communications with a SPYD2 */ /* If it's a serial port, use the baud rate given, and timeout in to secs */ -/* Return DTP_COMS_FAIL on failure to establish communications */ +/* Return SPYD2_COMS_FAIL on failure to establish communications */ static inst_code spyd2_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { spyd2 *p = (spyd2 *) pp; @@ -2866,7 +2880,7 @@ spyd2_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { /* (and Spyder 2 hangs if a reset ep is done on MSWin.) */ /* The spyder 2 doesn't work well with the winusb driver either, */ /* it needs icomuf_resetep_before_read to work at all, and */ - /* gets retries anyway. So we use the libusb0 driver for it. */ + /* gets retries anyway. So we use the libusb-win32 driver for it. */ #if defined(NT) if (p->itype == instSpyder3) { usbflags |= icomuf_resetep_before_read; /* The spyder USB is buggy ? */ @@ -3391,6 +3405,8 @@ spyd2_interp_error(inst *pp, int ec) { return "Display device selection out of range"; /* User error */ + case SPYD2_TOOBRIGHT: + return "Too bright to read accuractly"; case SPYD2_NO_REFRESH_DET: return "Unable to detect & measure refresh rate"; @@ -3445,6 +3461,7 @@ spyd2_interp_code(inst *pp, int ec) { case SPYD2_DISP_SEL_RANGE: return inst_wrong_setup | ec; + case SPYD2_TOOBRIGHT: case SPYD2_NO_REFRESH_DET: return inst_misread | ec; @@ -3461,6 +3478,7 @@ spyd2_del(inst *pp) { inst_del_disptype_list(p->dtlist, p->ndtlist); if (p->samples != NULL) free(p->samples); + p->vdel(pp); free(p); } diff --git a/spectro/spyd2.h b/spectro/spyd2.h index 923234f..0588b9b 100644 --- a/spectro/spyd2.h +++ b/spectro/spyd2.h @@ -56,6 +56,7 @@ #define SPYD2_TRIGTIMEOUT 0x04 #define SPYD2_OVERALLTIMEOUT 0x05 #define SPYD2_BAD_EE_CRC 0x06 +#define SPYD2_TOOBRIGHT 0x07 /* Internal software errors */ #define SPYD2_BAD_EE_ADDRESS 0x21 diff --git a/spectro/ss.c b/spectro/ss.c index 90720ca..837e264 100644 --- a/spectro/ss.c +++ b/spectro/ss.c @@ -131,7 +131,7 @@ static void check_calcount(ss *p, int atstart) { /* Establish communications with a Spectrolino/Spectroscan */ /* Use the baud rate given, and timeout in to secs */ -/* Return DTP_COMS_FAIL on failure to establish communications */ +/* Return SS_COMS_FAIL on failure to establish communications */ static inst_code ss_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { ss *p = (ss *)pp; @@ -2037,6 +2037,7 @@ ss_del(inst *pp) { if (p->icom != NULL) p->icom->del(p->icom); + p->vdel(pp); free (p); } diff --git a/spectro/strange.cal b/spectro/strange.cal new file mode 100644 index 0000000..5f2e94d --- /dev/null +++ b/spectro/strange.cal @@ -0,0 +1,272 @@ +CAL + +DESCRIPTOR "Argyll Device Calibration Curves" +ORIGINATOR "Argyll synthcal" +CREATED "Mon Oct 26 01:10:48 2015" +DEVICE_CLASS "DISPLAY" +COLOR_REP "RGB" + +NUMBER_OF_FIELDS 4 +BEGIN_DATA_FORMAT +RGB_I RGB_R RGB_G RGB_B +END_DATA_FORMAT + +NUMBER_OF_SETS 256 +BEGIN_DATA +0.00000 0.00000 0.00000 0.00000 +0.00392157 0.0000567518 0.0118787 0.0186065 +0.00784314 0.000184387 0.0206820 0.0302263 +0.0117647 0.000367355 0.0286065 0.0401466 +0.0156863 0.000599076 0.0360094 0.0491028 +0.0196078 0.000875445 0.0430471 0.0574042 +0.0235294 0.00119354 0.0498068 0.0652184 +0.0274510 0.00155112 0.0563438 0.0726496 +0.0313725 0.00194640 0.0626960 0.0797678 +0.0352941 0.00237789 0.0688909 0.0866232 +0.0392157 0.00284433 0.0749493 0.0932533 +0.0431373 0.00334462 0.0808876 0.0996872 +0.0470588 0.00387782 0.0867187 0.105948 +0.0509804 0.00444307 0.0924533 0.112053 +0.0549020 0.00503962 0.0981003 0.118020 +0.0588235 0.00566676 0.103667 0.123859 +0.0627451 0.00632388 0.109160 0.129583 +0.0666667 0.00701040 0.114585 0.135201 +0.0705882 0.00772579 0.119946 0.140720 +0.0745098 0.00846956 0.125248 0.146148 +0.0784314 0.00924125 0.130494 0.151490 +0.0823529 0.0100404 0.135689 0.156754 +0.0862745 0.0108667 0.140834 0.161942 +0.0901961 0.0117197 0.145932 0.167061 +0.0941176 0.0125991 0.150986 0.172112 +0.0980392 0.0135045 0.155998 0.177102 +0.101961 0.0144356 0.160971 0.182031 +0.105882 0.0153921 0.165905 0.186904 +0.109804 0.0163738 0.170803 0.191723 +0.113725 0.0173803 0.175665 0.196491 +0.117647 0.0184114 0.180495 0.201210 +0.121569 0.0194668 0.185292 0.205882 +0.125490 0.0205464 0.190059 0.210508 +0.129412 0.0216498 0.194796 0.215092 +0.133333 0.0227769 0.199504 0.219634 +0.137255 0.0239274 0.204184 0.224136 +0.141176 0.0251012 0.208838 0.228600 +0.145098 0.0262980 0.213466 0.233027 +0.149020 0.0275177 0.218069 0.237418 +0.152941 0.0287600 0.222648 0.241774 +0.156863 0.0300249 0.227204 0.246097 +0.160784 0.0313121 0.231737 0.250388 +0.164706 0.0326215 0.236248 0.254647 +0.168627 0.0339528 0.240737 0.258876 +0.172549 0.0353061 0.245205 0.263076 +0.176471 0.0366810 0.249654 0.267247 +0.180392 0.0380775 0.254082 0.271391 +0.184314 0.0394954 0.258491 0.275507 +0.188235 0.0409345 0.262882 0.279597 +0.192157 0.0423948 0.267254 0.283662 +0.196078 0.0438762 0.271609 0.287702 +0.200000 0.0453784 0.275946 0.291718 +0.203922 0.0469014 0.280266 0.295710 +0.207843 0.0484450 0.284570 0.299680 +0.211765 0.0500091 0.288857 0.303627 +0.215686 0.0515937 0.293128 0.307552 +0.219608 0.0531985 0.297384 0.311455 +0.223529 0.0548235 0.301625 0.315338 +0.227451 0.0564686 0.305851 0.319201 +0.231373 0.0581337 0.310063 0.323043 +0.235294 0.0598187 0.314260 0.326866 +0.239216 0.0615234 0.318443 0.330670 +0.243137 0.0632478 0.322613 0.334456 +0.247059 0.0649918 0.326769 0.338223 +0.250980 0.0667553 0.330911 0.341972 +0.254902 0.0685382 0.335041 0.345703 +0.258824 0.0703403 0.339159 0.349418 +0.262745 0.0721617 0.343264 0.353115 +0.266667 0.0740022 0.347356 0.356797 +0.270588 0.0758618 0.351437 0.360461 +0.274510 0.0777403 0.355505 0.364110 +0.278431 0.0796377 0.359563 0.367744 +0.282353 0.0815539 0.363608 0.371362 +0.286275 0.0834889 0.367643 0.374965 +0.290196 0.0854424 0.371666 0.378553 +0.294118 0.0874146 0.375679 0.382127 +0.298039 0.0894052 0.379681 0.385686 +0.301961 0.0914143 0.383672 0.389231 +0.305882 0.0934417 0.387653 0.392763 +0.309804 0.0954873 0.391624 0.396281 +0.313725 0.0975512 0.395585 0.399786 +0.317647 0.0996332 0.399536 0.403277 +0.321569 0.101733 0.403477 0.406756 +0.325490 0.103851 0.407409 0.410222 +0.329412 0.105987 0.411331 0.413676 +0.333333 0.108141 0.415244 0.417117 +0.337255 0.110313 0.419147 0.420546 +0.341176 0.112503 0.423042 0.423963 +0.345098 0.114710 0.426927 0.427368 +0.349020 0.116935 0.430804 0.430762 +0.352941 0.119177 0.434672 0.434144 +0.356863 0.121437 0.438532 0.437515 +0.360784 0.123714 0.442383 0.440875 +0.364706 0.126009 0.446225 0.444224 +0.368627 0.128321 0.450060 0.447563 +0.372549 0.130650 0.453886 0.450890 +0.376471 0.132997 0.457704 0.454207 +0.380392 0.135360 0.461514 0.457514 +0.384314 0.137741 0.465317 0.460811 +0.388235 0.140139 0.469111 0.464097 +0.392157 0.142554 0.472898 0.467374 +0.396078 0.144986 0.476678 0.470641 +0.400000 0.147435 0.480450 0.473898 +0.403922 0.149900 0.484214 0.477145 +0.407843 0.152383 0.487972 0.480383 +0.411765 0.154882 0.491722 0.483612 +0.415686 0.157398 0.495465 0.486831 +0.419608 0.159931 0.499200 0.490042 +0.423529 0.162480 0.502929 0.493243 +0.427451 0.165046 0.506651 0.496436 +0.431373 0.167628 0.510366 0.499619 +0.435294 0.170227 0.514075 0.502794 +0.439216 0.172842 0.517776 0.505961 +0.443137 0.175474 0.521472 0.509119 +0.447059 0.178122 0.525160 0.512269 +0.450980 0.180787 0.528842 0.515410 +0.454902 0.183467 0.532518 0.518543 +0.458824 0.186164 0.536187 0.521668 +0.462745 0.188877 0.539850 0.524785 +0.466667 0.191606 0.543507 0.527895 +0.470588 0.194351 0.547158 0.530996 +0.474510 0.197113 0.550803 0.534090 +0.478431 0.199890 0.554441 0.537176 +0.482353 0.202684 0.558074 0.540254 +0.486275 0.205493 0.561701 0.543325 +0.490196 0.208318 0.565322 0.546388 +0.494118 0.211159 0.568937 0.549444 +0.498039 0.214016 0.572547 0.552493 +0.501961 0.216889 0.576150 0.555535 +0.505882 0.219777 0.579748 0.558569 +0.509804 0.222681 0.583341 0.561597 +0.513725 0.225601 0.586928 0.564617 +0.517647 0.228536 0.590510 0.567631 +0.521569 0.231487 0.594086 0.570638 +0.525490 0.234454 0.597657 0.573638 +0.529412 0.237436 0.601222 0.576631 +0.533333 0.240434 0.604782 0.579618 +0.537255 0.243447 0.608337 0.582598 +0.541176 0.246476 0.611887 0.585571 +0.545098 0.249520 0.615431 0.588538 +0.549020 0.252579 0.618971 0.591499 +0.552941 0.255654 0.622505 0.594453 +0.556863 0.258744 0.626035 0.597401 +0.560784 0.261849 0.629559 0.600343 +0.564706 0.264970 0.633079 0.603279 +0.568627 0.268105 0.636594 0.606208 +0.572549 0.271256 0.640103 0.609132 +0.576471 0.274422 0.643608 0.612049 +0.580392 0.277603 0.647109 0.614961 +0.584314 0.280800 0.650604 0.617867 +0.588235 0.284011 0.654095 0.620766 +0.592157 0.287237 0.657581 0.623661 +0.596078 0.290478 0.661063 0.626549 +0.600000 0.293735 0.664540 0.629431 +0.603922 0.297006 0.668012 0.632308 +0.607843 0.300292 0.671480 0.635180 +0.611765 0.303593 0.674944 0.638045 +0.615686 0.306909 0.678403 0.640906 +0.619608 0.310239 0.681857 0.643761 +0.623529 0.313585 0.685308 0.646610 +0.627451 0.316945 0.688754 0.649454 +0.631373 0.320320 0.692195 0.652293 +0.635294 0.323709 0.695633 0.655126 +0.639216 0.327114 0.699066 0.657954 +0.643137 0.330533 0.702495 0.660777 +0.647059 0.333966 0.705919 0.663595 +0.650980 0.337414 0.709340 0.666408 +0.654902 0.340877 0.712756 0.669215 +0.658824 0.344354 0.716169 0.672018 +0.662745 0.347846 0.719577 0.674816 +0.666667 0.351352 0.722981 0.677608 +0.670588 0.354873 0.726381 0.680396 +0.674510 0.358408 0.729778 0.683179 +0.678431 0.361958 0.733170 0.685957 +0.682353 0.365522 0.736559 0.688730 +0.686275 0.369100 0.739943 0.691498 +0.690196 0.372693 0.743324 0.694262 +0.694118 0.376300 0.746701 0.697021 +0.698039 0.379921 0.750074 0.699775 +0.701961 0.383557 0.753443 0.702525 +0.705882 0.387207 0.756808 0.705270 +0.709804 0.390871 0.760170 0.708010 +0.713725 0.394549 0.763528 0.710746 +0.717647 0.398242 0.766882 0.713477 +0.721569 0.401948 0.770233 0.716204 +0.725490 0.405669 0.773580 0.718927 +0.729412 0.409404 0.776923 0.721645 +0.733333 0.413153 0.780263 0.724358 +0.737255 0.416916 0.783599 0.727068 +0.741176 0.420693 0.786932 0.729773 +0.745098 0.424484 0.790261 0.732473 +0.749020 0.428289 0.793587 0.735170 +0.752941 0.432108 0.796909 0.737862 +0.756863 0.435940 0.800228 0.740550 +0.760784 0.439787 0.803543 0.743234 +0.764706 0.443648 0.806855 0.745914 +0.768627 0.447523 0.810164 0.748589 +0.772549 0.451411 0.813469 0.751261 +0.776471 0.455314 0.816770 0.753928 +0.780392 0.459230 0.820069 0.756592 +0.784314 0.463160 0.823364 0.759251 +0.788235 0.467103 0.826656 0.761906 +0.792157 0.471061 0.829944 0.764558 +0.796078 0.475032 0.833230 0.767205 +0.800000 0.479017 0.836512 0.769849 +0.803922 0.483016 0.839790 0.772489 +0.807843 0.487028 0.843066 0.775124 +0.811765 0.491054 0.846339 0.777756 +0.815686 0.495094 0.849608 0.780385 +0.819608 0.499147 0.852874 0.783009 +0.823529 0.503214 0.856137 0.785630 +0.827451 0.507294 0.859397 0.788247 +0.831373 0.511388 0.862654 0.790860 +0.835294 0.515496 0.865908 0.793469 +0.839216 0.519617 0.869158 0.796075 +0.843137 0.523751 0.872406 0.798677 +0.847059 0.527899 0.875651 0.801276 +0.850980 0.532061 0.878892 0.803871 +0.854902 0.536236 0.882131 0.806462 +0.858824 0.540424 0.885367 0.809050 +0.862745 0.544626 0.888599 0.811634 +0.866667 0.548841 0.891829 0.814215 +0.870588 0.553070 0.895056 0.816792 +0.874510 0.557311 0.898280 0.819366 +0.878431 0.561567 0.901501 0.821936 +0.882353 0.565835 0.904719 0.824503 +0.886275 0.570117 0.907935 0.827066 +0.890196 0.574412 0.911147 0.829626 +0.894118 0.578721 0.914357 0.832183 +0.898039 0.583042 0.917564 0.834736 +0.901961 0.587377 0.920768 0.837286 +0.905882 0.591725 0.923969 0.839833 +0.909804 0.596087 0.927168 0.842376 +0.913725 0.600461 0.930363 0.844916 +0.917647 0.604849 0.933556 0.847453 +0.921569 0.609249 0.936747 0.849986 +0.925490 0.613663 0.939934 0.852516 +0.929412 0.618090 0.943119 0.855044 +0.933333 0.622530 0.946301 0.857567 +0.937255 0.626984 0.949481 0.860088 +0.941176 0.631450 0.952658 0.862606 +0.945098 0.635929 0.955832 0.865120 +0.949020 0.640421 0.959003 0.867631 +0.952941 0.644927 0.962172 0.870139 +0.956863 0.649445 0.965339 0.872644 +0.960784 0.653976 0.968502 0.875146 +0.964706 0.658521 0.971664 0.877645 +0.968627 0.663078 0.974822 0.880141 +0.972549 0.667648 0.977978 0.882634 +0.976471 0.672231 0.981132 0.885124 +0.980392 0.676827 0.984283 0.887610 +0.984314 0.681436 0.987431 0.890094 +0.988235 0.686058 0.990577 0.892575 +0.992157 0.690692 0.993721 0.895053 +0.996078 0.695340 0.996862 0.897528 +1.000000 0.700000 1.000000 0.900000 +END_DATA diff --git a/spectro/usbio.c b/spectro/usbio.c index 668544a..9f8964a 100644 --- a/spectro/usbio.c +++ b/spectro/usbio.c @@ -118,7 +118,7 @@ int rwsize, /* Bytes to read or write */ double tout /* Timeout in seconds */ ) { int rv = 0; /* Return value */ - int c, rwbytes; /* Data bytes read or written */ + int rwbytes; /* Data bytes read or written */ long top; /* timeout in msec */ if (p->log->debug >= 8) { @@ -412,7 +412,7 @@ double tout) /* Until data is all written, we time out, or the user aborts */ for (top = ttop; top > 0 && len > 0;) { - int c, rv; + int rv; a1logd(p->log, 8, "icoms_usb_ser_write: attempting to write %d bytes to usb top = %d\n",len,top); rv = icoms_usb_transaction(p, NULL, &wbytes, type, (unsigned char)ep, (unsigned char *)wbuf, len, top); diff --git a/spectro/usbio_nt.c b/spectro/usbio_nt.c index 8daac0d..f5c3af8 100644 --- a/spectro/usbio_nt.c +++ b/spectro/usbio_nt.c @@ -567,7 +567,7 @@ char **pnames /* List of process names to try and kill before opening */ /* -------------------------------------------------------------- */ -/* Our universal USB transfer function */ +/* Our universal USB transfer function, used for rd/wr. */ /* It appears that we may return a timeout with valid characters. */ static int icoms_usb_transaction( icoms *p, diff --git a/target/ifarp.c b/target/ifarp.c index 544f316..03fc914 100644 --- a/target/ifarp.c +++ b/target/ifarp.c @@ -310,6 +310,7 @@ ifarp_del(ifarp *s) { /* Constructor */ ifarp *new_ifarp( +int verb, /* Verbosity */ int di, /* Dimensionality of device space */ double ilimit, /* Ink limit (sum of device coords max) */ int inp, /* Number of points to generate */ @@ -320,7 +321,6 @@ void *od /* context for Perceptual function */ ) { ifarp *s; int e, i; - int verb = 1; #ifdef DEBUG printf("new_ifarp called with di %d, inp %d, fxno = %d\n",di,inp,fxno); @@ -855,7 +855,7 @@ char *argv[]; error ("Creation of xcolorant lu object failed"); /* Create the required points */ - s = new_ifarp(di, 1.5, npoints, NULL, 0, sa_percept, (void *)NULL); + s = new_ifarp(1, di, 1.5, npoints, NULL, 0, sa_percept, (void *)NULL); #ifdef DEBUG /* Dump perceptual map */ diff --git a/target/ifarp.h b/target/ifarp.h index 083411b..ee18840 100644 --- a/target/ifarp.h +++ b/target/ifarp.h @@ -59,9 +59,10 @@ struct _ifarp { }; typedef struct _ifarp ifarp; /* Constructor */ -extern ifarp *new_ifarp(int di, double ilimit, int npoints, +extern ifarp *new_ifarp(int verb, int di, double ilimit, int npoints, fxpos *fxlist, int fxno, - void (*percept)(void *od, double *out, double *in), void *od); + void (*percept)(void *od, double *out, double *in), void *od +); #define IFARP_H #endif /* IFARP_H */ diff --git a/target/printtarg.c b/target/printtarg.c index 863537f..1b03b3c 100644 --- a/target/printtarg.c +++ b/target/printtarg.c @@ -2912,8 +2912,8 @@ void usage(char *diag, ...) { fprintf(stderr," -b Force B&W spacers\n"); fprintf(stderr," -n Force no spacers\n"); fprintf(stderr," -f Create PostScript DeviceN Color fallback\n"); - fprintf(stderr," -w g|r|s|n White colorspace encoding DeviceGray (def), DeviceRGB, Separation or DeviceN\n"); - fprintf(stderr," -k g|c|s|n Black colorspace encoding DeviceGray (def), DeviceCMYK, Separation or DeviceN\n"); + fprintf(stderr," -w g|r|s|n White colorspace encoding: DeviceGray (def), DeviceRGB, Separation or DeviceN\n"); + fprintf(stderr," -k g|c|s|n Black colorspace encoding: DeviceGray (def), DeviceCMYK, Separation or DeviceN\n"); fprintf(stderr," -o k|r|n CMY colorspace encoding DeviceCMYK (def), inverted DeviceRGB or DeviceN\n"); fprintf(stderr," -e Output EPS compatible file\n"); fprintf(stderr," -t [res] Output 8 bit TIFF raster file, optional res DPI (default 100)\n"); @@ -3645,12 +3645,16 @@ char *argv[]; } } - if (verb) { - if (pap != NULL) + if (pap != NULL) { + sprintf(buf, "%.1fx%.1f",pap->w, pap->h); + if (verb) printf("Paper chosen is %s [%.1f x %.1f mm]\n", pap->name, pap->w, pap->h); - else + } else { + sprintf(buf, "%.1fx%.1f",cwidth, cheight); + if (verb) printf("Paper chosen is custom %.1f x %.1f mm\n", cwidth, cheight); } + ocg->add_kword(ocg, 0, "PAPER_SIZE", buf, NULL); if (rstart == -1) { rstart = clk % npat; diff --git a/target/targen.c b/target/targen.c index 4d1d7ac..a29ef63 100644 --- a/target/targen.c +++ b/target/targen.c @@ -2165,7 +2165,7 @@ int main(int argc, char *argv[]) { /* for some of these (new_prand). */ if (uselat) { /* A "greedy"/incremental far point approach */ - t = new_ifarp(di, uilimit, fsteps, fxlist, fxno, + t = new_ifarp(verb, di, uilimit, fsteps, fxlist, fxno, (void(*)(void *, double *, double *))pdata->dev_to_perc, (void *)pdata); sprintf(buf,"%d",fsteps - fxno); pp->add_kword(pp, 0, "IFP_PATCHES", buf, NULL); diff --git a/usb/ArgyllCMS.cat b/usb/ArgyllCMS.cat index 91c5a81..2b713c9 100644 Binary files a/usb/ArgyllCMS.cat and b/usb/ArgyllCMS.cat differ diff --git a/usb/ArgyllCMS.inf b/usb/ArgyllCMS.inf index 4de9f51..db0995f 100644 --- a/usb/ArgyllCMS.inf +++ b/usb/ArgyllCMS.inf @@ -1,229 +1,229 @@ -;-------------------------------------------------------------------------- -; Copyright 2012 Graeme W. Gill. -; -; Permission is hereby granted, free of charge, to any person obtaining a copy -; of this file, to deal -; in this file without restriction, including without limitation the rights -; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -; copies of this file, and to permit persons to whom this file is -; furnished to do so, subject to the following conditions: -; -; The above copyright notice and this permission notice shall be included in -; all copies or substantial portions of this file. -; -; THIS FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -; OUT OF OR IN CONNECTION WITH THIS FILE OR THE USE OR OTHER DEALINGS IN -; THIS FILE. -;-------------------------------------------------------------------------- - -; ==== Strings ==== - -[Strings] - -DeviceGUID = {247e32a0-32f9-11df-aacc-0002a5d5c51b} - -Date = "01/17/2012" ; MM/DD/YYYY -libusb0ver = "1.2.6.0" - -Libusb_ClassName = "Argyll LibUSB-win32 devices" -Libusb_DiskName = "LibUSB-win32 Device Install Disk" - -libusb0_SvcDesc = "LibUSB-win32 libusb0 - Kernel Driver 2012/1/17, 1.2.6.0" - -; ==== Version ==== - -[Version] -Signature = "$Windows NT$" -DriverVer = %Date%,%libusb0ver% -Provider = "ArgyllCMS" - -; (Note the ClassGuid must not be quoted or a string substitution to work on Win2K) -Class = %Libusb_ClassName% -ClassGuid = {817cffe0-328b-11df-9b9f-0002a5d5c51b} ; LibUSB-win32 ClassGUID -CatalogFile = "ArgyllCMS.cat" -CatalogFile.NTAMD64 = "ArgyllCMS_x64.cat" - -[ClassInstall32] -AddReg=class_install_add_reg - -[class_install_add_reg] -HKR,,,,%Libusb_ClassName% -HKR,,Icon,,"-20" ; -20 is for the USB icon - -; ==== Files Sources and Destinations ==== - -[SourceDisksNames] -1 = %Libusb_DiskName% - -[SourceDisksFiles] -libusb0.sys = 1,\bin\x86, - -[SourceDisksFiles.amd64] -libusb0.sys = 1,\bin\amd64, - -[DestinationDirs] -libusb0_files_sys = 10,system32\drivers - -; ==== libusb0 Device driver ==== - -[libusb0_files_sys] -libusb0.sys,libusb0.sys - -; For each one of these, there must be one for Services !!! -[LIBUSB0_DEV] -CopyFiles = Libusb0_files_sys - -[LIBUSB0_DEV.HW] -AddReg = libusb0_add_reg_hw - -[libusb0_add_reg] -HKR,,DevLoader,,*ntkern -HKR,,NTMPDriver,,libusb0.sys - -[libusb0_add_reg_hw] -HKR,,DeviceInterfaceGUIDs,0x10000,%DeviceGUID% -HKR,,SurpriseRemovalOK,0x00010001,1 ; Device properties - -[LIBUSB0_DEV.Services] -AddService = libusb0, 0x00000002, libusb0_add_service - -[libusb0_add_service] -DisplayName = %libusb0_SvcDesc% -ServiceType = 1 -StartType = 3 -ErrorControl = 0 -ServiceBinary = %12%\libusb0.sys - -; ==== Manufacturers ==== - -[Manufacturer] -"HCFR Association"=HCFR_Devices,NTx86,NTamd64 -"Sequel Imaging"=Sequel_Devices,NTx86,NTamd64 -"X-Rite"=X_Rite_Devices,NTx86,NTamd64 -"ColorVision"=ColorVision_Devices,NTx86,NTamd64 -"Gretag Macbeth/X-Rite"=GM_X_Rite_Devices,NTx86,NTamd64 -"Hughski Ltd"=Hughski_Devices,NTx86,NTamd64 -"Image Engineering"=ImageEngineering_Devices,NTx86,NTamd64 - -; ==== Devices ==== - -[HCFR_Devices] -"Colorimtre HCFR V3.1 (Argyll)" = LIBUSB0_DEV, USB\VID_04DB&PID_005B -"Colorimtre HCFR V4.0 (Argyll)" = LIBUSB0_DEV, USB\VID_04D8&PID_FE17 - -[Sequel_Devices] -"Eye-One Display 1 (Argyll)" = LIBUSB0_DEV, USB\VID_0670&PID_0001 - -[X_Rite_Devices] -"HueyL (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5001 -"HueyL (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5010 -"Eye-One Display 3 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5020 -"ColorMunki Smile (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_6003 -"DTP20 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D020 -"DTP92Q (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D092 -"DTP94 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D094 - -[ColorVision_Devices] -"Spyder1 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0100 -"Spyder2 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0200 -"Spyder3 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0300 -"Spyder4 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0400 -"Spyder5 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0500 - -[GM_X_Rite_Devices] -"Eye-One Pro (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2000 -"Eye-One Monitor (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2001 -"Eye-One Display 2 (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2003 -"Huey (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2005 -"ColorMunki (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2007 - -[Hughski_Devices] -"ColorHug 2 (Argyll)" = LIBUSB0_DEV, USB\VID_273F&PID_1004 -"ColorHug (Argyll)" = LIBUSB0_DEV, USB\VID_273F&PID_1001 -"ColorHug (Argyll)" = LIBUSB0_DEV, USB\VID_04D8&PID_F8DA - -[ImageEngineering_Devices] -"EX1 (Argyll)" = LIBUSB0_DEV, USB\VID_2457&PID_4000 - - -[HCFR_Devices.NTx86] -"Colorimtre HCFR V3.1 (Argyll)" = LIBUSB0_DEV, USB\VID_04DB&PID_005B -"Colorimtre HCFR V4.0 (Argyll)" = LIBUSB0_DEV, USB\VID_04D8&PID_FE17 - -[Sequel_Devices.NTx86] -"Eye-One Display 1 (Argyll)" = LIBUSB0_DEV, USB\VID_0670&PID_0001 - -[X_Rite_Devices.NTx86] -"HueyL (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5001 -"HueyL (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5010 -"Eye-One Display 3 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5020 -"ColorMunki Smile (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_6003 -"DTP20 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D020 -"DTP92Q (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D092 -"DTP94 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D094 - -[ColorVision_Devices.NTx86] -"Spyder1 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0100 -"Spyder2 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0200 -"Spyder3 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0300 -"Spyder4 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0400 -"Spyder5 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0500 - -[GM_X_Rite_Devices.NTx86] -"Eye-One Pro (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2000 -"Eye-One Monitor (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2001 -"Eye-One Display 2 (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2003 -"Huey (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2005 -"ColorMunki (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2007 - -[Hughski_Devices.NTx86] -"ColorHug 2 (Argyll)" = LIBUSB0_DEV, USB\VID_273F&PID_1004 -"ColorHug (Argyll)" = LIBUSB0_DEV, USB\VID_273F&PID_1001 -"ColorHug (Argyll)" = LIBUSB0_DEV, USB\VID_04D8&PID_F8DA - -[ImageEngineering_Devices.NTx86] -"EX1 (Argyll)" = LIBUSB0_DEV, USB\VID_2457&PID_4000 - - -[HCFR_Devices.NTamd64] -"Colorimtre HCFR V3.1 (Argyll)" = LIBUSB0_DEV, USB\VID_04DB&PID_005B -"Colorimtre HCFR V4.0 (Argyll)" = LIBUSB0_DEV, USB\VID_04D8&PID_FE17 - -[Sequel_Devices.NTamd64] -"Eye-One Display 1 (Argyll)" = LIBUSB0_DEV, USB\VID_0670&PID_0001 - -[X_Rite_Devices.NTamd64] -"HueyL (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5001 -"HueyL (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5010 -"Eye-One Display 3 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5020 -"ColorMunki Smile (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_6003 -"DTP20 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D020 -"DTP92Q (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D092 -"DTP94 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D094 - -[ColorVision_Devices.NTamd64] -"Spyder1 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0100 -"Spyder2 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0200 -"Spyder3 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0300 -"Spyder4 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0400 -"Spyder5 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0500 - -[GM_X_Rite_Devices.NTamd64] -"Eye-One Pro (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2000 -"Eye-One Monitor (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2001 -"Eye-One Display 2 (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2003 -"Huey (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2005 -"ColorMunki (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2007 - -[Hughski_Devices.NTamd64] -"ColorHug 2 (Argyll)" = LIBUSB0_DEV, USB\VID_273F&PID_1004 -"ColorHug (Argyll)" = LIBUSB0_DEV, USB\VID_273F&PID_1001 -"ColorHug (Argyll)" = LIBUSB0_DEV, USB\VID_04D8&PID_F8DA - -[ImageEngineering_Devices.NTamd64] -"EX1 (Argyll)" = LIBUSB0_DEV, USB\VID_2457&PID_4000 - +;-------------------------------------------------------------------------- +; Copyright 2012 Graeme W. Gill. +; +; Permission is hereby granted, free of charge, to any person obtaining a copy +; of this file, to deal +; in this file without restriction, including without limitation the rights +; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +; copies of this file, and to permit persons to whom this file is +; furnished to do so, subject to the following conditions: +; +; The above copyright notice and this permission notice shall be included in +; all copies or substantial portions of this file. +; +; THIS FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +; OUT OF OR IN CONNECTION WITH THIS FILE OR THE USE OR OTHER DEALINGS IN +; THIS FILE. +;-------------------------------------------------------------------------- + +; ==== Strings ==== + +[Strings] + +DeviceGUID = {247e32a0-32f9-11df-aacc-0002a5d5c51b} + +Date = "01/17/2012" ; MM/DD/YYYY +libusb0ver = "1.2.6.0" + +Libusb_ClassName = "Argyll LibUSB-win32 devices" +Libusb_DiskName = "LibUSB-win32 Device Install Disk" + +libusb0_SvcDesc = "LibUSB-win32 libusb0 - Kernel Driver 2012/1/17, 1.2.6.0" + +; ==== Version ==== + +[Version] +Signature = "$Windows NT$" +DriverVer = %Date%,%libusb0ver% +Provider = "ArgyllCMS" + +; (Note the ClassGuid must not be quoted or a string substitution to work on Win2K) +Class = %Libusb_ClassName% +ClassGuid = {817cffe0-328b-11df-9b9f-0002a5d5c51b} ; LibUSB-win32 ClassGUID +CatalogFile = "ArgyllCMS.cat" +CatalogFile.NTAMD64 = "ArgyllCMS_x64.cat" + +[ClassInstall32] +AddReg=class_install_add_reg + +[class_install_add_reg] +HKR,,,,%Libusb_ClassName% +HKR,,Icon,,"-20" ; -20 is for the USB icon + +; ==== Files Sources and Destinations ==== + +[SourceDisksNames] +1 = %Libusb_DiskName% + +[SourceDisksFiles] +libusb0.sys = 1,\bin\x86, + +[SourceDisksFiles.amd64] +libusb0.sys = 1,\bin\amd64, + +[DestinationDirs] +libusb0_files_sys = 10,system32\drivers + +; ==== libusb0 Device driver ==== + +[libusb0_files_sys] +libusb0.sys,libusb0.sys + +; For each one of these, there must be one for Services !!! +[LIBUSB0_DEV] +CopyFiles = Libusb0_files_sys + +[LIBUSB0_DEV.HW] +AddReg = libusb0_add_reg_hw + +[libusb0_add_reg] +HKR,,DevLoader,,*ntkern +HKR,,NTMPDriver,,libusb0.sys + +[libusb0_add_reg_hw] +HKR,,DeviceInterfaceGUIDs,0x10000,%DeviceGUID% +HKR,,SurpriseRemovalOK,0x00010001,1 ; Device properties + +[LIBUSB0_DEV.Services] +AddService = libusb0, 0x00000002, libusb0_add_service + +[libusb0_add_service] +DisplayName = %libusb0_SvcDesc% +ServiceType = 1 +StartType = 3 +ErrorControl = 0 +ServiceBinary = %12%\libusb0.sys + +; ==== Manufacturers ==== + +[Manufacturer] +"HCFR Association"=HCFR_Devices,NTx86,NTamd64 +"Sequel Imaging"=Sequel_Devices,NTx86,NTamd64 +"X-Rite"=X_Rite_Devices,NTx86,NTamd64 +"ColorVision"=ColorVision_Devices,NTx86,NTamd64 +"Gretag Macbeth/X-Rite"=GM_X_Rite_Devices,NTx86,NTamd64 +"Hughski Ltd"=Hughski_Devices,NTx86,NTamd64 +"Image Engineering"=ImageEngineering_Devices,NTx86,NTamd64 + +; ==== Devices ==== + +[HCFR_Devices] +"Colorimtre HCFR V3.1 (Argyll)" = LIBUSB0_DEV, USB\VID_04DB&PID_005B +"Colorimtre HCFR V4.0 (Argyll)" = LIBUSB0_DEV, USB\VID_04D8&PID_FE17 + +[Sequel_Devices] +"Eye-One Display 1 (Argyll)" = LIBUSB0_DEV, USB\VID_0670&PID_0001 + +[X_Rite_Devices] +"HueyL (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5001 +"HueyL (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5010 +"Eye-One Display 3 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5020 +"ColorMunki Smile (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_6003 +"DTP20 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D020 +"DTP92Q (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D092 +"DTP94 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D094 + +[ColorVision_Devices] +"Spyder1 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0100 +"Spyder2 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0200 +"Spyder3 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0300 +"Spyder4 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0400 +"Spyder5 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0500 + +[GM_X_Rite_Devices] +"Eye-One Pro (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2000 +"Eye-One Monitor (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2001 +"Eye-One Display 2 (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2003 +"Huey (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2005 +"ColorMunki (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2007 + +[Hughski_Devices] +"ColorHug 2 (Argyll)" = LIBUSB0_DEV, USB\VID_273F&PID_1004 +"ColorHug (Argyll)" = LIBUSB0_DEV, USB\VID_273F&PID_1001 +"ColorHug (Argyll)" = LIBUSB0_DEV, USB\VID_04D8&PID_F8DA + +[ImageEngineering_Devices] +"EX1 (Argyll)" = LIBUSB0_DEV, USB\VID_2457&PID_4000 + + +[HCFR_Devices.NTx86] +"Colorimtre HCFR V3.1 (Argyll)" = LIBUSB0_DEV, USB\VID_04DB&PID_005B +"Colorimtre HCFR V4.0 (Argyll)" = LIBUSB0_DEV, USB\VID_04D8&PID_FE17 + +[Sequel_Devices.NTx86] +"Eye-One Display 1 (Argyll)" = LIBUSB0_DEV, USB\VID_0670&PID_0001 + +[X_Rite_Devices.NTx86] +"HueyL (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5001 +"HueyL (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5010 +"Eye-One Display 3 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5020 +"ColorMunki Smile (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_6003 +"DTP20 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D020 +"DTP92Q (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D092 +"DTP94 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D094 + +[ColorVision_Devices.NTx86] +"Spyder1 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0100 +"Spyder2 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0200 +"Spyder3 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0300 +"Spyder4 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0400 +"Spyder5 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0500 + +[GM_X_Rite_Devices.NTx86] +"Eye-One Pro (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2000 +"Eye-One Monitor (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2001 +"Eye-One Display 2 (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2003 +"Huey (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2005 +"ColorMunki (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2007 + +[Hughski_Devices.NTx86] +"ColorHug 2 (Argyll)" = LIBUSB0_DEV, USB\VID_273F&PID_1004 +"ColorHug (Argyll)" = LIBUSB0_DEV, USB\VID_273F&PID_1001 +"ColorHug (Argyll)" = LIBUSB0_DEV, USB\VID_04D8&PID_F8DA + +[ImageEngineering_Devices.NTx86] +"EX1 (Argyll)" = LIBUSB0_DEV, USB\VID_2457&PID_4000 + + +[HCFR_Devices.NTamd64] +"Colorimtre HCFR V3.1 (Argyll)" = LIBUSB0_DEV, USB\VID_04DB&PID_005B +"Colorimtre HCFR V4.0 (Argyll)" = LIBUSB0_DEV, USB\VID_04D8&PID_FE17 + +[Sequel_Devices.NTamd64] +"Eye-One Display 1 (Argyll)" = LIBUSB0_DEV, USB\VID_0670&PID_0001 + +[X_Rite_Devices.NTamd64] +"HueyL (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5001 +"HueyL (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5010 +"Eye-One Display 3 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5020 +"ColorMunki Smile (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_6003 +"DTP20 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D020 +"DTP92Q (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D092 +"DTP94 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D094 + +[ColorVision_Devices.NTamd64] +"Spyder1 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0100 +"Spyder2 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0200 +"Spyder3 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0300 +"Spyder4 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0400 +"Spyder5 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0500 + +[GM_X_Rite_Devices.NTamd64] +"Eye-One Pro (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2000 +"Eye-One Monitor (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2001 +"Eye-One Display 2 (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2003 +"Huey (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2005 +"ColorMunki (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2007 + +[Hughski_Devices.NTamd64] +"ColorHug 2 (Argyll)" = LIBUSB0_DEV, USB\VID_273F&PID_1004 +"ColorHug (Argyll)" = LIBUSB0_DEV, USB\VID_273F&PID_1001 +"ColorHug (Argyll)" = LIBUSB0_DEV, USB\VID_04D8&PID_F8DA + +[ImageEngineering_Devices.NTamd64] +"EX1 (Argyll)" = LIBUSB0_DEV, USB\VID_2457&PID_4000 + diff --git a/usb/ArgyllCMS.inf.d b/usb/ArgyllCMS.inf.d index c130cee..c0809e9 100644 --- a/usb/ArgyllCMS.inf.d +++ b/usb/ArgyllCMS.inf.d @@ -1,39 +1,39 @@ - -[HCFR_Devices#PLAT#] -"Colorimtre HCFR V3.1 (Argyll)" = LIBUSB0_DEV, USB\VID_04DB&PID_005B -"Colorimtre HCFR V4.0 (Argyll)" = LIBUSB0_DEV, USB\VID_04D8&PID_FE17 - -[Sequel_Devices#PLAT#] -"Eye-One Display 1 (Argyll)" = LIBUSB0_DEV, USB\VID_0670&PID_0001 - -[X_Rite_Devices#PLAT#] -"HueyL (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5001 -"HueyL (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5010 -"Eye-One Display 3 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5020 -"ColorMunki Smile (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_6003 -"DTP20 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D020 -"DTP92Q (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D092 -"DTP94 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D094 - -[ColorVision_Devices#PLAT#] -"Spyder1 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0100 -"Spyder2 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0200 -"Spyder3 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0300 -"Spyder4 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0400 -"Spyder5 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0500 - -[GM_X_Rite_Devices#PLAT#] -"Eye-One Pro (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2000 -"Eye-One Monitor (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2001 -"Eye-One Display 2 (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2003 -"Huey (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2005 -"ColorMunki (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2007 - -[Hughski_Devices#PLAT#] -"ColorHug 2 (Argyll)" = LIBUSB0_DEV, USB\VID_273F&PID_1004 -"ColorHug (Argyll)" = LIBUSB0_DEV, USB\VID_273F&PID_1001 -"ColorHug (Argyll)" = LIBUSB0_DEV, USB\VID_04D8&PID_F8DA - -[ImageEngineering_Devices#PLAT#] -"EX1 (Argyll)" = LIBUSB0_DEV, USB\VID_2457&PID_4000 - + +[HCFR_Devices#PLAT#] +"Colorimtre HCFR V3.1 (Argyll)" = LIBUSB0_DEV, USB\VID_04DB&PID_005B +"Colorimtre HCFR V4.0 (Argyll)" = LIBUSB0_DEV, USB\VID_04D8&PID_FE17 + +[Sequel_Devices#PLAT#] +"Eye-One Display 1 (Argyll)" = LIBUSB0_DEV, USB\VID_0670&PID_0001 + +[X_Rite_Devices#PLAT#] +"HueyL (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5001 +"HueyL (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5010 +"Eye-One Display 3 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_5020 +"ColorMunki Smile (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_6003 +"DTP20 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D020 +"DTP92Q (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D092 +"DTP94 (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_D094 + +[ColorVision_Devices#PLAT#] +"Spyder1 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0100 +"Spyder2 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0200 +"Spyder3 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0300 +"Spyder4 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0400 +"Spyder5 (Argyll)" = LIBUSB0_DEV, USB\VID_085C&PID_0500 + +[GM_X_Rite_Devices#PLAT#] +"Eye-One Pro (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2000 +"Eye-One Monitor (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2001 +"Eye-One Display 2 (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2003 +"Huey (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2005 +"ColorMunki (Argyll)" = LIBUSB0_DEV, USB\VID_0971&PID_2007 + +[Hughski_Devices#PLAT#] +"ColorHug 2 (Argyll)" = LIBUSB0_DEV, USB\VID_273F&PID_1004 +"ColorHug (Argyll)" = LIBUSB0_DEV, USB\VID_273F&PID_1001 +"ColorHug (Argyll)" = LIBUSB0_DEV, USB\VID_04D8&PID_F8DA + +[ImageEngineering_Devices#PLAT#] +"EX1 (Argyll)" = LIBUSB0_DEV, USB\VID_2457&PID_4000 + diff --git a/usb/ArgyllCMS.inf.t b/usb/ArgyllCMS.inf.t index 635d9ef..a185d03 100644 --- a/usb/ArgyllCMS.inf.t +++ b/usb/ArgyllCMS.inf.t @@ -1,112 +1,112 @@ -;-------------------------------------------------------------------------- -; Copyright 2012 Graeme W. Gill. -; -; Permission is hereby granted, free of charge, to any person obtaining a copy -; of this file, to deal -; in this file without restriction, including without limitation the rights -; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -; copies of this file, and to permit persons to whom this file is -; furnished to do so, subject to the following conditions: -; -; The above copyright notice and this permission notice shall be included in -; all copies or substantial portions of this file. -; -; THIS FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -; OUT OF OR IN CONNECTION WITH THIS FILE OR THE USE OR OTHER DEALINGS IN -; THIS FILE. -;-------------------------------------------------------------------------- - -; ==== Strings ==== - -[Strings] - -DeviceGUID = {247e32a0-32f9-11df-aacc-0002a5d5c51b} - -Date = "01/17/2012" ; MM/DD/YYYY -libusb0ver = "1.2.6.0" - -Libusb_ClassName = "Argyll LibUSB-win32 devices" -Libusb_DiskName = "LibUSB-win32 Device Install Disk" - -libusb0_SvcDesc = "LibUSB-win32 libusb0 - Kernel Driver 2012/1/17, 1.2.6.0" - -; ==== Version ==== - -[Version] -Signature = "$Windows NT$" -DriverVer = %Date%,%libusb0ver% -Provider = "ArgyllCMS" - -; (Note the ClassGuid must not be quoted or a string substitution to work on Win2K) -Class = %Libusb_ClassName% -ClassGuid = {817cffe0-328b-11df-9b9f-0002a5d5c51b} ; LibUSB-win32 ClassGUID -CatalogFile = "ArgyllCMS.cat" -CatalogFile.NTAMD64 = "ArgyllCMS_x64.cat" - -[ClassInstall32] -AddReg=class_install_add_reg - -[class_install_add_reg] -HKR,,,,%Libusb_ClassName% -HKR,,Icon,,"-20" ; -20 is for the USB icon - -; ==== Files Sources and Destinations ==== - -[SourceDisksNames] -1 = %Libusb_DiskName% - -[SourceDisksFiles] -libusb0.sys = 1,\bin\x86, - -[SourceDisksFiles.amd64] -libusb0.sys = 1,\bin\amd64, - -[DestinationDirs] -libusb0_files_sys = 10,system32\drivers - -; ==== libusb0 Device driver ==== - -[libusb0_files_sys] -libusb0.sys,libusb0.sys - -; For each one of these, there must be one for Services !!! -[LIBUSB0_DEV] -CopyFiles = Libusb0_files_sys - -[LIBUSB0_DEV.HW] -AddReg = libusb0_add_reg_hw - -[libusb0_add_reg] -HKR,,DevLoader,,*ntkern -HKR,,NTMPDriver,,libusb0.sys - -[libusb0_add_reg_hw] -HKR,,DeviceInterfaceGUIDs,0x10000,%DeviceGUID% -HKR,,SurpriseRemovalOK,0x00010001,1 ; Device properties - -[LIBUSB0_DEV.Services] -AddService = libusb0, 0x00000002, libusb0_add_service - -[libusb0_add_service] -DisplayName = %libusb0_SvcDesc% -ServiceType = 1 -StartType = 3 -ErrorControl = 0 -ServiceBinary = %12%\libusb0.sys - -; ==== Manufacturers ==== - -[Manufacturer] -"HCFR Association"=HCFR_Devices,NTx86,NTamd64 -"Sequel Imaging"=Sequel_Devices,NTx86,NTamd64 -"X-Rite"=X_Rite_Devices,NTx86,NTamd64 -"ColorVision"=ColorVision_Devices,NTx86,NTamd64 -"Gretag Macbeth/X-Rite"=GM_X_Rite_Devices,NTx86,NTamd64 -"Hughski Ltd"=Hughski_Devices,NTx86,NTamd64 -"Image Engineering"=ImageEngineering_Devices,NTx86,NTamd64 - -; ==== Devices ==== +;-------------------------------------------------------------------------- +; Copyright 2012 Graeme W. Gill. +; +; Permission is hereby granted, free of charge, to any person obtaining a copy +; of this file, to deal +; in this file without restriction, including without limitation the rights +; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +; copies of this file, and to permit persons to whom this file is +; furnished to do so, subject to the following conditions: +; +; The above copyright notice and this permission notice shall be included in +; all copies or substantial portions of this file. +; +; THIS FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +; OUT OF OR IN CONNECTION WITH THIS FILE OR THE USE OR OTHER DEALINGS IN +; THIS FILE. +;-------------------------------------------------------------------------- + +; ==== Strings ==== + +[Strings] + +DeviceGUID = {247e32a0-32f9-11df-aacc-0002a5d5c51b} + +Date = "01/17/2012" ; MM/DD/YYYY +libusb0ver = "1.2.6.0" + +Libusb_ClassName = "Argyll LibUSB-win32 devices" +Libusb_DiskName = "LibUSB-win32 Device Install Disk" + +libusb0_SvcDesc = "LibUSB-win32 libusb0 - Kernel Driver 2012/1/17, 1.2.6.0" + +; ==== Version ==== + +[Version] +Signature = "$Windows NT$" +DriverVer = %Date%,%libusb0ver% +Provider = "ArgyllCMS" + +; (Note the ClassGuid must not be quoted or a string substitution to work on Win2K) +Class = %Libusb_ClassName% +ClassGuid = {817cffe0-328b-11df-9b9f-0002a5d5c51b} ; LibUSB-win32 ClassGUID +CatalogFile = "ArgyllCMS.cat" +CatalogFile.NTAMD64 = "ArgyllCMS_x64.cat" + +[ClassInstall32] +AddReg=class_install_add_reg + +[class_install_add_reg] +HKR,,,,%Libusb_ClassName% +HKR,,Icon,,"-20" ; -20 is for the USB icon + +; ==== Files Sources and Destinations ==== + +[SourceDisksNames] +1 = %Libusb_DiskName% + +[SourceDisksFiles] +libusb0.sys = 1,\bin\x86, + +[SourceDisksFiles.amd64] +libusb0.sys = 1,\bin\amd64, + +[DestinationDirs] +libusb0_files_sys = 10,system32\drivers + +; ==== libusb0 Device driver ==== + +[libusb0_files_sys] +libusb0.sys,libusb0.sys + +; For each one of these, there must be one for Services !!! +[LIBUSB0_DEV] +CopyFiles = Libusb0_files_sys + +[LIBUSB0_DEV.HW] +AddReg = libusb0_add_reg_hw + +[libusb0_add_reg] +HKR,,DevLoader,,*ntkern +HKR,,NTMPDriver,,libusb0.sys + +[libusb0_add_reg_hw] +HKR,,DeviceInterfaceGUIDs,0x10000,%DeviceGUID% +HKR,,SurpriseRemovalOK,0x00010001,1 ; Device properties + +[LIBUSB0_DEV.Services] +AddService = libusb0, 0x00000002, libusb0_add_service + +[libusb0_add_service] +DisplayName = %libusb0_SvcDesc% +ServiceType = 1 +StartType = 3 +ErrorControl = 0 +ServiceBinary = %12%\libusb0.sys + +; ==== Manufacturers ==== + +[Manufacturer] +"HCFR Association"=HCFR_Devices,NTx86,NTamd64 +"Sequel Imaging"=Sequel_Devices,NTx86,NTamd64 +"X-Rite"=X_Rite_Devices,NTx86,NTamd64 +"ColorVision"=ColorVision_Devices,NTx86,NTamd64 +"Gretag Macbeth/X-Rite"=GM_X_Rite_Devices,NTx86,NTamd64 +"Hughski Ltd"=Hughski_Devices,NTx86,NTamd64 +"Image Engineering"=ImageEngineering_Devices,NTx86,NTamd64 + +; ==== Devices ==== diff --git a/usb/ArgyllCMS_x64.cat b/usb/ArgyllCMS_x64.cat index 24b915e..1bed3d1 100644 Binary files a/usb/ArgyllCMS_x64.cat and b/usb/ArgyllCMS_x64.cat differ diff --git a/xicc/bt1886.c b/xicc/bt1886.c index 3f94dbe..ddd6066 100644 --- a/xicc/bt1886.c +++ b/xicc/bt1886.c @@ -107,8 +107,8 @@ void bt1886_setnop(bt1886_info *p) { p->outsc = 1.0; p->outo = 0.0; p->outL = 0.0; + p->tab[0] = 0.0; p->tab[1] = 0.0; - p->tab[2] = 0.0; } /* Setup the bt1886_info for the given target black point, proportion of */ diff --git a/xicc/cam02.c b/xicc/cam02.c index 5140f04..376d2c8 100644 --- a/xicc/cam02.c +++ b/xicc/cam02.c @@ -9,7 +9,7 @@ * Conference, with the addition of the Viewing Flare * model described on page 487 of "Digital Color Management", * by Edward Giorgianni and Thomas Madden, and the - * Helmholtz-Kohlraush effect, using the equation from + * Helmholtz-Kohlrausch effect, using the equation from * the Bradford-Hunt 96C model as detailed in Mark Fairchild's * book "Color Appearance Models". * The Slight modification to the Hunt-Pointer-Estevez matrix @@ -40,7 +40,9 @@ /* TTBD: Should convert to using Timo Kunkel and Erik Reinhard's simplified - and improved version of CIECAM02 (ie. "CIECAM02-KR"). + and improved version of CIECAM02 + [ "A Neurophysiology-Inspired Steady-State Color Appearance Model", + ie. "CIECAM02-KR" ? ] The rgbp compression has it's problems in terms of perceptual uniformity. A color with one component near zero might shift @@ -105,7 +107,7 @@ XYZ space, the J value used to multiply Chroma, is limited to be equivalent to not less than A == 0.1. - The Helmholtz-Kohlraush effect is crafted to have resonable + The Helmholtz-Kohlrausch effect is crafted to have resonable effects over the range of J from 0 to 100, and have more moderate effects outside this range. @@ -136,7 +138,11 @@ #undef DISABLE_HPE /* Debug - disable just Hunt-Pointer_Estevez matrix */ #undef DISABLE_NONLIN /* Debug - wire rgbp to rgba */ #undef DISABLE_TTD /* Debug - disable ttd vector 'tilt' */ -#undef DISABLE_HHKR /* Debug - disable Helmholtz-Kohlraush */ +#undef DISABLE_HHKR /* Debug - disable Helmholtz-Kohlrausch */ + + /* We reduce the HK effect from the Hunt equation, in the */ + /* light of real wold experiments. */ +#define HHKR_MUL 0.25 /* [0.25] - Helmholtz-Kohlrausch strength multiplier */ #ifdef ENABLE_COMPR # define BC_WHMINY 0.2 /* [0.2] Compression direction minimum Y value */ @@ -169,7 +175,7 @@ #define DDULIMIT 0.34 /* [0.34] ab component k3:k1 ratio limit (must be < 1.0) */ #define SSMINcJ 0.005 /* [0.005] ab scale cJ minimum value */ #define JLIMIT 0.005 /* [0.005] J encoding cutover point straight line (0 - 1.0 range) */ -#define HKLIMIT 0.7 /* [0.7] Maximum Helmholtz-Kohlraush lift */ +#define HKLIMIT 0.7 /* [0.7] Maximum Helmholtz-Kohlrausch lift out of 1.0 */ #ifdef TRACKMINMAX double minss = 1e60; @@ -282,7 +288,7 @@ double Yf, /* Flare as a fraction of the reference white (Y range 0.0 .. 1.0) * double Yg, /* Flare as a fraction of the adapting/surround (Y range 0.0 .. 1.0) */ double Gxyz[3], /* The Glare white coordinates (typically the Ambient color) */ /* If <= 0 will Wxyz will be used. */ -int hk /* Flag, NZ to use Helmholtz-Kohlraush effect */ +int hk /* Flag, NZ to use Helmholtz-Kohlrausch effect */ ) { double tt, t1, t2; double tm[3][3]; @@ -940,9 +946,10 @@ double XYZ[3] JJ = J; #ifndef DISABLE_HHKR - /* Helmholtz-Kohlraush effect */ + /* Helmholtz-Kohlrausch effect */ if (s->hk && J < 1.0) { - double kk = C/300.0 * sin(DBL_PI * fabs(0.5 * (h - 90.0))/180.0); +// double kk = C/300.0 * sin(DBL_PI * fabs(0.5 * (h - 90.0))/180.0); + double kk = HHKR_MUL * C/300.0 * sin(DBL_PI * fabs(0.5 * (h - 90.0))/180.0); if (kk > 1e-6) /* Limit kk to a reasonable range */ kk = 1.0/(s->hklimit + 1.0/kk); JJ = J + (1.0 - (J > 0.0 ? J : 0.0)) * kk; @@ -1035,9 +1042,10 @@ double Jab[3] J = JJ; #ifndef DISABLE_HHKR - /* Undo Helmholtz-Kohlraush effect */ + /* Undo Helmholtz-Kohlrausch effect */ if (s->hk && J < 1.0) { - double kk = C/300.0 * sin(DBL_PI * fabs(0.5 * (h - 90.0))/180.0); +// double kk = C/300.0 * sin(DBL_PI * fabs(0.5 * (h - 90.0))/180.0); + double kk = HHKR_MUL * C/300.0 * sin(DBL_PI * fabs(0.5 * (h - 90.0))/180.0); if (kk > 1e-6) /* Limit kk to a reasonable range */ kk = 1.0/(s->hklimit + 1.0/kk); J = (JJ - kk)/(1.0 - kk); diff --git a/xicc/iccgamut.c b/xicc/iccgamut.c index a77653f..77f8fdd 100644 --- a/xicc/iccgamut.c +++ b/xicc/iccgamut.c @@ -86,7 +86,7 @@ void usage(char *diag) { fprintf(stderr," b:background Background %% of image luminance (default 20)\n"); fprintf(stderr," l:imagewhite Image white in cd.m^2 if surround = auto (default 250)\n"); fprintf(stderr," f:flare Flare light %% of image luminance (default 0)\n"); - fprintf(stderr," g:glare Flare light %% of ambient (default 1)\n"); + fprintf(stderr," g:glare Flare light %% of ambient (default %d)\n",XICC_DEFAULT_GLARE); fprintf(stderr," g:X:Y:Z Flare color as XYZ (default media white, Abs: D50)\n"); fprintf(stderr," g:x:y Flare color as x, y\n"); fprintf(stderr," -s Create special cube surface topology plot\n"); diff --git a/xicc/tiffgamut.c b/xicc/tiffgamut.c index 9ddb62b..e373fbd 100644 --- a/xicc/tiffgamut.c +++ b/xicc/tiffgamut.c @@ -96,7 +96,7 @@ void usage(void) { fprintf(stderr," b:background Background %% of image luminance (default 20)\n"); fprintf(stderr," l:imagewhite Image white in cd.m^2 if surround = auto (default 250)\n"); fprintf(stderr," f:flare Flare light %% of image luminance (default 0)\n"); - fprintf(stderr," g:glare Flare light %% of ambient (default 1)\n"); + fprintf(stderr," g:glare Flare light %% of ambient (default %d)\n",XICC_DEFAULT_GLARE); fprintf(stderr," g:X:Y:Z Flare color as XYZ (default media white, Abs: D50)\n"); fprintf(stderr," g:x:y Flare color as x, y\n"); fprintf(stderr," -O outputfile Override the default output filename.\n"); diff --git a/xicc/tiffgmts.c b/xicc/tiffgmts.c index c31f852..446ea5c 100644 --- a/xicc/tiffgmts.c +++ b/xicc/tiffgmts.c @@ -58,7 +58,7 @@ void usage(void) { fprintf(stderr," -i intent p = perceptual, r = relative colorimetric,\n"); fprintf(stderr," s = saturation, a = absolute (default), d = profile default\n"); // fprintf(stderr," P = absolute perceptual, S = absolute saturation\n"); - fprintf(stderr," -p oride l = Lab_PCS (default), j = %s Appearance Jab\n",icxcam_description(cam_default),icxcam_description(cam_default)); + fprintf(stderr," -p oride l = Lab_PCS (default), j = %s Appearance Jab\n",icxcam_description(cam_default)); fprintf(stderr," -o order n = normal (priority: lut > matrix > monochrome)\n"); fprintf(stderr," r = reverse (priority: monochrome > matrix > lut)\n"); fprintf(stderr," -c viewcond set appearance mode and viewing conditions for %s,\n",icxcam_description(cam_default)); @@ -77,7 +77,7 @@ void usage(void) { fprintf(stderr," a:adaptation Adaptation luminance in cd.m^2 (default 50.0)\n"); fprintf(stderr," b:background Background %% of image luminance (default 20)\n"); fprintf(stderr," f:flare Flare light %% of image luminance (default 0)\n"); - fprintf(stderr," g:glare Flare light %% of ambient (default 1)\n"); + fprintf(stderr," g:glare Flare light %% of ambient (default 2)\n"); fprintf(stderr," g:X:Y:Z Flare color as XYZ (default media white, Abs: D50)\n"); fprintf(stderr," g:x:y Flare color as x, y\n"); fprintf(stderr," -V L,a,b Overide normal vector direction for span\n"); diff --git a/xicc/xicc.c b/xicc/xicc.c index a7556d5..058f492 100644 --- a/xicc/xicc.c +++ b/xicc/xicc.c @@ -1704,7 +1704,7 @@ double *wp /* Provide white point if xicc is NULL */ Glare is assumed to be from the ambient light reflecting from the display and also striking the observer directly, and is (typically) defaulted - to 1% of ambient here. + to 1% of ambient here. (too low ? Typical displays are 4-10%) */ @@ -1719,7 +1719,7 @@ double *wp /* Provide white point if xicc is NULL */ vc->Lv = 250.0; /* Average viewing conditions ratio */ vc->Yb = 0.2; /* Grey world */ vc->Yf = 0.0; /* 0% flare */ - vc->Yg = 0.01; /* 1% glare */ + vc->Yg = 0.01 * XICC_DEFAULT_GLARE; /* 5% glare */ } } else if (no == 2 @@ -1733,7 +1733,7 @@ double *wp /* Provide white point if xicc is NULL */ vc->Lv = 2000.0/3.1415; /* White of the image field */ vc->Yb = 0.2; /* Grey world */ vc->Yf = 0.0; /* 0% flare */ - vc->Yg = 0.01; /* 1% glare */ + vc->Yg = 0.01 * XICC_DEFAULT_GLARE; /* 5% glare */ } } else if (no == 0 @@ -1747,7 +1747,7 @@ double *wp /* Provide white point if xicc is NULL */ vc->Lv = 500.0/3.1415; /* White of the image field */ vc->Yb = 0.2; /* Grey world */ vc->Yf = 0.0; /* 0% flare */ - vc->Yg = 0.01; /* 1% glare */ + vc->Yg = 0.01 * XICC_DEFAULT_GLARE; /* 5% glare */ } } else if (no == 1 @@ -1761,7 +1761,7 @@ double *wp /* Provide white point if xicc is NULL */ vc->Lv = 150.0; /* White of the image field */ vc->Yb = 0.2; /* Grey world */ vc->Yf = 0.0; /* 0% flare */ - vc->Yg = 0.01; /* 1% glare */ + vc->Yg = 0.01 * XICC_DEFAULT_GLARE; /* 5% glare */ } } else if (no == 4 @@ -1775,7 +1775,7 @@ double *wp /* Provide white point if xicc is NULL */ vc->Lv = 150.0; /* White of the image field */ vc->Yb = 0.2; /* Grey world */ vc->Yf = 0.0; /* 0% flare */ - vc->Yg = 0.01; /* 1% glare */ + vc->Yg = 0.01 * XICC_DEFAULT_GLARE; /* 5% glare */ } } else if (no == 3 @@ -1789,7 +1789,7 @@ double *wp /* Provide white point if xicc is NULL */ vc->Lv = 120.0; /* White of the image field */ vc->Yb = 0.2; /* Grey world */ vc->Yf = 0.0; /* 0% flare */ - vc->Yg = 0.01; /* 1% glare */ + vc->Yg = 0.01 * XICC_DEFAULT_GLARE; /* 5% glare */ } } else if (no == 5 @@ -1803,7 +1803,7 @@ double *wp /* Provide white point if xicc is NULL */ vc->Lv = 100.0; /* White of the image field */ vc->Yb = 0.2; /* Grey world */ vc->Yf = 0.0; /* 0% flare */ - vc->Yg = 0.01; /* 1% glare */ + vc->Yg = 0.01 * XICC_DEFAULT_GLARE; /* 5% glare */ } } else if (no == 6 @@ -1817,7 +1817,7 @@ double *wp /* Provide white point if xicc is NULL */ vc->Lv = 80.0; /* White of the image field */ vc->Yb = 0.2; /* Grey world */ vc->Yf = 0.0; /* 0% flare */ - vc->Yg = 0.01; /* 1% glare */ + vc->Yg = 0.01 * XICC_DEFAULT_GLARE; /* 5% glare */ } } else if (no == 7 @@ -1831,7 +1831,7 @@ double *wp /* Provide white point if xicc is NULL */ vc->Lv = 80.0; /* White of the image field */ vc->Yb = 0.2; /* Grey world */ vc->Yf = 0.0; /* 0% flare */ - vc->Yg = 0.01; /* 1% glare */ + vc->Yg = 0.01 * XICC_DEFAULT_GLARE; /* 5% glare */ } } else if (no == 8 @@ -1845,7 +1845,7 @@ double *wp /* Provide white point if xicc is NULL */ vc->Yb = 0.2; /* Grey world */ vc->Lv = 1000.0/3.1415; /* White of the image field */ vc->Yf = 0.0; /* 0% flare */ - vc->Yg = 0.01; /* 1% glare */ + vc->Yg = 0.01 * XICC_DEFAULT_GLARE; /* 5% glare */ } } else if (no == 9 @@ -1884,7 +1884,7 @@ double *wp /* Provide white point if xicc is NULL */ vc->La = 53.0; /* Dim, adapted to slide ? */ vc->Yb = 0.2; /* Grey world */ vc->Yf = 0.0; /* 0% flare */ - vc->Yg = 0.01; /* 1% glare */ + vc->Yg = 0.01 * XICC_DEFAULT_GLARE; /* 5% glare */ } } else { @@ -2023,6 +2023,7 @@ char *as /* Alias string selector, NULL for none */ gmi->gamcknf = 0.0; gmi->gamxknf = 0.0; gmi->gampwf = 0.0; + gmi->gamlpwf = 0.0; /* No Linear Preserving Perceptual surface wghtg. factor */ gmi->gamswf = 0.0; gmi->satenh = 0.0; /* No saturation enhancement */ } @@ -2055,6 +2056,7 @@ char *as /* Alias string selector, NULL for none */ gmi->gamcknf = 0.0; gmi->gamxknf = 0.0; gmi->gampwf = 0.0; + gmi->gamlpwf = 0.0; /* No Linear Preserving Perceptual surface wghtg. factor */ gmi->gamswf = 0.0; gmi->satenh = 0.0; /* No saturation enhancement */ } @@ -2080,6 +2082,7 @@ char *as /* Alias string selector, NULL for none */ gmi->gamcknf = 0.0; gmi->gamxknf = 0.0; gmi->gampwf = 0.0; + gmi->gamlpwf = 0.0; /* No Linear Preserving Perceptual surface wghtg. factor */ gmi->gamswf = 0.0; gmi->satenh = 0.0; /* No saturation enhancement */ } @@ -2107,6 +2110,7 @@ char *as /* Alias string selector, NULL for none */ gmi->gamcknf = 0.0; gmi->gamxknf = 0.0; gmi->gampwf = 0.0; + gmi->gamlpwf = 0.0; /* No Linear Preserving Perceptual surface wghtg. factor */ gmi->gamswf = 0.0; gmi->satenh = 0.0; /* No saturation enhancement */ } @@ -2133,6 +2137,7 @@ char *as /* Alias string selector, NULL for none */ gmi->gamcknf = 0.0; /* No knee in gamut compress */ gmi->gamxknf = 0.0; /* No knee in gamut expand */ gmi->gampwf = 0.0; /* No Perceptual surface weighting factor */ + gmi->gamlpwf = 0.0; /* No Linear Preserving Perceptual surface wghtg. factor */ gmi->gamswf = 0.0; /* No Saturation surface weighting factor */ gmi->satenh = 0.0; /* No saturation enhancement */ } @@ -2158,9 +2163,10 @@ char *as /* Alias string selector, NULL for none */ gmi->bph = gmm_bendBP; /* extent and bend */ gmi->gamcpf = 1.0; /* Full gamut compression */ gmi->gamexf = 0.0; /* No gamut expansion */ - gmi->gamcknf = 0.9; /* 0.9 High Sigma knee in gamut compress */ + gmi->gamcknf = 1.0; /* Full Sigma knee in gamut compress */ gmi->gamxknf = 0.0; /* No knee in gamut expand */ gmi->gampwf = 1.0; /* Full Perceptual surface weighting factor */ + gmi->gamlpwf = 0.0; /* No Linear Preserving Perceptual surface wghtg. factor */ gmi->gamswf = 0.0; /* No Saturation surface weighting factor */ gmi->satenh = 0.0; /* No saturation enhancement */ } @@ -2184,18 +2190,49 @@ char *as /* Alias string selector, NULL for none */ gmi->bph = gmm_bendBP; /* extent and bend */ gmi->gamcpf = 1.0; /* Full gamut compression */ gmi->gamexf = 0.0; /* No gamut expansion */ - gmi->gamcknf = 0.9; /* 0.9 High Sigma knee in gamut compress */ + gmi->gamcknf = 1.0; /* Full Sigma knee in gamut compress */ gmi->gamxknf = 0.0; /* No knee in gamut expand */ gmi->gampwf = 1.0; /* Full Perceptual surface weighting factor */ + gmi->gamlpwf = 0.0; /* No Linear Preserving Perceptual surface wghtg. factor */ gmi->gamswf = 0.0; /* No Saturation surface weighting factor */ gmi->satenh = 0.0; /* No saturation enhancement */ } else if (no == 7 + || (as != NULL && stricmp(as,"lp") == 0)) { + + /* Align neutral axes and perceptually map white and black points, */ + /* perceptually compress out of gamut and map appearance space Jab to Jab, */ + /* and heavily weight preserving the luminance over saturation. */ + /* No neutral axis sigma enhancement. */ + no = 7; + gmi->as = "lp"; + gmi->desc = "lp - Luminance Preserving Perceptual"; + gmi->icci = icPerceptual; + gmi->usecas = perccas; /* Appearance space */ +// gmi->usecas = 0; /* Lab space */ + gmi->usemap = 1; /* Use gamut mapping */ + gmi->greymf = 1.0; /* Fully align grey axis */ + gmi->glumwcpf = 1.0; /* Fully compress grey axis at white end */ + gmi->glumwexf = 1.0; /* Fully expand grey axis at white end */ + gmi->glumbcpf = 1.0; /* Fully compress grey axis at black end */ + gmi->glumbexf = 1.0; /* Fully expand grey axis at black end */ + gmi->glumknf = 0.3; /* Low Sigma knee in grey compress/expand */ + gmi->bph = gmm_bendBP; /* extent and bend */ + gmi->gamcpf = 1.0; /* Full gamut compression */ + gmi->gamexf = 0.0; /* No gamut expansion */ + gmi->gamcknf = 1.3; /* [1.3] High Sigma knee in gamut compress */ + gmi->gamxknf = 0.0; /* No knee in gamut expand */ + gmi->gampwf = 0.0; /* No Perceptual weighting factor */ + gmi->gamlpwf = 1.0; /* Full Linear Preserving Perceptual wghtg. factor */ + gmi->gamswf = 0.0; /* No Saturation weighting factor */ + gmi->satenh = 0.0; /* No saturation enhancement */ + } + else if (no == 8 || (as != NULL && stricmp(as,"ms") == 0)) { /* Align neutral axes and perceptually map white and black points, */ /* perceptually compress and expand to match gamuts and map Jab to Jab. */ - no = 7; + no = 8; gmi->as = "ms"; gmi->desc = "ms - Saturation"; gmi->icci = icSaturation; @@ -2210,18 +2247,19 @@ char *as /* Alias string selector, NULL for none */ gmi->bph = gmm_bendBP; /* extent and bend */ gmi->gamcpf = 1.0; /* Full gamut compression */ gmi->gamexf = 1.0; /* Full gamut expansion */ - gmi->gamcknf = 1.0; /* High Sigma knee in gamut compress/expand */ - gmi->gamxknf = 0.4; /* Moderate Sigma knee in gamut compress/expand */ + gmi->gamcknf = 1.1; /* Sigma knee in gamut compress */ + gmi->gamxknf = 0.4; /* Moderate Sigma knee in gamut expand */ gmi->gampwf = 0.2; /* Slight perceptual surface weighting factor */ + gmi->gamlpwf = 0.0; /* No Linear Preserving Perceptual surface wghtg. factor */ gmi->gamswf = 0.8; /* Most saturation surface weighting factor */ gmi->satenh = 0.0; /* No saturation enhancement */ } - else if (no == 8 + else if (no == 9 || no == icxSaturationGMIntent || (as != NULL && stricmp(as,"s") == 0)) { /* Same as "ms" but enhance saturation */ - no = 8; + no = 9; gmi->as = "s"; gmi->desc = " s - Enhanced Saturation [ICC Saturation]"; gmi->icci = icSaturation; @@ -2236,17 +2274,18 @@ char *as /* Alias string selector, NULL for none */ gmi->bph = gmm_bendBP; /* extent and bend */ gmi->gamcpf = 1.0; /* Full gamut compression */ gmi->gamexf = 1.0; /* Full gamut expansion */ - gmi->gamcknf = 1.0; /* High sigma knee in gamut compress */ + gmi->gamcknf = 1.1; /* High sigma knee in gamut compress */ gmi->gamxknf = 0.5; /* Moderate sigma knee in gamut expand */ gmi->gampwf = 0.0; /* No Perceptual surface weighting factor */ + gmi->gamlpwf = 0.0; /* No Linear Preserving Perceptual surface wghtg. factor */ gmi->gamswf = 1.0; /* Full Saturation surface weighting factor */ gmi->satenh = 0.9; /* Medium saturation enhancement */ } - else if (no == 9 + else if (no == 10 || (as != NULL && stricmp(as,"al") == 0)) { /* Map absolute L*a*b* to L*a*b* and clip out of gamut */ - no = 9; + no = 10; gmi->as = "al"; gmi->desc = "al - Absolute Colorimetric (Lab)"; gmi->icci = icAbsoluteColorimetric; @@ -2264,15 +2303,16 @@ char *as /* Alias string selector, NULL for none */ gmi->gamcknf = 0.0; gmi->gamxknf = 0.0; gmi->gampwf = 0.0; + gmi->gamlpwf = 0.0; /* No Linear Preserving Perceptual surface wghtg. factor */ gmi->gamswf = 0.0; gmi->satenh = 0.0; /* No saturation enhancement */ } - else if (no == 10 + else if (no == 11 || (as != NULL && stricmp(as,"rl") == 0)) { /* Align neutral axes and linearly map white point, then */ /* map L*a*b* to L*a*b* and clip out of gamut */ - no = 10; + no = 11; gmi->as = "rl"; gmi->desc = "rl - White Point Matched Colorimetric (Lab)"; gmi->icci = icRelativeColorimetric; @@ -2290,6 +2330,7 @@ char *as /* Alias string selector, NULL for none */ gmi->gamcknf = 0.0; gmi->gamxknf = 0.0; gmi->gampwf = 0.0; + gmi->gamlpwf = 0.0; /* No Linear Preserving Perceptual surface wghtg. factor */ gmi->gamswf = 0.0; gmi->satenh = 0.0; /* No saturation enhancement */ } @@ -2344,6 +2385,7 @@ icxGMappingIntent *gmi /* Gamut Mapping parameters to return */ printf(" Gamut compression knee factor %f\n", gmi->gamcknf); printf(" Gamut expansion knee factor %f\n", gmi->gamxknf); printf(" Gamut Perceptual mapping weighting factor %f\n", gmi->gampwf); + printf(" Gamut Lightness Preserving Perceptual mapping weighting %f\n", gmi->gamlpwf); printf(" Gamut Saturation mapping weighting factor %f\n", gmi->gamswf); printf(" Saturation enhancement factor %f\n", gmi->satenh); } diff --git a/xicc/xicc.h b/xicc/xicc.h index f521de2..a5ecf95 100644 --- a/xicc/xicc.h +++ b/xicc/xicc.h @@ -194,6 +194,8 @@ typedef struct { char *desc; /* Possible description of this VC */ } icxViewCond; +#define XICC_DEFAULT_GLARE 5 /* Default glare in % */ + /* Method of black point adaptation */ typedef enum { gmm_BPadpt = 0, /* Adapt source black point to destination */ @@ -222,6 +224,7 @@ typedef struct { double gamcknf; /* Gamut compression knee factor, 0.0 - 1.0 */ double gamxknf; /* Gamut expansion knee factor, 0.0 - 1.0 */ double gampwf; /* Gamut Perceptual Map weighting factor, 0.0 - 1.0 */ + double gamlpwf; /* Gamut Lightness preserving perceptual Map whtg. factor, 0.0 - 1.0 */ double gamswf; /* Gamut Saturation Map weighting factor, 0.0 - 1.0 */ double satenh; /* Saturation enhancement value, 0.0 - Inf */ char *as; /* Alias string (option name) */ diff --git a/xicc/xicclu.c b/xicc/xicclu.c index 0ca00aa..f8fb9d6 100644 --- a/xicc/xicclu.c +++ b/xicc/xicclu.c @@ -116,7 +116,7 @@ void usage(char *diag) { fprintf(stderr," b:background Background %% of image luminance (default 20)\n"); fprintf(stderr," l:imagewhite Image white in cd.m^2 if surround = auto (default 250)\n"); fprintf(stderr," f:flare Flare light %% of image luminance (default 0)\n"); - fprintf(stderr," g:glare Flare light %% of ambient (default 1)\n"); + fprintf(stderr," g:glare Flare light %% of ambient (default %d)\n",XICC_DEFAULT_GLARE); fprintf(stderr," g:X:Y:Z Flare color as XYZ (default media white, Abs: D50)\n"); fprintf(stderr," g:x:y Flare color as x, y\n"); fprintf(stderr,"\n"); diff --git a/yajl/afiles b/yajl/afiles index 9292ab8..00a884b 100644 --- a/yajl/afiles +++ b/yajl/afiles @@ -25,8 +25,6 @@ yajl_parse.h yajl_parser.c yajl_parser.h yajl_test.c -yajl_test.exe -yajl_test.obj yajl_tree.c yajl_tree.h yajl_version.c -- cgit v1.2.3