Browse Source

Convolution Replace parallel row iteration with sequential loops

pull/3113/head
James Jackson-South 1 month ago
parent
commit
a9c43dc800
  1. 114
      src/ImageSharp/Processing/Processors/Convolution/BokehBlurProcessor{TPixel}.cs
  2. 16
      src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor{TPixel}.cs
  3. 33
      src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs
  4. 16
      src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs
  5. 12
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetectorCompassProcessor{TPixel}.cs
  6. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_BikeGrayscale_R16_C1_G3.png
  7. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_BikeGrayscale_R16_C2_G3.png
  8. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_BikeGrayscale_R8_C1_G1.png
  9. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_Bike_R16_C1_G3.png
  10. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_Bike_R16_C2_G3.png
  11. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_Bike_R8_C1_G1.png
  12. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_CalliphoraPartial_R16_C1_G3.png
  13. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_CalliphoraPartial_R16_C2_G3.png
  14. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_CalliphoraPartial_R8_C1_G1.png
  15. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_Solid50x50_(255,0,0,255)_R16_C1_G3.png
  16. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_Solid50x50_(255,0,0,255)_R16_C2_G3.png
  17. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_Solid50x50_(255,0,0,255)_R8_C1_G1.png
  18. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern200x100_R16_C1_G3.png
  19. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern200x100_R16_C2_G3.png
  20. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern200x100_R8_C1_G1.png
  21. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern23x31_R16_C1_G3.png
  22. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern23x31_R16_C2_G3.png
  23. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern23x31_R8_C1_G1.png
  24. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern30x20_R16_C1_G3.png
  25. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern30x20_R16_C2_G3.png
  26. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern30x20_R8_C1_G1.png
  27. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_cross_R16_C1_G3.png
  28. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_cross_R16_C2_G3.png
  29. 4
      tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_cross_R8_C1_G1.png

114
src/ImageSharp/Processing/Processors/Convolution/BokehBlurProcessor{TPixel}.cs

