Skip to content

Commit c661ab1

Browse files
authored
Merge pull request #1985 from SixLabors/bp/webpanimation
Add support for decoding webp images with animations
2 parents 5634228 + 980a1f0 commit c661ab1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1292
-399
lines changed

src/ImageSharp/Formats/Gif/GifDecoderCore.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public GifDecoderCore(Configuration configuration, IGifDecoderOptions options)
9494
/// <summary>
9595
/// Gets the dimensions of the image.
9696
/// </summary>
97-
public Size Dimensions => new Size(this.imageDescriptor.Width, this.imageDescriptor.Height);
97+
public Size Dimensions => new(this.imageDescriptor.Width, this.imageDescriptor.Height);
9898

9999
private MemoryAllocator MemoryAllocator => this.Configuration.MemoryAllocator;
100100

src/ImageSharp/Formats/Gif/GifFormat.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Six Labors.
1+
// Copyright (c) Six Labors.
22
// Licensed under the Apache License, Version 2.0.
33

44
using System.Collections.Generic;
@@ -17,7 +17,7 @@ private GifFormat()
1717
/// <summary>
1818
/// Gets the current instance.
1919
/// </summary>
20-
public static GifFormat Instance { get; } = new GifFormat();
20+
public static GifFormat Instance { get; } = new();
2121

2222
/// <inheritdoc/>
2323
public string Name => "GIF";
@@ -32,9 +32,9 @@ private GifFormat()
3232
public IEnumerable<string> FileExtensions => GifConstants.FileExtensions;
3333

3434
/// <inheritdoc/>
35-
public GifMetadata CreateDefaultFormatMetadata() => new GifMetadata();
35+
public GifMetadata CreateDefaultFormatMetadata() => new();
3636

