Browse Source

Complete conversion tests

pull/2739/head
James Jackson-South 2 years ago
parent
commit
9fdf204086
  1. 10
      src/ImageSharp/ColorProfiles/CieLuv.cs
  2. 57
      src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsCieLabRgb.cs
  3. 57
      src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsRgbCieLab.cs
  4. 2
      src/ImageSharp/ColorProfiles/Hsl.cs
  5. 6
      src/ImageSharp/ColorProfiles/Hsv.cs
  6. 2
      src/ImageSharp/ColorProfiles/LmsAdaptationMatrix.cs
  7. 4
      tests/ImageSharp.Tests/ColorProfiles/CieXyyAndHsvConversionTests.cs
  8. 4
      tests/ImageSharp.Tests/ColorProfiles/CieXyyAndHunterLabConversionTests.cs
  9. 49
      tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLuvConversionTest.cs
  10. 70
      tests/ImageSharp.Tests/ColorProfiles/CieXyzAndHslConversionTests.cs
  11. 70
      tests/ImageSharp.Tests/ColorProfiles/CieXyzAndHsvConversionTests.cs
  12. 74
      tests/ImageSharp.Tests/ColorProfiles/CieXyzAndHunterLabConversionTest.cs
  13. 4
      tests/ImageSharp.Tests/ColorProfiles/CieXyzAndLmsConversionTest.cs
  14. 70
      tests/ImageSharp.Tests/ColorProfiles/CieXyzAndYCbCrConversionTests.cs
  15. 69
      tests/ImageSharp.Tests/ColorProfiles/CmykAndCieLchConversionTests.cs
  16. 70
      tests/ImageSharp.Tests/ColorProfiles/CmykAndCieLuvConversionTests.cs
  17. 4
      tests/ImageSharp.Tests/ColorProfiles/CmykAndYCbCrConversionTests.cs
  18. 8
      tests/ImageSharp.Tests/ColorProfiles/RgbAndCieXyzConversionTest.cs
  19. 83
      tests/ImageSharp.Tests/ColorProfiles/RgbAndHslConversionTest.cs
  20. 81
      tests/ImageSharp.Tests/ColorProfiles/RgbAndHsvConversionTest.cs

10
src/ImageSharp/ColorProfiles/CieLuv.cs

@ -46,11 +46,6 @@ public readonly struct CieLuv : IColorProfile<CieLuv, CieXyz>
/// </summary>
public readonly float V { get; }
/// <summary>
/// Gets the reference white point of this color
/// </summary>
public readonly CieXyz WhitePoint { get; }
/// <summary>
/// Compares two <see cref="CieLuv"/> objects for equality.
/// </summary>
@ -185,7 +180,7 @@ public readonly struct CieLuv : IColorProfile<CieLuv, CieXyz>
=> ChromaticAdaptionWhitePointSource.WhitePoint;
/// <inheritdoc/>
public override int GetHashCode() => HashCode.Combine(this.L, this.U, this.V, this.WhitePoint);
public override int GetHashCode() => HashCode.Combine(this.L, this.U, this.V);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"CieLuv({this.L:#0.##}, {this.U:#0.##}, {this.V:#0.##})");
@ -198,8 +193,7 @@ public readonly struct CieLuv : IColorProfile<CieLuv, CieXyz>
public bool Equals(CieLuv other)
=> this.L.Equals(other.L)
&& this.U.Equals(other.U)
&& this.V.Equals(other.V)
&& this.WhitePoint.Equals(other.WhitePoint);
&& this.V.Equals(other.V);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static double ComputeU(in CieXyz source)

57
src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsCieLabRgb.cs

