diff --git a/src/ImageSharp/ColorProfiles/ColorProfileConverter.cs b/src/ImageSharp/ColorProfiles/ColorProfileConverter.cs
index fa3f3d7e21..d0afec4ab2 100644
--- a/src/ImageSharp/ColorProfiles/ColorProfileConverter.cs
+++ b/src/ImageSharp/ColorProfiles/ColorProfileConverter.cs
@@ -12,7 +12,7 @@ public class ColorProfileConverter
/// Initializes a new instance of the class.
///
public ColorProfileConverter()
- : this(new())
+ : this(new())
{
}
diff --git a/src/ImageSharp/ColorProfiles/Icc/IccProfileConverter.cs b/src/ImageSharp/ColorProfiles/Icc/IccProfileConverter.cs
deleted file mode 100644
index c8c4de4a60..0000000000
--- a/src/ImageSharp/ColorProfiles/Icc/IccProfileConverter.cs
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Six Labors Split License.
-
-using System.Buffers;
-using System.Numerics;
-using SixLabors.ImageSharp.Advanced;
-using SixLabors.ImageSharp.Memory;
-using SixLabors.ImageSharp.Metadata.Profiles.Icc;
-using SixLabors.ImageSharp.PixelFormats;
-
-namespace SixLabors.ImageSharp.ColorProfiles.Icc;
-
-///
-/// Allows the conversion between ICC profiles.
-///
-internal static class IccProfileConverter
-{
- ///
- /// Performs a conversion of the image pixels based on the input and output ICC profiles.
- ///
- /// The image to convert.
- /// The input ICC profile.
- /// The output ICC profile.
- public static void Convert(Image image, IccProfile inputIccProfile, IccProfile outputIccProfile)
- => image.AcceptVisitor(new IccProfileConverterVisitor(inputIccProfile, outputIccProfile));
-
- ///
- /// Performs a conversion of the image pixels based on the input and output ICC profiles.
- ///
- /// The type of pixel.
- /// The image to convert.
- /// The input ICC profile.
- /// The output ICC profile.
- public static void Convert(Image image, IccProfile inputIccProfile, IccProfile outputIccProfile)
- where TPixel : unmanaged, IPixel
- {
- IccDataToPcsConverter converterDataToPcs = new(inputIccProfile);
- IccPcsToDataConverter converterPcsToData = new(outputIccProfile);
- Configuration configuration = image.Configuration;
-
- image.ProcessPixelRows(accessor =>
- {
- ColorProfileConverter converter = new(new ColorConversionOptions()
- {
- SourceWhitePoint = new CieXyz(inputIccProfile.Header.PcsIlluminant),
- TargetWhitePoint = new CieXyz(outputIccProfile.Header.PcsIlluminant),
- });
-
- // TODO: Our Xxy/Lab conversion are dependent on the version number. We are applying the conversion using V4
- // but we should use the correct algorithm per version. This includes Lab/Lab Xyz/Xyz.
- using IMemoryOwner vectors = configuration.MemoryAllocator.Allocate(accessor.Width);
- Span vectorsSpan = vectors.GetSpan();
-
- // TODO: For debugging - remove.
- // It appears we have a scaling problem. The pcs values differ by on average 0.000001.
- Span temp = new Vector4[vectorsSpan.Length];
-
- for (int y = 0; y < accessor.Height; y++)
- {
- Span row = accessor.GetRowSpan(y);
- PixelOperations.Instance.ToVector4(configuration, row, vectorsSpan, PixelConversionModifiers.Scale);
-
- if (inputIccProfile.Header.ProfileConnectionSpace == IccColorSpaceType.CieLab &&
- outputIccProfile.Header.ProfileConnectionSpace == IccColorSpaceType.CieXyz)
- {
- for (int x = 0; x < vectorsSpan.Length; x++)
- {
- Vector4 pcs = converterDataToPcs.Calculate(vectorsSpan[x]);
- temp[x] = pcs;
- pcs = PcsToLab(pcs);
- CieLab lab = new(pcs.X, pcs.Y, pcs.Z);
- CieXyz xyz = converter.Convert(in lab);
- pcs = XyzToPcs(pcs, xyz);
-
- vectorsSpan[x] = converterPcsToData.Calculate(pcs);
- }
- }
- else if (inputIccProfile.Header.ProfileConnectionSpace == IccColorSpaceType.CieXyz &&
- outputIccProfile.Header.ProfileConnectionSpace == IccColorSpaceType.CieLab)
- {
- for (int x = 0; x < vectorsSpan.Length; x++)
- {
- Vector4 pcs = converterDataToPcs.Calculate(vectorsSpan[x]);
- CieXyz xyz = new(pcs.X, pcs.Y, pcs.Z);
- CieLab lab = converter.Convert(in xyz);
- 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.Instance.FromVector4Destructive(configuration, vectorsSpan, row, PixelConversionModifiers.Scale);
- }
- });
-
- image.Metadata.IccProfile = outputIccProfile;
- }
-
- private static unsafe Vector4 PcsToLab(Vector4 input)
- {
- Vector3* v = (Vector3*)&input;
- v[0] *= new Vector3(100f, 255, 255);
- 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 static unsafe Vector4 XyzToPcs(Vector4 input, CieXyz xyz)
- {
- Vector3* v = (Vector3*)&input;
- v[0] = xyz.ToVector3();
- v[0] *= 32768 / 65535f;
- return input;
- }
-
- private readonly struct IccProfileConverterVisitor : IImageVisitor
- {
- private readonly IccProfile inputIccProfile;
- private readonly IccProfile outputIccProfile;
-
- public IccProfileConverterVisitor(IccProfile inputIccProfile, IccProfile outputIccProfile)
- {
- this.inputIccProfile = inputIccProfile;
- this.outputIccProfile = outputIccProfile;
- }
-
- public void Visit(Image image)
- where TPixel : unmanaged, IPixel => Convert(image, this.inputIccProfile, this.outputIccProfile);
- }
-}
diff --git a/src/ImageSharp/Formats/DecoderOptions.cs b/src/ImageSharp/Formats/DecoderOptions.cs
index f606d2fff2..8c6b8fc225 100644
--- a/src/ImageSharp/Formats/DecoderOptions.cs
+++ b/src/ImageSharp/Formats/DecoderOptions.cs
@@ -62,8 +62,9 @@ public sealed class DecoderOptions
///
/// Gets a value that controls how ICC profiles are handled during decode.
+ /// TODO: Implement this.
///
- public ColorProfileHandling ColorProfileHandling { get; init; }
+ internal ColorProfileHandling ColorProfileHandling { get; init; }
internal void SetConfiguration(Configuration configuration) => this.configuration = configuration;
}
diff --git a/src/ImageSharp/Formats/ImageDecoder.cs b/src/ImageSharp/Formats/ImageDecoder.cs
index 0a8144712a..dd148dfedd 100644
--- a/src/ImageSharp/Formats/ImageDecoder.cs
+++ b/src/ImageSharp/Formats/ImageDecoder.cs
@@ -1,11 +1,8 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
-using SixLabors.ImageSharp.ColorProfiles.Icc;
-using SixLabors.ImageSharp.ColorSpaces.Conversion.Icc;
using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Metadata;
-using SixLabors.ImageSharp.Metadata.Profiles.Icc;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
@@ -26,7 +23,6 @@ public abstract class ImageDecoder : IImageDecoder
stream,
s => this.Decode(options, s, default));
- TransformColorProfile(options, image);
this.SetDecoderFormat(options.Configuration, image);
return image;
@@ -40,7 +36,6 @@ public abstract class ImageDecoder : IImageDecoder
stream,
s => this.Decode(options, s, default));
- TransformColorProfile(options, image);
this.SetDecoderFormat(options.Configuration, image);
return image;
@@ -56,7 +51,6 @@ public abstract class ImageDecoder : IImageDecoder
(s, ct) => this.Decode(options, s, ct),
cancellationToken).ConfigureAwait(false);
- TransformColorProfile(options, image);
this.SetDecoderFormat(options.Configuration, image);
return image;
@@ -71,7 +65,6 @@ public abstract class ImageDecoder : IImageDecoder
(s, ct) => this.Decode(options, s, ct),
cancellationToken).ConfigureAwait(false);
- TransformColorProfile(options, image);
this.SetDecoderFormat(options.Configuration, image);
return image;
@@ -166,25 +159,6 @@ public abstract class ImageDecoder : IImageDecoder
}
}
- ///
- /// Converts the decoded image color profile if present to a V4 sRGB profile.
- ///
- /// The decoder options.
- /// The image.
- protected static void TransformColorProfile(DecoderOptions options, Image image)
- {
- if (options.ColorProfileHandling == ColorProfileHandling.Preserve)
- {
- return;
- }
-
- IccProfile? profile = image.Metadata?.IccProfile;
- if (profile is not null)
- {
- IccProfileConverter.Convert(image, profile, SrgbV4Profile.GetProfile());
- }
- }
-
///
/// Determines whether the decoded image should be resized.
///
diff --git a/src/ImageSharp/Formats/SpecializedImageDecoder{T}.cs b/src/ImageSharp/Formats/SpecializedImageDecoder{T}.cs
index 2fb15aed29..38bfe817dd 100644
--- a/src/ImageSharp/Formats/SpecializedImageDecoder{T}.cs
+++ b/src/ImageSharp/Formats/SpecializedImageDecoder{T}.cs
@@ -23,7 +23,6 @@ public abstract class SpecializedImageDecoder : ImageDecoder, ISpecializedIma
stream,
s => this.Decode(options, s, default));
- TransformColorProfile(options.GeneralOptions, image);
this.SetDecoderFormat(options.GeneralOptions.Configuration, image);
return image;
@@ -37,7 +36,6 @@ public abstract class SpecializedImageDecoder : ImageDecoder, ISpecializedIma
stream,
s => this.Decode(options, s, default));
- TransformColorProfile(options.GeneralOptions, image);
this.SetDecoderFormat(options.GeneralOptions.Configuration, image);
return image;
@@ -53,7 +51,6 @@ public abstract class SpecializedImageDecoder : ImageDecoder, ISpecializedIma
(s, ct) => this.Decode(options, s, ct),
cancellationToken).ConfigureAwait(false);
- TransformColorProfile(options.GeneralOptions, image);
this.SetDecoderFormat(options.GeneralOptions.Configuration, image);
return image;
@@ -68,7 +65,6 @@ public abstract class SpecializedImageDecoder : ImageDecoder, ISpecializedIma
(s, ct) => this.Decode(options, s, ct),
cancellationToken).ConfigureAwait(false);
- TransformColorProfile(options.GeneralOptions, image);
this.SetDecoderFormat(options.GeneralOptions.Configuration, image);
return image;
diff --git a/tests/ImageSharp.Tests/ColorProfiles/Icc/IccProfileConverterTests.cs b/tests/ImageSharp.Tests/ColorProfiles/Icc/IccProfileConverterTests.cs
deleted file mode 100644
index ad8193774d..0000000000
--- a/tests/ImageSharp.Tests/ColorProfiles/Icc/IccProfileConverterTests.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Six Labors Split License.
-
-using SixLabors.ImageSharp.ColorProfiles.Icc;
-using SixLabors.ImageSharp.ColorSpaces.Conversion.Icc;
-using SixLabors.ImageSharp.Formats.Png;
-using SixLabors.ImageSharp.Metadata.Profiles.Icc;
-using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
-
-namespace SixLabors.ImageSharp.Tests.ColorProfiles.Icc;
-
-public class IccProfileConverterTests
-{
- private static readonly PngEncoder Encoder = new();
-
- [Theory(Skip = "Skip for now while we refactor the library")]
- [WithFile(TestImages.Jpeg.ICC.AdobeRgb, PixelTypes.Rgb24)]
- [WithFile(TestImages.Jpeg.ICC.AppleRGB, PixelTypes.Rgb24)]
- [WithFile(TestImages.Jpeg.ICC.ColorMatch, PixelTypes.Rgb24)]
- [WithFile(TestImages.Jpeg.ICC.WideRGB, PixelTypes.Rgb24)]
- [WithFile(TestImages.Jpeg.ICC.SRgb, PixelTypes.Rgb24)]
- [WithFile(TestImages.Jpeg.ICC.ProPhoto, PixelTypes.Rgb24)]
- [WithFile(TestImages.Jpeg.ICC.CMYK, PixelTypes.Rgb24)]
- public void CanRoundTripProfile(TestImageProvider provider)
- where TPixel : unmanaged, IPixel
- {
- using Image image = provider.GetImage();
-
- IccProfile profile = image.Metadata.IccProfile;
-
- TPixel expected = image[0, 0];
-
- IccProfileConverter.Convert(image, profile, profile);
-
- image.DebugSave(provider, extension: "png", appendPixelTypeToFileName: false, appendSourceFileOrDescription: true, encoder: Encoder);
-
- TPixel actual = image[0, 0];
-
- Assert.Equal(expected, actual);
- }
-
- [Theory(Skip = "Skip for now while we refactor the library")]
- [WithFile(TestImages.Jpeg.ICC.AdobeRgb, PixelTypes.Rgb24)]
- [WithFile(TestImages.Jpeg.ICC.AppleRGB, PixelTypes.Rgb24)]
- [WithFile(TestImages.Jpeg.ICC.ColorMatch, PixelTypes.Rgb24)]
- [WithFile(TestImages.Jpeg.ICC.WideRGB, PixelTypes.Rgb24)]
- [WithFile(TestImages.Jpeg.ICC.SRgb, PixelTypes.Rgb24)]
- [WithFile(TestImages.Jpeg.ICC.ProPhoto, PixelTypes.Rgb24)]
- [WithFile(TestImages.Jpeg.ICC.CMYK, PixelTypes.Rgb24)]
- public void CanConvertToSRGB(TestImageProvider provider)
- where TPixel : unmanaged, IPixel
- {
- using Image image = provider.GetImage();
- IccProfile profile = image.Metadata.IccProfile;
-
- IccProfile sRGBProfile = SrgbV4Profile.GetProfile();
-
- IccProfileConverter.Convert(image, profile, sRGBProfile);
-
- Assert.Equal(image.Metadata.IccProfile, sRGBProfile);
-
- image.DebugSave(provider, extension: "png", appendPixelTypeToFileName: false, appendSourceFileOrDescription: true, encoder: Encoder);
-
- // Mac reports a difference of 0.0000%
- image.CompareToReferenceOutput(ImageComparer.Tolerant(0.0001F), provider, appendPixelTypeToFileName: false);
- }
-}