Browse Source

Buffer length defined by RowOperation struct

pull/2241/head
Ynse Hoornenborg 4 years ago
parent
commit
05588d5d34
  1. 6
      src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor{TPixel}.cs
  2. 2
      src/ImageSharp/Processing/Processors/Convolution/Convolution2DRowOperation{TPixel}.cs
  3. 12
      src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs
  4. 7
      src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs
  5. 7
      src/ImageSharp/Processing/Processors/Convolution/MedianBlurProcessor{TPixel}.cs
  6. 4
      src/ImageSharp/Processing/Processors/Convolution/MedianRowOperation{TPixel}.cs

6
src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor{TPixel}.cs

@ -64,10 +64,6 @@ internal class Convolution2DProcessor<TPixel> : ImageProcessor<TPixel>
var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds());
// We use a rectangle 3x the interest width to allocate a buffer big enough
// for source and target bulk pixel conversion.
var operationBounds = new Rectangle(interest.X, interest.Y, interest.Width * 3, interest.Height);
using (var map = new KernelSamplingMap(allocator))
{
// Since the kernel sizes are identical we can use a single map.
@ -85,7 +81,7 @@ internal class Convolution2DProcessor<TPixel> : ImageProcessor<TPixel>
ParallelRowIterator.IterateRows<Convolution2DRowOperation<TPixel>, Vector4>(
this.Configuration,
operationBounds,
interest,
in operation);
}

2
src/ImageSharp/Processing/Processors/Convolution/Convolution2DRowOperation{TPixel}.cs

@ -49,7 +49,7 @@ internal readonly struct Convolution2DRowOperation<TPixel> : IRowOperation<Vecto
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public int GetRequiredBufferLength(Rectangle bounds)
=> bounds.Width;
=> 3 * bounds.Width;
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]

12
src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs

@ -70,10 +70,6 @@ internal class Convolution2PassProcessor<TPixel> : ImageProcessor<TPixel>
var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds());
// We use a rectangle 2x the interest width to allocate a buffer big enough
// for source and target bulk pixel conversion.
var operationBounds = new Rectangle(interest.X, interest.Y, interest.Width * 2, interest.Height);
// We can create a single sampling map with the size as if we were using the non separated 2D kernel
// the two 1D kernels represent, and reuse it across both convolution steps, like in the bokeh blur.
using var mapXY = new KernelSamplingMap(this.Configuration.MemoryAllocator);
@ -92,7 +88,7 @@ internal class Convolution2PassProcessor<TPixel> : ImageProcessor<TPixel>
ParallelRowIterator.IterateRows<HorizontalConvolutionRowOperation, Vector4>(
this.Configuration,
operationBounds,
interest,
in horizontalOperation);
// Vertical convolution
@ -107,7 +103,7 @@ internal class Convolution2PassProcessor<TPixel> : ImageProcessor<TPixel>
ParallelRowIterator.IterateRows<VerticalConvolutionRowOperation, Vector4>(
this.Configuration,
operationBounds,
interest,
in verticalOperation);
}
@ -146,7 +142,7 @@ internal class Convolution2PassProcessor<TPixel> : ImageProcessor<TPixel>
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public int GetRequiredBufferLength(Rectangle bounds)
=> bounds.Width;
=> 2 * bounds.Width;
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -312,7 +308,7 @@ internal class Convolution2PassProcessor<TPixel> : ImageProcessor<TPixel>
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public int GetRequiredBufferLength(Rectangle bounds)
=> bounds.Width;
=> 2 * bounds.Width;
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]

7
src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs

@ -57,9 +57,6 @@ internal class ConvolutionProcessor<TPixel> : ImageProcessor<TPixel>
var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds());
// We use a rectangle 2x the interest width to allocate a buffer big enough
// for source and target bulk pixel conversion.
var operationBounds = new Rectangle(interest.X, interest.Y, interest.Width * 2, interest.Height);
using (var map = new KernelSamplingMap(allocator))
{
map.BuildSamplingOffsetMap(this.KernelXY, interest);
@ -67,7 +64,7 @@ internal class ConvolutionProcessor<TPixel> : ImageProcessor<TPixel>
var operation = new RowOperation(interest, targetPixels, source.PixelBuffer, map, this.KernelXY, this.Configuration, this.PreserveAlpha);
ParallelRowIterator.IterateRows<RowOperation, Vector4>(
this.Configuration,
operationBounds,
interest,
in operation);
}
@ -109,7 +106,7 @@ internal class ConvolutionProcessor<TPixel> : ImageProcessor<TPixel>
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public int GetRequiredBufferLength(Rectangle bounds)
=> bounds.Width;
=> 2 * bounds.Width;
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]

7
src/ImageSharp/Processing/Processors/Convolution/MedianBlurProcessor{TPixel}.cs

@ -31,11 +31,6 @@ internal sealed class MedianBlurProcessor<TPixel> : ImageProcessor<TPixel>
Rectangle interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds());
// We use a rectangle with width set wider, to allocate a buffer big enough
// for kernel source, channel buffers, source rows and target bulk pixel conversion.
int operationWidth = (2 * kernelSize * kernelSize) + interest.Width + (kernelSize * interest.Width);
Rectangle operationBounds = new(interest.X, interest.Y, operationWidth, interest.Height);
using KernelSamplingMap map = new(this.Configuration.MemoryAllocator);
map.BuildSamplingOffsetMap(kernelSize, kernelSize, interest, this.definition.BorderWrapModeX, this.definition.BorderWrapModeY);
@ -50,7 +45,7 @@ internal sealed class MedianBlurProcessor<TPixel> : ImageProcessor<TPixel>
ParallelRowIterator.IterateRows<MedianRowOperation<TPixel>, Vector4>(
this.Configuration,
operationBounds,
interest,
in operation);
Buffer2D<TPixel>.SwapOrCopyContent(source.PixelBuffer, targetPixels);

4
src/ImageSharp/Processing/Processors/Convolution/MedianRowOperation{TPixel}.cs

@ -46,11 +46,11 @@ internal readonly struct MedianRowOperation<TPixel> : IRowOperation<Vector4>
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public int GetRequiredBufferLength(Rectangle bounds)
=> bounds.Width;
=> (2 * this.kernelSize * this.kernelSize) + bounds.Width + (kernelSize * bounds.Width);
public void Invoke(int y, Span<Vector4> span)
{
// Span has kernelSize^2 followed by bound width.
// Span has kernelSize^2 twice, then bound width followed by kernelsize * bounds width.
int boundsX = this.bounds.X;
int boundsWidth = this.bounds.Width;
int kernelCount = this.kernelSize * this.kernelSize;

Loading…
Cancel
Save