Browse Source

Naming and fixes

pull/2739/head
James Jackson-South 2 years ago
parent
commit
bf13f0095c
  1. 2
      src/ImageSharp/ColorProfiles/CieLab.cs
  2. 4
      src/ImageSharp/ColorProfiles/ColorConversionOptions.cs
  3. 15
      src/ImageSharp/ColorProfiles/ColorProfileConverter.cs
  4. 8
      src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsCieLabCieLab.cs
  5. 6
      src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsCieLabCieXyz.cs
  6. 6
      src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsCieLabRgb.cs
  7. 6
      src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsCieXyzCieLab.cs
  8. 6
      src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsCieXyzCieXyz.cs
  9. 8
      src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsCieXyzRgb.cs
  10. 6
      src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsRgbCieLab.cs
  11. 8
      src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsRgbCieXyz.cs
  12. 6
      src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsRgbRgb.cs
  13. 4
      src/ImageSharp/ColorProfiles/HunterLab.cs
  14. 4
      src/ImageSharp/ColorProfiles/KnownIlluminants.cs
  15. 38
      src/ImageSharp/ColorProfiles/KnownRgbWorkingSpaces.cs
  16. 55
      src/ImageSharp/ColorProfiles/VonKriesChromaticAdaptation.cs
  17. 4
      tests/ImageSharp.Tests/ColorProfiles/CieLabAndCieLchConversionTests.cs
  18. 4
      tests/ImageSharp.Tests/ColorProfiles/CieLabAndCieLchuvConversionTests.cs
  19. 4
      tests/ImageSharp.Tests/ColorProfiles/CieLabAndCieLuvConversionTests.cs
  20. 4
      tests/ImageSharp.Tests/ColorProfiles/CieLchAndCieLuvConversionTests.cs
  21. 4
      tests/ImageSharp.Tests/ColorProfiles/CieLchuvAndCieLchConversionTests.cs
  22. 4
      tests/ImageSharp.Tests/ColorProfiles/CieLchuvAndCieLuvConversionTests.cs
  23. 4
      tests/ImageSharp.Tests/ColorProfiles/CieLchuvAndCmykConversionTests.cs
  24. 4
      tests/ImageSharp.Tests/ColorProfiles/CieLuvAndCieXyyConversionTests.cs
  25. 4
      tests/ImageSharp.Tests/ColorProfiles/CieLuvAndHslConversionTests.cs
  26. 4
      tests/ImageSharp.Tests/ColorProfiles/CieLuvAndHsvConversionTests.cs
  27. 4
      tests/ImageSharp.Tests/ColorProfiles/CieLuvAndHunterLabConversionTests.cs
  28. 4
      tests/ImageSharp.Tests/ColorProfiles/CieLuvAndLmsConversionTests.cs
  29. 4
      tests/ImageSharp.Tests/ColorProfiles/CieLuvAndRgbConversionTests.cs
  30. 4
      tests/ImageSharp.Tests/ColorProfiles/CieLuvAndYCbCrConversionTests.cs
  31. 4
      tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLabConversionTest.cs
  32. 4
      tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLuvConversionTest.cs
  33. 204
      tests/ImageSharp.Tests/ColorProfiles/ColorProfileConverterChomaticAdaptationTests.cs
  34. 8
      tests/ImageSharp.Tests/ColorProfiles/RgbAndCieXyzConversionTest.cs
  35. 42
      tests/ImageSharp.Tests/ColorProfiles/VonKriesChromaticAdaptationTests.cs

2
src/ImageSharp/ColorProfiles/CieLab.cs

@ -16,7 +16,7 @@ public readonly struct CieLab : IProfileConnectingSpace<CieLab, CieXyz>
/// D50 standard illuminant.
/// Used when reference white is not specified explicitly.
/// </summary>
public static readonly CieXyz DefaultWhitePoint = Illuminants.D50;
public static readonly CieXyz DefaultWhitePoint = KnownIlluminants.D50;
/// <summary>
/// Initializes a new instance of the <see cref="CieLab"/> struct.

4
src/ImageSharp/ColorProfiles/ColorConversionOptions.cs

@ -28,12 +28,12 @@ public class ColorConversionOptions
/// <summary>
/// Gets the source white point used for chromatic adaptation in conversions from/to XYZ color space.
/// </summary>
public CieXyz WhitePoint { get; init; } = Illuminants.D50;
public CieXyz WhitePoint { get; init; } = KnownIlluminants.D50;
/// <summary>
/// Gets the destination white point used for chromatic adaptation in conversions from/to XYZ color space.
/// </summary>
public CieXyz TargetWhitePoint { get; init; } = Illuminants.D50;
public CieXyz TargetWhitePoint { get; init; } = KnownIlluminants.D50;
/// <summary>
/// Gets the source working space used for companding in conversions from/to XYZ color space.

15
src/ImageSharp/ColorProfiles/ColorProfileConverter.cs

@ -27,4 +27,19 @@ public class ColorProfileConverter
/// Gets the color profile conversion options.
/// </summary>
public ColorConversionOptions Options { get; }
internal (CieXyz From, CieXyz To) GetChromaticAdaptionWhitePoints<TFrom, TTo>()
where TFrom : struct, IColorProfile
where TTo : struct, IColorProfile
{
CieXyz sourceWhitePoint = TFrom.GetChromaticAdaptionWhitePointSource() == ChromaticAdaptionWhitePointSource.WhitePoint
? this.Options.WhitePoint
: this.Options.RgbWorkingSpace.WhitePoint;
CieXyz targetWhitePoint = TTo.GetChromaticAdaptionWhitePointSource() == ChromaticAdaptionWhitePointSource.WhitePoint
? this.Options.TargetWhitePoint
: this.Options.TargetRgbWorkingSpace.WhitePoint;
return (sourceWhitePoint, targetWhitePoint);
}
}

8
src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsCieLabCieLab.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers;
@ -19,7 +19,8 @@ internal static class ColorProfileConverterExtensionsCieLabCieLab
CieXyz pcsFromB = pcsFromA.ToProfileConnectingSpace(options);
// Adapt to target white point
pcsFromB = VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, in pcsFromB);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
pcsFromB = VonKriesChromaticAdaptation.Transform(in pcsFromB, whitePoints, options.AdaptationMatrix);
// Convert between PCS
CieLab pcsTo = CieLab.FromProfileConnectingSpace(options, in pcsFromB);
@ -44,7 +45,8 @@ internal static class ColorProfileConverterExtensionsCieLabCieLab
CieLab.ToProfileConnectionSpace(options, pcsFromTo, pcsFrom);
// Adapt to target white point
VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, pcsFrom, pcsFrom);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
VonKriesChromaticAdaptation.Transform(pcsFrom, pcsFrom, whitePoints, options.AdaptationMatrix);
// Convert between PCS.
CieLab.FromProfileConnectionSpace(options, pcsFrom, pcsFromTo);