@ -0,0 +1,57 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.ColorProfiles;
internal static class ColorProfileConverterExtensionsCieLabRgb
{
public static TTo Convert<TFrom, TTo>(this ColorProfileConverter converter, TFrom source)
where TFrom : struct, IColorProfile<TFrom, CieLab>
where TTo : struct, IColorProfile<TTo, Rgb>
{
ColorConversionOptions options = converter.Options;
// Convert to input PCS
CieLab pcsFromA = source.ToProfileConnectingSpace(options);
CieXyz pcsFromB = pcsFromA.ToProfileConnectingSpace(options);
// Adapt to target white point
pcsFromB = VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, in pcsFromB);
// Convert between PCS
Rgb pcsTo = Rgb.FromProfileConnectingSpace(options, in pcsFromB);
// Convert to output from PCS
return TTo.FromProfileConnectingSpace(options, pcsTo);
}
public static void Convert<TFrom, TTo>(this ColorProfileConverter converter, ReadOnlySpan<TFrom> source, Span<TTo> destination)
where TFrom : struct, IColorProfile<TFrom, CieLab>
where TTo : struct, IColorProfile<TTo, Rgb>
{
ColorConversionOptions options = converter.Options;
// Convert to input PCS.
using IMemoryOwner<CieLab> pcsFromAOwner = options.MemoryAllocator.Allocate<CieLab>(source.Length);
Span<CieLab> pcsFromA = pcsFromAOwner.GetSpan();
TFrom.ToProfileConnectionSpace(options, source, pcsFromA);
using IMemoryOwner<CieXyz> pcsFromBOwner = options.MemoryAllocator.Allocate<CieXyz>(source.Length);
Span<CieXyz> pcsFromB = pcsFromBOwner.GetSpan();
CieLab.ToProfileConnectionSpace(options, pcsFromA, pcsFromB);
// Adapt to target white point
VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, pcsFromB, pcsFromB);
// Convert between PCS.
using IMemoryOwner<Rgb> pcsToOwner = options.MemoryAllocator.Allocate<Rgb>(source.Length);
Span<Rgb> pcsTo = pcsToOwner.GetSpan();
Rgb.FromProfileConnectionSpace(options, pcsFromB, pcsTo);
// Convert to output from PCS
TTo.FromProfileConnectionSpace(options, pcsTo, destination);
}
}

57
src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsRgbCieLab.cs

@ -0,0 +1,57 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.ColorProfiles;
internal static class ColorProfileConverterExtensionsRgbCieLab
{
public static TTo Convert<TFrom, TTo>(this ColorProfileConverter converter, TFrom source)
where TFrom : struct, IColorProfile<TFrom, Rgb>
where TTo : struct, IColorProfile<TTo, CieLab>
{
ColorConversionOptions options = converter.Options;
// Convert to input PCS
Rgb pcsFromA = source.ToProfileConnectingSpace(options);
CieXyz pcsFromB = pcsFromA.ToProfileConnectingSpace(options);
// Adapt to target white point
pcsFromB = VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, in pcsFromB);
// Convert between PCS
CieLab pcsTo = CieLab.FromProfileConnectingSpace(options, in pcsFromB);
// Convert to output from PCS
return TTo.FromProfileConnectingSpace(options, pcsTo);
}
public static void Convert<TFrom, TTo>(this ColorProfileConverter converter, ReadOnlySpan<TFrom> source, Span<TTo> destination)
where TFrom : struct, IColorProfile<TFrom, Rgb>
where TTo : struct, IColorProfile<TTo, CieLab>
{
ColorConversionOptions options = converter.Options;
// Convert to input PCS.
using IMemoryOwner<Rgb> pcsFromAOwner = options.MemoryAllocator.Allocate<Rgb>(source.Length);
Span<Rgb> pcsFromA = pcsFromAOwner.GetSpan();
TFrom.ToProfileConnectionSpace(options, source, pcsFromA);
using IMemoryOwner<CieXyz> pcsFromBOwner = options.MemoryAllocator.Allocate<CieXyz>(source.Length);
Span<CieXyz> pcsFromB = pcsFromBOwner.GetSpan();
Rgb.ToProfileConnectionSpace(options, pcsFromA, pcsFromB);
// Adapt to target white point
VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, pcsFromB, pcsFromB);
// Convert between PCS.
using IMemoryOwner<CieLab> pcsToOwner = options.MemoryAllocator.Allocate<CieLab>(source.Length);
Span<CieLab> pcsTo = pcsToOwner.GetSpan();
CieLab.FromProfileConnectionSpace(options, pcsFromB, pcsTo);
// Convert to output from PCS
TTo.FromProfileConnectionSpace(options, pcsTo, destination);
}
}

2
src/ImageSharp/ColorProfiles/Hsl.cs

@ -114,7 +114,7 @@ public readonly struct Hsl : IColorProfile<Hsl, Rgb>
}
h *= 60F;
if (h < 0F)
if (h < -Constants.Epsilon)
{
h += 360F;
}

6
src/ImageSharp/ColorProfiles/Hsv.cs

@ -111,10 +111,10 @@ public readonly struct Hsv : IColorProfile<Hsv, Rgb>
h = 4 + ((r - g) / chroma);
}
h *= 60;
if (h < 0f)
h *= 60F;
if (h < -Constants.Epsilon)
{
h += 360;
h += 360F;
}
s = chroma / v;

2
src/ImageSharp/ColorProfiles/LmsAdaptationMatrix.cs

