Skip to content

Commit c19a82e

Browse files
Merge pull request #2922 from SixLabors/js/jpeg-icc-normalize
Enable colorimetric normalization of JPEG image data during decode
2 parents 1226eb5 + 65bb20b commit c19a82e

File tree

62 files changed

+808
-144
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+808
-144
lines changed

src/ImageSharp/Advanced/AotCompilerTools.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -277,11 +277,11 @@ private static void AotCompileImageDecoders<TPixel>()
277277
private static void AotCompileSpectralConverter<TPixel>()
278278
where TPixel : unmanaged, IPixel<TPixel>
279279
{
280-
default(SpectralConverter<TPixel>).GetPixelBuffer(default);
281-
default(GrayJpegSpectralConverter<TPixel>).GetPixelBuffer(default);
282-
default(RgbJpegSpectralConverter<TPixel>).GetPixelBuffer(default);
283-
default(TiffJpegSpectralConverter<TPixel>).GetPixelBuffer(default);
284-
default(TiffOldJpegSpectralConverter<TPixel>).GetPixelBuffer(default);
280+
default(SpectralConverter<TPixel>).GetPixelBuffer(default, default);
281+
default(GrayJpegSpectralConverter<TPixel>).GetPixelBuffer(default, default);
282+
default(RgbJpegSpectralConverter<TPixel>).GetPixelBuffer(default, default);
283+
default(TiffJpegSpectralConverter<TPixel>).GetPixelBuffer(default, default);
284+
default(TiffOldJpegSpectralConverter<TPixel>).GetPixelBuffer(default, default);
285285
}
286286

287287
/// <summary>

src/ImageSharp/ColorProfiles/ColorConversionOptions.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ namespace SixLabors.ImageSharp.ColorProfiles;
1414
public class ColorConversionOptions
1515
{
1616
private Matrix4x4 adaptationMatrix;
17-
private YCbCrMatrix yCbCrMatrix;
17+
private YCbCrTransform yCbCrTransform;
1818

1919
/// <summary>
2020
/// Initializes a new instance of the <see cref="ColorConversionOptions"/> class.
2121
/// </summary>
2222
public ColorConversionOptions()
2323
{
2424
this.AdaptationMatrix = KnownChromaticAdaptationMatrices.Bradford;
25-
this.YCbCrMatrix = KnownYCbCrMatrices.BT601;
25+
this.YCbCrTransform = KnownYCbCrMatrices.BT601;
2626
}
2727

2828
/// <summary>
@@ -53,13 +53,13 @@ public ColorConversionOptions()
5353
/// <summary>
5454
/// Gets the YCbCr matrix to used to perform conversions from/to RGB.
5555
/// </summary>
56-
public YCbCrMatrix YCbCrMatrix
56+
public YCbCrTransform YCbCrTransform
5757
{
58-
get => this.yCbCrMatrix;
58+
get => this.yCbCrTransform;
5959
init
6060
{
61-
this.yCbCrMatrix = value;
62-
this.TransposedYCbCrMatrix = value.Transpose();
61+
this.yCbCrTransform = value;
62+
this.TransposedYCbCrTransform = value.Transpose();
6363
}
6464
}
6565

@@ -88,7 +88,7 @@ public Matrix4x4 AdaptationMatrix
8888
}
8989
}
9090

91-
internal YCbCrMatrix TransposedYCbCrMatrix { get; private set; }
91+
internal YCbCrTransform TransposedYCbCrTransform { get; private set; }
9292

9393
internal Matrix4x4 InverseAdaptationMatrix { get; private set; }
9494
}
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
33

4-
// <auto-generated />
5-
64
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
75

8-
namespace SixLabors.ImageSharp.ColorProfiles.Conversion.Icc;
6+
namespace SixLabors.ImageSharp.ColorProfiles.Icc;
97

