Skip to content
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

Jpeg colorspace is undefined after metadata only (Identify call) pass #1692

Closed
4 tasks done
br3aker opened this issue Jul 11, 2021 · 2 comments · Fixed by #1694
Closed
4 tasks done

Jpeg colorspace is undefined after metadata only (Identify call) pass #1692

br3aker opened this issue Jul 11, 2021 · 2 comments · Fixed by #1694

Comments

@br3aker
Copy link
Contributor

br3aker commented Jul 11, 2021

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 DEBUG and RELEASE mode
  • 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):

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 false
using var image = Image.Load("image_path");
Console.WriteLine(image.Metadata.GetFormatMetadata(JpegFormat.Instance).ColorType.HasValue); // prints true
@br3aker
Copy link
Contributor Author

br3aker commented Jul 11, 2021

As this breaks existing jpeg decoder tests it'll be fixed as part of #1597.

@br3aker br3aker changed the title Jpeg colorspace is undefined after Jpeg colorspace is undefined after metadata only (Identify call) pass Jul 11, 2021
@JimBobSquarePants
Copy link
Member

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants