From 8de843200fb96e78aba7f68fd34eda094233af08 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 5 Nov 2018 13:49:14 +0000 Subject: [PATCH] Mask the PaletteQuantizer.CreateFrameQuantizer() methods. --- src/ImageSharp/Formats/Gif/GifEncoderCore.cs | 2 +- .../Quantization/PaletteQuantizer{TPixel}.cs | 36 ++++++--- .../Quantization/OctreeQuantizerTests.cs | 58 ++++++++++++++ .../Quantization/PaletteQuantizerTests.cs | 79 +++++++++++++++++++ .../Quantization/WuQuantizerTests.cs | 58 ++++++++++++++ 5 files changed, 223 insertions(+), 10 deletions(-) create mode 100644 tests/ImageSharp.Tests/Processing/Processors/Quantization/OctreeQuantizerTests.cs create mode 100644 tests/ImageSharp.Tests/Processing/Processors/Quantization/PaletteQuantizerTests.cs create mode 100644 tests/ImageSharp.Tests/Processing/Processors/Quantization/WuQuantizerTests.cs diff --git a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs index de68cd46ee..17ee616072 100644 --- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs @@ -158,7 +158,7 @@ namespace SixLabors.ImageSharp.Formats.Gif } else { - using (QuantizedFrame paletteQuantized = palleteQuantizer.CreateFrameQuantizer(image.GetConfiguration()).QuantizeFrame(frame)) + using (QuantizedFrame paletteQuantized = palleteQuantizer.CreateFrameQuantizer(image.GetConfiguration()).QuantizeFrame(frame)) { this.WriteImageData(paletteQuantized, stream); } diff --git a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs index ac143a767b..a350adfc0c 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs @@ -15,8 +15,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization public class PaletteQuantizer : IQuantizer where TPixel : struct, IPixel { - private readonly TPixel[] palette; - /// /// Initializes a new instance of the class. /// @@ -44,36 +42,56 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization public PaletteQuantizer(TPixel[] palette, IErrorDiffuser diffuser) { Guard.MustBeBetweenOrEqualTo(palette.Length, QuantizerConstants.MinColors, QuantizerConstants.MaxColors, nameof(palette)); - this.palette = palette; + this.Palette = palette; this.Diffuser = diffuser; } /// public IErrorDiffuser Diffuser { get; } + /// + /// Gets the palette. + /// + public TPixel[] Palette { get; } + + /// + /// Creates the generic frame quantizer. + /// + /// The to configure internal operations. + /// The . + public IFrameQuantizer CreateFrameQuantizer(Configuration configuration) + => ((IQuantizer)this).CreateFrameQuantizer(configuration); + + /// + /// Creates the generic frame quantizer. + /// + /// The to configure internal operations. + /// The maximum number of colors to hold in the color palette. + /// The . + public IFrameQuantizer CreateFrameQuantizer(Configuration configuration, int maxColors) + => ((IQuantizer)this).CreateFrameQuantizer(configuration, maxColors); + /// - public IFrameQuantizer CreateFrameQuantizer(Configuration configuration) - where TPixel1 : struct, IPixel + IFrameQuantizer IQuantizer.CreateFrameQuantizer(Configuration configuration) { if (!typeof(TPixel).Equals(typeof(TPixel1))) { throw new InvalidOperationException("Generic method type must be the same as class type."); } - TPixel[] paletteRef = this.palette; + TPixel[] paletteRef = this.Palette; return new PaletteFrameQuantizer(this, Unsafe.As(ref paletteRef)); } /// - public IFrameQuantizer CreateFrameQuantizer(Configuration configuration, int maxColors) - where TPixel1 : struct, IPixel + IFrameQuantizer IQuantizer.CreateFrameQuantizer(Configuration configuration, int maxColors) { if (!typeof(TPixel).Equals(typeof(TPixel1))) { throw new InvalidOperationException("Generic method type must be the same as class type."); } - TPixel[] paletteRef = this.palette; + TPixel[] paletteRef = this.Palette; TPixel1[] castPalette = Unsafe.As(ref paletteRef); maxColors = maxColors.Clamp(QuantizerConstants.MinColors, QuantizerConstants.MaxColors); diff --git a/tests/ImageSharp.Tests/Processing/Processors/Quantization/OctreeQuantizerTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Quantization/OctreeQuantizerTests.cs new file mode 100644 index 0000000000..b3900325db --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Processors/Quantization/OctreeQuantizerTests.cs @@ -0,0 +1,58 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Processors.Quantization; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Processing.Processors.Quantization +{ + public class OctreeQuantizerTests + { + [Fact] + public void OctreeQuantizerConstructor() + { + var quantizer = new OctreeQuantizer(128); + + Assert.Equal(128, quantizer.MaxColors); + Assert.Equal(KnownDiffusers.FloydSteinberg, quantizer.Diffuser); + + quantizer = new OctreeQuantizer(false); + Assert.Equal(QuantizerConstants.MaxColors, quantizer.MaxColors); + Assert.Null(quantizer.Diffuser); + + quantizer = new OctreeQuantizer(KnownDiffusers.Atkinson); + Assert.Equal(QuantizerConstants.MaxColors, quantizer.MaxColors); + Assert.Equal(KnownDiffusers.Atkinson, quantizer.Diffuser); + + quantizer = new OctreeQuantizer(KnownDiffusers.Atkinson, 128); + Assert.Equal(128, quantizer.MaxColors); + Assert.Equal(KnownDiffusers.Atkinson, quantizer.Diffuser); + } + + [Fact] + public void OctreeQuantizerCanCreateFrameQuantizer() + { + var quantizer = new OctreeQuantizer(); + IFrameQuantizer frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + + Assert.NotNull(frameQuantizer); + Assert.True(frameQuantizer.Dither); + Assert.Equal(KnownDiffusers.FloydSteinberg, frameQuantizer.Diffuser); + + quantizer = new OctreeQuantizer(false); + frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + + Assert.NotNull(frameQuantizer); + Assert.False(frameQuantizer.Dither); + Assert.Null(frameQuantizer.Diffuser); + + quantizer = new OctreeQuantizer(KnownDiffusers.Atkinson); + frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + Assert.NotNull(frameQuantizer); + Assert.True(frameQuantizer.Dither); + Assert.Equal(KnownDiffusers.Atkinson, frameQuantizer.Diffuser); + } + } +} diff --git a/tests/ImageSharp.Tests/Processing/Processors/Quantization/PaletteQuantizerTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Quantization/PaletteQuantizerTests.cs new file mode 100644 index 0000000000..a4e6edd53e --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Processors/Quantization/PaletteQuantizerTests.cs @@ -0,0 +1,79 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Processors.Quantization; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Processing.Processors.Quantization +{ + public class PaletteQuantizerTests + { + private static readonly Rgba32[] Rgb = new Rgba32[] { Rgba32.Red, Rgba32.Green, Rgba32.Blue }; + + [Fact] + public void PaletteQuantizerConstructor() + { + var quantizer = new PaletteQuantizer(Rgb); + + Assert.Equal(Rgb, quantizer.Palette); + Assert.Equal(KnownDiffusers.FloydSteinberg, quantizer.Diffuser); + + quantizer = new PaletteQuantizer(Rgb, false); + Assert.Equal(Rgb, quantizer.Palette); + Assert.Null(quantizer.Diffuser); + + quantizer = new PaletteQuantizer(Rgb, KnownDiffusers.Atkinson); + Assert.Equal(Rgb, quantizer.Palette); + Assert.Equal(KnownDiffusers.Atkinson, quantizer.Diffuser); + } + + [Fact] + public void PaletteQuantizerCanCreateFrameQuantizer() + { + var quantizer = new PaletteQuantizer(Rgb); + IFrameQuantizer frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + + Assert.NotNull(frameQuantizer); + Assert.True(frameQuantizer.Dither); + Assert.Equal(KnownDiffusers.FloydSteinberg, frameQuantizer.Diffuser); + + quantizer = new PaletteQuantizer(Rgb, false); + frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + + Assert.NotNull(frameQuantizer); + Assert.False(frameQuantizer.Dither); + Assert.Null(frameQuantizer.Diffuser); + + quantizer = new PaletteQuantizer(Rgb, KnownDiffusers.Atkinson); + frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + Assert.NotNull(frameQuantizer); + Assert.True(frameQuantizer.Dither); + Assert.Equal(KnownDiffusers.Atkinson, frameQuantizer.Diffuser); + } + + [Fact] + public void PaletteQuantizerThrowsOnInvalidGenericMethodCall() + { + var quantizer = new PaletteQuantizer(Rgb); + + Assert.Throws(() => ((IQuantizer)quantizer).CreateFrameQuantizer(Configuration.Default)); + } + + [Fact] + public void KnownQuantizersWebSafeTests() + { + IQuantizer quantizer = KnownQuantizers.WebSafe; + Assert.Equal(KnownDiffusers.FloydSteinberg, quantizer.Diffuser); + } + + [Fact] + public void KnownQuantizersWernerTests() + { + IQuantizer quantizer = KnownQuantizers.Werner; + Assert.Equal(KnownDiffusers.FloydSteinberg, quantizer.Diffuser); + } + } +} diff --git a/tests/ImageSharp.Tests/Processing/Processors/Quantization/WuQuantizerTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Quantization/WuQuantizerTests.cs new file mode 100644 index 0000000000..625043c7f1 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Processors/Quantization/WuQuantizerTests.cs @@ -0,0 +1,58 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Processors.Quantization; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Processing.Processors.Quantization +{ + public class WuQuantizerTests + { + [Fact] + public void WuQuantizerConstructor() + { + var quantizer = new WuQuantizer(128); + + Assert.Equal(128, quantizer.MaxColors); + Assert.Equal(KnownDiffusers.FloydSteinberg, quantizer.Diffuser); + + quantizer = new WuQuantizer(false); + Assert.Equal(QuantizerConstants.MaxColors, quantizer.MaxColors); + Assert.Null(quantizer.Diffuser); + + quantizer = new WuQuantizer(KnownDiffusers.Atkinson); + Assert.Equal(QuantizerConstants.MaxColors, quantizer.MaxColors); + Assert.Equal(KnownDiffusers.Atkinson, quantizer.Diffuser); + + quantizer = new WuQuantizer(KnownDiffusers.Atkinson, 128); + Assert.Equal(128, quantizer.MaxColors); + Assert.Equal(KnownDiffusers.Atkinson, quantizer.Diffuser); + } + + [Fact] + public void WuQuantizerCanCreateFrameQuantizer() + { + var quantizer = new WuQuantizer(); + IFrameQuantizer frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + + Assert.NotNull(frameQuantizer); + Assert.True(frameQuantizer.Dither); + Assert.Equal(KnownDiffusers.FloydSteinberg, frameQuantizer.Diffuser); + + quantizer = new WuQuantizer(false); + frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + + Assert.NotNull(frameQuantizer); + Assert.False(frameQuantizer.Dither); + Assert.Null(frameQuantizer.Diffuser); + + quantizer = new WuQuantizer(KnownDiffusers.Atkinson); + frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default); + Assert.NotNull(frameQuantizer); + Assert.True(frameQuantizer.Dither); + Assert.Equal(KnownDiffusers.Atkinson, frameQuantizer.Diffuser); + } + } +}