diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index dd5e16d7be..f2f06a2c73 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -204,18 +204,13 @@ public Image Decode(BufferedReadStream stream, CancellationToken break; case PngChunkType.FrameControl: frameCount++; - if (frameCount == this.maxFrames) - { - break; - } - currentFrame = null; currentFrameControl = this.ReadFrameControlChunk(chunk.Data.GetSpan()); break; case PngChunkType.FrameData: - if (frameCount == this.maxFrames) + if (frameCount >= this.maxFrames) { - break; + goto EOF; } if (image is null) @@ -271,6 +266,11 @@ public Image Decode(BufferedReadStream stream, CancellationToken previousFrameControl = currentFrameControl; } + if (frameCount >= this.maxFrames) + { + goto EOF; + } + break; case PngChunkType.Palette: this.palette = chunk.Data.GetSpan().ToArray(); @@ -389,7 +389,7 @@ public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellat break; case PngChunkType.FrameControl: ++frameCount; - if (frameCount == this.maxFrames) + if (frameCount >= this.maxFrames) { break; } @@ -397,7 +397,7 @@ public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellat lastFrameControl = this.ReadFrameControlChunk(chunk.Data.GetSpan()); break; case PngChunkType.FrameData: - if (frameCount == this.maxFrames) + if (frameCount >= this.maxFrames) { break; } diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs index 8d4bc3f461..11af57e39f 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs @@ -701,4 +701,14 @@ public void Decode_BadPalette(string file) string path = Path.GetFullPath(Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, file)); using Image image = Image.Load(path); } + + [Theory] + [WithFile(TestImages.Png.Issue2752, PixelTypes.Rgba32)] + public void CanDecodeJustOneFrame(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + DecoderOptions options = new() { MaxFrames = 1 }; + using Image image = provider.GetImage(PngDecoder.Instance, options); + Assert.Equal(1, image.Frames.Count); + } } diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 6526e702d6..847aac3478 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -156,6 +156,9 @@ public static class Png // Issue 2668: https://github.com/SixLabors/ImageSharp/issues/2668 public const string Issue2668 = "Png/issues/Issue_2668.png"; + // Issue 2752: https://github.com/SixLabors/ImageSharp/issues/2752 + public const string Issue2752 = "Png/issues/Issue_2752.png"; + public static class Bad { public const string MissingDataChunk = "Png/xdtn0g01.png"; diff --git a/tests/Images/Input/Png/issues/Issue_2752.png b/tests/Images/Input/Png/issues/Issue_2752.png new file mode 100644 index 0000000000..05863fbf2a --- /dev/null +++ b/tests/Images/Input/Png/issues/Issue_2752.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d4cb44eea721009c616de30a1f18c1de59635de4b313b13d685456a529ced97 +size 5590983