Skip to content

Commit 52c73f3

Browse files
Merge pull request #2987 from SixLabors/icc-pcs
Enforce ICC D50 PCS illuminant when converting colours between profiles
2 parents 73c4a1a + 819d0fc commit 52c73f3

File tree

3 files changed

+13
-7
lines changed

3 files changed

+13
-7
lines changed

src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsIcc.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ internal static TTo ConvertUsingIccProfile<TFrom, TTo>(this ColorProfileConverte
6060
ColorProfileConverter pcsConverter = new(new ColorConversionOptions
6161
{
6262
MemoryAllocator = converter.Options.MemoryAllocator,
63-
SourceWhitePoint = new CieXyz(converter.Options.SourceIccProfile.Header.PcsIlluminant),
64-
TargetWhitePoint = new CieXyz(converter.Options.TargetIccProfile.Header.PcsIlluminant),
63+
SourceWhitePoint = KnownIlluminants.D50Icc,
64+
TargetWhitePoint = KnownIlluminants.D50Icc
6565
});
6666

6767
// Normalize the source, then convert to the PCS space.
@@ -104,8 +104,8 @@ internal static void ConvertUsingIccProfile<TFrom, TTo>(this ColorProfileConvert
104104
ColorProfileConverter pcsConverter = new(new ColorConversionOptions
105105
{
106106
MemoryAllocator = converter.Options.MemoryAllocator,
107-
SourceWhitePoint = new CieXyz(converter.Options.SourceIccProfile.Header.PcsIlluminant),
108-
TargetWhitePoint = new CieXyz(converter.Options.TargetIccProfile.Header.PcsIlluminant),
107+
SourceWhitePoint = KnownIlluminants.D50Icc,
108+
TargetWhitePoint = KnownIlluminants.D50Icc
109109
});
110110

111111
using IMemoryOwner<Vector4> pcsBuffer = converter.Options.MemoryAllocator.Allocate<Vector4>(source.Length);

src/ImageSharp/ColorProfiles/KnownIlluminants.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace SixLabors.ImageSharp.ColorProfiles;
99
/// </summary>
1010
/// <remarks>
1111
/// Coefficients taken from: http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html
12+
/// and https://color.org/specification/ICC.1-2022-05.pdf
1213
/// <br />
1314
/// Descriptions taken from: http://en.wikipedia.org/wiki/Standard_illuminant
1415
/// </remarks>
@@ -30,10 +31,15 @@ public static class KnownIlluminants
3031
public static CieXyz C { get; } = new(0.98074F, 1F, 1.18232F);
3132

3233
/// <summary>
33-
/// Gets the Horizon Light. ICC profile PCS illuminant.
34+
/// Gets the Horizon Light.
3435
/// </summary>
3536
public static CieXyz D50 { get; } = new(0.96422F, 1F, 0.82521F);
3637

38+
/// <summary>
39+
/// Gets the D50 illuminant used in the ICC profile specification.
40+
/// </summary>
41+
public static CieXyz D50Icc { get; } = new(0.9642F, 1F, 0.8249F);
42+
3743
/// <summary>
3844
/// Gets the Mid-morning / Mid-afternoon Daylight illuminant.
3945
/// </summary>

tests/ImageSharp.Tests/ColorProfiles/Icc/ColorProfileConverterTests.Icc.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public class ColorProfileConverterTests(ITestOutputHelper testOutputHelper)
4242
[InlineData(TestIccProfiles.RommRgb, TestIccProfiles.StandardRgbV4)] // CMYK -> LAB -> CMYK (different bit depth v2 LUTs, 16-bit vs 8-bit)
4343
[InlineData(TestIccProfiles.Fogra39, TestIccProfiles.StandardRgbV2, 0.0005)] // CMYK -> LAB -> XYZ -> RGB (different LUT tags, A2B vs TRC) --- tolerance slightly higher due to difference in inverse curve implementation
4444
[InlineData(TestIccProfiles.StandardRgbV2, TestIccProfiles.Fogra39)] // RGB -> XYZ -> LAB -> CMYK (different LUT tags, TRC vs A2B)
45-
public void CanConvertIccProfiles(string sourceProfile, string targetProfile, double tolerance = 0.00005)
45+
public void CanConvertIccProfiles(string sourceProfile, string targetProfile, double tolerance = 0.000005)
4646
{
4747
List<Vector4> actual = Inputs.ConvertAll(input => GetActualTargetValues(input, sourceProfile, targetProfile));
4848
AssertConversion(sourceProfile, targetProfile, actual, tolerance, testOutputHelper);
@@ -63,7 +63,7 @@ public void CanConvertIccProfiles(string sourceProfile, string targetProfile, do
6363
[InlineData(TestIccProfiles.Fogra39, TestIccProfiles.StandardRgbV2, 0.0005)] // CMYK -> LAB -> XYZ -> RGB (different LUT tags, A2B vs TRC) --- tolerance slightly higher due to difference in inverse curve implementation
6464
[InlineData(TestIccProfiles.StandardRgbV2, TestIccProfiles.Fogra39)] // RGB -> XYZ -> LAB -> CMYK (different LUT tags, TRC vs A2B)
6565
[InlineData(TestIccProfiles.Issue129, TestIccProfiles.StandardRgbV4)] // CMYK -> LAB -> -> XYZ -> RGB
66-
public void CanBulkConvertIccProfiles(string sourceProfile, string targetProfile, double tolerance = 0.00005)
66+
public void CanBulkConvertIccProfiles(string sourceProfile, string targetProfile, double tolerance = 0.000005)
6767
{
6868
List<Vector4> actual = GetBulkActualTargetValues(Inputs, sourceProfile, targetProfile);
6969
AssertConversion(sourceProfile, targetProfile, actual, tolerance, testOutputHelper);

0 commit comments

Comments
 (0)