Repository navigation
Jpeg colorspace is undefined after metadata only (Identify call) pass #1692
Copy link
Copy link
Closed
Labels
Description
Prerequisites
- I have written a descriptive issue title
- I have verified that I am running the latest version of ImageSharp
- I have verified if the problem exist in both
DEBUGandRELEASEmode - I have searched open and closed issues to ensure it has not already been reported
Description
Jpeg color space is undefined after metadataOnly decoding pass. This is happening because colorspace deduction (and metadata population) logic is locked behind if(!metadataOnly) check in SOF marker parsing (line 916):
ImageSharp/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
Lines 868 to 918 in fe65a38
| if (!metadataOnly) | |
| { | |
| remaining -= length; | |
| const int componentBytes = 3; | |
| if (remaining > this.ComponentCount * componentBytes) | |
| { | |
| JpegThrowHelper.ThrowBadMarker("SOFn", remaining); | |
| } | |
| stream.Read(this.temp, 0, remaining); | |
| // No need to pool this. They max out at 4 | |
| this.Frame.ComponentIds = new byte[this.ComponentCount]; | |
| this.Frame.ComponentOrder = new byte[this.ComponentCount]; | |
| this.Frame.Components = new JpegComponent[this.ComponentCount]; | |
| this.ColorSpace = this.DeduceJpegColorSpace(); | |
| int maxH = 0; | |
| int maxV = 0; | |
| int index = 0; | |
| for (int i = 0; i < this.ComponentCount; i++) | |
| { | |
| byte hv = this.temp[index + 1]; | |
| int h = (hv >> 4) & 15; | |
| int v = hv & 15; | |
| if (maxH < h) | |
| { | |
| maxH = h; | |
| } | |
| if (maxV < v) | |
| { | |
| maxV = v; | |
| } | |
| var component = new JpegComponent(this.Configuration.MemoryAllocator, this.Frame, this.temp[index], h, v, this.temp[index + 2], i); | |
| this.Frame.Components[i] = component; | |
| this.Frame.ComponentIds[i] = component.Id; | |
| index += componentBytes; | |
| } | |
| this.Frame.MaxHorizontalFactor = maxH; | |
| this.Frame.MaxVerticalFactor = maxV; | |
| this.ColorSpace = this.DeduceJpegColorSpace(); | |
| this.Metadata.GetJpegMetadata().ColorType = this.ColorSpace == JpegColorSpace.Grayscale ? JpegColorType.Luminance : JpegColorType.YCbCr; | |
| this.Frame.InitComponents(); | |
| this.ImageSizeInMCU = new Size(this.Frame.McusPerLine, this.Frame.McusPerColumn); |
Steps to Reproduce
var info = Image.Identify("image_path");
Console.WriteLine(info.Metadata.GetFormatMetadata(JpegFormat.Instance).ColorType.HasValue); // prints falseusing var image = Image.Load("image_path");
Console.WriteLine(image.Metadata.GetFormatMetadata(JpegFormat.Instance).ColorType.HasValue); // prints trueReactions are currently unavailable
Activity
br3aker commentedon Jul 11, 2021
As this breaks existing jpeg decoder tests it'll be fixed as part of #1597.
[-]Jpeg colorspace is undefined after [/-][+]Jpeg colorspace is undefined after metadata only (Identify call) pass[/+]JimBobSquarePants commentedon Jul 11, 2021
Ha! well spotted! We're deducing the colorspace 2 times. Once at line 884 and once at line 916 but hiding both in that block!