diff --git a/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs index 2b8ef3f0b..2fea9615f 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/OctreeFrameQuantizer{TPixel}.cs @@ -6,6 +6,7 @@ using System.Buffers; using System.Collections.Generic; using System.Numerics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -111,21 +112,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// private sealed class Octree { - /// - /// Mask used when getting the appropriate pixels for a given node. - /// - private static readonly byte[] Mask = new byte[] - { - 0b10000000, - 0b1000000, - 0b100000, - 0b10000, - 0b1000, - 0b100, - 0b10, - 0b1 - }; - /// /// The root of the Octree /// @@ -162,6 +148,21 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization this.previousNode = null; } + /// + /// Gets the mask used when getting the appropriate pixels for a given node. + /// + private static ReadOnlySpan Mask => new byte[] + { + 0b10000000, + 0b1000000, + 0b100000, + 0b10000, + 0b1000, + 0b100, + 0b10, + 0b1 + }; + /// /// Gets or sets the number of leaves in the tree /// @@ -513,8 +514,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization [MethodImpl(InliningOptions.ShortMethod)] private static int GetColorIndex(ref Rgba32 color, int level) { + DebugGuard.MustBeLessThan(level, Mask.Length, nameof(level)); + int shift = 7 - level; - byte mask = Mask[level]; + ref byte maskRef = ref MemoryMarshal.GetReference(Mask); + byte mask = Unsafe.Add(ref maskRef, level); + return ((color.R & mask) >> shift) | ((color.G & mask) >> (shift - 1)) | ((color.B & mask) >> (shift - 2));