diff --git a/src/ImageSharp/Formats/WebP/Lossy/Vp8Histogram.cs b/src/ImageSharp/Formats/WebP/Lossy/Vp8Histogram.cs
index e569ab0d9c..cadd8a2c7f 100644
--- a/src/ImageSharp/Formats/WebP/Lossy/Vp8Histogram.cs
+++ b/src/ImageSharp/Formats/WebP/Lossy/Vp8Histogram.cs
@@ -18,6 +18,15 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossy
private int lastNonZero;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public Vp8Histogram()
+ {
+ this.maxValue = 0;
+ this.lastNonZero = 1;
+ }
+
public int GetAlpha()
{
// 'alpha' will later be clipped to [0..MAX_ALPHA] range, clamping outer
diff --git a/src/ImageSharp/Formats/WebP/Lossy/YuvConversion.cs b/src/ImageSharp/Formats/WebP/Lossy/YuvConversion.cs
index cf3f32e8ec..c49d2048c0 100644
--- a/src/ImageSharp/Formats/WebP/Lossy/YuvConversion.cs
+++ b/src/ImageSharp/Formats/WebP/Lossy/YuvConversion.cs
@@ -51,7 +51,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
PixelOperations.Instance.ToRgba32(configuration, rowSpan, rgbaRow0);
PixelOperations.Instance.ToRgba32(configuration, nextRowSpan, rgbaRow1);
- var rowsHaveAlpha = CheckNonOpaque(rgbaRow0) && CheckNonOpaque(rgbaRow1);
+ bool rowsHaveAlpha = CheckNonOpaque(rgbaRow0) && CheckNonOpaque(rgbaRow1);
// Downsample U/V planes, two rows at a time.
if (!rowsHaveAlpha)
diff --git a/src/ImageSharp/Formats/WebP/WebpEncoderCore.cs b/src/ImageSharp/Formats/WebP/WebpEncoderCore.cs
index 4c405b262a..9fe477d0cd 100644
--- a/src/ImageSharp/Formats/WebP/WebpEncoderCore.cs
+++ b/src/ImageSharp/Formats/WebP/WebpEncoderCore.cs
@@ -84,12 +84,12 @@ namespace SixLabors.ImageSharp.Formats.Webp
if (this.lossy)
{
- var enc = new Vp8Encoder(this.memoryAllocator, this.configuration, image.Width, image.Height, this.quality, this.method, this.entropyPasses);
+ using var enc = new Vp8Encoder(this.memoryAllocator, this.configuration, image.Width, image.Height, this.quality, this.method, this.entropyPasses);
enc.Encode(image, stream);
}
else
{
- var enc = new Vp8LEncoder(this.memoryAllocator, this.configuration, image.Width, image.Height, this.quality, this.method);
+ using var enc = new Vp8LEncoder(this.memoryAllocator, this.configuration, image.Width, image.Height, this.quality, this.method);
enc.Encode(image, stream);
}
}
diff --git a/tests/ImageSharp.Tests/Formats/WebP/DominantCostRangeTests.cs b/tests/ImageSharp.Tests/Formats/WebP/DominantCostRangeTests.cs
new file mode 100644
index 0000000000..417b9fed53
--- /dev/null
+++ b/tests/ImageSharp.Tests/Formats/WebP/DominantCostRangeTests.cs
@@ -0,0 +1,79 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.Formats.Webp.Lossless;
+using Xunit;
+
+namespace SixLabors.ImageSharp.Tests.Formats.Webp
+{
+ [Trait("Format", "Webp")]
+ public class DominantCostRangeTests
+ {
+ [Fact]
+ public void DominantCost_Constructor()
+ {
+ var dominantCostRange = new DominantCostRange();
+ Assert.Equal(0, dominantCostRange.LiteralMax);
+ Assert.Equal(double.MaxValue, dominantCostRange.LiteralMin);
+ Assert.Equal(0, dominantCostRange.RedMax);
+ Assert.Equal(double.MaxValue, dominantCostRange.RedMin);
+ Assert.Equal(0, dominantCostRange.BlueMax);
+ Assert.Equal(double.MaxValue, dominantCostRange.BlueMin);
+ }
+
+ [Fact]
+ public void UpdateDominantCostRange_Works()
+ {
+ // arrange
+ var dominantCostRange = new DominantCostRange();
+ var histogram = new Vp8LHistogram(10)
+ {
+ LiteralCost = 1.0d,
+ RedCost = 2.0d,
+ BlueCost = 3.0d
+ };
+
+ // act
+ dominantCostRange.UpdateDominantCostRange(histogram);
+
+ // assert
+ Assert.Equal(1.0d, dominantCostRange.LiteralMax);
+ Assert.Equal(1.0d, dominantCostRange.LiteralMin);
+ Assert.Equal(2.0d, dominantCostRange.RedMax);
+ Assert.Equal(2.0d, dominantCostRange.RedMin);
+ Assert.Equal(3.0d, dominantCostRange.BlueMax);
+ Assert.Equal(3.0d, dominantCostRange.BlueMin);
+ }
+
+ [Theory]
+ [InlineData(3, 19)]
+ [InlineData(4, 34)]
+ public void GetHistoBinIndex_Works(int partitions, int expectedIndex)
+ {
+ // arrange
+ var dominantCostRange = new DominantCostRange()
+ {
+ BlueMax = 253.4625,
+ BlueMin = 109.0,
+ LiteralMax = 285.0,
+ LiteralMin = 133.0,
+ RedMax = 191.0,
+ RedMin = 109.0
+ };
+ var histogram = new Vp8LHistogram(6)
+ {
+ LiteralCost = 247.0d,
+ RedCost = 112.0d,
+ BlueCost = 202.0d,
+ BitCost = 733.0d
+ };
+ dominantCostRange.UpdateDominantCostRange(histogram);
+
+ // act
+ int binIndex = dominantCostRange.GetHistoBinIndex(histogram, partitions);
+
+ // assert
+ Assert.Equal(expectedIndex, binIndex);
+ }
+ }
+}
diff --git a/tests/ImageSharp.Tests/Formats/WebP/ImageExtensionsTest.cs b/tests/ImageSharp.Tests/Formats/WebP/ImageExtensionsTests.cs
similarity index 97%
rename from tests/ImageSharp.Tests/Formats/WebP/ImageExtensionsTest.cs
rename to tests/ImageSharp.Tests/Formats/WebP/ImageExtensionsTests.cs
index 7559bafc23..31fc1919c4 100644
--- a/tests/ImageSharp.Tests/Formats/WebP/ImageExtensionsTest.cs
+++ b/tests/ImageSharp.Tests/Formats/WebP/ImageExtensionsTests.cs
@@ -11,11 +11,11 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Formats.Webp
{
[Trait("Format", "Webp")]
- public class ImageExtensionsTest
+ public class ImageExtensionsTests
{
private readonly Configuration configuration;
- public ImageExtensionsTest()
+ public ImageExtensionsTests()
{
this.configuration = new Configuration();
this.configuration.AddWebp();
@@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp
[Fact]
public void SaveAsWebp_Path()
{
- string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest));
+ string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTests));
string file = Path.Combine(dir, "SaveAsWebp_Path.webp");
using (var image = new Image(this.configuration, 10, 10))
@@ -41,7 +41,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp
[Fact]
public async Task SaveAsWebpAsync_Path()
{
- string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTest));
+ string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTests));
string file = Path.Combine(dir, "SaveAsWebpAsync_Path.webp");
using (var image = new Image(this.configuration, 10, 10))
diff --git a/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs
index 9074c06ad6..be7bc27d3a 100644
--- a/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs
+++ b/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs
@@ -5,7 +5,7 @@ using SixLabors.ImageSharp.Formats.Webp.Lossless;
using SixLabors.ImageSharp.Tests.TestUtilities;
using Xunit;
-namespace SixLabors.ImageSharp.Tests.Formats.WebP
+namespace SixLabors.ImageSharp.Tests.Formats.Webp
{
[Trait("Format", "Webp")]
public class LosslessUtilsTests
diff --git a/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs
index 421015d1f9..e63ca2feca 100644
--- a/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs
@@ -11,7 +11,7 @@ using SixLabors.ImageSharp.Tests.TestUtilities;
#endif
using Xunit;
-namespace SixLabors.ImageSharp.Tests.Formats.WebP
+namespace SixLabors.ImageSharp.Tests.Formats.Webp
{
[Trait("Format", "Webp")]
public class PredictorEncoderTests
@@ -82,14 +82,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.WebP
};
// Convert image pixels to bgra array.
- var imgBytes = File.ReadAllBytes(TestImageFullPath(TestImages.WebP.Peak));
+ byte[] imgBytes = File.ReadAllBytes(TestImageFullPath(TestImages.WebP.Peak));
using var image = Image.Load(imgBytes);
uint[] bgra = ToBgra(image);
int colorTransformBits = 3;
int transformWidth = LosslessUtils.SubSampleSize(image.Width, colorTransformBits);
int transformHeight = LosslessUtils.SubSampleSize(image.Height, colorTransformBits);
- var transformData = new uint[transformWidth * transformHeight];
+ uint[] transformData = new uint[transformWidth * transformHeight];
// act
PredictorEncoder.ColorSpaceTransform(image.Width, image.Height, colorTransformBits, 75, bgra, transformData);
@@ -111,14 +111,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.WebP
};
// Convert image pixels to bgra array.
- var imgBytes = File.ReadAllBytes(TestImageFullPath(TestImages.WebP.Lossless.BikeSmall));
+ byte[] imgBytes = File.ReadAllBytes(TestImageFullPath(TestImages.WebP.Lossless.BikeSmall));
using var image = Image.Load(imgBytes, new WebpDecoder());
uint[] bgra = ToBgra(image);
int colorTransformBits = 4;
int transformWidth = LosslessUtils.SubSampleSize(image.Width, colorTransformBits);
int transformHeight = LosslessUtils.SubSampleSize(image.Height, colorTransformBits);
- var transformData = new uint[transformWidth * transformHeight];
+ uint[] transformData = new uint[transformWidth * transformHeight];
// act
PredictorEncoder.ColorSpaceTransform(image.Width, image.Height, colorTransformBits, 75, bgra, transformData);
diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8HistogramTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8HistogramTests.cs
new file mode 100644
index 0000000000..d4e1f69e06
--- /dev/null
+++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8HistogramTests.cs
@@ -0,0 +1,115 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+using System.Collections.Generic;
+using SixLabors.ImageSharp.Formats.WebP.Lossy;
+using Xunit;
+
+namespace SixLabors.ImageSharp.Tests.Formats.Webp
+{
+ [Trait("Format", "Webp")]
+ public class Vp8HistogramTests
+ {
+ public static IEnumerable