Browse Source

ResizeWindow refactor 2

af/merge-core
Anton Firszov 7 years ago
parent
commit
c337c4cb0f
  1. 14
      src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs
  2. 67
      src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWindow.cs

14
src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs

@ -235,27 +235,27 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
PixelConversionModifiers conversionModifiers = PixelConversionModifiers conversionModifiers =
PixelConversionModifiers.Premultiply.ApplyCompanding(this.Compand); PixelConversionModifiers.Premultiply.ApplyCompanding(this.Compand);
BufferArea<TPixel> sourceArea = source.PixelBuffer.GetArea(sourceRectangle);
// Interpolate the image using the calculated weights. // Interpolate the image using the calculated weights.
// A 2-pass 1D algorithm appears to be faster than splitting a 1-pass 2D algorithm // A 2-pass 1D algorithm appears to be faster than splitting a 1-pass 2D algorithm
// First process the columns. Since we are not using multiple threads startY and endY // First process the columns. Since we are not using multiple threads startY and endY
// are the upper and lower bounds of the source rectangle. // are the upper and lower bounds of the source rectangle.
using (var resizeWindow = new ResizeWindow( using (var resizeWindow = new ResizeWindow<TPixel>(
configuration, configuration,
sourceRectangle, sourceArea,
conversionModifiers, conversionModifiers,
this.horizontalKernelMap, this.horizontalKernelMap,
this.verticalKernelMap, this.verticalKernelMap,
width, width,
workingRect, workingRect,
startX)) startX))
using (IMemoryOwner<Vector4> tempBuffer = source.MemoryAllocator.Allocate<Vector4>(Math.Max(sourceRectangle.Width, width))) using (IMemoryOwner<Vector4> tempBuffer = source.MemoryAllocator.Allocate<Vector4>(width))
{ {
Span<Vector4> tempRowSpan = tempBuffer.GetSpan(); resizeWindow.Initialize();
resizeWindow.Initialize(source.PixelBuffer, tempRowSpan);
// Now process the rows. // Now process the rows.
Span<Vector4> tempColSpan = tempBuffer.GetSpan().Slice(0, width); Span<Vector4> tempColSpan = tempBuffer.GetSpan();
for (int y = workingRect.Top; y < workingRect.Bottom; y++) for (int y = workingRect.Top; y < workingRect.Bottom; y++)
{ {

67
src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWindow.cs

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Buffers;
using System.Numerics; using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@ -12,27 +13,32 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors.Transforms namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{ {
class ResizeWindow : IDisposable class ResizeWindow<TPixel> : IDisposable
where TPixel : struct, IPixel<TPixel>
{ {
private readonly Buffer2D<Vector4> buffer; private readonly Buffer2D<Vector4> buffer;
private readonly Configuration configuration; private readonly Configuration configuration;
private readonly Rectangle sourceRectangle;
private readonly PixelConversionModifiers conversionModifiers; private readonly PixelConversionModifiers conversionModifiers;
private readonly ResizeKernelMap horizontalKernelMap; private readonly ResizeKernelMap horizontalKernelMap;
private readonly ResizeKernelMap verticalKernelMap; private readonly BufferArea<TPixel> source;
private readonly Rectangle workingRectangle; private readonly Rectangle sourceRectangle;
private readonly int startX; private readonly int startX;
private readonly IMemoryOwner<Vector4> tempRowBuffer;
private readonly ResizeKernelMap verticalKernelMap;
private readonly Rectangle workingRectangle;
public ResizeWindow( public ResizeWindow(
Configuration configuration, Configuration configuration,
Rectangle sourceRectangle, BufferArea<TPixel> source,
PixelConversionModifiers conversionModifiers, PixelConversionModifiers conversionModifiers,
ResizeKernelMap horizontalKernelMap, ResizeKernelMap horizontalKernelMap,
ResizeKernelMap verticalKernelMap, ResizeKernelMap verticalKernelMap,
@ -41,31 +47,45 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
int startX) int startX)
{ {
this.configuration = configuration; this.configuration = configuration;
this.sourceRectangle = sourceRectangle; this.source = source;
this.sourceRectangle = source.Rectangle;
this.conversionModifiers = conversionModifiers; this.conversionModifiers = conversionModifiers;
this.horizontalKernelMap = horizontalKernelMap; this.horizontalKernelMap = horizontalKernelMap;
this.verticalKernelMap = verticalKernelMap; this.verticalKernelMap = verticalKernelMap;
this.workingRectangle = workingRectangle; this.workingRectangle = workingRectangle;
this.startX = startX; this.startX = startX;
this.buffer = configuration.MemoryAllocator.Allocate2D<Vector4>(sourceRectangle.Height, destWidth, AllocationOptions.Clean); this.buffer = configuration.MemoryAllocator.Allocate2D<Vector4>(
this.sourceRectangle.Height,
destWidth,
AllocationOptions.Clean);
this.tempRowBuffer = configuration.MemoryAllocator.Allocate<Vector4>(this.sourceRectangle.Width);
this.Top = sourceRectangle.Top; this.Top = this.sourceRectangle.Top;
this.Bottom = sourceRectangle.Bottom; this.Bottom = this.sourceRectangle.Bottom;
} }
public int Bottom { get; private set; }
public int Top { get; private set; } public int Top { get; private set; }
public int Bottom { get; private set; } public void Dispose()
{
this.buffer.Dispose();
}
public void Initialize<TPixel>( [MethodImpl(MethodImplOptions.AggressiveInlining)]
Buffer2D<TPixel> source, public Span<Vector4> GetColumnSpan(int x)
Span<Vector4> tempRowSpan)
where TPixel : struct, IPixel<TPixel>
{ {
for (int y = this.sourceRectangle.Top; y < this.sourceRectangle.Bottom; y++) return this.buffer.GetRowSpan(x);
}
public void Initialize()
{
Span<Vector4> tempRowSpan = this.tempRowBuffer.GetSpan();
for (int y = 0; y < this.sourceRectangle.Height; y++)
{ {
Span<TPixel> sourceRow = source.GetRowSpan(y).Slice(this.sourceRectangle.X); Span<TPixel> sourceRow = this.source.GetRowSpan(y);
PixelOperations<TPixel>.Instance.ToVector4( PixelOperations<TPixel>.Instance.ToVector4(
this.configuration, this.configuration,
@ -73,7 +93,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
tempRowSpan, tempRowSpan,
this.conversionModifiers); this.conversionModifiers);
ref Vector4 firstPassBaseRef = ref this.buffer.Span[y - this.sourceRectangle.Y]; ref Vector4 firstPassBaseRef = ref this.buffer.Span[y];
for (int x = this.workingRectangle.Left; x < this.workingRectangle.Right; x++) for (int x = this.workingRectangle.Left; x < this.workingRectangle.Right; x++)
{ {
@ -82,16 +102,5 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
} }
} }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Span<Vector4> GetColumnSpan(int x)
{
return this.buffer.GetRowSpan(x);
}
public void Dispose()
{
this.buffer.Dispose();
}
} }
} }
Loading…
Cancel
Save