|
|
@ -1,17 +1,16 @@ |
|
|
// Copyright (c) Six Labors.
|
|
|
// 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; |
|
|
using SixLabors.ImageSharp.Metadata.Profiles.Icc; |
|
|
|
|
|
|
|
|
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc |
|
|
namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc; |
|
|
{ |
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// Color converter for ICC profiles
|
|
|
/// Color converter for ICC profiles
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
internal abstract partial class IccConverterBase |
|
|
internal abstract partial class IccConverterBase |
|
|
{ |
|
|
{ |
|
|
private ConversionMethod GetConversionMethod(IccProfile profile, IccRenderingIntent renderingIntent) |
|
|
private static ConversionMethod GetConversionMethod(IccProfile profile, IccRenderingIntent renderingIntent) |
|
|
{ |
|
|
{ |
|
|
switch (profile.Header.Class) |
|
|
switch (profile.Header.Class) |
|
|
{ |
|
|
{ |
|
|
@ -19,40 +18,40 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc |
|
|
case IccProfileClass.DisplayDevice: |
|
|
case IccProfileClass.DisplayDevice: |
|
|
case IccProfileClass.OutputDevice: |
|
|
case IccProfileClass.OutputDevice: |
|
|
case IccProfileClass.ColorSpace: |
|
|
case IccProfileClass.ColorSpace: |
|
|
return this.CheckMethod1(profile, renderingIntent); |
|
|
return CheckMethod1(profile, renderingIntent); |
|
|
|
|
|
|
|
|
case IccProfileClass.DeviceLink: |
|
|
case IccProfileClass.DeviceLink: |
|
|
case IccProfileClass.Abstract: |
|
|
case IccProfileClass.Abstract: |
|
|
return this.CheckMethod2(profile); |
|
|
return CheckMethod2(profile); |
|
|
|
|
|
|
|
|
default: |
|
|
default: |
|
|
return ConversionMethod.Invalid; |
|
|
return ConversionMethod.Invalid; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private ConversionMethod CheckMethod1(IccProfile profile, IccRenderingIntent renderingIntent) |
|
|
private static ConversionMethod CheckMethod1(IccProfile profile, IccRenderingIntent renderingIntent) |
|
|
{ |
|
|
{ |
|
|
ConversionMethod method = ConversionMethod.Invalid; |
|
|
ConversionMethod method = ConversionMethod.Invalid; |
|
|
|
|
|
|
|
|
method = this.CheckMethodD(profile, renderingIntent); |
|
|
method = CheckMethodD(profile, renderingIntent); |
|
|
if (method != ConversionMethod.Invalid) |
|
|
if (method != ConversionMethod.Invalid) |
|
|
{ |
|
|
{ |
|
|
return method; |
|
|
return method; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
method = this.CheckMethodA(profile, renderingIntent); |
|
|
method = CheckMethodA(profile, renderingIntent); |
|
|
if (method != ConversionMethod.Invalid) |
|
|
if (method != ConversionMethod.Invalid) |
|
|
{ |
|
|
{ |
|
|
return method; |
|
|
return method; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
method = this.CheckMethodA0(profile); |
|
|
method = CheckMethodA0(profile); |
|
|
if (method != ConversionMethod.Invalid) |
|
|
if (method != ConversionMethod.Invalid) |
|
|
{ |
|
|
{ |
|
|
return method; |
|
|
return method; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
method = this.CheckMethodTrc(profile); |
|
|
method = CheckMethodTrc(profile); |
|
|
if (method != ConversionMethod.Invalid) |
|
|
if (method != ConversionMethod.Invalid) |
|
|
{ |
|
|
{ |
|
|
return method; |
|
|
return method; |
|
|
@ -61,27 +60,27 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc |
|
|
return ConversionMethod.Invalid; |
|
|
return ConversionMethod.Invalid; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private ConversionMethod CheckMethodD(IccProfile profile, IccRenderingIntent renderingIntent) |
|
|
private static ConversionMethod CheckMethodD(IccProfile profile, IccRenderingIntent renderingIntent) |
|
|
{ |
|
|
{ |
|
|
if ((this.HasTag(profile, IccProfileTag.DToB0) || this.HasTag(profile, IccProfileTag.BToD0)) |
|
|
if ((HasTag(profile, IccProfileTag.DToB0) || HasTag(profile, IccProfileTag.BToD0)) |
|
|
&& renderingIntent == IccRenderingIntent.Perceptual) |
|
|
&& renderingIntent == IccRenderingIntent.Perceptual) |
|
|
{ |
|
|
{ |
|
|
return ConversionMethod.D0; |
|
|
return ConversionMethod.D0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if ((this.HasTag(profile, IccProfileTag.DToB1) || this.HasTag(profile, IccProfileTag.BToD1)) |
|
|
if ((HasTag(profile, IccProfileTag.DToB1) || HasTag(profile, IccProfileTag.BToD1)) |
|
|
&& renderingIntent == IccRenderingIntent.MediaRelativeColorimetric) |
|
|
&& renderingIntent == IccRenderingIntent.MediaRelativeColorimetric) |
|
|
{ |
|
|
{ |
|
|
return ConversionMethod.D1; |
|
|
return ConversionMethod.D1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if ((this.HasTag(profile, IccProfileTag.DToB2) || this.HasTag(profile, IccProfileTag.BToD2)) |
|
|
if ((HasTag(profile, IccProfileTag.DToB2) || HasTag(profile, IccProfileTag.BToD2)) |
|
|
&& renderingIntent == IccRenderingIntent.Saturation) |
|
|
&& renderingIntent == IccRenderingIntent.Saturation) |
|
|
{ |
|
|
{ |
|
|
return ConversionMethod.D2; |
|
|
return ConversionMethod.D2; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if ((this.HasTag(profile, IccProfileTag.DToB3) || this.HasTag(profile, IccProfileTag.BToD3)) |
|
|
if ((HasTag(profile, IccProfileTag.DToB3) || HasTag(profile, IccProfileTag.BToD3)) |
|
|
&& renderingIntent == IccRenderingIntent.AbsoluteColorimetric) |
|
|
&& renderingIntent == IccRenderingIntent.AbsoluteColorimetric) |
|
|
{ |
|
|
{ |
|
|
return ConversionMethod.D3; |
|
|
return ConversionMethod.D3; |
|
|
@ -90,21 +89,21 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc |
|
|
return ConversionMethod.Invalid; |
|
|
return ConversionMethod.Invalid; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private ConversionMethod CheckMethodA(IccProfile profile, IccRenderingIntent renderingIntent) |
|
|
private static ConversionMethod CheckMethodA(IccProfile profile, IccRenderingIntent renderingIntent) |
|
|
{ |
|
|
{ |
|
|
if ((this.HasTag(profile, IccProfileTag.AToB0) || this.HasTag(profile, IccProfileTag.BToA0)) |
|
|
if ((HasTag(profile, IccProfileTag.AToB0) || HasTag(profile, IccProfileTag.BToA0)) |
|
|
&& renderingIntent == IccRenderingIntent.Perceptual) |
|
|
&& renderingIntent == IccRenderingIntent.Perceptual) |
|
|
{ |
|
|
{ |
|
|
return ConversionMethod.A0; |
|
|
return ConversionMethod.A0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if ((this.HasTag(profile, IccProfileTag.AToB1) || this.HasTag(profile, IccProfileTag.BToA1)) |
|
|
if ((HasTag(profile, IccProfileTag.AToB1) || HasTag(profile, IccProfileTag.BToA1)) |
|
|
&& renderingIntent == IccRenderingIntent.MediaRelativeColorimetric) |
|
|
&& renderingIntent == IccRenderingIntent.MediaRelativeColorimetric) |
|
|
{ |
|
|
{ |
|
|
return ConversionMethod.A1; |
|
|
return ConversionMethod.A1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if ((this.HasTag(profile, IccProfileTag.AToB2) || this.HasTag(profile, IccProfileTag.BToA2)) |
|
|
if ((HasTag(profile, IccProfileTag.AToB2) || HasTag(profile, IccProfileTag.BToA2)) |
|
|
&& renderingIntent == IccRenderingIntent.Saturation) |
|
|
&& renderingIntent == IccRenderingIntent.Saturation) |
|
|
{ |
|
|
{ |
|
|
return ConversionMethod.A2; |
|
|
return ConversionMethod.A2; |
|
|
@ -113,25 +112,25 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc |
|
|
return ConversionMethod.Invalid; |
|
|
return ConversionMethod.Invalid; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private ConversionMethod CheckMethodA0(IccProfile profile) |
|
|
private static ConversionMethod CheckMethodA0(IccProfile profile) |
|
|
{ |
|
|
{ |
|
|
bool valid = this.HasTag(profile, IccProfileTag.AToB0) || this.HasTag(profile, IccProfileTag.BToA0); |
|
|
bool valid = HasTag(profile, IccProfileTag.AToB0) || HasTag(profile, IccProfileTag.BToA0); |
|
|
return valid ? ConversionMethod.A0 : ConversionMethod.Invalid; |
|
|
return valid ? ConversionMethod.A0 : ConversionMethod.Invalid; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private ConversionMethod CheckMethodTrc(IccProfile profile) |
|
|
private static ConversionMethod CheckMethodTrc(IccProfile profile) |
|
|
{ |
|
|
{ |
|
|
if (this.HasTag(profile, IccProfileTag.RedMatrixColumn) |
|
|
if (HasTag(profile, IccProfileTag.RedMatrixColumn) |
|
|
&& this.HasTag(profile, IccProfileTag.GreenMatrixColumn) |
|
|
&& HasTag(profile, IccProfileTag.GreenMatrixColumn) |
|
|
&& this.HasTag(profile, IccProfileTag.BlueMatrixColumn) |
|
|
&& HasTag(profile, IccProfileTag.BlueMatrixColumn) |
|
|
&& this.HasTag(profile, IccProfileTag.RedTrc) |
|
|
&& HasTag(profile, IccProfileTag.RedTrc) |
|
|
&& this.HasTag(profile, IccProfileTag.GreenTrc) |
|
|
&& HasTag(profile, IccProfileTag.GreenTrc) |
|
|
&& this.HasTag(profile, IccProfileTag.BlueTrc)) |
|
|
&& HasTag(profile, IccProfileTag.BlueTrc)) |
|
|
{ |
|
|
{ |
|
|
return ConversionMethod.ColorTrc; |
|
|
return ConversionMethod.ColorTrc; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (this.HasTag(profile, IccProfileTag.GrayTrc)) |
|
|
if (HasTag(profile, IccProfileTag.GrayTrc)) |
|
|
{ |
|
|
{ |
|
|
return ConversionMethod.GrayTrc; |
|
|
return ConversionMethod.GrayTrc; |
|
|
} |
|
|
} |
|
|
@ -139,14 +138,14 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc |
|
|
return ConversionMethod.Invalid; |
|
|
return ConversionMethod.Invalid; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private ConversionMethod CheckMethod2(IccProfile profile) |
|
|
private static ConversionMethod CheckMethod2(IccProfile profile) |
|
|
{ |
|
|
{ |
|
|
if (this.HasTag(profile, IccProfileTag.DToB0) || this.HasTag(profile, IccProfileTag.BToD0)) |
|
|
if (HasTag(profile, IccProfileTag.DToB0) || HasTag(profile, IccProfileTag.BToD0)) |
|
|
{ |
|
|
{ |
|
|
return ConversionMethod.D0; |
|
|
return ConversionMethod.D0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (this.HasTag(profile, IccProfileTag.AToB0) || this.HasTag(profile, IccProfileTag.AToB0)) |
|
|
if (HasTag(profile, IccProfileTag.AToB0) || HasTag(profile, IccProfileTag.AToB0)) |
|
|
{ |
|
|
{ |
|
|
return ConversionMethod.A0; |
|
|
return ConversionMethod.A0; |
|
|
} |
|
|
} |
|
|
@ -154,20 +153,13 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Icc |
|
|
return ConversionMethod.Invalid; |
|
|
return ConversionMethod.Invalid; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private bool HasTag(IccProfile profile, IccProfileTag tag) |
|
|
private static bool HasTag(IccProfile profile, IccProfileTag tag) |
|
|
{ |
|
|
=> profile.Entries.Any(t => t.TagSignature == tag); |
|
|
return profile.Entries.Any(t => t.TagSignature == tag); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private IccTagDataEntry GetTag(IccProfile profile, IccProfileTag tag) |
|
|
private static IccTagDataEntry GetTag(IccProfile profile, IccProfileTag tag) |
|
|
{ |
|
|
=> profile.Entries.FirstOrDefault(t => t.TagSignature == tag); |
|
|
return profile.Entries.FirstOrDefault(t => t.TagSignature == tag); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private T GetTag<T>(IccProfile profile, IccProfileTag tag) |
|
|
private static T GetTag<T>(IccProfile profile, IccProfileTag tag) |
|
|
where T : IccTagDataEntry |
|
|
where T : IccTagDataEntry |
|
|
{ |
|
|
=> profile.Entries.OfType<T>().FirstOrDefault(t => t.TagSignature == tag); |
|
|
return profile.Entries.OfType<T>().FirstOrDefault(t => t.TagSignature == tag); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
|