diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs index 70f3a9202..083cae240 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs @@ -268,6 +268,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg while (fileMarker.Marker != JpegConstants.Markers.EOI || (fileMarker.Marker == JpegConstants.Markers.EOI && fileMarker.Invalid)) { + cancellationToken.ThrowIfCancellationRequested(); + if (!fileMarker.Invalid) { // Get the marker length diff --git a/src/ImageSharp/Image.FromFile.cs b/src/ImageSharp/Image.FromFile.cs index d3464d20d..eeb15e2ae 100644 --- a/src/ImageSharp/Image.FromFile.cs +++ b/src/ImageSharp/Image.FromFile.cs @@ -131,7 +131,8 @@ namespace SixLabors.ImageSharp /// public static async Task IdentifyAsync(Configuration configuration, string filePath, CancellationToken cancellationToken) { - (IImageInfo ImageInfo, IImageFormat Format) res = await IdentifyWithFormatAsync(configuration, filePath, cancellationToken); + (IImageInfo ImageInfo, IImageFormat Format) res = await IdentifyWithFormatAsync(configuration, filePath, cancellationToken) + .ConfigureAwait(false); return res.ImageInfo; } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs index 2bc64789e..086798cef 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs @@ -127,34 +127,44 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } [Theory] + [InlineData(TestImages.Jpeg.Baseline.Jpeg420Small, 0)] [InlineData(TestImages.Jpeg.Issues.ExifGetString750Transform, 1)] - [InlineData(TestImages.Jpeg.Issues.ExifGetString750Transform, 3)] + [InlineData(TestImages.Jpeg.Issues.ExifGetString750Transform, 10)] + [InlineData(TestImages.Jpeg.Issues.ExifGetString750Transform, 30)] [InlineData(TestImages.Jpeg.Issues.BadRstProgressive518, 1)] - [InlineData(TestImages.Jpeg.Issues.BadRstProgressive518, 3)] - public async Task Decode_IsCancellable(string fileName, int waitMilliseconds) + [InlineData(TestImages.Jpeg.Issues.BadRstProgressive518, 10)] + [InlineData(TestImages.Jpeg.Issues.BadRstProgressive518, 30)] + public async Task Decode_IsCancellable(string fileName, int cancellationDelayMs) { + // Decoding these huge files took 300ms on i7-8650U in 2020. 30ms should be safe for cancellation delay. string hugeFile = Path.Combine( TestEnvironment.InputImagesDirectoryFullPath, fileName); var cts = new CancellationTokenSource(); - cts.CancelAfter(waitMilliseconds); + if (cancellationDelayMs == 0) + { + cts.Cancel(); + } + else + { + cts.CancelAfter(cancellationDelayMs); + } + await Assert.ThrowsAsync(() => Image.LoadAsync(hugeFile, cts.Token)); } [Theory] - [InlineData(TestImages.Jpeg.Issues.ExifGetString750Transform, 1)] - [InlineData(TestImages.Jpeg.Issues.ExifGetString750Transform, 3)] - [InlineData(TestImages.Jpeg.Issues.BadRstProgressive518, 1)] - [InlineData(TestImages.Jpeg.Issues.BadRstProgressive518, 3)] - public async Task Identify_IsCancellable(string fileName, int waitMilliseconds) + [InlineData(TestImages.Jpeg.Issues.ExifGetString750Transform)] + [InlineData(TestImages.Jpeg.Issues.BadRstProgressive518)] + public async Task Identify_IsCancellable(string fileName) { string hugeFile = Path.Combine( TestEnvironment.InputImagesDirectoryFullPath, fileName); var cts = new CancellationTokenSource(); - cts.CancelAfter(waitMilliseconds); + cts.CancelAfter(TimeSpan.FromTicks(1)); await Assert.ThrowsAsync(() => Image.IdentifyAsync(hugeFile, cts.Token)); }