From a476559758ceb3700d9bf80911a3b1e87ac5cbf8 Mon Sep 17 00:00:00 2001 From: Roy Date: Mon, 3 Oct 2022 15:27:16 +0300 Subject: Use Lubricant Transform --- .../ViewModels/ColorConversionViewVM.cs | 2 + .../Tango.MachineStudio.RML/Views/RmlView.xaml | 1 + Software/Visual_Studio/Tango.BL/DTO/RmlDTOBase.cs | 8 + .../Visual_Studio/Tango.BL/Entities/RmlBase.cs | 38 +++++ .../Tango.ColorConversion/DefaultColorConverter.cs | 8 + Software/Visual_Studio/Tango.DAL.Remote/DB/RML.cs | 1 + .../Tango.DAL.Remote/DB/RemoteADO.edmx | 3 + .../Tango.DAL.Remote/DB/RemoteADO.edmx.diagram | 178 ++++++++++----------- .../Tango.PMR/ColorLab/ConversionInput.cs | 35 +++- .../Tango.PMR/ColorLab/GradientConversionInput.cs | 37 ++++- .../Tango.PMR/ColorLab/OutOfGamutInput.cs | 37 ++++- .../ColorLab/RecommendedProcessTableInput.cs | 37 ++++- .../SQLExaminer/Configurations/OverrideData.xml | Bin 93812 -> 93918 bytes 13 files changed, 281 insertions(+), 104 deletions(-) (limited to 'Software/Visual_Studio') diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorConversionViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorConversionViewVM.cs index 0882d43e0..ca3c3e322 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorConversionViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorConversionViewVM.cs @@ -245,6 +245,7 @@ namespace Tango.MachineStudio.RML.ViewModels input.ThreadB = RML.WhitePointB; input.UseLightInks = RML.UseLightInks; + input.UseLubricantTransform = RML.UseLubricantTransform; input.VMax = RML.VMax; //Validate calibration data @@ -383,6 +384,7 @@ namespace Tango.MachineStudio.RML.ViewModels input.ThreadB = RML.WhitePointB; input.UseLightInks = RML.UseLightInks; + input.UseLubricantTransform = RML.UseLubricantTransform; input.VMax = RML.VMax; foreach (var vm in LiquidsCalibrationData.Where(x => x.LiquidType.HasPigment)) diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlView.xaml index 7e3b4fa4a..08af47ef4 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlView.xaml @@ -267,6 +267,7 @@ Enable Gradient Generation Use Light Inks + Use Lubricant Transform diff --git a/Software/Visual_Studio/Tango.BL/DTO/RmlDTOBase.cs b/Software/Visual_Studio/Tango.BL/DTO/RmlDTOBase.cs index be6c9486f..e3b9f676c 100644 --- a/Software/Visual_Studio/Tango.BL/DTO/RmlDTOBase.cs +++ b/Software/Visual_Studio/Tango.BL/DTO/RmlDTOBase.cs @@ -269,6 +269,14 @@ namespace Tango.BL.DTO get; set; } + /// + /// use lubricant transform + /// + public Boolean UseLubricantTransform + { + get; set; + } + /// /// head type /// diff --git a/Software/Visual_Studio/Tango.BL/Entities/RmlBase.cs b/Software/Visual_Studio/Tango.BL/Entities/RmlBase.cs index 5aac56248..17b29d691 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/RmlBase.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/RmlBase.cs @@ -71,6 +71,8 @@ namespace Tango.BL.Entities public event EventHandler UseLightInksChanged; + public event EventHandler UseLubricantTransformChanged; + public event EventHandler HeadTypeChanged; public event EventHandler QualificationLevelChanged; @@ -973,6 +975,33 @@ namespace Tango.BL.Entities } } + protected Boolean _uselubricanttransform; + + /// + /// Gets or sets the rmlbase use lubricant transform. + /// + + [Column("USE_LUBRICANT_TRANSFORM")] + + public Boolean UseLubricantTransform + { + get + { + return _uselubricanttransform; + } + + set + { + if (_uselubricanttransform != value) + { + _uselubricanttransform = value; + + OnUseLubricantTransformChanged(value); + + } + } + } + protected Int32 _headtype; /// @@ -2261,6 +2290,15 @@ namespace Tango.BL.Entities RaisePropertyChanged(nameof(UseLightInks)); } + /// + /// Called when the UseLubricantTransform has changed. + /// + protected virtual void OnUseLubricantTransformChanged(Boolean uselubricanttransform) + { + UseLubricantTransformChanged?.Invoke(this, uselubricanttransform); + RaisePropertyChanged(nameof(UseLubricantTransform)); + } + /// /// Called when the HeadType has changed. /// diff --git a/Software/Visual_Studio/Tango.ColorConversion/DefaultColorConverter.cs b/Software/Visual_Studio/Tango.ColorConversion/DefaultColorConverter.cs index cdb00a3ee..20e17bcc6 100644 --- a/Software/Visual_Studio/Tango.ColorConversion/DefaultColorConverter.cs +++ b/Software/Visual_Studio/Tango.ColorConversion/DefaultColorConverter.cs @@ -149,6 +149,8 @@ namespace Tango.ColorConversion conversionInput.UseLightInks = rml.UseLightInks && lightInksInstalled && useLightInks && settings.UseLightInks; + conversionInput.UseLubricantTransform = rml.UseLubricantTransform; + conversionInput.VMax = rml.VMax; conversionInput.ForwardData = ByteString.CopyFrom(rml.Cct.Data); @@ -337,6 +339,8 @@ namespace Tango.ColorConversion input.ThreadA = rml.WhitePointA; input.ThreadB = rml.WhitePointB; + input.UseLubricantTransform = rml.UseLubricantTransform; + input.InputCoordinates = new InputCoordinates(); if (stop.BrushColorSpace == ColorSpaces.RGB) @@ -553,6 +557,8 @@ namespace Tango.ColorConversion var settings = SettingsManager.Default.GetOrCreate(); input.UseLightInks = settings.UseLightInks && rml.UseLightInks && machine.LightInksInstalled && useLightInks; + input.UseLubricantTransform = rml.UseLubricantTransform; + //TODO: Do we need input.Vmax ?? (Mirta) foreach (var prTable in rml.GetActiveProcessGroup().ProcessParametersTables) @@ -802,6 +808,8 @@ namespace Tango.ColorConversion conversionInput.LubData = ByteString.CopyFrom(rml.Lub.Data); } + conversionInput.UseLubricantTransform = rml.UseLubricantTransform; + conversionInput.ThreadL = rml.WhitePointL; conversionInput.ThreadA = rml.WhitePointA; conversionInput.ThreadB = rml.WhitePointB; diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/RML.cs b/Software/Visual_Studio/Tango.DAL.Remote/DB/RML.cs index 5488e8c54..b1f71c687 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/RML.cs +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/RML.cs @@ -61,6 +61,7 @@ namespace Tango.DAL.Remote.DB public int COLOR_CONVERSION_VERSION { get; set; } public bool USE_COLOR_LIB_GRADIENTS { get; set; } public bool USE_LIGHT_INKS { get; set; } + public bool USE_LUBRICANT_TRANSFORM { get; set; } public int HEAD_TYPE { get; set; } public int QUALIFICATION_LEVEL { get; set; } public Nullable QUALIFICATION_DATE { get; set; } diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx index d52f40cab..dc068684b 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx @@ -1309,6 +1309,7 @@ + @@ -6823,6 +6824,7 @@ + @@ -10214,6 +10216,7 @@ + diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram index f48276400..5beb4e96f 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram @@ -5,102 +5,102 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - + + + + + + + + + + - - + + diff --git a/Software/Visual_Studio/Tango.PMR/ColorLab/ConversionInput.cs b/Software/Visual_Studio/Tango.PMR/ColorLab/ConversionInput.cs index 592297ca0..a1f1538d3 100644 --- a/Software/Visual_Studio/Tango.PMR/ColorLab/ConversionInput.cs +++ b/Software/Visual_Studio/Tango.PMR/ColorLab/ConversionInput.cs @@ -24,7 +24,7 @@ namespace Tango.PMR.ColorLab { string.Concat( "ChVDb252ZXJzaW9uSW5wdXQucHJvdG8SElRhbmdvLlBNUi5Db2xvckxhYhoW", "SW5wdXRDb29yZGluYXRlcy5wcm90bxoQQ29sb3JTcGFjZS5wcm90bxoSUHJv", - "Y2Vzc1JhbmdlLnByb3RvIrMDCg9Db252ZXJzaW9uSW5wdXQSDwoHVGhyZWFk", + "Y2Vzc1JhbmdlLnByb3RvItIDCg9Db252ZXJzaW9uSW5wdXQSDwoHVGhyZWFk", "TBgBIAEoARIPCgdUaHJlYWRBGAIgASgBEg8KB1RocmVhZEIYAyABKAESMgoK", "Q29sb3JTcGFjZRgEIAEoDjIeLlRhbmdvLlBNUi5Db2xvckxhYi5Db2xvclNw", "YWNlEj4KEElucHV0Q29vcmRpbmF0ZXMYBSABKAsyJC5UYW5nby5QTVIuQ29s", @@ -34,11 +34,12 @@ namespace Tango.PMR.ColorLab { "UmFuZ2VzGAsgAygLMiAuVGFuZ28uUE1SLkNvbG9yTGFiLlByb2Nlc3NSYW5n", "ZRIUCgxHZW5lcmF0ZUhpdmUYDCABKAgSFAoMVXNlTGlnaHRJbmtzGA0gASgI", "EgwKBFZNYXgYDiABKAESDwoHR2JkRGF0YRgPIAEoDBIPCgdMdWJEYXRhGBAg", - "ASgMQh4KHGNvbS50d2luZS50YW5nby5wbXIuY29sb3JsYWJiBnByb3RvMw==")); + "ASgMEh0KFVVzZUx1YnJpY2FudFRyYW5zZm9ybRgRIAEoCEIeChxjb20udHdp", + "bmUudGFuZ28ucG1yLmNvbG9ybGFiYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Tango.PMR.ColorLab.InputCoordinatesReflection.Descriptor, global::Tango.PMR.ColorLab.ColorSpaceReflection.Descriptor, global::Tango.PMR.ColorLab.ProcessRangeReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.ColorLab.ConversionInput), global::Tango.PMR.ColorLab.ConversionInput.Parser, new[]{ "ThreadL", "ThreadA", "ThreadB", "ColorSpace", "InputCoordinates", "ForwardData", "InverseData", "SegmentLength", "DeltaChroma", "DeltaL", "ProcessRanges", "GenerateHive", "UseLightInks", "VMax", "GbdData", "LubData" }, null, null, null) + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.ColorLab.ConversionInput), global::Tango.PMR.ColorLab.ConversionInput.Parser, new[]{ "ThreadL", "ThreadA", "ThreadB", "ColorSpace", "InputCoordinates", "ForwardData", "InverseData", "SegmentLength", "DeltaChroma", "DeltaL", "ProcessRanges", "GenerateHive", "UseLightInks", "VMax", "GbdData", "LubData", "UseLubricantTransform" }, null, null, null) })); } #endregion @@ -85,6 +86,7 @@ namespace Tango.PMR.ColorLab { vMax_ = other.vMax_; gbdData_ = other.gbdData_; lubData_ = other.lubData_; + useLubricantTransform_ = other.useLubricantTransform_; } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -267,6 +269,17 @@ namespace Tango.PMR.ColorLab { } } + /// Field number for the "UseLubricantTransform" field. + public const int UseLubricantTransformFieldNumber = 17; + private bool useLubricantTransform_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool UseLubricantTransform { + get { return useLubricantTransform_; } + set { + useLubricantTransform_ = value; + } + } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ConversionInput); @@ -296,6 +309,7 @@ namespace Tango.PMR.ColorLab { if (VMax != other.VMax) return false; if (GbdData != other.GbdData) return false; if (LubData != other.LubData) return false; + if (UseLubricantTransform != other.UseLubricantTransform) return false; return true; } @@ -318,6 +332,7 @@ namespace Tango.PMR.ColorLab { if (VMax != 0D) hash ^= VMax.GetHashCode(); if (GbdData.Length != 0) hash ^= GbdData.GetHashCode(); if (LubData.Length != 0) hash ^= LubData.GetHashCode(); + if (UseLubricantTransform != false) hash ^= UseLubricantTransform.GetHashCode(); return hash; } @@ -389,6 +404,10 @@ namespace Tango.PMR.ColorLab { output.WriteRawTag(130, 1); output.WriteBytes(LubData); } + if (UseLubricantTransform != false) { + output.WriteRawTag(136, 1); + output.WriteBool(UseLubricantTransform); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -440,6 +459,9 @@ namespace Tango.PMR.ColorLab { if (LubData.Length != 0) { size += 2 + pb::CodedOutputStream.ComputeBytesSize(LubData); } + if (UseLubricantTransform != false) { + size += 2 + 1; + } return size; } @@ -497,6 +519,9 @@ namespace Tango.PMR.ColorLab { if (other.LubData.Length != 0) { LubData = other.LubData; } + if (other.UseLubricantTransform != false) { + UseLubricantTransform = other.UseLubricantTransform; + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -574,6 +599,10 @@ namespace Tango.PMR.ColorLab { LubData = input.ReadBytes(); break; } + case 136: { + UseLubricantTransform = input.ReadBool(); + break; + } } } } diff --git a/Software/Visual_Studio/Tango.PMR/ColorLab/GradientConversionInput.cs b/Software/Visual_Studio/Tango.PMR/ColorLab/GradientConversionInput.cs index abb24ddb0..37e3642fa 100644 --- a/Software/Visual_Studio/Tango.PMR/ColorLab/GradientConversionInput.cs +++ b/Software/Visual_Studio/Tango.PMR/ColorLab/GradientConversionInput.cs @@ -24,19 +24,20 @@ namespace Tango.PMR.ColorLab { string.Concat( "Ch1HcmFkaWVudENvbnZlcnNpb25JbnB1dC5wcm90bxISVGFuZ28uUE1SLkNv", "bG9yTGFiGhJQcm9jZXNzUmFuZ2UucHJvdG8aEUlucHV0TGlxdWlkLnByb3Rv", - "GhdHcmFkaWVudElucHV0U3RvcC5wcm90byLAAgoXR3JhZGllbnRDb252ZXJz", + "GhdHcmFkaWVudElucHV0U3RvcC5wcm90byLfAgoXR3JhZGllbnRDb252ZXJz", "aW9uSW5wdXQSDwoHVGhyZWFkTBgBIAEoARIPCgdUaHJlYWRBGAIgASgBEg8K", "B1RocmVhZEIYAyABKAESEwoLRm9yd2FyZERhdGEYBCABKAwSFQoNU2VnbWVu", "dExlbmd0aBgFIAEoARI0CgVTdG9wcxgGIAMoCzIlLlRhbmdvLlBNUi5Db2xv", "ckxhYi5HcmFkaWVudElucHV0U3RvcBI1CgxJbnB1dExpcXVpZHMYByADKAsy", "Hy5UYW5nby5QTVIuQ29sb3JMYWIuSW5wdXRMaXF1aWQSNwoNUHJvY2Vzc1Jh", "bmdlcxgIIAMoCzIgLlRhbmdvLlBNUi5Db2xvckxhYi5Qcm9jZXNzUmFuZ2US", - "DwoHR2JkRGF0YRgJIAEoDBIPCgdMdWJEYXRhGAogASgMQh4KHGNvbS50d2lu", - "ZS50YW5nby5wbXIuY29sb3JsYWJiBnByb3RvMw==")); + "DwoHR2JkRGF0YRgJIAEoDBIPCgdMdWJEYXRhGAogASgMEh0KFVVzZUx1YnJp", + "Y2FudFRyYW5zZm9ybRgLIAEoCEIeChxjb20udHdpbmUudGFuZ28ucG1yLmNv", + "bG9ybGFiYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Tango.PMR.ColorLab.ProcessRangeReflection.Descriptor, global::Tango.PMR.ColorLab.InputLiquidReflection.Descriptor, global::Tango.PMR.ColorLab.GradientInputStopReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.ColorLab.GradientConversionInput), global::Tango.PMR.ColorLab.GradientConversionInput.Parser, new[]{ "ThreadL", "ThreadA", "ThreadB", "ForwardData", "SegmentLength", "Stops", "InputLiquids", "ProcessRanges", "GbdData", "LubData" }, null, null, null) + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.ColorLab.GradientConversionInput), global::Tango.PMR.ColorLab.GradientConversionInput.Parser, new[]{ "ThreadL", "ThreadA", "ThreadB", "ForwardData", "SegmentLength", "Stops", "InputLiquids", "ProcessRanges", "GbdData", "LubData", "UseLubricantTransform" }, null, null, null) })); } #endregion @@ -77,6 +78,7 @@ namespace Tango.PMR.ColorLab { processRanges_ = other.processRanges_.Clone(); gbdData_ = other.gbdData_; lubData_ = other.lubData_; + useLubricantTransform_ = other.useLubricantTransform_; } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -191,6 +193,17 @@ namespace Tango.PMR.ColorLab { } } + /// Field number for the "UseLubricantTransform" field. + public const int UseLubricantTransformFieldNumber = 11; + private bool useLubricantTransform_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool UseLubricantTransform { + get { return useLubricantTransform_; } + set { + useLubricantTransform_ = value; + } + } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as GradientConversionInput); @@ -214,6 +227,7 @@ namespace Tango.PMR.ColorLab { if(!processRanges_.Equals(other.processRanges_)) return false; if (GbdData != other.GbdData) return false; if (LubData != other.LubData) return false; + if (UseLubricantTransform != other.UseLubricantTransform) return false; return true; } @@ -230,6 +244,7 @@ namespace Tango.PMR.ColorLab { hash ^= processRanges_.GetHashCode(); if (GbdData.Length != 0) hash ^= GbdData.GetHashCode(); if (LubData.Length != 0) hash ^= LubData.GetHashCode(); + if (UseLubricantTransform != false) hash ^= UseLubricantTransform.GetHashCode(); return hash; } @@ -271,6 +286,10 @@ namespace Tango.PMR.ColorLab { output.WriteRawTag(82); output.WriteBytes(LubData); } + if (UseLubricantTransform != false) { + output.WriteRawTag(88); + output.WriteBool(UseLubricantTransform); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -300,6 +319,9 @@ namespace Tango.PMR.ColorLab { if (LubData.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeBytesSize(LubData); } + if (UseLubricantTransform != false) { + size += 1 + 1; + } return size; } @@ -332,6 +354,9 @@ namespace Tango.PMR.ColorLab { if (other.LubData.Length != 0) { LubData = other.LubData; } + if (other.UseLubricantTransform != false) { + UseLubricantTransform = other.UseLubricantTransform; + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -382,6 +407,10 @@ namespace Tango.PMR.ColorLab { LubData = input.ReadBytes(); break; } + case 88: { + UseLubricantTransform = input.ReadBool(); + break; + } } } } diff --git a/Software/Visual_Studio/Tango.PMR/ColorLab/OutOfGamutInput.cs b/Software/Visual_Studio/Tango.PMR/ColorLab/OutOfGamutInput.cs index e56cf37fe..ebde255c5 100644 --- a/Software/Visual_Studio/Tango.PMR/ColorLab/OutOfGamutInput.cs +++ b/Software/Visual_Studio/Tango.PMR/ColorLab/OutOfGamutInput.cs @@ -24,18 +24,19 @@ namespace Tango.PMR.ColorLab { string.Concat( "ChVPdXRPZkdhbXV0SW5wdXQucHJvdG8SElRhbmdvLlBNUi5Db2xvckxhYhoW", "SW5wdXRDb29yZGluYXRlcy5wcm90bxoQQ29sb3JTcGFjZS5wcm90bxoSUHJv", - "Y2Vzc1JhbmdlLnByb3RvIqgCCg9PdXRPZkdhbXV0SW5wdXQSDwoHVGhyZWFk", + "Y2Vzc1JhbmdlLnByb3RvIscCCg9PdXRPZkdhbXV0SW5wdXQSDwoHVGhyZWFk", "TBgBIAEoARIPCgdUaHJlYWRBGAIgASgBEg8KB1RocmVhZEIYAyABKAESMgoK", "Q29sb3JTcGFjZRgEIAEoDjIeLlRhbmdvLlBNUi5Db2xvckxhYi5Db2xvclNw", "YWNlEj4KEElucHV0Q29vcmRpbmF0ZXMYBSABKAsyJC5UYW5nby5QTVIuQ29s", "b3JMYWIuSW5wdXRDb29yZGluYXRlcxITCgtGb3J3YXJkRGF0YRgGIAEoDBI3", "Cg1Qcm9jZXNzUmFuZ2VzGAcgAygLMiAuVGFuZ28uUE1SLkNvbG9yTGFiLlBy", - "b2Nlc3NSYW5nZRIPCgdHYmREYXRhGAggASgMEg8KB0x1YkRhdGEYCSABKAxC", - "HgocY29tLnR3aW5lLnRhbmdvLnBtci5jb2xvcmxhYmIGcHJvdG8z")); + "b2Nlc3NSYW5nZRIPCgdHYmREYXRhGAggASgMEg8KB0x1YkRhdGEYCSABKAwS", + "HQoVVXNlTHVicmljYW50VHJhbnNmb3JtGAogASgIQh4KHGNvbS50d2luZS50", + "YW5nby5wbXIuY29sb3JsYWJiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Tango.PMR.ColorLab.InputCoordinatesReflection.Descriptor, global::Tango.PMR.ColorLab.ColorSpaceReflection.Descriptor, global::Tango.PMR.ColorLab.ProcessRangeReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.ColorLab.OutOfGamutInput), global::Tango.PMR.ColorLab.OutOfGamutInput.Parser, new[]{ "ThreadL", "ThreadA", "ThreadB", "ColorSpace", "InputCoordinates", "ForwardData", "ProcessRanges", "GbdData", "LubData" }, null, null, null) + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.ColorLab.OutOfGamutInput), global::Tango.PMR.ColorLab.OutOfGamutInput.Parser, new[]{ "ThreadL", "ThreadA", "ThreadB", "ColorSpace", "InputCoordinates", "ForwardData", "ProcessRanges", "GbdData", "LubData", "UseLubricantTransform" }, null, null, null) })); } #endregion @@ -75,6 +76,7 @@ namespace Tango.PMR.ColorLab { processRanges_ = other.processRanges_.Clone(); gbdData_ = other.gbdData_; lubData_ = other.lubData_; + useLubricantTransform_ = other.useLubricantTransform_; } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -180,6 +182,17 @@ namespace Tango.PMR.ColorLab { } } + /// Field number for the "UseLubricantTransform" field. + public const int UseLubricantTransformFieldNumber = 10; + private bool useLubricantTransform_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool UseLubricantTransform { + get { return useLubricantTransform_; } + set { + useLubricantTransform_ = value; + } + } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as OutOfGamutInput); @@ -202,6 +215,7 @@ namespace Tango.PMR.ColorLab { if(!processRanges_.Equals(other.processRanges_)) return false; if (GbdData != other.GbdData) return false; if (LubData != other.LubData) return false; + if (UseLubricantTransform != other.UseLubricantTransform) return false; return true; } @@ -217,6 +231,7 @@ namespace Tango.PMR.ColorLab { hash ^= processRanges_.GetHashCode(); if (GbdData.Length != 0) hash ^= GbdData.GetHashCode(); if (LubData.Length != 0) hash ^= LubData.GetHashCode(); + if (UseLubricantTransform != false) hash ^= UseLubricantTransform.GetHashCode(); return hash; } @@ -260,6 +275,10 @@ namespace Tango.PMR.ColorLab { output.WriteRawTag(74); output.WriteBytes(LubData); } + if (UseLubricantTransform != false) { + output.WriteRawTag(80); + output.WriteBool(UseLubricantTransform); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -290,6 +309,9 @@ namespace Tango.PMR.ColorLab { if (LubData.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeBytesSize(LubData); } + if (UseLubricantTransform != false) { + size += 1 + 1; + } return size; } @@ -326,6 +348,9 @@ namespace Tango.PMR.ColorLab { if (other.LubData.Length != 0) { LubData = other.LubData; } + if (other.UseLubricantTransform != false) { + UseLubricantTransform = other.UseLubricantTransform; + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -375,6 +400,10 @@ namespace Tango.PMR.ColorLab { LubData = input.ReadBytes(); break; } + case 80: { + UseLubricantTransform = input.ReadBool(); + break; + } } } } diff --git a/Software/Visual_Studio/Tango.PMR/ColorLab/RecommendedProcessTableInput.cs b/Software/Visual_Studio/Tango.PMR/ColorLab/RecommendedProcessTableInput.cs index 8384769a6..4e5a52d8d 100644 --- a/Software/Visual_Studio/Tango.PMR/ColorLab/RecommendedProcessTableInput.cs +++ b/Software/Visual_Studio/Tango.PMR/ColorLab/RecommendedProcessTableInput.cs @@ -24,19 +24,20 @@ namespace Tango.PMR.ColorLab { string.Concat( "CiJSZWNvbW1lbmRlZFByb2Nlc3NUYWJsZUlucHV0LnByb3RvEhJUYW5nby5Q", "TVIuQ29sb3JMYWIaElByb2Nlc3NSYW5nZS5wcm90bxoRSW5wdXRMaXF1aWQu", - "cHJvdG8aF0dyYWRpZW50SW5wdXRTdG9wLnByb3RvIsQCChxSZWNvbW1lbmRl", + "cHJvdG8aF0dyYWRpZW50SW5wdXRTdG9wLnByb3RvIuMCChxSZWNvbW1lbmRl", "ZFByb2Nlc3NUYWJsZUlucHV0Eg8KB1RocmVhZEwYASABKAESDwoHVGhyZWFk", "QRgCIAEoARIPCgdUaHJlYWRCGAMgASgBEhMKC0ZvcndhcmREYXRhGAQgASgM", "EjQKBVN0b3BzGAUgAygLMiUuVGFuZ28uUE1SLkNvbG9yTGFiLkdyYWRpZW50", "SW5wdXRTdG9wEjUKDElucHV0TGlxdWlkcxgGIAMoCzIfLlRhbmdvLlBNUi5D", "b2xvckxhYi5JbnB1dExpcXVpZBI3Cg1Qcm9jZXNzUmFuZ2VzGAcgAygLMiAu", "VGFuZ28uUE1SLkNvbG9yTGFiLlByb2Nlc3NSYW5nZRIUCgxVc2VMaWdodElu", - "a3MYCCABKAgSDwoHR2JkRGF0YRgJIAEoDBIPCgdMdWJEYXRhGAogASgMQh4K", - "HGNvbS50d2luZS50YW5nby5wbXIuY29sb3JsYWJiBnByb3RvMw==")); + "a3MYCCABKAgSDwoHR2JkRGF0YRgJIAEoDBIPCgdMdWJEYXRhGAogASgMEh0K", + "FVVzZUx1YnJpY2FudFRyYW5zZm9ybRgLIAEoCEIeChxjb20udHdpbmUudGFu", + "Z28ucG1yLmNvbG9ybGFiYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Tango.PMR.ColorLab.ProcessRangeReflection.Descriptor, global::Tango.PMR.ColorLab.InputLiquidReflection.Descriptor, global::Tango.PMR.ColorLab.GradientInputStopReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.ColorLab.RecommendedProcessTableInput), global::Tango.PMR.ColorLab.RecommendedProcessTableInput.Parser, new[]{ "ThreadL", "ThreadA", "ThreadB", "ForwardData", "Stops", "InputLiquids", "ProcessRanges", "UseLightInks", "GbdData", "LubData" }, null, null, null) + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.ColorLab.RecommendedProcessTableInput), global::Tango.PMR.ColorLab.RecommendedProcessTableInput.Parser, new[]{ "ThreadL", "ThreadA", "ThreadB", "ForwardData", "Stops", "InputLiquids", "ProcessRanges", "UseLightInks", "GbdData", "LubData", "UseLubricantTransform" }, null, null, null) })); } #endregion @@ -77,6 +78,7 @@ namespace Tango.PMR.ColorLab { useLightInks_ = other.useLightInks_; gbdData_ = other.gbdData_; lubData_ = other.lubData_; + useLubricantTransform_ = other.useLubricantTransform_; } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -191,6 +193,17 @@ namespace Tango.PMR.ColorLab { } } + /// Field number for the "UseLubricantTransform" field. + public const int UseLubricantTransformFieldNumber = 11; + private bool useLubricantTransform_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool UseLubricantTransform { + get { return useLubricantTransform_; } + set { + useLubricantTransform_ = value; + } + } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as RecommendedProcessTableInput); @@ -214,6 +227,7 @@ namespace Tango.PMR.ColorLab { if (UseLightInks != other.UseLightInks) return false; if (GbdData != other.GbdData) return false; if (LubData != other.LubData) return false; + if (UseLubricantTransform != other.UseLubricantTransform) return false; return true; } @@ -230,6 +244,7 @@ namespace Tango.PMR.ColorLab { if (UseLightInks != false) hash ^= UseLightInks.GetHashCode(); if (GbdData.Length != 0) hash ^= GbdData.GetHashCode(); if (LubData.Length != 0) hash ^= LubData.GetHashCode(); + if (UseLubricantTransform != false) hash ^= UseLubricantTransform.GetHashCode(); return hash; } @@ -271,6 +286,10 @@ namespace Tango.PMR.ColorLab { output.WriteRawTag(82); output.WriteBytes(LubData); } + if (UseLubricantTransform != false) { + output.WriteRawTag(88); + output.WriteBool(UseLubricantTransform); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -300,6 +319,9 @@ namespace Tango.PMR.ColorLab { if (LubData.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeBytesSize(LubData); } + if (UseLubricantTransform != false) { + size += 1 + 1; + } return size; } @@ -332,6 +354,9 @@ namespace Tango.PMR.ColorLab { if (other.LubData.Length != 0) { LubData = other.LubData; } + if (other.UseLubricantTransform != false) { + UseLubricantTransform = other.UseLubricantTransform; + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -382,6 +407,10 @@ namespace Tango.PMR.ColorLab { LubData = input.ReadBytes(); break; } + case 88: { + UseLubricantTransform = input.ReadBool(); + break; + } } } } diff --git a/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/OverrideData.xml b/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/OverrideData.xml index d89a2de1f..9e3db5c20 100644 Binary files a/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/OverrideData.xml and b/Software/Visual_Studio/Tango.SQLExaminer/SQLExaminer/Configurations/OverrideData.xml differ -- cgit v1.3.1 From 85b307bcb943872c94b771ab0f0ea2c08c2a5af4 Mon Sep 17 00:00:00 2001 From: Mirta Date: Tue, 11 Oct 2022 07:22:48 +0300 Subject: Features: 7224 - Gamut Boundary Descriptor 7226 - ImproveK Ink Logic 6435 - Improve LI logic 6434 - Allow for mixed Calibration Types --- .../PMR/ColorLab/ConversionInput.pb-c.c | 32 +- .../PMR/ColorLab/ConversionInput.pb-c.h | 6 +- .../PMR/ColorLab/GradientConversionInput.pb-c.c | 32 +- .../PMR/ColorLab/GradientConversionInput.pb-c.h | 6 +- .../PMR/ColorLab/OutOfGamutInput.pb-c.c | 32 +- .../PMR/ColorLab/OutOfGamutInput.pb-c.h | 6 +- .../ColorLab/RecommendedProcessTableInput.pb-c.c | 32 +- .../ColorLab/RecommendedProcessTableInput.pb-c.h | 6 +- .../ColorLib/Tango.ColorLib_v6/ColorConverter.cpp | 1138 ++++++++++++-------- .../ColorLib/Tango.ColorLib_v6/ColorConverter.h | 26 +- .../ColorLib/Tango.ColorLib_v6/ForwardModel.cpp | 18 +- .../ColorLib/Tango.ColorLib_v6/ForwardModel.h | 2 +- .../Tango.ColorLib_v6/Utils/ColorConvert.cpp | 41 +- .../Tango.ColorLib_v6/Utils/ColorConvert.h | 2 + .../Tango.ColorLib_v6/Utils/ColorTable.cpp | 234 ++-- .../ColorLib/Tango.ColorLib_v6/Utils/ColorTable.h | 7 +- .../Tango.ColorLib_v6/Utils/ColorTransf.cpp | 30 +- .../ColorLib/Tango.ColorLib_v6/Utils/ColorTransf.h | 3 - .../ColorLib/Tango.ColorLib_v6/Utils/GBD.cpp | 99 +- .../ColorLib/Tango.ColorLib_v6/Utils/GBD.h | 13 +- .../ColorLib/Tango.ColorLib_v6/Utils/LevMar.cpp | 2 +- .../ColorLib/Tango.ColorLib_v6/Utils/LevMar.h | 1 - .../Tango.ColorLib_v6/Utils/NDInterpUtils.cpp | 27 +- .../Tango.ColorLib_v6/Utils/NDInterpUtils.h | 6 +- .../Tango.ColorLib_v6/Utils/ObjectiveFunction.cpp | 1 + .../Tango.ColorLib_v6/Utils/ObjectiveFunction.h | 1 + 26 files changed, 1182 insertions(+), 621 deletions(-) (limited to 'Software/Visual_Studio') diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/ConversionInput.pb-c.c b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/ConversionInput.pb-c.c index 0defc9edf..92f60a719 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/ConversionInput.pb-c.c +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/ConversionInput.pb-c.c @@ -52,7 +52,7 @@ void conversion_input__free_unpacked assert(message->base.descriptor == &conversion_input__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } -static const ProtobufCFieldDescriptor conversion_input__field_descriptors[14] = +static const ProtobufCFieldDescriptor conversion_input__field_descriptors[16] = { { "ThreadL", @@ -222,15 +222,41 @@ static const ProtobufCFieldDescriptor conversion_input__field_descriptors[14] = 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, + { + "GbdData", + 15, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_BYTES, + offsetof(ConversionInput, has_gbddata), + offsetof(ConversionInput, gbddata), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "LubData", + 16, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_BYTES, + offsetof(ConversionInput, has_lubdata), + offsetof(ConversionInput, lubdata), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned conversion_input__field_indices_by_name[] = { 3, /* field[3] = ColorSpace */ 8, /* field[8] = DeltaChroma */ 9, /* field[9] = DeltaL */ 5, /* field[5] = ForwardData */ + 14, /* field[14] = GbdData */ 11, /* field[11] = GenerateHive */ 4, /* field[4] = InputCoordinates */ 6, /* field[6] = InverseData */ + 15, /* field[15] = LubData */ 10, /* field[10] = ProcessRanges */ 7, /* field[7] = SegmentLength */ 1, /* field[1] = ThreadA */ @@ -242,7 +268,7 @@ static const unsigned conversion_input__field_indices_by_name[] = { static const ProtobufCIntRange conversion_input__number_ranges[1 + 1] = { { 1, 0 }, - { 0, 14 } + { 0, 16 } }; const ProtobufCMessageDescriptor conversion_input__descriptor = { @@ -252,7 +278,7 @@ const ProtobufCMessageDescriptor conversion_input__descriptor = "ConversionInput", "", sizeof(ConversionInput), - 14, + 16, conversion_input__field_descriptors, conversion_input__field_indices_by_name, 1, conversion_input__number_ranges, diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/ConversionInput.pb-c.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/ConversionInput.pb-c.h index 794ddaaac..5f03aeceb 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/ConversionInput.pb-c.h +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/ConversionInput.pb-c.h @@ -56,10 +56,14 @@ struct _ConversionInput protobuf_c_boolean uselightinks; protobuf_c_boolean has_vmax; double vmax; + protobuf_c_boolean has_gbddata; + ProtobufCBinaryData gbddata; + protobuf_c_boolean has_lubdata; + ProtobufCBinaryData lubdata; }; #define CONVERSION_INPUT__INIT \ { PROTOBUF_C_MESSAGE_INIT (&conversion_input__descriptor) \ - , 0, 0, 0, 0, 0, 0, 0, COLOR_SPACE__Volume, NULL, 0, {0,NULL}, 0, {0,NULL}, 0, 0, 0, 0, 0, 0, 0,NULL, 0, 0, 0, 0, 0, 0 } + , 0, 0, 0, 0, 0, 0, 0, COLOR_SPACE__Volume, NULL, 0, {0,NULL}, 0, {0,NULL}, 0, 0, 0, 0, 0, 0, 0,NULL, 0, 0, 0, 0, 0, 0, 0, {0,NULL}, 0, {0,NULL} } /* ConversionInput methods */ diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/GradientConversionInput.pb-c.c b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/GradientConversionInput.pb-c.c index cd3d79ab6..3b4f011b3 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/GradientConversionInput.pb-c.c +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/GradientConversionInput.pb-c.c @@ -52,7 +52,7 @@ void gradient_conversion_input__free_unpacked assert(message->base.descriptor == &gradient_conversion_input__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } -static const ProtobufCFieldDescriptor gradient_conversion_input__field_descriptors[8] = +static const ProtobufCFieldDescriptor gradient_conversion_input__field_descriptors[10] = { { "ThreadL", @@ -150,10 +150,36 @@ static const ProtobufCFieldDescriptor gradient_conversion_input__field_descripto 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, + { + "GbdData", + 9, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_BYTES, + offsetof(GradientConversionInput, has_gbddata), + offsetof(GradientConversionInput, gbddata), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "LubData", + 10, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_BYTES, + offsetof(GradientConversionInput, has_lubdata), + offsetof(GradientConversionInput, lubdata), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned gradient_conversion_input__field_indices_by_name[] = { 3, /* field[3] = ForwardData */ + 8, /* field[8] = GbdData */ 6, /* field[6] = InputLiquids */ + 9, /* field[9] = LubData */ 7, /* field[7] = ProcessRanges */ 4, /* field[4] = SegmentLength */ 5, /* field[5] = Stops */ @@ -164,7 +190,7 @@ static const unsigned gradient_conversion_input__field_indices_by_name[] = { static const ProtobufCIntRange gradient_conversion_input__number_ranges[1 + 1] = { { 1, 0 }, - { 0, 8 } + { 0, 10 } }; const ProtobufCMessageDescriptor gradient_conversion_input__descriptor = { @@ -174,7 +200,7 @@ const ProtobufCMessageDescriptor gradient_conversion_input__descriptor = "GradientConversionInput", "", sizeof(GradientConversionInput), - 8, + 10, gradient_conversion_input__field_descriptors, gradient_conversion_input__field_indices_by_name, 1, gradient_conversion_input__number_ranges, diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/GradientConversionInput.pb-c.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/GradientConversionInput.pb-c.h index e38d1316c..fa9007907 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/GradientConversionInput.pb-c.h +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/GradientConversionInput.pb-c.h @@ -45,10 +45,14 @@ struct _GradientConversionInput InputLiquid **inputliquids; size_t n_processranges; ProcessRange **processranges; + protobuf_c_boolean has_gbddata; + ProtobufCBinaryData gbddata; + protobuf_c_boolean has_lubdata; + ProtobufCBinaryData lubdata; }; #define GRADIENT_CONVERSION_INPUT__INIT \ { PROTOBUF_C_MESSAGE_INIT (&gradient_conversion_input__descriptor) \ - , 0, 0, 0, 0, 0, 0, 0, {0,NULL}, 0, 0, 0,NULL, 0,NULL, 0,NULL } + , 0, 0, 0, 0, 0, 0, 0, {0,NULL}, 0, 0, 0,NULL, 0,NULL, 0,NULL, 0, {0,NULL}, 0, {0,NULL} } /* GradientConversionInput methods */ diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/OutOfGamutInput.pb-c.c b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/OutOfGamutInput.pb-c.c index e51e63783..115985567 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/OutOfGamutInput.pb-c.c +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/OutOfGamutInput.pb-c.c @@ -52,7 +52,7 @@ void out_of_gamut_input__free_unpacked assert(message->base.descriptor == &out_of_gamut_input__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } -static const ProtobufCFieldDescriptor out_of_gamut_input__field_descriptors[7] = +static const ProtobufCFieldDescriptor out_of_gamut_input__field_descriptors[9] = { { "ThreadL", @@ -138,11 +138,37 @@ static const ProtobufCFieldDescriptor out_of_gamut_input__field_descriptors[7] = 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, + { + "GbdData", + 8, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_BYTES, + offsetof(OutOfGamutInput, has_gbddata), + offsetof(OutOfGamutInput, gbddata), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "LubData", + 9, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_BYTES, + offsetof(OutOfGamutInput, has_lubdata), + offsetof(OutOfGamutInput, lubdata), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned out_of_gamut_input__field_indices_by_name[] = { 3, /* field[3] = ColorSpace */ 5, /* field[5] = ForwardData */ + 7, /* field[7] = GbdData */ 4, /* field[4] = InputCoordinates */ + 8, /* field[8] = LubData */ 6, /* field[6] = ProcessRanges */ 1, /* field[1] = ThreadA */ 2, /* field[2] = ThreadB */ @@ -151,7 +177,7 @@ static const unsigned out_of_gamut_input__field_indices_by_name[] = { static const ProtobufCIntRange out_of_gamut_input__number_ranges[1 + 1] = { { 1, 0 }, - { 0, 7 } + { 0, 9 } }; const ProtobufCMessageDescriptor out_of_gamut_input__descriptor = { @@ -161,7 +187,7 @@ const ProtobufCMessageDescriptor out_of_gamut_input__descriptor = "OutOfGamutInput", "", sizeof(OutOfGamutInput), - 7, + 9, out_of_gamut_input__field_descriptors, out_of_gamut_input__field_indices_by_name, 1, out_of_gamut_input__number_ranges, diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/OutOfGamutInput.pb-c.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/OutOfGamutInput.pb-c.h index bcaec7a85..4255f3b82 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/OutOfGamutInput.pb-c.h +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/OutOfGamutInput.pb-c.h @@ -42,10 +42,14 @@ struct _OutOfGamutInput ProtobufCBinaryData forwarddata; size_t n_processranges; ProcessRange **processranges; + protobuf_c_boolean has_gbddata; + ProtobufCBinaryData gbddata; + protobuf_c_boolean has_lubdata; + ProtobufCBinaryData lubdata; }; #define OUT_OF_GAMUT_INPUT__INIT \ { PROTOBUF_C_MESSAGE_INIT (&out_of_gamut_input__descriptor) \ - , 0, 0, 0, 0, 0, 0, 0, COLOR_SPACE__Volume, NULL, 0, {0,NULL}, 0,NULL } + , 0, 0, 0, 0, 0, 0, 0, COLOR_SPACE__Volume, NULL, 0, {0,NULL}, 0,NULL, 0, {0,NULL}, 0, {0,NULL} } /* OutOfGamutInput methods */ diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/RecommendedProcessTableInput.pb-c.c b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/RecommendedProcessTableInput.pb-c.c index 12a349283..1d4e52e7f 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/RecommendedProcessTableInput.pb-c.c +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/RecommendedProcessTableInput.pb-c.c @@ -52,7 +52,7 @@ void recommended_process_table_input__free_unpacked assert(message->base.descriptor == &recommended_process_table_input__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } -static const ProtobufCFieldDescriptor recommended_process_table_input__field_descriptors[8] = +static const ProtobufCFieldDescriptor recommended_process_table_input__field_descriptors[10] = { { "ThreadL", @@ -150,10 +150,36 @@ static const ProtobufCFieldDescriptor recommended_process_table_input__field_des 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, + { + "GbdData", + 9, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_BYTES, + offsetof(RecommendedProcessTableInput, has_gbddata), + offsetof(RecommendedProcessTableInput, gbddata), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "LubData", + 10, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_BYTES, + offsetof(RecommendedProcessTableInput, has_lubdata), + offsetof(RecommendedProcessTableInput, lubdata), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned recommended_process_table_input__field_indices_by_name[] = { 3, /* field[3] = ForwardData */ + 8, /* field[8] = GbdData */ 5, /* field[5] = InputLiquids */ + 9, /* field[9] = LubData */ 6, /* field[6] = ProcessRanges */ 4, /* field[4] = Stops */ 1, /* field[1] = ThreadA */ @@ -164,7 +190,7 @@ static const unsigned recommended_process_table_input__field_indices_by_name[] = static const ProtobufCIntRange recommended_process_table_input__number_ranges[1 + 1] = { { 1, 0 }, - { 0, 8 } + { 0, 10 } }; const ProtobufCMessageDescriptor recommended_process_table_input__descriptor = { @@ -174,7 +200,7 @@ const ProtobufCMessageDescriptor recommended_process_table_input__descriptor = "RecommendedProcessTableInput", "", sizeof(RecommendedProcessTableInput), - 8, + 10, recommended_process_table_input__field_descriptors, recommended_process_table_input__field_indices_by_name, 1, recommended_process_table_input__number_ranges, diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/RecommendedProcessTableInput.pb-c.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/RecommendedProcessTableInput.pb-c.h index 98b4e1613..393b50ddc 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/RecommendedProcessTableInput.pb-c.h +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v5/PMR/ColorLab/RecommendedProcessTableInput.pb-c.h @@ -45,10 +45,14 @@ struct _RecommendedProcessTableInput ProcessRange **processranges; protobuf_c_boolean has_uselightinks; protobuf_c_boolean uselightinks; + protobuf_c_boolean has_gbddata; + ProtobufCBinaryData gbddata; + protobuf_c_boolean has_lubdata; + ProtobufCBinaryData lubdata; }; #define RECOMMENDED_PROCESS_TABLE_INPUT__INIT \ { PROTOBUF_C_MESSAGE_INIT (&recommended_process_table_input__descriptor) \ - , 0, 0, 0, 0, 0, 0, 0, {0,NULL}, 0,NULL, 0,NULL, 0,NULL, 0, 0 } + , 0, 0, 0, 0, 0, 0, 0, {0,NULL}, 0,NULL, 0,NULL, 0,NULL, 0, 0, 0, {0,NULL}, 0, {0,NULL} } /* RecommendedProcessTableInput methods */ diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ColorConverter.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ColorConverter.cpp index 58e0237aa..406f7de0e 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ColorConverter.cpp +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ColorConverter.cpp @@ -41,6 +41,13 @@ #include #include +#ifdef MEMORY_TEST +#define _CRTDBG_MAP_ALLOC +#include +#include +#include +#endif + #ifdef _DEBUG #define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ ) // Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the @@ -64,33 +71,56 @@ #define maxPerRegion 100.0 #define GamutMinReg0 200 #define GamutMinReg1 300 +#define GamutD 1 +#define CCtable 0 //#define LowVolumeThreshold 0.5 //#define LowVolHalf LowVolumeThreshold/2 #define GradientEndThr 0.95 #define DilutionFactor 10 //#define LightInksThr 5 +// Changes April 2022 +//Eliminate stretching of Thread Inks to match Color Tables Inks +// m_CalibMode becomes obsolete +// Rounding of Inks will be performed outside of the Color Engine +//A tolerance to the Volume Limit will be added to take care of the effects of rounding +//The value of volume will be double precision without rounding + +bool sortbysec(const std::pair &a, + const std::pair &b) +{ + return (a.second < b.second); +} Tango::ColorLib::ColorConverter::ColorConverter() : m_CalibCurves(NULL), m_Conv02(NULL), m_maxNlPerCM(NULL), m_CTmaxNlPerCM(NULL), m_currentMaxNLPerCM(NULL), m_maxCalX(NULL), m_nInks(0), m_nVolumes(0), m_CalibMode(0), m_CalibGain(NULL), m_CalibOffset(NULL), - m_GradStops(NULL), m_nGradStops(0), m_colortable(NULL), m_ProcessRangesMaxP(NULL), + m_GradStops(NULL), m_nGradStops(0), m_ProcessRangesMaxP(NULL), m_ProcessRangesMinP(NULL), m_CurrentProcessRangesMax(NULL), m_CurrentProcessRangesMin(NULL), - m_nProcessRanges(0), //m_NormGamutRegionMaxLim(NULL), - m_GamutRegionMaxLim(NULL), - m_GamutRegionMinLim(NULL), m_forwardmodel(NULL), + m_nProcessRanges(0), m_GamutRegionMaxLim(NULL), m_ThreadGBD(NULL), + m_GamutRegionMinLim(NULL), m_ObjFunction(NULL), m_Minimize(NULL), m_UseLightInks(false), m_InkNames(NULL), m_LightInksThr (0.0), - m_LowVolumeThreshold(0.0), m_LowVolHalf(0.0) + m_LowVolumeThreshold(0.0), m_LowVolHalf(0.0), m_Has_GBD(false) //, m_NormFactor(0.0), m_InvnormFactor(0.0) { m_whitepointLab.Set(-1, -1, -1); m_whitepointXYZ_Strip.Set(-1, -1, -1); m_WP.Set(-1, -1, -1); + m_colortable = new ColorTable(); +#ifdef MEMORY_TEST + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG); +#endif // MEMORY_TEST } Tango::ColorLib::ColorConverter::~ColorConverter() { + + if (m_colortable != NULL) + { + delete m_colortable; + m_colortable = NULL; + } if (m_Conv02 != NULL) { delete m_Conv02; @@ -106,10 +136,20 @@ Tango::ColorLib::ColorConverter::~ColorConverter() delete[] m_GradStops; m_GradStops = NULL; } - if (m_colortable != NULL) + if (m_CalibGain != NULL) { - delete m_colortable; - m_colortable = NULL; + delete[] m_CalibGain; + m_CalibGain = NULL; + } + if (m_CalibOffset != NULL) + { + delete[] m_CalibOffset; + m_CalibOffset = NULL; + } + if (m_ThreadGBD != NULL) + { + delete m_ThreadGBD; + m_ThreadGBD = NULL; } /* if (m_NormGamutRegionMaxLim != NULL) { @@ -134,23 +174,14 @@ Tango::ColorLib::ColorConverter::~ColorConverter() if (m_ProcessRangesMinP != NULL) { delete[] m_ProcessRangesMinP; - m_ProcessRangesMaxP = NULL; + m_ProcessRangesMinP = NULL; } if (m_InkNames != NULL) { delete[] m_InkNames; m_InkNames = NULL; } - if (m_CalibGain != NULL) - { - delete[] m_CalibGain; - m_CalibGain = NULL; - } - if (m_CalibOffset != NULL) - { - delete[] m_CalibOffset; - m_CalibOffset = NULL; - } + if (m_maxCalX != NULL) { delete[] m_maxCalX; @@ -166,7 +197,19 @@ Tango::ColorLib::ColorConverter::~ColorConverter() delete[] m_CurrentProcessRangesMin; m_CurrentProcessRangesMin = NULL; } - //_CrtDumpMemoryLeaks(); + if (m_ObjFunction != NULL) + { + delete m_ObjFunction; + m_ObjFunction = NULL; + } + if (m_Minimize != NULL) + { + delete m_Minimize; + m_Minimize = NULL; + } +#ifdef MEMORY_TEST + _CrtDumpMemoryLeaks(); +#endif // MEMORY_TEST } void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conversionInput, VectorXd Lab, @@ -275,7 +318,7 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conv GamutRegion[iHive], InGamut, sur, CS); PercentagetoNLcm(Vol, Vol); // Volume is in Color Table Units int CTUnits = 1; - GetClosestInk(Vol, GamutRegion[iHive], Vol, CTUnits, InGamut); //Input Volume is in [nl/cm] Output Volume is in [%] + GetClosestInk(Vol, GamutRegion[iHive], Vol, CTUnits); //Input Volume is in [nl/cm] Output Volume is in [%] ConfineVolumes(Vol); VectorToDouble(LabOutV, LabInFinal1); VectorToDouble(RGBOutV, tmpRGB); @@ -286,21 +329,21 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conv m_colortable->m_B2ATransform->evalLab2InkP(Lab1P, InkOutP, GamutRegion[iHive]); //InkOut is in the [0-100] interval InGamut = IsInGamut(Lab1P, sur, CS, LabOnGamut); LimitLab(LabOnGamut); - if (m_CalibMode == 1) - { - ApplyCTLinearCurves(InkOutP, InkOutP); // full range color table units - InkOutV = DoubleToVector(InkOutP, m_nInks); - ColorTable2Threadunits(InkOutV, InkOutV); // full range Thread units - ConvertToNLInks(InkOutV, NLInkOut); - int CTUnits = 0; - LimitNLInks2Volume(NLInkOut, GamutRegion[iHive], Vol, CTUnits, InGamut ); - } - else + + bool isBounded; + ApplyCTLinearCurves(InkOutP, InkOutP); // full range color table units + InkOutV = DoubleToVector(InkOutP, m_nInks); + LimitInksPercentage(InkOutV, InkOutV, isBounded, 1); + int CTUnits = 0; + m_currentMaxNLPerCM = m_maxNlPerCM; + ConvertToNLInks(InkOutV, NLInkOut); //Thread units + LimitNLInks2Volume(NLInkOut, GamutRegion[iHive], Volume, CTUnits, InGamut, isBounded); + //recalculate LabOut and RGBOut Values if they changed by bounding + if (isBounded) { - for (int iInk = 0; iInk < m_nInks; ++iInk) - InkOutP[iInk] *= tmpNormFactor[iInk]; //full range Thread units - int CTUnits = 0; - LimitNLInks2Volume(DoubleToVector(InkOutP, m_nInks), GamutRegion[iHive], Vol, CTUnits, InGamut); + ColorConvert CConvertD65(D65, D65); //Destination, source + ConvertVolumeToLabRel(Volume, LabOutV, GamutRegion[iHive], CTUnits); + VectorToDouble(LabOutV, LabOnGamut); } m_Conv02->ChangeWP(LabOnGamut, LabInFinal1, m_whitepointXYZ_Strip, m_WP); //convert back to Absolute @@ -542,6 +585,49 @@ void Tango::ColorLib::ColorConverter::fillLab(OutputCoordinates *outputCoords, V outputCoords->b = LabOut(2); } +void Tango::ColorLib::ColorConverter::readThreadGamut(ConversionInput*conversionInput) +{ + if (m_Has_GBD) + { + uint8_t *data = conversionInput->gbddata.data; + int nprocessranges = conversionInput->n_processranges; + if (nprocessranges <= 0) + throw std::exception("number of process ranges is zero or less"); + if(m_ThreadGBD == NULL) + m_ThreadGBD = new ColorTable(); + m_ThreadGBD->InitColorTables(m_Has_GBD, data, nprocessranges, GamutD); + } +} + +void Tango::ColorLib::ColorConverter::readThreadGamut(RecommendedProcessTableInput*conversionInput) +{ + if (m_Has_GBD) + { + uint8_t *data = conversionInput->gbddata.data; + int nprocessranges = conversionInput->n_processranges; + if (nprocessranges <= 0) + throw std::exception("number of process ranges is zero or less"); + if (m_ThreadGBD == NULL) + m_ThreadGBD = new ColorTable(); + m_ThreadGBD->InitColorTables(m_Has_GBD, data, nprocessranges,GamutD); + } +} + +void Tango::ColorLib::ColorConverter::readThreadGamut(OutOfGamutInput*conversionInput) +{ + if (m_Has_GBD) + { + uint8_t *data = conversionInput->gbddata.data; + int nprocessranges = conversionInput->n_processranges; + if (nprocessranges <= 0) + throw std::exception("number of process ranges is zero or less"); + + if (m_ThreadGBD == NULL) + m_ThreadGBD = new ColorTable(); + m_ThreadGBD->InitColorTables(m_Has_GBD, data, nprocessranges, GamutD); + } +} + void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput* conversionInput) { SetStripWhitepoint(conversionInput->threadl, conversionInput->threada, conversionInput->threadb); @@ -550,9 +636,8 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput* int nprocessranges = conversionInput->n_processranges; if (nprocessranges <= 0) throw std::exception("number of process ranges is zero or less"); - - m_colortable->InitColorTables(has_forwarddata, data, nprocessranges); - SetNumberofInks(m_colortable->GetnA2BnSepOut()); + m_colortable->InitColorTables(has_forwarddata, data, nprocessranges, CCtable); + SetNumberofInks(m_colortable->GetnA2BnSepIn()); } void Tango::ColorLib::ColorConverter::readColorTransformations(OutOfGamutInput* Input) @@ -563,8 +648,7 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(OutOfGamutInput* int nprocessranges = Input->n_processranges; if (nprocessranges <= 0) throw std::exception("number of process ranges is zero or less"); - - m_colortable->InitColorTables(has_forwarddata, data, nprocessranges); + m_colortable->InitColorTables(has_forwarddata, data, nprocessranges, CCtable); SetNumberofInks(m_colortable->GetnA2BnSepOut()); } @@ -576,8 +660,7 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(RecommendedProces int nprocessranges = conversionInput->n_processranges; if (nprocessranges <= 0) throw std::exception("number of process ranges is zero or less"); - - m_colortable->InitColorTables(has_forwarddata, data, nprocessranges); + m_colortable->InitColorTables(has_forwarddata, data, nprocessranges, CCtable); SetNumberofInks(m_colortable->GetnA2BnSepOut()); } @@ -657,7 +740,24 @@ void Tango::ColorLib::ColorConverter::readCalibrationTables(InputLiquid **inputl return; } -void Tango::ColorLib::ColorConverter::SetCalibMode() +void Tango::ColorLib::ColorConverter::SetMaxCalValues() +{ + double *maxVal = new double[m_nInks]; + m_maxCalX = new double[m_nInks]; + for (int i = 0; i < m_nInks; ++i) + maxVal[i] = m_CalibCurves[i].GetMaxXValue(); //in ink % + for (int i = 0; i < m_nInks; ++i) + { + m_maxCalX[i] = maxVal[i]; + } + if (maxVal != NULL) + { + delete[] maxVal; + maxVal = NULL; + } +} + +/*void Tango::ColorLib::ColorConverter::SetCalibMode() { double *maxVal = new double[m_nInks]; m_maxCalX = new double[m_nInks]; @@ -697,7 +797,7 @@ void Tango::ColorLib::ColorConverter::SetCalibMode() delete[] maxVal; maxVal = NULL; } -} +} */ void Tango::ColorLib::ColorConverter::SetCalibFactorization() { @@ -724,7 +824,7 @@ void Tango::ColorLib::ColorConverter::SetCalibFactorization() (m_ProcessRangesMaxP[m_nProcessRanges - 1] * m_CTmaxNlPerCM(i))) / denom; } } -} +} void Tango::ColorLib::ColorConverter::SetCalibData(CalibrationData *calibrationData, int i, CalibData *tmpCurve) { @@ -799,16 +899,24 @@ bool Tango::ColorLib::ColorConverter::CheckMonotonicity(CalibrationData *calibda { throw std::exception("non-monotonic x-axis "); retvalue = false; - return(retvalue); } diffy = CFx * (yval[i + 1] - yval[i]); if (diffy <= 0.0) { throw std::exception("non-monotonic y-axis "); retvalue = false; - return(retvalue); } } + if (xval != NULL) + { + delete[] xval; + xval = NULL; + } + if (yval != NULL) + { + delete[] yval; + yval = NULL; + } return retvalue; } @@ -848,20 +956,13 @@ void Tango::ColorLib::ColorConverter::ConvertLabColorToLinearInks(InputCoordinat //Color Tables are encoded in 16 bits which are equivalent to [0-100] //The same is true for linear curves //Therefore the factorization by normfactor has to be done after the calculation of the linear curves - //Linear Curves in the color table are defined in the full range (Sylko [0-200]%) + //Linear Curves in the color table are defined in the full range //We apply the linear curves to the full range // InkOutP is in the full range of the color table - if(m_CalibMode ==1) - ApplyCTLinearCurves(InkOutP, InkOutP); - else - { - double *tmpval = m_colortable->GetNormFactor(); - for (int i = 0; i < m_nInks; ++i) - InkOutP[i] *= tmpval[i]; - } + ApplyCTLinearCurves(InkOutP, InkOutP); InkOut = DoubleToVector(InkOutP, m_nInks); -double *LabOutFinal = new double[3]; + double *LabOutFinal = new double[3]; //double *LabOutFinal = DBG_NEW double[3]; for (int i = 0; i < 3; ++i) LabOutFinal[i] = LabOnGamut[i]; @@ -959,15 +1060,7 @@ void Tango::ColorLib::ColorConverter::ConvertRGBColorToLinearInks(InputCoordinat //Convert to Lab to get the actual in Gamut Lab //Convert InkOut to Linear via initial calibration Tables //Initial calibration tables are the ones that were included in the color table - // if m_CalibMode = 0, do not convert via calibration tables - if(m_CalibMode ==1) - ApplyCTLinearCurves(InkOutP, InkOutP); - else - { - double *tmpval = m_colortable->GetNormFactor(); - for (int i = 0; i < m_nInks; ++i) - InkOutP[i] *= tmpval[i]; - } + ApplyCTLinearCurves(InkOutP, InkOutP); InkOut = DoubleToVector(InkOutP, m_nInks); //Convert to CT thread, LabOnGamut is in Relative Colorimetric Space @@ -1027,7 +1120,7 @@ void Tango::ColorLib::ColorConverter::Thread2ColorTableunits(VectorXd InkIn, Vec else InkOut(i) = InkIn(i); } -} +} void Tango::ColorLib::ColorConverter::ColorTable2Threadunits(VectorXd InkIn, VectorXd &InkOut) { @@ -1046,40 +1139,56 @@ void Tango::ColorLib::ColorConverter::ColorTable2Threadunits(VectorXd InkIn, Vec else InkOut(i) = InkIn(i); } -} +} void Tango::ColorLib::ColorConverter::ApplyCTLinearCurves(double *InkIn, double* InkOut) { double *tmpNormFactor = m_colortable->GetNormFactor(); - if (m_CalibMode == 1) + + for (int i = 0; i < m_nInks; ++i) { - for (int i = 0; i < m_nInks; ++i) - { - m_colortable->m_LinCurves->m_InterpCurves[i].Eval(InkIn[i] * 655.35, InkOut[i]); - InkOut[i] /= 655.35; - InkOut[i] *= tmpNormFactor[i]; - } + m_colortable->m_LinCurves->m_InterpCurves[i].Eval(InkIn[i] * 655.35, InkOut[i]); + InkOut[i] /= 655.35; + InkOut[i] *= tmpNormFactor[i]; } - else +} + +void Tango::ColorLib::ColorConverter::ApplyCTLinearCurvesR(double *InkIn, double* InkOut) +{ + double *tmpNormFactor = m_colortable->GetNormFactor(); + + for (int i = 0; i < m_nInks; ++i) { - for (int i = 0; i < m_nInks; ++i) - InkOut[i] *= tmpNormFactor[i]; + m_colortable->m_LinCurvesR->m_InterpCurves[i].Eval(InkIn[i] * 655.35, InkOut[i]); + InkOut[i] /= 655.35; + InkOut[i] *= tmpNormFactor[i]; } } void Tango::ColorLib::ColorConverter::ApplyCTInvLinearCurves(double *InkIn, double* InkOut) { double *tmpNormFactor = m_colortable->GetInverseNormFactor(); - if (m_CalibMode == 1) + + for (int i = 0; i < m_nInks; ++i) { - for (int i = 0; i < m_nInks; ++i) - { - m_colortable->m_LinCurves->m_InvInterpCurves[i].Eval(InkIn[i] * 655.35*tmpNormFactor[i], InkOut[i]); - InkOut[i] /= 655.35; - InkOut[i] /= tmpNormFactor[i]; - } + m_colortable->m_LinCurves->m_InvInterpCurves[i].Eval(InkIn[i] * 655.35*tmpNormFactor[i], InkOut[i]); + InkOut[i] /= 655.35; + InkOut[i] /= tmpNormFactor[i]; } } + +void Tango::ColorLib::ColorConverter::ApplyCTInvLinearCurvesR(double *InkIn, double* InkOut) +{ + double *tmpNormFactor = m_colortable->GetInverseNormFactor(); + + for (int i = 0; i < m_nInks; ++i) + { + m_colortable->m_LinCurvesR->m_InvInterpCurves[i].Eval(InkIn[i] * 655.35*tmpNormFactor[i], InkOut[i]); + InkOut[i] /= 655.35; + InkOut[i] /= tmpNormFactor[i]; + } +} + //void Tango::ColorLib::ColorConverter::ConvertCMYKColorToLinearInks(InputCoordinates* inputcoordinates, // VectorXd &InkOut, VectorXd &RGBOut, // VectorXd &LabOut, int &GamutRegion, bool &InGamut, SURROUND sur, CAM02CS CS) @@ -1184,28 +1293,6 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(InputCoordinates* InkOut, RGBOut, LabOut, GamutRegion, InGamut, sur, CS); break; } - - //case(COLOR_SPACE__CMYK): - //{ - // ConvertCMYKColorToLinearInks(inputcoordinates, - // InkOut, RGBOut, LabOut, GamutRegion, InGamut, sur, CS); - - // break; - //} - //case(COLOR_SPACE__Catalog): - //{ - // int32_t inData; - // if (inputcoordinates->has_pantoncode) - // inData = inputcoordinates->pantoncode; - // else - // { - // //mismatch between color space and data - // throw std::exception("Mismatch between color space and data"); - // return; - // } - // break; - //} - default: { throw std::exception(" Unsupported Color Space"); @@ -1237,7 +1324,7 @@ void Tango::ColorLib::ColorConverter::ConvertToLinearInks(VectorXd InkIn, Vecto void Tango::ColorLib::ColorConverter::VolumeToNLInkP(VectorXd Volume, VectorXd &NLInkP) { - //Volume is in %. In order to be compatible with NL to volume it has to be tranlated to nl/cm + //Volume is in %. In order to be compatible with NL to volume it has to be converted to nl/cm VectorXd InkP(m_TotalNumberofInks); int MaxInd = -1; double InkMax = -1.; @@ -1396,6 +1483,7 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates VectorXd InkOut((int)(m_nInks)); VectorXd Volume((int)(m_TotalNumberofInks)); VectorXd FinalVolumeNoLI(m_nInks); + ForwardModel* forwardmodel = m_colortable->GetForwardModel(); //Convert to Nonlinear Inks double SumVol_Ink = 0.0; @@ -1403,7 +1491,6 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates for (int i = 0; i < m_TotalNumberofInks; ++i) Volume(i) = inputcoordinates->inputliquids[i]->volume; - if (m_UseLightInks) { //Convert Light Ink Volumes to Ink Volumes @@ -1428,104 +1515,92 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates double *InkOutP = new double[m_nInks]; double *LinInkP = new double[m_nInks]; double *Ink4RGB = new double[m_nInks]; - VectorXd Ink4Vol(m_nInks); - + bool isBounded = false; + //Volume Catalogue values are assumed to be in the ColorTable colorspace + //Volume should remain unchanged regardless of the thread loaded if (colorspace == COLOR_SPACE__Catalog) { - for (int i = 0; i < m_nInks; ++i) // % to nl/cm + for (int i = 0; i < m_nInks; ++i) // % to nl/cm VolumeNoLI(i) *= (m_CTmaxNlPerCM(i) / 100); m_currentMaxNLPerCM = m_CTmaxNlPerCM; for (int iP = 0; iP < m_nProcessRanges; ++iP) { - m_CurrentProcessRangesMax[iP] = m_GamutRegionMaxLim[iP]; + m_CurrentProcessRangesMax[iP] = m_GamutRegionMaxLim[iP]; //of Color Table m_CurrentProcessRangesMin[iP] = m_GamutRegionMinLim[iP]; } - GamutRegion = GetGamutRegion(VolumeNoLI, m_GamutRegionMaxLim); //Volume is in Color Table Units - int CTUnits = 1; + int CTUnits = 1; // do not convert to thread units //Catalogue Volume Values should have InGamut = true - GetClosestInk(VolumeNoLI, GamutRegion, VolumeNoLI, CTUnits, InGamut); //Input VolumeNoLI is in [nl/cm] Output VolumeNoLI is in [%] + GetClosestInk(VolumeNoLI, GamutRegion, VolumeNoLI, CTUnits); //Input VolumeNoLI is in [nl/cm] Output VolumeNoLI is in [%] for (int i = 0; i < m_nInks; ++i) - FinalVolumeNoLI(i) = VolumeNoLI(i); - + FinalVolumeNoLI(i) = VolumeNoLI(i); //VolumeNoLi is in Color Table Units + PercentagetoNLcm(VolumeNoLI, VolumeNoLI); //in [nl/cm] converted in Color Table Space + GamutRegion = GetGamutRegion(VolumeNoLI, m_GamutRegionMaxLim); //Volume is in Color Table Units + NLcmtoPercentage(VolumeNoLI, VolumeNoLI); // in [%] VolumeToNLInkP(VolumeNoLI, NLInkP); //NLInkP is in % VectorToDouble(NLInkP, InkOutP); - // NLcmtoPercentage(VolumeNoLI, VolumeNoLI); - + //Non Linear Inks are in Color Table space, convert to reflect the thread characteristics // Inks are in their natural coordinates // Inks need to be converted to thread units, RGB is calculated from initial inks - if(m_CalibMode ==1) - { //Convert to [0-100] before applying the Linear Curves - double *tmpval = m_colortable->GetInverseNormFactor(); - for (int i = 0; i < m_nInks; ++i) - InkOutP[i] *= tmpval[i]; //scaled to real units, still in % - ApplyCTLinearCurves(InkOutP, LinInkP); //Full Range in Color Table Units % - ColorTable2Threadunits(DoubleToVector(LinInkP, m_nInks), InkOut); //Full Range in Thread units % - ConvertToNLInks(InkOut,InkOut); //ful range in Thread units % - } - else - ColorTable2Threadunits(DoubleToVector(InkOutP, m_nInks), InkOut); // Full Range in % - - Ink4Vol = InkOut; + double *tmpval = m_colortable->GetInverseNormFactor(); + for (int i = 0; i < m_nInks; ++i) + InkOutP[i] *= tmpval[i]; //scaled to real units, still in % + ApplyCTLinearCurves(InkOutP, LinInkP); //Full Range in Color Table Units % + + LimitInksPercentage(DoubleToVector(LinInkP, m_nInks), InkOut, isBounded, 1); //Limited in Color Table Space + ColorTable2Threadunits(DoubleToVector(LinInkP, m_nInks), InkOut); //Full Range in Thread units % + //Ink percentages were bounded, there is no problem using the calibration curves + ConvertToNLInks(InkOut,InkOut); //ful range in Thread units % } else if (colorspace == COLOR_SPACE__Volume) { //Volume is in Thread Space, need to convert to Color Table space to get RGB for (int i = 0; i < m_nInks; ++i) // % to nl/cm in Thread Space VolumeNoLI(i) *= (m_maxNlPerCM(i) / 100); - m_currentMaxNLPerCM = m_maxNlPerCM; + m_currentMaxNLPerCM = m_maxNlPerCM; //Thread space for (int i = 0; i < m_nProcessRanges; ++i) { m_CurrentProcessRangesMax[i] = m_ProcessRangesMaxP[i]; m_CurrentProcessRangesMin[i] = m_ProcessRangesMinP[i]; } - GamutRegion = GetGamutRegion(VolumeNoLI, m_CurrentProcessRangesMax); - int CTUnits = 0; - GetClosestInk(VolumeNoLI, GamutRegion, VolumeNoLI, CTUnits, InGamut); //VolumenoLi Input is in [nl/cm], VolumeNoLI Output is in [%] in thread space + int CTUnits = 0; //to convert to Color Table space + GetClosestInk(VolumeNoLI, GamutRegion, VolumeNoLI, CTUnits); //VolumenoLi Input is in [nl/cm], VolumeNoLI Output is in [%] in thread space VolumeToNLInkP(VolumeNoLI, NLInkP); //NLInkP is in % Full Range + PercentagetoNLcm(VolumeNoLI, VolumeNoLI); //in [nl/cm] + GamutRegion = GetGamutRegion(VolumeNoLI, m_CurrentProcessRangesMax); + NLcmtoPercentage(VolumeNoLI, VolumeNoLI); // in [%] + //save the above volume as the final one, then calculate RGB coordinates + //In doing this Input and Output remain the same. for (int i = 0; i < m_nInks; ++i) FinalVolumeNoLI(i) = VolumeNoLI(i); + VectorToDouble(NLInkP, InkOutP); - Ink4Vol = NLInkP; //NLInkP are the final Volume values, the transformations are applied to get the right RGB - if (m_CalibMode == 1) - { - VectorXd InkLinV(m_nInks); - ConvertToLinearInks(NLInkP, InkLinV); //Use Calib tables //full range Thread Units % - Thread2ColorTableunits(InkLinV, InkLinV); //full range Color Table Units % - //Linear Inks are in their natural coordinates % - VectorToDouble(InkLinV, InkOutP); - //for (int i = 0; i < m_nInks; ++i) - // InkOutP[i] *= m_colortable->GetInverseNormFactor(); //[0-100] - ApplyCTInvLinearCurves(InkOutP, InkOutP); //full range % in Color Table Space // //Inks are now nonlinear - } - else - { - Thread2ColorTableunits(NLInkP, InkOut); //full range color table units - VectorToDouble(InkOut, InkOutP); //full range color table units - } + + VectorXd InkLinV(m_nInks); + ConvertToLinearInks(NLInkP, InkLinV); //Use Calib tables //full range Thread Units % + Thread2ColorTableunits(InkLinV, InkLinV); //full range Color Table Units % + //Linear Inks are in their natural coordinates % + VectorToDouble(InkLinV, InkOutP); + ApplyCTInvLinearCurves(InkOutP, InkOutP); //full range % in Color Table Space // //Inks are now nonlinear in Color Table space } for (int i = 0; i < m_nInks; ++i) Ink4RGB[i] = InkOutP[i]; //July 29 2020 //Inks are limited in their nonlinear form - //Ink4Vol is in Thread units - m_currentMaxNLPerCM = m_maxNlPerCM; + m_currentMaxNLPerCM = m_maxNlPerCM; // thread for (int j = 0; j < m_nProcessRanges; ++j) { - m_CurrentProcessRangesMax[j] = m_ProcessRangesMaxP[j]; + m_CurrentProcessRangesMax[j] = m_ProcessRangesMaxP[j]; //thread space m_CurrentProcessRangesMin[j] = m_ProcessRangesMinP[j]; } - LimitInks(Ink4Vol, InkOutP); //in [nl/cm] nonlinear inks // Color table Space - NLInkPToVolume(DoubleToVector(InkOutP, m_nInks), VolumeNoLI); //VolumeNoLI in [nl/cm] - GamutRegion = GetGamutRegion(VolumeNoLI, m_ProcessRangesMaxP); - NLcmtoPercentage(VolumeNoLI, VolumeNoLI); //VolumeNoLI in % + //Convert to RGB //GamutRegion = 0; //Convert to Lab @@ -1535,8 +1610,8 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates double *tmpval = m_colortable->GetInverseNormFactor(); if (m_colortable->GetTableSubVersion() > 0) { - for (int i = 0; i < m_nInks; ++i) - Ink4RGB[i] *= tmpval[i]; //[0-100] range, same as Color Table + for (int i = 0; i < m_nInks; ++i) + Ink4RGB[i] *= tmpval[i]; //[0-100] range, same as Color Table ApplyCTLinearCurves(Ink4RGB, Ink4RGB); //Use Color Table Curves //full range % Linear tmpval = m_colortable->GetInverseNormFactor(); @@ -1545,7 +1620,7 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates Ink4RGB[i] *= tmpval[i]; //[0-100] range, same as Color Table Ink4RGB[i] /= 100.0; } - m_forwardmodel->CalcFM(Ink4RGB, LabOutP); + forwardmodel->CalcFM(Ink4RGB, LabOutP); } else { @@ -1575,7 +1650,6 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates { RGBOut(i) = RGBOutP[i]; } - for (int i = 0; i < m_nInks; ++i) VolumeNoLI(i) = FinalVolumeNoLI(i); @@ -1667,34 +1741,14 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i m_WP.Set(0.9505, 1.00, 1.0888); //D65 // Read Color Transformations - if (m_colortable == NULL) - m_colortable = new ColorTable(); - readColorTransformations(conversionInput); + readColorTransformations(conversionInput); + SetRMLParameters(conversionInput); - //Set Process Ranges - if (conversionInput->n_processranges <= 0) - throw std::exception("number of process ranges is zero"); - else - m_nProcessRanges = conversionInput->n_processranges; - - double *tmpVal; - /* if (m_NormGamutRegionMaxLim == NULL) - m_NormGamutRegionMaxLim = new double[m_nProcessRanges]; - tmpVal = m_colortable->GetNormGamutRegionMaxLim(); - for (int i = 0; i < m_nProcessRanges; ++i) - m_NormGamutRegionMaxLim[i] = tmpVal[i]; */ - - if (m_GamutRegionMaxLim == NULL) - m_GamutRegionMaxLim = new double[m_nProcessRanges]; - tmpVal = m_colortable->GetGamutRegionMaxLim(); - for (int i = 0; i < m_nProcessRanges; ++i) - m_GamutRegionMaxLim[i] = tmpVal[i]; - - if (m_GamutRegionMinLim == NULL) - m_GamutRegionMinLim = new double[m_nProcessRanges]; - tmpVal = m_colortable->GetGamutRegionMinLim(); - for (int i = 0; i < m_nProcessRanges; ++i) - m_GamutRegionMinLim[i] = tmpVal[i]; + m_Has_GBD = conversionInput->has_gbddata; + readThreadGamut(conversionInput); + //Verify the right Gamut Boundary Descriptor was loaded + VerifyGBD(); + //read calibration tables and store them in m_CalibCurves InputLiquid **inputliquids = conversionInput->inputcoordinates->inputliquids; @@ -1702,16 +1756,23 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i int n_inputliquids = numofInks - numLightInks; readCalibrationTables(inputliquids, n_inputliquids); + //replace Gamut descriptor of Color Table with matching thread GBD + //just the gamut boundary is replaced, it is used to set the proper in/out gamut and + //corresponding gamut mapping + if(m_Has_GBD) + { + m_colortable->SetGBD(m_ThreadGBD->m_GBD); + } //Define Parameters for Direct Inversion if(m_colortable->GetTableSubVersion()>0) { C_RGB_XYZ_Lab whitepoint_CT = m_colortable->GetWhitePoint_CT(); - m_forwardmodel = m_colortable->GetForwardModel(); + ForwardModel* forwardmodel = m_colortable->GetForwardModel(); ColorConvert CConvertD65(D65, D65); C_RGB_XYZ_Lab relWP_CT; CConvertD65.ChangeWP(whitepoint_CT, relWP_CT, m_WP, m_whitepointXYZ_Strip); - m_forwardmodel->SetFreeTerm(relWP_CT); - m_ObjFunction = new ObjectiveFunction(m_forwardmodel); + forwardmodel->SetFreeTerm(relWP_CT); + m_ObjFunction = new ObjectiveFunction(forwardmodel); PrepareObjectiveFunctionPars(); m_Minimize = new LevMar(m_ObjFunction); m_Minimize->Init(); @@ -1725,90 +1786,30 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i CAM02CS CS = UCS; if (m_Conv02 == NULL) m_Conv02 = new ColorConvert(IL, IL, Y_b, L_A, sur, CS); - //m_Conv02 = DBG_NEW ColorConvert(IL, IL, Y_b, L_A, sur, CS); - - // Compare Strip White point to Color Table White Point - //CompareWhitePoints(); - + if (n_inputliquids != m_nInks) throw std::exception("Number of available inks does not match ink tables\0"); - //Tables have been filled - //Set Process Ranges - for (int i = 0; i < m_nProcessRanges; ++i) - { - if (conversionInput->processranges[i]->maxinkuptake <= 0) - throw std::exception("Process Range is zero\0"); - } - double diff = 0; - for (int i = 1; i < m_nProcessRanges; ++i) - { - diff = conversionInput->processranges[i]->maxinkuptake - conversionInput->processranges[i - 1]->maxinkuptake; - if (diff < 0) - throw std::exception("Process Ranges are not monotonic\0"); - } - if (m_ProcessRangesMaxP == NULL) - m_ProcessRangesMaxP = new double[m_nProcessRanges]; - for (int i = 0; i < m_nProcessRanges; ++i) - { - m_ProcessRangesMaxP[i] = conversionInput->processranges[i]->maxinkuptake; - } - if (m_ProcessRangesMinP == NULL) - m_ProcessRangesMinP = new double[m_nProcessRanges]; - for (int i = 0; i < m_nProcessRanges; ++i) - { - m_ProcessRangesMinP[i] = conversionInput->processranges[i]->mininkuptake; - } - - if (m_CurrentProcessRangesMax == NULL) - m_CurrentProcessRangesMax = new double[m_nProcessRanges]; - if (m_CurrentProcessRangesMin == NULL) - m_CurrentProcessRangesMin = new double[m_nProcessRanges]; - - //define Low Volume threshold and Light Inks Threshold - m_LightInksThr = conversionInput->vmax; - m_LowVolumeThreshold = m_LightInksThr / DilutionFactor; - m_LowVolHalf = m_LowVolumeThreshold / 2; - //SetLowVolThr_nlcm(); - - VectorXd InkOut(m_nInks); - VectorXd RGBOut(3); - VectorXd LabOut(3); - VectorXd NLInkOut(m_nInks); - VectorXd Volume(m_nInks); - VectorXd VolumeOut(m_nInks); - //set maxNlPerCM - VectorXd NlperCM(m_nInks); - NlperCM.setZero(); - m_maxNlPerCM = NlperCM; - for (int i = 0; i < m_nInks; ++i) - SetMaxNLperCM(conversionInput->inputcoordinates->inputliquids[i]->maxnanoliterpercentimeter, i); - m_CTmaxNlPerCM = NlperCM; - double *tmpLF = new double[m_nInks]; - tmpLF = m_colortable->GetCTLiquidFactors(); - for (int i = 0; i < m_nInks; ++i) - m_CTmaxNlPerCM(i) = tmpLF[i]; - if (tmpLF != NULL) - { - delete[] tmpLF; - tmpLF = NULL; - } - // Set Calibration mode 0 up tp 100%, 1 with High Volume Calib - SetCalibMode(); + //SetCalibMode(); //Calculate normalization per ink SetCalibFactorization(); + SetMaxCalValues(); m_nVolumes = m_nInks; int GamutRegion = 0; //Convert input data to linear inks ColorSpace colorspace = conversionInput->colorspace; InputCoordinates *IC = conversionInput->inputcoordinates; VectorXd VolumeLI(m_TotalNumberofInks); - + VectorXd InkOut(m_nInks); + VectorXd RGBOut(3); + VectorXd LabOut(3); + VectorXd NLInkOut(m_nInks); + VectorXd Volume(m_nInks); + VectorXd VolumeOut(m_nInks); if (conversionInput->colorspace == COLOR_SPACE__Volume) { ConvertVolumeToRGBDisplay(IC, conversionInput->n_processranges, colorspace, Volume, RGBOut, LabOut, GamutRegion, InGamut); - } else if (conversionInput->colorspace == COLOR_SPACE__Catalog) { @@ -1829,17 +1830,19 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i GamutRegion, InGamut, sur, CS); PercentagetoNLcm(Volume, Volume); //Volume is in Color Table Units int CTUnits = 1; - GetClosestInk(Volume, GamutRegion, Volume, CTUnits, InGamut); //Input Volume is in [nl/cm] Output Volume is in [%] + GetClosestInk(Volume, GamutRegion, Volume, CTUnits); //Input Volume is in [nl/cm] Output Volume is in [%] ConfineVolumes(Volume); } else { ConvertColorToLinearInks(conversionInput->inputcoordinates, conversionInput->colorspace, InkOut, RGBOut, LabOut, GamutRegion, InGamut); - //Inks are in Linear Space , convert to nonlinear by using Calibration Tables, + //Inks are in Linear Space , (they were converted to linear in the previous call) convert to nonlinear by using Calibration Tables, //data is in full range of color table % //convert data to the thread range in % ColorTable2Threadunits(InkOut, InkOut); + bool isBounded; + LimitInksPercentage(InkOut, InkOut, isBounded, 1); int CTUnits = 0; m_currentMaxNLPerCM = m_maxNlPerCM; for (int i = 0; i < m_nProcessRanges; ++i) @@ -1847,13 +1850,16 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i m_CurrentProcessRangesMax[i] = m_ProcessRangesMaxP[i]; m_CurrentProcessRangesMin[i] = m_ProcessRangesMinP[i]; } - if (m_CalibMode == 1) + ConvertToNLInks(InkOut, NLInkOut); //thread units + LimitNLInks2Volume(NLInkOut, GamutRegion, Volume, CTUnits, InGamut, isBounded); + //recalculate LabOut and RGBOut Values if they changed by bounding + if (isBounded) { - ConvertToNLInks(InkOut, NLInkOut); - LimitNLInks2Volume(NLInkOut, GamutRegion, Volume, CTUnits, InGamut); + ColorConvert CConvertD65(D65, D65); //Destination, source + ConvertVolumeToLabRel(Volume, LabOut, GamutRegion, CTUnits); + RGBOut = CConvertD65.LabtoRGB(LabOut); // Lab is in Relative Colorimetric + CConvertD65.ChangeWP(LabOut, LabOut, m_whitepointXYZ_Strip, m_WP); //To Absolute } - else - LimitNLInks2Volume(InkOut, GamutRegion, Volume, CTUnits, InGamut); } } //Split Volume into inks and Light Inks @@ -1967,6 +1973,7 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i GamutRegionV = NULL; } + } //Pack output... @@ -2753,12 +2760,13 @@ size_t Tango::ColorLib::ColorConverter::P_IsInGamut(uint8_t * input_buffer, size //count number if inks int numofInks = 0; int numLightInks = 0; - if (m_colortable == NULL) - m_colortable = new ColorTable(); CountNumberofInks(conversionInput, numofInks, numLightInks); readColorTransformations(conversionInput); + m_Has_GBD = conversionInput->has_gbddata; + if(m_Has_GBD) + readThreadGamut(conversionInput); //read calibration tables and store them in m_CalibCurves int n_inputliquids = numofInks - numLightInks; @@ -2766,7 +2774,11 @@ size_t Tango::ColorLib::ColorConverter::P_IsInGamut(uint8_t * input_buffer, size //Read CMYK Calibration Tables only. Light Inks have no calibration tables readCalibrationTables(inputliquid, n_inputliquids); - + //replace Gamut descriptor of Color Table with matching thread GBD + //just the gamut boundary is replaced, it is used to set the proper in/out gamut and + //corresponding gamut mapping + if(m_Has_GBD) + m_colortable->SetGBD(m_ThreadGBD->m_GBD); //Initialize CIECAM02 transformation Illum IL = D65; SURROUND sur = average; @@ -2924,8 +2936,6 @@ size_t Tango::ColorLib::ColorConverter::GenerateGradient(uint8_t * input_buffer, conversionOutput->has_haserror = false; //Get segment length... double segmentLength = conversionInput->segmentlength; - if (m_colortable == NULL) - m_colortable = new ColorTable(); PrepareGradient(conversionInput, conversionOutput); //Pack output... @@ -3325,25 +3335,30 @@ void Tango::ColorLib::ColorConverter::ConvertGradStoptoVolume(InputCoordinates* C_RGB_XYZ_Lab DataLab; VectorXd InkOut(m_nInks); - double *normFactor = new double[m_nInks]; +/* double *normFactor = new double[m_nInks]; if (!same_regions) normFactor = m_colortable->GetNormFactor(); else { for (int iInks = 0; iInks < m_nInks; ++iInks) normFactor[iInks] = 1.0; - } + }*/ ColorConvert CConvertD65(D65, D65); //Destination, source + bool isBounded; + VectorXd NLInkOut(m_nInks); + bool InGamut = true; //Gradient Stops are in Gamut + if (colorspace == COLOR_SPACE__RGB) { //Convert RGB to Volume, no need to calculate RGBOut and LabOut //Data is in Relative Colorimetric color space //We expect that [255,255,255](white) will be mapped to the thread white, meaning all inks should be zero - // and the coverted RGB will refect the color of the thread, but will be shown in Relative Colorimetric to the user + // and the converted RGB will refect the color of the thread, but will be shown in Relative Colorimetric to the user //convert to Lab double *LabIn = new double[3]; double *RGBOutP = new double[3]; + double *LabOut = new double[3]; RGBOutP[0] = inputcoordinates->red; RGBOutP[1] = inputcoordinates->green; RGBOutP[2] = inputcoordinates->blue; @@ -3354,33 +3369,47 @@ void Tango::ColorLib::ColorConverter::ConvertGradStoptoVolume(InputCoordinates* //convert to inks int GamutRegion; double *InkOutP = new double[m_nInks]; + VectorXd InkOutV(m_nInks); + + VectorXd LabOutV(3); + int GRegion = 1; + + //Output Inks are in nonlinear units + //Convert them to linear by using the Color Tables Curves + //Limit inks if needed based on the thread characteristics + //Convert to NL inks by using Thread Curves + //Convert to Volume if (same_regions) { m_colortable->m_B2ARTransform->evalLab2InkP(LabIn, InkOutP, GamutRegion); //InkOut is in units of 16 bits InkOut = DoubleToVector(InkOutP, m_nInks); - ColorTable2Threadunits(InkOut, InkOut); - //LimitNLInks2VolumeThr(InkOut, GamutRegion, Volume); + ApplyCTLinearCurvesR(InkOutP, InkOutP); // full range color table units + InkOutV = DoubleToVector(InkOutP, m_nInks); + GRegion = 0; + LimitInksPercentage(InkOutV, InkOutV, isBounded, GRegion); + int CTUnits = 0; + m_currentMaxNLPerCM = m_maxNlPerCM; + //Need to calculate Calib tables that match the limited region + ConvertToNLInks(InkOutV, NLInkOut); + LimitNLInks2Volume(NLInkOut, GamutRegion, Volume, CTUnits, InGamut, isBounded); } else { + //Output Inks are in nonlinear units + //Convert them to linear by using the Color Tables Curves + //Limit inks if needed based on the thread characteristics + //Convert to NL inks by using Thread Curves + //Convert to Volume m_colortable->m_B2ATransform->evalLab2InkP(LabIn, InkOutP, GamutRegion); //InkOut is in the [0-100] interval - if (m_CalibMode == 1) - { - VectorXd NLInkOut(m_nInks); - ApplyCTLinearCurves(InkOutP, InkOutP); //Full range Color Table Units - InkOut = DoubleToVector(InkOutP, m_nInks); - ColorTable2Threadunits(InkOut, InkOut); //Full Range Thread Units - ConvertToNLInks(InkOut, InkOut); - //LimitNLInks2Volume(NLInkOut, GamutRegion, Volume); - } - else - { - double *tmpval = m_colortable->GetNormFactor(); - for (int i = 0; i < m_nInks; ++i) - InkOutP[i] *= tmpval[i]; //Full Range - ColorTable2Threadunits(DoubleToVector(InkOutP, m_nInks) , InkOut); //Full Range - //LimitNLInks2VolumeThr(InkOut, GamutRegion, Volume); - } + ApplyCTLinearCurves(InkOutP, InkOutP); // full range color table units + InkOutV = DoubleToVector(InkOutP, m_nInks); + GRegion = 1; + LimitInksPercentage(InkOutV, InkOutV, isBounded, GRegion); + int CTUnits = 0; + m_currentMaxNLPerCM = m_maxNlPerCM; + ConvertToNLInks(InkOutV, NLInkOut); + LimitNLInks2Volume(NLInkOut, GamutRegion, Volume, CTUnits, InGamut, isBounded); + //recalculate LabOut and RGBOut Values if they changed by bounding } if (InkOutP != NULL) @@ -3393,6 +3422,11 @@ void Tango::ColorLib::ColorConverter::ConvertGradStoptoVolume(InputCoordinates* delete[] LabIn; LabIn = NULL; } + if (LabOut != NULL) + { + delete[] LabOut; + LabOut = NULL; + } if (RGBOutP != NULL) { delete[] RGBOutP; @@ -3413,32 +3447,31 @@ void Tango::ColorLib::ColorConverter::ConvertGradStoptoVolume(InputCoordinates* double *InkOutP = new double[m_nInks]; if (same_regions) { - m_colortable->m_B2ARTransform->evalLab2InkP(LabIn, InkOutP, GamutRegion); //InkOut is in the [0-100] interval - //for (int i = 0; i < m_nInks; ++i) - // InkOutP[i] *= m_colortable->GetNormFactor(); //Full Range Color Table Units + m_colortable->m_B2ARTransform->evalLab2InkP(LabIn, InkOutP, GamutRegion); //InkOut is in units of 16 bits + InkOut = DoubleToVector(InkOutP, m_nInks); + ApplyCTLinearCurvesR(InkOutP, InkOutP); // full range color table units InkOut = DoubleToVector(InkOutP, m_nInks); - ColorTable2Threadunits(InkOut, InkOut); //Full Range Thread Units + GamutRegion = 0; + LimitInksPercentage(InkOut, InkOut, isBounded, GamutRegion); + int CTUnits = 0; + m_currentMaxNLPerCM = m_maxNlPerCM; + //Need to calculate Calib tables that match the limited region + ConvertToNLInks(InkOut, NLInkOut); + LimitNLInks2Volume(NLInkOut, GamutRegion, Volume, CTUnits, InGamut, isBounded); } else { m_colortable->m_B2ATransform->evalLab2InkP(LabIn, InkOutP, GamutRegion); //InkOut is in the [0-100] interval + ApplyCTLinearCurves(InkOutP, InkOutP); // full range color table units InkOut = DoubleToVector(InkOutP, m_nInks); - if (m_CalibMode == 1) - { - ApplyCTLinearCurves(InkOutP, InkOutP); //full range Color Table Units - ColorTable2Threadunits(InkOut, InkOut); //full range Thread Units - ConvertToNLInks(InkOut, InkOut); - } - else - { - double *tmpval = m_colortable->GetNormFactor(); - for (int i = 0; i < m_nInks; ++i) - InkOutP[i] *= tmpval[i]; //Full Range Color Table units - ColorTable2Threadunits(DoubleToVector(InkOutP, m_nInks), InkOut); //full range Thread Units - } + GamutRegion = 1; + LimitInksPercentage(InkOut, InkOut, isBounded, GamutRegion); + int CTUnits = 0; + m_currentMaxNLPerCM = m_maxNlPerCM; + ConvertToNLInks(InkOut, NLInkOut); + LimitNLInks2Volume(NLInkOut, GamutRegion, Volume, CTUnits, InGamut, isBounded); } - if (InkOutP != NULL) { delete[] InkOutP; @@ -3463,6 +3496,7 @@ void Tango::ColorLib::ColorConverter::ConvertGradStoptoVolume(InputCoordinates* m_CurrentProcessRangesMin[i] = m_ProcessRangesMinP[i]; } LimitNLInks2VolumeThr(InkOut, GamutRegion, Volume); + return; } @@ -3501,7 +3535,7 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c bool has_forwarddata = conversionInput->has_forwarddata; uint8_t *data = conversionInput->forwarddata.data; m_nProcessRanges = conversionInput->n_processranges; - m_colortable->InitColorTables(has_forwarddata, data, m_nProcessRanges); + m_colortable->InitColorTables(has_forwarddata, data, m_nProcessRanges, CCtable); //Color Table SetNumberofInks(m_colortable->GetnA2BnSepIn()); double *tmpVal; /* if (m_NormGamutRegionMaxLim == NULL) @@ -3583,27 +3617,23 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c m_maxNlPerCM = NlperCM; for (int i = 0; i < m_nInks; ++i) SetMaxNLperCM(conversionInput->inputliquids[i]->maxnanoliterpercentimeter, i); - double *tmpLF = new double[m_nInks]; - tmpLF = m_colortable->GetCTLiquidFactors(); + //double *tmpLF = new double[m_nInks]; + double *tmpLF = m_colortable->GetCTLiquidFactors(); m_CTmaxNlPerCM = NlperCM; for (int i = 0; i < m_nInks; ++i) m_CTmaxNlPerCM(i) = tmpLF[i]; - if (tmpLF != NULL) - { - delete[] tmpLF; - tmpLF = NULL; - } + if (m_GamutRegionMaxLim == NULL) m_GamutRegionMaxLim = new double[m_nInks]; if (m_GamutRegionMinLim == NULL) m_GamutRegionMinLim = new double[m_nInks]; // Set Calibration mode 0 up tp 100%, 1 with High Volume Calib - SetCalibMode(); + //SetCalibMode(); //Calculate normalization per ink SetCalibFactorization(); - + SetMaxCalValues(); //m_nVolumes = m_nB2AnSepOut; int GamutRegion = 0; /* for (int i = 0; i < m_nGradStops; ++i) @@ -3856,9 +3886,6 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c } - - - void Tango::ColorLib::ColorConverter::fillStop(GradientOutputStop *&stop, VectorXd Volume, int GamutRegion, double Position) { OutputLiquid** outputLiquids = (OutputLiquid**)malloc(sizeof(OutputLiquid*) * m_nVolumes); @@ -4075,12 +4102,12 @@ void Tango::ColorLib::ColorConverter::RecommendedProcessTableInput2InputCoordin } } -void Tango::ColorLib::ColorConverter::LimitInks(VectorXd inInks, double *BoundedInks) +void Tango::ColorLib::ColorConverter::LimitInks(VectorXd inInks, double *BoundedInks, int GRegion) { //convert Ink % to [nl/cm] //Bound Ink for (int i = 0; i < m_nInks; ++i) - BoundedInks[i] = std::min(inInks(i)*m_currentMaxNLPerCM(i) / 100.0, m_CurrentProcessRangesMax[m_nProcessRanges - 1]); + BoundedInks[i] = std::min(inInks(i)*m_currentMaxNLPerCM(i) / 100.0, m_CurrentProcessRangesMax[GRegion]); } void Tango::ColorLib::ColorConverter::NLcmtoPercentage(VectorXd InVolume, VectorXd &OutVolume) @@ -4230,6 +4257,7 @@ void Tango::ColorLib::ColorConverter::ProcessGradientStops(InputCoordinates **in if (m_GradStops[i].Get_ColorSpace() == COLOR_SPACE__Volume || m_GradStops[i].Get_ColorSpace() == COLOR_SPACE__Catalog) { //Convert volume to Lab //Convert lab to rgb + //Volume is assumed to be within the limits of the loaded thread limits ConvertVolumeToRGBDisplay(inputcoordinates[i], m_nProcessRanges, m_GradStops[i].Get_ColorSpace(), Volume, RGBOut, LabOut, GamutRegion, InGamut); VectorToDouble(LabOut, LabOutV); @@ -4254,22 +4282,27 @@ void Tango::ColorLib::ColorConverter::ProcessGradientStops(InputCoordinates **in C_RGB_XYZ_Lab Lab(LabOutV[0], LabOutV[1], LabOutV[2]); C_RGB_XYZ_Lab RGB(RGBOut); //convert data to the thread range in % - ColorTable2Threadunits(InkOut, InkOut); + bool isBounded; + LimitInksPercentage(InkOut, InkOut, isBounded, 1); int CTUnits = 0; m_currentMaxNLPerCM = m_maxNlPerCM; - for (int iP = 0; iP < m_nProcessRanges; ++iP) + for (int i = 0; i < m_nProcessRanges; ++i) { - m_CurrentProcessRangesMax[iP] = m_ProcessRangesMaxP[i]; - m_CurrentProcessRangesMin[iP] = m_ProcessRangesMinP[i]; + m_CurrentProcessRangesMax[i] = m_ProcessRangesMaxP[i]; + m_CurrentProcessRangesMin[i] = m_ProcessRangesMinP[i]; } - - if (m_CalibMode == 1) + ConvertToNLInks(InkOut, NLInkOut); + LimitNLInks2Volume(NLInkOut, GamutRegion, Volume, CTUnits, InGamut, isBounded); + //recalculate LabOut and RGBOut Values if they changed by bounding + if (isBounded) { - ConvertToNLInks(InkOut, NLInkOut); - LimitNLInks2Volume(NLInkOut, GamutRegion, Volume, CTUnits, InGamut); + ColorConvert CConvertD65(D65, D65); //Destination, source + ConvertVolumeToLabRel(Volume, LabOut, GamutRegion, CTUnits); + RGBOut = CConvertD65.LabtoRGB(LabOut); // Lab is in Relative Colorimetric + CConvertD65.ChangeWP(LabOut, LabOut, m_whitepointXYZ_Strip, m_WP); //To Absolute + C_RGB_XYZ_Lab Lab(LabOut[0], LabOut[1], LabOut[2]); + C_RGB_XYZ_Lab RGB(RGBOut); } - else - LimitNLInks2Volume(InkOut, GamutRegion, Volume, CTUnits, InGamut); //fill data //fill volume @@ -4345,38 +4378,24 @@ bool Tango::ColorLib::ColorConverter::CheckLabInRGBGamut(C_RGB_XYZ_Lab Lab) // } //} -void Tango::ColorLib::ColorConverter::LimitNLInks2Volume(VectorXd NLInks, int &GamutRegion, VectorXd &Volume, int CTUnits, bool &InGamut) -{ - //VectorXd NLInkOut(m_nInks); - double *InkOutL = new double[m_nInks]; -// NLInks are in the full thread range - LimitInks(NLInks, InkOutL); // NLInks is in %, InkOutL in [nl/cm] - NLInkPToVolume(DoubleToVector(InkOutL, m_nInks), Volume); // InkOutL in [nl/cm] Volume in [nl/cm] - GamutRegion = GetGamutRegion(Volume, m_CurrentProcessRangesMax); //Volume in [nl/cm] - GetClosestInk(Volume, GamutRegion, Volume, CTUnits, InGamut); //Input Volume is in [nl/cm] Output Volume is in [%] - //NLcmtoPercentage(Volume, Volume); - ConfineVolumes(Volume); // Input Volume is in[%] Output Volume is in[%] - if (InkOutL != NULL) - { - delete[]InkOutL; - InkOutL = NULL; - } -} + void Tango::ColorLib::ColorConverter::LimitNLInks2VolumeNoFix(VectorXd NLInks, int &GamutRegion, VectorXd &Volume) { //VectorXd NLInkOut(m_nInks); - double *InkOutL = new double[m_nInks]; +// double *InkOutL = new double[m_nInks]; // NLInks are in the full thread range - LimitInks(NLInks, InkOutL); // NLInks is in %, InkOutL in [nl/cm] - NLInkPToVolume(DoubleToVector(InkOutL, m_nInks), Volume); // InkOutL in [nl/cm] Volume in [nl/cm] +// LimitInks(NLInks, InkOutL); // NLInks is in %, InkOutL in [nl/cm] +// NLInkPToVolume(DoubleToVector(InkOutL, m_nInks), Volume); // InkOutL in [nl/cm] Volume in [nl/cm] + NLInkPToVolume(NLInks, Volume); // InkOutL in [nl/cm] Volume in [nl/cm] + GamutRegion = GetGamutRegion(Volume, m_CurrentProcessRangesMax); //Volume in [nl/cm] NLcmtoPercentage(Volume, Volume); //Volume is in % - if (InkOutL != NULL) +/* if (InkOutL != NULL) { delete[]InkOutL; InkOutL = NULL; - } + }*/ } void Tango::ColorLib::ColorConverter::ConfineVolumes(VectorXd &Volume) @@ -4414,7 +4433,7 @@ void Tango::ColorLib::ColorConverter::LimitNLInks2VolumeThr(VectorXd NLInks, int { // VectorXd NLInkOut(m_nInks); double *InkOutL = new double[m_nInks]; - LimitInks(NLInks, InkOutL); // InkOutL in [nl/cm] + LimitInks(NLInks, InkOutL,1 ); // InkOutL in [nl/cm] NLInkPToVolume(DoubleToVector(InkOutL, m_nInks), Volume); // [nl/cm] GamutRegion = GetGamutRegion(Volume, m_CurrentProcessRangesMax); LimitLowVolume(Volume, GamutRegion, Volume); // [nl/cm] @@ -4427,8 +4446,10 @@ void Tango::ColorLib::ColorConverter::LimitNLInks2VolumeThr(VectorXd NLInks, int } } -void Tango::ColorLib::ColorConverter::GetClosestInk(VectorXd Volume, int &GamutRegion, VectorXd &BestVolume, int CTUnits, bool &InGamut) +void Tango::ColorLib::ColorConverter::GetClosestInk(VectorXd Volume, int &GamutRegion, VectorXd &BestVolume, int CTUnits) { + //Volume is in[nl/cm] + //BestVolume is in % VectorXd LabOut(3); NumConversions D2B; double *diffVolume = new double[m_nInks]; @@ -4464,7 +4485,6 @@ void Tango::ColorLib::ColorConverter::GetClosestInk(VectorXd Volume, int &GamutR if (indCount > 0) { double LabTarget[3]; - InGamut = false; ConvertVolumeToLabRel(Volume, LabOut, GamutRegion, CTUnits); VectorToDouble(LabOut, LabTarget); int pwr2LVThr = (int)pow(2, indCount); @@ -4547,21 +4567,23 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToLabRel(VectorXd &Volume, Ve VectorXd NLInkP(m_nInks); VectorXd LInkP(m_nInks); VectorXd InkOut((int)(m_nInks)); - + ForwardModel* forwardmodel = m_colortable->GetForwardModel(); //Convert to Nonlinear Inks double SumVol_Ink = 0.0; - //Volume is in [nl/cm] - VolumeToNLInkP(Volume, NLInkP); + //Volume is in % + VolumeToNLInkP(Volume, NLInkP); // NLInkP is in % double *InkOutP = new double[m_nInks]; //Limit inks based on m_maxNlpercm //Inks are limited in their nonlinear form - LimitInks(NLInkP, InkOutP); //InkOutP is in [nl/cm] + LimitInks(NLInkP, InkOutP, 1); //InkOutP is in [nl/cm] NLInkPToVolume(DoubleToVector(InkOutP, m_nInks), Volume); //Volume is in [nl/cm] GamutRegion = GetGamutRegion(Volume, m_CurrentProcessRangesMax); NLcmtoPercentage(Volume, Volume); //Volume is back to percentage VolumeToNLInkP(Volume, NLInkP); + //Volume and NLInkP were initially bounded by the Gamut Boundary descriptor, therefore their limits are according to the thread limits + //Normalize NLInk to the Color Table Range if(CTUnits ==0) Thread2ColorTableunits(NLInkP, NLInkP); @@ -4574,13 +4596,17 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToLabRel(VectorXd &Volume, Ve if (m_colortable->GetTableSubVersion() > 0) { - ConvertToLinearInks(NLInkP, LInkP); - VectorToDouble(LInkP, InkOutP); for (int i = 0; i < m_nInks; ++i) - InkOutP[i] *= tmpval[i]; + NLInkP(i) *= tmpval[i]; //scaled to real units, still in % + VectorToDouble(NLInkP, InkOutP); + ApplyCTLinearCurves(InkOutP, InkOutP); //in Linear , CT space full range + for (int i = 0; i < m_nInks; ++i) // Forward Model in [0-1] interval + { + InkOutP[i] *= tmpval[i]; InkOutP[i] /= 100.0; - m_forwardmodel->CalcFM(InkOutP, LabOutP); + } + forwardmodel->CalcFM(InkOutP, LabOutP); } else { @@ -4687,13 +4713,13 @@ void Tango::ColorLib::ColorConverter::SplitVolume(VectorXd Volume, VectorXd &Vol double PrevLow = low; while (resplit == true) { + TotalVolume = 0.0; for (int i = 0; i < m_TotalNumberofInks; ++i) TotalVolume += VolumeLI(i); if (TotalVolume > UpperLimit) { - VolumeLI = PrevVolume; - GamutRegion = PrevGamutRegion; - resplit = false; + //Check if only some of the inks can be brought back to non-light inks + GetBackLightInks(VolumeLI, GamutRegion, PrevVolume, resplit, PrevGamutRegion); } else if (TotalVolume > InitTotalVolume) { @@ -4755,6 +4781,84 @@ void Tango::ColorLib::ColorConverter::SplitVolume(VectorXd Volume, VectorXd &Vol NLcmtoPercentage(VolumeLI, VolumeLI); } +void Tango::ColorLib::ColorConverter::GetBackLightInks(VectorXd &VolumeLI, int &GamutRegion, VectorXd PrevVolume, + bool resplit, int PrevGamutRegion) +{ + int *LgtInksIndex = new int[m_TotalNumberofInks - m_nInks]; + double *LightVol = new double[m_TotalNumberofInks - m_nInks]; + int numLgtInks = 0; + double UpperLimit = m_CurrentProcessRangesMax[m_nProcessRanges - 1]; + double TotalVolume = 0.0; + + //Find light inks and its indices + for (int i = m_nInks; i < m_TotalNumberofInks; ++i) + { + if (VolumeLI(i) > 0) + { + LgtInksIndex[numLgtInks] = i; + LightVol[numLgtInks] = VolumeLI(i); + numLgtInks++; + } + } + if (numLgtInks > 1) + { + sortPairs(LgtInksIndex, LightVol, numLgtInks); //Light inks are sorted in ascending order + //revert and check + for (int j = 0; j < m_TotalNumberofInks; ++j) + TotalVolume += VolumeLI(j); + int i = numLgtInks - 1; + while((TotalVolume > UpperLimit) & (i >=0)) + { + VolumeLI(LgtInksIndex[i] - m_nInks) = LightVol[i] / DilutionFactor; + VolumeLI(LgtInksIndex[i]) =0.0; + for (int j = 0; j < m_TotalNumberofInks; ++j) + TotalVolume += VolumeLI(i); + i--; + } + findGamutRegion(GamutRegion, TotalVolume); + resplit = false; + } + else + { + VolumeLI = PrevVolume; + GamutRegion = PrevGamutRegion; + resplit = false; + } + if (LgtInksIndex != NULL) + { + delete[] LgtInksIndex; + LgtInksIndex = NULL; + } + if (LightVol != NULL) + { + delete[] LightVol; + LightVol = NULL; + } +} + + + +void Tango::ColorLib::ColorConverter::sortPairs(int *LgtInksIndex, double*LightVol, int numLgtInks) +{ + // declaring vector of pairs + std::vector< std::pair > vect; + + // Initialise 1st and 2nd element of pairs + // Enter values in vector of pairs + for (int i = 0; i < numLgtInks; i++) + vect.push_back(std::make_pair(LgtInksIndex[i], LightVol[i])); + + // sort 2nd element of pair + std::sort(vect.begin(), vect.end(), sortbysec); + + for (int i = 0; i < numLgtInks; i++) + { + LgtInksIndex[i] = vect[i].first; + LightVol[i] = vect[i].second; + } +} + + void Tango::ColorLib::ColorConverter::DefineSplitLimits(double &low, double &high, double InitTotalVolume) { //Set Limits @@ -4885,10 +4989,10 @@ size_t Tango::ColorLib::ColorConverter::GetRecommendedProcessParameters(uint8_t bool InGamut = false; m_WP.Set(0.9505, 1.00, 1.0888); //D65 - - if (m_colortable == NULL) - m_colortable = new ColorTable(); readColorTransformations(Input); + m_Has_GBD = Input->has_gbddata; + if (m_Has_GBD) + readThreadGamut(Input); if (Input->n_processranges <= 0) throw std::exception("number of process ranges is zero"); else @@ -4919,15 +5023,21 @@ size_t Tango::ColorLib::ColorConverter::GetRecommendedProcessParameters(uint8_t int n_inputliquids = numofInks - numLightInks; readCalibrationTables(inputliquids, n_inputliquids); + //replace Gamut descriptor of Color Table with matching thread GBD + //just the gamut boundary is replaced, it is used to set the proper in/out gamut and + //corresponding gamut mapping + if(m_Has_GBD) + m_colortable->SetGBD(m_ThreadGBD->m_GBD); + if (m_colortable->GetTableSubVersion() > 0) { C_RGB_XYZ_Lab whitepoint_CT = m_colortable->GetWhitePoint_CT(); - m_forwardmodel = m_colortable->GetForwardModel(); + ForwardModel* forwardmodel = m_colortable->GetForwardModel(); ColorConvert CConvertD65(D65, D65); C_RGB_XYZ_Lab relWP_CT; CConvertD65.ChangeWP(whitepoint_CT, relWP_CT, m_WP, m_whitepointXYZ_Strip); - m_forwardmodel->SetFreeTerm(relWP_CT); - m_ObjFunction = new ObjectiveFunction(m_forwardmodel); + forwardmodel->SetFreeTerm(relWP_CT); + m_ObjFunction = new ObjectiveFunction(forwardmodel); PrepareObjectiveFunctionPars(); m_Minimize = new LevMar(m_ObjFunction); m_Minimize->Init(); @@ -4989,21 +5099,16 @@ size_t Tango::ColorLib::ColorConverter::GetRecommendedProcessParameters(uint8_t SetMaxNLperCM(Input->inputliquids[i]->maxnanoliterpercentimeter, i); m_CTmaxNlPerCM = NlperCM; - double *tmpLF = new double[m_nInks]; - tmpLF = m_colortable->GetCTLiquidFactors(); + //double *tmpLF = new double[m_nInks]; + double *tmpLF = m_colortable->GetCTLiquidFactors(); for (int i = 0; i < m_nInks; ++i) m_CTmaxNlPerCM(i) = tmpLF[i]; - if (tmpLF != NULL) - { - delete[] tmpLF; - tmpLF = NULL; - } - + // Set Calibration mode 0 up tp 100%, 1 with High Volume Calib - SetCalibMode(); +// SetCalibMode(); //Calculate normalization per ink SetCalibFactorization(); - + SetMaxCalValues(); m_nVolumes = m_nInks; int nstops = Input->n_stops; @@ -5110,7 +5215,7 @@ size_t Tango::ColorLib::ColorConverter::GetRecommendedProcessParameters(uint8_t GamutRegion[istops], InGamut, sur, CS); PercentagetoNLcm(Volume, Volume); //Volume is in Color Table Units int CTUnits = 1; - GetClosestInk(Volume, GamutRegion[istops], Volume, CTUnits, InGamut); //Input Volume is in [nl/cm] Output Volume is in [%] + GetClosestInk(Volume, GamutRegion[istops], Volume, CTUnits); //Input Volume is in [nl/cm] Output Volume is in [%] ConfineVolumes(Volume); } else @@ -5120,21 +5225,26 @@ size_t Tango::ColorLib::ColorConverter::GetRecommendedProcessParameters(uint8_t //Inks are in their initial state in % //Inks are in Linear Space , convert to nonlinear by using Calibration Tables, //convert data to the thread range in % - ColorTable2Threadunits(InkOut, InkOut); // InkOut is in thread units + + bool isBounded; + LimitInksPercentage(InkOut, InkOut, isBounded, 1); int CTUnits = 0; m_currentMaxNLPerCM = m_maxNlPerCM; - for (int iP = 0; iP < m_nProcessRanges; ++iP) + for (int i = 0; i < m_nProcessRanges; ++i) { - m_CurrentProcessRangesMax[iP] = m_ProcessRangesMaxP[iP]; - m_CurrentProcessRangesMin[iP] = m_ProcessRangesMinP[iP]; + m_CurrentProcessRangesMax[i] = m_ProcessRangesMaxP[i]; + m_CurrentProcessRangesMin[i] = m_ProcessRangesMinP[i]; } - if (m_CalibMode == 1) + ConvertToNLInks(InkOut, NLInkOut); + LimitNLInks2Volume(NLInkOut, GamutRegion[istops], Volume, CTUnits, InGamut, isBounded); + //recalculate LabOut and RGBOut Values if they changed by bounding + if (isBounded) { - ConvertToNLInks(InkOut, NLInkOut); - LimitNLInks2Volume(NLInkOut, GamutRegion[istops], Volume, CTUnits, InGamut); //Volume is in [%] + ColorConvert CConvertD65(D65, D65); //Destination, source + ConvertVolumeToLabRel(Volume, LabOut, GamutRegion[istops], CTUnits); + RGBOut = CConvertD65.LabtoRGB(LabOut); // Lab is in Relative Colorimetric + CConvertD65.ChangeWP(LabOut, LabOut, m_whitepointXYZ_Strip, m_WP); //To Absolute } - else - LimitNLInks2Volume(InkOut, GamutRegion[istops], Volume, CTUnits, InGamut); //Volume is in [%] } if (Input->uselightinks) { //Convert to light inks @@ -5278,10 +5388,10 @@ size_t Tango::ColorLib::ColorConverter::CheckOutOfGamut(uint8_t * input_buffer, bool InGamut = false; m_WP.Set(0.9505, 1.00, 1.0888); //D65 - - if (m_colortable == NULL) - m_colortable = new ColorTable(); readColorTransformations(Input); + m_Has_GBD = Input->has_gbddata; + if (m_Has_GBD) + readThreadGamut(Input); if (Input->n_processranges <= 0) throw std::exception("number of process ranges is zero"); else @@ -5477,7 +5587,10 @@ void Tango::ColorLib::ColorConverter::DirectInversionCalc(double *LabIn, VectorX { //Declarations ColorConvert ColConv(D65, D65); + ForwardModel* forwardmodel = m_colortable->GetForwardModel(); int i, k; + bool isBounded; + //Initialize variables int nfree = m_ObjFunction->GetNumFreeParams(); double *InitCMY = new double[nfree]; int nfixed = m_ObjFunction->GetNumFixedParams(); @@ -5494,18 +5607,18 @@ void Tango::ColorLib::ColorConverter::DirectInversionCalc(double *LabIn, VectorX double **Vol = new double*[nk]; int *FeasibleSolutionsInd = new int[nk]; int *VecGamutRegion = new int[nk]; - + VectorXd InkTmp(m_nInks); VectorXd VolumeTmp(npars); C_RGB_XYZ_Lab LabTmp; double *dECMC = new double[nk]; C_RGB_XYZ_Lab LabInVec; - VectorXd LabOutTmp(3); + LabInVec.Set(LabIn[0], LabIn[1], LabIn[2]); C_RGB_XYZ_Lab LabOutVec; - m_currentMaxNLPerCM = m_maxNlPerCM; + m_currentMaxNLPerCM = m_maxNlPerCM; // thread units for (i = 0; i < m_nProcessRanges; ++i) { - m_CurrentProcessRangesMax[i] = m_ProcessRangesMaxP[i]; + m_CurrentProcessRangesMax[i] = m_ProcessRangesMaxP[i]; // thread units m_CurrentProcessRangesMin[i] = m_ProcessRangesMinP[i]; } for (i = 0; i < nk; ++i) @@ -5514,8 +5627,10 @@ void Tango::ColorLib::ColorConverter::DirectInversionCalc(double *LabIn, VectorX finalLab[i] = new double[3]; Vol[i] = new double[npars]; } + double *BndSol = new double[m_nInks]; double *LabInFinal2 = new double[3]; double *LabOnGamut = new double[3]; + double *LabBounded = new double[3]; ColConv.ChangeWP(LabIn, LabInFinal2, m_WP, m_whitepointXYZ_Strip); //LabInFinal2 is in Relative Colorimetric Space LimitLab(LabInFinal2); @@ -5524,8 +5639,7 @@ void Tango::ColorLib::ColorConverter::DirectInversionCalc(double *LabIn, VectorX LabTmp.Set(LabOnGamut[0], LabOnGamut[1], LabOnGamut[2]); m_ObjFunction->SetLabGoal(LabOnGamut); - - //convert to Inks + //calculate solutions unsigned int nIterations; for (i = 0; i < nfree; ++i) @@ -5533,19 +5647,21 @@ void Tango::ColorLib::ColorConverter::DirectInversionCalc(double *LabIn, VectorX for (i = 0; i < nfixed; ++i) ValK[i] = 0.0; m_Minimize->SetLabIn(LabOnGamut); + int CTUnits = 0; + for (k = 0; k < nk; ++k) { ValK[0] = (double)k * dK; m_Minimize->MinimizationAlgorithm(InitCMY, ValK, nIterations); //result is returned in InitCMY - LabOutTmp = DoubleToVector(LabOnGamut, 3); - LabOutTmp += DoubleToVector(m_Minimize->GetLabOut(), 3); + LabOut = DoubleToVector(LabOnGamut, 3); + LabOut += DoubleToVector(m_Minimize->GetLabOut(), 3); for (int i = 0; i < nfree; ++i) SolVector[k][i] = std::min(std::max(100 * InitCMY[i], 0.0), 100.0); SolVector[k][nfree] = std::min(std::max(100 * ValK[0], 0.0), 100.0); //Solution Vector is in linear units in the interval [0,100] - + isBounded = false; for (int i = 0; i < 3; ++i) - finalLab[k][i] = LabOutTmp[i]; - LabOutVec.Set(LabOutTmp[0], LabOutTmp[1], LabOutTmp[2]); + finalLab[k][i] = LabOut[i]; + LabOutVec.Set(LabOut[0], LabOut[1], LabOut[2]); ColConv.dEcmc(LabTmp, LabOutVec, dECMC[k]); //Result is in Linear Inks @@ -5556,19 +5672,23 @@ void Tango::ColorLib::ColorConverter::DirectInversionCalc(double *LabIn, VectorX InkOut = DoubleToVector(SolVector[k], m_nInks); double *tmpval = m_colortable->GetNormFactor(); for (int i = 0; i < m_nInks; ++i) - InkOut(i) *= tmpval[i]; - ColorTable2Threadunits(InkOut, InkOut); //in % - - if (m_CalibMode == 1) - { - ConvertToNLInks(InkOut, InkOut); // in % - LimitNLInks2VolumeNoFix(InkOut, GamutRegion, VolumeTmp); //VolumeTmp is in % - // NLInkPToVolume(InkOut, VolumeTmp); // in % - //LimitNLInks2Volume(InkOut, GamutRegion, VolumeTmp); - } - else + InkOut(i) *= tmpval[i]; // in [%] + //Limit ink percentage, if they changed recalculate Lab and dE + + ColorTable2Threadunits(InkOut, InkOut); //in % + ConvertToNLInks(InkOut, InkOut); // in %, thread units + LimitNLInks2Volume(InkOut, GamutRegion, VolumeTmp, CTUnits, + InGamut, isBounded); //InkOut contains the modified Inks in nonlinear form, VolumeTmp contains the modified volume + if (isBounded) //inks were changed, recalculate Lab values { - LimitNLInks2VolumeNoFix(InkOut, GamutRegion, VolumeTmp); + VectorToDouble(InkOut, BndSol); + for (int i = 0; i < m_nInks; ++i) + BndSol[i] /= (tmpval[i]*100.0); + forwardmodel->CalcFM(BndSol, LabBounded); + for (int i = 0; i < 3; ++i) + finalLab[k][i] = LabBounded[i]; + LabOutVec.Set(LabBounded[0], LabBounded[1], LabBounded[2]); + ColConv.dEcmc(LabTmp, LabOutVec, dECMC[k]); } VecGamutRegion[k] = GamutRegion; // NLInkPToVolume(InkOut, VolumeTmp); // in % @@ -5595,6 +5715,7 @@ void Tango::ColorLib::ColorConverter::DirectInversionCalc(double *LabIn, VectorX } double minVal = 1e+05; int minInd = -1; + int kComponent = 3; if (nfeas >= 0) { for (i = 0; i < nfeas + 1; ++i) @@ -5608,12 +5729,19 @@ void Tango::ColorLib::ColorConverter::DirectInversionCalc(double *LabIn, VectorX } else { + //There are no feasible solutions + //Eliminate all solutions that have a K lower then the uniformity threshold + //Sacrifiicing accuracy to uniformity + for (i = 0; i < nk; ++i) { - if (dECMC[i] < minVal) + if (Vol[i][kComponent] > m_LightInksThr) { - minVal = dECMC[i]; - minInd = i; + if (dECMC[i] < minVal) + { + minVal = dECMC[i]; + minInd = i; + } } } } @@ -5626,15 +5754,14 @@ void Tango::ColorLib::ColorConverter::DirectInversionCalc(double *LabIn, VectorX GamutRegion = VecGamutRegion[minInd]; double *LabOutFinal = new double[3]; + for (int i = 0; i < 3; ++i) LabOutFinal[i] = finalLab[minInd][i]; //LabOutFinal is in Relative Colorimetric //Reverse the conversion process to bring back Lab to STRIP white point ColConv.ChangeWP(LabOutFinal, LabOutFinal, m_whitepointXYZ_Strip, m_WP); - ColConv.ChangeWP(LabOnGamut, LabOnGamut, m_whitepointXYZ_Strip, m_WP); - LabOut = DoubleToVector(LabOnGamut, 3); - + LabOut = DoubleToVector(LabOutFinal, 3); ColConv.SetReferenceWhite(D65); //Convert to RGB double *RGBOutP = new double[3]; @@ -5798,3 +5925,144 @@ size_t Tango::ColorLib::ColorConverter::InitConvertLiquids(ConversionInput *conv conversionInput->inputcoordinates->n_inputliquids = expected_liquids; return((size_t)expected_liquids); } + +void Tango::ColorLib::ColorConverter::LimitInksPercentage(VectorXd inInks, VectorXd &outInks, bool &isBounded, int GRegion) +{ + double *BoundedInks = new double[m_nInks]; + LimitInks(inInks, BoundedInks, GRegion); //Limited based on the definition of m_currentMaxNLPerCM + outInks = DoubleToVector(BoundedInks, m_nInks); // BoundedInks is in nl/cm + NLcmtoPercentage(outInks, outInks); + isBounded = false; + for (int i = 1; i < m_nInks; ++i) + { + if (std::fabs(inInks(i) - outInks(i)) > eps) + isBounded = true; + } + if (BoundedInks != NULL) + { + delete[] BoundedInks; + BoundedInks = NULL; + } +} + +void Tango::ColorLib::ColorConverter::LimitNLInks2Volume(VectorXd &NLInks, int &GamutRegion, VectorXd &Volume, int CTUnits, + bool &InGamut, bool isBounded) +{ + //VectorXd NLInkOut(m_nInks); + double *InkOutL = new double[m_nInks]; + VectorXd NLInksV(m_nInks); + // NLInks are in the full thread range + LimitInks(NLInks, InkOutL, 1); // NLInks is in %, InkOutL in [nl/cm] + NLInkPToVolume(DoubleToVector(InkOutL, m_nInks), Volume); // InkOutL in [nl/cm] Volume in [nl/cm] + GamutRegion = GetGamutRegion(Volume, m_CurrentProcessRangesMax); //Volume in [nl/cm] + GetClosestInk(Volume, GamutRegion, Volume, CTUnits); //Input Volume is in [nl/cm] Output Volume is in [%] + //NLcmtoPercentage(Volume, Volume); + ConfineVolumes(Volume); // Input Volume is in[%] Output Volume is in[%] + VolumeToNLInkP(Volume, NLInksV); //NLInks are in % + for (int i = 1; i < m_nInks; ++i) + { + if (std::fabs(NLInks(i) - NLInksV(i)) > eps) + isBounded = true; + } + if (InkOutL != NULL) + { + delete[]InkOutL; + InkOutL = NULL; + } +} + +void Tango::ColorLib::ColorConverter::SetRMLParameters(ConversionInput *conversionInput) +{ + //Set Process Ranges + if (conversionInput->n_processranges <= 0) + throw std::exception("number of process ranges is zero"); + else + m_nProcessRanges = conversionInput->n_processranges; + + double *tmpVal; + if (m_GamutRegionMaxLim == NULL) + m_GamutRegionMaxLim = new double[m_nProcessRanges]; + tmpVal = m_colortable->GetGamutRegionMaxLim(); + for (int i = 0; i < m_nProcessRanges; ++i) + m_GamutRegionMaxLim[i] = tmpVal[i]; + + if (m_GamutRegionMinLim == NULL) + m_GamutRegionMinLim = new double[m_nProcessRanges]; + tmpVal = m_colortable->GetGamutRegionMinLim(); + for (int i = 0; i < m_nProcessRanges; ++i) + m_GamutRegionMinLim[i] = tmpVal[i]; + + //Set Process Ranges + //Verify process ranges are not zero and monotonic + for (int i = 0; i < m_nProcessRanges; ++i) + { + if (conversionInput->processranges[i]->maxinkuptake <= 0) + throw std::exception("Process Range is zero\0"); + } + double diff = 0; + for (int i = 1; i < m_nProcessRanges; ++i) + { + diff = conversionInput->processranges[i]->maxinkuptake - conversionInput->processranges[i - 1]->maxinkuptake; + if (diff < 0) + throw std::exception("Process Ranges are not monotonic\0"); + } + //MaxInkUptake + if (m_ProcessRangesMaxP == NULL) + m_ProcessRangesMaxP = new double[m_nProcessRanges]; + for (int i = 0; i < m_nProcessRanges; ++i) + { + m_ProcessRangesMaxP[i] = conversionInput->processranges[i]->maxinkuptake; + } + //MinInkUptake + if (m_ProcessRangesMinP == NULL) + m_ProcessRangesMinP = new double[m_nProcessRanges]; + for (int i = 0; i < m_nProcessRanges; ++i) + { + m_ProcessRangesMinP[i] = conversionInput->processranges[i]->mininkuptake; + } +//Allocate Current Process Ranges, could be table ranges or thread ranges + if (m_CurrentProcessRangesMax == NULL) + m_CurrentProcessRangesMax = new double[m_nProcessRanges]; + if (m_CurrentProcessRangesMin == NULL) + m_CurrentProcessRangesMin = new double[m_nProcessRanges]; + + //define Low Volume threshold and Light Inks Threshold + m_LightInksThr = conversionInput->vmax; + m_LowVolumeThreshold = m_LightInksThr / DilutionFactor; + m_LowVolHalf = m_LowVolumeThreshold / 2; + + //set maxNlPerCM + VectorXd NlperCM(m_nInks); + NlperCM.setZero(); + m_maxNlPerCM = NlperCM; + for (int i = 0; i < m_nInks; ++i) + SetMaxNLperCM(conversionInput->inputcoordinates->inputliquids[i]->maxnanoliterpercentimeter, i); + m_CTmaxNlPerCM = NlperCM; + double *tmpLF = m_colortable->GetCTLiquidFactors(); + for (int i = 0; i < m_nInks; ++i) + m_CTmaxNlPerCM(i) = tmpLF[i]; +} + +void Tango::ColorLib::ColorConverter::VerifyGBD() +{ + if (m_Has_GBD) + { + if (m_nProcessRanges != m_ThreadGBD->GetnGamutRegions()) //m_nProcessRanges from RML + { + throw std::exception("Number of Process Ranges missmatch\0"); + } + + double *GBDLiquidFactors = m_ThreadGBD->GetCTLiquidFactors(); + for (int i = 1; i < m_nInks; ++i) + { + if (std::abs(GBDLiquidFactors[i] - m_maxNlPerCM(i))) + throw std::exception("Liquid Factors missmatch\0"); + } + double *GBDProcessRanges = m_ThreadGBD->GetGamutRegionMaxLim(); + for (int i = 1; i < m_nProcessRanges; ++i) + { + if (std::abs(GBDProcessRanges[i] - m_ProcessRangesMaxP[i])) + throw std::exception(" Process Ranges missmatch\0"); + } + } +} \ No newline at end of file diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ColorConverter.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ColorConverter.h index 01e05f545..c66e2a87c 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ColorConverter.h +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ColorConverter.h @@ -67,8 +67,6 @@ namespace Tango dESpaced }GradOffset; - - namespace ColorLib { class ColorConverter @@ -104,6 +102,7 @@ namespace Tango size_t P_IsInGamut(uint8_t * input_buffer, size_t input_buffer_size, uint8_t *& output_buffer); private: ColorTable *m_colortable; + ColorTable *m_ThreadGBD; ColorConvert *m_Conv02; LiquidType *m_InkNames; // Interp *m_LinInterp; @@ -119,6 +118,7 @@ namespace Tango double *m_ProcessRangesMinP; int m_nProcessRanges; bool m_UseLightInks; + bool m_Has_GBD; double m_LightInksThr; double m_LowVolumeThreshold; double m_LowVolHalf; @@ -135,7 +135,7 @@ namespace Tango int m_CalibMode; // bool m_AdaptWP; CalibData *m_CalibCurves; - ForwardModel *m_forwardmodel; + //ForwardModel *m_forwardmodel; int m_nInks; int m_nVolumes; //double *m_ProcessRangesMaxInkUptake; @@ -152,6 +152,9 @@ namespace Tango void readColorTransformations(ConversionInput* conversionInput); void readColorTransformations(OutOfGamutInput* Input); void readColorTransformations(RecommendedProcessTableInput *Input); + void readThreadGamut(ConversionInput*conversionInput); + void readThreadGamut(RecommendedProcessTableInput*conversionInput); + void readThreadGamut(OutOfGamutInput*conversionInput); // void readColorTables(bool has_rddata, uint8_t *data, int nprocessranges); void readCalibrationTables(InputLiquid **inputliquids, int n_inputliquids); void SetCalibData(CalibrationData* calibrationData, int i, CalibData *tmpCurve); @@ -188,7 +191,8 @@ namespace Tango void GradInput2InputCoords(GradientConversionInput *conversionInput, InputCoordinates **inputcoordinates); void ProcessGradientStops(InputCoordinates **inputcoordinates); void PrepareGradient(GradientConversionInput* conversionInput, GradientConversionOutput *conversionOutput); - void LimitInks(VectorXd inInks, double *BoundedInks); + void LimitInks(VectorXd inInks, double *BoundedInks, int GRegion); + void LimitInksPercentage(VectorXd inInks, VectorXd &outInks, bool &isBounded, int GRegion); void NLcmtoPercentage(VectorXd InVolume, VectorXd &OutVolume); void PercentagetoNLcm(VectorXd InVolume, VectorXd &OutVolume); int GetGamutRegion(VectorXd Volume, double *GamutLimits); @@ -206,10 +210,10 @@ namespace Tango VectorXd &LabOut, int &GamutRegion, bool &InGamut, SURROUND sur, CAM02CS CS);*/ void LimitLowVolume(VectorXd InVolume, int &GamutRegion, VectorXd &OutVolume); void LimitLowVolumeP(VectorXd InVolume, int &GamutRegion, VectorXd &OutVolume); - void LimitNLInks2Volume(VectorXd NLInks, int &GamutRegion, VectorXd &OutVolume, int CTUnits, bool &InGamut); + void LimitNLInks2Volume(VectorXd &NLInks, int &GamutRegion, VectorXd &OutVolume, int CTUnits, bool &InGamut, bool isBounded); void LimitNLInks2VolumeNoFix(VectorXd NLInks, int &GamutRegion, VectorXd &Volume); void LimitNLInks2VolumeThr(VectorXd NLInks, int &GamutRegion, VectorXd &Volume); - void GetClosestInk(VectorXd Volume, int &GamutRegion, VectorXd &BestVolume, int CTUnits, bool &InGamut); + void GetClosestInk(VectorXd Volume, int &GamutRegion, VectorXd &BestVolume, int CTUnits); bool CheckMonotonicity(CalibrationData *calibdata); void ConfineVolumes(VectorXd &Volume); void SplitVolume(VectorXd Volume, VectorXd &VolumeLI, int &GamutRegion); @@ -217,11 +221,19 @@ namespace Tango void findGamutRegion(int &GamutRegion, double TotalVolume); void SetCalibMode(); void SetCalibFactorization(); + void SetMaxCalValues(); void ApplyCTLinearCurves(double *InkIn, double* InkOut); + void ApplyCTLinearCurvesR(double *InkIn, double* InkOut); void ApplyCTInvLinearCurves(double *InkIn, double* InkOut); + void ApplyCTInvLinearCurvesR(double *InkIn, double* InkOut); void ColorTable2Threadunits(VectorXd InkIn, VectorXd &InkOut); - void Thread2ColorTableunits(VectorXd InkIn, VectorXd &InkOut); + void Thread2ColorTableunits(VectorXd InkIn, VectorXd &InkOut); void PrepareObjectiveFunctionPars(); + void sortPairs(int *LgtInksIndex, double*LightVol, int numLgtInks); + void GetBackLightInks(VectorXd &VolumeLI, int &GamutRegion, VectorXd PrevVolume, + bool resplit, int PrevGamutRegion); + void SetRMLParameters(ConversionInput *conversionInput); + void VerifyGBD(); }; } } diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ForwardModel.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ForwardModel.cpp index 076064f66..ef08b45d6 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ForwardModel.cpp +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ForwardModel.cpp @@ -25,8 +25,8 @@ using namespace std; ForwardModel::ForwardModel() : - m_nChannels(0), m_nPCSChannels(0), m_whiteptLab(NULL), m_prec(0), - m_nEntries(0), m_CoeffList(NULL), m_expList(NULL), m_Vandermonde(NULL) + m_nChannels(0), m_nPCSChannels(0), m_whiteptLab(NULL), m_prec(0), + m_nEntries(0), m_CoeffList(NULL), m_expList(NULL), m_Vandermonde(NULL) { } @@ -35,7 +35,7 @@ ForwardModel::~ForwardModel() { if (m_CoeffList != NULL) { - for (int i=0; i< m_nPCSChannels; ++i) + for (int i = 0; i < m_nPCSChannels; ++i) delete[] m_CoeffList[i]; delete[] m_CoeffList; m_CoeffList = NULL; @@ -189,19 +189,19 @@ void ForwardModel::CalcFM(double *InInk, double *OutLab) { int i, k; //Calculate Vandermonde Vector [1 x number of entries] - for ( i = 0; i < m_nEntries; ++i) + for (i = 0; i < m_nEntries; ++i) { m_Vandermonde[i] = 1.0; - for ( k = 0; k < m_nChannels; ++k) - m_Vandermonde[i] *= std::pow( InInk[k], m_expList[i][k]); + for (k = 0; k < m_nChannels; ++k) + m_Vandermonde[i] *= std::pow(InInk[k], m_expList[i][k]); } //calculate Lab Vandermodex Coeefficients + FreeTerm for (i = 0; i < m_nPCSChannels; ++i) - { + { OutLab[i] = m_whiteptLab[i]; for (k = 0; k < m_nEntries; ++k) - OutLab[i] += m_Vandermonde[k] * m_CoeffList[k][i] ; + OutLab[i] += m_Vandermonde[k] * m_CoeffList[k][i]; } } @@ -209,7 +209,7 @@ void ForwardModel::SetFreeTerm(C_RGB_XYZ_Lab whiteptLab) { if (m_whiteptLab == NULL) m_whiteptLab = new double[m_nPCSChannels]; - + m_whiteptLab[0] = whiteptLab.Get_x(); m_whiteptLab[1] = whiteptLab.Get_y(); m_whiteptLab[2] = whiteptLab.Get_z(); diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ForwardModel.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ForwardModel.h index 5a310548f..3c7955bbb 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ForwardModel.h +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/ForwardModel.h @@ -23,7 +23,7 @@ private: void Set_nChannels(int nChannels) { m_nChannels = nChannels; }; void Set_nPCSChannels(int nPCSChannels) { m_nPCSChannels = nPCSChannels; }; void Set_nEntries(int nEntries) { m_nEntries = nEntries; }; - + double **m_CoeffList; double **m_expList; double *m_Vandermonde; diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorConvert.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorConvert.cpp index cc53b0473..087bac57e 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorConvert.cpp +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorConvert.cpp @@ -410,6 +410,21 @@ const C_RGB_XYZ_Lab &ColorConvert::GetReferenceWhite(void) const return(DataRGB); } +VectorXd ColorConvert::LabtoRGB(VectorXd & LabVal) + { + C_RGB_XYZ_Lab DataXYZ; + C_RGB_XYZ_Lab DataLab; + DataLab.Set(LabVal); + DataXYZ = LabToXYZ(DataLab); + C_RGB_XYZ_Lab DataRGB; + DataRGB = XYZtoRGB(DataXYZ); + VectorXd VecRGB(3); + VecRGB(0) = DataRGB.Get_x(); + VecRGB(1) = DataRGB.Get_y(); + VecRGB(2) = DataRGB.Get_z(); + return(VecRGB); + } + C_RGB_XYZ_Lab ColorConvert::LabtoRGBNoClip(C_RGB_XYZ_Lab& LabVal) { C_RGB_XYZ_Lab DataXYZ; @@ -469,19 +484,23 @@ const C_RGB_XYZ_Lab &ColorConvert::GetReferenceWhite(void) const LabOut[0] = LabOut1.Get_x(); LabOut[1] = LabOut1.Get_y(); LabOut[2] = LabOut1.Get_z(); - // SetReferenceWhite(SourceWhite); -/* C_RGB_XYZ_Lab LabOut2; - LabOut2 = XYZToLab(XYZ); - double *LabD = new double[3]; - double x = 100 - Lab.Get_x(); - double f = 100.0 / (100.0 + pow(x, 3) / 100.0); - LabD[0] = f*LabOut1.Get_x() + (1-f) *LabOut2.Get_x(); - LabD[1] = f*LabOut1.Get_y() + (1 - f) *LabOut2.Get_y(); - LabD[2] = f*LabOut1.Get_z() + (1 - f) *LabOut2.Get_z(); - return(LabD); */ } - + void ColorConvert::ChangeWP(VectorXd LabIn, VectorXd LabOut, C_RGB_XYZ_Lab SourceWhite, C_RGB_XYZ_Lab DestWhite) + { + SetReferenceWhite(SourceWhite); + C_RGB_XYZ_Lab Lab; + Lab.Set(LabIn(0), LabIn(1), LabIn(2)); + C_RGB_XYZ_Lab XYZ = LabToXYZ(Lab); + SetReferenceWhite(DestWhite); + C_RGB_XYZ_Lab LabOut1; + LabOut1 = XYZToLab(XYZ); + // LabOut1.Clamp(LowLab, HighLab); + // double *LabD = new double[3]; + LabOut(0) = LabOut1.Get_x(); + LabOut(1) = LabOut1.Get_y(); + LabOut(2) = LabOut1.Get_z(); + } void ColorConvert::ChangeWP(C_RGB_XYZ_Lab XYZIn, C_RGB_XYZ_Lab &LabOut, C_RGB_XYZ_Lab SourceWhite, C_RGB_XYZ_Lab DestWhite) { SetReferenceWhite(SourceWhite); diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorConvert.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorConvert.h index 55e1ebc41..0fba95be1 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorConvert.h +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorConvert.h @@ -81,7 +81,9 @@ class ColorConvert void LabtoRGB(double*InLab, double* OutRGB ); void ChangeWP(double *LabIn, double *LabOut, C_RGB_XYZ_Lab SourceWhite, C_RGB_XYZ_Lab DestWhite); void ChangeWP(C_RGB_XYZ_Lab LabIn, C_RGB_XYZ_Lab &LabOut, C_RGB_XYZ_Lab SourceWhite, C_RGB_XYZ_Lab DestWhite); + void ChangeWP(VectorXd LabIn, VectorXd LabOut, C_RGB_XYZ_Lab SourceWhite, C_RGB_XYZ_Lab DestWhite); C_RGB_XYZ_Lab LabtoRGB(C_RGB_XYZ_Lab& LabVal); + VectorXd LabtoRGB(VectorXd & LabVal); void RGBtoLab(double *InRGB, double *OutLab); C_RGB_XYZ_Lab RGBtoLab(C_RGB_XYZ_Lab& RGB); // void RGBtoLab(std::vector&InRGB, double *OutLab); diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorTable.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorTable.cpp index 768647a0b..28d255dea 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorTable.cpp +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorTable.cpp @@ -14,8 +14,10 @@ m_nA2BnSepIn(0), m_nA2BnSepOut(0), m_TableVersion(0), m_TableSubVersion(0), m_NormFactor(NULL), m_InvNormFactor(NULL), m_nGamutRegions(0), m_nProcessRanges(0), m_GamutRegionMinLim(NULL), m_GamutRegionMaxLim(NULL), m_NormGamutRegionMaxLim(NULL), m_CTLiquidFactors(NULL), -m_whitepointXYZ_CT(0.0), m_forwardmodel(NULL), m_forwardmodelR(NULL) +m_whitepointXYZ_CT(0.0) { + m_forwardmodel = new ForwardModel(); + m_forwardmodelR = new ForwardModel(); } ColorTable::~ColorTable() @@ -65,6 +67,11 @@ ColorTable::~ColorTable() delete[] m_GamutRegionMaxLim; m_GamutRegionMaxLim = NULL; } + if (m_GamutRegionMinLim != NULL) + { + delete[] m_GamutRegionMinLim; + m_GamutRegionMinLim = NULL; + } if (m_NormGamutRegionMaxLim != NULL) { delete[] m_NormGamutRegionMaxLim; @@ -80,23 +87,36 @@ ColorTable::~ColorTable() delete[] m_InvNormFactor; m_InvNormFactor = NULL; } - /*if (m_CTLiquidFactors != NULL) + if (m_CTLiquidFactors != NULL) { delete[] m_CTLiquidFactors; m_CTLiquidFactors = NULL; - }*/ + } + if(m_forwardmodel != NULL) + { + delete m_forwardmodel; + m_forwardmodel = NULL; + } + if (m_forwardmodelR != NULL) + { + delete m_forwardmodelR; + m_forwardmodelR = NULL; + } } -void ColorTable::InitColorTables(bool has_rddata, uint8_t *data, int nprocessranges) +void ColorTable::InitColorTables(bool has_rddata, uint8_t *data, int nprocessranges, int TType ) { - readColorTables(has_rddata, data, nprocessranges); - SetNormFactor(); - SetInverseNormFactor(); - if (m_NormGamutRegionMaxLim == NULL) - m_NormGamutRegionMaxLim = new double[m_nGamutRegions]; - NormGamutRegionMaxLim(); + if (has_rddata) + { + readColorTables(has_rddata, data, nprocessranges, TType); + SetNormFactor(); + SetInverseNormFactor(); + if (m_NormGamutRegionMaxLim == NULL) + m_NormGamutRegionMaxLim = new double[m_nGamutRegions]; + NormGamutRegionMaxLim(); + } } -void ColorTable::readColorTables(bool has_data, uint8_t * data, int nprocessranges) +void ColorTable::readColorTables(bool has_data, uint8_t * data, int nprocessranges, int TableType) { //parse Color Tansformations, placed in forward data int bytesread = 0; @@ -120,12 +140,12 @@ void ColorTable::readColorTables(bool has_data, uint8_t * data, int nprocessrang return; } double *tmpGamutRegionsLim = header->GetGamutRegionsMaxLimit(); - if(m_GamutRegionMaxLim == NULL) + if (m_GamutRegionMaxLim == NULL) m_GamutRegionMaxLim = new double[m_nGamutRegions]; for (int i = 0; i < m_nGamutRegions; ++i) { - if(tmpGamutRegionsLim[i]<=0) - { + if (tmpGamutRegionsLim[i] <= 0) + { throw std::exception("Gamut region Limit is zero or negative\0"); return; } @@ -146,26 +166,29 @@ void ColorTable::readColorTables(bool has_data, uint8_t * data, int nprocessrang else m_CTLiquidFactors[i] = tmpLF[i]; //in [nl/cm] } - if (m_GamutRegionMinLim == NULL) - m_GamutRegionMinLim = new double[m_nGamutRegions]; - if (m_TableSubVersion > 0) + if (TableType == 0) { - tmpGamutRegionsLim = header->GetGamutRegionsMinLimit(); - for (int i = 0; i < m_nGamutRegions; ++i) + if (m_GamutRegionMinLim == NULL) + m_GamutRegionMinLim = new double[m_nGamutRegions]; + if (m_TableSubVersion > 0) { - if (tmpGamutRegionsLim[i] <= 0) + tmpGamutRegionsLim = header->GetGamutRegionsMinLimit(); + for (int i = 0; i < m_nGamutRegions; ++i) { - throw std::exception("Min Gamut region Limit is zero or negative\0"); - return; + if (tmpGamutRegionsLim[i] <= 0) + { + throw std::exception("Min Gamut region Limit is zero or negative\0"); + return; + } + else + m_GamutRegionMinLim[i] = tmpGamutRegionsLim[i]; //in [nl/cm] } - else - m_GamutRegionMinLim[i] = tmpGamutRegionsLim[i]; //in [nl/cm] } - } - else - { - m_GamutRegionMinLim[0] = 200; - m_GamutRegionMinLim[1] = 300; + else + { + m_GamutRegionMinLim[0] = 200; + m_GamutRegionMinLim[1] = 300; + } } uint32_t tmp; uint8_t *buff = data; @@ -176,7 +199,7 @@ void ColorTable::readColorTables(bool has_data, uint8_t * data, int nprocessrang char **TagNames = new char*[tag_count]; //char **TagNames = DBG_NEW char*[tag_count]; int **TagSize = new int*[tag_count]; - + //int **TagSize = DBG_NEW int*[tag_count]; char tmpC[80]; int n = 0; @@ -188,8 +211,8 @@ void ColorTable::readColorTables(bool has_data, uint8_t * data, int nprocessrang tmp = conv.ByteToInt(buff, bytesread); n = sizeof(tmp); //tmpC = DBG_NEW char[n]; - conv.getchar(tmp, *tmpC); - TagNames[i] = new char[n+1]; + conv.getchar(tmp, *tmpC); + TagNames[i] = new char[n + 1]; //TagNames[i] = DBG_NEW char[n]; strncpy_s(TagNames[i], n + 1, tmpC, n); bytesread += 4; @@ -235,7 +258,7 @@ void ColorTable::readColorTables(bool has_data, uint8_t * data, int nprocessrang throw std::exception("Unknown Tag in Color Tables"); } - + for (int k = 0; k < tag_count; ++k) { switch (TList[k]) @@ -244,7 +267,7 @@ void ColorTable::readColorTables(bool has_data, uint8_t * data, int nprocessrang { uint8_t *A2BLUT = &(data[TagSize[k][0]]); int A2BLutsize = TagSize[k][1]; - if(m_A2BTransform == NULL) + if (m_A2BTransform == NULL) m_A2BTransform = new ColorTransf(); //m_A2BTransform = DBG_NEW ColorTransf(); m_A2BTransform->InitData(A2BLUT, A2BLutsize); @@ -266,7 +289,7 @@ void ColorTable::readColorTables(bool has_data, uint8_t * data, int nprocessrang { uint8_t *B2ALUT = &(data[TagSize[k][0]]); int B2ALutsize = TagSize[k][1]; - if(m_B2ATransform == NULL) + if (m_B2ATransform == NULL) m_B2ATransform = new ColorTransf(); //m_B2ATransform = DBG_NEW ColorTransf(); m_B2ATransform->InitData(B2ALUT, B2ALutsize); @@ -278,7 +301,7 @@ void ColorTable::readColorTables(bool has_data, uint8_t * data, int nprocessrang { uint8_t *B2ARLUT = &(data[TagSize[k][0]]); int B2ARLutsize = TagSize[k][1]; - if(m_B2ARTransform == NULL) + if (m_B2ARTransform == NULL) m_B2ARTransform = new ColorTransf(); //m_B2ATransform = DBG_NEW ColorTransf(); m_B2ARTransform->InitData(B2ARLUT, B2ARLutsize); @@ -296,7 +319,7 @@ void ColorTable::readColorTables(bool has_data, uint8_t * data, int nprocessrang case gbd: { uint8_t *GBDList = &(data[TagSize[k][0]]); - if(m_GBD == NULL) + if (m_GBD == NULL) m_GBD = new GBD(); //m_GBD = DBG_NEW GBD(); int GBDSize = TagSize[k][1]; @@ -306,7 +329,7 @@ void ColorTable::readColorTables(bool has_data, uint8_t * data, int nprocessrang case gbdR: { uint8_t *GBDRList = &(data[TagSize[k][0]]); - if(m_GBDR == NULL) + if (m_GBDR == NULL) m_GBDR = new GBD(); //m_GBD = DBG_NEW GBD(); int GBDRSize = TagSize[k][1]; @@ -316,7 +339,7 @@ void ColorTable::readColorTables(bool has_data, uint8_t * data, int nprocessrang case lcrv: { uint8_t *CurvesData = &(data[TagSize[k][0]]); - if(m_LinCurves == NULL) + if (m_LinCurves == NULL) m_LinCurves = new Curves(); int CurvesSize = TagSize[k][1]; m_LinCurves->InitData(CurvesData, CurvesSize); @@ -352,8 +375,7 @@ void ColorTable::readColorTables(bool has_data, uint8_t * data, int nprocessrang case FMCo: { uint8_t *FMD = &(data[TagSize[k][0]]); - if (m_forwardmodel == NULL) - m_forwardmodel = new ForwardModel(); + int FMSize = TagSize[k][1]; m_forwardmodel->InitData(FMD, FMSize); break; @@ -361,8 +383,7 @@ void ColorTable::readColorTables(bool has_data, uint8_t * data, int nprocessrang case FMCR: { uint8_t *FMD = &(data[TagSize[k][0]]); - if (m_forwardmodelR == NULL) - m_forwardmodelR = new ForwardModel(); + int FMSize = TagSize[k][1]; m_forwardmodelR->InitData(FMD, FMSize); break; @@ -380,7 +401,7 @@ void ColorTable::readColorTables(bool has_data, uint8_t * data, int nprocessrang for (int i = 0; i < tag_count; ++i) { delete[] TagNames[i]; - // TagNames[i] = NULL; + // TagNames[i] = NULL; } delete[]TagNames; TagNames = NULL; @@ -412,73 +433,77 @@ void ColorTable::readColorTables(bool has_data, uint8_t * data, int nprocessrang //Verify all relevant tags had been read - if (m_A2BTransform == NULL) + if (TableType == 0) { - throw std::exception("Missing Forward Transform in Color Tables"); - return; - } - if( TblVer > 1 ) - { - if (m_A2BRTransform == NULL) + if (m_A2BTransform == NULL) { - throw std::exception("Missing Reduced Forward Transform in Color Tables"); + throw std::exception("Missing Forward Transform in Color Tables"); return; - } - } - if (m_B2ATransform == NULL) - { - throw std::exception("Missing Inverse Transform in Color Tables"); - return; - } - if (TblVer > 1) - { - if (m_B2ARTransform == NULL) + } + if (TblVer > 1) { - throw std::exception("Missing Reduced Inverse Transform in Color Tables"); + if (m_A2BRTransform == NULL) + { + throw std::exception("Missing Reduced Forward Transform in Color Tables"); + return; + } + } + if (m_B2ATransform == NULL) + { + throw std::exception("Missing Inverse Transform in Color Tables"); return; } - } - if (m_GBD == NULL) - { - throw std::exception("Missing Gamut Boundary Descriptor in Color Tables"); - return; - } - if (TblVer > 1) - { - if (m_GBDR == NULL) + if (TblVer > 1) + { + if (m_B2ARTransform == NULL) + { + throw std::exception("Missing Reduced Inverse Transform in Color Tables"); + return; + } + } + + if ((m_whitepointXYZ_CT.Get_x() == -1) && (m_whitepointXYZ_CT.Get_y() == -1) && (m_whitepointXYZ_CT.Get_z() == -1)) { - throw std::exception("Missing Reduced Gamut Boundary Descriptor in Color Tables"); + throw std::exception("Missing Whitepoint in Color Tables"); return; } - } - if ((m_whitepointXYZ_CT.Get_x() == -1) && (m_whitepointXYZ_CT.Get_y() == -1) && (m_whitepointXYZ_CT.Get_z() == -1)) - { - throw std::exception("Missing Whitepoint in Color Tables"); - return; - } - if (m_LinCurves == NULL) - { - throw std::exception("Missing Linear Curves in Color Tables"); - return; - } - if( TblVer > 1) - { - if (m_LinCurvesR == NULL) + if (m_LinCurves == NULL) { - throw std::exception("Missing Linear Curves 100 in Color Tables"); + throw std::exception("Missing Linear Curves in Color Tables"); return; } - } - if (m_TableSubVersion > 0) - { - if(m_forwardmodel == NULL) - throw std::exception("Missing Forward Model Info in Color Tables"); - return; - if(m_TableVersion > 1) + if (TblVer > 1) { - if (m_forwardmodelR == NULL) - throw std::exception("Missing Forward Model 100 Info in Color Tables"); + if (m_LinCurvesR == NULL) + { + throw std::exception("Missing Linear Curves 100 in Color Tables"); + return; + } + } + if (m_TableSubVersion > 0) + { + if (m_forwardmodel == NULL) + throw std::exception("Missing Forward Model Info in Color Tables"); return; + if (m_TableVersion > 1) + { + if (m_forwardmodelR == NULL) + throw std::exception("Missing Forward Model 100 Info in Color Tables"); + return; + } + } + if (m_GBD == NULL) + { + throw std::exception("Missing Gamut Boundary Descriptor in Color Tables"); + return; + } + if (TblVer > 1) + { + if (m_GBDR == NULL) + { + throw std::exception("Missing Reduced Gamut Boundary Descriptor in Color Tables"); + return; + } } } return; // OK @@ -767,3 +792,18 @@ void ColorTable::NormGamutRegionMaxLim() m_NormGamutRegionMaxLim[i] = 100 * m_GamutRegionMaxLim[i] / GamutRegionMaxLim0; } +void ColorTable::SetGBD(GBD *GamutDescriptor) +{ + + int old_nTriangles = m_GBD->GetNTriangles(); + int new_nTriangles = GamutDescriptor->GetNTriangles(); + m_GBD->SetCenter(GamutDescriptor->getCenter()); //Set Gamut Center + m_GBD->SetNDev_Channels(GamutDescriptor->GetDev_Channels()); //Set Number of Device Channels + m_GBD->SetNPCS_Channels(GamutDescriptor->GetNPCS_Channels()); //Set number of PCS channels + m_GBD->SetNTriangles(GamutDescriptor->GetNTriangles()); //Set Number of Triangles + m_GBD->SetNVertices(GamutDescriptor->GetNVertices()); //Set Number of Vertices + m_GBD->SetVertices(GamutDescriptor->GetVertices(0), 0, old_nTriangles, new_nTriangles); //Set Vertices + m_GBD->SetVertices(GamutDescriptor->GetVertices(1), 1, old_nTriangles, new_nTriangles); + m_GBD->SetVertices(GamutDescriptor->GetVertices(2), 2, old_nTriangles, new_nTriangles); +} + diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorTable.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorTable.h index 319e10fb7..6cf953637 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorTable.h +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorTable.h @@ -24,17 +24,19 @@ typedef enum { FMCo, FMCR }TagList; + class ColorTable { public: ColorTable(); ~ColorTable(); - void InitColorTables(bool has_rddata, uint8_t *data, int nprocessranges); + void InitColorTables(bool has_rddata, uint8_t *data, int nprocessranges, int TableType ); int GetnB2AnSepIn( ){ return(m_nB2AnSepIn); }; int GetnB2AnSepOut() { return(m_nB2AnSepOut); }; int GetnA2BnSepIn() { return(m_nA2BnSepIn); }; int GetnA2BnSepOut() { return(m_nA2BnSepOut); }; int GetnGamutRegions() { return(m_nGamutRegions); }; + void SetGBD(GBD *GamutDescriptor); double *GetNormFactor() { return(m_NormFactor); }; double *GetInverseNormFactor() { return(m_InvNormFactor); }; double *GetNormGamutRegionMaxLim() { return(m_NormGamutRegionMaxLim); }; @@ -56,10 +58,11 @@ public: ForwardModel *m_forwardmodel; ForwardModel *m_forwardmodelR; private: - void readColorTables(bool has_rddata, uint8_t *data, int nprocessranges); + void readColorTables(bool has_rddata, uint8_t *data, int nprocessranges, int TableType); void SetNormFactor(); void SetInverseNormFactor(); void NormGamutRegionMaxLim(); + int m_nB2AnSepIn; int m_nB2AnSepOut; int m_nA2BnSepIn; diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorTransf.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorTransf.cpp index 9e59abf4d..ded4200aa 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorTransf.cpp +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorTransf.cpp @@ -35,9 +35,9 @@ using namespace std; ColorTransf::ColorTransf() : - m_MSBShift(0), m_DataBuffer(NULL), m_SeparationsIn(0), + m_MSBShift(0), m_SeparationsIn(0), m_SeparationsOut(0), m_nGridPoints(0), m_GamutLimitsNlperCM(NULL), - m_NGamutRegions(0), m_ByteBuffer(NULL), m_InputCurves(NULL), m_OutputCurves(NULL), + m_NGamutRegions(0), m_InputCurves(NULL), m_OutputCurves(NULL), m_num_input_table_entries(0), m_num_output_table_entries(0) { @@ -45,21 +45,11 @@ using namespace std; ColorTransf::~ColorTransf() { - if (m_DataBuffer != NULL) - { - delete[] m_DataBuffer; - m_DataBuffer = NULL; - } if (m_GamutLimitsNlperCM != NULL) { delete[] m_GamutLimitsNlperCM; m_GamutLimitsNlperCM = NULL; } - if (m_ByteBuffer != NULL) - { - delete[] m_ByteBuffer; - m_ByteBuffer = NULL; - } if (m_InputCurves != NULL) { delete[] m_InputCurves; @@ -203,8 +193,8 @@ using namespace std; if (TablePrecision == 1) { // int lsizeH2 = (lSize - bytesread + 1) / 2; - if(m_ByteBuffer == NULL) - m_ByteBuffer = new unsigned char[clut_size]; + unsigned char *ByteBuffer = new unsigned char[clut_size]; + int lSizeperSep = clut_size / m_SeparationsOut; int indR = 0; for (int i = 0; i < lSizeperSep; ++i) @@ -212,32 +202,30 @@ using namespace std; for (int j = 0; j < m_SeparationsOut; ++j) { //m_ByteBuffer[indR] = Conv.ByteToShort(buffer, bytesread); - m_ByteBuffer[indR] = buffer[bytesread]; + ByteBuffer[indR] = buffer[bytesread]; bytesread += 1; indR++; } } - m_InterpColor.InitData(m_ByteBuffer, m_SeparationsIn, m_SeparationsOut, m_nGridPoints, m_MSBShift); + m_InterpColor.InitData(ByteBuffer, m_SeparationsIn, m_SeparationsOut, m_nGridPoints, m_MSBShift); } else { // int lsizeH4 = (lSize - bytesread + 1) / 2; - if(m_DataBuffer == NULL) - m_DataBuffer = new unsigned short[clut_size]; - //m_DataBuffer = DBG_NEW unsigned short[lsizeH4]; + unsigned short *DataBuffer = new unsigned short[clut_size]; int lSizeperSep = clut_size / m_SeparationsOut; int indR = 0; for (int i = 0; i < lSizeperSep; ++i) { for (int j = 0; j < m_SeparationsOut; ++j) { - m_DataBuffer[indR] = Conv.ByteToShort(buffer, bytesread); + DataBuffer[indR] = Conv.ByteToShort(buffer, bytesread); bytesread += 2; indR++; } } // terminate reading data file - m_InterpColor.InitData(m_DataBuffer, m_SeparationsIn, m_SeparationsOut, m_nGridPoints, m_MSBShift); + m_InterpColor.InitData(DataBuffer, m_SeparationsIn, m_SeparationsOut, m_nGridPoints, m_MSBShift); } //Read Output Curves diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorTransf.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorTransf.h index e61135dae..ea0b3d033 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorTransf.h +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ColorTransf.h @@ -35,9 +35,6 @@ private: Interp *m_OutputCurves; void free_char_array(char* charname); - unsigned short *m_DataBuffer; - unsigned char *m_ByteBuffer; - void SetNGridpoints(int nGridPoints) { m_nGridPoints = nGridPoints; }; void SetSeparationsIn(int SeparationsIn) { m_SeparationsIn = SeparationsIn; }; void SetSeparationsOut(int SeparationsOut) { m_SeparationsOut = SeparationsOut; }; diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/GBD.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/GBD.cpp index 3e4f49878..9294168fe 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/GBD.cpp +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/GBD.cpp @@ -40,7 +40,7 @@ typedef enum { GBD::GBD() : m_prec(0), m_nPCSChan(0), - m_nDevChan(0), m_CenterLab(0), m_nVertices(0), m_Vertices(NULL), + m_nDevChan(0), m_CenterLab(0), m_nVertices(0), m_nTriangles(0), m_vert0(NULL), m_vert1(NULL), m_vert2(NULL) { @@ -69,12 +69,6 @@ GBD::~GBD() delete[] m_vert2; m_vert2 = NULL; } - if (m_Vertices != NULL) - { - delete[] m_Vertices; - m_Vertices = NULL; - } - } void GBD::TriangleRayIntersection(double *origin, double *direction, bool &intersect, double *xCoor) @@ -174,6 +168,96 @@ void GBD::TriangleRayIntersection(double *origin, double *direction, bool &inter return; } +double **GBD::GetVertices(int iVert) +{ + switch (iVert) + { + case 0: + { + return(m_vert0); + break; + } + case 1: + { + return(m_vert1); + break; + } + case 2: + { + return(m_vert2); + break; + } + default: + { + throw std::exception("Unsupported vertex number"); + return(0); + } + } +} + + +void GBD::SetVertices(double **vert, int iVert, int oldn, int newn) +{ + switch (iVert) + { + case 0: + { + if (m_vert0 != NULL) + { + for (int i = 0; i < oldn; ++i) + delete[] m_vert0[i]; + delete[] m_vert0; + } + m_vert0 = new double*[newn]; + for (int i = 0; i < newn; ++i) + { + m_vert0[i] = new double[m_nPCSChan]; + for (int j = 0; j < m_nPCSChan; ++j) + m_vert0[i][j] = vert[i][j]; + } + break; + } + case 1: + { + if (m_vert1 != NULL) + { + for (int i = 0; i < oldn; ++i) + delete[] m_vert1[i]; + delete[] m_vert1; + } + m_vert1 = new double*[newn]; + for (int i = 0; i < newn; ++i) + { + m_vert1[i] = new double[m_nPCSChan]; + for (int j = 0; j < m_nPCSChan; ++j) + m_vert1[i][j] = vert[i][j]; + } + break; + } + case 2: + { + if (m_vert2 != NULL) + { + for (int i = 0; i < oldn; ++i) + delete[] m_vert2[i]; + delete[] m_vert2; + } + m_vert2 = new double*[newn]; + for (int i = 0; i < newn; ++i) + { + m_vert2[i] = new double[m_nPCSChan]; + for (int j = 0; j < m_nPCSChan; ++j) + m_vert2[i][j] = vert[i][j]; + } + break; + } + default: + { + throw std::exception("Unsupported vertex number"); + return; + } + } +} void GBD::InitData(unsigned char* colorTransformBuffer, long colorTransformFileSize) { // 0-3 prec @@ -338,3 +422,4 @@ void GBD::crossProduct(VectorXd vect_A, VectorXd vect_B, VectorXd &cross_P) return; } + diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/GBD.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/GBD.h index 61aadf37a..75c528d1c 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/GBD.h +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/GBD.h @@ -13,8 +13,15 @@ public: int GetDev_Channels() { return(m_nDevChan); }; int GetNTriangles() { return(m_nTriangles); }; C_RGB_XYZ_Lab getCenter(){ return(m_CenterLab);}; + double **GetVertices(int i); + void SetVertices(double **Vert, int i, int oldn, int newn); void InitData(unsigned char* colorTransformBuffer, long colorTransformFileSize); void TriangleRayIntersection(double *origin, double *direction, bool &intersect, double *xCoor); + void SetNVertices(int nVertices) { m_nVertices = nVertices; }; + void SetNPCS_Channels(int nPCSChan) { m_nPCSChan = nPCSChan; }; + void SetNDev_Channels(int nDevChan) { m_nDevChan = nDevChan; }; + void SetNTriangles(int nTriangles) { m_nTriangles = nTriangles; }; + void SetCenter(C_RGB_XYZ_Lab center) {m_CenterLab = center;}; private: int m_prec; int m_nDevChan; @@ -22,14 +29,10 @@ private: int m_nVertices; int m_nTriangles; C_RGB_XYZ_Lab m_CenterLab; - C_RGB_XYZ_Lab *m_Vertices; double **m_vert0; double **m_vert1; double **m_vert2; - void SetNVertices(int nVertices) { m_nVertices = nVertices; }; - void SetNPCS_Channels(int nPCSChan) { m_nPCSChan = nPCSChan; }; - void SetNDev_Channels(int nDevChan) { m_nDevChan = nDevChan; }; - void SetNTriangles(int nTriangles) { m_nTriangles = nTriangles; }; + //void SetCenter( C_RGB_XYZ_Lab CenterLab); double dotProduct(VectorXd vect_A, VectorXd vect_B); void crossProduct(VectorXd vect_A, VectorXd vect_B, VectorXd &cross_P); diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/LevMar.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/LevMar.cpp index 865713737..ade641230 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/LevMar.cpp +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/LevMar.cpp @@ -106,7 +106,7 @@ LevMar::~LevMar() } if (m_LULS != NULL) { - delete[] m_LULS; + delete m_LULS; m_LULS = NULL; } } diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/LevMar.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/LevMar.h index fff02fe0a..289508345 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/LevMar.h +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/LevMar.h @@ -51,7 +51,6 @@ private: C_RGB_XYZ_Lab m_WPLabRel; C_RGB_XYZ_Lab m_WPTarget; VectorXd m_distWeights; - ColorTable m_ColorTable; double *m_ValsIn; double *m_Lab_Iter; double *m_difLab; diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/NDInterpUtils.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/NDInterpUtils.cpp index ccdff3e9d..5c265eb8a 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/NDInterpUtils.cpp +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/NDInterpUtils.cpp @@ -24,7 +24,7 @@ extern "C" NDInterpUtils::NDInterpUtils() : m_MSBShift(Sh4MSB), m_DataBuffer(NULL), m_nSeparationsIn(nSeparationsIn), m_Point(NULL), m_nSeparationsOut(nSeparationsOut), m_nGridPoints(0), m_SubCubeSize(0), m_LastCubeComp(0), - m_tmpResult(NULL) + m_tmpResult(NULL), m_ByteBuffer(NULL) { } @@ -48,7 +48,7 @@ extern "C" void NDInterpUtils::InitData(unsigned char *DataBuffer, int SeparationsIn, int SeparationsOut, int nGridPoints, int MSBShift) { SetMSBShift(MSBShift); - SetNDData((unsigned short *)DataBuffer); + SetNDData((unsigned char *)DataBuffer); SetSeparationsIn(SeparationsIn); SetSeparationsOut(SeparationsOut); SetNGridpoints(nGridPoints); @@ -68,10 +68,31 @@ extern "C" delete m_Point; if (m_tmpResult != NULL) delete m_tmpResult; - + if (m_DataBuffer != NULL) + delete m_DataBuffer; + if (m_ByteBuffer != NULL) + delete m_ByteBuffer; } + void NDInterpUtils::SetNDData(unsigned short *DataBuffer) + { + int nsize = sizeof(DataBuffer); + if (m_DataBuffer == NULL) + m_DataBuffer = new unsigned short[nsize]; + + for (int i = 0; i < nsize; ++i) + m_DataBuffer[i] = DataBuffer[i]; + } + void NDInterpUtils::SetNDData(unsigned char *DataBuffer) + { + int nsize = sizeof(DataBuffer); + if (m_ByteBuffer == NULL) + m_ByteBuffer = new unsigned char[nsize]; + + for (int i = 0; i < nsize; ++i) + m_ByteBuffer[i] = DataBuffer[i]; + } void NDInterpUtils::ColorMap4(const unsigned short * ValIn, double * ValOut) { diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/NDInterpUtils.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/NDInterpUtils.h index 992de082c..2e8e49002 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/NDInterpUtils.h +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/NDInterpUtils.h @@ -36,12 +36,13 @@ private: int m_nSeparationsOut; int m_nGridPoints; unsigned short *m_DataBuffer; + unsigned char *m_ByteBuffer; unsigned short *m_Point; int *m_tmpResult; void SetSubCubeSize(); void SetMSBShift(unsigned char ShMSB) { m_MSBShift = ShMSB; }; void SetLastCubeComp() { m_LastCubeComp = 0xFF - m_SubCubeSize / 2; }; - void SetdataBuffer(unsigned short *DataBuffer) { m_DataBuffer = DataBuffer; }; + void getMax4(int a, int b, int c, int d, int &max, int &pos); void getOrdering4(int a, int b, int c, int d, int &max, int &mid1, int &mid2, int &min, int &maxPos, @@ -51,7 +52,8 @@ private: int &max, int &mid1, int &min, int &maxPos, int &midPos1, int &minPos); void SetMSBShift(int MSBShift) { m_MSBShift = MSBShift; }; - void SetNDData(unsigned short *DataBuffer) { m_DataBuffer = DataBuffer; }; + void SetNDData(unsigned short *DataBuffer); + void SetNDData(unsigned char *DataBuffer); void SetSeparationsIn(int SeparationsIn) { m_nSeparationsIn = SeparationsIn; }; void SetSeparationsOut(int SeparationsOut) { m_nSeparationsOut = SeparationsOut; }; void SetNGridpoints(int nGridPoints) { m_nGridPoints = nGridPoints; }; diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ObjectiveFunction.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ObjectiveFunction.cpp index 2e746f09b..181c60ccb 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ObjectiveFunction.cpp +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ObjectiveFunction.cpp @@ -6,6 +6,7 @@ #include "ColorTable.h" #include "Dense" + using Eigen::MatrixXd; using Eigen::VectorXd; using Eigen::VectorXi; diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ObjectiveFunction.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ObjectiveFunction.h index 2e2da1f64..21427e516 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ObjectiveFunction.h +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v6/Utils/ObjectiveFunction.h @@ -4,6 +4,7 @@ #include "C_RGB_XYZ_Lab.h" #include "ColorTable.h" +#include "ForwardModel.h" class ObjectiveFunction { -- cgit v1.3.1