Browse Source

Revert "quantizer mess"

This reverts commit eab8a96236.
af/UniformUnmanagedMemoryPoolMemoryAllocator-02-MemoryGuards
Anton Firszov 5 years ago
parent
commit
8745f84ac3
  1. 8
      src/ImageSharp/Advanced/AotCompilerTools.cs
  2. 2
      src/ImageSharp/Processing/Processors/Dithering/ErroDither.KnownTypes.cs
  3. 26
      src/ImageSharp/Processing/Processors/Dithering/ErrorDither.cs
  4. 8
      src/ImageSharp/Processing/Processors/Dithering/IDither.cs
  5. 2
      src/ImageSharp/Processing/Processors/Dithering/OrderedDither.KnownTypes.cs
  6. 31
      src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs
  7. 4
      src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessor{TPixel}.cs
  8. 36
      src/ImageSharp/Processing/Processors/Quantization/EuclideanPixelMap{TPixel}.cs
  9. 16
      src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs
  10. 12
      src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs
  11. 16
      src/ImageSharp/Processing/Processors/Quantization/QuantizerUtilities.cs
  12. 13
      src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs

8
src/ImageSharp/Advanced/AotCompilerTools.cs

@ -508,16 +508,16 @@ namespace SixLabors.ImageSharp.Advanced
[Preserve]
private static void AotCompileDither<TPixel, TDither>()
where TPixel : unmanaged, IPixel<TPixel>
where TDither : class, IDither
where TDither : struct, IDither
{
var octree = default(OctreeQuantizer<TPixel>);
default(TDither).ApplyQuantizationDither<OctreeQuantizer<TPixel>, TPixel>(octree, default, default, default);
default(TDither).ApplyQuantizationDither<OctreeQuantizer<TPixel>, TPixel>(ref octree, default, default, default);
var palette = default(PaletteQuantizer<TPixel>);
default(TDither).ApplyQuantizationDither<PaletteQuantizer<TPixel>, TPixel>(palette, default, default, default);
default(TDither).ApplyQuantizationDither<PaletteQuantizer<TPixel>, TPixel>(ref palette, default, default, default);
var wu = default(WuQuantizer<TPixel>);
default(TDither).ApplyQuantizationDither<WuQuantizer<TPixel>, TPixel>(wu, default, default, default);
default(TDither).ApplyQuantizationDither<WuQuantizer<TPixel>, TPixel>(ref wu, default, default, default);
default(TDither).ApplyPaletteDither<PaletteDitherProcessor<TPixel>.DitherProcessor, TPixel>(default, default, default);
}

2
src/ImageSharp/Processing/Processors/Dithering/ErroDither.KnownTypes.cs

