-
-
Notifications
You must be signed in to change notification settings - Fork 874
Enable colorimetric normalization of JPEG image data during decode #2922
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Adds colorimetric normalization support for JPEG (and JPEG-compressed TIFF) data by embedding ICC-based conversions into the decoding pipeline.
- Introduces
DecoderOptions.ColorProfileHandling
to specify Preserve, Compact, or Convert behavior. - Extends grayscale and CMYK JPEG converters with
ConvertToRgbInPlaceWithIcc
paths and integrates ICC removal inImageDecoder
. - Renames and updates YCbCr types to
YCbCrTransform
, and adjusts color-profile classes for the new workflows.
Reviewed Changes
Copilot reviewed 59 out of 59 changed files in this pull request and generated no comments.
Show a summary per file
File | Description |
---|---|
src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleVector512.cs | Add ICC-aware override and repeat grayscale channel in vectorized path |
src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleVector256.cs | Add ICC-aware override and repeat grayscale channel in vectorized path |
src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleVector128.cs | Add ICC-aware override and repeat grayscale channel in vectorized path |
src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleScalar.cs | Implement scalar ICC conversion with buffer packing/unpacking |
src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykVector512.cs | Add ICC-aware override for CMYK vectorized converter |
src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykVector256.cs | Add ICC-aware override for CMYK vectorized converter |
src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykVector128.cs | Add ICC-aware override for CMYK vectorized converter |
src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykScalar.cs | Implement scalar ICC conversion for CMYK |
src/ImageSharp/Formats/ImageDecoder.cs | Invoke HandleIccProfile after decode/identify to strip profiles |
src/ImageSharp/Formats/DecoderOptions.cs | Expose ColorProfileHandling and add profile‐selection helpers |
src/ImageSharp/Formats/ColorProfileHandling.cs | Define Compact and update docs for enum |
src/ImageSharp/ColorProfiles/YccK.cs | Rename matrix references to YCbCrTransform |
src/ImageSharp/ColorProfiles/YCbCrTransform.cs | Rename YCbCrMatrix to YCbCrTransform and update ctor/docs |
src/ImageSharp/ColorProfiles/YCbCr.cs | Update property references to YCbCrTransform |
src/ImageSharp/ColorProfiles/Y.cs | Update transform references for Y channel |
src/ImageSharp/ColorProfiles/Rgb.cs | Replace ToScaledVector3 calls with AsVector3Unsafe |
src/ImageSharp/ColorProfiles/KnownYCbCrMatrices.cs | Rename constants to YCbCrTransform |
src/ImageSharp/ColorProfiles/Icc/CompactSrgbV4Profile.cs | Rename class to CompactSrgbV4Profile and adjust namespace |
src/ImageSharp/ColorProfiles/ColorConversionOptions.cs | Change YCbCrMatrix property to YCbCrTransform |
src/ImageSharp/Advanced/AotCompilerTools.cs | Update AOT stubs to match new GetPixelBuffer signatures |
Comments suppressed due to low confidence (5)
src/ImageSharp/ColorProfiles/ColorConversionOptions.cs:55
- Update this XML summary to reflect the renamed property (
YCbCrTransform
) and its semantics (e.g., "Gets the YCbCr transform used to perform conversions...").
/// Gets the YCbCr matrix to used to perform conversions from/to RGB.
src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleVector512.cs:22
- The
Configuration
type isn’t imported in this file, causing a compilation error; addusing SixLabors.ImageSharp;
at the top so thatConfiguration
is recognized.
public override void ConvertToRgbInPlaceWithIcc(Configuration configuration, in ComponentValues values, IccProfile profile)
src/ImageSharp/Formats/ImageDecoder.cs:325
- [nitpick] This logic is duplicated in two overloads; consider consolidating into a single generic or helper method to reduce code duplication.
private static void HandleIccProfile(DecoderOptions options, Image image)
src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleScalar.cs:54
- Allocating a new buffer for every decode may impact performance; consider reusing pooled buffers or using stackalloc for small images to reduce allocation overhead.
using IMemoryOwner<float> memoryOwner = configuration.MemoryAllocator.Allocate<float>(values.Component0.Length * 3);
src/ImageSharp/Formats/DecoderOptions.cs:72
- The out parameter
value
is overly generic and nullable despite theNotNullWhen(true)
annotation; rename it to a descriptive name (e.g.out IccProfile profileToConvert
) and consider making it non-nullable when returned true.
internal bool TryGetIccProfileForColorConversion(IccProfile? profile, [NotNullWhen(true)] out IccProfile? value)
(Sorry, misclicking!) Happy to take a look but will be in a couple of weeks after my break |
Prerequisites
Description
This PR adds support for normalizing color data in JPEG files (and TIFF files with JPEG compression) to sRGB during decoding.
A new
DecoderOptions.ColorProfileHandling
property controls this behavior with the following options:Several internal helper methods have been introduced to allow decoders to determine and apply the correct behavior.
All shared JPEG color converters now use a common scalar interleaving path to manipulate planar data for
ColorProfileConverter
. There's likely room for SIMD-based performance improvements here (AVX-512?).@waacton - might be of interest to you since it introduces questions around deriving RGB working spaces from ICC profiles which you are likely to better understand than I.
@saucecontrol - tagging you since your compact sRGB v4 profile implementation was invaluable (and shamelessly borrowed 😁).