diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs index e1611b059b..eaf6b4df7f 100644 --- a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs @@ -68,11 +68,6 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals /// private readonly MemoryAllocator memoryAllocator; - /// - /// The global configuration. - /// - private Configuration? configuration; - /// /// The color depth, in number of bits per pixel. /// @@ -123,7 +118,7 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals Guard.NotNull(image, nameof(image)); Guard.NotNull(stream, nameof(stream)); - this.configuration = image.GetConfiguration(); + Configuration configuration = image.GetConfiguration(); ImageMetadata metadata = image.Metadata; BmpMetadata bmpMetadata = metadata.GetBmpMetadata(); this.bitsPerPixel ??= bmpMetadata.BitsPerPixel; @@ -164,7 +159,7 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals WriteBitmapFileHeader(stream, infoHeaderSize, colorPaletteSize, iccProfileSize, infoHeader, buffer); this.WriteBitmapInfoHeader(stream, infoHeader, buffer, infoHeaderSize); - this.WriteImage(stream, image); + this.WriteImage(stream, image, configuration); WriteColorProfile(stream, iccProfileData, buffer); stream.Flush(); @@ -316,38 +311,39 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals /// /// The containing pixel data. /// - private void WriteImage(Stream stream, Image image) + /// The global configuration. + private void WriteImage(Stream stream, Image image, Configuration configuration) where TPixel : unmanaged, IPixel { Buffer2D pixels = image.Frames.RootFrame.PixelBuffer; switch (this.bitsPerPixel) { case BmpBitsPerPixel.Pixel32: - this.Write32BitPixelData(stream, pixels); + this.Write32BitPixelData(stream, pixels, configuration); break; case BmpBitsPerPixel.Pixel24: - this.Write24BitPixelData(stream, pixels); + this.Write24BitPixelData(stream, pixels, configuration); break; case BmpBitsPerPixel.Pixel16: - this.Write16BitPixelData(stream, pixels); + this.Write16BitPixelData(stream, pixels, configuration); break; case BmpBitsPerPixel.Pixel8: - this.Write8BitPixelData(stream, image); + this.Write8BitPixelData(stream, image, configuration); break; case BmpBitsPerPixel.Pixel4: - this.Write4BitPixelData(stream, image); + this.Write4BitPixelData(stream, image, configuration); break; case BmpBitsPerPixel.Pixel2: - this.Write2BitPixelData(stream, image); + this.Write2BitPixelData(stream, image, configuration); break; case BmpBitsPerPixel.Pixel1: - this.Write1BitPixelData(stream, image); + this.Write1BitPixelData(stream, image, configuration); break; } } @@ -361,7 +357,8 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals /// The pixel format. /// The to write to. /// The containing pixel data. - private void Write32BitPixelData(Stream stream, Buffer2D pixels) + /// The global configuration. + private void Write32BitPixelData(Stream stream, Buffer2D pixels, Configuration configuration) where TPixel : unmanaged, IPixel { using IMemoryOwner row = this.AllocateRow(pixels.Width, 4); @@ -371,7 +368,7 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals { Span pixelSpan = pixels.DangerousGetRowSpan(y); PixelOperations.Instance.ToBgra32Bytes( - this.configuration, + configuration, pixelSpan, rowSpan, pixelSpan.Length); @@ -385,7 +382,8 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals /// The pixel format. /// The to write to. /// The containing pixel data. - private void Write24BitPixelData(Stream stream, Buffer2D pixels) + /// The global configuration. + private void Write24BitPixelData(Stream stream, Buffer2D pixels, Configuration configuration) where TPixel : unmanaged, IPixel { int width = pixels.Width; @@ -397,7 +395,7 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals { Span pixelSpan = pixels.DangerousGetRowSpan(y); PixelOperations.Instance.ToBgr24Bytes( - this.configuration, + configuration, pixelSpan, row.Slice(0, rowBytesWithoutPadding), width); @@ -411,7 +409,8 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals /// The type of the pixel. /// The to write to. /// The containing pixel data. - private void Write16BitPixelData(Stream stream, Buffer2D pixels) + /// The global configuration. + private void Write16BitPixelData(Stream stream, Buffer2D pixels, Configuration configuration) where TPixel : unmanaged, IPixel { int width = pixels.Width; @@ -424,7 +423,7 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals Span pixelSpan = pixels.DangerousGetRowSpan(y); PixelOperations.Instance.ToBgra5551Bytes( - this.configuration, + configuration, pixelSpan, row.Slice(0, rowBytesWithoutPadding), pixelSpan.Length); @@ -439,7 +438,8 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals /// The type of the pixel. /// The to write to. /// The containing pixel data. - private void Write8BitPixelData(Stream stream, Image image) + /// The global configuration. + private void Write8BitPixelData(Stream stream, Image image, Configuration configuration) where TPixel : unmanaged, IPixel { bool isL8 = typeof(TPixel) == typeof(L8); @@ -452,7 +452,7 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals } else { - this.Write8BitColor(stream, image, colorPalette); + this.Write8BitColor(stream, image, colorPalette, configuration); } } @@ -463,16 +463,17 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals /// The to write to. /// The containing pixel data. /// A byte span of size 1024 for the color palette. - private void Write8BitColor(Stream stream, Image image, Span colorPalette) + /// The global configuration + private void Write8BitColor(Stream stream, Image image, Span colorPalette, Configuration configuration) where TPixel : unmanaged, IPixel { - using IQuantizer frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer(this.configuration); + using IQuantizer frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer(configuration); frameQuantizer.BuildPalette(this.pixelSamplingStrategy, image); using IndexedImageFrame quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds); ReadOnlySpan quantizedColorPalette = quantized.Palette.Span; - this.WriteColorPalette(stream, quantizedColorPalette, colorPalette); + this.WriteColorPalette(stream, quantizedColorPalette, colorPalette, configuration); for (int y = image.Height - 1; y >= 0; y--) { @@ -530,10 +531,11 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals /// The type of the pixel. /// The to write to. /// The containing pixel data. - private void Write4BitPixelData(Stream stream, Image image) + /// The global configuration. + private void Write4BitPixelData(Stream stream, Image image, Configuration configuration) where TPixel : unmanaged, IPixel { - using IQuantizer frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer(this.configuration, new QuantizerOptions() + using IQuantizer frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer(configuration, new QuantizerOptions() { MaxColors = 16 }); @@ -545,7 +547,7 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals Span colorPalette = colorPaletteBuffer.GetSpan(); ReadOnlySpan quantizedColorPalette = quantized.Palette.Span; - this.WriteColorPalette(stream, quantizedColorPalette, colorPalette); + this.WriteColorPalette(stream, quantizedColorPalette, colorPalette, configuration); ReadOnlySpan pixelRowSpan = quantized.DangerousGetRowSpan(0); int rowPadding = pixelRowSpan.Length % 2 != 0 ? this.padding - 1 : this.padding; @@ -577,10 +579,11 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals /// The type of the pixel. /// The to write to. /// The containing pixel data. - private void Write2BitPixelData(Stream stream, Image image) + /// The global configuration + private void Write2BitPixelData(Stream stream, Image image, Configuration configuration) where TPixel : unmanaged, IPixel { - using IQuantizer frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer(this.configuration, new QuantizerOptions() + using IQuantizer frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer(configuration, new QuantizerOptions() { MaxColors = 4 }); @@ -592,7 +595,7 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals Span colorPalette = colorPaletteBuffer.GetSpan(); ReadOnlySpan quantizedColorPalette = quantized.Palette.Span; - this.WriteColorPalette(stream, quantizedColorPalette, colorPalette); + this.WriteColorPalette(stream, quantizedColorPalette, colorPalette, configuration); ReadOnlySpan pixelRowSpan = quantized.DangerousGetRowSpan(0); int rowPadding = pixelRowSpan.Length % 4 != 0 ? this.padding - 1 : this.padding; @@ -633,10 +636,11 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals /// The type of the pixel. /// The to write to. /// The containing pixel data. - private void Write1BitPixelData(Stream stream, Image image) + /// The global configuration + private void Write1BitPixelData(Stream stream, Image image, Configuration configuration) where TPixel : unmanaged, IPixel { - using IQuantizer frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer(this.configuration, new QuantizerOptions() + using IQuantizer frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer(configuration, new QuantizerOptions() { MaxColors = 2 }); @@ -648,7 +652,7 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals Span colorPalette = colorPaletteBuffer.GetSpan(); ReadOnlySpan quantizedColorPalette = quantized.Palette.Span; - this.WriteColorPalette(stream, quantizedColorPalette, colorPalette); + this.WriteColorPalette(stream, quantizedColorPalette, colorPalette, configuration); ReadOnlySpan quantizedPixelRow = quantized.DangerousGetRowSpan(0); int rowPadding = quantizedPixelRow.Length % 8 != 0 ? this.padding - 1 : this.padding; @@ -683,11 +687,12 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals /// The to write to. /// The color palette from the quantized image. /// A temporary byte span to write the color palette to. - private void WriteColorPalette(Stream stream, ReadOnlySpan quantizedColorPalette, Span colorPalette) + /// The global configuration + private void WriteColorPalette(Stream stream, ReadOnlySpan quantizedColorPalette, Span colorPalette, Configuration configuration) where TPixel : unmanaged, IPixel { int quantizedColorBytes = quantizedColorPalette.Length * 4; - PixelOperations.Instance.ToBgra32(this.configuration, quantizedColorPalette, MemoryMarshal.Cast(colorPalette[..quantizedColorBytes])); + PixelOperations.Instance.ToBgra32(configuration, quantizedColorPalette, MemoryMarshal.Cast(colorPalette[..quantizedColorBytes])); Span colorPaletteAsUInt = MemoryMarshal.Cast(colorPalette); for (int i = 0; i < colorPaletteAsUInt.Length; i++) { diff --git a/src/ImageSharp/Processing/Processors/Quantization/IQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/IQuantizer.cs index f46cea2e0b..9d5b606040 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/IQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/IQuantizer.cs @@ -21,7 +21,7 @@ public interface IQuantizer /// The to configure internal operations. /// The pixel format. /// The . - IQuantizer CreatePixelSpecificQuantizer(Configuration? configuration) + IQuantizer CreatePixelSpecificQuantizer(Configuration configuration) where TPixel : unmanaged, IPixel; /// @@ -31,6 +31,6 @@ public interface IQuantizer /// The to configure internal operations. /// The options to create the quantizer with. /// The . - IQuantizer CreatePixelSpecificQuantizer(Configuration? configuration, QuantizerOptions options) + IQuantizer CreatePixelSpecificQuantizer(Configuration configuration, QuantizerOptions options) where TPixel : unmanaged, IPixel; } diff --git a/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs index 0d2450e221..0a1032bf0d 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs @@ -34,12 +34,12 @@ public class OctreeQuantizer : IQuantizer public QuantizerOptions Options { get; } /// - public IQuantizer CreatePixelSpecificQuantizer(Configuration? configuration) + public IQuantizer CreatePixelSpecificQuantizer(Configuration configuration) where TPixel : unmanaged, IPixel => this.CreatePixelSpecificQuantizer(configuration, this.Options); /// - public IQuantizer CreatePixelSpecificQuantizer(Configuration? configuration, QuantizerOptions options) + public IQuantizer CreatePixelSpecificQuantizer(Configuration configuration, QuantizerOptions options) where TPixel : unmanaged, IPixel => new OctreeQuantizer(configuration, options); } diff --git a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs index c5617fe862..fe4af9005a 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs @@ -39,12 +39,12 @@ public class PaletteQuantizer : IQuantizer public QuantizerOptions Options { get; } /// - public IQuantizer CreatePixelSpecificQuantizer(Configuration? configuration) + public IQuantizer CreatePixelSpecificQuantizer(Configuration configuration) where TPixel : unmanaged, IPixel => this.CreatePixelSpecificQuantizer(configuration, this.Options); /// - public IQuantizer CreatePixelSpecificQuantizer(Configuration? configuration, QuantizerOptions options) + public IQuantizer CreatePixelSpecificQuantizer(Configuration configuration, QuantizerOptions options) where TPixel : unmanaged, IPixel { Guard.NotNull(options, nameof(options)); diff --git a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs index dff9155401..86d798d965 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs @@ -33,12 +33,12 @@ public class WuQuantizer : IQuantizer public QuantizerOptions Options { get; } /// - public IQuantizer CreatePixelSpecificQuantizer(Configuration? configuration) + public IQuantizer CreatePixelSpecificQuantizer(Configuration configuration) where TPixel : unmanaged, IPixel => this.CreatePixelSpecificQuantizer(configuration, this.Options); /// - public IQuantizer CreatePixelSpecificQuantizer(Configuration? configuration, QuantizerOptions options) + public IQuantizer CreatePixelSpecificQuantizer(Configuration configuration, QuantizerOptions options) where TPixel : unmanaged, IPixel => new WuQuantizer(configuration, options); }