@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.ColorProfiles;
/// </summary>
/// <remarks>
/// Matrix data obtained from:
/// Two New von Kries Based Chromatic Adaptation Transforms Found by Numerical Optimization
/// Two New Von Kries Based Chromatic Adaptation Transforms Found by Numerical Optimization
/// S. Bianco, R. Schettini
/// DISCo, Department of Informatics, Systems and Communication, University of Milan-Bicocca, viale Sarca 336, 20126 Milan, Italy
/// https://web.stanford.edu/~sujason/ColorBalancing/Papers/Two%20New%20von%20Kries%20Based%20Chromatic%20Adaptation.pdf

4
tests/ImageSharp.Tests/ColorProfiles/CieXyyAndHsvConversionTests.cs

@ -15,7 +15,7 @@ public class CieXyyAndHsvConversionTests
[Theory]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(0.360555, 0.936901, 0.1001514, 120, 1, 0.42770)]
public void Convert_CieXyy_to_Hsv(float x, float y, float yl, float h, float s, float v)
public void Convert_CieXyy_To_Hsv(float x, float y, float yl, float h, float s, float v)
{
// Arrange
CieXyy input = new(x, y, yl);
@ -43,7 +43,7 @@ public class CieXyyAndHsvConversionTests
[Theory]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(120, 1, 0.42770, 0.32114, 0.59787, 0.10976)]
public void Convert_Hsv_to_CieXyy(float h, float s, float v, float x, float y, float yl)
public void Convert_Hsv_To_CieXyy(float h, float s, float v, float x, float y, float yl)
{
// Arrange
Hsv input = new(h, s, v);

4
tests/ImageSharp.Tests/ColorProfiles/CieXyyAndHunterLabConversionTests.cs

@ -15,7 +15,7 @@ public class CieXyyAndHunterLabConversionTests
[Theory]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(0.360555, 0.936901, 0.1001514, 31.6467056, -33.00599, 25.67032)]
public void Convert_CieXyy_to_HunterLab(float x, float y, float yl, float l, float a, float b)
public void Convert_CieXyy_To_HunterLab(float x, float y, float yl, float l, float a, float b)
{
// Arrange
CieXyy input = new(x, y, yl);
@ -43,7 +43,7 @@ public class CieXyyAndHunterLabConversionTests
[Theory]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(31.6467056, -33.00599, 25.67032, 0.360555, 0.936901, 0.1001514)]
public void Convert_HunterLab_to_CieXyy(float l, float a, float b, float x, float y, float yl)
public void Convert_HunterLab_To_CieXyy(float l, float a, float b, float x, float y, float yl)
{
// Arrange
HunterLab input = new(l, a, b);

49
tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLuvConversionTest.cs

@ -18,29 +18,28 @@ public class CieXyzAndCieLuvConversionTest
[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)
[InlineData(0.000493, 0.000111, 0, 0.10026589, 0.9332349, -0.00704865158)]
[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
CieLuv input = new(l, u, v);
CieXyz expected = new(x, y, z);
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<CieLuv> inputSpan = new CieLuv[5];
Span<CieXyz> inputSpan = new CieXyz[5];
inputSpan.Fill(input);
Span<CieXyz> actualSpan = new CieXyz[5];
Span<CieLuv> actualSpan = new CieLuv[5];
// Act
CieXyz actual = converter.Convert<CieLuv, CieXyz>(input);
converter.Convert<CieLuv, CieXyz>(inputSpan, actualSpan);
CieLuv actual = converter.Convert<CieXyz, CieLuv>(input);
converter.Convert<CieXyz, CieLuv>(inputSpan, actualSpan);
// Assert
Assert.Equal(expected, actual, Comparer);
@ -53,27 +52,29 @@ public class CieXyzAndCieLuvConversionTest
[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)
[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
CieXyz input = new(x, y, z);
CieLuv expected = new(l, u, v);
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<CieXyz> inputSpan = new CieXyz[5];
Span<CieLuv> inputSpan = new CieLuv[5];
inputSpan.Fill(input);
Span<CieLuv> actualSpan = new CieLuv[5];
Span<CieXyz> actualSpan = new CieXyz[5];
// Act
CieLuv actual = converter.Convert<CieXyz, CieLuv>(input);
CieXyz actual = converter.Convert<CieLuv, CieXyz>(input);
converter.Convert<CieLuv, CieXyz>(inputSpan, actualSpan);
// Assert
Assert.Equal(expected, actual, Comparer);

70
tests/ImageSharp.Tests/ColorProfiles/CieXyzAndHslConversionTests.cs

@ -0,0 +1,70 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.ColorProfiles;
namespace SixLabors.ImageSharp.Tests.ColorProfiles;
/// <summary>
/// Tests <see cref="CieXyz"/>-<see cref="Hsl"/> conversions.
/// </summary>
public class CieXyzAndHslConversionTests
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0002F);
[Theory]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(0.360555, 0.936901, 0.1001514, 120, 1, 0.5)]
public void Convert_CieXyz_to_Hsl(float x, float y, float yl, float h, float s, float l)
{
// Arrange
CieXyz input = new(x, y, yl);
Hsl expected = new(h, s, l);
ColorProfileConverter converter = new();
Span<CieXyz> inputSpan = new CieXyz[5];
inputSpan.Fill(input);
Span<Hsl> actualSpan = new Hsl[5];
// Act
Hsl actual = converter.Convert<CieXyz, Hsl>(input);
converter.Convert<CieXyz, Hsl>(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(120, 1, 0.5, 0.38506496, 0.716878653, 0.09710451)]
public void Convert_Hsl_to_CieXyz(float h, float s, float l, float x, float y, float yl)
{
// Arrange
Hsl input = new(h, s, l);
CieXyz expected = new(x, y, yl);
ColorProfileConverter converter = new();
Span<Hsl> inputSpan = new Hsl[5];
inputSpan.Fill(input);
Span<CieXyz> actualSpan = new CieXyz[5];
// Act
CieXyz actual = converter.Convert<Hsl, CieXyz>(input);
converter.Convert<Hsl, CieXyz>(inputSpan, actualSpan);
// Assert
Assert.Equal(expected, actual, Comparer);
for (int i = 0; i < actualSpan.Length; i++)
{
Assert.Equal(expected, actualSpan[i], Comparer);
}
}
}

70
tests/ImageSharp.Tests/ColorProfiles/CieXyzAndHsvConversionTests.cs

@ -0,0 +1,70 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.ColorProfiles;
namespace SixLabors.ImageSharp.Tests.ColorProfiles;
/// <summary>
/// Tests <see cref="CieXyz"/>-<see cref="Hsv"/> conversions.
/// </summary>
public class CieXyzAndHsvConversionTests
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0002F);
[Theory]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(0.360555, 0.936901, 0.1001514, 120, 1, 0.9999999)]
public void Convert_CieXyz_to_Hsv(float x, float y, float yl, float h, float s, float v)
{
// Arrange
CieXyz input = new(x, y, yl);
Hsv expected = new(h, s, v);
ColorProfileConverter converter = new();
Span<CieXyz> inputSpan = new CieXyz[5];
inputSpan.Fill(input);
Span<Hsv> actualSpan = new Hsv[5];
// Act
Hsv actual = converter.Convert<CieXyz, Hsv>(input);
converter.Convert<CieXyz, Hsv>(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(120, 1, 0.9999999, 0.3850648, 0.7168785, 0.09710446)]
public void Convert_Hsv_to_CieXyz(float h, float s, float v, float x, float y, float yl)
{
// Arrange
Hsv input = new(h, s, v);
CieXyz expected = new(x, y, yl);
ColorProfileConverter converter = new();
Span<Hsv> inputSpan = new Hsv[5];
inputSpan.Fill(input);
Span<CieXyz> actualSpan = new CieXyz[5];
// Act
CieXyz actual = converter.Convert<Hsv, CieXyz>(input);
converter.Convert<Hsv, CieXyz>(inputSpan, actualSpan);
// Assert
Assert.Equal(expected, actual, Comparer);
for (int i = 0; i < actualSpan.Length; i++)
{
Assert.Equal(expected, actualSpan[i], Comparer);
}
}
}