@ -1,10 +1,12 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.ColorProfiles.Companding;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors.Convolution.Parameters;
@ -77,22 +79,36 @@ internal class BokehBlurProcessor<TPixel> : ImageProcessor<TPixel>
{
Rectangle sourceRectangle = Rectangle.Intersect(this.SourceRectangle, source.Bounds);
MemoryAllocator allocator = this.Configuration.MemoryAllocator;
// Convolution is memory-bandwidth-bound with low arithmetic intensity.
// Parallelization degrades performance due to cache line contention from
// overlapping source row reads. See #3111.
// Preliminary gamma highlight pass
if (this.gamma == 3F)
{
ApplyGamma3ExposureRowOperation gammaOperation = new(sourceRectangle, source.PixelBuffer, this.Configuration);
ParallelRowIterator.IterateRows<ApplyGamma3ExposureRowOperation, Vector4>(
this.Configuration,
sourceRectangle,
in gammaOperation);
using IMemoryOwner<Vector4> gammaBuffer = allocator.Allocate<Vector4>(gammaOperation.GetRequiredBufferLength(sourceRectangle));
Span<Vector4> gammaSpan = gammaBuffer.Memory.Span;
for (int y = sourceRectangle.Top; y < sourceRectangle.Bottom; y++)
{
gammaOperation.Invoke(y, gammaSpan);
}
}
else
{
ApplyGammaExposureRowOperation gammaOperation = new(sourceRectangle, source.PixelBuffer, this.Configuration, this.gamma);
ParallelRowIterator.IterateRows<ApplyGammaExposureRowOperation, Vector4>(
this.Configuration,
sourceRectangle,
in gammaOperation);
using IMemoryOwner<Vector4> gammaBuffer = allocator.Allocate<Vector4>(gammaOperation.GetRequiredBufferLength(sourceRectangle));
Span<Vector4> gammaSpan = gammaBuffer.Memory.Span;
for (int y = sourceRectangle.Top; y < sourceRectangle.Bottom; y++)
{
gammaOperation.Invoke(y, gammaSpan);
}
}
// Create a 0-filled buffer to use to store the result of the component convolutions
@ -105,18 +121,20 @@ internal class BokehBlurProcessor<TPixel> : ImageProcessor<TPixel>
if (this.gamma == 3F)
{
ApplyInverseGamma3ExposureRowOperation operation = new(sourceRectangle, source.PixelBuffer, processingBuffer, this.Configuration);
ParallelRowIterator.IterateRows(
this.Configuration,
sourceRectangle,
in operation);
for (int y = sourceRectangle.Top; y < sourceRectangle.Bottom; y++)
{
operation.Invoke(y);
}
}
else
{
ApplyInverseGammaExposureRowOperation operation = new(sourceRectangle, source.PixelBuffer, processingBuffer, this.Configuration, 1 / this.gamma);
ParallelRowIterator.IterateRows(
this.Configuration,
sourceRectangle,
in operation);
ApplyInverseGammaExposureRowOperation operation = new(sourceRectangle, source.PixelBuffer, processingBuffer, this.Configuration, this.gamma);
for (int y = sourceRectangle.Top; y < sourceRectangle.Bottom; y++)
{
operation.Invoke(y);
}
}
}
@ -169,10 +187,15 @@ internal class BokehBlurProcessor<TPixel> : ImageProcessor<TPixel>
kernel,
configuration);
ParallelRowIterator.IterateRows<FirstPassConvolutionRowOperation, Vector4>(
configuration,
sourceRectangle,
in horizontalOperation);
using (IMemoryOwner<Vector4> hBuffer = configuration.MemoryAllocator.Allocate<Vector4>(horizontalOperation.GetRequiredBufferLength(sourceRectangle)))
{
Span<Vector4> hSpan = hBuffer.Memory.Span;
for (int y = sourceRectangle.Top; y < sourceRectangle.Bottom; y++)
{
horizontalOperation.Invoke(y, hSpan);
}
}
// Vertical 1D convolutions to accumulate the partial results on the target buffer
BokehBlurProcessor.SecondPassConvolutionRowOperation verticalOperation = new(
@ -184,10 +207,10 @@ internal class BokehBlurProcessor<TPixel> : ImageProcessor<TPixel>
parameters.Z,
parameters.W);
ParallelRowIterator.IterateRows(
configuration,
sourceRectangle,
in verticalOperation);
for (int y = sourceRectangle.Top; y < sourceRectangle.Bottom; y++)
{
verticalOperation.Invoke(y);
}
}
}
@ -305,15 +328,9 @@ internal class BokehBlurProcessor<TPixel> : ImageProcessor<TPixel>
{
Span<TPixel> targetRowSpan = this.targetPixels.DangerousGetRowSpan(y)[this.bounds.X..];
PixelOperations<TPixel>.Instance.ToVector4(this.configuration, targetRowSpan[..span.Length], span, PixelConversionModifiers.Premultiply);
ref Vector4 baseRef = ref MemoryMarshal.GetReference(span);
for (int x = 0; x < this.bounds.Width; x++)
{
ref Vector4 v = ref Unsafe.Add(ref baseRef, (uint)x);
v.X = MathF.Pow(v.X, this.gamma);
v.Y = MathF.Pow(v.Y, this.gamma);
v.Z = MathF.Pow(v.Z, this.gamma);
}
// Input is premultiplied [0,1] so the LUT is safe here.
GammaCompanding.Expand(span[..this.bounds.Width], this.gamma);
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.configuration, span, targetRowSpan);
}
@ -367,7 +384,7 @@ internal class BokehBlurProcessor<TPixel> : ImageProcessor<TPixel>
private readonly Buffer2D<TPixel> targetPixels;
private readonly Buffer2D<Vector4> sourceValues;
private readonly Configuration configuration;
private readonly float inverseGamma;
private readonly float gamma;
[MethodImpl(InliningOptions.ShortMethod)]
public ApplyInverseGammaExposureRowOperation(
@ -375,36 +392,26 @@ internal class BokehBlurProcessor<TPixel> : ImageProcessor<TPixel>
Buffer2D<TPixel> targetPixels,
Buffer2D<Vector4> sourceValues,
Configuration configuration,
float inverseGamma)
float gamma)
{
this.bounds = bounds;
this.targetPixels = targetPixels;
this.sourceValues = sourceValues;
this.configuration = configuration;
this.inverseGamma = inverseGamma;
this.gamma = gamma;
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void Invoke(int y)
{
Vector4 low = Vector4.Zero;
Vector4 high = new(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
Span<TPixel> targetPixelSpan = this.targetPixels.DangerousGetRowSpan(y)[this.bounds.X..];
Span<Vector4> sourceRowSpan = this.sourceValues.DangerousGetRowSpan(y)[this.bounds.X..];
ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceRowSpan);
Span<Vector4> sourceRowSpan = this.sourceValues.DangerousGetRowSpan(y).Slice(this.bounds.X, this.bounds.Width);
for (int x = 0; x < this.bounds.Width; x++)
{
ref Vector4 v = ref Unsafe.Add(ref sourceRef, (uint)x);
Vector4 clamp = Numerics.Clamp(v, low, high);
v.X = MathF.Pow(clamp.X, this.inverseGamma);
v.Y = MathF.Pow(clamp.Y, this.inverseGamma);
v.Z = MathF.Pow(clamp.Z, this.inverseGamma);
}
Numerics.Clamp(MemoryMarshal.Cast<Vector4, float>(sourceRowSpan), 0, 1F);
GammaCompanding.Compress(sourceRowSpan, this.gamma);
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.configuration, sourceRowSpan[..this.bounds.Width], targetPixelSpan, PixelConversionModifiers.Premultiply);
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.configuration, sourceRowSpan, targetPixelSpan, PixelConversionModifiers.Premultiply);
}
}
@ -433,17 +440,16 @@ internal class BokehBlurProcessor<TPixel> : ImageProcessor<TPixel>
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public unsafe void Invoke(int y)
public void Invoke(int y)
{
Span<Vector4> sourceRowSpan = this.sourceValues.DangerousGetRowSpan(y).Slice(this.bounds.X, this.bounds.Width);
ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceRowSpan);
Numerics.Clamp(MemoryMarshal.Cast<Vector4, float>(sourceRowSpan), 0, float.PositiveInfinity);
Numerics.Clamp(MemoryMarshal.Cast<Vector4, float>(sourceRowSpan), 0, 1F);
Numerics.CubeRootOnXYZ(sourceRowSpan);
Span<TPixel> targetPixelSpan = this.targetPixels.DangerousGetRowSpan(y)[this.bounds.X..];
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.configuration, sourceRowSpan[..this.bounds.Width], targetPixelSpan, PixelConversionModifiers.Premultiply);
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.configuration, sourceRowSpan, targetPixelSpan, PixelConversionModifiers.Premultiply);
}
}
}

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

