Browse Source

Cleanup and perf fixes.

af/octree-no-pixelmap
James Jackson-South 6 years ago
parent
commit
eb8ee78d29
  1. 97
      src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs

97
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<TPixel> row = source.GetPixelRowSpan(y);
ReadOnlySpan<TPixel> 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
/// <param name="b">The blue value.</param>
/// <param name="a">The alpha value.</param>
/// <returns>The index.</returns>
[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<Rgba32> rgbaBuffer = this.memoryAllocator.Allocate<Rgba32>(source.Width))
using IMemoryOwner<Rgba32> rgbaBuffer = this.memoryAllocator.Allocate<Rgba32>(source.Width);
Span<Rgba32> 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<TPixel> row = source.GetPixelRowSpan(y);
Span<Rgba32> rgbaSpan = rgbaBuffer.GetSpan();
PixelOperations<TPixel>.Instance.ToRgba32(source.GetConfiguration(), row, rgbaSpan);
ref Rgba32 scanBaseRef = ref MemoryMarshal.GetReference(rgbaSpan);
Span<TPixel> row = source.GetPixelRowSpan(y);
PixelOperations<TPixel>.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
/// <param name="memoryAllocator">The memory allocator used for allocating buffers.</param>
private void Get3DMoments(MemoryAllocator memoryAllocator)
{
using IMemoryOwner<Moment> volume = memoryAllocator.Allocate<Moment>(IndexCount * IndexAlphaCount);
using IMemoryOwner<Moment> area = memoryAllocator.Allocate<Moment>(IndexAlphaCount);
Span<Moment> momentSpan = this.moments.GetSpan();
using (IMemoryOwner<Moment> volume = memoryAllocator.Allocate<Moment>(IndexCount * IndexAlphaCount))
using (IMemoryOwner<Moment> area = memoryAllocator.Allocate<Moment>(IndexAlphaCount))
Span<Moment> volumeSpan = volume.GetSpan();
Span<Moment> areaSpan = area.GetSpan();
int baseIndex = GetPaletteIndex(1, 0, 0, 0);
for (int r = 1; r < IndexCount; r++)
{
Span<Moment> volumeSpan = volume.GetSpan();
Span<Moment> 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>Returns a value indicating whether the box has been split.</returns>
private bool Cut(ref Box set1, ref Box set2)
{
Moment whole = Volume(ref set1, this.moments.GetSpan());
ReadOnlySpan<Moment> 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
/// <returns>
/// The quantized value
/// </returns>
[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<byte> tagSpan = this.tag.GetSpan();
ReadOnlySpan<byte> 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;
/// <inheritdoc/>
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);
/// <inheritdoc/>
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;
/// <inheritdoc/>
public override int GetHashCode()
public readonly override int GetHashCode()
{
HashCode hash = default;
hash.Add(this.RMin);

Loading…
Cancel
Save