6
src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsCieLabCieXyz.cs

@ -21,7 +21,8 @@ internal static class ColorProfileConverterExtensionsCieLabCieXyz
CieXyz pcsTo = pcsFrom.ToProfileConnectingSpace(options);
// Adapt to target white point
pcsTo = VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, in pcsTo);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
pcsTo = VonKriesChromaticAdaptation.Transform(in pcsTo, whitePoints, options.AdaptationMatrix);
// Convert to output from PCS
return TTo.FromProfileConnectingSpace(options, pcsTo);
@ -44,7 +45,8 @@ internal static class ColorProfileConverterExtensionsCieLabCieXyz
CieLab.ToProfileConnectionSpace(options, pcsFrom, pcsTo);
// Adapt to target white point
VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, pcsTo, pcsTo);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
VonKriesChromaticAdaptation.Transform(pcsTo, pcsTo, whitePoints, options.AdaptationMatrix);
// Convert to output from PCS
TTo.FromProfileConnectionSpace(options, pcsTo, destination);

6
src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsCieLabRgb.cs

@ -19,7 +19,8 @@ internal static class ColorProfileConverterExtensionsCieLabRgb
CieXyz pcsFromB = pcsFromA.ToProfileConnectingSpace(options);
// Adapt to target white point
pcsFromB = VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, in pcsFromB);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
pcsFromB = VonKriesChromaticAdaptation.Transform(in pcsFromB, whitePoints, options.AdaptationMatrix);
// Convert between PCS
Rgb pcsTo = Rgb.FromProfileConnectingSpace(options, in pcsFromB);
@ -44,7 +45,8 @@ internal static class ColorProfileConverterExtensionsCieLabRgb
CieLab.ToProfileConnectionSpace(options, pcsFromA, pcsFromB);
// Adapt to target white point
VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, pcsFromB, pcsFromB);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
VonKriesChromaticAdaptation.Transform(pcsFromB, pcsFromB, whitePoints, options.AdaptationMatrix);
// Convert between PCS.
using IMemoryOwner<Rgb> pcsToOwner = options.MemoryAllocator.Allocate<Rgb>(source.Length);

6
src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsCieXyzCieLab.cs

@ -18,7 +18,8 @@ internal static class ColorProfileConverterExtensionsCieXyzCieLab
CieXyz pcsFrom = source.ToProfileConnectingSpace(options);
// Adapt to target white point
pcsFrom = VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, in pcsFrom);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
pcsFrom = VonKriesChromaticAdaptation.Transform(in pcsFrom, whitePoints, options.AdaptationMatrix);
// Convert between PCS
CieLab pcsTo = CieLab.FromProfileConnectingSpace(options, in pcsFrom);
@ -39,7 +40,8 @@ internal static class ColorProfileConverterExtensionsCieXyzCieLab
TFrom.ToProfileConnectionSpace(options, source, pcsFrom);
// Adapt to target white point
VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, pcsFrom, pcsFrom);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
VonKriesChromaticAdaptation.Transform(pcsFrom, pcsFrom, whitePoints, options.AdaptationMatrix);
// Convert between PCS.
using IMemoryOwner<CieLab> pcsToOwner = options.MemoryAllocator.Allocate<CieLab>(source.Length);

6
src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsCieXyzCieXyz.cs

@ -18,7 +18,8 @@ internal static class ColorProfileConverterExtensionsCieXyzCieXyz
CieXyz pcsFrom = source.ToProfileConnectingSpace(options);
// Adapt to target white point
pcsFrom = VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, in pcsFrom);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
pcsFrom = VonKriesChromaticAdaptation.Transform(in pcsFrom, whitePoints, options.AdaptationMatrix);
// Convert to output from PCS
return TTo.FromProfileConnectingSpace(options, pcsFrom);
@ -36,7 +37,8 @@ internal static class ColorProfileConverterExtensionsCieXyzCieXyz
TFrom.ToProfileConnectionSpace(options, source, pcsFrom);
// Adapt to target white point
VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, pcsFrom, pcsFrom);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
VonKriesChromaticAdaptation.Transform(pcsFrom, pcsFrom, whitePoints, options.AdaptationMatrix);
// Convert to output from PCS
TTo.FromProfileConnectionSpace(options, pcsFrom, destination);

8
src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsCieXyzRgb.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers;
@ -18,7 +18,8 @@ internal static class ColorProfileConverterExtensionsCieXyzRgb
CieXyz pcsFrom = source.ToProfileConnectingSpace(options);
// Adapt to target white point
pcsFrom = VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, in pcsFrom);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
pcsFrom = VonKriesChromaticAdaptation.Transform(in pcsFrom, whitePoints, options.AdaptationMatrix);
// Convert between PCS
Rgb pcsTo = Rgb.FromProfileConnectingSpace(options, in pcsFrom);
@ -39,7 +40,8 @@ internal static class ColorProfileConverterExtensionsCieXyzRgb
TFrom.ToProfileConnectionSpace(options, source, pcsFrom);
// Adapt to target white point
VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, pcsFrom, pcsFrom);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
VonKriesChromaticAdaptation.Transform(pcsFrom, pcsFrom, whitePoints, options.AdaptationMatrix);
// Convert between PCS.
using IMemoryOwner<Rgb> pcsToOwner = options.MemoryAllocator.Allocate<Rgb>(source.Length);

6
src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsRgbCieLab.cs

@ -19,7 +19,8 @@ internal static class ColorProfileConverterExtensionsRgbCieLab
CieXyz pcsFromB = pcsFromA.ToProfileConnectingSpace(options);
// Adapt to target white point
pcsFromB = VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, in pcsFromB);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
pcsFromB = VonKriesChromaticAdaptation.Transform(in pcsFromB, whitePoints, options.AdaptationMatrix);
// Convert between PCS
CieLab pcsTo = CieLab.FromProfileConnectingSpace(options, in pcsFromB);
@ -44,7 +45,8 @@ internal static class ColorProfileConverterExtensionsRgbCieLab
Rgb.ToProfileConnectionSpace(options, pcsFromA, pcsFromB);
// Adapt to target white point
VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, pcsFromB, pcsFromB);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
VonKriesChromaticAdaptation.Transform(pcsFromB, pcsFromB, whitePoints, options.AdaptationMatrix);
// Convert between PCS.
using IMemoryOwner<CieLab> pcsToOwner = options.MemoryAllocator.Allocate<CieLab>(source.Length);