74
tests/ImageSharp.Tests/ColorProfiles/CieXyzAndHunterLabConversionTest.cs

@ -0,0 +1,74 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.ColorProfiles;
namespace SixLabors.ImageSharp.Tests.ColorProfiles;
/// <summary>
/// Tests <see cref="CieXyz"/>-<see cref="HunterLab"/> conversions.
/// </summary>
/// <remarks>
/// Test data generated using:
/// <see href="http://www.brucelindbloom.com/index.html?ColorCalculator.html"/>
/// </remarks>
public class CieXyzAndHunterLabConversionTest
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0002f);
[Theory]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(0.360555, 0.936901, 0.1001514, 96.79365, -100.951096, 49.35507)]
public void Convert_Xyz_To_HunterLab(float x, float y, float z, float l, float a, float b)
{
// Arrange
CieXyz input = new(x, y, z);
HunterLab expected = new(l, a, b);
ColorProfileConverter converter = new();
Span<CieXyz> inputSpan = new CieXyz[5];
inputSpan.Fill(input);
Span<HunterLab> actualSpan = new HunterLab[5];
// Act
HunterLab actual = converter.Convert<CieXyz, HunterLab>(input);
converter.Convert<CieXyz, HunterLab>(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(31.6467056, -33.00599, 25.67032, 0.0385420471, 0.10015139, -0.0317969956)]
public void Convert_HunterLab_To_Xyz(float l, float a, float b, float x, float y, float z)
{
// Arrange
HunterLab input = new(l, a, b);
CieXyz expected = new(x, y, z);
ColorProfileConverter converter = new();
Span<HunterLab> inputSpan = new HunterLab[5];
inputSpan.Fill(input);
Span<CieXyz> actualSpan = new CieXyz[5];
// Act
CieXyz actual = converter.Convert<HunterLab, CieXyz>(input);
converter.Convert<HunterLab, CieXyz>(inputSpan, actualSpan);
// Assert
Assert.Equal(expected, actual, Comparer);
for (int i = 0; i < actualSpan.Length; i++)
{
Assert.Equal(expected, actualSpan[i], Comparer);
}
}
}

