diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/IRawJpegData.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/IRawJpegData.cs
index b715eef98c..948f4dc8cc 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/IRawJpegData.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/IRawJpegData.cs
@@ -16,11 +16,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
///
Size ImageSizeInPixels { get; }
- ///
- /// Gets the number of components.
- ///
- int ComponentCount { get; }
-
///
/// Gets the color space
///
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegFrame.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegFrame.cs
index 3a136b4103..a1242a43a3 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegFrame.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegFrame.cs
@@ -84,6 +84,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
///
public int McusPerColumn { get; set; }
+ ///
+ /// Gets the color depth, in number of bits per pixel.
+ ///
+ public int BitsPerPixel => this.ComponentCount * this.Precision;
+
///
public void Dispose()
{
diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
index 45d08dadf5..0fd4b2f0f5 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
@@ -127,11 +127,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
///
public int ImageHeight => this.ImageSizeInPixels.Height;
- ///
- /// Gets the color depth, in number of bits per pixel.
- ///
- public int BitsPerPixel => this.ComponentCount * this.Frame.Precision;
-
///
/// Gets a value indicating whether the metadata should be ignored when the image is being decoded.
///
@@ -142,9 +137,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
///
public ImageMetadata Metadata { get; private set; }
- ///
- public int ComponentCount { get; private set; }
-
///
public JpegColorSpace ColorSpace { get; private set; }
@@ -222,7 +214,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
this.InitIptcProfile();
this.InitDerivedMetadataProperties();
- return new ImageInfo(new PixelTypeInfo(this.BitsPerPixel), this.ImageWidth, this.ImageHeight, this.Metadata);
+ return new ImageInfo(new PixelTypeInfo(this.Frame.BitsPerPixel), this.ImageWidth, this.ImageHeight, this.Metadata);
}
///
@@ -373,14 +365,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// Returns the correct colorspace based on the image component count
///
/// The
- private JpegColorSpace DeduceJpegColorSpace()
+ private JpegColorSpace DeduceJpegColorSpace(byte componentCount)
{
- if (this.ComponentCount == 1)
+ if (componentCount == 1)
{
return JpegColorSpace.Grayscale;
}
- if (this.ComponentCount == 3)
+ if (componentCount == 3)
{
if (!this.adobe.Equals(default) && this.adobe.ColorTransform == JpegConstants.Adobe.ColorTransformUnknown)
{
@@ -392,14 +384,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
return JpegColorSpace.YCbCr;
}
- if (this.ComponentCount == 4)
+ if (componentCount == 4)
{
return this.adobe.ColorTransform == JpegConstants.Adobe.ColorTransformYcck
? JpegColorSpace.Ycck
: JpegColorSpace.Cmyk;
}
- JpegThrowHelper.ThrowInvalidImageContentException($"Unsupported color mode. Supported component counts 1, 3, and 4; found {this.ComponentCount}");
+ JpegThrowHelper.ThrowInvalidImageContentException($"Unsupported color mode. Supported component counts 1, 3, and 4; found {componentCount}");
return default;
}
@@ -835,18 +827,21 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
JpegThrowHelper.ThrowInvalidImageContentException("Only 8-Bit and 12-Bit precision supported.");
}
- // 2 byte: height
+ // 2 byte: Height
int frameHeight = (this.temp[1] << 8) | this.temp[2];
- // 2 byte: width
+ // 2 byte: Width
int frameWidth = (this.temp[3] << 8) | this.temp[4];
// Validity check: width/height > 0 (they are upper-bounded by 2 byte max value so no need to check that)
if (frameHeight == 0 || frameWidth == 0)
{
- JpegThrowHelper.ThrowInvalidImageDimensions(this.Frame.PixelWidth, this.Frame.PixelHeight);
+ JpegThrowHelper.ThrowInvalidImageDimensions(frameWidth, frameHeight);
}
+ // 1 byte: Number of components
+ byte componentCount = this.temp[5];
+ this.ColorSpace = this.DeduceJpegColorSpace(componentCount);
this.Frame = new JpegFrame
{
@@ -855,13 +850,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
Precision = precision,
PixelHeight = frameHeight,
PixelWidth = frameWidth,
- ComponentCount = this.temp[5]
+ ComponentCount = componentCount
};
this.ImageSizeInPixels = new Size(this.Frame.PixelWidth, this.Frame.PixelHeight);
- this.ComponentCount = this.Frame.ComponentCount;
- this.ColorSpace = this.DeduceJpegColorSpace();
this.Metadata.GetJpegMetadata().ColorType = this.ColorSpace == JpegColorSpace.Grayscale ? JpegColorType.Luminance : JpegColorType.YCbCr;
if (!metadataOnly)
@@ -869,7 +862,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
remaining -= length;
const int componentBytes = 3;
- if (remaining > this.ComponentCount * componentBytes)
+ if (remaining > componentCount * componentBytes)
{
JpegThrowHelper.ThrowBadMarker("SOFn", remaining);
}
@@ -877,14 +870,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
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.Frame.ComponentIds = new byte[componentCount];
+ this.Frame.ComponentOrder = new byte[componentCount];
+ this.Frame.Components = new JpegComponent[componentCount];
int maxH = 0;
int maxV = 0;
int index = 0;
- for (int i = 0; i < this.ComponentCount; i++)
+ for (int i = 0; i < componentCount; i++)
{
byte hv = this.temp[index + 1];
int h = (hv >> 4) & 15;
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ParseStreamTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/ParseStreamTests.cs
index a124ec1918..2162ee13c6 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/ParseStreamTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/ParseStreamTests.cs
@@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
{
using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(TestImages.Jpeg.Baseline.Jpeg400))
{
- Assert.Equal(1, decoder.ComponentCount);
+ Assert.Equal(1, decoder.Frame.ComponentCount);
Assert.Equal(1, decoder.Components.Length);
Size expectedSizeInBlocks = decoder.ImageSizeInPixels.DivideRoundUp(8);
@@ -106,7 +106,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile))
{
- Assert.Equal(componentCount, decoder.ComponentCount);
+ Assert.Equal(componentCount, decoder.Frame.ComponentCount);
Assert.Equal(componentCount, decoder.Components.Length);
JpegComponent c0 = decoder.Components[0];