Browse Source

Move disposing the alpha data to the AlphaEncoder

pull/1971/head
Brian Popow 4 years ago
parent
commit
192cfb03f9
  1. 19
      src/ImageSharp/Formats/Webp/AlphaEncoder.cs
  2. 13
      src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs

19
src/ImageSharp/Formats/Webp/AlphaEncoder.cs

@ -13,8 +13,10 @@ namespace SixLabors.ImageSharp.Formats.Webp
/// <summary>
/// Methods for encoding the alpha data of a VP8 image.
/// </summary>
internal static class AlphaEncoder
internal class AlphaEncoder : IDisposable
{
private IMemoryOwner<byte> alphaData;
/// <summary>
/// Encodes the alpha channel data.
/// Data is either compressed as lossless webp image or uncompressed.
@ -26,12 +28,12 @@ namespace SixLabors.ImageSharp.Formats.Webp
/// <param name="compress">Indicates, if the data should be compressed with the lossless webp compression.</param>
/// <param name="size">The size in bytes of the alpha data.</param>
/// <returns>The encoded alpha data.</returns>
public static IMemoryOwner<byte> EncodeAlpha<TPixel>(Image<TPixel> image, Configuration configuration, MemoryAllocator memoryAllocator, bool compress, out int size)
public IMemoryOwner<byte> EncodeAlpha<TPixel>(Image<TPixel> image, Configuration configuration, MemoryAllocator memoryAllocator, bool compress, out int size)
where TPixel : unmanaged, IPixel<TPixel>
{
int width = image.Width;
int height = image.Height;
IMemoryOwner<byte> 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<Rgba32> alphaAsImage = DispatchAlphaToGreen(image, alphaData.GetSpan());
using Image<Rgba32> 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;
}
/// <summary>
@ -124,5 +126,8 @@ namespace SixLabors.ImageSharp.Formats.Webp
return alphaDataBuffer;
}
/// <inheritdoc/>
public void Dispose() => this.alphaData?.Dispose();
}
}

13
src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs

@ -241,11 +241,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
public int DqUvDc { get; private set; }
/// <summary>
/// Gets or sets the alpha data.
/// </summary>
private IMemoryOwner<byte> AlphaData { get; set; }
/// <summary>
/// Gets the luma component.
/// </summary>
@ -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<byte> alphaData = Span<byte>.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<byte> 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<byte>.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();
}
/// <summary>

Loading…
Cancel
Save