Browse Source

Remove duplicate Adaption checks and reduce allocations.

af/merge-core
James Jackson-South 7 years ago
parent
commit
09be4d225c
  1. 65
      src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Adapt.cs
  2. 9
      src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLab.cs
  3. 2
      src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLch.cs
  4. 2
      src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLchuv.cs
  5. 12
      src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLuv.cs
  6. 22
      src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyz.cs
  7. 7
      src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.HunterLab.cs
  8. 24
      src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.LinearRgb.cs
  9. 21
      src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.cs

65
src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Adapt.cs

@ -1,7 +1,6 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation;
namespace SixLabors.ImageSharp.ColorSpaces.Conversion
@ -16,12 +15,26 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
/// Target white point is <see cref="ColorSpaceConverterOptions.WhitePoint"/>.
/// </summary>
/// <param name="color">The color to adapt</param>
/// <param name="sourceWhitePoint">The white point to adapt for</param>
/// <param name="sourceWhitePoint">The source white point.</param>
/// <returns>The adapted color</returns>
public CieXyz Adapt(in CieXyz color, in CieXyz sourceWhitePoint)
public CieXyz Adapt(in CieXyz color, in CieXyz sourceWhitePoint) => this.Adapt(color, sourceWhitePoint, this.whitePoint);
/// <summary>
/// Performs chromatic adaptation of given <see cref="CieXyz"/> color.
/// Target white point is <see cref="ColorSpaceConverterOptions.WhitePoint"/>.
/// </summary>
/// <param name="color">The color to adapt</param>
/// <param name="sourceWhitePoint">The source white point.</param>
/// <param name="targetWhitePoint">The target white point.</param>
/// <returns>The adapted color</returns>
public CieXyz Adapt(in CieXyz color, in CieXyz sourceWhitePoint, in CieXyz targetWhitePoint)
{
this.CheckChromaticAdaptation();
return this.chromaticAdaptation.Transform(color, sourceWhitePoint, this.whitePoint);
if (!this.performChromaticAdaptation || sourceWhitePoint.Equals(targetWhitePoint))
{
return color;
}
return this.chromaticAdaptation.Transform(color, sourceWhitePoint, targetWhitePoint);
}
/// <summary>
@ -31,9 +44,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
/// <returns>The adapted color</returns>
public CieLab Adapt(in CieLab color)
{
this.CheckChromaticAdaptation();
if (color.WhitePoint.Equals(this.targetLabWhitePoint))
if (!this.performChromaticAdaptation || color.WhitePoint.Equals(this.targetLabWhitePoint))
{
return color;
}
@ -49,9 +60,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
/// <returns>The adapted color</returns>
public CieLch Adapt(in CieLch color)
{
this.CheckChromaticAdaptation();
if (color.WhitePoint.Equals(this.targetLabWhitePoint))
if (!this.performChromaticAdaptation || color.WhitePoint.Equals(this.targetLabWhitePoint))
{
return color;
}
@ -67,9 +76,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
/// <returns>The adapted color</returns>
public CieLchuv Adapt(in CieLchuv color)
{
this.CheckChromaticAdaptation();
if (color.WhitePoint.Equals(this.targetLabWhitePoint))
if (!this.performChromaticAdaptation || color.WhitePoint.Equals(this.targetLabWhitePoint))
{
return color;
}
@ -85,9 +92,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
/// <returns>The adapted color</returns>
public CieLuv Adapt(in CieLuv color)
{
this.CheckChromaticAdaptation();
if (color.WhitePoint.Equals(this.targetLuvWhitePoint))
if (!this.performChromaticAdaptation || color.WhitePoint.Equals(this.targetLuvWhitePoint))
{
return color;
}
@ -103,9 +108,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
/// <returns>The adapted color</returns>
public HunterLab Adapt(in HunterLab color)
{
this.CheckChromaticAdaptation();
if (color.WhitePoint.Equals(this.targetHunterLabWhitePoint))
if (!this.performChromaticAdaptation || color.WhitePoint.Equals(this.targetHunterLabWhitePoint))
{
return color;
}
@ -121,9 +124,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
/// <returns>The adapted color</returns>
public LinearRgb Adapt(in LinearRgb color)
{
this.CheckChromaticAdaptation();
if (color.WorkingSpace.Equals(this.targetRgbWorkingSpace))
if (!this.performChromaticAdaptation || color.WorkingSpace.Equals(this.targetRgbWorkingSpace))
{
return color;
}
@ -136,8 +137,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
CieXyz adapted = this.chromaticAdaptation.Transform(unadapted, color.WorkingSpace.WhitePoint, this.targetRgbWorkingSpace.WhitePoint);
// Conversion back to RGB
CieXyzToLinearRgbConverter converterToRGB = this.GetCieXyxToLinearRgbConverter(this.targetRgbWorkingSpace);
return converterToRGB.Convert(adapted);
return this.cieXyzToLinearRgbConverter.Convert(adapted);
}
/// <summary>
@ -147,19 +147,14 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
/// <returns>The adapted color</returns>
public Rgb Adapt(in Rgb color)
{
var linearInput = this.ToLinearRgb(color);
LinearRgb linearOutput = this.Adapt(linearInput);
return this.ToRgb(linearOutput);
}
private void CheckChromaticAdaptation()
{
const string NoAdapterMessage = "Cannot perform chromatic adaptation, provide a chromatic adaptation method and white point.";
if (!this.performChromaticAdaptation)
{
throw new InvalidOperationException(NoAdapterMessage);
return color;
}
var linearInput = this.ToLinearRgb(color);
LinearRgb linearOutput = this.Adapt(linearInput);
return this.ToRgb(linearOutput);
}
}
}

9
src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLab.cs

@ -28,11 +28,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
// Conversion (perserving white point)
CieLab unadapted = CieLchToCieLabConverter.Convert(color);
if (!this.performChromaticAdaptation)
{
return unadapted;
}
// Adaptation
return this.Adapt(unadapted);
}
@ -165,9 +160,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
public CieLab ToCieLab(in CieXyz color)
{
// Adaptation
CieXyz adapted = this.performLabChromaticAdaptation
? this.chromaticAdaptation.Transform(color, this.whitePoint, this.targetLabWhitePoint)
: color;
CieXyz adapted = this.Adapt(color, this.whitePoint, this.targetLabWhitePoint);
// Conversion
return this.cieXyzToCieLabConverter.Convert(adapted);

2
src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLch.cs

@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
public CieLch ToCieLch(in CieLab color)
{
// Adaptation
CieLab adapted = this.performChromaticAdaptation ? this.Adapt(color) : color;
CieLab adapted = this.Adapt(color);
// Conversion
return CieLabToCieLchConverter.Convert(adapted);

2
src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLchuv.cs

@ -92,7 +92,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
public CieLchuv ToCieLchuv(in CieLuv color)
{
// Adaptation
CieLuv adapted = this.performChromaticAdaptation ? this.Adapt(color) : color;
CieLuv adapted = this.Adapt(color);
// Conversion
return CieLuvToCieLchuvConverter.Convert(adapted);

12
src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLuv.cs

@ -89,11 +89,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
// Conversion (perserving white point)
CieLuv unadapted = CieLchuvToCieLuvConverter.Convert(color);
if (!this.performChromaticAdaptation)
{
return unadapted;
}
// Adaptation
return this.Adapt(unadapted);
}
@ -159,13 +154,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
public CieLuv ToCieLuv(in CieXyz color)
{
// Adaptation
CieXyz adapted = !this.whitePoint.Equals(this.targetLabWhitePoint) && this.performChromaticAdaptation
? this.chromaticAdaptation.Transform(color, this.whitePoint, this.targetLabWhitePoint)
: color;
CieXyz adapted = this.Adapt(color, this.whitePoint, this.targetLabWhitePoint);
// Conversion
var converter = new CieXyzToCieLuvConverter(this.targetLuvWhitePoint);
return converter.Convert(adapted);
return this.cieXyzToCieLuvConverter.Convert(adapted);
}
/// <summary>

22
src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyz.cs

@ -32,11 +32,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
CieXyz unadapted = CieLabToCieXyzConverter.Convert(color);
// Adaptation
CieXyz adapted = color.WhitePoint.Equals(this.whitePoint) || !this.performChromaticAdaptation
? unadapted
: this.Adapt(unadapted, color.WhitePoint);
return adapted;
return this.Adapt(unadapted, color.WhitePoint);
}
/// <summary>
@ -141,11 +137,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
CieXyz unadapted = CieLuvToCieXyzConverter.Convert(color);
// Adaptation
CieXyz adapted = color.WhitePoint.Equals(this.whitePoint) || !this.performChromaticAdaptation
? unadapted
: this.Adapt(unadapted, color.WhitePoint);
return adapted;
return this.Adapt(unadapted, color.WhitePoint);
}
/// <summary>
@ -314,11 +306,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
CieXyz unadapted = HunterLabToCieXyzConverter.Convert(color);
// Adaptation
CieXyz adapted = color.WhitePoint.Equals(this.whitePoint) || !this.performChromaticAdaptation
? unadapted
: this.Adapt(unadapted, color.WhitePoint);
return adapted;
return this.Adapt(unadapted, color.WhitePoint);
}
/// <summary>
@ -354,9 +342,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
CieXyz unadapted = converter.Convert(color);
// Adaptation
return color.WorkingSpace.WhitePoint.Equals(this.whitePoint) || !this.performChromaticAdaptation
? unadapted
: this.Adapt(unadapted, color.WorkingSpace.WhitePoint);
return this.Adapt(unadapted, color.WorkingSpace.WhitePoint);
}
/// <summary>

