diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
index cef8396d4b..f6dad651b7 100644
--- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
@@ -125,6 +125,11 @@ internal sealed class PngDecoderCore : ImageDecoderCore
///
private readonly int maxUncompressedLength;
+ ///
+ /// A value indicating whether the image data has been read.
+ ///
+ private bool hasImageData;
+
///
/// Initializes a new instance of the class.
///
@@ -746,7 +751,11 @@ private void ReadScanlines(
where TPixel : unmanaged, IPixel
{
using ZlibInflateStream inflateStream = new(this.currentStream, getData);
- inflateStream.AllocateNewBytes(chunkLength, true);
+ if (!inflateStream.AllocateNewBytes(chunkLength, !this.hasImageData))
+ {
+ return;
+ }
+
DeflateStream dataStream = inflateStream.CompressedStream!;
if (this.header.InterlaceMethod is PngInterlaceMode.Adam7)
@@ -800,7 +809,7 @@ private void DecodePixelData(
int bytesRead = compressedStream.Read(scanSpan, currentRowBytesRead, bytesPerFrameScanline - currentRowBytesRead);
if (bytesRead <= 0)
{
- return;
+ goto EXIT;
}
currentRowBytesRead += bytesRead;
@@ -845,6 +854,7 @@ private void DecodePixelData(
}
EXIT:
+ this.hasImageData = true;
blendMemory?.Dispose();
}
@@ -903,7 +913,7 @@ private void DecodeInterlacedPixelData(
int bytesRead = compressedStream.Read(this.scanline.GetSpan(), currentRowBytesRead, bytesPerInterlaceScanline - currentRowBytesRead);
if (bytesRead <= 0)
{
- return;
+ goto EXIT;
}
currentRowBytesRead += bytesRead;
@@ -976,6 +986,7 @@ private void DecodeInterlacedPixelData(
}
EXIT:
+ this.hasImageData = true;
blendMemory?.Dispose();
}
diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs
index 11af57e39f..5a5dd9aaa7 100644
--- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs
@@ -705,10 +705,20 @@ public void Decode_BadPalette(string file)
[Theory]
[WithFile(TestImages.Png.Issue2752, PixelTypes.Rgba32)]
public void CanDecodeJustOneFrame(TestImageProvider provider)
- where TPixel : unmanaged, IPixel
+ where TPixel : unmanaged, IPixel
{
DecoderOptions options = new() { MaxFrames = 1 };
using Image image = provider.GetImage(PngDecoder.Instance, options);
Assert.Equal(1, image.Frames.Count);
}
+
+ [Theory]
+ [WithFile(TestImages.Png.Issue2924, PixelTypes.Rgba32)]
+ public void CanDecode_Issue2924(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel
+ {
+ using Image image = provider.GetImage(PngDecoder.Instance);
+ image.DebugSave(provider);
+ image.CompareToReferenceOutput(provider);
+ }
}
diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs
index 6463f799b5..0c73860e9c 100644
--- a/tests/ImageSharp.Tests/TestImages.cs
+++ b/tests/ImageSharp.Tests/TestImages.cs
@@ -160,6 +160,9 @@ public static class Png
// Issue 2752: https://github.com/SixLabors/ImageSharp/issues/2752
public const string Issue2752 = "Png/issues/Issue_2752.png";
+ // Issue 2924: https://github.com/SixLabors/ImageSharp/issues/2924
+ public const string Issue2924 = "Png/issues/Issue_2924.png";
+
public static class Bad
{
public const string MissingDataChunk = "Png/xdtn0g01.png";
diff --git a/tests/Images/External/ReferenceOutput/PngDecoderTests/CanDecode_Issue2924_Rgba32_Issue_2924.png b/tests/Images/External/ReferenceOutput/PngDecoderTests/CanDecode_Issue2924_Rgba32_Issue_2924.png
new file mode 100644
index 0000000000..023f346e03
--- /dev/null
+++ b/tests/Images/External/ReferenceOutput/PngDecoderTests/CanDecode_Issue2924_Rgba32_Issue_2924.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4347cd89196c09496288724afdd876b227063149bba33615c338ebb474a0cb19
+size 47260
diff --git a/tests/Images/Input/Png/issues/Issue_2924.png b/tests/Images/Input/Png/issues/Issue_2924.png
new file mode 100644
index 0000000000..0454642190
--- /dev/null
+++ b/tests/Images/Input/Png/issues/Issue_2924.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fd366a2de522041c706729b01a6030df6c82a4e87ea3509cc78a47486f097044
+size 49376