Browse Source

Use ArrayPool byte with pinning.

pull/1654/head
James Jackson-South 5 years ago
parent
commit
27ec4ac074
  1. 34
      src/ImageSharp/Processing/Processors/Quantization/EuclideanPixelMap{TPixel}.cs
  2. 2
      tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs

34
src/ImageSharp/Processing/Processors/Quantization/EuclideanPixelMap{TPixel}.cs

@ -5,7 +5,6 @@ using System;
using System.Buffers;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Processing.Processors.Quantization
@ -34,7 +33,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
{
this.Palette = palette;
this.rgbaPalette = new Rgba32[palette.Length];
this.cache = new ColorDistanceCache(configuration.MemoryAllocator);
this.cache = ColorDistanceCache.Create();
PixelOperations<TPixel>.Instance.ToRgba32(configuration, this.Palette.Span, this.rgbaPalette);
}
@ -142,18 +141,22 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
private const int RgbShift = 8 - IndexBits;
private const int AlphaShift = 8 - IndexAlphaBits;
private const int TableLength = IndexCount * IndexCount * IndexCount * IndexAlphaCount;
private readonly IMemoryOwner<short> tableOwner;
private const int TableLengthBytes = TableLength * sizeof(short);
private MemoryHandle tableHandle;
private readonly short* table;
private readonly byte[] table;
private readonly short* tablePointer;
public ColorDistanceCache(MemoryAllocator memoryAllocator)
private ColorDistanceCache(int length, int lengthBytes)
{
this.tableOwner = memoryAllocator.Allocate<short>(TableLength);
this.tableOwner.GetSpan().Fill(-1);
this.tableHandle = this.tableOwner.Memory.Pin();
this.table = (short*)this.tableHandle.Pointer;
this.table = ArrayPool<byte>.Shared.Rent(lengthBytes);
this.tableHandle = this.table.AsMemory().Pin();
new Span<short>(this.tableHandle.Pointer, length).Fill(-1);
this.tablePointer = (short*)this.tableHandle.Pointer;
}
public static ColorDistanceCache Create()
=> new ColorDistanceCache(TableLength, TableLengthBytes);
[MethodImpl(InliningOptions.ShortMethod)]
public void Add(Rgba32 rgba, byte index)
{
@ -162,7 +165,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
int b = rgba.B >> RgbShift;
int a = rgba.A >> AlphaShift;
int idx = GetPaletteIndex(r, g, b, a);
this.table[idx] = index;
this.tablePointer[idx] = index;
}
[MethodImpl(InliningOptions.ShortMethod)]
@ -173,12 +176,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
int b = rgba.B >> RgbShift;
int a = rgba.A >> AlphaShift;
int idx = GetPaletteIndex(r, g, b, a);
match = this.table[idx];
match = this.tablePointer[idx];
return match > -1;
}
public void Clear() => this.tableOwner.GetSpan().Fill(-1);
[MethodImpl(InliningOptions.ShortMethod)]
private static int GetPaletteIndex(int r, int g, int b, int a)
=> (r << ((IndexBits * 2) + IndexAlphaBits))
@ -192,8 +193,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
public void Dispose()
{
this.tableHandle.Dispose();
this.tableOwner?.Dispose();
if (this.table != null)
{
ArrayPool<byte>.Shared.Return(this.table);
this.tableHandle.Dispose();
}
}
}
}

2
tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs

@ -156,7 +156,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Dithering
appendPixelTypeToFileName: false);
}
[Theory(Skip = "Unable to assign capacity smaller than the image.")]
[Theory]
[WithFile(TestImages.Png.Bike, PixelTypes.Rgba32, nameof(OrderedDither.Ordered3x3))]
[WithFile(TestImages.Png.Bike, PixelTypes.Rgba32, nameof(ErrorDither.FloydSteinberg))]
public void CommonDitherers_WorkWithDiscoBuffers<TPixel>(

Loading…
Cancel
Save