Skip to content

Commit 63b7ecd

Browse files
committed
Fix frame dispose operation handling
1 parent d933db7 commit 63b7ecd

File tree

6 files changed

+25
-20
lines changed

6 files changed

+25
-20
lines changed

src/ImageSharp/Formats/Png/PngDecoderCore.cs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,13 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
240240
currentFrameControl.Value,
241241
cancellationToken);
242242

243-
previousFrame = currentFrame;
244-
previousFrameControl = currentFrameControl;
243+
// if current frame dispose is restore to previous, then from future frame's perspective, it never happened
244+
if (currentFrameControl.Value.DisposeOperation != PngDisposalMethod.RestoreToPrevious)
245+
{
246+
previousFrame = currentFrame;
247+
previousFrameControl = currentFrameControl;
248+
}
249+
245250
break;
246251
case PngChunkType.Data:
247252

@@ -639,18 +644,18 @@ private void InitializeFrame<TPixel>(
639644
out ImageFrame<TPixel> frame)
640645
where TPixel : unmanaged, IPixel<TPixel>
641646
{
642-
// We create a clone of the previous frame and add it.
643-
// We will overpaint the difference of pixels on the current frame to create a complete image.
644-
// This ensures that we have enough pixel data to process without distortion. #2450
645647
frame = image.Frames.AddFrame(previousFrame ?? image.Frames.RootFrame);
646648

647-
// If the first `fcTL` chunk uses a `dispose_op` of APNG_DISPOSE_OP_PREVIOUS it should be treated as APNG_DISPOSE_OP_BACKGROUND.
648-
if (previousFrameControl.DisposeOperation == PngDisposalMethod.RestoreToBackground
649-
|| (previousFrame is null && previousFrameControl.DisposeOperation == PngDisposalMethod.RestoreToPrevious))
649+
// if restoring to before first frame, restore to background
650+
if (previousFrame is null && previousFrameControl.DisposeOperation == PngDisposalMethod.RestoreToPrevious)
651+
{
652+
Buffer2DRegion<TPixel> pixelRegion = frame.PixelBuffer.GetRegion();
653+
pixelRegion.Clear();
654+
}
655+
else if (previousFrameControl.DisposeOperation == PngDisposalMethod.RestoreToBackground)
650656
{
651657
Rectangle restoreArea = previousFrameControl.Bounds;
652-
Rectangle interest = Rectangle.Intersect(frame.Bounds(), restoreArea);
653-
Buffer2DRegion<TPixel> pixelRegion = frame.PixelBuffer.GetRegion(interest);
658+
Buffer2DRegion<TPixel> pixelRegion = frame.PixelBuffer.GetRegion(restoreArea);
654659
pixelRegion.Clear();
655660
}
656661

Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading

0 commit comments

Comments
 (0)