From 204fddd8355f3dcbb75dbec613102d7582010dc0 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 18 Jul 2022 13:11:24 +1000 Subject: [PATCH] Pass cancellation token to decompressors. --- .../Decompressors/DeflateTiffCompression.cs | 3 ++- .../Decompressors/JpegTiffCompression.cs | 16 +++++++--------- .../Decompressors/LzwTiffCompression.cs | 3 ++- .../ModifiedHuffmanTiffCompression.cs | 3 ++- .../Decompressors/NoneTiffCompression.cs | 3 ++- .../Decompressors/PackBitsTiffCompression.cs | 3 ++- .../Decompressors/T4TiffCompression.cs | 3 ++- .../Decompressors/T6TiffCompression.cs | 3 ++- .../Decompressors/WebpTiffCompression.cs | 5 +++-- .../Tiff/Compression/TiffBaseDecompressor.cs | 9 ++++++--- src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs | 6 ++++-- .../Compression/DeflateTiffCompressionTests.cs | 12 +++++------- .../Tiff/Compression/LzwTiffCompressionTests.cs | 6 +++--- .../Tiff/Compression/NoneTiffCompressionTests.cs | 2 +- .../Compression/PackBitsTiffCompressionTests.cs | 2 +- 15 files changed, 44 insertions(+), 35 deletions(-) diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs index 37debc9f6..ae89fce0e 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs @@ -3,6 +3,7 @@ using System; using System.IO.Compression; +using System.Threading; using SixLabors.ImageSharp.Compression.Zlib; using SixLabors.ImageSharp.Formats.Tiff.Constants; using SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation; @@ -40,7 +41,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors } /// - protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer) + protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer, CancellationToken cancellationToken) { long pos = stream.Position; using (var deframeStream = new ZlibInflateStream( diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs index babcb4516..ef44263a5 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs @@ -48,7 +48,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors } /// - protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer) + protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer, CancellationToken cancellationToken) { if (this.jpegTables != null) { @@ -60,12 +60,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors case TiffPhotometricInterpretation.WhiteIsZero: { using SpectralConverter spectralConverterGray = new GrayJpegSpectralConverter(configuration); - var scanDecoderGray = new HuffmanScanDecoder(stream, spectralConverterGray, CancellationToken.None); + var scanDecoderGray = new HuffmanScanDecoder(stream, spectralConverterGray, cancellationToken); jpegDecoder.LoadTables(this.jpegTables, scanDecoderGray); - jpegDecoder.ParseStream(stream, spectralConverterGray, CancellationToken.None); + jpegDecoder.ParseStream(stream, spectralConverterGray, cancellationToken); - // TODO: Should we pass through the CancellationToken from the tiff decoder? - using Buffer2D decompressedBuffer = spectralConverterGray.GetPixelBuffer(CancellationToken.None); + using Buffer2D decompressedBuffer = spectralConverterGray.GetPixelBuffer(cancellationToken); CopyImageBytesToBuffer(buffer, decompressedBuffer); break; } @@ -75,12 +74,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors { using SpectralConverter spectralConverter = new TiffJpegSpectralConverter(configuration, this.photometricInterpretation); - var scanDecoder = new HuffmanScanDecoder(stream, spectralConverter, CancellationToken.None); + var scanDecoder = new HuffmanScanDecoder(stream, spectralConverter, cancellationToken); jpegDecoder.LoadTables(this.jpegTables, scanDecoder); - jpegDecoder.ParseStream(stream, spectralConverter, CancellationToken.None); + jpegDecoder.ParseStream(stream, spectralConverter, cancellationToken); - // TODO: Should we pass through the CancellationToken from the tiff decoder? - using Buffer2D decompressedBuffer = spectralConverter.GetPixelBuffer(CancellationToken.None); + using Buffer2D decompressedBuffer = spectralConverter.GetPixelBuffer(cancellationToken); CopyImageBytesToBuffer(buffer, decompressedBuffer); break; } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwTiffCompression.cs index 57da76f6c..a53704abf 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwTiffCompression.cs @@ -2,6 +2,7 @@ // Licensed under the Six Labors Split License. using System; +using System.Threading; using SixLabors.ImageSharp.Formats.Tiff.Constants; using SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation; using SixLabors.ImageSharp.IO; @@ -35,7 +36,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors } /// - protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer) + protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer, CancellationToken cancellationToken) { var decoder = new TiffLzwDecoder(stream); decoder.DecodePixels(buffer); diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanTiffCompression.cs index 16d3f125b..c95048b68 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanTiffCompression.cs @@ -2,6 +2,7 @@ // Licensed under the Six Labors Split License. using System; +using System.Threading; using SixLabors.ImageSharp.Formats.Tiff.Constants; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Memory; @@ -40,7 +41,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors private TiffFillOrder FillOrder { get; } /// - protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer) + protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer, CancellationToken cancellationToken) { var bitReader = new ModifiedHuffmanBitReader(stream, this.FillOrder, byteCount); diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/NoneTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/NoneTiffCompression.cs index 291d40c85..6bec4e2ce 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/NoneTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/NoneTiffCompression.cs @@ -2,6 +2,7 @@ // Licensed under the Six Labors Split License. using System; +using System.Threading; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Memory; @@ -24,7 +25,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors } /// - protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer) + protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer, CancellationToken cancellationToken) => _ = stream.Read(buffer, 0, Math.Min(buffer.Length, byteCount)); /// diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs index 9df331b6e..230f9f5c9 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs @@ -3,6 +3,7 @@ using System; using System.Buffers; +using System.Threading; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Memory; @@ -27,7 +28,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors } /// - protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer) + protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer, CancellationToken cancellationToken) { if (this.compressedDataMemory == null) { diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs index 2fed2b742..e8513c474 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs @@ -2,6 +2,7 @@ // Licensed under the Six Labors Split License. using System; +using System.Threading; using SixLabors.ImageSharp.Formats.Tiff.Constants; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Memory; @@ -53,7 +54,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors private TiffFillOrder FillOrder { get; } /// - protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer) + protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer, CancellationToken cancellationToken) { if (this.faxCompressionOptions.HasFlag(FaxCompressionOptions.TwoDimensionalCoding)) { diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T6TiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T6TiffCompression.cs index 2373e7b9b..1a105e96a 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T6TiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T6TiffCompression.cs @@ -4,6 +4,7 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Threading; using SixLabors.ImageSharp.Formats.Tiff.Constants; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Memory; @@ -49,7 +50,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors private TiffFillOrder FillOrder { get; } /// - protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer) + protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer, CancellationToken cancellationToken) { int height = stripHeight; buffer.Clear(); diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs index e918837c1..d2461bfa2 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs @@ -3,6 +3,7 @@ using System; using System.Runtime.InteropServices; +using System.Threading; using SixLabors.ImageSharp.Formats.Tiff.Constants; using SixLabors.ImageSharp.Formats.Webp; using SixLabors.ImageSharp.IO; @@ -31,9 +32,9 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors => this.options = options; /// - protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer) + protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer, CancellationToken cancellationToken) { - using Image image = new WebpDecoder().Decode(this.options, stream, default); + using Image image = new WebpDecoder().Decode(this.options, stream, cancellationToken); CopyImageBytesToBuffer(buffer, image.Frames.RootFrame.PixelBuffer); } diff --git a/src/ImageSharp/Formats/Tiff/Compression/TiffBaseDecompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseDecompressor.cs index d828a7f4f..aaa3e9499 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/TiffBaseDecompressor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseDecompressor.cs @@ -3,6 +3,7 @@ using System; using System.IO; +using System.Threading; using SixLabors.ImageSharp.Formats.Tiff.Constants; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Memory; @@ -34,13 +35,14 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression /// The number of bytes to read from the input stream. /// The height of the strip. /// The output buffer for uncompressed data. - public void Decompress(BufferedReadStream stream, ulong stripOffset, ulong stripByteCount, int stripHeight, Span buffer) + /// The token to monitor cancellation. + public void Decompress(BufferedReadStream stream, ulong stripOffset, ulong stripByteCount, int stripHeight, Span buffer, CancellationToken cancellationToken) { DebugGuard.MustBeLessThanOrEqualTo(stripOffset, (ulong)long.MaxValue, nameof(stripOffset)); DebugGuard.MustBeLessThanOrEqualTo(stripByteCount, (ulong)long.MaxValue, nameof(stripByteCount)); stream.Seek((long)stripOffset, SeekOrigin.Begin); - this.Decompress(stream, (int)stripByteCount, stripHeight, buffer); + this.Decompress(stream, (int)stripByteCount, stripHeight, buffer, cancellationToken); if ((long)stripOffset + (long)stripByteCount < stream.Position) { @@ -55,6 +57,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression /// The number of bytes to read from the input stream. /// The height of the strip. /// The output buffer for uncompressed data. - protected abstract void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer); + /// The token to monitor cancellation. + protected abstract void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span buffer, CancellationToken cancellationToken); } } diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs index f2e5fc7de..6b3abbc9e 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs @@ -410,7 +410,8 @@ namespace SixLabors.ImageSharp.Formats.Tiff stripOffsets[stripIndex], stripByteCounts[stripIndex], stripHeight, - stripBuffers[planeIndex].GetSpan()); + stripBuffers[planeIndex].GetSpan(), + cancellationToken); stripIndex += stripsPerPlane; } @@ -498,7 +499,8 @@ namespace SixLabors.ImageSharp.Formats.Tiff stripOffsets[stripIndex], stripByteCounts[stripIndex], stripHeight, - stripBufferSpan); + stripBufferSpan, + cancellationToken); colorDecoder.Decode(stripBufferSpan, pixels, 0, top, frame.Width, stripHeight); } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs index ac775b712..12f20cd30 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs @@ -23,16 +23,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression [InlineData(new byte[] { 1, 2, 42, 53, 42, 53, 42, 53, 42, 53, 42, 53, 3, 4 })] // Repeated sequence public void Compress_Decompress_Roundtrip_Works(byte[] data) { - using (BufferedReadStream stream = CreateCompressedStream(data)) - { - var buffer = new byte[data.Length]; + using BufferedReadStream stream = CreateCompressedStream(data); + byte[] buffer = new byte[data.Length]; - using var decompressor = new DeflateTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffColorType.BlackIsZero8, TiffPredictor.None, false); + using var decompressor = new DeflateTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffColorType.BlackIsZero8, TiffPredictor.None, false); - decompressor.Decompress(stream, 0, (uint)stream.Length, 1, buffer); + decompressor.Decompress(stream, 0, (uint)stream.Length, 1, buffer, default); - Assert.Equal(data, buffer); - } + Assert.Equal(data, buffer); } private static BufferedReadStream CreateCompressedStream(byte[] data) diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs index b2bd316a4..197beade2 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs @@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression public void Compress_Works(byte[] inputData, byte[] expectedCompressedData) { - var compressedData = new byte[expectedCompressedData.Length]; + byte[] compressedData = new byte[expectedCompressedData.Length]; Stream streamData = CreateCompressedStream(inputData); streamData.Read(compressedData, 0, expectedCompressedData.Length); @@ -37,10 +37,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression public void Compress_Decompress_Roundtrip_Works(byte[] data) { using BufferedReadStream stream = CreateCompressedStream(data); - var buffer = new byte[data.Length]; + byte[] buffer = new byte[data.Length]; using var decompressor = new LzwTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffColorType.BlackIsZero8, TiffPredictor.None, false); - decompressor.Decompress(stream, 0, (uint)stream.Length, 1, buffer); + decompressor.Decompress(stream, 0, (uint)stream.Length, 1, buffer, default); Assert.Equal(data, buffer); } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/NoneTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/NoneTiffCompressionTests.cs index 33cac791e..ca457d15e 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/NoneTiffCompressionTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/NoneTiffCompressionTests.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression byte[] buffer = new byte[expectedResult.Length]; using var decompressor = new NoneTiffCompression(default, default, default); - decompressor.Decompress(stream, 0, byteCount, 1, buffer); + decompressor.Decompress(stream, 0, byteCount, 1, buffer, default); Assert.Equal(expectedResult, buffer); } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/PackBitsTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/PackBitsTiffCompressionTests.cs index 7f1452c41..4ed4330ec 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/PackBitsTiffCompressionTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/PackBitsTiffCompressionTests.cs @@ -31,7 +31,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression byte[] buffer = new byte[expectedResult.Length]; using var decompressor = new PackBitsTiffCompression(MemoryAllocator.Create(), default, default); - decompressor.Decompress(stream, 0, (uint)inputData.Length, 1, buffer); + decompressor.Decompress(stream, 0, (uint)inputData.Length, 1, buffer, default); Assert.Equal(expectedResult, buffer); }