diff --git a/src/ImageSharp/Processing/Processors/Dithering/ErrorDither.cs b/src/ImageSharp/Processing/Processors/Dithering/ErrorDither.cs index 1a107c2cfd..0fe2d4b2c3 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/ErrorDither.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/ErrorDither.cs @@ -27,6 +27,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering [MethodImpl(InliningOptions.ShortMethod)] public ErrorDither(in DenseMatrix matrix, int offset) { + Guard.MustBeGreaterThan(offset, 0, nameof(offset)); + this.matrix = matrix; this.offset = offset; } @@ -95,6 +97,11 @@ public void ApplyQuantizationDither( where TFrameQuantizer : struct, IQuantizer where TPixel : unmanaged, IPixel { + if (this == default) + { + ThrowDefaultInstance(); + } + int offsetY = bounds.Top; int offsetX = bounds.Left; float scale = quantizer.Options.DitherScale; @@ -122,6 +129,11 @@ public void ApplyPaletteDither( where TPaletteDitherImageProcessor : struct, IPaletteDitherImageProcessor where TPixel : unmanaged, IPixel { + if (this == default) + { + ThrowDefaultInstance(); + } + float scale = processor.DitherScale; for (int y = bounds.Top; y < bounds.Bottom; y++) { @@ -210,5 +222,9 @@ public bool Equals(IDither other) /// public override int GetHashCode() => HashCode.Combine(this.offset, this.matrix); + + [MethodImpl(InliningOptions.ColdPath)] + private static void ThrowDefaultInstance() + => throw new ImageProcessingException("Cannot use the default value type instance to dither."); } } diff --git a/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs b/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs index c317ddf02a..2f5a5cf85e 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs @@ -24,6 +24,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering [MethodImpl(InliningOptions.ShortMethod)] public OrderedDither(uint length) { + Guard.MustBeGreaterThan(length, 0, nameof(length)); + DenseMatrix ditherMatrix = OrderedDitherFactory.CreateDitherMatrix(length); // Create a new matrix to run against, that pre-thresholds the values. @@ -109,6 +111,11 @@ public void ApplyQuantizationDither( where TFrameQuantizer : struct, IQuantizer where TPixel : unmanaged, IPixel { + if (this == default) + { + ThrowDefaultInstance(); + } + int spread = CalculatePaletteSpread(destination.Palette.Length); float scale = quantizer.Options.DitherScale; @@ -134,6 +141,11 @@ public void ApplyPaletteDither( where TPaletteDitherImageProcessor : struct, IPaletteDitherImageProcessor where TPixel : unmanaged, IPixel { + if (this == default) + { + ThrowDefaultInstance(); + } + int spread = CalculatePaletteSpread(processor.Palette.Length); float scale = processor.DitherScale; @@ -201,5 +213,9 @@ public bool Equals(IDither other) [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => HashCode.Combine(this.thresholdMatrix, this.modulusX, this.modulusY); + + [MethodImpl(InliningOptions.ColdPath)] + private static void ThrowDefaultInstance() + => throw new ImageProcessingException("Cannot use the default value type instance to dither."); } } diff --git a/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs index 861697594a..c1b695f653 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs @@ -11,14 +11,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// public class OctreeQuantizer : IQuantizer { - private static readonly QuantizerOptions DefaultOptions = new QuantizerOptions(); - /// /// Initializes a new instance of the class /// using the default . /// public OctreeQuantizer() - : this(DefaultOptions) + : this(new QuantizerOptions()) { } diff --git a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs index 4f73f4ac81..5da674cc9c 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs @@ -11,7 +11,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// public class PaletteQuantizer : IQuantizer { - private static readonly QuantizerOptions DefaultOptions = new QuantizerOptions(); private readonly ReadOnlyMemory colorPalette; /// @@ -19,7 +18,7 @@ public class PaletteQuantizer : IQuantizer /// /// The color palette. public PaletteQuantizer(ReadOnlyMemory palette) - : this(palette, DefaultOptions) + : this(palette, new QuantizerOptions()) { } diff --git a/src/ImageSharp/Processing/Processors/Quantization/WebSafePaletteQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/WebSafePaletteQuantizer.cs index 5dda17dc60..e717152f95 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WebSafePaletteQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WebSafePaletteQuantizer.cs @@ -1,8 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. -using SixLabors.ImageSharp.Processing.Processors.Dithering; - namespace SixLabors.ImageSharp.Processing.Processors.Quantization { /// @@ -10,13 +8,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// public class WebSafePaletteQuantizer : PaletteQuantizer { - private static readonly QuantizerOptions DefaultOptions = new QuantizerOptions(); - /// /// Initializes a new instance of the class. /// public WebSafePaletteQuantizer() - : this(DefaultOptions) + : this(new QuantizerOptions()) { } diff --git a/src/ImageSharp/Processing/Processors/Quantization/WernerPaletteQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/WernerPaletteQuantizer.cs index 6675263df6..8a96f8ecce 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WernerPaletteQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WernerPaletteQuantizer.cs @@ -9,13 +9,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// public class WernerPaletteQuantizer : PaletteQuantizer { - private static readonly QuantizerOptions DefaultOptions = new QuantizerOptions(); - /// /// Initializes a new instance of the class. /// public WernerPaletteQuantizer() - : this(DefaultOptions) + : this(new QuantizerOptions()) { } diff --git a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs index 95adb7e5d6..337948bef5 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs @@ -10,14 +10,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// public class WuQuantizer : IQuantizer { - private static readonly QuantizerOptions DefaultOptions = new QuantizerOptions(); - /// /// Initializes a new instance of the class /// using the default . /// public WuQuantizer() - : this(DefaultOptions) + : this(new QuantizerOptions()) { } diff --git a/tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs index 37443a5b40..0465cae940 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs @@ -43,6 +43,13 @@ public static readonly TheoryData OrderedDitherers { KnownDitherings.Ordered3x3, nameof(KnownDitherings.Ordered3x3) } }; + public static readonly TheoryData DefaultInstanceDitherers + = new TheoryData + { + default(ErrorDither), + default(OrderedDither) + }; + private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.05f); private static IDither DefaultDitherer => KnownDitherings.Bayer4x4; @@ -175,5 +182,18 @@ public void CommonDitherers_WorkWithDiscoBuffers( c => c.Dither(dither), name); } + + [Theory] + [MemberData(nameof(DefaultInstanceDitherers))] + public void ShouldThrowForDefaultDitherInstance(IDither dither) + { + void Command() + { + using var image = new Image(10, 10); + image.Mutate(x => x.Dither(dither)); + } + + Assert.Throws(Command); + } } } diff --git a/tests/ImageSharp.Tests/Processing/Processors/Quantization/QuantizerTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Quantization/QuantizerTests.cs index af1d7f3f38..c99e101380 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Quantization/QuantizerTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Quantization/QuantizerTests.cs @@ -5,6 +5,7 @@ using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Processors.Dithering; using SixLabors.ImageSharp.Processing.Processors.Quantization; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using Xunit; @@ -152,6 +153,13 @@ public static readonly TheoryData DitherScaleQuantizers new WuQuantizer(OrderedDitherOptions), }; + public static readonly TheoryData DefaultInstanceDitherers + = new TheoryData + { + default(ErrorDither), + default(OrderedDither) + }; + private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.05F); [Theory] @@ -217,5 +225,20 @@ public void ApplyQuantizationWithDitheringScale(TestImageProvider(10, 10); + var quantizer = new WebSafePaletteQuantizer(); + quantizer.Options.Dither = dither; + image.Mutate(x => x.Quantize(quantizer)); + } + + Assert.Throws(Command); + } } }