Browse Source

Fix frame dispose operation handling

pull/2713/head
SpaceCheetah 2 years ago
parent
commit
63b7ecd87e
No known key found for this signature in database GPG Key ID: A60F20D29141DFF9
  1. 25
      src/ImageSharp/Formats/Png/PngDecoderCore.cs
  2. 4
      tests/Images/External/ReferenceOutput/PngDecoderTests/Decode_VerifyAllFrames_Rgba32_frame-offset.png/00.png
  3. 4
      tests/Images/External/ReferenceOutput/PngDecoderTests/Decode_VerifyAllFrames_Rgba32_frame-offset.png/01.png
  4. 4
      tests/Images/External/ReferenceOutput/PngDecoderTests/Decode_VerifyAllFrames_Rgba32_frame-offset.png/02.png
  5. 4
      tests/Images/External/ReferenceOutput/PngDecoderTests/Decode_VerifyAllFrames_Rgba32_frame-offset.png/03.png
  6. 4
      tests/Images/External/ReferenceOutput/PngDecoderTests/Decode_VerifyAllFrames_Rgba32_frame-offset.png/04.png

25
src/ImageSharp/Formats/Png/PngDecoderCore.cs

@ -240,8 +240,13 @@ internal sealed class PngDecoderCore : IImageDecoderInternals
currentFrameControl.Value,
cancellationToken);
previousFrame = currentFrame;
previousFrameControl = currentFrameControl;
// if current frame dispose is restore to previous, then from future frame's perspective, it never happened
if (currentFrameControl.Value.DisposeOperation != PngDisposalMethod.RestoreToPrevious)
{
previousFrame = currentFrame;
previousFrameControl = currentFrameControl;
}
break;
case PngChunkType.Data:
@ -639,18 +644,18 @@ internal sealed class PngDecoderCore : IImageDecoderInternals
out ImageFrame<TPixel> frame)
where TPixel : unmanaged, IPixel<TPixel>
{
// We create a clone of the previous frame and add it.
// We will overpaint the difference of pixels on the current frame to create a complete image.
// This ensures that we have enough pixel data to process without distortion. #2450
frame = image.Frames.AddFrame(previousFrame ?? image.Frames.RootFrame);
// If the first `fcTL` chunk uses a `dispose_op` of APNG_DISPOSE_OP_PREVIOUS it should be treated as APNG_DISPOSE_OP_BACKGROUND.
if (previousFrameControl.DisposeOperation == PngDisposalMethod.RestoreToBackground
|| (previousFrame is null && previousFrameControl.DisposeOperation == PngDisposalMethod.RestoreToPrevious))
// if restoring to before first frame, restore to background
if (previousFrame is null && previousFrameControl.DisposeOperation == PngDisposalMethod.RestoreToPrevious)
{
Buffer2DRegion<TPixel> pixelRegion = frame.PixelBuffer.GetRegion();
pixelRegion.Clear();
}
else if (previousFrameControl.DisposeOperation == PngDisposalMethod.RestoreToBackground)
{
Rectangle restoreArea = previousFrameControl.Bounds;
Rectangle interest = Rectangle.Intersect(frame.Bounds(), restoreArea);
Buffer2DRegion<TPixel> pixelRegion = frame.PixelBuffer.GetRegion(interest);
Buffer2DRegion<TPixel> pixelRegion = frame.PixelBuffer.GetRegion(restoreArea);
pixelRegion.Clear();
}

4
tests/Images/External/ReferenceOutput/PngDecoderTests/Decode_VerifyAllFrames_Rgba32_frame-offset.png/00.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:84e2353264e3488122f4d488d7c4b198ff5192ad0c662c7fb0a369c957ecc7ea
size 353
oid sha256:b85aaf7153e0ca538856a58d7b069bcc13fadc468ea603c85f8782cc691f86c3
size 387

4
tests/Images/External/ReferenceOutput/PngDecoderTests/Decode_VerifyAllFrames_Rgba32_frame-offset.png/01.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2916711d3f4d72eb66a5cfc2b40a3318eb4cce5b367658cfc7e3b573fd39cc33
size 693
oid sha256:fcb83d6893dcfd869b764ff9846c259eaa0caf26cec3f0fc2cbae2c26f2eeaa5
size 660

4
tests/Images/External/ReferenceOutput/PngDecoderTests/Decode_VerifyAllFrames_Rgba32_frame-offset.png/02.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7f9d5503414ccefa6b66661b1e93c2c3f6e4491f14af006a71153cecf43b52f5
size 806
oid sha256:562ec382f6d2af68e66092bf6949f66147d5f608d3c618eea5a7c1ea400737ff
size 768

4
tests/Images/External/ReferenceOutput/PngDecoderTests/Decode_VerifyAllFrames_Rgba32_frame-offset.png/03.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fe42b7dc6524d5589ad680650f4bcd181319b40b258b31e0932d6e936818e980
size 570
oid sha256:d12a7791b960072e32b78bd9aaf456dc99341eea1c66ea05050433d8c082c6ac
size 579

4
tests/Images/External/ReferenceOutput/PngDecoderTests/Decode_VerifyAllFrames_Rgba32_frame-offset.png/04.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8002ff5b3451b348f285eec15dd7a093c62d11d8b77c3ead9ac89ca6eb29977d
size 669
oid sha256:2db38d7ffcc95c23a5c94a06f10c6cc67406ae581a955c99ede4af97b1a044f8
size 628

Loading…
Cancel
Save