@ -1,8 +1,8 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers;
using System.Numerics;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
@ -79,10 +79,16 @@ internal class Convolution2DProcessor<TPixel> : ImageProcessor<TPixel>
this.Configuration,
this.PreserveAlpha);
ParallelRowIterator.IterateRows<Convolution2DRowOperation<TPixel>, Vector4>(
this.Configuration,
interest,
in operation);
// Convolution is memory-bandwidth-bound with low arithmetic intensity.
// Parallelization degrades performance due to cache line contention from
// overlapping source row reads. See #3111.
using IMemoryOwner<Vector4> buffer = allocator.Allocate<Vector4>(operation.GetRequiredBufferLength(interest));
Span<Vector4> span = buffer.Memory.Span;
for (int y = interest.Top; y < interest.Bottom; y++)
{
operation.Invoke(y, span);
}
}
Buffer2D<TPixel>.SwapOrCopyContent(source.PixelBuffer, targetPixels);

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

@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -106,6 +107,12 @@ internal class Convolution2PassProcessor<TPixel> : ImageProcessor<TPixel>
mapXY.BuildSamplingOffsetMap(this.KernelX.Length, this.KernelX.Length, interest, this.BorderWrapModeX, this.BorderWrapModeY);
MemoryAllocator allocator = this.Configuration.MemoryAllocator;
// Convolution is memory-bandwidth-bound with low arithmetic intensity.
// Parallelization degrades performance due to cache line contention from
// overlapping source row reads. See #3111.
// Horizontal convolution
HorizontalConvolutionRowOperation horizontalOperation = new(
interest,
@ -116,10 +123,15 @@ internal class Convolution2PassProcessor<TPixel> : ImageProcessor<TPixel>
this.Configuration,
this.PreserveAlpha);
ParallelRowIterator.IterateRows<HorizontalConvolutionRowOperation, Vector4>(
this.Configuration,
interest,
in horizontalOperation);
using (IMemoryOwner<Vector4> hBuffer = allocator.Allocate<Vector4>(horizontalOperation.GetRequiredBufferLength(interest)))
{
Span<Vector4> hSpan = hBuffer.Memory.Span;
for (int y = interest.Top; y < interest.Bottom; y++)
{
horizontalOperation.Invoke(y, hSpan);
}
}
// Vertical convolution
VerticalConvolutionRowOperation verticalOperation = new(
@ -131,10 +143,15 @@ internal class Convolution2PassProcessor<TPixel> : ImageProcessor<TPixel>
this.Configuration,
this.PreserveAlpha);
ParallelRowIterator.IterateRows<VerticalConvolutionRowOperation, Vector4>(
this.Configuration,
interest,
in verticalOperation);
using (IMemoryOwner<Vector4> vBuffer = allocator.Allocate<Vector4>(verticalOperation.GetRequiredBufferLength(interest)))
{
Span<Vector4> vSpan = vBuffer.Memory.Span;
for (int y = interest.Top; y < interest.Bottom; y++)
{
verticalOperation.Invoke(y, vSpan);
}
}
}
/// <summary>

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

