Skip to content

Commit 5cd9872

Browse files
committed
Fix handling of case where default image isn't animated
1 parent b29962a commit 5cd9872

File tree

2 files changed

+17
-10
lines changed

2 files changed

+17
-10
lines changed

src/ImageSharp/Formats/Png/PngDecoderCore.cs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,7 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
234234
PngThrowHelper.ThrowMissingFrameControl();
235235
}
236236

237-
previousFrameControl ??= new((uint)this.header.Width, (uint)this.header.Height);
238-
this.InitializeFrame(previousFrameControl.Value, currentFrameControl.Value, image, previousFrame, out currentFrame);
237+
this.InitializeFrame(previousFrameControl, currentFrameControl.Value, image, previousFrame, out currentFrame);
239238

240239
this.currentStream.Position += 4;
241240
this.ReadScanlines(
@@ -255,7 +254,7 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
255254

256255
break;
257256
case PngChunkType.Data:
258-
257+
pngMetadata.DefaultImageAnimated = currentFrameControl != null;
259258
currentFrameControl ??= new((uint)this.header.Width, (uint)this.header.Height);
260259
if (image is null)
261260
{
@@ -272,9 +271,12 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
272271
this.ReadNextDataChunk,
273272
currentFrameControl.Value,
274273
cancellationToken);
274+
if (pngMetadata.DefaultImageAnimated)
275+
{
276+
previousFrame = currentFrame;
277+
previousFrameControl = currentFrameControl;
278+
}
275279

276-
previousFrame = currentFrame;
277-
previousFrameControl = currentFrameControl;
278280
break;
279281
case PngChunkType.Palette:
280282
this.palette = chunk.Data.GetSpan().ToArray();
@@ -643,7 +645,7 @@ private void InitializeImage<TPixel>(ImageMetadata metadata, FrameControl frameC
643645
/// <param name="previousFrame">The previous frame.</param>
644646
/// <param name="frame">The created frame</param>
645647
private void InitializeFrame<TPixel>(
646-
FrameControl previousFrameControl,
648+
FrameControl? previousFrameControl,
647649
FrameControl currentFrameControl,
648650
Image<TPixel> image,
649651
ImageFrame<TPixel>? previousFrame,
@@ -652,15 +654,15 @@ private void InitializeFrame<TPixel>(
652654
{
653655
frame = image.Frames.AddFrame(previousFrame ?? image.Frames.RootFrame);
654656

655-
// if restoring to before first frame, restore to background
656-
if (previousFrame is null && previousFrameControl.DisposeOperation == PngDisposalMethod.RestoreToPrevious)
657+
// If restoring to before first frame, restore to background. Same if first frame (previousFrameControl null).
658+
if (previousFrameControl == null || (previousFrame is null && previousFrameControl.Value.DisposeOperation == PngDisposalMethod.RestoreToPrevious))
657659
{
658660
Buffer2DRegion<TPixel> pixelRegion = frame.PixelBuffer.GetRegion();
659661
pixelRegion.Clear();
660662
}
661-
else if (previousFrameControl.DisposeOperation == PngDisposalMethod.RestoreToBackground)
663+
else if (previousFrameControl.Value.DisposeOperation == PngDisposalMethod.RestoreToBackground)
662664
{
663-
Rectangle restoreArea = previousFrameControl.Bounds;
665+
Rectangle restoreArea = previousFrameControl.Value.Bounds;
664666
Buffer2DRegion<TPixel> pixelRegion = frame.PixelBuffer.GetRegion(restoreArea);
665667
pixelRegion.Clear();
666668
}

src/ImageSharp/Formats/Png/PngMetadata.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ private PngMetadata(PngMetadata other)
8383
/// </summary>
8484
public uint RepeatCount { get; set; } = 1;
8585

86+
/// <summary>
87+
/// Gets or sets a value indicating whether the default image is shown as part of the animated sequence
88+
/// </summary>
89+
public bool DefaultImageAnimated { get; set; }
90+
8691
/// <inheritdoc/>
8792
public IDeepCloneable DeepClone() => new PngMetadata(this);
8893

0 commit comments

Comments
 (0)