diff --git a/src/ImageSharp/Formats/ImageDecoder.cs b/src/ImageSharp/Formats/ImageDecoder.cs index b9bcd97e9..a93a9221b 100644 --- a/src/ImageSharp/Formats/ImageDecoder.cs +++ b/src/ImageSharp/Formats/ImageDecoder.cs @@ -212,8 +212,26 @@ public abstract class ImageDecoder : IImageDecoder // would incur synchronous IO reads which must be avoided in this asynchronous method. Instead, we will *always* run the // code below to copy the stream to an in-memory buffer before invoking the action. - // TODO: Avoid the existing double copy caused by calling IdentifyAsync followed by DecodeAsync. - // Perhaps we can make overloads accepting the chunked memorystream? Or maybe AOT is good with pattern matching against types? + // TODO: Enable these optimizations. Several Decode_Cancellation tests fail if enables as no exception is thrown. + // if (stream is MemoryStream ms) + // { + // return Action(ms, ms.Position, cancellationToken); + // } + + // if (stream is ChunkedMemoryStream cms) + // { + // return Action(cms, cms.Position, cancellationToken); + // } + + // if (stream is BufferedReadStream brs && brs.BaseStream is MemoryStream) + // { + // return Action(brs, brs.Position, cancellationToken); + // } + + // if (stream is BufferedReadStream brs2 && brs2.BaseStream is ChunkedMemoryStream) + // { + // return Action(brs2, brs2.Position, cancellationToken); + // } Configuration configuration = options.Configuration; using ChunkedMemoryStream memoryStream = new(configuration.MemoryAllocator); await stream.CopyToAsync(memoryStream, configuration.StreamProcessingBufferSize, cancellationToken).ConfigureAwait(false); diff --git a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs index 7a3296120..15e57b48a 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs @@ -86,6 +86,26 @@ public partial class ImageTests }) .Returns(this.localStreamReturnImageAgnostic); + this.localDecoder + .Setup(x => x.DecodeAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((_, s, _) => + { + using var ms = new MemoryStream(); + s.CopyTo(ms); + this.DecodedData = ms.ToArray(); + }) + .Returns(Task.FromResult(this.localStreamReturnImageRgba32)); + + this.localDecoder + .Setup(x => x.DecodeAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((_, s, _) => + { + using var ms = new MemoryStream(); + s.CopyTo(ms); + this.DecodedData = ms.ToArray(); + }) + .Returns(Task.FromResult(this.localStreamReturnImageAgnostic)); + this.localMimeTypeDetector = new MockImageFormatDetector(this.localImageFormatMock.Object); this.LocalConfiguration = new Configuration();