diff --git a/src/ImageSharp/Formats/AlphaAwareImageEncoder.cs b/src/ImageSharp/Formats/AlphaAwareImageEncoder.cs
index f753e7282..1c1a8b291 100644
--- a/src/ImageSharp/Formats/AlphaAwareImageEncoder.cs
+++ b/src/ImageSharp/Formats/AlphaAwareImageEncoder.cs
@@ -1,6 +1,8 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
+using SixLabors.ImageSharp.Processing.Processors.Quantization;
+
namespace SixLabors.ImageSharp.Formats;
///
@@ -10,6 +12,8 @@ public abstract class AlphaAwareImageEncoder : ImageEncoder
{
///
/// Gets or initializes the mode that determines how transparent pixels are handled during encoding.
+ /// This overrides any other settings that may affect the encoding of transparent pixels
+ /// including those passed via .
///
public TransparentColorMode TransparentColorMode { get; init; }
}
diff --git a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs
index 114cb4347..c0d74e03e 100644
--- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs
+++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs
@@ -150,10 +150,7 @@ internal sealed class GifEncoderCore
TransparentColorMode mode = this.transparentColorMode;
QuantizerOptions options = this.quantizer.Options.DeepClone(o => o.TransparentColorMode = mode);
- // Quantize the first frame. Checking to see whether we can clear the transparent pixels
- // to allow for a smaller color palette and encoded result.
- // TODO: What should we use as the background color here?
- Color background = Color.Transparent;
+ // Quantize the first frame.
using (IQuantizer frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer(this.configuration, options))
{
IPixelSamplingStrategy strategy = this.pixelSamplingStrategy;
@@ -163,12 +160,12 @@ internal sealed class GifEncoderCore
{
if (useGlobalTable)
{
- frameQuantizer.BuildPalette(mode, strategy, image);
+ frameQuantizer.BuildPalette(strategy, image);
quantized = frameQuantizer.QuantizeFrame(encodingFrame, image.Bounds);
}
else
{
- frameQuantizer.BuildPalette(mode, strategy, encodingFrame);
+ frameQuantizer.BuildPalette(strategy, encodingFrame);
quantized = frameQuantizer.QuantizeFrame(encodingFrame, encodingFrame.Bounds);
}
}
@@ -176,13 +173,14 @@ internal sealed class GifEncoderCore
{
quantized = this.QuantizeAdditionalFrameAndUpdateMetadata(
encodingFrame,
+ options,
encodingFrame.Bounds,
frameMetadata,
true,
default,
false,
frameMetadata.HasTransparency ? frameMetadata.TransparencyIndex : -1,
- background);
+ Color.Transparent);
}
}
@@ -197,6 +195,7 @@ internal sealed class GifEncoderCore
frameMetadata.TransparencyIndex = ClampIndex(derivedTransparencyIndex);
}
+ // TODO: We should be checking the metadata here also I think?
if (!TryGetBackgroundIndex(quantized, this.backgroundColor, out byte backgroundIndex))
{
backgroundIndex = derivedTransparencyIndex >= 0
@@ -235,6 +234,7 @@ internal sealed class GifEncoderCore
this.EncodeAdditionalFrames(
stream,
image,
+ options,
globalPalette,
derivedTransparencyIndex,
frameMetadata.DisposalMode,
@@ -264,6 +264,7 @@ internal sealed class GifEncoderCore
private void EncodeAdditionalFrames(
Stream stream,
Image image,
+ QuantizerOptions options,
ReadOnlyMemory globalPalette,
int globalTransparencyIndex,
FrameDisposalMode previousDisposalMode,
@@ -301,7 +302,7 @@ internal sealed class GifEncoderCore
// The palette quantizer can reuse the same global pixel map across multiple frames since the palette is unchanging.
// This allows a reduction of memory usage across multi-frame gifs using a global palette
// and also allows use to reuse the cache from previous runs.
- globalPaletteQuantizer = new(this.configuration, this.quantizer!.Options, globalPalette);
+ globalPaletteQuantizer = new(this.configuration, options, globalPalette);
hasGlobalPaletteQuantizer = true;
}
@@ -311,6 +312,7 @@ internal sealed class GifEncoderCore
currentFrame,
nextFrame,
encodingFrame,
+ options,
useLocal,
gifMetadata,
globalPaletteQuantizer,
@@ -361,6 +363,7 @@ internal sealed class GifEncoderCore
ImageFrame currentFrame,
ImageFrame? nextFrame,
ImageFrame encodingFrame,
+ QuantizerOptions options,
bool useLocal,
GifFrameMetadata metadata,
PaletteQuantizer globalPaletteQuantizer,
@@ -392,6 +395,7 @@ internal sealed class GifEncoderCore
using IndexedImageFrame quantized = this.QuantizeAdditionalFrameAndUpdateMetadata(
encodingFrame,
+ options,
bounds,
metadata,
useLocal,
@@ -416,6 +420,7 @@ internal sealed class GifEncoderCore
private IndexedImageFrame QuantizeAdditionalFrameAndUpdateMetadata(
ImageFrame encodingFrame,
+ QuantizerOptions options,
Rectangle bounds,
GifFrameMetadata metadata,
bool useLocal,
@@ -446,7 +451,12 @@ internal sealed class GifEncoderCore
transparencyIndex = palette.Length;
metadata.TransparencyIndex = ClampIndex(transparencyIndex);
- PaletteQuantizer quantizer = new(palette, new() { Dither = null }, transparencyIndex, transparentColor);
+ QuantizerOptions paletteOptions = options.DeepClone(o =>
+ {
+ o.MaxColors = palette.Length;
+ o.Dither = null;
+ });
+ PaletteQuantizer quantizer = new(palette, paletteOptions, transparencyIndex, transparentColor);
using IQuantizer frameQuantizer = quantizer.CreatePixelSpecificQuantizer(this.configuration, quantizer.Options);
quantized = frameQuantizer.BuildPaletteAndQuantizeFrame(encodingFrame, bounds);
}
@@ -454,7 +464,7 @@ internal sealed class GifEncoderCore
{
// We must quantize the frame to generate a local color table.
IQuantizer quantizer = this.hasQuantizer ? this.quantizer! : FallbackQuantizer;
- using IQuantizer frameQuantizer = quantizer.CreatePixelSpecificQuantizer(this.configuration, quantizer.Options);
+ using IQuantizer frameQuantizer = quantizer.CreatePixelSpecificQuantizer(this.configuration, options);
quantized = frameQuantizer.BuildPaletteAndQuantizeFrame(encodingFrame, bounds);
// The transparency index derived by the quantizer will differ from the index
@@ -466,7 +476,12 @@ internal sealed class GifEncoderCore
else
{
// Just use the local palette.
- PaletteQuantizer quantizer = new(palette, new() { Dither = null }, transparencyIndex, transparentColor);
+ QuantizerOptions paletteOptions = options.DeepClone(o =>
+ {
+ o.MaxColors = palette.Length;
+ o.Dither = null;
+ });
+ PaletteQuantizer quantizer = new(palette, paletteOptions, transparencyIndex, transparentColor);
using IQuantizer frameQuantizer = quantizer.CreatePixelSpecificQuantizer(this.configuration, quantizer.Options);
quantized = frameQuantizer.BuildPaletteAndQuantizeFrame(encodingFrame, bounds);
}
@@ -475,7 +490,7 @@ internal sealed class GifEncoderCore
{
// We must quantize the frame to generate a local color table.
IQuantizer quantizer = this.hasQuantizer ? this.quantizer! : FallbackQuantizer;
- using IQuantizer frameQuantizer = quantizer.CreatePixelSpecificQuantizer(this.configuration, quantizer.Options);
+ using IQuantizer frameQuantizer = quantizer.CreatePixelSpecificQuantizer(this.configuration, options);
quantized = frameQuantizer.BuildPaletteAndQuantizeFrame(encodingFrame, bounds);
// The transparency index derived by the quantizer might differ from the index
diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
index 07be36ae2..e9b76522c 100644
--- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
@@ -1574,13 +1574,21 @@ internal sealed class PngEncoderCore : IDisposable
{
// We can use the color data from the decoded metadata here.
// We avoid dithering by default to preserve the original colors.
- this.quantizer = new PaletteQuantizer(metadata.ColorTable.Value, new() { Dither = null });
+ QuantizerOptions options = new() { Dither = null, TransparentColorMode = encoder.TransparentColorMode };
+ this.quantizer = new PaletteQuantizer(metadata.ColorTable.Value, options);
}
else
{
// Don't use the default transparency threshold for quantization as PNG can handle multiple transparent colors.
// We choose a value that is close to zero so that edge cases causes by lower bit depths for the alpha channel are handled correctly.
- this.quantizer = new WuQuantizer(new QuantizerOptions { TransparencyThreshold = 0, MaxColors = ColorNumerics.GetColorCountForBitDepth(bitDepth) });
+ QuantizerOptions options = new()
+ {
+ TransparencyThreshold = 0,
+ MaxColors = ColorNumerics.GetColorCountForBitDepth(bitDepth),
+ TransparentColorMode = encoder.TransparentColorMode
+ };
+
+ this.quantizer = new WuQuantizer(options);
}
}
@@ -1604,7 +1612,6 @@ internal sealed class PngEncoderCore : IDisposable
}
frameQuantizer.BuildPalette(
- encoder.TransparentColorMode,
encoder.PixelSamplingStrategy,
image);
diff --git a/src/ImageSharp/Formats/TransparentColorMode.cs b/src/ImageSharp/Formats/TransparentColorMode.cs
index c4d9c927e..fe88c314f 100644
--- a/src/ImageSharp/Formats/TransparentColorMode.cs
+++ b/src/ImageSharp/Formats/TransparentColorMode.cs
@@ -4,7 +4,7 @@
namespace SixLabors.ImageSharp.Formats;
///
-/// Specifies how transparent pixels should be handled during encoding and quantization.
+/// Specifies how pixels with transparent alpha components should be handled during encoding and quantization.
///
public enum TransparentColorMode
{
diff --git a/src/ImageSharp/Processing/Processors/Quantization/IQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/IQuantizer{TPixel}.cs
index 02c2052fe..1e6420eaa 100644
--- a/src/ImageSharp/Processing/Processors/Quantization/IQuantizer{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Quantization/IQuantizer{TPixel}.cs
@@ -1,7 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
-using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
@@ -36,37 +35,13 @@ public interface IQuantizer : IDisposable
/// Adds colors to the quantized palette from the given pixel source.
///
/// The of source pixels to register.
- public void AddPaletteColors(in Buffer2DRegion pixelRegion)
- => this.AddPaletteColors(pixelRegion, TransparentColorMode.Preserve);
-
- ///
- /// Adds colors to the quantized palette from the given pixel source.
- ///
- /// The of source pixels to register.
- /// The to use when adding colors to the palette.
- public void AddPaletteColors(in Buffer2DRegion pixelRegion, TransparentColorMode mode);
-
- ///
- /// Quantizes an image frame and return the resulting output pixels.
- ///
- /// The source image frame to quantize.
- /// The bounds within the frame to quantize.
- ///
- /// A representing a quantized version of the source frame pixels.
- ///
- ///
- /// Only executes the second (quantization) step. The palette has to be built by calling .
- /// To run both steps, use .
- ///
- public IndexedImageFrame QuantizeFrame(ImageFrame source, Rectangle bounds)
- => this.QuantizeFrame(source, bounds, TransparentColorMode.Preserve);
+ public void AddPaletteColors(in Buffer2DRegion pixelRegion);
///
/// Quantizes an image frame and return the resulting output pixels.
///
/// The source image frame to quantize.
/// The bounds within the frame to quantize.
- /// The to use when quantizing the frame.
///
/// A representing a quantized version of the source frame pixels.
///
@@ -74,7 +49,7 @@ public interface IQuantizer : IDisposable
/// Only executes the second (quantization) step. The palette has to be built by calling .
/// To run both steps, use .
///
- public IndexedImageFrame QuantizeFrame(ImageFrame source, Rectangle bounds, TransparentColorMode mode);
+ public IndexedImageFrame QuantizeFrame(ImageFrame source, Rectangle bounds);
///
/// Returns the index and color from the quantized palette corresponding to the given color.
diff --git a/src/ImageSharp/Processing/Processors/Quantization/IQuantizingPixelRowDelegate{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/IQuantizingPixelRowDelegate{TPixel}.cs
index ce06adf45..3cf4c93d6 100644
--- a/src/ImageSharp/Processing/Processors/Quantization/IQuantizingPixelRowDelegate{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Quantization/IQuantizingPixelRowDelegate{TPixel}.cs
@@ -1,7 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
-using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Processing.Processors.Quantization;
@@ -13,11 +12,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization;
internal interface IQuantizingPixelRowDelegate
where TPixel : unmanaged, IPixel
{
- ///
- /// Gets the transparent color mode to use when adding colors to the palette.
- ///
- public TransparentColorMode TransparentColorMode { get; }
-
///
/// Processes a row of pixels for quantization.
///
diff --git a/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs
index 5f55a4410..07596b68a 100644
--- a/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs
@@ -6,7 +6,6 @@ using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
@@ -75,9 +74,9 @@ public struct OctreeQuantizer : IQuantizer
}
///
- public readonly void AddPaletteColors(in Buffer2DRegion pixelRegion, TransparentColorMode mode)
+ public readonly void AddPaletteColors(in Buffer2DRegion pixelRegion)
{
- PixelRowDelegate pixelRowDelegate = new(this.octree, mode);
+ PixelRowDelegate pixelRowDelegate = new(this.octree);
QuantizerUtilities.AddPaletteColors, TPixel, Rgba32, PixelRowDelegate>(
ref Unsafe.AsRef(in this),
in pixelRegion,
@@ -103,12 +102,7 @@ public struct OctreeQuantizer : IQuantizer
///
[MethodImpl(InliningOptions.ShortMethod)]
public readonly IndexedImageFrame QuantizeFrame(ImageFrame source, Rectangle bounds)
- => this.QuantizeFrame(source, bounds, TransparentColorMode.Preserve);
-
- ///
- [MethodImpl(InliningOptions.ShortMethod)]
- public readonly IndexedImageFrame QuantizeFrame(ImageFrame source, Rectangle bounds, TransparentColorMode mode)
- => QuantizerUtilities.QuantizeFrame(ref Unsafe.AsRef(in this), source, bounds, mode);
+ => QuantizerUtilities.QuantizeFrame(ref Unsafe.AsRef(in this), source, bounds);
///
[MethodImpl(InliningOptions.ShortMethod)]
@@ -146,13 +140,7 @@ public struct OctreeQuantizer : IQuantizer
{
private readonly Octree octree;
- public PixelRowDelegate(Octree octree, TransparentColorMode mode)
- {
- this.octree = octree;
- this.TransparentColorMode = mode;
- }
-
- public TransparentColorMode TransparentColorMode { get; }
+ public PixelRowDelegate(Octree octree) => this.octree = octree;
public void Invoke(ReadOnlySpan row, int rowIndex) => this.octree.AddColors(row);
}
diff --git a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs
index c29a36159..4fd044ab4 100644
--- a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs
@@ -3,7 +3,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
-using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
@@ -76,29 +75,18 @@ internal struct PaletteQuantizer : IQuantizer
///
[MethodImpl(InliningOptions.ShortMethod)]
public readonly void AddPaletteColors(in Buffer2DRegion pixelRegion)
- => this.AddPaletteColors(in pixelRegion, TransparentColorMode.Preserve);
-
- ///
- [MethodImpl(InliningOptions.ShortMethod)]
- public readonly void AddPaletteColors(in Buffer2DRegion pixelRegion, TransparentColorMode mode)
{
}
///
[MethodImpl(InliningOptions.ShortMethod)]
public readonly IndexedImageFrame QuantizeFrame(ImageFrame source, Rectangle bounds)
- => this.QuantizeFrame(source, bounds, TransparentColorMode.Preserve);
-
- ///
- [MethodImpl(InliningOptions.ShortMethod)]
- public readonly IndexedImageFrame QuantizeFrame(ImageFrame source, Rectangle bounds, TransparentColorMode mode)
- => QuantizerUtilities.QuantizeFrame(ref Unsafe.AsRef(in this), source, bounds, mode);
+ => QuantizerUtilities.QuantizeFrame(ref Unsafe.AsRef(in this), source, bounds);
///
[MethodImpl(InliningOptions.ShortMethod)]
public readonly byte GetQuantizedColor(TPixel color, out TPixel match)
{
- // TODO: We need to use thesholding here.
if (this.transparencyIndex >= 0 && color.Equals(this.transparentColor))
{
match = this.transparentColor;
diff --git a/src/ImageSharp/Processing/Processors/Quantization/QuantizerOptions.cs b/src/ImageSharp/Processing/Processors/Quantization/QuantizerOptions.cs
index 9d32f737e..16dfd5b33 100644
--- a/src/ImageSharp/Processing/Processors/Quantization/QuantizerOptions.cs
+++ b/src/ImageSharp/Processing/Processors/Quantization/QuantizerOptions.cs
@@ -81,7 +81,8 @@ public class QuantizerOptions : IDeepCloneable
}
///
- /// Gets or sets the transparent color mode used for handling transparent colors.
+ /// Gets or sets the transparent color mode used for handling transparent colors
+ /// when not using thresholding.
/// Defaults to .
///
public TransparentColorMode TransparentColorMode { get; set; } = TransparentColorMode.Preserve;
diff --git a/src/ImageSharp/Processing/Processors/Quantization/QuantizerUtilities.cs b/src/ImageSharp/Processing/Processors/Quantization/QuantizerUtilities.cs
index bf9ae2af0..e121aff90 100644
--- a/src/ImageSharp/Processing/Processors/Quantization/QuantizerUtilities.cs
+++ b/src/ImageSharp/Processing/Processors/Quantization/QuantizerUtilities.cs
@@ -18,7 +18,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization;
///
public static class QuantizerUtilities
{
- internal static QuantizerOptions DeepClone(this QuantizerOptions options, Action? mutate)
+ ///
+ /// Performs a deep clone the instance and optionally mutates the clone.
+ ///
+ /// The instance to clone.
+ /// An optional delegate to mutate the cloned instance.
+ /// The cloned instance.
+ public static QuantizerOptions DeepClone(this QuantizerOptions options, Action? mutate)
{
QuantizerOptions clone = options.DeepClone();
mutate?.Invoke(clone);
@@ -170,29 +176,6 @@ public static class QuantizerUtilities
ImageFrame source,
Rectangle bounds)
where TPixel : unmanaged, IPixel
- => BuildPaletteAndQuantizeFrame(
- quantizer,
- source,
- bounds,
- TransparentColorMode.Preserve);
-
- ///
- /// Execute both steps of the quantization.
- ///
- /// The pixel specific quantizer.
- /// The source image frame to quantize.
- /// The bounds within the frame to quantize.
- /// The transparent color mode.
- /// The pixel type.
- ///
- /// A representing a quantized version of the source frame pixels.
- ///
- public static IndexedImageFrame BuildPaletteAndQuantizeFrame(
- this IQuantizer quantizer,
- ImageFrame source,
- Rectangle bounds,
- TransparentColorMode mode)
- where TPixel : unmanaged, IPixel
{
Guard.NotNull(quantizer, nameof(quantizer));
Guard.NotNull(source, nameof(source));
@@ -200,7 +183,7 @@ public static class QuantizerUtilities
Rectangle interest = Rectangle.Intersect(source.Bounds, bounds);
Buffer2DRegion region = source.PixelBuffer.GetRegion(interest);
- quantizer.AddPaletteColors(in region, mode);
+ quantizer.AddPaletteColors(in region);
return quantizer.QuantizeFrame(source, bounds);
}
@@ -212,15 +195,13 @@ public static class QuantizerUtilities
/// The pixel specific quantizer.
/// The source image frame to quantize.
/// The bounds within the frame to quantize.
- /// The transparent color mode.
///
/// A representing a quantized version of the source frame pixels.
///
public static IndexedImageFrame QuantizeFrame(
ref TFrameQuantizer quantizer,
ImageFrame source,
- Rectangle bounds,
- TransparentColorMode mode)
+ Rectangle bounds)
where TFrameQuantizer : struct, IQuantizer
where TPixel : unmanaged, IPixel
{
@@ -235,13 +216,13 @@ public static class QuantizerUtilities
if (quantizer.Options.Dither is null)
{
- SecondPass(ref quantizer, source, destination, interest, mode);
+ 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 clone = source.Clone();
- SecondPass(ref quantizer, clone, destination, interest, mode);
+ SecondPass(ref quantizer, clone, destination, interest);
}
return destination;
@@ -259,29 +240,10 @@ public static class QuantizerUtilities
IPixelSamplingStrategy pixelSamplingStrategy,
Image source)
where TPixel : unmanaged, IPixel
- => quantizer.BuildPalette(
- TransparentColorMode.Preserve,
- pixelSamplingStrategy,
- source);
-
- ///
- /// Adds colors to the quantized palette from the given pixel regions.
- ///
- /// The pixel format.
- /// The pixel specific quantizer.
- /// The transparent color mode.
- /// The pixel sampling strategy.
- /// The source image to sample from.
- public static void BuildPalette(
- this IQuantizer quantizer,
- TransparentColorMode mode,
- IPixelSamplingStrategy pixelSamplingStrategy,
- Image source)
- where TPixel : unmanaged, IPixel
{
foreach (Buffer2DRegion region in pixelSamplingStrategy.EnumeratePixelRegions(source))
{
- quantizer.AddPaletteColors(in region, mode);
+ quantizer.AddPaletteColors(in region);
}
}
@@ -297,29 +259,10 @@ public static class QuantizerUtilities
IPixelSamplingStrategy pixelSamplingStrategy,
ImageFrame source)
where TPixel : unmanaged, IPixel
- => quantizer.BuildPalette(
- TransparentColorMode.Preserve,
- pixelSamplingStrategy,
- source);
-
- ///
- /// Adds colors to the quantized palette from the given pixel regions.
- ///
- /// The pixel format.
- /// The pixel specific quantizer.
- /// The transparent color mode.
- /// The pixel sampling strategy.
- /// The source image frame to sample from.
- public static void BuildPalette(
- this IQuantizer quantizer,
- TransparentColorMode mode,
- IPixelSamplingStrategy pixelSamplingStrategy,
- ImageFrame source)
- where TPixel : unmanaged, IPixel
{
foreach (Buffer2DRegion region in pixelSamplingStrategy.EnumeratePixelRegions(source))
{
- quantizer.AddPaletteColors(in region, mode);
+ quantizer.AddPaletteColors(in region);
}
}
@@ -340,7 +283,7 @@ public static class QuantizerUtilities
Span delegateRow = delegateRowOwner.Memory.Span;
bool replaceByThreshold = ShouldReplacePixelsByAlphaThreshold(threshold);
- bool replaceTransparent = EncodingUtilities.ShouldReplaceTransparentPixels(rowDelegate.TransparentColorMode);
+ bool replaceTransparent = EncodingUtilities.ShouldReplaceTransparentPixels(mode);
if (replaceByThreshold || replaceTransparent)
{
@@ -389,13 +332,14 @@ public static class QuantizerUtilities
ref TFrameQuantizer quantizer,
ImageFrame source,
IndexedImageFrame destination,
- Rectangle bounds,
- TransparentColorMode mode)
+ Rectangle bounds)
where TFrameQuantizer : struct, IQuantizer
where TPixel : unmanaged, IPixel
{
float threshold = quantizer.Options.TransparencyThreshold;
bool replaceByThreshold = ShouldReplacePixelsByAlphaThreshold(threshold);
+
+ TransparentColorMode mode = quantizer.Options.TransparentColorMode;
bool replaceTransparent = EncodingUtilities.ShouldReplaceTransparentPixels(mode);
IDither? dither = quantizer.Options.Dither;
diff --git a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs
index 4b709838e..03d6ac0da 100644
--- a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs
@@ -6,7 +6,6 @@ using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
@@ -107,9 +106,9 @@ internal struct WuQuantizer : IQuantizer
}
///
- public readonly void AddPaletteColors(in Buffer2DRegion pixelRegion, TransparentColorMode mode)
+ public readonly void AddPaletteColors(in Buffer2DRegion pixelRegion)
{
- PixelRowDelegate pixelRowDelegate = new(ref Unsafe.AsRef(in this), mode);
+ PixelRowDelegate pixelRowDelegate = new(ref Unsafe.AsRef(in this));
QuantizerUtilities.AddPaletteColors, TPixel, Rgba32, PixelRowDelegate>(
ref Unsafe.AsRef(in this),
in pixelRegion,
@@ -162,12 +161,7 @@ internal struct WuQuantizer : IQuantizer
///
[MethodImpl(InliningOptions.ShortMethod)]
public readonly IndexedImageFrame QuantizeFrame(ImageFrame source, Rectangle bounds)
- => this.QuantizeFrame(source, bounds, TransparentColorMode.Preserve);
-
- ///
- [MethodImpl(InliningOptions.ShortMethod)]
- public readonly IndexedImageFrame QuantizeFrame(ImageFrame source, Rectangle bounds, TransparentColorMode mode)
- => QuantizerUtilities.QuantizeFrame(ref Unsafe.AsRef(in this), source, bounds, mode);
+ => QuantizerUtilities.QuantizeFrame(ref Unsafe.AsRef(in this), source, bounds);
///
public readonly byte GetQuantizedColor(TPixel color, out TPixel match)
@@ -891,13 +885,7 @@ internal struct WuQuantizer : IQuantizer
{
private readonly WuQuantizer quantizer;
- public PixelRowDelegate(ref WuQuantizer quantizer, TransparentColorMode mode)
- {
- this.quantizer = quantizer;
- this.TransparentColorMode = mode;
- }
-
- public TransparentColorMode TransparentColorMode { get; }
+ public PixelRowDelegate(ref WuQuantizer quantizer) => this.quantizer = quantizer;
public void Invoke(ReadOnlySpan row, int rowIndex) => this.quantizer.Build3DHistogram(row);
}