mirror of https://github.com/SixLabors/ImageSharp
189 changed files with 11833 additions and 3651 deletions
@ -0,0 +1,55 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System.Numerics; |
||||
|
using SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.ColorSpaces.Conversion |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Configuration options for the <see cref="ColorSpaceConverter"/> class.
|
||||
|
/// </summary>
|
||||
|
public class ColorSpaceConverterOptions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets or sets the white point used for chromatic adaptation in conversions from/to XYZ color space.
|
||||
|
/// When <value>default</value>, no adaptation will be performed.
|
||||
|
/// Defaults to: <see cref="CieLuv.DefaultWhitePoint"/>.
|
||||
|
/// </summary>
|
||||
|
public CieXyz WhitePoint { get; set; } = CieLuv.DefaultWhitePoint; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the white point used *when creating* Luv/LChuv colors. (Luv/LChuv colors on the input already contain the white point information)
|
||||
|
/// Defaults to: <see cref="CieLuv.DefaultWhitePoint"/>.
|
||||
|
/// </summary>
|
||||
|
public CieXyz TargetLuvWhitePoint { get; set; } = CieLuv.DefaultWhitePoint; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the white point used *when creating* Lab/LChab colors. (Lab/LChab colors on the input already contain the white point information)
|
||||
|
/// Defaults to: <see cref="CieLab.DefaultWhitePoint"/>.
|
||||
|
/// </summary>
|
||||
|
public CieXyz TargetLabWhitePoint { get; set; } = CieLab.DefaultWhitePoint; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the white point used *when creating* HunterLab colors. (HunterLab colors on the input already contain the white point information)
|
||||
|
/// Defaults to: <see cref="HunterLab.DefaultWhitePoint"/>.
|
||||
|
/// </summary>
|
||||
|
public CieXyz TargetHunterLabWhitePoint { get; set; } = HunterLab.DefaultWhitePoint; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the target working space used *when creating* RGB colors. (RGB colors on the input already contain the working space information)
|
||||
|
/// Defaults to: <see cref="Rgb.DefaultWorkingSpace"/>.
|
||||
|
/// </summary>
|
||||
|
public RgbWorkingSpaceBase TargetRgbWorkingSpace { get; set; } = Rgb.DefaultWorkingSpace; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the chromatic adaptation method used. When <value>null</value>, no adaptation will be performed.
|
||||
|
/// </summary>
|
||||
|
public IChromaticAdaptation ChromaticAdaptation { get; set; } = new VonKriesChromaticAdaptation(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets transformation matrix used in conversion to and from <see cref="Lms"/>.
|
||||
|
/// </summary>
|
||||
|
public Matrix4x4 LmsAdaptationMatrix { get; set; } = CieXyzAndLmsConverter.DefaultTransformationMatrix; |
||||
|
} |
||||
|
} |
||||
@ -1,22 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
namespace SixLabors.ImageSharp.ColorSpaces.Conversion |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Converts color between two color spaces.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">The input color type.</typeparam>
|
|
||||
/// <typeparam name="TResult">The result color type.</typeparam>
|
|
||||
internal interface IColorConversion<T, TResult> |
|
||||
where T : struct |
|
||||
where TResult : struct |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Performs the conversion from the input to an instance of the output type.
|
|
||||
/// </summary>
|
|
||||
/// <param name="input">The input color instance.</param>
|
|
||||
/// <returns>The converted result</returns>
|
|
||||
TResult Convert(in T input); |
|
||||
} |
|
||||
} |
|
||||
@ -1,49 +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.CmykColorSapce |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Color converter between CMYK and Rgb
|
|
||||
/// </summary>
|
|
||||
internal class CmykAndRgbConverter : IColorConversion<Cmyk, Rgb>, IColorConversion<Rgb, Cmyk> |
|
||||
{ |
|
||||
/// <inheritdoc/>
|
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
public Rgb Convert(in Cmyk input) |
|
||||
{ |
|
||||
float r = (1F - input.C) * (1F - input.K); |
|
||||
float g = (1F - input.M) * (1F - input.K); |
|
||||
float b = (1F - input.Y) * (1F - input.K); |
|
||||
|
|
||||
return new Rgb(r, g, b); |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
public Cmyk Convert(in Rgb input) |
|
||||
{ |
|
||||
// To CMYK
|
|
||||
float c = 1F - input.R; |
|
||||
float m = 1F - input.G; |
|
||||
float y = 1F - input.B; |
|
||||
|
|
||||
// To CMYK
|
|
||||
float k = MathF.Min(c, MathF.Min(m, y)); |
|
||||
|
|
||||
if (MathF.Abs(k - 1F) < Constants.Epsilon) |
|
||||
{ |
|
||||
return new Cmyk(0, 0, 0, 1F); |
|
||||
} |
|
||||
|
|
||||
c = (c - k) / (1F - k); |
|
||||
m = (m - k) / (1F - k); |
|
||||
y = (y - k) / (1F - k); |
|
||||
|
|
||||
return new Cmyk(c, m, y, k); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,51 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Color converter between <see cref="Cmyk"/> and <see cref="Rgb"/>
|
||||
|
/// </summary>
|
||||
|
internal sealed class CmykAndRgbConverter |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Performs the conversion from the <see cref="Cmyk"/> input to an instance of <see cref="Rgb"/> type.
|
||||
|
/// </summary>
|
||||
|
/// <param name="input">The input color instance.</param>
|
||||
|
/// <returns>The converted result</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public Rgb Convert(in Cmyk input) |
||||
|
{ |
||||
|
Vector3 rgb = (Vector3.One - new Vector3(input.C, input.M, input.Y)) * (Vector3.One - new Vector3(input.K)); |
||||
|
return new Rgb(rgb); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Performs the conversion from the <see cref="Rgb"/> input to an instance of <see cref="Cmyk"/> type.
|
||||
|
/// </summary>
|
||||
|
/// <param name="input">The input color instance.</param>
|
||||
|
/// <returns>The converted result</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public Cmyk Convert(in Rgb input) |
||||
|
{ |
||||
|
// To CMY
|
||||
|
Vector3 cmy = Vector3.One - input.ToVector3(); |
||||
|
|
||||
|
// To CMYK
|
||||
|
var k = new Vector3(MathF.Min(cmy.X, MathF.Min(cmy.Y, cmy.Z))); |
||||
|
|
||||
|
if (MathF.Abs(k.X - 1F) < Constants.Epsilon) |
||||
|
{ |
||||
|
return new Cmyk(0, 0, 0, 1F); |
||||
|
} |
||||
|
|
||||
|
cmy = (cmy - k) / (Vector3.One - k); |
||||
|
|
||||
|
return new Cmyk(cmy.X, cmy.Y, cmy.Z, k.X); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System.Runtime.CompilerServices; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Color converter between <see cref="LinearRgb"/> and <see cref="Rgb"/>
|
||||
|
/// </summary>
|
||||
|
internal sealed class LinearRgbToRgbConverter |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Performs the conversion from the <see cref="LinearRgb"/> input to an instance of <see cref="Rgb"/> type.
|
||||
|
/// </summary>
|
||||
|
/// <param name="input">The input color instance.</param>
|
||||
|
/// <returns>The converted result</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public Rgb Convert(in LinearRgb input) |
||||
|
{ |
||||
|
var vector = input.ToVector3(); |
||||
|
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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System.Runtime.CompilerServices; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Color converter between Rgb and LinearRgb
|
||||
|
/// </summary>
|
||||
|
internal class RgbToLinearRgbConverter |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Performs the conversion from the <see cref="Rgb"/> input to an instance of <see cref="LinearRgb"/> type.
|
||||
|
/// </summary>
|
||||
|
/// <param name="input">The input color instance.</param>
|
||||
|
/// <returns>The converted result</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public LinearRgb Convert(in Rgb input) |
||||
|
{ |
||||
|
var vector = input.ToVector3(); |
||||
|
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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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 |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Implements gamma companding
|
|
||||
/// </summary>
|
|
||||
/// <remarks>
|
|
||||
/// <see href="http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html"/>
|
|
||||
/// <see href="http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_RGB.html"/>
|
|
||||
/// </remarks>
|
|
||||
internal class GammaCompanding : ICompanding |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="GammaCompanding"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="gamma">The gamma value.</param>
|
|
||||
public GammaCompanding(float gamma) |
|
||||
{ |
|
||||
this.Gamma = gamma; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the gamma value
|
|
||||
/// </summary>
|
|
||||
public float Gamma { get; } |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
public float Expand(float channel) |
|
||||
{ |
|
||||
return MathF.Pow(channel, this.Gamma); |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
public float Compress(float channel) |
|
||||
{ |
|
||||
return MathF.Pow(channel, 1 / this.Gamma); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -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 |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Implements L* companding
|
|
||||
/// </summary>
|
|
||||
/// <remarks>
|
|
||||
/// For more info see:
|
|
||||
/// <see href="http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html"/>
|
|
||||
/// <see href="http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_RGB.html"/>
|
|
||||
/// </remarks>
|
|
||||
internal class LCompanding : ICompanding |
|
||||
{ |
|
||||
/// <inheritdoc/>
|
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
public float Expand(float channel) |
|
||||
{ |
|
||||
return channel <= 0.08 ? 100 * channel / CieConstants.Kappa : MathF.Pow((channel + 0.16F) / 1.16F, 3); |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
[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; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,24 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System.Numerics; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSapce |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Color converter between LinearRgb and Rgb
|
|
||||
/// </summary>
|
|
||||
internal class LinearRgbToRgbConverter : IColorConversion<LinearRgb, Rgb> |
|
||||
{ |
|
||||
/// <inheritdoc/>
|
|
||||
public Rgb Convert(in LinearRgb 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); |
|
||||
|
|
||||
return new Rgb(vector, input.WorkingSpace); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -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 |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Implements Rec. 2020 companding function (for 12-bits).
|
|
||||
/// </summary>
|
|
||||
/// <remarks>
|
|
||||
/// <see href="http://en.wikipedia.org/wiki/Rec._2020"/>
|
|
||||
/// For 10-bits, companding is identical to <see cref="Rec709Companding"/>
|
|
||||
/// </remarks>
|
|
||||
internal class Rec2020Companding : ICompanding |
|
||||
{ |
|
||||
/// <inheritdoc/>
|
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
public float Expand(float channel) |
|
||||
{ |
|
||||
return channel < 0.08145F ? channel / 4.5F : MathF.Pow((channel + 0.0993F) / 1.0993F, 2.222222F); |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
public float Compress(float channel) |
|
||||
{ |
|
||||
return channel < 0.0181F ? 4500F * channel : (1.0993F * channel) - 0.0993F; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -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 |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Implements the Rec. 709 companding function
|
|
||||
/// </summary>
|
|
||||
/// <remarks>
|
|
||||
/// http://en.wikipedia.org/wiki/Rec._709
|
|
||||
/// </remarks>
|
|
||||
internal class Rec709Companding : ICompanding |
|
||||
{ |
|
||||
/// <inheritdoc/>
|
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
public float Expand(float channel) |
|
||||
{ |
|
||||
return channel < 0.081F ? channel / 4.5F : MathF.Pow((channel + 0.099F) / 1.099F, 2.222222F); |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
public float Compress(float channel) |
|
||||
{ |
|
||||
return channel < 0.018F ? 4500F * channel : (1.099F * channel) - 0.099F; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,24 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System.Numerics; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSapce |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Color converter between Rgb and LinearRgb
|
|
||||
/// </summary>
|
|
||||
internal class RgbToLinearRgbConverter : IColorConversion<Rgb, LinearRgb> |
|
||||
{ |
|
||||
/// <inheritdoc/>
|
|
||||
public LinearRgb Convert(in Rgb 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); |
|
||||
|
|
||||
return new LinearRgb(vector, input.WorkingSpace); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,98 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSapce |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Trivial implementation of <see cref="RgbWorkingSpace"/>
|
|
||||
/// </summary>
|
|
||||
internal class RgbWorkingSpace |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="RgbWorkingSpace"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="referenceWhite">The reference white point.</param>
|
|
||||
/// <param name="companding">The function pair for converting to <see cref="CieXyz"/> and back.</param>
|
|
||||
/// <param name="chromaticityCoordinates">The chromaticity of the rgb primaries.</param>
|
|
||||
public RgbWorkingSpace(CieXyz referenceWhite, ICompanding companding, RgbPrimariesChromaticityCoordinates chromaticityCoordinates) |
|
||||
{ |
|
||||
this.WhitePoint = referenceWhite; |
|
||||
this.Companding = companding; |
|
||||
this.ChromaticityCoordinates = chromaticityCoordinates; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the reference white point
|
|
||||
/// </summary>
|
|
||||
public CieXyz WhitePoint { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the function pair for converting to <see cref="CieXyz"/> and back.
|
|
||||
/// </summary>
|
|
||||
public ICompanding Companding { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the chromaticity of the rgb primaries.
|
|
||||
/// </summary>
|
|
||||
public RgbPrimariesChromaticityCoordinates ChromaticityCoordinates { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Compares two <see cref="RgbWorkingSpace"/> objects for equality.
|
|
||||
/// </summary>
|
|
||||
/// <param name="left">
|
|
||||
/// The <see cref="RgbWorkingSpace"/> on the left side of the operand.
|
|
||||
/// </param>
|
|
||||
/// <param name="right">
|
|
||||
/// The <see cref="RgbWorkingSpace"/> on the right side of the operand.
|
|
||||
/// </param>
|
|
||||
/// <returns>
|
|
||||
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
|
|
||||
/// </returns>
|
|
||||
public static bool operator ==(RgbWorkingSpace left, RgbWorkingSpace right) |
|
||||
{ |
|
||||
return Equals(left, right); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Compares two <see cref="RgbWorkingSpace"/> objects for inequality
|
|
||||
/// </summary>
|
|
||||
/// <param name="left">
|
|
||||
/// The <see cref="RgbWorkingSpace"/> on the left side of the operand.
|
|
||||
/// </param>
|
|
||||
/// <param name="right">
|
|
||||
/// The <see cref="RgbWorkingSpace"/> on the right side of the operand.
|
|
||||
/// </param>
|
|
||||
/// <returns>
|
|
||||
/// True if the current left is unequal to the <paramref name="right"/> parameter; otherwise, false.
|
|
||||
/// </returns>
|
|
||||
public static bool operator !=(RgbWorkingSpace left, RgbWorkingSpace right) |
|
||||
{ |
|
||||
return !Equals(left, right); |
|
||||
} |
|
||||
|
|
||||
public override bool Equals(object obj) |
|
||||
{ |
|
||||
return obj is RgbWorkingSpace other && this.Equals(other); |
|
||||
} |
|
||||
|
|
||||
public bool Equals(RgbWorkingSpace other) |
|
||||
{ |
|
||||
// TODO: Object.Equals for ICompanding will be slow.
|
|
||||
return this.WhitePoint.Equals(other.WhitePoint) |
|
||||
&& this.ChromaticityCoordinates.Equals(other.ChromaticityCoordinates) |
|
||||
&& Equals(this.Companding, other.Companding); |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
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; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -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 |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Implements sRGB companding
|
|
||||
/// </summary>
|
|
||||
/// <remarks>
|
|
||||
/// For more info see:
|
|
||||
/// <see href="http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html"/>
|
|
||||
/// <see href="http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_RGB.html"/>
|
|
||||
/// </remarks>
|
|
||||
internal class SRgbCompanding : ICompanding |
|
||||
{ |
|
||||
/// <inheritdoc/>
|
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
public float Expand(float channel) |
|
||||
{ |
|
||||
return channel <= 0.04045F ? channel / 12.92F : MathF.Pow((channel + 0.055F) / 1.055F, 2.4F); |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
public float Compress(float channel) |
|
||||
{ |
|
||||
return channel <= 0.0031308F ? 12.92F * channel : (1.055F * MathF.Pow(channel, 0.416666666666667F)) - 0.055F; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,36 @@ |
|||||
|
// 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 |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Implements gamma companding
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// <see href="http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html"/>
|
||||
|
/// <see href="http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_RGB.html"/>
|
||||
|
/// </remarks>
|
||||
|
public static class GammaCompanding |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Expands a companded channel to its linear equivalent with respect to the energy.
|
||||
|
/// </summary>
|
||||
|
/// <param name="channel">The channel value.</param>
|
||||
|
/// <param name="gamma">The gamma value.</param>
|
||||
|
/// <returns>The <see cref="float"/> representing the linear channel value.</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static float Expand(float channel, float gamma) => MathF.Pow(channel, gamma); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Compresses an uncompanded channel (linear) to its nonlinear equivalent.
|
||||
|
/// </summary>
|
||||
|
/// <param name="channel">The channel value.</param>
|
||||
|
/// <param name="gamma">The gamma value.</param>
|
||||
|
/// <returns>The <see cref="float"/> representing the nonlinear channel value.</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static float Compress(float channel, float gamma) => MathF.Pow(channel, 1 / gamma); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,65 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System.Runtime.CompilerServices; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The gamma working space.
|
||||
|
/// </summary>
|
||||
|
public class GammaWorkingSpace : RgbWorkingSpaceBase |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="GammaWorkingSpace" /> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="gamma">The gamma value.</param>
|
||||
|
/// <param name="referenceWhite">The reference white point.</param>
|
||||
|
/// <param name="chromaticityCoordinates">The chromaticity of the rgb primaries.</param>
|
||||
|
public GammaWorkingSpace(float gamma, CieXyz referenceWhite, RgbPrimariesChromaticityCoordinates chromaticityCoordinates) |
||||
|
: base(referenceWhite, chromaticityCoordinates) => this.Gamma = gamma; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the gamma value.
|
||||
|
/// </summary>
|
||||
|
public float Gamma { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public override float Compress(float channel) => GammaCompanding.Compress(channel, this.Gamma); |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public override float Expand(float channel) => GammaCompanding.Expand(channel, this.Gamma); |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override bool Equals(object obj) |
||||
|
{ |
||||
|
if (obj is null) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (ReferenceEquals(this, obj)) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
if (obj is GammaWorkingSpace other) |
||||
|
{ |
||||
|
return this.Gamma.Equals(other.Gamma) |
||||
|
&& this.WhitePoint.Equals(other.WhitePoint) |
||||
|
&& this.ChromaticityCoordinates.Equals(other.ChromaticityCoordinates); |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override int GetHashCode() |
||||
|
{ |
||||
|
int hash = base.GetHashCode(); |
||||
|
return HashHelpers.Combine(hash, this.Gamma.GetHashCode()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,37 @@ |
|||||
|
// 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 |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Implements L* companding
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// For more info see:
|
||||
|
/// <see href="http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html"/>
|
||||
|
/// <see href="http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_RGB.html"/>
|
||||
|
/// </remarks>
|
||||
|
public static class LCompanding |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Expands a companded channel to its linear equivalent with respect to the energy.
|
||||
|
/// </summary>
|
||||
|
/// <param name="channel">The channel value.</param>
|
||||
|
/// <returns>The <see cref="float"/> representing the linear channel value.</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static float Expand(float channel) |
||||
|
=> channel <= 0.08 ? 100 * channel / CieConstants.Kappa : ImageMaths.Pow3((channel + 0.16F) / 1.16F); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Compresses an uncompanded channel (linear) to its nonlinear equivalent.
|
||||
|
/// </summary>
|
||||
|
/// <param name="channel">The channel value</param>
|
||||
|
/// <returns>The <see cref="float"/> representing the nonlinear channel value.</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static float Compress(float channel) |
||||
|
=> channel <= CieConstants.Epsilon ? channel * CieConstants.Kappa / 100F : MathF.Pow(1.16F * channel, 0.3333333F) - 0.16F; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System.Runtime.CompilerServices; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// L* working space.
|
||||
|
/// </summary>
|
||||
|
public sealed class LWorkingSpace : RgbWorkingSpaceBase |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="LWorkingSpace" /> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="referenceWhite">The reference white point.</param>
|
||||
|
/// <param name="chromaticityCoordinates">The chromaticity of the rgb primaries.</param>
|
||||
|
public LWorkingSpace(CieXyz referenceWhite, RgbPrimariesChromaticityCoordinates chromaticityCoordinates) |
||||
|
: base(referenceWhite, chromaticityCoordinates) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public override float Compress(float channel) => LCompanding.Compress(channel); |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public override float Expand(float channel) => LCompanding.Expand(channel); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,36 @@ |
|||||
|
// 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 |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Implements Rec. 2020 companding function (for 12-bits).
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// <see href="http://en.wikipedia.org/wiki/Rec._2020"/>
|
||||
|
/// For 10-bits, companding is identical to <see cref="Rec709Companding"/>
|
||||
|
/// </remarks>
|
||||
|
public static class Rec2020Companding |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Expands a companded channel to its linear equivalent with respect to the energy.
|
||||
|
/// </summary>
|
||||
|
/// <param name="channel">The channel value.</param>
|
||||
|
/// <returns>The <see cref="float"/> representing the linear channel value.</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static float Expand(float channel) |
||||
|
=> channel < 0.08145F ? channel / 4.5F : MathF.Pow((channel + 0.0993F) / 1.0993F, 2.222222F); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Compresses an uncompanded channel (linear) to its nonlinear equivalent.
|
||||
|
/// </summary>
|
||||
|
/// <param name="channel">The channel value.</param>
|
||||
|
/// <returns>The <see cref="float"/> representing the nonlinear channel value.</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static float Compress(float channel) |
||||
|
=> channel < 0.0181F ? 4500F * channel : (1.0993F * channel) - 0.0993F; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System.Runtime.CompilerServices; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Rec. 2020 (ITU-R Recommendation BT.2020F) working space.
|
||||
|
/// </summary>
|
||||
|
public sealed class Rec2020WorkingSpace : RgbWorkingSpaceBase |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Rec2020WorkingSpace" /> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="referenceWhite">The reference white point.</param>
|
||||
|
/// <param name="chromaticityCoordinates">The chromaticity of the rgb primaries.</param>
|
||||
|
public Rec2020WorkingSpace(CieXyz referenceWhite, RgbPrimariesChromaticityCoordinates chromaticityCoordinates) |
||||
|
: base(referenceWhite, chromaticityCoordinates) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public override float Compress(float channel) => Rec2020Companding.Compress(channel); |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public override float Expand(float channel) => Rec2020Companding.Expand(channel); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
// 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 |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Implements the Rec. 709 companding function.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// http://en.wikipedia.org/wiki/Rec._709
|
||||
|
/// </remarks>
|
||||
|
public static class Rec709Companding |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Expands a companded channel to its linear equivalent with respect to the energy.
|
||||
|
/// </summary>
|
||||
|
/// <param name="channel">The channel value.</param>
|
||||
|
/// <returns>The <see cref="float"/> representing the linear channel value.</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static float Expand(float channel) |
||||
|
=> channel < 0.081F ? channel / 4.5F : MathF.Pow((channel + 0.099F) / 1.099F, 2.222222F); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Compresses an uncompanded channel (linear) to its nonlinear equivalent.
|
||||
|
/// </summary>
|
||||
|
/// <param name="channel">The channel value.</param>
|
||||
|
/// <returns>The <see cref="float"/> representing the nonlinear channel value.</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static float Compress(float channel) |
||||
|
=> channel < 0.018F ? 4500F * channel : (1.099F * channel) - 0.099F; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System.Runtime.CompilerServices; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Rec. 709 (ITU-R Recommendation BT.709) working space.
|
||||
|
/// </summary>
|
||||
|
public sealed class Rec709WorkingSpace : RgbWorkingSpaceBase |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Rec709WorkingSpace" /> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="referenceWhite">The reference white point.</param>
|
||||
|
/// <param name="chromaticityCoordinates">The chromaticity of the rgb primaries.</param>
|
||||
|
public Rec709WorkingSpace(CieXyz referenceWhite, RgbPrimariesChromaticityCoordinates chromaticityCoordinates) |
||||
|
: base(referenceWhite, chromaticityCoordinates) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public override float Compress(float channel) => Rec709Companding.Compress(channel); |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public override float Expand(float channel) => Rec709Companding.Expand(channel); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,83 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Base class for all implementations of <see cref="RgbWorkingSpaceBase"/>.
|
||||
|
/// </summary>
|
||||
|
public abstract class RgbWorkingSpaceBase |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="RgbWorkingSpaceBase"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="referenceWhite">The reference white point.</param>
|
||||
|
/// <param name="chromaticityCoordinates">The chromaticity of the rgb primaries.</param>
|
||||
|
protected RgbWorkingSpaceBase(CieXyz referenceWhite, RgbPrimariesChromaticityCoordinates chromaticityCoordinates) |
||||
|
{ |
||||
|
this.WhitePoint = referenceWhite; |
||||
|
this.ChromaticityCoordinates = chromaticityCoordinates; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the reference white point
|
||||
|
/// </summary>
|
||||
|
public CieXyz WhitePoint { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the chromaticity of the rgb primaries.
|
||||
|
/// </summary>
|
||||
|
public RgbPrimariesChromaticityCoordinates ChromaticityCoordinates { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Expands a companded channel to its linear equivalent with respect to the energy.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// For more info see:
|
||||
|
/// <see href="http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html"/>
|
||||
|
/// </remarks>
|
||||
|
/// <param name="channel">The channel value.</param>
|
||||
|
/// <returns>The <see cref="float"/> representing the linear channel value.</returns>
|
||||
|
public abstract float Expand(float channel); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Compresses an uncompanded channel (linear) to its nonlinear equivalent (depends on the RGB color system).
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// For more info see:
|
||||
|
/// <see href="http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_RGB.html"/>
|
||||
|
/// </remarks>
|
||||
|
/// <param name="channel">The channel value.</param>
|
||||
|
/// <returns>The <see cref="float"/> representing the nonlinear channel value.</returns>
|
||||
|
public abstract float Compress(float channel); |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override bool Equals(object obj) |
||||
|
{ |
||||
|
if (obj is null) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (ReferenceEquals(this, obj)) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
if (obj is RgbWorkingSpaceBase other) |
||||
|
{ |
||||
|
return this.WhitePoint.Equals(other.WhitePoint) |
||||
|
&& this.ChromaticityCoordinates.Equals(other.ChromaticityCoordinates); |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override int GetHashCode() |
||||
|
{ |
||||
|
int hash = this.WhitePoint.GetHashCode(); |
||||
|
return HashHelpers.Combine(hash, this.ChromaticityCoordinates.GetHashCode()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
// 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 |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Implements sRGB companding
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// For more info see:
|
||||
|
/// <see href="http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html"/>
|
||||
|
/// <see href="http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_RGB.html"/>
|
||||
|
/// </remarks>
|
||||
|
public static class SRgbCompanding |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Expands a companded channel to its linear equivalent with respect to the energy.
|
||||
|
/// </summary>
|
||||
|
/// <param name="channel">The channel value</param>
|
||||
|
/// <returns>The <see cref="float"/> representing the linear channel value.</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static float Expand(float channel) => channel <= 0.04045F ? channel / 12.92F : MathF.Pow((channel + 0.055F) / 1.055F, 2.4F); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Compresses an uncompanded channel (linear) to its nonlinear equivalent.
|
||||
|
/// </summary>
|
||||
|
/// <param name="channel">The channel value</param>
|
||||
|
/// <returns>The <see cref="float"/> representing the nonlinear channel value.</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static float Compress(float channel) => channel <= 0.0031308F ? 12.92F * channel : (1.055F * MathF.Pow(channel, 0.416666666666667F)) - 0.055F; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System.Runtime.CompilerServices; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The sRgb working space.
|
||||
|
/// </summary>
|
||||
|
public sealed class SRgbWorkingSpace : RgbWorkingSpaceBase |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="SRgbWorkingSpace" /> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="referenceWhite">The reference white point.</param>
|
||||
|
/// <param name="chromaticityCoordinates">The chromaticity of the rgb primaries.</param>
|
||||
|
public SRgbWorkingSpace(CieXyz referenceWhite, RgbPrimariesChromaticityCoordinates chromaticityCoordinates) |
||||
|
: base(referenceWhite, chromaticityCoordinates) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public override float Compress(float channel) => SRgbCompanding.Compress(channel); |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public override float Expand(float channel) => SRgbCompanding.Expand(channel); |
||||
|
} |
||||
|
} |
||||
@ -1,28 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.ColorSpaces |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Defines a generalized method that a value type or class implements to create
|
|
||||
/// a type-specific method for determining approximate equality of instances.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of objects to compare.</typeparam>
|
|
||||
/// <typeparam name="TPrecision">The object specifying the type to specify precision with.</typeparam>
|
|
||||
internal interface IAlmostEquatable<in TPixel, in TPrecision> |
|
||||
where TPrecision : struct, IComparable<TPrecision> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Indicates whether the current object is equal to another object of the same type
|
|
||||
/// when compared to the specified precision level.
|
|
||||
/// </summary>
|
|
||||
/// <param name="other">An object to compare with this object.</param>
|
|
||||
/// <param name="precision">The object specifying the level of precision.</param>
|
|
||||
/// <returns>
|
|
||||
/// true if the current object is equal to the other parameter; otherwise, false.
|
|
||||
/// </returns>
|
|
||||
bool AlmostEquals(TPixel other, TPrecision precision); |
|
||||
} |
|
||||
} |
|
||||
@ -1,18 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System.Numerics; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.ColorSpaces |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Color represented as a vector in its color space
|
|
||||
/// </summary>
|
|
||||
internal interface IColorVector |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Gets the vector representation of the color
|
|
||||
/// </summary>
|
|
||||
Vector3 Vector { get; } |
|
||||
} |
|
||||
} |
|
||||
@ -1,37 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation.RgbColorSapce; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.ColorSpaces |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Pair of companding functions for <see cref="RgbWorkingSpace"/>.
|
|
||||
/// Used for conversion to <see cref="CieXyz"/> and backwards.
|
|
||||
/// See also: <seealso cref="RgbWorkingSpace.Companding"/>
|
|
||||
/// </summary>
|
|
||||
internal interface ICompanding |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Expands a companded channel to its linear equivalent with respect to the energy.
|
|
||||
/// </summary>
|
|
||||
/// <remarks>
|
|
||||
/// For more info see:
|
|
||||
/// <see href="http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html"/>
|
|
||||
/// </remarks>
|
|
||||
/// <param name="channel">The channel value</param>
|
|
||||
/// <returns>The linear channel value</returns>
|
|
||||
float Expand(float channel); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Compresses an uncompanded channel (linear) to its nonlinear equivalent (depends on the RGB color system).
|
|
||||
/// </summary>
|
|
||||
/// <remarks>
|
|
||||
/// For more info see:
|
|
||||
/// <see href="http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_RGB.html"/>
|
|
||||
/// </remarks>
|
|
||||
/// <param name="channel">The channel value</param>
|
|
||||
/// <returns>The nonlinear channel value</returns>
|
|
||||
float Compress(float channel); |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,40 @@ |
|||||
|
using System; |
||||
|
using BenchmarkDotNet.Attributes; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Benchmarks.General |
||||
|
{ |
||||
|
public class Pow |
||||
|
{ |
||||
|
[Params(-1.333F, 1.333F)] |
||||
|
public float X { get; set; } |
||||
|
|
||||
|
|
||||
|
[Benchmark(Baseline = true, Description = "Math.Pow 2")] |
||||
|
public float MathPow() |
||||
|
{ |
||||
|
float x = this.X; |
||||
|
return (float)Math.Pow(x, 2); |
||||
|
} |
||||
|
|
||||
|
[Benchmark(Description = "Pow x2")] |
||||
|
public float PowMult() |
||||
|
{ |
||||
|
float x = this.X; |
||||
|
return x * x; |
||||
|
} |
||||
|
|
||||
|
[Benchmark(Description = "Math.Pow 3")] |
||||
|
public float MathPow3() |
||||
|
{ |
||||
|
float x = this.X; |
||||
|
return (float)Math.Pow(x, 3); |
||||
|
} |
||||
|
|
||||
|
[Benchmark(Description = "Pow x3")] |
||||
|
public float PowMult3() |
||||
|
{ |
||||
|
float x = this.X; |
||||
|
return x * x * x; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System.Numerics; |
||||
|
using SixLabors.ImageSharp.ColorSpaces; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Tests.Colorspaces |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Tests the <see cref="CieLab"/> struct.
|
||||
|
/// </summary>
|
||||
|
public class CieLabTests |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void CieLabConstructorAssignsFields() |
||||
|
{ |
||||
|
const float l = 75F; |
||||
|
const float a = -64F; |
||||
|
const float b = 87F; |
||||
|
var cieLab = new CieLab(l, a, b); |
||||
|
|
||||
|
Assert.Equal(l, cieLab.L); |
||||
|
Assert.Equal(a, cieLab.A); |
||||
|
Assert.Equal(b, cieLab.B); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void CieLabEquality() |
||||
|
{ |
||||
|
var x = default(CieLab); |
||||
|
var y = new CieLab(Vector3.One); |
||||
|
|
||||
|
Assert.True(default(CieLab) == default(CieLab)); |
||||
|
Assert.True(default(CieLab) != new CieLab(1, 0, 1)); |
||||
|
Assert.False(default(CieLab) == new CieLab(1, 0, 1)); |
||||
|
Assert.Equal(default(CieLab), default(CieLab)); |
||||
|
Assert.Equal(new CieLab(1, 0, 1), new CieLab(1, 0, 1)); |
||||
|
Assert.Equal(new CieLab(Vector3.One), new CieLab(Vector3.One)); |
||||
|
Assert.False(x.Equals(y)); |
||||
|
Assert.False(default(CieLab) == new CieLab(1, 0, 1)); |
||||
|
Assert.False(x.Equals((object)y)); |
||||
|
Assert.False(x.GetHashCode().Equals(y.GetHashCode())); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,44 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System.Numerics; |
||||
|
using SixLabors.ImageSharp.ColorSpaces; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Tests.Colorspaces |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Tests the <see cref="CieLch"/> struct.
|
||||
|
/// </summary>
|
||||
|
public class CieLchTests |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void CieLchConstructorAssignsFields() |
||||
|
{ |
||||
|
const float l = 75F; |
||||
|
const float c = 64F; |
||||
|
const float h = 287F; |
||||
|
var cieLch = new CieLch(l, c, h); |
||||
|
|
||||
|
Assert.Equal(l, cieLch.L); |
||||
|
Assert.Equal(c, cieLch.C); |
||||
|
Assert.Equal(h, cieLch.H); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void CieLchEquality() |
||||
|
{ |
||||
|
var x = default(CieLch); |
||||
|
var y = new CieLch(Vector3.One); |
||||
|
|
||||
|
Assert.True(default(CieLch) == default(CieLch)); |
||||
|
Assert.False(default(CieLch) != default(CieLch)); |
||||
|
Assert.Equal(default(CieLch), default(CieLch)); |
||||
|
Assert.Equal(new CieLch(1, 0, 1), new CieLch(1, 0, 1)); |
||||
|
Assert.Equal(new CieLch(Vector3.One), new CieLch(Vector3.One)); |
||||
|
Assert.False(x.Equals(y)); |
||||
|
Assert.False(x.Equals((object)y)); |
||||
|
Assert.False(x.GetHashCode().Equals(y.GetHashCode())); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,44 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System.Numerics; |
||||
|
using SixLabors.ImageSharp.ColorSpaces; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Tests.Colorspaces |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Tests the <see cref="CieLchuv"/> struct.
|
||||
|
/// </summary>
|
||||
|
public class CieLchuvTests |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void CieLchuvConstructorAssignsFields() |
||||
|
{ |
||||
|
const float l = 75F; |
||||
|
const float c = 64F; |
||||
|
const float h = 287F; |
||||
|
var cieLchuv = new CieLchuv(l, c, h); |
||||
|
|
||||
|
Assert.Equal(l, cieLchuv.L); |
||||
|
Assert.Equal(c, cieLchuv.C); |
||||
|
Assert.Equal(h, cieLchuv.H); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void CieLchuvEquality() |
||||
|
{ |
||||
|
var x = default(CieLchuv); |
||||
|
var y = new CieLchuv(Vector3.One); |
||||
|
|
||||
|
Assert.True(default(CieLchuv) == default(CieLchuv)); |
||||
|
Assert.False(default(CieLchuv) != default(CieLchuv)); |
||||
|
Assert.Equal(default(CieLchuv), default(CieLchuv)); |
||||
|
Assert.Equal(new CieLchuv(1, 0, 1), new CieLchuv(1, 0, 1)); |
||||
|
Assert.Equal(new CieLchuv(Vector3.One), new CieLchuv(Vector3.One)); |
||||
|
Assert.False(x.Equals(y)); |
||||
|
Assert.False(x.Equals((object)y)); |
||||
|
Assert.False(x.GetHashCode().Equals(y.GetHashCode())); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue