|
|
@ -7,7 +7,7 @@ using System.Collections.Generic; |
|
|
using System.Numerics; |
|
|
using System.Numerics; |
|
|
using System.Runtime.CompilerServices; |
|
|
using System.Runtime.CompilerServices; |
|
|
using System.Runtime.InteropServices; |
|
|
using System.Runtime.InteropServices; |
|
|
using SixLabors.ImageSharp.Advanced; |
|
|
using SixLabors.ImageSharp.Memory; |
|
|
using SixLabors.ImageSharp.PixelFormats; |
|
|
using SixLabors.ImageSharp.PixelFormats; |
|
|
using SixLabors.ImageSharp.Processing.Processors.Dithering; |
|
|
using SixLabors.ImageSharp.Processing.Processors.Dithering; |
|
|
|
|
|
|
|
|
@ -40,6 +40,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization |
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// Initializes a new instance of the <see cref="FrameQuantizer{TPixel}"/> class.
|
|
|
/// Initializes a new instance of the <see cref="FrameQuantizer{TPixel}"/> class.
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="configuration">The configuration which allows altering default behaviour or extending the library.</param>
|
|
|
/// <param name="quantizer">The quantizer</param>
|
|
|
/// <param name="quantizer">The quantizer</param>
|
|
|
/// <param name="singlePass">
|
|
|
/// <param name="singlePass">
|
|
|
/// If true, the quantization process only needs to loop through the source pixels once
|
|
|
/// If true, the quantization process only needs to loop through the source pixels once
|
|
|
@ -49,10 +50,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization |
|
|
/// only call the <see cref="SecondPass(ImageFrame{TPixel}, Span{byte}, ReadOnlySpan{TPixel}, int, int)"/> method.
|
|
|
/// only call the <see cref="SecondPass(ImageFrame{TPixel}, Span{byte}, ReadOnlySpan{TPixel}, int, int)"/> method.
|
|
|
/// If two passes are required, the code will also call <see cref="FirstPass(ImageFrame{TPixel}, int, int)"/>.
|
|
|
/// If two passes are required, the code will also call <see cref="FirstPass(ImageFrame{TPixel}, int, int)"/>.
|
|
|
/// </remarks>
|
|
|
/// </remarks>
|
|
|
protected FrameQuantizer(IQuantizer quantizer, bool singlePass) |
|
|
protected FrameQuantizer(Configuration configuration, IQuantizer quantizer, bool singlePass) |
|
|
{ |
|
|
{ |
|
|
Guard.NotNull(quantizer, nameof(quantizer)); |
|
|
Guard.NotNull(quantizer, nameof(quantizer)); |
|
|
|
|
|
|
|
|
|
|
|
this.Configuration = configuration; |
|
|
this.Diffuser = quantizer.Diffuser; |
|
|
this.Diffuser = quantizer.Diffuser; |
|
|
this.Dither = this.Diffuser != null; |
|
|
this.Dither = this.Diffuser != null; |
|
|
this.singlePass = singlePass; |
|
|
this.singlePass = singlePass; |
|
|
@ -61,6 +63,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization |
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// Initializes a new instance of the <see cref="FrameQuantizer{TPixel}"/> class.
|
|
|
/// Initializes a new instance of the <see cref="FrameQuantizer{TPixel}"/> class.
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="configuration">The configuration which allows altering default behaviour or extending the library.</param>
|
|
|
/// <param name="diffuser">The diffuser</param>
|
|
|
/// <param name="diffuser">The diffuser</param>
|
|
|
/// <param name="singlePass">
|
|
|
/// <param name="singlePass">
|
|
|
/// If true, the quantization process only needs to loop through the source pixels once
|
|
|
/// If true, the quantization process only needs to loop through the source pixels once
|
|
|
@ -70,8 +73,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization |
|
|
/// only call the <see cref="SecondPass(ImageFrame{TPixel}, Span{byte}, ReadOnlySpan{TPixel}, int, int)"/> method.
|
|
|
/// only call the <see cref="SecondPass(ImageFrame{TPixel}, Span{byte}, ReadOnlySpan{TPixel}, int, int)"/> method.
|
|
|
/// If two passes are required, the code will also call <see cref="FirstPass(ImageFrame{TPixel}, int, int)"/>.
|
|
|
/// If two passes are required, the code will also call <see cref="FirstPass(ImageFrame{TPixel}, int, int)"/>.
|
|
|
/// </remarks>
|
|
|
/// </remarks>
|
|
|
protected FrameQuantizer(IErrorDiffuser diffuser, bool singlePass) |
|
|
protected FrameQuantizer(Configuration configuration, IErrorDiffuser diffuser, bool singlePass) |
|
|
{ |
|
|
{ |
|
|
|
|
|
this.Configuration = configuration; |
|
|
this.Diffuser = diffuser; |
|
|
this.Diffuser = diffuser; |
|
|
this.Dither = this.Diffuser != null; |
|
|
this.Dither = this.Diffuser != null; |
|
|
this.singlePass = singlePass; |
|
|
this.singlePass = singlePass; |
|
|
@ -83,6 +87,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization |
|
|
/// <inheritdoc />
|
|
|
/// <inheritdoc />
|
|
|
public bool Dither { get; } |
|
|
public bool Dither { get; } |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Gets the configuration which allows altering default behaviour or extending the library.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
protected Configuration Configuration { get; } |
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
/// <inheritdoc/>
|
|
|
public void Dispose() |
|
|
public void Dispose() |
|
|
{ |
|
|
{ |
|
|
@ -109,15 +118,16 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization |
|
|
|
|
|
|
|
|
// Collect the palette. Required before the second pass runs.
|
|
|
// Collect the palette. Required before the second pass runs.
|
|
|
ReadOnlyMemory<TPixel> palette = this.GetPalette(); |
|
|
ReadOnlyMemory<TPixel> palette = this.GetPalette(); |
|
|
Configuration configuration = image.GetConfiguration(); |
|
|
MemoryAllocator memoryAllocator = this.Configuration.MemoryAllocator; |
|
|
this.paletteVector = configuration.MemoryAllocator.Allocate<Vector4>(palette.Length); |
|
|
|
|
|
|
|
|
this.paletteVector = memoryAllocator.Allocate<Vector4>(palette.Length); |
|
|
PixelOperations<TPixel>.Instance.ToVector4( |
|
|
PixelOperations<TPixel>.Instance.ToVector4( |
|
|
configuration, |
|
|
this.Configuration, |
|
|
palette.Span, |
|
|
palette.Span, |
|
|
this.paletteVector.Memory.Span, |
|
|
this.paletteVector.Memory.Span, |
|
|
PixelConversionModifiers.Scale); |
|
|
PixelConversionModifiers.Scale); |
|
|
|
|
|
|
|
|
var quantizedFrame = new QuantizedFrame<TPixel>(image.MemoryAllocator, width, height, palette); |
|
|
var quantizedFrame = new QuantizedFrame<TPixel>(memoryAllocator, width, height, palette); |
|
|
|
|
|
|
|
|
Span<byte> pixelSpan = quantizedFrame.GetWritablePixelSpan(); |
|
|
Span<byte> pixelSpan = quantizedFrame.GetWritablePixelSpan(); |
|
|
if (this.Dither) |
|
|
if (this.Dither) |
|
|
|