4
tests/ImageSharp.Tests/ColorProfiles/CieXyzAndLmsConversionTest.cs

@ -22,7 +22,7 @@ public class CieXyzAndLmsConversionTest
[InlineData(0.2664, 1.7135, -0.0685, 0, 1, 0)]
[InlineData(-0.175737162, 0.039960061, 1.121059368, 0, 0, 1.08883)]
[InlineData(0.2262677362, 0.0961411609, 0.0484570397, 0.216938, 0.150041, 0.048850)]
public void Convert_Lms_to_CieXyz(float l, float m, float s, float x, float y, float z)
public void Convert_Lms_To_CieXyz(float l, float m, float s, float x, float y, float z)
{
// Arrange
Lms input = new(l, m, s);
@ -54,7 +54,7 @@ public class CieXyzAndLmsConversionTest
[InlineData(0, 1, 0, 0.2664, 1.7135, -0.0685)]
[InlineData(0, 0, 1.08883, -0.175737162, 0.039960061, 1.121059368)]
[InlineData(0.216938, 0.150041, 0.048850, 0.2262677362, 0.0961411609, 0.0484570397)]
public void Convert_CieXyz_to_Lms(float x, float y, float z, float l, float m, float s)
public void Convert_CieXyz_To_Lms(float x, float y, float z, float l, float m, float s)
{
// Arrange
CieXyz input = new(x, y, z);

70
tests/ImageSharp.Tests/ColorProfiles/CieXyzAndYCbCrConversionTests.cs

@ -0,0 +1,70 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.ColorProfiles;
namespace SixLabors.ImageSharp.Tests.ColorProfiles;
/// <summary>
/// Tests <see cref="CieXyz"/>-<see cref="YCbCr"/> conversions.
/// </summary>
public class CieXyzAndYCbCrConversionTests
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0002f);
[Theory]
[InlineData(0, 0, 0, 0, 128, 128)]
[InlineData(0.360555, 0.936901, 0.1001514, 149.685, 43.52769, 21.23457)]
public void Convert_CieXyz_to_YCbCr(float x, float y, float z, float y2, float cb, float cr)
{
// Arrange
CieXyz input = new(x, y, z);
YCbCr expected = new(y2, cb, cr);
ColorProfileConverter converter = new();
Span<CieXyz> inputSpan = new CieXyz[5];
inputSpan.Fill(input);
Span<YCbCr> actualSpan = new YCbCr[5];
// Act
YCbCr actual = converter.Convert<CieXyz, YCbCr>(input);
converter.Convert<CieXyz, YCbCr>(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, 128, 128, 0, 0, 0)]
[InlineData(149.685, 43.52769, 21.23457, 0.38506496, 0.716878653, 0.0971045)]
public void Convert_YCbCr_to_CieXyz(float y2, float cb, float cr, float x, float y, float z)
{
// Arrange
YCbCr input = new(y2, cb, cr);
CieXyz expected = new(x, y, z);
ColorProfileConverter converter = new();
Span<YCbCr> inputSpan = new YCbCr[5];
inputSpan.Fill(input);
Span<CieXyz> actualSpan = new CieXyz[5];
// Act
CieXyz actual = converter.Convert<YCbCr, CieXyz>(input);
converter.Convert<YCbCr, CieXyz>(inputSpan, actualSpan);
// Assert
Assert.Equal(expected, actual, Comparer);
for (int i = 0; i < actualSpan.Length; i++)
{
Assert.Equal(expected, actualSpan[i], Comparer);
}
}
}