10-
internal static class SrgbV4Profile
8+
internal static class CompactSrgbV4Profile
119
{
10+
private static readonly Lazy<IccProfile> LazyIccProfile = new(GetIccProfile);
11+
1212
// Generated using the sRGB-v4.icc profile found at https://github.com/saucecontrol/Compact-ICC-Profiles
13-
private static ReadOnlySpan<byte> Data => new byte[]
14-
{
13+
private static ReadOnlySpan<byte> Data =>
14+
[
1515
0, 0, 1, 224, 108, 99, 109, 115, 4, 32, 0, 0, 109, 110, 116, 114, 82, 71, 66, 32, 88, 89, 90, 32, 7, 226, 0, 3, 0,
1616
20, 0, 9, 0, 14, 0, 29, 97, 99, 115, 112, 77, 83, 70, 84, 0, 0, 0, 0, 115, 97, 119, 115, 99, 116, 114, 108, 0, 0,
1717
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 214, 0, 1, 0, 0, 0, 0, 211, 45, 104, 97, 110, 100, 163, 178, 171,
@@ -29,11 +29,9 @@ internal static class SrgbV4Profile
2929
3, 143, 88, 89, 90, 32, 0, 0, 0, 0, 0, 0, 98, 150, 0, 0, 183, 137, 0, 0, 24, 218, 88, 89, 90, 32, 0, 0, 0,
3030
0, 0, 0, 36, 160, 0, 0, 15, 133, 0, 0, 182, 196, 112, 97, 114, 97, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 102, 105,
3131
0, 0, 242, 167, 0, 0, 13, 89, 0, 0, 19, 208, 0, 0, 10, 91,
32-
};
32+
];
3333

34-
private static readonly Lazy<IccProfile> LazyIccProfile = new(() => GetIccProfile());
35-
36-
public static IccProfile GetProfile() => LazyIccProfile.Value;
34+
public static IccProfile Profile => LazyIccProfile.Value;
3735

3836
private static IccProfile GetIccProfile()
3937
{
@@ -42,4 +40,3 @@ private static IccProfile GetIccProfile()
4240
return new IccProfile(buffer);
4341
}
4442
}
45-