8
src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsRgbCieXyz.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers;
@ -21,7 +21,8 @@ internal static class ColorProfileConverterExtensionsRgbCieXyz
CieXyz pcsTo = pcsFrom.ToProfileConnectingSpace(options);
// Adapt to target white point
pcsTo = VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, in pcsTo);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
pcsTo = VonKriesChromaticAdaptation.Transform(in pcsTo, whitePoints, options.AdaptationMatrix);
// Convert to output from PCS
return TTo.FromProfileConnectingSpace(options, pcsTo);
@ -44,7 +45,8 @@ internal static class ColorProfileConverterExtensionsRgbCieXyz
Rgb.ToProfileConnectionSpace(options, pcsFrom, pcsTo);
// Adapt to target white point
VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, pcsTo, pcsTo);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
VonKriesChromaticAdaptation.Transform(pcsTo, pcsTo, whitePoints, options.AdaptationMatrix);
// Convert to output from PCS
TTo.FromProfileConnectionSpace(options, pcsTo, destination);

6
src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsRgbRgb.cs

@ -19,7 +19,8 @@ internal static class ColorProfileConverterExtensionsRgbRgb
CieXyz pcsFromB = pcsFromA.ToProfileConnectingSpace(options);
// Adapt to target white point
pcsFromB = VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, in pcsFromB);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
pcsFromB = VonKriesChromaticAdaptation.Transform(in pcsFromB, whitePoints, options.AdaptationMatrix);
// Convert between PCS
Rgb pcsTo = Rgb.FromProfileConnectingSpace(options, in pcsFromB);
@ -44,7 +45,8 @@ internal static class ColorProfileConverterExtensionsRgbRgb
Rgb.ToProfileConnectionSpace(options, pcsFromTo, pcsFrom);
// Adapt to target white point
VonKriesChromaticAdaptation.Transform<TFrom, TTo>(options, pcsFrom, pcsFrom);
(CieXyz From, CieXyz To) whitePoints = converter.GetChromaticAdaptionWhitePoints<TFrom, TTo>();
VonKriesChromaticAdaptation.Transform(pcsFrom, pcsFrom, whitePoints, options.AdaptationMatrix);
// Convert between PCS.
Rgb.FromProfileConnectionSpace(options, pcsFrom, pcsFromTo);

4
src/ImageSharp/ColorProfiles/HunterLab.cs

