|
|
@ -72,8 +72,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
|
|
protected override void OnFrameApply(ImageFrame<TPixel> source) |
|
|
protected override void OnFrameApply(ImageFrame<TPixel> source) |
|
|
{ |
|
|
{ |
|
|
// Preliminary gamma highlight pass
|
|
|
// Preliminary gamma highlight pass
|
|
|
var gammaOperation = new ApplyGammaExposureRowIntervalOperation(this.SourceRectangle, source.PixelBuffer, this.Configuration, this.gamma); |
|
|
var gammaOperation = new ApplyGammaExposureRowOperation(this.SourceRectangle, source.PixelBuffer, this.Configuration, this.gamma); |
|
|
ParallelRowIterator.IterateRows<ApplyGammaExposureRowIntervalOperation, Vector4>( |
|
|
ParallelRowIterator.IterateRows<ApplyGammaExposureRowOperation, Vector4>( |
|
|
this.Configuration, |
|
|
this.Configuration, |
|
|
this.SourceRectangle, |
|
|
this.SourceRectangle, |
|
|
in gammaOperation); |
|
|
in gammaOperation); |
|
|
@ -87,7 +87,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
|
|
float inverseGamma = 1 / this.gamma; |
|
|
float inverseGamma = 1 / this.gamma; |
|
|
|
|
|
|
|
|
// Apply the inverse gamma exposure pass, and write the final pixel data
|
|
|
// Apply the inverse gamma exposure pass, and write the final pixel data
|
|
|
var operation = new ApplyInverseGammaExposureRowIntervalOperation(this.SourceRectangle, source.PixelBuffer, processingBuffer, this.Configuration, inverseGamma); |
|
|
var operation = new ApplyInverseGammaExposureRowOperation(this.SourceRectangle, source.PixelBuffer, processingBuffer, this.Configuration, inverseGamma); |
|
|
ParallelRowIterator.IterateRows( |
|
|
ParallelRowIterator.IterateRows( |
|
|
this.Configuration, |
|
|
this.Configuration, |
|
|
this.SourceRectangle, |
|
|
this.SourceRectangle, |
|
|
@ -120,14 +120,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
|
|
Vector4 parameters = Unsafe.Add(ref paramsRef, i); |
|
|
Vector4 parameters = Unsafe.Add(ref paramsRef, i); |
|
|
|
|
|
|
|
|
// Compute the vertical 1D convolution
|
|
|
// Compute the vertical 1D convolution
|
|
|
var verticalOperation = new ApplyVerticalConvolutionRowIntervalOperation(sourceRectangle, firstPassBuffer, source.PixelBuffer, kernel); |
|
|
var verticalOperation = new ApplyVerticalConvolutionRowOperation(sourceRectangle, firstPassBuffer, source.PixelBuffer, kernel); |
|
|
ParallelRowIterator.IterateRows( |
|
|
ParallelRowIterator.IterateRows( |
|
|
configuration, |
|
|
configuration, |
|
|
sourceRectangle, |
|
|
sourceRectangle, |
|
|
in verticalOperation); |
|
|
in verticalOperation); |
|
|
|
|
|
|
|
|
// Compute the horizontal 1D convolutions and accumulate the partial results on the target buffer
|
|
|
// Compute the horizontal 1D convolutions and accumulate the partial results on the target buffer
|
|
|
var horizontalOperation = new ApplyHorizontalConvolutionRowIntervalOperation(sourceRectangle, processingBuffer, firstPassBuffer, kernel, parameters.Z, parameters.W); |
|
|
var horizontalOperation = new ApplyHorizontalConvolutionRowOperation(sourceRectangle, processingBuffer, firstPassBuffer, kernel, parameters.Z, parameters.W); |
|
|
ParallelRowIterator.IterateRows( |
|
|
ParallelRowIterator.IterateRows( |
|
|
configuration, |
|
|
configuration, |
|
|
sourceRectangle, |
|
|
sourceRectangle, |
|
|
@ -138,7 +138,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// A <see langword="struct"/> implementing the vertical convolution logic for <see cref="BokehBlurProcessor{T}"/>.
|
|
|
/// A <see langword="struct"/> implementing the vertical convolution logic for <see cref="BokehBlurProcessor{T}"/>.
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
private readonly struct ApplyVerticalConvolutionRowIntervalOperation : IRowIntervalOperation |
|
|
private readonly struct ApplyVerticalConvolutionRowOperation : IRowOperation |
|
|
{ |
|
|
{ |
|
|
private readonly Rectangle bounds; |
|
|
private readonly Rectangle bounds; |
|
|
private readonly Buffer2D<ComplexVector4> targetValues; |
|
|
private readonly Buffer2D<ComplexVector4> targetValues; |
|
|
@ -148,7 +148,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
|
|
private readonly int maxX; |
|
|
private readonly int maxX; |
|
|
|
|
|
|
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
public ApplyVerticalConvolutionRowIntervalOperation( |
|
|
public ApplyVerticalConvolutionRowOperation( |
|
|
Rectangle bounds, |
|
|
Rectangle bounds, |
|
|
Buffer2D<ComplexVector4> targetValues, |
|
|
Buffer2D<ComplexVector4> targetValues, |
|
|
Buffer2D<TPixel> sourcePixels, |
|
|
Buffer2D<TPixel> sourcePixels, |
|
|
@ -164,9 +164,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
/// <inheritdoc/>
|
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
public void Invoke(in RowInterval rows) |
|
|
public void Invoke(int y) |
|
|
{ |
|
|
|
|
|
for (int y = rows.Min; y < rows.Max; y++) |
|
|
|
|
|
{ |
|
|
{ |
|
|
Span<ComplexVector4> targetRowSpan = this.targetValues.GetRowSpan(y).Slice(this.bounds.X); |
|
|
Span<ComplexVector4> targetRowSpan = this.targetValues.GetRowSpan(y).Slice(this.bounds.X); |
|
|
|
|
|
|
|
|
@ -176,12 +174,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// A <see langword="struct"/> implementing the horizontal convolution logic for <see cref="BokehBlurProcessor{T}"/>.
|
|
|
/// A <see langword="struct"/> implementing the horizontal convolution logic for <see cref="BokehBlurProcessor{T}"/>.
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
private readonly struct ApplyHorizontalConvolutionRowIntervalOperation : IRowIntervalOperation |
|
|
private readonly struct ApplyHorizontalConvolutionRowOperation : IRowOperation |
|
|
{ |
|
|
{ |
|
|
private readonly Rectangle bounds; |
|
|
private readonly Rectangle bounds; |
|
|
private readonly Buffer2D<Vector4> targetValues; |
|
|
private readonly Buffer2D<Vector4> targetValues; |
|
|
@ -193,7 +190,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
|
|
private readonly int maxX; |
|
|
private readonly int maxX; |
|
|
|
|
|
|
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
public ApplyHorizontalConvolutionRowIntervalOperation( |
|
|
public ApplyHorizontalConvolutionRowOperation( |
|
|
Rectangle bounds, |
|
|
Rectangle bounds, |
|
|
Buffer2D<Vector4> targetValues, |
|
|
Buffer2D<Vector4> targetValues, |
|
|
Buffer2D<ComplexVector4> sourceValues, |
|
|
Buffer2D<ComplexVector4> sourceValues, |
|
|
@ -213,9 +210,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
/// <inheritdoc/>
|
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
public void Invoke(in RowInterval rows) |
|
|
public void Invoke(int y) |
|
|
{ |
|
|
|
|
|
for (int y = rows.Min; y < rows.Max; y++) |
|
|
|
|
|
{ |
|
|
{ |
|
|
Span<Vector4> targetRowSpan = this.targetValues.GetRowSpan(y).Slice(this.bounds.X); |
|
|
Span<Vector4> targetRowSpan = this.targetValues.GetRowSpan(y).Slice(this.bounds.X); |
|
|
|
|
|
|
|
|
@ -225,12 +220,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// A <see langword="struct"/> implementing the gamma exposure logic for <see cref="BokehBlurProcessor{T}"/>.
|
|
|
/// A <see langword="struct"/> implementing the gamma exposure logic for <see cref="BokehBlurProcessor{T}"/>.
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
private readonly struct ApplyGammaExposureRowIntervalOperation : IRowIntervalOperation<Vector4> |
|
|
private readonly struct ApplyGammaExposureRowOperation : IRowOperation<Vector4> |
|
|
{ |
|
|
{ |
|
|
private readonly Rectangle bounds; |
|
|
private readonly Rectangle bounds; |
|
|
private readonly Buffer2D<TPixel> targetPixels; |
|
|
private readonly Buffer2D<TPixel> targetPixels; |
|
|
@ -238,7 +232,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
|
|
private readonly float gamma; |
|
|
private readonly float gamma; |
|
|
|
|
|
|
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
public ApplyGammaExposureRowIntervalOperation( |
|
|
public ApplyGammaExposureRowOperation( |
|
|
Rectangle bounds, |
|
|
Rectangle bounds, |
|
|
Buffer2D<TPixel> targetPixels, |
|
|
Buffer2D<TPixel> targetPixels, |
|
|
Configuration configuration, |
|
|
Configuration configuration, |
|
|
@ -252,9 +246,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
/// <inheritdoc/>
|
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
public void Invoke(in RowInterval rows, Span<Vector4> span) |
|
|
public void Invoke(int y, Span<Vector4> span) |
|
|
{ |
|
|
|
|
|
for (int y = rows.Min; y < rows.Max; y++) |
|
|
|
|
|
{ |
|
|
{ |
|
|
Span<TPixel> targetRowSpan = this.targetPixels.GetRowSpan(y).Slice(this.bounds.X); |
|
|
Span<TPixel> targetRowSpan = this.targetPixels.GetRowSpan(y).Slice(this.bounds.X); |
|
|
PixelOperations<TPixel>.Instance.ToVector4(this.configuration, targetRowSpan.Slice(0, span.Length), span, PixelConversionModifiers.Premultiply); |
|
|
PixelOperations<TPixel>.Instance.ToVector4(this.configuration, targetRowSpan.Slice(0, span.Length), span, PixelConversionModifiers.Premultiply); |
|
|
@ -271,12 +263,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
|
|
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.configuration, span, targetRowSpan); |
|
|
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.configuration, span, targetRowSpan); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// A <see langword="struct"/> implementing the inverse gamma exposure logic for <see cref="BokehBlurProcessor{T}"/>.
|
|
|
/// A <see langword="struct"/> implementing the inverse gamma exposure logic for <see cref="BokehBlurProcessor{T}"/>.
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
private readonly struct ApplyInverseGammaExposureRowIntervalOperation : IRowIntervalOperation |
|
|
private readonly struct ApplyInverseGammaExposureRowOperation : IRowOperation |
|
|
{ |
|
|
{ |
|
|
private readonly Rectangle bounds; |
|
|
private readonly Rectangle bounds; |
|
|
private readonly Buffer2D<TPixel> targetPixels; |
|
|
private readonly Buffer2D<TPixel> targetPixels; |
|
|
@ -285,7 +276,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
|
|
private readonly float inverseGamma; |
|
|
private readonly float inverseGamma; |
|
|
|
|
|
|
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
public ApplyInverseGammaExposureRowIntervalOperation( |
|
|
public ApplyInverseGammaExposureRowOperation( |
|
|
Rectangle bounds, |
|
|
Rectangle bounds, |
|
|
Buffer2D<TPixel> targetPixels, |
|
|
Buffer2D<TPixel> targetPixels, |
|
|
Buffer2D<Vector4> sourceValues, |
|
|
Buffer2D<Vector4> sourceValues, |
|
|
@ -301,13 +292,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
/// <inheritdoc/>
|
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
public void Invoke(in RowInterval rows) |
|
|
public void Invoke(int y) |
|
|
{ |
|
|
{ |
|
|
Vector4 low = Vector4.Zero; |
|
|
Vector4 low = Vector4.Zero; |
|
|
var high = new Vector4(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity); |
|
|
var high = new Vector4(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity); |
|
|
|
|
|
|
|
|
for (int y = rows.Min; y < rows.Max; y++) |
|
|
|
|
|
{ |
|
|
|
|
|
Span<TPixel> targetPixelSpan = this.targetPixels.GetRowSpan(y).Slice(this.bounds.X); |
|
|
Span<TPixel> targetPixelSpan = this.targetPixels.GetRowSpan(y).Slice(this.bounds.X); |
|
|
Span<Vector4> sourceRowSpan = this.sourceValues.GetRowSpan(y).Slice(this.bounds.X); |
|
|
Span<Vector4> sourceRowSpan = this.sourceValues.GetRowSpan(y).Slice(this.bounds.X); |
|
|
ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceRowSpan); |
|
|
ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceRowSpan); |
|
|
@ -326,4 +315,3 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|