69
tests/ImageSharp.Tests/ColorProfiles/CmykAndCieLchConversionTests.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;
/// <summary>
/// Tests <see cref="Cmyk"/>-<see cref="CieLch"/> conversions.
/// </summary>
public class CmykAndCieLchConversionTests
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0002f);
[Theory]
[InlineData(0.360555, 0.1036901, 0.818514, 0.274615, 62.85025, 64.77041, 118.2425)]
public void Convert_Cmyk_To_CieLch(float c, float m, float y, float k, float l, float c2, float h)
{
// Arrange
Cmyk input = new(c, m, y, k);
CieLch expected = new(l, c2, h);
ColorProfileConverter converter = new();
Span<Cmyk> inputSpan = new Cmyk[5];
inputSpan.Fill(input);
Span<CieLch> actualSpan = new CieLch[5];
// Act
CieLch actual = converter.Convert<Cmyk, CieLch>(input);
converter.Convert<Cmyk, CieLch>(inputSpan, actualSpan);
// Assert
Assert.Equal(expected, actual, Comparer);
for (int i = 0; i < actualSpan.Length; i++)
{
Assert.Equal(expected, actualSpan[i], Comparer);
}
}
[Theory]
[InlineData(100, 3.81656E-05, 218.6598, 0, 1.192093E-07, 0, 5.960464E-08)]
[InlineData(62.85025, 64.77041, 118.2425, 0.286581, 0, 0.7975187, 0.34983)]
public void Convert_CieLch_To_Cmyk(float l, float c2, float h, float c, float m, float y, float k)
{
// Arrange
CieLch input = new(l, c2, h);
Cmyk expected = new(c, m, y, k);
ColorProfileConverter converter = new();
Span<CieLch> inputSpan = new CieLch[5];
inputSpan.Fill(input);
Span<Cmyk> actualSpan = new Cmyk[5];
// Act
Cmyk actual = converter.Convert<CieLch, Cmyk>(input);
converter.Convert<CieLch, Cmyk>(inputSpan, actualSpan);
// Assert
Assert.Equal(expected, actual, Comparer);
for (int i = 0; i < actualSpan.Length; i++)
{
Assert.Equal(expected, actualSpan[i], Comparer);
}
}
}

70
tests/ImageSharp.Tests/ColorProfiles/CmykAndCieLuvConversionTests.cs

@ -0,0 +1,70 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.ColorProfiles;
namespace SixLabors.ImageSharp.Tests.ColorProfiles;
/// <summary>
/// Tests <see cref="Cmyk"/>-<see cref="CieLuv"/> conversions.
/// </summary>
public class CmykAndCieLuvConversionTests
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0002f);
[Theory]
[InlineData(0, 0, 0, 0, 100, -1.937151E-05, -3.874302E-05)]
[InlineData(0.360555, 0.1036901, 0.818514, 0.274615, 62.85024, -24.4844189, 54.8588524)]
public void Convert_Cmyk_To_CieLuv(float c, float m, float y, float k, float l, float u, float v)
{
// Arrange
Cmyk input = new(c, m, y, k);
CieLuv expected = new(l, u, v);
ColorProfileConverter converter = new();
Span<Cmyk> inputSpan = new Cmyk[5];
inputSpan.Fill(input);
Span<CieLuv> actualSpan = new CieLuv[5];
// Act
CieLuv actual = converter.Convert<Cmyk, CieLuv>(input);
converter.Convert<Cmyk, CieLuv>(inputSpan, actualSpan);
// Assert
Assert.Equal(expected, actual, Comparer);
for (int i = 0; i < actualSpan.Length; i++)
{
Assert.Equal(expected, actualSpan[i], Comparer);
}
}
[Theory]
[InlineData(100, -1.937151E-05, -3.874302E-05, 0, 5.96046448E-08, 0, 0)]
[InlineData(62.85024, -24.4844189, 54.8588524, 0.2865809, 0, 0.797518551, 0.3498301)]
public void Convert_CieLuv_To_Cmyk(float l, float u, float v, float c, float m, float y, float k)
{
// Arrange
CieLuv input = new(l, u, v);
Cmyk expected = new(c, m, y, k);
ColorProfileConverter converter = new();
Span<CieLuv> inputSpan = new CieLuv[5];
inputSpan.Fill(input);
Span<Cmyk> actualSpan = new Cmyk[5];
// Act
Cmyk actual = converter.Convert<CieLuv, Cmyk>(input);
converter.Convert<CieLuv, Cmyk>(inputSpan, actualSpan);
// Assert
Assert.Equal(expected, actual, Comparer);
for (int i = 0; i < actualSpan.Length; i++)
{
Assert.Equal(expected, actualSpan[i], Comparer);
}
}
}

