Browse Source

Correct readonly-semantics for QuantizedFrame

af/merge-core
Anton Firszov 7 years ago
parent
commit
63ffdcb18f
  1. 2
      src/ImageSharp/Advanced/AotCompilerTools.cs
  2. 2
      src/ImageSharp/Formats/Gif/GifEncoderCore.cs
  3. 6
      src/ImageSharp/Formats/Gif/LzwEncoder.cs
  4. 2
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  5. 7
      src/ImageSharp/Processing/Processors/Quantization/FrameQuantizer{TPixel}.cs
  6. 2
      src/ImageSharp/Processing/Processors/Quantization/QuantizeProcessor{TPixel}.cs
  7. 11
      src/ImageSharp/Processing/Processors/Quantization/QuantizedFrame{TPixel}.cs
  8. 26
      src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs
  9. 8
      src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs

2
src/ImageSharp/Advanced/AotCompilerTools.cs

@ -104,7 +104,7 @@ namespace SixLabors.ImageSharp.Advanced
private static void AotCompileWuQuantizer<TPixel>()
where TPixel : struct, IPixel<TPixel>
{
var test = new WuFrameQuantizer<TPixel>(new WuQuantizer(false));
var test = new WuFrameQuantizer<TPixel>(Configuration.Default.MemoryAllocator, new WuQuantizer(false));
test.QuantizeFrame(new ImageFrame<TPixel>(Configuration.Default, 1, 1));
test.AotGetPalette();
}

2
src/ImageSharp/Formats/Gif/GifEncoderCore.cs

@ -164,7 +164,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
using (QuantizedFrame<TPixel> paletteQuantized = palleteFrameQuantizer.QuantizeFrame(frame))
{
this.WriteImageData(paletteQuantized, stream);
}
}
}
}
}

6
src/ImageSharp/Formats/Gif/LzwEncoder.cs