@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering
/// <summary>
/// An error diffusion dithering implementation.
/// </summary>
public partial class ErrorDither
public readonly partial struct ErrorDither
{
/// <summary>
/// Applies error diffusion based dithering using the Atkinson image dithering algorithm.

26
src/ImageSharp/Processing/Processors/Dithering/ErrorDither.cs

@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering
/// An error diffusion dithering implementation.
/// <see href="http://www.efg2.com/Lab/Library/ImageProcessing/DHALF.TXT"/>
/// </summary>
public partial class ErrorDither : IDither, IEquatable<ErrorDither>, IEquatable<IDither>
public readonly partial struct ErrorDither : IDither, IEquatable<ErrorDither>, IEquatable<IDither>
{
private readonly int offset;
private readonly DenseMatrix<float> matrix;
@ -91,17 +91,17 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void ApplyQuantizationDither<TFrameQuantizer, TPixel>(
TFrameQuantizer quantizer,
ref TFrameQuantizer quantizer,
ImageFrame<TPixel> source,
IndexedImageFrame<TPixel> destination,
Rectangle bounds)
where TFrameQuantizer : class, IQuantizer<TPixel>
where TFrameQuantizer : struct, IQuantizer<TPixel>
where TPixel : unmanaged, IPixel<TPixel>
{
// if (this == default)
// {
// ThrowDefaultInstance();
// }
if (this == default)
{
ThrowDefaultInstance();
}
int offsetY = bounds.Top;
int offsetX = bounds.Left;
@ -131,16 +131,16 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void ApplyPaletteDither<TPaletteDitherImageProcessor, TPixel>(
TPaletteDitherImageProcessor processor,
in TPaletteDitherImageProcessor processor,
ImageFrame<TPixel> source,
Rectangle bounds)
where TPaletteDitherImageProcessor : class, IPaletteDitherImageProcessor<TPixel>
where TPaletteDitherImageProcessor : struct, IPaletteDitherImageProcessor<TPixel>
where TPixel : unmanaged, IPixel<TPixel>
{
// if (this == default)
// {
// ThrowDefaultInstance();
// }
if (this == default)
{
ThrowDefaultInstance();
}
Buffer2D<TPixel> sourceBuffer = source.PixelBuffer;
float scale = processor.DitherScale;

8
src/ImageSharp/Processing/Processors/Dithering/IDither.cs

@ -22,11 +22,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering
/// <param name="destination">The destination quantized frame.</param>
/// <param name="bounds">The region of interest bounds.</param>
void ApplyQuantizationDither<TFrameQuantizer, TPixel>(
TFrameQuantizer quantizer,
ref TFrameQuantizer quantizer,
ImageFrame<TPixel> source,
IndexedImageFrame<TPixel> destination,
Rectangle bounds)
where TFrameQuantizer : class, IQuantizer<TPixel>
where TFrameQuantizer : struct, IQuantizer<TPixel>
where TPixel : unmanaged, IPixel<TPixel>;
/// <summary>
@ -39,10 +39,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering
/// <param name="source">The source image.</param>
/// <param name="bounds">The region of interest bounds.</param>
void ApplyPaletteDither<TPaletteDitherImageProcessor, TPixel>(
TPaletteDitherImageProcessor processor,
in TPaletteDitherImageProcessor processor,
ImageFrame<TPixel> source,
Rectangle bounds)
where TPaletteDitherImageProcessor : class, IPaletteDitherImageProcessor<TPixel>
where TPaletteDitherImageProcessor : struct, IPaletteDitherImageProcessor<TPixel>
where TPixel : unmanaged, IPixel<TPixel>;
}
}

2
src/ImageSharp/Processing/Processors/Dithering/OrderedDither.KnownTypes.cs

@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering
/// <content>
/// An ordered dithering matrix with equal sides of arbitrary length
/// </content>
public partial class OrderedDither
public readonly partial struct OrderedDither
{
/// <summary>
/// Applies order dithering using the 2x2 Bayer dithering matrix.

31
src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs

@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering
/// <summary>
/// An ordered dithering matrix with equal sides of arbitrary length
/// </summary>
public partial class OrderedDither : IDither, IEquatable<OrderedDither>, IEquatable<IDither>
public readonly partial struct OrderedDither : IDither, IEquatable<OrderedDither>, IEquatable<IDither>
{
private readonly DenseMatrix<float> thresholdMatrix;
private readonly int modulusX;
@ -105,17 +105,17 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void ApplyQuantizationDither<TFrameQuantizer, TPixel>(
TFrameQuantizer quantizer,
ref TFrameQuantizer quantizer,
ImageFrame<TPixel> source,
IndexedImageFrame<TPixel> destination,
Rectangle bounds)
where TFrameQuantizer : class, IQuantizer<TPixel>
where TFrameQuantizer : struct, IQuantizer<TPixel>
where TPixel : unmanaged, IPixel<TPixel>
{
// if (this == default)
// {
// ThrowDefaultInstance();
// }
if (this == default)
{
ThrowDefaultInstance();
}
int spread = CalculatePaletteSpread(destination.Palette.Length);
float scale = quantizer.Options.DitherScale;
@ -134,24 +134,19 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering
}
}
// public void ApplyQuantizationDither<TFrameQuantizer, TPixel>(TFrameQuantizer quantizer, ImageFrame<TPixel> source,
// IndexedImageFrame<TPixel> destination, Rectangle bounds)
// where TFrameQuantizer : class, IQuantizer<TPixel> where TPixel : unmanaged, IPixel<TPixel> =>
// throw new NotImplementedException();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void ApplyPaletteDither<TPaletteDitherImageProcessor, TPixel>(
TPaletteDitherImageProcessor processor,
in TPaletteDitherImageProcessor processor,
ImageFrame<TPixel> source,
Rectangle bounds)
where TPaletteDitherImageProcessor : class, IPaletteDitherImageProcessor<TPixel>
where TPaletteDitherImageProcessor : struct, IPaletteDitherImageProcessor<TPixel>
where TPixel : unmanaged, IPixel<TPixel>
{
// if (this == default)
// {
// ThrowDefaultInstance();
// }
if (this == default)
{
ThrowDefaultInstance();
}
int spread = CalculatePaletteSpread(processor.Palette.Length);
float scale = processor.DitherScale;

4
src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessor{TPixel}.cs

@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering
protected override void OnFrameApply(ImageFrame<TPixel> source)
{
var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds());
this.dither.ApplyPaletteDither(this.ditherProcessor, source, interest);
this.dither.ApplyPaletteDither(in this.ditherProcessor, source, interest);
}
/// <inheritdoc/>
@ -74,7 +74,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering
/// <see cref="IPaletteDitherImageProcessor{TPixel}.GetPaletteColor(TPixel)"/>.
/// </summary>
/// <remarks>Internal for AOT</remarks>
internal class DitherProcessor : IPaletteDitherImageProcessor<TPixel>, IDisposable
internal readonly struct DitherProcessor : IPaletteDitherImageProcessor<TPixel>, IDisposable
{
private readonly EuclideanPixelMap<TPixel> pixelMap;

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

@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
where TPixel : unmanaged, IPixel<TPixel>
{
private Rgba32[] rgbaPalette;
private ColorDistanceCache cache;
private readonly ColorDistanceCache cache;
private readonly Configuration configuration;
/// <summary>
@ -136,13 +136,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
return (deltaR * deltaR) + (deltaG * deltaG) + (deltaB * deltaB) + (deltaA * deltaA);
}
public void Dispose()
{
this.cache.Dispose();
GC.SuppressFinalize(this);
}
~EuclideanPixelMap() => throw new Exception("very bad");
public void Dispose() => this.cache.Dispose();
/// <summary>
/// A cache for storing color distance matching results.
@ -155,7 +149,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
/// Entry count is currently limited to 1185921 entries (2371842 bytes ~2.26MB).
/// </para>
/// </remarks>
private class ColorDistanceCache : IDisposable
private unsafe struct ColorDistanceCache : IDisposable
{
private const int IndexBits = 5;
private const int IndexAlphaBits = 5;
@ -164,18 +158,16 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
private const int RgbShift = 8 - IndexBits;
private const int AlphaShift = 8 - IndexAlphaBits;
private const int Entries = IndexCount * IndexCount * IndexCount * IndexAlphaCount;
// private MemoryHandle tableHandle;
private MemoryHandle tableHandle;
private readonly IMemoryOwner<short> table;
// private readonly short* tablePointer;
private Memory<short> tableMemory;
private readonly short* tablePointer;
public ColorDistanceCache(MemoryAllocator allocator)
{
this.table = allocator.Allocate<short>(Entries);
this.table.GetSpan().Fill(-1);
this.tableMemory = this.table.Memory;
// this.tableHandle = this.table.Memory.Pin();
// this.tablePointer = (short*)this.tableHandle.Pointer;
this.tableHandle = this.table.Memory.Pin();
this.tablePointer = (short*)this.tableHandle.Pointer;
}
[MethodImpl(InliningOptions.ShortMethod)]
@ -186,8 +178,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.tablePointer[idx] = index;
this.table.Memory.Span[idx] = index;
this.tablePointer[idx] = index;
}
[MethodImpl(InliningOptions.ShortMethod)]
@ -198,8 +189,7 @@ 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.tablePointer[idx];
match = this.tableMemory.Span[idx];
match = this.tablePointer[idx];
return match > -1;
}
@ -224,15 +214,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
{
if (this.table != null)
{
// this.tableHandle.Dispose();
this.tableHandle.Dispose();
this.table.Dispose();
}
GC.SuppressFinalize(this);
}
~ColorDistanceCache()
{
throw new Exception("very bad");
}
}
}

