Browse Source

Merge pull request #2258 from SixLabors/bp/Issue2257

Fix issue decoding lossy webp with alpha channel
pull/2268/head
James Jackson-South 4 years ago
committed by GitHub
parent
commit
b4556632d7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      src/ImageSharp/Formats/Webp/AlphaDecoder.cs
  2. 11
      tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs
  3. 35
      tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs
  4. 1
      tests/ImageSharp.Tests/TestImages.cs
  5. 3
      tests/Images/Input/Webp/issues/Issue2257.webp

8
src/ImageSharp/Formats/Webp/AlphaDecoder.cs

@ -61,7 +61,13 @@ internal class AlphaDecoder : IDisposable
var bitReader = new Vp8LBitReader(data);
this.LosslessDecoder = new WebpLosslessDecoder(bitReader, memoryAllocator, configuration);
this.LosslessDecoder.DecodeImageStream(this.Vp8LDec, width, height, true);
this.Use8BDecode = this.Vp8LDec.Transforms.Count > 0 && Is8BOptimizable(this.Vp8LDec.Metadata);
// Special case: if alpha data uses only the color indexing transform and
// doesn't use color cache (a frequent case), we will use DecodeAlphaData()
// method that only needs allocation of 1 byte per pixel (alpha channel).
this.Use8BDecode = this.Vp8LDec.Transforms.Count is 1
&& this.Vp8LDec.Transforms[0].TransformType == Vp8LTransformType.ColorIndexingTransform
&& Is8BOptimizable(this.Vp8LDec.Metadata);
}
}

11
tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs

@ -396,6 +396,17 @@ public class WebpDecoderTests
image.CompareToOriginal(provider, ReferenceDecoder);
}
// https://github.com/SixLabors/ImageSharp/issues/2257
[Theory]
[WithFile(Lossy.Issue2257, PixelTypes.Rgba32)]
public void WebpDecoder_CanDecode_Issue2257<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using Image<TPixel> image = provider.GetImage(WebpDecoder);
image.DebugSave(provider);
image.CompareToOriginal(provider, ReferenceDecoder);
}
[Theory]
[WithFile(Lossless.LossLessCorruptImage3, PixelTypes.Rgba32)]
public void WebpDecoder_ThrowImageFormatException_OnInvalidImages<TPixel>(TestImageProvider<TPixel> provider)

35
tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs

@ -267,28 +267,51 @@ public class WebpEncoderTests
}
[Theory]
[WithFile(TestImages.Png.Transparency, PixelTypes.Rgba32, false, 64020)]
[WithFile(TestImages.Png.Transparency, PixelTypes.Rgba32, true, 16200)]
public void Encode_Lossy_WithAlpha_Works<TPixel>(TestImageProvider<TPixel> provider, bool compressed, int expectedFileSize)
[WithFile(TestImages.Png.Transparency, PixelTypes.Rgba32, 64020)]
public void Encode_Lossy_WithAlpha_Works<TPixel>(TestImageProvider<TPixel> provider, int expectedFileSize)
where TPixel : unmanaged, IPixel<TPixel>
{
var encoder = new WebpEncoder()
{
FileFormat = WebpFileFormatType.Lossy,
UseAlphaCompression = compressed
UseAlphaCompression = false
};
using Image<TPixel> image = provider.GetImage();
string encodedFile = image.VerifyEncoder(
provider,
"webp",
$"with_alpha_compressed_{compressed}",
"with_alpha",
encoder,
ImageComparer.Tolerant(0.04f),
referenceDecoder: new MagickReferenceDecoder());
int encodedBytes = File.ReadAllBytes(encodedFile).Length;
Assert.True(encodedBytes <= expectedFileSize);
Assert.True(encodedBytes <= expectedFileSize, $"encoded bytes are {encodedBytes} and should be smaller then expected file size of {expectedFileSize}");
}
[Theory]
[WithFile(TestImages.Png.Transparency, PixelTypes.Rgba32, 16200)]
public void Encode_Lossy_WithAlphaUsingCompression_Works<TPixel>(TestImageProvider<TPixel> provider, int expectedFileSize)
where TPixel : unmanaged, IPixel<TPixel>
{
var encoder = new WebpEncoder()
{
FileFormat = WebpFileFormatType.Lossy,
UseAlphaCompression = true
};
using Image<TPixel> image = provider.GetImage();
string encodedFile = image.VerifyEncoder(
provider,
"webp",
"with_alpha_compressed",
encoder,
ImageComparer.Tolerant(0.04f),
referenceDecoder: new MagickReferenceDecoder());
int encodedBytes = File.ReadAllBytes(encodedFile).Length;
Assert.True(encodedBytes <= expectedFileSize, $"encoded bytes are {encodedBytes} and should be smaller then expected file size of {expectedFileSize}");
}
[Theory]

1
tests/ImageSharp.Tests/TestImages.cs

@ -737,6 +737,7 @@ public static class TestImages
// Issues
public const string Issue1594 = "Webp/issues/Issue1594.webp";
public const string Issue2243 = "Webp/issues/Issue2243.webp";
public const string Issue2257 = "Webp/issues/Issue2257.webp";
}
}

3
tests/Images/Input/Webp/issues/Issue2257.webp

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:55f87aee4283615bad9705ac459867facba5b6be114d7e1ece51db7c1ef87916
size 117810
Loading…
Cancel
Save