@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -96,10 +97,17 @@ internal class ConvolutionProcessor<TPixel> : ImageProcessor<TPixel>
map.BuildSamplingOffsetMap(this.KernelXY.Rows, this.KernelXY.Columns, interest, this.BorderWrapModeX, this.BorderWrapModeY);
RowOperation operation = new(interest, targetPixels, source.PixelBuffer, map, this.KernelXY, this.Configuration, this.PreserveAlpha);
ParallelRowIterator.IterateRows<RowOperation, Vector4>(
this.Configuration,
interest,
in operation);
// Convolution is memory-bandwidth-bound with low arithmetic intensity.
// Parallelization degrades performance due to cache line contention from
// overlapping source row reads. See #3111.
using IMemoryOwner<Vector4> buffer = allocator.Allocate<Vector4>(operation.GetRequiredBufferLength(interest));
Span<Vector4> span = buffer.Memory.Span;
for (int y = interest.Top; y < interest.Bottom; y++)
{
operation.Invoke(y, span);
}
}
Buffer2D<TPixel>.SwapOrCopyContent(source.PixelBuffer, targetPixels);

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

@ -83,11 +83,15 @@ internal class EdgeDetectorCompassProcessor<TPixel> : ImageProcessor<TPixel>
processor.Apply(pass);
}
// Convolution is memory-bandwidth-bound with low arithmetic intensity.
// Parallelization degrades performance due to cache line contention from
// overlapping source row reads. See #3111.
RowOperation operation = new(source.PixelBuffer, pass.PixelBuffer, interest);
ParallelRowIterator.IterateRows(
this.Configuration,
interest,
in operation);
for (int y = interest.Top; y < interest.Bottom; y++)
{
operation.Invoke(y);
}
}
}

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_BikeGrayscale_R16_C1_G3.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b3a6e47d880b7276702e6bf4b1ba1b4781abfa2cd99ee9321a56169440fc318c
size 49844
oid sha256:0c047a274060b1bf73af9c922bff4f2ea627bd0fad023b3c3a5852f49d026c6b
size 50025

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_BikeGrayscale_R16_C2_G3.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:18b4837dceb9a065c5b27133b67ef257a0f050fa1342d02a7e06d3501e068f47
size 44966
oid sha256:aa1b0b58ddb6a5c29ccd78f1bc2e773a2005493b92efe5c0deb8056af6fc0208
size 45605

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_BikeGrayscale_R8_C1_G1.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e652706e1aec475c8eec08392d65be1bd888cc79eccc4019eb3826db71c6dac0
size 54744
oid sha256:ead63aaaf5b185342f83317c2400b7ada29a82223e35e9a7382f690101ae40f7
size 54798

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_Bike_R16_C1_G3.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ffc82427285a2bfeb3226e3e87ac316e41a2a8f853bb406b88ba2ae7bfae099d
size 164923
oid sha256:025751d22eeeac10878e79d2bf1987e0a055cf9f54903048673189a385036744
size 157237

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_Bike_R16_C2_G3.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2ea08065be7271e7ff75ed49e63544701bc14a03bd44d754fb056370559dd105
size 149483
oid sha256:77cae565842c0c8b0314d1c10c72f4b52483d002c614a33734b534f743d06b5d
size 146574

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_Bike_R8_C1_G1.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7a61bca9de7e0b6bf6f88c4d01b9e3f1611f6866db10e4a1168550ab84804f42
size 178531
oid sha256:223027dcd3a8e5ded5f98b3aa47b0e18bc40b569e47f6bfdab1126f4420e5977
size 171283

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_CalliphoraPartial_R16_C1_G3.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4e2f6c6c42ddd15c0730edcd402bf8fd05a1116cb72495e3156a545988ff0230
size 85901
oid sha256:db64cd4e0369fa2db33aa1f21a94466ca39a191b0e0adbbbfbcbca44284c61ab
size 86151

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_CalliphoraPartial_R16_C2_G3.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8193ce8690dbb99517cd56e5a866268c0a5c971c992058afb818393658781b91
size 77762
oid sha256:afc3a020178a68715ab0dafa30ee1db81630b760fde3df3271048acc627f178c
size 77614

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_CalliphoraPartial_R8_C1_G1.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:412c302f92500d855658d466aa1a686386ed998f6a3d5fe7326cd148a6f829ae
size 116229
oid sha256:5ea7e0c3e16acf40491354191278a09af2db5ac6e0e7b92ba377f8fc9d52e305
size 117067

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_Solid50x50_(255,0,0,255)_R16_C1_G3.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d753a7dc732d6f01f7bce8c6de50d70158639aa5e0eb18d168e417fe36492731
size 135
oid sha256:ba9b046556b04556632f4b651dc9d8ebc4d27699e53567179ef15a850567fee9
size 85

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_Solid50x50_(255,0,0,255)_R16_C2_G3.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d753a7dc732d6f01f7bce8c6de50d70158639aa5e0eb18d168e417fe36492731
size 135
oid sha256:ba9b046556b04556632f4b651dc9d8ebc4d27699e53567179ef15a850567fee9
size 85

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_Solid50x50_(255,0,0,255)_R8_C1_G1.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d753a7dc732d6f01f7bce8c6de50d70158639aa5e0eb18d168e417fe36492731
size 135
oid sha256:ba9b046556b04556632f4b651dc9d8ebc4d27699e53567179ef15a850567fee9
size 85

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern200x100_R16_C1_G3.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:570cb16b4026d38cbf586592c34d0fe303f2c1d99baeb531670c4ba25956f9c3
size 15489
oid sha256:20bb78a7539049ced92c936c2a78fdeb3809ffe0cb1dfae034e55e326de094a8
size 14285

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern200x100_R16_C2_G3.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:27813f975640c7ac15e78af910efc796ada950cd7efcd9a4fe045d531de24ec8
size 15197
oid sha256:a55e413991f9817ce9cecaf9d3ed31f5cd7559f9d527ff2e03c8bea5be091887
size 13943

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern200x100_R8_C1_G1.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e10a91175585b3843b25b710dc45f734ba706b60fc56a21748da355f27b8dcf5
size 12776
oid sha256:2afdab1f7f430c3f38fa7a6cdac60fbeb03ebcdda00a1bc79b289680a6811388
size 12056

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern23x31_R16_C1_G3.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6c0aca87ea94ec94c4d9e458dd33d366e0166533ee3e3c39066ee9d8be63a74e
size 1393
oid sha256:028cd8201f9e7cd4988d63cc80d9afc96d0c739c65d807f7c755947e49e65111
size 1326

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern23x31_R16_C2_G3.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9d486512f51a57c90de6c3126791fbd3b7e7dd756932b5bd716660ee9b72f010
size 1168
oid sha256:213e3bd008292b807e2a2ec216ec017a31cd165f4d2a8bc86b3deea3daffc81c
size 1109

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern23x31_R8_C1_G1.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:79f344abd9f1cfe6e8c2f0be52fd9498ee3ee6370cea94244d90fdaba7fa5e71
size 1488
oid sha256:2ceeb731111403f6354c460e403a30a2269ae1b2e2a9ef9b3819bdcadb50b859
size 1424

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern30x20_R16_C1_G3.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:90a45e7212ce97754be0e1432fffdc62ef5d2bdc30fdff0477a1951754cc0929
size 1113
oid sha256:fa9d77a2f1b727a42323a8ac19cb4cabdef0e7f0257bc92bb0100cd280f87613
size 1076

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern30x20_R16_C2_G3.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7c61766f05dc48413c21baea8af1994895aa354732109fd5701a42f746f1f412
size 1005
oid sha256:fc9986cd6042d8cad709a5768dc464fc171a3cb5d3457406c11c46ef55388daf
size 956

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_TestPattern30x20_R8_C1_G1.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:be002593c2874eab803d0dc9b5646fb51b94ea92e17158797609219f46c2f723
size 1518
oid sha256:7e92efee845abd30705bb9a9cf61997092fca89b48e20d8383a0c08ab159a0af
size 1491

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_cross_R16_C1_G3.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:11edba36c7f73271d9575b16cc7663a1e75c3b34560df51b7430cfde3ce1ea08
size 6576
oid sha256:21e8dce4256aecb250e0079c8bd60deb8b2ca55848fb0fd647ed3115afcf82af
size 8401

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_cross_R16_C2_G3.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:75320c25e8977e5d56ff32f054e15773bd797e4ba745cd7bf3a2fd4c7000e3df
size 6400
oid sha256:c4b1b7f904b23b6d7bd7b0fc4c533d3c213f38bcab689e9dac1936b05b71e9cf
size 8268

4
tests/Images/External/ReferenceOutput/BokehBlurTest/BokehBlurFilterProcessor_cross_R8_C1_G1.png

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8bb334d24245359fda8b64a74cbd30267cbdd1238e0aeae674b57be5371cd7db
size 6266
oid sha256:33ca697815ebf4c74343e0abc7a418af8ffdd8fa0830285770249a1f20929eae
size 8444

Loading…
Cancel
Save