16
src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs

@ -5,7 +5,6 @@ using System;
using System.Buffers;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
@ -17,7 +16,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
/// <see href="http://msdn.microsoft.com/en-us/library/aa479306.aspx"/>
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
public class OctreeQuantizer<TPixel> : IQuantizer<TPixel>
public struct OctreeQuantizer<TPixel> : IQuantizer<TPixel>
where TPixel : unmanaged, IPixel<TPixel>
{
private readonly int maxColors;
@ -53,11 +52,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
this.isDisposed = false;
}
~OctreeQuantizer()
{
throw new Exception("Very bad");
}
/// <inheritdoc/>
public Configuration Configuration { get; }
@ -132,12 +126,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public IndexedImageFrame<TPixel> QuantizeFrame(ImageFrame<TPixel> source, Rectangle bounds)
=> QuantizerUtilities.QuantizeFrame(this, source, bounds);
public readonly IndexedImageFrame<TPixel> QuantizeFrame(ImageFrame<TPixel> source, Rectangle bounds)
=> QuantizerUtilities.QuantizeFrame(ref Unsafe.AsRef(this), source, bounds);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public byte GetQuantizedColor(TPixel color, out TPixel match)
public readonly byte GetQuantizedColor(TPixel color, out TPixel match)
{
// Octree only maps the RGB component of a color
// so cannot tell the difference between a fully transparent
@ -164,8 +158,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
this.pixelMap?.Dispose();
this.pixelMap = null;
}
GC.SuppressFinalize(this);
}
/// <summary>