@ -181,7 +181,7 @@ public readonly struct HunterLab : IColorProfile<HunterLab, CieXyz>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static float ComputeKa(in CieXyz whitePoint)
{
if (whitePoint.Equals(Illuminants.C))
if (whitePoint.Equals(KnownIlluminants.C))
{
return 175F;
}
@ -192,7 +192,7 @@ public readonly struct HunterLab : IColorProfile<HunterLab, CieXyz>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static float ComputeKb(in CieXyz whitePoint)
{
if (whitePoint == Illuminants.C)
if (whitePoint == KnownIlluminants.C)
{
return 70F;
}

4
src/ImageSharp/ColorProfiles/Illuminants.cs → src/ImageSharp/ColorProfiles/KnownIlluminants.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
namespace SixLabors.ImageSharp.ColorProfiles;
@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.ColorProfiles;
/// <br />
/// Descriptions taken from: http://en.wikipedia.org/wiki/Standard_illuminant
/// </remarks>
public static class Illuminants
public static class KnownIlluminants
{
/// <summary>
/// Incandescent / Tungsten

38
src/ImageSharp/ColorProfiles/KnownRgbWorkingSpaces.cs

@ -19,96 +19,96 @@ public static class KnownRgbWorkingSpaces
/// Uses proper companding function, according to:
/// <see href="http://www.brucelindbloom.com/index.html?Eqn_Rgb_to_XYZ.html"/>
/// </remarks>
public static readonly RgbWorkingSpace SRgb = new SRgbWorkingSpace(Illuminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6400F, 0.3300F), new CieXyChromaticityCoordinates(0.3000F, 0.6000F), new CieXyChromaticityCoordinates(0.1500F, 0.0600F)));
public static readonly RgbWorkingSpace SRgb = new SRgbWorkingSpace(KnownIlluminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6400F, 0.3300F), new CieXyChromaticityCoordinates(0.3000F, 0.6000F), new CieXyChromaticityCoordinates(0.1500F, 0.0600F)));
/// <summary>
/// Simplified sRgb working space (uses <see cref="GammaCompanding">gamma companding</see> instead of <see cref="SRgbCompanding"/>).
/// See also <see cref="SRgb"/>.
/// </summary>
public static readonly RgbWorkingSpace SRgbSimplified = new GammaWorkingSpace(2.2F, Illuminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6400F, 0.3300F), new CieXyChromaticityCoordinates(0.3000F, 0.6000F), new CieXyChromaticityCoordinates(0.1500F, 0.0600F)));
public static readonly RgbWorkingSpace SRgbSimplified = new GammaWorkingSpace(2.2F, KnownIlluminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6400F, 0.3300F), new CieXyChromaticityCoordinates(0.3000F, 0.6000F), new CieXyChromaticityCoordinates(0.1500F, 0.0600F)));
/// <summary>
/// Rec. 709 (ITU-R Recommendation BT.709) working space.
/// </summary>
public static readonly RgbWorkingSpace Rec709 = new Rec709WorkingSpace(Illuminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.64F, 0.33F), new CieXyChromaticityCoordinates(0.30F, 0.60F), new CieXyChromaticityCoordinates(0.15F, 0.06F)));
public static readonly RgbWorkingSpace Rec709 = new Rec709WorkingSpace(KnownIlluminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.64F, 0.33F), new CieXyChromaticityCoordinates(0.30F, 0.60F), new CieXyChromaticityCoordinates(0.15F, 0.06F)));
/// <summary>
/// Rec. 2020 (ITU-R Recommendation BT.2020F) working space.
/// </summary>
public static readonly RgbWorkingSpace Rec2020 = new Rec2020WorkingSpace(Illuminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.708F, 0.292F), new CieXyChromaticityCoordinates(0.170F, 0.797F), new CieXyChromaticityCoordinates(0.131F, 0.046F)));
public static readonly RgbWorkingSpace Rec2020 = new Rec2020WorkingSpace(KnownIlluminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.708F, 0.292F), new CieXyChromaticityCoordinates(0.170F, 0.797F), new CieXyChromaticityCoordinates(0.131F, 0.046F)));
/// <summary>
/// ECI Rgb v2 working space.
/// </summary>
public static readonly RgbWorkingSpace ECIRgbv2 = new LWorkingSpace(Illuminants.D50, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6700F, 0.3300F), new CieXyChromaticityCoordinates(0.2100F, 0.7100F), new CieXyChromaticityCoordinates(0.1400F, 0.0800F)));
public static readonly RgbWorkingSpace ECIRgbv2 = new LWorkingSpace(KnownIlluminants.D50, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6700F, 0.3300F), new CieXyChromaticityCoordinates(0.2100F, 0.7100F), new CieXyChromaticityCoordinates(0.1400F, 0.0800F)));
/// <summary>
/// Adobe Rgb (1998) working space.
/// </summary>
public static readonly RgbWorkingSpace AdobeRgb1998 = new GammaWorkingSpace(2.2F, Illuminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6400F, 0.3300F), new CieXyChromaticityCoordinates(0.2100F, 0.7100F), new CieXyChromaticityCoordinates(0.1500F, 0.0600F)));
public static readonly RgbWorkingSpace AdobeRgb1998 = new GammaWorkingSpace(2.2F, KnownIlluminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6400F, 0.3300F), new CieXyChromaticityCoordinates(0.2100F, 0.7100F), new CieXyChromaticityCoordinates(0.1500F, 0.0600F)));
/// <summary>
/// Apple sRgb working space.
/// </summary>
public static readonly RgbWorkingSpace ApplesRgb = new GammaWorkingSpace(1.8F, Illuminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6250F, 0.3400F), new CieXyChromaticityCoordinates(0.2800F, 0.5950F), new CieXyChromaticityCoordinates(0.1550F, 0.0700F)));
public static readonly RgbWorkingSpace ApplesRgb = new GammaWorkingSpace(1.8F, KnownIlluminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6250F, 0.3400F), new CieXyChromaticityCoordinates(0.2800F, 0.5950F), new CieXyChromaticityCoordinates(0.1550F, 0.0700F)));
/// <summary>
/// Best Rgb working space.
/// </summary>
public static readonly RgbWorkingSpace BestRgb = new GammaWorkingSpace(2.2F, Illuminants.D50, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.7347F, 0.2653F), new CieXyChromaticityCoordinates(0.2150F, 0.7750F), new CieXyChromaticityCoordinates(0.1300F, 0.0350F)));
public static readonly RgbWorkingSpace BestRgb = new GammaWorkingSpace(2.2F, KnownIlluminants.D50, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.7347F, 0.2653F), new CieXyChromaticityCoordinates(0.2150F, 0.7750F), new CieXyChromaticityCoordinates(0.1300F, 0.0350F)));
/// <summary>
/// Beta Rgb working space.
/// </summary>
public static readonly RgbWorkingSpace BetaRgb = new GammaWorkingSpace(2.2F, Illuminants.D50, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6888F, 0.3112F), new CieXyChromaticityCoordinates(0.1986F, 0.7551F), new CieXyChromaticityCoordinates(0.1265F, 0.0352F)));
public static readonly RgbWorkingSpace BetaRgb = new GammaWorkingSpace(2.2F, KnownIlluminants.D50, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6888F, 0.3112F), new CieXyChromaticityCoordinates(0.1986F, 0.7551F), new CieXyChromaticityCoordinates(0.1265F, 0.0352F)));
/// <summary>
/// Bruce Rgb working space.
/// </summary>
public static readonly RgbWorkingSpace BruceRgb = new GammaWorkingSpace(2.2F, Illuminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6400F, 0.3300F), new CieXyChromaticityCoordinates(0.2800F, 0.6500F), new CieXyChromaticityCoordinates(0.1500F, 0.0600F)));
public static readonly RgbWorkingSpace BruceRgb = new GammaWorkingSpace(2.2F, KnownIlluminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6400F, 0.3300F), new CieXyChromaticityCoordinates(0.2800F, 0.6500F), new CieXyChromaticityCoordinates(0.1500F, 0.0600F)));
/// <summary>
/// CIE Rgb working space.
/// </summary>
public static readonly RgbWorkingSpace CIERgb = new GammaWorkingSpace(2.2F, Illuminants.E, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.7350F, 0.2650F), new CieXyChromaticityCoordinates(0.2740F, 0.7170F), new CieXyChromaticityCoordinates(0.1670F, 0.0090F)));
public static readonly RgbWorkingSpace CIERgb = new GammaWorkingSpace(2.2F, KnownIlluminants.E, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.7350F, 0.2650F), new CieXyChromaticityCoordinates(0.2740F, 0.7170F), new CieXyChromaticityCoordinates(0.1670F, 0.0090F)));
/// <summary>
/// ColorMatch Rgb working space.
/// </summary>
public static readonly RgbWorkingSpace ColorMatchRgb = new GammaWorkingSpace(1.8F, Illuminants.D50, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6300F, 0.3400F), new CieXyChromaticityCoordinates(0.2950F, 0.6050F), new CieXyChromaticityCoordinates(0.1500F, 0.0750F)));
public static readonly RgbWorkingSpace ColorMatchRgb = new GammaWorkingSpace(1.8F, KnownIlluminants.D50, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6300F, 0.3400F), new CieXyChromaticityCoordinates(0.2950F, 0.6050F), new CieXyChromaticityCoordinates(0.1500F, 0.0750F)));
/// <summary>
/// Don Rgb 4 working space.
/// </summary>
public static readonly RgbWorkingSpace DonRgb4 = new GammaWorkingSpace(2.2F, Illuminants.D50, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6960F, 0.3000F), new CieXyChromaticityCoordinates(0.2150F, 0.7650F), new CieXyChromaticityCoordinates(0.1300F, 0.0350F)));
public static readonly RgbWorkingSpace DonRgb4 = new GammaWorkingSpace(2.2F, KnownIlluminants.D50, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6960F, 0.3000F), new CieXyChromaticityCoordinates(0.2150F, 0.7650F), new CieXyChromaticityCoordinates(0.1300F, 0.0350F)));
/// <summary>
/// Ekta Space PS5 working space.
/// </summary>
public static readonly RgbWorkingSpace EktaSpacePS5 = new GammaWorkingSpace(2.2F, Illuminants.D50, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6950F, 0.3050F), new CieXyChromaticityCoordinates(0.2600F, 0.7000F), new CieXyChromaticityCoordinates(0.1100F, 0.0050F)));
public static readonly RgbWorkingSpace EktaSpacePS5 = new GammaWorkingSpace(2.2F, KnownIlluminants.D50, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6950F, 0.3050F), new CieXyChromaticityCoordinates(0.2600F, 0.7000F), new CieXyChromaticityCoordinates(0.1100F, 0.0050F)));
/// <summary>
/// NTSC Rgb working space.
/// </summary>
public static readonly RgbWorkingSpace NTSCRgb = new GammaWorkingSpace(2.2F, Illuminants.C, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6700F, 0.3300F), new CieXyChromaticityCoordinates(0.2100F, 0.7100F), new CieXyChromaticityCoordinates(0.1400F, 0.0800F)));
public static readonly RgbWorkingSpace NTSCRgb = new GammaWorkingSpace(2.2F, KnownIlluminants.C, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6700F, 0.3300F), new CieXyChromaticityCoordinates(0.2100F, 0.7100F), new CieXyChromaticityCoordinates(0.1400F, 0.0800F)));
/// <summary>
/// PAL/SECAM Rgb working space.
/// </summary>
public static readonly RgbWorkingSpace PALSECAMRgb = new GammaWorkingSpace(2.2F, Illuminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6400F, 0.3300F), new CieXyChromaticityCoordinates(0.2900F, 0.6000F), new CieXyChromaticityCoordinates(0.1500F, 0.0600F)));
public static readonly RgbWorkingSpace PALSECAMRgb = new GammaWorkingSpace(2.2F, KnownIlluminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6400F, 0.3300F), new CieXyChromaticityCoordinates(0.2900F, 0.6000F), new CieXyChromaticityCoordinates(0.1500F, 0.0600F)));
/// <summary>
/// ProPhoto Rgb working space.
/// </summary>
public static readonly RgbWorkingSpace ProPhotoRgb = new GammaWorkingSpace(1.8F, Illuminants.D50, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.7347F, 0.2653F), new CieXyChromaticityCoordinates(0.1596F, 0.8404F), new CieXyChromaticityCoordinates(0.0366F, 0.0001F)));
public static readonly RgbWorkingSpace ProPhotoRgb = new GammaWorkingSpace(1.8F, KnownIlluminants.D50, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.7347F, 0.2653F), new CieXyChromaticityCoordinates(0.1596F, 0.8404F), new CieXyChromaticityCoordinates(0.0366F, 0.0001F)));
/// <summary>
/// SMPTE-C Rgb working space.
/// </summary>
public static readonly RgbWorkingSpace SMPTECRgb = new GammaWorkingSpace(2.2F, Illuminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6300F, 0.3400F), new CieXyChromaticityCoordinates(0.3100F, 0.5950F), new CieXyChromaticityCoordinates(0.1550F, 0.0700F)));
public static readonly RgbWorkingSpace SMPTECRgb = new GammaWorkingSpace(2.2F, KnownIlluminants.D65, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6300F, 0.3400F), new CieXyChromaticityCoordinates(0.3100F, 0.5950F), new CieXyChromaticityCoordinates(0.1550F, 0.0700F)));
/// <summary>
/// Wide Gamut Rgb working space.
/// </summary>
public static readonly RgbWorkingSpace WideGamutRgb = new GammaWorkingSpace(2.2F, Illuminants.D50, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.7350F, 0.2650F), new CieXyChromaticityCoordinates(0.1150F, 0.8260F), new CieXyChromaticityCoordinates(0.1570F, 0.0180F)));
public static readonly RgbWorkingSpace WideGamutRgb = new GammaWorkingSpace(2.2F, KnownIlluminants.D50, new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.7350F, 0.2650F), new CieXyChromaticityCoordinates(0.1150F, 0.8260F), new CieXyChromaticityCoordinates(0.1570F, 0.0180F)));
}

