Skip to content

Commit 9b8ef10

Browse files
committed
Fix handling of case where default image isn't animated
1 parent d15a2e7 commit 9b8ef10

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
@@ -228,8 +228,7 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
228228
PngThrowHelper.ThrowMissingFrameControl();
229229
}
230230

231-
previousFrameControl ??= new((uint)this.header.Width, (uint)this.header.Height);
232-
this.InitializeFrame(previousFrameControl.Value, currentFrameControl.Value, image, previousFrame, out currentFrame);
231+
this.InitializeFrame(previousFrameControl, currentFrameControl.Value, image, previousFrame, out currentFrame);
233232

234233
this.currentStream.Position += 4;
235234
this.ReadScanlines(
@@ -249,7 +248,7 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
249248

250249
break;
251250
case PngChunkType.Data:
252-
251+
pngMetadata.DefaultImageAnimated = currentFrameControl != null;
253252
currentFrameControl ??= new((uint)this.header.Width, (uint)this.header.Height);
254253
if (image is null)
255254
{
@@ -266,9 +265,12 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
266265
this.ReadNextDataChunk,
267266
currentFrameControl.Value,
268267
cancellationToken);
268+
if (pngMetadata.DefaultImageAnimated)
269+
{
270+
previousFrame = currentFrame;
271+
previousFrameControl = currentFrameControl;
272+
}
269273

270-
previousFrame = currentFrame;
271-
previousFrameControl = currentFrameControl;
272274
break;
273275
case PngChunkType.Palette:
274276
this.palette = chunk.Data.GetSpan().ToArray();
@@ -637,7 +639,7 @@ private void InitializeImage<TPixel>(ImageMetadata metadata, FrameControl frameC
637639
/// <param name="previousFrame">The previous frame.</param>
638640
/// <param name="frame">The created frame</param>
639641
private void InitializeFrame<TPixel>(
640-
FrameControl previousFrameControl,
642+
FrameControl? previousFrameControl,
641643
FrameControl currentFrameControl,
642644
Image<TPixel> image,
643645
ImageFrame<TPixel>? previousFrame,
@@ -646,15 +648,15 @@ private void InitializeFrame<TPixel>(
646648
{
647649
frame = image.Frames.AddFrame(previousFrame ?? image.Frames.RootFrame);
648650

649-
// if restoring to before first frame, restore to background
650-
if (previousFrame is null && previousFrameControl.DisposeOperation == PngDisposalMethod.RestoreToPrevious)
651+
// If restoring to before first frame, restore to background. Same if first frame (previousFrameControl null).
652+
if (previousFrameControl == null || (previousFrame is null && previousFrameControl.Value.DisposeOperation == PngDisposalMethod.RestoreToPrevious))
651653
{
652654
Buffer2DRegion<TPixel> pixelRegion = frame.PixelBuffer.GetRegion();
653655
pixelRegion.Clear();
654656
}
655-
else if (previousFrameControl.DisposeOperation == PngDisposalMethod.RestoreToBackground)
657+
else if (previousFrameControl.Value.DisposeOperation == PngDisposalMethod.RestoreToBackground)
656658
{
657-
Rectangle restoreArea = previousFrameControl.Bounds;
659+
Rectangle restoreArea = previousFrameControl.Value.Bounds;
658660
Buffer2DRegion<TPixel> pixelRegion = frame.PixelBuffer.GetRegion(restoreArea);
659661
pixelRegion.Clear();
660662
}

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)