From db3c973f22ec1f42282d29b01f78c3f92f0b7261 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sat, 5 Jun 2021 00:12:55 +0100 Subject: [PATCH] Fix octree transparency handling --- .../Quantization/OctreeQuantizer{TPixel}.cs | 16 +++++++--------- .../Quantization/WuQuantizer{TPixel}.cs | 5 ++--- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs index 0227d80d79..aaf9a0cecc 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs @@ -41,9 +41,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization this.Configuration = configuration; this.Options = options; - this.maxColors = this.Options.MaxColors; + this.maxColors = Math.Min(byte.MaxValue, this.Options.MaxColors); this.octree = new Octree(Numerics.Clamp(ColorNumerics.GetBitsNeededForColorDepth(this.maxColors), 1, 8)); - this.paletteOwner = configuration.MemoryAllocator.Allocate(this.maxColors, AllocationOptions.Clean); + this.paletteOwner = configuration.MemoryAllocator.Allocate(this.maxColors + 1, AllocationOptions.Clean); this.palette = default; this.pixelMap = default; this.isDithering = !(this.Options.Dither is null); @@ -90,14 +90,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization } } - Span paletteSpan = this.paletteOwner.GetSpan(); int paletteIndex = 0; + Span paletteSpan = this.paletteOwner.GetSpan(); this.octree.Palletize(paletteSpan, this.maxColors, ref paletteIndex); - // Length of reduced palette + transparency. - ReadOnlyMemory result = this.paletteOwner.Memory.Slice(0, Math.Min(paletteIndex + 2, this.maxColors)); + ReadOnlyMemory result = this.paletteOwner.Memory.Slice(0, paletteSpan.Length); this.pixelMap = new EuclideanPixelMap(this.Configuration, result); - this.palette = result; } @@ -118,7 +116,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization return (byte)this.pixelMap.GetClosestColor(color, out match); } - ref TPixel paletteRef = ref MemoryMarshal.GetReference(this.pixelMap.Palette.Span); + ref TPixel paletteRef = ref MemoryMarshal.GetReference(this.palette.Span); byte index = (byte)this.octree.GetPaletteIndex(color); match = Unsafe.Add(ref paletteRef, index); return index; @@ -254,7 +252,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization [MethodImpl(InliningOptions.ShortMethod)] public int GetPaletteIndex(TPixel color) { - Rgba32 rgba = default; + Unsafe.SkipInit(out Rgba32 rgba); color.ToRgba32(ref rgba); return this.root.GetPaletteIndex(ref rgba, 0); } @@ -453,7 +451,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization Vector3.Zero, new Vector3(255)); - TPixel pixel = default; + Unsafe.SkipInit(out TPixel pixel); pixel.FromRgba32(new Rgba32((byte)vector.X, (byte)vector.Y, (byte)vector.Z, byte.MaxValue)); palette[index] = pixel; diff --git a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs index e449678559..80b2c3ef4b 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs @@ -6,7 +6,6 @@ using System.Buffers; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -142,7 +141,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization } } - ReadOnlyMemory result = this.paletteOwner.Memory.Slice(0, this.maxColors); + ReadOnlyMemory result = this.paletteOwner.Memory.Slice(0, paletteSpan.Length); this.pixelMap = new EuclideanPixelMap(this.Configuration, result); this.palette = result; } @@ -170,7 +169,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization ReadOnlySpan tagSpan = this.tagsOwner.GetSpan(); byte index = tagSpan[GetPaletteIndex(r + 1, g + 1, b + 1, a + 1)]; - ref TPixel paletteRef = ref MemoryMarshal.GetReference(this.pixelMap.Palette.Span); + ref TPixel paletteRef = ref MemoryMarshal.GetReference(this.palette.Span); match = Unsafe.Add(ref paletteRef, index); return index; }