From e67a67171c53eadbf76548475160f117ed3ed236 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 8 May 2024 19:59:15 +1000 Subject: [PATCH] Add some XYZ tests --- src/ImageSharp/ColorProfiles/CieLuv.cs | 10 +-- .../CieXyzAndCieLchuvConversionTests.cs | 69 +++++++++++++++ .../CieXyzAndCieLuvConversionTest.cs | 86 +++++++++++++++++++ 3 files changed, 160 insertions(+), 5 deletions(-) create mode 100644 tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLchuvConversionTests.cs create mode 100644 tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLuvConversionTest.cs diff --git a/src/ImageSharp/ColorProfiles/CieLuv.cs b/src/ImageSharp/ColorProfiles/CieLuv.cs index 8708ea255..304a14c7a 100644 --- a/src/ImageSharp/ColorProfiles/CieLuv.cs +++ b/src/ImageSharp/ColorProfiles/CieLuv.cs @@ -94,7 +94,7 @@ public readonly struct CieLuv : IColorProfile ? ((116 * Math.Pow(yr, e)) - 16d) : (CieConstants.Kappa * yr); - if (double.IsNaN(l)) + if (double.IsNaN(l) || l == -0d) { l = 0; } @@ -107,7 +107,7 @@ public readonly struct CieLuv : IColorProfile u = 0; } - if (double.IsNaN(v) || u == -0d) + if (double.IsNaN(v) || v == -0d) { v = 0; } @@ -151,17 +151,17 @@ public readonly struct CieLuv : IColorProfile double x = (d - b) / (a - c); double z = (x * a) + b; - if (double.IsNaN(x)) + if (double.IsNaN(x) || x == -0d) { x = 0; } - if (double.IsNaN(y)) + if (double.IsNaN(y) || y == -0d) { y = 0; } - if (double.IsNaN(z)) + if (double.IsNaN(z) || z == -0d) { z = 0; } diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLchuvConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLchuvConversionTests.cs new file mode 100644 index 000000000..fa604250f --- /dev/null +++ b/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLchuvConversionTests.cs @@ -0,0 +1,69 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using SixLabors.ImageSharp.ColorProfiles; + +namespace SixLabors.ImageSharp.Tests.ColorProfiles; + +/// +/// Tests - conversions. +/// +public class CieXyzAndCieLchuvConversionTests +{ + private static readonly ApproximateColorProfileComparer Comparer = new(.0002f); + + [Theory] + [InlineData(0.360555, 0.936901, 0.1001514, 97.50697, 177.345169, 142.601547)] + public void Convert_CieXyz_to_CieLchuv(float x, float y, float yl, float l, float c, float h) + { + // Arrange + CieXyz input = new(x, y, yl); + CieLchuv expected = new(l, c, h); + ColorProfileConverter converter = new(); + + Span inputSpan = new CieXyz[5]; + inputSpan.Fill(input); + + Span actualSpan = new CieLchuv[5]; + + // Act + CieLchuv actual = converter.Convert(input); + converter.Convert(inputSpan, actualSpan); + + // Assert + Assert.Equal(expected, actual, Comparer); + + for (int i = 0; i < actualSpan.Length; i++) + { + Assert.Equal(expected, actualSpan[i], Comparer); + } + } + + [Theory] + [InlineData(0, 0, 0, 0, 0, 0)] + [InlineData(97.50697, 177.345169, 142.601547, 0.360555, 0.936901, 0.1001514)] + public void Convert_CieLchuv_to_CieXyz(float l, float c, float h, float x, float y, float yl) + { + // Arrange + CieLchuv input = new(l, c, h); + CieXyz expected = new(x, y, yl); + ColorProfileConverter converter = new(); + + Span inputSpan = new CieLchuv[5]; + inputSpan.Fill(input); + + Span actualSpan = new CieXyz[5]; + + // Act + CieXyz actual = converter.Convert(input); + converter.Convert(inputSpan, actualSpan); + + // Assert + Assert.Equal(expected, actual, Comparer); + + for (int i = 0; i < actualSpan.Length; i++) + { + Assert.Equal(expected, actualSpan[i], Comparer); + } + } +} diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLuvConversionTest.cs b/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLuvConversionTest.cs new file mode 100644 index 000000000..68151eaa0 --- /dev/null +++ b/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLuvConversionTest.cs @@ -0,0 +1,86 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using SixLabors.ImageSharp.ColorProfiles; + +namespace SixLabors.ImageSharp.Tests.ColorProfiles; + +/// +/// Tests - conversions. +/// +/// +/// Test data generated using: +/// +/// +public class CieXyzAndCieLuvConversionTest +{ + private static readonly ApproximateColorProfileComparer Comparer = new(.0002f); + + [Theory] + [InlineData(0, 0, 0, 0, 0, 0)] + [InlineData(0, 100, 50, 0, 0, 0)] + [InlineData(0.1, 100, 50, 0.000493, 0.000111, -0.000709)] + [InlineData(70.0000, 86.3525, 2.8240, 0.569310, 0.407494, 0.365843)] + [InlineData(10.0000, -1.2345, -10.0000, 0.012191, 0.011260, 0.025939)] + [InlineData(100, 0, 0, 0.950470, 1.000000, 1.088830)] + [InlineData(1, 1, 1, 0.001255, 0.001107, 0.000137)] + public void Convert_Luv_to_Xyz(float l, float u, float v, float x, float y, float z) + { + // Arrange + CieLuv input = new(l, u, v); + CieXyz expected = new(x, y, z); + + ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 }; + ColorProfileConverter converter = new(options); + + Span inputSpan = new CieLuv[5]; + inputSpan.Fill(input); + + Span actualSpan = new CieXyz[5]; + + // Act + CieXyz actual = converter.Convert(input); + converter.Convert(inputSpan, actualSpan); + + // Assert + Assert.Equal(expected, actual, Comparer); + + for (int i = 0; i < actualSpan.Length; i++) + { + Assert.Equal(expected, actualSpan[i], Comparer); + } + } + + [Theory] + [InlineData(0, 0, 0, 0, 0, 0)] + [InlineData(0.000493, 0.000111, 0, 0.1003, 0.9332, -0.0070)] + [InlineData(0.569310, 0.407494, 0.365843, 70.0000, 86.3524, 2.8240)] + [InlineData(0.012191, 0.011260, 0.025939, 9.9998, -1.2343, -9.9999)] + [InlineData(0.950470, 1.000000, 1.088830, 100, 0, 0)] + [InlineData(0.001255, 0.001107, 0.000137, 0.9999, 0.9998, 1.0004)] + public void Convert_Xyz_to_Luv(float x, float y, float z, float l, float u, float v) + { + // Arrange + CieXyz input = new(x, y, z); + CieLuv expected = new(l, u, v); + + ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 }; + ColorProfileConverter converter = new(options); + + Span inputSpan = new CieXyz[5]; + inputSpan.Fill(input); + + Span actualSpan = new CieLuv[5]; + + // Act + CieLuv actual = converter.Convert(input); + + // Assert + Assert.Equal(expected, actual, Comparer); + + for (int i = 0; i < actualSpan.Length; i++) + { + Assert.Equal(expected, actualSpan[i], Comparer); + } + } +}