diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index b9e872502..6fd3eb30c 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -32,6 +32,12 @@ True PixelOperationsTests.Specialized.Generated.tt + + Always + + + Always + @@ -47,6 +53,7 @@ + @@ -80,9 +87,5 @@ - - - - diff --git a/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccProfileTests.cs b/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccProfileTests.cs index 9c4abfe3e..6b7050161 100644 --- a/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccProfileTests.cs +++ b/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccProfileTests.cs @@ -1,8 +1,11 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using SixLabors.ImageSharp.ColorProfiles; using SixLabors.ImageSharp.Metadata.Profiles.Icc; using SixLabors.ImageSharp.Tests.TestDataIcc; +using Wacton.Unicolour; +using Wacton.Unicolour.Icc; namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Icc; @@ -40,4 +43,67 @@ public class IccProfileTests Assert.Equal(expected, result); } + + private const string Fogra39 = "Coated_Fogra39L_VIGC_300.icc"; + private const string Swop2006 = "SWOP2006_Coated5v2.icc"; + + [Theory] + [InlineData(Fogra39, Fogra39)] + [InlineData(Fogra39, Swop2006)] + [InlineData(Swop2006, Fogra39)] + [InlineData(Swop2006, Swop2006)] + public void UnicolourComparison(string sourceProfileName, string targetProfileName) + { + string sourceIccFilepath = Path.Combine(".", "TestDataIcc", "Profiles", sourceProfileName); + string targetIccFilepath = Path.Combine(".", "TestDataIcc", "Profiles", targetProfileName); + + // TODO: pass in specific values to test? use random values? + Cmyk input = new(0.8f, 0.6f, 0.4f, 0.2f); + Cmyk expectedTargetValues = GetExpectedTargetCmyk(sourceIccFilepath, targetIccFilepath, input); + + ColorProfileConverter converter = new(new ColorConversionOptions + { + SourceIccProfile = new IccProfile(File.ReadAllBytes(sourceIccFilepath)), + TargetIccProfile = new IccProfile(File.ReadAllBytes(targetIccFilepath)) + }); + + Cmyk actualTargetValues = converter.Convert(input); + + const double tolerance = 0.0000005; + Assert.Equal(expectedTargetValues.C, actualTargetValues.C, tolerance); + Assert.Equal(expectedTargetValues.M, actualTargetValues.M, tolerance); + Assert.Equal(expectedTargetValues.Y, actualTargetValues.Y, tolerance); + Assert.Equal(expectedTargetValues.K, actualTargetValues.K, tolerance); + } + + private static Cmyk GetExpectedTargetCmyk(string sourceIccFilepath, string targetIccFilepath, Cmyk sourceCmyk) + { + Wacton.Unicolour.Configuration sourceConfig = GetUnicolourConfig(sourceIccFilepath); + Wacton.Unicolour.Configuration targetConfig = GetUnicolourConfig(targetIccFilepath); + + Channels channels = new(sourceCmyk.C, sourceCmyk.M, sourceCmyk.Y, sourceCmyk.K); + + Unicolour source = new(sourceConfig, channels); + ColourSpace pcs = sourceConfig.Icc.Profile!.Header.Pcs == "Lab " ? ColourSpace.Lab : ColourSpace.Xyz; + ColourTriplet pcsTriplet = pcs == ColourSpace.Lab ? source.Lab.Triplet : source.Xyz.Triplet; + Unicolour target = new(targetConfig, pcs, pcsTriplet.Tuple); + double[] targetCmyk = target.Icc.Values; + return new Cmyk((float)targetCmyk[0], (float)targetCmyk[1], (float)targetCmyk[2], (float)targetCmyk[3]); + } + + // Unicolour configurations are relatively expensive to instantiate + private static readonly Dictionary UnicolourConfigCache = new(); + + private static Wacton.Unicolour.Configuration GetUnicolourConfig(string iccFilepath) + { + Wacton.Unicolour.Configuration config; + if (UnicolourConfigCache.TryGetValue(iccFilepath, out config)) + { + return config; + } + + config = new Wacton.Unicolour.Configuration(iccConfiguration: new(iccFilepath, Intent.Unspecified)); + UnicolourConfigCache.Add(iccFilepath, config); + return config; + } } diff --git a/tests/ImageSharp.Tests/TestDataIcc/Profiles/Coated_Fogra39L_VIGC_300.icc b/tests/ImageSharp.Tests/TestDataIcc/Profiles/Coated_Fogra39L_VIGC_300.icc new file mode 100644 index 000000000..c6ae96169 Binary files /dev/null and b/tests/ImageSharp.Tests/TestDataIcc/Profiles/Coated_Fogra39L_VIGC_300.icc differ diff --git a/tests/ImageSharp.Tests/TestDataIcc/Profiles/SWOP2006_Coated5v2.icc b/tests/ImageSharp.Tests/TestDataIcc/Profiles/SWOP2006_Coated5v2.icc new file mode 100644 index 000000000..4c14430de Binary files /dev/null and b/tests/ImageSharp.Tests/TestDataIcc/Profiles/SWOP2006_Coated5v2.icc differ