From e2d30e0583c047a4bedf4c8d0c86320f1b3fd8ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 11 Jul 2018 22:19:41 +0200 Subject: some changes --- usb/ArgyllCMS.inf | 464 ++++++++++++++++++++++++++-------------------------- usb/ArgyllCMS.inf.d | 80 ++++----- usb/ArgyllCMS.inf.t | 224 ++++++++++++------------- 3 files changed, 384 insertions(+), 384 deletions(-) diff --git a/usb/ArgyllCMS.inf b/usb/ArgyllCMS.inf index e4d702f..c1865cf 100755 --- a/usb/ArgyllCMS.inf +++ b/usb/ArgyllCMS.inf @@ -1,232 +1,232 @@ -;-------------------------------------------------------------------------- -; 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 -"i1 Studio (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_6008 -"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 -"i1 Studio (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_6008 -"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 -"i1 Studio (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_6008 -"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 +"i1 Studio (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_6008 +"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 +"i1 Studio (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_6008 +"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 +"i1 Studio (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_6008 +"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 9cb0292..225eb9c 100755 --- a/usb/ArgyllCMS.inf.d +++ b/usb/ArgyllCMS.inf.d @@ -1,40 +1,40 @@ - -[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 -"i1 Studio (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_6008 -"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 +"i1 Studio (Argyll)" = LIBUSB0_DEV, USB\VID_0765&PID_6008 +"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 100755 --- 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 ==== -- cgit v1.2.3 From a0442ed58dee48a521ea053083ea967894507898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 11 Jul 2018 22:19:56 +0200 Subject: New upstream version 2.0.1+repack --- Jambase | 4 + Readme.txt | 6 +- doc/ArgyllDoc.html | 800 ++++++++++++++- doc/ChangesSummary.html | 2509 ++++++++++++++++++++++++----------------------- doc/XRGA.html | 24 +- doc/collink.html | 130 ++- doc/instruments.html | 219 ++++- doc/profcheck.html | 16 +- doc/spec2cie.html | 24 + doc/spotread.html | 50 +- gamut/gammap.c | 2 + h/aconfig.h | 9 +- h/counters.h | 6 +- icc/Jamfile | 2 +- icc/icc.c | 240 ++--- icc/icc.h | 62 +- link/collink.c | 1422 ++++++++++++++------------- log.txt | 42 +- makepackagebin.sh | 7 + namedc/namedc.c | 8 +- numlib/Jamfile | 4 +- numlib/afiles | 5 + numlib/dhsx.c | 11 +- numlib/dhsx.h | 6 +- numlib/dnsq.c | 1 + numlib/dnsq.h | 3 +- numlib/dnsqtest.c | 2 +- numlib/gnewt.c | 413 ++++++++ numlib/gnewt.h | 59 ++ numlib/ludecomp.c | 73 +- numlib/ludecomp.h | 26 +- numlib/numlib.h | 2 + numlib/numsup.c | 200 +++- numlib/numsup.h | 45 +- numlib/powell.c | 712 +++++++++++--- numlib/powell.h | 23 +- numlib/quadprog.c | 35 +- numlib/quadprog.h | 18 +- numlib/rand.c | 21 +- numlib/rand.h | 10 +- numlib/roots.c | 217 ++++ numlib/roots.h | 23 + numlib/tconjgrad.c | 162 +++ plot/plot.c | 346 ++++--- plot/plot.h | 30 + profile/colverify.c | 2 +- profile/mppcheck.c | 2 +- profile/mppprof.c | 8 +- profile/printcal.c | 2 +- profile/profcheck.c | 4 +- profile/profin.c | 3 +- profile/profout.c | 3 +- ref/linear.cal | 2 +- ref/strange.cal | 2 +- render/render.h | 2 +- rspl/Jamfile | 2 +- rspl/smtmpp.c | 1 + rspl/smtnd.c | 1 + rspl/t2d.c | 1 + rspl/t2ddf.c | 1 + rspl/t3d.c | 1 + rspl/t3ddf.c | 1 + spectro/ccxxmake.c | 16 +- spectro/chartread.c | 15 +- spectro/colorhug.c | 12 +- spectro/conv.c | 3 + spectro/dispcal.c | 32 +- spectro/dispread.c | 10 +- spectro/dispsup.c | 46 +- spectro/dispsup.h | 18 +- spectro/disptechs.c | 2 +- spectro/dispwin.c | 4 + spectro/ex1.c | 2 +- spectro/i1d3.c | 6 +- spectro/i1d3.h | 20 +- spectro/i1pro_imp.c | 171 +++- spectro/i1pro_imp.h | 37 +- spectro/icoms.c | 10 + spectro/icoms.h | 3 + spectro/icoms_nt.c | 11 + spectro/illumread.c | 6 +- spectro/inst.c | 59 +- spectro/inst.h | 6 +- spectro/instappsup.c | 30 +- spectro/instappsup.h | 5 +- spectro/instlib.ksh | 1 + spectro/kleink10.c | 21 +- spectro/linear.cal | 2 +- spectro/munki_imp.c | 4 +- spectro/sa_conv.h | 4 + spectro/spec2cie.c | 129 ++- spectro/specbos.c | 64 +- spectro/specbos.h | 4 +- spectro/spotread.c | 100 +- spectro/spyd2.c | 2 +- spectro/ss.c | 5 +- spectro/ss_imp.c | 34 +- spectro/strange.cal | 2 +- spectro/vtpglut.c | 10 + spectro/xrga.c | 15 +- target/ofps.c | 1 + target/prand.c | 1 + target/targen.c | 2 + tweak/refine.c | 2 +- usb/ArgyllCMS.cat | Bin 3635 -> 3635 bytes usb/ArgyllCMS_x64.cat | Bin 3619 -> 3619 bytes xicc/bt1886.c | 2 +- xicc/bt1886.h | 3 +- xicc/ccmx.c | 7 - xicc/ccss.c | 10 +- xicc/ccttest.c | 1 + xicc/cgatsplot.c | 1 + xicc/cv.c | 1 + xicc/cvtest.c | 1 + xicc/mpp.c | 8 +- xicc/mpplu.c | 1 + xicc/specplot.c | 1 + xicc/specsubsamp.c | 1 + xicc/spectest.c | 11 +- xicc/spectest2.c | 7 +- xicc/transplot.c | 1 + xicc/xcal.c | 1 + xicc/xdgb.c | 2 +- xicc/xfit.c | 2 +- xicc/xicc.c | 1 + xicc/xicclu.c | 2 +- xicc/xlutfix.c | 3 +- xicc/xspect.c | 306 +++--- xicc/xspect.h | 27 +- 129 files changed, 6380 insertions(+), 3014 deletions(-) mode change 100644 => 100755 doc/ArgyllDoc.html mode change 100644 => 100755 doc/ChangesSummary.html create mode 100755 numlib/gnewt.c create mode 100755 numlib/gnewt.h create mode 100755 numlib/roots.c create mode 100755 numlib/roots.h create mode 100755 numlib/tconjgrad.c diff --git a/Jambase b/Jambase index a54a03f..3d046e4 100755 --- a/Jambase +++ b/Jambase @@ -647,6 +647,10 @@ if $(NT) Wbemuuid.lib Version.lib ; + if $(MSVCVER) >= 8 { + STDLIBS += psapi.lib ; + } + SHSTDLIBS ?= $(STDLIBS) ; LINKFLAG ?= ; STDHDRS ?= $(MSNTSDK)\\Include ; diff --git a/Readme.txt b/Readme.txt index 38c9ce1..82e9ee1 100755 --- a/Readme.txt +++ b/Readme.txt @@ -1,8 +1,8 @@ -Argyll CMS README file - Version 2.0.0 +Argyll CMS README file - Version 2.0.1 -------------------------------------- -Date: 17th November 2017 +Date: 9th July 2018 Author: Graeme Gill Introduction @@ -26,7 +26,7 @@ provided for each major tool, and a general guide to using the tools for typical color management tasks is also available. A mailing list provides support for more advanced usage. -This is Version 2.0.0, a feature and bug fix update to the last major release V1.9.2. +This is Version 2.0.1, a bug fix update to the last major release V2.0.0. The first public release of icclib was in November 1998, and of Argyll was in October 2000. Code development commenced in 1995. See Changes Summary for an overview of changes since the last release. Changes diff --git a/doc/ArgyllDoc.html b/doc/ArgyllDoc.html old mode 100644 new mode 100755 index 8463fcf..f346f18 --- a/doc/ArgyllDoc.html +++ b/doc/ArgyllDoc.html @@ -10,9 +10,9 @@ Argyll Documentation Top -

ArgyllCMS documentation index (V2.0.0)
+

ArgyllCMS documentation index (V2.0.1)

- Date:   17th November 2017
+ Date:   9th July 2018
Author: Graeme Gill

Introduction

ArgyllCMS is an ICC compatible color management system, available as @@ -35,24 +35,13 @@ general guide to using the tools for typical color management tasks is also available. A mailing list provides support for more advanced usage.
-

This is Version 2.0.0, a feature and bug fix update to the last - major releaseV1.9.2. The first public release of icclib was in - November 1998, and of ArgyllCMS was in October 2000. Code - development commenced in 1995. See 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.

+

This is Version 2.0.1, a bug fix update to the last major release + V2.0.0. The first public release of icclib was in November 1998, + and of ArgyllCMS was in October 2000. Code development commenced + in 1995. See 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.

@@ -146,6 +135,12 @@ + + + + + + @@ -175,13 +170,13 @@ 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
+ 12) Apple OS X10.12 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, 10 - 64 bit.
-

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

but may well compile and run correctly in many more than this.

This is a command line terminal only environment. Those unfamiliar with command line environments @@ -276,6 +271,12 @@ + + + + + + @@ -301,6 +302,12 @@ + + + + + + @@ -392,6 +399,12 @@ + + + + + + @@ -462,6 +475,12 @@ + + + + + + @@ -600,6 +619,12 @@ + + + + + + @@ -732,6 +757,12 @@ + + + + + + @@ -863,6 +894,12 @@ + + + + + + @@ -996,6 +1033,12 @@ + + + + + + @@ -1127,6 +1170,12 @@ + + + + + + @@ -1258,6 +1307,12 @@ + + + + + + @@ -1272,14 +1327,13 @@ colorimeter.
    ColorMunki Design - or Photo           - - spot and "swipe" reflective/emissive spectrometer (UV cut only).
-                                                             - - - - The i1Studio version of this instrument is also reported to - work.
+ or Photo or i1Studio
+             +             +             +               +          - spot and "swipe" + reflective/emissive spectrometer (UV cut only).
                                    @@ -1308,8 +1362,8 @@                                                       -        Quato Silver Haze 3 OEM and HP - DreamColor  i1d3 are also reported to work.]
+        Quato Silver Haze 3 OEM,  HP + DreamColor & Wacom i1d3 are also reported to work.]
    Eye-One Pro2                                - spot and @@ -1462,6 +1516,12 @@ + + + + + + @@ -1594,6 +1654,12 @@ + + + + + + @@ -1735,6 +1801,12 @@ + + + + + + @@ -1869,6 +1941,12 @@ + + + + + + @@ -2007,6 +2085,12 @@ + + + + + + @@ -2158,6 +2242,12 @@ + + + + + + @@ -2184,6 +2274,12 @@ + + + + + + @@ -2221,6 +2317,12 @@ + + + + + + @@ -2244,6 +2346,12 @@ + + + + + + @@ -2342,6 +2450,12 @@ + + + + + + @@ -2527,6 +2641,12 @@ + + + + + + @@ -2656,6 +2776,12 @@ + + + + + + @@ -2880,6 +3006,12 @@ calibration + + + + + + @@ -2912,6 +3044,12 @@ calibration + + + + + + @@ -2922,7 +3060,9 @@ calibration Little Argyll GUI by Russell Cottrell, and for cameras or scanners, CoCa by Andrew - Stawowczyk Long.
+ Stawowczyk Long. Another GUI worth looking at is Coloris, by Rémi and Lionel + Wetteren.

Others can be found with a suitable search.
@@ -3054,6 +3194,12 @@ href="http://www.google.com/search?hl=en&source=hp&q=argyllcms+GUI&a + + + + + + @@ -3200,6 +3346,12 @@ href="http://www.google.com/search?hl=en&source=hp&q=argyllcms+GUI&a + + + + + + @@ -3332,6 +3484,12 @@ href="http://www.google.com/search?hl=en&source=hp&q=argyllcms+GUI&a + + + + + + @@ -3464,6 +3622,12 @@ href="http://www.google.com/search?hl=en&source=hp&q=argyllcms+GUI&a + + + + + + @@ -3599,6 +3763,12 @@ href="http://www.google.com/search?hl=en&source=hp&q=argyllcms+GUI&a + + + + + + @@ -3731,6 +3901,12 @@ href="http://www.google.com/search?hl=en&source=hp&q=argyllcms+GUI&a + + + + + + @@ -4014,6 +4190,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -4147,6 +4329,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -4280,6 +4468,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -4415,6 +4609,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -4549,6 +4749,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -4682,6 +4888,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -4815,6 +5027,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -4953,6 +5171,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -5090,6 +5314,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -5224,6 +5454,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -5357,6 +5593,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -5429,6 +5671,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -5562,6 +5810,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -5625,6 +5879,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -5759,6 +6019,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -5891,6 +6157,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -6024,6 +6296,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -6158,6 +6436,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -6293,6 +6577,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -6426,6 +6716,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -6558,6 +6854,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -6691,6 +6993,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -6824,6 +7132,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -6957,6 +7271,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -7098,6 +7418,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -7230,6 +7556,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -7363,6 +7695,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -7498,6 +7836,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -7630,6 +7974,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -7762,6 +8112,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -7893,6 +8249,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -8029,6 +8391,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -8160,6 +8528,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -8235,6 +8609,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -8367,6 +8747,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -8500,6 +8886,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -8635,6 +9027,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -8773,6 +9171,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -8912,6 +9316,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -8948,6 +9358,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -9083,6 +9499,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -9215,6 +9637,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -9348,6 +9776,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -9481,6 +9915,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -9613,6 +10053,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -9747,6 +10193,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -9879,6 +10331,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -10012,6 +10470,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -10151,6 +10615,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -10284,6 +10754,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -10418,6 +10894,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -10555,6 +11037,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -10688,6 +11176,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -10820,6 +11314,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -10952,6 +11452,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -11084,6 +11590,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -11217,6 +11729,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -11349,6 +11867,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -11481,6 +12005,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -11613,6 +12143,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -11749,6 +12285,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -11786,6 +12328,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -11919,6 +12467,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -12051,6 +12605,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -12184,6 +12744,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -12321,6 +12887,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -12453,6 +13025,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -12586,6 +13164,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -12724,6 +13308,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -12857,6 +13447,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -12991,6 +13587,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -13125,6 +13727,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -13256,6 +13864,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -13388,6 +14002,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -13520,6 +14140,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -13653,6 +14279,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -13785,6 +14417,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -13918,6 +14556,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -14055,6 +14699,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -14189,6 +14839,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -14322,6 +14978,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -14482,6 +15144,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -14613,6 +15281,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -14744,6 +15418,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -14879,6 +15559,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -15011,6 +15697,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -15142,6 +15834,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -15281,6 +15979,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -15412,6 +16116,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -15543,6 +16253,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -15674,6 +16390,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -15805,6 +16527,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + @@ -15941,6 +16669,12 @@ href="http://www.google.com/search?hl=en&q=windows+command+prompt+tutorial"> + + + + + + diff --git a/doc/ChangesSummary.html b/doc/ChangesSummary.html old mode 100644 new mode 100755 index 354437d..1327552 --- a/doc/ChangesSummary.html +++ b/doc/ChangesSummary.html @@ -1,1155 +1,1184 @@ - - - - - - - - - - Argyll CMS changes since last release - - -

Summary of Argyll CMS Changes since last release

-

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

-

[V1.9.2 -> V2.0.0] 17th November 2017

- -

[V1.9.1 -> V1.9.2] 17th October 2016

- -

[V1.8.3 -> V1.9.1] 28th September 2016

- -

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

- -

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

- -

[V1.8.0 -> V1.8.1] 4th September 2015

- -

[V1.7.0 -> V1.8.0] 20th August 2015

- -

[V1.6.3 -> V1.7.0] 1st May 2015

- -

[V1.6.2 -> V1.6.3] 26th January 2014

- -

[V1.6.1 -> V1.6.2] 18th November 2013

- -

[V1.6.0 -> V1.6.1] 30th September 2013

- -

[V1.5.1 -> V1.6.0] 16th August 2013

- -

[V1.5.0 -> V1.5.1] 8th March 2013

- -

[V1.4.0 -> V1.5.0] 1st March 2013

- -

[V1.3.7 -> V1.4.0] 20th April 2012

- -

[V1.3.6 -> V1.3.7] 26th March 2012

- -

[V1.3.5 -> V1.3.6] 19th March 2012
-

- -

[V1.3.4 -> V1.3.5] 24th October 2011

- -

[V1.3.3 -> V1.3.4] 31st August 2011

- -

[V1.3.2 -> V1.3.3] 13th May 2011

- - -

[V1.3.1 -> V1.3.2] 4th November 2010
-

- -

[V1.3.0 -> V1.3.1] 26th October 2010
-

- -

[V1.2.0 -> V1.3.0] 8th September 2010
-

- -

[V1.1.1 -> V1.2.0] 30 July 2010
-

- -

[V1.1.0 -> V1.1.1] 21 February 2010
-

- -

[V1.0.4 -> V1.1.0] 17th January 2010
-

- -

[V1.0.3 -> V1.0.4] 30th June 2009
-

- -

[V1.0.2 -> V1.0.3] 3rd September 2008
-

- +

[V0.70 Beta 8 -> V1.0.0] 1st July 2008
+

+
+ Apart from numerous bug fixes and many minor feature additions and + improvements, the main changes to this version compared to the + previous one are:
+ + As usual, a more detailed description of all changes is in the log.txt + file that accompanies the source code. +

[V0.60 -> V0.70 Beta 8]15th January 2008
+

+ +
+
+
+


+  
+  
+  
+  
+  
+  

+
+ + diff --git a/doc/XRGA.html b/doc/XRGA.html index 778b8bd..d0ce315 100755 --- a/doc/XRGA.html +++ b/doc/XRGA.html @@ -28,15 +28,16 @@ href="https://www.xrite.com/documents/literature/en/L7-462_XRGA_WhitePaper_en.pd + + is possible between these different standards. While such a conversion is not perfect, it reduces the discontinuities between old instrument families and current X-Rite instruments.

By default, Argyll will use the native calibration of Gretag-Macbeth and X-Rite instruments. These are summarized here:
-
 
- +
+ Design, Photo or i1Studio
+ @@ -137,5 +139,21 @@ href="https://www.xrite.com/documents/literature/en/L7-462_XRGA_WhitePaper_en.pd You can also convert from one standard to the other using spec2cie.

+ For informational purposes, the native calibration of some other + Gretag-Macbeth and X-Rite instruments are:
+
+
DTP20 @@ -76,7 +77,8 @@ href="https://www.xrite.com/documents/literature/en/L7-462_XRGA_WhitePaper_en.pd
ColorMunki - Design or Photo XRGA
+ + + + + + +
HP Z printer Sensor 
+
GMDI
+
+
+
+
diff --git a/doc/collink.html b/doc/collink.html index b746c5d..fbb1aaa 100755 --- a/doc/collink.html +++ b/doc/collink.html @@ -18,6 +18,9 @@ inverting the forward profile,  to allow black ink regeneration or to retain the source black characteristic from the source profile.
+
+ The -O option allows creation of a device + link that contains just per channel calibration curves.

Usage Summary

collink [-options] srcprofile dstprofile linkedprofile
@@ -132,6 +136,7 @@ existing + profile, rather than link (Debug option)

@@ -232,6 +238,7 @@ preserve + device curves in result
@@ -303,6 +310,7 @@ Include + abstract profile in link
@@ -311,7 +319,7 @@ Include href="#a">-a file.cal        Apply calibration curves to link output and append linear
-  -H file.cal        +  -H file.cal        @@ -329,8 +337,11 @@ Include - Append calibration curves to 3dlut
+ + Append calibration curves to 3dlut
+  -O file.cal        + Use just calibration curves as link and append linear
 -s                 @@ -375,6 +386,7 @@ Mode + (default)
@@ -426,6 +438,7 @@ Gamut + Mapping Mode using inverse outprofile A2B [optional source gamut]


@@ -633,6 +649,7 @@ aw + Absolute Colorimetric (in Jab) with scaling to fit white point

@@ -724,6 +742,7 @@ r + White Point Matched Appearance [ICC Relative Colorimetric]


@@ -957,6 +981,7 @@ s + Enhanced Saturation [ICC Saturation]

 


@@ -1470,6 +1507,7 @@ Adaptatation + luminance in cd.m^2 (default 50.0)
         + g:glare       Glare light % of ambient (default 5)
          @@ -1603,6 +1644,7 @@ light + g:X:Y:Z       Glare color as XYZ @@ -1636,6 +1678,7 @@ light + g:x:y         Glare color @@ -1649,11 +1692,13 @@ light + m:mtaf        Mid-tone partial adaptation factor (default 0.0)
          + m:X:Y:Z       Mid-tone Adaptation white as XYZ (default D50)
@@ -1705,6 +1750,7 @@ source + total ink limit, 0 - 400% (estimate by default)





@@ -2091,6 +2144,7 @@ destination + Create "3DLut" output file as well as devlink
@@ -2129,6 +2183,7 @@ destination + eeColor .txt file
@@ -2155,6 +2210,7 @@ destination + MadVR .3dlut   file
@@ -2162,6 +2218,7 @@ destination c               + IRIDAS .cube file
 
-I B               @@ -2177,6 +2234,7 @@ destination + Use BT.1886 source EOTF with technical gamma 2.4
 -I b:g.g           Use @@ -2225,6 +2283,7 @@ destination + Video encode input as:
@@ -2262,6 +2321,7 @@ destination + Video encode output as:
@@ -2346,6 +2408,7 @@ destination + RGB (16-235)/255 "TV" levels, clip WTW [Input Only]
@@ -2373,6 +2436,7 @@ destination + Rec601 YCbCr SD (16-235,240)/255 "TV" levels
@@ -2400,6 +2464,7 @@ destination + Rec709 1125/60Hz YCbCr HD (16-235,240)/255 "TV" levels
@@ -2427,6 +2492,7 @@ destination + Rec709 1250/50Hz YCbCr HD (16-235,240)/255 "TV" levels
@@ -2454,6 +2520,7 @@ destination + Rec2020 YCbCr UHD (16-235,240)/255 "TV" levels
@@ -2481,6 +2548,7 @@ destination + Rec2020 Constant Luminance YCbCr UHD (16-235,240)/255 "TV" @@ -2509,6 +2577,7 @@ destination + xvYCC Rec601 YCbCr Rec709 Prims. SD (16-235,240)/255 "TV" levels
@@ -2536,6 +2605,7 @@ destination + xvYCC Rec709 YCbCr Rec709 Prims. HD (16-235,240)/255 "TV" levels
@@ -2583,6 +2653,7 @@ gamut + gammap_p.x3d.html and gammap_s.x3d.html diagostics
@@ -2633,6 +2704,7 @@ ICC + profile. A TIFF or @@ -2684,6 +2756,7 @@ ICC + profile. A -q
@@ -2895,6 +2969,13 @@ ICC 3dLut is used by MadVR v0.86.9 or latter. By default no calibration curves are appended to a MadVR 3dLut.

+ The -O parameter causes calibration curves + in the supplied file to be use to creat the link. ICC profiles are + not expectedt or used. This option allows a device link to be used + to apply just per channel calibraion curves. Note that many normal + options will be ignored or may cause unexpected results when used + with this option.
+
The basic linking style is chosen by using the -s (default), -g or -G flags. The three behaviors are:

@@ -2994,6 +3075,7 @@ ICC +  p = perceptual, r = relative colorimetric,
@@ -3268,6 +3350,7 @@ ICC +    _______  enle
@@ -3313,6 +3396,7 @@ ICC +    /
@@ -3358,6 +3442,7 @@ ICC +   /
@@ -3403,6 +3488,7 @@ ICC +  /
@@ -3448,6 +3534,7 @@ ICC + /
@@ -3499,6 +3586,7 @@ White            &nb + Black
@@ -3704,6 +3792,7 @@ White            &nb + Full output offset with effective gamma of 2.2
-I B                  @@ -3719,6 +3808,7 @@ White            &nb + Full input offset (BT.1886 like) with technical gamma of 2.4. This exactly implements the BT.1886 specification.
-I G                  @@ -3735,6 +3825,7 @@ White            &nb + Full output offset with technical gamma of 2.2

-I b:2.3             @@ -3751,6 +3842,7 @@ White            &nb + Full input offset (BT.1886 like) with effective gamma of 2.3
-I g:2.3             @@ -3767,6 +3859,7 @@ White            &nb + Full output offset with effective gamma of 2.3
-I B:2.35           @@ -3782,6 +3875,7 @@ White            &nb + Full input offset (BT.1886 like) with technical gamma of 2.35
-I G:2.35           @@ -3797,6 +3891,7 @@ White            &nb + Full output offset with technical gamma of 2.35

-I b:0.4:2.3        @@ -3815,6 +3910,7 @@ White            &nb + Same as above.
-I B:0.4:2.35      60% input offset, 40% output offset with technical gamma of 2.35
@@ -3838,6 +3934,7 @@ White            &nb + T                @@ -3862,6 +3959,7 @@ White            &nb + RGB (16-235)/255 "TV" levels, clip WTW @@ -3874,6 +3972,7 @@ White            &nb + x                @@ -3897,6 +3996,7 @@ White            &nb + xvYCC Rec601 YCbCr Rec709 Prims. SD (16-235,240)/255 "TV" @@ -3925,6 +4025,7 @@ White            &nb + xvYCC Rec709 YCbCr Rec709 Prims. HD (16-235,240)/255 "TV" @@ -3975,6 +4076,7 @@ White            &nb + normal RGB 0..1 full range levels (default)
@@ -4002,6 +4104,7 @@ White            &nb + RGB (16-235)/255 "TV" levels
@@ -4067,6 +4172,7 @@ White            &nb + Rec709 1125/60Hz YCbCr HD (16-235,240)/255 "TV" levels
@@ -4094,6 +4200,7 @@ White            &nb + Rec709 1250/50Hz YCbCr HD (16-235,240)/255 "TV" levels
@@ -4121,6 +4228,7 @@ White            &nb + Rec2020 YCbCr UHD (16-235,240)/255 "TV" levels
@@ -4148,6 +4256,7 @@ White            &nb + Rec2020 Constant Luminance YCbCr UHD (16-235,240)/255 "TV" @@ -4165,15 +4274,17 @@ White            &nb X3DOM plots to be created that illustrate the gamut mapping generated.

- The inprofile argument specifies the - source profile. This is the color space/device we are attempting to - emulate in the overall conversion. A TIFF or JPEG file with - embedded profile may be used here.
+ The srcprofile argument specifies + the source profile. This is the color space/device we are attempting + to emulate in the overall conversion. A TIFF or JPEG file + with embedded profile may be used here. This argument must be + omitted if the -O option is used.

- The outprofile argument specifies the + The dstprofile argument specifies the destination profile. This is the device we are actually displaying on or printing to. A TIFF or JPEG file with embedded profile - may be used here.
+ may be used here.
This argument must be omitted if + the -O option is used.

The linkedprofile argument specifies the resulting device link profile. This profile will contain the @@ -4219,6 +4330,7 @@ White            &nb + Usage Scenarios page.
diff --git a/doc/instruments.html b/doc/instruments.html index 283755a..eea6fc5 100755 --- a/doc/instruments.html +++ b/doc/instruments.html @@ -60,6 +60,9 @@ + + + @@ -75,6 +78,9 @@ + + +    - Tele-Spectro-Radiometer

@@ -146,6 +152,9 @@ + + + @@ -223,6 +232,9 @@ + + + @@ -288,6 +300,9 @@ + + + @@ -353,6 +368,9 @@ + + + @@ -420,6 +438,9 @@ + + + @@ -485,6 +506,9 @@ + + + @@ -550,6 +574,9 @@ + + + @@ -615,6 +642,9 @@ + + + @@ -680,19 +710,26 @@ + + + ColorMunki - Design or Photo  + Design or Photo or i1Studio
+             +             +             +                         - spot and "swipe" reflective/emissive spectrometer (UV cut only).
-                                                              - - - The i1 Studio version of this instrument is also reported to work.
                                                            + + + [ The OEM  XEROX PhaserMeter is also reported to work. ]
    Eye-One Pro2                                - spot and @@ -805,6 +842,9 @@ + + + @@ -871,6 +911,9 @@ + + + @@ -946,6 +989,9 @@ + + + @@ -1014,6 +1060,9 @@ + + + @@ -1086,6 +1135,9 @@ + + + @@ -1170,6 +1222,9 @@ + + + @@ -1227,6 +1282,9 @@ + + + @@ -1569,6 +1627,9 @@ + + + @@ -1743,6 +1804,9 @@ + + + instructions.

@@ -1780,6 +1844,9 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e + + + @@ -1824,6 +1891,9 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e + + + @@ -1854,6 +1924,9 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e + + + @@ -1925,6 +1998,9 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e There are some OEM versions of this instrument around too, and the XEROX + + + PhaserMeter instruments (part of the Xerox PhaserMatch 5.0 package) are also reported to work.
@@ -1974,8 +2050,7 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e
Native Calibration Standard:

- Reflection measurements are natively X-Rite XRGA.
+ Reflection measurements are natively X-Rite XRGA.


@@ -2226,6 +2301,9 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e + + + @@ -2311,6 +2389,9 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e + + + @@ -2377,6 +2458,9 @@ href="http://www.image-engineering.de/iq-products/iq-tools/measurement-devices/e + + + @@ -2459,6 +2543,9 @@ Gretag + + + @@ -2520,6 +2607,9 @@ Gretag + + + Eye-One Pro Rev E) from  i1 + + + Basic Pro 2.

@@ -2555,6 +2648,9 @@ href="http://www.xrite.com/categories/calibration-profiling/i1basic-pro-2">i1 + + + Pro reflective/emissive spectrometer below for details on the operation of this type of @@ -2562,8 +2658,7 @@ href="http://www.xrite.com/categories/calibration-profiling/i1basic-pro-2">i1
Native Calibration Standard:

- Reflection measurements are natively X-Rite XRGA.XRGA.



@@ -2632,9 +2727,7 @@ href="http://www.xrite.com/categories/calibration-profiling/i1basic-pro-2">i1
Reflection measurements are natively historical Gretag MacBeth standard (GMDI) for RevA-D,
- and  natively X-Rite XRGA - for Rev E.
+ and  natively X-Rite XRGA for Rev E.

Special features:

@@ -2781,6 +2874,9 @@ href="http://www.xrite.com/categories/calibration-profiling/i1basic-pro-2">i1 + + + @@ -2834,6 +2930,9 @@ href="http://www.xrite.com/categories/calibration-profiling/i1basic-pro-2">i1 + + + @@ -2904,6 +3003,9 @@ href="http://www.xrite.com/categories/calibration-profiling/i1basic-pro-2">i1 + + + @@ -2970,6 +3072,9 @@ href="http://www.xrite.com/categories/calibration-profiling/i1basic-pro-2">i1 + + + @@ -3025,7 +3130,7 @@ href="http://xritephoto.com/ph_product_overview.aspx?id=1454&catid=109">pack href="http://www.spectracal.com/">SpectraCal OEM i1Display, ChromaPure, NEC - SpectraSensor Pro and , HP @@ -3062,8 +3167,14 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + + + DreamColor and Wacom - DreamColor instruments are also reported to work. They will + Color Manager 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 @@ -3148,6 +3259,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + Pro
are discontinued instruments. They may still be available as old stock, or second hand.
@@ -3215,6 +3329,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -3281,6 +3398,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -3372,6 +3492,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -3438,6 +3561,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -3538,6 +3664,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -3604,6 +3733,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -3795,6 +3927,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -3870,6 +4005,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -3940,6 +4078,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -4079,6 +4220,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -4154,6 +4298,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -4224,6 +4371,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -4304,6 +4454,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -4388,6 +4541,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -4454,6 +4610,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -4520,6 +4679,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -4556,6 +4718,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -4592,6 +4757,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -4627,6 +4795,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -4663,6 +4834,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -4699,6 +4873,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -4725,6 +4902,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + Cube
@@ -4763,6 +4943,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -4799,6 +4982,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + @@ -4824,6 +5010,9 @@ href="http://www8.hp.com/us/en/products/oas/product-detail.html?oid=5225568">HP + + + diff --git a/doc/profcheck.html b/doc/profcheck.html index 0676c14..6dfa27d 100755 --- a/doc/profcheck.html +++ b/doc/profcheck.html @@ -33,6 +33,7 @@ Show + CIE94 delta E values
 -k           @@ -49,6 +50,7 @@ create + X3DOM visualization (iccprofile.x3d.html)
 -x           @@ -62,6 +64,7 @@ Use + X3DOM axes
 -m              Make @@ -74,6 +77,7 @@ X3DOM + lines a minimum of 0.5
 -e              Color @@ -86,11 +90,13 @@ vectors + acording to delta E
 -s              + Sort output by delta E
 -h              @@ -100,6 +106,7 @@ vectors + Plot a histogram of delta E's
 -P de           @@ -118,6 +125,7 @@ Specify + a device value to sort against

 -p           @@ -131,6 +139,7 @@ Sort + device value by PCS/Lab target
  -f @@ -145,6 +154,7 @@ Sort + M0, M1, M2, A, C, D50 (def.), D50M2, D65, F5, F8, F10 or file.sp]
 -i illum        Choose @@ -159,6 +169,7 @@ Sort + A, C, D50 (def.), D50M2, D65, F5, F8, F10 or file.sp

@@ -175,11 +186,13 @@ Sort + 1931_2 (def.), 1964_10, 2012_2, 2012_10, S&B + 1955_2, shaw, J&V 1978_2 or file.cmf
 -I intent       r = relative @@ -217,6 +230,7 @@ Sort Device values -> Profile PCS values should + be .ti3 PCS values

The -c option causes the differences between the test values @@ -264,7 +278,7 @@ Sort is appropriate if a profcheck -h on the resulting profile no longer has a long tail. Note that using this procedure will be of no benefit if the tail is due to an inherently poor fit of the - profile to the data rather than reading innacuracy, even if it makes + profile to the data rather than reading inaccuracy, even if it makes the fit appear to be better.

NOTE that the pruning does not take any special care as to diff --git a/doc/spec2cie.html b/doc/spec2cie.html index d973289..4554531 100755 --- a/doc/spec2cie.html +++ b/doc/spec2cie.html @@ -22,6 +22,7 @@ + EMISINPUT (See the description of the .ti3 format. This would have to be done manually, as no ArgyllCMS tools generate such @@ -38,12 +39,14 @@ + output.[ti3|sp]
 
-v                        + Verbose mode
 -A NN|AX|AG|XA|XG|GA|GX   XRGA conversion (default NN)
@@ -58,10 +61,12 @@ +                + Override actual instrument illuminant in .ti3 or .sp file:
                         @@ -70,6 +75,7 @@ +          (only used in conjunction with -f)
 -f [illum] @@ -77,23 +83,27 @@ + Use Fluorescent Whitening Agent compensation [simulated inst. illum.:
                   +         M0, M1, M2, A, C, D50 (def.), D50M2, D65, F5, F8, F10 or file.sp]
 -i + illum                  + Choose illuminant for computation of CIE XYZ from spectral data & FWA:
           @@ -110,10 +120,12 @@ +              +   Choose CIE Observer for spectral data:
              @@ -121,10 +133,12 @@ +          1931_2
(def.), 1964_10, 2012_2, + 2012_10, S&B 1955_2, shaw, J&V 1978_2 or file.cmf
 -n                        @@ -140,6 +154,7 @@ output + spectral values
 -p                        @@ -148,6 +163,7 @@ output + Plot each values spectrum
 input.[ti3|sp]            @@ -239,6 +255,7 @@ output + colprof -f for a fuller explanation.

The -i parameter allows specifying a @@ -281,6 +298,13 @@ output should generally be linked with other profiles that have the same illuminant and observer.

+ If a non D50 illuminant is used, then an extra set of L*a*b* output + fields will be created in the resulting CGATS file, containing + values relative to the illuminant white point. These will be + labelled XXXLAB_L etc, where XXX is the name of the illuminant. + These are informational only, and are not used by any ArgyllCMS + tools.
+
The -o flag allows specifying a tristimulus observer, and is used to compute PCS (Profile Connection Space) tristimulus values. The following choices are available:
diff --git a/doc/spotread.html b/doc/spotread.html index 143b61e..6f09669 100755 --- a/doc/spotread.html +++ b/doc/spotread.html @@ -59,6 +59,7 @@ +       Verbose mode

@@ -295,6 +300,7 @@ + Use display white brightness relative measurement mode
@@ -323,6 +329,7 @@ + Use display white point relative chromatically adjusted mode
@@ -368,6 +375,7 @@ + Use telephoto measurement mode (absolute results)
@@ -413,6 +421,7 @@ + Use
projectorprojector @@ -550,6 +561,7 @@ + Use ambient flash measurement mode (absolute results)
@@ -594,6 +606,7 @@ + Display type - instrument specific list to choose from.

@@ -636,6 +649,7 @@ M0, + M1, M2, A, D50 (def.), D50M2, D65, F5, F8, F10 or file.sp


, 1964_10,
2012_2, 2012_10, S&B + 1955_2, shaw, J&V 1978_2 or file.cmf
@@ -794,6 +811,7 @@ D50 + Set filter configuration:
@@ -837,6 +855,7 @@ D50 + None
@@ -880,6 +899,7 @@ D50 + Polarising filter
@@ -923,6 +943,7 @@ D50 + D65
@@ -966,6 +987,7 @@ D50 + U.V. Cut
@@ -984,7 +1006,10 @@ D50 + XRGA conversion (default N)
+  -w                    + Use -i param. illuminant for comuting L*a*b*
 -x                    @@ -1026,6 +1051,7 @@ D50 + Display Yxy instead of Lab
@@ -1070,6 +1096,7 @@ D50 + Display LCh instead of Lab

@@ -1115,6 +1142,7 @@ D50 + Display Luv instead of Lab
@@ -1159,6 +1187,7 @@ D50 + Show running average and std. devation from ref.
@@ -1203,6 +1232,7 @@ D50 + Display correlated color temperatures, CRI and TLCI
@@ -1246,6 +1276,7 @@ D50 + Disable initial calibration of instrument if possible
@@ -1290,6 +1321,7 @@ D50 + Do one cal. or measure and exit
@@ -1311,6 +1343,7 @@ D50 + Preset reference to spectrum
 -X file.ccmx          @@ -1352,6 +1385,7 @@ D50 + Apply Colorimeter Correction Matrix
@@ -1400,6 +1434,7 @@ Samples + for calibration
@@ -1437,6 +1472,7 @@ Samples +      Override refresh, non-refresh display @@ -1464,6 +1500,7 @@ Samples + Override measured refresh rate with rate Hz

@@ -1485,6 +1522,7 @@ Samples + Save white tile ref. spectrum to file
 -Y L                  Test for i1Pro Lamp @@ -1537,6 +1575,7 @@ none, + h = HW, x = Xon/Xoff
@@ -1585,6 +1624,7 @@ none, + Optional file to save reading results
colprof -f for a fuller @@ -1877,9 +1920,9 @@ none,         The G argument sets the calibration to GMDI.

- The -x option causes the reading to be - displayed as XYZ and Yxy values, rather than the default XYZ and - L*a*b*
+ The -w option causes the L*a*b* reading to + converted using the -i parameter white point, + rather than the default of D50.

The -h option causes the reading to be displayed as XYZ and LCh values, rather than the default XYZ and @@ -1995,6 +2038,7 @@ none, + -Y n options overrides the refresh display mode set by the #include #include +#include "aconfig.h" #include "icc.h" #include "numlib.h" #include "xicc.h" @@ -165,6 +166,7 @@ struct { #include "vrml.h" #ifdef PLOT_LMAP #include "plot.h" +#include "ui.h" #endif /* Callback context for enhancing the saturation of the clut values */ diff --git a/h/aconfig.h b/h/aconfig.h index dde4e69..6251893 100755 --- a/h/aconfig.h +++ b/h/aconfig.h @@ -7,7 +7,7 @@ /* * Author: Graeme W. Gill * - * Copyright 2006 - 2017, Graeme W. Gill + * Copyright 2006 - 2018, Graeme W. Gill * All rights reserved. * * This material is licenced under the GNU GENERAL PUBLIC LICENSE Version 2 or later :- @@ -24,8 +24,8 @@ /* major number = 8 bits */ #ifndef USE_NG_VERSION -# define ARGYLL_VERSION 0x02000 -# define ARGYLL_VERSION_STR "2.0.0" +# define ARGYLL_VERSION 0x02001 +# define ARGYLL_VERSION_STR "2.0.1" #else # define ARGYLL_VERSION NG_VERSION # define ARGYLL_VERSION_STR "NG_VERSION_STR" @@ -54,6 +54,9 @@ # endif #endif +/* Maximum number of graphs supported by plot */ +#define MXGPHS 12 + /* Maximum file path length */ #define MAXNAMEL 1024 diff --git a/h/counters.h b/h/counters.h index 7e48e03..f84b6a2 100755 --- a/h/counters.h +++ b/h/counters.h @@ -160,7 +160,7 @@ /* ------------------------------------------------------- */ /* Macros combination counter */ /* Declare the counter name nn, combinations out of total */ -/* mxdi should be set to maximum combinations */ +/* mxdi should be set to maximum combinations. */ /* e.g. if there are 8 objects, and we want all combinations */ /* of 4 out of the 8, we would use: COMBO(nn, 4, 4, 8) */ @@ -209,7 +209,7 @@ } \ } -/* After increment, expression is TRUE if counter is done */ +/* After init or increment, expression is TRUE if counter is done */ #define CB_DONE(nn) \ (nn##_e >= nn##_cmb) @@ -272,7 +272,7 @@ } \ } -/* After increment, expression is TRUE if counter is done */ +/* After init or increment, expression is TRUE if counter is done */ #define XCB_DONE(nn) \ CB_DONE(nn) diff --git a/icc/Jamfile b/icc/Jamfile index 4bedbba..21b9dcb 100755 --- a/icc/Jamfile +++ b/icc/Jamfile @@ -41,7 +41,7 @@ MainsFromSources icctest.c lutest.c iccdump.c icclu.c iccrw.c ; # This is an example program for making a matrix display profile MainsFromSources mkDispProf.c ; -#MainsFromSources t.c ; +#MainsFromSources t2.c ; if $(BUILD_JUNK) { diff --git a/icc/icc.c b/icc/icc.c index de8c539..9c49081 100755 --- a/icc/icc.c +++ b/icc/icc.c @@ -13560,7 +13560,7 @@ void icmClamp3(double out[3], double in[3]) { out[i] = in[i] < 0.0 ? 0.0 : in[i]; } -/* Invert a 3 vector */ +/* Invert (negate) a 3 vector */ void icmInv3(double out[3], double in[3]) { int i; for (i = 0; i < 3; i++) @@ -13858,7 +13858,7 @@ double in[3][3] */ det = icmDet3x3(in); - if ( fabs(det) < ICM_SMALL_NUMBER) + if (fabs(det) < ICM_SMALL_NUMBER) return 1; /* calculate the adjoint matrix */ @@ -13871,6 +13871,23 @@ double in[3][3] return 0; } +/* Invert a 2x2 transform matrix. Return 1 if error. */ +int icmInverse2x2(double out[2][2], double in[2][2]) { + double det = det2x2(in[0][0], in[0][1], in[1][0], in[1][1]); + + if (fabs(det) < ICM_SMALL_NUMBER) + return 1; + + det = 1.0/det; + + out[0][0] = det * in[1][1]; + out[0][1] = det * -in[0][1]; + out[1][0] = det * -in[1][0]; + out[1][1] = det * in[0][0]; + + return 0; +} + /* - - - - - - - - - - - - - - - - - - - - - - - - */ /* Transpose a 3x3 matrix */ void icmTranspose3x3(double out[3][3], double in[3][3]) { @@ -14006,17 +14023,6 @@ int icmNormalize3(double out[3], double in[3], double len) { return 0; } -/* Compute the norm (length) of a vector define by two points */ -double icmNorm22(double in1[2], double in0[2]) { - int j; - double rv; - for (rv = 0.0, j = 0; j < 2; j++) { - double tt = in1[j] - in0[j]; - rv += tt * tt; - } - return sqrt(rv); -} - /* Compute the norm (length) squared of a vector define by two points */ double icmNorm33sq(double in1[3], double in0[3]) { int j; @@ -14232,143 +14238,6 @@ double icmClip4marg(double out[4], double in[4]) { /* - - - - - - - - - - - - - - - - - - - - - - - - */ -/* - - mat in out - -[ ] [] [] -[ ] [] [] -[ ] * [] => [] -[ ] [] [] -[ ] [] [] - - */ - -/* Multiply 5 array by 5x5 transform matrix */ -void icmMulBy5x5(double out[5], double mat[5][5], double in[5]) { - int i, j; - double tt[5]; - - for (i = 0; i < 5; i++) { - tt[i] = 0.0; - for (j = 0; j < 5; j++) - tt[i] += mat[i][j] * in[j]; - } - - for (i = 0; i < 5; i++) - out[i] = tt[i]; -} - -/* Transpose a 5x5 matrix */ -void icmTranspose5x5(double out[5][5], double in[5][5]) { - int i, j; - if (out != in) { - for (i = 0; i < 5; i++) - for (j = 0; j < 5; j++) - out[i][j] = in[j][i]; - } else { - double tt[5][5]; - for (i = 0; i < 5; i++) - for (j = 0; j < 5; j++) - tt[i][j] = in[j][i]; - for (i = 0; i < 5; i++) - for (j = 0; j < 5; j++) - out[i][j] = tt[i][j]; - } -} - -/* Clip a vector to the range 0.0 .. 1.0 */ -/* and return any clipping margine */ -double icmClip5marg(double out[5], double in[5]) { - int j; - double tt, marg = 0.0; - for (j = 0; j < 5; j++) { - out[j] = in[j]; - if (out[j] < 0.0) { - tt = 0.0 - out[j]; - out[j] = 0.0; - if (tt > marg) - marg = tt; - } else if (out[j] > 1.0) { - tt = out[j] - 1.0; - out[j] = 1.0; - if (tt > marg) - marg = tt; - } - } - return marg; -} - - -/* Multiply 6 array by 6x6 transform matrix */ -void icmMulBy6x6(double out[6], double mat[6][6], double in[6]) { - int i, j; - double tt[6]; - - for (i = 0; i < 6; i++) { - tt[i] = 0.0; - for (j = 0; j < 6; j++) - tt[i] += mat[i][j] * in[j]; - } - - for (i = 0; i < 6; i++) - out[i] = tt[i]; -} - -/* Transpose a 6x6 matrix */ -void icmTranspose6x6(double out[6][6], double in[6][6]) { - int i, j; - if (out != in) { - for (i = 0; i < 6; i++) - for (j = 0; j < 6; j++) - out[i][j] = in[j][i]; - } else { - double tt[6][6]; - for (i = 0; i < 6; i++) - for (j = 0; j < 6; j++) - tt[i][j] = in[j][i]; - for (i = 0; i < 6; i++) - for (j = 0; j < 6; j++) - out[i][j] = tt[i][j]; - } -} - -/* Clip a vector to the range 0.0 .. 1.0 */ -/* and return any clipping margine */ -double icmClip6marg(double out[6], double in[6]) { - int j; - double tt, marg = 0.0; - for (j = 0; j < 6; j++) { - out[j] = in[j]; - if (out[j] < 0.0) { - tt = 0.0 - out[j]; - out[j] = 0.0; - if (tt > marg) - marg = tt; - } else if (out[j] > 1.0) { - tt = out[j] - 1.0; - out[j] = 1.0; - if (tt > marg) - marg = tt; - } - } - return marg; -} - -/* - - - - - - - - - - - - - - - - - - - - - - - - */ -/* Multiply 2 array by 2x2 transform matrix */ -void icmMulBy2x2(double out[2], double mat[2][2], double in[2]) { - double tt[2]; - - tt[0] = mat[0][0] * in[0] + mat[0][1] * in[1]; - tt[1] = mat[1][0] * in[0] + mat[1][1] * in[1]; - - out[0] = tt[0]; - out[1] = tt[1]; -} - -/* - - - - - - - - - - - - - - - - - - - - - - - - */ - /* Copy a 3x4 transform matrix */ void icmCpy3x4(double dst[3][4], double src[3][4]) { int i, j; @@ -14638,6 +14507,52 @@ double icmPlaneDist3(double eq[4], double p[3]) { } /* - - - - - - - - - - - - - - - - - - - - - - - - */ + +/* Compute the norm (length) of a vector define by two points */ +double icmNorm22(double in1[2], double in0[2]) { + int j; + double rv; + for (rv = 0.0, j = 0; j < 2; j++) { + double tt = in1[j] - in0[j]; + rv += tt * tt; + } + return sqrt(rv); +} + +/* Compute the norm (length) squared of of a vector defined by two points */ +double icmNorm22sq(double in1[2], double in0[2]) { + int j; + double rv; + for (rv = 0.0, j = 0; j < 2; j++) { + double tt = in1[j] - in0[j]; + rv += tt * tt; + } + return rv; +} + +/* Multiply 2 array by 2x2 transform matrix */ +void icmMulBy2x2(double out[2], double mat[2][2], double in[2]) { + double tt[2]; + + tt[0] = mat[0][0] * in[0] + mat[0][1] * in[1]; + tt[1] = mat[1][0] * in[0] + mat[1][1] * in[1]; + + out[0] = tt[0]; + out[1] = tt[1]; +} + +/* Compute the dot product of two 2 vectors */ +double icmDot2(double in1[2], double in2[2]) { + return in1[0] * in2[0] + in1[1] * in2[1]; +} + +/* Compute the dot product of two 2 vectors defined by 4 points */ +/* 1->2 and 3->4 */ +double icmDot22(double in1[2], double in2[2], double in3[2], double in4[2]) { + return (in2[0] - in1[0]) * (in4[0] - in3[0]) + + (in2[1] - in1[1]) * (in4[1] - in3[1]); +} + /* Given 2 2D points, compute a plane equation (implicit line equation). */ /* The normal will be right handed given the order of the points */ /* The plane equation will be the 2 normal components and the constant. */ @@ -14769,7 +14684,7 @@ int icmLineIntersect2(double res[2], double p1[2], double p2[2], double p3[2], d } /* Given two finite 2D lines define by 4 points, compute their paramaterized intersection. */ -/* aprm may be NULL */ +/* aprm may be NULL. Param is prop. from p1 -> p2, p3 -> p4 */ /* Return 2 if there is no intersection (lines are parallel) */ /* Return 1 lines do not cross within their length */ int icmParmLineIntersect2(double res[2], double aprm[2], double p1[2], double p2[2], double p3[2], double p4[2]) { @@ -14803,6 +14718,23 @@ int icmParmLineIntersect2(double res[2], double aprm[2], double p1[2], double p2 return 0; } +/* Compute a blend between in0 and in1 */ +void icmBlend2(double out[2], double in0[2], double in1[2], double bf) { + out[0] = (1.0 - bf) * in0[0] + bf * in1[0]; + out[1] = (1.0 - bf) * in0[1] + bf * in1[1]; +} + +/* Scale a 2 vector by the given ratio */ +void icmScale2(double out[2], double in[2], double rat) { + out[0] = in[0] * rat; + out[1] = in[1] * rat; +} + +/* Scale a 2 vector by the given ratio and add it */ +void icmScaleAdd2(double out[3], double in2[2], double in1[2], double rat) { + out[0] = in2[0] + in1[0] * rat; + out[1] = in2[1] + in1[1] * rat; +} /* - - - - - - - - - - - - - - - - - - - - - - - - */ /* CIE Y (range 0 .. 1) to perceptual CIE 1976 L* (range 0 .. 100) */ @@ -14893,12 +14825,14 @@ icmLab2XYZ(icmXYZNumber *w, double *out, double *in) { * This is a modern update to L*a*b*, based on IPT space. * * Differences to L*a*b* and IPT: - * Using inverse CIE 2012 2degree LMS to XYZ matrix instead of Hunt-Pointer-Estevez + * Using inverse CIE 2012 2degree LMS to XYZ matrix instead of Hunt-Pointer-Estevez. * Von Kries chromatic adapation in LMS space. * Using L* compression rather than IPT pure 0.43 power. * Tweaked LMS' to IPT matrix to account for change in XYZ to LMS matrix. * Output scaled to L*a*b* type ranges, to maintain 1 JND scale. - * (Watch out - L* value is not a non-linear Y value though!). + * (Watch out - L* value is not a non-linear Y value though! + * - Interesting that Dolby force L to be just dependent on Y + * by making L = 0.5 L | 0.5 M in ICtCp space). */ /* CIE XYZ to perceptual Lpt */ diff --git a/icc/icc.h b/icc/icc.h index 1e2caf8..75b7736 100755 --- a/icc/icc.h +++ b/icc/icc.h @@ -1784,6 +1784,12 @@ extern ICCLIB_API unsigned int icmCSSig2chanNames( icColorSpaceSignature sig, ch /* Copy a 2 vector */ #define icmCpy2(d_ary, s_ary) ((d_ary)[0] = (s_ary)[0], (d_ary)[1] = (s_ary)[1]) +#define icmAdd2(d_ary, s1_ary, s2_ary) ((d_ary)[0] = (s1_ary)[0] + (s2_ary)[0], \ + (d_ary)[1] = (s1_ary)[1] + (s2_ary)[1]) + +#define icmSub2(d_ary, s1_ary, s2_ary) ((d_ary)[0] = (s1_ary)[0] - (s2_ary)[0], \ + (d_ary)[1] = (s1_ary)[1] - (s2_ary)[1]) + /* Copy a 3 vector */ #define icmCpy3(d_ary, s_ary) ((d_ary)[0] = (s_ary)[0], (d_ary)[1] = (s_ary)[1], \ (d_ary)[2] = (s_ary)[2]) @@ -1792,10 +1798,12 @@ extern ICCLIB_API unsigned int icmCSSig2chanNames( icColorSpaceSignature sig, ch #define icmCpy4(d_ary, s_ary) ((d_ary)[0] = (s_ary)[0], (d_ary)[1] = (s_ary)[1], \ (d_ary)[2] = (s_ary)[2], (d_ary)[3] = (s_ary)[3]) +/* - - - - - - - - - - - - - - */ + /* Clamp a 3 vector to be +ve */ void icmClamp3(double out[3], double in[3]); -/* Invert a 3 vector */ +/* Invert (negate) a 3 vector */ void icmInv3(double out[3], double in[3]); /* Add two 3 vectors */ @@ -1832,8 +1840,6 @@ double icmDot3(double in1[3], double in2[3]); /* Compute the cross product of two 3D vectors, out = in1 x in2 */ void icmCross3(double out[3], double in1[3], double in2[3]); -#define icmNorm2(i) sqrt((i)[0] * (i)[0] + (i)[1] * (i)[1]) - /* Compute the norm squared (length squared) of a 3 vector */ double icmNorm3sq(double in[3]); @@ -1869,9 +1875,6 @@ double icmClip3marg(double out[3], double in[3]); /* Normalise a 3 vector to the given length. Return nz if not normalisable */ int icmNormalize3(double out[3], double in[3], double len); -/* Compute the norm (length) of of a vector defined by two points */ -double icmNorm22(double in1[2], double in0[2]); - /* Compute the norm squared (length squared) of a vector defined by two points */ double icmNorm33sq(double in1[3], double in0[3]); @@ -1983,30 +1986,24 @@ double icmClip4marg(double out[4], double in[4]); /* - - - - - - - - - - - - - - - - - - - - - - - */ -/* Multiply 5 vector by 5x5 transform matrix */ -/* Organization is mat[out][in] */ -void icmMulBy5x5(double out[5], double mat[5][5], double in[5]); +#define icmNorm2(i) sqrt((i)[0] * (i)[0] + (i)[1] * (i)[1]) -/* Transpose a 5x5 matrix */ -void icmTranspose5x5(double out[5][5], double in[5][5]); - -/* Clip a vector to the range 0.0 .. 1.0 */ -/* and return any clipping margine */ -double icmClip5marg(double out[5], double in[5]); +#define icmNorm2sq(i) ((i)[0] * (i)[0] + (i)[1] * (i)[1]) +/* Compute the norm (length) of of a vector defined by two points */ +double icmNorm22(double in1[2], double in0[2]); -/* Multiply 6 vector by 6x6 transform matrix */ -/* Organization is mat[out][in] */ -void icmMulBy6x6(double out[6], double mat[6][6], double in[6]); +/* Compute the norm (length) squared of of a vector defined by two points */ +double icmNorm22sq(double in1[2], double in0[2]); -/* Transpose a 6x6 matrix */ -void icmTranspose6x6(double out[6][6], double in[6][6]); +/* Compute the dot product of two 2 vectors */ +double icmDot2(double in1[2], double in2[2]); -/* Clip a vector to the range 0.0 .. 1.0 */ -/* and return any clipping margine */ -double icmClip6marg(double out[6], double in[6]); +#define ICMDOT2(o, i, j) ((o) = (i)[0] * (j)[0] + (i)[1] * (j)[1]) -/* - - - - - - - - - - - - - - - - - - - - - - - */ +/* Compute the dot product of two 2 vectors defined by 4 points */ +/* 1->2 and 3->4 */ +double icmDot22(double in1[2], double in2[2], double in3[2], double in4[2]); /* Given 2 2D points, compute a plane equation. */ /* The normal will be right handed given the order of the points */ @@ -2038,13 +2035,26 @@ int icmLinePointClosest2(double cp[2], double *pa, int icmLineIntersect2(double res[2], double p1[2], double p2[2], double p3[2], double p4[2]); /* Given two finite 2D lines define by 4 points, compute their paramaterized intersection. */ -/* aprm may be NULL */ -/* Return nz if there is no intersection (lines are parallel or do not cross in length) */ +/* aprm may be NULL. Param is prop. from p1 -> p2, p3 -> p4 */ +/* Return 2 if there is no intersection (lines are parallel) */ +/* Return 1 lines do not cross within their length */ int icmParmLineIntersect2(double ares[2], double aprm[2], double p1[2], double p2[2], double p3[2], double p4[2]); +/* Invert a 2x2 transform matrix. Return 1 if error. */ +int icmInverse2x2(double out[2][2], double in[2][2]); + /* Multiply 2 array by 2x2 transform matrix */ void icmMulBy2x2(double out[2], double mat[2][2], double in[2]); +/* Compute a blend between in0 and in1 */ +void icmBlend2(double out[2], double in0[2], double in1[2], double bf); + +/* Scale a 2 vector by the given ratio */ +void icmScale2(double out[2], double in[2], double rat); + +/* Scale a 2 vector by the given ratio and add it */ +void icmScaleAdd2(double out[2], double in2[3], double in1[2], double rat); + /* - - - - - - - - - - - - - - */ /* Simple macro to transfer an array to an XYZ number */ diff --git a/link/collink.c b/link/collink.c index 798bc14..3172f2b 100755 --- a/link/collink.c +++ b/link/collink.c @@ -181,6 +181,18 @@ #include "gammap.h" #include "vrml.h" +/* flag usage: + + 0123456789 + . + + abcdefghijklmnopqrstuvwxyz + ....... . .. ....... .. + + ABCDEFGHIJKLMNOPQRSTUVWXYZ + . ....... . . .. .. . +*/ + void usage(char *diag, ...) { int i; fprintf(stderr,"Link ICC profiles, Version %s\n",ARGYLL_VERSION_STR); @@ -211,6 +223,7 @@ void usage(char *diag, ...) { fprintf(stderr," -p absprof Include abstract profile in link\n"); fprintf(stderr," -a file.cal Apply calibration curves to link output and append linear\n"); fprintf(stderr," -H file.cal Append calibration curves to 3dlut\n"); + fprintf(stderr," -O file.cal Use just calibration curves as link and append linear\n"); fprintf(stderr," -s Simple Mode (default)\n"); fprintf(stderr," -g [src.gam] Gamut Mapping Mode [optional source image gamut]\n"); fprintf(stderr," -G [src.gam] Gamut Mapping Mode using inverse outprofile A2B\n"); @@ -219,7 +232,7 @@ void usage(char *diag, ...) { fprintf(stderr," s = saturation, a = absolute colorimetric\n"); fprintf(stderr," -o out_intent p = perceptual, r = relative colorimetric,\n"); fprintf(stderr," s = saturation, a = absolute colorimetric\n"); - fprintf(stderr," Gamut Mapping Mode Options:\n"); + fprintf(stderr," Gamut Mapping Mode Options:\n"); fprintf(stderr," -i intent set linking intent from the following choice:\n"); for (i = 0; ; i++) { icxGMappingIntent gmi; @@ -382,6 +395,8 @@ struct _clink { /* 2 = set MadVR cal1 to cal */ xcal *cal; /* Calibration to apply, NULL if none */ + int calonly; /* calibration curve only - no ICC profile linking */ + /* (We current assume that xyzscale can't be used with gmi) */ double xyzscale; /* < 1.0 if Y is to be scaled in destination XYZ space */ double swxyz[3]; /* Source white point in XYZ */ @@ -1057,559 +1072,568 @@ void devip_devop(void *cntx, double *out, double *in) { #endif } - /* Do DevIn' -> PCS */ - switch(p->in.alg) { - case icmMonoFwdType: { - icxLuMono *lu = (icxLuMono *)p->in.luo; /* Safe to coerce */ + if (p->calonly) { - if (p->in.nocurve) { /* No explicit curve, so do implicit here */ - rv |= lu->fwd_curve(lu, pcsv, win); - rv |= lu->fwd_map(lu, pcsv, pcsv); - } else { - rv |= lu->fwd_map(lu, pcsv, win); + vect_cpy(out, win, p->cal->devchan); + + } else { + + /* Do DevIn' -> PCS */ + switch(p->in.alg) { + case icmMonoFwdType: { + icxLuMono *lu = (icxLuMono *)p->in.luo; /* Safe to coerce */ + + if (p->in.nocurve) { /* No explicit curve, so do implicit here */ + rv |= lu->fwd_curve(lu, pcsv, win); + rv |= lu->fwd_map(lu, pcsv, pcsv); + } else { + rv |= lu->fwd_map(lu, pcsv, win); + } + rv |= lu->fwd_abs(lu, pcsv, pcsv); + break; } - rv |= lu->fwd_abs(lu, pcsv, pcsv); - break; - } - case icmMatrixFwdType: { - icxLuMatrix *lu = (icxLuMatrix *)p->in.luo; /* Safe to coerce */ - icmLuMatrix *plu = (icmLuMatrix *)lu->plu; /* Safe to coerce */ + case icmMatrixFwdType: { + icxLuMatrix *lu = (icxLuMatrix *)p->in.luo; /* Safe to coerce */ + icmLuMatrix *plu = (icmLuMatrix *)lu->plu; /* Safe to coerce */ - if (p->in.nocurve) { /* No explicit curve, so do implicit here */ + if (p->in.nocurve) { /* No explicit curve, so do implicit here */ - if (p->in.tvenc == 8 || p->in.tvenc == 9) { /* xvYCC */ - if (p->in.bt1886) - bt1886_fwd_curve(&p->in.bt, pcsv, win); - else - xvYCC_fwd_curve(pcsv, win); /* Allow for overrange values */ - xvYCC_fwd_matrix(pcsv, pcsv); /* Rec709 primaries */ + if (p->in.tvenc == 8 || p->in.tvenc == 9) { /* xvYCC */ + if (p->in.bt1886) + bt1886_fwd_curve(&p->in.bt, pcsv, win); + else + xvYCC_fwd_curve(pcsv, win); /* Allow for overrange values */ + xvYCC_fwd_matrix(pcsv, pcsv); /* Rec709 primaries */ + } else { + if (p->in.bt1886) + bt1886_fwd_curve(&p->in.bt, pcsv, win); + else + rv |= lu->fwd_curve(lu, pcsv, win); + rv |= lu->fwd_matrix(lu, pcsv, pcsv); + } } else { - if (p->in.bt1886) - bt1886_fwd_curve(&p->in.bt, pcsv, win); + if (p->in.tvenc == 8 || p->in.tvenc == 9) /* xvYCC */ + xvYCC_fwd_matrix(pcsv, pcsv); /* Rec709 primaries */ else - rv |= lu->fwd_curve(lu, pcsv, win); - rv |= lu->fwd_matrix(lu, pcsv, pcsv); + rv |= lu->fwd_matrix(lu, pcsv, win); } - } else { - if (p->in.tvenc == 8 || p->in.tvenc == 9) /* xvYCC */ - xvYCC_fwd_matrix(pcsv, pcsv); /* Rec709 primaries */ - else - rv |= lu->fwd_matrix(lu, pcsv, win); - } #ifdef DEBUG - DEBUGCND printf("After matrix PCS' XYZ %s Lab %s\n",icmPdv(p->in.chan, pcsv), icmPLab(pcsv)); + DEBUGCND printf("After matrix PCS' XYZ %s Lab %s\n",icmPdv(p->in.chan, pcsv), icmPLab(pcsv)); #endif - if (p->in.bt1886) { - bt1886_wp_adjust(&p->in.bt, pcsv, pcsv); + if (p->in.bt1886) { + bt1886_wp_adjust(&p->in.bt, pcsv, pcsv); #ifdef DEBUG - DEBUGCND printf("After bt1886 PCS' XYZ %s Lab %s\n",icmPdv(p->in.chan, pcsv), icmPLab(pcsv)); + DEBUGCND printf("After bt1886 PCS' XYZ %s Lab %s\n",icmPdv(p->in.chan, pcsv), icmPLab(pcsv)); #endif - } + } - rv |= lu->fwd_abs(lu, pcsv, pcsv); + rv |= lu->fwd_abs(lu, pcsv, pcsv); - break; - } - case icmLutType: { - icxLuLut *lu = (icxLuLut *)p->in.luo; /* Safe to coerce */ - if (p->in.nocurve) { /* No explicit curve, so we've got Dev */ - /* Since not PCS, in_abs and matrix cannot be valid, */ - /* so input curve on own is ok to use. */ - rv |= lu->input(lu, pcsv, win); /* Dev -> Dev' */ - rv |= lu->clut(lu, pcsv, pcsv); /* Dev' -> PCS' */ - } else { /* We've got Dev' */ - rv |= lu->clut(lu, pcsv, win); /* Dev' -> PCS' */ + break; } - /* We've got the input profile PCS' at this point. */ + case icmLutType: { + icxLuLut *lu = (icxLuLut *)p->in.luo; /* Safe to coerce */ + if (p->in.nocurve) { /* No explicit curve, so we've got Dev */ + /* Since not PCS, in_abs and matrix cannot be valid, */ + /* so input curve on own is ok to use. */ + rv |= lu->input(lu, pcsv, win); /* Dev -> Dev' */ + rv |= lu->clut(lu, pcsv, pcsv); /* Dev' -> PCS' */ + } else { /* We've got Dev' */ + rv |= lu->clut(lu, pcsv, win); /* Dev' -> PCS' */ + } + /* We've got the input profile PCS' at this point. */ - /* If we're transfering the K value from the input profile to the */ - /* output, copy it into locus[], which will be given to the inverse */ - /* lookup function, else the inverse lookup will generate a K using */ - /* the curve parameters. */ + /* If we're transfering the K value from the input profile to the */ + /* output, copy it into locus[], which will be given to the inverse */ + /* lookup function, else the inverse lookup will generate a K using */ + /* the curve parameters. */ //printf("~1 out.inking = %d\n",p->out.inking); - if (p->out.inking == 0 || p->out.inking == 6) { - if (p->out.locus) { - /* Converts PCS' to K locus proportion */ - lu->clut_locus(lu, locus, pcsv, win); /* Compute possible locus values */ + if (p->out.inking == 0 || p->out.inking == 6) { + if (p->out.locus) { + /* Converts PCS' to K locus proportion */ + lu->clut_locus(lu, locus, pcsv, win); /* Compute possible locus values */ //printf("~1 looked up locus value\n"); - } else { - for (i = 0; i < p->in.chan; i++) /* Target is K input value */ - locus[i] = win[i]; - /* Convert K' to K value ready for aux target */ - if (!p->in.nocurve) { /* we have an input curve, so convert Dev' -> Dev */ - lu->inv_input(lu, locus, locus); - } + } else { + for (i = 0; i < p->in.chan; i++) /* Target is K input value */ + locus[i] = win[i]; + /* Convert K' to K value ready for aux target */ + if (!p->in.nocurve) { /* we have an input curve, so convert Dev' -> Dev */ + lu->inv_input(lu, locus, locus); + } //printf("~1 copied win to locus\n"); - } + } #ifdef DEBUG - DEBUGCND printf("Got possible K %s of %f %f %f %f\n",p->out.locus ? "locus" : "value", locus[0],locus[1],locus[2],locus[3]); + DEBUGCND printf("Got possible K %s of %f %f %f %f\n",p->out.locus ? "locus" : "value", locus[0],locus[1],locus[2],locus[3]); #endif + } + rv |= lu->output(lu, pcsv, pcsv); /* PCS' -> */ + rv |= lu->out_abs(lu, pcsv, pcsv); /* PCS */ + break; } - rv |= lu->output(lu, pcsv, pcsv); /* PCS' -> */ - rv |= lu->out_abs(lu, pcsv, pcsv); /* PCS */ - break; + default: + error("Unexpected algorithm type %d in devip of devip_devop()",p->in.alg); } - default: - error("Unexpected algorithm type %d in devip of devip_devop()",p->in.alg); - } - /* At this point, the PCS is: - * - * If not gamut mapped: - * Lab in the intent selected for the source profile - * If gamut mapped: - * either - * Absolute Lab - * or - * Jab derived from absolute XYZ via the in/out viewing conditions + /* At this point, the PCS is: + * + * If not gamut mapped: + * Lab in the intent selected for the source profile + * If gamut mapped: + * either + * Absolute Lab + * or + * Jab derived from absolute XYZ via the in/out viewing conditions * * and locus[] contains any auxiliar target values if the - * auxiliary is not being created by a rule applied to the PCS. - */ + * auxiliary is not being created by a rule applied to the PCS. + */ - /* - * The order to do this intermediate processing is hard to figure out, - * as is the interaction between such elements. How should the - * abstract profile be properly handled ? - * what should we do if the wphack/rgbbkhack is on and Y scaling is on ? - */ + /* + * The order to do this intermediate processing is hard to figure out, + * as is the interaction between such elements. How should the + * abstract profile be properly handled ? + * what should we do if the wphack/rgbbkhack is on and Y scaling is on ? + */ #ifdef DEBUG - DEBUGCND printf("PCS before map %f %f %f\n",pcsv[0], pcsv[1], pcsv[2]); + DEBUGCND printf("PCS before map %f %f %f\n",pcsv[0], pcsv[1], pcsv[2]); #endif - if (p->wphack) { - int e; - double dd = 0.0; - for (e = 0; e < 3; e++) { /* Does this match the input white point ? */ - double tt; - tt = pcsv[e] - p->in.wp[e]; - dd += tt * tt; - } - dd = sqrt(dd); - - if (dd < 1.0) { /* Triggered withing 1 delta E */ - if (clip == 0) /* Don't count zero's white caused by video input clipping */ - p->wphacked++; - wptrig = 1; - if (p->wphack == 2) { - for (e = 0; e < 3; e++) /* Map input white to given white */ - pcsv[e] = p->hwp[e]; - } else { - for (e = 0; e < 3; e++) /* Map input white to output white */ - pcsv[e] = p->out.wp[e]; + if (p->wphack) { + int e; + double dd = 0.0; + for (e = 0; e < 3; e++) { /* Does this match the input white point ? */ + double tt; + tt = pcsv[e] - p->in.wp[e]; + dd += tt * tt; } + dd = sqrt(dd); + + if (dd < 1.0) { /* Triggered withing 1 delta E */ + if (clip == 0) /* Don't count zero's white caused by video input clipping */ + p->wphacked++; + wptrig = 1; + if (p->wphack == 2) { + for (e = 0; e < 3; e++) /* Map input white to given white */ + pcsv[e] = p->hwp[e]; + } else { + for (e = 0; e < 3; e++) /* Map input white to output white */ + pcsv[e] = p->out.wp[e]; + } #ifndef DEBUG - if (p->verb) + if (p->verb) #endif - { - printf("White point hack mapped %f %f %f to %f %f %f, hit withing %f\n", + { + printf("White point hack mapped %f %f %f to %f %f %f, hit withing %f\n", p->in.wp[0],p->in.wp[1],p->in.wp[2],pcsv[0], pcsv[1], pcsv[2],dd); - fflush(stdout); + fflush(stdout); + } } } - } - /* Do luminence scaling if requested */ - if (wptrig == 0 && p->xyzscale < 1.0) { - double xyz[3]; + /* Do luminence scaling if requested */ + if (wptrig == 0 && p->xyzscale < 1.0) { + double xyz[3]; //printf("~1 got xyzscale = %f\n",p->xyzscale); //printf("PCS %f %f %f\n",pcsv[0], pcsv[1], pcsv[2]); - /* Convert our PCS to XYZ */ - if (p->pcsor == icxSigJabData) { - /* We're being bad in delving inside the xluo, but we'll fix it latter */ - p->out.luo->cam->cam_to_XYZ(p->out.luo->cam, xyz, pcsv); - } else - error("Internal :- not setup to handle Y scaling and non-Jab PCS"); + /* Convert our PCS to XYZ */ + if (p->pcsor == icxSigJabData) { + /* We're being bad in delving inside the xluo, but we'll fix it latter */ + p->out.luo->cam->cam_to_XYZ(p->out.luo->cam, xyz, pcsv); + } else + error("Internal :- not setup to handle Y scaling and non-Jab PCS"); //printf("XYZ %f %f %f\n",xyz[0], xyz[1], xyz[2]); - /* Scale it */ - xyz[0] *= p->xyzscale; - xyz[1] *= p->xyzscale; - xyz[2] *= p->xyzscale; + /* Scale it */ + xyz[0] *= p->xyzscale; + xyz[1] *= p->xyzscale; + xyz[2] *= p->xyzscale; //printf("scaled XYZ %f %f %f\n",xyz[0], xyz[1], xyz[2]); - /* Convert back to PCS */ - if (p->pcsor == icxSigJabData) { - /* We're being bad in delving inside the xluo, but we'll fix it latter */ - p->out.luo->cam->XYZ_to_cam(p->out.luo->cam, pcsv, xyz); - } else - error("Internal :- not setup to handle Y scaling and non-Jab PCS"); + /* Convert back to PCS */ + if (p->pcsor == icxSigJabData) { + /* We're being bad in delving inside the xluo, but we'll fix it latter */ + p->out.luo->cam->XYZ_to_cam(p->out.luo->cam, pcsv, xyz); + } else + error("Internal :- not setup to handle Y scaling and non-Jab PCS"); //printf("scaled PCS %f %f %f\n",pcsv[0], pcsv[1], pcsv[2]); #ifdef DEBUG - DEBUGCND printf("PCS after Y scale %f %f %f\n",pcsv[0], pcsv[1], pcsv[2]); + DEBUGCND printf("PCS after Y scale %f %f %f\n",pcsv[0], pcsv[1], pcsv[2]); #endif - } + } - /* Do gamut mapping */ - if (wptrig == 0 && p->mode > 0 && p->gmi.usemap) { - /* We've used pcsor to ensure PCS space is appropriate */ - - /* Doing XXXK -> XXXK */ - if (p->nhack == 2) { - /* Ideally we would create a 4D PCSK -> PCSK gamut mapping */ - /* to smoothly and accurately cope with the changing source */ - /* and destination gamuts acording to their degree of "K onlyness". */ - /* In practice we're going to simply interpolated between */ - /* two extremes: unrestricted gamut and K only black gamut. */ - double map0[3], map1[3]; - - /* Compute blend of normal gamut map and Konly to Konly gamut map */ - { - p->map->domap(p->map, map0, pcsv); - p->Kmap->domap(p->Kmap, map1, pcsv); - icmBlend3(pcsvm, map0, map1, konlyness); - } + /* Do gamut mapping */ + if (wptrig == 0 && p->mode > 0 && p->gmi.usemap) { + /* We've used pcsor to ensure PCS space is appropriate */ + + /* Doing XXXK -> XXXK */ + if (p->nhack == 2) { + /* Ideally we would create a 4D PCSK -> PCSK gamut mapping */ + /* to smoothly and accurately cope with the changing source */ + /* and destination gamuts acording to their degree of "K onlyness". */ + /* In practice we're going to simply interpolated between */ + /* two extremes: unrestricted gamut and K only black gamut. */ + double map0[3], map1[3]; + + /* Compute blend of normal gamut map and Konly to Konly gamut map */ + { + p->map->domap(p->map, map0, pcsv); + p->Kmap->domap(p->Kmap, map1, pcsv); + icmBlend3(pcsvm, map0, map1, konlyness); + } #ifdef DEBUG - DEBUGCND printf("PCS after map0 %f %f %f map1 %f %f %f\n", map0[0], map0[1], map0[2], map1[0], map1[1], map1[2]); + DEBUGCND printf("PCS after map0 %f %f %f map1 %f %f %f\n", map0[0], map0[1], map0[2], map1[0], map1[1], map1[2]); #endif - /* Normal gamut mapping */ - } else { - { - p->map->domap(p->map, pcsvm, pcsv); + /* Normal gamut mapping */ + } else { + { + p->map->domap(p->map, pcsvm, pcsv); + } } - } #ifdef DEBUG - DEBUGCND printf("PCS after map %f %f %f\n",pcsvm[0], pcsvm[1], pcsvm[2]); + DEBUGCND printf("PCS after map %f %f %f\n",pcsvm[0], pcsvm[1], pcsvm[2]); #endif - } else { - pcsvm[0] = pcsv[0]; - pcsvm[1] = pcsv[1]; - pcsvm[2] = pcsv[2]; - } + } else { + pcsvm[0] = pcsv[0]; + pcsvm[1] = pcsv[1]; + pcsvm[2] = pcsv[2]; + } - /* Gamut mapped PCS value is now in pcsvm[] */ - - /* Abstract profile transform, PCS -> PCS */ - /* pcsor -> abstract -> pcsor conversion */ - /* We're applying any abstract profile after gamut mapping, */ - /* on the assumption is primarily being used to "correct" the */ - /* output device. Ideally the gamut mapping should take the change */ - /* the abstract profile has on the output device into account, but */ - /* currently we're not doing this... */ - if (wptrig == 0 && p->abs_luo != NULL) { - /* Abstract profile is either absolute or relative. */ - /* We need to convert the current PCS into something compatible. */ - /* This is more ugly than it really should be, so we're ignoring it. */ - /* We should really run the source through the abstract profile before */ - /* creating the gamut mapping, to be able to use abstract with gamut */ - /* mapping properly. */ - p->abs_luo->lookup(p->abs_luo, pcsvm, pcsvm); + /* Gamut mapped PCS value is now in pcsvm[] */ + + /* Abstract profile transform, PCS -> PCS */ + /* pcsor -> abstract -> pcsor conversion */ + /* We're applying any abstract profile after gamut mapping, */ + /* on the assumption is primarily being used to "correct" the */ + /* output device. Ideally the gamut mapping should take the change */ + /* the abstract profile has on the output device into account, but */ + /* currently we're not doing this... */ + if (wptrig == 0 && p->abs_luo != NULL) { + /* Abstract profile is either absolute or relative. */ + /* We need to convert the current PCS into something compatible. */ + /* This is more ugly than it really should be, so we're ignoring it. */ + /* We should really run the source through the abstract profile before */ + /* creating the gamut mapping, to be able to use abstract with gamut */ + /* mapping properly. */ + p->abs_luo->lookup(p->abs_luo, pcsvm, pcsvm); #ifdef DEBUG - DEBUGCND printf("PCS after abstract %f %f %f\n",pcsvm[0], pcsvm[1], pcsvm[2]); + DEBUGCND printf("PCS after abstract %f %f %f\n",pcsvm[0], pcsvm[1], pcsvm[2]); #endif - } + } - /* If we're using the existing B2A inking to determine K, */ - /* lookup the output profiles K value for this PCS */ - if (p->mode >= 2 && p->out.inking == 7) { - double tdevv[MAX_CHAN]; + /* If we're using the existing B2A inking to determine K, */ + /* lookup the output profiles K value for this PCS */ + if (p->mode >= 2 && p->out.inking == 7) { + double tdevv[MAX_CHAN]; //printf("~1 dealing with out.inking = %d\n",p->out.inking); - if (p->out.alg != icmLutType || p->out.c->header->colorSpace != icSigCmykData) - error ("Attempting to use non-CMYK output profile to determine K inking"); + if (p->out.alg != icmLutType || p->out.c->header->colorSpace != icSigCmykData) + error ("Attempting to use non-CMYK output profile to determine K inking"); - /* Lookup PCS in B2A of output profile to get target K value */ + /* Lookup PCS in B2A of output profile to get target K value */ //printf("~1 looking up pcs %f %f %f in B2A\n", pcsvm[0], pcsvm[1], pcsvm[2]); - p->out.b2aluo->lookup(p->out.b2aluo, tdevv, pcsvm); + p->out.b2aluo->lookup(p->out.b2aluo, tdevv, pcsvm); //printf("~1 resulting dev %f %f %f %f\n", tdevv[0], tdevv[1], tdevv[2], tdevv[3]); - if (p->out.locus) { - double tpcsv[MAX_CHAN]; - icxLuLut *lu = (icxLuLut *)p->out.luo; /* Safe to coerce */ + if (p->out.locus) { + double tpcsv[MAX_CHAN]; + icxLuLut *lu = (icxLuLut *)p->out.luo; /* Safe to coerce */ - /* Convert PCS to PCS' ready for locus lookup */ - lu->in_abs(lu, tpcsv, pcsvm); - lu->matrix(lu, tpcsv, tpcsv); - lu->input(lu, tpcsv, tpcsv); - lu->clut_locus(lu, locus, tpcsv, tdevv); /* Compute locus values */ - } else { - for (i = 0; i < p->out.chan; i++) /* Target is K value */ - locus[i] = tdevv[i]; - } + /* Convert PCS to PCS' ready for locus lookup */ + lu->in_abs(lu, tpcsv, pcsvm); + lu->matrix(lu, tpcsv, tpcsv); + lu->input(lu, tpcsv, tpcsv); + lu->clut_locus(lu, locus, tpcsv, tdevv); /* Compute locus values */ + } else { + for (i = 0; i < p->out.chan; i++) /* Target is K value */ + locus[i] = tdevv[i]; + } #ifdef DEBUG - DEBUGCND printf("Got possible K %s of %f %f %f %f\n",p->out.locus ? "locus" : "value", locus[0],locus[1],locus[2],locus[3]); + DEBUGCND printf("Got possible K %s of %f %f %f %f\n",p->out.locus ? "locus" : "value", locus[0],locus[1],locus[2],locus[3]); #endif - } + } - /* Do PCS -> DevOut' */ - if (p->nhack == 3 /* All to K only */ - || ntrig /* Neutral or K only to K only hack has triggered */ - || cmytrig /* 100% CMY rough hack has triggered */ - || rgbbktrig) { /* RGB black inpu thas triggered */ - - if (p->nhack == 3 || ntrig) { /* Neutral to K only hack has triggered */ - co pp; - pp.p[0] = pcsvm[0]; /* Input L value */ - p->pcs2k->interp(p->pcs2k, &pp); /* L -> K' */ - if (pp.v[0] < 0.0) /* rspl might have extrapolated */ - pp.v[0] = 0.0; - else if (pp.v[0] > 1.0) - pp.v[0] = 1.0; - out[0] = out[1] = out[2] = 0.0; /* We know output is CMYK' */ - out[3] = pp.v[0]; + /* Do PCS -> DevOut' */ + if (p->nhack == 3 /* All to K only */ + || ntrig /* Neutral or K only to K only hack has triggered */ + || cmytrig /* 100% CMY rough hack has triggered */ + || rgbbktrig) { /* RGB black inpu thas triggered */ + + if (p->nhack == 3 || ntrig) { /* Neutral to K only hack has triggered */ + co pp; + pp.p[0] = pcsvm[0]; /* Input L value */ + p->pcs2k->interp(p->pcs2k, &pp); /* L -> K' */ + if (pp.v[0] < 0.0) /* rspl might have extrapolated */ + pp.v[0] = 0.0; + else if (pp.v[0] > 1.0) + pp.v[0] = 1.0; + out[0] = out[1] = out[2] = 0.0; /* We know output is CMYK' */ + out[3] = pp.v[0]; #ifndef DEBUG - if (p->verb) + if (p->verb) #endif - if (ntrig) { - printf("Neutral hack mapped %s to 0 0 0 %f\n", icmPdv(p->in.chan,win), out[3]); - fflush(stdout); - } - } else if (cmytrig) { /* 100% CMY rough hack has triggered */ - if (cmytrig & 1) { - out[0] = 1.0; - out[1] = out[2] = out[3] = 0.0; - } - if (cmytrig & 2) { - out[1] = 1.0; - out[0] = out[2] = out[3] = 0.0; - } - if (cmytrig & 4) { - out[2] = 1.0; - out[0] = out[1] = out[3] = 0.0; - } + if (ntrig) { + printf("Neutral hack mapped %s to 0 0 0 %f\n", icmPdv(p->in.chan,win), out[3]); + fflush(stdout); + } + } else if (cmytrig) { /* 100% CMY rough hack has triggered */ + if (cmytrig & 1) { + out[0] = 1.0; + out[1] = out[2] = out[3] = 0.0; + } + if (cmytrig & 2) { + out[1] = 1.0; + out[0] = out[2] = out[3] = 0.0; + } + if (cmytrig & 4) { + out[2] = 1.0; + out[0] = out[1] = out[3] = 0.0; + } #ifndef DEBUG - if (p->verb) + if (p->verb) #endif - if (cmytrig != 0) { - if (p->in.chan == 4) - printf("CMY hack mapped %s to %s\n",icmPdv(p->in.chan, win), icmPdv(p->out.chan, out)); - fflush(stdout); + if (cmytrig != 0) { + if (p->in.chan == 4) + printf("CMY hack mapped %s to %s\n",icmPdv(p->in.chan, win), icmPdv(p->out.chan, out)); + fflush(stdout); + } + } else if (rgbbktrig) { + out[0] = out[1] = out[2] = 0.0; } - } else if (rgbbktrig) { - out[0] = out[1] = out[2] = 0.0; - } #ifdef DEBUG - DEBUGCND printf("DevOut' after hack trigger %s\n\n",icmPdv(p->out.chan, out)); + DEBUGCND printf("DevOut' after hack trigger %s\n\n",icmPdv(p->out.chan, out)); #endif - } else { /* Various hacks haven't triggered */ + } else { /* Various hacks haven't triggered */ - switch(p->out.alg) { - case icmMonoBwdType: { - icxLuMono *lu = (icxLuMono *)p->out.luo; /* Safe to coerce */ + switch(p->out.alg) { + case icmMonoBwdType: { + icxLuMono *lu = (icxLuMono *)p->out.luo; /* Safe to coerce */ - rv |= lu->bwd_abs(lu, pcsvm, pcsvm); - rv |= lu->bwd_map(lu, out, pcsvm); - if (p->out.nocurve) { /* No explicit curve, so do implicit here */ - rv |= lu->bwd_curve(lu, out, out); - } - break; - } - case icmMatrixBwdType: { - icxLuMatrix *lu = (icxLuMatrix *)p->out.luo; /* Safe to coerce */ - - rv |= lu->bwd_abs(lu, pcsvm, pcsvm); - rv |= lu->bwd_matrix(lu, out, pcsvm); - if (p->out.nocurve) { /* No explicit curve, so do implicit here */ - rv |= lu->bwd_curve(lu, out, out); + rv |= lu->bwd_abs(lu, pcsvm, pcsvm); + rv |= lu->bwd_map(lu, out, pcsvm); + if (p->out.nocurve) { /* No explicit curve, so do implicit here */ + rv |= lu->bwd_curve(lu, out, out); + } + break; } - break; - } - case icmLutType: { - icxLuLut *lu = (icxLuLut *)p->out.luo; /* Safe to coerce */ + case icmMatrixBwdType: { + icxLuMatrix *lu = (icxLuMatrix *)p->out.luo; /* Safe to coerce */ - if (p->mode < 2) { /* Using B2A table */ - rv |= lu->in_abs(lu, pcsvm, pcsvm); - rv |= lu->matrix(lu, pcsvm, pcsvm); - rv |= lu->input(lu, pcsvm, pcsvm); - rv |= lu->clut(lu, out, pcsvm); + rv |= lu->bwd_abs(lu, pcsvm, pcsvm); + rv |= lu->bwd_matrix(lu, out, pcsvm); if (p->out.nocurve) { /* No explicit curve, so do implicit here */ - rv |= lu->output(lu, out, out); + rv |= lu->bwd_curve(lu, out, out); } + break; + } + case icmLutType: { + icxLuLut *lu = (icxLuLut *)p->out.luo; /* Safe to coerce */ - } else { /* Use inverse A2B table */ - int i; + if (p->mode < 2) { /* Using B2A table */ + rv |= lu->in_abs(lu, pcsvm, pcsvm); + rv |= lu->matrix(lu, pcsvm, pcsvm); + rv |= lu->input(lu, pcsvm, pcsvm); + rv |= lu->clut(lu, out, pcsvm); + if (p->out.nocurve) { /* No explicit curve, so do implicit here */ + rv |= lu->output(lu, out, out); + } + + } else { /* Use inverse A2B table */ + int i; #ifdef USE_MERGE_CLUT_OPT # pragma message("!!!!!!!!!!!! USE_MERGE_CLUT_OPT turned on !!!!!!!!!") - /* Because we have used the ICX_MERGE_CLUT flag, we don't need */ - /* to call inv_out_abs() and inv_output() */ + /* Because we have used the ICX_MERGE_CLUT flag, we don't need */ + /* to call inv_out_abs() and inv_output() */ #else - rv |= lu->inv_out_abs(lu, pcsvm, pcsvm); - rv |= lu->inv_output(lu, pcsvm, pcsvm); + rv |= lu->inv_out_abs(lu, pcsvm, pcsvm); + rv |= lu->inv_output(lu, pcsvm, pcsvm); #endif #ifdef DEBUG - DEBUGCND printf("Calling inv_clut with K aux targets %f %f %f %f and pcsvm %f %f %f %f\n", - locus[0],locus[1],locus[2],locus[3],pcsvm[0],pcsvm[1],pcsvm[2],pcsvm[3]); + DEBUGCND printf("Calling inv_clut with K aux targets %f %f %f %f and pcsvm %f %f %f %f\n", + locus[0],locus[1],locus[2],locus[3],pcsvm[0],pcsvm[1],pcsvm[2],pcsvm[3]); #endif - /* locus[] contains possible K target or locus value, */ - /* so copy it to out[] so that inv_clut will use it. */ - for (i = 0; i < p->out.chan; i++) - out[i] = locus[i]; + /* locus[] contains possible K target or locus value, */ + /* so copy it to out[] so that inv_clut will use it. */ + for (i = 0; i < p->out.chan; i++) + out[i] = locus[i]; - rv |= lu->inv_clut(lu, out, pcsvm); + rv |= lu->inv_clut(lu, out, pcsvm); #ifdef DEBUG - DEBUGCND printf("Got result %f %f %f %f\n", out[0],out[1],out[2],out[3]); + DEBUGCND printf("Got result %f %f %f %f\n", out[0],out[1],out[2],out[3]); #endif - - if (p->out.nocurve) { /* No explicit curve, so do implicit here */ - rv |= lu->inv_input(lu, out, out); + + if (p->out.nocurve) { /* No explicit curve, so do implicit here */ + rv |= lu->inv_input(lu, out, out); + } } + break; } - break; - } - default: - error("Unexpected algorithm type %d in devop of devip_devop()",p->out.alg); - } - if (rv >= 2) - error("icc lookup failed: %d, %s",p->in.c->errc,p->in.c->err); + default: + error("Unexpected algorithm type %d in devop of devip_devop()",p->out.alg); + } + if (rv >= 2) + error("icc lookup failed: %d, %s",p->in.c->errc,p->in.c->err); #ifdef DEBUG - DEBUGCND printf("DevOut' after PCS->Dev %s\n\n",icmPdv(p->out.chan, out)); + DEBUGCND printf("DevOut' after PCS->Dev %s\n\n",icmPdv(p->out.chan, out)); #endif - } + } - if (p->cal != NULL && p->addcal == 1 && p->out.nocurve) { - p->cal->interp(p->cal, out, out); + /* Apply calibration curve */ + if (p->cal != NULL && p->addcal == 1 && p->out.nocurve) { + p->cal->interp(p->cal, out, out); #ifdef DEBUG - DEBUGCND printf("DevOut' after cal curve %s\n\n",icmPdv(p->out.chan, out)); + DEBUGCND printf("DevOut' after cal curve %s\n\n",icmPdv(p->out.chan, out)); #endif - } - - /* Video encode */ - if (p->out.nocurve && p->out.tvenc != 0) { - for (i = 0; i < p->out.chan; i++) { - if (out[i] < 0.0) - out[i] = 0.0; - else if (out[i] > 1.0) - out[i] = 1.0; - } - if (p->out.tvenc == 1) { /* Video 16-235 range */ - icmRGB_2_VidRGB(out, out); - } else if (p->out.tvenc == 3) { /* Rec601 YCbCr */ - icmRec601_RGBd_2_YPbPr(out, out); - icmRecXXX_YPbPr_2_YCbCr(out, out); - } else if (p->out.tvenc == 4) { /* Rec709 1150/60/2:1 YCbCr */ - icmRec709_RGBd_2_YPbPr(out, out); - icmRecXXX_YPbPr_2_YCbCr(out, out); - } else if (p->out.tvenc == 5) { /* Rec709 1250/50/2:1 YCbCr */ - icmRec709_50_RGBd_2_YPbPr(out, out); - icmRecXXX_YPbPr_2_YCbCr(out, out); - } else if (p->out.tvenc == 6) { /* Rec2020 Non-constant Luminance YCbCr encoding */ - icmRec2020_NCL_RGBd_2_YPbPr(out, out); - icmRecXXX_YPbPr_2_YCbCr(out, out); - } else if (p->out.tvenc == 7) { /* Rec2020 Constant Luminance YCbCr encoding */ - icmRec2020_CL_RGBd_2_YPbPr(out, out); - icmRecXXX_YPbPr_2_YCbCr(out, out); } + /* Video encode */ + if (p->out.nocurve && p->out.tvenc != 0) { + for (i = 0; i < p->out.chan; i++) { + if (out[i] < 0.0) + out[i] = 0.0; + else if (out[i] > 1.0) + out[i] = 1.0; + } + if (p->out.tvenc == 1) { /* Video 16-235 range */ + icmRGB_2_VidRGB(out, out); + } else if (p->out.tvenc == 3) { /* Rec601 YCbCr */ + icmRec601_RGBd_2_YPbPr(out, out); + icmRecXXX_YPbPr_2_YCbCr(out, out); + } else if (p->out.tvenc == 4) { /* Rec709 1150/60/2:1 YCbCr */ + icmRec709_RGBd_2_YPbPr(out, out); + icmRecXXX_YPbPr_2_YCbCr(out, out); + } else if (p->out.tvenc == 5) { /* Rec709 1250/50/2:1 YCbCr */ + icmRec709_50_RGBd_2_YPbPr(out, out); + icmRecXXX_YPbPr_2_YCbCr(out, out); + } else if (p->out.tvenc == 6) { /* Rec2020 Non-constant Luminance YCbCr encoding */ + icmRec2020_NCL_RGBd_2_YPbPr(out, out); + icmRecXXX_YPbPr_2_YCbCr(out, out); + } else if (p->out.tvenc == 7) { /* Rec2020 Constant Luminance YCbCr encoding */ + icmRec2020_CL_RGBd_2_YPbPr(out, out); + icmRecXXX_YPbPr_2_YCbCr(out, out); + } + #ifdef NEVER - else if (p->out.tvenc == 8) { /* SD xvYCC with Rec601 YCbCr encoding */ - icmRec601_RGBd_2_YPbPr(out, out); - icmRecXXX_YPbPr_2_YCbCr(out, out); - } else if (p->out.tvenc == 9) { /* HD xvYCC with Rec709 YCbCr encoding */ - icmRec709_RGBd_2_YPbPr(out, out); - icmRecXXX_YPbPr_2_YCbCr(out, out); - } + else if (p->out.tvenc == 8) { /* SD xvYCC with Rec601 YCbCr encoding */ + icmRec601_RGBd_2_YPbPr(out, out); + icmRecXXX_YPbPr_2_YCbCr(out, out); + } else if (p->out.tvenc == 9) { /* HD xvYCC with Rec709 YCbCr encoding */ + icmRec709_RGBd_2_YPbPr(out, out); + icmRecXXX_YPbPr_2_YCbCr(out, out); + } #endif /* NEVER */ #ifdef DEBUG - DEBUGCND printf("DevOut' after TVenc %s\n",icmPdv(p->out.chan, out)); + DEBUGCND printf("DevOut' after TVenc %s\n",icmPdv(p->out.chan, out)); #endif - } + } - if (clip && p->out.nocurve && p->out.tvenc != 0) { + if (clip && p->out.nocurve && p->out.tvenc != 0) { - /* For RGB encoding, unscale +ve clip to preserve hue */ - if (p->out.tvenc == 1) { /* RGB Video 16-235 range */ + /* For RGB encoding, unscale +ve clip to preserve hue */ + if (p->out.tvenc == 1) { /* RGB Video 16-235 range */ - if (!p->in.tvclip && scale > 1.0) { /* We got +ve clipping */ + if (!p->in.tvclip && scale > 1.0) { /* We got +ve clipping */ - /* Re-scale all non-black values */ - for (i = 0; i < 3; i++) { - if (out[i] > (16.0/255.0)) - out[i] = (out[i] - 16.0/255.0) * scale + 16.0/255.0; + /* Re-scale all non-black values */ + for (i = 0; i < 3; i++) { + if (out[i] > (16.0/255.0)) + out[i] = (out[i] - 16.0/255.0) * scale + 16.0/255.0; + } } - } - /* Deal with -ve clipping and sync */ - for (i = 0; i < 3; i++) { - if (clip & (1 << i)) { + /* Deal with -ve clipping and sync */ + for (i = 0; i < 3; i++) { + if (clip & (1 << i)) { - if (full[i] == 0.0) { /* Only extrapolate in black direction */ - double ifull = 1.0 - full[i]; /* Opposite limit to full */ + if (full[i] == 0.0) { /* Only extrapolate in black direction */ + double ifull = 1.0 - full[i]; /* Opposite limit to full */ + + /* Do simple extrapolation (Not perfect though) */ + out[i] = ifull + (out[i] - ifull) * (uci[i] - ifull)/(cin[i] - ifull); + } - /* Do simple extrapolation (Not perfect though) */ - out[i] = ifull + (out[i] - ifull) * (uci[i] - ifull)/(cin[i] - ifull); - } - - /* Clip or pass sync through */ - if (out[i] < 0.0 || out[i] > 1.0 /* clip */ + /* Clip or pass sync through */ + if (out[i] < 0.0 || out[i] > 1.0 /* clip */ #ifdef PRESERVE_SYNC - || fabs(uci[i] - full[i]) < 1e-6 /* or input is at sync level */ + || fabs(uci[i] - full[i]) < 1e-6 /* or input is at sync level */ #endif - ) - out[i] = full[i]; + ) + out[i] = full[i]; + } } - } - /* For YCrCb, do simple linear extrapolation of out of range input. */ - /* (Note we should really change this to preserve hue instead !) */ - } else { - for (i = 0; i < 3; i++) { - if (clip & (1 << i)) { - double ifull = 1.0 - full[i]; /* Opposite limit to full */ - - /* Do simple extrapolation (Not perfect though) */ - out[i] = ifull + (out[i] - ifull) * (uci[i] - ifull)/(cin[i] - ifull); - - if (out[i] < 0.0 || out[i] > 1.0 /* clip */ + /* For YCrCb, do simple linear extrapolation of out of range input. */ + /* (Note we should really change this to preserve hue instead !) */ + } else { + for (i = 0; i < 3; i++) { + if (clip & (1 << i)) { + double ifull = 1.0 - full[i]; /* Opposite limit to full */ + + /* Do simple extrapolation (Not perfect though) */ + out[i] = ifull + (out[i] - ifull) * (uci[i] - ifull)/(cin[i] - ifull); + + if (out[i] < 0.0 || out[i] > 1.0 /* clip */ #ifdef PRESERVE_SYNC - || fabs(uci[i] - full[i]) < 1e-6 /* or input is at sync level */ + || fabs(uci[i] - full[i]) < 1e-6 /* or input is at sync level */ #endif - ) - out[i] = full[i]; + ) + out[i] = full[i]; + } } } - } #ifdef DEBUG - DEBUGCND printf("DevOut' after TVenc un-clip %s\n",icmPdv(p->out.chan, out)); + DEBUGCND printf("DevOut' after TVenc un-clip %s\n",icmPdv(p->out.chan, out)); #endif - } + } - /* For eeColor and Full range RGB, make sure that the cLUT output maps to 1.0 */ - /* The output curve will correct this, irrespective of out.nocurve */ - if (p->tdlut == 1) { /* eeColor encoded input */ - /* ~~ it's not clear if this re-scaling would help with other */ - /* encodings like xvYCC ? */ - if (p->out.tvenc == 0) { /* Full range RGB */ - for (i = 0; i < 3; i++) { - out[i] /= p->coscale[i]; - if (out[i] > 1.0) - out[i] = 1.0; - } + /* For eeColor and Full range RGB, make sure that the cLUT output maps to 1.0 */ + /* The output curve will correct this, irrespective of out.nocurve */ + if (p->tdlut == 1) { /* eeColor encoded input */ + /* ~~ it's not clear if this re-scaling would help with other */ + /* encodings like xvYCC ? */ + if (p->out.tvenc == 0) { /* Full range RGB */ + for (i = 0; i < 3; i++) { + out[i] /= p->coscale[i]; + if (out[i] > 1.0) + out[i] = 1.0; + } #ifdef DEBUG - DEBUGCND printf("DevOut' after eeColor de-scale %s\n\n",icmPdv(p->out.chan, out)); + DEBUGCND printf("DevOut' after eeColor de-scale %s\n\n",icmPdv(p->out.chan, out)); #endif + } } - } - /* lcurve is incompatible with coscale and tvenc ?? */ - if (p->out.lcurve) { /* Apply Y to L* to make output perceptual */ + /* lcurve is incompatible with coscale and tvenc ?? */ + if (p->out.lcurve) { /* Apply Y to L* to make output perceptual */ #ifdef DEBUG - DEBUGCND printf("DevOut' before y2l_curve %s\n\n",icmPdv(p->out.chan, out)); + DEBUGCND printf("DevOut' before y2l_curve %s\n\n",icmPdv(p->out.chan, out)); #endif - y2l_curve(out, out, p->out.lcurve == 2); - } + y2l_curve(out, out, p->out.lcurve == 2); + } #ifdef DEBUG - DEBUGCND printf("DevIn'->DevOut' ret %s\n\n",icmPdv(p->out.chan, out)); + DEBUGCND printf("DevIn'->DevOut' ret %s\n\n",icmPdv(p->out.chan, out)); #endif + } /* Not calonly */ + if (p->verb) { /* Output percent intervals */ int pc; p->count++; @@ -1694,6 +1718,7 @@ void devop_devo(void *cntx, double *out, double *in) { #ifdef DEBUG DEBUGCND printf("After output curve %s\n",icmPdv(p->out.chan, out)); #endif + /* Apply calibration curve */ if (p->cal != NULL && p->addcal == 1) { p->cal->interp(p->cal, out, out); @@ -1711,7 +1736,15 @@ void devop_devo(void *cntx, double *out, double *in) { DEBUGCND printf("After Video encode %s\n",icmPdv(p->out.chan, out)); } #endif + + /* Apply calibration curve */ + } else if (p->calonly && p->cal != NULL && p->addcal == 1) { + p->cal->interp(p->cal, out, out); +#ifdef DEBUG + DEBUGCND printf("After calibration curve %s\n",icmPdv(p->out.chan, out)); +#endif } + #ifdef DEBUG DEBUGCND printf("DevOut'->DevOut ret %s\n",icmPdv(p->out.chan, out)); #endif @@ -1841,13 +1874,13 @@ int write_cube_3DLut(clink *li, icc *icc, char *fname); int main(int argc, char *argv[]) { int fa, nfa, mfa; /* argument we're looking at */ - char in_name[MAXNAMEL+1]; + char in_name[MAXNAMEL+1] = "\000"; char sgam_name[MAXNAMEL+1] = "\000"; /* Source gamut name */ char abs_name[MAXNAMEL+1] = "\000"; /* Abstract profile name */ char cal_name[MAXNAMEL+1] = "\000"; /* Calibration filename */ - char out_name[MAXNAMEL+1]; - char link_name[MAXNAMEL+1]; - char tdlut_name[MAXNAMEL+1]; + char out_name[MAXNAMEL+1] = "\000"; + char link_name[MAXNAMEL+1] = "\000"; + char tdlut_name[MAXNAMEL+1] = "\000"; int verify = 0; /* Do verify pass */ int outinkset = 0; /* The user specfied an output inking */ int intentset = 0; /* The user specified an intent */ @@ -1855,6 +1888,7 @@ main(int argc, char *argv[]) { int modeset = 0; /* The gamut mapping mode was set by the user */ int addcal = 0; /* 1 = Incorporate cal. curves in 3dLUT and set linear MadVR cal1 */ /* 2 = Set 3dLut MadVR cal1 to calibration curves */ + int calonly = 0; /* calibration curve only - no ICC profile linking */ int rv = 0; icxViewCond ivc, ovc; /* Viewing Condition Overrides for in and out profiles */ int ivc_e = -1, ovc_e = -1; /* Enumerated viewing condition */ @@ -1946,7 +1980,7 @@ main(int argc, char *argv[]) { /* Process the arguments */ mfa = 3; /* Minimum final arguments */ - for(fa = 1;fa < argc;fa++) { + for (fa = 1; fa < argc; fa++) { nfa = fa; /* skip to nfa if next argument is used */ if (argv[fa][0] == '-') { /* Look for any flags */ @@ -2100,10 +2134,23 @@ main(int argc, char *argv[]) { /* Calibration curves */ else if (argv[fa][1] == 'a' + || argv[fa][1] == 'O' || argv[fa][1] == 'H') { addcal = 1; if (argv[fa][1] == 'H') addcal = 2; + if (argv[fa][1] == 'O') { + calonly = 1; + + /* Hmm. Make on the fly change to mfa... */ + mfa = 1; + if (na == NULL && (fa+1+mfa) < argc) { + if (argv[fa+1][0] != '-') { + nfa = fa + 1; + na = argv[nfa]; /* next is seperate non-flag argument */ + } + } + } if (na == NULL) usage("Expected calibration filename after -%c",argv[fa][1]); fa = nfa; strncpy(cal_name,na,MAXNAMEL); cal_name[MAXNAMEL] = '\000'; @@ -2577,12 +2624,21 @@ main(int argc, char *argv[]) { } #endif - if (fa >= argc || argv[fa][0] == '-') usage("Missing input profile"); - strncpy(in_name,argv[fa++],MAXNAMEL); in_name[MAXNAMEL] = '\000'; + /* Is this a link created just from a calibration file ? */ + if (calonly) { /* yes */ + li.calonly = calonly; - if (fa >= argc || argv[fa][0] == '-') usage("Missing output profile"); - strncpy(out_name,argv[fa++],MAXNAMEL); out_name[MAXNAMEL] = '\000'; + /* no */ + } else { + /* Get the ICC source & destination profile names */ + if (fa >= argc || argv[fa][0] == '-') usage("Missing input profile"); + strncpy(in_name,argv[fa++],MAXNAMEL); in_name[MAXNAMEL] = '\000'; + + if (fa >= argc || argv[fa][0] == '-') usage("Missing output profile"); + strncpy(out_name,argv[fa++],MAXNAMEL); out_name[MAXNAMEL] = '\000'; + } + /* Get the resulting link profile name */ if (fa >= argc || argv[fa][0] == '-') usage("Missing result profile"); strncpy(link_name,argv[fa++],MAXNAMEL); link_name[MAXNAMEL] = '\000'; @@ -2910,68 +2966,6 @@ main(int argc, char *argv[]) { usage("Can't use 'white point hack' and Luminence scaling intent together"); /* - - - - - - - - - - - - - - - - - - - */ - /* Open up the input device profile for reading, and read header etc. */ - if ((li.in.c = read_embedded_icc(in_name)) == NULL) - error ("Can't open file '%s'",in_name); - li.in.h = li.in.c->header; - - /* Check that it is a suitable device input icc */ - if (li.in.h->deviceClass != icSigInputClass - && li.in.h->deviceClass != icSigDisplayClass - && li.in.h->deviceClass != icSigOutputClass - && li.in.h->deviceClass != icSigColorSpaceClass) /* For sRGB etc. */ - error("Input profile '%s' isn't a device profile",in_name); - - /* Wrap with an expanded icc */ - if ((li.in.x = new_xicc(li.in.c)) == NULL) - error ("Creation of input profile xicc failed"); - - /* Set the default ink limits if not set on command line */ - icxDefaultLimits(li.in.x, &li.in.ink.tlimit, li.in.ink.tlimit, &li.in.ink.klimit, li.in.ink.klimit); - - if (li.verb) { - if (li.in.ink.tlimit >= 0.0) - printf("Input total ink limit assumed is %3.0f%%\n",100.0 * li.in.ink.tlimit); - if (li.in.ink.klimit >= 0.0) - printf("Input black ink limit assumed is %3.0f%%\n",100.0 * li.in.ink.klimit); - } - - /* - - - - - - - - - - - - - - - - - - - */ - /* Open up the abstract profile if requested */ - if (abs_name[0] != '\000') { - if ((li.abs_fp = new_icmFileStd_name(abs_name,"r")) == NULL) - error ("Can't open abstract profile file '%s'",abs_name); - - if ((li.abs_icc = new_icc()) == NULL) - error ("Creation of Abstract profile ICC object failed"); - - /* Read header etc. */ - if ((rv = li.abs_icc->read(li.abs_icc,li.abs_fp,0)) != 0) - error ("%d, %s",rv,li.abs_icc->err); - - if (li.abs_icc->header->deviceClass != icSigAbstractClass) - error("Abstract profile isn't an abstract profile"); - - /* Take intended abstract intent from profile itself */ - if ((li.abs_intent = li.abs_icc->header->renderingIntent) != icAbsoluteColorimetric) - li.abs_intent = icRelativeColorimetric; - - /* Wrap with an expanded icc */ - if ((li.abs_xicc = new_xicc(li.abs_icc)) == NULL) - error ("Creation of abstract profile xicc failed"); - } - /* - - - - - - - - - - - - - - - - - - - */ - /* Open up the output device output profile for reading, and read header etc. */ - if ((li.out.c = read_embedded_icc(out_name)) == NULL) - error ("Can't open file '%s'",out_name); - li.out.h = li.out.c->header; - - if (li.out.h->deviceClass != icSigInputClass - && li.out.h->deviceClass != icSigDisplayClass - && li.out.h->deviceClass != icSigOutputClass - && li.out.h->deviceClass != icSigColorSpaceClass) /* For sRGB etc. */ - error("Output profile isn't a device profile"); - /* Grab the calibration if requested */ if (addcal) { if ((li.cal = new_xcal()) == NULL) @@ -2986,194 +2980,261 @@ main(int argc, char *argv[]) { /* and we don't currently have a way of detecting this */ } - /* Wrap with an expanded icc */ - if ((li.out.x = new_xicc(li.out.c)) == NULL) - error ("Creation of output profile xicc failed"); + if (!calonly) { - /* Set the default ink limits if not set on command line */ - icxDefaultLimits(li.out.x, &li.out.ink.tlimit, li.out.ink.tlimit, &li.out.ink.klimit, li.out.ink.klimit); + /* Open up the input device profile for reading, and read header etc. */ + if ((li.in.c = read_embedded_icc(in_name)) == NULL) + error ("Can't open file '%s'",in_name); + li.in.h = li.in.c->header; - if (li.verb) { - if (li.out.ink.tlimit >= 0.0) - printf("Output total ink limit assumed is %3.0f%%\n",100.0 * li.out.ink.tlimit); - if (li.out.ink.klimit >= 0.0) - printf("Output black ink limit assumed is %3.0f%%\n",100.0 * li.out.ink.klimit); - } + /* Check that it is a suitable device input icc */ + if (li.in.h->deviceClass != icSigInputClass + && li.in.h->deviceClass != icSigDisplayClass + && li.in.h->deviceClass != icSigOutputClass + && li.in.h->deviceClass != icSigColorSpaceClass) /* For sRGB etc. */ + error("Input profile '%s' isn't a device profile",in_name); - /* deal with output black generation. */ - /* Ink limits will have been set in option parsing */ + /* Wrap with an expanded icc */ + if ((li.in.x = new_xicc(li.in.c)) == NULL) + error ("Creation of input profile xicc failed"); - switch (li.out.inking) { - case 0: /* Use input profile K level or locus */ - /* Sanity check */ - if (li.in.h->colorSpace != li.out.h->colorSpace) - error("Can't transfer black ink in & out unless the same colorspaces"); - li.out.ink.k_rule = li.out.locus ? icxKlocus : icxKvalue; /* Given as aux parameter in PCS -> Device */ - break; - case 7: /* Use output profile K level or locus */ - li.out.ink.k_rule = li.out.locus ? icxKlocus : icxKvalue; /* Given as aux parameter in PCS -> Device */ - break; - case 1: /* Minimum K */ - li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k; - li.out.ink.c.Kstle = 0.0; - li.out.ink.c.Kstpo = 0.0; - li.out.ink.c.Kenpo = 1.0; - li.out.ink.c.Kenle = 0.0; - li.out.ink.c.Kshap = 1.0; - break; - case 2: /* 0.5 K */ - li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k; - li.out.ink.c.Kstle = 0.5; - li.out.ink.c.Kstpo = 0.0; - li.out.ink.c.Kenpo = 1.0; - li.out.ink.c.Kenle = 0.5; - li.out.ink.c.Kshap = 1.0; - break; - case 3: /* Maximum K */ - li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k; - li.out.ink.c.Kstle = 1.0; - li.out.ink.c.Kstpo = 0.0; - li.out.ink.c.Kenpo = 1.0; - li.out.ink.c.Kenle = 1.0; - li.out.ink.c.Kshap = 1.0; - break; - case 4: /* Ramp K */ - li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k; - li.out.ink.c.Kstle = 0.0; - li.out.ink.c.Kstpo = 0.0; - li.out.ink.c.Kenpo = 1.0; - li.out.ink.c.Kenle = 1.0; - li.out.ink.c.Kshap = 1.0; - break; - case 5: /* Curve */ - li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k; - break; /* Other params already set by options */ - case 6: /* Use input profile K locus + dual curve limits */ - /* Sanity check */ - if (li.in.h->colorSpace != li.out.h->colorSpace) - error("Can't transfer black ink in & out unless the same colorspaces"); - li.out.ink.k_rule = li.out.locus ? icxKl5l : icxKl5lk; /* Aux param in PCS -> Device */ - break; /* Other params already set by options */ - } + /* Set the default ink limits if not set on command line */ + icxDefaultLimits(li.in.x, &li.in.ink.tlimit, li.in.ink.tlimit, &li.in.ink.klimit, li.in.ink.klimit); - for (i = 0; i < 2; i++) { - xicc *x; - icxViewCond *v, *vc; - int es; - int *set; - - if (i == 0) { - v = &ivc; /* Override parameters */ - vc = &li.in.vc; /* Target parameters */ - set = &li.in.vc_set; - es = ivc_e; - x = li.in.x; /* xicc */ - } else { - v = &ovc; /* Override parameters */ - vc = &li.out.vc; /* Target parameters */ - set = &li.out.vc_set; - es = ovc_e; - x = li.out.x; /* xicc */ - } - - /* Set the default viewing conditions */ - xicc_enum_viewcond(x, vc, -1, NULL, 0, NULL); - - /* Override the default viewing conditions. */ - /* (?? Could move this code into xicc_enum_viewcond() as an option ??) */ - /* First any enumerated selection */ - if (es != -1) { - if (xicc_enum_viewcond(x, vc, es, NULL, 0, NULL) == -999) - error ("%d, %s",x->errc, x->err); - *set = 1; - } - /* Then any individual paramaters */ - if (v->Ev >= 0) { - vc->Ev = v->Ev; - *set = 1; - } - if (v->Wxyz[0] >= 0.0 && v->Wxyz[1] > 0.0 && v->Wxyz[2] >= 0.0) { - /* Normalise XYZ to current media white */ - vc->Wxyz[0] = v->Wxyz[0]/v->Wxyz[1] * vc->Wxyz[1]; - vc->Wxyz[2] = v->Wxyz[2]/v->Wxyz[1] * vc->Wxyz[1]; - *set = 1; - } - if (v->Wxyz[0] >= 0.0 && v->Wxyz[1] >= 0.0 && v->Wxyz[2] < 0.0) { - /* Convert Yxy to XYZ */ - double x = v->Wxyz[0]; - double y = v->Wxyz[1]; /* If Y == 1.0, then X+Y+Z = 1/y */ - double z = 1.0 - x - y; - vc->Wxyz[0] = x/y * vc->Wxyz[1]; - vc->Wxyz[2] = z/y * vc->Wxyz[1]; - *set = 1; - } - if (v->La >= 0.0) { - vc->La = v->La; - *set = 1; - } - if (v->Yb >= 0.0) { - vc->Yb = v->Yb; - *set = 1; - } - if (v->Lv >= 0.0) { - vc->Lv = v->Lv; - *set = 1; - } - if (v->Yf >= 0.0) { - vc->Yf = v->Yf; - *set = 1; - } - if (v->Yg >= 0.0) { - vc->Yg = v->Yg; - *set = 1; - } - if (v->Gxyz[0] >= 0.0 && v->Gxyz[1] > 0.0 && v->Gxyz[2] >= 0.0) { - /* Normalise XYZ to current media white */ - vc->Gxyz[0] = v->Gxyz[0]/v->Gxyz[1] * vc->Gxyz[1]; - vc->Gxyz[2] = v->Gxyz[2]/v->Gxyz[1] * vc->Gxyz[1]; - *set = 1; - } - if (v->Gxyz[0] >= 0.0 && v->Gxyz[1] >= 0.0 && v->Gxyz[2] < 0.0) { - /* Convert Yxy to XYZ */ - double x = v->Gxyz[0]; - double y = v->Gxyz[1]; /* If Y == 1.0, then X+Y+Z = 1/y */ - double z = 1.0 - x - y; - vc->Gxyz[0] = x/y * vc->Gxyz[1]; - vc->Gxyz[2] = z/y * vc->Gxyz[1]; - *set = 1; + if (li.verb) { + if (li.in.ink.tlimit >= 0.0) + printf("Input total ink limit assumed is %3.0f%%\n",100.0 * li.in.ink.tlimit); + if (li.in.ink.klimit >= 0.0) + printf("Input black ink limit assumed is %3.0f%%\n",100.0 * li.in.ink.klimit); } - if (v->hkscale >= 0.0) { - vc->hkscale = v->hkscale; - *set = 1; + /* - - - - - - - - - - - - - - - - - - - */ + /* Open up the abstract profile if requested */ + if (abs_name[0] != '\000') { + if ((li.abs_fp = new_icmFileStd_name(abs_name,"r")) == NULL) + error ("Can't open abstract profile file '%s'",abs_name); + + if ((li.abs_icc = new_icc()) == NULL) + error ("Creation of Abstract profile ICC object failed"); + + /* Read header etc. */ + if ((rv = li.abs_icc->read(li.abs_icc,li.abs_fp,0)) != 0) + error ("%d, %s",rv,li.abs_icc->err); + + if (li.abs_icc->header->deviceClass != icSigAbstractClass) + error("Abstract profile isn't an abstract profile"); + + /* Take intended abstract intent from profile itself */ + if ((li.abs_intent = li.abs_icc->header->renderingIntent) != icAbsoluteColorimetric) + li.abs_intent = icRelativeColorimetric; + + /* Wrap with an expanded icc */ + if ((li.abs_xicc = new_xicc(li.abs_icc)) == NULL) + error ("Creation of abstract profile xicc failed"); } - if (v->mtaf >= 0.0) { - vc->mtaf = v->mtaf; - *set = 1; + /* - - - - - - - - - - - - - - - - - - - */ + /* Open up the output device output profile for reading, and read header etc. */ + if ((li.out.c = read_embedded_icc(out_name)) == NULL) + error ("Can't open file '%s'",out_name); + li.out.h = li.out.c->header; + + if (li.out.h->deviceClass != icSigInputClass + && li.out.h->deviceClass != icSigDisplayClass + && li.out.h->deviceClass != icSigOutputClass + && li.out.h->deviceClass != icSigColorSpaceClass) /* For sRGB etc. */ + error("Output profile isn't a device profile"); + + /* Wrap with an expanded icc */ + if ((li.out.x = new_xicc(li.out.c)) == NULL) + error ("Creation of output profile xicc failed"); + + /* Set the default ink limits if not set on command line */ + icxDefaultLimits(li.out.x, &li.out.ink.tlimit, li.out.ink.tlimit, &li.out.ink.klimit, li.out.ink.klimit); + + if (li.verb) { + if (li.out.ink.tlimit >= 0.0) + printf("Output total ink limit assumed is %3.0f%%\n",100.0 * li.out.ink.tlimit); + if (li.out.ink.klimit >= 0.0) + printf("Output black ink limit assumed is %3.0f%%\n",100.0 * li.out.ink.klimit); } - if (v->Wxyz2[0] >= 0.0 && v->Wxyz2[1] > 0.0 && v->Wxyz2[2] >= 0.0) { - /* Normalise XYZ */ - vc->Wxyz2[0] = v->Wxyz2[0]/v->Wxyz2[1] * vc->Wxyz2[1]; - vc->Wxyz2[2] = v->Wxyz2[2]/v->Wxyz2[1] * vc->Wxyz2[1]; - *set = 1; + + /* deal with output black generation. */ + /* Ink limits will have been set in option parsing */ + + switch (li.out.inking) { + case 0: /* Use input profile K level or locus */ + /* Sanity check */ + if (li.in.h->colorSpace != li.out.h->colorSpace) + error("Can't transfer black ink in & out unless the same colorspaces"); + li.out.ink.k_rule = li.out.locus ? icxKlocus : icxKvalue; /* Given as aux parameter in PCS -> Device */ + break; + case 7: /* Use output profile K level or locus */ + li.out.ink.k_rule = li.out.locus ? icxKlocus : icxKvalue; /* Given as aux parameter in PCS -> Device */ + break; + case 1: /* Minimum K */ + li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k; + li.out.ink.c.Kstle = 0.0; + li.out.ink.c.Kstpo = 0.0; + li.out.ink.c.Kenpo = 1.0; + li.out.ink.c.Kenle = 0.0; + li.out.ink.c.Kshap = 1.0; + break; + case 2: /* 0.5 K */ + li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k; + li.out.ink.c.Kstle = 0.5; + li.out.ink.c.Kstpo = 0.0; + li.out.ink.c.Kenpo = 1.0; + li.out.ink.c.Kenle = 0.5; + li.out.ink.c.Kshap = 1.0; + break; + case 3: /* Maximum K */ + li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k; + li.out.ink.c.Kstle = 1.0; + li.out.ink.c.Kstpo = 0.0; + li.out.ink.c.Kenpo = 1.0; + li.out.ink.c.Kenle = 1.0; + li.out.ink.c.Kshap = 1.0; + break; + case 4: /* Ramp K */ + li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k; + li.out.ink.c.Kstle = 0.0; + li.out.ink.c.Kstpo = 0.0; + li.out.ink.c.Kenpo = 1.0; + li.out.ink.c.Kenle = 1.0; + li.out.ink.c.Kshap = 1.0; + break; + case 5: /* Curve */ + li.out.ink.k_rule = li.out.locus ? icxKluma5 : icxKluma5k; + break; /* Other params already set by options */ + case 6: /* Use input profile K locus + dual curve limits */ + /* Sanity check */ + if (li.in.h->colorSpace != li.out.h->colorSpace) + error("Can't transfer black ink in & out unless the same colorspaces"); + li.out.ink.k_rule = li.out.locus ? icxKl5l : icxKl5lk; /* Aux param in PCS -> Device */ + break; /* Other params already set by options */ } - if (v->Wxyz2[0] >= 0.0 && v->Wxyz2[1] >= 0.0 && v->Wxyz2[2] < 0.0) { - /* Convert Yxy to XYZ */ - double x = v->Wxyz2[0]; - double y = v->Wxyz2[1]; /* If Y == 1.0, then X+Y+Z = 1/y */ - double z = 1.0 - x - y; - vc->Wxyz2[0] = x/y * vc->Wxyz2[1]; - vc->Wxyz2[2] = z/y * vc->Wxyz2[1]; - *set = 1; + + /* Deal with source & dest viewing conditions */ + for (i = 0; i < 2; i++) { + xicc *x; + icxViewCond *v, *vc; + int es; + int *set; + + if (i == 0) { + v = &ivc; /* Override parameters */ + vc = &li.in.vc; /* Target parameters */ + set = &li.in.vc_set; + es = ivc_e; + x = li.in.x; /* xicc */ + } else { + v = &ovc; /* Override parameters */ + vc = &li.out.vc; /* Target parameters */ + set = &li.out.vc_set; + es = ovc_e; + x = li.out.x; /* xicc */ + } + + /* Set the default viewing conditions */ + xicc_enum_viewcond(x, vc, -1, NULL, 0, NULL); + + /* Override the default viewing conditions. */ + /* (?? Could move this code into xicc_enum_viewcond() as an option ??) */ + /* First any enumerated selection */ + if (es != -1) { + if (xicc_enum_viewcond(x, vc, es, NULL, 0, NULL) == -999) + error ("%d, %s",x->errc, x->err); + *set = 1; + } + /* Then any individual paramaters */ + if (v->Ev >= 0) { + vc->Ev = v->Ev; + *set = 1; + } + if (v->Wxyz[0] >= 0.0 && v->Wxyz[1] > 0.0 && v->Wxyz[2] >= 0.0) { + /* Normalise XYZ to current media white */ + vc->Wxyz[0] = v->Wxyz[0]/v->Wxyz[1] * vc->Wxyz[1]; + vc->Wxyz[2] = v->Wxyz[2]/v->Wxyz[1] * vc->Wxyz[1]; + *set = 1; + } + if (v->Wxyz[0] >= 0.0 && v->Wxyz[1] >= 0.0 && v->Wxyz[2] < 0.0) { + /* Convert Yxy to XYZ */ + double x = v->Wxyz[0]; + double y = v->Wxyz[1]; /* If Y == 1.0, then X+Y+Z = 1/y */ + double z = 1.0 - x - y; + vc->Wxyz[0] = x/y * vc->Wxyz[1]; + vc->Wxyz[2] = z/y * vc->Wxyz[1]; + *set = 1; + } + if (v->La >= 0.0) { + vc->La = v->La; + *set = 1; + } + if (v->Yb >= 0.0) { + vc->Yb = v->Yb; + *set = 1; + } + if (v->Lv >= 0.0) { + vc->Lv = v->Lv; + *set = 1; + } + if (v->Yf >= 0.0) { + vc->Yf = v->Yf; + *set = 1; + } + if (v->Yg >= 0.0) { + vc->Yg = v->Yg; + *set = 1; + } + if (v->Gxyz[0] >= 0.0 && v->Gxyz[1] > 0.0 && v->Gxyz[2] >= 0.0) { + /* Normalise XYZ to current media white */ + vc->Gxyz[0] = v->Gxyz[0]/v->Gxyz[1] * vc->Gxyz[1]; + vc->Gxyz[2] = v->Gxyz[2]/v->Gxyz[1] * vc->Gxyz[1]; + *set = 1; + } + if (v->Gxyz[0] >= 0.0 && v->Gxyz[1] >= 0.0 && v->Gxyz[2] < 0.0) { + /* Convert Yxy to XYZ */ + double x = v->Gxyz[0]; + double y = v->Gxyz[1]; /* If Y == 1.0, then X+Y+Z = 1/y */ + double z = 1.0 - x - y; + vc->Gxyz[0] = x/y * vc->Gxyz[1]; + vc->Gxyz[2] = z/y * vc->Gxyz[1]; + *set = 1; + } + + if (v->hkscale >= 0.0) { + vc->hkscale = v->hkscale; + *set = 1; + } + if (v->mtaf >= 0.0) { + vc->mtaf = v->mtaf; + *set = 1; + } + if (v->Wxyz2[0] >= 0.0 && v->Wxyz2[1] > 0.0 && v->Wxyz2[2] >= 0.0) { + /* Normalise XYZ */ + vc->Wxyz2[0] = v->Wxyz2[0]/v->Wxyz2[1] * vc->Wxyz2[1]; + vc->Wxyz2[2] = v->Wxyz2[2]/v->Wxyz2[1] * vc->Wxyz2[1]; + *set = 1; + } + if (v->Wxyz2[0] >= 0.0 && v->Wxyz2[1] >= 0.0 && v->Wxyz2[2] < 0.0) { + /* Convert Yxy to XYZ */ + double x = v->Wxyz2[0]; + double y = v->Wxyz2[1]; /* If Y == 1.0, then X+Y+Z = 1/y */ + double z = 1.0 - x - y; + vc->Wxyz2[0] = x/y * vc->Wxyz2[1]; + vc->Wxyz2[2] = z/y * vc->Wxyz2[1]; + *set = 1; + } } - } + + } /* Not calonly */ if (li.verb) printf("Configured options\n"); /* - - - - - - - - - - - - - - - - - - - */ /* Setup the profile color lookup information */ - { + if (!calonly) { icmLuAlgType oalg; /* Native output algorithm */ icColorSpaceSignature natpcs; /* Underlying native output PCS */ int flb = 0, fl = 0; /* luobj flags */ @@ -3542,9 +3603,23 @@ main(int argc, char *argv[]) { } /* - - - - - - - - - - - - - - - - - - - */ - /* Sanity checking */ + if (calonly) { /* Fudge the in & out settings */ + li.in.csp = li.cal->colspace; + li.in.chan = li.cal->devchan; + li.in.nocurve = 1; + li.in.lcurve = 0; + li.in.bt1886 = 0; - if (li.cal != NULL) { + li.out.csp = li.cal->colspace; + li.out.chan = li.cal->devchan; + li.out.nocurve = 1; + li.out.lcurve = 0; + li.out.bt1886 = 0; + + li.mode = 0; /* Simple mode */ + + /* Sanity checking */ + } else if (li.cal != NULL) { if (li.cal->colspace != li.out.csp) { error("Calibration space %s doesn't match output profile %s", icm2str(icmColorSpaceSignature, li.cal->colspace), @@ -3905,12 +3980,14 @@ main(int argc, char *argv[]) { if (li.in.tvenc >= 3) { wh->colorSpace = icSigYCbCrData; /* Use YCbCr encoding */ } else { - wh->colorSpace = li.in.h->colorSpace; /* Input profile device space */ +// wh->colorSpace = li.in.h->colorSpace; /* Input profile device space */ + wh->colorSpace = li.in.csp; /* Input profile device space */ } if (li.out.tvenc >= 3) { wh->pcs = icSigYCbCrData; /* Use YCbCr encoding */ } else { - wh->pcs = li.out.h->colorSpace; /* Output profile device space */ +// wh->pcs = li.out.h->colorSpace; /* Output profile device space */ + wh->pcs = li.out.csp; /* Output profile device space */ } if (li.mode > 0) { wh->renderingIntent = li.gmi.icci; /* Closest ICC intent */ @@ -4009,8 +4086,21 @@ main(int argc, char *argv[]) { wo->allocate((icmBase *)wo);/* Allocate space */ strcpy(wo->desc, dst); /* Copy the string in */ } + /* ProfileSequenceDescTag: */ - { + if (li.calonly) { /* Fake one up */ + unsigned int i; + icmProfileSequenceDesc *wo; + if ((wo = (icmProfileSequenceDesc *)wr_icc->add_tag( + wr_icc, icSigProfileSequenceDescTag, icSigProfileSequenceDescType)) == NULL) + return 1; + + wo->count = 2; /* Number of descriptions in sequence */ + if (wo->allocate((icmBase *)wo) != 0) /* Allocate space for all the DescStructures */ + error("allocate failed: %d, %s",wr_icc->errc,wr_icc->err); + + /* Real one */ + } else { unsigned int i; icmProfileSequenceDesc *wo; if ((wo = (icmProfileSequenceDesc *)wr_icc->add_tag( @@ -4107,7 +4197,7 @@ main(int argc, char *argv[]) { } } /* ColorantTable: */ - { + if (!li.calonly) { int i; unsigned int j; int repclip = 0; @@ -4560,8 +4650,10 @@ main(int argc, char *argv[]) { #endif /* USE_APXLS */ 0, &li, /* Context */ - li.in.h->colorSpace, /* Input color space */ - li.out.h->colorSpace, /* Output color space */ +// li.in.h->colorSpace, /* Input color space */ + li.in.csp, /* Input color space */ +// li.out.h->colorSpace, /* Output color space */ + li.out.csp, /* Output color space */ devi_devip, /* Input transfer tables devi->devi' */ NULL, NULL, /* Use default input colorspace range */ devip_devop, /* devi' -> devo' transfer function */ @@ -4840,15 +4932,21 @@ main(int argc, char *argv[]) { li.cal->del(li.cal); } - li.in.luo->del(li.in.luo); - li.in.x->del(li.in.x); - li.in.c->del(li.in.c); + if (li.in.luo != NULL) + li.in.luo->del(li.in.luo); + if (li.in.x != NULL) + li.in.x->del(li.in.x); + if (li.in.c != NULL) + li.in.c->del(li.in.c); if (li.out.b2aluo != NULL) li.out.b2aluo->del(li.out.b2aluo); - li.out.luo->del(li.out.luo); - li.out.x->del(li.out.x); - li.out.c->del(li.out.c); + if (li.out.luo != NULL) + li.out.luo->del(li.out.luo); + if (li.out.x != NULL) + li.out.x->del(li.out.x); + if (li.out.c != NULL) + li.out.c->del(li.out.c); return 0; } diff --git a/log.txt b/log.txt index 16a181c..9a77d82 100755 --- a/log.txt +++ b/log.txt @@ -2,11 +2,49 @@ Argyll CMS change log ===================== -Version 2.1.0 Beta -------------- +Not included yet: +---------------- * Started adding comms for Lumagen Radiance detection. +Version 2.0.1 9th July 2018 +------------- + +* Increased maximum render channels to 16 + +* Added -O option to collink to allow creating a link + purely from calibration file. + +* Fixed JETI specbos & specval timeout when in averaging mode + and dark measurement. + +* Changed JETI specval 1511 driver to ignore REMOTE command + error with newer firmware. + +* Changed Klein K10 serial parameters in attempt to prevent + serial lock up on MSWindows. + +* Made a failure of the conf:maxtin command with a JETI 1201 + a soft error, to allow for old firmware versions. + +* Change colorhug Linux driver to reset on close. This may overcome + a problem re-starting the driver. + +* Fixed i1Pro driver to cope with stripped down OEM i1Pro2 that is missing + one piece of calibration information. + +* Fixed display calibration selection to allow for more + than 62 entries. This is to fix problem using Klein K10 + that has a lot of saved calibrations. + +* Changed spec2cie to add extra informational L*a*b* output fields, if + a non D50 illuminant (-i option) is used. + +* Added -w parameter to spotread, to use the -i parameter illuminant + for L*a*b* calculation. + +* Fixed bug in spec2cie - XRGA conversion wasn't saving spectrum out. + Version 2.0.0 17th November 2017 ------------- diff --git a/makepackagebin.sh b/makepackagebin.sh index 2688bf4..192e89a 100755 --- a/makepackagebin.sh +++ b/makepackagebin.sh @@ -177,11 +177,18 @@ if [ X$USETAR = "Xtrue" ] ; then fi # tar -xzf to extract # tar -tzf to list + # to update a file: + # gzip -d archive.tgz + # tar -uf application.tar file + # gzip application.tar + # mv application.tar.gz application.tgz + # or "tgzupdate.sh application" # Should we use "COPYFILE_DISABLE=1 tar .." on OS X ?? else zip -9 -r $PACKAGE $TOPDIR # unzip to extract # unzip -l to list + # zip archive.zip file to update fi rm -rf $TOPDIR echo "Done GNU Argyll binary distribution $PACKAGE" diff --git a/namedc/namedc.c b/namedc/namedc.c index 2fc7796..7f8967f 100755 --- a/namedc/namedc.c +++ b/namedc/namedc.c @@ -710,7 +710,7 @@ static int read_cxf(namedc *p, const char *filename, int options) { else if (strcmp(name, "FieldOfView_10_Degree") == 0) p->obs = icxOT_CIE_1964_10; else { - a1logd(p->log, 2, "read_cxf: Illuminant '%s' unrecognised\n",name); + a1logd(p->log, 2, "read_cxf: Observer '%s' unrecognised\n",name); p->obs = icxOT_CIE_1931_2; } } @@ -784,7 +784,7 @@ static int read_cxf(namedc *p, const char *filename, int options) { else if (strcmp(name, "10_Degree") == 0) p->obs = icxOT_CIE_1964_10; else { - a1logd(p->log, 2, "read_cxf: Illuminant '%s' unrecognised\n",name); + a1logd(p->log, 2, "read_cxf: Observer '%s' unrecognised\n",name); p->obs = icxOT_CIE_1931_2; } } @@ -1087,7 +1087,7 @@ int match(struct _namedc *p, double *de, double *pLab, xspect *rspect, int deTyp if (rspect != NULL) { if (p->sp2cie == NULL) { - if ((p->sp2cie = new_xsp2cie(p->ill, NULL, p->obs, NULL, icSigLabData, 0)) == NULL) { + if ((p->sp2cie = new_xsp2cie(p->ill, 0.0, NULL, p->obs, NULL, icSigLabData, 0)) == NULL) { snprintf(p->err, NAMEDC_ERRL, "creating spetral conversion failed"); a1logd(p->log, 1, "match: %s\n",p->err); return -1; @@ -1109,7 +1109,7 @@ int match(struct _namedc *p, double *de, double *pLab, xspect *rspect, int deTyp xsp2cie *tt; xspect ts; // Get the XYZ of the given white point for the illuminant and observer - if ((tt = new_xsp2cie(p->ill, NULL, p->obs, NULL, icSigXYZData, 0)) == NULL) { + if ((tt = new_xsp2cie(p->ill, 0.0, NULL, p->obs, NULL, icSigXYZData, 0)) == NULL) { snprintf(p->err, NAMEDC_ERRL, "creating spetral conversion failed"); a1logd(p->log, 1, "match: %s\n",p->err); return -1; diff --git a/numlib/Jamfile b/numlib/Jamfile index 2d5edaf..e2a06fd 100755 --- a/numlib/Jamfile +++ b/numlib/Jamfile @@ -20,13 +20,13 @@ Headers = numlib.h libui.h ; HDRS = ../h ; # Numeric library -Library libnum.lib : numsup.c dnsq.c powell.c dhsx.c varmet.c ludecomp.c svd.c zbrent.c rand.c sobol.c aatree.c quadprog.c ; +Library libnum.lib : numsup.c dnsq.c powell.c dhsx.c varmet.c ludecomp.c svd.c zbrent.c rand.c sobol.c aatree.c quadprog.c gnewt.c roots.c ; # Link all utilities with libnum LINKLIBS = libnum ; # All test programs are made from a single source file -MainsFromSources dnsqtest.c tpowell.c tdhsx.c LUtest.c svdtest.c zbrenttest.c soboltest.c qptest.c ; +MainsFromSources dnsqtest.c tpowell.c tconjgrad.c tdhsx.c LUtest.c svdtest.c zbrenttest.c soboltest.c qptest.c ; # Compile .c as .m if $(OS) = MACOSX { diff --git a/numlib/afiles b/numlib/afiles index b2138b2..e427b7d 100755 --- a/numlib/afiles +++ b/numlib/afiles @@ -4,6 +4,8 @@ afiles Jamfile dnsq.c dnsq.h +gnewt.c +gnewt.h dnsqtest.c numlib.h numsup.c @@ -11,6 +13,7 @@ numsup.h powell.h powell.c tpowell.c +tconjgrad.c varmet.h varmet.c dhsx.h @@ -35,5 +38,7 @@ aatree.c quadprog.h quadprog.c qptest.c +roots.h +roots.c ui.h ui.c diff --git a/numlib/dhsx.c b/numlib/dhsx.c index e9da0eb..aa9f462 100755 --- a/numlib/dhsx.c +++ b/numlib/dhsx.c @@ -20,7 +20,7 @@ #undef DEBUG -int dhsx_debug = 1; +int dhsx_debug = 0; static void simplexinit(int di, double *cp, double **p, double *r, double sv, int ii); static double trypoint(int di,double *cp, double **p, double *y, int hix, double hpfac, @@ -92,9 +92,15 @@ void *fdata /* Data needed by function */ lox = i; } tryy = (*funk)(fdata, cp); /* Value at initial point */ +#ifdef DEBUG + if (dhsx_debug) printf(" initial point %s = %e\n",debPdv(di,cp),tryy); +#endif /* DEBUG */ /* If our initial point is better than any of the simplex verticies */ if (y[lox] > tryy) { +#ifdef DEBUG + if (dhsx_debug) printf(" initial point is better than surrounding simplex\n"); +#endif /* DEBUG */ /* Move all the verticies to match moving lox to cp */ for (i = 0; i < nsp; i++) { if (i == lox) @@ -263,6 +269,9 @@ void *fdata /* Data needed by function */ for (j = 0; j < di; j++) cp[j] = p[lox][j]; } +#ifdef DEBUG + else if (dhsx_debug) printf("C point val %f is best\n",tryy); +#endif free_dvector(y2, 0, nsp-1); free_dmatrix(p2, 0, nsp-1, 0, di-1); free_dvector(y, 0, nsp-1); diff --git a/numlib/dhsx.h b/numlib/dhsx.h index 78cdb10..8a4e1ff 100755 --- a/numlib/dhsx.h +++ b/numlib/dhsx.h @@ -14,9 +14,9 @@ /* return 0 on sucess, 1 on failure due to excessive itterations */ /* Result will be in cp */ int dhsx( - double *rv, /* If not NULL, return the residual error */ - int di, /* Dimentionality */ - double *cp, /* Initial starting point, return minimum */ + double *rv, /* If not NULL, return the residual error */ + int di, /* Dimentionality */ + double *cp, /* Initial starting point, return minimum */ double *s, /* Size of initial search area */ double ftol, /* Finishing tollerance of error change */ double athr, /* Absolute return value threshold. (Set high to not use) */ diff --git a/numlib/dnsq.c b/numlib/dnsq.c index 75f00a8..31bebe4 100755 --- a/numlib/dnsq.c +++ b/numlib/dnsq.c @@ -112,6 +112,7 @@ int dnsqe( info = 4; if (info == 0) warning("dnsqe: invalid input parameter."); + return info; } /* dnsqe */ diff --git a/numlib/dnsq.h b/numlib/dnsq.h index e06e562..28dd5de 100755 --- a/numlib/dnsq.h +++ b/numlib/dnsq.h @@ -84,7 +84,8 @@ int dnsq_jac( /* Return < 0 on abort */ ); #define M_LARGE 1.79e+308 -#define M_DIVER 2.22e-15 +#define M_DIVER 2.22e-15 /* Machine precision (10 x IEEE double) */ +#define M_SQRT_DIVER 4.71e-8 /* sqrt(M_DIVER) */ /* Simplified dnsq() */ int dnsqe( diff --git a/numlib/dnsqtest.c b/numlib/dnsqtest.c index 3f02819..f05bed4 100755 --- a/numlib/dnsqtest.c +++ b/numlib/dnsqtest.c @@ -74,7 +74,7 @@ int main(void) /* Unless high precision solutions are required, */ /* this is the recommended setting. */ - tol = sqrt(M_DIVER); + tol = M_SQRT_DIVER; info = dnsqe(NULL, fcn, NULL, n, x, ss, fvec, tol, tol, 0, nprint); fnorm = denorm(n, fvec); diff --git a/numlib/gnewt.c b/numlib/gnewt.c new file mode 100755 index 0000000..c95cec7 --- /dev/null +++ b/numlib/gnewt.c @@ -0,0 +1,413 @@ + +/* + * Copyright 2018 Graeme Gill + * All rights reserved. + * + * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :- + * see the License.txt file for licencing details. + */ + +#include "numsup.h" +#include "ludecomp.h" +#include "gnewt.h" /* Public interface definitions */ + +#undef DEBUG + +#ifdef DEBUG +# define DBG(xx) printf xx; +#else +# define DBG(xx) +#endif + + +#define TOLX 1.0e-7 /* Convergence criterion on delx */ +#define STPMX 100.0 /* Maximum step multiplier */ + +static void apxjac(int n, double *x, double *fvec, double **df, void *fdata, + void (*fcn)(void *fdata, int n, double *x, double *fvec)); + +static int linesearch(int n, double *xold, double fold, double *delf, double *delx, + double *x, double *fvec, double *fp, double maxstep, void *fdata, + void (*fcn)(void *fdata, int n, double *x, double *f), int *pfit, int maxjac, int it); + +#define FMAX(A, B) ((A) > (B) ? (A) : (B)) + +int gnewt( + void *fdata, /* Opaque pointer to pass to fcn() and jac() */ + void (*fcn)(void *fdata, int n, double *x, double *fvec), + /* Pointer to function we are solving */ + void (*jac)(void *fdata, int n, double *x, double **fjac), + /* Function to compute jacobian */ + int n, /* Number of functions and variables */ + double x[], /* Initial solution estimate, returns final solution */ + double rfvec[], /* Optionaly return soln. function values */ + double xtol, /* Desired tollerance of root */ + double ftol, /* Desired tollerance of the solution */ + int maxfcn, /* Maximum number of function itterations */ + int maxjac /* Maximum number of jacobian itterations */ +) { + int i, j, it, fit, jit, *pivx, _pivx[10]; + double f, fold; /* half magnitide squared of fvec[] */ + double *delf, _delf[10]; /* del f where f = 0.5 F.F */ + double *fvec, _fvec[10]; /* F(x) */ + double **fjac, *_fjac[11], __fjac[10 * 10]; + double *xold, _xold[10]; + double bigfx, bigx, maxstep; + double *delx, _delx[10]; /* Full step delta x */ + double sum; + int rv = 0; + +#ifdef DEBUG + double *fvec_check; + double **fjac_check; +#endif + + DBG(("gnewt:\n")) + + fit = jit = 0; + + /* Do local vector/array allocations */ + if (n <= 10) { + pivx = _pivx; + if (rfvec == NULL) { + fvec = _fvec; + } else + fvec = rfvec; + _fjac[0] = __fjac; + fjac = _fjac+1; /* dmatrix_reset() will setup fjac */ + xold = _xold; + delf = _delf; + delx = _delx; + } else { + pivx = ivector(0, n-1); /* LU decomp. pivod record */ + if (rfvec == NULL) { + fvec = dvector(0, n-1); /* Function value */ + } else + fvec = rfvec; + fjac = dmatrix(0, n-1, 0, n-1); /* Jacobian matrix */ + xold = dvector(0, n-1); /* Previous value of x[] */ + delf = dvector(0, n-1); /* del f */ + delx = dvector(0, n-1); /* Full step delta x */ + } +#ifdef DEBUG + fvec_check = dvector(0, n-1); + fjac_check = dmatrix(0, n-1, 0, n-1); +#endif + + /* Initial function value */ + fcn(fdata, n, x, fvec); + fit++; + + DBG((" x %s\n",debPdv(n,x))) + DBG((" fvec %s\n",debPdv(n,fvec))) + + /* Compute half magnitide squared of function value at x */ + for (sum = 0.0, i = 0; i < n; i++) + sum += fvec[i] * fvec[i]; + f = 0.5 * sum; + DBG((" f %f\n",f)) + + /* test for initial value being a root */ + for (bigfx = 0.0, i = 0; i < n; i++) { + double tt = fabs(fvec[i]); + if (tt > bigfx) + bigfx = tt; + } + if (bigfx < (0.01 * ftol)) { + goto done; + } + + /* Compute line search x maximum step size */ + for (sum = 0.0, i = 0 ; i < n; i++) + sum += x[i] * x[i]; + maxstep = STPMX * FMAX(sqrt(sum), (double)n); + DBG((" maxstep %f\n",maxstep)) + + /* Until we are done */ + for (it = 0; fit < maxfcn && jit < maxjac; it++) { + double rip; + + DBG((" fit %d jit %d\n",fit,jit)) + + /* Compute Jacobian matrix */ + if (jac != NULL) { + /* lu_decomp may have swapped rows - so fix it */ + dmatrix_reset(fjac, 0, n-1, 0, n-1); + jac(fdata, n, x, fjac); /* User function */ + } else { + apxjac(n, x, fvec, fjac, fdata, fcn); /* Numerical aproximation */ + } + jit++; + +#ifdef DEBUG + copy_dmatrix(fjac_check, fjac, 0, n-1, 0, n-1); + + DBG((" fjac = \n")) + for (i = 0; i < n; i++) + DBG((" %d: %s\n",i,debPdv(n, fjac[i]))) + DBG(("\n")) +#endif + + /* Compute del f for the line search. */ + for (i = 0; i < n; i++) { + for (sum = 0.0, j = 0; j < n; j++) + sum += fjac[j][i] * fvec[j]; /* Hmm. df/dx . f */ + delf[i] = sum; + } + + /* Save current values of x and f to be able to monitor progres */ + for (i = 0; i < n; i++) + xold[i] = x[i]; + fold = f; + + /* Desired delta f to make F(x) == 0 */ + for (i = 0; i < n; i++) + delx[i] = -fvec[i]; + DBG((" -fvec %s\n",debPdv(n,delx))) + + /* Solve for delta x using Jacobian and desired delta f */ + if (lu_decomp(fjac, n, pivx, &rip)) { + rv = 2; + goto done; + } + lu_backsub(fjac, n, pivx, delx); + DBG((" delx %s\n",debPdv(n,delx))) + +#ifdef DEBUG + matrix_vect_mult(fvec_check, n, fjac_check, n, n, delx, n); + DBG((" check -fvec : %s\n\n",debPdv(n,fvec_check))) +#endif + + if ((rv = linesearch(n, xold, fold, delf, delx, x, fvec, &f, maxstep, fdata, fcn, + &fit, maxfcn, it)) != 0) { + if (rv != 1) { /* Not run out of itterations error */ + DBG((" linesearch failed with %d\n",rv)) + goto done; + } + } + + DBG((" after linesearch:\n")) + DBG((" x %s\n",debPdv(n,x))) + DBG((" fvec %s\n",debPdv(n,fvec))) + + /* See if f() has converged */ + for (bigfx = 0.0, i = 0; i < n; i++) { + if (fabs(fvec[i]) > bigfx) + bigfx = fabs(fvec[i]); + } + DBG((" bigfx %f ftol %f\n",bigfx,ftol)) + if (bigfx < ftol) { + goto done; + } + + /* Could check for zero gradient problem here... */ + + /* See if x[] has converged */ + for (bigx = 0.0, i = 0; i < n; i++) { + double tt = (fabs(x[i] - xold[i]))/FMAX(fabs(x[i]), 1.0); + if (tt > bigx) + bigx = tt; + } + DBG((" bigx %f xtol %f\n",bigx,xtol)) + if (bigx < xtol) + goto done; + } + + rv = 1; + + done:; + + if (n > 10) { + if (fvec != rfvec) + free_dvector(fvec, 0, n-1); + free_dvector(xold, 0, n-1); + free_dvector(delx, 0, n-1); + free_dvector(delf, 0, n-1); + free_dmatrix(fjac, 0, n-1, 0, n-1); + free_ivector(pivx, 0, n-1); + } +#ifdef DEBUG + free_dvector(fvec_check,0, n-1); + free_dmatrix(fjac_check,0, n-1, 0, n-1); +#endif + + return rv; +} + +/* - - - - - - - - */ + +#define ALF 1.0e-4 /* Ensures sufficient decrease in function value. */ + +/* Search for a step size that makes progress */ +/* Return nz on error */ +static int linesearch( + int n, + double *xold, + double fold, + double *delf, /* del f */ + double *delx, /* full step delta x[] */ + double *x, /* in/out current x[] */ + double *fvec, /* return fvec at x[] */ + double *fp, /* in/out f value */ + double maxstep, /* maximum x step */ + void *fdata, /* Context for fcn */ + void (*fcn)(void *fdata, int n, double *x, double *f), + int *pfit, /* Inc number of itts */ + int maxfcn, /* Max function its */ + int it /* Caller iteration count */ +) { + int i; + double f = *fp, f2; + double lmda1, lmda2, min_lmda; + double sum, slope, bigx; + + DBG(("linesearch:\n")) + + /* Comute magnitude of step */ + for (sum = 0.0, i = 0; i < n; i++) + sum += delx[i] * delx[i]; + sum = sqrt(sum); + + /* re-scale if step is too big */ + if (sum > maxstep) { + for (i = 0; i < n; i++) + delx[i] *= maxstep/sum; + } + + for (slope = 0.0, i = 0; i < n; i++) + slope += delf[i] * delx[i]; + if (slope >= 0.0) { + DBG((" slope %f >= 0.0\n",slope)) + return 3; + } + + bigx = 0.0; + for (i = 0;i < n; i++) { + double tt = fabs(delx[i])/FMAX(fabs(xold[i]), 1.0); + if (tt > bigx) + bigx = tt; + } + min_lmda = TOLX/bigx; + + /* Try full Newton step first */ + lmda1 = 1.0; + + DBG((" lmda1 %f min_lmda %f\n",lmda1, min_lmda)) + + /* Top of loop */ + for (; *pfit < maxfcn; it++) { + double tmp_lmda; + + DBG((" lmda1 %f\n",lmda1)) + + /* Take step */ + for (i = 0;i < n;i++) + x[i] = xold[i] + lmda1 * delx[i]; + + /* Compute f = 0.5 F.F at x */ + fcn(fdata, n, x, fvec); + (*pfit)++; + DBG((" x %s\n",debPdv(n,x))) + DBG((" fvec %s\n",debPdv(n,fvec))) + for (sum = 0.0, i = 0; i < n; i++) + sum += fvec[i] * fvec[i]; + f = 0.5 * sum; + +//if (it == 0) printf(" linesearch: At 1st full step f %f -> %f\n", *fp, f); + + /* Convergence on delx. */ + if (lmda1 < min_lmda) { + + for (i = 0; i < n; i++) + x[i] = xold[i]; + return 0; + + } else if (f <= fold + ALF * lmda1 * slope) { + *fp = f; + return 0; /* Sufficient function decrease */ + + } else { /* Backtrack. */ + if (lmda1 == 1.0) /* First time */ + tmp_lmda = -slope/(2.0 * (f - fold-slope)); + + else { /* Subsequent backtracks */ + double c, d, e; + double a, b, rhs1, rhs2; + + rhs1 = f - fold - slope * lmda1; + rhs2 = f2 - fold - slope * lmda2; + c = rhs1/(lmda1 * lmda1); + d = rhs2/(lmda2 * lmda2); + e = lmda1 - lmda2; + a = (c - d)/e; + b = (-lmda2 * c + lmda1 * d)/e; + if (a == 0.0) + tmp_lmda = -slope/(2.0 * b); + else { + double disc = b * b - 3.0 * a * slope; + + if (disc < 0.0) + tmp_lmda = 0.5 * lmda1; + else if (b <= 0.0) + tmp_lmda = (-b + sqrt(disc))/(3.0 * a); + else + tmp_lmda = -slope/(b + sqrt(disc)); + } + if (tmp_lmda > 0.5 * lmda1) + tmp_lmda = 0.5 * lmda1; + } + } + lmda2 = lmda1; + lmda1 = FMAX(tmp_lmda, lmda1 * 0.1); + f2 = f; + } + + *fp = f; + + return 1; +} + +/* - - - - - - - - */ + +/* Compute forward difference as aprox. Jacobian matrix */ + +#define JEPS 1.0e-8 /* Aprox. sqrt of machine precision */ + +static void apxjac( + int n, /* Dimensions */ + double *x, /* Location x to compute Jacobian */ + double *fvec, /* Function value at x */ + double **df, /* Return Jacobian */ + void *fdata, /* fcn() context */ + void (*fcn)(void *fdata, int n, double *x, double *fvec) +) { + int i, j; + double h, temp, *f, _f[10]; + + if (n <= 10) + f = _f; + else + f = dvector(0, n); + + for (j = 0; j < n; j++) { + temp = x[j]; + + h = JEPS * fabs(temp); + if (h == 0.0) + h = JEPS; + x[j] = temp + h; /* Add delta */ + h = x[j] - temp; /* Actual delta with fp precision limits */ + + fcn(fdata, n, x, f); + + x[j] = temp; /* Restore value */ + + for (i = 0; i < n; i++) + df[i][j] = (f[i] - fvec[i])/h; + } + + if (f != _f) + free_dvector(f, 0, n-1); +} + + diff --git a/numlib/gnewt.h b/numlib/gnewt.h new file mode 100755 index 0000000..322d511 --- /dev/null +++ b/numlib/gnewt.h @@ -0,0 +1,59 @@ +#ifndef GNEWT_H +#define GNEWT_H + +/* Global newton non-linear equation solver */ + +/* + * Copyright 2018 Graeme W. Gill + * All rights reserved. + * + * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :- + * see the License.txt file for licencing details. + */ + +#ifdef __cplusplus + extern "C" { +#endif + +/* + + return values: + + 0 Success + + 1 Ran out of itterations + + 2 Inverting Jacobian failed + + */ + +int gnewt( + void *fdata, /* Opaque pointer to pass to fcn() and jac() */ + void (*fcn)(void *fdata, int n, double *x, double *fvec), + /* Pointer to function we are solving */ + void (*jac)(void *fdata, int n, double *x, double **fjac), + /* Function to compute jacobian */ + int n, /* Number of functions and variables */ + double x[], /* Initial solution estimate, returns final solution */ + double rfvec[], /* Optionaly return soln. function values */ + double xtol, /* Desired tollerance of root */ + double ftol, /* Desired tollerance of the solution */ + int maxfcn, /* Maximum number of function itterations */ + int maxjac /* Maximum number of jacobian itterations */ +); + +#ifdef __cplusplus + } +#endif + +#endif /* GNEWT_H */ + + + + + + + + + + diff --git a/numlib/ludecomp.c b/numlib/ludecomp.c index b756bfe..06fc6a8 100755 --- a/numlib/ludecomp.c +++ b/numlib/ludecomp.c @@ -163,6 +163,7 @@ int n /* Dimensionality */ /* Decompose the square matrix A[][] into lower and upper triangles */ /* NOTE that it returns transposed inverse by normal convention. */ +/* NOTE that rows get swaped by swapping matrix pointers! */ /* Use sym_matrix_trans() to fix this. */ /* Return 1 if the matrix is singular. */ int @@ -260,14 +261,14 @@ double *rip /* Row interchange parity, +/- 1.0, used for determinant */ return 0; } -/* Solve a set of simultaneous equations from the */ +/* Solve a set of simultaneous equations A.x = b from the */ /* LU decomposition, by back substitution. */ void lu_backsub( double **a, /* A[][] LU decomposed matrix */ int n, /* Dimensionality */ int *pivx, /* Pivoting row permutations record */ -double *b /* Input B[] vecor, return X[] */ +double *b /* Input B[] vector, return X[] */ ) { int i, j; int nvi; /* When >= 0, indicates non-vanishing B[] index */ @@ -441,15 +442,13 @@ int n /* Dimensionality */ } /* Pseudo-Invert matrix A using lu decomposition */ -/* NOTE that it returns transposed inverse by normal convention. */ -/* Use matrix_trans() to fix this, or use matrix_trans_mult(). */ /* Return 1 if the matrix is singular, 0 if OK */ int lu_psinvert( double **out, /* Output[0..N-1][0..M-1] */ double **in, /* Input[0..M-1][0..N-1] input matrix */ -int m, /* Rows */ -int n /* Columns */ +int m, /* In Rows */ +int n /* In Columns */ ) { int rv = 0; double **tr; /* Transpose */ @@ -490,13 +489,73 @@ int n /* Columns */ } free_dmatrix(sq, 0, m-1, 0, m-1); } - free_dmatrix(tr, 0, n-1, 0, m-1); return rv; } +/* ----------------------------------------------------------------- */ + +// ~~~ Hmm. Need to verify this code is correct... + +/* Use Cholesky decomposition on a symetric positive-definite matrix. */ +/* Only the upper triangle of the matrix A is accessed. */ +/* L returns the decomposition */ +/* Return nz if A is not positive-definite */ +int llt_decomp(double **L, double **A, int n) { + int i, j, k; + double sum; + + /* Scan though upper triangle */ + for (i = 0; i < n; i++) { + + for (j = i; j < n; j++) { + + sum = A[i][j]; + for (k = i-1; k >= 0; k--) { + sum -= A[i][k] * A[j][k]; + } + + if (i != j) { + L[j][i] = sum/L[i][i]; + } else { + if (sum <= 0.0) + return 1; + L[i][i] = sqrt(sum); + } + } + } + return 0; +} + +/* Solve a set of simultaneous equations A.x = b from the */ +/* LLt decomposition, by back substitution. */ +void llt_backsub( +double **L, /* A[][] LLt decomposition in lower triangle */ +int n, /* Dimensionality */ +double *b, /* Input B[] */ +double *x /* Return X[] (may be same as B[]) */ +) { + int i, k; + double sum; + + /* Solve L.y = b, storing y in x. */ + for (i = 0; i < n; i++) { + sum = b[i]; + for (k = i-1; k >= 0; k--) + sum -= L[i][k] * x[k]; + x[i] = sum/L[i][i]; + } + + /* Solve Lt.x = y */ + for (i = n; i >= 0; i--) { + sum = x[i]; + for (k = i+1 ; k < n; k++) + sum -= L[k][i] * x[k]; + x[i] = sum/L[i][i]; + } +} diff --git a/numlib/ludecomp.h b/numlib/ludecomp.h index 1075a5b..3f92ef8 100755 --- a/numlib/ludecomp.h +++ b/numlib/ludecomp.h @@ -38,6 +38,7 @@ int n /* Dimensionality */ ); /* Decompose the square matrix A[][] into lower and upper triangles */ +/* NOTE that rows get swaped by swapping matrix pointers! */ /* Return 1 if the matrix is singular. */ int lu_decomp( @@ -89,17 +90,34 @@ int n /* Dimensionality */ ); /* Pseudo-Invert matrix A using lu decomposition */ -/* NOTE that it returns transposed inverse by normal convention. */ -/* Use matrix_trans() to fix this, or use matrix_trans_mult(). */ /* Return 1 if the matrix is singular, 0 if OK */ int lu_psinvert( double **out, /* Output[0..N-1][0..M-1] */ double **in, /* Input[0..M-1][0..N-1] input matrix */ -int m, /* Rows */ -int n /* Columns */ +int m, /* In Rows */ +int n /* In Columns */ ); +/* - - - - - - - - - - - - - - - - - - - */ + +/* Use Cholesky decomposition on a symetric positive-definite matrix. */ +/* Only the upper triangle of the matrix A is accessed. */ +/* L returns the decomposition */ +/* Return nz if A is not positive-definite */ +int llt_decomp(double **L, double **A, int n); + + +/* Solve a set of simultaneous equations A.x = b from the */ +/* LLt decomposition, by back substitution. */ +void llt_backsub( +double **L, /* A[][] LLt decomposition in lower triangle */ +int n, /* Dimensionality */ +double *b, /* Input B[] */ +double *x /* Return X[] (may be same as B[]) */ +); + + #ifdef __cplusplus } #endif diff --git a/numlib/numlib.h b/numlib/numlib.h index 430ce7a..28ec9ab 100755 --- a/numlib/numlib.h +++ b/numlib/numlib.h @@ -6,6 +6,7 @@ #include "numsup.h" /* Support routines, macros */ #include "dnsq.h" /* Non-linear equation solver */ +#include "gnewt.h" /* Global Newton non-linear equation solver */ #include "powell.h" /* Powell multi dimentional minimiser */ #include "dhsx.h" /* Downhill simplex multi dimentional minimiser */ #include "varmet.h" /* Variable Metric multi dimentional minimiser */ @@ -16,5 +17,6 @@ #include "sobol.h" /* Sub-random vector generators */ #include "aatree.h" /* Anderson balanced binary tree */ #include "quadprog.h" /* Quadradic Programming solution */ +#include "roots.h" /* Quadratic, Cubic and Quartic root solving */ #endif /* NUMLIB_H */ diff --git a/numlib/numsup.c b/numlib/numsup.c index eab81ed..ce76337 100755 --- a/numlib/numsup.c +++ b/numlib/numsup.c @@ -1080,6 +1080,29 @@ int nch free((char *)(m+nrl-1)); } +/* In case rows have been swapped, reset the pointers */ +void dmatrix_reset( +double **m, +int nrl, /* Row low index */ +int nrh, /* Row high index */ +int ncl, /* Col low index */ +int nch /* Col high index */ +) { + int i; + int cols; + + if (nrh < nrl) /* Prevent failure for 0 dimension */ + nrh = nrl; + if (nch < ncl) + nch = ncl; + + cols = nch - ncl + 1; + + m[nrl] = m[nrl-1] - ncl; /* Set first row address, offset to ncl */ + for(i = nrl+1; i <= nrh; i++) /* Set subsequent row addresses */ + m[i] = m[i-1] + cols; +} + /* --------------------- */ /* 2D diagonal half matrix vector malloc/free */ /* A half matrix must have equal rows and columns, */ @@ -1854,19 +1877,61 @@ int matrix_vect_mult( return 0; } +/* Multiply a 0 based transposed matrix by a vector */ +/* d may be same as v */ +int matrix_trans_vect_mult( + double *d, int nd, + double **m, int nr, int nc, + double *v, int nv +) { + int i, j; + double *_v = v, vv[20]; + + if (d == v) { + if (nv <= 20) { + _v = vv; + } else { + _v = dvector(0, nv-1); + } + for (j = 0; j < nv; j++) + _v[j] = v[j]; + } + + /* Input vector must match matrix columns */ + if (nv != nr) + return 1; + + /* Output vector must match matrix rows */ + if (nd != nc) + return 1; + + for (i = 0; i < nd; i++) { + d[i] = 0.0; + for (j = 0; j < nv; j++) + d[i] += m[j][i] * _v[j]; + } + + if (_v != v && _v != vv) + free_dvector(_v, 0, nv-1); + + return 0; +} + /* Set zero based dvector */ void vect_set(double *d, double v, int len) { - int i; - for (i = 0; i < len; i++) - d[i] = v; + if (v == 0.0) + memset((char *)d, 0, len * sizeof(double)); + else { + int i; + for (i = 0; i < len; i++) + d[i] = v; + } } /* Copy zero based dvector */ void vect_cpy(double *d, double *s, int len) { - int i; - for (i = 0; i < len; i++) - d[i] = s[i]; + memmove((char *)d, (char *)s, len * sizeof(double)); } @@ -1900,6 +1965,35 @@ void vect_sub( d[i] -= v[i]; } +/* Scale a vector, */ +/* d may be same as v */ +void vect_scale(double *d, double *s, double scale, int len) { + int i; + + for (i = 0; i < len; i++) + d[i] = s[i] * scale; +} + +/* Take dot product of two vectors */ +double vect_dot(double *s1, double *s2, int len) { + int i; + double rv = 0.0; + for (i = 0; i < len; i++) + rv += s1[i] * s2[i]; + return rv; +} + +/* Return the vectors magnitude */ +double vect_mag(double *s, int len) { + int i; + double rv = 0.0; + + for (i = 0; i < len; i++) + rv += s[i] * s[i]; + + return sqrt(rv); +} + /* - - - - - - - - - - - - - - - - - - - - - - */ @@ -2019,6 +2113,85 @@ void adump_svector(a1log *log, char *id, char *pfx, short *a, int nc) { a1logd(g_log, 0, "\n"); } +/* ============================================================================ */ +/* C matrix support */ + +/* Clip a vector to the range 0.0 .. 1.0 */ +/* and return any clipping margine */ +double vect_ClipNmarg(int n, double *out, double *in) { + int j; + double tt, marg = 0.0; + for (j = 0; j < n; j++) { + out[j] = in[j]; + if (out[j] < 0.0) { + tt = 0.0 - out[j]; + out[j] = 0.0; + if (tt > marg) + marg = tt; + } else if (out[j] > 1.0) { + tt = out[j] - 1.0; + out[j] = 1.0; + if (tt > marg) + marg = tt; + } + } + return marg; +} + +/* + + mat in out + +[ ] [] [] +[ ] [] [] +[ ] * [] => [] +[ ] [] [] +[ ] [] [] + + */ + +/* Multiply N vector by NxN transform matrix */ +/* Organization is mat[out][in] */ +void vect_MulByNxN(int n, double *out, double *mat, double *in) { + int i, j; + double _tt[20], *tt = _tt; + + if (n > 20) + tt = dvector(0, n-1); + + for (i = 0; i < n; i++) { + tt[i] = 0.0; + for (j = 0; j < n; j++) + tt[i] += mat[i * n + j] * in[j]; + } + + for (i = 0; i < n; i++) + out[i] = tt[i]; + + if (n > 20) + free_dvector(tt, 0, n-1); +} + +/* Transpose an NxN matrix */ +void matrix_TransposeNxN(int n, double *out, double *in) { + int i, j; + + if (in != out) { + for (i = 0; i < n; i++) + for (j = 0; j < n; j++) + out[i * n + j] = in[j * n + i]; + } else { + for (i = 0; i < n; i++) { + for (j = i+1; j < n; j++) { + double tt; + tt = out[i * n + j]; + out[i * n + j] = out[j * n + i]; + out[j * n + i] = tt; + } + } + } +} + /* Print C double matrix to g_log debug */ /* id identifies matrix */ /* pfx used at start of each line */ @@ -2694,9 +2867,9 @@ char *debPiv(int di, int *p) { return buf[ix]; } -/* Print a double color vector to a string. */ +/* Print a double color vector to a string with format. */ /* Returned static buffer is re-used every 5 calls. */ -char *debPdv(int di, double *p) { +char *debPdvf(int di, char *fmt, double *p) { static char buf[5][DEB_MAX_CHAN * 100]; static int ix = 0; int e; @@ -2705,6 +2878,9 @@ char *debPdv(int di, double *p) { if (p == NULL) return "(null)"; + if (fmt == NULL) + fmt = "%.8f"; + if (++ix >= 5) ix = 0; bp = buf[ix]; @@ -2715,11 +2891,17 @@ char *debPdv(int di, double *p) { for (e = 0; e < di; e++) { if (e > 0) *bp++ = ' '; - sprintf(bp, "%.8f", p[e]); bp += strlen(bp); + sprintf(bp, fmt, p[e]); bp += strlen(bp); } return buf[ix]; } +/* Print a double color vector to a string. */ +/* Returned static buffer is re-used every 5 calls. */ +char *debPdv(int di, double *p) { + return debPdvf(di, NULL, p); +} + /* Print a float color vector to a string. */ /* Returned static buffer is re-used every 5 calls. */ char *debPfv(int di, float *p) { diff --git a/numlib/numsup.h b/numlib/numsup.h index 86ad6a8..972d5b3 100755 --- a/numlib/numsup.h +++ b/numlib/numsup.h @@ -411,6 +411,7 @@ void free_dvector(double *v,int nl,int nh); double **dmatrix(int nrl, int nrh, int ncl, int nch); double **dmatrixz(int nrl, int nrh, int ncl, int nch); void free_dmatrix(double **m, int nrl, int nrh, int ncl, int nch); +void dmatrix_reset(double **m, int nrl, int nrh, int ncl, int nch); double **dhmatrix(int nrl, int nrh, int ncl, int nch); double **dhmatrixz(int nrl, int nrh, int ncl, int nch); @@ -486,6 +487,14 @@ int matrix_vect_mult( double *v, int nv ); +/* Multiply a 0 based transposed matrix by a vector */ +/* d may be same as v */ +int matrix_trans_vect_mult( + double *d, int nd, + double **m, int nr, int nc, + double *v, int nv +); + /* Set zero based dvector */ void vect_set(double *d, double v, int len); @@ -498,16 +507,21 @@ void vect_neg(double *d, double *s, int len); /* Add two vectors, d += v */ /* d may be same as v */ -void vect_add( - double *d, double *v, int len -); +void vect_add(double *d, double *v, int len); /* Subtract two vectors, d -= v */ /* d may be same as v */ -void vect_sub( - double *d, double *v, int len -); +void vect_sub(double *d, double *v, int len); + +/* Scale a vector, */ +/* d may be same as v */ +void vect_scale(double *d, double *s, double scale, int len); + +/* Take dot product of two vectors */ +double vect_dot(double *s1, double *s2, int len); +/* Return the vectors magnitude */ +double vect_mag(double *s, int len); /* Diagnostics */ /* id identifies matrix/vector */ @@ -524,6 +538,20 @@ void adump_fvector(a1log *log, char *id, char *pfx, float *a, int nc); void adump_ivector(a1log *log, char *id, char *pfx, int *a, int nc); void adump_svector(a1log *log, char *id, char *pfx, short *a, int nc); +/* ===================================================== */ +/* C matrix support */ + +/* Clip a vector to the range 0.0 .. 1.0 */ +/* and return any clipping margine */ +double vect_ClipNmarg(int n, double *out, double *in); + +/* Multiply N vector by NxN transform matrix */ +/* Organization is mat[out][in] */ +void vect_MulByNxN(int n, double *out, double *mat, double *in); + +/* Transpose an NxN matrix */ +void matrix_TransposeNxN(int n, double *out, double *in); + /* Dump C type matrix */ void adump_C_dmatrix(a1log *log, char *id, char *pfx, double *a, int nr, int nc); @@ -631,10 +659,15 @@ char *debPiv(int di, int *p); /* Returned static buffer is re-used every 5 calls. */ char *debPdv(int di, double *p); +/* Print a double vector to a string with format. */ +/* Returned static buffer is re-used every 5 calls. */ +char *debPdvf(int di, char *fmt, double *p); + /* Print a float vector to a string. */ /* Returned static buffer is re-used every 5 calls. */ char *debPfv(int di, float *p); + /*******************************************/ /* Numerical diagnostics */ diff --git a/numlib/powell.c b/numlib/powell.c index 47acc15..7fb57a7 100755 --- a/numlib/powell.c +++ b/numlib/powell.c @@ -40,8 +40,10 @@ #include "numsup.h" #include "powell.h" -#undef SLOPE_SANITY_CHECK /* exermental */ -#undef ABSTOL /* Make tollerance absolute */ +#undef SLOPE_SANITY_CHECK /* [und] expermental */ +#undef ABSTOL /* [und] Make tollerance absolute */ +#undef USE_LINMIND /* [und] Use limind for conjgrad (typically slower) */ + /* Some debugging printfs (not comprehensive): */ #undef PDEBUG /* Powell debug */ #undef CDEBUG /* Conjgrad debug */ @@ -71,6 +73,7 @@ # define LDBG(xxx) #endif +/* -------------------------------------- */ /* Standard interface for powell function */ /* return 0 on sucess, 1 on failure due to excessive itterions */ /* Result will be in cp */ @@ -91,10 +94,10 @@ void (*prog)(void *pdata, int perc), /* Optional progress percentage callback * void *pdata /* Opaque data needed by prog() */ ) { int i; - double **dmtx; /* Direction vector */ - double *spt; /* Sarting point before exploring all the directions */ - double *xpt; /* Extrapolated point */ - double *svec; /* Search vector */ + double **dmtx, *_dmtx[10], __dmtx[10 * 10] = { 0.0 }; /* Direction vector */ + double *spt, _spt[10]; /* Sarting point before exploring all the directions */ + double *xpt, _xpt[10]; /* Extrapolated point */ + double *svec, _svec[10]; /* Search vector */ int iter; double retv; /* Returned function value at p */ double stopth; /* Current stop threshold */ @@ -102,10 +105,20 @@ void *pdata /* Opaque data needed by prog() */ double curdel; /* Current change in function value */ int pc = 0; /* Percentage complete */ - dmtx = dmatrixz(0, di-1, 0, di-1); /* Zero filled */ - spt = dvector(0,di-1); - xpt = dvector(0,di-1); - svec = dvector(0,di-1); + if (di <= 10) { + int j; + for (j = i = 0; i < di; i++, j += di) + _dmtx[i] = __dmtx + j; + dmtx = _dmtx; + spt = _spt; + xpt = _xpt; + svec = _svec; + } else { + dmtx = dmatrixz(0, di-1, 0, di-1); /* Zero filled */ + spt = dvector(0, di-1); + xpt = dvector(0, di-1); + svec = dvector(0, di-1); + } /* Create initial direction matrix by */ /* placing search start on diagonal */ @@ -213,11 +226,14 @@ void *pdata /* Opaque data needed by prog() */ } //printf("~1 iters = %d\n",iter); + /* Free up all the temporary vectors and matrix */ - free_dvector(svec,0,di-1); - free_dvector(xpt,0,di-1); - free_dvector(spt,0,di-1); - free_dmatrix(dmtx, 0, di-1, 0, di-1); + if (di > 10) { + free_dvector(svec, 0, di-1); + free_dvector(xpt, 0, di-1); + free_dvector(spt, 0, di-1); + free_dmatrix(dmtx, 0, di-1, 0, di-1); + } if (prog != NULL) /* Report final progress */ prog(pdata, 100); @@ -232,12 +248,323 @@ void *pdata /* Opaque data needed by prog() */ return 1; /* Failed due to execessive itterations */ } +/* - - - - - - - - - - - - - - - - - */ + +#define POWELL_GOLD 1.618034 +#define POWELL_CGOLD 0.3819660 +#define POWELL_MAXIT 100 + +/* Line bracketing and minimisation routine. */ +/* Return value at minimum. */ +double linmin( +double cp[], /* Start point, and returned value */ +double xi[], /* Search vector */ +int di, /* Dimensionality */ +#ifdef ABSTOL +double ftol, /* Absolute tolerance to stop on */ +#else +double ftol, /* Relative tolerance to stop on */ +#endif +double (*func)(void *fdata, double tp[]), /* Error function to evaluate */ +void *fdata) /* Opaque data for func() */ +{ + int i; + double ax, xx, bx; /* Search vector multipliers */ + double af, xf, bf; /* Function values at those points */ + double *xt, _xt[10]; /* Trial point */ + + if (di <= 10) + xt = _xt; + else + xt = dvector(0, di-1); /* Vector for trial point */ + + /* -------------------------- */ + /* First bracket the solution */ + + LDBG((" linmin: Bracketing solution\n")) + + /* The line is measured as startpoint + offset * search vector. */ + /* (Search isn't symetric, but it seems to depend on cp being */ + /* best current solution ?) */ + ax = 0.0; + for (i = 0; i < di; i++) + xt[i] = cp[i] + ax * xi[i]; + af = (*func)(fdata, xt); + + /* xx being vector offset 0.618 */ + xx = 1.0/POWELL_GOLD; + for (i = 0; i < di; i++) + xt[i] = cp[i] + xx * xi[i]; + xf = (*func)(fdata, xt); + + LDBG((" linmin: Initial points a:%f:%f -> b:%f:%f\n",ax,af,xx,xf)) + + /* Fix it so that we are decreasing from point a -> x */ + if (xf > af) { + double tt; + tt = ax; ax = xx; xx = tt; + tt = af; af = xf; xf = tt; + } + LDBG((" linmin: Ordered Initial points a:%f:%f -> b:%f:%f\n",ax,af,xx,xf)) + + bx = xx + POWELL_GOLD * (xx-ax); /* Guess b beyond a -> x */ + for (i = 0; i < di; i++) + xt[i] = cp[i] + bx * xi[i]; + bf = (*func)(fdata, xt); + + LDBG((" linmin: Initial bracket a:%f:%f x:%f:%f b:%f:%f\n",ax,af,xx,xf,bx,bf)) + +#ifdef SLOPE_SANITY_CHECK + /* If we're not seeing a slope indicitive of progress */ + /* of order ftol, give up straight away */ + if (2000.0 * fabs(xf - bf) <= ftol * (fabs(xf) + fabs(bf)) + && 2000.0 * fabs(af - xf) <= ftol * (fabs(af) + fabs(xf))) { + LDBG((" linmin: giving up because slope is too shallow\n")) + if (xt != _xt) + free_dvector(xt,0,di-1); + + if (bf < xf) { + xf = bf; + xx = bx; + } + goto done; + } +#endif /* SLOPE_SANITY_CHECK */ + + /* While not bracketed */ + while (xf > bf) { + double ulim, ux, uf; + double tt, r, q; + + LDBG((" linmin: Not bracketed because xf %f > bf %f\n",xf, bf)) + LDBG((" ax = %f, xx = %f, bx = %f\n",ax,xx,bx)) + + /* Compute ux by parabolic interpolation from a, x & b */ + q = (xx - bx) * (xf - af); + r = (xx - ax) * (xf - bf); + tt = q - r; + if (tt >= 0.0 && tt < 1e-20) /* If +ve too small */ + tt = 1e-20; + else if (tt <= 0.0 && tt > -1e-20) /* If -ve too small */ + tt = -1e-20; + ux = xx - ((xx - bx) * q - (xx - ax) * r) / (2.0 * tt); + ulim = xx + 100.0 * (bx - xx); /* Extrapolation limit */ + +//printf("~1 ux = %f, ulim = %f\n",ux,ulim); + if ((xx - ux) * (ux - bx) > 0.0) { /* u is between x and b */ + + for (i = 0; i < di; i++) /* Evaluate u */ + xt[i] = cp[i] + ux * xi[i]; + uf = (*func)(fdata, xt); + +//printf("~1 u is between x and b, uf = %f\n",uf); + + if (uf < bf) { /* Minimum is between x and b */ +//printf("~1 min is between x and b\n"); + ax = xx; af = xf; + xx = ux; xf = uf; + break; + } else if (uf > xf) { /* Minimum is between a and u */ +//printf("~1 min is between a and u\n"); + bx = ux; bf = uf; + break; + } + + /* Parabolic fit didn't work, look further out in direction of b */ + ux = bx + POWELL_GOLD * (bx-xx); +//printf("~1 parabolic fit didn't work,look further in direction of b (%f)\n",ux); + + } else if ((bx - ux) * (ux - ulim) > 0.0) { /* u is between b and limit */ + for (i = 0; i < di; i++) /* Evaluate u */ + xt[i] = cp[i] + ux * xi[i]; + uf = (*func)(fdata, xt); + +//printf("~1 u is between b and limit uf = %f\n",uf); + if (uf > bf) { /* Minimum is between x and u */ +//printf("~1 min is between x and uf\n"); + ax = xx; af = xf; + xx = bx; xf = bf; + bx = ux; bf = uf; + break; + } + xx = bx; xf = bf; /* Continue looking */ + bx = ux; bf = uf; + ux = bx + POWELL_GOLD * (bx - xx); /* Test beyond b */ +//printf("~1 continue looking beyond b (%f)\n",ux); + + } else if ((ux - ulim) * (ulim - bx) >= 0.0) { /* u is beyond limit */ + ux = ulim; +//printf("~1 use limit\n"); + } else { /* u is to left side of x ? */ + ux = bx + POWELL_GOLD * (bx-xx); +//printf("~1 look gold beyond b (%f)\n",ux); + } + /* Evaluate u, and move into place at b */ + for (i = 0; i < di; i++) + xt[i] = cp[i] + ux * xi[i]; + uf = (*func)(fdata, xt); +//printf("~1 lookup ux %f value uf = %f\n",ux,uf); + ax = xx; af = xf; + xx = bx; xf = bf; + bx = ux; bf = uf; +//printf("~1 move along to the right (a<-x, x<-b, b- x -> b */ +//printf("~1 got bracketed minimum at %f (%f), %f (%f), %f (%f)\n",ax,af,xx,xf,bx,bf); + + /* --------------------------------------- */ + /* Now use brent minimiser bewteen a and b */ + { + /* a and b bracket solution */ + /* x is best function value so far */ + /* w is second best function value so far */ + /* v is previous second best, or third best */ + /* u is most recently tested point */ + double wx, vx, ux; /* Search vector multipliers */ + double wf, vf = 0.0, uf; /* Function values at those points */ + int iter; + double de = 0.0; /* Distance moved on previous step */ + double e = 0.0; /* Distance moved on 2nd previous step */ + + /* Make sure a and b are in ascending order */ + if (ax > bx) { + double tt; + tt = ax; ax = bx; bx = tt; + tt = af; af = bf; bf = tt; + } + + wx = vx = xx; /* Initial values of other center points */ + wf = xf = xf; + + for (iter = 1; iter <= POWELL_MAXIT; iter++) { + double mx = 0.5 * (ax + bx); /* m is center of bracket values */ +#ifdef ABSTOL + double tol1 = ftol; /* Absolute tollerance */ +#else + double tol1 = ftol * fabs(xx) + 1e-10; +#endif + double tol2 = 2.0 * tol1; + + LDBG((" linmin it %d: Got bracket a:%f:%f x:%f:%f b:%f:%f\n",iter,ax,af,xx,xf,bx,bf)) + + /* See if we're done */ +//printf("~1 linmin check %f <= %f\n",fabs(xx - mx), tol2 - 0.5 * (bx - ax)); + if (fabs(xx - mx) <= (tol2 - 0.5 * (bx - ax))) { + LDBG((" linmin: We're done because %e <= %e\n",fabs(xx - mx), tol2 - 0.5 * (bx - ax))) + break; + } + + LDBG((" linmin: e %e tol2 %e\n",e,tol1)) + + if (fabs(e) > tol1) { /* Do a trial parabolic fit */ + double te, p, q, r; + r = (xx-wx) * (xf-vf); + q = (xx-vx) * (xf-wf); + p = (xx-vx) * q - (xx-wx) * r; + q = 2.0 * (q - r); + if (q > 0.0) + p = -p; + else + q = -q; + te = e; /* Save previous e value */ + e = de; /* Previous steps distance moved */ + + LDBG((" linmin: Trial parabolic fit\n" )) + + if (fabs(p) >= fabs(0.5 * q * te) || p <= q * (ax-xx) || p >= q * (bx-xx)) { + /* Give up on the parabolic fit, and use the golden section search */ + e = ((xx >= mx) ? ax-xx : bx-xx); /* Override previous distance moved */ + de = POWELL_CGOLD * e; + LDBG((" linmin: Moving to golden section search\n" )) + } else { /* Use parabolic fit */ + de = p/q; /* Change in xb */ + ux = xx + de; /* Trial point according to parabolic fit */ + if ((ux - ax) < tol2 || (bx - ux) < tol2) { + if ((mx - xx) > 0.0) /* Don't use parabolic, use tol1 */ + de = tol1; /* tol1 is +ve */ + else + de = -tol1; + } + LDBG((" linmin: Using parabolic fit\n" )) + } + } else { /* Keep using the golden section search */ + e = ((xx >= mx) ? ax-xx : bx-xx); /* Override previous distance moved */ + de = POWELL_CGOLD * e; + LDBG((" linmin: Continuing golden section search\n" )) + } + + if (fabs(de) >= tol1) { /* If de moves as much as tol1 would */ + ux = xx + de; /* use it */ + LDBG((" linmin: ux = %f = xx %f + de %f\n",ux,xx,de)) + } else { /* else move by tol1 in direction de */ + if (de > 0.0) { + ux = xx + tol1; + LDBG((" linmin: ux = %f = xx %f + tol1 %e\n",ux,xx,tol1)) + } else { + ux = xx - tol1; + LDBG((" linmin: ux = %f = xx %f - tol1 %f\n",ux,xx,tol1)) + } + } + + /* Evaluate function */ + for (i = 0; i < di; i++) + xt[i] = cp[i] + ux * xi[i]; + uf = (*func)(fdata, xt); + + if (uf <= xf) { /* Found new best solution */ + LDBG((" linmin: found new best solution at %f val %f\n",ux,uf)) + if (ux >= xx) { + ax = xx; af = xf; /* New lower bracket */ + } else { + bx = xx; bf = xf; /* New upper bracket */ + } + vx = wx; vf = wf; /* New previous 2nd best solution */ + wx = xx; wf = xf; /* New 2nd best solution from previous best */ + xx = ux; xf = uf; /* New best solution from latest */ + } else { /* Found a worse solution */ + LDBG((" linmin: found new worse solution at %f val %f\n",ux,uf)) + LDBG((" linmin: current best at %f val %f\n",xx,xf)) + if (ux < xx) { + ax = ux; af = uf; /* New lower bracket */ + } else { + bx = ux; bf = uf; /* New upper bracket */ + } + if (uf <= wf || wx == xx) { /* New 2nd best solution, or equal best */ + vx = wx; vf = wf; /* New previous 2nd best solution */ + wx = ux; wf = uf; /* New 2nd best from latest */ + } else if (uf <= vf || vx == xx || vx == wx) { /* New 3rd best, or equal 1st & 2nd */ + vx = ux; vf = uf; /* New previous 2nd best from latest */ + } + } + } + /* !!! should do something if iter > POWELL_MAXIT !!!! */ + /* Solution is at xx, xf */ + } + + done:; + + /* Compute solution vector at xx */ + LDBG((" linmin: computing soln from best at %f val %f\n",xx,xf)) + for (i = 0; i < di; i++) + cp[i] += xx * xi[i]; + + if (xt != _xt) + free_dvector(xt,0,di-1); +//printf("~~~ line minimizer returning %e\n",xf); + return xf; +} + +#undef POWELL_GOLD +#undef POWELL_CGOLD +#undef POWELL_MAXIT + /* -------------------------------------- */ -/* Conjugate Gradient optimiser */ +/* Conjugate Gradient optimiser using partial derivatives. */ /* return 0 on sucess, 1 on failure due to excessive itterions */ /* Result will be in cp */ /* Note that we could use gradient in line minimiser, */ -/* but haven't bothered yet. */ +/* but this seems to be slower, so we don't use it. */ int conjgrad( double *rv, /* If not NULL, return the residual error */ int di, /* Dimentionality */ @@ -250,79 +577,93 @@ double ftol, /* Relative tollerance of error change to stop on */ #endif int maxit, /* Maximum iterations allowed */ double (*func)(void *fdata, double tp[]), /* Error function to evaluate */ -double (*dfunc)(void *fdata, double dp[], double tp[]), /* Gradient function to evaluate */ +double (*dfunc)(void *fdata, double dp[], double tp[]), /* Gradient & function to evaluate */ + /* dfunc() should return DFUNC_NRV if it doesn't return function value */ void *fdata, /* Opaque data needed by function */ void (*prog)(void *pdata, int perc), /* Optional progress percentage callback */ void *pdata /* Opaque data needed by prog() */ ) { int i, iter; - double *svec; /* Search vector */ - double *gvec; /* G direction vector */ - double *hvec; /* H direction vector */ + double *svec, _svec[10]; /* Search vector */ + double *ssvec, _ssvec[10]; /* s[] scaled search vector */ + double *gvec, _gvec[10]; /* G direction vector */ + double *hvec, _hvec[10]; /* H direction vector */ double retv; /* Returned function value at p */ double stopth; /* Current stop threshold */ double startdel = -1.0; /* Initial change in function value */ double curdel; /* Current change in function value */ - double svec_sca; /* initial svec scale factor */ + double brat; /* svec to s[] ratio */ + double svec_sca; /* svec scale factor */ int pc = 0; /* Percentage complete */ - svec = dvector(0,di-1); - gvec = dvector(0,di-1); - hvec = dvector(0,di-1); + if (di <= 10) { + svec = _svec; + ssvec = _ssvec; + gvec = _gvec; + hvec = _hvec; + } else { + svec = dvector(0, di-1); + ssvec = dvector(0, di-1); + gvec = dvector(0, di-1); + hvec = dvector(0, di-1); + } + + CDBG(("conjgrad with di %d\n", di)) if (prog != NULL) /* Report initial progress */ prog(pdata, pc); - /* Initial gradient function evaluation */ + /* Initial function and gradient evaluation */ retv = (*dfunc)(fdata, svec, cp); - - /* svec[] seems to be large after this. */ - /* Rescale it to conform to maximum of s[] */ - for (svec_sca = 0.0, i = 0; i < di; i++) { - if (fabs(svec[i]) > svec_sca) - svec_sca = fabs(svec[i]); + if (retv == DFUNC_NRV) + retv = (*func)(fdata, cp); + + /* svec[] seems to be large after this. Compute scaled version that */ + /* has maximum of s[] so that line search is guided by the search radius. */ + for (brat = 0.0, i = 0; i < di; i++) { + double rat = fabs(svec[i]) / fabs(s[i]); + if (rat > brat) + brat = rat; } - /* set scale so largest <= 1 */ - if (svec_sca < 1e-12) - svec_sca = 1.0; - else - svec_sca = 1.0/svec_sca; - - CDBG((" initial dir = %s\n", debPdv(di,svec))); - CDBG((" initial retv = %f\n",retv)); + svec_sca = 1.0/brat; /* Initial vector setup */ for (i = 0; i < di; i++) { - gvec[i] = hvec[i] = -svec[i]; /* Inverse gradient */ - svec[i] = s[i] * -svec[i] * svec_sca; /* Scale the search vector */ + svec[i] = gvec[i] = hvec[i] = -svec[i]; /* Inverse gradient */ + ssvec[i] = svec[i] * svec_sca; /* Scale the search vector to s[] size */ } - CDBG(("Initial svec = %s\n", debPdv(di,svec))); + + CDBG((" initial dir = %s\n", debPdv(di, ssvec))); + CDBG((" initial retv = %f\n",retv)); /* Itterate untill we converge on a solution, or give up. */ for (iter = 1; iter < maxit; iter++) { double gamden, gamnum, gam; double pretv; /* Previous function return value */ - CDBG(("conjrad: about to do linmin\n")) + CDBG(("conjrad it %d: about to do linmind\n",iter)) pretv = retv; - retv = linmin(cp, svec, di, ftol, func, fdata); +#ifdef USE_LINMIND + retv = linmind(cp, ssvec, di, ftol, func, dfunc, fdata); +#else + retv = linmin(cp, ssvec, di, ftol, func, fdata); +#endif #ifdef ABSTOL stopth = ftol; /* Absolute tollerance */ #else - stopth = ftol * 0.5 * (fabs(pretv) + fabs(retv) + DBL_EPSILON); // Old code + stopth = ftol * 0.5 * (fabs(pretv) + fabs(retv) + DBL_EPSILON); #endif curdel = fabs(pretv - retv); CDBG((" this retv = %f, pretv = %f, curdel = %f\n",retv,pretv,curdel)); if (startdel < 0.0) { startdel = curdel; - } else { + } else if (prog != NULL) { /* Update percentage */ int tt; tt = (int)(100.0 * pow((log(curdel) - log(startdel))/(log(stopth) - log(startdel)), 4.0) + 0.5); if (tt > pc && tt < 100) { pc = tt; - if (prog != NULL) /* Report initial progress */ - prog(pdata, pc); + prog(pdata, pc); /* Report initial progress */ } } @@ -336,7 +677,7 @@ void *pdata /* Opaque data needed by prog() */ CDBG(("conjrad: recomputing direction\n")) (*dfunc)(fdata, svec, cp); /* (Don't use retv as it wrecks stop test) */ - CDBG((" pderiv = %s\n", debPdv(di,svec))); + CDBG((" pderiv = %s\n", debPdv(di, svec))); /* Compute gamma */ for (gamnum = gamden = 0.0, i = 0; i < di; i++) { @@ -360,25 +701,26 @@ void *pdata /* Opaque data needed by prog() */ svec[i] = hvec[i] = gvec[i] + gam * hvec[i]; } - /* svec[] seems to be large after this. */ - /* Rescale it to conform to maximum of s[] */ - for (svec_sca = 0.0, i = 0; i < di; i++) { - if (fabs(svec[i]) > svec_sca) - svec_sca = fabs(svec[i]); + /* svec[] seems to be large after this. Compute scaled version that */ + /* has maximum of s[] so that line search is guided by the search radius. */ + for (brat = 0.0, i = 0; i < di; i++) { + double rat = fabs(svec[i]) / fabs(s[i]); + if (rat > brat) + brat = rat; } - /* set scale so largest <= 1 */ - if (svec_sca < 1e-12) - svec_sca = 1.0; - else - svec_sca = 1.0/svec_sca; + svec_sca = 1.0/brat; for (i = 0; i < di; i++) - svec[i] = svec[i] * s[i] * svec_sca; - CDBG((" svec = %s\n", debPdv(di,svec))); + ssvec[i] = svec[i] * svec_sca; + + CDBG((" ssvec = %s\n", debPdv(di,ssvec))); } /* Free up all the temporary vectors and matrix */ - free_dvector(hvec,0,di-1); - free_dvector(gvec,0,di-1); - free_dvector(svec,0,di-1); + if (di > 10) { + free_dvector(hvec, 0, di-1); + free_dvector(gvec, 0, di-1); + free_dvector(ssvec, 0, di-1); + free_dvector(svec, 0, di-1); + } if (prog != NULL) /* Report final progress */ prog(pdata, 100); @@ -394,14 +736,15 @@ void *pdata /* Opaque data needed by prog() */ return 1; /* Failed due to execessive itterations */ } -/*------------------------------*/ #define POWELL_GOLD 1.618034 -#define POWELL_CGOLD 0.3819660 #define POWELL_MAXIT 100 -/* Line bracketing and minimisation routine. */ +/* Line bracketing and minimisation routine using derivatives */ +/* This is not used, because it typically makes it slower */ +/* - it may take less itterations, but each itteration uses */ +/* a func() and dfunc() call, at least doubling itter overhead. */ /* Return value at minimum. */ -double linmin( +double linmind( double cp[], /* Start point, and returned value */ double xi[], /* Search vector */ int di, /* Dimensionality */ @@ -410,23 +753,29 @@ double ftol, /* Absolute tolerance to stop on */ #else double ftol, /* Relative tolerance to stop on */ #endif -double (*func)(void *fdata, double tp[]), /* Error function to evaluate */ +double (*func)(void *fdata, double tp[]), /* Error function to evaluate */ +double (*dfunc)(void *fdata, double dp[], double tp[]), /* Gradient function to evaluate */ + /* dfunc() should return DFUNC_NRV if it doesn't return function value */ void *fdata) /* Opaque data for func() */ { int i; double ax, xx, bx; /* Search vector multipliers */ double af, xf, bf; /* Function values at those points */ - double *xt, XT[10]; /* Trial point */ + double *xt, _xt[10]; /* Trial point */ + double *df, _df[10]; /* Derivative vector */ - if (di <= 10) - xt = XT; - else + if (di <= 10) { + xt = _xt; + df = _df; + } else { xt = dvector(0, di-1); /* Vector for trial point */ + df = dvector(0, di-1); /* Vector for trial point */ + } /* -------------------------- */ /* First bracket the solution */ - LDBG(("linmin: Bracketing solution\n")) + LDBG((" linmind: Bracketing solution\n")) /* The line is measured as startpoint + offset * search vector. */ /* (Search isn't symetric, but it seems to depend on cp being */ @@ -442,7 +791,7 @@ void *fdata) /* Opaque data for func() */ xt[i] = cp[i] + xx * xi[i]; xf = (*func)(fdata, xt); - LDBG(("linmin: Initial points a:%f:%f -> b:%f:%f\n",ax,af,xx,xf)) + LDBG((" linmind: Initial points a:%f:%f -> b:%f:%f\n",ax,af,xx,xf)) /* Fix it so that we are decreasing from point a -> x */ if (xf > af) { @@ -450,33 +799,31 @@ void *fdata) /* Opaque data for func() */ tt = ax; ax = xx; xx = tt; tt = af; af = xf; xf = tt; } - LDBG(("linmin: Ordered Initial points a:%f:%f -> b:%f:%f\n",ax,af,xx,xf)) + LDBG((" linmind: Ordered Initial points a:%f:%f -> b:%f:%f\n",ax,af,xx,xf)) bx = xx + POWELL_GOLD * (xx-ax); /* Guess b beyond a -> x */ for (i = 0; i < di; i++) xt[i] = cp[i] + bx * xi[i]; bf = (*func)(fdata, xt); - LDBG(("linmin: Initial bracket a:%f:%f x:%f:%f b:%f:%f\n",ax,af,xx,xf,bx,bf)) + LDBG((" linmind: Initial bracket a:%f:%f x:%f:%f b:%f:%f\n",ax,af,xx,xf,bx,bf)) #ifdef SLOPE_SANITY_CHECK /* If we're not seeing a slope indicitive of progress */ /* of order ftol, give up straight away */ if (2000.0 * fabs(xf - bf) <= ftol * (fabs(xf) + fabs(bf)) && 2000.0 * fabs(af - xf) <= ftol * (fabs(af) + fabs(xf))) { - LDBG(("linmin: giving up because slope is too shallow\n")) - if (xt != XT) - free_dvector(xt,0,di-1); + LDBG((" linmind: giving up because slope is too shallow\n")) + if (di > 10) { + free_dvector(df, 0, di-1); + free_dvector(xt, 0, di-1); + } if (bf < xf) { xf = bf; xx = bx; } - - /* Compute solution vector */ - for (i = 0; i < di; i++) - cp[i] += xx * xi[i]; - return xf; + goto done; } #endif /* SLOPE_SANITY_CHECK */ @@ -485,8 +832,7 @@ void *fdata) /* Opaque data for func() */ double ulim, ux, uf; double tt, r, q; -// LDBG(("linmin: Not bracketed a:%f:%f x:%f%f b:%f:%f\n",ax,af,xx,xf,bx,bf)) - LDBG(("linmin: Not bracketed because xf %f > bf %f\n",xf, bf)) + LDBG((" linmind: Not bracketed because xf %f > bf %f\n",xf, bf)) LDBG((" ax = %f, xx = %f, bx = %f\n",ax,xx,bx)) /* Compute ux by parabolic interpolation from a, x & b */ @@ -559,7 +905,7 @@ void *fdata) /* Opaque data for func() */ bx = ux; bf = uf; //printf("~1 move along to the right (a<-x, x<-b, b- x -> b */ //printf("~1 got bracketed minimum at %f (%f), %f (%f), %f (%f)\n",ax,af,xx,xf,bx,bf); @@ -571,8 +917,10 @@ void *fdata) /* Opaque data for func() */ /* w is second best function value so far */ /* v is previous second best, or third best */ /* u is most recently tested point */ + double wx, vx, ux; /* Search vector multipliers */ double wf, vf = 0.0, uf; /* Function values at those points */ + double xd, wd, vd, ud; /* Derivative values at those points */ int iter; double de = 0.0; /* Distance moved on previous step */ double e = 0.0; /* Distance moved on 2nd previous step */ @@ -587,6 +935,16 @@ void *fdata) /* Opaque data for func() */ wx = vx = xx; /* Initial values of other center points */ wf = xf = xf; + /* Lookup derivative at x (we already have xf from bracketing) */ + for (i = 0; i < di; i++) + xt[i] = cp[i] + xx * xi[i]; + (*dfunc)(fdata, df, xt); + for (xd = 0.0, i = 0; i < di; i++) + xd += xi[i] * df[i]; + wd = ud = xd; + + LDBG((" linmind: xx %f, deriv. xd %f\n",xx,xd)) + for (iter = 1; iter <= POWELL_MAXIT; iter++) { double mx = 0.5 * (ax + bx); /* m is center of bracket values */ #ifdef ABSTOL @@ -596,113 +954,169 @@ void *fdata) /* Opaque data for func() */ #endif double tol2 = 2.0 * tol1; - LDBG(("linmin: Got bracket a:%f:%f x:%f:%f b:%f:%f\n",ax,af,xx,xf,bx,bf)) + LDBG((" linmind it %d: Got bracket a:%f:%f x:%f:%f b:%f:%f\n",iter, ax,af,xx,xf,bx,bf)) /* See if we're done */ -//printf("~1 linmin check %f <= %f\n",fabs(xx - mx), tol2 - 0.5 * (bx - ax)); if (fabs(xx - mx) <= (tol2 - 0.5 * (bx - ax))) { - LDBG(("linmin: We're done because %f <= %f\n",fabs(xx - mx), tol2 - 0.5 * (bx - ax))) + LDBG((" linmind: We're done because %e <= %e\n",fabs(xx - mx), tol2 - 0.5 * (bx - ax))) break; } - if (fabs(e) > tol1) { /* Do a trial parabolic fit */ - double te, p, q, r; - r = (xx-wx) * (xf-vf); - q = (xx-vx) * (xf-wf); - p = (xx-vx) * q - (xx-wx) * r; - q = 2.0 * (q - r); - if (q > 0.0) - p = -p; - else - q = -q; + LDBG((" linmind: e %f tol2 %f\n",e,tol1)) + + if (fabs(e) > tol1) { /* Do a trial secant fit */ + double te; + double dx1, dx2; /* Secant extrapolation points */ + double ux1, ux2; + int ch1, ch2; + + LDBG((" linmind: Doing trial secant fit\n" )) + + dx2 = dx1 = 2.0 * (bx - ax); /* Default to values out of the ax..bx bracket */ + + /* Extrapolated points from last two points (secant method) */ + if (wd != xd) + dx1 = (wx - xx) * xd/(xd - wd); + if (vd != xd) + dx2 = (vx - xx) * xd/(xd - vd); + + ux1 = xx + dx1; + ux2 = xx + dx2; + + /* Check which one is reasonable */ + ch1 = (ax - ux1) * (ux1 - bx) > 0.0 && xd * dx1 < 0.0; + ch2 = (ax - ux2) * (ux2 - bx) > 0.0 && xd * dx2 < 0.0; + + LDBG((" linmind: Doing dx1 %f dx2 %f ux1 %f ux2 %f ch1 %d ch2 %d\n",dx1,dx2,ux1,ux2,ch1,ch2)) + te = e; /* Save previous e value */ e = de; /* Previous steps distance moved */ - LDBG(("linmin: Trial parabolic fit\n" )) + if (!ch1 && !ch2) + goto bisect; - if (fabs(p) >= fabs(0.5 * q * te) || p <= q * (ax-xx) || p >= q * (bx-xx)) { - /* Give up on the parabolic fit, and use the golden section search */ - e = ((xx >= mx) ? ax-xx : bx-xx); /* Override previous distance moved */ - de = POWELL_CGOLD * e; - LDBG(("linmin: Moving to golden section search\n" )) - } else { /* Use parabolic fit */ - de = p/q; /* Change in xb */ - ux = xx + de; /* Trial point according to parabolic fit */ - if ((ux - ax) < tol2 || (bx - ux) < tol2) { - if ((mx - xx) > 0.0) /* Don't use parabolic, use tol1 */ - de = tol1; /* tol1 is +ve */ - else - de = -tol1; - } - LDBG(("linmin: Using parabolic fit\n" )) + /* Use smallest or the one that's valid */ + if (ch1 && ch2) + de = fabs(dx1) < fabs(dx2) ? dx1 : dx2; + if (ch1) + de = dx1; + else if (ch2) + de = dx2; + + LDBG((" linmind: set de %f\n",de)) + + if (fabs(de) > fabs(0.5 * te)) { + LDBG((" linmind: abs(de) %f > abs(te/2 = %f)\n",fabs(de),fabs(0.5 * te))) + goto bisect; } - } else { /* Keep using the golden section search */ - e = ((xx >= mx) ? ax-xx : bx-xx); /* Override previous distance moved */ - de = POWELL_CGOLD * e; - LDBG(("linmin: Continuing golden section search\n" )) + + ux = xx + de; + + if ((ux - ax) < tol2 || (bx - ux) < tol2) { + if ((mx - xx) < 0.0) + de = -fabs(tol1); + else + de = fabs(tol1); + LDBG((" linmind: Set de to tol1 %f\n",de)) + } +#ifdef LDEBUG + else { + LDBG((" linmind: Using secant fit de %f\n",de)) + } +#endif + + /* else bisect picking side using sign of derivative */ + } else { + bisect: + e = (xd >= 0.0 ? ax - xx : bx -xx); + de = 0.5 * e; + LDBG((" linmind: Continuing bisection search de %f\n",de)) } - if (fabs(de) >= tol1) { /* If de moves as much as tol1 would */ + if (fabs(de) >= tol1) { /* If de moves as much as tol1 or more */ ux = xx + de; /* use it */ - LDBG(("linmin: ux = %f = xx %f + de %f\n",ux,xx,de)) + + /* Evaluate function */ + for (i = 0; i < di; i++) + xt[i] = cp[i] + ux * xi[i]; + uf = (*func)(fdata, xt); + + LDBG((" linmind: ux = %f = xx %f + de %f, uf %f\n",ux,xx,de,uf)) + } else { /* else move by tol1 in direction de */ if (de > 0.0) { ux = xx + tol1; - LDBG(("linmin: ux = %f = xx %f + tol1 %f\n",ux,xx,tol1)) + LDBG((" linmind: ux = %f = xx %f + tol1 %f\n",ux,xx,tol1)) } else { ux = xx - tol1; - LDBG(("linmin: ux = %f = xx %f - tol1 %f\n",ux,xx,tol1)) + LDBG((" linmind: ux = %f = xx %f - tol1 %f\n",ux,xx,tol1)) + } + /* Evaluate function */ + for (i = 0; i < di; i++) + xt[i] = cp[i] + ux * xi[i]; + uf = (*func)(fdata, xt); + + LDBG((" linmind: uf %f\n",uf)) + + if (uf > xf) { /* If tol1 step downhill takes us uphill, we're done */ + goto done; } } - /* Evaluate function */ - for (i = 0; i < di; i++) - xt[i] = cp[i] + ux * xi[i]; - uf = (*func)(fdata, xt); + /* Evaluate derivative at trial point */ + (*dfunc)(fdata, df, xt); + for (ud = 0.0, i = 0; i < di; i++) + ud += xi[i] * df[i]; + + LDBG((" linmind: ux %f, deriv. ud %f\n",ux,ud)) + /* Houskeeping: */ if (uf <= xf) { /* Found new best solution */ - LDBG(("linmin: found new best solution at %f val %f\n",ux,uf)) + LDBG((" linmind: found new best solution at %f val %f dval %f\n",ux,uf,ud)) if (ux >= xx) { - ax = xx; af = xf; /* New lower bracket */ + ax = xx; af = xf; /* New lower bracket */ } else { bx = xx; bf = xf; /* New upper bracket */ } - vx = wx; vf = wf; /* New previous 2nd best solution */ - wx = xx; wf = xf; /* New 2nd best solution from previous best */ - xx = ux; xf = uf; /* New best solution from latest */ - } else { /* Found a worse solution */ - LDBG(("linmin: found new worse solution at %f val %f\n",ux,uf)) - LDBG(("linmin: current best at %f val %f\n",xx,xf)) + vx = wx; vf = wf; vd = wd; /* New previous 2nd best solution */ + wx = xx; wf = xf; wd = xd; /* New 2nd best solution from previous best */ + xx = ux; xf = uf; xd = ud; /* New best solution from latest */ + + } else { /* Found a worse solution */ + LDBG((" linmind: found new worse solution at %f val %f dval %f\n",ux,uf,ud)) + LDBG((" linmind: current best at %f val %f dval %f\n",xx,xf,xd)) if (ux < xx) { ax = ux; af = uf; /* New lower bracket */ } else { bx = ux; bf = uf; /* New upper bracket */ } if (uf <= wf || wx == xx) { /* New 2nd best solution, or equal best */ - vx = wx; vf = wf; /* New previous 2nd best solution */ - wx = ux; wf = uf; /* New 2nd best from latest */ + vx = wx; vf = wf; vd = wd; /* New previous 2nd best solution */ + wx = ux; wf = uf; wd = ud; /* New 2nd best from latest */ } else if (uf <= vf || vx == xx || vx == wx) { /* New 3rd best, or equal 1st & 2nd */ - vx = ux; vf = uf; /* New previous 2nd best from latest */ + vx = ux; vf = uf; vd = ud; /* New previous 2nd best from latest */ } } - } - /* !!! should do something if iter > POWELL_MAXIT !!!! */ + } /* Next itter */ + + /* !!! should do something if iter > POWELL_MAXIT ??? */ /* Solution is at xx, xf */ + done:; + if (di > 10) { + free_dvector(df, 0, di-1); + free_dvector(xt, 0, di-1); + } /* Compute solution vector */ - LDBG(("linmin: computing soln from best at %f val %f\n",xx,xf)) + LDBG((" linmind: computing soln from best at %f val %f dval %f\n",xx,xf,xd)) for (i = 0; i < di; i++) cp[i] += xx * xi[i]; - } - if (xt != XT) - free_dvector(xt,0,di-1); -//printf("~~~ line minimizer returning %e\n",xf); + } /* Minimizer context */ + return xf; } #undef POWELL_GOLD -#undef POWELL_CGOLD #undef POWELL_MAXIT -/**************************************************/ diff --git a/numlib/powell.h b/numlib/powell.h index 4b86573..642cb65 100755 --- a/numlib/powell.h +++ b/numlib/powell.h @@ -15,6 +15,8 @@ extern "C" { #endif +#define DFUNC_NRV 1e100 + /* Standard interface for powell function */ /* return 0 on sucess, 1 on failure due to excessive itterations */ /* Result will be in cp */ @@ -32,7 +34,7 @@ void (*prog)(void *pdata, int perc), /* Optional progress percentage callback * void *pdata /* Opaque data needed by prog() */ ); -/* Conjugate Gradient optimiser */ +/* Conjugate Gradient optimiser using partial derivatives. */ /* return 0 on sucess, 1 on failure due to excessive itterations */ /* Result will be in cp */ int conjgrad( @@ -43,7 +45,8 @@ double s[], /* Size of initial search area */ double ftol, /* Tollerance of error change to stop on */ int maxit, /* Maximum iterations allowed */ double (*func)(void *fdata, double tp[]), /* Error function to evaluate */ -double (*dfunc)(void *fdata, double dp[], double tp[]), /* Gradient function to evaluate */ +double (*dfunc)(void *fdata, double dp[], double tp[]), /* Gradient & function to evaluate */ + /* dfunc() should return DFUNC_NRV if it doesn't return function value */ void *fdata, /* Opaque data needed by function */ void (*prog)(void *pdata, int perc), /* Optional progress percentage callback */ void *pdata /* Opaque data needed by prog() */ @@ -69,6 +72,22 @@ double (*func)(void *fdata, double tp[]), /* Error function to evaluate */ void *fdata /* Opaque data for func() */ ); +/* Line bracketing and minimisation routine using derivatives. */ +/* Return value at minimum. */ +double linmind( +double cp[], /* Start point, and returned value */ +double xi[], /* Search vector */ +int di, /* Dimensionality */ +#ifdef ABSTOL +double ftol, /* Absolute tolerance to stop on */ +#else +double ftol, /* Relative tolerance to stop on */ +#endif +double (*func)(void *fdata, double tp[]), /* Error function to evaluate */ +double (*dfunc)(void *fdata, double dp[], double tp[]), /* Gradient & function to evaluate */ +void *fdata /* Opaque data for func() */ +); + #ifdef __cplusplus } #endif diff --git a/numlib/quadprog.c b/numlib/quadprog.c index 847601f..4e94cec 100755 --- a/numlib/quadprog.c +++ b/numlib/quadprog.c @@ -233,7 +233,7 @@ double quadprog( /* Return solution cost, QP_INFEASIBLE if infeasible/error */ /* and compute the current solution value */ f_value = 0.5 * scalar_product(g0, x, n); #ifdef TRACE_SOLVER - printf("Unconstrained solution: %f",f_value); + printf("Unconstrained solution: f_value %f\n",f_value); print_vector("x", x, n); #endif @@ -314,9 +314,11 @@ l1: iter++; #endif if (fabs(psi) <= m * DBL_EPSILON * c1 * c2* 100.0) { - /* numerically there are not infeasibilities anymore */ + /* numerically there are no infeasibilities anymore */ +#ifdef TRACE_SOLVER + printf("numerically there are no infeasibilities anymore\n"); +#endif q = iq; - goto done; } @@ -338,8 +340,10 @@ l2: /* Step 2: check for feasibility and determine a new S-pair */ } } if (ss >= 0.0) { +#ifdef TRACE_SOLVER + printf(" ss %f >= 0.0\n",ss); +#endif q = iq; - goto done; } @@ -398,7 +402,7 @@ l2a: /* the step is chosen as the minimum of t1 and t2 */ t = FMIN(t1, t2); #ifdef TRACE_SOLVER - printf("Step sizes: %f (t1 = %f, t2 = %f\n",t,t1,t2); + printf("Step size: %e (t1 = %e, t2 = %e\n",t,t1,t2); #endif /* Step 2c: determine new S-pair and take step: */ @@ -407,6 +411,9 @@ l2a: if (t >= QP_INFEASIBLE) { /* QPP is infeasible */ // FIXME: unbounded to raise +#ifdef TRACE_SOLVER + printf(" QPP is infeasible\n"); +#endif q = iq; f_value = QP_INFEASIBLE; goto done; @@ -449,18 +456,21 @@ l2a: if (fabs(t - t2) < DBL_EPSILON) { #ifdef TRACE_SOLVER - printf("Full step has taken %f\n",t); + printf("Full step has been taken %f\n",t); print_vector("x", x, n); #endif - /* full step has taken */ - /* add constraint ip to the active set*/ + /* full step has been taken */ + /* Add constraint ip to the active set*/ if (!add_constraint(R, J, d, &iq, &R_norm, n)) { +#ifdef TRACE_SOLVER + printf("add_constraint failed - removing constraint ant step\n",t); +#endif iaexcl[ip] = 0; delete_constraint(R, J, A, u, n, p, &iq, ip); #ifdef TRACE_SOLVER print_matrix("R", R, n, n); print_ivector("A", A, iq); - print_ivector("iai", iai, iq); // ?? iq size of m+p ? + print_ivector("iai", iai, m+p); #endif for (i = 0; i < m; i++) iai[i] = i; @@ -477,7 +487,7 @@ l2a: #ifdef TRACE_SOLVER print_matrix("R", R, n, n); print_ivector("A", A, iq); - print_ivector("iai", iai, iq); // ?? iq size of m+p ? + print_ivector("iai", iai, m + p); #endif goto l1; } @@ -532,6 +542,11 @@ l2a: free_svector(iaexcl, 0, m + p-1); } +#ifdef TRACE_SOLVER + printf("Returning f_value %e\n",f_value); + print_vector("Returning x", x, n); +#endif + return f_value; } diff --git a/numlib/quadprog.h b/numlib/quadprog.h index 7d28ec8..d091b75 100755 --- a/numlib/quadprog.h +++ b/numlib/quadprog.h @@ -25,20 +25,20 @@ The problem is in the form: min 0.5 * x G x + g0 x s.t. - CE^T x + ce0 = 0 - CI^T x + ci0 >= 0 + CE^t x + ce0 = 0 + CI^t x + ci0 >= 0 The matrix and vectors dimensions are as follows: - G: n * n - g0: n + G: n * n + g0: n - CE: n * p - ce0: p + CE: n * p + ce0: p - CI: n * m - ci0: m + CI: n * m + ci0: m - x: n + x: n References: D. Goldfarb, A. Idnani. A numerically stable dual method for solving strictly convex quadratic programs. Mathematical Programming 27 (1983) pp. 1-33. diff --git a/numlib/rand.c b/numlib/rand.c index 9e58de3..e2fdfdf 100755 --- a/numlib/rand.c +++ b/numlib/rand.c @@ -39,12 +39,18 @@ double ranno(void) { return rand32_th(NULL, 0) / 4294967295.0; } -/* Return a random double in the range min to max */ +/* Return a uniform random double in the range min to max */ double d_rand(double min, double max) { return d_rand_th(NULL, min, max); } +/* Return a squared distribution random double in the range min to max */ +double +d2_rand(double min, double max) { + return d2_rand_th(NULL, min, max); +} + /* Return a random integer in the range min to max inclusive */ int i_rand(int min, int max) { @@ -81,6 +87,7 @@ unsigned int seed /* Optional seed. Non-zero re-initialized with that seed */ p = &g_rand; if (seed != 0) { +//printf("~1 rand 0x%x seed 0x%x\n",p,seed); p->pvs_inited = 0; p->ran = seed; } @@ -98,21 +105,29 @@ unsigned int seed /* Optional seed. Non-zero re-initialized with that seed */ p->last = p->pvs[i]; /* Value generated */ p->pvs[i] = p->ran = PSRAND32(p->ran); /* New value */ +//printf("~1 rand 0x%x ret 0x%x\n",p,p->last-1); return p->last-1; } /* return a random number between 0.0 and 1.0 */ /* based on rand32 */ double ranno_th(rand_state *p) { - return rand32_th(NULL, 0) / 4294967295.0; + return rand32_th(p, 0) / 4294967295.0; } -/* Return a random double in the range min to max */ +/* Return a uniform random double in the range min to max */ double d_rand_th(rand_state *p, double min, double max) { return min + (max - min) * ranno_th(p); } +/* Return a squared distribution random double in the range min to max */ +double +d2_rand_th(rand_state *p, double min, double max) { + double val = ranno_th(p); + return min + (max - min) * val * val; +} + /* Return a random integer in the range min to max inclusive */ int i_rand_th(rand_state *p, int min, int max) { diff --git a/numlib/rand.h b/numlib/rand.h index e190fcd..0339b24 100755 --- a/numlib/rand.h +++ b/numlib/rand.h @@ -24,9 +24,12 @@ unsigned int seed); /* Optional seed. Non-zero re-initialized with that seed * /* Return a random integer in the range min to max inclusive */ int i_rand(int min, int max); -/* Return a random double in the range min to max inclusive */ +/* Return a uniform random double in the range min to max inclusive */ double d_rand(double min, double max); +/* Return a squared distribution random double in the range min to max inclusive */ +double d2_rand(double min, double max); + /* Return a random floating point number with a gausian/normal */ /* distribution, centered about 0.0, with standard deviation 1.0 */ /* and an average deviation of 0.564 */ @@ -61,9 +64,12 @@ unsigned int seed); /* Optional seed. Non-zero re-initialized with that seed * /* Return a random integer in the range min to max inclusive */ int i_rand_th(rand_state *p, int min, int max); -/* Return a random double in the range min to max inclusive */ +/* Return a uniform random double in the range min to max inclusive */ double d_rand_th(rand_state *p, double min, double max); +/* Return a squared distribution random double in the range min to max inclusive */ +double d2_rand_th(rand_state *p, double min, double max); + /* Return a random floating point number with a gausian/normal */ /* distribution, centered about 0.0, with standard deviation 1.0 */ /* and an average deviation of 0.564 */ diff --git a/numlib/roots.c b/numlib/roots.c new file mode 100755 index 0000000..04e1526 --- /dev/null +++ b/numlib/roots.c @@ -0,0 +1,217 @@ + +/* + * Roots3And4.c + * + * Utility functions to find cubic and quartic roots. + * + * Coefficients are passed like this: + * + * c[0] + c[1]*x + c[2]*x^2 + c[3]*x^3 + c[4]*x^4 = 0 + * + * The functions return the number of non-complex roots and + * put the values into the s array. + * + * Author: Jochen Schwarze (schwarze@isa.de) + * + * Jan 26, 1990 Version for Graphics Gems + * Oct 11, 1990 Fixed sign problem for negative q's in SolveQuartic + * (reported by Mark Podlipec), + * Old-style function definitions, + * IsZero() as a macro + * Nov 23, 1990 Some systems do not declare acos() and cbrt() in + * , though the functions exist in the library. + * If large coefficients are used, EQN_EPS should be + * reduced considerably (e.g. to 1E-30), results will be + * correct but multiple roots might be reported more + * than once. + * Apr 18, 2018 Reformat for inclusing in ArgyllCMS - GWG + * + * The authors and the publisher hold no copyright restrictions + * on any of these files; this source code is public domain, and + * is freely available to the entire computer graphics community + * for study, use, and modification. We do request that the + * comment at the top of each file, identifying the original + * author and its original publication in the book Graphics + * Gems, be retained in all programs that use these files. + * + */ + +#include +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/* epsilon surrounding for near zero values */ +#define EQN_EPS 1e-9 +#define IsZero(x) ((x) > -EQN_EPS && (x) < EQN_EPS) + +#define CBRT(x) ((x) > 0.0 ? pow((double)(x), 1.0/3.0) : \ + ((x) < 0.0 ? -pow((double)-(x), 1.0/3.0) : 0.0)) + +int SolveQuadric(double c[3], double s[2]) { + double p, q, D; + + /* normal form: x^2 + px + q = 0 */ + p = c[1] / (2 * c[2]); + q = c[0] / c[2]; + + D = p * p - q; + + if (IsZero(D)) { + s[ 0 ] = - p; + return 1; + } else if (D < 0) { + return 0; + } else /* if (D > 0) */ { + double sqrt_D = sqrt(D); + + s[0] = sqrt_D - p; + s[1] = - sqrt_D - p; + return 2; + } +} + + +int SolveCubic(double c[4], double s[3]) { + int i, num; + double sub; + double A, B, C; + double sq_A, p, q; + double cb_p, D; + + /* normal form: x^3 + Ax^2 + Bx + C = 0 */ + A = c[2] / c[3]; + B = c[1] / c[3]; + C = c[0] / c[3]; + + /* substitute x = y - A/3 to eliminate quadric term: */ + /* x^3 +px + q = 0 */ + sq_A = A * A; + p = 1.0/3 * (-1.0/3 * sq_A + B); + q = 1.0/2 * (2.0/27 * A * sq_A - 1.0/3 * A * B + C); + + /* use Cardano's formula */ + cb_p = p * p * p; + D = q * q + cb_p; + + if (IsZero(D)) { + if (IsZero(q)) { /* one triple solution */ + s[0] = 0.0; + num = 1; + } else { /* one single and one double solution */ + double u = CBRT(-q); + s[0] = 2.0 * u; + s[1] = - u; + num = 2; + } + } else if (D < 0) { /* Casus irreducibilis: three real solutions */ + double phi = 1.0/3 * acos(-q / sqrt(-cb_p)); + double t = 2 * sqrt(-p); + + s[0] = t * cos(phi); + s[1] = -t * cos(phi + M_PI / 3.0); + s[2] = -t * cos(phi - M_PI / 3.0); + num = 3; + } else { /* one real solution */ + double sqrt_D = sqrt(D); + double u = CBRT(sqrt_D - q); + double v = -CBRT(sqrt_D + q); + + s[0] = u + v; + num = 1; + } + + /* resubstitute */ + sub = 1.0/3.0 * A; + + for (i = 0; i < num; i++) + s[i] -= sub; + + return num; +} + + +int SolveQuartic(double c[5], double s[4]) { + double coeffs[4]; + double z, u, v, sub; + double A, B, C, D; + double sq_A, p, q, r; + int i, num; + + /* normal form: x^4 + Ax^3 + Bx^2 + Cx + D = 0 */ + A = c[3] / c[4]; + B = c[2] / c[4]; + C = c[1] / c[4]; + D = c[0] / c[4]; + + /* substitute x = y - A/4 to eliminate cubic term: + x^4 + px^2 + qx + r = 0 */ + sq_A = A * A; + p = - 3.0/8 * sq_A + B; + q = 1.0/8 * sq_A * A - 1.0/2 * A * B + C; + r = - 3.0/256*sq_A*sq_A + 1.0/16*sq_A*B - 1.0/4*A*C + D; + + if (IsZero(r)) { + /* no absolute term: y(y^3 + py + q) = 0 */ + + coeffs[0] = q; + coeffs[1] = p; + coeffs[2] = 0; + coeffs[3] = 1.0; + + num = SolveCubic(coeffs, s); + + s[num++] = 0; + } else { + /* solve the resolvent cubic ... */ + coeffs[0] = 1.0/2.0 * r * p - 1.0/8.0 * q * q; + coeffs[1] = - r; + coeffs[2] = - 1.0/2.0 * p; + coeffs[3] = 1.0; + + (void) SolveCubic(coeffs, s); + + /* ... and take the one real solution ... */ + z = s[0]; + + /* ... to build two quadric equations */ + u = z * z - r; + v = 2 * z - p; + + if (IsZero(u)) + u = 0; + else if (u > 0) + u = sqrt(u); + else + return 0; + + if (IsZero(v)) + v = 0; + else if (v > 0) + v = sqrt(v); + else + return 0; + + coeffs[0] = z - u; + coeffs[1] = q < 0 ? -v : v; + coeffs[2] = 1.0; + + num = SolveQuadric(coeffs, s); + + coeffs[0]= z + u; + coeffs[1] = q < 0 ? v : -v; + coeffs[2] = 1.0; + + num += SolveQuadric(coeffs, s + num); + } + + /* resubstitute */ + sub = 1.0/4.0 * A; + + for (i = 0; i < num; i++) + s[i] -= sub; + + return num; +} + + diff --git a/numlib/roots.h b/numlib/roots.h new file mode 100755 index 0000000..e14b72d --- /dev/null +++ b/numlib/roots.h @@ -0,0 +1,23 @@ + +/* + * Roots3And4.c + * + * Utility functions to find cubic and quartic roots, + * coefficients are passed like this: + * + * c[0] + c[1]*x + c[2]*x^2 + c[3]*x^3 + c[4]*x^4 = 0 + * + * The functions return the number of non-complex roots and + * put the values into the s array. + * + * Author: Jochen Schwarze (schwarze@isa.de) + * (From Graphics Gems I) + */ + +int SolveQuadric(double c[3], double s[2]); + +int SolveCubic(double c[4], double s[3]); + +int SolveQuartic(double c[5], double s[4]); + + diff --git a/numlib/tconjgrad.c b/numlib/tconjgrad.c new file mode 100755 index 0000000..aa98871 --- /dev/null +++ b/numlib/tconjgrad.c @@ -0,0 +1,162 @@ +/* Code to test the conjgrad minimiser */ +/* + * Copyright 1999, 2018 Graeme W. Gill + * All rights reserved. + * + * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :- + * see the License.txt file for licencing details. + */ + +#include +#include "numlib.h" + +/* Final approximate solution: */ + +double expect[9] = { + -0.5706545E+00, + -0.6816283E+00, + -0.7017325E+00, + -0.7042129E+00, + -0.7013690E+00, + -0.6918656E+00, + -0.6657920E+00, + -0.5960342E+00, + -0.4164121E+00 }; + +double fcn( /* Return function value */ + void *fdata, /* Opaque data pointer */ + double tp[] /* Multivriate input value */ +); + +static double dfcn( + void *fdata, + double dp[], + double tp[] +); + +#define N 9 + +static void progress(void *pdata, int perc) { + printf("%c% 3d%%",cr_char,perc); + if (perc == 100) + printf("\n"); + fflush(stdout); +} + +int main(void) +{ + double cp[N]; /* Function input values */ + double s[N]; /* Search area */ + double err; + int j; + int nprint = 0; /* Itteration debugging print = off */ + int rc; + + error_program = "tpowell"; /* Set global error reporting string */ + check_if_not_interactive(); + + /* The following starting values provide a rough solution. */ + for (j = 0; j < N; j++) { + cp[j] = -1.f; + s[j] = 0.9; + } + + nprint = 0; + + /* Set tol to the square root of the machine precision. */ + /* Unless high precision solutions are required, */ + /* this is the recommended setting. */ + + rc = conjgrad( + &err, + N, /* Dimentionality */ + cp, /* Initial starting point */ + s, /* Size of initial search area */ + 0.00000001, /* Tollerance of error change to stop on */ + 1000, /* Maximum iterations allowed */ + fcn, /* Error function to evaluate */ + dfcn, /* Partial derivative function */ + NULL, /* Opaque data needed by function */ + progress, /* Progress callback */ + NULL /* Context for callback */ + ); + + + fprintf(stdout,"Status = %d, final approximate solution err = %f:\n",rc,err); + for (j = 0; j < N; j++) { + fprintf(stdout,"cp[%d] = %e, expect %e\n",j,cp[j],expect[j]); + } + + return 0; +} /* main() */ + +/* Function being minimized */ +double fcn( /* Return function value */ +void *fdata, /* Opaque data pointer */ +double tp[] /* Multivriate input value */ +) { + double err, tt; + double temp, temp1, temp2; + int k; + + /* Function Body */ + err = 0.0; + for (k = 0; k < N; ++k) { + temp = (3.0 - 2.0 * tp[k]) * tp[k]; + temp1 = 0.0; + if (k != 0) { + temp1 = tp[k-1]; + } + temp2 = 0.0; + if (k != ((N)-1)) + temp2 = tp[k+1]; + tt = temp - temp1 - 2.0 * temp2 + 1.0; + err += tt * tt; + } + err = sqrt(err); +//printf("Returning %16.14f\n",err); + return err; +} + + +/* Compute aprox. forward difference */ + +#define JEPS 1.0e-8 /* Aprox. sqrt of machine precision */ + +static double dfcn( +void *fdata, +double dp[], +double tp[] +) { + int i; + double d, h, temp; + + d = fcn(fdata, tp); + + for (i = 0; i < N; i++) { + temp = tp[i]; + + h = JEPS * fabs(temp); + if (h == 0.0) + h = JEPS; + tp[i] = temp + h; /* Add delta */ + h = tp[i] - temp; /* Actual delta with fp precision limits */ + + dp[i] = (fcn(fdata, tp) - d)/h; + + tp[i] = temp; /* Restore value */ + } + + return DFUNC_NRV; +} + + + + + + + + + + + diff --git a/plot/plot.c b/plot/plot.c index be4d1cf..d0cf081 100755 --- a/plot/plot.c +++ b/plot/plot.c @@ -35,6 +35,7 @@ #include #endif #include +#include "aconfig.h" #include "numlib.h" #include "plot.h" //#ifdef STANDALONE_TEST @@ -54,14 +55,12 @@ #define DEFWHEIGHT 500 /* Graph order is Black = Y1, Red = Y2, Green = Y3, Blue = Y4, Yellow = Y5, Purple = Y6 */ -/* Brown = Y7, Orange = Y8, Grey = Y9, Magenta = Y10 */ +/* Brown = Y7, Orange = Y8, Grey = Y9, Magenta = Y10, Lime = Y11, Pink = Y12 */ double nicenum(double x, int round); -#define MXGPHS 10 /* Number of graphs with common X axis */ - /* Colors of the graphs */ -static int gcolors[MXGPHS][3] = { +int plot_colors[MXGPHS][3] = { { 0, 0, 0}, /* Black */ { 210, 30, 0}, /* Red */ { 0, 200, 90}, /* Green */ @@ -71,7 +70,9 @@ static int gcolors[MXGPHS][3] = { { 136, 86, 68}, /* Brown */ { 248, 95, 0}, /* Orange */ { 160, 160, 160}, /* Grey */ - { 220, 30, 220} /* Magenta */ + { 220, 30, 220}, /* Magenta */ + { 112, 255, 161}, /* Lime */ + { 255, 191, 80} /* Pink */ }; /* Information defining plot */ @@ -90,6 +91,7 @@ struct _plot_info { double *x1, *x2; double *yy[MXGPHS]; /* y1 - y10 */ + plot_col *ncols; char **ntext; int n; @@ -123,7 +125,7 @@ static int do_plot_imp( double ratio, /* Aspect ratio of window, X/Y, 1.0 = nominal */ int dowait, /* > 0 wait for user to hit space key, < 0 delat dowait seconds. */ double *x1, double *x2, - double *yy[MXGPHS], char **ntext, + double *yy[MXGPHS], plot_col *ncols, char **ntext, int n, double *x7, double *y7, plot_col *mcols, char **mtext, int m, @@ -184,7 +186,7 @@ int n) { return do_plot_imp(PLOTF_NONE, xmin, xmax, ymin, ymax, 1.0, 1, - x, NULL, yy, NULL, n, + x, NULL, yy, NULL, NULL, n, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, 0); } @@ -256,7 +258,7 @@ int m) { return do_plot_imp(PLOTF_NONE, xmin, xmax, ymin, ymax, 1.0, 1, - x, NULL, yy, NULL, n, + x, NULL, yy, NULL, NULL, n, x4, y4, NULL, NULL, m , NULL, NULL, NULL, NULL, NULL, 0); } @@ -331,7 +333,7 @@ double ratio return do_plot_imp(PLOTF_NONE, xmin, xmax, ymin, ymax, ratio, dowait, - x, NULL, yy, NULL, n, + x, NULL, yy, NULL, NULL, n, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, 0); } @@ -393,7 +395,7 @@ int n) { /* Number of values */ return do_plot_imp(PLOTF_NONE, xmin, xmax, ymin, ymax, 1.0, 1, - x, NULL, yy, NULL, n, + x, NULL, yy, NULL, NULL, n, NULL, NULL, NULL, NULL, n , NULL, NULL, NULL, NULL, NULL, 0); } @@ -472,49 +474,26 @@ int m) { return do_plot_imp(PLOTF_NONE, xmin, xmax, ymin, ymax, 1.0, 1, - x, NULL, yy, NULL, n, + x, NULL, yy, NULL, NULL, n, xp, yp, NULL, NULL, m, NULL, NULL, NULL, NULL, NULL, 0); } /* Public routines */ -/* Plot up to 10 graphs. Wait for a key */ -/* return 0 on success, -1 on error */ -/* If n is -ve, reverse the X axis */ +/* Plot up to 12 graphs + optional crosses */ int -do_plot10( -double *x, /* X coord */ -double *y1, /* Black */ -double *y2, /* Red */ -double *y3, /* Green */ -double *y4, /* Blue */ -double *y5, /* Yellow */ -double *y6, /* Purple */ -double *y7, /* Brown */ -double *y8, /* Orange */ -double *y9, /* Grey */ -double *y10,/* White */ -int n, /* Number of values */ -int zero /* Flag - make sure zero is in y range */ +do_plotNpwz( +double *x, /* X coord */ +double **yy, /* Y values, NULL for none */ +int n, /* Number of values, -ve for reverse X axis */ +double *xp, double *yp, /* And crosses */ +int m, /* Number of crosses */ +int dowait, /* == 0 no wait, > 0, wait for user key, < 0 wait for secs */ +int zero /* Flag - nz, make sure zero is in y range */ ) { int i, j; double xmin, xmax, ymin, ymax; int nn = abs(n); - double *yy[MXGPHS]; - - for (j = 0; j < MXGPHS; j++) - yy[j] = NULL; - - yy[0] = y1; - yy[1] = y2; - yy[2] = y3; - yy[3] = y4; - yy[4] = y5; - yy[5] = y6; - yy[6] = y7; - yy[7] = y8; - yy[8] = y9; - yy[9] = y10; /* Determine min and max dimensions of plot */ xmin = ymin = 1e6; @@ -536,9 +515,24 @@ int zero /* Flag - make sure zero is in y range */ } } + for (i = 0; i < m; i++) { + if (xp != NULL) { + if (xmin > xp[i]) + xmin = xp[i]; + if (xmax < xp[i]) + xmax = xp[i]; + } + if (yp != NULL) { + if (ymin > yp[i]) + ymin = yp[i]; + if (ymax < yp[i]) + ymax = yp[i]; + } + } + if (zero && ymin > 0.0) ymin = 0.0; - + /* Work out scale factors */ if ((xmax - xmin) == 0.0) xmax += 0.5, xmin -= 0.5; @@ -546,9 +540,9 @@ int zero /* Flag - make sure zero is in y range */ ymax += 0.5, ymin -= 0.5; return do_plot_imp(PLOTF_NONE, - xmin, xmax, ymin, ymax, 1.0, 1, - x, NULL, yy, NULL, n, - NULL, NULL, NULL, NULL, n , + xmin, xmax, ymin, ymax, 1.0, dowait, + x, NULL, yy, NULL, NULL, n, + xp, yp, NULL, NULL, m, NULL, NULL, NULL, NULL, NULL, 0); } @@ -558,8 +552,9 @@ int zero /* Flag - make sure zero is in y range */ /* if dowait < 0, wait for no seconds */ /* return 0 on success, -1 on error */ /* If n is -ve, reverse the X axis */ +/* If zero, ensure Y goes to zero */ int -do_plot10pw( +do_plot10pwz( double *x, /* X coord */ double *y1, /* Black */ double *y2, /* Red */ @@ -571,13 +566,13 @@ double *y7, /* Brown */ double *y8, /* Orange */ double *y9, /* Grey */ double *y10,/* White */ -int n, /* Number of values */ +int n, /* Number of values, -ve for reverse X axis */ double *xp, double *yp, /* And crosses */ -int m, -int dowait) { - int i, j; - double xmin, xmax, ymin, ymax; - int nn = abs(n); +int m, /* Number of crosses */ +int dowait, /* == 0 no wait, > 0, wait for user key, < 0 wait for secs */ +int zero /* Flag - nz, make sure zero is in y range */ +) { + int j; double *yy[MXGPHS]; for (j = 0; j < MXGPHS; j++) @@ -594,52 +589,54 @@ int dowait) { yy[8] = y9; yy[9] = y10; - /* Determine min and max dimensions of plot */ - xmin = ymin = 1e6; - xmax = ymax = -1e6; - - for (i = 0; i < n; i++) { - if (xmin > x[i]) - xmin = x[i]; - if (xmax < x[i]) - xmax = x[i]; - - for (j = 0; j < MXGPHS; j++) { - if (yy[j] != NULL) { - if (ymin > yy[j][i]) - ymin = yy[j][i]; - if (ymax < yy[j][i]) - ymax = yy[j][i]; - } - } - } - - for (i = 0; i < m; i++) { - if (xp != NULL) { - if (xmin > xp[i]) - xmin = xp[i]; - if (xmax < xp[i]) - xmax = xp[i]; - } - if (yp != NULL) { - if (ymin > yp[i]) - ymin = yp[i]; - if (ymax < yp[i]) - ymax = yp[i]; - } - } + return do_plotNpwz(x, yy, n, xp, yp, m, dowait, zero); +} - /* Work out scale factors */ - if ((xmax - xmin) == 0.0) - xmax += 0.5, xmin -= 0.5; - if ((ymax - ymin) == 0.0) - ymax += 0.5, ymin -= 0.5; +/* Plot up to 10 graphs. Wait for a key */ +/* return 0 on success, -1 on error */ +/* If n is -ve, reverse the X axis */ +int +do_plot10( +double *x, /* X coord */ +double *y1, /* Black */ +double *y2, /* Red */ +double *y3, /* Green */ +double *y4, /* Blue */ +double *y5, /* Yellow */ +double *y6, /* Purple */ +double *y7, /* Brown */ +double *y8, /* Orange */ +double *y9, /* Grey */ +double *y10,/* White */ +int n, /* Number of values */ +int zero /* Flag - make sure zero is in y range */ +) { + return do_plot10pwz(x, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, n, NULL, NULL, 0, 1, zero); +} - return do_plot_imp(PLOTF_NONE, - xmin, xmax, ymin, ymax, 1.0, dowait, - x, NULL, yy, NULL, n, - xp, yp, NULL, NULL, m, - NULL, NULL, NULL, NULL, NULL, 0); +/* Plot up to 10 graphs + optional crosses */ +/* if dowait > 0, wait for user key */ +/* if dowait < 0, wait for no seconds */ +/* return 0 on success, -1 on error */ +/* If n is -ve, reverse the X axis */ +int +do_plot10pw( +double *x, /* X coord */ +double *y1, /* Black */ +double *y2, /* Red */ +double *y3, /* Green */ +double *y4, /* Blue */ +double *y5, /* Yellow */ +double *y6, /* Purple */ +double *y7, /* Brown */ +double *y8, /* Orange */ +double *y9, /* Grey */ +double *y10,/* White */ +int n, /* Number of values */ +double *xp, double *yp, /* And crosses */ +int m, +int dowait) { + return do_plot10pwz(x, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, n, xp, yp, m, dowait, 0); } /* Plot up to 10 graphs + optional crosses. Wait for a key */ @@ -661,7 +658,7 @@ double *y10,/* White */ int n, /* Number of values */ double *xp, double *yp, /* And crosses */ int m) { - return do_plot10pw(x, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, n, xp, yp, m, 1); + return do_plot10pwz(x, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, n, xp, yp, m, 1, 0); } @@ -695,7 +692,7 @@ int m /* Number of points */ return do_plot_imp(PLOTF_VECCROSSES, xmin, xmax, ymin, ymax, 1.0, dowait, - x1, x2, yy, NULL, n, + x1, x2, yy, NULL, NULL, n, x3, y3, mcols, mtext, m, NULL, NULL, NULL, NULL, NULL, 0); } @@ -737,7 +734,54 @@ int o /* Number of vectors */ return do_plot_imp(PLOTF_VECCROSSES, xmin, xmax, ymin, ymax, 1.0, dowait, - x1, x2, yy, ntext, n, + x1, x2, yy, NULL, ntext, n, + x3, y3, mcols, mtext, m, + x4, y4, x5, y5, ocols, o); +} + +/* Plot a bunch of colored vectors + points + optional colored points & notation */ +/* + optional colored vectors */ +/* return 0 on success, -1 on error */ +/* Vectors are x1, y1 to x2, y2 with color ncols and annotated 'X' at x2, y2, */ +/* Colored annotated Crosss at x3, y3. */ +/* Colored vector from x4, y4 to x5, y5 */ +int do_plot_vec3( +double xmin, +double xmax, +double ymin, +double ymax, +double *x1, /* n vector start */ +double *y1, +double *x2, /* vector end and diagonal cross */ +double *y2, +plot_col *ncols,/* Vector and cross colors */ +char **ntext, /* text annotation at cross */ +int n, /* Number of vectors */ +int dowait, +double *x3, /* m extra crosses */ +double *y3, +plot_col *mcols,/* cross colors */ +char **mtext, /* text annotation at cross */ +int m, /* Number of crosses */ +double *x4, /* o vector start */ +double *y4, +double *x5, /* o vector end */ +double *y5, +plot_col *ocols,/* Vector colors */ +int o /* Number of vectors */ +) { + int j; + double *yy[MXGPHS]; + + for (j = 0; j < MXGPHS; j++) + yy[j] = NULL; + + yy[0] = y1; + yy[1] = y2; + + return do_plot_imp(PLOTF_VECCROSSES, + xmin, xmax, ymin, ymax, 1.0, dowait, + x1, x2, yy, ncols, ntext, n, x3, y3, mcols, mtext, m, x4, y4, x5, y5, ocols, o); } @@ -836,7 +880,7 @@ DWORD WINAPI plot_message_thread(LPVOID lpParameter) { /* Hybrid Graph uses x1 : y1, y2, y3, y4, y5, y6 for up to 6 graph curves + */ /* optional diagonal crosses at x7, y7 in yellow (x2 == NULL). */ /* Vector uses x1, y1 to x2, y2 as a vector with a (optional) diagonal cross at x2, y2 */ -/* all in black with annotation ntext at the cross, */ +/* all in black or ncols with annotation ntext at the cross, */ /* plus a (optiona) diagonal cross at x7, y7 in yellow. The color for x7, y7 can be */ /* overidden by an array of colors mcols, plus optional label text mtext. (x2 != NULL) */ /* n = number of points/vectors. -ve for reversed X axis */ @@ -848,7 +892,7 @@ static int do_plot_imp( double ratio, /* Aspect ratio of window, X/Y */ int dowait, /* > 0 wait for user to hit space key, < 0 delat dowait seconds. */ double *x1, double *x2, - double *yy[MXGPHS], char **ntext, + double *yy[MXGPHS], plot_col *ncols, char **ntext, int n, double *x7, double *y7, plot_col *mcols, char **mtext, int m, @@ -883,11 +927,12 @@ static int do_plot_imp( if (x2 == NULL) pd.graph = 1; /* 6 graphs + points */ else - pd.graph = 0; + pd.graph = 0; /* vectors + optional crosses */ pd.x1 = x1; pd.x2 = x2; for (j = 0; j < MXGPHS; j++) pd.yy[j] = yy[j]; + pd.ncols = ncols; pd.ntext = ntext; pd.n = abs(n); @@ -1105,25 +1150,13 @@ plot_info *p DeleteObject(pen); if (p->graph) { /* Up to MXGPHS graphs + crosses */ - int gcolors[MXGPHS][3] = { - { 0, 0, 0}, /* Black */ - { 210, 30, 0}, /* Red */ - { 0, 200, 90}, /* Green */ - { 0, 10, 255}, /* Blue */ - { 200, 200, 0}, /* Yellow */ - { 220, 0, 255}, /* Purple */ - { 136, 86, 68}, /* Brown */ - { 248, 95, 0}, /* Orange */ - { 160, 160, 160}, /* Grey */ - { 220, 220, 220} /* White */ - }; for (j = MXGPHS-1; j >= 0; j--) { double *yp = p->yy[j]; if (yp == NULL) continue; - pen = CreatePen(PS_SOLID,ILTHICK,RGB(gcolors[j][0],gcolors[j][1],gcolors[j][2])); + pen = CreatePen(PS_SOLID,ILTHICK,RGB(plot_colors[j][0],plot_colors[j][1],plot_colors[j][2])); SelectObject(hdc,pen); lx = (int)((p->x1[0] - p->mnx) * p->scx + 0.5); @@ -1149,8 +1182,9 @@ plot_info *p } else { /* Vectors with cross */ - pen = CreatePen(PS_SOLID,ILTHICK,RGB(0,0,0)); - SelectObject(hdc,pen); + /* Default is black */ + pen = CreatePen(PS_SOLID,ILTHICK, RGB(0,0,0)); + SelectObject(hdc, pen); if (p->ntext != NULL) { HFONT fon; @@ -1170,6 +1204,20 @@ plot_info *p for (i = 0; i < p->n; i++) { int cx,cy; + if (p->ncols != NULL) { + int rgb[3]; + + for (j = 0; j < 3; j++) + rgb[j] = (int)(p->ncols[i].rgb[j] * 255.0 + 0.5); + + DeleteObject(pen); + pen = CreatePen(PS_SOLID,ILTHICK,RGB(rgb[0],rgb[1],rgb[2])); + SelectObject(hdc,pen); + + if (p->mtext != NULL) + SetTextColor(hdc, RGB(rgb[0],rgb[1],rgb[2])); + } + lx = (int)((p->x1[i] - p->mnx) * p->scx + 0.5); ly = (int)((p->yy[0][i] - p->mny) * p->scy + 0.5); @@ -1450,7 +1498,7 @@ static void create_my_win(void *cntx) { /* Hybrid Graph uses x1 : y1, y2, y3, y4, y5, y6 for up to 6 graph curves + */ /* optional diagonal crosses at x7, y7 in yellow (x2 == NULL). */ /* Vector uses x1, y1 to x2, y2 as a vector with a (optional) diagonal cross at x2, y2 */ -/* all in black with annotation ntext at the cross, */ +/* all in black or ncols with annotation ntext at the cross, */ /* plus a (optiona) diagonal cross at x7, y7 in yellow. The color for x7, y7 can be */ /* overidden by an array of colors mcols, plus optional label text mtext. (x2 != NULL) */ /* n = number of points/vectors. -ve for reversed X axis */ @@ -1462,7 +1510,7 @@ static int do_plot_imp( double ratio, /* Aspect ratio of window, X/Y */ int dowait, /* > 0 wait for user to hit space key, < 0 delat dowait seconds. */ double *x1, double *x2, - double *yy[MXGPHS], char **ntext, + double *yy[MXGPHS], plot_col *ncols, char **ntext, int n, double *x7, double *y7, plot_col *mcols, char **mtext, int m, @@ -1504,6 +1552,7 @@ static int do_plot_imp( pd.x2 = x2; for (j = 0; j < MXGPHS; j++) pd.yy[j] = yy[j]; + pd.ncols = ncols; pd.ntext = ntext; pd.n = abs(n); @@ -1761,26 +1810,15 @@ static void DoPlot(NSRect *rect, plot_info *pdp) { [path setLineDash: NULL count: 0 phase: 0.0 ]; if (pdp->graph) { /* Up to 6 graphs */ - int gcolors[MXGPHS][3] = { - { 0, 0, 0}, /* Black */ - { 210, 30, 0}, /* Red */ - { 0, 200, 90}, /* Green */ - { 0, 10, 255}, /* Blue */ - { 200, 200, 0}, /* Yellow */ - { 220, 0, 255}, /* Purple */ - { 136, 86, 68}, /* Brown */ - { 248, 95, 0}, /* Orange */ - { 160, 160, 160}, /* Grey */ - { 220, 220, 220} /* White */ - }; for (j = MXGPHS-1; j >= 0; j--) { double *yp = pdp->yy[j]; if (yp == NULL) continue; - [[NSColor colorWithCalibratedRed: gcolors[j][0]/255.0 - green: gcolors[j][1]/255.0 - blue: gcolors[j][2]/255.0 + + [[NSColor colorWithCalibratedRed: plot_colors[j][0]/255.0 + green: plot_colors[j][1]/255.0 + blue: plot_colors[j][2]/255.0 alpha: 1.0] setStroke]; if (pdp->n > 0) { @@ -1804,6 +1842,7 @@ static void DoPlot(NSRect *rect, plot_info *pdp) { } } else { /* Vectors */ + [[NSColor colorWithCalibratedRed: 0.0 green: 0.0 blue: 0.0 @@ -1817,6 +1856,20 @@ static void DoPlot(NSRect *rect, plot_info *pdp) { for (i = 0; i < pdp->n; i++) { int cx,cy; + if (pdp->ncols != NULL) { + [[NSColor colorWithCalibratedRed: pdp->ncols[i].rgb[0]/255.0 + green: pdp->ncols[i].rgb[1]/255.0 + blue: pdp->ncols[i].rgb[2]/255.0 + alpha: 1.0] setStroke]; + + if (pdp->ntext != NULL) { + tcol = [NSColor colorWithCalibratedRed: pdp->ncols[i].rgb[0]/255.0 + green: pdp->ncols[i].rgb[1]/255.0 + blue: pdp->ncols[i].rgb[2]/255.0 + alpha: 1.0]; + } + } + lx = (int)((pdp->x1[i] - pdp->mnx) * pdp->scx + 0.5); ly = (int)((pdp->yy[0][i] - pdp->mny) * pdp->scy + 0.5); @@ -1924,7 +1977,7 @@ void DoPlot(Display *mydisplay, Window mywindow, GC mygc, plot_info *pdp); /* Hybrid Graph uses x1 : y1, y2, y3, y4, y5, y6 for up to 6 graph curves + */ /* optional diagonal crosses at x7, y7 in yellow (x2 == NULL). */ /* Vector uses x1, y1 to x2, y2 as a vector with a (optional) diagonal cross at x2, y2 */ -/* all in black with annotation ntext at the cross, */ +/* all in black or ncols with annotation ntext at the cross, */ /* plus a (optiona) diagonal cross at x7, y7 in yellow. The color for x7, y7 can be */ /* overidden by an array of colors mcols, plus optional label text mtext. (x2 != NULL) */ /* n = number of points/vectors. -ve for reversed X axis */ @@ -1936,7 +1989,7 @@ static int do_plot_imp( double ratio, /* Aspect ratio of window, X/Y */ int dowait, /* > 0 wait for user to hit space key, < 0 delat dowait seconds. */ double *x1, double *x2, - double *yy[MXGPHS], char **ntext, + double *yy[MXGPHS], plot_col *ncols, char **ntext, int n, double *x7, double *y7, plot_col *mcols, char **mtext, int m, @@ -1977,6 +2030,7 @@ static int do_plot_imp( pd.x2 = x2; for (j = 0; j < MXGPHS; j++) pd.yy[j] = yy[j]; + pd.ncols = ncols; pd.ntext = ntext; pd.n = abs(n); @@ -2225,9 +2279,9 @@ plot_info *pdp if (yp == NULL) continue; - col.red = gcolors[j][0] * 256; - col.green = gcolors[j][1] * 256; - col.blue = gcolors[j][2] * 256; + col.red = plot_colors[j][0] * 256; + col.green = plot_colors[j][1] * 256; + col.blue = plot_colors[j][2] * 256; XAllocColor(mydisplay, mycmap, &col); XSetForeground(mydisplay,mygc, col.pixel); XSetLineAttributes(mydisplay, mygc, ILTHICK, LineSolid, CapButt, JoinBevel); @@ -2252,7 +2306,6 @@ plot_info *pdp } else { /* Vectors */ - col.red = col.green = col.blue = 0 * 256; XAllocColor(mydisplay, mycmap, &col); XSetForeground(mydisplay,mygc, col.pixel); XSetLineAttributes(mydisplay, mygc, ILTHICK, LineSolid, CapButt, JoinBevel); @@ -2260,6 +2313,15 @@ plot_info *pdp for (i = 0; i < pdp->n; i++) { int cx,cy; + if (pdp->ncols != NULL) { + col.red = (int)(pdp->ncols[i].rgb[0] * 65535.0 + 0.5); + col.green = (int)(pdp->ncols[i].rgb[1] * 65535.0 + 0.5); + col.blue = (int)(pdp->ncols[i].rgb[2] * 65535.0 + 0.5); + XAllocColor(mydisplay, mycmap, &col); + XSetForeground(mydisplay,mygc, col.pixel); + XSetLineAttributes(mydisplay, mygc, ILTHICK, LineSolid, CapButt, JoinBevel); + } + lx = (int)((pdp->x1[i] - pdp->mnx) * pdp->scx + 0.5); ly = (int)((pdp->yy[0][i] - pdp->mny) * pdp->scy + 0.5); diff --git a/plot/plot.h b/plot/plot.h index 8e3db5e..b586903 100755 --- a/plot/plot.h +++ b/plot/plot.h @@ -11,6 +11,10 @@ * see the License.txt file for licencing details. */ +/* MXGPHS is defined in aconfig.h */ + +extern int plot_colors[MXGPHS][3]; + /* Graph order is Black = Y1, Red = Y2, Green = Y3, Blue = Y4, Yellow = Y5, Purple = Y6 */ /* Brown = Y7, Orange = Y8, Grey = Y9, White = Y10 */ @@ -78,6 +82,20 @@ int do_plot10pw(double *x, double *y1, double *y2, double *y3, double *y4, doubl double *y7, double *y8, double *y9, double *y10, int n, double *xp, double *yp, int m, int dowait); +/* Plot up to 10 graphs + optional crosses */ +/* if dowait > 0, wait for user key */ +/* if dowait < 0, wait for no seconds */ +/* return 0 on success, -1 on error */ +/* If n is -ve, reverse the X axis */ +/* if dozero flag, make sure y range covers zero */ +int do_plot10pwz(double *x, double *y1, double *y2, double *y3, double *y4, double *y5, double *y6, + double *y7, double *y8, double *y9, double *y10, + int n, double *xp, double *yp, int m, int dowait, int zero); + +/* Public routines */ +/* Plot up to MXGPHS (12) graphs + optional crosses */ +int do_plotNpwz(double *x, double **yy, int n, double *xp, double *yp, int m, int dowait, int zero); + /* Plot a bunch of vectors + points + optional colored points & notation */ /* return 0 on success, -1 on error */ /* Vectors are x1, y1 to x2, y2 with 'X' at x2, y2, */ @@ -99,5 +117,17 @@ int do_plot_vec2(double xmin, double xmax, double ymin, double ymax, double *x3, double *y3, plot_col *mcols, char **mtext, int m, double *x4, double *y4, double *x5, double *y5, plot_col *ocols, int o); +/* Plot a bunch of colored vectors + points + optional colored points & notation */ +/* + optional colored vectors */ +/* return 0 on success, -1 on error */ +/* Vectors are x1, y1 to x2, y2 with color ncols and annotated 'X' at x2, y2, */ +/* Colored annotated Crosss at x3, y3. */ +/* Colored vector from x4, y4 to x5, y5 */ +int do_plot_vec3(double xmin, double xmax, double ymin, double ymax, + double *x1, double *y1, double *x2, double *y2, plot_col *ncols, char **ntext, int n, + int dowait, + double *x3, double *y3, plot_col *mcols, char **mtext, int m, + double *x4, double *y4, double *x5, double *y5, plot_col *ocols, int o); + #define PLOT_H #endif /* PLOT_H */ diff --git a/profile/colverify.c b/profile/colverify.c index d7100a3..de99c15 100755 --- a/profile/colverify.c +++ b/profile/colverify.c @@ -759,7 +759,7 @@ int main(int argc, char *argv[]) if (l_observ == icxOT_none) l_observ = icxOT_CIE_1931_2; - if ((sp2cie = new_xsp2cie(l_illum, l_illum == icxIT_none ? NULL : &cust_illum, + if ((sp2cie = new_xsp2cie(l_illum, 0.0, l_illum == icxIT_none ? NULL : &cust_illum, l_observ, custObserver, icSigXYZData, icxClamp)) == NULL) error("Creation of spectral conversion object failed"); diff --git a/profile/mppcheck.c b/profile/mppcheck.c index 6615a84..07ecc16 100755 --- a/profile/mppcheck.c +++ b/profile/mppcheck.c @@ -502,7 +502,7 @@ int main(int argc, char *argv[]) xsp2cie *sc; xspect sp; - if ((sc = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL) + if ((sc = new_xsp2cie(icxIT_D50, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL) error("Failed to create xsp2cie object"); /* Set standard D50 viewer & illum. */ diff --git a/profile/mppprof.c b/profile/mppprof.c index 41fe2fc..ace8c97 100755 --- a/profile/mppprof.c +++ b/profile/mppprof.c @@ -693,13 +693,13 @@ make_output_mpp( xspect sp; if (isDisplay) { - if ((sc = new_xsp2cie(icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL) + if ((sc = new_xsp2cie(icxIT_none, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL) error("Failed to create xsp2cie object"); p->set_ilob(p, icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, 0); } else { /* Set standard D50 viewer & illum. */ - if ((sc = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL) + if ((sc = new_xsp2cie(icxIT_D50, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL) error("Failed to create xsp2cie object"); p->set_ilob(p, icxIT_D50, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, 0); @@ -865,13 +865,13 @@ make_output_mpp( if (isDisplay) { /* Set emissive viewer. */ - if ((sc = new_xsp2cie(icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL) + if ((sc = new_xsp2cie(icxIT_none, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL) error("Failed to create xsp2cie object"); /* (mpp will ignore illuminant for display anyway ??) */ p2->set_ilob(p2, icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, 0); } else { /* Set standard D50 viewer & illum. */ - if ((sc = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL) + if ((sc = new_xsp2cie(icxIT_D50, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL) error("Failed to create xsp2cie object"); p2->set_ilob(p2, icxIT_D50, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, 0); } diff --git a/profile/printcal.c b/profile/printcal.c index 9bbcb41..cee9ed9 100755 --- a/profile/printcal.c +++ b/profile/printcal.c @@ -1105,7 +1105,7 @@ int main(int argc, char *argv[]) { } /* Create a spectral conversion object to XYZ */ - if ((sp2cie = new_xsp2cie(illum, &cust_illum, observ, NULL, icSigXYZData, icxClamp)) == NULL) + if ((sp2cie = new_xsp2cie(illum, 0.0, &cust_illum, observ, NULL, icSigXYZData, icxClamp)) == NULL) error("Creation of spectral conversion object failed"); /* To add FWA comp. would have to locate/create spectral white here, */ diff --git a/profile/profcheck.c b/profile/profcheck.c index 62d39bd..ae00dc0 100755 --- a/profile/profcheck.c +++ b/profile/profcheck.c @@ -781,7 +781,7 @@ int main(int argc, char *argv[]) } /* Create a spectral conversion object */ - if ((sp2cie = new_xsp2cie(illum, illum == icxIT_none ? NULL : &cust_illum, + if ((sp2cie = new_xsp2cie(illum, 0.0, illum == icxIT_none ? NULL : &cust_illum, obType, custObserver, icSigLabData, icxClamp)) == NULL) error("Creation of spectral conversion object failed"); @@ -945,7 +945,7 @@ int main(int argc, char *argv[]) /* Open up the file for reading */ if ((rd_fp = new_icmFileStd_name(iccname,"r")) == NULL) - error("Write: Can't open file '%s'",iccname); + error("Read: Can't open file '%s'",iccname); if ((rd_icco = new_icc()) == NULL) error("Read: Creation of ICC object failed"); diff --git a/profile/profin.c b/profile/profin.c index 92317bb..d20b47a 100755 --- a/profile/profin.c +++ b/profile/profin.c @@ -37,6 +37,7 @@ #define verbo stdout #include +#include "aconfig.h" #include "counters.h" #include "numlib.h" #include "icc.h" @@ -786,7 +787,7 @@ make_input_icc( illum = icxIT_none; cust_illum = NULL; } - if ((sp2cie = new_xsp2cie(illum, cust_illum, obType, custObserver, + if ((sp2cie = new_xsp2cie(illum, 0.0, cust_illum, obType, custObserver, wantLab ? icSigLabData : icSigXYZData, icxClamp)) == NULL) error("Creation of spectral conversion object failed"); diff --git a/profile/profout.c b/profile/profout.c index 47726f1..fe6be0a 100755 --- a/profile/profout.c +++ b/profile/profout.c @@ -89,6 +89,7 @@ #define FILTER_MAX_RAD 0.1 /* [0.1] Filtering maximum radius in grid */ #include +#include "aconfig.h" #include "numlib.h" #include "icc.h" #include "cgats.h" @@ -1798,7 +1799,7 @@ make_output_icc( } /* Create a spectral conversion object */ - if ((sp2cie = new_xsp2cie(illum, cust_illum, obType, custObserver, + if ((sp2cie = new_xsp2cie(illum, 0.0, cust_illum, obType, custObserver, wantLab ? icSigLabData : icSigXYZData, icxClamp)) == NULL) error("Creation of spectral conversion object failed"); diff --git a/ref/linear.cal b/ref/linear.cal index 1dafbde..4555f15 100755 --- a/ref/linear.cal +++ b/ref/linear.cal @@ -2,7 +2,7 @@ CAL DESCRIPTOR "Argyll Device Calibration Curves" ORIGINATOR "Argyll synthcal" -CREATED "Fri Nov 17 01:11:11 2017" +CREATED "Thu Jul 05 04:49:42 2018" DEVICE_CLASS "DISPLAY" COLOR_REP "RGB" diff --git a/ref/strange.cal b/ref/strange.cal index b31bbed..f620429 100755 --- a/ref/strange.cal +++ b/ref/strange.cal @@ -2,7 +2,7 @@ CAL DESCRIPTOR "Argyll Device Calibration Curves" ORIGINATOR "Argyll synthcal" -CREATED "Fri Nov 17 01:11:11 2017" +CREATED "Thu Jul 05 04:49:42 2018" DEVICE_CLASS "DISPLAY" COLOR_REP "RGB" diff --git a/render/render.h b/render/render.h index 26b7028..5104ebd 100755 --- a/render/render.h +++ b/render/render.h @@ -26,7 +26,7 @@ /* the bottom left corner. */ /* Device color values range from 0.0 to 1.0 */ -#define MXCH2D 8 /* Maximum color channels */ +#define MXCH2D 16 /* Maximum color channels */ #define TOTC2D (MXCH2D+1) /* Maximum total components */ #define PRIX2D (MXCH2D) /* Index of primitive kept with color value */ diff --git a/rspl/Jamfile b/rspl/Jamfile index 6f80f9f..d007562 100644 --- a/rspl/Jamfile +++ b/rspl/Jamfile @@ -69,7 +69,7 @@ if ( $(HOME) = "D:\\usr\\graeme" && $(PWD) = "/src/argyll/rspl" ) Main lchw_solve : lchw_solve.c : : : ../h ../numlib ../icc ../plot : : ../plot/libplot ../icc/libicc ../numlib/libui ../numlib/libnum ; Main lchw_deriv : lchw_deriv.c : : : ../h ../numlib ../icc ../plot : : ../plot/libplot ../icc/libicc ../numlib/libui ../numlib/libnum ; Main lchw_2deriv : lchw_2deriv.c : : : ../h ../numlib ../icc ../plot : : ../plot/libplot ../icc/libicc ../numlib/libui ../numlib/libnum ; - Main crossv : crossv.c : : : ../numlib ../plot : : ../plot/libplot ../numlib/libui ../numlib/libnum ; + Main crossv : crossv.c : : : ../h ../numlib ../plot : : ../plot/libplot ../numlib/libui ../numlib/libnum ; } if $(BUILD_JUNK) { diff --git a/rspl/smtmpp.c b/rspl/smtmpp.c index 1264d4b..baa01b7 100755 --- a/rspl/smtmpp.c +++ b/rspl/smtmpp.c @@ -25,6 +25,7 @@ #include #include #include +#include "aconfig.h" #include "rspl.h" #include "numlib.h" #include "xicc.h" diff --git a/rspl/smtnd.c b/rspl/smtnd.c index 355d20b..b4eeab9 100755 --- a/rspl/smtnd.c +++ b/rspl/smtnd.c @@ -23,6 +23,7 @@ #include #include #include +#include "aconfig.h" #include "rspl.h" #include "numlib.h" #include "xicc.h" /* For mpp support */ diff --git a/rspl/t2d.c b/rspl/t2d.c index e3f304c..6c1f742 100755 --- a/rspl/t2d.c +++ b/rspl/t2d.c @@ -19,6 +19,7 @@ #include #include #include +#include "aconfig.h" #include "rspl.h" #include "tiffio.h" #include "plot.h" diff --git a/rspl/t2ddf.c b/rspl/t2ddf.c index 115d5f5..926968f 100755 --- a/rspl/t2ddf.c +++ b/rspl/t2ddf.c @@ -19,6 +19,7 @@ #include #include #include +#include "aconfig.h" #include "rspl.h" #include "tiffio.h" #include "plot.h" diff --git a/rspl/t3d.c b/rspl/t3d.c index c526669..d3a77b0 100755 --- a/rspl/t3d.c +++ b/rspl/t3d.c @@ -19,6 +19,7 @@ #include #include #include +#include "aconfig.h" #include "rspl.h" #include "tiffio.h" #include "plot.h" diff --git a/rspl/t3ddf.c b/rspl/t3ddf.c index 4a43f0d..65b0678 100755 --- a/rspl/t3ddf.c +++ b/rspl/t3ddf.c @@ -19,6 +19,7 @@ #include #include #include +#include "aconfig.h" #include "rspl.h" #include "tiffio.h" #include "plot.h" diff --git a/spectro/ccxxmake.c b/spectro/ccxxmake.c index 4d8c057..a982107 100755 --- a/spectro/ccxxmake.c +++ b/spectro/ccxxmake.c @@ -228,8 +228,8 @@ int main(int argc, char *argv[]) { int comno = COMPORT; /* COM port used */ flow_control fc = fc_nc; /* Default flow control */ int highres = 0; /* High res mode if available */ - int dtype = 0; /* Display kind, 0 = default, 1 = CRT, 2 = LCD, etc */ - int sdtype = -1; /* Spectro display kind, -1 = use dtype */ + int ditype = 0; /* Display kind selector, 0 = default */ + int sditype = -1; /* Spectro display kind, -1 = use ditype */ int refrmode = -1; /* Refresh mode */ double refrate = 0.0; /* 0.0 = default, > 0.0 = override refresh rate */ int cbid = 0; /* Calibration base display mode ID */ @@ -411,7 +411,9 @@ int main(int argc, char *argv[]) { } else if (argv[fa][1] == 'y') { fa = nfa; if (na == NULL) usage(0,"Parameter expected after -y"); - dtype = na[0]; + ditype = na[0]; + if (ditype == '_' && na[1] != '\000') + ditype = ditype << 8 | na[1]; /* For ccss, set a default */ if (na[0] == 'r') { @@ -424,7 +426,7 @@ int main(int argc, char *argv[]) { } else if (argv[fa][1] == 'z') { fa = nfa; if (na == NULL) usage(0,"Parameter expected after -z"); - sdtype = na[0]; + sditype = na[0]; /* Test patch offset and size */ } else if (argv[fa][1] == 'P') { @@ -884,7 +886,7 @@ int main(int argc, char *argv[]) { } /* Create a spectral conversion object */ - if ((sp2cie = new_xsp2cie(icxIT_none, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL) + if ((sp2cie = new_xsp2cie(icxIT_none, 0.0, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL) error("Creation of spectral conversion object failed"); for (i = 0; i < npat; i++) { @@ -1260,7 +1262,7 @@ int main(int argc, char *argv[]) { /* Should we use current cal rather than native ??? */ if ((dr = new_disprd(&errc, icmps->get_path(icmps, comno), - fc, dtype, sdtype, 1, tele, nadaptive, + fc, ditype, sditype, 1, tele, nadaptive, noinitcal, 0, highres, refrate, 3, NULL, NULL, NULL, 0, disp, 0, fullscreen, override, webdisp, ccid, @@ -1318,7 +1320,7 @@ int main(int argc, char *argv[]) { if (spec) { /* Create a spectral conversion object */ - if ((sp2cie = new_xsp2cie(icxIT_none, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL) + if ((sp2cie = new_xsp2cie(icxIT_none, 0.0, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL) error("Creation of spectral conversion object failed"); } for (i = 0; i < npat; i++) { /* For all grid points */ diff --git a/spectro/chartread.c b/spectro/chartread.c index 6a9db39..14ee129 100755 --- a/spectro/chartread.c +++ b/spectro/chartread.c @@ -256,7 +256,7 @@ int trans, /* Use transmission mode */ int emis, /* Use emissive mode */ int displ, /* 1 = Use display emissive mode, 2 = display bright rel. */ /* 3 = display white rel. */ -int dtype, /* Display type selection charater */ +int ditype, /* Display type selection charater */ inst_opt_filter fe, /* Optional filter */ xcalstd scalstd, /* X-Rite calibration standard to set */ xcalstd *ucalstd, /* X-Rite calibration standard actually used */ @@ -398,11 +398,11 @@ a1log *log /* verb, debug & error log */ } /* Set display type or calibration mode */ - if (dtype != 0) { + if (ditype != 0) { if (cap2 & inst2_disptype) { int ix; - if ((ix = inst_get_disptype_index(it, dtype, 0)) < 0) { + if ((ix = inst_get_disptype_index(it, ditype, 0)) < 0) { printf("Setting display type ix %d failed\n",ix); it->del(it); return -1; @@ -2188,7 +2188,7 @@ int main(int argc, char *argv[]) { int emis = 0; /* Use emissive mode */ int displ = 0; /* 1 = Use display emissive mode, 2 = display bright rel. */ /* 3 = display white rel. */ - int dtype = 0; /* Display type selection charater */ + int ditype = 0; /* Display type selection charater(s) */ inst_opt_filter fe = inst_opt_filter_unknown; int pbypatch = 0; /* Read patch by patch */ int disbidi = 0; /* Disable bi-directional strip recognition */ @@ -2383,7 +2383,10 @@ int main(int argc, char *argv[]) { } else if (argv[fa][1] == 'y') { fa = nfa; if (na == NULL) usage(); - dtype = na[0]; + ditype = na[0]; + if (ditype == '_' && na[1] != '\000') + ditype = ditype << 8 | na[1]; + /* Request patch by patch measurement */ } else if (argv[fa][1] == 'p') { @@ -2998,7 +3001,7 @@ int main(int argc, char *argv[]) { /* Read all of the strips in */ if (read_strips(itype, scols, &atype, npat, totpa, stipa, pis, paix, saix, ixord, rstart, rand, hex, ipath, fc, plen, glen, tlen, - trans, emis, displ, dtype, fe, scalstd, &ucalstd, nocal, disbidi, highres, + trans, emis, displ, ditype, fe, scalstd, &ucalstd, nocal, disbidi, highres, ccxxname, obType, custObserver, scan_tol, pbypatch, xtern, spectral, uvmode, accurate_expd, emit_warnings, doplot, g_log) == 0) { diff --git a/spectro/colorhug.c b/spectro/colorhug.c index aa8ba21..e09362c 100755 --- a/spectro/colorhug.c +++ b/spectro/colorhug.c @@ -435,6 +435,7 @@ static inst_code colorhug_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { int se; colorhug *p = (colorhug *) pp; + icomuflags usbflags = icomuf_none; a1logd(p->log, 2, "colorhug_init_coms: About to init coms\n"); @@ -444,7 +445,7 @@ colorhug_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { a1logd(p->log, 3, "colorhug_init_coms: About to init HID\n"); /* Set config, interface */ - if ((se = p->icom->set_hid_port(p->icom, icomuf_none, 0, NULL)) != ICOM_OK) { + if ((se = p->icom->set_hid_port(p->icom, usbflags, 0, NULL)) != ICOM_OK) { a1logd(p->log, 1, "colorhug_init_coms: set_hid_port failed ICOM err 0x%x\n",se); return colorhug_interp_code((inst *)p, icoms2colorhug_err(se)); } @@ -453,9 +454,16 @@ colorhug_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { a1logd(p->log, 3, "colorhug_init_coms: About to init USB\n"); +#if defined(UNIX_X11) + usbflags |= icomuf_detach; + /* Some Linux drivers can't open the device a second time, so */ + /* use the reset on close workaround. */ + usbflags |= icomuf_reset_before_close; +#endif + /* Set config, interface, write end point, read end point */ // ~~ does Linux need icomuf_reset_before_close ? Why ? - if ((se = p->icom->set_usb_port(p->icom, 1, 0x00, 0x00, icomuf_detach, 0, NULL)) + if ((se = p->icom->set_usb_port(p->icom, 1, 0x00, 0x00, usbflags, 0, NULL)) != ICOM_OK) { a1logd(p->log, 1, "colorhug_init_coms: set_usb_port failed ICOM err 0x%x\n",se); return colorhug_interp_code((inst *)p, icoms2colorhug_err(se)); diff --git a/spectro/conv.c b/spectro/conv.c index a728566..92556ec 100755 --- a/spectro/conv.c +++ b/spectro/conv.c @@ -697,6 +697,9 @@ static int delayed_beep(void *pp) { # endif #else /* UNIX */ /* Linux is pretty lame in this regard... */ + /* Maybe we could write an 8Khz 8 bit sample to /dev/dsp, or /dev/audio ? */ + /* The ALSA system is the modern way for audio output. */ + /* Also check out what sox does: */ fprintf(stdout, "\a"); fflush(stdout); #endif return 0; diff --git a/spectro/dispcal.c b/spectro/dispcal.c index a4798af..10f333b 100755 --- a/spectro/dispcal.c +++ b/spectro/dispcal.c @@ -1684,7 +1684,7 @@ int main(int argc, char *argv[]) { icompaths *icmps = NULL; icompath *ipath = NULL; flow_control fc = fc_nc; /* Default flow control */ - int dtype = 0; /* Display type selection charater */ + int ditype = 0; /* Display type selection charater(s) */ int tele = 0; /* nz if telephoto mode */ int nocal = 0; /* Disable auto calibration */ int noplace = 0; /* Disable initial user placement check */ @@ -2121,7 +2121,9 @@ int main(int argc, char *argv[]) { } else if (argv[fa][1] == 'y') { fa = nfa; if (na == NULL) usage(0,"Parameter expected after -y"); - dtype = na[0]; + ditype = na[0]; + if (ditype == '_' && na[1] != '\000') + ditype = ditype << 8 | na[1]; /* Daylight color temperature */ } else if (argv[fa][1] == 't' || argv[fa][1] == 'T') { @@ -2342,7 +2344,7 @@ int main(int argc, char *argv[]) { } if (docalib) { - if ((rv = disprd_calibration(ipath, fc, dtype, -1, 0, tele, nadaptive, nocal, disp, + if ((rv = disprd_calibration(ipath, fc, ditype, -1, 0, tele, nadaptive, nocal, disp, webdisp, ccid, #ifdef NT madvrdisp, @@ -2384,7 +2386,7 @@ int main(int argc, char *argv[]) { native = 0; /* But measure current calibrated & CM response for verify or report calibrated */ /* Get ready to do some readings */ - if ((dr = new_disprd(&errc, ipath, fc, dtype, -1, 0, tele, nadaptive, nocal, noplace, + if ((dr = new_disprd(&errc, ipath, fc, ditype, -1, 0, tele, nadaptive, nocal, noplace, highres, refrate, native, &noramdac, &nocm, NULL, 0, disp, out_tvenc, fullscreen, override, webdisp, ccid, #ifdef NT @@ -2677,14 +2679,15 @@ int main(int argc, char *argv[]) { /* Read in the setup, user and model values */ - if (dtype == 0) { /* If the use hasn't set anything */ + if (ditype == 0) { /* If the use hasn't set anything */ if ((fi = icg->find_kword(icg, 0, "DEVICE_TYPE")) >= 0) { if (strcmp(icg->t[0].kdata[fi], "CRT") == 0) - dtype = 'c'; + ditype = 'c'; else if (strcmp(icg->t[0].kdata[fi], "LCD") == 0) - dtype = 'l'; - else - dtype = icg->t[0].kdata[fi][0]; + ditype = 'l'; + else { + ditype = icg->t[0].kdata[fi][0]; // Hmm. not handling '_' ... + } } } //printf("~1 dealt with device type\n"); @@ -3024,8 +3027,8 @@ int main(int argc, char *argv[]) { if (out_tvenc) printf("Using TV encoding range of (16-235)/255\n"); - if (dtype > 0) - printf("Display type is '%c'\n",dtype); + if (ditype > 0) + printf("Display type is '%s'\n",inst_distr(ditype)); if (doupdate) { if (x.nat) @@ -5269,8 +5272,11 @@ int main(int argc, char *argv[]) { ocg->add_kword(ocg, 0, "TV_OUTPUT_ENCODING",out_tvenc ? "YES" : "NO", NULL); /* Put the target parameters in the CGATS file too */ - if (dtype != 0) { - sprintf(buf,"%c",dtype); + if (ditype != 0) { + if ((ditype & ~0xff) != 0) + sprintf(buf,"%c%c",((ditype >> 8) & 0xff), ditype & 0xff); + else + sprintf(buf,"%c",ditype); ocg->add_kword(ocg, 0, "DEVICE_TYPE", buf, NULL); } diff --git a/spectro/dispread.c b/spectro/dispread.c index 5e332cc..baa042e 100755 --- a/spectro/dispread.c +++ b/spectro/dispread.c @@ -242,7 +242,7 @@ int main(int argc, char *argv[]) { int nadaptive = 0; /* Use non-adaptive mode if available */ int bdrift = 0; /* Flag, nz for black drift compensation */ int wdrift = 0; /* Flag, nz for white drift compensation */ - int dtype = 0; /* Display type selection charater */ + int ditype = 0; /* Display type selection charater(s) */ int tele = 0; /* NZ if telephoto mode */ int noautocal = 0; /* Disable auto calibration */ int noplace = 0; /* Disable user instrument placement */ @@ -426,7 +426,9 @@ int main(int argc, char *argv[]) { } else if (argv[fa][1] == 'y') { fa = nfa; if (na == NULL) usage(0,"Parameter expected after -y"); - dtype = na[0]; + ditype = na[0]; + if (ditype == '_' && na[1] != '\000') + ditype = ditype << 8 | na[1]; /* Calibration file */ } else if (argv[fa][1] == 'k' @@ -701,7 +703,7 @@ int main(int argc, char *argv[]) { } if (docalib) { - if ((rv = disprd_calibration(ipath, fc, dtype, -1, 0, tele, nadaptive, noautocal, + if ((rv = disprd_calibration(ipath, fc, ditype, -1, 0, tele, nadaptive, noautocal, disp, webdisp, ccid, #ifdef NT madvrdisp, @@ -919,7 +921,7 @@ int main(int argc, char *argv[]) { cal[0][0] = -1.0; /* Not used */ } - if ((dr = new_disprd(&errc, ipath, fc, dtype, -1, 0, tele, nadaptive, noautocal, noplace, + if ((dr = new_disprd(&errc, ipath, fc, ditype, -1, 0, tele, nadaptive, noautocal, noplace, highres, refrate, native, &noramdac, &nocm, cal, ncal, disp, out_tvenc, fullscreen, override, webdisp, ccid, #ifdef NT diff --git a/spectro/dispsup.c b/spectro/dispsup.c index 21e847f..bbb4151 100755 --- a/spectro/dispsup.c +++ b/spectro/dispsup.c @@ -205,9 +205,9 @@ inst_code setup_display_calibrate( int disprd_calibration( icompath *ipath, /* Instrument path to open, &icomFakeDevice == fake */ flow_control fc, /* Serial flow control */ -int dtype, /* Display type selection character */ -int sdtype, /* Spectro dtype, use dtype if -1 */ -int docbid, /* NZ to only allow cbid dtypes */ +int ditype, /* Display type selection character(s) */ +int sditype, /* Spectro ditype, use ditype if -1 */ +int docbid, /* NZ to only allow cbid ditypes */ int tele, /* NZ for tele mode, falls back to spot mode */ int nadaptive, /* NZ for non-adaptive mode */ int noinitcal, /* NZ to disable initial instrument calibration */ @@ -326,16 +326,17 @@ a1log *log /* Verb, debug & error log */ p->capabilities(p, &cap, &cap2, &cap3); /* If this is a spectral instrument, and a different */ - /* spectral inst. dtype is supplied, then use it */ - if (IMODETST(cap, inst_mode_spectral) && sdtype >= 0) - dtype = sdtype; + /* spectral inst. ditype is supplied, then use it */ + if (IMODETST(cap, inst_mode_spectral) && sditype >= 0) + ditype = sditype; /* Set the display type or calibration mode */ - if (dtype != 0) { /* Given selection character */ + if (ditype != 0) { /* Given selection character */ if (cap2 & inst2_disptype) { int ix; - if ((ix = inst_get_disptype_index(p, dtype, docbid)) < 0) { - a1logd(log,1,"Display type selection '%c' is not valid for instrument\n",dtype); + if ((ix = inst_get_disptype_index(p, ditype, docbid)) < 0) { + a1logd(log,1,"Display type selection '%s' is not valid for instrument\n", + inst_distr(ditype)); p->del(p); return -1; } @@ -2156,7 +2157,7 @@ static int config_inst_displ(disprd *p) { inst2_capability cap2; inst3_capability cap3; inst_mode mode = 0; - int dtype = p->dtype; + int ditype = p->ditype; int rv; p->it->capabilities(p->it, &cap, &cap2, &cap3); @@ -2229,16 +2230,17 @@ static int config_inst_displ(disprd *p) { } /* If this is a spectral instrument, and a different */ - /* spectral inst. dtype is supplied, then use it */ - if (IMODETST(cap, inst_mode_spectral) && p->sdtype >= 0) - dtype = p->sdtype; + /* spectral inst. ditype is supplied, then use it */ + if (IMODETST(cap, inst_mode_spectral) && p->sditype >= 0) + ditype = p->sditype; /* Set the display type or calibration mode */ - if (dtype != 0) { + if (ditype != 0) { if (cap2 & inst2_disptype) { int ix; - if ((ix = inst_get_disptype_index(p->it, dtype, p->docbid)) < 0) { - a1logd(p->log,1,"Display type selection '%c' is not valid for instrument\n",dtype); + if ((ix = inst_get_disptype_index(p->it, ditype, p->docbid)) < 0) { + a1logd(p->log,1,"Display type selection '%s' is not valid for instrument\n", + inst_distr(ditype)); if (p->docbid) return 16; return 15; @@ -2356,9 +2358,9 @@ disprd *new_disprd( int *errc, /* Error code. May be NULL (could use log for this instead?) */ icompath *ipath, /* Instrument path to open, &icomFakeDevice == fake */ flow_control fc, /* Flow control */ -int dtype, /* Display type selection character */ -int sdtype, /* Spectro dtype, use dtype if -1 */ -int docbid, /* NZ to only allow cbid dtypes */ +int ditype, /* Display type selection character(s) */ +int sditype, /* Spectro ditype, use ditype if -1 */ +int docbid, /* NZ to only allow cbid ditypes */ int tele, /* NZ for tele mode. Falls back to display mode */ int nadaptive, /* NZ for non-adaptive mode */ int noinitcal, /* No initial instrument calibration */ @@ -2436,8 +2438,8 @@ a1log *log /* Verb, debug & error log */ p->custObserver = custObserver; p->bdrift = bdrift; p->wdrift = wdrift; - p->dtype = dtype; - p->sdtype = sdtype; + p->ditype = ditype; + p->sditype = sditype; p->docbid = docbid; p->refrmode = -1; /* Unknown */ p->cbid = 0; /* Unknown */ @@ -2568,7 +2570,7 @@ a1log *log /* Verb, debug & error log */ /* Create a spectral conversion object if needed */ if (p->spectral && p->obType != icxOT_none) { - if ((p->sp2cie = new_xsp2cie(icxIT_none, NULL, p->obType, custObserver, icSigXYZData, icxNoClamp)) + if ((p->sp2cie = new_xsp2cie(icxIT_none, 0.0, NULL, p->obType, custObserver, icSigXYZData, icxNoClamp)) == NULL) { a1logd(log,1,"new_disprd failed because creation of spectral conversion object failed\n"); p->del(p); diff --git a/spectro/dispsup.h b/spectro/dispsup.h index 07a66e2..3687979 100755 --- a/spectro/dispsup.h +++ b/spectro/dispsup.h @@ -49,9 +49,9 @@ inst_code setup_display_calibrate( int disprd_calibration( icompath *ipath, /* Instrument path to open, &icomFakeDevice == fake */ flow_control fc, /* Serial flow control */ -int dtype, /* Display type, 0 = unknown, 1 = CRT, 2 = LCD */ -int sdtype, /* Spectro dtype, use dtype if -1 */ -int docbid, /* NZ to only allow cbid dtypes */ +int ditype, /* Display type selection character(s) */ +int sditype, /* Spectro ditype, use ditype if -1 */ +int docbid, /* NZ to only allow cbid ditypes */ int tele, /* NZ for tele mode */ int nadaptive, /* NZ for non-adaptive mode */ int noinitcal, /* NZ to disable initial instrument calibration */ @@ -116,9 +116,9 @@ struct _disprd { baud_rate br; flow_control fc; inst *it; /* Instrument */ - int dtype; /* Display type, 0 = unknown, 1 = CRT, 2 = LCD */ - int sdtype; /* Spectro dtype */ - int docbid; /* NZ to only allow cbid dtypes */ + int ditype; /* Display type selection character(s) */ + int sditype; /* Spectro ditype */ + int docbid; /* NZ to only allow cbid ditypes */ int refrmode; /* Refresh display mode, -1 if unknow, 0 = if no, 1 if yes */ int cbid; /* The current Calibration Base display mode ID, 0 if unknown */ int tele; /* NZ for tele mode */ @@ -229,9 +229,9 @@ disprd *new_disprd( int *errc, /* Error code. May be NULL */ icompath *ipath, /* Instrument path to open, &icomFakeDevice == fake */ flow_control fc, /* Serial flow control */ -int dtype, /* Display type, 0 = unknown, 1 = CRT, 2 = LCD */ -int sdtype, /* Spectro dtype, use dtype if -1 */ -int docbid, /* NZ to only allow cbid dtypes */ +int ditype, /* Display type selection character(s) */ +int sditype, /* Spectro ditype, use ditype if -1 */ +int docbid, /* NZ to only allow cbid ditypes */ int tele, /* NZ for tele mode */ int nadaptive, /* NZ for non-adaptive mode */ int noinitcal, /* No initial instrument calibration */ diff --git a/spectro/disptechs.c b/spectro/disptechs.c index bade777..dc38480 100755 --- a/spectro/disptechs.c +++ b/spectro/disptechs.c @@ -330,7 +330,7 @@ static disptech_info disptech_info_array[] = { }; -static int unknown_ix = -1; +static int unknown_ix = -1; /* Set to actual index by find_unknown() */ static void find_unknown() { int i; diff --git a/spectro/dispwin.c b/spectro/dispwin.c index 7761db1..9261592 100755 --- a/spectro/dispwin.c +++ b/spectro/dispwin.c @@ -1754,6 +1754,8 @@ static char *cur_profile(dispwin *p) { /* Return a CMProfileRef/ColorSyncProfileRef for the */ /* displays profile. Return NULL on error */ +/* Could use CGDisplayCopyColorSpace() instead of */ +/* cur_profile_url/ColorSyncProfileCreateWithURL for 10.5 + ? */ static void *cur_colorsync_ref(dispwin *p) { void *cspr = NULL; @@ -3853,6 +3855,8 @@ static void create_my_win(void *cntx) { #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 /* Get the ColorSync profile for this display */ + /* Could use CGDisplayCopyColorSpace() instead of */ + /* cur_colorsync_ref() code for 10.5 + ? */ if ((cspr = cur_colorsync_ref(p)) == NULL) { debugr2((errout,"cur_colorsync_ref failed\n")); diff --git a/spectro/ex1.c b/spectro/ex1.c index 929af3d..ee417dd 100755 --- a/spectro/ex1.c +++ b/spectro/ex1.c @@ -382,7 +382,7 @@ ex1_init_inst(inst *pp) { } #endif /* NEVER */ - p->conv = new_xsp2cie(icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, icxNoClamp); + p->conv = new_xsp2cie(icxIT_none, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, icxNoClamp); if (p->conv == NULL) return EX1_INT_CIECONVFAIL; diff --git a/spectro/i1d3.c b/spectro/i1d3.c index 7e5c396..c822324 100755 --- a/spectro/i1d3.c +++ b/spectro/i1d3.c @@ -2205,7 +2205,7 @@ i1d3_comp_calmat( sampRGB = dmatrix(0, nsamp-1, 0, 3-1); /* Compute XYZ of the sample array */ - if ((conv = new_xsp2cie(icxIT_none, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL) + if ((conv = new_xsp2cie(icxIT_none, 0.0, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL) return i1d3_interp_code((inst *)p, I1D3_INT_CIECONVFAIL); for (i = 0; i < nsamp; i++) { conv->convert(conv, sampXYZ[i], &samples[i]); @@ -2213,7 +2213,7 @@ i1d3_comp_calmat( conv->del(conv); /* Compute sensor RGB of the sample array */ - if ((conv = new_xsp2cie(icxIT_none, NULL, icxOT_custom, RGBcmfs, icSigXYZData, icxClamp)) == NULL) { + if ((conv = new_xsp2cie(icxIT_none, 0.0, NULL, icxOT_custom, RGBcmfs, icSigXYZData, icxClamp)) == NULL) { free_dmatrix(sampXYZ, 0, nsamp-1, 0, 3-1); free_dmatrix(sampRGB, 0, nsamp-1, 0, 3-1); return i1d3_interp_code((inst *)p, I1D3_INT_CIECONVFAIL); @@ -2880,7 +2880,7 @@ double mtx[3][3] i1d3 *p = (i1d3 *)pp; inst_code ev = inst_ok; - a1logd(p->log, 4, "i1d3_col_cor_mat%s\n",mtx == NULL ? " (noop)": ""); + a1logd(p->log, 4, "i1d3_col_cor_mat%s dtech %d cbid %d\n",mtx == NULL ? " (noop)": "",dtech,cbid); if (!p->gotcoms) return inst_no_coms; diff --git a/spectro/i1d3.h b/spectro/i1d3.h index 6152a00..c8f72df 100755 --- a/spectro/i1d3.h +++ b/spectro/i1d3.h @@ -81,16 +81,20 @@ /* Sub-type of instrument */ typedef enum { - i1d3_disppro = 0, /* i1 DisplayPro */ - i1d3_munkdisp = 1, /* ColorMunki Display */ - i1d3_oem = 2, /* Generic OEM */ - i1d3_nec_ssp = 3, /* NEC SpectraSensor Pro */ - i1d3_quato_sh3 = 4, /* Quato Silver Haze 3 */ - i1d3_hp_dreamc = 5, /* HP DreameColor */ - i1d3_sc_c6 = 6, /* SpectraCal C6 */ - i1d3_wacom_dc = 7 /* Wacom DC */ + i1d3_disppro = 0, /* i1 DisplayPro */ + i1d3_munkdisp = 1, /* ColorMunki Display */ + i1d3_oem = 2, /* Generic OEM */ + i1d3_nec_ssp = 3, /* NEC SpectraSensor Pro */ + i1d3_quato_sh3 = 4, /* Quato Silver Haze 3 */ + i1d3_hp_dreamc = 5, /* HP DreameColor */ + i1d3_sc_c6 = 6, /* SpectraCal C6 */ + i1d3_wacom_dc = 7, /* Wacom DC */ } i1d3_dtype; +/* Generic OEM aliases: + i1d3_viewsonic_xri1 +*/ + /* Measurement mode */ typedef enum { i1d3_adaptive = 0, /* Frequency over fixed period then adaptive period measurement (def) */ diff --git a/spectro/i1pro_imp.c b/spectro/i1pro_imp.c index 03f0a0d..cd870fa 100755 --- a/spectro/i1pro_imp.c +++ b/spectro/i1pro_imp.c @@ -582,25 +582,33 @@ i1pro_code i1pro_imp_init(i1pro *p) { /* Information about the instrument */ - if ((ip = m->data->get_ints(m->data, &count, key_serno)) == NULL || count < 1) + if ((ip = m->data->get_ints(m->data, &count, key_serno)) == NULL || count < 1) { + a1logd(p->log,7,"Missing key_serno\n"); return I1PRO_HW_CALIBINFO; + } m->serno = ip[0]; a1logd(p->log,2,"Serial number = %d\n",m->serno); sprintf(m->sserno,"%ud",m->serno); - if ((ip = m->data->get_ints(m->data, &count, key_dom)) == NULL || count < 1) + if ((ip = m->data->get_ints(m->data, &count, key_dom)) == NULL || count < 1) { + a1logd(p->log,7,"Missing key_dom\n"); return I1PRO_HW_CALIBINFO; + } m->dom = ip[0]; a1logd(p->log,2, "Date of manufactur = %d-%d-%d\n", m->dom/1000000, (m->dom/10000) % 100, m->dom % 10000); - if ((ip = m->data->get_ints(m->data, &count, key_cpldrev)) == NULL || count < 1) + if ((ip = m->data->get_ints(m->data, &count, key_cpldrev)) == NULL || count < 1) { + a1logd(p->log,7,"Missing key_cpldrev\n"); return I1PRO_HW_CALIBINFO; + } m->cpldrev = ip[0]; a1logd(p->log,2,"CPLD rev = %d\n",m->cpldrev); - if ((ip = m->data->get_ints(m->data, &count, key_capabilities)) == NULL || count < 1) + if ((ip = m->data->get_ints(m->data, &count, key_capabilities)) == NULL || count < 1) { + a1logd(p->log,7,"Missing key_capabilities\n"); return I1PRO_HW_CALIBINFO; + } m->capabilities = ip[0]; if (m->capabilities & 0x6000) /* Has ambient */ m->capabilities2 |= I1PRO_CAP2_AMBIENT; /* Mimic in capabilities2 */ @@ -608,8 +616,10 @@ i1pro_code i1pro_imp_init(i1pro *p) { if (m->capabilities & 0x6000) a1logd(p->log,2," Can read ambient\n"); - if ((ip = m->data->get_ints(m->data, &count, key_physfilt)) == NULL || count < 1) + if ((ip = m->data->get_ints(m->data, &count, key_physfilt)) == NULL || count < 1) { + a1logd(p->log,7,"Missing key_physfilt\n"); return I1PRO_HW_CALIBINFO; + } m->physfilt = ip[0]; if (m->physfilt == 0x82) m->capabilities2 |= I1PRO_CAP2_UV_FILT; /* Mimic in cap 2 */ @@ -639,10 +649,14 @@ i1pro_code i1pro_imp_init(i1pro *p) { if (m->nsen > NSEN_MAX) /* Static allocation assumed */ return I1PRO_HW_UNEX_SPECPARMS; } - if (m->data->get_ints(m->data, &m->nwav[0], key_mtx_index) == 0) + if (m->data->get_ints(m->data, &m->nwav[0], key_mtx_index) == 0) { + a1logd(p->log,7,"Missing key_mtx_index\n"); return I1PRO_HW_CALIBINFO; - if (m->nwav[0] != 36) + } + if (m->nwav[0] != 36) { + a1logd(p->log,7,"key_mtx_index != 36 elements\n"); return I1PRO_HW_CALIBINFO; + } m->wl_short[0] = 380.0; /* Normal res. range */ m->wl_long[0] = 730.0; @@ -651,18 +665,24 @@ i1pro_code i1pro_imp_init(i1pro *p) { m->wl_long[1] = HIGHRES_LONG; m->nwav[1] = (int)((m->wl_long[1]-m->wl_short[1])/HIGHRES_WIDTH + 0.5) + 1; - if ((dp = m->data->get_doubles(m->data, &count, key_hg_factor)) == NULL || count < 1) + if ((dp = m->data->get_doubles(m->data, &count, key_hg_factor)) == NULL || count < 1) { + a1logd(p->log,7,"Missing key_hg_factor\n"); return I1PRO_HW_CALIBINFO; + } m->highgain = dp[0]; a1logd(p->log,2,"High gain = %.10f\n",m->highgain); if ((m->lin0 = m->data->get_doubles(m->data, &m->nlin0, key_ng_lin)) == NULL - || m->nlin0 < 1) + || m->nlin0 < 1) { + a1logd(p->log,7,"Missing key_ng_lin\n"); return I1PRO_HW_CALIBINFO; + } if ((m->lin1 = m->data->get_doubles(m->data, &m->nlin1, key_hg_lin)) == NULL - || m->nlin1 < 1) + || m->nlin1 < 1) { + a1logd(p->log,7,"Missing key_hg_lin\n"); return I1PRO_HW_CALIBINFO; + } if (p->log->debug >= 2) { char oline[200] = { '\000' }, *bp = oline; @@ -681,8 +701,10 @@ i1pro_code i1pro_imp_init(i1pro *p) { a1logd(p->log,2,oline); } - if ((dp = m->data->get_doubles(m->data, &count, key_min_int_time)) == NULL || count < 1) + if ((dp = m->data->get_doubles(m->data, &count, key_min_int_time)) == NULL || count < 1) { + a1logd(p->log,7,"Missing key_min_int_time\n"); return I1PRO_HW_CALIBINFO; + } m->min_int_time = dp[0]; /* And then override it */ @@ -695,62 +717,84 @@ i1pro_code i1pro_imp_init(i1pro *p) { m->min_int_time = 0.00884; /* == 1 sub clock */ } - if ((dp = m->data->get_doubles(m->data, &count, key_max_int_time)) == NULL || count < 1) + if ((dp = m->data->get_doubles(m->data, &count, key_max_int_time)) == NULL || count < 1) { + a1logd(p->log,7,"Missing key_max_int_time\n"); return I1PRO_HW_CALIBINFO; + } m->max_int_time = dp[0]; if ((m->mtx_o.index = m->data->get_ints(m->data, &count, key_mtx_index)) == NULL - || count != m->nwav[0]) + || count != m->nwav[0]) { + a1logd(p->log,7,"Missing key_mtx_index\n"); return I1PRO_HW_CALIBINFO; + } if ((m->mtx_o.nocoef = m->data->get_ints(m->data, &count, key_mtx_nocoef)) == NULL - || count != m->nwav[0]) + || count != m->nwav[0]) { + a1logd(p->log,7,"Missing key_mtx_nocoef\n"); return I1PRO_HW_CALIBINFO; + } for (xcount = i = 0; i < m->nwav[0]; i++) /* Count number expected in matrix coeffs */ xcount += m->mtx_o.nocoef[i]; if ((m->mtx_o.coef = m->data->get_doubles(m->data, &count, key_mtx_coef)) == NULL - || count != xcount) + || count != xcount) { + a1logd(p->log,7,"Missing key_mtx_coef\n"); return I1PRO_HW_CALIBINFO; + } if ((m->white_ref[0] = m->data->get_doubles(m->data, &count, key_white_ref)) == NULL - || count != m->nwav[0]) { - if (p->dtype != instI1Monitor) + || count != m->nwav[0]) { + if (p->dtype != instI1Monitor) { + a1logd(p->log,7,"Missing key_white_ref\n"); return I1PRO_HW_CALIBINFO; + } m->white_ref[0] = NULL; } if ((m->emis_coef[0] = m->data->get_doubles(m->data, &count, key_emis_coef)) == NULL - || count != m->nwav[0]) + || count != m->nwav[0]) { + a1logd(p->log,7,"Missing key_emis_coef\n"); return I1PRO_HW_CALIBINFO; + } if ((m->amb_coef[0] = m->data->get_doubles(m->data, &count, key_amb_coef)) == NULL - || count != m->nwav[0]) { + || count != m->nwav[0]) { if (p->dtype != instI1Monitor - && m->capabilities & 0x6000) /* Expect ambient calibration */ + && m->capabilities & 0x6000) { /* Expect ambient calibration */ + a1logd(p->log,7,"Missing key_amb_coef\n"); return I1PRO_HW_CALIBINFO; + } m->amb_coef[0] = NULL; } /* Default to original EEProm raw to wav filters values*/ m->mtx[0][0] = m->mtx_o; /* Std res reflective */ m->mtx[0][1] = m->mtx_o; /* Std res emissive */ - if ((ip = m->data->get_ints(m->data, &count, key_sens_target)) == NULL || count < 1) + if ((ip = m->data->get_ints(m->data, &count, key_sens_target)) == NULL || count < 1) { + a1logd(p->log,7,"Missing key_sens_target\n"); return I1PRO_HW_CALIBINFO; + } m->sens_target = ip[0]; - if ((ip = m->data->get_ints(m->data, &count, key_sens_dark)) == NULL || count < 1) + if ((ip = m->data->get_ints(m->data, &count, key_sens_dark)) == NULL || count < 1) { + a1logd(p->log,7,"Missing key_sens_dark\n"); return I1PRO_HW_CALIBINFO; + } m->sens_dark = ip[0]; - if ((ip = m->data->get_ints(m->data, &count, key_ng_sens_sat)) == NULL || count < 1) + if ((ip = m->data->get_ints(m->data, &count, key_ng_sens_sat)) == NULL || count < 1) { + a1logd(p->log,7,"Missing key_ng_sens_sat\n"); return I1PRO_HW_CALIBINFO; + } m->sens_sat0 = ip[0]; - if ((ip = m->data->get_ints(m->data, &count, key_hg_sens_sat)) == NULL || count < 1) + if ((ip = m->data->get_ints(m->data, &count, key_hg_sens_sat)) == NULL || count < 1) { + a1logd(p->log,7,"Missing key_hg_sens_sat\n"); return I1PRO_HW_CALIBINFO; + } m->sens_sat1 = ip[0]; a1logd(p->log,2,"sens_target %d, sens_dark %d, sens_sat0 %d, sens_sat1 %d\n", @@ -809,8 +853,10 @@ i1pro_code i1pro_imp_init(i1pro *p) { /* Capability bits */ if ((ip = m->data->get_ints(m->data, &count, key2_capabilities)) == NULL - || count != 1) + || count != 1) { + a1logd(p->log,7,"Missing key2_capabilities\n"); return I1PRO_HW_CALIBINFO; + } m->capabilities2 = *ip; if (p->log->debug >= 2) { a1logd(p->log,2,"Capabilities2 flag = 0x%x\n",m->capabilities2); @@ -831,64 +877,94 @@ i1pro_code i1pro_imp_init(i1pro *p) { if (m->capabilities2 & I1PRO_CAP2_WL_LED) { /* wavelength LED calibration integration time (0.56660) */ if ((dp = m->data->get_doubles(m->data, &count, key2_wlcal_intt)) == NULL - || count != 1) + || count != 1) { + a1logd(p->log,7,"Missing key2_wlcal_intt\n"); return I1PRO_HW_CALIBINFO; + } m->wl_cal_inttime = *dp; /* Wavelength calibration minimum level */ if ((ip = m->data->get_ints(m->data, &count, key2_wlcal_minlev)) == NULL - || count != 1) + || count != 1) { + a1logd(p->log,7,"Missing key2_wlcal_minlev\n"); return I1PRO_HW_CALIBINFO; + } /* Normalize it to 1.0 seconds (ie. 500/0.56660) */ m->wl_cal_min_level = (double)(*ip) / m->wl_cal_inttime; /* wavelength LED measurement expected FWHM in nm */ if ((dp = m->data->get_doubles(m->data, &count, key2_wlcal_fwhm)) == NULL - || count != 1) + || count != 1) { + a1logd(p->log,7,"Missing key2_wlcal_fwhm\n"); return I1PRO_HW_CALIBINFO; + } m->wl_cal_fwhm = *dp; /* wavelength LED measurement FWHM tollerance in nm */ if ((dp = m->data->get_doubles(m->data, &count, key2_wlcal_fwhm_tol)) == NULL - || count != 1) + || count != 1) { + a1logd(p->log,7,"Missing key2_wlcal_fwhm_tol\n"); return I1PRO_HW_CALIBINFO; + } m->wl_cal_fwhm_tol = *dp; /* wavelength LED reference spectrum */ - if ((m->wl_led_spec = m->data->get_doubles(m->data, &m->wl_led_count, key2_wlcal_spec)) == NULL) + if ((m->wl_led_spec = m->data->get_doubles(m->data, &m->wl_led_count, + key2_wlcal_spec)) == NULL) { + a1logd(p->log,7,"Missing key2_wlcal_spec\n"); return I1PRO_HW_CALIBINFO; + } /* wavelength LED spectraum reference offset */ if ((ip = m->data->get_ints(m->data, &count, key2_wlcal_ooff)) == NULL - || count != 1) + || count != 1) { + a1logd(p->log,7,"Missing key2_wlcal_ooff\n"); return I1PRO_HW_CALIBINFO; + } m->wl_led_ref_off = *ip; /* Hmm. this is odd, but it doesn't work correctly otherwise... */ m->wl_led_ref_off--; /* wavelength calibration maximum error */ if ((dp = m->data->get_doubles(m->data, &count, key2_wlcal_max)) == NULL - || count != 1) + || count != 1) { + a1logd(p->log,7,"Missing key2_wlcal_max\n"); return I1PRO_HW_CALIBINFO; + } m->wl_err_max = *dp; } - /* CCD bin to wavelength polinomial */ - if ((m->wlpoly1 = m->data->get_doubles(m->data, &count, key2_wlpoly_1)) == NULL || count != 4) + /* CCD bin to wavelength polinomial (Emission) */ + if ((m->wlpoly2 = m->data->get_doubles(m->data, &count, key2_wlpoly_2)) == NULL + || count != 4) { + a1logd(p->log,7,"Missing key2_wlpoly_2\n"); return I1PRO_HW_CALIBINFO; + } - if ((m->wlpoly2 = m->data->get_doubles(m->data, &count, key2_wlpoly_2)) == NULL || count != 4) - return I1PRO_HW_CALIBINFO; + /* CCD bin to wavelength polinomial (Reflection) */ + if ((m->wlpoly1 = m->data->get_doubles(m->data, &count, key2_wlpoly_1)) == NULL || count != 4) { + /* Hmm. no key2_wlpoly_1. This seems to be the case for */ + /* some stripped down OEM instruments. Use key2_wlpoly_2 instead */ + if ((m->wlpoly2 = m->data->get_doubles(m->data, &count, key2_wlpoly_2)) == NULL + || count != 4) { + a1logd(p->log,7,"Missing key2_wlpoly_1 and key2_wlpoly_2\n"); + return I1PRO_HW_CALIBINFO; + } + } /* Stray light compensation. Note that 16 bit numbers are signed. */ if ((sip = m->data->get_shorts(m->data, &count, key2_straylight)) == NULL - || count != (36 * 36)) + || count != (36 * 36)) { + a1logd(p->log,7,"Missing key2_straylight\n"); return I1PRO_HW_CALIBINFO; + } /* stray light scale factor */ if ((dp = m->data->get_doubles(m->data, &count, key2_straylight_scale)) == NULL - || count != 1) + || count != 1) { + a1logd(p->log,7,"Missing key2_straylight_scale\n"); return I1PRO_HW_CALIBINFO; + } /* Convert from ints to floats */ m->straylight[0] = dmatrixz(0, 35, 0, 35); @@ -1060,6 +1136,7 @@ i1pro_code i1pro_imp_init(i1pro *p) { s->scan = 1; s->adaptive = 1; s->inttime = m->min_int_time; /* Maximize scan rate */ + /* (see i1pro_imp_calibrate() too) */ s->dark_int_time = s->inttime; if (m->fwrev >= 301) /* (We're not using scan targoscale though) */ s->targoscale = 0.25; @@ -1127,6 +1204,7 @@ i1pro_code i1pro_imp_init(i1pro *p) { s->scan = 1; s->adaptive = 1; /* ???? */ s->inttime = m->min_int_time; /* Maximize scan rate */ + /* (see i1pro_imp_calibrate() too) */ s->lamptime = 0.0; s->dark_int_time = s->inttime; if (m->fwrev >= 301) @@ -1223,6 +1301,7 @@ i1pro_code i1pro_imp_init(i1pro *p) { s->scan = 1; s->adaptive = 0; s->inttime = m->min_int_time; /* Maximize scan rate */ + /* (see i1pro_imp_calibrate() too) */ s->dark_int_time = s->inttime; if (m->fwrev >= 301) /* (We're not using scan targoscale though) */ s->targoscale = 0.25; @@ -10175,9 +10254,9 @@ i1pro_code i1pro_conv2XYZ( double sms; /* Weighting */ if (s->emiss) - conv = new_xsp2cie(icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, (icxClamping)clamp); + conv = new_xsp2cie(icxIT_none, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, (icxClamping)clamp); else - conv = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, (icxClamping)clamp); + conv = new_xsp2cie(icxIT_D50, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, (icxClamping)clamp); if (conv == NULL) return I1PRO_INT_CIECONVFAIL; @@ -10325,16 +10404,16 @@ i1pro_code i1pro_check_white_reference1( /* And check them against tolerance for the illuminant. */ if (m->physfilt == 0x82) { /* UV filter */ - a1logd(p->log,2,"Checking white reference (UV): 0.0 < avg01 %f < 0.05, 1.2 < avg2227 %f < 1.76\n",avg01,avg2227); - if (0.0 < avg01 && avg01 < 0.05 - && 1.2 < avg2227 && avg2227 < 1.76) { + a1logd(p->log,2,"Checking white reference (UV): 0.0 <= avg01 %f <= 0.05, 1.2 <= avg2227 %f <= 1.76\n",avg01,avg2227); + if (0.0 <= avg01 && avg01 <= 0.05 + && 1.2 <= avg2227 && avg2227 <= 1.76) { return I1PRO_OK; } } else { /* No filter */ - a1logd(p->log,2,"Checking white reference: 0.11 < avg01 %f < 0.22, 1.35 < avg2227 %f < 1.6\n",avg01,avg2227); - if (0.11 < avg01 && avg01 < 0.22 - && 1.35 < avg2227 && avg2227 < 1.6) { + a1logd(p->log,2,"Checking white reference: 0.11 <= avg01 %f <= 0.22, 1.35 <= avg2227 %f <= 1.6\n",avg01,avg2227); + if (0.11 <= avg01 && avg01 <= 0.22 + && 1.35 <= avg2227 && avg2227 <= 1.6) { return I1PRO_OK; } } diff --git a/spectro/i1pro_imp.h b/spectro/i1pro_imp.h index 582cc98..00cf52d 100755 --- a/spectro/i1pro_imp.h +++ b/spectro/i1pro_imp.h @@ -248,7 +248,7 @@ struct _i1proimp { /* 0x81 == emission only ?? */ /* 0x82 == UV filter */ int capabilities2; /* Rev E capabilities - set #defines above */ - /* Also set for RevA-D */ + /* Also set for RevA-D to simplify capability testing */ /* Underlying calibration information */ int nsen; /* Raw + extra sample bands read = 128 for i1pro, 136 for Rev E */ @@ -1290,14 +1290,45 @@ typedef enum { key2_wlcal_max = 0x2f46, /* double, wavelength calibration error limit, ie. 5.0 */ - key2_wlpoly_1 = 0x2f62, /* double[4], CCD bin to wavelength polinomial #1 (normal) */ - key2_wlpoly_2 = 0x2f63, /* double[4], CCD bin to wavelength polinomial #2 ??? */ + key2_wlpoly_1 = 0x2f62, /* double[4], CCD bin to wavelength polinomial #1 (reflective ?) */ + key2_wlpoly_2 = 0x2f63, /* double[4], CCD bin to wavelength polinomial #2 (emissive ?) */ key2_straylight = 0x2f58, /* int16[36][6] signed stray light values */ key2_straylight_scale = 0x2f59 /* double stray light scale factor */ } i1key; +/* + +Missing keys for Stripped down OEM i1pro2 (Capabilities2 flag = 0x30) +i.e. missing Ambient, WL Led, UV Led, Zebra ruller, + has indicator Leds, UV filter. + +Table entry 34 is Key 0x0bba, type 3 addr 0x1c4c, size 4 Unkn + +Table entry 5 is Key 0x2eea, type 3 addr 0x2218, size 4 Unkn +Table entry 6 is Key 0x2eeb, type 3 addr 0x221c, size 4 key2_sens_target +Table entry 9 is Key 0x2ef5, type 4 addr 0x2228, size 4 Unkn +Table entry 10 is Key 0x2ef6, type 4 addr 0x222c, size 4 Unkn +Table entry 11 is Key 0x2ef9, type 4 addr 0x2230, size 4 key2_uvcal_intt +Table entry 12 is Key 0x2efa, type 4 addr 0x2234, size 4 key2_wlcal_intt +Table entry 13 is Key 0x2efe, type 3 addr 0x2238, size 4 key2_wlcal_minlev +Table entry 14 is Key 0x2eff, type 3 addr 0x223c, size 4 Unkn +Table entry 21 is Key 0x2f44, type 4 addr 0x2258, size 200 key2_wlcal_spec +Table entry 22 is Key 0x2f45, type 3 addr 0x2320, size 4 key2_wlcal_ooff +Table entry 23 is Key 0x2f46, type 4 addr 0x2324, size 4 key2_wlcal_max +Table entry 24 is Key 0x2f4e, type 4 addr 0x2328, size 4 key2_wlcal_fwhm +Table entry 25 is Key 0x2f4f, type 4 addr 0x232c, size 4 key2_wlcal_fwhm_tol +Table entry 26 is Key 0x2f50, type 4 addr 0x2330, size 4 Unkn +Table entry 29 is Key 0x2f62, type 4 addr 0x2d58, size 16 key2_wlpoly_1 +Table entry 31 is Key 0x2f6c, type 4 addr 0x2d78, size 8 Unkn +Table entry 32 is Key 0x2f6d, type 4 addr 0x2d80, size 4 Unkn +Table entry 33 is Key 0x2f6e, type 4 addr 0x2d84, size 4 Unkn +Table entry 34 is Key 0x2f76, type 4 addr 0x2d88, size 72 Unkn +Table entry 35 is Key 0x2f77, type 4 addr 0x2dd0, size 72 Unkn + +*/ + /* Data type */ typedef enum { diff --git a/spectro/icoms.c b/spectro/icoms.c index 875f3b6..08ddd92 100755 --- a/spectro/icoms.c +++ b/spectro/icoms.c @@ -760,8 +760,12 @@ int frbw /* nz to Flush Read Before Write */ int debug = p->log->debug; int bread; + p->ser_clearerr(p); + if (debug < 8) p->log->debug = 0; + /* (Could use tcflush() or ioctl(TCFLSH) on *nix, */ + /* except these don't work on USB serial ports!) */ for (;;) { bread = 0; p->read(p, tbuf, 500, &bread, NULL, 500, 0.02); @@ -813,6 +817,11 @@ double tout /* Timeout for write and then read (i.e. max = 2 x tout) */ return icoms_write_read_ex(p, wbuf, nwch, rbuf, bsize, bread, tc, ntc, tout, 0); } +/* Default NOP implementation - Serial open or set_methods may override */ +static void icoms_ser_clearerr(icoms *p) { + return; +} + /* Optional callback to client from device */ /* Default implementation is a NOOP */ static int icoms_interrupt(icoms *p, @@ -907,6 +916,7 @@ icoms *new_icoms( p->read = NULL; p->write_read = icoms_write_read; p->write_read_ex = icoms_write_read_ex; + p->ser_clearerr = icoms_ser_clearerr; /* Default NOP implementation */ p->interrupt = icoms_interrupt; p->del = icoms_del; diff --git a/spectro/icoms.h b/spectro/icoms.h index 4e18b62..74af2ee 100755 --- a/spectro/icoms.h +++ b/spectro/icoms.h @@ -515,6 +515,9 @@ struct _icoms { double tout, /* Timeout in seconds */ int frbw); /* nz to Flush Read Before Write */ + /* For serial device, clear any errors */ + void (*ser_clearerr)(struct _icoms *p); + /* For a USB device, do a control message */ /* return icom error */ int (*usb_control)(struct _icoms *p, diff --git a/spectro/icoms_nt.c b/spectro/icoms_nt.c index 39ff6f0..7ac074b 100755 --- a/spectro/icoms_nt.c +++ b/spectro/icoms_nt.c @@ -163,6 +163,16 @@ void serial_close_port(icoms *p) { } } +/* Clear any serial errors */ +static void nt_ser_clearerr(icoms *p) { + DWORD errs; + + if (!ClearCommError(p->phandle, &errs,NULL)) + error("nt_ser_clearerr: failed, and Clear error failed"); + + return; +} + /* -------------------------------------------------------------------- */ #ifndef CBR_230400 @@ -428,6 +438,7 @@ int delayms) { /* Delay after open in msec */ p->write = icoms_ser_write; p->read = icoms_ser_read; + p->ser_clearerr = nt_ser_clearerr; } a1logd(p->log, 8, "icoms_set_ser_port: port characteristics set ok\n"); diff --git a/spectro/illumread.c b/spectro/illumread.c index 28ecbca..aee546c 100755 --- a/spectro/illumread.c +++ b/spectro/illumread.c @@ -1063,14 +1063,14 @@ int main(int argc, char *argv[]) bf.r_sp = &r_sp; bf.p_sp = &p_sp; - if ((bf.pap = new_xsp2cie(icxIT_custom, &i_sp, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL) + if ((bf.pap = new_xsp2cie(icxIT_custom, 0.0, &i_sp, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL) error("new_xsp2cie pap failed"); if (bf.pap->set_fwa(bf.pap, &insp, NULL, &p_sp) != 0) error ("Setting FWA compensation failed"); /* Setup the equal energy to Lab conversion */ - if ((bf.ref = new_xsp2cie(icxIT_E, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL) + if ((bf.ref = new_xsp2cie(icxIT_E, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL) error("new_xsp2cie ref failed"); /* Estimate an initial gain match */ @@ -1154,7 +1154,7 @@ int main(int argc, char *argv[]) xspect cpdsp; /* FWA corrected calculated daylight paper reflectance */ /* Setup the referencec comversion */ - if ((cf.ref = new_xsp2cie(icxIT_E, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL) + if ((cf.ref = new_xsp2cie(icxIT_E, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, icxClamp)) == NULL) error("new_xsp2cie ref failed"); cf.ill = bf.ill; diff --git a/spectro/inst.c b/spectro/inst.c index 07ace6e..7f1368a 100755 --- a/spectro/inst.c +++ b/spectro/inst.c @@ -41,11 +41,11 @@ #ifndef SALONEINSTLIB #include "copyright.h" #include "aconfig.h" +#include "rand.h" #else #include "sa_config.h" #endif /* !SALONEINSTLIB */ #include "numsup.h" -#include "rand.h" #include "cgats.h" #include "xspect.h" #include "conv.h" @@ -881,6 +881,12 @@ static inst_disptypesel *expand_dlist(inst_disptypesel *list, int nlist, int *na than any aliases that come after it, and the aliases as more important than the fallback list, so we need to do three passes through all the selections. + + If we run out of single letter selectors (i.e. K10), + then we switch to the two letter prefixed selector "_X". + + NOTE that we assume that we cannot exaust the single letter + selectors via hard coded, ccmx or ccss calibrations. */ /* Create the display type list */ @@ -892,8 +898,8 @@ int doccss, /* Add installed ccss files */ int doccmx /* Add matching installed ccmx files */ ) { inst_disptypesel *list = NULL; - int i, j, k, nlist = 0, nalist = 0; - char usels[256]; /* Used selectors */ + int i, j, k, k2, nlist = 0, nalist = 0; + char usels[256]; /* Used selectors 1 */ static char *asels = "123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; int fail = 0; @@ -902,8 +908,9 @@ int doccmx /* Add matching installed ccmx files */ *pdtlist = NULL; *pndtlist = 0; - for (i = 0; i < 256; i++) - usels[i] = ((char)-1); + for (j = 0; j < 256; j++) + usels[j] = ((char)-1); + k2 = 0; /* Single letter selector */ k = 0; /* Next selector index */ /* First create a list of calibrations and their desired selectors: */ @@ -1031,26 +1038,42 @@ int doccmx /* Add matching installed ccmx files */ /* Set remaining from fallback */ for (i = 0; i < nlist; i++) { - disptechs_set_sel(2, i, list[i].sel, list[i].isel, usels, &k, asels); - if (list[i].sel[0] == '\000') - fail = 1; + if (k2 == 0) { /* Single letter selector */ + disptechs_set_sel(2, i, list[i].sel, list[i].isel, usels, &k, asels); + if (list[i].sel[0] == '\000') { /* Switch to two letter */ + for (j = 0; j < 256; j++) + usels[j] = ((char)-1); + k2 = 1; /* Two letter selector */ + k = 0; /* Next selector index */ + } + } + if (k2 == 1) { /* Two letter selector */ + list[i].sel[0] = '_'; + disptechs_set_sel(2, i, &list[i].sel[1], list[i].isel, usels, &k, asels); + if (list[i].sel[0] == '\000') { /* Ran out of two letter selectors! */ + fail = 1; + break; + } + } } /* Any calibrations that failed to find a character will be left as a nul string */ /* Add alternate selectors if they are free. */ - for (;;) { - int more = 0; - for (i = 0; i < nlist; i++) { - /* Add unused secondaries */ - disptechs_set_sel(3, i, list[i].sel, list[i].isel, usels, &k, asels); - - if (list[i].isel[0] != '\000') { /* Still more secondaries available */ - more = 1; + if (k2 == 0) { /* If not run out of 1 letter selectors */ + for (;;) { + int more = 0; + for (i = 0; i < nlist; i++) { + /* Add unused secondaries */ + disptechs_set_sel(3, i, list[i].sel, list[i].isel, usels, &k, asels); + + if (list[i].isel[0] != '\000') { /* Still more secondaries available */ + more = 1; + } } + if (!more) + break; } - if (!more) - break; } if (pndtlist != NULL) diff --git a/spectro/inst.h b/spectro/inst.h index 04e02d6..601f7b3 100755 --- a/spectro/inst.h +++ b/spectro/inst.h @@ -43,8 +43,8 @@ and agreed to support. */ -#include "dev.h" /* Base device class */ #include "insttypes.h" /* libinst Includes this functionality */ +#include "dev.h" /* Base device class */ #include "disptechs.h" /* libinst Includes this functionality */ #include "icoms.h" /* libinst Includes this functionality */ #include "conv.h" @@ -69,6 +69,10 @@ #ifdef NEVER /* Declared in xicc/xspect.h */ +// ~~~ should add absorbance mode - +// i.e. modified transmissive mode where units are +// log10(incident/transmitted) = Beer-Lambert Law + /* Type of measurement result */ typedef enum { /* XYZ units, Spectral units */ inst_mrt_none = 0, /* Not set */ diff --git a/spectro/instappsup.c b/spectro/instappsup.c index 6c3dd68..0cb5798 100755 --- a/spectro/instappsup.c +++ b/spectro/instappsup.c @@ -479,6 +479,7 @@ inst2_capability inst_show_disptype_options(FILE *fp, char *oline, icompaths *ic if (docbib && sels[j].cbid == 0) continue; /* Skip non cbid type */ + /* Break up selector chars/pairs with '|' */ m = pstart; for (k = 0; k < (INST_DTYPE_SEL_LEN-1); k++) { if (sels[j].sel[k] == '\000') @@ -486,6 +487,8 @@ inst2_capability inst_show_disptype_options(FILE *fp, char *oline, icompaths *ic if (m > pstart) buf[m++] = '|'; buf[m++] = sels[j].sel[k]; + if (sels[j].sel[k] == '_') + buf[m++] = sels[j].sel[++k]; } while (m < (olen+1)) /* Indent it by 1 */ buf[m++] = ' '; @@ -534,8 +537,9 @@ inst2_capability inst_show_disptype_options(FILE *fp, char *oline, icompaths *ic /* A helper function to turn a -y flag into a selection index */ /* If docbib is nz, then only allow base calibration display types */ +/* c will be 16 bits ('_' + 'X') if a 2 char selector */ /* Return -1 on error */ -int inst_get_disptype_index(inst *it, int c, int docbib) { +int inst_get_disptype_index(inst *it, int ditype, int docbib) { inst2_capability cap; int j, k; @@ -555,7 +559,14 @@ int inst_get_disptype_index(inst *it, int c, int docbib) { for (k = 0; k < (INST_DTYPE_SEL_LEN-1); k++) { if (sels[j].sel[k] == '\000') break; - if (sels[j].sel[k] == c) { + if (sels[j].sel[k] == '_') { /* 2 char selector */ + k++; + if (sels[j].sel[k-1] == (0xff & (ditype >> 8)) + && sels[j].sel[k] == (0xff & ditype)) { + return j; + } + } + if (sels[j].sel[k] == ditype) { return j; } } @@ -564,6 +575,21 @@ int inst_get_disptype_index(inst *it, int c, int docbib) { return -1; } +/* Return a static string of the ditype flag char(s) */ +char *inst_distr(int ditype) { + static char buf[5]; + + if ((ditype >> 8) & 0xff) { + buf[0] = (ditype >> 8) & 0xff; + buf[1] = ditype & 0xff; + buf[2] = '\000'; + } else { + buf[0] = ditype; + buf[1] = '\000'; + } + + return buf; +} /* ================================================================= */ diff --git a/spectro/instappsup.h b/spectro/instappsup.h index 8da4325..c5b95fc 100755 --- a/spectro/instappsup.h +++ b/spectro/instappsup.h @@ -91,7 +91,10 @@ inst2_capability inst_show_disptype_options(FILE *fp, char *oline, icompaths *ic /* A helper function to turn a -y flag into a list index */ /* If docbib is nz, then only allow base calibration display types */ /* Return 0 on error */ -int inst_get_disptype_index(inst *it, int c, int docbib); +int inst_get_disptype_index(inst *it, int ditype, int docbib); + +/* Return a static string of the ditype flag char(s) */ +char *inst_distr(int ditype); #ifdef __cplusplus } diff --git a/spectro/instlib.ksh b/spectro/instlib.ksh index 8b0303f..47243e4 100755 --- a/spectro/instlib.ksh +++ b/spectro/instlib.ksh @@ -57,6 +57,7 @@ SPECTRO_FILES=" hidio.h hidio.c icoms.h + dev.h inst.h inst.c insttypes.c diff --git a/spectro/kleink10.c b/spectro/kleink10.c index d169156..6b057ff 100755 --- a/spectro/kleink10.c +++ b/spectro/kleink10.c @@ -2,7 +2,7 @@ /* * Argyll Color Correction System * - * JETI kleink10 1211/1201 related functions + * Klein K10 related functions * * Author: Graeme W. Gill * Date: 29/4/2014 @@ -68,6 +68,7 @@ #undef PLOT_REFRESH /* [und] Plot refresh rate measurement info */ #undef PLOT_UPDELAY /* [und] Plot update delay measurement info */ +#undef TEST_FAKE_CALIBS /* Fake having a full calibration set (98 calibs) */ #undef TEST_BAUD_CHANGE /* Torture test baud rate change on non high speed K10 */ static inst_disptypesel k10_disptypesel[98]; @@ -216,7 +217,7 @@ int nd /* nz to disable debug messages */ strncpy((char *)cmd, (char *)in, 2); cmd[2] = '\000'; - if ((se = p->icom->write_read(p->icom, in, 0, out, bsize, &bread, NULL, nchar, to)) + if ((se = p->icom->write_read_ex(p->icom, in, 0, out, bsize, &bread, NULL, nchar, to, 1)) != ICOM_OK) { rv = icoms2k10_err(se); @@ -331,7 +332,7 @@ struct _kleink10 *p, baud_rate br ) { int se, rv = K10_OK; - if ((se = p->icom->set_ser_port(p->icom, fc_HardwareDTR, br, parity_none, + if ((se = p->icom->set_ser_port(p->icom, fc_None, br, parity_none, stop_1, length_8)) != ICOM_OK) { rv = icoms2k10_err(se); } else { @@ -388,7 +389,7 @@ k10_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { } a1logd(p->log, 5, "k10_init_coms: Trying %s baud, %d msec to go\n", baud_rate_to_str(brt[i]), etime- msec_time()); - if ((se = p->icom->set_ser_port(p->icom, fc_HardwareDTR, brt[i], parity_none, + if ((se = p->icom->set_ser_port(p->icom, fc_None, brt[i], parity_none, stop_1, length_8)) != ICOM_OK) { amutex_unlock(p->lock); a1logd(p->log, 5, "k10_init_coms: set_ser_port failed with 0x%x\n",se); @@ -872,8 +873,16 @@ kleink10 *p) { name[j] = buf[i + j]; if (((unsigned char *)name)[0] == 0xff) { +#ifdef TEST_FAKE_CALIBS + #pragma message("!!!!!!!!!!!!!!! Klein K10 TEST_FULL_CALIB set !!!!!!!!!!!!!!!!!!!") + sprintf(name, "Fake_%d",ix); +#else + //printf("Cal %d is 0xff - skipping\n",ix); continue; +#endif } + + /* Remove trailing spaces */ for (j = 19; j >= 0; j--) { if (name[j] != ' ') { name[j+1] = '\000'; @@ -881,7 +890,7 @@ kleink10 *p) { } } -// printf("Adding Cal %d is '%s'\n",ix,name); + // printf("Adding Cal %d is '%s'\n",ix,name); /* Add it to the list */ memset((void *)&k10_disptypesel[n], 0, sizeof(inst_disptypesel)); @@ -974,7 +983,7 @@ int usefast /* If nz use fast rate is possible */ #ifdef HIGH_SPEED /* This isn't reliable, because there is no way to ensure that */ /* the T1 command has been sent before we change the baud rate, */ - /* anf if we wait too long will will loose the measurements. */ + /* and if we wait too long we will loose the measurements. */ if (usefast && strcmp(p->firm_ver, "v01.09fh") > 0) { isnew = 1; /* We can use faster T1 command */ rate = 384; diff --git a/spectro/linear.cal b/spectro/linear.cal index 1dafbde..64b2392 100755 --- a/spectro/linear.cal +++ b/spectro/linear.cal @@ -2,7 +2,7 @@ CAL DESCRIPTOR "Argyll Device Calibration Curves" ORIGINATOR "Argyll synthcal" -CREATED "Fri Nov 17 01:11:11 2017" +CREATED "Mon Jul 09 03:30:52 2018" DEVICE_CLASS "DISPLAY" COLOR_REP "RGB" diff --git a/spectro/munki_imp.c b/spectro/munki_imp.c index d8690e8..f95140b 100755 --- a/spectro/munki_imp.c +++ b/spectro/munki_imp.c @@ -7886,9 +7886,9 @@ munki_code munki_conv2XYZ( double sms; /* Weighting */ if (s->emiss) - conv = new_xsp2cie(icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, (icxClamping)clamp); + conv = new_xsp2cie(icxIT_none, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, (icxClamping)clamp); else - conv = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, (icxClamping)clamp); + conv = new_xsp2cie(icxIT_D50, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, (icxClamping)clamp); if (conv == NULL) return MUNKI_INT_CIECONVFAIL; diff --git a/spectro/sa_conv.h b/spectro/sa_conv.h index 0f7e635..0d4718d 100755 --- a/spectro/sa_conv.h +++ b/spectro/sa_conv.h @@ -191,6 +191,10 @@ void sa_Yxy2XYZ(double *out, double *in); #define icmLab2XYZ sa_Lab2XYZ #define icmYxy2XYZ sa_Yxy2XYZ +/* Lpt isn't used by instlib, so dummy it out */ +#define icmXYZ2Lpt sa_XYZ2Lab +#define icmLpt2XYZ sa_Lab2XYZ + /* A helper object that computes MD5 checksums */ struct _sa_MD5 { /* Private: */ diff --git a/spectro/spec2cie.c b/spectro/spec2cie.c index 6c56e67..fd40c51 100755 --- a/spectro/spec2cie.c +++ b/spectro/spec2cie.c @@ -53,7 +53,7 @@ This is intended for conversion of reflective measurements to XYZ - there is no illuminant for emissive values. - L*a*b* is always D50. + L*a*b* is always D50, since it is intended for ICC profile construction. */ @@ -133,10 +133,10 @@ main(int argc, char *argv[]) int ci, mi, yi, ki; /* Indexes of device values */ int fwacomp = 0; /* FWA compensation */ int doplot = 0; /* Plot each patches spectrum */ - char* illum_str = "D50"; icxIllumeType tillum = icxIT_none; /* Target/simulated instrument illuminant, if set. */ xspect cust_tillum, *tillump = NULL; /* Custom target/simulated illumination spectrum */ /* if tillum == icxIT_custom */ + char* illum_str = "D50"; icxIllumeType illum = icxIT_none; /* CIE calc. illuminant spectrum, and FWA inst. */ /* illuminant if tillum not set. */ xspect cust_illum; /* Custom CIE illumination spectrum if illum == icxIT_custom */ @@ -149,6 +149,8 @@ main(int argc, char *argv[]) icxObserverType obType = icxOT_none; xspect custObserver[3]; /* Custom observer CMF's */ + icmXYZNumber ill_wp_XYZ; /* if ill_wp != NULL, same as ill_wp */ + int npat; /* Number of patches */ int ti; /* Field index */ char *kw; @@ -654,10 +656,11 @@ main(int argc, char *argv[]) int Xi, Yi, Zi, Li, ai, bi; /* CGATS indexes for each field */ int spi[XSPECT_MAX_BANDS]; /* CGATS indexes for each wavelength */ int oXi, oYi, oZi, oLi, oai, obi; /* CGATS indexes for each ouput field */ + int oL2i, oa2i, ob2i; /* For illuminant wp L*a*b* output */ xsp2cie *sp2cie; /* Spectral conversion object */ xspect sp; double XYZ[3]; - double Lab[3]; + double Lab[3], Lab2[3]; char buf[100]; /* These are only set if fwa is needed */ xspect rmwsp; /* Raw medium white spectrum */ @@ -710,6 +713,17 @@ main(int argc, char *argv[]) } + /* If CIE calculation illuminant is not standard, compute it's white point */ + if (illum != icxIT_D50 && illum != icxIT_none) { + ill_wp = _ill_wp; + + /* Compute normalised XYZ of illuminant */ + if (icx_ill_sp2XYZ(ill_wp, obType, custObserver, illum, 0.0, &cust_illum, 0) != 0) + error("icx_ill_sp2XYZ returned error"); + + icmAry2XYZ(ill_wp_XYZ, ill_wp); + } + /* copy fields to output file (except spectral if nospec) */ for (i = 0; i < icg->t[0].nfields; i++) { @@ -758,27 +772,51 @@ main(int argc, char *argv[]) oai = ai; obi = bi; - /* allocate elements */ + /* If non-standard illuminant is being used, add extra LAB fields */ + /* to show illuminant relative values (Not used for profiling!) */ + if (ill_wp != NULL) { + char buf[50] = { '\000' }, *cp; - if ((elems = (cgats_set_elem *) - calloc(ocg->t[0].nfields, sizeof(cgats_set_elem))) == NULL) - { - error("Out of memory"); - } + strncpy(buf, illum_str, 40); - /* If CIE calculation illuminant is not standard, compute it's white point */ - if (illum != icxIT_D50 && illum != icxIT_none) { - ill_wp = _ill_wp; + /* Replace spaces */ + for (cp = buf; *cp != '\000'; cp++) { + if (*cp == ' ') + *cp = '_'; + } + /* Remove extension */ + for (; cp >= buf; cp--) { + if (*cp == '.') { + *cp = '\000'; + break; + } + } + strcat(buf, "LAB"); + cp = buf + strlen(buf); + cp[0] = '_'; - /* Compute normalised XYZ of illuminant */ - if (icx_ill_sp2XYZ(ill_wp, obType, custObserver, illum, 0.0, &cust_illum, 0) != 0) - error("icx_ill_sp2XYZ returned error"); + cp[1] = 'L'; + if ((oL2i = ocg->add_field(ocg, 0, buf, r_t)) < 0) + error ("Cannot add field to table"); + + cp[1] = 'A'; + if ((oa2i = ocg->add_field(ocg, 0, buf, r_t)) < 0) + error ("Cannot add field to table"); + + cp[1] = 'B'; + if ((ob2i = ocg->add_field(ocg, 0, buf, r_t)) < 0) + error ("Cannot add field to table"); + } + + /* allocate elements */ + if ((elems = (cgats_set_elem *) + calloc(ocg->t[0].nfields, sizeof(cgats_set_elem))) == NULL) { + error("Out of memory"); } /* Create a spectral conversion object */ - if ((sp2cie = new_xsp2cie(illum, &cust_illum, obType, custObserver, - icSigXYZData, icxClamp)) == NULL) - { + if ((sp2cie = new_xsp2cie(illum, 0.0, &cust_illum, obType, custObserver, + icSigXYZData, icxClamp)) == NULL) { error ("Creation of spectral conversion object failed"); } @@ -921,14 +959,15 @@ main(int argc, char *argv[]) ocg->add_kword(ocg, 0, "ILLUMINANT_WHITE_POINT_XYZ",buf, NULL); } - /* Transform patches from spectral to CIE */ + /* Transform patches from spectral to CIE, */ + /* after correcting the spectrum for possible XRGA and FWA. */ for (i = 0; i < npat; i++) { - xspect corr_sp; /* copy all input colums to output (except spectral if nospec) */ for (jj = j = 0; j < icg->t[0].nfields; j++) { if (nospec) { + /* See if this is a spectral field */ for (k = 0; nospec && k < sp.spec_n; k++) { if (spi[k] == j) @@ -963,39 +1002,27 @@ main(int argc, char *argv[]) } /* Read the spectral values for this patch */ - for (j = 0; j < sp.spec_n; j++) { + for (j = 0; j < sp.spec_n; j++) sp.spec[j] = *((double *)icg->t[0].fdata[i][spi[j]]); - } + if (calstdo != xcalstd_none) xspec_convert_xrga(&sp, &sp, calpol, calstdo, calstdi); + /* Convert it to CIE space */ if (fwacomp) { - corr_sp = sp; /* Copy spectrum */ - - /* Convert it to CIE space */ - sp2cie->sconvert (sp2cie, &corr_sp, XYZ, &sp); - - /* Write the corrected spectral values for this patch */ - if (nospec == 0) { - for (j = 0; j < sp.spec_n; j++) { - elems[spi[j]].d = sp.spec[j] = corr_sp.spec[j]; - } - } + sp2cie->sconvert(sp2cie, &sp, XYZ, &sp); + } else { + sp2cie->convert(sp2cie, XYZ, &sp); } - /* No FWA comp */ - else { - /* Convert it to CIE space */ - sp2cie->convert (sp2cie, XYZ, &sp); + /* Standard pseudo-absolute D50 ICC Lab */ + icmXYZ2Lab(&icmD50, Lab, XYZ); + /* Illuminant relative Lab */ + if (ill_wp != NULL) { + icmXYZ2Lab(&ill_wp_XYZ, Lab2, XYZ); } - /* Could use sp2cie->get_cie_il() to get CIE white point */ - /* if we wanted to return L*a*b* relative to that. */ - /* We would have to mark that in the .ti3 though. */ - /* This won't work for emmisive though, since get_cie_il() will return 'E' */ - icmXYZ2Lab(&icmD50, Lab, XYZ); - #ifdef ALLOW_PLOT if (doplot) { int ii; @@ -1018,14 +1045,28 @@ main(int argc, char *argv[]) do_plot(xx,y1,NULL,NULL,ii); } #endif + /* Write the corrected spectral values for this patch */ + if (nospec == 0 + && (calstdo != xcalstd_none || fwacomp)) { + for (j = 0; j < sp.spec_n; j++) { + elems[spi[j]].d = sp.spec[j]; + } + } + elems[oXi].d = XYZ[0] * 100.0; elems[oYi].d = XYZ[1] * 100.0; elems[oZi].d = XYZ[2] * 100.0; - + elems[oLi].d = Lab[0]; elems[oai].d = Lab[1]; elems[obi].d = Lab[2]; + if (ill_wp != NULL) { + elems[oL2i].d = Lab2[0]; + elems[oa2i].d = Lab2[1]; + elems[ob2i].d = Lab2[2]; + } + ocg->add_setarr(ocg, 0, elems); } diff --git a/spectro/specbos.c b/spectro/specbos.c index 136fb34..6d2d5c0 100755 --- a/spectro/specbos.c +++ b/spectro/specbos.c @@ -383,11 +383,9 @@ specbos_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { if (dispen) { p->model = 1511; - /* Set remote mode */ + /* Set remote mode (for old firmare) */ if ((ev = specbos_command(p, "*REMOTE 1\r", buf, MAX_MES_SIZE, 1.0)) != inst_ok) { - amutex_unlock(p->lock); - a1logd(p->log, 2, "specbos_init_coms: failed to set remote mode\n"); - return inst_protocol_error; + a1logd(p->log, 2, "specbos_init_coms: remote command failed (newer firmware ?)\n"); } } @@ -579,6 +577,9 @@ specbos_init_inst(inst *pp) { } } + /* Set target maximum measure time (no averaging) */ + /* (We will then setup instrument to compy with this target) */ + /* 3.6 is the assumed maximum fixed overhead */ p->measto = 20.0; /* Set default. Specbos default is 60.0 */ if (p->model == 1211) @@ -624,10 +625,11 @@ specbos_init_inst(inst *pp) { return ev; } #else /* Bound auto by no. averages (better - limit maxint to 1.0) */ - double dmaxtint = 1.0; /* Recommended maximum */ + double dmaxtint = 1.0; /* Recommended maximum is 1.0 */ int maxtint; int maxaver; /* Maximum averages for auto int time */ + /* Set the max integration time to 1.0 seconds: */ maxtint = (int)(dmaxtint * 1000.0+0.5); if (maxtint < 1000 || maxtint > 64999) { @@ -638,23 +640,24 @@ specbos_init_inst(inst *pp) { maxtint = 64999; } - /* Set maximum integration time */ sprintf(mes, "*para:maxtint %d\r", maxtint); if ((ev = specbos_command(p, mes, buf, MAX_MES_SIZE, 1.0)) != inst_ok) { amutex_unlock(p->lock); return ev; } + /* Then compute the maximum number of measurements to meet measto: */ + /* Total time = overhead + initial sample + 2 * int time per measure */ maxaver = (int)ceil((p->measto - 3.6)/(2.0 * dmaxtint)); - //printf("maxaver %d\n",maxaver); - if (maxaver < 2) { warning("specbos: assert, maxaver %d out of range",maxaver); maxaver = 2; } + a1logd(p->log, 6, "specbos_init_inst: set maxaver %d\n",maxaver); + /* Set maximum number of auto averages. Min value is 2 */ sprintf(mes, "*para:maxaver %d\r", maxaver); if ((ev = specbos_command(p, mes, buf, MAX_MES_SIZE, 1.0)) != inst_ok) { @@ -679,16 +682,25 @@ specbos_init_inst(inst *pp) { warning("specbos: assert, maxtint %d out of range",maxtin); if (maxtin < 1000) maxtin = 1000; - else if (maxtin > 64999) - maxtin = 64999; + else if (maxtin > 60000) /* 60 secs according to auxiliary doco. */ + maxtin = 60000; } - /* Set maximum integration time */ - /* (1201 *para:maxtint doesn't work !!) */ + /* Set maximum integration time that auto will use */ sprintf(mes, "*conf:maxtin %d\r", maxtin); if ((ev = specbos_command(p, mes, buf, MAX_MES_SIZE, 1.0)) != inst_ok) { - amutex_unlock(p->lock); - return ev; + /* 1201 Firmware V1.8.3 and earlier doesn't support maxtin. */ + /* Ignore error with a warning. */ + if (p->model == 1201) { + if (!p->maxtin_warn) + warning("specbos: conf:maxtin %d command failed (Old Firmware ?)",maxtin); + p->maxtin_warn = 1; + + /* Fatal error otherwise */ + } else { + amutex_unlock(p->lock); + return ev; + } } #ifdef NEVER /* Use default */ @@ -972,6 +984,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */ int user_trig = 0; int pos = -1; inst_code rv = inst_protocol_error; + double measto = p->measto; if (!p->gotcoms) return inst_no_coms; @@ -1062,10 +1075,21 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */ if ((rv = set_average(p, p->noaverage, 0)) != inst_ok) return rv; + /* Adjust timeout to account for averaging */ + /* (Allow extra 1 sec fudge factor per average) */ + if (p->noaverage > 1) { + measto = p->noaverage * (p->measto - 3.6 + 1.0) + 3.6; + a1logd(p->log, 6, " Adjusted measto to %f for noaver %d\n",measto,p->noaverage); + } + /* Set to average 10 readings for transmission */ } else if ((p->mode & inst_mode_illum_mask) == inst_mode_transmission) { if ((rv = set_average(p, DEFAULT_TRANS_NAV, 0)) != inst_ok) return rv; + + measto = DEFAULT_TRANS_NAV * (p->measto - 3.6 + 1.0) + 3.6; + a1logd(p->log, 6, " Adjusted measto to %f for noaver %d\n",measto,DEFAULT_TRANS_NAV); + /* Or default 1 otherwise */ } else { if ((rv = set_average(p, DEFAULT_NAV, 0)) != inst_ok) @@ -1080,12 +1104,12 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */ } } - /* Trigger a measurement */ + /* Trigger a measurement (Allow 10 second timeout margine) */ /* (Note that ESC will abort it) */ if (p->model == 1501 || p->model == 1511) - ec = specbos_fcommand(p, "*meas:refer\r", buf, MAX_MES_SIZE, p->measto + 10.0 , 1, tmeas, 0); + ec = specbos_fcommand(p, "*meas:refer\r", buf, MAX_MES_SIZE, measto + 10.0 , 1, tmeas, 0); else - ec = specbos_fcommand(p, "*init\r", buf, MAX_MES_SIZE, p->measto + 10.0 , 1, tmeas, 0); + ec = specbos_fcommand(p, "*init\r", buf, MAX_MES_SIZE, measto + 10.0 , 1, tmeas, 0); // Test out bug workaround // if (!p->badCal) ec = SPECBOS_EXCEED_CAL_WL; @@ -1118,9 +1142,9 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */ /* Try command again */ if (p->model == 1501 || p->model == 1511) - ec = specbos_fcommand(p, "*meas:refer\r", buf, MAX_MES_SIZE, p->measto + 10.0 , 1, tmeas, 0); + ec = specbos_fcommand(p, "*meas:refer\r", buf, MAX_MES_SIZE, measto + 10.0 , 1, tmeas, 0); else - ec = specbos_fcommand(p, "*init\r", buf, MAX_MES_SIZE, p->measto + 10.0 , 1, tmeas, 0); + ec = specbos_fcommand(p, "*init\r", buf, MAX_MES_SIZE, measto + 10.0 , 1, tmeas, 0); } /* Restore single reading if transmission */ @@ -1405,7 +1429,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */ /* Convert to XYZ */ if (p->conv == NULL) { - p->conv = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, + p->conv = new_xsp2cie(icxIT_D50, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, icxNoClamp); if (p->conv == NULL) { a1logd(p->log, 1, "specbos_read_sample: Emulated transmission new_xsp2cie() failed"); diff --git a/spectro/specbos.h b/spectro/specbos.h index ef6fc2f..4ef4a88 100755 --- a/spectro/specbos.h +++ b/spectro/specbos.h @@ -150,7 +150,7 @@ struct _specbos { inst_opt_type trig; /* Reading trigger mode */ - double measto; /* Expected measurement timeout value */ + double measto; /* Measurement maximum time target value */ int nbands; /* Number of spectral bands */ double wl_short; double wl_long; @@ -169,6 +169,8 @@ struct _specbos { int dpos; /* Diffuser position, 0 = emissive, 1 = ambient */ int laser; /* Target laser state, nz = on */ + int maxtin_warn; /* NZ if conf:maxtin failure warning has been given */ + }; typedef struct _specbos specbos; /* Constructor */ diff --git a/spectro/spotread.c b/spectro/spotread.c index 16f6f2d..1b4189b 100755 --- a/spectro/spotread.c +++ b/spectro/spotread.c @@ -21,6 +21,8 @@ /* TTBD * + * Add option to automatically read continuously, until stopped. (A bit like -O) + * Make -V average the spectrum too (if present), and allow it to * be saved to a .sp file. * @@ -45,19 +47,19 @@ #include #include #ifndef SALONEINSTLIB -#include "copyright.h" -#include "aconfig.h" -#include "numlib.h" -#include "cgats.h" -#include "xicc.h" -#include "conv.h" -#include "plot.h" -#include "ui.h" +# include "copyright.h" +# include "aconfig.h" +# include "numlib.h" +# include "cgats.h" +# include "xicc.h" +# include "conv.h" +# include "plot.h" +# include "ui.h" #else /* SALONEINSTLIB */ -#include "sa_config.h" -#include "numsup.h" -#include "xspect.h" -#include "conv.h" +# include "sa_config.h" +# include "numsup.h" +# include "xspect.h" +# include "conv.h" #endif /* SALONEINSTLIB */ #include "inst.h" #include "icoms.h" @@ -252,7 +254,7 @@ static inst_code uicallback(void *cntx, inst_ui_purp purp) { ABCDEFGHIJKLMNOPQRSTUVWXYZ upper ... . . .. . .. ... - lower . .... .. . .. . .. + lower . .... .. . .. .... */ @@ -332,6 +334,9 @@ usage(char *diag, ...) { fprintf(stderr," u U.V. Cut\n"); fprintf(stderr," -E extrafilterfile Apply extra filter compensation file\n"); fprintf(stderr," -A N|A|X|G XRGA conversion (default N)\n"); +#ifndef SALONEINSTLIB + fprintf(stderr," -w Use -i param. illuminant for comuting L*a*b*\n"); +#endif fprintf(stderr," -x Display Yxy instead of Lab\n"); fprintf(stderr," -h Display LCh instead of Lab\n"); #ifndef SALONEINSTLIB @@ -413,7 +418,7 @@ int main(int argc, char *argv[]) { icompaths *icmps = NULL; int comport = COMPORT; /* COM port used */ icompath *ipath = NULL; - int dtype = 0; /* Display type selection charater */ + int ditype = 0; /* Display type selection character(s) */ inst_mode cap = inst_mode_none; /* Instrument mode capabilities */ inst2_capability cap2 = inst2_none; /* Instrument capabilities 2 */ inst3_capability cap3 = inst3_none; /* Instrument capabilities 3 */ @@ -430,7 +435,10 @@ int main(int argc, char *argv[]) { int illum_set = 0; /* User asked for custom illuminant spectrum */ icxIllumeType illum = icxIT_D50; /* Spectral defaults */ xspect cust_illum; /* Custom illumination spectrum */ - icxObserverType obType = icxOT_default; + int labwpillum = 0; /* nz to use illum WP for L*a*b* conversion */ + icmXYZNumber labwp = { icmD50_100.X, icmD50_100.Y, icmD50_100.Z }; /* Lab conversion wp */ + char labwpname[100] = "D50"; /* Name of Lab conversion wp */ + icxObserverType obType = icxOT_default; /* Default is 1931_2 */ xspect custObserver[3]; /* If obType = icxOT_custom */ xspect sp; /* Last spectrum read */ xspect rsp; /* Reference spectrum */ @@ -519,7 +527,9 @@ int main(int argc, char *argv[]) { } else if (argv[fa][1] == 'y') { fa = nfa; if (na == NULL) usage("Paramater expected following -y"); - dtype = na[0]; + ditype = na[0]; + if (ditype == '_' && na[1] != '\000') + ditype = ditype << 8 | na[1]; #ifndef SALONEINSTLIB /* Simulated instrument illumination (FWA) */ @@ -620,6 +630,12 @@ int main(int argc, char *argv[]) { usage("Unrecognised illuminant '%s'",na); #endif /* SALONEINSTLIB */ +#ifndef SALONEINSTLIB + /* Use -i illuminant for L*a*b* conversion */ + } else if (argv[fa][1] == 'w') { + labwpillum = 1; +#endif /* !SALONEINSTLIB */ + /* Spectral Observer type */ } else if (argv[fa][1] == 'Q') { fa = nfa; @@ -901,11 +917,29 @@ int main(int argc, char *argv[]) { } /* Check for some user mistakes */ - - if ((tillum_set || illum_set) && emiss) + if ((tillum_set || illum_set) && emiss ) warning("-I or -i parameter makes no sense with emissive or ambient measurement!"); + if (illum_set && labwpillum && emiss) { + warning("-w for emissive is ignored!"); + labwpillum = 0; + } + /* - - - - - - - - - - - - - - - - - - - */ + /* Setup Lab conversion wp if not D50 */ + if (illum_set && labwpillum && !emiss) { + double xyz[3]; + + strcpy(labwpname, standardIlluminant_name(illum, 0.0)); + + if (icx_ill_sp2XYZ(xyz, obType, custObserver, illum, 0.0, &cust_illum, 0)) + error("Looking up W.P. of illuminant failed"); + + icmScale3(xyz, xyz, 100.0); + icmAry2XYZ(labwp, xyz); + + } + if ((icmps = new_icompaths(g_log)) == NULL) error("Finding instrument paths failed"); if ((ipath = icmps->get_path(icmps, comport)) == NULL) @@ -1204,12 +1238,12 @@ int main(int argc, char *argv[]) { } /* Set displaytype or calibration mode */ - if (dtype != 0) { + if (ditype != 0) { if (cap2 & inst2_disptype) { int ix; - if ((ix = inst_get_disptype_index(it, dtype, 0)) < 0) { + if ((ix = inst_get_disptype_index(it, ditype, 0)) < 0) { it->del(it); - usage("Failed to locate display type matching '%c'",dtype); + usage("Failed to locate display type matching '%s'",inst_distr(ditype)); } if ((rv = it->set_disptype(it, ix)) != inst_ok) { @@ -1547,7 +1581,7 @@ int main(int argc, char *argv[]) { illum = icxIT_none; /* Create a spectral conversion object */ - if ((sp2cie = new_xsp2cie(illum, &cust_illum, obType, custObserver, icSigXYZData, + if ((sp2cie = new_xsp2cie(illum, 0.0, &cust_illum, obType, custObserver, icSigXYZData, refstats ? icxNoClamp : icxClamp)) == NULL) error("Creation of spectral conversion object failed"); @@ -1593,9 +1627,9 @@ int main(int argc, char *argv[]) { for (j = 0; j < 3; j++) rXYZ[j] *= 100.0; /* 0..100 scale */ } - icmXYZ2Lab(&icmD50_100, rLab, rXYZ); + icmXYZ2Lab(&labwp, rLab, rXYZ); if (verb) - printf("Preset ref. XYZ %f %f %f, Lab %f %f %f\n", rXYZ[0], rXYZ[1], rXYZ[2], rLab[0], rLab[1], rLab[2]); + printf("Preset ref. XYZ %f %f %f, %s Lab %f %f %f\n", rXYZ[0], rXYZ[1], rXYZ[2], labwpname, rLab[0], rLab[1], rLab[2]); } #endif @@ -2315,7 +2349,7 @@ int main(int argc, char *argv[]) { /* Creat the base conversion object */ if (sp2cief[fidx] == NULL) { - if ((sp2cief[fidx] = new_xsp2cie(illum, &cust_illum, obType, + if ((sp2cief[fidx] = new_xsp2cie(illum, 0.0, &cust_illum, obType, custObserver, icSigXYZData, refstats ? icxNoClamp : icxClamp)) == NULL) error("Creation of spectral conversion object failed"); } @@ -2520,8 +2554,8 @@ int main(int argc, char *argv[]) { vdt_sn = -1.0; } - /* Compute D50 Lab from XYZ */ - icmXYZ2Lab(&icmD50_100, Lab, XYZ); + /* Compute D50 (or other) Lab from XYZ */ + icmXYZ2Lab(&labwp, Lab, XYZ); /* Compute Yxy from XYZ */ icmXYZ2Yxy(Yxy, XYZ); @@ -2529,7 +2563,7 @@ int main(int argc, char *argv[]) { /* Compute LCh from Lab */ icmLab2LCh(LCh, Lab); - /* Compute D50 Yuv from XYZ */ + /* Compute Yuv from XYZ */ icmXYZ21976UCS(Yuv, XYZ); #else /* SALONEINSTLIB */ @@ -2547,8 +2581,8 @@ int main(int argc, char *argv[]) { if (wXYZ[0] < 0.0) { /* If we haven't save a white ref. yet */ if (XYZ[1] < 10.0) error ("White of XYZ %f %f %f doesn't seem reasonable",XYZ[0], XYZ[1], XYZ[2]); - printf("\n Making result XYZ: %f %f %f, D50 Lab: %f %f %f white reference.\n", - XYZ[0], XYZ[1], XYZ[2], Lab[0], Lab[1], Lab[2]); + printf("\n Making result XYZ: %f %f %f, %s Lab: %f %f %f white reference.\n", + XYZ[0], XYZ[1], XYZ[2], labwpname, Lab[0], Lab[1], Lab[2]); wXYZ[0] = XYZ[0]; wXYZ[1] = XYZ[1]; wXYZ[2] = XYZ[2]; @@ -2576,7 +2610,7 @@ int main(int argc, char *argv[]) { } /* recompute Lab */ - icmXYZ2Lab(&icmD50_100, Lab, XYZ); + icmXYZ2Lab(&labwp, Lab, XYZ); /* recompute Yxy from XYZ */ icmXYZ2Yxy(Yxy, XYZ); @@ -2625,8 +2659,8 @@ int main(int argc, char *argv[]) { #endif } else { /* Print out the XYZ and Lab */ - printf("\n Result is XYZ: %f %f %f, D50 Lab: %f %f %f\n", - XYZ[0], XYZ[1], XYZ[2], Lab[0], Lab[1], Lab[2]); + printf("\n Result is XYZ: %f %f %f, %s Lab: %f %f %f\n", + XYZ[0], XYZ[1], XYZ[2], labwpname, Lab[0], Lab[1], Lab[2]); } } diff --git a/spectro/spyd2.c b/spectro/spyd2.c index 28051f3..539c2c0 100755 --- a/spectro/spyd2.c +++ b/spectro/spyd2.c @@ -2146,7 +2146,7 @@ spyd4_comp_calmat( } /* Compute XYZ of the real sample array. */ - if ((conv = new_xsp2cie(icxIT_none, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL) + if ((conv = new_xsp2cie(icxIT_none, 0.0, NULL, obType, custObserver, icSigXYZData, icxClamp)) == NULL) return spyd2_interp_code((inst *)p, SPYD2_INT_CIECONVFAIL); sampXYZ = dmatrix(0, nasamp-1, 0, 3-1); for (i = 0; i < nsamp; i++) { diff --git a/spectro/ss.c b/spectro/ss.c index 4f95fdb..7e67fbe 100755 --- a/spectro/ss.c +++ b/spectro/ss.c @@ -54,10 +54,11 @@ You should be able to use the table enter key anywhere the user is asked to hit a key. - The corner positioning could be smarter. + The corner positioning could be smarter (i.e. move to the anticipated corned + automatically). The SpectroscanT transmission cal. merely reminds the user (via verbose) - that it is assuming the correct apatture, rather than given them + that it is assuming the correct apature, rather than given them a chance to change it. */ diff --git a/spectro/ss_imp.c b/spectro/ss_imp.c index 0de14ea..bfe7e25 100755 --- a/spectro/ss_imp.c +++ b/spectro/ss_imp.c @@ -1497,8 +1497,8 @@ ss_tmt tm /* Table mode (Reflectance/Transmission) */ inst_code ss_do_SetDeviceOnline(ss *p) { #ifdef EMSST if (p->tmode != 0) - *((char *)0) = 55; -// return inst_unsupported; +// *((char *)0) = 55; // Trigger backtrace + return inst_unsupported; #endif ss_add_ssreq(p, ss_SetDeviceOnline); ss_command(p, DF_TMO); @@ -1514,7 +1514,8 @@ inst_code ss_do_SetDeviceOnline(ss *p) { inst_code ss_do_SetDeviceOffline(ss *p) { #ifdef EMSST if (p->tmode != 0) - *((char *)0) = 55; +// *((char *)0) = 55; // Trigger backtrace + return inst_unsupported; #endif ss_add_ssreq(p, ss_SetDeviceOffline); ss_command(p, DF_TMO); @@ -1559,7 +1560,8 @@ double y /* Y coord in mm, 0-230.0, accurate to 0.1mm */ ) { #ifdef EMSST if (p->tmode != 0) - *((char *)0) = 55; +// *((char *)0) = 55; // Trigger backtrace + return inst_unsupported; #endif ss_add_ssreq(p, ss_MoveAbsolut); ss_add_1(p, r); @@ -1581,7 +1583,8 @@ double y /* Y distance in mm, 0-230.0, accurate to 0.1mm */ ) { #ifdef EMSST if (p->tmode != 0) - *((char *)0) = 55; +// *((char *)0) = 55; // Trigger backtrace + return inst_unsupported; #endif ss_add_ssreq(p, ss_MoveRelative); ss_add_2(p, (int)(x * 10 + 0.5)); @@ -1600,7 +1603,8 @@ ss *p ) { #ifdef EMSST if (p->tmode != 0) - *((char *)0) = 55; +// *((char *)0) = 55; // Trigger backtrace + return inst_unsupported; #endif ss_add_ssreq(p, ss_MoveHome); ss_command(p, MV_TMO); @@ -1617,7 +1621,8 @@ ss *p ) { #ifdef EMSST if (p->tmode != 0) - *((char *)0) = 55; +// *((char *)0) = 55; // Trigger backtrace + return inst_unsupported; #endif ss_add_ssreq(p, ss_MoveUp); ss_command(p, MV_TMO); @@ -1634,7 +1639,8 @@ ss *p ) { #ifdef EMSST if (p->tmode != 0) - *((char *)0) = 55; +// *((char *)0) = 55; // Trigger backtrace + return inst_unsupported; #endif ss_add_ssreq(p, ss_MoveDown); ss_command(p, MV_TMO); @@ -1656,7 +1662,8 @@ ss_zkt *zk /* Return the Z coordinate (Up/Down) */ ) { #ifdef EMSST if (p->tmode != 0) - *((char *)0) = 55; +// *((char *)0) = 55; // Trigger backtrace + return inst_unsupported; #endif ss_add_ssreq(p, ss_OutputActualPosition); ss_add_1(p, r); @@ -1680,7 +1687,8 @@ ss_wrpt wrp /* White Reference Position (Tile1/Tile2) */ ) { #ifdef EMSST if (p->tmode != 0) - *((char *)0) = 55; +// *((char *)0) = 55; // Trigger backtrace + return inst_unsupported; #endif ss_add_ssreq(p, ss_MoveToWhiteRefPos); ss_add_1(p, wrp); @@ -1749,7 +1757,8 @@ ss_llt ll /* Transmission light level (Off/Surround/Low) */ if (p->tmode != 0) return inst_ok; else - *((char *)0) = 55; +// *((char *)0) = 55; // Trigger backtrace + return inst_unsupported; #endif ss_add_ssreq(p, ss_SetLightLevel); ss_add_1(p, ll); @@ -1775,7 +1784,8 @@ double y /* Y coord in mm, 0-230.0, accurate to 0.1mm */ p->sby = y; return inst_ok; } else { - *((char *)0) = 55; +// *((char *)0) = 55; // Trigger backtrace + return inst_unsupported; } #endif ss_add_ssreq(p, ss_SetTransmStandbyPos); diff --git a/spectro/strange.cal b/spectro/strange.cal index b31bbed..5f4d4b4 100755 --- a/spectro/strange.cal +++ b/spectro/strange.cal @@ -2,7 +2,7 @@ CAL DESCRIPTOR "Argyll Device Calibration Curves" ORIGINATOR "Argyll synthcal" -CREATED "Fri Nov 17 01:11:11 2017" +CREATED "Mon Jul 09 03:30:52 2018" DEVICE_CLASS "DISPLAY" COLOR_REP "RGB" diff --git a/spectro/vtpglut.c b/spectro/vtpglut.c index 2308466..b558bf4 100755 --- a/spectro/vtpglut.c +++ b/spectro/vtpglut.c @@ -14,6 +14,16 @@ * see the License2.txt file for licencing details. */ +/* + TTBD: + + Note that there is some support for HW 3dLUTs in X11 xrandr + in a patch for xf86-videeo-amdgpu drmmode_display.c + submitted on 3 May 2018. + See + +*/ + #include #include #include diff --git a/spectro/xrga.c b/spectro/xrga.c index 7318fce..d481b6a 100755 --- a/spectro/xrga.c +++ b/spectro/xrga.c @@ -160,23 +160,20 @@ void xspec_convert_xrga(xspect *dst, xspect *srcp, xcalpol pol, xcalstd dsp, xca xspect tmp, *src = srcp; /* If no conversion and no copy needed */ - if ((ssp == xcalstd_native || dsp == xcalstd_native || dsp == ssp) - && dst == src) + if (!XCALSTD_NEEDED(ssp, dsp) && dst == src) return; - /* If no conversion needed */ - if (ssp == xcalstd_native || dsp == xcalstd_native || dsp == ssp) { + /* If no conversion needed */ + if (!XCALSTD_NEEDED(ssp, dsp)) { *dst = *src; /* Struct copy */ return; } - /* If the dest is the same as the src, make a temporary copy */ + /* If the dest is the same as the src, make a temporary copy, */ + /* since convert_xrga() needs them to be distinct */ if (dst == src) { tmp = *src; /* Struct copy */ src = &tmp; - - } else { - XSPECT_COPY_INFO(dst, src); /* Copy parameters */ } eq = &xrga_equations[pol][ssp][dsp]; @@ -210,7 +207,7 @@ void ipatch_convert_xrga(ipatch *vals, int nvals, /* Re-compute XYZ */ if (vals[i].XYZ_v) { if (conv == NULL) { - conv = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2, + conv = new_xsp2cie(icxIT_D50, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, (icxClamping)clamp); } conv->convert(conv, vals[i].XYZ, &vals[i].sp); diff --git a/target/ofps.c b/target/ofps.c index 54a0ea1..d965097 100755 --- a/target/ofps.c +++ b/target/ofps.c @@ -128,6 +128,7 @@ #if defined(__IBMC__) #include #endif +#include "aconfig.h" #include "numlib.h" #include "sort.h" #include "counters.h" diff --git a/target/prand.c b/target/prand.c index 7ce5760..7040373 100755 --- a/target/prand.c +++ b/target/prand.c @@ -26,6 +26,7 @@ #if defined(__IBMC__) #include #endif +#include "aconfig.h" #include "numlib.h" #include "sort.h" #include "icc.h" diff --git a/target/targen.c b/target/targen.c index 96cda6c..ee12243 100755 --- a/target/targen.c +++ b/target/targen.c @@ -18,6 +18,8 @@ /* TTBD: + Should add option to create just surface test patches. + Should add an option to generate grey and near grey or other PCS based pattern test points based on the previous profile. How about an option to read in an CGATS file containing diff --git a/tweak/refine.c b/tweak/refine.c index c9e16bd..6415874 100755 --- a/tweak/refine.c +++ b/tweak/refine.c @@ -671,7 +671,7 @@ main(int argc, char *argv[]) { } /* Create a spectral conversion object */ - if ((sp2cie = new_xsp2cie(illum, illum == icxIT_none ? NULL : &cust_illum, + if ((sp2cie = new_xsp2cie(illum, 0.0, illum == icxIT_none ? NULL : &cust_illum, obType, custObserver, icSigLabData, icxClamp)) == NULL) error("Creation of spectral conversion object failed"); diff --git a/usb/ArgyllCMS.cat b/usb/ArgyllCMS.cat index d905b40..e0a2d35 100755 Binary files a/usb/ArgyllCMS.cat and b/usb/ArgyllCMS.cat differ diff --git a/usb/ArgyllCMS_x64.cat b/usb/ArgyllCMS_x64.cat index f734475..e3c213f 100755 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 ddd6066..2dad1a6 100755 --- a/xicc/bt1886.c +++ b/xicc/bt1886.c @@ -12,7 +12,7 @@ * */ -/* BT.1886 stype input offset transfer curve, */ +/* BT.1886 type input offset transfer curve, */ /* + general gamma + input + output offset curve support. */ #include diff --git a/xicc/bt1886.h b/xicc/bt1886.h index f14efdc..b0399c9 100755 --- a/xicc/bt1886.h +++ b/xicc/bt1886.h @@ -14,10 +14,9 @@ * */ -/* BT.1886 stype input offset transfer curve, */ +/* BT.1886 type input offset transfer curve, */ /* + general gamma + input + output offset curve support. */ - typedef struct { icmXYZNumber w; /* White point for Lab conversion */ double ingo; /* input Y offset for bt1886 */ diff --git a/xicc/ccmx.c b/xicc/ccmx.c index 7206f31..7a004d9 100755 --- a/xicc/ccmx.c +++ b/xicc/ccmx.c @@ -277,13 +277,6 @@ cgats *icg /* input cgats structure */ } } - if ((ti = icg->find_kword(icg, 0, "OEM")) >= 0) { - if ((p->ref = strdup(icg->t[0].kdata[ti])) == NULL) { - sprintf(p->err, "read_ccmx: malloc failed"); - return 2; - } - } - if ((ti = icg->find_kword(icg, 0, "OEM")) >= 0) { if (stricmp(icg->t[0].kdata[ti], "YES") == 0) p->oem = 1; diff --git a/xicc/ccss.c b/xicc/ccss.c index aae278e..b561b7b 100755 --- a/xicc/ccss.c +++ b/xicc/ccss.c @@ -29,12 +29,14 @@ #include #include #include +# include "aconfig.h" #ifndef SALONEINSTLIB -#include "numlib.h" -#include "icc.h" +# include "numlib.h" +# include "icc.h" +# include "plot.h" /* For debugging */ #else -#include "numsup.h" -#include "sa_conv.h" +# include "numsup.h" +# include "sa_conv.h" #endif #include "cgats.h" #include "xspect.h" diff --git a/xicc/ccttest.c b/xicc/ccttest.c index f7f4363..d9c480b 100755 --- a/xicc/ccttest.c +++ b/xicc/ccttest.c @@ -20,6 +20,7 @@ #include #include +#include "aconfig.h" #include "cgats.h" #include "xspect.h" #include "numlib.h" diff --git a/xicc/cgatsplot.c b/xicc/cgatsplot.c index bb598fc..a3315dd 100755 --- a/xicc/cgatsplot.c +++ b/xicc/cgatsplot.c @@ -20,6 +20,7 @@ #include #include #include +#include "aconfig.h" #include "numlib.h" #include "icc.h" #include "cgats.h" diff --git a/xicc/cv.c b/xicc/cv.c index 7cd7927..a61ef96 100755 --- a/xicc/cv.c +++ b/xicc/cv.c @@ -16,6 +16,7 @@ #include #include #include +#include "aconfig.h" #include "plot.h" #include "ui.h" diff --git a/xicc/cvtest.c b/xicc/cvtest.c index a9fa59f..3520933 100755 --- a/xicc/cvtest.c +++ b/xicc/cvtest.c @@ -25,6 +25,7 @@ #if defined(__IBMC__) && defined(_M_IX86) #include #endif +#include "aconfig.h" #include "numlib.h" #include "plot.h" #include "ui.h" diff --git a/xicc/mpp.c b/xicc/mpp.c index 86b6c30..4164021 100755 --- a/xicc/mpp.c +++ b/xicc/mpp.c @@ -113,6 +113,7 @@ #if defined(__IBMC__) && defined(_M_IX86) #include #endif +#include "aconfig.h" #include "numlib.h" #include "cgats.h" #include "icc.h" @@ -123,8 +124,9 @@ #include "gamut.h" #include "mpp.h" #ifdef DOPLOT -#include "plot.h" -#endif /* DOPLOT */ +# include "plot.h" +# include "ui.h" +#endif /* Forward declarations */ static double bandval(mpp *p, int band, double *dev); @@ -715,7 +717,7 @@ int use_fwa /* NZ to involke FWA. */ custIllum = NULL; } - if ((p->spc = new_xsp2cie(ilType, custIllum, obType, custObserver, rcs, 1)) == NULL) + if ((p->spc = new_xsp2cie(ilType, 0.0, custIllum, obType, custObserver, rcs, 1)) == NULL) error("mpp->set_ilob, new_xsp2cie failed"); if (use_fwa) { diff --git a/xicc/mpplu.c b/xicc/mpplu.c index ecc67b0..bcf09bf 100755 --- a/xicc/mpplu.c +++ b/xicc/mpplu.c @@ -23,6 +23,7 @@ #include #include #include +#include "aconfig.h" #include "numlib.h" #include "xicc.h" #include "counters.h" diff --git a/xicc/specplot.c b/xicc/specplot.c index de819ed..ead2066 100755 --- a/xicc/specplot.c +++ b/xicc/specplot.c @@ -21,6 +21,7 @@ #include #include +#include "aconfig.h" #include "cgats.h" #include "xspect.h" #include "numlib.h" diff --git a/xicc/specsubsamp.c b/xicc/specsubsamp.c index 1d6bbde..616b7ad 100755 --- a/xicc/specsubsamp.c +++ b/xicc/specsubsamp.c @@ -19,6 +19,7 @@ #include #include +#include "aconfig.h" #include "cgats.h" #include "xspect.h" #include "numlib.h" diff --git a/xicc/spectest.c b/xicc/spectest.c index 0bcc716..86c95a8 100755 --- a/xicc/spectest.c +++ b/xicc/spectest.c @@ -29,12 +29,13 @@ #include #include +#include "aconfig.h" +#include "numlib.h" #include "cgats.h" #include "xspect.h" -#include "numlib.h" #ifdef DOPLOT -#include "plot.h" -#include "ui.h" +# include "plot.h" +# include "ui.h" #endif @@ -631,11 +632,11 @@ main(void) { standardIlluminant(&sill, matilum[m][ss].ill, 0); /* Instrument */ /* Create two conversions for the target/check illuminant */ - if ((pcon = new_xsp2cie(icxIT_custom, &pill, icxOT_Shaw_Fairchild_2, + if ((pcon = new_xsp2cie(icxIT_custom, 0.0, &pill, icxOT_Shaw_Fairchild_2, NULL, icSigLabData, 1)) == NULL) error ("Creating conversion failed"); - if ((scon = new_xsp2cie(icxIT_custom, &pill, icxOT_Shaw_Fairchild_2, + if ((scon = new_xsp2cie(icxIT_custom, 0.0, &pill, icxOT_Shaw_Fairchild_2, NULL, icSigLabData, 1)) == NULL) error ("Creating conversion failed"); diff --git a/xicc/spectest2.c b/xicc/spectest2.c index a1c338d..81832a4 100755 --- a/xicc/spectest2.c +++ b/xicc/spectest2.c @@ -25,14 +25,15 @@ #include #include +#include "aconfig.h" #include "cgats.h" #include "xspect.h" #include "insttypes.h" //#include "inst.h" #include "numlib.h" #ifdef DOPLOT -#include "plot.h" -#include "ui.h" +# include "plot.h" +# include "ui.h" #endif @@ -237,7 +238,7 @@ main(void) { printf("Material %d\n", m+1); /* Create two conversions for the target/check illuminant */ - if ((con = new_xsp2cie(icxIT_D50, NULL, icxOT_CIE_1931_2, + if ((con = new_xsp2cie(icxIT_D50, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigLabData, 1)) == NULL) error ("Creating conversion failed"); diff --git a/xicc/transplot.c b/xicc/transplot.c index 6473e2b..aa4a1ff 100755 --- a/xicc/transplot.c +++ b/xicc/transplot.c @@ -25,6 +25,7 @@ #include #include #include +#include "aconfig.h" #include "icc.h" #include "numlib.h" #include "plot.h" diff --git a/xicc/xcal.c b/xicc/xcal.c index 4a5b37e..c1639d6 100755 --- a/xicc/xcal.c +++ b/xicc/xcal.c @@ -33,6 +33,7 @@ #include "copyright.h" #include "aconfig.h" #include "numlib.h" +#include "plot.h" #include "xicc.h" #else #include "sa_config.h" diff --git a/xicc/xdgb.c b/xicc/xdgb.c index 80914b8..fd5d90d 100755 --- a/xicc/xdgb.c +++ b/xicc/xdgb.c @@ -33,8 +33,8 @@ #include "numlib.h" #include "icc.h" #include "rspl.h" -#include "xicc.h" #include "plot.h" +#include "xicc.h" #include "xdgb.h" #include "sort.h" diff --git a/xicc/xfit.c b/xicc/xfit.c index b5a8694..a4cfee6 100755 --- a/xicc/xfit.c +++ b/xicc/xfit.c @@ -74,8 +74,8 @@ #include "numlib.h" #include "icc.h" #include "rspl.h" -#include "xicc.h" #include "plot.h" +#include "xicc.h" #include "xfit.h" #include "sort.h" diff --git a/xicc/xicc.c b/xicc/xicc.c index eef469d..e0be01a 100755 --- a/xicc/xicc.c +++ b/xicc/xicc.c @@ -37,6 +37,7 @@ #if defined(__IBMC__) && defined(_M_IX86) #include #endif +#include "aconfig.h" #include "numlib.h" #include "counters.h" #include "plot.h" diff --git a/xicc/xicclu.c b/xicc/xicclu.c index 6bbb62a..e95e188 100755 --- a/xicc/xicclu.c +++ b/xicc/xicclu.c @@ -34,8 +34,8 @@ #include "copyright.h" #include "aconfig.h" #include "numlib.h" -#include "xicc.h" #include "plot.h" +#include "xicc.h" #include "ui.h" #undef SPTEST /* [und] Test (flawed) rspl gamut surface code */ diff --git a/xicc/xlutfix.c b/xicc/xlutfix.c index a0c0e4e..5492280 100755 --- a/xicc/xlutfix.c +++ b/xicc/xlutfix.c @@ -132,8 +132,9 @@ */ -#include "icc.h" +#include "aconfig.h" #include "numlib.h" +#include "icc.h" #include "xicc.h" /* NOTE:- that we only implement support for CMYK output here !!! */ diff --git a/xicc/xspect.c b/xicc/xspect.c index b77f322..fff4d46 100755 --- a/xicc/xspect.c +++ b/xicc/xspect.c @@ -30,14 +30,16 @@ #include #include #include +# include "aconfig.h" #ifndef SALONEINSTLIB # include "numlib.h" -# include "cgats.h" -# include "plot.h" /* For debugging */ +# include "plot.h" /* For debugging */ +# include "ui.h" #else # include "numsup.h" # include "sa_conv.h" #endif +#include "cgats.h" #include "conv.h" #include "xspect.h" @@ -614,7 +616,6 @@ static xspect il_F8 = { }; - /* CIE F10 */ /* Fluorescent, Narrow band 5000K, CRI 81 */ static xspect il_F10 = { @@ -749,6 +750,61 @@ double temp /* Optional temperature in degrees kelvin, for Dtemp and Ptemp * return 1; } +/* Return a string describing the standard illuminant */ +/* (Returns static buffer for temp based) */ +char *standardIlluminant_name( +icxIllumeType ilType, /* Type of illuminant */ +double temp /* Optional temperature in degrees kelvin, For Dtemp and Ptemp */ +) { + static char buf[50]; + switch (ilType) { + case icxIT_none: + return "None"; + case icxIT_custom: + return "Custom"; + case icxIT_A: + return "A"; + case icxIT_C: + return 0; + case icxIT_default: + case icxIT_D50: + return 0; + case icxIT_D50M2: + return 0; + case icxIT_D55: + return "D55"; + case icxIT_D65: + return "D65"; + case icxIT_D75: + return "D75"; + case icxIT_E: + return "E"; +#ifndef SALONEINSTLIB + case icxIT_F5: + return "F5"; + case icxIT_F8: + return "F8"; + case icxIT_F10: + return "F10"; + case icxIT_Spectrocam: + return "Spectrocam"; +#endif + case icxIT_ODtemp: + sprintf(buf, "OD%d",(int)(temp+0.5)); + return buf; + case icxIT_Dtemp: + sprintf(buf, "D%d",(int)(temp+0.5)); + return buf; + case icxIT_OPtemp: + sprintf(buf, "OP%d",(int)(temp+0.5)); + return buf; + case icxIT_Ptemp: + sprintf(buf, "P%d",(int)(temp+0.5)); + return buf; + } + return "Unknown"; +} + /* ------------- */ /* Observer Data */ @@ -3514,6 +3570,8 @@ static xspect FWA1_emit = { #endif /* STOCKFWA */ +#endif /* !SALONEINSTLIB */ + /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Return a string describing the inst_meas_type */ char *meas_type2str(inst_meas_type mt) { @@ -3901,7 +3959,6 @@ int read_cmf(xspect sp[3], char *fname) { } /* ------------- */ -#endif /* !SALONEINSTLIB */ /* Get a raw 3rd order polinomial interpolated spectrum value. */ @@ -4353,15 +4410,15 @@ void xspect_plot(xspect *sp1, xspect *sp2, xspect *sp3) { xspect_plot_w(sp1, sp2, sp3, 1); } -/* Plot up to 10 spectra in an array */ -void xspect_plot10(xspect *sp, int n) { +/* Plot up to 12 spectra in an array, and wait for key */ +void xspect_plotN(xspect *sp, int n) { double xx[XSPECT_MAX_BANDS]; - double *yp[10]; - double yy[10][XSPECT_MAX_BANDS]; + double *yp[MXGPHS]; + double yy[MXGPHS][XSPECT_MAX_BANDS]; double wl, wlshort, wllong; int i, j; - for (i = 0; i < 10; i++) + for (i = 0; i < MXGPHS; i++) yp[i] = NULL; if (sp == NULL) @@ -4370,7 +4427,7 @@ void xspect_plot10(xspect *sp, int n) { wlshort = sp->spec_wl_short; wllong = sp->spec_wl_long; - for (i = 0; i < n; i++) { + for (i = 0; i < n && i < MXGPHS; i++) { if (sp[i].spec_wl_short < wlshort) wlshort = sp[i].spec_wl_short; if (sp[i].spec_wl_long > wllong) @@ -4386,24 +4443,23 @@ void xspect_plot10(xspect *sp, int n) { gcc_bug_fix(j); #endif xx[j] = wl; - for (i = 0; i < n; i++) { + for (i = 0; i < n && i < MXGPHS; i++) { yp[i] = yy[i]; yy[i][j] = value_xspect(&sp[i], wl); } } - do_plot10(xx, yp[0], yp[1], yp[2], yp[3], yp[4], - yp[5], yp[6], yp[7], yp[8], yp[9], j, 0); + do_plotNpwz(xx, yp, j, NULL, NULL, 0, 1, 0); } -/* Plot up to 10 spectra pointed to by an array */ -void xspect_plot10p_w(xspect *sp[10], int n, int wait) { +/* Plot up to 12 spectra pointed to by an array, with optional wait */ +void xspect_plotNp_w(xspect *sp[MXGPHS], int n, int wait) { double xx[XSPECT_MAX_BANDS]; - double *yp[10]; - double yy[10][XSPECT_MAX_BANDS]; + double *yp[MXGPHS]; + double yy[MXGPHS][XSPECT_MAX_BANDS]; double wl, wlshort, wllong; int i, j; - for (i = 0; i < 10; i++) + for (i = 0; i < MXGPHS; i++) yp[i] = NULL; if (sp == NULL) @@ -4412,7 +4468,7 @@ void xspect_plot10p_w(xspect *sp[10], int n, int wait) { wlshort = 1e6; wllong = -1e6; - for (i = 0; i < n; i++) { + for (i = 0; i < n && i < MXGPHS; i++) { if (sp[i] == NULL) continue; if (sp[i]->spec_wl_short < wlshort) @@ -4433,20 +4489,19 @@ void xspect_plot10p_w(xspect *sp[10], int n, int wait) { gcc_bug_fix(j); #endif xx[j] = wl; - for (i = 0; i < n; i++) { + for (i = 0; i < n && i < MXGPHS; i++) { if (sp[i] == NULL) continue; yp[i] = yy[i]; yy[i][j] = value_xspect(sp[i], wl); } } - do_plot10pw(xx, yp[0], yp[1], yp[2], yp[3], yp[4], - yp[5], yp[6], yp[7], yp[8], yp[9], j, NULL, NULL, 0, wait); + do_plotNpwz(xx, yp, j, NULL, NULL, 0, wait, 0); } /* Plot up to 10 spectra pointed to by an array * wait for a key */ -void xspect_plot10p(xspect *sp[10], int n) { - xspect_plot10p_w(sp, n, 1); +void xspect_plotNp(xspect *sp[MXGPHS], int n) { + xspect_plotNp_w(sp, n, 1); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -5084,7 +5139,7 @@ double *FWAc) { /* rather than integrated if they are not at 1nm spacing. */ static void xsp2cie_fwa_sconvert( xsp2cie *p, /* this */ -xspect *sout, /* Return corrected input spectrum (may be NULL, or same as imput) */ +xspect *sout, /* Return corrected input spectrum (may be NULL, or same as input) */ double *out, /* Return XYZ or D50 Lab value (may be NULL) */ xspect *in /* Spectrum to be converted */ ) { @@ -5605,13 +5660,13 @@ xspect *in /* Colorant reflectance to be applied */ /* rather than integrated if they are not at 1nm spacing. */ static void xsp2cie_photo2rad( xsp2cie *p, /* this */ -double *routp, /* Return total lumens */ -double *poutp, /* Return total mW */ +double *loutp, /* Return total lumens (photometric) */ +double *mwoutp, /* Return total mW (radiometric) */ xspect *sout, /* Return input spectrum converted to lm/nm */ xspect *in /* Spectrum to be converted */ ) { - double rscale = 0.0; - double rout, pout; + double lscale = 0.0; + double lout, mwout; double ww; /* Compute the Y value (normalised to 1.0) */ @@ -5623,40 +5678,41 @@ xspect *in /* Spectrum to be converted */ /* ANSI CGATS.5-1993 spec. If illumninant or material spectra */ /* values are truncated at the extremes, then the last valid values */ /* are used, also consistent with CIE and ANSI CGATS recommendations. */ - rout = 0.0; - pout = 0.0; + /* Also intergate the radiometric total. */ + lout = 0.0; + mwout = 0.0; for (ww = p->spec_wl_short; ww <= p->spec_wl_long; ww += p->spec_bw) { double I = 1.0, O, S; if (!p->isemis) getval_xspec(&p->illuminant, &I, ww); getval_xspec(&p->observer[1], &O, ww); getval_xspec(in, &S, ww); - rscale += I * O; /* Integrate Y illuminant * observer values */ - rout += I * O * S; - pout += S; + lscale += I * O; /* Integrate Y illuminant * observer values */ + lout += I * O * S; + mwout += S; } if (p->isemis) { - // Hmm. Should we really make rscale += O for this case and then - // rscale = 0.683002/rscale ?? - rscale = 0.683002; /* Convert from mW/m^2 to Lumens/m^2 */ + // Hmm. Should we really make lscale += O for this case and then + // lscale = 0.683002/lscale ?? + lscale = 0.683002; /* Convert from mW/m^2 to Lumens/m^2 */ /* (== 683 Luments/Watt/m^2) */ } else { - rscale *= p->spec_bw; /* Scale for integration interval */ - rscale = 1.0/rscale; + lscale *= p->spec_bw; /* Scale for integration interval */ + lscale = 1.0/lscale; } /* Scale for illuminant/observer normalisation of Y */ - rout *= rscale; + lout *= lscale; #ifdef CLAMP_XYZ - if (p->clamp && rout < 0.0) - rout = 0.0; /* Just to be sure we don't get silly values */ + if (p->clamp && lout < 0.0) + lout = 0.0; /* Just to be sure we don't get silly values */ #endif /* CLAMP_XYZ */ - if (routp != NULL) - *routp = rout; + if (loutp != NULL) + *loutp = lout; - pout *= p->spec_bw; /* Scale for integration interval */ - if (poutp != NULL) - *poutp = pout; + mwout *= p->spec_bw; /* Scale for integration interval */ + if (mwoutp != NULL) + *mwoutp = mwout; /* Compute phometric output spectrum. For reflective/transmissive, this is */ /* the illuminant times the reflectivity/transmissitivity times Y weighting, */ @@ -5675,7 +5731,7 @@ xspect *in /* Spectrum to be converted */ getval_xspec(&p->illuminant, &I, ww); getval_xspec(&p->observer[1], &O, ww); getval_xspec(in, &S, ww); - sout->spec[i] = rscale * I * O * S; + sout->spec[i] = lscale * I * O * S; } } } @@ -5787,6 +5843,7 @@ xsp2cie *p /* Create and return a new spectral conversion object */ xsp2cie *new_xsp2cie( icxIllumeType ilType, /* Illuminant */ +double temp, /* Optional temperature in degrees kelvin, if ilType = Dtemp etc. */ xspect *custIllum, /* Custom illuminant if ilType == icxIT_custom */ icxObserverType obType, /* Observer */ xspect custObserver[3], /* Custom observer if obType == icxOT_custom */ @@ -5801,119 +5858,38 @@ icxClamping clamp /* NZ to clamp XYZ/Lab to be +ve */ return NULL; p->isemis = 0; - switch (ilType) { - case icxIT_none: - p->illuminant = il_none; /* Emissive */ - p->isemis = 1; - break; - case icxIT_custom: - p->illuminant = *custIllum; /* Struct copy */ - break; - case icxIT_A: - p->illuminant = il_A; - break; - case icxIT_C: - p->illuminant = il_C; - break; - case icxIT_default: - case icxIT_D50: - p->illuminant = il_D50; - break; - case icxIT_D50M2: - if (il_D50M2.spec_n == 0) - uv_filter(&il_D50M2, &il_D50); - p->illuminant = il_D50M2; - break; - case icxIT_D55: - daylight_il(&p->illuminant, 5500.0); - break; - case icxIT_D65: - p->illuminant = il_D65; - break; - case icxIT_D75: - daylight_il(&p->illuminant, 7500.0); - case icxIT_E: - p->illuminant = il_none; - break; -#ifndef SALONEINSTLIB - case icxIT_F5: - p->illuminant = il_F5; - break; - case icxIT_F8: - p->illuminant = il_F8; - break; - case icxIT_F10: - p->illuminant = il_F10; - break; - case icxIT_Spectrocam: - p->illuminant = il_Spectrocam; - break; -#endif /* !SALONEINSTLIB */ - default: + + if (ilType == icxIT_custom) { + p->illuminant = *custIllum; + + } else if (ilType == icxIT_none) { + p->isemis = 1; + p->illuminant = il_none; /* Not used */ + + } else { + if (standardIlluminant(&p->illuminant, ilType, temp) != 0) { DBGF((DBGA,"new_xsp2cie() unrecognised illuminant 0x%x\n",ilType)); free(p); return NULL; + } } - /* Do 3 structure copies to record observer sensitivity curves */ - switch (obType) { - case icxOT_custom: - p->observer[0] = custObserver[0]; - p->observer[1] = custObserver[1]; - p->observer[2] = custObserver[2]; - break; - case icxOT_default: - case icxOT_CIE_1931_2: - p->observer[0] = ob_CIE_1931_2[0]; - p->observer[1] = ob_CIE_1931_2[1]; - p->observer[2] = ob_CIE_1931_2[2]; - break; - case icxOT_CIE_1964_10: - p->observer[0] = ob_CIE_1964_10[0]; - p->observer[1] = ob_CIE_1964_10[1]; - p->observer[2] = ob_CIE_1964_10[2]; - break; - case icxOT_CIE_2012_2: - p->observer[0] = ob_CIE_2012_2[0]; - p->observer[1] = ob_CIE_2012_2[1]; - p->observer[2] = ob_CIE_2012_2[2]; - break; - case icxOT_CIE_2012_10: - p->observer[0] = ob_CIE_2012_10[0]; - p->observer[1] = ob_CIE_2012_10[1]; - p->observer[2] = ob_CIE_2012_10[2]; - break; -#ifndef SALONEINSTLIB - case icxOT_Stiles_Burch_2: - p->observer[0] = ob_Stiles_Burch_2[0]; - p->observer[1] = ob_Stiles_Burch_2[1]; - p->observer[2] = ob_Stiles_Burch_2[2]; - break; - case icxOT_Judd_Voss_2: - p->observer[0] = ob_Judd_Voss_2[0]; - p->observer[1] = ob_Judd_Voss_2[1]; - p->observer[2] = ob_Judd_Voss_2[2]; - break; - case icxOT_CIE_1964_10c: - p->observer[0] = ob_CIE_1964_10c[0]; - p->observer[1] = ob_CIE_1964_10c[1]; - p->observer[2] = ob_CIE_1964_10c[2]; - break; - case icxOT_Shaw_Fairchild_2: - p->observer[0] = ob_Shaw_Fairchild_2[0]; - p->observer[1] = ob_Shaw_Fairchild_2[1]; - p->observer[2] = ob_Shaw_Fairchild_2[2]; - break; - case icxOT_EBU_2012: - p->observer[0] = ob_EBU_2012[0]; - p->observer[1] = ob_EBU_2012[1]; - p->observer[2] = ob_EBU_2012[2]; - break; -#endif /* !SALONEINSTLIB */ - default: + /* Get copies of the 3 observer curves */ + if (obType == icxOT_custom) { + p->observer[0] = custObserver[0]; + p->observer[1] = custObserver[1]; + p->observer[2] = custObserver[2]; + } else { + xspect *sp3[3]; + + if (standardObserver(sp3, obType)) { DBGF((DBGA,"new_xsp2cie() unrecognised observer type 0x%x\n",obType)); free(p); return NULL; + } + p->observer[0] = *sp3[0]; + p->observer[1] = *sp3[1]; + p->observer[2] = *sp3[2]; } if (rcs == icSigXYZData) @@ -8166,15 +8142,9 @@ double ct, /* Input temperature in degrees K */ xspect *custIllum, /* Optional custom illuminant */ xspect *sp /* Spectrum to be converted */ ) { - xspect ill; /* Xspect to fill in */ xsp2cie *conv; /* Means of converting spectrum to XYZ */ - if (ilType == icxIT_custom) - ill = *custIllum; - else if (standardIlluminant(&ill, ilType, ct) != 0) - return 1; - - if ((conv = new_xsp2cie(icxIT_custom, &ill, obType, custObserver, icSigXYZData, 1)) == NULL) + if ((conv = new_xsp2cie(ilType, ct, custIllum, obType, custObserver, icSigXYZData, 1)) == NULL) return 1; conv->convert(conv, xyz, sp); @@ -8208,7 +8178,7 @@ int abs /* If nz return absolute value in cd/m^2 or Lux */ else if (standardIlluminant(&sp, ilType, ct) != 0) return 1; - if ((conv = new_xsp2cie(icxIT_none, NULL, obType, custObserver, icSigXYZData, 1)) == NULL) + if ((conv = new_xsp2cie(icxIT_none, 0.0, NULL, obType, custObserver, icSigXYZData, 1)) == NULL) return 1; conv->convert(conv, xyz, &sp); @@ -8381,7 +8351,7 @@ int viscct /* nz to use visual CIEDE2000, 0 to use CCT CIE 1960 UCS. */ return -1.0; x.ilType = ilType; - if ((x.conv = new_xsp2cie(icxIT_none, NULL, obType, custObserver, icSigXYZData, 1)) == NULL) + if ((x.conv = new_xsp2cie(icxIT_none, 0.0, NULL, obType, custObserver, icSigXYZData, 1)) == NULL) return -1; if (xyz == NULL) { @@ -8496,7 +8466,7 @@ xspect *sample /* Illuminant sample to compute CRI of */ //DBGF((DBGA,"icx_CIE1995_CRI called\n")); - if ((tocie = new_xsp2cie(icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, 1)) == NULL) + if ((tocie = new_xsp2cie(icxIT_none, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, 1)) == NULL) return -1.0; /* Compute the XYZ of the sample */ @@ -8561,7 +8531,7 @@ if (dc > 0.0054) DBGF((DBGA,"CRI is invalid\n")); } /* Check out the delta E for each reflective sample */ - if ((tocie = new_xsp2cie(icxIT_custom, &wts, icxOT_CIE_1931_2, NULL, icSigXYZData, 1)) == NULL) { + if ((tocie = new_xsp2cie(icxIT_custom, 0.0, &wts, icxOT_CIE_1931_2, NULL, icSigXYZData, 1)) == NULL) { sample->norm = sampnorm; /* Restore this */ return -1.0; } @@ -8575,7 +8545,7 @@ if (dc > 0.0054) DBGF((DBGA,"CRI is invalid\n")); } tocie->del(tocie); - if ((tocie = new_xsp2cie(icxIT_custom, sample, icxOT_CIE_1931_2, NULL, icSigXYZData, 1)) == NULL) { + if ((tocie = new_xsp2cie(icxIT_custom, 0.0, sample, icxOT_CIE_1931_2, NULL, icSigXYZData, 1)) == NULL) { sample->norm = sampnorm; /* Restore this */ return -1.0; } @@ -8720,7 +8690,7 @@ xspect *sample /* Illuminant sample to compute TLCI of */ //DBGF((DBGA,"icx_EBU2012_TLCI called\n")); /* Create spectral to XYZ for UCS space delta */ - if ((tocie = new_xsp2cie(icxIT_none, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, 1)) == NULL) { + if ((tocie = new_xsp2cie(icxIT_none, 0.0, NULL, icxOT_CIE_1931_2, NULL, icSigXYZData, 1)) == NULL) { //DBGF((DBGA,"Ref new_xsp2cie failed\n")); return -1.0; } @@ -8822,12 +8792,12 @@ if (dc > 0.0054) DBGF((DBGA,"TLCI is invalid\n")); /* Note that xsp2cie will normalise the values such that the "Y" value */ /* (actually G here) to be 1.0 for the perfect diffusor for the given illuminant, */ /* but that the white balancing scaling would do this anyway. */ - if ((reftoRGB = new_xsp2cie(icxIT_custom, &wts, icxOT_EBU_2012, NULL, icSigXYZData, 1)) == NULL) { + if ((reftoRGB = new_xsp2cie(icxIT_custom, 0.0, &wts, icxOT_EBU_2012, NULL, icSigXYZData, 1)) == NULL) { //DBGF((DBGA,"new_xsp2cie for ref failed\n")); sample->norm = sampnorm; /* Restore this */ return -1.0; } - if ((satoRGB = new_xsp2cie(icxIT_custom, sample, icxOT_EBU_2012, NULL, icSigXYZData, 1)) == NULL) { + if ((satoRGB = new_xsp2cie(icxIT_custom, 0.0, sample, icxOT_EBU_2012, NULL, icSigXYZData, 1)) == NULL) { //DBGF((DBGA,"new_xsp2cie for samp failed\n")); sample->norm = sampnorm; /* Restore this */ reftoRGB->del(reftoRGB); diff --git a/xicc/xspect.h b/xicc/xspect.h index b42a961..76b8b89 100755 --- a/xicc/xspect.h +++ b/xicc/xspect.h @@ -178,14 +178,14 @@ void xspect_plot_w(xspect *sp1, xspect *sp2, xspect *sp3, int wait); /* Plot up to 3 spectra & wait for key */ void xspect_plot(xspect *sp1, xspect *sp2, xspect *sp3); -/* Plot up to 10 spectra in an array */ -void xspect_plot10(xspect *sp, int n); +/* Plot up to 12 spectra in an array */ +void xspect_plotN(xspect *sp, int n); -/* Plot up to 10 spectra pointed to by an array & wait for key */ -void xspect_plot10p(xspect *sp[10], int n); +/* Plot up to 12 spectra pointed to by an array & wait for key */ +void xspect_plotNp(xspect *sp[MXGPHS], int n); -/* Plot up to 10 spectra pointed to by an array */ -void xspect_plot10p_w(xspect *sp[10], int n, int wait); +/* Plot up to 12 spectra pointed to by an array */ +void xspect_plotNp_w(xspect *sp[MXGPHS], int n, int wait); #endif /* !SALONEINSTLIB*/ @@ -226,6 +226,12 @@ xspect *sp, /* Xspect to fill in */ icxIllumeType ilType, /* Type of illuminant */ double temp); /* Optional temperature in degrees kelvin, For Dtemp and Ptemp */ +/* Return a string describing the standard illuminant */ +/* (Returns static buffer for temp based) */ +char *standardIlluminant_name( +icxIllumeType ilType, /* Type of illuminant */ +double temp); /* Optional temperature in degrees kelvin, For Dtemp and Ptemp */ + /* Given an emission spectrum, set the UV output to the given level. */ /* The shape of the UV is taken from FWA1_stim, and the level is */ /* with respect to the average of the input spectrum. */ @@ -326,7 +332,7 @@ struct _xsp2cie { /* Convert and also return (possibly corrected) reflectance spectrum */ /* Spectrum will be same wlength range and readings as input spectrum */ - /* Note that the returned XYZ is 0..1 range for reflectanc. */ + /* Note that the returned XYZ is 0..1 range for reflectance. */ /* Emissive spectral values are assumed to be in mW/nm, and sampled */ /* rather than integrated if they are not at 1nm spacing. */ void (*sconvert) (struct _xsp2cie *p, /* this */ @@ -397,6 +403,7 @@ struct _xsp2cie { xsp2cie *new_xsp2cie( icxIllumeType ilType, /* Observer Illuminant to use */ + double temp, /* Optional temp. in degrees kelvin, if ilType = Dtemp etc */ xspect *custIllum, /* Custom illuminant if ilType == icxIT_custom */ icxObserverType obType, /* Observer */ @@ -491,9 +498,6 @@ xspect *custIllum, /* Optional custom illuminant */ xspect *sp /* Spectrum to be converted */ ); -/* ------------------------------------------------- */ -/* Color temperature and CRI */ - /* Given an illuminant definition and an observer model, return */ /* the normalised XYZ value for that spectrum. */ /* Return 0 on sucess, 1 on error */ @@ -509,6 +513,9 @@ int abs /* If nz return absolute value in cd/m^2 or Lux */ /* else return Y = 1 normalised value */ ); +/* ------------------------------------------------- */ +/* Color temperature and CRI */ + /* Given a choice of temperature dependent illuminant (icxIT_[O]Dtemp or icxIT_[O]Ptemp), */ /* return the closest correlated color temperature to the given spectrum or XYZ. */ /* An observer type can be chosen for interpretting the spectrum of the input and */ -- cgit v1.2.3 From f5991c577f8c4cd7cf5305bc244dd0ee70136aba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 11 Jul 2018 23:14:38 +0200 Subject: refresh patches --- .pc/.quilt_patches | 1 + .pc/.quilt_series | 1 + .pc/.version | 1 + debian/changelog | 5 +- debian/patches/0001_jam.patch | 6 +- debian/patches/0100_spelling.patch | 116 +++++------- debian/patches/0105_dispwin_segfault.patch | 2 +- spectro/linear.cal | 272 ----------------------------- spectro/strange.cal | 272 ----------------------------- 9 files changed, 50 insertions(+), 626 deletions(-) create mode 100644 .pc/.quilt_patches create mode 100644 .pc/.quilt_series create mode 100644 .pc/.version delete mode 100755 spectro/linear.cal delete mode 100755 spectro/strange.cal diff --git a/.pc/.quilt_patches b/.pc/.quilt_patches new file mode 100644 index 0000000..6857a8d --- /dev/null +++ b/.pc/.quilt_patches @@ -0,0 +1 @@ +debian/patches diff --git a/.pc/.quilt_series b/.pc/.quilt_series new file mode 100644 index 0000000..c206706 --- /dev/null +++ b/.pc/.quilt_series @@ -0,0 +1 @@ +series diff --git a/.pc/.version b/.pc/.version new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/.pc/.version @@ -0,0 +1 @@ +2 diff --git a/debian/changelog b/debian/changelog index bb38595..43cb0b0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,9 @@ -argyll (2.0.0+repack-2) UNRELEASED; urgency=medium +argyll (2.0.1+repack-1) UNRELEASED; urgency=medium * debian/copyright: Add copyright for numlib/quadprog.*. + * - -- Jörg Frings-Fürst Sun, 03 Dec 2017 20:41:38 +0100 + -- Jörg Frings-Fürst Wed, 11 Jul 2018 22:21:14 +0200 argyll (2.0.0+repack-1) unstable; urgency=medium diff --git a/debian/patches/0001_jam.patch b/debian/patches/0001_jam.patch index b0469f3..976f485 100644 --- a/debian/patches/0001_jam.patch +++ b/debian/patches/0001_jam.patch @@ -8,7 +8,7 @@ Index: trunk/Jambase =================================================================== --- trunk.orig/Jambase +++ trunk/Jambase -@@ -941,7 +941,7 @@ else if $(UNIX) +@@ -945,7 +945,7 @@ else if $(UNIX) # UNIX defaults @@ -17,7 +17,7 @@ Index: trunk/Jambase CCOPTFLAG ?= -O2 ; CCDEBUGFLAG ?= -g ; CCPROFFLAG ?= ; -@@ -951,7 +951,7 @@ else if $(UNIX) +@@ -955,7 +955,7 @@ else if $(UNIX) CHGRP ?= chgrp ; CHOWN ?= chown ; LEX ?= lex ; @@ -26,7 +26,7 @@ Index: trunk/Jambase LINKOPTFLAG ?= -O ; # Affects creating .so's LINKSTRIPFLAG ?= -s ; LINKDEBUGFLAG ?= ; -@@ -1037,7 +1037,7 @@ else if $(UNIX) +@@ -1041,7 +1041,7 @@ else if $(UNIX) RMDIR ?= $(RM) ; RSH ?= rsh ; SED ?= sed ; diff --git a/debian/patches/0100_spelling.patch b/debian/patches/0100_spelling.patch index 9797224..1b7d8cb 100644 --- a/debian/patches/0100_spelling.patch +++ b/debian/patches/0100_spelling.patch @@ -41,7 +41,7 @@ Index: trunk/spectro/dispcal.c comport = atoi(na); if (comport < 1 || comport > 50) usage(0,"-c parameter %d out of range",comport); -@@ -3111,7 +3111,7 @@ int main(int argc, char *argv[]) { +@@ -3114,7 +3114,7 @@ int main(int argc, char *argv[]) { /* Black level adjustment */ /* Due to the possibility of the channel offsets not being even, */ /* we use the largest of the XYZ values after they have been */ @@ -54,7 +54,7 @@ Index: trunk/spectro/spotread.c =================================================================== --- trunk.orig/spectro/spotread.c +++ trunk/spectro/spotread.c -@@ -509,7 +509,7 @@ int main(int argc, char *argv[]) { +@@ -517,7 +517,7 @@ int main(int argc, char *argv[]) { /* COM port */ } else if (argv[fa][1] == 'c') { fa = nfa; @@ -63,16 +63,7 @@ Index: trunk/spectro/spotread.c { comport = atoi(na); if (comport < 1 || comport > 40) usage("-c parameter %d out of range",comport); -@@ -518,7 +518,7 @@ int main(int argc, char *argv[]) { - /* Display type */ - } else if (argv[fa][1] == 'y') { - fa = nfa; -- if (na == NULL) usage("Paramater expected following -y"); -+ if (na == NULL) usage("Parameter expected following -y"); - dtype = na[0]; - - #ifndef SALONEINSTLIB -@@ -526,7 +526,7 @@ int main(int argc, char *argv[]) { +@@ -536,7 +536,7 @@ int main(int argc, char *argv[]) { } else if (argv[fa][1] == 'I') { fa = nfa; @@ -81,7 +72,7 @@ Index: trunk/spectro/spotread.c if (strcmp(na, "A") == 0 || strcmp(na, "M0") == 0) { tillum_set = spec = 1; -@@ -574,7 +574,7 @@ int main(int argc, char *argv[]) { +@@ -584,7 +584,7 @@ int main(int argc, char *argv[]) { /* Spectral Illuminant type for XYZ computation */ } else if (argv[fa][1] == 'i') { fa = nfa; @@ -90,7 +81,7 @@ Index: trunk/spectro/spotread.c if (strcmp(na, "A") == 0) { illum_set = spec = 1; illum = icxIT_A; -@@ -623,7 +623,7 @@ int main(int argc, char *argv[]) { +@@ -639,7 +639,7 @@ int main(int argc, char *argv[]) { /* Spectral Observer type */ } else if (argv[fa][1] == 'Q') { fa = nfa; @@ -99,7 +90,7 @@ Index: trunk/spectro/spotread.c if (strcmp(na, "1931_2") == 0) { /* Classic 2 degree */ obType = icxOT_CIE_1931_2; } else if (strcmp(na, "1964_10") == 0) { /* Classic 10 degree */ -@@ -712,7 +712,7 @@ int main(int argc, char *argv[]) { +@@ -728,7 +728,7 @@ int main(int argc, char *argv[]) { /* Filter configuration */ } else if (argv[fa][1] == 'F') { fa = nfa; @@ -108,7 +99,7 @@ Index: trunk/spectro/spotread.c if (na[0] == 'n' || na[0] == 'N') fe = inst_opt_filter_none; else if (na[0] == 'p' || na[0] == 'P') -@@ -727,13 +727,13 @@ int main(int argc, char *argv[]) { +@@ -743,13 +743,13 @@ int main(int argc, char *argv[]) { /* Extra filter compensation file */ } else if (argv[fa][1] == 'E') { fa = nfa; @@ -124,7 +115,7 @@ Index: trunk/spectro/spotread.c if (na[0] == 'N') calstd = xcalstd_none; else if (na[0] == 'A') -@@ -743,7 +743,7 @@ int main(int argc, char *argv[]) { +@@ -759,7 +759,7 @@ int main(int argc, char *argv[]) { else if (na[0] == 'G') calstd = xcalstd_gmdi; else @@ -133,7 +124,7 @@ Index: trunk/spectro/spotread.c /* Show Yxy */ } else if (argv[fa][1] == 'x') { -@@ -1479,7 +1479,7 @@ int main(int argc, char *argv[]) { +@@ -1513,7 +1513,7 @@ int main(int argc, char *argv[]) { /* Or something is wrong with instrument capabilities */ } else { @@ -159,7 +150,7 @@ Index: trunk/spectro/dispwin.c =================================================================== --- trunk.orig/spectro/dispwin.c +++ trunk/spectro/dispwin.c -@@ -5234,7 +5234,7 @@ int ddebug /* >0 to print debug sta +@@ -5238,7 +5238,7 @@ int ddebug /* >0 to print debug sta vinfo = XGetVisualInfo(p->mydisplay, VisualIDMask, &template, &nitems); if (nitems < 1) { @@ -242,7 +233,7 @@ Index: trunk/spectro/i1pro_imp.c =================================================================== --- trunk.orig/spectro/i1pro_imp.c +++ trunk/spectro/i1pro_imp.c -@@ -2701,7 +2701,7 @@ int *pinstmsec) { /* Return instrument l +@@ -2780,7 +2780,7 @@ int *pinstmsec) { /* Return instrument l break; } @@ -251,7 +242,7 @@ Index: trunk/spectro/i1pro_imp.c /* Compute overall delay */ dispmsec = (int)(samp[i].sec * 1000.0 + 0.5); /* Display update time */ -@@ -3154,7 +3154,7 @@ i1pro_code i1pro_imp_measure( +@@ -3233,7 +3233,7 @@ i1pro_code i1pro_imp_measure( } } @@ -260,7 +251,7 @@ Index: trunk/spectro/i1pro_imp.c if (user_trig) return I1PRO_USER_TRIG; return ev; -@@ -3816,7 +3816,7 @@ i1pro_code i1pro_imp_meas_refrate( +@@ -3895,7 +3895,7 @@ i1pro_code i1pro_imp_meas_refrate( } } } else { @@ -269,7 +260,7 @@ Index: trunk/spectro/i1pro_imp.c } return I1PRO_RD_NOREFR_FOUND; -@@ -3911,7 +3911,7 @@ i1pro_code i1pro_restore_refspot_cal(i1p +@@ -3990,7 +3990,7 @@ i1pro_code i1pro_restore_refspot_cal(i1p return I1PRO_OK; } @@ -278,7 +269,7 @@ Index: trunk/spectro/i1pro_imp.c s->dark_valid = 1; s->ddate = m->caldate; -@@ -3956,7 +3956,7 @@ i1pro_code i1pro_restore_refspot_cal(i1p +@@ -4035,7 +4035,7 @@ i1pro_code i1pro_restore_refspot_cal(i1p return I1PRO_OK; } @@ -287,7 +278,7 @@ Index: trunk/spectro/i1pro_imp.c s->cal_valid = 1; s->cfdate = m->caldate; -@@ -4312,7 +4312,7 @@ i1pro_code i1pro_save_calibration(i1pro +@@ -4391,7 +4391,7 @@ i1pro_code i1pro_save_calibration(i1pro write_doubles(&x, fp, s->idark_data[3]-1, m->nraw+1); } @@ -313,7 +304,7 @@ Index: trunk/spectro/ss.c =================================================================== --- trunk.orig/spectro/ss.c +++ trunk/spectro/ss.c -@@ -375,7 +375,7 @@ ss_init_coms(inst *pp, baud_rate br, flo +@@ -376,7 +376,7 @@ ss_init_coms(inst *pp, baud_rate br, flo p->gotcoms = 1; @@ -322,7 +313,7 @@ Index: trunk/spectro/ss.c return inst_ok; } -@@ -1744,7 +1744,7 @@ ss_interp_error(inst *pp, int ec) { +@@ -1745,7 +1745,7 @@ ss_interp_error(inst *pp, int ec) { case ss_et_FilterOutOfPos: return "Filter wheel out of position"; case ss_et_SendTimeout: @@ -331,7 +322,7 @@ Index: trunk/spectro/ss.c case ss_et_DriveError: return "Data drive defect"; case ss_et_MeasDisabled: -@@ -1864,7 +1864,7 @@ ss_interp_error(inst *pp, int ec) { +@@ -1865,7 +1865,7 @@ ss_interp_error(inst *pp, int ec) { case ss_et_BadHexEncoding: return "Message received from instrument has bad Hex encoding"; case ss_et_RecBufferOverun: @@ -370,7 +361,7 @@ Index: trunk/xicc/cv.c =================================================================== --- trunk.orig/xicc/cv.c +++ trunk/xicc/cv.c -@@ -101,7 +101,7 @@ main(int argc, char *argv[]) { +@@ -102,7 +102,7 @@ main(int argc, char *argv[]) { printf("There are %d parameters:\n",np); fflush(stdout); for (i = 0; i < np; i++) { @@ -667,34 +658,7 @@ Index: trunk/link/collink.c =================================================================== --- trunk.orig/link/collink.c +++ trunk/link/collink.c -@@ -1122,7 +1122,7 @@ void devip_devop(void *cntx, double *out - } - /* We've got the input profile PCS' at this point. */ - -- /* If we're transfering the K value from the input profile to the */ -+ /* If we're transferring the K value from the input profile to the */ - /* output, copy it into locus[], which will be given to the inverse */ - /* lookup function, else the inverse lookup will generate a K using */ - /* the curve parameters. */ -@@ -1204,7 +1204,7 @@ void devip_devop(void *cntx, double *out - if (p->verb) - #endif - { -- printf("White point hack mapped %f %f %f to %f %f %f, hit withing %f\n", -+ printf("White point hack mapped %f %f %f to %f %f %f, hit within %f\n", - p->in.wp[0],p->in.wp[1],p->in.wp[2],pcsv[0], pcsv[1], pcsv[2],dd); - fflush(stdout); - } -@@ -1254,7 +1254,7 @@ void devip_devop(void *cntx, double *out - if (p->nhack == 2) { - /* Ideally we would create a 4D PCSK -> PCSK gamut mapping */ - /* to smoothly and accurately cope with the changing source */ -- /* and destination gamuts acording to their degree of "K onlyness". */ -+ /* and destination gamuts according to their degree of "K onlyness". */ - /* In practice we're going to simply interpolated between */ - /* two extremes: unrestricted gamut and K only black gamut. */ - double map0[3], map1[3]; -@@ -4807,7 +4807,7 @@ main(int argc, char *argv[]) { +@@ -4899,7 +4899,7 @@ main(int argc, char *argv[]) { } if (li.verb) @@ -720,7 +684,7 @@ Index: trunk/spectro/dispsup.c =================================================================== --- trunk.orig/spectro/dispsup.c +++ trunk/spectro/dispsup.c -@@ -721,7 +721,7 @@ static int disprd_read_imp( +@@ -722,7 +722,7 @@ static int disprd_read_imp( scb->serno = p->serno++; scb->msec = msec_time(); @@ -729,7 +693,7 @@ Index: trunk/spectro/dispsup.c val.XYZ[0], val.XYZ[1], val.XYZ[2]); scb->mtype = val.mtype; -@@ -1241,7 +1241,7 @@ int disprd_ambient( +@@ -1242,7 +1242,7 @@ int disprd_ambient( /* Or something is wrong with instrument capabilities */ } else { @@ -738,7 +702,7 @@ Index: trunk/spectro/dispsup.c return 2; } -@@ -2344,7 +2344,7 @@ static int config_inst_displ(disprd *p) +@@ -2346,7 +2346,7 @@ static int config_inst_displ(disprd *p) /* Reset key meanings */ inst_reset_uih(); @@ -751,7 +715,7 @@ Index: trunk/gamut/gammap.c =================================================================== --- trunk.orig/gamut/gammap.c +++ trunk/gamut/gammap.c -@@ -859,7 +859,7 @@ gammap *new_gammap( +@@ -861,7 +861,7 @@ gammap *new_gammap( #endif if (gmi->bph == gmm_clipBP) { @@ -764,7 +728,7 @@ Index: trunk/profile/profout.c =================================================================== --- trunk.orig/profile/profout.c +++ trunk/profile/profout.c -@@ -1104,7 +1104,7 @@ make_output_icc( +@@ -1105,7 +1105,7 @@ make_output_icc( if (iccver < icmVersion2_4) { iccver = icmVersion2_4; /* Need 2.4.0 for Display intents */ if (verb) @@ -790,7 +754,7 @@ Index: trunk/xicc/xspect.c =================================================================== --- trunk.orig/xicc/xspect.c +++ trunk/xicc/xspect.c -@@ -4454,7 +4454,7 @@ void xspect_plot10p(xspect *sp[10], int +@@ -4509,7 +4509,7 @@ void xspect_plotNp(xspect *sp[MXGPHS], i /* Given an emission spectrum, set the UV output to the given level. */ /* The shape of the UV is taken from FWA1_stim, and the level is */ /* with respect to the Y of the input spectrum. */ @@ -812,7 +776,7 @@ Index: trunk/spectro/ccxxmake.c comno = atoi(na); if (comno < 1 || comno > 40) usage(0,"-c parameter %d out of range",comno); -@@ -508,7 +508,7 @@ int main(int argc, char *argv[]) { +@@ -510,7 +510,7 @@ int main(int argc, char *argv[]) { /* Serial port flow control */ } else if (argv[fa][1] == 'W') { fa = nfa; @@ -821,7 +785,7 @@ Index: trunk/spectro/ccxxmake.c if (na[0] == 'n' || na[0] == 'N') fc = fc_None; else if (na[0] == 'h' || na[0] == 'H') -@@ -597,7 +597,7 @@ int main(int argc, char *argv[]) { +@@ -599,7 +599,7 @@ int main(int argc, char *argv[]) { strcat(outname, doccss ? ".ccss" : ".ccmx"); if (fakeseq && doccss) @@ -830,7 +794,7 @@ Index: trunk/spectro/ccxxmake.c printf("\n"); -@@ -813,7 +813,7 @@ int main(int argc, char *argv[]) { +@@ -815,7 +815,7 @@ int main(int argc, char *argv[]) { refs[i][2] = cols[i][2]; } gotref = 1; @@ -1298,7 +1262,7 @@ Index: trunk/xicc/mpp.c =================================================================== --- trunk.orig/xicc/mpp.c +++ trunk/xicc/mpp.c -@@ -733,7 +733,7 @@ int use_fwa /* NZ to involke +@@ -735,7 +735,7 @@ int use_fwa /* NZ to involke error ("mpp->set_ilob, instrument doesn't have an FWA illuminent"); if (p->spc->set_fwa(p->spc, &inst, NULL, &white)) @@ -1324,7 +1288,7 @@ Index: trunk/target/ofps.c =================================================================== --- trunk.orig/target/ofps.c +++ trunk/target/ofps.c -@@ -2612,7 +2612,7 @@ static int position_vtx( +@@ -2613,7 +2613,7 @@ static int position_vtx( if (tries > s->maxretries) s->maxretries = tries; #ifdef DEBUG @@ -1333,7 +1297,7 @@ Index: trunk/target/ofps.c printf(" oog = %f, eperr = %f, ceperr = %f\n",vv->oog,vv->eperr,vv->ceperr); #endif //if (tries > 10) -@@ -2627,7 +2627,7 @@ static int position_vtx( +@@ -2628,7 +2628,7 @@ static int position_vtx( #ifdef DUMP_FERR /* Create .tiff of dnsq function error */ if (tries >= DUMP_FERR) { @@ -1342,7 +1306,7 @@ Index: trunk/target/ofps.c /* Re-run the last unsucessful dnsq, to trace the path */ pcx.debug = 1; -@@ -6221,7 +6221,7 @@ static int ofps_findhit_vtxs(ofps *s, no +@@ -6222,7 +6222,7 @@ static int ofps_findhit_vtxs(ofps *s, no int hit = 0; if (nn->ix < 0) @@ -1351,7 +1315,7 @@ Index: trunk/target/ofps.c #ifdef DEBUG if (s->agrid_init == 0) -@@ -8023,7 +8023,7 @@ ofps *s +@@ -8024,7 +8024,7 @@ ofps *s warning("Verify of incremental vertexes failed!"); printf("Verify of incremental vertexes failed!\n"); } else { @@ -1360,7 +1324,7 @@ Index: trunk/target/ofps.c } #ifdef DUMP_STRUCTURE dump_node_vtxs(s, 1); -@@ -8443,7 +8443,7 @@ int nopstop /* Debug - number of opti +@@ -8444,7 +8444,7 @@ int nopstop /* Debug - number of opti fprintf(stderr,"Average dnsqs/position = %.2f\n",s->dnsqs/(double)s->positions); fprintf(stderr,"Average function calls/dnsq = %.1f\n",s->funccount/(double)s->dnsqs); fprintf(stderr,"Maximum function calls/dnsq = %d\n",s->maxfunc); @@ -1457,7 +1421,7 @@ Index: trunk/spectro/kleink10.c =================================================================== --- trunk.orig/spectro/kleink10.c +++ trunk/spectro/kleink10.c -@@ -729,7 +729,7 @@ int ix /* Klein calibration index 1 +@@ -730,7 +730,7 @@ int ix /* Klein calibration index 1 if (buf[0] != 'D' || buf[1] != '1') { amutex_unlock(p->lock); @@ -1466,7 +1430,7 @@ Index: trunk/spectro/kleink10.c return inst_protocol_error; } -@@ -2068,7 +2068,7 @@ int *pinstmsec) { /* Return instrument r +@@ -2077,7 +2077,7 @@ int *pinstmsec) { /* Return instrument r break; } @@ -1570,7 +1534,7 @@ Index: trunk/spectro/specbos.c /* See if it's a 1501 or 1511 */ if (p->model == 1501) { -@@ -1669,7 +1669,7 @@ char id[CALIDLEN] /* Condition identifi +@@ -1693,7 +1693,7 @@ char id[CALIDLEN] /* Condition identifi if ((ev = specbos_get_n_a_cals((inst *)p, &needed, &available)) != inst_ok) return ev; @@ -1583,7 +1547,7 @@ Index: trunk/plot/plot.c =================================================================== --- trunk.orig/plot/plot.c +++ trunk/plot/plot.c -@@ -2459,7 +2459,7 @@ static void dprintf(char *fmt, ...) { +@@ -2521,7 +2521,7 @@ static void dprintf(char *fmt, ...) { printf("~1 found NtQueryInformationProcess\n"); fflush(stdout); if(NtQueryInformationProcess(GetCurrentProcess(), 0, &pbi, sizeof(pbi), &ulSize) >= 0 && ulSize == sizeof(pbi)) { diff --git a/debian/patches/0105_dispwin_segfault.patch b/debian/patches/0105_dispwin_segfault.patch index 3ead582..d69d9d6 100644 --- a/debian/patches/0105_dispwin_segfault.patch +++ b/debian/patches/0105_dispwin_segfault.patch @@ -10,7 +10,7 @@ Index: trunk/spectro/dispwin.c =================================================================== --- trunk.orig/spectro/dispwin.c +++ trunk/spectro/dispwin.c -@@ -6277,6 +6277,7 @@ main(int argc, char *argv[]) { +@@ -6281,6 +6281,7 @@ main(int argc, char *argv[]) { /* Display number */ else if (argv[fa][1] == 'd') { diff --git a/spectro/linear.cal b/spectro/linear.cal deleted file mode 100755 index 64b2392..0000000 --- a/spectro/linear.cal +++ /dev/null @@ -1,272 +0,0 @@ -CAL - -DESCRIPTOR "Argyll Device Calibration Curves" -ORIGINATOR "Argyll synthcal" -CREATED "Mon Jul 09 03:30:52 2018" -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/strange.cal b/spectro/strange.cal deleted file mode 100755 index 5f4d4b4..0000000 --- a/spectro/strange.cal +++ /dev/null @@ -1,272 +0,0 @@ -CAL - -DESCRIPTOR "Argyll Device Calibration Curves" -ORIGINATOR "Argyll synthcal" -CREATED "Mon Jul 09 03:30:52 2018" -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 -- cgit v1.2.3 From d5f2af436940024641556f38fbd23a0f618fbe24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 11 Jul 2018 23:16:08 +0200 Subject: refresh patches --- debian/changelog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 43cb0b0..c9b311c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,7 +1,8 @@ argyll (2.0.1+repack-1) UNRELEASED; urgency=medium + * New upstream release: + - Refresh patches. * debian/copyright: Add copyright for numlib/quadprog.*. - * -- Jörg Frings-Fürst Wed, 11 Jul 2018 22:21:14 +0200 -- cgit v1.2.3 From 360345ec00b95d4b1fed15a8e252740277e605b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 11 Jul 2018 23:17:05 +0200 Subject: rm .pc/ --- .pc/.quilt_patches | 1 - .pc/.quilt_series | 1 - .pc/.version | 1 - 3 files changed, 3 deletions(-) delete mode 100644 .pc/.quilt_patches delete mode 100644 .pc/.quilt_series delete mode 100644 .pc/.version diff --git a/.pc/.quilt_patches b/.pc/.quilt_patches deleted file mode 100644 index 6857a8d..0000000 --- a/.pc/.quilt_patches +++ /dev/null @@ -1 +0,0 @@ -debian/patches diff --git a/.pc/.quilt_series b/.pc/.quilt_series deleted file mode 100644 index c206706..0000000 --- a/.pc/.quilt_series +++ /dev/null @@ -1 +0,0 @@ -series diff --git a/.pc/.version b/.pc/.version deleted file mode 100644 index 0cfbf08..0000000 --- a/.pc/.version +++ /dev/null @@ -1 +0,0 @@ -2 -- cgit v1.2.3 From e7ece066b19a1a92dacfeb6654713321c8b91812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 15 Jul 2018 17:48:13 +0200 Subject: Remove obsolete /etc/hotplug/usb/Argyll.usermap --- debian/argyll.install | 1 - debian/changelog | 1 + debian/maintscript | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 debian/maintscript diff --git a/debian/argyll.install b/debian/argyll.install index 0b1afee..731397a 100644 --- a/debian/argyll.install +++ b/debian/argyll.install @@ -1,3 +1,2 @@ usb/55-Argyll.rules lib/udev/rules.d/ -usb/Argyll.usermap etc/hotplug/usb usr/bin/* diff --git a/debian/changelog b/debian/changelog index c9b311c..dcdc57c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,7 @@ argyll (2.0.1+repack-1) UNRELEASED; urgency=medium * New upstream release: - Refresh patches. * debian/copyright: Add copyright for numlib/quadprog.*. + * Remove obsolete /etc/hotplug/usb/Argyll.usermap (Closes: #885549). -- Jörg Frings-Fürst Wed, 11 Jul 2018 22:21:14 +0200 diff --git a/debian/maintscript b/debian/maintscript new file mode 100644 index 0000000..99b4d26 --- /dev/null +++ b/debian/maintscript @@ -0,0 +1 @@ +rm_conffile /etc/hotplug/usb/Argyll.usermap 2.0.1-1~ -- cgit v1.2.3 From 711b90e2fe8e1b842c3181a6909af1e432fe0fdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 15 Jul 2018 17:59:24 +0200 Subject: Add more typos to patches/0100_spelling.patch --- debian/changelog | 1 + debian/patches/0100_spelling.patch | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/debian/changelog b/debian/changelog index dcdc57c..5436b25 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,7 @@ argyll (2.0.1+repack-1) UNRELEASED; urgency=medium - Refresh patches. * debian/copyright: Add copyright for numlib/quadprog.*. * Remove obsolete /etc/hotplug/usb/Argyll.usermap (Closes: #885549). + * Add more typos to patches/0100_spelling.patch. -- Jörg Frings-Fürst Wed, 11 Jul 2018 22:21:14 +0200 diff --git a/debian/patches/0100_spelling.patch b/debian/patches/0100_spelling.patch index 1b7d8cb..04dc5e9 100644 --- a/debian/patches/0100_spelling.patch +++ b/debian/patches/0100_spelling.patch @@ -63,6 +63,15 @@ Index: trunk/spectro/spotread.c { comport = atoi(na); if (comport < 1 || comport > 40) usage("-c parameter %d out of range",comport); +@@ -526,7 +526,7 @@ int main(int argc, char *argv[]) { + /* Display type */ + } else if (argv[fa][1] == 'y') { + fa = nfa; +- if (na == NULL) usage("Paramater expected following -y"); ++ if (na == NULL) usage("Parameter expected following -y"); + ditype = na[0]; + if (ditype == '_' && na[1] != '\000') + ditype = ditype << 8 | na[1]; @@ -536,7 +536,7 @@ int main(int argc, char *argv[]) { } else if (argv[fa][1] == 'I') { @@ -1376,6 +1385,15 @@ Index: trunk/spectro/smcube.c p->gotcoms = 1; +@@ -768,7 +768,7 @@ smcube_interp_error(inst *pp, int ec) { + case SMCUBE_INT_THREADFAILED: + return "Starting diffuser position thread failed"; + case SMCUBE_INT_ILL_WRITE: +- return "Attemp to write to factory calibration"; ++ return "Attempt to write to factory calibration"; + case SMCUBE_INT_WHITE_CALIB: + return "No valid white calibration"; + case SMCUBE_INT_BLACK_CALIB: @@ -1248,7 +1248,7 @@ smcube_get_idle_time(smcube *p, int *pit itime = read_ORD16_be(buf + 4); @@ -1682,3 +1700,16 @@ Index: trunk/spectro/munki_imp.h #define MUNKI_INT_CAL_SAVE 0x65 /* Unable to save calibration to file */ #define MUNKI_INT_CAL_RESTORE 0x66 /* Unable to restore calibration from file */ #define MUNKI_INT_CAL_TOUCH 0x67 /* Unable to touch calibration file */ +Index: trunk/spectro/spec2cie.c +=================================================================== +--- trunk.orig/spectro/spec2cie.c ++++ trunk/spectro/spec2cie.c +@@ -215,7 +215,7 @@ main(int argc, char *argv[]) + calstdi = xcalstd_gmdi; + calstdo = xcalstd_xrdi; + } else { +- //usage("Paramater after -A '%c%c' not recognized",na[0],na[1]); ++ //usage("Parameter after -A '%c%c' not recognized",na[0],na[1]); + usage(); + } + } -- cgit v1.2.3