Browse Source

Add Lab<=>Xyz conversion

pull/1567/head
James Jackson-South 3 years ago
parent
commit
ed476785dc
  1. 56
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccProfileConverter.cs

56
src/ImageSharp/ColorSpaces/Conversion/Implementation/Icc/IccProfileConverter.cs

@ -48,10 +48,44 @@ internal static class IccProfileConverter
Span<TPixel> row = accessor.GetRowSpan(y);
PixelOperations<TPixel>.Instance.ToVector4(configuration, row, vectorsSpan, PixelConversionModifiers.Scale);
for (int x = 0; x < vectorsSpan.Length; x++)
if (inputIccProfile.Header.ProfileConnectionSpace == IccColorSpaceType.CieLab
&& outputIccProfile.Header.ProfileConnectionSpace == IccColorSpaceType.CieXyz)
{
Vector4 pcs = converterDataToPcs.Calculate(vectorsSpan[x]);
vectorsSpan[x] = converterPcsToData.Calculate(pcs);
ColorSpaceConverter converter = new();
for (int x = 0; x < vectorsSpan.Length; x++)
{
Vector4 pcs = converterDataToPcs.Calculate(vectorsSpan[x]);
pcs = PcsToLab(pcs);
CieXyz xyz = converter.ToCieXyz(new CieLab(pcs.X, pcs.Y, pcs.Z, new CieXyz(inputIccProfile.Header.PcsIlluminant)));
pcs = new Vector4(xyz.X, xyz.Y, xyz.Z, pcs.W);
vectorsSpan[x] = converterPcsToData.Calculate(pcs);
}
}
else if (inputIccProfile.Header.ProfileConnectionSpace == IccColorSpaceType.CieXyz
&& outputIccProfile.Header.ProfileConnectionSpace == IccColorSpaceType.CieLab)
{
Vector3 illuminant = outputIccProfile.Header.PcsIlluminant;
ColorSpaceConverter converter = new(new ColorSpaceConverterOptions()
{
WhitePoint = new(illuminant),
});
for (int x = 0; x < vectorsSpan.Length; x++)
{
Vector4 pcs = converterDataToPcs.Calculate(vectorsSpan[x]);
CieLab lab = converter.ToCieLab(new CieXyz(pcs.X, pcs.Y, pcs.Z));
pcs = LabToPcs(pcs, lab);
vectorsSpan[x] = converterPcsToData.Calculate(pcs);
}
}
else
{
for (int x = 0; x < vectorsSpan.Length; x++)
{
Vector4 pcs = converterDataToPcs.Calculate(vectorsSpan[x]);
vectorsSpan[x] = converterPcsToData.Calculate(pcs);
}
}
PixelOperations<TPixel>.Instance.FromVector4Destructive(configuration, vectorsSpan, row);
@ -61,6 +95,22 @@ internal static class IccProfileConverter
image.Metadata.IccProfile = outputIccProfile;
}
private static unsafe Vector4 PcsToLab(Vector4 input)
{
Vector3* v = (Vector3*)&input;
v[0] *= 100F;
v[0] -= new Vector3(0, 128F, 128F);
return input;
}
private static unsafe Vector4 LabToPcs(Vector4 input, CieLab lab)
{
Vector3* v = (Vector3*)&input;
v[0] = new Vector3(lab.L, lab.A + 128F, lab.B + 128F);
v[0] /= 100F;
return input;
}
private readonly struct IccProfileConverterVisitor : IImageVisitor
{
private readonly IccProfile inputIccProfile;

Loading…
Cancel
Save