Browse Source

Fix build

pull/1567/head
James Jackson-South 3 years ago
parent
commit
dc166a7804
  1. 146
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/ClutCalculator.cs
  2. 75
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/ColorTrcCalculator.cs
  3. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/CurveCalculator.CalculationType.cs
  4. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/CurveCalculator.cs
  5. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/GrayTrcCalculator.cs
  6. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/ISingleCalculator.cs
  7. 4
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/IVector4Calculator.cs
  8. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/LutABCalculator.CalculationType.cs
  9. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/LutABCalculator.cs
  10. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/LutCalculator.cs
  11. 10
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/LutEntryCalculator.cs
  12. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/MatrixCalculator.cs
  13. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/ParametricCurveCalculator.cs
  14. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/TrcCalculator.cs
  15. 244
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccConverterBase.Checks.cs
  16. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccConverterBase.ConversionMethod.cs
  17. 62
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccConverterbase.Conversions.cs
  18. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccConverterbase.cs
  19. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccDataToDataConverter.cs
  20. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccDataToPcsConverter.cs
  21. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccPcsToDataConverter.cs
  22. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccPcsToPcsConverter.cs
  23. 30
      tests/ImageSharp.Tests/Colorspaces/Icc/Calculators/ClutCalculatorTests.cs

146
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/ClutCalculator.cs

