From 2e89d3c932b05c4bb81737e1e8d8e6ae9168a31a Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sun, 15 Aug 2021 08:55:18 +0200 Subject: [PATCH] Fix deduce jpeg color type --- src/ImageSharp/Formats/Jpeg/JpegColorType.cs | 2 +- .../Formats/Jpeg/JpegDecoderCore.cs | 52 +++++++++++++------ 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/JpegColorType.cs b/src/ImageSharp/Formats/Jpeg/JpegColorType.cs index a0b9c7fe68..11d5f65a4c 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegColorType.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegColorType.cs @@ -30,6 +30,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg /// /// The pixel data will be preserved as RGB without any sub sampling. /// - Rgb, + Rgb = 3, } } diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs index 13049dda12..343362f6c8 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs @@ -409,8 +409,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg /// /// Returns the correct colorspace based on the image component count and the jpeg frame component id's. /// + /// The number of components. /// The - private JpegColorSpace DeduceJpegColorSpace(byte componentCount, JpegComponent[] components) + private JpegColorSpace DeduceJpegColorSpace(byte componentCount) { if (componentCount == 1) { @@ -425,7 +426,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg } // If the component Id's are R, G, B in ASCII the colorspace is RGB and not YCbCr. - if (components[2].Id == 66 && components[1].Id == 71 && components[0].Id == 82) + if (this.Components[2].Id == 66 && this.Components[1].Id == 71 && this.Components[0].Id == 82) { return JpegColorSpace.RGB; } @@ -446,6 +447,35 @@ namespace SixLabors.ImageSharp.Formats.Jpeg return default; } + /// + /// Returns the jpeg color type based on the colorspace and subsampling used. + /// + /// Jpeg color type. + private JpegColorType DeduceJpegColorType() + { + switch (this.ColorSpace) + { + case JpegColorSpace.Grayscale: + return JpegColorType.Luminance; + case JpegColorSpace.RGB: + return JpegColorType.Rgb; + case JpegColorSpace.YCbCr: + if (this.Frame.Components[0].HorizontalSamplingFactor == 1 && this.Frame.Components[0].VerticalSamplingFactor == 1 && + this.Frame.Components[1].HorizontalSamplingFactor == 1 && this.Frame.Components[1].VerticalSamplingFactor == 1 && + this.Frame.Components[2].HorizontalSamplingFactor == 1 && this.Frame.Components[2].VerticalSamplingFactor == 1) + { + return JpegColorType.YCbCrRatio444; + } + else + { + return JpegColorType.YCbCrRatio420; + } + + default: + return JpegColorType.YCbCrRatio420; + } + } + /// /// Initializes the EXIF profile. /// @@ -859,7 +889,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg } /// - /// Processes the Start of Frame marker. Specified in section B.2.2. + /// Processes the Start of Frame marker. Specified in section B.2.2. /// /// The input stream. /// The remaining bytes in the segment block. @@ -951,20 +981,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg index += componentBytes; } - this.ColorSpace = this.DeduceJpegColorSpace(componentCount, this.Frame.Components); - - switch (this.ColorSpace) - { - case JpegColorSpace.Grayscale: - this.Metadata.GetJpegMetadata().ColorType = JpegColorType.Luminance; - break; - case JpegColorSpace.RGB: - this.Metadata.GetJpegMetadata().ColorType = JpegColorType.Rgb; - break; - default: - this.Metadata.GetJpegMetadata().ColorType = JpegColorType.YCbCrRatio420; - break; - } + this.ColorSpace = this.DeduceJpegColorSpace(componentCount); + this.Metadata.GetJpegMetadata().ColorType = this.DeduceJpegColorType(); if (!metadataOnly) {