diff --git a/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs index 11af7b17f..49e6f63ea 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs @@ -194,7 +194,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization for (int y = 0; y < height; y++) { - Span row = source.GetPixelRowSpan(y); + ReadOnlySpan row = source.GetPixelRowSpan(y); // And loop through each column for (int x = 0; x < width; x++) @@ -237,7 +237,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// The blue value. /// The alpha value. /// The index. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private static int GetPaletteIndex(int r, int g, int b, int a) { return (r << ((IndexBits * 2) + IndexAlphaBits)) @@ -409,28 +409,27 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization // Build up the 3-D color histogram // Loop through each row - using (IMemoryOwner rgbaBuffer = this.memoryAllocator.Allocate(source.Width)) + using IMemoryOwner rgbaBuffer = this.memoryAllocator.Allocate(source.Width); + Span rgbaSpan = rgbaBuffer.GetSpan(); + ref Rgba32 scanBaseRef = ref MemoryMarshal.GetReference(rgbaSpan); + + for (int y = 0; y < height; y++) { - for (int y = 0; y < height; y++) - { - Span row = source.GetPixelRowSpan(y); - Span rgbaSpan = rgbaBuffer.GetSpan(); - PixelOperations.Instance.ToRgba32(source.GetConfiguration(), row, rgbaSpan); - ref Rgba32 scanBaseRef = ref MemoryMarshal.GetReference(rgbaSpan); + Span row = source.GetPixelRowSpan(y); + PixelOperations.Instance.ToRgba32(source.GetConfiguration(), row, rgbaSpan); - // And loop through each column - for (int x = 0; x < width; x++) - { - ref Rgba32 rgba = ref Unsafe.Add(ref scanBaseRef, x); + // And loop through each column + for (int x = 0; x < width; x++) + { + ref Rgba32 rgba = ref Unsafe.Add(ref scanBaseRef, x); - int r = rgba.R >> (8 - IndexBits); - int g = rgba.G >> (8 - IndexBits); - int b = rgba.B >> (8 - IndexBits); - int a = rgba.A >> (8 - IndexAlphaBits); + int r = (rgba.R >> (8 - IndexBits)) + 1; + int g = (rgba.G >> (8 - IndexBits)) + 1; + int b = (rgba.B >> (8 - IndexBits)) + 1; + int a = (rgba.A >> (8 - IndexAlphaBits)) + 1; - int index = GetPaletteIndex(r + 1, g + 1, b + 1, a + 1); - momentSpan[index] += rgba; - } + int index = GetPaletteIndex(r, g, b, a); + momentSpan[index] += rgba; } } } @@ -441,38 +440,38 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// The memory allocator used for allocating buffers. private void Get3DMoments(MemoryAllocator memoryAllocator) { + using IMemoryOwner volume = memoryAllocator.Allocate(IndexCount * IndexAlphaCount); + using IMemoryOwner area = memoryAllocator.Allocate(IndexAlphaCount); + Span momentSpan = this.moments.GetSpan(); - using (IMemoryOwner volume = memoryAllocator.Allocate(IndexCount * IndexAlphaCount)) - using (IMemoryOwner area = memoryAllocator.Allocate(IndexAlphaCount)) + Span volumeSpan = volume.GetSpan(); + Span areaSpan = area.GetSpan(); + int baseIndex = GetPaletteIndex(1, 0, 0, 0); + + for (int r = 1; r < IndexCount; r++) { - Span volumeSpan = volume.GetSpan(); - Span areaSpan = area.GetSpan(); + volumeSpan.Clear(); - for (int r = 1; r < IndexCount; r++) + for (int g = 1; g < IndexCount; g++) { - volume.Clear(); + areaSpan.Clear(); - for (int g = 1; g < IndexCount; g++) + for (int b = 1; b < IndexCount; b++) { - area.Clear(); + Moment line = default; - for (int b = 1; b < IndexCount; b++) + for (int a = 1; a < IndexAlphaCount; a++) { - Moment line = default; + int ind1 = GetPaletteIndex(r, g, b, a); + line += momentSpan[ind1]; - for (int a = 1; a < IndexAlphaCount; a++) - { - int ind1 = GetPaletteIndex(r, g, b, a); - line += momentSpan[ind1]; + areaSpan[a] += line; - areaSpan[a] += line; + int inv = (b * IndexAlphaCount) + a; + volumeSpan[inv] += areaSpan[a]; - int inv = (b * IndexAlphaCount) + a; - volumeSpan[inv] += areaSpan[a]; - - int ind2 = ind1 - GetPaletteIndex(1, 0, 0, 0); - momentSpan[ind1] = momentSpan[ind2] + volumeSpan[inv]; - } + int ind2 = ind1 - baseIndex; + momentSpan[ind1] = momentSpan[ind2] + volumeSpan[inv]; } } } @@ -573,7 +572,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// Returns a value indicating whether the box has been split. private bool Cut(ref Box set1, ref Box set2) { - Moment whole = Volume(ref set1, this.moments.GetSpan()); + ReadOnlySpan momentSpan = this.moments.GetSpan(); + Moment whole = Volume(ref set1, momentSpan); float maxR = this.Maximize(ref set1, 3, set1.RMin + 1, set1.RMax, out int cutR, whole); float maxG = this.Maximize(ref set1, 2, set1.GMin + 1, set1.GMax, out int cutG, whole); @@ -731,7 +731,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// /// The quantized value /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private byte QuantizePixel(ref TPixel pixel) { if (this.Dither) @@ -750,8 +750,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization int b = rgba.B >> (8 - IndexBits); int a = rgba.A >> (8 - IndexAlphaBits); - Span tagSpan = this.tag.GetSpan(); - + ReadOnlySpan tagSpan = this.tag.GetSpan(); return tagSpan[GetPaletteIndex(r + 1, g + 1, b + 1, a + 1)]; } @@ -894,10 +893,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization public int Volume; /// - public override bool Equals(object obj) => obj is Box box && this.Equals(box); + public readonly override bool Equals(object obj) + => obj is Box box + && this.Equals(box); /// - public bool Equals(Box other) => + public readonly bool Equals(Box other) => this.RMin == other.RMin && this.RMax == other.RMax && this.GMin == other.GMin @@ -909,7 +910,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization && this.Volume == other.Volume; /// - public override int GetHashCode() + public readonly override int GetHashCode() { HashCode hash = default; hash.Add(this.RMin);