@ -1,104 +1,102 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using System;
using System.Numerics;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc;
internal class ClutCalculator : IVector4Calculator
{
internal class ClutCalculator : IVector4Calculator
private readonly int inputCount;
private readonly int outputCount;
private readonly float[][] lut;
private readonly byte[] gridPointCount;
private readonly int[] indexFactor;
private readonly int nodeCount;
public ClutCalculator(IccClut clut)
{
private int inputCount;
private int outputCount;
private float[][] lut;
private byte[] gridPointCount;
private int[] indexFactor;
private int nodeCount;
public ClutCalculator(IccClut clut)
{
Guard.NotNull(clut, nameof(clut));
this.inputCount = clut.InputChannelCount;
this.outputCount = clut.OutputChannelCount;
this.lut = clut.Values;
this.gridPointCount = clut.GridPointCount;
this.indexFactor = this.CalculateIndexFactor(clut.InputChannelCount, clut.GridPointCount);
this.nodeCount = (int)Math.Pow(2, clut.InputChannelCount);
}
Guard.NotNull(clut, nameof(clut));
this.inputCount = clut.InputChannelCount;
this.outputCount = clut.OutputChannelCount;
this.lut = clut.Values;
this.gridPointCount = clut.GridPointCount;
this.indexFactor = CalculateIndexFactor(clut.InputChannelCount, clut.GridPointCount);
this.nodeCount = (int)Math.Pow(2, clut.InputChannelCount);
}
public unsafe Vector4 Calculate(Vector4 value)
{
value = Vector4.Clamp(value, Vector4.Zero, Vector4.One);
public unsafe Vector4 Calculate(Vector4 value)
{
value = Vector4.Clamp(value, Vector4.Zero, Vector4.One);
Vector4 result = default;
this.Interpolate((float*)&value, this.inputCount, (float*)&result, this.outputCount);
Vector4 result = default;
this.Interpolate((float*)&value, this.inputCount, (float*)&result, this.outputCount);
return result;
return result;
}
private static int[] CalculateIndexFactor(int inputCount, byte[] gridPointCount)
{
int[] factors = new int[inputCount];
int gpc = 1;
for (int j = inputCount - 1; j >= 0; j--)
{
factors[j] = gpc * (gridPointCount[j] - 1);
gpc *= gridPointCount[j];
}
private int[] CalculateIndexFactor(int inputCount, byte[] gridPointCount)
return factors;
}
private unsafe void Interpolate(float* values, int valueLength, float* result, int resultLength)
{
float[][] nodes = new float[this.nodeCount][];
for (int i = 0; i < nodes.Length; i++)
{
int[] factors = new int[inputCount];
int gpc = 1;
for (int j = inputCount - 1; j >= 0; j--)
int index = 0;
for (int j = 0; j < valueLength; j++)
{
factors[j] = gpc * (gridPointCount[j] - 1);
gpc *= gridPointCount[j];
float fraction = 1f / (this.gridPointCount[j] - 1);
int position = (int)(values[j] / fraction) + ((i >> j) & 1);
index += (int)((this.indexFactor[j] * (position * fraction)) + 0.5f);
}
return factors;
nodes[i] = this.lut[index];
}
private unsafe void Interpolate(float* values, int valueLength, float* result, int resultLength)
Span<float> factors = stackalloc float[this.nodeCount];
for (int i = 0; i < factors.Length; i++)
{
float[][] nodes = new float[this.nodeCount][];
for (int i = 0; i < nodes.Length; i++)
float factor = 1;
for (int j = 0; j < valueLength; j++)
{
int index = 0;
for (int j = 0; j < valueLength; j++)
{
float fraction = 1f / (this.gridPointCount[j] - 1);
int position = (int)(values[j] / fraction) + ((i >> j) & 1);
index += (int)((this.indexFactor[j] * (position * fraction)) + 0.5f);
}
float fraction = 1f / (this.gridPointCount[j] - 1);
int position = (int)(values[j] / fraction);
nodes[i] = this.lut[index];
}
float low = position * fraction;
float high = (position + 1) * fraction;
float percentage = (high - values[j]) / (high - low);
Span<float> factors = stackalloc float[this.nodeCount];
for (int i = 0; i < factors.Length; i++)
{
float factor = 1;
for (int j = 0; j < valueLength; j++)
if (((i >> j) & 1) == 1)
{
float fraction = 1f / (this.gridPointCount[j] - 1);
int position = (int)(values[j] / fraction);
float low = position * fraction;
float high = (position + 1) * fraction;
float percentage = (high - values[j]) / (high - low);
if (((i >> j) & 1) == 1)
{
factor *= percentage;
}
else
{
factor *= 1 - percentage;
}
factor *= percentage;
}
else
{
factor *= 1 - percentage;
}
factors[i] = factor;
}
for (int i = 0; i < resultLength; i++)
factors[i] = factor;
}
for (int i = 0; i < resultLength; i++)
{
for (int j = 0; j < nodes.Length; j++)
{
for (int j = 0; j < nodes.Length; j++)
{
result[i] += nodes[j][i] * factors[j];
}
result[i] += nodes[j][i] * factors[j];
}
}
}

75
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/ColorTrcCalculator.cs

@ -1,54 +1,53 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using System.Numerics;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc;
internal class ColorTrcCalculator : IVector4Calculator
{
internal class ColorTrcCalculator : IVector4Calculator
{
private TrcCalculator curveCalculator;
private Matrix4x4 matrix;
private bool toPcs;
private TrcCalculator curveCalculator;
private Matrix4x4 matrix;
private bool toPcs;
public ColorTrcCalculator(
IccXyzTagDataEntry redMatrixColumn,
IccXyzTagDataEntry greenMatrixColumn,
IccXyzTagDataEntry blueMatrixColumn,
IccTagDataEntry redTrc,
IccTagDataEntry greenTrc,
IccTagDataEntry blueTrc,
bool toPcs)
{
this.toPcs = toPcs;
this.curveCalculator = new TrcCalculator(new IccTagDataEntry[] { redTrc, greenTrc, blueTrc }, !toPcs);
public ColorTrcCalculator(
IccXyzTagDataEntry redMatrixColumn,
IccXyzTagDataEntry greenMatrixColumn,
IccXyzTagDataEntry blueMatrixColumn,
IccTagDataEntry redTrc,
IccTagDataEntry greenTrc,
IccTagDataEntry blueTrc,
bool toPcs)
{
this.toPcs = toPcs;
this.curveCalculator = new TrcCalculator(new IccTagDataEntry[] { redTrc, greenTrc, blueTrc }, !toPcs);
Vector3 mr = redMatrixColumn.Data[0];
Vector3 mg = greenMatrixColumn.Data[0];
Vector3 mb = blueMatrixColumn.Data[0];
this.matrix = new Matrix4x4(mr.X, mr.Y, mr.Z, 0, mg.X, mg.Y, mg.Z, 0, mb.X, mb.Y, mb.Z, 0, 0, 0, 0, 1);
Vector3 mr = redMatrixColumn.Data[0];
Vector3 mg = greenMatrixColumn.Data[0];
Vector3 mb = blueMatrixColumn.Data[0];
this.matrix = new Matrix4x4(mr.X, mr.Y, mr.Z, 0, mg.X, mg.Y, mg.Z, 0, mb.X, mb.Y, mb.Z, 0, 0, 0, 0, 1);
if (!toPcs)
{
Matrix4x4.Invert(this.matrix, out this.matrix);
}
if (!toPcs)
{
Matrix4x4.Invert(this.matrix, out this.matrix);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector4 Calculate(Vector4 value)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector4 Calculate(Vector4 value)
{
if (this.toPcs)
{
value = this.curveCalculator.Calculate(value);
return Vector4.Transform(value, this.matrix);
}
else
{
if (this.toPcs)
{
value = this.curveCalculator.Calculate(value);
return Vector4.Transform(value, this.matrix);
}
else
{
value = Vector4.Transform(value, this.matrix);
return this.curveCalculator.Calculate(value);
}
value = Vector4.Transform(value, this.matrix);
return this.curveCalculator.Calculate(value);
}
}
}

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/CurveCalculator.CalculationType.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc
{

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/CurveCalculator.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using System;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/GrayTrcCalculator.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using System.Numerics;
using System.Runtime.CompilerServices;

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/ISingleCalculator.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc
{

4
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/IVector4Calculator.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Numerics;

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/LutABCalculator.CalculationType.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc
{

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/LutABCalculator.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using System;
using System.Numerics;

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/LutCalculator.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using System;
using System.Runtime.CompilerServices;

10
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/LutEntryCalculator.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using System.Numerics;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
@ -53,17 +53,17 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc
private void Init(IccLut[] inputCurve, IccLut[] outputCurve, IccClut clut, Matrix4x4 matrix)
{
this.inputCurve = this.InitLut(inputCurve);
this.outputCurve = this.InitLut(outputCurve);
this.inputCurve = InitLut(inputCurve);
this.outputCurve = InitLut(outputCurve);
this.clutCalculator = new ClutCalculator(clut);
this.matrix = matrix;
this.doTransform = !matrix.IsIdentity && inputCurve.Length == 3;
}
private LutCalculator[] InitLut(IccLut[] curves)
private static LutCalculator[] InitLut(IccLut[] curves)
{
var calculators = new LutCalculator[curves.Length];
LutCalculator[] calculators = new LutCalculator[curves.Length];
for (int i = 0; i < curves.Length; i++)
{
calculators[i] = new LutCalculator(curves[i].Values, false);

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/MatrixCalculator.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using System.Numerics;
using System.Runtime.CompilerServices;

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/ParametricCurveCalculator.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using System;
using System.Runtime.CompilerServices;

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/Calculators/TrcCalculator.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using System.Numerics;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;

244
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccConverterBase.Checks.cs

@ -1,173 +1,165 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using System.Linq;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc;
/// <summary>
/// Color converter for ICC profiles
/// </summary>
internal abstract partial class IccConverterBase
{
/// <summary>
/// Color converter for ICC profiles
/// </summary>
internal abstract partial class IccConverterBase
private static ConversionMethod GetConversionMethod(IccProfile profile, IccRenderingIntent renderingIntent)
{
private ConversionMethod GetConversionMethod(IccProfile profile, IccRenderingIntent renderingIntent)
switch (profile.Header.Class)
{
switch (profile.Header.Class)
{
case IccProfileClass.InputDevice:
case IccProfileClass.DisplayDevice:
case IccProfileClass.OutputDevice:
case IccProfileClass.ColorSpace:
return this.CheckMethod1(profile, renderingIntent);
case IccProfileClass.InputDevice:
case IccProfileClass.DisplayDevice:
case IccProfileClass.OutputDevice:
case IccProfileClass.ColorSpace:
return CheckMethod1(profile, renderingIntent);
case IccProfileClass.DeviceLink:
case IccProfileClass.Abstract:
return CheckMethod2(profile);
default:
return ConversionMethod.Invalid;
}
}
case IccProfileClass.DeviceLink:
case IccProfileClass.Abstract:
return this.CheckMethod2(profile);
private static ConversionMethod CheckMethod1(IccProfile profile, IccRenderingIntent renderingIntent)
{
ConversionMethod method = ConversionMethod.Invalid;
default:
return ConversionMethod.Invalid;
}
method = CheckMethodD(profile, renderingIntent);
if (method != ConversionMethod.Invalid)
{
return method;
}
private ConversionMethod CheckMethod1(IccProfile profile, IccRenderingIntent renderingIntent)
method = CheckMethodA(profile, renderingIntent);
if (method != ConversionMethod.Invalid)
{
ConversionMethod method = ConversionMethod.Invalid;
method = this.CheckMethodD(profile, renderingIntent);
if (method != ConversionMethod.Invalid)
{
return method;
}
method = this.CheckMethodA(profile, renderingIntent);
if (method != ConversionMethod.Invalid)
{
return method;
}
method = this.CheckMethodA0(profile);
if (method != ConversionMethod.Invalid)
{
return method;
}
method = this.CheckMethodTrc(profile);
if (method != ConversionMethod.Invalid)
{
return method;
}
return ConversionMethod.Invalid;
return method;
}
private ConversionMethod CheckMethodD(IccProfile profile, IccRenderingIntent renderingIntent)
method = CheckMethodA0(profile);
if (method != ConversionMethod.Invalid)
{
if ((this.HasTag(profile, IccProfileTag.DToB0) || this.HasTag(profile, IccProfileTag.BToD0))
&& renderingIntent == IccRenderingIntent.Perceptual)
{
return ConversionMethod.D0;
}
return method;
}
if ((this.HasTag(profile, IccProfileTag.DToB1) || this.HasTag(profile, IccProfileTag.BToD1))
&& renderingIntent == IccRenderingIntent.MediaRelativeColorimetric)
{
return ConversionMethod.D1;
}
method = CheckMethodTrc(profile);
if (method != ConversionMethod.Invalid)
{
return method;
}
if ((this.HasTag(profile, IccProfileTag.DToB2) || this.HasTag(profile, IccProfileTag.BToD2))
&& renderingIntent == IccRenderingIntent.Saturation)
{
return ConversionMethod.D2;
}
return ConversionMethod.Invalid;
}
if ((this.HasTag(profile, IccProfileTag.DToB3) || this.HasTag(profile, IccProfileTag.BToD3))
&& renderingIntent == IccRenderingIntent.AbsoluteColorimetric)
{
return ConversionMethod.D3;
}
private static ConversionMethod CheckMethodD(IccProfile profile, IccRenderingIntent renderingIntent)
{
if ((HasTag(profile, IccProfileTag.DToB0) || HasTag(profile, IccProfileTag.BToD0))
&& renderingIntent == IccRenderingIntent.Perceptual)
{
return ConversionMethod.D0;
}
return ConversionMethod.Invalid;
if ((HasTag(profile, IccProfileTag.DToB1) || HasTag(profile, IccProfileTag.BToD1))
&& renderingIntent == IccRenderingIntent.MediaRelativeColorimetric)
{
return ConversionMethod.D1;
}
private ConversionMethod CheckMethodA(IccProfile profile, IccRenderingIntent renderingIntent)
if ((HasTag(profile, IccProfileTag.DToB2) || HasTag(profile, IccProfileTag.BToD2))
&& renderingIntent == IccRenderingIntent.Saturation)
{
if ((this.HasTag(profile, IccProfileTag.AToB0) || this.HasTag(profile, IccProfileTag.BToA0))
&& renderingIntent == IccRenderingIntent.Perceptual)
{
return ConversionMethod.A0;
}
return ConversionMethod.D2;
}
if ((this.HasTag(profile, IccProfileTag.AToB1) || this.HasTag(profile, IccProfileTag.BToA1))
&& renderingIntent == IccRenderingIntent.MediaRelativeColorimetric)
{
return ConversionMethod.A1;
}
if ((HasTag(profile, IccProfileTag.DToB3) || HasTag(profile, IccProfileTag.BToD3))
&& renderingIntent == IccRenderingIntent.AbsoluteColorimetric)
{
return ConversionMethod.D3;
}
if ((this.HasTag(profile, IccProfileTag.AToB2) || this.HasTag(profile, IccProfileTag.BToA2))
&& renderingIntent == IccRenderingIntent.Saturation)
{
return ConversionMethod.A2;
}
return ConversionMethod.Invalid;
}
return ConversionMethod.Invalid;
private static ConversionMethod CheckMethodA(IccProfile profile, IccRenderingIntent renderingIntent)
{
if ((HasTag(profile, IccProfileTag.AToB0) || HasTag(profile, IccProfileTag.BToA0))
&& renderingIntent == IccRenderingIntent.Perceptual)
{
return ConversionMethod.A0;
}
private ConversionMethod CheckMethodA0(IccProfile profile)
if ((HasTag(profile, IccProfileTag.AToB1) || HasTag(profile, IccProfileTag.BToA1))
&& renderingIntent == IccRenderingIntent.MediaRelativeColorimetric)
{
bool valid = this.HasTag(profile, IccProfileTag.AToB0) || this.HasTag(profile, IccProfileTag.BToA0);
return valid ? ConversionMethod.A0 : ConversionMethod.Invalid;
return ConversionMethod.A1;
}
private ConversionMethod CheckMethodTrc(IccProfile profile)
if ((HasTag(profile, IccProfileTag.AToB2) || HasTag(profile, IccProfileTag.BToA2))
&& renderingIntent == IccRenderingIntent.Saturation)
{
if (this.HasTag(profile, IccProfileTag.RedMatrixColumn)
&& this.HasTag(profile, IccProfileTag.GreenMatrixColumn)
&& this.HasTag(profile, IccProfileTag.BlueMatrixColumn)
&& this.HasTag(profile, IccProfileTag.RedTrc)
&& this.HasTag(profile, IccProfileTag.GreenTrc)
&& this.HasTag(profile, IccProfileTag.BlueTrc))
{
return ConversionMethod.ColorTrc;
}
if (this.HasTag(profile, IccProfileTag.GrayTrc))
{
return ConversionMethod.GrayTrc;
}
return ConversionMethod.Invalid;
return ConversionMethod.A2;
}
private ConversionMethod CheckMethod2(IccProfile profile)
{
if (this.HasTag(profile, IccProfileTag.DToB0) || this.HasTag(profile, IccProfileTag.BToD0))
{
return ConversionMethod.D0;
}
return ConversionMethod.Invalid;
}
if (this.HasTag(profile, IccProfileTag.AToB0) || this.HasTag(profile, IccProfileTag.AToB0))
{
return ConversionMethod.A0;
}
private static ConversionMethod CheckMethodA0(IccProfile profile)
{
bool valid = HasTag(profile, IccProfileTag.AToB0) || HasTag(profile, IccProfileTag.BToA0);
return valid ? ConversionMethod.A0 : ConversionMethod.Invalid;
}
return ConversionMethod.Invalid;
private static ConversionMethod CheckMethodTrc(IccProfile profile)
{
if (HasTag(profile, IccProfileTag.RedMatrixColumn)
&& HasTag(profile, IccProfileTag.GreenMatrixColumn)
&& HasTag(profile, IccProfileTag.BlueMatrixColumn)
&& HasTag(profile, IccProfileTag.RedTrc)
&& HasTag(profile, IccProfileTag.GreenTrc)
&& HasTag(profile, IccProfileTag.BlueTrc))
{
return ConversionMethod.ColorTrc;
}
private bool HasTag(IccProfile profile, IccProfileTag tag)
if (HasTag(profile, IccProfileTag.GrayTrc))
{
return profile.Entries.Any(t => t.TagSignature == tag);
return ConversionMethod.GrayTrc;
}
private IccTagDataEntry GetTag(IccProfile profile, IccProfileTag tag)
return ConversionMethod.Invalid;
}
private static ConversionMethod CheckMethod2(IccProfile profile)
{
if (HasTag(profile, IccProfileTag.DToB0) || HasTag(profile, IccProfileTag.BToD0))
{
return profile.Entries.FirstOrDefault(t => t.TagSignature == tag);
return ConversionMethod.D0;
}
private T GetTag<T>(IccProfile profile, IccProfileTag tag)
where T : IccTagDataEntry
if (HasTag(profile, IccProfileTag.AToB0) || HasTag(profile, IccProfileTag.AToB0))
{
return profile.Entries.OfType<T>().FirstOrDefault(t => t.TagSignature == tag);
return ConversionMethod.A0;
}
return ConversionMethod.Invalid;
}
private static bool HasTag(IccProfile profile, IccProfileTag tag)
=> profile.Entries.Any(t => t.TagSignature == tag);
private static IccTagDataEntry GetTag(IccProfile profile, IccProfileTag tag)
=> profile.Entries.FirstOrDefault(t => t.TagSignature == tag);
private static T GetTag<T>(IccProfile profile, IccProfileTag tag)
where T : IccTagDataEntry
=> profile.Entries.OfType<T>().FirstOrDefault(t => t.TagSignature == tag);
}

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccConverterBase.ConversionMethod.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc
{

62
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccConverterbase.Conversions.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using System;
using SixLabors.ImageSharp.ColorSpaces.Conversion.Icc;
@ -22,57 +22,57 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc
/// <param name="renderingIntent">The wanted rendering intent. Can be ignored if not available</param>
protected void Init(IccProfile profile, bool toPcs, IccRenderingIntent renderingIntent)
{
ConversionMethod method = this.GetConversionMethod(profile, renderingIntent);
ConversionMethod method = GetConversionMethod(profile, renderingIntent);
switch (method)
{
case ConversionMethod.D0:
this.calculator = toPcs ?
this.InitD(profile, IccProfileTag.DToB0) :
this.InitD(profile, IccProfileTag.BToD0);
InitD(profile, IccProfileTag.DToB0) :
InitD(profile, IccProfileTag.BToD0);
break;
case ConversionMethod.D1:
this.calculator = toPcs ?
this.InitD(profile, IccProfileTag.DToB1) :
this.InitD(profile, IccProfileTag.BToD1);
InitD(profile, IccProfileTag.DToB1) :
InitD(profile, IccProfileTag.BToD1);
break;
case ConversionMethod.D2:
this.calculator = toPcs ?
this.InitD(profile, IccProfileTag.DToB2) :
this.InitD(profile, IccProfileTag.BToD2);
InitD(profile, IccProfileTag.DToB2) :
InitD(profile, IccProfileTag.BToD2);
break;
case ConversionMethod.D3:
this.calculator = toPcs ?
this.InitD(profile, IccProfileTag.DToB3) :
this.InitD(profile, IccProfileTag.BToD3);
InitD(profile, IccProfileTag.DToB3) :
InitD(profile, IccProfileTag.BToD3);
break;
case ConversionMethod.A0:
this.calculator = toPcs ?
this.InitA(profile, IccProfileTag.AToB0) :
this.InitA(profile, IccProfileTag.BToA0);
InitA(profile, IccProfileTag.AToB0) :
InitA(profile, IccProfileTag.BToA0);
break;
case ConversionMethod.A1:
this.calculator = toPcs ?
this.InitA(profile, IccProfileTag.AToB1) :
this.InitA(profile, IccProfileTag.BToA1);
InitA(profile, IccProfileTag.AToB1) :
InitA(profile, IccProfileTag.BToA1);
break;
case ConversionMethod.A2:
this.calculator = toPcs ?
this.InitA(profile, IccProfileTag.AToB2) :
this.InitA(profile, IccProfileTag.BToA2);
InitA(profile, IccProfileTag.AToB2) :
InitA(profile, IccProfileTag.BToA2);
break;
case ConversionMethod.ColorTrc:
this.calculator = this.InitColorTrc(profile, toPcs);
this.calculator = InitColorTrc(profile, toPcs);
break;
case ConversionMethod.GrayTrc:
this.calculator = this.InitGrayTrc(profile, toPcs);
this.calculator = InitGrayTrc(profile, toPcs);
break;
case ConversionMethod.Invalid:
@ -81,9 +81,9 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc
}
}
private IVector4Calculator InitA(IccProfile profile, IccProfileTag tag)
private static IVector4Calculator InitA(IccProfile profile, IccProfileTag tag)
{
IccTagDataEntry entry = this.GetTag(profile, tag);
IccTagDataEntry entry = GetTag(profile, tag);
switch (entry)
{
case IccLut8TagDataEntry lut8:
@ -100,9 +100,9 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc
}
}
private IVector4Calculator InitD(IccProfile profile, IccProfileTag tag)
private static IVector4Calculator InitD(IccProfile profile, IccProfileTag tag)
{
IccMultiProcessElementsTagDataEntry entry = this.GetTag<IccMultiProcessElementsTagDataEntry>(profile, tag);
IccMultiProcessElementsTagDataEntry entry = GetTag<IccMultiProcessElementsTagDataEntry>(profile, tag);
if (entry == null)
{
throw new InvalidIccProfileException("Entry is null.");
@ -111,15 +111,15 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc
throw new NotImplementedException("Multi process elements are not supported");
}
private IVector4Calculator InitColorTrc(IccProfile profile, bool toPcs)
private static IVector4Calculator InitColorTrc(IccProfile profile, bool toPcs)
{
IccXyzTagDataEntry redMatrixColumn = this.GetTag<IccXyzTagDataEntry>(profile, IccProfileTag.RedMatrixColumn);
IccXyzTagDataEntry greenMatrixColumn = this.GetTag<IccXyzTagDataEntry>(profile, IccProfileTag.GreenMatrixColumn);
IccXyzTagDataEntry blueMatrixColumn = this.GetTag<IccXyzTagDataEntry>(profile, IccProfileTag.BlueMatrixColumn);
IccXyzTagDataEntry redMatrixColumn = GetTag<IccXyzTagDataEntry>(profile, IccProfileTag.RedMatrixColumn);
IccXyzTagDataEntry greenMatrixColumn = GetTag<IccXyzTagDataEntry>(profile, IccProfileTag.GreenMatrixColumn);
IccXyzTagDataEntry blueMatrixColumn = GetTag<IccXyzTagDataEntry>(profile, IccProfileTag.BlueMatrixColumn);
IccTagDataEntry redTrc = this.GetTag(profile, IccProfileTag.RedTrc);
IccTagDataEntry greenTrc = this.GetTag(profile, IccProfileTag.GreenTrc);
IccTagDataEntry blueTrc = this.GetTag(profile, IccProfileTag.BlueTrc);
IccTagDataEntry redTrc = GetTag(profile, IccProfileTag.RedTrc);
IccTagDataEntry greenTrc = GetTag(profile, IccProfileTag.GreenTrc);
IccTagDataEntry blueTrc = GetTag(profile, IccProfileTag.BlueTrc);
if (redMatrixColumn == null ||
greenMatrixColumn == null ||
@ -141,9 +141,9 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc
toPcs);
}
private IVector4Calculator InitGrayTrc(IccProfile profile, bool toPcs)
private static IVector4Calculator InitGrayTrc(IccProfile profile, bool toPcs)
{
IccTagDataEntry entry = this.GetTag(profile, IccProfileTag.GrayTrc);
IccTagDataEntry entry = GetTag(profile, IccProfileTag.GrayTrc);
return new GrayTrcCalculator(entry, toPcs);
}
}

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccConverterbase.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using System.Numerics;
using System.Runtime.CompilerServices;

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccDataToDataConverter.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Metadata.Profiles.Icc;

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccDataToPcsConverter.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Metadata.Profiles.Icc;

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccPcsToDataConverter.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Metadata.Profiles.Icc;

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccPcsToPcsConverter.cs

@ -1,5 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Metadata.Profiles.Icc;

30
tests/ImageSharp.Tests/Colorspaces/Icc/Calculators/ClutCalculatorTests.cs

@ -1,29 +1,27 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
// Licensed under the Six Labors Split License.
using System.Numerics;
using SixLabors.ImageSharp.ColorSpaces.Conversion.Icc;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
using SixLabors.ImageSharp.Tests.TestDataIcc.Conversion;
using Xunit;
namespace SixLabors.ImageSharp.Tests.Colorspaces.Icc.Calculators
namespace SixLabors.ImageSharp.Tests.Colorspaces.Icc.Calculators;
/// <summary>
/// Tests ICC <see cref="ClutCalculator"/>
/// </summary>
[Trait("Color", "Conversion")]
public class ClutCalculatorTests
{
/// <summary>
/// Tests ICC <see cref="ClutCalculator"/>
/// </summary>
[Trait("Color", "Conversion")]
public class ClutCalculatorTests
[Theory]
[MemberData(nameof(IccConversionDataClut.ClutConversionTestData), MemberType = typeof(IccConversionDataClut))]
internal void ClutCalculator_WithClut_ReturnsResult(IccClut lut, Vector4 input, Vector4 expected)
{
[Theory]
[MemberData(nameof(IccConversionDataClut.ClutConversionTestData), MemberType = typeof(IccConversionDataClut))]
internal void ClutCalculator_WithClut_ReturnsResult(IccClut lut, Vector4 input, Vector4 expected)
{
var calculator = new ClutCalculator(lut);
ClutCalculator calculator = new(lut);
Vector4 result = calculator.Calculate(input);
Vector4 result = calculator.Calculate(input);
VectorAssert.Equal(expected, result, 4);
}
VectorAssert.Equal(expected, result, 4);
}
}

Loading…
Cancel
Save