Browse Source

fix encodedAlphaData leak and #2171

pull/2420/head
antonfirsov 3 years ago
parent
commit
b5326e6d75
  1. 100
      src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs

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

@ -329,60 +329,68 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
bool alphaCompressionSucceeded = false;
using var alphaEncoder = new AlphaEncoder();
Span<byte> alphaData = Span<byte>.Empty;
if (hasAlpha)
IMemoryOwner<byte> encodedAlphaData = null;
try
{
// TODO: This can potentially run in an separate task.
IMemoryOwner<byte> encodedAlphaData = alphaEncoder.EncodeAlpha(image, this.configuration, this.memoryAllocator, this.alphaCompression, out alphaDataSize);
alphaData = encodedAlphaData.GetSpan();
if (alphaDataSize < pixelCount)
if (hasAlpha)
{
// Only use compressed data, if the compressed data is actually smaller then the uncompressed data.
alphaCompressionSucceeded = true;
// TODO: This can potentially run in an separate task.
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.
alphaCompressionSucceeded = true;
}
}
}
// Stats-collection loop.
this.StatLoop(width, height, yStride, uvStride);
it.Init();
it.InitFilter();
var info = new Vp8ModeScore();
var residual = new Vp8Residual();
do
{
bool dontUseSkip = !this.Proba.UseSkipProba;
info.Clear();
it.Import(y, u, v, yStride, uvStride, width, height, false);
// Warning! order is important: first call VP8Decimate() and
// *then* decide how to code the skip decision if there's one.
if (!this.Decimate(it, ref info, this.rdOptLevel) || dontUseSkip)
{
this.CodeResiduals(it, info, residual);
}
else
// Stats-collection loop.
this.StatLoop(width, height, yStride, uvStride);
it.Init();
it.InitFilter();
var info = new Vp8ModeScore();
var residual = new Vp8Residual();
do
{
it.ResetAfterSkip();
bool dontUseSkip = !this.Proba.UseSkipProba;
info.Clear();
it.Import(y, u, v, yStride, uvStride, width, height, false);
// Warning! order is important: first call VP8Decimate() and
// *then* decide how to code the skip decision if there's one.
if (!this.Decimate(it, ref info, this.rdOptLevel) || dontUseSkip)
{
this.CodeResiduals(it, info, residual);
}
else
{
it.ResetAfterSkip();
}
it.SaveBoundary();
}
while (it.Next());
it.SaveBoundary();
// Store filter stats.
this.AdjustFilterStrength();
// Write bytes from the bitwriter buffer to the stream.
ImageMetadata metadata = image.Metadata;
metadata.SyncProfiles();
this.bitWriter.WriteEncodedImageToStream(
stream,
metadata.ExifProfile,
metadata.XmpProfile,
(uint)width,
(uint)height,
hasAlpha,
alphaData.Slice(0, alphaDataSize),
this.alphaCompression && alphaCompressionSucceeded);
}
finally
{
encodedAlphaData?.Dispose();
}
while (it.Next());
// Store filter stats.
this.AdjustFilterStrength();
// Write bytes from the bitwriter buffer to the stream.
ImageMetadata metadata = image.Metadata;
metadata.SyncProfiles();
this.bitWriter.WriteEncodedImageToStream(
stream,
metadata.ExifProfile,
metadata.XmpProfile,
(uint)width,
(uint)height,
hasAlpha,
alphaData,
this.alphaCompression && alphaCompressionSucceeded);
}
/// <inheritdoc/>

Loading…
Cancel
Save