diff --git a/src/ImageSharp/Common/Helpers/Numerics.cs b/src/ImageSharp/Common/Helpers/Numerics.cs index 7de838bc9..bfbaa1b31 100644 --- a/src/ImageSharp/Common/Helpers/Numerics.cs +++ b/src/ImageSharp/Common/Helpers/Numerics.cs @@ -968,7 +968,7 @@ namespace SixLabors.ImageSharp /// Tells whether input value is outside of the given range. /// /// Value. - /// Mininum value, inclusive. + /// Minimum value, inclusive. /// Maximum value, inclusive. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsOutOfRange(int value, int min, int max) diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs index 88dbcb882..3b2c765b3 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs @@ -65,13 +65,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors jpegDecoder.ParseStream(stream, spectralConverterGray, CancellationToken.None); // TODO: Should we pass through the CancellationToken from the tiff decoder? - using var decompressedBuffer = spectralConverterGray.GetPixelBuffer(CancellationToken.None); + using Buffer2D decompressedBuffer = spectralConverterGray.GetPixelBuffer(CancellationToken.None); CopyImageBytesToBuffer(buffer, decompressedBuffer); break; } - // If the PhotometricInterpretation is YCbCr we explicitly assume the JPEG data is in RGB color space. - // There seems no other way to determine that the JPEG data is RGB colorspace (no APP14 marker, componentId's are not RGB). case TiffPhotometricInterpretation.YCbCr: case TiffPhotometricInterpretation.Rgb: { @@ -82,7 +80,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors jpegDecoder.ParseStream(stream, spectralConverter, CancellationToken.None); // TODO: Should we pass through the CancellationToken from the tiff decoder? - using var decompressedBuffer = spectralConverter.GetPixelBuffer(CancellationToken.None); + using Buffer2D decompressedBuffer = spectralConverter.GetPixelBuffer(CancellationToken.None); CopyImageBytesToBuffer(buffer, decompressedBuffer); break; } diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrConverter.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrConverter.cs index c6594f908..41c3facd1 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrConverter.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrConverter.cs @@ -19,16 +19,16 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation private static readonly Rational[] DefaultLuma = { - new Rational(299, 1000), - new Rational(587, 1000), - new Rational(114, 1000) + new(299, 1000), + new(587, 1000), + new(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) + new(0, 1), new(255, 1), + new(128, 1), new(255, 1), + new(128, 1), new(255, 1) }; public YCbCrConverter(Rational[] referenceBlackAndWhite, Rational[] coefficients) diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs index 1cd3d2c0c..c595246a5 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs @@ -228,7 +228,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff /// The pixel format. /// The IFD tags. /// The token to monitor cancellation. - /// The tiff frame. + /// The tiff frame. private ImageFrame DecodeFrame(ExifProfile tags, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs index 6baf71466..206f06843 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs @@ -459,6 +459,13 @@ namespace SixLabors.ImageSharp.Formats.Tiff case TiffCompression.Jpeg: { options.CompressionType = TiffDecoderCompressionType.Jpeg; + + if (options.PhotometricInterpretation is TiffPhotometricInterpretation.YCbCr && options.JpegTables is null) + { + // Note: Setting PhotometricInterpretation to RGB here, since the jpeg decoder will handle the conversion of the pixel data. + options.PhotometricInterpretation = TiffPhotometricInterpretation.Rgb; + } + break; } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs index 01715cfc7..837ee0613 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs @@ -642,6 +642,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff [WithFile(RgbJpegCompressed, PixelTypes.Rgba32)] [WithFile(RgbWithStripsJpegCompressed, PixelTypes.Rgba32)] [WithFile(YCbCrJpegCompressed, PixelTypes.Rgba32)] + [WithFile(YCbCrJpegCompressed2, PixelTypes.Rgba32)] [WithFile(RgbJpegCompressedNoJpegTable, PixelTypes.Rgba32)] [WithFile(GrayscaleJpegCompressed, PixelTypes.Rgba32)] public void TiffDecoder_CanDecode_JpegCompressed(TestImageProvider provider) diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 842601144..e638180c7 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -834,6 +834,7 @@ namespace SixLabors.ImageSharp.Tests public const string RgbYCbCr888Contiguoush2v2 = "Tiff/rgb-ycbcr-contig-08_h2v2.tiff"; public const string RgbYCbCr888Contiguoush4v4 = "Tiff/rgb-ycbcr-contig-08_h4v4.tiff"; public const string YCbCrJpegCompressed = "Tiff/ycbcr_jpegcompressed.tiff"; + public const string YCbCrJpegCompressed2 = "Tiff/ycbcr_jpegcompressed2.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/ycbcr_jpegcompressed2.tiff b/tests/Images/Input/Tiff/ycbcr_jpegcompressed2.tiff new file mode 100644 index 000000000..26495d577 --- /dev/null +++ b/tests/Images/Input/Tiff/ycbcr_jpegcompressed2.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:533f92b6a45c2de4dc0f3cdb8debf45dcfe84790cfa652404b2f44e15f06e44f +size 38816