Browse Source

Leave alpha data uncompressed, if compression does not yield in smaller data

pull/1971/head
Brian Popow 4 years ago
parent
commit
b12ad7596e
  1. 11
      src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs
  2. 9
      src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs

11
src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs

@ -264,12 +264,15 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
/// <typeparam name="TPixel">The type of the pixel.</typeparam>
/// <param name="image">The <see cref="Image{TPixel}"/> to encode from.</param>
/// <param name="alphaData">The destination buffer to write the encoded alpha data to.</param>
/// <returns>The size of the data in bytes.</returns>
/// <returns>The size of the compressed data in bytes.
/// If the size of the data is the same as the pixel count, the compression would not yield in smaller data and is left uncompressed.
/// </returns>
public int EncodeAlphaImageData<TPixel>(Image<TPixel> image, IMemoryOwner<byte> alphaData)
where TPixel : unmanaged, IPixel<TPixel>
{
int width = image.Width;
int height = image.Height;
int pixelCount = width * height;
// Convert image pixels to bgra array.
this.ConvertPixelsToBgra(image, width, height);
@ -278,6 +281,12 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
this.EncodeStream(image);
this.bitWriter.Finish();
int size = this.bitWriter.NumBytes();
if (size >= pixelCount)
{
// Compressing would not yield in smaller data -> leave the data uncompressed.
return pixelCount;
}
this.bitWriter.WriteToBuffer(alphaData.GetSpan());
return size;
}

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

@ -302,6 +302,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
{
int width = image.Width;
int height = image.Height;
int pixelCount = width * height;
Span<byte> y = this.Y.GetSpan();
Span<byte> u = this.U.GetSpan();
Span<byte> v = this.V.GetSpan();
@ -329,10 +330,16 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
// Extract and encode alpha channel data, if present.
int alphaDataSize = 0;
bool alphaCompressionSucceeded = false;
if (hasAlpha)
{
// TODO: This can potentially run in an separate task.
this.AlphaData = AlphaEncoder.EncodeAlpha(image, this.configuration, this.memoryAllocator, this.alphaCompression, out alphaDataSize);
if (alphaDataSize < pixelCount)
{
// Only use compressed data, if the compressed data is actually smaller then the uncompressed data.
alphaCompressionSucceeded = true;
}
}
// Stats-collection loop.
@ -376,7 +383,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
(uint)height,
hasAlpha,
hasAlpha ? this.AlphaData.GetSpan().Slice(0, alphaDataSize) : Span<byte>.Empty,
this.alphaCompression);
this.alphaCompression && alphaCompressionSucceeded);
}
/// <inheritdoc/>

Loading…
Cancel
Save