55
src/ImageSharp/ColorProfiles/VonKriesChromaticAdaptation.cs

@ -19,34 +19,24 @@ public static class VonKriesChromaticAdaptation
/// <summary>
/// Performs a linear transformation of a source color in to the destination color.
/// </summary>
/// <typeparam name="TFrom">The type of color profile to convert from.</typeparam>
/// <typeparam name="TTo">The type of color profile to convert to.</typeparam>
/// <remarks>Doesn't crop the resulting color space coordinates (e.g. allows negative values for XYZ coordinates).</remarks>
/// <param name="options">The color profile conversion options.</param>
/// <param name="source">The source color.</param>
/// <param name="whitePoints">The conversion white points.</param>
/// <param name="matrix">The chromatic adaptation matrix.</param>
/// <returns>The <see cref="CieXyz"/></returns>
public static CieXyz Transform<TFrom, TTo>(ColorConversionOptions options, in CieXyz source)
where TFrom : struct, IColorProfile
where TTo : struct, IColorProfile
public static CieXyz Transform(in CieXyz source, (CieXyz From, CieXyz To) whitePoints, Matrix4x4 matrix)
{
CieXyz sourceWhitePoint = TFrom.GetChromaticAdaptionWhitePointSource() == ChromaticAdaptionWhitePointSource.WhitePoint
? options.WhitePoint
: options.RgbWorkingSpace.WhitePoint;
CieXyz from = whitePoints.From;
CieXyz to = whitePoints.To;
CieXyz targetWhitePoint = TTo.GetChromaticAdaptionWhitePointSource() == ChromaticAdaptionWhitePointSource.WhitePoint
? options.TargetWhitePoint
: options.TargetRgbWorkingSpace.WhitePoint;
if (sourceWhitePoint.Equals(targetWhitePoint))
if (from.Equals(to))
{
return new(source.X, source.Y, source.Z);
}
Matrix4x4 matrix = options.AdaptationMatrix;
Vector3 sourceColorLms = Vector3.Transform(source.ToVector3(), matrix);
Vector3 sourceWhitePointLms = Vector3.Transform(sourceWhitePoint.ToVector3(), matrix);
Vector3 targetWhitePointLms = Vector3.Transform(targetWhitePoint.ToVector3(), matrix);
Vector3 sourceWhitePointLms = Vector3.Transform(from.ToVector3(), matrix);
Vector3 targetWhitePointLms = Vector3.Transform(to.ToVector3(), matrix);
Vector3 vector = targetWhitePointLms / sourceWhitePointLms;
Vector3 targetColorLms = Vector3.Multiply(vector, sourceColorLms);
@ -58,41 +48,36 @@ public static class VonKriesChromaticAdaptation
/// <summary>
/// Performs a bulk linear transformation of a source color in to the destination color.
/// </summary>
/// <typeparam name="TFrom">The type of color profile to convert from.</typeparam>
/// <typeparam name="TTo">The type of color profile to convert to.</typeparam>
/// <remarks>Doesn't crop the resulting color space coordinates (e. g. allows negative values for XYZ coordinates).</remarks>
/// <param name="options">The color profile conversion options.</param>
/// <param name="source">The span to the source colors.</param>
/// <param name="destination">The span to the destination colors.</param>
public static void Transform<TFrom, TTo>(ColorConversionOptions options, ReadOnlySpan<CieXyz> source, Span<CieXyz> destination)
where TFrom : struct, IColorProfile
where TTo : struct, IColorProfile
/// <param name="whitePoints">The conversion white points.</param>
/// <param name="matrix">The chromatic adaptation matrix.</param>
public static void Transform(
ReadOnlySpan<CieXyz> source,
Span<CieXyz> destination,
(CieXyz From, CieXyz To) whitePoints,
Matrix4x4 matrix)
{
Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination));
int count = source.Length;
CieXyz sourceWhitePoint = TFrom.GetChromaticAdaptionWhitePointSource() == ChromaticAdaptionWhitePointSource.WhitePoint
? options.WhitePoint
: options.RgbWorkingSpace.WhitePoint;
CieXyz targetWhitePoint = TTo.GetChromaticAdaptionWhitePointSource() == ChromaticAdaptionWhitePointSource.WhitePoint
? options.TargetWhitePoint
: options.TargetRgbWorkingSpace.WhitePoint;
CieXyz from = whitePoints.From;
CieXyz to = whitePoints.To;
if (sourceWhitePoint.Equals(targetWhitePoint))
if (from.Equals(to))
{
source.CopyTo(destination[..count]);
return;
}
Matrix4x4 matrix = options.AdaptationMatrix;
Matrix4x4.Invert(matrix, out Matrix4x4 inverseMatrix);
ref CieXyz sourceBase = ref MemoryMarshal.GetReference(source);
ref CieXyz destinationBase = ref MemoryMarshal.GetReference(destination);
Vector3 sourceWhitePointLms = Vector3.Transform(sourceWhitePoint.ToVector3(), matrix);
Vector3 targetWhitePointLms = Vector3.Transform(targetWhitePoint.ToVector3(), matrix);
Vector3 sourceWhitePointLms = Vector3.Transform(from.ToVector3(), matrix);
Vector3 targetWhitePointLms = Vector3.Transform(to.ToVector3(), matrix);
Vector3 vector = targetWhitePointLms / sourceWhitePointLms;

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

