diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index 2247cd6b7b..8d47a9794b 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -176,7 +176,7 @@ internal sealed class PngDecoderCore : IImageDecoderInternals this.InitializeImage(metadata, out image); } - this.ReadScanlines(chunk, image.Frames.RootFrame, pngMetadata); + this.ReadScanlines(chunk, image.Frames.RootFrame, pngMetadata, cancellationToken); break; case PngChunkType.Palette: @@ -555,7 +555,8 @@ internal sealed class PngDecoderCore : IImageDecoderInternals /// The png chunk containing the compressed scanline data. /// The pixel data. /// The png metadata - private void ReadScanlines(PngChunk chunk, ImageFrame image, PngMetadata pngMetadata) + /// The cancellation token. + private void ReadScanlines(PngChunk chunk, ImageFrame image, PngMetadata pngMetadata, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { using ZlibInflateStream deframeStream = new(this.currentStream, this.ReadNextDataChunk); @@ -564,11 +565,11 @@ internal sealed class PngDecoderCore : IImageDecoderInternals if (this.header.InterlaceMethod == PngInterlaceMode.Adam7) { - this.DecodeInterlacedPixelData(dataStream, image, pngMetadata); + this.DecodeInterlacedPixelData(dataStream, image, pngMetadata, cancellationToken); } else { - this.DecodePixelData(dataStream, image, pngMetadata); + this.DecodePixelData(dataStream, image, pngMetadata, cancellationToken); } } @@ -579,11 +580,13 @@ internal sealed class PngDecoderCore : IImageDecoderInternals /// The compressed pixel data stream. /// The image to decode to. /// The png metadata - private void DecodePixelData(DeflateStream compressedStream, ImageFrame image, PngMetadata pngMetadata) + /// The CancellationToken + private void DecodePixelData(DeflateStream compressedStream, ImageFrame image, PngMetadata pngMetadata, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { while (this.currentRow < this.header.Height) { + cancellationToken.ThrowIfCancellationRequested(); Span scanlineSpan = this.scanline.GetSpan(); while (this.currentRowBytesRead < this.bytesPerScanline) { @@ -639,7 +642,8 @@ internal sealed class PngDecoderCore : IImageDecoderInternals /// The compressed pixel data stream. /// The current image. /// The png metadata. - private void DecodeInterlacedPixelData(DeflateStream compressedStream, ImageFrame image, PngMetadata pngMetadata) + /// The cancellation token. + private void DecodeInterlacedPixelData(DeflateStream compressedStream, ImageFrame image, PngMetadata pngMetadata, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { int pass = 0; @@ -661,6 +665,7 @@ internal sealed class PngDecoderCore : IImageDecoderInternals while (this.currentRow < this.header.Height) { + cancellationToken.ThrowIfCancellationRequested(); while (this.currentRowBytesRead < bytesPerInterlaceScanline) { int bytesRead = compressedStream.Read(this.scanline.GetSpan(), this.currentRowBytesRead, bytesPerInterlaceScanline - this.currentRowBytesRead); diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs b/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs index 9e97854003..06cbe9ac0d 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs @@ -89,7 +89,7 @@ public partial class ImageTests await Assert.ThrowsAnyAsync(async () => { using Image image = await Image.LoadAsync(options, "someFakeFile", cts.Token); - }).WaitAsync(TimeSpan.FromSeconds(60)); + }).WaitAsync(TimeSpan.FromSeconds(30)); } } }