7
src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.HunterLab.cs

@ -4,7 +4,6 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation;
namespace SixLabors.ImageSharp.ColorSpaces.Conversion
{
@ -181,12 +180,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
public HunterLab ToHunterLab(in CieXyz color)
{
// Adaptation
CieXyz adapted = !this.whitePoint.Equals(this.targetHunterLabWhitePoint) && this.performChromaticAdaptation
? this.chromaticAdaptation.Transform(color, this.whitePoint, this.targetHunterLabWhitePoint)
: color;
CieXyz adapted = this.Adapt(color, this.whitePoint, this.targetHunterLabWhitePoint);
// Conversion
return new CieXyzToHunterLabConverter(this.targetHunterLabWhitePoint).Convert(adapted);
return this.cieXyzToHunterLabConverter.Convert(adapted);
}
/// <summary>

24
src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.LinearRgb.cs

@ -15,8 +15,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
{
private static readonly RgbToLinearRgbConverter RgbToLinearRgbConverter = new RgbToLinearRgbConverter();
private CieXyzToLinearRgbConverter cieXyzToLinearRgbConverter;
/// <summary>
/// Converts a <see cref="CieLab"/> into a <see cref="LinearRgb"/>
/// </summary>
@ -185,13 +183,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
public LinearRgb ToLinearRgb(in CieXyz color)
{
// Adaptation
CieXyz adapted = this.targetRgbWorkingSpace.WhitePoint.Equals(this.whitePoint) || !this.performChromaticAdaptation
? color
: this.chromaticAdaptation.Transform(color, this.whitePoint, this.targetRgbWorkingSpace.WhitePoint);
CieXyz adapted = this.Adapt(color, this.whitePoint, this.targetRgbWorkingSpace.WhitePoint);
// Conversion
CieXyzToLinearRgbConverter xyzConverter = this.GetCieXyxToLinearRgbConverter(this.targetRgbWorkingSpace);
return xyzConverter.Convert(adapted);
return this.cieXyzToLinearRgbConverter.Convert(adapted);
}
/// <summary>
@ -438,20 +433,5 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
dp = this.ToLinearRgb(sp);
}
}
/// <summary>
/// Gets the correct converter for the given rgb working space.
/// </summary>
/// <param name="workingSpace">The target working space</param>
/// <returns>The <see cref="CieXyzToLinearRgbConverter"/></returns>
private CieXyzToLinearRgbConverter GetCieXyxToLinearRgbConverter(RgbWorkingSpace workingSpace)
{
if (this.cieXyzToLinearRgbConverter != null && this.cieXyzToLinearRgbConverter.TargetWorkingSpace.Equals(workingSpace))
{
return this.cieXyzToLinearRgbConverter;
}
return this.cieXyzToLinearRgbConverter = new CieXyzToLinearRgbConverter(workingSpace);
}
}
}