@ -30,7 +30,7 @@ public class CieLabAndCieLchConversionTests
// Arrange
CieLch input = new(l, c, h);
CieLab expected = new(l2, a, b);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D50, TargetWhitePoint = Illuminants.D50 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D50 };
ColorProfileConverter converter = new(options);
Span<CieLch> inputSpan = new CieLch[5];
@ -65,7 +65,7 @@ public class CieLabAndCieLchConversionTests
// Arrange
CieLab input = new(l, a, b);
CieLch expected = new(l2, c, h);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D50, TargetWhitePoint = Illuminants.D50 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D50 };
ColorProfileConverter converter = new(options);
Span<CieLab> inputSpan = new CieLab[5];

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

@ -24,7 +24,7 @@ public class CieLabAndCieLchuvConversionTests
// Arrange
CieLchuv input = new(l, c, h);
CieLab expected = new(l2, a, b);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D50 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D50 };
ColorProfileConverter converter = new(options);
Span<CieLchuv> inputSpan = new CieLchuv[5];
@ -53,7 +53,7 @@ public class CieLabAndCieLchuvConversionTests
// Arrange
CieLab input = new(l, a, b);
CieLchuv expected = new(l2, c, h);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D50, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<CieLab> inputSpan = new CieLab[5];

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

@ -24,7 +24,7 @@ public class CieLabAndCieLuvConversionTests
// Arrange
CieLuv input = new(l, u, v);
CieLab expected = new(l2, a, b);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D50 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D50 };
ColorProfileConverter converter = new(options);
Span<CieLuv> inputSpan = new CieLuv[5];
@ -53,7 +53,7 @@ public class CieLabAndCieLuvConversionTests
// Arrange
CieLab input = new(l, a, b);
CieLuv expected = new(l2, u, v);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D50, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<CieLab> inputSpan = new CieLab[5];

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

@ -20,7 +20,7 @@ public class CieLchAndCieLuvConversionTests
// Arrange
CieLch input = new(l, c, h);
CieLuv expected = new(l2, u, v);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D50, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<CieLch> inputSpan = new CieLch[5];
@ -48,7 +48,7 @@ public class CieLchAndCieLuvConversionTests
// Arrange
CieLuv input = new(l2, u, v);
CieLch expected = new(l, c, h);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D50 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D50 };
ColorProfileConverter converter = new(options);
Span<CieLuv> inputSpan = new CieLuv[5];

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

@ -20,7 +20,7 @@ public class CieLchuvAndCieLchConversionTests
// Arrange
CieLch input = new(l2, c2, h2);
CieLchuv expected = new(l, c, h);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D50, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<CieLch> inputSpan = new CieLch[5];
@ -48,7 +48,7 @@ public class CieLchuvAndCieLchConversionTests
// Arrange
CieLchuv input = new(l, c, h);
CieLch expected = new(l2, c2, h2);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D50 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D50 };
ColorProfileConverter converter = new(options);
Span<CieLchuv> inputSpan = new CieLchuv[5];

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

@ -30,7 +30,7 @@ public class CieLchuvAndCieLuvConversionTests
// Arrange
CieLchuv input = new(l, c, h);
CieLuv expected = new(l2, u, v);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<CieLchuv> inputSpan = new CieLchuv[5];
@ -66,7 +66,7 @@ public class CieLchuvAndCieLuvConversionTests
// Arrange
CieLuv input = new(l, u, v);
CieLchuv expected = new(l2, c, h);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<CieLuv> inputSpan = new CieLuv[5];

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

@ -20,7 +20,7 @@ public class CieLchuvAndCmykConversionTests
// Arrange
Cmyk input = new(c2, m, y, k);
CieLchuv expected = new(l, c, h);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<Cmyk> inputSpan = new Cmyk[5];
@ -49,7 +49,7 @@ public class CieLchuvAndCmykConversionTests
// Arrange
CieLchuv input = new(l, c, h);
Cmyk expected = new(c2, m, y, k);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<CieLchuv> inputSpan = new CieLchuv[5];

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

@ -20,7 +20,7 @@ public class CieLuvAndCieXyyConversionTests
// Arrange
CieLuv input = new(l, u, v);
CieXyy expected = new(x, y, yl);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<CieLuv> inputSpan = new CieLuv[5];
@ -49,7 +49,7 @@ public class CieLuvAndCieXyyConversionTests
// Arrange
CieXyy input = new(x, y, yl);
CieLuv expected = new(l, u, v);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<CieXyy> inputSpan = new CieXyy[5];

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

@ -20,7 +20,7 @@ public class CieLuvAndHslConversionTests
// Arrange
CieLuv input = new(l, u, v);
Hsl expected = new(h, s, l2);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<CieLuv> inputSpan = new CieLuv[5];
@ -49,7 +49,7 @@ public class CieLuvAndHslConversionTests
// Arrange
Hsl input = new(h, s, l2);
CieLuv expected = new(l, u, v);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<Hsl> inputSpan = new Hsl[5];

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

