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.Buffers;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Processing.Processors.Quantization namespace SixLabors.ImageSharp.Processing.Processors.Quantization
@ -34,7 +33,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
{ {
this.Palette = palette; this.Palette = palette;
this.rgbaPalette = new Rgba32[palette.Length]; 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); 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 RgbShift = 8 - IndexBits;
private const int AlphaShift = 8 - IndexAlphaBits; private const int AlphaShift = 8 - IndexAlphaBits;
private const int TableLength = IndexCount * IndexCount * IndexCount * IndexAlphaCount; private const int TableLength = IndexCount * IndexCount * IndexCount * IndexAlphaCount;
private readonly IMemoryOwner<short> tableOwner; private const int TableLengthBytes = TableLength * sizeof(short);
private MemoryHandle tableHandle; 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.table = ArrayPool<byte>.Shared.Rent(lengthBytes);
this.tableOwner.GetSpan().Fill(-1); this.tableHandle = this.table.AsMemory().Pin();
this.tableHandle = this.tableOwner.Memory.Pin(); new Span<short>(this.tableHandle.Pointer, length).Fill(-1);
this.table = (short*)this.tableHandle.Pointer; this.tablePointer = (short*)this.tableHandle.Pointer;
} }
public static ColorDistanceCache Create()
=> new ColorDistanceCache(TableLength, TableLengthBytes);
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public void Add(Rgba32 rgba, byte index) public void Add(Rgba32 rgba, byte index)
{ {
@ -162,7 +165,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
int b = rgba.B >> RgbShift; int b = rgba.B >> RgbShift;
int a = rgba.A >> AlphaShift; int a = rgba.A >> AlphaShift;
int idx = GetPaletteIndex(r, g, b, a); int idx = GetPaletteIndex(r, g, b, a);
this.table[idx] = index; this.tablePointer[idx] = index;
} }
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
@ -173,12 +176,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
int b = rgba.B >> RgbShift; int b = rgba.B >> RgbShift;
int a = rgba.A >> AlphaShift; int a = rgba.A >> AlphaShift;
int idx = GetPaletteIndex(r, g, b, a); int idx = GetPaletteIndex(r, g, b, a);
match = this.table[idx]; match = this.tablePointer[idx];
return match > -1; return match > -1;
} }
public void Clear() => this.tableOwner.GetSpan().Fill(-1);
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
private static int GetPaletteIndex(int r, int g, int b, int a) private static int GetPaletteIndex(int r, int g, int b, int a)
=> (r << ((IndexBits * 2) + IndexAlphaBits)) => (r << ((IndexBits * 2) + IndexAlphaBits))
@ -192,8 +193,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
public void Dispose() public void Dispose()
{ {
this.tableHandle.Dispose(); if (this.table != null)
this.tableOwner?.Dispose(); {
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); 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(OrderedDither.Ordered3x3))]
[WithFile(TestImages.Png.Bike, PixelTypes.Rgba32, nameof(ErrorDither.FloydSteinberg))] [WithFile(TestImages.Png.Bike, PixelTypes.Rgba32, nameof(ErrorDither.FloydSteinberg))]
public void CommonDitherers_WorkWithDiscoBuffers<TPixel>( public void CommonDitherers_WorkWithDiscoBuffers<TPixel>(

Loading…
Cancel
Save