4
tests/ImageSharp.Tests/ColorProfiles/CmykAndYCbCrConversionTests.cs

@ -15,7 +15,7 @@ public class CmykAndYCbCrConversionTests
[Theory]
[InlineData(0, 0, 0, 0, 255, 128, 128)]
[InlineData(0.360555, 0.1036901, 0.818514, 0.274615, 136.5134, 69.90555, 114.9948)]
public void Convert_Cmyk_to_YCbCr(float c, float m, float y, float k, float y2, float cb, float cr)
public void Convert_Cmyk_To_YCbCr(float c, float m, float y, float k, float y2, float cb, float cr)
{
// Arrange
Cmyk input = new(c, m, y, k);
@ -43,7 +43,7 @@ public class CmykAndYCbCrConversionTests
[Theory]
[InlineData(255, 128, 128, 0, 0, 0, 5.960464E-08)]
[InlineData(136.5134, 69.90555, 114.9948, 0.2891567, 0, 0.7951807, 0.3490196)]
public void Convert_YCbCr_to_Cmyk(float y2, float cb, float cr, float c, float m, float y, float k)
public void Convert_YCbCr_To_Cmyk(float y2, float cb, float cr, float c, float m, float y, float k)
{
// Arrange
YCbCr input = new(y2, cb, cr);

8
tests/ImageSharp.Tests/ColorProfiles/RgbAndCieXyzConversionTest.cs

@ -24,7 +24,7 @@ public class RgbAndCieXyzConversionTest
[InlineData(0.00000, 0.00000, 0.82521, 0, 0.181415, 1)]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(0.297676, 0.267854, 0.045504, 0.720315, 0.509999, 0.168112)]
public void Convert_XYZ_D50_to_SRGB(float x, float y, float z, float r, float g, float b)
public void Convert_XYZ_D50_To_SRGB(float x, float y, float z, float r, float g, float b)
{
// Arrange
CieXyz input = new(x, y, z);
@ -57,7 +57,7 @@ public class RgbAndCieXyzConversionTest
[InlineData(0, 0, 1.088830, 0, 0.235458, 1)]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(0.297676, 0.267854, 0.045504, 0.754903, 0.501961, 0.099998)]
public void Convert_XYZ_D65_to_SRGB(float x, float y, float z, float r, float g, float b)
public void Convert_XYZ_D65_To_SRGB(float x, float y, float z, float r, float g, float b)
{
// Arrange
CieXyz input = new(x, y, z);
@ -90,7 +90,7 @@ public class RgbAndCieXyzConversionTest
[InlineData(0, 1, 0, 0.385065, 0.716879, 0.0971045)]
[InlineData(0, 0, 1, 0.143080, 0.060617, 0.714173)]
[InlineData(0.754902, 0.501961, 0.100000, 0.315757, 0.273323, 0.035506)]
public void Convert_SRGB_to_XYZ_D50(float r, float g, float b, float x, float y, float z)
public void Convert_SRGB_To_XYZ_D50(float r, float g, float b, float x, float y, float z)
{
// Arrange
Rgb input = new(r, g, b);
@ -123,7 +123,7 @@ public class RgbAndCieXyzConversionTest
[InlineData(0, 1, 0, 0.357576, 0.715152, 0.119192)]
[InlineData(0, 0, 1, 0.1804375, 0.072175, 0.950304)]
[InlineData(0.754902, 0.501961, 0.100000, 0.297676, 0.267854, 0.045504)]
public void Convert_SRGB_to_XYZ_D65(float r, float g, float b, float x, float y, float z)
public void Convert_SRGB_To_XYZ_D65(float r, float g, float b, float x, float y, float z)
{
// Arrange
Rgb input = new(r, g, b);

83
tests/ImageSharp.Tests/ColorProfiles/RgbAndHslConversionTest.cs

@ -0,0 +1,83 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.ColorProfiles;
namespace SixLabors.ImageSharp.Tests.ColorProfiles.Conversion;
/// <summary>
/// Tests <see cref="Rgb"/>-<see cref="Hsl"/> conversions.
/// </summary>
/// <remarks>
/// Test data generated using:
/// <see href="http://www.colorhexa.com"/>
/// <see href="http://www.rapidtables.com/convert/color/hsl-to-rgb"/>
/// </remarks>
public class RgbAndHslConversionTest
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0001f);
[Theory]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(0, 1, 1, 1, 1, 1)]
[InlineData(360, 1, 1, 1, 1, 1)]
[InlineData(0, 1, .5F, 1, 0, 0)]
[InlineData(120, 1, .5F, 0, 1, 0)]
[InlineData(240, 1, .5F, 0, 0, 1)]
public void Convert_Hsl_To_Rgb(float h, float s, float l, float r, float g, float b)
{
// Arrange
Hsl input = new(h, s, l);
Rgb expected = new(r, g, b);
ColorProfileConverter converter = new();
Span<Hsl> inputSpan = new Hsl[5];
inputSpan.Fill(input);
Span<Rgb> actualSpan = new Rgb[5];
// Act
Rgb actual = converter.Convert<Hsl, Rgb>(input);
converter.Convert<Hsl, Rgb>(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(1, 1, 1, 0, 0, 1)]
[InlineData(1, 0, 0, 0, 1, .5F)]
[InlineData(0, 1, 0, 120, 1, .5F)]
[InlineData(0, 0, 1, 240, 1, .5F)]
[InlineData(0.7, 0.8, 0.6, 90, 0.3333, 0.7F)]
public void Convert_Rgb_To_Hsl(float r, float g, float b, float h, float s, float l)
{
// Arrange
Rgb input = new(r, g, b);
Hsl expected = new(h, s, l);
ColorProfileConverter converter = new();
Span<Rgb> inputSpan = new Rgb[5];
inputSpan.Fill(input);
Span<Hsl> actualSpan = new Hsl[5];
// Act
Hsl actual = converter.Convert<Rgb, Hsl>(input);
converter.Convert<Rgb, Hsl>(inputSpan, actualSpan);
// Assert
Assert.Equal(expected, actual, Comparer);
for (int i = 0; i < actualSpan.Length; i++)
{
Assert.Equal(expected, actualSpan[i], Comparer);
}
}
}

81
tests/ImageSharp.Tests/ColorProfiles/RgbAndHsvConversionTest.cs

@ -0,0 +1,81 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.ColorProfiles;
namespace SixLabors.ImageSharp.Tests.ColorProfiles;
/// <summary>
/// Tests <see cref="Rgb"/>-<see cref="Hsv"/> conversions.
/// </summary>
/// <remarks>
/// Test data generated using:
/// <see href="http://www.colorhexa.com"/>
/// </remarks>
public class RgbAndHsvConversionTest
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0001f);
[Theory]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(0, 0, 1, 1, 1, 1)]
[InlineData(360, 1, 1, 1, 0, 0)]
[InlineData(0, 1, 1, 1, 0, 0)]
[InlineData(120, 1, 1, 0, 1, 0)]
[InlineData(240, 1, 1, 0, 0, 1)]
public void Convert_Hsv_To_Rgb(float h, float s, float v, float r, float g, float b)
{
// Arrange
Hsv input = new(h, s, v);
Rgb expected = new(r, g, b);
ColorProfileConverter converter = new();
Span<Hsv> inputSpan = new Hsv[5];
inputSpan.Fill(input);
Span<Rgb> actualSpan = new Rgb[5];
// Act
Rgb actual = converter.Convert<Hsv, Rgb>(input);
converter.Convert<Hsv, Rgb>(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(1, 1, 1, 0, 0, 1)]
[InlineData(1, 0, 0, 0, 1, 1)]
[InlineData(0, 1, 0, 120, 1, 1)]
[InlineData(0, 0, 1, 240, 1, 1)]
public void Convert_Rgb_To_Hsv(float r, float g, float b, float h, float s, float v)
{
// Arrange
Rgb input = new(r, g, b);
Hsv expected = new(h, s, v);
ColorProfileConverter converter = new();
Span<Rgb> inputSpan = new Rgb[5];
inputSpan.Fill(input);
Span<Hsv> actualSpan = new Hsv[5];
// Act
Hsv actual = converter.Convert<Rgb, Hsv>(input);
converter.Convert<Rgb, Hsv>(inputSpan, actualSpan);
// Assert
Assert.Equal(expected, actual, Comparer);
for (int i = 0; i < actualSpan.Length; i++)
{
Assert.Equal(expected, actualSpan[i], Comparer);
}
}
}
Loading…
Cancel
Save