21
src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.cs

@ -12,18 +12,19 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
public partial class ColorSpaceConverter
{
// Options.
private Matrix4x4 lmsAdaptationMatrix;
private CieXyz whitePoint;
private CieXyz targetLuvWhitePoint;
private CieXyz targetLabWhitePoint;
private CieXyz targetHunterLabWhitePoint;
private RgbWorkingSpace targetRgbWorkingSpace;
private IChromaticAdaptation chromaticAdaptation;
private bool performChromaticAdaptation;
private bool performLabChromaticAdaptation;
private Matrix4x4 lmsAdaptationMatrix;
private CieXyzAndLmsConverter cieXyzAndLmsConverter;
private CieXyzToCieLabConverter cieXyzToCieLabConverter;
private readonly RgbWorkingSpace targetRgbWorkingSpace;
private readonly IChromaticAdaptation chromaticAdaptation;
private readonly bool performChromaticAdaptation;
private readonly CieXyzAndLmsConverter cieXyzAndLmsConverter;
private readonly CieXyzToCieLabConverter cieXyzToCieLabConverter;
private readonly CieXyzToCieLuvConverter cieXyzToCieLuvConverter;
private readonly CieXyzToHunterLabConverter cieXyzToHunterLabConverter;
private readonly CieXyzToLinearRgbConverter cieXyzToLinearRgbConverter;
/// <summary>
/// Initializes a new instance of the <see cref="ColorSpaceConverter"/> class.
@ -47,11 +48,13 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
this.targetRgbWorkingSpace = options.TargetRgbWorkingSpace;
this.chromaticAdaptation = options.ChromaticAdaptation;
this.performChromaticAdaptation = this.chromaticAdaptation != null;
this.performLabChromaticAdaptation = !this.whitePoint.Equals(this.targetLabWhitePoint) && this.performChromaticAdaptation;
this.lmsAdaptationMatrix = options.LmsAdaptationMatrix;
this.cieXyzAndLmsConverter = new CieXyzAndLmsConverter(this.lmsAdaptationMatrix);
this.cieXyzToCieLabConverter = new CieXyzToCieLabConverter(this.targetLabWhitePoint);
this.cieXyzToCieLuvConverter = new CieXyzToCieLuvConverter(this.targetLuvWhitePoint);
this.cieXyzToHunterLabConverter = new CieXyzToHunterLabConverter(this.targetHunterLabWhitePoint);
this.cieXyzToLinearRgbConverter = new CieXyzToLinearRgbConverter(this.targetRgbWorkingSpace);
}
}
}
Loading…
Cancel
Save