diff --git a/src/ImageSharp/Image.FromStream.cs b/src/ImageSharp/Image.FromStream.cs index 0efdd5f65..eefb08776 100644 --- a/src/ImageSharp/Image.FromStream.cs +++ b/src/ImageSharp/Image.FromStream.cs @@ -588,7 +588,20 @@ public abstract partial class Image await stream.CopyToAsync(memoryStream, configuration.StreamProcessingBufferSize, cancellationToken).ConfigureAwait(false); memoryStream.Position = 0; - return action(memoryStream, cancellationToken); + T Action(Stream ms, CancellationToken ct) + { + // Reset the position of the seekable stream if we did not read to the end + // to allow additional reads. + T result = action(ms, ct); + if (stream.CanSeek && ms.Position != ms.Length) + { + stream.Position = ms.Position; + } + + return result; + } + + return Action(memoryStream, cancellationToken); } [DoesNotReturn] diff --git a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs index 3d50618e6..172821acc 100644 --- a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs +++ b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs @@ -61,6 +61,21 @@ public class GeneralFormatTests Assert.NotEqual(i[5, 5], j[5, 5]); } + [Fact] + public async Task ReadOriginIsRespectedOnLoadAsync() + { + using FileStream stream = File.OpenRead(TestFile.GetInputFileFullPath(TestImages.Png.Issue2259)); + using Image i = await Image.LoadAsync(stream); + long position1 = stream.Position; + Assert.NotEqual(0, position1); + + using Image j = await Image.LoadAsync(stream); + long position2 = stream.Position; + Assert.True(position2 > position1); + + Assert.NotEqual(i[5, 5], j[5, 5]); + } + [Fact] public void ImageCanEncodeToString() {