mirror of https://github.com/SixLabors/ImageSharp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
512 lines
21 KiB
512 lines
21 KiB
// Copyright (c) Six Labors.
|
|
// Licensed under the Six Labors Split License.
|
|
|
|
using System.Runtime.InteropServices;
|
|
using SixLabors.ImageSharp.Formats.Gif;
|
|
using SixLabors.ImageSharp.Formats.Png;
|
|
using SixLabors.ImageSharp.Formats.Webp;
|
|
using SixLabors.ImageSharp.Metadata;
|
|
using SixLabors.ImageSharp.PixelFormats;
|
|
using SixLabors.ImageSharp.Tests.TestUtilities;
|
|
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
|
|
using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
|
|
using static SixLabors.ImageSharp.Tests.TestImages.Webp;
|
|
|
|
namespace SixLabors.ImageSharp.Tests.Formats.Webp;
|
|
|
|
[Trait("Format", "Webp")]
|
|
public class WebpEncoderTests
|
|
{
|
|
private static string TestImageLossyFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, Lossy.NoFilter06);
|
|
|
|
[Theory]
|
|
[WithFile(Lossless.Animated, PixelTypes.Rgba32)]
|
|
public void Encode_AnimatedLossless<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage();
|
|
WebpEncoder encoder = new()
|
|
{
|
|
FileFormat = WebpFileFormatType.Lossless,
|
|
Quality = 100
|
|
};
|
|
|
|
// Always save as we need to compare the encoded output.
|
|
provider.Utility.SaveTestOutputFile(image, "webp", encoder);
|
|
|
|
// Compare encoded result
|
|
image.VerifyEncoder(provider, "webp", string.Empty, encoder);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(Lossy.Animated, PixelTypes.Rgba32)]
|
|
[WithFile(Lossy.AnimatedLandscape, PixelTypes.Rgba32)]
|
|
public void Encode_AnimatedLossy<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage();
|
|
WebpEncoder encoder = new()
|
|
{
|
|
FileFormat = WebpFileFormatType.Lossy,
|
|
Quality = 100
|
|
};
|
|
|
|
// Always save as we need to compare the encoded output.
|
|
provider.Utility.SaveTestOutputFile(image, "webp", encoder);
|
|
|
|
// Compare encoded result
|
|
// The reference decoder seems to produce differences up to 0.1% but the input/output have been
|
|
// checked to be correct.
|
|
string path = provider.Utility.GetTestOutputFileName("webp", null, true);
|
|
using Image<Rgba32> encoded = Image.Load<Rgba32>(path);
|
|
encoded.CompareToReferenceOutput(ImageComparer.Tolerant(0.01f), provider, null, "webp");
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32)]
|
|
public void Encode_AnimatedFormatTransform_FromGif<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(GifDecoder.Instance);
|
|
using MemoryStream memStream = new();
|
|
|
|
image.Save(memStream, new WebpEncoder());
|
|
memStream.Position = 0;
|
|
|
|
using Image<TPixel> output = Image.Load<TPixel>(memStream);
|
|
|
|
ImageComparer.Exact.VerifySimilarity(output, image);
|
|
|
|
GifMetadata gif = image.Metadata.GetGifMetadata();
|
|
WebpMetadata webp = output.Metadata.GetWebpMetadata();
|
|
|
|
Assert.Equal(gif.RepeatCount, webp.RepeatCount);
|
|
|
|
for (int i = 0; i < image.Frames.Count; i++)
|
|
{
|
|
GifFrameMetadata gifF = image.Frames[i].Metadata.GetGifMetadata();
|
|
WebpFrameMetadata webpF = output.Frames[i].Metadata.GetWebpMetadata();
|
|
|
|
Assert.Equal(gifF.FrameDelay, (int)(webpF.FrameDelay / 10));
|
|
|
|
switch (gifF.DisposalMethod)
|
|
{
|
|
case GifDisposalMethod.RestoreToBackground:
|
|
Assert.Equal(WebpDisposalMethod.RestoreToBackground, webpF.DisposalMethod);
|
|
break;
|
|
case GifDisposalMethod.RestoreToPrevious:
|
|
case GifDisposalMethod.Unspecified:
|
|
case GifDisposalMethod.NotDispose:
|
|
default:
|
|
Assert.Equal(WebpDisposalMethod.DoNotDispose, webpF.DisposalMethod);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.APng, PixelTypes.Rgba32)]
|
|
public void Encode_AnimatedFormatTransform_FromPng<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
|
|
using MemoryStream memStream = new();
|
|
image.Save(memStream, new WebpEncoder());
|
|
memStream.Position = 0;
|
|
|
|
using Image<TPixel> output = Image.Load<TPixel>(memStream);
|
|
ImageComparer.Exact.VerifySimilarity(output, image);
|
|
PngMetadata png = image.Metadata.GetPngMetadata();
|
|
WebpMetadata webp = output.Metadata.GetWebpMetadata();
|
|
|
|
Assert.Equal(png.RepeatCount, webp.RepeatCount);
|
|
|
|
for (int i = 0; i < image.Frames.Count; i++)
|
|
{
|
|
PngFrameMetadata pngF = image.Frames[i].Metadata.GetPngMetadata();
|
|
WebpFrameMetadata webpF = output.Frames[i].Metadata.GetWebpMetadata();
|
|
|
|
Assert.Equal((uint)(pngF.FrameDelay.ToDouble() * 1000), webpF.FrameDelay);
|
|
|
|
switch (pngF.BlendMethod)
|
|
{
|
|
case PngBlendMethod.Source:
|
|
Assert.Equal(WebpBlendingMethod.Source, webpF.BlendMethod);
|
|
break;
|
|
case PngBlendMethod.Over:
|
|
default:
|
|
Assert.Equal(WebpBlendingMethod.Over, webpF.BlendMethod);
|
|
break;
|
|
}
|
|
|
|
switch (pngF.DisposalMethod)
|
|
{
|
|
case PngDisposalMethod.RestoreToBackground:
|
|
Assert.Equal(WebpDisposalMethod.RestoreToBackground, webpF.DisposalMethod);
|
|
break;
|
|
case PngDisposalMethod.DoNotDispose:
|
|
default:
|
|
Assert.Equal(WebpDisposalMethod.DoNotDispose, webpF.DisposalMethod);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(Flag, PixelTypes.Rgba32, WebpFileFormatType.Lossy)] // If its not a webp input image, it should default to lossy.
|
|
[WithFile(Lossless.NoTransform1, PixelTypes.Rgba32, WebpFileFormatType.Lossless)]
|
|
[WithFile(Lossy.BikeWithExif, PixelTypes.Rgba32, WebpFileFormatType.Lossy)]
|
|
public void Encode_PreserveRatio<TPixel>(TestImageProvider<TPixel> provider, WebpFileFormatType expectedFormat)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
WebpEncoder options = new();
|
|
using Image<TPixel> input = provider.GetImage();
|
|
using MemoryStream memoryStream = new();
|
|
input.Save(memoryStream, options);
|
|
|
|
memoryStream.Position = 0;
|
|
using Image<Rgba32> output = Image.Load<Rgba32>(memoryStream);
|
|
|
|
ImageMetadata meta = output.Metadata;
|
|
WebpMetadata webpMetaData = meta.GetWebpMetadata();
|
|
Assert.Equal(expectedFormat, webpMetaData.FileFormat);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(Flag, PixelTypes.Rgba32)]
|
|
[WithFile(TestImages.Png.PalettedTwoColor, PixelTypes.Rgba32)]
|
|
[WithFile(TestImages.Png.Paletted256Colors, PixelTypes.Rgba32)]
|
|
public void Encode_Lossless_WithPalette_Works<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
WebpEncoder encoder = new()
|
|
{
|
|
FileFormat = WebpFileFormatType.Lossless,
|
|
Quality = 100,
|
|
Method = WebpEncodingMethod.BestQuality
|
|
};
|
|
|
|
using Image<TPixel> image = provider.GetImage();
|
|
image.VerifyEncoder(provider, "webp", string.Empty, encoder);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Bmp.Car, PixelTypes.Rgba32, 100)]
|
|
[WithFile(TestImages.Bmp.Car, PixelTypes.Rgba32, 80)]
|
|
[WithFile(TestImages.Bmp.Car, PixelTypes.Rgba32, 20)]
|
|
public void Encode_Lossless_WithDifferentQuality_Works<TPixel>(TestImageProvider<TPixel> provider, int quality)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
WebpEncoder encoder = new()
|
|
{
|
|
FileFormat = WebpFileFormatType.Lossless,
|
|
Quality = quality
|
|
};
|
|
|
|
using Image<TPixel> image = provider.GetImage();
|
|
string testOutputDetails = string.Concat("lossless", "_q", quality);
|
|
image.VerifyEncoder(provider, "webp", testOutputDetails, encoder);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 0, 75)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 1, 75)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 2, 75)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 3, 75)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 4, 75)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 5, 75)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 6, 75)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 0, 100)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 1, 100)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 2, 100)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 3, 100)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 4, 100)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 5, 100)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 6, 100)]
|
|
public void Encode_Lossless_WithDifferentMethodAndQuality_Works<TPixel>(TestImageProvider<TPixel> provider, WebpEncodingMethod method, int quality)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
WebpEncoder encoder = new()
|
|
{
|
|
FileFormat = WebpFileFormatType.Lossless,
|
|
Method = method,
|
|
Quality = quality
|
|
};
|
|
|
|
using Image<TPixel> image = provider.GetImage();
|
|
string testOutputDetails = string.Concat("lossless", "_m", method, "_q", quality);
|
|
image.VerifyEncoder(provider, "webp", testOutputDetails, encoder);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 15114)]
|
|
public void Encode_Lossless_WithBestQuality_HasExpectedSize<TPixel>(TestImageProvider<TPixel> provider, int expectedBytes)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
WebpEncoder encoder = new()
|
|
{
|
|
FileFormat = WebpFileFormatType.Lossless,
|
|
Method = WebpEncodingMethod.BestQuality
|
|
};
|
|
|
|
using Image<TPixel> image = provider.GetImage();
|
|
using MemoryStream memoryStream = new();
|
|
image.Save(memoryStream, encoder);
|
|
|
|
Assert.Equal(memoryStream.Length, expectedBytes);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(RgbTestPattern100x100, PixelTypes.Rgba32, 85)]
|
|
[WithFile(RgbTestPattern100x100, PixelTypes.Rgba32, 60)]
|
|
[WithFile(RgbTestPattern80x80, PixelTypes.Rgba32, 40)]
|
|
[WithFile(RgbTestPattern80x80, PixelTypes.Rgba32, 20)]
|
|
[WithFile(RgbTestPattern80x80, PixelTypes.Rgba32, 10)]
|
|
[WithFile(RgbTestPattern63x63, PixelTypes.Rgba32, 40)]
|
|
public void Encode_Lossless_WithNearLosslessFlag_Works<TPixel>(TestImageProvider<TPixel> provider, int nearLosslessQuality)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
WebpEncoder encoder = new()
|
|
{
|
|
FileFormat = WebpFileFormatType.Lossless,
|
|
NearLossless = true,
|
|
NearLosslessQuality = nearLosslessQuality
|
|
};
|
|
|
|
using Image<TPixel> image = provider.GetImage();
|
|
string testOutputDetails = string.Concat("nearlossless", "_q", nearLosslessQuality);
|
|
image.VerifyEncoder(provider, "webp", testOutputDetails, encoder, customComparer: GetComparer(nearLosslessQuality));
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 0)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 1)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 2)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 3)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 4)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 5)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 6)]
|
|
[WithFile(Lossy.Alpha1, PixelTypes.Rgba32, 4)]
|
|
public void Encode_Lossless_WithPreserveTransparentColor_Works<TPixel>(TestImageProvider<TPixel> provider, WebpEncodingMethod method)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
WebpEncoder encoder = new()
|
|
{
|
|
FileFormat = WebpFileFormatType.Lossless,
|
|
Method = method,
|
|
TransparentColorMode = WebpTransparentColorMode.Preserve
|
|
};
|
|
|
|
using Image<TPixel> image = provider.GetImage();
|
|
string testOutputDetails = string.Concat("lossless", "_m", method);
|
|
image.VerifyEncoder(provider, "webp", testOutputDetails, encoder);
|
|
}
|
|
|
|
[Fact]
|
|
public void Encode_Lossless_OneByOnePixel_Works()
|
|
{
|
|
// Just make sure, encoding 1 pixel by 1 pixel does not throw an exception.
|
|
using Image<Rgba32> image = new(1, 1);
|
|
WebpEncoder encoder = new() { FileFormat = WebpFileFormatType.Lossless };
|
|
using (MemoryStream memStream = new())
|
|
{
|
|
image.SaveAsWebp(memStream, encoder);
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 100)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 75)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 20)]
|
|
public void Encode_Lossy_WithDifferentQuality_Works<TPixel>(TestImageProvider<TPixel> provider, int quality)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
WebpEncoder encoder = new()
|
|
{
|
|
FileFormat = WebpFileFormatType.Lossy,
|
|
Quality = quality
|
|
};
|
|
|
|
using Image<TPixel> image = provider.GetImage();
|
|
string testOutputDetails = string.Concat("lossy", "_q", quality);
|
|
image.VerifyEncoder(provider, "webp", testOutputDetails, encoder, customComparer: GetComparer(quality));
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 100)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 80)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 50)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 30)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 10)]
|
|
public void Encode_Lossy_WithDifferentFilterStrength_Works<TPixel>(TestImageProvider<TPixel> provider, int filterStrength)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
WebpEncoder encoder = new()
|
|
{
|
|
FileFormat = WebpFileFormatType.Lossy,
|
|
FilterStrength = filterStrength
|
|
};
|
|
|
|
using Image<TPixel> image = provider.GetImage();
|
|
string testOutputDetails = string.Concat("lossy", "_f", filterStrength);
|
|
image.VerifyEncoder(provider, "webp", testOutputDetails, encoder, customComparer: GetComparer(75));
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 100)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 80)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 50)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 30)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 10)]
|
|
public void Encode_Lossy_WithDifferentSpatialNoiseShapingStrength_Works<TPixel>(TestImageProvider<TPixel> provider, int snsStrength)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
WebpEncoder encoder = new()
|
|
{
|
|
FileFormat = WebpFileFormatType.Lossy,
|
|
SpatialNoiseShaping = snsStrength
|
|
};
|
|
|
|
using Image<TPixel> image = provider.GetImage();
|
|
string testOutputDetails = string.Concat("lossy", "_sns", snsStrength);
|
|
image.VerifyEncoder(provider, "webp", testOutputDetails, encoder, customComparer: GetComparer(75));
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 0, 75)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 1, 75)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 2, 75)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 3, 75)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 4, 75)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 5, 75)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 6, 75)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 0, 100)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 1, 100)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 2, 100)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 3, 100)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 4, 100)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 5, 100)]
|
|
[WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 6, 100)]
|
|
public void Encode_Lossy_WithDifferentMethodsAndQuality_Works<TPixel>(TestImageProvider<TPixel> provider, WebpEncodingMethod method, int quality)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
WebpEncoder encoder = new()
|
|
{
|
|
FileFormat = WebpFileFormatType.Lossy,
|
|
Method = method,
|
|
Quality = quality
|
|
};
|
|
|
|
using Image<TPixel> image = provider.GetImage();
|
|
string testOutputDetails = string.Concat("lossy", "_m", method, "_q", quality);
|
|
image.VerifyEncoder(provider, "webp", testOutputDetails, encoder, customComparer: GetComparer(quality));
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.Transparency, PixelTypes.Rgba32)]
|
|
public void Encode_Lossy_WithAlpha_Works<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
// Floating point differences result in minor pixel differences affecting compression.
|
|
// Output have been manually verified.
|
|
int expectedFileSize = TestEnvironment.OSArchitecture == Architecture.Arm64 ? 64060 : 64020;
|
|
|
|
WebpEncoder encoder = new()
|
|
{
|
|
FileFormat = WebpFileFormatType.Lossy,
|
|
UseAlphaCompression = false
|
|
};
|
|
|
|
using Image<TPixel> image = provider.GetImage();
|
|
string encodedFile = image.VerifyEncoder(
|
|
provider,
|
|
"webp",
|
|
"with_alpha",
|
|
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]
|
|
[WithFile(TestImages.Png.Transparency, PixelTypes.Rgba32)]
|
|
public void Encode_Lossy_WithAlphaUsingCompression_Works<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
// Floating point differences result in minor pixel differences affecting compression.
|
|
// Output have been manually verified.
|
|
int expectedFileSize = TestEnvironment.OSArchitecture == Architecture.Arm64 ? 16240 : 16200;
|
|
|
|
WebpEncoder encoder = new()
|
|
{
|
|
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]
|
|
[WithFile(TestPatternOpaque, PixelTypes.Rgba32)]
|
|
[WithFile(TestPatternOpaqueSmall, PixelTypes.Rgba32)]
|
|
public void Encode_Lossless_WorksWithTestPattern<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage();
|
|
|
|
WebpEncoder encoder = new() { FileFormat = WebpFileFormatType.Lossless };
|
|
image.VerifyEncoder(provider, "webp", string.Empty, encoder);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestPatternOpaque, PixelTypes.Rgba32)]
|
|
[WithFile(TestPatternOpaqueSmall, PixelTypes.Rgba32)]
|
|
public void Encode_Lossy_WorksWithTestPattern<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage();
|
|
|
|
WebpEncoder encoder = new() { FileFormat = WebpFileFormatType.Lossy };
|
|
image.VerifyEncoder(provider, "webp", string.Empty, encoder, ImageComparer.Tolerant(0.04f));
|
|
}
|
|
|
|
public static void RunEncodeLossy_WithPeakImage()
|
|
{
|
|
TestImageProvider<Rgba32> provider = TestImageProvider<Rgba32>.File(TestImageLossyFullPath);
|
|
using Image<Rgba32> image = provider.GetImage();
|
|
|
|
WebpEncoder encoder = new() { FileFormat = WebpFileFormatType.Lossy };
|
|
image.VerifyEncoder(provider, "webp", string.Empty, encoder, ImageComparer.Tolerant(0.04f));
|
|
}
|
|
|
|
[Fact]
|
|
public void RunEncodeLossy_WithPeakImage_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunEncodeLossy_WithPeakImage, HwIntrinsics.AllowAll);
|
|
|
|
[Fact]
|
|
public void RunEncodeLossy_WithPeakImage_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunEncodeLossy_WithPeakImage, HwIntrinsics.DisableHWIntrinsic);
|
|
|
|
private static ImageComparer GetComparer(int quality)
|
|
{
|
|
float tolerance = 0.01f; // ~1.0%
|
|
|
|
if (quality < 30)
|
|
{
|
|
tolerance = 0.02f; // ~2.0%
|
|
}
|
|
|
|
return ImageComparer.Tolerant(tolerance);
|
|
}
|
|
}
|
|
|