3737
/// <inheritdoc/>
38-
public GifFrameMetadata CreateDefaultFormatFrameMetadata() => new GifFrameMetadata();
38+
public GifFrameMetadata CreateDefaultFormatFrameMetadata() => new();
3939
}
4040
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Apache License, Version 2.0.
3+
4+
namespace SixLabors.ImageSharp.Formats.Webp
5+
{
6+
/// <summary>
7+
/// Indicates how transparent pixels of the current frame are to be blended with corresponding pixels of the previous canvas.
8+
/// </summary>
9+
internal enum AnimationBlendingMethod
10+
{
11+
/// <summary>
12+
/// Use alpha blending. After disposing of the previous frame, render the current frame on the canvas using alpha-blending.
13+
/// If the current frame does not have an alpha channel, assume alpha value of 255, effectively replacing the rectangle.
14+
/// </summary>
15+
AlphaBlending = 0,
16+
17+
/// <summary>
18+
/// Do not blend. After disposing of the previous frame,
19+
/// render the current frame on the canvas by overwriting the rectangle covered by the current frame.
20+
/// </summary>
21+
DoNotBlend = 1
22+
}
23+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Apache License, Version 2.0.
3+
4+
namespace SixLabors.ImageSharp.Formats.Webp
5+
{
6+
/// <summary>
7+
/// Indicates how the current frame is to be treated after it has been displayed (before rendering the next frame) on the canvas.
8+
/// </summary>
9+
internal enum AnimationDisposalMethod
10+
{
11+
/// <summary>
12+
/// Do not dispose. Leave the canvas as is.
13+
/// </summary>
14+
DoNotDispose = 0,
15+
16+
/// <summary>
17+
/// Dispose to background color. Fill the rectangle on the canvas covered by the current frame with background color specified in the ANIM chunk.
18+
/// </summary>
19+
Dispose = 1
20+
}
21+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Apache License, Version 2.0.
3+
4+
namespace SixLabors.ImageSharp.Formats.Webp
5+
{
6+
internal struct AnimationFrameData
7+
{
8+
/// <summary>
9+
/// The animation chunk size.
10+
/// </summary>
11+
public uint DataSize;
12+
13+
/// <summary>
14+
/// The X coordinate of the upper left corner of the frame is Frame X * 2.
15+
/// </summary>
16+
public uint X;
17+
18+
/// <summary>
19+
/// The Y coordinate of the upper left corner of the frame is Frame Y * 2.
20+
/// </summary>
21+
public uint Y;
22+
23+
/// <summary>
24+
/// The width of the frame.
25+
/// </summary>
26+
public uint Width;
27+
28+
/// <summary>
29+
/// The height of the frame.
30+
/// </summary>
31+
public uint Height;
32+
33+
/// <summary>
34+
/// The time to wait before displaying the next frame, in 1 millisecond units.
35+
/// Note the interpretation of frame duration of 0 (and often smaller then 10) is implementation defined.
36+
/// </summary>
37+
public uint Duration;
38+
39+
/// <summary>
40+
/// Indicates how transparent pixels of the current frame are to be blended with corresponding pixels of the previous canvas.
41+
/// </summary>
42+
public AnimationBlendingMethod BlendingMethod;
43+
44+
/// <summary>
45+
/// Indicates how the current frame is to be treated after it has been displayed (before rendering the next frame) on the canvas.
46+
/// </summary>
47+
public AnimationDisposalMethod DisposalMethod;
48+
}
49+
}

src/ImageSharp/Formats/Webp/IWebpDecoderOptions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Apache License, Version 2.0.
33

4+
using SixLabors.ImageSharp.Metadata;
5+
46
namespace SixLabors.ImageSharp.Formats.Webp
57
{
68
/// <summary>
@@ -12,5 +14,10 @@ internal interface IWebpDecoderOptions
1214
/// Gets a value indicating whether the metadata should be ignored when the image is being decoded.
1315
/// </summary>
1416
bool IgnoreMetadata { get; }
17+
18+
/// <summary>
19+
/// Gets the decoding mode for multi-frame images.
20+
/// </summary>
21+
FrameDecodingMode DecodingMode { get; }
1522
}
1623
}

src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public WebpLosslessDecoder(Vp8LBitReader bitReader, MemoryAllocator memoryAlloca
8787
private static ReadOnlySpan<byte> LiteralMap => new byte[] { 0, 1, 1, 1, 0 };
8888

8989
/// <summary>
90-
/// Decodes the image from the stream using the bitreader.
90+
/// Decodes the lossless webp image from the stream.
9191
/// </summary>
9292
/// <typeparam name="TPixel">The pixel format.</typeparam>
9393
/// <param name="pixels">The pixel buffer to store the decoded data.</param>

src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,16 @@ public WebpLossyDecoder(Vp8BitReader bitReader, MemoryAllocator memoryAllocator,
5757
this.configuration = configuration;
5858
}
5959

60-
public void Decode<TPixel>(Buffer2D<TPixel> pixels, int width, int height, WebpImageInfo info)
60+
/// <summary>
61+
/// Decodes the lossless webp image from the stream.
62+
/// </summary>
63+
/// <typeparam name="TPixel">The pixel format.</typeparam>
64+
/// <param name="pixels">The pixel buffer to store the decoded data.</param>
65+
/// <param name="width">The width of the image.</param>
66+
/// <param name="height">The height of the image.</param>
67+
/// <param name="info">Information about the image.</param>
68+
/// <param name="alphaData">The ALPH chunk data.</param>
69+
public void Decode<TPixel>(Buffer2D<TPixel> pixels, int width, int height, WebpImageInfo info, IMemoryOwner<byte> alphaData)
6170
where TPixel : unmanaged, IPixel<TPixel>
6271
{
6372
// Paragraph 9.2: color space and clamp type follow.
@@ -105,7 +114,7 @@ public void Decode<TPixel>(Buffer2D<TPixel> pixels, int width, int height, WebpI
105114
using (var alphaDecoder = new AlphaDecoder(
106115
width,
107116
height,
108-
info.Features.AlphaData,
117+
alphaData,
109118
info.Features.AlphaChunkHeader,
110119
this.memoryAllocator,
111120
this.configuration))

src/ImageSharp/Formats/Webp/MetadataExtensions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,12 @@ public static partial class MetadataExtensions
1717
/// <param name="metadata">The metadata this method extends.</param>
1818
/// <returns>The <see cref="WebpMetadata"/>.</returns>
1919
public static WebpMetadata GetWebpMetadata(this ImageMetadata metadata) => metadata.GetFormatMetadata(WebpFormat.Instance);
20+
21+
/// <summary>
22+
/// Gets the webp format specific metadata for the image frame.
23+
/// </summary>
24+
/// <param name="metadata">The metadata this method extends.</param>
25+
/// <returns>The <see cref="WebpFrameMetadata"/>.</returns>
26+
public static WebpFrameMetadata GetWebpMetadata(this ImageFrameMetadata metadata) => metadata.GetFormatMetadata(WebpFormat.Instance);
2027
}
2128
}

0 commit comments

Comments
 (0)