@ -180,7 +180,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// </summary>
/// <param name="indexedPixels">The span of indexed pixels.</param>
/// <param name="stream">The stream to write to.</param>
public void Encode(Span<byte> indexedPixels, Stream stream)
public void Encode(ReadOnlySpan<byte> indexedPixels, Stream stream)
{
// Write "initial code size" byte
stream.WriteByte((byte)this.initialCodeSize);
@ -251,7 +251,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// <param name="indexedPixels">The span of indexed pixels.</param>
/// <param name="intialBits">The initial bits.</param>
/// <param name="stream">The stream to write to.</param>
private void Compress(Span<byte> indexedPixels, int intialBits, Stream stream)
private void Compress(ReadOnlySpan<byte> indexedPixels, int intialBits, Stream stream)
{
int fcode;
int c;
@ -375,7 +375,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// The <see cref="int"/>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int NextPixel(Span<byte> indexedPixels)
private int NextPixel(ReadOnlySpan<byte> indexedPixels)
{
return indexedPixels[this.position++] & 0xFF;
}

2
src/ImageSharp/Formats/Png/PngEncoderCore.cs

@ -676,7 +676,7 @@ namespace SixLabors.ImageSharp.Formats.Png
{
ref byte colorTableRef = ref MemoryMarshal.GetReference(colorTable.GetSpan());
ref byte alphaTableRef = ref MemoryMarshal.GetReference(alphaTable.GetSpan());
Span<byte> quantizedSpan = quantized.GetPixelSpan();
ReadOnlySpan<byte> quantizedSpan = quantized.GetPixelSpan();
Rgba32 rgba = default;

7
src/ImageSharp/Processing/Processors/Quantization/FrameQuantizer{TPixel}.cs

@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
}
/// <inheritdoc/>
public virtual QuantizedFrame<TPixel> QuantizeFrame(ImageFrame<TPixel> image)
public QuantizedFrame<TPixel> QuantizeFrame(ImageFrame<TPixel> image)
{
Guard.NotNull(image, nameof(image));
@ -112,17 +112,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
var quantizedFrame = new QuantizedFrame<TPixel>(image.MemoryAllocator, width, height, palette);
Span<byte> pixelSpan = quantizedFrame.GetWritablePixelSpan();
if (this.Dither)
{
// We clone the image as we don't want to alter the original via dithering.
using (ImageFrame<TPixel> clone = image.Clone())
{
this.SecondPass(clone, quantizedFrame.GetPixelSpan(), palette.Span, width, height);
this.SecondPass(clone, pixelSpan, palette.Span, width, height);
}
}
else
{
this.SecondPass(image, quantizedFrame.GetPixelSpan(), palette.Span, width, height);
this.SecondPass(image, pixelSpan, palette.Span, width, height);
}
return quantizedFrame;

2
src/ImageSharp/Processing/Processors/Quantization/QuantizeProcessor{TPixel}.cs

@ -45,7 +45,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
ReadOnlySpan<byte> quantizedPixelSpan = quantized.GetPixelSpan();
ReadOnlySpan<TPixel> paletteSpan = quantized.Palette.Span;
int yy = y * source.Width;
for (int x = 0; x < source.Width; x++)

11
src/ImageSharp/Processing/Processors/Quantization/QuantizedFrame{TPixel}.cs

@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
/// <param name="width">The image width.</param>
/// <param name="height">The image height.</param>
/// <param name="palette">The color palette.</param>
public QuantizedFrame(MemoryAllocator memoryAllocator, int width, int height, ReadOnlyMemory<TPixel> palette)
internal QuantizedFrame(MemoryAllocator memoryAllocator, int width, int height, ReadOnlyMemory<TPixel> palette)
{
Guard.MustBeGreaterThan(width, 0, nameof(width));
Guard.MustBeGreaterThan(height, 0, nameof(height));
@ -58,7 +58,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
/// </summary>
/// <returns>The <see cref="Span{T}"/></returns>
[MethodImpl(InliningOptions.ShortMethod)]
public Span<byte> GetPixelSpan() => this.pixels.GetSpan();
public ReadOnlySpan<byte> GetPixelSpan() => this.pixels.GetSpan();
/// <summary>
/// Gets the representation of the pixels as a <see cref="Span{T}"/> of contiguous memory
@ -67,7 +67,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
/// <param name="rowIndex">The row.</param>
/// <returns>The <see cref="Span{T}"/></returns>
[MethodImpl(InliningOptions.ShortMethod)]
public Span<byte> GetRowSpan(int rowIndex) => this.GetPixelSpan().Slice(rowIndex * this.Width, this.Width);
public ReadOnlySpan<byte> GetRowSpan(int rowIndex) => this.GetPixelSpan().Slice(rowIndex * this.Width, this.Width);
/// <inheritdoc/>
public void Dispose()
@ -76,5 +76,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
this.pixels = null;
this.Palette = null;
}
/// <summary>
/// Get the non-readonly span of pixel data so <see cref="FrameQuantizer{TPixel}"/> can fill it.
/// </summary>
internal Span<byte> GetWritablePixelSpan() => this.pixels.GetSpan();
}
}

26
src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs

@ -120,33 +120,31 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
/// <summary>
/// Initializes a new instance of the <see cref="WuFrameQuantizer{TPixel}"/> class.
/// </summary>
/// <param name="memoryAllocator">The <see cref="MemoryAllocator"/>.</param>
/// <param name="quantizer">The wu quantizer</param>
/// <remarks>
/// The Wu quantizer is a two pass algorithm. The initial pass sets up the 3-D color histogram,
/// the second pass quantizes a color based on the position in the histogram.
/// </remarks>
public WuFrameQuantizer(WuQuantizer quantizer)
: this(quantizer, quantizer.MaxColors)
public WuFrameQuantizer(MemoryAllocator memoryAllocator, WuQuantizer quantizer)
: this(memoryAllocator, quantizer, quantizer.MaxColors)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="WuFrameQuantizer{TPixel}"/> class.
/// </summary>
/// <param name="memoryAllocator">The <see cref="MemoryAllocator"/>.</param>
/// <param name="quantizer">The wu quantizer.</param>
/// <param name="maxColors">The maximum number of colors to hold in the color palette.</param>
/// <remarks>
/// The Wu quantizer is a two pass algorithm. The initial pass sets up the 3-D color histogram,
/// the second pass quantizes a color based on the position in the histogram.
/// </remarks>
public WuFrameQuantizer(WuQuantizer quantizer, int maxColors)
: base(quantizer, false) => this.colors = maxColors;
/// <inheritdoc/>
public override QuantizedFrame<TPixel> QuantizeFrame(ImageFrame<TPixel> image)
public WuFrameQuantizer(MemoryAllocator memoryAllocator, WuQuantizer quantizer, int maxColors)
: base(quantizer, false)
{
Guard.NotNull(image, nameof(image));
MemoryAllocator memoryAllocator = image.MemoryAllocator;
Guard.NotNull(memoryAllocator, nameof(memoryAllocator));
this.vwt = memoryAllocator.Allocate<long>(TableLength, AllocationOptions.Clean);
this.vmr = memoryAllocator.Allocate<long>(TableLength, AllocationOptions.Clean);
@ -156,7 +154,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
this.m2 = memoryAllocator.Allocate<double>(TableLength, AllocationOptions.Clean);
this.tag = memoryAllocator.Allocate<byte>(TableLength, AllocationOptions.Clean);
return base.QuantizeFrame(image);
this.colors = maxColors;
}
/// <inheritdoc/>
@ -169,6 +167,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
this.vma?.Dispose();
this.m2?.Dispose();
this.tag?.Dispose();
this.vwt = null;
this.vmr = null;
this.vmg = null;
this.vmb = null;
this.vma = null;
this.m2 = null;
this.tag = null;
}
internal ReadOnlyMemory<TPixel> AotGetPalette() => this.GetPalette();

8
src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs

@ -72,14 +72,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
/// <inheritdoc />
public IFrameQuantizer<TPixel> CreateFrameQuantizer<TPixel>(Configuration configuration)
where TPixel : struct, IPixel<TPixel>
=> new WuFrameQuantizer<TPixel>(this);
{
Guard.NotNull(configuration, nameof(configuration));
return new WuFrameQuantizer<TPixel>(configuration.MemoryAllocator, this);
}
/// <inheritdoc/>
public IFrameQuantizer<TPixel> CreateFrameQuantizer<TPixel>(Configuration configuration, int maxColors)
where TPixel : struct, IPixel<TPixel>
{
Guard.NotNull(configuration, nameof(configuration));
maxColors = maxColors.Clamp(QuantizerConstants.MinColors, QuantizerConstants.MaxColors);
return new WuFrameQuantizer<TPixel>(this, maxColors);
return new WuFrameQuantizer<TPixel>(configuration.MemoryAllocator, this, maxColors);
}
private static IErrorDiffuser GetDiffuser(bool dither) => dither ? KnownDiffusers.FloydSteinberg : null;

Loading…
Cancel
Save