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); }