Browse Source

Stub code to prevent unnecessary stream copying on decode.

pull/2301/head
James Jackson-South 3 years ago
parent
commit
dd882691fc
  1. 22
      src/ImageSharp/Formats/ImageDecoder.cs
  2. 20
      tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs

22
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);

20
tests/ImageSharp.Tests/Image/ImageTests.ImageLoadTestBase.cs

@ -86,6 +86,26 @@ public partial class ImageTests
})
.Returns(this.localStreamReturnImageAgnostic);
this.localDecoder
.Setup(x => x.DecodeAsync<Rgba32>(It.IsAny<DecoderOptions>(), It.IsAny<Stream>(), It.IsAny<CancellationToken>()))
.Callback<DecoderOptions, Stream, CancellationToken>((_, 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<DecoderOptions>(), It.IsAny<Stream>(), It.IsAny<CancellationToken>()))
.Callback<DecoderOptions, Stream, CancellationToken>((_, s, _) =>
{
using var ms = new MemoryStream();
s.CopyTo(ms);
this.DecodedData = ms.ToArray();
})
.Returns(Task.FromResult<Image>(this.localStreamReturnImageAgnostic));
this.localMimeTypeDetector = new MockImageFormatDetector(this.localImageFormatMock.Object);
this.LocalConfiguration = new Configuration();

Loading…
Cancel
Save