diff --git a/src/ImageSharp/Formats/Webp/AlphaEncoder.cs b/src/ImageSharp/Formats/Webp/AlphaEncoder.cs
index 38497281ff..1019073d87 100644
--- a/src/ImageSharp/Formats/Webp/AlphaEncoder.cs
+++ b/src/ImageSharp/Formats/Webp/AlphaEncoder.cs
@@ -13,8 +13,10 @@ namespace SixLabors.ImageSharp.Formats.Webp
///
/// Methods for encoding the alpha data of a VP8 image.
///
- internal static class AlphaEncoder
+ internal class AlphaEncoder : IDisposable
{
+ private IMemoryOwner alphaData;
+
///
/// Encodes the alpha channel data.
/// Data is either compressed as lossless webp image or uncompressed.
@@ -26,12 +28,12 @@ namespace SixLabors.ImageSharp.Formats.Webp
/// Indicates, if the data should be compressed with the lossless webp compression.
/// The size in bytes of the alpha data.
/// The encoded alpha data.
- public static IMemoryOwner EncodeAlpha(Image image, Configuration configuration, MemoryAllocator memoryAllocator, bool compress, out int size)
+ public IMemoryOwner EncodeAlpha(Image image, Configuration configuration, MemoryAllocator memoryAllocator, bool compress, out int size)
where TPixel : unmanaged, IPixel
{
int width = image.Width;
int height = image.Height;
- IMemoryOwner alphaData = ExtractAlphaChannel(image, configuration, memoryAllocator);
+ this.alphaData = ExtractAlphaChannel(image, configuration, memoryAllocator);
if (compress)
{
@@ -51,15 +53,15 @@ namespace SixLabors.ImageSharp.Formats.Webp
// The transparency information will be stored in the green channel of the ARGB quadruplet.
// The green channel is allowed extra transformation steps in the specification -- unlike the other channels,
// that can improve compression.
- using Image alphaAsImage = DispatchAlphaToGreen(image, alphaData.GetSpan());
+ using Image alphaAsImage = DispatchAlphaToGreen(image, this.alphaData.GetSpan());
- size = lossLessEncoder.EncodeAlphaImageData(alphaAsImage, alphaData);
+ size = lossLessEncoder.EncodeAlphaImageData(alphaAsImage, this.alphaData);
- return alphaData;
+ return this.alphaData;
}
size = width * height;
- return alphaData;
+ return this.alphaData;
}
///
@@ -124,5 +126,8 @@ namespace SixLabors.ImageSharp.Formats.Webp
return alphaDataBuffer;
}
+
+ ///
+ public void Dispose() => this.alphaData?.Dispose();
}
}
diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs
index 60bdee362c..927b04c0cf 100644
--- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs
+++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs
@@ -241,11 +241,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
public int DqUvDc { get; private set; }
- ///
- /// Gets or sets the alpha data.
- ///
- private IMemoryOwner AlphaData { get; set; }
-
///
/// Gets the luma component.
///
@@ -331,10 +326,13 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
// Extract and encode alpha channel data, if present.
int alphaDataSize = 0;
bool alphaCompressionSucceeded = false;
+ using var alphaEncoder = new AlphaEncoder();
+ Span alphaData = Span.Empty;
if (hasAlpha)
{
// TODO: This can potentially run in an separate task.
- this.AlphaData = AlphaEncoder.EncodeAlpha(image, this.configuration, this.memoryAllocator, this.alphaCompression, out alphaDataSize);
+ IMemoryOwner encodedAlphaData = alphaEncoder.EncodeAlpha(image, this.configuration, this.memoryAllocator, this.alphaCompression, out alphaDataSize);
+ alphaData = encodedAlphaData.GetSpan();
if (alphaDataSize < pixelCount)
{
// Only use compressed data, if the compressed data is actually smaller then the uncompressed data.
@@ -382,7 +380,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
(uint)width,
(uint)height,
hasAlpha,
- hasAlpha ? this.AlphaData.GetSpan().Slice(0, alphaDataSize) : Span.Empty,
+ alphaData,
this.alphaCompression && alphaCompressionSucceeded);
}
@@ -392,7 +390,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
this.Y.Dispose();
this.U.Dispose();
this.V.Dispose();
- this.AlphaData?.Dispose();
}
///