src/ImageSharp/ColorProfiles/KnownYCbCrMatrices.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public static class KnownYCbCrMatrices
1515
/// <summary>
1616
/// ITU-R BT.601 (SD video standard).
1717
/// </summary>
18-
public static readonly YCbCrMatrix BT601 = new(
18+
public static readonly YCbCrTransform BT601 = new(
1919
new Matrix4x4(
2020
0.299000F, 0.587000F, 0.114000F, 0F,
2121
-0.168736F, -0.331264F, 0.500000F, 0F,
@@ -31,7 +31,7 @@ public static class KnownYCbCrMatrices
3131
/// <summary>
3232
/// ITU-R BT.709 (HD video, sRGB standard).
3333
/// </summary>
34-
public static readonly YCbCrMatrix BT709 = new(
34+
public static readonly YCbCrTransform BT709 = new(
3535
new Matrix4x4(
3636
0.212600F, 0.715200F, 0.072200F, 0F,
3737
-0.114572F, -0.385428F, 0.500000F, 0F,
@@ -47,7 +47,7 @@ public static class KnownYCbCrMatrices
4747
/// <summary>
4848
/// ITU-R BT.2020 (UHD/4K video standard).
4949
/// </summary>
50-
public static readonly YCbCrMatrix BT2020 = new(
50+
public static readonly YCbCrTransform BT2020 = new(
5151
new Matrix4x4(
5252
0.262700F, 0.678000F, 0.059300F, 0F,
5353
-0.139630F, -0.360370F, 0.500000F, 0F,

src/ImageSharp/ColorProfiles/Rgb.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public static Rgb FromScaledVector4(Vector4 source)
9898
/// <returns>The <see cref="Vector4"/>.</returns>
9999
[MethodImpl(MethodImplOptions.AggressiveInlining)]
100100
public Vector4 ToScaledVector4()
101-
=> new(this.ToScaledVector3(), 1F);
101+
=> new(this.AsVector3Unsafe(), 1F);
102102

103103
/// <inheritdoc/>
104104
public static void ToScaledVector4(ReadOnlySpan<Rgb> source, Span<Vector4> destination)
@@ -154,7 +154,7 @@ public CieXyz ToProfileConnectingSpace(ColorConversionOptions options)
154154
Rgb linear = FromScaledVector4(options.SourceRgbWorkingSpace.Expand(this.ToScaledVector4()));
155155

156156
// Then convert to xyz
157-
return new CieXyz(Vector3.Transform(linear.ToScaledVector3(), GetRgbToCieXyzMatrix(options.SourceRgbWorkingSpace)));
157+
return new CieXyz(Vector3.Transform(linear.AsVector3Unsafe(), GetRgbToCieXyzMatrix(options.SourceRgbWorkingSpace)));
158158
}
159159

160160
/// <inheritdoc/>
@@ -171,7 +171,7 @@ public static void ToProfileConnectionSpace(ColorConversionOptions options, Read
171171
Rgb linear = FromScaledVector4(options.SourceRgbWorkingSpace.Expand(rgb.ToScaledVector4()));
172172

173173
// Then convert to xyz
174-
destination[i] = new CieXyz(Vector3.Transform(linear.ToScaledVector3(), matrix));
174+
destination[i] = new CieXyz(Vector3.Transform(linear.AsVector3Unsafe(), matrix));
175175
}
176176
}
177177

src/ImageSharp/ColorProfiles/Y.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ public Rgb ToProfileConnectingSpace(ColorConversionOptions options)
9090
/// <inheritdoc/>
9191
public static Y FromProfileConnectingSpace(ColorConversionOptions options, in Rgb source)
9292
{
93-
Matrix4x4 m = options.YCbCrMatrix.Forward;
94-
float offset = options.YCbCrMatrix.Offset.X;
93+
Matrix4x4 m = options.YCbCrTransform.Forward;
94+
float offset = options.YCbCrTransform.Offset.X;
9595
return new(Vector3.Dot(source.AsVector3Unsafe(), new Vector3(m.M11, m.M12, m.M13)) + offset);
9696
}
9797

src/ImageSharp/ColorProfiles/YCbCr.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ public static void FromScaledVector4(ReadOnlySpan<Vector4> source, Span<YCbCr> d
130130
public static YCbCr FromProfileConnectingSpace(ColorConversionOptions options, in Rgb source)
131131
{
132132
Vector3 rgb = source.AsVector3Unsafe();
133-
Matrix4x4 m = options.TransposedYCbCrMatrix.Forward;
134-
Vector3 offset = options.TransposedYCbCrMatrix.Offset;
133+
Matrix4x4 m = options.TransposedYCbCrTransform.Forward;
134+
Vector3 offset = options.TransposedYCbCrTransform.Offset;
135135

136136
return new YCbCr(Vector3.Transform(rgb, m) + offset, true);
137137
}
@@ -152,8 +152,8 @@ public static void FromProfileConnectionSpace(ColorConversionOptions options, Re
152152
/// <inheritdoc/>
153153
public Rgb ToProfileConnectingSpace(ColorConversionOptions options)
154154
{
155-
Matrix4x4 m = options.TransposedYCbCrMatrix.Inverse;
156-
Vector3 offset = options.TransposedYCbCrMatrix.Offset;
155+
Matrix4x4 m = options.TransposedYCbCrTransform.Inverse;
156+
Vector3 offset = options.TransposedYCbCrTransform.Offset;
157157
Vector3 normalized = this.AsVector3Unsafe() - offset;
158158

159159
return Rgb.FromScaledVector3(Vector3.Transform(normalized, m));

src/ImageSharp/ColorProfiles/YcbCrMatrix.cs renamed to src/ImageSharp/ColorProfiles/YCbCrTransform.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.ColorProfiles;
88

99
/// <summary>
1010
/// <para>
11-
/// Represents a YCbCr color matrix containing forward and inverse transformation matrices,
11+
/// Represents a YCbCr color transform containing forward and inverse transformation matrices,
1212
/// and the chrominance offsets to apply for full-range encoding
1313
/// </para>
1414
/// <para>
@@ -17,10 +17,10 @@ namespace SixLabors.ImageSharp.ColorProfiles;
1717
/// working spaces will produce incorrect conversions.
1818
/// </para>
1919
/// </summary>
20-
public readonly struct YCbCrMatrix
20+
public readonly struct YCbCrTransform
2121
{
2222
/// <summary>
23-
/// Initializes a new instance of the <see cref="YCbCrMatrix"/> struct.
23+
/// Initializes a new instance of the <see cref="YCbCrTransform"/> struct.
2424
/// </summary>
2525
/// <param name="forward">
2626
/// The forward transformation matrix from RGB to YCbCr. The matrix must include the
@@ -34,7 +34,7 @@ public readonly struct YCbCrMatrix
3434
/// The chrominance offsets to be added after the forward conversion,
3535
/// and subtracted before the inverse conversion. Usually <c>(0, 0.5, 0.5)</c>.
3636
/// </param>
37-
public YCbCrMatrix(Matrix4x4 forward, Matrix4x4 inverse, Vector3 offset)
37+
public YCbCrTransform(Matrix4x4 forward, Matrix4x4 inverse, Vector3 offset)
3838
{
3939
this.Forward = forward;
4040
this.Inverse = inverse;
@@ -56,6 +56,6 @@ public YCbCrMatrix(Matrix4x4 forward, Matrix4x4 inverse, Vector3 offset)
5656
/// </summary>
5757
public Vector3 Offset { get; }
5858

59-
internal YCbCrMatrix Transpose()
59+
internal YCbCrTransform Transpose()
6060
=> new(Matrix4x4.Transpose(this.Forward), Matrix4x4.Transpose(this.Inverse), this.Offset);
6161
}

src/ImageSharp/ColorProfiles/YccK.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ public static void FromScaledVector4(ReadOnlySpan<Vector4> source, Span<YccK> de
131131
/// <inheritdoc/>
132132
public Rgb ToProfileConnectingSpace(ColorConversionOptions options)
133133
{
134-
Matrix4x4 m = options.TransposedYCbCrMatrix.Inverse;
135-
Vector3 offset = options.TransposedYCbCrMatrix.Offset;
134+
Matrix4x4 m = options.TransposedYCbCrTransform.Inverse;
135+
Vector3 offset = options.TransposedYCbCrTransform.Offset;
136136
Vector3 normalized = this.AsVector3Unsafe() - offset;
137137

138138
return Rgb.FromScaledVector3(Vector3.Transform(normalized, m) * (1F - this.K));
@@ -141,8 +141,8 @@ public Rgb ToProfileConnectingSpace(ColorConversionOptions options)
141141
/// <inheritdoc/>
142142
public static YccK FromProfileConnectingSpace(ColorConversionOptions options, in Rgb source)
143143
{
144-
Matrix4x4 m = options.TransposedYCbCrMatrix.Forward;
145-
Vector3 offset = options.TransposedYCbCrMatrix.Offset;
144+
Matrix4x4 m = options.TransposedYCbCrTransform.Forward;
145+
Vector3 offset = options.TransposedYCbCrTransform.Offset;
146146

147147
Vector3 rgb = source.AsVector3Unsafe();
148148
float k = 1F - MathF.Max(rgb.X, MathF.Max(rgb.Y, rgb.Z));

src/ImageSharp/Formats/ColorProfileHandling.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,14 @@ public enum ColorProfileHandling
1313
/// </summary>
1414
Preserve,
1515

16+
/// <summary>
17+
/// Removes any embedded Standard sRGB ICC color profiles without transforming the pixels of the image.
18+
/// </summary>
19+
Compact,
20+
1621
/// <summary>
1722
/// Transforms the pixels of the image based on the conversion of any embedded ICC color profiles to sRGB V4 profile.
18-
/// The original profile is then replaced.
23+
/// The original profile is then removed.
1924
/// </summary>
2025
Convert
2126
}

0 commit comments

Comments
 (0)