From 19270664b0e386e718c582759218bd606cbeef32 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 15 Feb 2019 21:55:16 +1100 Subject: [PATCH] Remove hardcoded subsampling. Fix #817 (#834) --- .../Jpeg/Components/Decoder/JpegComponent.cs | 38 +++++-------------- .../Formats/Jpg/JpegDecoderTests.Images.cs | 1 + tests/ImageSharp.Tests/TestImages.cs | 3 +- tests/Images/External | 2 +- .../Jpg/baseline/ycck-subsample-1222.jpg | 3 ++ 5 files changed, 17 insertions(+), 30 deletions(-) create mode 100644 tests/Images/Input/Jpg/baseline/ycck-subsample-1222.jpg diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponent.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponent.cs index ef03582d69..cfed5d535f 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponent.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponent.cs @@ -2,8 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using SixLabors.ImageSharp.Memory; using SixLabors.Memory; @@ -12,9 +10,9 @@ using SixLabors.Primitives; namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder { /// - /// Represents a single frame component + /// Represents a single frame component. /// - internal class JpegComponent : IDisposable, IJpegComponent + internal sealed class JpegComponent : IDisposable, IJpegComponent { private readonly MemoryAllocator memoryAllocator; @@ -31,12 +29,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder } /// - /// Gets the component Id + /// Gets the component Id. /// public byte Id { get; } /// - /// Gets or sets DC coefficient predictor + /// Gets or sets DC coefficient predictor. /// public int DcPredictor { get; set; } @@ -69,22 +67,22 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder public Size SamplingFactors { get; set; } /// - /// Gets the number of blocks per line + /// Gets the number of blocks per line. /// public int WidthInBlocks { get; private set; } /// - /// Gets the number of blocks per column + /// Gets the number of blocks per column. /// public int HeightInBlocks { get; private set; } /// - /// Gets or sets the index for the DC Huffman table + /// Gets or sets the index for the DC Huffman table. /// public int DCHuffmanTableId { get; set; } /// - /// Gets or sets the index for the AC Huffman table + /// Gets or sets the index for the AC Huffman table. /// public int ACHuffmanTableId { get; set; } @@ -109,24 +107,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder int blocksPerColumnForMcu = this.Frame.McusPerColumn * this.VerticalSamplingFactor; this.SizeInBlocks = new Size(blocksPerLineForMcu, blocksPerColumnForMcu); - // For 4-component images (either CMYK or YCbCrK), we only support two - // hv vectors: [0x11 0x11 0x11 0x11] and [0x22 0x11 0x11 0x22]. - // Theoretically, 4-component JPEG images could mix and match hv values - // but in practice, those two combinations are the only ones in use, - // and it simplifies the applyBlack code below if we can assume that: - // - for CMYK, the C and K channels have full samples, and if the M - // and Y channels subsample, they subsample both horizontally and - // vertically. - // - for YCbCrK, the Y and K channels have full samples. - if (this.Index == 0 || this.Index == 3) - { - this.SubSamplingDivisors = new Size(1, 1); - } - else - { - JpegComponent c0 = this.Frame.Components[0]; - this.SubSamplingDivisors = c0.SamplingFactors.DivideBy(this.SamplingFactors); - } + JpegComponent c0 = this.Frame.Components[0]; + this.SubSamplingDivisors = c0.SamplingFactors.DivideBy(this.SamplingFactors); int totalNumberOfBlocks = blocksPerColumnForMcu * (blocksPerLineForMcu + 1); int width = this.WidthInBlocks + 1; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs index 03f1826edd..9f34d7d09b 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs @@ -21,6 +21,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg TestImages.Jpeg.Baseline.Jpeg444, TestImages.Jpeg.Baseline.Bad.BadEOF, TestImages.Jpeg.Baseline.MultiScanBaselineCMYK, + TestImages.Jpeg.Baseline.YcckSubsample1222, TestImages.Jpeg.Baseline.Bad.BadRST, TestImages.Jpeg.Issues.MultiHuffmanBaseline394, TestImages.Jpeg.Issues.ExifDecodeOutOfRange694, diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 3a497683ad..e28caf6277 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -140,13 +140,14 @@ namespace SixLabors.ImageSharp.Tests public const string MultiScanBaselineCMYK = "Jpg/baseline/MultiScanBaselineCMYK.jpg"; public const string Ratio1x1 = "Jpg/baseline/ratio-1x1.jpg"; public const string Testorig12bit = "Jpg/baseline/testorig12.jpg"; + public const string YcckSubsample1222 = "Jpg/baseline/ycck-subsample-1222.jpg"; public static readonly string[] All = { Cmyk, Ycck, Exif, Floorplan, Calliphora, Turtle, GammaDalaiLamaGray, Hiyamugi, Jpeg400, Jpeg420Exif, Jpeg444, - Ratio1x1, Testorig12bit + Ratio1x1, Testorig12bit, YcckSubsample1222 }; } diff --git a/tests/Images/External b/tests/Images/External index 74995302e3..32dc8aec11 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit 74995302e3c9a5913f1cf09d71b15f888d0ec022 +Subproject commit 32dc8aec1109b681f056264e6bde1f3a76f08aba diff --git a/tests/Images/Input/Jpg/baseline/ycck-subsample-1222.jpg b/tests/Images/Input/Jpg/baseline/ycck-subsample-1222.jpg new file mode 100644 index 0000000000..17c23f1358 --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/ycck-subsample-1222.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca7c16a2984d14ebc483780d9d1e8c131eca01d89f53512cc7add538c93a38c6 +size 31527