diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
index caa104c6e..3bc2ccf49 100644
--- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
@@ -228,8 +228,7 @@ internal sealed class PngDecoderCore : IImageDecoderInternals
PngThrowHelper.ThrowMissingFrameControl();
}
- previousFrameControl ??= new((uint)this.header.Width, (uint)this.header.Height);
- this.InitializeFrame(previousFrameControl.Value, currentFrameControl.Value, image, previousFrame, out currentFrame);
+ this.InitializeFrame(previousFrameControl, currentFrameControl.Value, image, previousFrame, out currentFrame);
this.currentStream.Position += 4;
this.ReadScanlines(
@@ -249,7 +248,7 @@ internal sealed class PngDecoderCore : IImageDecoderInternals
break;
case PngChunkType.Data:
-
+ pngMetadata.DefaultImageAnimated = currentFrameControl != null;
currentFrameControl ??= new((uint)this.header.Width, (uint)this.header.Height);
if (image is null)
{
@@ -266,9 +265,12 @@ internal sealed class PngDecoderCore : IImageDecoderInternals
this.ReadNextDataChunk,
currentFrameControl.Value,
cancellationToken);
+ if (pngMetadata.DefaultImageAnimated)
+ {
+ previousFrame = currentFrame;
+ previousFrameControl = currentFrameControl;
+ }
- previousFrame = currentFrame;
- previousFrameControl = currentFrameControl;
break;
case PngChunkType.Palette:
this.palette = chunk.Data.GetSpan().ToArray();
@@ -637,7 +639,7 @@ internal sealed class PngDecoderCore : IImageDecoderInternals
/// The previous frame.
/// The created frame
private void InitializeFrame(
- FrameControl previousFrameControl,
+ FrameControl? previousFrameControl,
FrameControl currentFrameControl,
Image image,
ImageFrame? previousFrame,
@@ -646,15 +648,15 @@ internal sealed class PngDecoderCore : IImageDecoderInternals
{
frame = image.Frames.AddFrame(previousFrame ?? image.Frames.RootFrame);
- // if restoring to before first frame, restore to background
- if (previousFrame is null && previousFrameControl.DisposeOperation == PngDisposalMethod.RestoreToPrevious)
+ // If restoring to before first frame, restore to background. Same if first frame (previousFrameControl null).
+ if (previousFrameControl == null || (previousFrame is null && previousFrameControl.Value.DisposeOperation == PngDisposalMethod.RestoreToPrevious))
{
Buffer2DRegion pixelRegion = frame.PixelBuffer.GetRegion();
pixelRegion.Clear();
}
- else if (previousFrameControl.DisposeOperation == PngDisposalMethod.RestoreToBackground)
+ else if (previousFrameControl.Value.DisposeOperation == PngDisposalMethod.RestoreToBackground)
{
- Rectangle restoreArea = previousFrameControl.Bounds;
+ Rectangle restoreArea = previousFrameControl.Value.Bounds;
Buffer2DRegion pixelRegion = frame.PixelBuffer.GetRegion(restoreArea);
pixelRegion.Clear();
}
diff --git a/src/ImageSharp/Formats/Png/PngMetadata.cs b/src/ImageSharp/Formats/Png/PngMetadata.cs
index 93ddcf263..c4ff3bbe2 100644
--- a/src/ImageSharp/Formats/Png/PngMetadata.cs
+++ b/src/ImageSharp/Formats/Png/PngMetadata.cs
@@ -83,6 +83,11 @@ public class PngMetadata : IDeepCloneable
///
public uint RepeatCount { get; set; } = 1;
+ ///
+ /// Gets or sets a value indicating whether the default image is shown as part of the animated sequence
+ ///
+ public bool DefaultImageAnimated { get; set; }
+
///
public IDeepCloneable DeepClone() => new PngMetadata(this);