@ -20,7 +20,7 @@ public class CieLuvAndHsvConversionTests
// Arrange
CieLuv input = new(l, u, v);
Hsv expected = new(h, s, v2);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<CieLuv> inputSpan = new CieLuv[5];
@ -49,7 +49,7 @@ public class CieLuvAndHsvConversionTests
// Arrange
Hsv input = new(h, s, v2);
CieLuv expected = new(l, u, v);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<Hsv> inputSpan = new Hsv[5];

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

@ -20,7 +20,7 @@ public class CieLuvAndHunterLabConversionTests
// Arrange
CieLuv input = new(l, u, v);
HunterLab expected = new(l2, a, b);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D50 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D50 };
ColorProfileConverter converter = new(options);
Span<CieLuv> inputSpan = new CieLuv[5];
@ -49,7 +49,7 @@ public class CieLuvAndHunterLabConversionTests
// Arrange
HunterLab input = new(l2, a, b);
CieLuv expected = new(l, u, v);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D50, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<HunterLab> inputSpan = new HunterLab[5];

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

@ -20,7 +20,7 @@ public class CieLuvAndLmsConversionTests
// Arrange
CieLuv input = new(l, u, v);
Lms expected = new(l2, m, s);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<CieLuv> inputSpan = new CieLuv[5];
@ -49,7 +49,7 @@ public class CieLuvAndLmsConversionTests
// Arrange
Lms input = new(l2, m, s);
CieLuv expected = new(l, u, v);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<Lms> inputSpan = new Lms[5];

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

@ -20,7 +20,7 @@ public class CieLuvAndRgbConversionTests
// Arrange
CieLuv input = new(l, u, v);
Rgb expected = new(r, g, b);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<CieLuv> inputSpan = new CieLuv[5];
@ -49,7 +49,7 @@ public class CieLuvAndRgbConversionTests
// Arrange
Rgb input = new(r, g, b);
CieLuv expected = new(l, u, v);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<Rgb> inputSpan = new Rgb[5];

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

@ -20,7 +20,7 @@ public class CieLuvAndYCbCrConversionTests
// Arrange
CieLuv input = new(l, u, v);
YCbCr expected = new(y, cb, cr);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<CieLuv> inputSpan = new CieLuv[5];
@ -49,7 +49,7 @@ public class CieLuvAndYCbCrConversionTests
// Arrange
YCbCr input = new(y, cb, cr);
CieLuv expected = new(l, u, v);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<YCbCr> inputSpan = new YCbCr[5];

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

@ -29,7 +29,7 @@ public class CieXyzAndCieLabConversionTest
{
// Arrange
CieLab input = new(l, a, b);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
CieXyz expected = new(x, y, z);
@ -62,7 +62,7 @@ public class CieXyzAndCieLabConversionTest
{
// Arrange
CieXyz input = new(x, y, z);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
CieLab expected = new(l, a, b);

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

@ -29,7 +29,7 @@ public class CieXyzAndCieLuvConversionTest
CieXyz input = new(x, y, z);
CieLuv expected = new(l, u, v);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<CieXyz> inputSpan = new CieXyz[5];
@ -64,7 +64,7 @@ public class CieXyzAndCieLuvConversionTest
CieLuv input = new(l, u, v);
CieXyz expected = new(x, y, z);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetWhitePoint = Illuminants.D65 };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span<CieLuv> inputSpan = new CieLuv[5];

204
tests/ImageSharp.Tests/ColorProfiles/ColorProfileConverterChomaticAdaptationTests.cs

@ -0,0 +1,204 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ColorProfiles;
using SixLabors.ImageSharp.ColorProfiles;
namespace SixLabors.ImageSharp.Tests.ColorProfiles;
/// <summary>
/// Tests chromatic adaptation within the <see cref="ColorProfileConverter"/>.
/// Test data generated using:
/// <see cref="http://www.brucelindbloom.com/index.html?ChromAdaptCalc.html"/>
/// <see cref="http://www.brucelindbloom.com/index.html?ColorCalculator.html"/>
/// </summary>
public class ColorProfileConverterChomaticAdaptationTests
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0001F);
[Theory]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(1, 1, 1, 1, 1, 1)]
[InlineData(0.206162, 0.260277, 0.746717, 0.220000, 0.130000, 0.780000)]
public void Adapt_RGB_WideGamutRGB_To_sRGB(float r1, float g1, float b1, float r2, float g2, float b2)
{
// Arrange
Rgb input = new(r1, g1, b1);
Rgb expected = new(r2, g2, b2);
ColorConversionOptions options = new()
{
RgbWorkingSpace = KnownRgbWorkingSpaces.WideGamutRgb,
TargetRgbWorkingSpace = KnownRgbWorkingSpaces.SRgb
};
ColorProfileConverter converter = new(options);
// Action
Rgb actual = converter.Convert<Rgb, Rgb>(input);
// Assert
Assert.Equal(expected, actual, Comparer);
}
[Theory]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(1, 1, 1, 1, 1, 1)]
[InlineData(0.220000, 0.130000, 0.780000, 0.206162, 0.260277, 0.746717)]
public void Adapt_RGB_SRGB_To_WideGamutRGB(float r1, float g1, float b1, float r2, float g2, float b2)
{
// Arrange
Rgb input = new(r1, g1, b1);
Rgb expected = new(r2, g2, b2);
ColorConversionOptions options = new()
{
RgbWorkingSpace = KnownRgbWorkingSpaces.SRgb,
TargetRgbWorkingSpace = KnownRgbWorkingSpaces.WideGamutRgb
};
ColorProfileConverter converter = new(options);
// Action
Rgb actual = converter.Convert<Rgb, Rgb>(input);
// Assert
Assert.Equal(expected, actual, Comparer);
}
[Theory]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(22, 33, 1, 22.269869, 32.841164, 1.633926)]
public void Adapt_Lab_D65_To_D50(float l1, float a1, float b1, float l2, float a2, float b2)
{
// Arrange
CieLab input = new(l1, a1, b1);
CieLab expected = new(l2, a2, b2);
ColorConversionOptions options = new()
{
WhitePoint = KnownIlluminants.D65,
TargetWhitePoint = KnownIlluminants.D50
};
ColorProfileConverter converter = new(options);
// Action
CieLab actual = converter.Convert<CieLab, CieLab>(input);
// Assert
Assert.Equal(expected, actual, Comparer);
}
[Theory]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(0.5, 0.5, 0.5, 0.510286, 0.501489, 0.378970)]
public void Adapt_Xyz_D65_To_D50_Bradford(float x1, float y1, float z1, float x2, float y2, float z2)
{
// Arrange
CieXyz input = new(x1, y1, z1);
CieXyz expected = new(x2, y2, z2);
ColorConversionOptions options = new()
{
WhitePoint = KnownIlluminants.D65,
TargetWhitePoint = KnownIlluminants.D50,
AdaptationMatrix = KnownChromaticAdaptationMatrices.Bradford
};
ColorProfileConverter converter = new(options);
// Action
CieXyz actual = converter.Convert<CieXyz, CieXyz>(input);
// Assert
Assert.Equal(expected, actual, Comparer);
}
[Theory]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(0.5, 0.5, 0.5, 0.507233, 0.500000, 0.378943)]
public void Adapt_Xyz_D65_To_D50_XyzScaling(float x1, float y1, float z1, float x2, float y2, float z2)
{
// Arrange
CieXyz input = new(x1, y1, z1);
CieXyz expected = new(x2, y2, z2);
ColorConversionOptions options = new()
{
WhitePoint = KnownIlluminants.D65,
TargetWhitePoint = KnownIlluminants.D50,
AdaptationMatrix = KnownChromaticAdaptationMatrices.XyzScaling
};
ColorProfileConverter converter = new(options);
// Action
CieXyz actual = converter.Convert<CieXyz, CieXyz>(input);
// Assert
Assert.Equal(expected, actual, Comparer);
}
[Theory]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(22, 33, 1, 22.28086, 33.0681534, 1.30099022)]
public void Adapt_HunterLab_D65_To_D50(float l1, float a1, float b1, float l2, float a2, float b2)
{
// Arrange
HunterLab input = new(l1, a1, b1);
HunterLab expected = new(l2, a2, b2);
ColorConversionOptions options = new()
{
WhitePoint = KnownIlluminants.D65,
TargetWhitePoint = KnownIlluminants.D50,
};
ColorProfileConverter converter = new(options);
// Action
HunterLab actual = converter.Convert<HunterLab, HunterLab>(input);
// Assert
Assert.Equal(expected, actual, Comparer);
}
[Theory]
[InlineData(0, 0, 0, 0, 0, 0)]
[InlineData(22, 33, 1, 22, 34.0843468, 359.009)]
public void Adapt_CieLchuv_D65_To_D50_XyzScaling(float l1, float c1, float h1, float l2, float c2, float h2)
{
// Arrange
CieLchuv input = new(l1, c1, h1);
CieLchuv expected = new(l2, c2, h2);
ColorConversionOptions options = new()
{
WhitePoint = KnownIlluminants.D65,
TargetWhitePoint = KnownIlluminants.D50,
AdaptationMatrix = KnownChromaticAdaptationMatrices.XyzScaling
};
ColorProfileConverter converter = new(options);
// Action
CieLchuv actual = converter.Convert<CieLchuv, CieLchuv>(input);
// Assert
Assert.Equal(expected, actual, Comparer);
}
[Theory]
[InlineData(22, 33, 1, 22, 33, 0.9999999)]
public void Adapt_CieLch_D65_To_D50_XyzScaling(float l1, float c1, float h1, float l2, float c2, float h2)
{
// Arrange
CieLch input = new(l1, c1, h1);
CieLch expected = new(l2, c2, h2);
ColorConversionOptions options = new()
{
WhitePoint = KnownIlluminants.D65,
TargetWhitePoint = KnownIlluminants.D50,
AdaptationMatrix = KnownChromaticAdaptationMatrices.XyzScaling
};
ColorProfileConverter converter = new(options);
// Action
CieLch actual = converter.Convert<CieLch, CieLch>(input);
// Assert
Assert.Equal(expected, actual, Comparer);
}
}

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