12
src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs

@ -3,7 +3,6 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
@ -14,7 +13,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
/// <see href="http://msdn.microsoft.com/en-us/library/aa479306.aspx"/>
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
internal class PaletteQuantizer<TPixel> : IQuantizer<TPixel>
internal struct PaletteQuantizer<TPixel> : IQuantizer<TPixel>
where TPixel : unmanaged, IPixel<TPixel>
{
private EuclideanPixelMap<TPixel> pixelMap;
@ -36,8 +35,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
this.pixelMap = new EuclideanPixelMap<TPixel>(configuration, palette);
}
~PaletteQuantizer() => throw new Exception("Very bad");
/// <inheritdoc/>
public Configuration Configuration { get; }
@ -49,8 +46,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public IndexedImageFrame<TPixel> QuantizeFrame(ImageFrame<TPixel> source, Rectangle bounds)
=> QuantizerUtilities.QuantizeFrame(this, source, bounds);
public readonly IndexedImageFrame<TPixel> QuantizeFrame(ImageFrame<TPixel> source, Rectangle bounds)
=> QuantizerUtilities.QuantizeFrame(ref Unsafe.AsRef(this), source, bounds);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
@ -60,7 +57,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public byte GetQuantizedColor(TPixel color, out TPixel match)
public readonly byte GetQuantizedColor(TPixel color, out TPixel match)
=> (byte)this.pixelMap.GetClosestColor(color, out match);
/// <inheritdoc/>
@ -68,7 +65,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
{
this.pixelMap?.Dispose();
this.pixelMap = null;
GC.SuppressFinalize(this);
}
}
}

