// Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. using System; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing.Processors.Quantization; using Xunit; namespace SixLabors.ImageSharp.Tests { public class QuantizedImageTests { private Configuration Configuration => Configuration.Default; [Fact] public void QuantizersDitherByDefault() { var werner = new WernerPaletteQuantizer(); var webSafe = new WebSafePaletteQuantizer(); var octree = new OctreeQuantizer(); var wu = new WuQuantizer(); Assert.NotNull(werner.Diffuser); Assert.NotNull(webSafe.Diffuser); Assert.NotNull(octree.Diffuser); Assert.NotNull(wu.Diffuser); Assert.True(werner.CreateFrameQuantizer(this.Configuration).Dither); Assert.True(webSafe.CreateFrameQuantizer(this.Configuration).Dither); Assert.True(octree.CreateFrameQuantizer(this.Configuration).Dither); Assert.True(wu.CreateFrameQuantizer(this.Configuration).Dither); } [Theory] [WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32, true)] [WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32, false)] public void OctreeQuantizerYieldsCorrectTransparentPixel( TestImageProvider provider, bool dither) where TPixel : struct, IPixel { using (Image image = provider.GetImage()) { Assert.True(image[0, 0].Equals(default(TPixel))); var quantizer = new OctreeQuantizer(dither); foreach (ImageFrame frame in image.Frames) { IQuantizedFrame quantized = quantizer.CreateFrameQuantizer(this.Configuration).QuantizeFrame(frame); int index = this.GetTransparentIndex(quantized); Assert.Equal(index, quantized.GetPixelSpan()[0]); } } } [Theory] [WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32, true)] [WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32, false)] public void WuQuantizerYieldsCorrectTransparentPixel(TestImageProvider provider, bool dither) where TPixel : struct, IPixel { using (Image image = provider.GetImage()) { Assert.True(image[0, 0].Equals(default(TPixel))); var quantizer = new WuQuantizer(dither); foreach (ImageFrame frame in image.Frames) { IQuantizedFrame quantized = quantizer.CreateFrameQuantizer(this.Configuration).QuantizeFrame(frame); int index = this.GetTransparentIndex(quantized); Assert.Equal(index, quantized.GetPixelSpan()[0]); } } } private int GetTransparentIndex(IQuantizedFrame quantized) where TPixel : struct, IPixel { // Transparent pixels are much more likely to be found at the end of a palette int index = -1; Rgba32 trans = default; ReadOnlySpan paletteSpan = quantized.Palette.Span; for (int i = paletteSpan.Length - 1; i >= 0; i--) { paletteSpan[i].ToRgba32(ref trans); if (trans.Equals(default)) { index = i; } } return index; } } }