Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 54 additions & 46 deletions src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -329,60 +329,68 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream)
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/>
Expand Down