From a92d8bdf769cc71ebd13f3fca67caef800cd8e7f Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Tue, 6 Feb 2018 21:13:48 +1100 Subject: [PATCH] Refactor RgbWorkingSpace --- .../Implementation/Rgb/GammaCompanding.cs | 46 ----- .../Implementation/Rgb/LCompanding.cs | 35 ---- .../Rgb/LinearRgbToRgbConverter.cs | 6 +- .../Implementation/Rgb/Rec2020Companding.cs | 32 ---- .../Implementation/Rgb/Rec709Companding.cs | 31 ---- .../Rgb/RgbGammaWorkingSpace.cs | 89 +++++++++ .../Implementation/Rgb/RgbLWorkingSpace.cs | 82 +++++++++ .../Rgb/RgbRec2020WorkingSpace.cs | 79 ++++++++ .../Rgb/RgbRec709WorkingSpace.cs | 78 ++++++++ .../Implementation/Rgb/RgbSRgbWorkingSpace.cs | 80 +++++++++ .../Rgb/RgbToLinearRgbConverter.cs | 6 +- .../Implementation/Rgb/RgbWorkingSpace.cs | 105 ----------- .../Implementation/Rgb/SRgbCompanding.cs | 33 ---- src/ImageSharp/ColorSpaces/ICompanding.cs | 35 ---- .../ColorSpaces/IRgbWorkingSpace.cs | 21 ++- .../ColorSpaces/RgbWorkingSpaces.cs | 169 +++++++++++++++--- 16 files changed, 581 insertions(+), 346 deletions(-) delete mode 100644 src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/GammaCompanding.cs delete mode 100644 src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/LCompanding.cs delete mode 100644 src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/Rec2020Companding.cs delete mode 100644 src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/Rec709Companding.cs create mode 100644 src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbGammaWorkingSpace.cs create mode 100644 src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbLWorkingSpace.cs create mode 100644 src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbRec2020WorkingSpace.cs create mode 100644 src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbRec709WorkingSpace.cs create mode 100644 src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbSRgbWorkingSpace.cs delete mode 100644 src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbWorkingSpace.cs delete mode 100644 src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/SRgbCompanding.cs delete mode 100644 src/ImageSharp/ColorSpaces/ICompanding.cs diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/GammaCompanding.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/GammaCompanding.cs deleted file mode 100644 index 21a80225e..000000000 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/GammaCompanding.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Runtime.CompilerServices; - -namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSapce -{ - /// - /// Implements gamma companding - /// - /// - /// - /// - /// - public class GammaCompanding : ICompanding - { - /// - /// Initializes a new instance of the class. - /// - /// The gamma value. - public GammaCompanding(float gamma) - { - this.Gamma = gamma; - } - - /// - /// Gets the gamma value - /// - public float Gamma { get; } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Expand(float channel) - { - return MathF.Pow(channel, this.Gamma); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Compress(float channel) - { - return MathF.Pow(channel, 1 / this.Gamma); - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/LCompanding.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/LCompanding.cs deleted file mode 100644 index 132861b47..000000000 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/LCompanding.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Runtime.CompilerServices; - -namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSapce -{ - /// - /// Implements L* companding - /// - /// - /// For more info see: - /// - /// - /// - public class LCompanding : ICompanding - { - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Expand(float channel) - { - return channel <= 0.08 ? 100 * channel / CieConstants.Kappa : MathF.Pow((channel + 0.16F) / 1.16F, 3); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Compress(float channel) - { - return channel <= CieConstants.Epsilon - ? channel * CieConstants.Kappa / 100F - : MathF.Pow(1.16F * channel, 0.3333333F) - 0.16F; - } - } -} diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/LinearRgbToRgbConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/LinearRgbToRgbConverter.cs index 29ea0f314..25dbc746b 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/LinearRgbToRgbConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/LinearRgbToRgbConverter.cs @@ -16,9 +16,9 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSap DebugGuard.NotNull(input, nameof(input)); Vector3 vector = input.Vector; - vector.X = input.WorkingSpace.Companding.Compress(vector.X); - vector.Y = input.WorkingSpace.Companding.Compress(vector.Y); - vector.Z = input.WorkingSpace.Companding.Compress(vector.Z); + vector.X = input.WorkingSpace.Compress(vector.X); + vector.Y = input.WorkingSpace.Compress(vector.Y); + vector.Z = input.WorkingSpace.Compress(vector.Z); return new Rgb(vector, input.WorkingSpace); } diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/Rec2020Companding.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/Rec2020Companding.cs deleted file mode 100644 index 11761f0e4..000000000 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/Rec2020Companding.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Runtime.CompilerServices; - -namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSapce -{ - /// - /// Implements Rec. 2020 companding function (for 12-bits). - /// - /// - /// - /// For 10-bits, companding is identical to - /// - public class Rec2020Companding : ICompanding - { - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Expand(float channel) - { - return channel < 0.08145F ? channel / 4.5F : MathF.Pow((channel + 0.0993F) / 1.0993F, 2.222222F); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Compress(float channel) - { - return channel < 0.0181F ? 4500F * channel : (1.0993F * channel) - 0.0993F; - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/Rec709Companding.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/Rec709Companding.cs deleted file mode 100644 index ccda6bf52..000000000 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/Rec709Companding.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Runtime.CompilerServices; - -namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSapce -{ - /// - /// Implements the Rec. 709 companding function - /// - /// - /// http://en.wikipedia.org/wiki/Rec._709 - /// - public class Rec709Companding : ICompanding - { - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Expand(float channel) - { - return channel < 0.081F ? channel / 4.5F : MathF.Pow((channel + 0.099F) / 1.099F, 2.222222F); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Compress(float channel) - { - return channel < 0.018F ? 4500F * channel : (1.099F * channel) - 0.099F; - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbGammaWorkingSpace.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbGammaWorkingSpace.cs new file mode 100644 index 000000000..891beba1a --- /dev/null +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbGammaWorkingSpace.cs @@ -0,0 +1,89 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Runtime.CompilerServices; + +namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSapce +{ + /// + /// Represents an that implements gamma companding + /// + /// + /// + /// + /// + internal class RgbGammaWorkingSpace : IRgbWorkingSpace, IEquatable + { + /// + /// Initializes a new instance of the class. + /// + /// The reference white point. + /// The gamma value. + /// The chromaticity of the rgb primaries. + public RgbGammaWorkingSpace(CieXyz referenceWhite, float gamma, RgbPrimariesChromaticityCoordinates chromaticityCoordinates) + { + this.WhitePoint = referenceWhite; + this.Gamma = gamma; + this.ChromaticityCoordinates = chromaticityCoordinates; + } + + /// + public CieXyz WhitePoint { get; } + + /// + public RgbPrimariesChromaticityCoordinates ChromaticityCoordinates { get; } + + /// + /// Gets the gamma value + /// + public float Gamma { get; } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Expand(float channel) + { + return MathF.Pow(channel, this.Gamma); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Compress(float channel) + { + return MathF.Pow(channel, 1 / this.Gamma); + } + + /// + public override bool Equals(object obj) + { + return obj is RgbGammaWorkingSpace space && this.Equals(space); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(IRgbWorkingSpace other) + { + return other is RgbGammaWorkingSpace space && this.Equals(space); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(RgbGammaWorkingSpace other) + { + return other != null && + this.WhitePoint.Equals(other.WhitePoint) && + this.ChromaticityCoordinates.Equals(other.ChromaticityCoordinates) && + this.Gamma == other.Gamma; + } + + /// + public override int GetHashCode() + { + return HashHelpers.Combine( + this.WhitePoint.GetHashCode(), + HashHelpers.Combine( + this.ChromaticityCoordinates.GetHashCode(), + this.Gamma.GetHashCode())); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbLWorkingSpace.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbLWorkingSpace.cs new file mode 100644 index 000000000..c2d75cd90 --- /dev/null +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbLWorkingSpace.cs @@ -0,0 +1,82 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Runtime.CompilerServices; + +namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSapce +{ + /// + /// Represents an that implements L* companding + /// + /// + /// For more info see: + /// + /// + /// + internal class RgbLWorkingSpace : IRgbWorkingSpace, IEquatable + { + /// + /// Initializes a new instance of the class. + /// + /// The reference white point. + /// The chromaticity of the rgb primaries. + public RgbLWorkingSpace(CieXyz referenceWhite, RgbPrimariesChromaticityCoordinates chromaticityCoordinates) + { + this.WhitePoint = referenceWhite; + this.ChromaticityCoordinates = chromaticityCoordinates; + } + + /// + public CieXyz WhitePoint { get; } + + /// + public RgbPrimariesChromaticityCoordinates ChromaticityCoordinates { get; } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Expand(float channel) + { + return channel <= 0.08 ? 100 * channel / CieConstants.Kappa : MathF.Pow((channel + 0.16F) / 1.16F, 3); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Compress(float channel) + { + return channel <= CieConstants.Epsilon + ? channel * CieConstants.Kappa / 100F + : MathF.Pow(1.16F * channel, 0.3333333F) - 0.16F; + } + + /// + public override bool Equals(object obj) + { + return obj is RgbLWorkingSpace space && this.Equals(space); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(IRgbWorkingSpace other) + { + return other is RgbLWorkingSpace space && this.Equals(space); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(RgbLWorkingSpace other) + { + return other != null && + this.WhitePoint.Equals(other.WhitePoint) && + this.ChromaticityCoordinates.Equals(other.ChromaticityCoordinates); + } + + /// + public override int GetHashCode() + { + return HashHelpers.Combine( + this.WhitePoint.GetHashCode(), + this.ChromaticityCoordinates.GetHashCode()); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbRec2020WorkingSpace.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbRec2020WorkingSpace.cs new file mode 100644 index 000000000..cc814e9b3 --- /dev/null +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbRec2020WorkingSpace.cs @@ -0,0 +1,79 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Runtime.CompilerServices; + +namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSapce +{ + /// + /// Represents an that implements Rec. 2020 companding (for 12-bits). + /// + /// + /// + /// For 10-bits, companding is identical to + /// + internal class RgbRec2020WorkingSpace : IRgbWorkingSpace, IEquatable + { + /// + /// Initializes a new instance of the class. + /// + /// The reference white point. + /// The chromaticity of the rgb primaries. + public RgbRec2020WorkingSpace(CieXyz referenceWhite, RgbPrimariesChromaticityCoordinates chromaticityCoordinates) + { + this.WhitePoint = referenceWhite; + this.ChromaticityCoordinates = chromaticityCoordinates; + } + + /// + public CieXyz WhitePoint { get; } + + /// + public RgbPrimariesChromaticityCoordinates ChromaticityCoordinates { get; } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Expand(float channel) + { + return channel < 0.08145F ? channel / 4.5F : MathF.Pow((channel + 0.0993F) / 1.0993F, 2.222222F); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Compress(float channel) + { + return channel < 0.0181F ? 4500F * channel : (1.0993F * channel) - 0.0993F; + } + + /// + public override bool Equals(object obj) + { + return obj is RgbRec2020WorkingSpace space && this.Equals(space); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(IRgbWorkingSpace other) + { + return other is RgbRec2020WorkingSpace space && this.Equals(space); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(RgbRec2020WorkingSpace other) + { + return other != null && + this.WhitePoint.Equals(other.WhitePoint) && + this.ChromaticityCoordinates.Equals(other.ChromaticityCoordinates); + } + + /// + public override int GetHashCode() + { + return HashHelpers.Combine( + this.WhitePoint.GetHashCode(), + this.ChromaticityCoordinates.GetHashCode()); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbRec709WorkingSpace.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbRec709WorkingSpace.cs new file mode 100644 index 000000000..87301dd65 --- /dev/null +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbRec709WorkingSpace.cs @@ -0,0 +1,78 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Runtime.CompilerServices; + +namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSapce +{ + /// + /// Represents an that implements Rec. 709 companding. + /// + /// + /// + /// + internal class RgbRec709WorkingSpace : IRgbWorkingSpace, IEquatable + { + /// + /// Initializes a new instance of the class. + /// + /// The reference white point. + /// The chromaticity of the rgb primaries. + public RgbRec709WorkingSpace(CieXyz referenceWhite, RgbPrimariesChromaticityCoordinates chromaticityCoordinates) + { + this.WhitePoint = referenceWhite; + this.ChromaticityCoordinates = chromaticityCoordinates; + } + + /// + public CieXyz WhitePoint { get; } + + /// + public RgbPrimariesChromaticityCoordinates ChromaticityCoordinates { get; } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Expand(float channel) + { + return channel < 0.081F ? channel / 4.5F : MathF.Pow((channel + 0.099F) / 1.099F, 2.222222F); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Compress(float channel) + { + return channel < 0.018F ? 4500F * channel : (1.099F * channel) - 0.099F; + } + + /// + public override bool Equals(object obj) + { + return obj is RgbRec709WorkingSpace space && this.Equals(space); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(IRgbWorkingSpace other) + { + return other is RgbRec709WorkingSpace space && this.Equals(space); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(RgbRec709WorkingSpace other) + { + return other != null && + this.WhitePoint.Equals(other.WhitePoint) && + this.ChromaticityCoordinates.Equals(other.ChromaticityCoordinates); + } + + /// + public override int GetHashCode() + { + return HashHelpers.Combine( + this.WhitePoint.GetHashCode(), + this.ChromaticityCoordinates.GetHashCode()); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbSRgbWorkingSpace.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbSRgbWorkingSpace.cs new file mode 100644 index 000000000..98edaa0b3 --- /dev/null +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbSRgbWorkingSpace.cs @@ -0,0 +1,80 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Runtime.CompilerServices; + +namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSapce +{ + /// + /// Represents an that implements sRGB companding + /// + /// + /// For more info see: + /// + /// + /// + internal class RgbSRgbWorkingSpace : IRgbWorkingSpace, IEquatable + { + /// + /// Initializes a new instance of the class. + /// + /// The reference white point. + /// The chromaticity of the rgb primaries. + public RgbSRgbWorkingSpace(CieXyz referenceWhite, RgbPrimariesChromaticityCoordinates chromaticityCoordinates) + { + this.WhitePoint = referenceWhite; + this.ChromaticityCoordinates = chromaticityCoordinates; + } + + /// + public CieXyz WhitePoint { get; } + + /// + public RgbPrimariesChromaticityCoordinates ChromaticityCoordinates { get; } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Expand(float channel) + { + return channel <= 0.04045F ? channel / 12.92F : MathF.Pow((channel + 0.055F) / 1.055F, 2.4F); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Compress(float channel) + { + return channel <= 0.0031308F ? 12.92F * channel : (1.055F * MathF.Pow(channel, 0.416666666666667F)) - 0.055F; + } + + /// + public override bool Equals(object obj) + { + return obj is RgbSRgbWorkingSpace space && this.Equals(space); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(IRgbWorkingSpace other) + { + return other is RgbSRgbWorkingSpace space && this.Equals(space); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(RgbSRgbWorkingSpace other) + { + return other != null && + this.WhitePoint.Equals(other.WhitePoint) && + this.ChromaticityCoordinates.Equals(other.ChromaticityCoordinates); + } + + /// + public override int GetHashCode() + { + return HashHelpers.Combine( + this.WhitePoint.GetHashCode(), + this.ChromaticityCoordinates.GetHashCode()); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbToLinearRgbConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbToLinearRgbConverter.cs index e40ecc192..89a57051f 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbToLinearRgbConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbToLinearRgbConverter.cs @@ -16,9 +16,9 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSap Guard.NotNull(input, nameof(input)); Vector3 vector = input.Vector; - vector.X = input.WorkingSpace.Companding.Expand(vector.X); - vector.Y = input.WorkingSpace.Companding.Expand(vector.Y); - vector.Z = input.WorkingSpace.Companding.Expand(vector.Z); + vector.X = input.WorkingSpace.Expand(vector.X); + vector.Y = input.WorkingSpace.Expand(vector.Y); + vector.Z = input.WorkingSpace.Expand(vector.Z); return new LinearRgb(vector, input.WorkingSpace); } diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbWorkingSpace.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbWorkingSpace.cs deleted file mode 100644 index a7b63d657..000000000 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/RgbWorkingSpace.cs +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSapce -{ - /// - /// Trivial implementation of - /// - internal class RgbWorkingSpace : IRgbWorkingSpace - { - /// - /// Initializes a new instance of the class. - /// - /// The reference white point. - /// The function pair for converting to and back. - /// The chromaticity of the rgb primaries. - public RgbWorkingSpace(CieXyz referenceWhite, ICompanding companding, RgbPrimariesChromaticityCoordinates chromaticityCoordinates) - { - this.WhitePoint = referenceWhite; - this.Companding = companding; - this.ChromaticityCoordinates = chromaticityCoordinates; - } - - /// - /// Gets the reference white point - /// - public CieXyz WhitePoint { get; } - - /// - /// Gets the function pair for converting to and back. - /// - public ICompanding Companding { get; } - - /// - /// Gets the chromaticity of the rgb primaries. - /// - public RgbPrimariesChromaticityCoordinates ChromaticityCoordinates { get; } - - /// - /// Compares two objects for equality. - /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// - /// - /// True if the current left is equal to the parameter; otherwise, false. - /// - public static bool operator ==(RgbWorkingSpace left, RgbWorkingSpace right) - { - return left.Equals(right); - } - - /// - /// Compares two objects for inequality - /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// - /// - /// True if the current left is unequal to the parameter; otherwise, false. - /// - public static bool operator !=(RgbWorkingSpace left, RgbWorkingSpace right) - { - return !left.Equals(right); - } - - /// - public override bool Equals(object obj) - { - if (obj is RgbWorkingSpace) - { - return this.Equals((RgbWorkingSpace)obj); - } - - return false; - } - - /// - public bool Equals(IRgbWorkingSpace other) - { - // This should be refactored as separate classes with different companding implementations. - return this.WhitePoint.Equals(other.WhitePoint) - && this.ChromaticityCoordinates.Equals(other.ChromaticityCoordinates) - && Equals(this.Companding, other.Companding); - } - - /// - public override int GetHashCode() - { - unchecked - { - int hashCode = this.WhitePoint.GetHashCode(); - hashCode = (hashCode * 397) ^ this.ChromaticityCoordinates.GetHashCode(); - hashCode = (hashCode * 397) ^ (this.Companding?.GetHashCode() ?? 0); - return hashCode; - } - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/SRgbCompanding.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/SRgbCompanding.cs deleted file mode 100644 index ce8ea7c6e..000000000 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Rgb/SRgbCompanding.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Runtime.CompilerServices; - -namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSapce -{ - /// - /// Implements sRGB companding - /// - /// - /// For more info see: - /// - /// - /// - public class SRgbCompanding : ICompanding - { - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Expand(float channel) - { - return channel <= 0.04045F ? channel / 12.92F : MathF.Pow((channel + 0.055F) / 1.055F, 2.4F); - } - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Compress(float channel) - { - return channel <= 0.0031308F ? 12.92F * channel : (1.055F * MathF.Pow(channel, 0.416666666666667F)) - 0.055F; - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/ICompanding.cs b/src/ImageSharp/ColorSpaces/ICompanding.cs deleted file mode 100644 index 2dfa575ed..000000000 --- a/src/ImageSharp/ColorSpaces/ICompanding.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -namespace SixLabors.ImageSharp.ColorSpaces -{ - /// - /// Pair of companding functions for . - /// Used for conversion to and backwards. - /// See also: - /// - internal interface ICompanding - { - /// - /// Expands a companded channel to its linear equivalent with respect to the energy. - /// - /// - /// For more info see: - /// - /// - /// The channel value - /// The linear channel value - float Expand(float channel); - - /// - /// Compresses an uncompanded channel (linear) to its nonlinear equivalent (depends on the RGB color system). - /// - /// - /// For more info see: - /// - /// - /// The channel value - /// The nonlinear channel value - float Compress(float channel); - } -} diff --git a/src/ImageSharp/ColorSpaces/IRgbWorkingSpace.cs b/src/ImageSharp/ColorSpaces/IRgbWorkingSpace.cs index bd31fd61a..1af3a219d 100644 --- a/src/ImageSharp/ColorSpaces/IRgbWorkingSpace.cs +++ b/src/ImageSharp/ColorSpaces/IRgbWorkingSpace.cs @@ -22,10 +22,25 @@ namespace SixLabors.ImageSharp.ColorSpaces RgbPrimariesChromaticityCoordinates ChromaticityCoordinates { get; } /// - /// Gets the companding function associated with the RGB color system. Used for conversion to XYZ and backwards. + /// Expands a compressed channel to its linear equivalent with respect to the energy. + /// + /// + /// For more info see: /// - /// + /// + /// The channel value + /// The linear channel value + float Expand(float channel); + + /// + /// Compresses an expanded channel (linear) to its nonlinear equivalent (depends on the RGB color system). /// - ICompanding Companding { get; } + /// + /// For more info see: + /// + /// + /// The channel value + /// The nonlinear channel value + float Compress(float channel); } } \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/RgbWorkingSpaces.cs b/src/ImageSharp/ColorSpaces/RgbWorkingSpaces.cs index 098ca9a4a..93557154d 100644 --- a/src/ImageSharp/ColorSpaces/RgbWorkingSpaces.cs +++ b/src/ImageSharp/ColorSpaces/RgbWorkingSpaces.cs @@ -19,97 +19,226 @@ namespace SixLabors.ImageSharp.ColorSpaces /// Uses proper companding function, according to: /// /// - public static readonly IRgbWorkingSpace SRgb = new RgbWorkingSpace(Illuminants.D65, new SRgbCompanding(), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6400F, 0.3300F), new CieXyChromaticityCoordinates(0.3000F, 0.6000F), new CieXyChromaticityCoordinates(0.1500F, 0.0600F))); + public static readonly IRgbWorkingSpace SRgb = + new RgbSRgbWorkingSpace( + Illuminants.D65, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.6400F, 0.3300F), + new CieXyChromaticityCoordinates(0.3000F, 0.6000F), + new CieXyChromaticityCoordinates(0.1500F, 0.0600F))); /// - /// Simplified sRgb working space (uses gamma companding instead of ). + /// Simplified sRgb working space that uses gamma companding instead of srgb companding. /// See also . /// - public static readonly IRgbWorkingSpace SRgbSimplified = new RgbWorkingSpace(Illuminants.D65, new GammaCompanding(2.2F), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6400F, 0.3300F), new CieXyChromaticityCoordinates(0.3000F, 0.6000F), new CieXyChromaticityCoordinates(0.1500F, 0.0600F))); + public static readonly IRgbWorkingSpace SRgbSimplified = + new RgbGammaWorkingSpace( + Illuminants.D65, + 2.2F, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.6400F, 0.3300F), + new CieXyChromaticityCoordinates(0.3000F, 0.6000F), + new CieXyChromaticityCoordinates(0.1500F, 0.0600F))); /// /// Rec. 709 (ITU-R Recommendation BT.709) working space /// - public static readonly IRgbWorkingSpace Rec709 = new RgbWorkingSpace(Illuminants.D65, new Rec709Companding(), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.64F, 0.33F), new CieXyChromaticityCoordinates(0.30F, 0.60F), new CieXyChromaticityCoordinates(0.15F, 0.06F))); + public static readonly IRgbWorkingSpace Rec709 = + new RgbRec709WorkingSpace( + Illuminants.D65, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.64F, 0.33F), + new CieXyChromaticityCoordinates(0.30F, 0.60F), + new CieXyChromaticityCoordinates(0.15F, 0.06F))); /// /// Rec. 2020 (ITU-R Recommendation BT.2020F) working space /// - public static readonly IRgbWorkingSpace Rec2020 = new RgbWorkingSpace(Illuminants.D65, new Rec2020Companding(), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.708F, 0.292F), new CieXyChromaticityCoordinates(0.170F, 0.797F), new CieXyChromaticityCoordinates(0.131F, 0.046F))); + public static readonly IRgbWorkingSpace Rec2020 = + new RgbRec2020WorkingSpace( + Illuminants.D65, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.708F, 0.292F), + new CieXyChromaticityCoordinates(0.170F, 0.797F), + new CieXyChromaticityCoordinates(0.131F, 0.046F))); /// /// ECI Rgb v2 working space /// - public static readonly IRgbWorkingSpace ECIRgbv2 = new RgbWorkingSpace(Illuminants.D50, new LCompanding(), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6700F, 0.3300F), new CieXyChromaticityCoordinates(0.2100F, 0.7100F), new CieXyChromaticityCoordinates(0.1400F, 0.0800F))); + public static readonly IRgbWorkingSpace ECIRgbv2 = + new RgbLWorkingSpace( + Illuminants.D50, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.6700F, 0.3300F), + new CieXyChromaticityCoordinates(0.2100F, 0.7100F), + new CieXyChromaticityCoordinates(0.1400F, 0.0800F))); /// /// Adobe Rgb (1998) working space /// - public static readonly IRgbWorkingSpace AdobeRgb1998 = new RgbWorkingSpace(Illuminants.D65, new GammaCompanding(2.2F), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6400F, 0.3300F), new CieXyChromaticityCoordinates(0.2100F, 0.7100F), new CieXyChromaticityCoordinates(0.1500F, 0.0600F))); + public static readonly IRgbWorkingSpace AdobeRgb1998 = + new RgbGammaWorkingSpace( + Illuminants.D65, + 2.2F, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.6400F, 0.3300F), + new CieXyChromaticityCoordinates(0.2100F, 0.7100F), + new CieXyChromaticityCoordinates(0.1500F, 0.0600F))); /// /// Apple sRgb working space /// - public static readonly IRgbWorkingSpace ApplesRgb = new RgbWorkingSpace(Illuminants.D65, new GammaCompanding(1.8F), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6250F, 0.3400F), new CieXyChromaticityCoordinates(0.2800F, 0.5950F), new CieXyChromaticityCoordinates(0.1550F, 0.0700F))); + public static readonly IRgbWorkingSpace ApplesRgb = + new RgbGammaWorkingSpace( + Illuminants.D65, + 1.8F, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.6250F, 0.3400F), + new CieXyChromaticityCoordinates(0.2800F, 0.5950F), + new CieXyChromaticityCoordinates(0.1550F, 0.0700F))); /// /// Best Rgb working space /// - public static readonly IRgbWorkingSpace BestRgb = new RgbWorkingSpace(Illuminants.D50, new GammaCompanding(2.2F), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.7347F, 0.2653F), new CieXyChromaticityCoordinates(0.2150F, 0.7750F), new CieXyChromaticityCoordinates(0.1300F, 0.0350F))); + public static readonly IRgbWorkingSpace BestRgb = + new RgbGammaWorkingSpace( + Illuminants.D50, + 2.2F, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.7347F, 0.2653F), + new CieXyChromaticityCoordinates(0.2150F, 0.7750F), + new CieXyChromaticityCoordinates(0.1300F, 0.0350F))); /// /// Beta Rgb working space /// - public static readonly IRgbWorkingSpace BetaRgb = new RgbWorkingSpace(Illuminants.D50, new GammaCompanding(2.2F), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6888F, 0.3112F), new CieXyChromaticityCoordinates(0.1986F, 0.7551F), new CieXyChromaticityCoordinates(0.1265F, 0.0352F))); + public static readonly IRgbWorkingSpace BetaRgb = + new RgbGammaWorkingSpace( + Illuminants.D50, + 2.2F, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.6888F, 0.3112F), + new CieXyChromaticityCoordinates(0.1986F, 0.7551F), + new CieXyChromaticityCoordinates(0.1265F, 0.0352F))); /// /// Bruce Rgb working space /// - public static readonly IRgbWorkingSpace BruceRgb = new RgbWorkingSpace(Illuminants.D65, new GammaCompanding(2.2F), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6400F, 0.3300F), new CieXyChromaticityCoordinates(0.2800F, 0.6500F), new CieXyChromaticityCoordinates(0.1500F, 0.0600F))); + public static readonly IRgbWorkingSpace BruceRgb = + new RgbGammaWorkingSpace( + Illuminants.D65, + 2.2F, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.6400F, 0.3300F), + new CieXyChromaticityCoordinates(0.2800F, 0.6500F), + new CieXyChromaticityCoordinates(0.1500F, 0.0600F))); /// /// CIE Rgb working space /// - public static readonly IRgbWorkingSpace CIERgb = new RgbWorkingSpace(Illuminants.E, new GammaCompanding(2.2F), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.7350F, 0.2650F), new CieXyChromaticityCoordinates(0.2740F, 0.7170F), new CieXyChromaticityCoordinates(0.1670F, 0.0090F))); + public static readonly IRgbWorkingSpace CIERgb = + new RgbGammaWorkingSpace( + Illuminants.E, + 2.2F, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.7350F, 0.2650F), + new CieXyChromaticityCoordinates(0.2740F, 0.7170F), + new CieXyChromaticityCoordinates(0.1670F, 0.0090F))); /// /// ColorMatch Rgb working space /// - public static readonly IRgbWorkingSpace ColorMatchRgb = new RgbWorkingSpace(Illuminants.D50, new GammaCompanding(1.8F), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6300F, 0.3400F), new CieXyChromaticityCoordinates(0.2950F, 0.6050F), new CieXyChromaticityCoordinates(0.1500F, 0.0750F))); + public static readonly IRgbWorkingSpace ColorMatchRgb = + new RgbGammaWorkingSpace( + Illuminants.D50, + 1.8F, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.6300F, 0.3400F), + new CieXyChromaticityCoordinates(0.2950F, 0.6050F), + new CieXyChromaticityCoordinates(0.1500F, 0.0750F))); /// /// Don Rgb 4 working space /// - public static readonly IRgbWorkingSpace DonRgb4 = new RgbWorkingSpace(Illuminants.D50, new GammaCompanding(2.2F), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6960F, 0.3000F), new CieXyChromaticityCoordinates(0.2150F, 0.7650F), new CieXyChromaticityCoordinates(0.1300F, 0.0350F))); + public static readonly IRgbWorkingSpace DonRgb4 = + new RgbGammaWorkingSpace( + Illuminants.D50, + 2.2F, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.6960F, 0.3000F), + new CieXyChromaticityCoordinates(0.2150F, 0.7650F), + new CieXyChromaticityCoordinates(0.1300F, 0.0350F))); /// /// Ekta Space PS5 working space /// - public static readonly IRgbWorkingSpace EktaSpacePS5 = new RgbWorkingSpace(Illuminants.D50, new GammaCompanding(2.2F), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6950F, 0.3050F), new CieXyChromaticityCoordinates(0.2600F, 0.7000F), new CieXyChromaticityCoordinates(0.1100F, 0.0050F))); + public static readonly IRgbWorkingSpace EktaSpacePS5 = + new RgbGammaWorkingSpace( + Illuminants.D50, + 2.2F, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.6950F, 0.3050F), + new CieXyChromaticityCoordinates(0.2600F, 0.7000F), + new CieXyChromaticityCoordinates(0.1100F, 0.0050F))); /// /// NTSC Rgb working space /// - public static readonly IRgbWorkingSpace NTSCRgb = new RgbWorkingSpace(Illuminants.C, new GammaCompanding(2.2F), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6700F, 0.3300F), new CieXyChromaticityCoordinates(0.2100F, 0.7100F), new CieXyChromaticityCoordinates(0.1400F, 0.0800F))); + public static readonly IRgbWorkingSpace NTSCRgb = + new RgbGammaWorkingSpace( + Illuminants.C, + 2.2F, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.6700F, 0.3300F), + new CieXyChromaticityCoordinates(0.2100F, 0.7100F), + new CieXyChromaticityCoordinates(0.1400F, 0.0800F))); /// /// PAL/SECAM Rgb working space /// - public static readonly IRgbWorkingSpace PALSECAMRgb = new RgbWorkingSpace(Illuminants.D65, new GammaCompanding(2.2F), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6400F, 0.3300F), new CieXyChromaticityCoordinates(0.2900F, 0.6000F), new CieXyChromaticityCoordinates(0.1500F, 0.0600F))); + public static readonly IRgbWorkingSpace PALSECAMRgb = + new RgbGammaWorkingSpace( + Illuminants.D65, + 2.2F, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.6400F, 0.3300F), + new CieXyChromaticityCoordinates(0.2900F, 0.6000F), + new CieXyChromaticityCoordinates(0.1500F, 0.0600F))); /// /// ProPhoto Rgb working space /// - public static readonly IRgbWorkingSpace ProPhotoRgb = new RgbWorkingSpace(Illuminants.D50, new GammaCompanding(1.8F), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.7347F, 0.2653F), new CieXyChromaticityCoordinates(0.1596F, 0.8404F), new CieXyChromaticityCoordinates(0.0366F, 0.0001F))); + public static readonly IRgbWorkingSpace ProPhotoRgb = + new RgbGammaWorkingSpace( + Illuminants.D50, + 1.8F, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.7347F, 0.2653F), + new CieXyChromaticityCoordinates(0.1596F, 0.8404F), + new CieXyChromaticityCoordinates(0.0366F, 0.0001F))); /// /// SMPTE-C Rgb working space /// - public static readonly IRgbWorkingSpace SMPTECRgb = new RgbWorkingSpace(Illuminants.D65, new GammaCompanding(2.2F), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.6300F, 0.3400F), new CieXyChromaticityCoordinates(0.3100F, 0.5950F), new CieXyChromaticityCoordinates(0.1550F, 0.0700F))); + public static readonly IRgbWorkingSpace SMPTECRgb = + new RgbGammaWorkingSpace( + Illuminants.D65, + 2.2F, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.6300F, 0.3400F), + new CieXyChromaticityCoordinates(0.3100F, 0.5950F), + new CieXyChromaticityCoordinates(0.1550F, 0.0700F))); /// /// Wide Gamut Rgb working space /// - public static readonly IRgbWorkingSpace WideGamutRgb = new RgbWorkingSpace(Illuminants.D50, new GammaCompanding(2.2F), new RgbPrimariesChromaticityCoordinates(new CieXyChromaticityCoordinates(0.7350F, 0.2650F), new CieXyChromaticityCoordinates(0.1150F, 0.8260F), new CieXyChromaticityCoordinates(0.1570F, 0.0180F))); + public static readonly IRgbWorkingSpace WideGamutRgb = + new RgbGammaWorkingSpace( + Illuminants.D50, + 2.2F, + new RgbPrimariesChromaticityCoordinates( + new CieXyChromaticityCoordinates(0.7350F, 0.2650F), + new CieXyChromaticityCoordinates(0.1150F, 0.8260F), + new CieXyChromaticityCoordinates(0.1570F, 0.0180F))); } } \ No newline at end of file