Browse Source

Mask the PaletteQuantizer<TPixel>.CreateFrameQuantizer() methods.

pull/741/head
James Jackson-South 8 years ago
parent
commit
8de843200f
  1. 2
      src/ImageSharp/Formats/Gif/GifEncoderCore.cs
  2. 36
      src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs
  3. 58
      tests/ImageSharp.Tests/Processing/Processors/Quantization/OctreeQuantizerTests.cs
  4. 79
      tests/ImageSharp.Tests/Processing/Processors/Quantization/PaletteQuantizerTests.cs
  5. 58
      tests/ImageSharp.Tests/Processing/Processors/Quantization/WuQuantizerTests.cs

2
src/ImageSharp/Formats/Gif/GifEncoderCore.cs

@ -158,7 +158,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
}
else
{
using (QuantizedFrame<TPixel> paletteQuantized = palleteQuantizer.CreateFrameQuantizer<TPixel>(image.GetConfiguration()).QuantizeFrame(frame))
using (QuantizedFrame<TPixel> paletteQuantized = palleteQuantizer.CreateFrameQuantizer(image.GetConfiguration()).QuantizeFrame(frame))
{
this.WriteImageData(paletteQuantized, stream);
}

36
src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs

@ -15,8 +15,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
public class PaletteQuantizer<TPixel> : IQuantizer
where TPixel : struct, IPixel<TPixel>
{
private readonly TPixel[] palette;
/// <summary>
/// Initializes a new instance of the <see cref="PaletteQuantizer{TPixel}"/> class.
/// </summary>
@ -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;
}
/// <inheritdoc/>
public IErrorDiffuser Diffuser { get; }
/// <summary>
/// Gets the palette.
/// </summary>
public TPixel[] Palette { get; }
/// <summary>
/// Creates the generic frame quantizer.
/// </summary>
/// <param name="configuration">The <see cref="Configuration"/> to configure internal operations.</param>
/// <returns>The <see cref="IFrameQuantizer{TPixel}"/>.</returns>
public IFrameQuantizer<TPixel> CreateFrameQuantizer(Configuration configuration)
=> ((IQuantizer)this).CreateFrameQuantizer<TPixel>(configuration);
/// <summary>
/// Creates the generic frame quantizer.
/// </summary>
/// <param name="configuration">The <see cref="Configuration"/> to configure internal operations.</param>
/// <param name="maxColors">The maximum number of colors to hold in the color palette.</param>
/// <returns>The <see cref="IFrameQuantizer{TPixel}"/>.</returns>
public IFrameQuantizer<TPixel> CreateFrameQuantizer(Configuration configuration, int maxColors)
=> ((IQuantizer)this).CreateFrameQuantizer<TPixel>(configuration, maxColors);
/// <inheritdoc/>
public IFrameQuantizer<TPixel1> CreateFrameQuantizer<TPixel1>(Configuration configuration)
where TPixel1 : struct, IPixel<TPixel1>
IFrameQuantizer<TPixel1> IQuantizer.CreateFrameQuantizer<TPixel1>(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<TPixel1>(this, Unsafe.As<TPixel[], TPixel1[]>(ref paletteRef));
}
/// <inheritdoc/>
public IFrameQuantizer<TPixel1> CreateFrameQuantizer<TPixel1>(Configuration configuration, int maxColors)
where TPixel1 : struct, IPixel<TPixel1>
IFrameQuantizer<TPixel1> IQuantizer.CreateFrameQuantizer<TPixel1>(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<TPixel[], TPixel1[]>(ref paletteRef);
maxColors = maxColors.Clamp(QuantizerConstants.MinColors, QuantizerConstants.MaxColors);

58
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<Rgba32> frameQuantizer = quantizer.CreateFrameQuantizer<Rgba32>(Configuration.Default);
Assert.NotNull(frameQuantizer);
Assert.True(frameQuantizer.Dither);
Assert.Equal(KnownDiffusers.FloydSteinberg, frameQuantizer.Diffuser);
quantizer = new OctreeQuantizer(false);
frameQuantizer = quantizer.CreateFrameQuantizer<Rgba32>(Configuration.Default);
Assert.NotNull(frameQuantizer);
Assert.False(frameQuantizer.Dither);
Assert.Null(frameQuantizer.Diffuser);
quantizer = new OctreeQuantizer(KnownDiffusers.Atkinson);
frameQuantizer = quantizer.CreateFrameQuantizer<Rgba32>(Configuration.Default);
Assert.NotNull(frameQuantizer);
Assert.True(frameQuantizer.Dither);
Assert.Equal(KnownDiffusers.Atkinson, frameQuantizer.Diffuser);
}
}
}

79
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<Rgba32>(Rgb);
Assert.Equal(Rgb, quantizer.Palette);
Assert.Equal(KnownDiffusers.FloydSteinberg, quantizer.Diffuser);
quantizer = new PaletteQuantizer<Rgba32>(Rgb, false);
Assert.Equal(Rgb, quantizer.Palette);
Assert.Null(quantizer.Diffuser);
quantizer = new PaletteQuantizer<Rgba32>(Rgb, KnownDiffusers.Atkinson);
Assert.Equal(Rgb, quantizer.Palette);
Assert.Equal(KnownDiffusers.Atkinson, quantizer.Diffuser);
}
[Fact]
public void PaletteQuantizerCanCreateFrameQuantizer()
{
var quantizer = new PaletteQuantizer<Rgba32>(Rgb);
IFrameQuantizer<Rgba32> frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default);
Assert.NotNull(frameQuantizer);
Assert.True(frameQuantizer.Dither);
Assert.Equal(KnownDiffusers.FloydSteinberg, frameQuantizer.Diffuser);
quantizer = new PaletteQuantizer<Rgba32>(Rgb, false);
frameQuantizer = quantizer.CreateFrameQuantizer(Configuration.Default);
Assert.NotNull(frameQuantizer);
Assert.False(frameQuantizer.Dither);
Assert.Null(frameQuantizer.Diffuser);
quantizer = new PaletteQuantizer<Rgba32>(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<Rgba32>(Rgb);
Assert.Throws<InvalidOperationException>(() => ((IQuantizer)quantizer).CreateFrameQuantizer<Rgb24>(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);
}
}
}

58
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<Rgba32> frameQuantizer = quantizer.CreateFrameQuantizer<Rgba32>(Configuration.Default);
Assert.NotNull(frameQuantizer);
Assert.True(frameQuantizer.Dither);
Assert.Equal(KnownDiffusers.FloydSteinberg, frameQuantizer.Diffuser);
quantizer = new WuQuantizer(false);
frameQuantizer = quantizer.CreateFrameQuantizer<Rgba32>(Configuration.Default);
Assert.NotNull(frameQuantizer);
Assert.False(frameQuantizer.Dither);
Assert.Null(frameQuantizer.Diffuser);
quantizer = new WuQuantizer(KnownDiffusers.Atkinson);
frameQuantizer = quantizer.CreateFrameQuantizer<Rgba32>(Configuration.Default);
Assert.NotNull(frameQuantizer);
Assert.True(frameQuantizer.Dither);
Assert.Equal(KnownDiffusers.Atkinson, frameQuantizer.Diffuser);
}
}
}
Loading…
Cancel
Save