diff --git a/src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs b/src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs index d642253851..ff69d65ee6 100644 --- a/src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs @@ -122,8 +122,8 @@ namespace SixLabors.ImageSharp.Drawing.Brushes internal override void Apply(Span scanline, int x, int y) { // Create a span for colors - using (var amountBuffer = MemoryManager.Current.Allocate(scanline.Length)) - using (var overlay = MemoryManager.Current.Allocate(scanline.Length)) + using (var amountBuffer = this.Target.MemoryManager.Allocate(scanline.Length)) + using (var overlay = this.Target.MemoryManager.Allocate(scanline.Length)) { int sourceY = (y - this.offsetY) % this.yLength; int offsetX = x - this.offsetX; diff --git a/src/ImageSharp.Drawing/Brushes/PatternBrush{TPixel}.cs b/src/ImageSharp.Drawing/Brushes/PatternBrush{TPixel}.cs index 4b26c4edce..2a25979873 100644 --- a/src/ImageSharp.Drawing/Brushes/PatternBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Brushes/PatternBrush{TPixel}.cs @@ -152,8 +152,8 @@ namespace SixLabors.ImageSharp.Drawing.Brushes internal override void Apply(Span scanline, int x, int y) { int patternY = y % this.pattern.Height; - using (var amountBuffer = MemoryManager.Current.Allocate(scanline.Length)) - using (var overlay = MemoryManager.Current.Allocate(scanline.Length)) + using (var amountBuffer = this.Target.MemoryManager.Allocate(scanline.Length)) + using (var overlay = this.Target.MemoryManager.Allocate(scanline.Length)) { for (int i = 0; i < scanline.Length; i++) { diff --git a/src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs b/src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs index 5a50e12fb8..08bbb571ad 100644 --- a/src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs +++ b/src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs @@ -65,8 +65,8 @@ namespace SixLabors.ImageSharp.Drawing.Brushes.Processors /// scanlineBuffer will be > scanlineWidth but provide and offset in case we want to share a larger buffer across runs. internal virtual void Apply(Span scanline, int x, int y) { - using (var amountBuffer = MemoryManager.Current.Allocate(scanline.Length)) - using (var overlay = MemoryManager.Current.Allocate(scanline.Length)) + using (var amountBuffer = this.Target.MemoryManager.Allocate(scanline.Length)) + using (var overlay = this.Target.MemoryManager.Allocate(scanline.Length)) { for (int i = 0; i < scanline.Length; i++) { diff --git a/src/ImageSharp.Drawing/Brushes/RecolorBrush{TPixel}.cs b/src/ImageSharp.Drawing/Brushes/RecolorBrush{TPixel}.cs index 1c02884f2a..d480457113 100644 --- a/src/ImageSharp.Drawing/Brushes/RecolorBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Brushes/RecolorBrush{TPixel}.cs @@ -144,8 +144,8 @@ namespace SixLabors.ImageSharp.Drawing.Brushes /// internal override void Apply(Span scanline, int x, int y) { - using (var amountBuffer = MemoryManager.Current.Allocate(scanline.Length)) - using (var overlay = MemoryManager.Current.Allocate(scanline.Length)) + using (var amountBuffer = this.Target.MemoryManager.Allocate(scanline.Length)) + using (var overlay = this.Target.MemoryManager.Allocate(scanline.Length)) { for (int i = 0; i < scanline.Length; i++) { diff --git a/src/ImageSharp.Drawing/Brushes/SolidBrush{TPixel}.cs b/src/ImageSharp.Drawing/Brushes/SolidBrush{TPixel}.cs index b935bbe363..2d460603bb 100644 --- a/src/ImageSharp.Drawing/Brushes/SolidBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Brushes/SolidBrush{TPixel}.cs @@ -61,7 +61,7 @@ namespace SixLabors.ImageSharp.Drawing.Brushes public SolidBrushApplicator(ImageFrame source, TPixel color, GraphicsOptions options) : base(source, options) { - this.Colors = MemoryManager.Current.Allocate(source.Width); + this.Colors = source.MemoryManager.Allocate(source.Width); for (int i = 0; i < this.Colors.Length; i++) { this.Colors[i] = color; @@ -96,7 +96,7 @@ namespace SixLabors.ImageSharp.Drawing.Brushes { Span destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length); - using (var amountBuffer = MemoryManager.Current.Allocate(scanline.Length)) + using (var amountBuffer = this.Target.MemoryManager.Allocate(scanline.Length)) { for (int i = 0; i < scanline.Length; i++) { diff --git a/src/ImageSharp.Drawing/Paths/DrawPath.cs b/src/ImageSharp.Drawing/Paths/DrawPath.cs index b6c821a60b..a46d5751f6 100644 --- a/src/ImageSharp.Drawing/Paths/DrawPath.cs +++ b/src/ImageSharp.Drawing/Paths/DrawPath.cs @@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp public static IImageProcessingContext Draw(this IImageProcessingContext source, IPen pen, IPath path, GraphicsOptions options) where TPixel : struct, IPixel { - return source.Fill(pen.StrokeFill, new ShapePath(path, pen), options); + return source.Fill(pen.StrokeFill, new ShapePath(source.GetMemoryManager(), path, pen), options); } /// diff --git a/src/ImageSharp.Drawing/Paths/FillPaths.cs b/src/ImageSharp.Drawing/Paths/FillPaths.cs index f554ed7581..5972c52a05 100644 --- a/src/ImageSharp.Drawing/Paths/FillPaths.cs +++ b/src/ImageSharp.Drawing/Paths/FillPaths.cs @@ -25,7 +25,7 @@ namespace SixLabors.ImageSharp public static IImageProcessingContext Fill(this IImageProcessingContext source, IBrush brush, IPath path, GraphicsOptions options) where TPixel : struct, IPixel { - return source.Fill(brush, new ShapeRegion(path), options); + return source.Fill(brush, new ShapeRegion(source.GetMemoryManager(), path), options); } /// @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp public static IImageProcessingContext Fill(this IImageProcessingContext source, IBrush brush, IPath path) where TPixel : struct, IPixel { - return source.Fill(brush, new ShapeRegion(path), GraphicsOptions.Default); + return source.Fill(brush, new ShapeRegion(source.GetMemoryManager(), path), GraphicsOptions.Default); } /// diff --git a/src/ImageSharp.Drawing/Paths/ShapePath.cs b/src/ImageSharp.Drawing/Paths/ShapePath.cs index 61f1291c45..f973668e54 100644 --- a/src/ImageSharp.Drawing/Paths/ShapePath.cs +++ b/src/ImageSharp.Drawing/Paths/ShapePath.cs @@ -4,6 +4,8 @@ using System; using System.Buffers; using System.Numerics; + +using SixLabors.ImageSharp.Memory; using SixLabors.Shapes; namespace SixLabors.ImageSharp.Drawing @@ -19,8 +21,8 @@ namespace SixLabors.ImageSharp.Drawing /// The shape. /// The pen to apply to the shape. // SixLabors.shape willbe moving to a Span/ReadOnlySpan based API shortly use ToArray for now. - public ShapePath(IPath shape, Pens.IPen pen) - : base(shape.GenerateOutline(pen.StrokeWidth, pen.StrokePattern.ToArray())) + public ShapePath(MemoryManager memoryManager, IPath shape, Pens.IPen pen) + : base(memoryManager, shape.GenerateOutline(pen.StrokeWidth, pen.StrokePattern.ToArray())) { } } diff --git a/src/ImageSharp.Drawing/Paths/ShapeRegion.cs b/src/ImageSharp.Drawing/Paths/ShapeRegion.cs index 7851bac50b..489468dbed 100644 --- a/src/ImageSharp.Drawing/Paths/ShapeRegion.cs +++ b/src/ImageSharp.Drawing/Paths/ShapeRegion.cs @@ -15,12 +15,15 @@ namespace SixLabors.ImageSharp.Drawing /// internal class ShapeRegion : Region { + private readonly MemoryManager memoryManager; + /// /// Initializes a new instance of the class. /// /// The shape. - public ShapeRegion(IPath shape) + public ShapeRegion(MemoryManager memoryManager, IPath shape) { + this.memoryManager = memoryManager; this.Shape = shape.AsClosedPath(); int left = (int)MathF.Floor(shape.Bounds.Left); int top = (int)MathF.Floor(shape.Bounds.Top); @@ -46,7 +49,7 @@ namespace SixLabors.ImageSharp.Drawing { var start = new PointF(this.Bounds.Left - 1, y); var end = new PointF(this.Bounds.Right + 1, y); - using (var innerBuffer = MemoryManager.Current.Allocate(buffer.Length)) + using (var innerBuffer = this.memoryManager.Allocate(buffer.Length)) { PointF[] array = innerBuffer.Array; int count = this.Shape.FindIntersections(start, end, array, 0); diff --git a/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs b/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs index 2d411e0b65..201adfecc0 100644 --- a/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs +++ b/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs @@ -84,7 +84,7 @@ namespace SixLabors.ImageSharp.Drawing.Processors maxY = Math.Min(this.Location.Y + this.Size.Height, maxY); int width = maxX - minX; - using (var amount = MemoryManager.Current.Allocate(width)) + using (var amount = this.Image.GetConfiguration().MemoryManager.Allocate(width)) { for (int i = 0; i < width; i++) { diff --git a/src/ImageSharp.Drawing/Processors/FillProcessor.cs b/src/ImageSharp.Drawing/Processors/FillProcessor.cs index f4763af1e3..0174a63880 100644 --- a/src/ImageSharp.Drawing/Processors/FillProcessor.cs +++ b/src/ImageSharp.Drawing/Processors/FillProcessor.cs @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.Drawing.Processors int width = maxX - minX; - using (var amount = MemoryManager.Current.Allocate(width)) + using (var amount = source.MemoryManager.Allocate(width)) using (BrushApplicator applicator = this.brush.CreateApplicator(source, sourceRectangle, this.options)) { for (int i = 0; i < width; i++) diff --git a/src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs b/src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs index 82ffea08ea..f3e3d0397f 100644 --- a/src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs +++ b/src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs @@ -102,7 +102,7 @@ namespace SixLabors.ImageSharp.Drawing.Processors { float[] buffer = arrayPool.Rent(maxIntersections); int scanlineWidth = maxX - minX; - using (var scanline = MemoryManager.Current.Allocate(scanlineWidth)) + using (var scanline = source.MemoryManager.Allocate(scanlineWidth)) { try { diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs index 8ea676d322..bc8ad1c529 100644 --- a/src/ImageSharp/Configuration.cs +++ b/src/ImageSharp/Configuration.cs @@ -83,6 +83,11 @@ namespace SixLabors.ImageSharp /// public IEnumerable ImageFormats => this.imageFormats; + /// + /// Gets or sets the that is currently in use. + /// + public MemoryManager MemoryManager { get; set; } = new ArrayPoolMemoryManager(1024 * 80); + /// /// Gets the maximum header size of all the formats. /// diff --git a/src/ImageSharp/DefaultInternalImageProcessorContext.cs b/src/ImageSharp/DefaultInternalImageProcessorContext.cs index 575525a773..22bcc82e16 100644 --- a/src/ImageSharp/DefaultInternalImageProcessorContext.cs +++ b/src/ImageSharp/DefaultInternalImageProcessorContext.cs @@ -1,7 +1,9 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Helpers; +using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using SixLabors.Primitives; @@ -72,5 +74,7 @@ namespace SixLabors.ImageSharp { return this.ApplyProcessor(processor, this.source.Bounds()); } + + public MemoryManager GetMemoryManager() => this.source.GetConfiguration().MemoryManager; } } \ No newline at end of file diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs index 4faccc58fd..07b7fabb6c 100644 --- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs @@ -263,7 +263,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp var color = default(TPixel); var rgba = new Rgba32(0, 0, 0, 255); - using (var buffer = Buffer2D.CreateClean(width, height)) + using (var buffer = this.configuration.MemoryManager.Allocate2D(width, height, true)) { this.UncompressRle8(width, buffer.Span); @@ -385,7 +385,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp padding = 4 - padding; } - using (var row = MemoryManager.Current.Allocate(arrayWidth + padding, true)) + using (var row = this.configuration.MemoryManager.Allocate(arrayWidth + padding, true)) { var color = default(TPixel); var rgba = new Rgba32(0, 0, 0, 255); @@ -435,7 +435,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp var color = default(TPixel); var rgba = new Rgba32(0, 0, 0, 255); - using (var buffer = MemoryManager.Current.Allocate(stride)) + using (var buffer = this.configuration.MemoryManager.Allocate(stride)) { for (int y = 0; y < height; y++) { diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs index 0003dbc823..51a598bc0c 100644 --- a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.Formats.Gif if (this.logicalScreenDescriptor.GlobalColorTableFlag) { this.globalColorTableLength = this.logicalScreenDescriptor.GlobalColorTableSize * 3; - this.globalColorTable = MemoryManager.Current.Allocate(this.globalColorTableLength, true); + this.globalColorTable = this.configuration.MemoryManager.Allocate(this.globalColorTableLength, true); // Read the global color table from the stream stream.Read(this.globalColorTable.Array, 0, this.globalColorTableLength); @@ -320,11 +320,11 @@ namespace SixLabors.ImageSharp.Formats.Gif if (imageDescriptor.LocalColorTableFlag) { int length = imageDescriptor.LocalColorTableSize * 3; - localColorTable = MemoryManager.Current.Allocate(length, true); + localColorTable = this.configuration.MemoryManager.Allocate(length, true); this.currentStream.Read(localColorTable.Array, 0, length); } - indices = MemoryManager.Current.Allocate(imageDescriptor.Width * imageDescriptor.Height, true); + indices = this.configuration.MemoryManager.Allocate(imageDescriptor.Width * imageDescriptor.Height, true); this.ReadFrameIndices(imageDescriptor, indices); this.ReadFrameColors(indices, localColorTable ?? this.globalColorTable, imageDescriptor); diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegComponentPostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegComponentPostProcessor.cs index 7c91e85e74..ea9e52ae1b 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegComponentPostProcessor.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegComponentPostProcessor.cs @@ -22,11 +22,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder /// /// Initializes a new instance of the class. /// - public JpegComponentPostProcessor(JpegImagePostProcessor imagePostProcessor, IJpegComponent component) + public JpegComponentPostProcessor(MemoryManager memoryManager, JpegImagePostProcessor imagePostProcessor, IJpegComponent component) { this.Component = component; this.ImagePostProcessor = imagePostProcessor; - this.ColorBuffer = MemoryManager.Current.Allocate2D( + this.ColorBuffer = memoryManager.Allocate2D( imagePostProcessor.PostProcessorBufferSize.Width, imagePostProcessor.PostProcessorBufferSize.Height); diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs index 44deb6722b..44841bd676 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs @@ -45,15 +45,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder /// Initializes a new instance of the class. /// /// The representing the uncompressed spectral Jpeg data - public JpegImagePostProcessor(IRawJpegData rawJpeg) + public JpegImagePostProcessor(MemoryManager memoryManager, IRawJpegData rawJpeg) { this.RawJpeg = rawJpeg; IJpegComponent c0 = rawJpeg.Components.First(); this.NumberOfPostProcessorSteps = c0.SizeInBlocks.Height / BlockRowsPerStep; this.PostProcessorBufferSize = new Size(c0.SizeInBlocks.Width * 8, PixelRowsPerStep); - this.ComponentProcessors = rawJpeg.Components.Select(c => new JpegComponentPostProcessor(this, c)).ToArray(); - this.rgbaBuffer = MemoryManager.Current.Allocate(rawJpeg.ImageSizeInPixels.Width); + this.ComponentProcessors = rawJpeg.Components.Select(c => new JpegComponentPostProcessor(memoryManager, this, c)).ToArray(); + this.rgbaBuffer = memoryManager.Allocate(rawJpeg.ImageSizeInPixels.Width); this.colorConverter = ColorConverters.JpegColorConverter.GetConverter(rawJpeg.ColorSpace); } diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponent.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponent.cs index c87752b371..c2b4d632a1 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponent.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponent.cs @@ -55,7 +55,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder /// Initializes /// /// The instance - public void InitializeDerivedData(OrigJpegDecoderCore decoder) + public void InitializeDerivedData(MemoryManager memoryManager, OrigJpegDecoderCore decoder) { // For 4-component images (either CMYK or YCbCrK), we only support two // hv vectors: [0x11 0x11 0x11 0x11] and [0x22 0x11 0x11 0x22]. @@ -78,7 +78,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder this.SubSamplingDivisors = c0.SamplingFactors.DivideBy(this.SamplingFactors); } - this.SpectralBlocks = Buffer2D.CreateClean(this.SizeInBlocks); + this.SpectralBlocks = memoryManager.Allocate2D(this.SizeInBlocks.Width, this.SizeInBlocks.Height, true); } /// diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs index 61b18af551..053b016e64 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs @@ -659,7 +659,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort foreach (OrigComponent component in this.Components) { - component.InitializeDerivedData(this); + component.InitializeDerivedData(this.configuration.MemoryManager, this); } this.ColorSpace = this.DeduceJpegColorSpace(); @@ -767,7 +767,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort private Image PostProcessIntoImage() where TPixel : struct, IPixel { - using (var postProcessor = new JpegImagePostProcessor(this)) + using (var postProcessor = new JpegImagePostProcessor(this.configuration.MemoryManager, this)) { var image = new Image(this.configuration, this.ImageWidth, this.ImageHeight, this.MetaData); postProcessor.PostProcess(image.Frames.RootFrame); diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs index 5d51e2ad58..18e1773909 100644 --- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs +++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs @@ -15,10 +15,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components /// internal class PdfJsFrameComponent : IDisposable, IJpegComponent { + private readonly MemoryManager memoryManager; #pragma warning disable SA1401 // Fields should be private - public PdfJsFrameComponent(PdfJsFrame frame, byte id, int horizontalFactor, int verticalFactor, byte quantizationTableIndex, int index) + public PdfJsFrameComponent(MemoryManager memoryManager, PdfJsFrame frame, byte id, int horizontalFactor, int verticalFactor, byte quantizationTableIndex, int index) { + this.memoryManager = memoryManager; this.Frame = frame; this.Id = id; this.HorizontalSamplingFactor = horizontalFactor; @@ -114,7 +116,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components int blocksBufferSize = 64 * this.BlocksPerColumnForMcu * (this.BlocksPerLineForMcu + 1); // Pooled. Disposed via frame disposal - this.BlockData = MemoryManager.Current.Allocate(blocksBufferSize, true); + this.BlockData = this.memoryManager.Allocate(blocksBufferSize, true); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsHuffmanTable.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsHuffmanTable.cs index 38f223dcac..4142ae354c 100644 --- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsHuffmanTable.cs +++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsHuffmanTable.cs @@ -22,14 +22,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components /// /// The code lengths /// The huffman values - public PdfJsHuffmanTable(byte[] lengths, byte[] values) + public PdfJsHuffmanTable(MemoryManager memoryManager, byte[] lengths, byte[] values) { - this.lookahead = MemoryManager.Current.Allocate(256, true); - this.valOffset = MemoryManager.Current.Allocate(18, true); - this.maxcode = MemoryManager.Current.Allocate(18, true); + this.lookahead = memoryManager.Allocate(256, true); + this.valOffset = memoryManager.Allocate(18, true); + this.maxcode = memoryManager.Allocate(18, true); - using (var huffsize = MemoryManager.Current.Allocate(257, true)) - using (var huffcode = MemoryManager.Current.Allocate(257, true)) + using (var huffsize = memoryManager.Allocate(257, true)) + using (var huffcode = memoryManager.Allocate(257, true)) { GenerateSizeTable(lengths, huffsize); GenerateCodeTable(huffsize, huffcode); @@ -37,7 +37,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components GenerateLookaheadTables(lengths, values, this.lookahead); } - this.huffval = MemoryManager.Current.Allocate(values.Length, true); + this.huffval = memoryManager.Allocate(values.Length, true); Buffer.BlockCopy(values, 0, this.huffval.Array, 0, values.Length); this.MaxCode = this.maxcode.Array; diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsJpegPixelArea.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsJpegPixelArea.cs index eb16807969..eebc57b862 100644 --- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsJpegPixelArea.cs +++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsJpegPixelArea.cs @@ -14,6 +14,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components /// internal struct PdfJsJpegPixelArea : IDisposable { + private readonly MemoryManager memoryManager; + private readonly int imageWidth; private readonly int imageHeight; @@ -28,8 +30,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components /// The image width /// The image height /// The number of components - public PdfJsJpegPixelArea(int imageWidth, int imageHeight, int numberOfComponents) + public PdfJsJpegPixelArea(MemoryManager memoryManager, int imageWidth, int imageHeight, int numberOfComponents) { + this.memoryManager = memoryManager; this.imageWidth = imageWidth; this.imageHeight = imageHeight; this.Width = 0; @@ -69,11 +72,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components this.rowStride = width * numberOfComponents; var scale = new Vector2(this.imageWidth / (float)width, this.imageHeight / (float)height); - this.componentData = MemoryManager.Current.Allocate(width * height * numberOfComponents); + this.componentData = this.memoryManager.Allocate(width * height * numberOfComponents); Span componentDataSpan = this.componentData; const uint Mask3Lsb = 0xFFFFFFF8; // Used to clear the 3 LSBs - using (var xScaleBlockOffset = MemoryManager.Current.Allocate(width)) + using (var xScaleBlockOffset = this.memoryManager.Allocate(width)) { Span xScaleBlockOffsetSpan = xScaleBlockOffset; for (int i = 0; i < numberOfComponents; i++) diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsQuantizationTables.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsQuantizationTables.cs index a585c5080f..f7302b1564 100644 --- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsQuantizationTables.cs +++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsQuantizationTables.cs @@ -40,6 +40,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components 63 }; + public PdfJsQuantizationTables(MemoryManager memoryManager) + { + this.Tables = memoryManager.Allocate2D(64, 4); + } + /// /// Gets or sets the quantization tables. /// @@ -49,8 +54,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components get; set; } - = MemoryManager.Current.Allocate2D(64, 4); - /// public void Dispose() { diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs index 917e3c7e3f..863c4380bf 100644 --- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs @@ -216,7 +216,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort ushort marker = this.ReadUint16(); fileMarker = new PdfJsFileMarker(marker, (int)this.InputStream.Position - 2); - this.quantizationTables = new PdfJsQuantizationTables(); + this.quantizationTables = new PdfJsQuantizationTables(this.configuration.MemoryManager); this.dcHuffmanTables = new PdfJsHuffmanTables(); this.acHuffmanTables = new PdfJsHuffmanTables(); @@ -335,7 +335,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort throw new ImageFormatException($"Unsupported color mode. Max components 4; found {this.NumberOfComponents}"); } - this.pixelArea = new PdfJsJpegPixelArea(image.Width, image.Height, this.NumberOfComponents); + this.pixelArea = new PdfJsJpegPixelArea(this.configuration.MemoryManager, image.Width, image.Height, this.NumberOfComponents); this.pixelArea.LinearizeBlockData(this.components, image.Width, image.Height); if (this.NumberOfComponents == 1) @@ -648,7 +648,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort maxV = v; } - var component = new PdfJsFrameComponent(this.Frame, this.temp[index], h, v, this.temp[index + 2], i); + var component = new PdfJsFrameComponent(this.configuration.MemoryManager, this.Frame, this.temp[index], h, v, this.temp[index + 2], i); this.Frame.Components[i] = component; this.Frame.ComponentIds[i] = component.Id; @@ -673,14 +673,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort throw new ImageFormatException($"DHT has wrong length: {remaining}"); } - using (var huffmanData = MemoryManager.Current.Allocate(256, true)) + using (var huffmanData = this.configuration.MemoryManager.Allocate(256, true)) { for (int i = 2; i < remaining;) { byte huffmanTableSpec = (byte)this.InputStream.ReadByte(); this.InputStream.Read(huffmanData.Array, 0, 16); - using (var codeLengths = MemoryManager.Current.Allocate(17, true)) + using (var codeLengths = this.configuration.MemoryManager.Allocate(17, true)) { int codeLengthSum = 0; @@ -689,7 +689,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort codeLengthSum += codeLengths[j] = huffmanData[j - 1]; } - using (var huffmanValues = MemoryManager.Current.Allocate(256, true)) + using (var huffmanValues = this.configuration.MemoryManager.Allocate(256, true)) { this.InputStream.Read(huffmanValues.Array, 0, codeLengthSum); @@ -784,8 +784,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort { int blocksPerLine = component.BlocksPerLine; int blocksPerColumn = component.BlocksPerColumn; - using (var computationBuffer = MemoryManager.Current.Allocate(64, true)) - using (var multiplicationBuffer = MemoryManager.Current.Allocate(64, true)) + using (var computationBuffer = this.configuration.MemoryManager.Allocate(64, true)) + using (var multiplicationBuffer = this.configuration.MemoryManager.Allocate(64, true)) { Span quantizationTable = this.quantizationTables.Tables.GetRowSpan(frameComponent.QuantizationTableIndex); Span computationBufferSpan = computationBuffer; @@ -823,7 +823,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort /// The values private void BuildHuffmanTable(PdfJsHuffmanTables tables, int index, byte[] codeLengths, byte[] values) { - tables[index] = new PdfJsHuffmanTable(codeLengths, values); + tables[index] = new PdfJsHuffmanTable(this.configuration.MemoryManager, codeLengths, values); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/ImageSharp/Formats/Png/PngConfigurationModule.cs b/src/ImageSharp/Formats/Png/PngConfigurationModule.cs index 9346f7567e..abf5bc6bb9 100644 --- a/src/ImageSharp/Formats/Png/PngConfigurationModule.cs +++ b/src/ImageSharp/Formats/Png/PngConfigurationModule.cs @@ -9,11 +9,11 @@ namespace SixLabors.ImageSharp.Formats.Png public sealed class PngConfigurationModule : IConfigurationModule { /// - public void Configure(Configuration host) + public void Configure(Configuration config) { - host.SetEncoder(ImageFormats.Png, new PngEncoder()); - host.SetDecoder(ImageFormats.Png, new PngDecoder()); - host.AddImageFormatDetector(new PngImageFormatDetector()); + config.SetEncoder(ImageFormats.Png, new PngEncoder(config.MemoryManager)); + config.SetDecoder(ImageFormats.Png, new PngDecoder()); + config.AddImageFormatDetector(new PngImageFormatDetector()); } } } \ No newline at end of file diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index ebda05a1e9..7e354b58bc 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -375,8 +375,8 @@ namespace SixLabors.ImageSharp.Formats.Png this.bytesPerSample = this.header.BitDepth / 8; } - this.previousScanline = MemoryManager.Current.Allocate(this.bytesPerScanline, true); - this.scanline = MemoryManager.Current.Allocate(this.bytesPerScanline, true); + this.previousScanline = this.configuration.MemoryManager.Allocate(this.bytesPerScanline, true); + this.scanline = this.configuration.MemoryManager.Allocate(this.bytesPerScanline, true); } /// @@ -669,7 +669,7 @@ namespace SixLabors.ImageSharp.Formats.Png if (this.header.BitDepth == 16) { int length = this.header.Width * 3; - using (var compressed = MemoryManager.Current.Allocate(length)) + using (var compressed = this.configuration.MemoryManager.Allocate(length)) { // TODO: Should we use pack from vector here instead? this.From16BitTo8Bit(scanlineBuffer, compressed, length); @@ -686,7 +686,7 @@ namespace SixLabors.ImageSharp.Formats.Png if (this.header.BitDepth == 16) { int length = this.header.Width * 3; - using (var compressed = MemoryManager.Current.Allocate(length)) + using (var compressed = this.configuration.MemoryManager.Allocate(length)) { // TODO: Should we use pack from vector here instead? this.From16BitTo8Bit(scanlineBuffer, compressed, length); @@ -727,7 +727,7 @@ namespace SixLabors.ImageSharp.Formats.Png if (this.header.BitDepth == 16) { int length = this.header.Width * 4; - using (var compressed = MemoryManager.Current.Allocate(length)) + using (var compressed = this.configuration.MemoryManager.Allocate(length)) { // TODO: Should we use pack from vector here instead? this.From16BitTo8Bit(scanlineBuffer, compressed, length); @@ -930,7 +930,7 @@ namespace SixLabors.ImageSharp.Formats.Png if (this.header.BitDepth == 16) { int length = this.header.Width * 3; - using (var compressed = MemoryManager.Current.Allocate(length)) + using (var compressed = this.configuration.MemoryManager.Allocate(length)) { // TODO: Should we use pack from vector here instead? this.From16BitTo8Bit(scanlineBuffer, compressed, length); @@ -998,7 +998,7 @@ namespace SixLabors.ImageSharp.Formats.Png if (this.header.BitDepth == 16) { int length = this.header.Width * 4; - using (var compressed = MemoryManager.Current.Allocate(length)) + using (var compressed = this.configuration.MemoryManager.Allocate(length)) { // TODO: Should we use pack from vector here instead? this.From16BitTo8Bit(scanlineBuffer, compressed, length); diff --git a/src/ImageSharp/Formats/Png/PngEncoder.cs b/src/ImageSharp/Formats/Png/PngEncoder.cs index 2fc6911f0b..f65ce59b2f 100644 --- a/src/ImageSharp/Formats/Png/PngEncoder.cs +++ b/src/ImageSharp/Formats/Png/PngEncoder.cs @@ -2,6 +2,8 @@ // Licensed under the Apache License, Version 2.0. using System.IO; + +using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Quantizers; @@ -12,6 +14,13 @@ namespace SixLabors.ImageSharp.Formats.Png /// public sealed class PngEncoder : IImageEncoder, IPngEncoderOptions { + private readonly MemoryManager memoryManager; + + public PngEncoder(MemoryManager memoryManager) + { + this.memoryManager = memoryManager; + } + /// /// Gets or sets a value indicating whether the metadata should be ignored when the image is being encoded. /// @@ -66,7 +75,7 @@ namespace SixLabors.ImageSharp.Formats.Png public void Encode(Image image, Stream stream) where TPixel : struct, IPixel { - using (var encoder = new PngEncoderCore(this)) + using (var encoder = new PngEncoderCore(this.memoryManager, this)) { encoder.Encode(image, stream); } diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index 9be0f5ee44..e3e209ed43 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -20,6 +20,8 @@ namespace SixLabors.ImageSharp.Formats.Png /// internal sealed class PngEncoderCore : IDisposable { + private readonly MemoryManager memoryManager; + /// /// The maximum block size, defaults at 64k for uncompressed blocks. /// @@ -149,8 +151,9 @@ namespace SixLabors.ImageSharp.Formats.Png /// Initializes a new instance of the class. /// /// The options for influancing the encoder - public PngEncoderCore(IPngEncoderOptions options) + public PngEncoderCore(MemoryManager memoryManager, IPngEncoderOptions options) { + this.memoryManager = memoryManager; this.ignoreMetadata = options.IgnoreMetadata; this.paletteSize = options.PaletteSize > 0 ? options.PaletteSize.Clamp(1, int.MaxValue) : int.MaxValue; this.pngColorType = options.PngColorType; @@ -620,16 +623,16 @@ namespace SixLabors.ImageSharp.Formats.Png this.bytesPerScanline = this.width * this.bytesPerPixel; int resultLength = this.bytesPerScanline + 1; - this.previousScanline = MemoryManager.Current.Allocate(this.bytesPerScanline, true); - this.rawScanline = MemoryManager.Current.Allocate(this.bytesPerScanline, true); - this.result = MemoryManager.Current.Allocate(resultLength, true); + this.previousScanline = this.memoryManager.Allocate(this.bytesPerScanline, true); + this.rawScanline = this.memoryManager.Allocate(this.bytesPerScanline, true); + this.result = this.memoryManager.Allocate(resultLength, true); if (this.pngColorType != PngColorType.Palette) { - this.sub = MemoryManager.Current.Allocate(resultLength, true); - this.up = MemoryManager.Current.Allocate(resultLength, true); - this.average = MemoryManager.Current.Allocate(resultLength, true); - this.paeth = MemoryManager.Current.Allocate(resultLength, true); + this.sub = this.memoryManager.Allocate(resultLength, true); + this.up = this.memoryManager.Allocate(resultLength, true); + this.average = this.memoryManager.Allocate(resultLength, true); + this.paeth = this.memoryManager.Allocate(resultLength, true); } byte[] buffer; diff --git a/src/ImageSharp/IImageProcessingContext{TPixel}.cs b/src/ImageSharp/IImageProcessingContext{TPixel}.cs index 552e8d579d..1556987df6 100644 --- a/src/ImageSharp/IImageProcessingContext{TPixel}.cs +++ b/src/ImageSharp/IImageProcessingContext{TPixel}.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using SixLabors.Primitives; @@ -28,6 +29,8 @@ namespace SixLabors.ImageSharp /// The processor to apply /// The current operations class to allow chaining of operations. IImageProcessingContext ApplyProcessor(IImageProcessor processor); + + MemoryManager GetMemoryManager(); } /// diff --git a/src/ImageSharp/Image/Image.Decode.cs b/src/ImageSharp/Image/Image.Decode.cs index 1bce23cfcb..69063a8de1 100644 --- a/src/ImageSharp/Image/Image.Decode.cs +++ b/src/ImageSharp/Image/Image.Decode.cs @@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp return null; } - using (var buffer = MemoryManager.Current.Allocate(maxHeaderSize)) + using (var buffer = config.MemoryManager.Allocate(maxHeaderSize)) { long startPosition = stream.Position; stream.Read(buffer.Array, 0, maxHeaderSize); diff --git a/src/ImageSharp/Image/ImageFrame.LoadPixelData.cs b/src/ImageSharp/Image/ImageFrame.LoadPixelData.cs index e2230c4367..153a757e18 100644 --- a/src/ImageSharp/Image/ImageFrame.LoadPixelData.cs +++ b/src/ImageSharp/Image/ImageFrame.LoadPixelData.cs @@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp int count = width * height; Guard.MustBeGreaterThanOrEqualTo(data.Length, count, nameof(data)); - var image = new ImageFrame(width, height); + var image = new ImageFrame(Configuration.Default.MemoryManager, width, height); SpanHelper.Copy(data, image.GetPixelSpan(), count); return image; diff --git a/src/ImageSharp/Image/ImageFrameCollection.cs b/src/ImageSharp/Image/ImageFrameCollection.cs index 3e9bb03435..bfdf1df76b 100644 --- a/src/ImageSharp/Image/ImageFrameCollection.cs +++ b/src/ImageSharp/Image/ImageFrameCollection.cs @@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp this.parent = parent; // Frames are already cloned within the caller - this.frames.Add(new ImageFrame(width, height)); + this.frames.Add(new ImageFrame(parent.GetConfiguration().MemoryManager, width, height)); } internal ImageFrameCollection(Image parent, IEnumerable> frames) @@ -143,7 +143,7 @@ namespace SixLabors.ImageSharp /// public ImageFrame CreateFrame() { - var frame = new ImageFrame(this.RootFrame.Width, this.RootFrame.Height); + var frame = new ImageFrame(this.parent.GetConfiguration().MemoryManager, this.RootFrame.Width, this.RootFrame.Height); this.frames.Add(frame); return frame; } diff --git a/src/ImageSharp/Image/ImageFrame{TPixel}.cs b/src/ImageSharp/Image/ImageFrame{TPixel}.cs index a0e4976cb6..2f2f545dbb 100644 --- a/src/ImageSharp/Image/ImageFrame{TPixel}.cs +++ b/src/ImageSharp/Image/ImageFrame{TPixel}.cs @@ -20,6 +20,8 @@ namespace SixLabors.ImageSharp public sealed class ImageFrame : IPixelSource, IDisposable where TPixel : struct, IPixel { + public MemoryManager MemoryManager { get; } + /// /// The image pixels. Not private as Buffer2D requires an array in its constructor. /// @@ -32,8 +34,8 @@ namespace SixLabors.ImageSharp /// /// The width of the image in pixels. /// The height of the image in pixels. - internal ImageFrame(int width, int height) - : this(width, height, new ImageFrameMetaData()) + internal ImageFrame(MemoryManager memoryManager, int width, int height) + : this(memoryManager, width, height, new ImageFrameMetaData()) { } @@ -43,13 +45,15 @@ namespace SixLabors.ImageSharp /// The width of the image in pixels. /// The height of the image in pixels. /// The meta data. - internal ImageFrame(int width, int height, ImageFrameMetaData metaData) + internal ImageFrame(MemoryManager memoryManager, int width, int height, ImageFrameMetaData metaData) { + Guard.NotNull(memoryManager, nameof(memoryManager)); Guard.MustBeGreaterThan(width, 0, nameof(width)); Guard.MustBeGreaterThan(height, 0, nameof(height)); Guard.NotNull(metaData, nameof(metaData)); - this.pixelBuffer = Buffer2D.CreateClean(width, height); + this.MemoryManager = memoryManager; + this.pixelBuffer = memoryManager.Allocate2D(width, height, true); this.MetaData = metaData; } @@ -57,9 +61,10 @@ namespace SixLabors.ImageSharp /// Initializes a new instance of the class. /// /// The source. - internal ImageFrame(ImageFrame source) + internal ImageFrame(MemoryManager memoryManager, ImageFrame source) { - this.pixelBuffer = MemoryManager.Current.Allocate2D(source.pixelBuffer.Width, source.pixelBuffer.Height); + this.MemoryManager = memoryManager; + this.pixelBuffer = memoryManager.Allocate2D(source.pixelBuffer.Width, source.pixelBuffer.Height); source.pixelBuffer.Span.CopyTo(this.pixelBuffer.Span); this.MetaData = source.MetaData.Clone(); } @@ -198,7 +203,7 @@ namespace SixLabors.ImageSharp Func scaleFunc = PackedPixelConverterHelper.ComputeScaleFunction(); - var target = new ImageFrame(this.Width, this.Height, this.MetaData.Clone()); + var target = new ImageFrame(this.MemoryManager, this.Width, this.Height, this.MetaData.Clone()); using (PixelAccessor pixels = this.Lock()) using (PixelAccessor targetPixels = target.Lock()) @@ -227,7 +232,7 @@ namespace SixLabors.ImageSharp /// The internal ImageFrame Clone() { - return new ImageFrame(this); + return new ImageFrame(this.MemoryManager, this); } /// diff --git a/src/ImageSharp/Image/PixelAccessor{TPixel}.cs b/src/ImageSharp/Image/PixelAccessor{TPixel}.cs index 70d67954cc..fca57b3c8e 100644 --- a/src/ImageSharp/Image/PixelAccessor{TPixel}.cs +++ b/src/ImageSharp/Image/PixelAccessor{TPixel}.cs @@ -55,7 +55,7 @@ namespace SixLabors.ImageSharp /// The width of the image represented by the pixel buffer. /// The height of the image represented by the pixel buffer. public PixelAccessor(int width, int height) - : this(width, height, Buffer2D.CreateClean(width, height), true) + : this(width, height, Configuration.Default.MemoryManager.Allocate2D(width, height, true), true) { } diff --git a/src/ImageSharp/Image/PixelArea{TPixel}.cs b/src/ImageSharp/Image/PixelArea{TPixel}.cs index e6ae556f7d..fa3499b6d7 100644 --- a/src/ImageSharp/Image/PixelArea{TPixel}.cs +++ b/src/ImageSharp/Image/PixelArea{TPixel}.cs @@ -116,7 +116,7 @@ namespace SixLabors.ImageSharp this.RowStride = (width * GetComponentCount(componentOrder)) + padding; this.Length = this.RowStride * height; - this.byteBuffer = MemoryManager.Current.Allocate(this.Length, true); + this.byteBuffer = Configuration.Default.MemoryManager.Allocate(this.Length, true); } /// diff --git a/src/ImageSharp/Memory/Buffer2D{T}.cs b/src/ImageSharp/Memory/Buffer2D{T}.cs index 73444d4978..82cb25f476 100644 --- a/src/ImageSharp/Memory/Buffer2D{T}.cs +++ b/src/ImageSharp/Memory/Buffer2D{T}.cs @@ -56,24 +56,6 @@ namespace SixLabors.ImageSharp.Memory } } - /// - /// Creates a clean instance of initializing it's elements with 'default(T)'. - /// - /// The number of elements in a row - /// The number of rows - /// The instance - public static Buffer2D CreateClean(int width, int height) - { - return new Buffer2D(MemoryManager.Current.Allocate(width * height, true), width, height); - } - - /// - /// Creates a clean instance of initializing it's elements with 'default(T)'. - /// - /// The size of the buffer - /// The instance - public static Buffer2D CreateClean(Size size) => CreateClean(size.Width, size.Height); - public void Dispose() { this.Buffer?.Dispose(); diff --git a/src/ImageSharp/Memory/MemoryManager.cs b/src/ImageSharp/Memory/MemoryManager.cs index b68a01feb1..67d72d2b43 100644 --- a/src/ImageSharp/Memory/MemoryManager.cs +++ b/src/ImageSharp/Memory/MemoryManager.cs @@ -11,11 +11,6 @@ namespace SixLabors.ImageSharp.Memory /// public abstract class MemoryManager { - /// - /// Gets or sets the that is currently in use. - /// - public static MemoryManager Current { get; set; } = new ArrayPoolMemoryManager(1024 * 80); - /// /// Allocates a of size , optionally /// clearing the buffer before it gets returned. diff --git a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs b/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs index 4772816730..4ca53244ad 100644 --- a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs @@ -45,7 +45,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -84,7 +84,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -123,7 +123,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -162,7 +162,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -201,7 +201,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -240,7 +240,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -279,7 +279,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -318,7 +318,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -357,7 +357,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -396,7 +396,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -435,7 +435,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -474,7 +474,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -513,7 +513,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -552,7 +552,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -591,7 +591,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -630,7 +630,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -669,7 +669,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -708,7 +708,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -747,7 +747,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -786,7 +786,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -825,7 +825,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); diff --git a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.tt b/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.tt index cb99237c45..5e9268dff1 100644 --- a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.tt @@ -87,7 +87,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) + using (Buffer buffer = Configuration.Default.MemoryManager.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); diff --git a/src/ImageSharp/Processing/ColorMatrix/Lomograph.cs b/src/ImageSharp/Processing/ColorMatrix/Lomograph.cs index 947e531578..96231e168b 100644 --- a/src/ImageSharp/Processing/ColorMatrix/Lomograph.cs +++ b/src/ImageSharp/Processing/ColorMatrix/Lomograph.cs @@ -51,7 +51,7 @@ namespace SixLabors.ImageSharp public static IImageProcessingContext Lomograph(this IImageProcessingContext source, GraphicsOptions options) where TPixel : struct, IPixel { - source.ApplyProcessor(new LomographProcessor(options)); + source.ApplyProcessor(new LomographProcessor(source.GetMemoryManager(), options)); return source; } @@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp public static IImageProcessingContext Lomograph(this IImageProcessingContext source, Rectangle rectangle, GraphicsOptions options) where TPixel : struct, IPixel { - source.ApplyProcessor(new LomographProcessor(options), rectangle); + source.ApplyProcessor(new LomographProcessor(source.GetMemoryManager(), options), rectangle); return source; } } diff --git a/src/ImageSharp/Processing/ColorMatrix/Polaroid.cs b/src/ImageSharp/Processing/ColorMatrix/Polaroid.cs index c96087d57e..7cc0e2419f 100644 --- a/src/ImageSharp/Processing/ColorMatrix/Polaroid.cs +++ b/src/ImageSharp/Processing/ColorMatrix/Polaroid.cs @@ -51,7 +51,7 @@ namespace SixLabors.ImageSharp public static IImageProcessingContext Polaroid(this IImageProcessingContext source, GraphicsOptions options) where TPixel : struct, IPixel { - source.ApplyProcessor(new PolaroidProcessor(options)); + source.ApplyProcessor(new PolaroidProcessor(source.GetMemoryManager(), options)); return source; } @@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp public static IImageProcessingContext Polaroid(this IImageProcessingContext source, Rectangle rectangle, GraphicsOptions options) where TPixel : struct, IPixel { - source.ApplyProcessor(new PolaroidProcessor(options), rectangle); + source.ApplyProcessor(new PolaroidProcessor(source.GetMemoryManager(), options), rectangle); return source; } } diff --git a/src/ImageSharp/Processing/Effects/BackgroundColor.cs b/src/ImageSharp/Processing/Effects/BackgroundColor.cs index da00b4ddd0..18caa67cca 100644 --- a/src/ImageSharp/Processing/Effects/BackgroundColor.cs +++ b/src/ImageSharp/Processing/Effects/BackgroundColor.cs @@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp /// The . public static IImageProcessingContext BackgroundColor(this IImageProcessingContext source, TPixel color, GraphicsOptions options) where TPixel : struct, IPixel - => source.ApplyProcessor(new BackgroundColorProcessor(color, options)); + => source.ApplyProcessor(new BackgroundColorProcessor(source.GetMemoryManager(), color, options)); /// /// Replaces the background color of image with the given one. @@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp /// The . public static IImageProcessingContext BackgroundColor(this IImageProcessingContext source, TPixel color, Rectangle rectangle, GraphicsOptions options) where TPixel : struct, IPixel - => source.ApplyProcessor(new BackgroundColorProcessor(color, options), rectangle); + => source.ApplyProcessor(new BackgroundColorProcessor(source.GetMemoryManager(), color, options), rectangle); /// /// Replaces the background color of image with the given one. diff --git a/src/ImageSharp/Processing/Overlays/Glow.cs b/src/ImageSharp/Processing/Overlays/Glow.cs index ee35963487..a8994b18a1 100644 --- a/src/ImageSharp/Processing/Overlays/Glow.cs +++ b/src/ImageSharp/Processing/Overlays/Glow.cs @@ -157,7 +157,7 @@ namespace SixLabors.ImageSharp /// The . private static IImageProcessingContext Glow(this IImageProcessingContext source, TPixel color, ValueSize radius, Rectangle rectangle, GraphicsOptions options) where TPixel : struct, IPixel - => source.ApplyProcessor(new GlowProcessor(color, radius, options), rectangle); + => source.ApplyProcessor(new GlowProcessor(source.GetMemoryManager(), color, radius, options), rectangle); /// /// Applies a radial glow effect to an image. @@ -170,6 +170,6 @@ namespace SixLabors.ImageSharp /// The . private static IImageProcessingContext Glow(this IImageProcessingContext source, TPixel color, ValueSize radius, GraphicsOptions options) where TPixel : struct, IPixel - => source.ApplyProcessor(new GlowProcessor(color, radius, options)); + => source.ApplyProcessor(new GlowProcessor(source.GetMemoryManager(), color, radius, options)); } } diff --git a/src/ImageSharp/Processing/Overlays/Vignette.cs b/src/ImageSharp/Processing/Overlays/Vignette.cs index cc93ccedc6..3a691ed00d 100644 --- a/src/ImageSharp/Processing/Overlays/Vignette.cs +++ b/src/ImageSharp/Processing/Overlays/Vignette.cs @@ -151,10 +151,10 @@ namespace SixLabors.ImageSharp private static IImageProcessingContext VignetteInternal(this IImageProcessingContext source, TPixel color, ValueSize radiusX, ValueSize radiusY, Rectangle rectangle, GraphicsOptions options) where TPixel : struct, IPixel - => source.ApplyProcessor(new VignetteProcessor(color, radiusX, radiusY, options), rectangle); + => source.ApplyProcessor(new VignetteProcessor(source.GetMemoryManager(), color, radiusX, radiusY, options), rectangle); private static IImageProcessingContext VignetteInternal(this IImageProcessingContext source, TPixel color, ValueSize radiusX, ValueSize radiusY, GraphicsOptions options) where TPixel : struct, IPixel - => source.ApplyProcessor(new VignetteProcessor(color, radiusX, radiusY, options)); + => source.ApplyProcessor(new VignetteProcessor(source.GetMemoryManager(), color, radiusX, radiusY, options)); } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/ColorMatrix/LomographProcessor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/LomographProcessor.cs index 1ec76bf554..a95d5fef65 100644 --- a/src/ImageSharp/Processing/Processors/ColorMatrix/LomographProcessor.cs +++ b/src/ImageSharp/Processing/Processors/ColorMatrix/LomographProcessor.cs @@ -2,6 +2,8 @@ // Licensed under the Apache License, Version 2.0. using System.Numerics; + +using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; using SixLabors.Primitives; @@ -15,14 +17,17 @@ namespace SixLabors.ImageSharp.Processing.Processors where TPixel : struct, IPixel { private static readonly TPixel VeryDarkGreen = ColorBuilder.FromRGBA(0, 10, 0, 255); + + private readonly MemoryManager memoryManager; + private readonly GraphicsOptions options; /// /// Initializes a new instance of the class. /// /// The options effecting blending and composition. - public LomographProcessor(GraphicsOptions options) - { + public LomographProcessor(MemoryManager memoryManager, GraphicsOptions options) { + this.memoryManager = memoryManager; this.options = options; } @@ -41,7 +46,7 @@ namespace SixLabors.ImageSharp.Processing.Processors /// protected override void AfterApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration) { - new VignetteProcessor(VeryDarkGreen, this.options).Apply(source, sourceRectangle, configuration); + new VignetteProcessor(this.memoryManager, VeryDarkGreen, this.options).Apply(source, sourceRectangle, configuration); } } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/ColorMatrix/PolaroidProcessor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/PolaroidProcessor.cs index f910562e64..76a616a1b0 100644 --- a/src/ImageSharp/Processing/Processors/ColorMatrix/PolaroidProcessor.cs +++ b/src/ImageSharp/Processing/Processors/ColorMatrix/PolaroidProcessor.cs @@ -2,6 +2,8 @@ // Licensed under the Apache License, Version 2.0. using System.Numerics; + +using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; using SixLabors.Primitives; @@ -16,14 +18,17 @@ namespace SixLabors.ImageSharp.Processing.Processors { private static readonly TPixel VeryDarkOrange = ColorBuilder.FromRGB(102, 34, 0); private static readonly TPixel LightOrange = ColorBuilder.FromRGBA(255, 153, 102, 178); + + private readonly MemoryManager memoryManager; + private readonly GraphicsOptions options; /// /// Initializes a new instance of the class. /// /// The options effecting blending and composition. - public PolaroidProcessor(GraphicsOptions options) - { + public PolaroidProcessor(MemoryManager memoryManager, GraphicsOptions options) { + this.memoryManager = memoryManager; this.options = options; } @@ -48,8 +53,8 @@ namespace SixLabors.ImageSharp.Processing.Processors /// protected override void AfterApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration) { - new VignetteProcessor(VeryDarkOrange, this.options).Apply(source, sourceRectangle, configuration); - new GlowProcessor(LightOrange, source.Width / 4F, this.options).Apply(source, sourceRectangle, configuration); + new VignetteProcessor(this.memoryManager, VeryDarkOrange, this.options).Apply(source, sourceRectangle, configuration); + new GlowProcessor(this.memoryManager, LightOrange, source.Width / 4F, this.options).Apply(source, sourceRectangle, configuration); } } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Effects/BackgroundColorProcessor.cs b/src/ImageSharp/Processing/Processors/Effects/BackgroundColorProcessor.cs index 5f6fd40238..b81fe3cf31 100644 --- a/src/ImageSharp/Processing/Processors/Effects/BackgroundColorProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Effects/BackgroundColorProcessor.cs @@ -17,6 +17,8 @@ namespace SixLabors.ImageSharp.Processing.Processors internal class BackgroundColorProcessor : ImageProcessor where TPixel : struct, IPixel { + private readonly MemoryManager memoryManager; + private readonly GraphicsOptions options; /// @@ -24,9 +26,10 @@ namespace SixLabors.ImageSharp.Processing.Processors /// /// The to set the background color to. /// The options defining blending algorithum and amount. - public BackgroundColorProcessor(TPixel color, GraphicsOptions options) + public BackgroundColorProcessor(MemoryManager memoryManager, TPixel color, GraphicsOptions options) { this.Value = color; + this.memoryManager = memoryManager; this.options = options; } @@ -67,8 +70,8 @@ namespace SixLabors.ImageSharp.Processing.Processors int width = maxX - minX; - using (var colors = MemoryManager.Current.Allocate(width)) - using (var amount = MemoryManager.Current.Allocate(width)) + using (var colors = this.memoryManager.Allocate(width)) + using (var amount = this.memoryManager.Allocate(width)) { for (int i = 0; i < width; i++) { diff --git a/src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs b/src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs index 0cee4c0b2d..521da20a76 100644 --- a/src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs @@ -19,6 +19,8 @@ namespace SixLabors.ImageSharp.Processing.Processors internal class GlowProcessor : ImageProcessor where TPixel : struct, IPixel { + private readonly MemoryManager memoryManager; + private readonly GraphicsOptions options; private readonly PixelBlender blender; @@ -28,8 +30,9 @@ namespace SixLabors.ImageSharp.Processing.Processors /// The color or the glow. /// The radius of the glow. /// The options effecting blending and composition. - public GlowProcessor(TPixel color, ValueSize radius, GraphicsOptions options) + public GlowProcessor(MemoryManager memoryManager, TPixel color, ValueSize radius, GraphicsOptions options) { + this.memoryManager = memoryManager; this.options = options; this.GlowColor = color; this.Radius = radius; @@ -83,7 +86,7 @@ namespace SixLabors.ImageSharp.Processing.Processors } int width = maxX - minX; - using (var rowColors = MemoryManager.Current.Allocate(width)) + using (var rowColors = this.memoryManager.Allocate(width)) { for (int i = 0; i < width; i++) { @@ -96,7 +99,7 @@ namespace SixLabors.ImageSharp.Processing.Processors configuration.ParallelOptions, y => { - using (var amounts = MemoryManager.Current.Allocate(width)) + using (var amounts = this.memoryManager.Allocate(width)) { int offsetY = y - startY; int offsetX = minX - startX; diff --git a/src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs b/src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs index 60915e6db2..dc60ffec91 100644 --- a/src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs @@ -19,6 +19,8 @@ namespace SixLabors.ImageSharp.Processing.Processors internal class VignetteProcessor : ImageProcessor where TPixel : struct, IPixel { + private readonly MemoryManager memoryManager; + private readonly GraphicsOptions options; private readonly PixelBlender blender; @@ -29,11 +31,12 @@ namespace SixLabors.ImageSharp.Processing.Processors /// The x-radius. /// The y-radius. /// The options effecting blending and composition. - public VignetteProcessor(TPixel color, ValueSize radiusX, ValueSize radiusY, GraphicsOptions options) + public VignetteProcessor(MemoryManager memoryManager, TPixel color, ValueSize radiusX, ValueSize radiusY, GraphicsOptions options) { this.VignetteColor = color; this.RadiusX = radiusX; this.RadiusY = radiusY; + this.memoryManager = memoryManager; this.options = options; this.blender = PixelOperations.Instance.GetPixelBlender(this.options.BlenderMode); } @@ -43,9 +46,10 @@ namespace SixLabors.ImageSharp.Processing.Processors /// /// The color of the vignette. /// The options effecting blending and composition. - public VignetteProcessor(TPixel color, GraphicsOptions options) + public VignetteProcessor(MemoryManager memoryManager, TPixel color, GraphicsOptions options) { this.VignetteColor = color; + this.memoryManager = memoryManager; this.options = options; this.blender = PixelOperations.Instance.GetPixelBlender(this.options.BlenderMode); } @@ -104,7 +108,7 @@ namespace SixLabors.ImageSharp.Processing.Processors } int width = maxX - minX; - using (var rowColors = MemoryManager.Current.Allocate(width)) + using (var rowColors = this.memoryManager.Allocate(width)) { for (int i = 0; i < width; i++) { @@ -117,7 +121,7 @@ namespace SixLabors.ImageSharp.Processing.Processors configuration.ParallelOptions, y => { - using (var amounts = MemoryManager.Current.Allocate(width)) + using (var amounts = this.memoryManager.Allocate(width)) { int offsetY = y - startY; int offsetX = minX - startX; diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.Weights.cs b/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.Weights.cs index 9d76bf60f1..c86fe89b70 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.Weights.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.Weights.cs @@ -164,9 +164,9 @@ namespace SixLabors.ImageSharp.Processing.Processors /// /// The size of the source window /// The size of the destination window - public WeightsBuffer(int sourceSize, int destinationSize) + public WeightsBuffer(MemoryManager memoryManager, int sourceSize, int destinationSize) { - this.dataBuffer = Buffer2D.CreateClean(sourceSize, destinationSize); + this.dataBuffer = memoryManager.Allocate2D(sourceSize, destinationSize, true); this.Weights = new WeightsWindow[destinationSize]; } diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs index 781f3a01c7..6b608d1021 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs @@ -3,6 +3,8 @@ using System; using System.Runtime.CompilerServices; + +using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; using SixLabors.Primitives; @@ -25,18 +27,20 @@ namespace SixLabors.ImageSharp.Processing.Processors /// /// The structure that specifies the portion of the target image object to draw to. /// - protected ResamplingWeightedProcessor(IResampler sampler, int width, int height, Rectangle resizeRectangle) + protected ResamplingWeightedProcessor(MemoryManager memoryManager, IResampler sampler, int width, int height, Rectangle resizeRectangle) { + Guard.NotNull(memoryManager, nameof(memoryManager)); Guard.NotNull(sampler, nameof(sampler)); Guard.MustBeGreaterThan(width, 0, nameof(width)); Guard.MustBeGreaterThan(height, 0, nameof(height)); + this.MemoryManager = memoryManager; this.Sampler = sampler; this.Width = width; this.Height = height; this.ResizeRectangle = resizeRectangle; } - + /// /// Gets the sampler to perform the resize operation. /// @@ -56,6 +60,8 @@ namespace SixLabors.ImageSharp.Processing.Processors /// Gets or sets the resize rectangle. /// public Rectangle ResizeRectangle { get; protected set; } + + protected MemoryManager MemoryManager { get; } /// /// Gets or sets the horizontal weights. @@ -86,7 +92,7 @@ namespace SixLabors.ImageSharp.Processing.Processors IResampler sampler = this.Sampler; float radius = MathF.Ceiling(scale * sampler.Radius); - var result = new WeightsBuffer(sourceSize, destinationSize); + var result = new WeightsBuffer(this.MemoryManager, sourceSize, destinationSize); for (int i = 0; i < destinationSize; i++) { diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs index dbc05876dd..6c4ea7e67d 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs @@ -26,8 +26,8 @@ namespace SixLabors.ImageSharp.Processing.Processors /// The sampler to perform the resize operation. /// The target width. /// The target height. - public ResizeProcessor(IResampler sampler, int width, int height) - : base(sampler, width, height, new Rectangle(0, 0, width, height)) + public ResizeProcessor(MemoryManager memoryManager, IResampler sampler, int width, int height) + : base(memoryManager, sampler, width, height, new Rectangle(0, 0, width, height)) { } @@ -40,8 +40,8 @@ namespace SixLabors.ImageSharp.Processing.Processors /// /// The structure that specifies the portion of the target image object to draw to. /// - public ResizeProcessor(IResampler sampler, int width, int height, Rectangle resizeRectangle) - : base(sampler, width, height, resizeRectangle) + public ResizeProcessor(MemoryManager memoryManager, IResampler sampler, int width, int height, Rectangle resizeRectangle) + : base(memoryManager, sampler, width, height, resizeRectangle) { } @@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.Processing.Processors // ------------ // For resize we know we are going to populate every pixel with fresh data and we want a different target size so // let's manually clone an empty set of images at the correct target and then have the base class process them in turn. - IEnumerable> frames = source.Frames.Select(x => new ImageFrame(this.Width, this.Height, x.MetaData.Clone())); // this will create places holders + IEnumerable> frames = source.Frames.Select(x => new ImageFrame(source.GetConfiguration().MemoryManager, this.Width, this.Height, x.MetaData.Clone())); // this will create places holders var image = new Image(config, source.MetaData.Clone(), frames); // base the place holder images in to prevent a extra frame being added return image; @@ -121,7 +121,7 @@ namespace SixLabors.ImageSharp.Processing.Processors // First process the columns. Since we are not using multiple threads startY and endY // are the upper and lower bounds of the source rectangle. // TODO: Using a transposed variant of 'firstPassPixels' could eliminate the need for the WeightsWindow.ComputeWeightedColumnSum() method, and improve speed! - using (var firstPassPixels = MemoryManager.Current.Allocate2D(width, source.Height)) + using (var firstPassPixels = this.MemoryManager.Allocate2D(width, source.Height)) { firstPassPixels.Buffer.Clear(); @@ -132,7 +132,7 @@ namespace SixLabors.ImageSharp.Processing.Processors y => { // TODO: Without Parallel.For() this buffer object could be reused: - using (var tempRowBuffer = MemoryManager.Current.Allocate(source.Width)) + using (var tempRowBuffer = this.MemoryManager.Allocate(source.Width)) { Span firstPassRow = firstPassPixels.GetRowSpan(y); Span sourceRow = source.GetPixelRowSpan(y); diff --git a/src/ImageSharp/Processing/Transforms/Resize.cs b/src/ImageSharp/Processing/Transforms/Resize.cs index 3c7cbca311..c54267a9f5 100644 --- a/src/ImageSharp/Processing/Transforms/Resize.cs +++ b/src/ImageSharp/Processing/Transforms/Resize.cs @@ -193,7 +193,7 @@ namespace SixLabors.ImageSharp Guard.MustBeGreaterThan(width, 0, nameof(width)); Guard.MustBeGreaterThan(height, 0, nameof(height)); - img.Mutate(x => x.ApplyProcessor(new ResizeProcessor(sampler, width, height, targetRectangle) { Compand = compand }, sourceRectangle)); + img.Mutate(x => x.ApplyProcessor(new ResizeProcessor(source.GetMemoryManager(), sampler, width, height, targetRectangle) { Compand = compand }, sourceRectangle)); }); } @@ -233,7 +233,7 @@ namespace SixLabors.ImageSharp Guard.MustBeGreaterThan(width, 0, nameof(width)); Guard.MustBeGreaterThan(height, 0, nameof(height)); - img.Mutate(x => x.ApplyProcessor(new ResizeProcessor(sampler, width, height, targetRectangle) { Compand = compand })); + img.Mutate(x => x.ApplyProcessor(new ResizeProcessor(source.GetMemoryManager(), sampler, width, height, targetRectangle) { Compand = compand })); }); } } diff --git a/tests/ImageSharp.Tests/FakeImageOperationsProvider.cs b/tests/ImageSharp.Tests/FakeImageOperationsProvider.cs index f750bfcfad..a1c199b161 100644 --- a/tests/ImageSharp.Tests/FakeImageOperationsProvider.cs +++ b/tests/ImageSharp.Tests/FakeImageOperationsProvider.cs @@ -5,6 +5,9 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; + +using SixLabors.ImageSharp.Advanced; +using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using SixLabors.Primitives; @@ -84,6 +87,9 @@ namespace SixLabors.ImageSharp.Tests }); return this; } + + public MemoryManager GetMemoryManager() => this.source.GetConfiguration().MemoryManager; + public struct AppliedOpperation { public Rectangle? Rectangle { get; set; }