@ -28,7 +28,7 @@ public class RgbAndCieXyzConversionTest
{
// Arrange
CieXyz input = new(x, y, z);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D50, TargetRgbWorkingSpace = KnownRgbWorkingSpaces.SRgb };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D50, TargetRgbWorkingSpace = KnownRgbWorkingSpaces.SRgb };
ColorProfileConverter converter = new(options);
Rgb expected = new(r, g, b);
@ -61,7 +61,7 @@ public class RgbAndCieXyzConversionTest
{
// Arrange
CieXyz input = new(x, y, z);
ColorConversionOptions options = new() { WhitePoint = Illuminants.D65, TargetRgbWorkingSpace = KnownRgbWorkingSpaces.SRgb };
ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetRgbWorkingSpace = KnownRgbWorkingSpaces.SRgb };
ColorProfileConverter converter = new(options);
Rgb expected = new(r, g, b);
@ -94,7 +94,7 @@ public class RgbAndCieXyzConversionTest
{
// Arrange
Rgb input = new(r, g, b);
ColorConversionOptions options = new() { TargetWhitePoint = Illuminants.D50, RgbWorkingSpace = KnownRgbWorkingSpaces.SRgb };
ColorConversionOptions options = new() { TargetWhitePoint = KnownIlluminants.D50, RgbWorkingSpace = KnownRgbWorkingSpaces.SRgb };
ColorProfileConverter converter = new(options);
CieXyz expected = new(x, y, z);
@ -127,7 +127,7 @@ public class RgbAndCieXyzConversionTest
{
// Arrange
Rgb input = new(r, g, b);
ColorConversionOptions options = new() { TargetWhitePoint = Illuminants.D65, RgbWorkingSpace = KnownRgbWorkingSpaces.SRgb };
ColorConversionOptions options = new() { TargetWhitePoint = KnownIlluminants.D65, RgbWorkingSpace = KnownRgbWorkingSpaces.SRgb };
ColorProfileConverter converter = new(options);
CieXyz expected = new(x, y, z);

42
tests/ImageSharp.Tests/ColorProfiles/VonKriesChromaticAdaptationTests.cs

@ -0,0 +1,42 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.ColorProfiles;
namespace SixLabors.ImageSharp.Tests.ColorProfiles;
public class VonKriesChromaticAdaptationTests
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0001F);
public static readonly TheoryData<CieXyz, CieXyz> WhitePoints = new()
{
{ KnownIlluminants.D65, KnownIlluminants.D50 },
{ KnownIlluminants.D65, KnownIlluminants.D65 }
};
[Theory]
[MemberData(nameof(WhitePoints))]
public void SingleAndBulkTransformYieldIdenticalResults(CieXyz from, CieXyz to)
{
ColorConversionOptions options = new()
{
WhitePoint = from,
TargetWhitePoint = to
};
CieXyz input = new(1, 0, 1);
CieXyz expected = VonKriesChromaticAdaptation.Transform(in input, (from, to), KnownChromaticAdaptationMatrices.Bradford);
Span<CieXyz> inputSpan = new CieXyz[5];
inputSpan.Fill(input);
Span<CieXyz> actualSpan = new CieXyz[5];
VonKriesChromaticAdaptation.Transform(inputSpan, actualSpan, (from, to), KnownChromaticAdaptationMatrices.Bradford);
for (int i = 0; i < inputSpan.Length; i++)
{
Assert.Equal(expected, actualSpan[i], Comparer);
}
}
}
Loading…
Cancel
Save