16
src/ImageSharp/Processing/Processors/Quantization/QuantizerUtilities.cs

@ -71,10 +71,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
/// A <see cref="IndexedImageFrame{TPixel}"/> representing a quantized version of the source frame pixels.
/// </returns>
public static IndexedImageFrame<TPixel> QuantizeFrame<TFrameQuantizer, TPixel>(
TFrameQuantizer quantizer,
ref TFrameQuantizer quantizer,
ImageFrame<TPixel> source,
Rectangle bounds)
where TFrameQuantizer : class, IQuantizer<TPixel>
where TFrameQuantizer : struct, IQuantizer<TPixel>
where TPixel : unmanaged, IPixel<TPixel>
{
Guard.NotNull(source, nameof(source));
@ -88,13 +88,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
if (quantizer.Options.Dither is null)
{
SecondPass(quantizer, source, destination, interest);
SecondPass(ref quantizer, source, destination, interest);
}
else
{
// We clone the image as we don't want to alter the original via error diffusion based dithering.
using ImageFrame<TPixel> clone = source.Clone();
SecondPass(quantizer, clone, destination, interest);
SecondPass(ref quantizer, clone, destination, interest);
}
return destination;
@ -114,11 +114,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
[MethodImpl(InliningOptions.ShortMethod)]
private static void SecondPass<TFrameQuantizer, TPixel>(
TFrameQuantizer quantizer,
ref TFrameQuantizer quantizer,
ImageFrame<TPixel> source,
IndexedImageFrame<TPixel> destination,
Rectangle bounds)
where TFrameQuantizer : class, IQuantizer<TPixel>
where TFrameQuantizer : struct, IQuantizer<TPixel>
where TPixel : unmanaged, IPixel<TPixel>
{
IDither dither = quantizer.Options.Dither;
@ -136,14 +136,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
for (int x = bounds.Left; x < bounds.Right; x++)
{
destinationRow[x - offsetX] = quantizer.GetQuantizedColor(sourceRow[x], out TPixel _);
destinationRow[x - offsetX] = Unsafe.AsRef(quantizer).GetQuantizedColor(sourceRow[x], out TPixel _);
}
}
return;
}
dither.ApplyQuantizationDither(quantizer, source, destination, bounds);
dither.ApplyQuantizationDither(ref quantizer, source, destination, bounds);
}
}
}

13
src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs

@ -5,7 +5,6 @@ using System;
using System.Buffers;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
@ -32,7 +31,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
/// </para>
/// </remarks>
/// <typeparam name="TPixel">The pixel format.</typeparam>
internal class WuQuantizer<TPixel> : IQuantizer<TPixel>
internal struct WuQuantizer<TPixel> : IQuantizer<TPixel>
where TPixel : unmanaged, IPixel<TPixel>
{
private readonly MemoryAllocator memoryAllocator;
@ -101,8 +100,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
this.isDithering = this.isDithering = !(this.Options.Dither is null);
}
~WuQuantizer() => throw new Exception("very bad");
/// <inheritdoc/>
public Configuration Configuration { get; }
@ -165,11 +162,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public IndexedImageFrame<TPixel> QuantizeFrame(ImageFrame<TPixel> source, Rectangle bounds)
=> QuantizerUtilities.QuantizeFrame(this, source, bounds);
public readonly IndexedImageFrame<TPixel> QuantizeFrame(ImageFrame<TPixel> source, Rectangle bounds)
=> QuantizerUtilities.QuantizeFrame(ref Unsafe.AsRef(this), source, bounds);
/// <inheritdoc/>
public byte GetQuantizedColor(TPixel color, out TPixel match)
public readonly byte GetQuantizedColor(TPixel color, out TPixel match)
{
if (this.isDithering)
{
@ -206,8 +203,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
this.pixelMap?.Dispose();
this.pixelMap = null;
}
GC.SuppressFinalize(this);
}
/// <summary>

Loading…
Cancel
Save