From 1ec339458958cffc226a2089e9f4ad622505d785 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sun, 8 Aug 2021 19:30:01 +0200 Subject: [PATCH] Throw NotSupported exception when luma and chroma subsampling is not equal --- .../YCbCrTiffColor{TPixel}.cs | 32 +------------------ .../Formats/Tiff/TiffDecoderOptionsParser.cs | 12 +++++++ .../Formats/Tiff/TiffDecoderTests.cs | 1 + tests/ImageSharp.Tests/TestImages.cs | 4 +-- ...ig-08.tiff => flower-ycbcr-contig-08.tiff} | 0 5 files changed, 16 insertions(+), 33 deletions(-) rename tests/Images/Input/Tiff/{flower_ycbcr_contig-08.tiff => flower-ycbcr-contig-08.tiff} (100%) diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrTiffColor{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrTiffColor{TPixel}.cs index 55ad67a3cf..0678272124 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrTiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrTiffColor{TPixel}.cs @@ -12,37 +12,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation { private readonly YCbCrConverter converter; - private static readonly Rational[] DefaultLuma = - { - new Rational(299, 1000), - new Rational(587, 1000), - new Rational(114, 1000) - }; - - private static readonly Rational[] DefaultReferenceBlackWhite = - { - new Rational(0, 1), new Rational(255, 1), - new Rational(128, 1), new Rational(255, 1), - new Rational(128, 1), new Rational(255, 1) - }; - - public YCbCrTiffColor(Rational[] referenceBlackAndWhite, Rational[] coefficients) - { - referenceBlackAndWhite ??= DefaultReferenceBlackWhite; - coefficients ??= DefaultLuma; - - if (referenceBlackAndWhite.Length != 6) - { - TiffThrowHelper.ThrowImageFormatException("reference black and white array should have 6 entry's"); - } - - if (coefficients.Length != 3) - { - TiffThrowHelper.ThrowImageFormatException("luma coefficients array should have 6 entry's"); - } - - this.converter = new YCbCrConverter(referenceBlackAndWhite, coefficients); - } + public YCbCrTiffColor(Rational[] referenceBlackAndWhite, Rational[] coefficients) => this.converter = new YCbCrConverter(referenceBlackAndWhite, coefficients); /// public override void Decode(ReadOnlySpan data, Buffer2D pixels, int left, int top, int width, int height) diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs index 857509f87a..1d1473dc43 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs @@ -57,6 +57,12 @@ namespace SixLabors.ImageSharp.Formats.Tiff } } + ushort[] ycbcrSubSampling = exifProfile.GetValue(ExifTag.YCbCrSubsampling)?.Value; + if (ycbcrSubSampling != null && ycbcrSubSampling[0] != ycbcrSubSampling[1]) + { + TiffThrowHelper.ThrowNotSupported("ImageSharp only supports YCbCr images with equal luma and chroma samples."); + } + if (exifProfile.GetValue(ExifTag.StripRowCounts)?.Value != null) { TiffThrowHelper.ThrowNotSupported("Variable-sized strips are not supported."); @@ -274,6 +280,12 @@ namespace SixLabors.ImageSharp.Formats.Tiff TiffThrowHelper.ThrowNotSupported("The number of samples in the TIFF BitsPerSample entry is not supported."); } + ushort bitsPerChannel = options.BitsPerSample.Channel0; + if (bitsPerChannel != 8) + { + TiffThrowHelper.ThrowNotSupported("Only 8 bits per channel is supported for YCbCr images."); + } + options.ColorType = options.PlanarConfiguration == TiffPlanarConfiguration.Chunky ? TiffColorType.YCbCr : TiffColorType.YCbCrPlanar; break; diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs index 4b7438af4c..b2e2e2535d 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs @@ -160,6 +160,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff [Theory] [WithFile(FlowerYCbCr888Contiguous, PixelTypes.Rgba32)] + [WithFile(FlowerYCbCr888Planar, PixelTypes.Rgba32)] public void TiffDecoder_CanDecode_YCbCr_24Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 5c2d3ceb55..a79ff9da84 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -575,8 +575,8 @@ namespace SixLabors.ImageSharp.Tests public const string FlowerRgb888Contiguous = "Tiff/flower-rgb-contig-08.tiff"; public const string FlowerRgb888Planar6Strips = "Tiff/flower-rgb-planar-08-6strips.tiff"; public const string FlowerRgb888Planar15Strips = "Tiff/flower-rgb-planar-08-15strips.tiff"; - public const string FlowerYCbCr888Contiguous = "Tiff/flower_ycbcr_contig-08.tiff"; - public const string FlowerYCbCr888Planar = "Tiff/flower_ycbcr_planar-08.tiff"; + public const string FlowerYCbCr888Contiguous = "Tiff/flower-ycbcr-contig-08.tiff"; + public const string FlowerYCbCr888Planar = "Tiff/flower-ycbcr-planar-08.tiff"; public const string FlowerRgb444Contiguous = "Tiff/flower-rgb-contig-04.tiff"; public const string FlowerRgb444Planar = "Tiff/flower-rgb-planar-04.tiff"; public const string FlowerRgb222Contiguous = "Tiff/flower-rgb-contig-02.tiff"; diff --git a/tests/Images/Input/Tiff/flower_ycbcr_contig-08.tiff b/tests/Images/Input/Tiff/flower-ycbcr-contig-08.tiff similarity index 100% rename from tests/Images/Input/Tiff/flower_ycbcr_contig-08.tiff rename to tests/Images/Input/Tiff/flower-ycbcr-contig-08.tiff