Skip to content

Commit 481481e

Browse files
Sergio0694JimBobSquarePants
authored andcommitted
Bokeh blur implementation (#842)
* Added base BokehBlurProcessor class, and kernel parameters * Added method to calculate the kernel parameters * Switched to float, added method to create the 1D kernels * Added complex kernels normalization * Added BokehBlurExtensions class * Added the Complex64 struct type * Switched to Complex64 in the BokehBlurProcessor * Added caching system for the bokeh processor parameters * Added WeightedSum method to the Complex64 type * Added IEquatable<T> interface to the Complex64 type * New complex types added * Added method to reshape a DenseMatrix<T> with no copies * Added bokeh convolution first pass (WIP) * Added second bokeh convolution pass (WIP) * Added image sum pass to the bokeh processor (WIP) * Minor bug fixes (WIP) * Switched to Vector4 processing in the bokeh computation * Minor tweaks * Added Unit test for the bokeh kernel components * Minor performance improvements * Minor code refactoring, added gamma parameter (WIP) * Removed unused temp buffers in the bokeh processing * Gamma highlight processing implemented * Speed optimizations, fixed partials computations in target rectangle * Increased epsilon value in the unit tests * Fixed for alpha transparency blur * Fixed a bug when only blurring a target rectangle * Added bokeh blur image tests (WIP) * Added IXunitSerializable interface to the test info class * culture independent parsing in BokehBlurTest.cs * Performance optimizations in the bokeh processor * Reduced number of memory allocations, fixed bug with multiple components * Initialization and other speed improvements * More initialization speed improvements * Replaced LINQ with manual loop * Added BokehBlur overload to just specify the target bounds * Speed optimizations to the bokeh 1D convolutions * More speed optimizations to the bokeh processor * Fixed code style and Complex64.ToString method * Fixed processing buffer initialization * Minor performance improvements * FIxed issue when applying bokeh blur to specific bounds * Minor speed optimizaations * Minor code refactoring * Fixed convolution upper bound in second 1D pass * improve BokehBlurTest coverage * use Gray8 instead of Alpha8 * Adjusted guard position in bokeh processor constructor * Added BokehBlurParameters struct * Added BokehBlurKernelData struct * Minor code refactoring * Fixed API change build errors * Bug fixes with the pixel premultiplication steps * Removed unwanted unpremultiplication pass * Removed unused using directives * Fixed missing using directives in conditional branches * Update from latest upstream master * Update Block8x8F.Generated.cs * Update GenericBlock8x8.Generated.cs * Manual checking for files with LF (see gitter) * Removed unused using directive * Added IEquatable<ComplexVector4> interface * Added IEquatable<BokehBlurParameters> interface * Moved bokeh blur parameters types * Added reference to original source code * Complex convolution methods moved to another class * Switched to MathF in the bokeh blur processor * Switched to Vector4.Clamp * Added Buffer2D<T>.Slice API * Added BokehBlurExecutionMode enum * Added new bokeh blur processor constructors * Added new bokeh blur extension overloads with execution mode * Code refactoring in preparation for the execution mode switch * Implemented execution mode switch in the bokeh processor * Moved BokehBlurExecutionMode struct * Removed unused using directives * Minor code refactoring * More minor code refactoring * Update External * Fix undisposed buffers * Bokeh blur processor cache switched to concurrent dictionary * Minor code refactoring
1 parent 3f3b7ab commit 481481e

File tree

68 files changed

+1382
-98
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+1382
-98
lines changed

src/ImageSharp/Color/Color.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// Licensed under the Apache License, Version 2.0.
33

44
using System;
5-
using System.Buffers.Binary;
6-
using System.Globalization;
75
using System.Numerics;
86
using System.Runtime.CompilerServices;
97
using System.Runtime.InteropServices;
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Copyright (c) Six Labors and contributors.
2+
// Licensed under the Apache License, Version 2.0.
3+
4+
using System;
5+
using System.Runtime.CompilerServices;
6+
using System.Runtime.InteropServices;
7+
8+
using SixLabors.ImageSharp.Memory;
9+
using SixLabors.ImageSharp.PixelFormats;
10+
using SixLabors.ImageSharp.Primitives;
11+
12+
namespace SixLabors.ImageSharp
13+
{
14+
/// <summary>
15+
/// Extension methods for <see cref="Buffer2D{T}"/>.
16+
/// TODO: One day rewrite all this to use SIMD intrinsics. There's a lot of scope for improvement.
17+
/// </summary>
18+
internal static class Buffer2DUtils
19+
{
20+
/// <summary>
21+
/// Computes the sum of vectors in <paramref name="targetRow"/> weighted by the kernel weight values.
22+
/// </summary>
23+
/// <typeparam name="TPixel">The pixel format.</typeparam>
24+
/// <param name="kernel">The 1D convolution kernel.</param>
25+
/// <param name="sourcePixels">The source frame.</param>
26+
/// <param name="targetRow">The target row.</param>
27+
/// <param name="row">The current row.</param>
28+
/// <param name="column">The current column.</param>
29+
/// <param name="minRow">The minimum working area row.</param>
30+
/// <param name="maxRow">The maximum working area row.</param>
31+
/// <param name="minColumn">The minimum working area column.</param>
32+
/// <param name="maxColumn">The maximum working area column.</param>
33+
public static void Convolve4<TPixel>(
34+
Span<Complex64> kernel,
35+
Buffer2D<TPixel> sourcePixels,
36+
Span<ComplexVector4> targetRow,
37+
int row,
38+
int column,
39+
int minRow,
40+
int maxRow,
41+
int minColumn,
42+
int maxColumn)
43+
where TPixel : struct, IPixel<TPixel>
44+
{
45+
ComplexVector4 vector = default;
46+
int kernelLength = kernel.Length;
47+
int radiusY = kernelLength >> 1;
48+
int sourceOffsetColumnBase = column + minColumn;
49+
ref Complex64 baseRef = ref MemoryMarshal.GetReference(kernel);
50+
51+
for (int i = 0; i < kernelLength; i++)
52+
{
53+
int offsetY = (row + i - radiusY).Clamp(minRow, maxRow);
54+
int offsetX = sourceOffsetColumnBase.Clamp(minColumn, maxColumn);
55+
Span<TPixel> sourceRowSpan = sourcePixels.GetRowSpan(offsetY);
56+
var currentColor = sourceRowSpan[offsetX].ToVector4();
57+
58+
vector.Sum(Unsafe.Add(ref baseRef, i) * currentColor);
59+
}
60+
61+
targetRow[column] = vector;
62+
}
63+
64+
/// <summary>
65+
/// Computes the sum of vectors in <paramref name="targetRow"/> weighted by the kernel weight values.
66+
/// </summary>
67+
/// <param name="kernel">The 1D convolution kernel.</param>
68+
/// <param name="sourceValues">The source frame.</param>
69+
/// <param name="targetRow">The target row.</param>
70+
/// <param name="row">The current row.</param>
71+
/// <param name="column">The current column.</param>
72+
/// <param name="minRow">The minimum working area row.</param>
73+
/// <param name="maxRow">The maximum working area row.</param>
74+
/// <param name="minColumn">The minimum working area column.</param>
75+
/// <param name="maxColumn">The maximum working area column.</param>
76+
public static void Convolve4(
77+
Span<Complex64> kernel,
78+
Buffer2D<ComplexVector4> sourceValues,
79+
Span<ComplexVector4> targetRow,
80+
int row,
81+
int column,
82+
int minRow,
83+
int maxRow,
84+
int minColumn,
85+
int maxColumn)
86+
{
87+
ComplexVector4 vector = default;
88+
int kernelLength = kernel.Length;
89+
int radiusX = kernelLength >> 1;
90+
int sourceOffsetColumnBase = column + minColumn;
91+
92+
int offsetY = row.Clamp(minRow, maxRow);
93+
ref ComplexVector4 sourceRef = ref MemoryMarshal.GetReference(sourceValues.GetRowSpan(offsetY));
94+
ref Complex64 baseRef = ref MemoryMarshal.GetReference(kernel);
95+
96+
for (int x = 0; x < kernelLength; x++)
97+
{
98+
int offsetX = (sourceOffsetColumnBase + x - radiusX).Clamp(minColumn, maxColumn);
99+
vector.Sum(Unsafe.Add(ref baseRef, x) * Unsafe.Add(ref sourceRef, offsetX));
100+
}
101+
102+
targetRow[column] = vector;
103+
}
104+
}
105+
}

src/ImageSharp/Common/Helpers/DenseMatrixUtils.cs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Six Labors and contributors.
1+
// Copyright (c) Six Labors and contributors.
22
// Licensed under the Apache License, Version 2.0.
33

44
using System;
@@ -45,8 +45,6 @@ public static void Convolve2D3<TPixel>(
4545
int maxColumn)
4646
where TPixel : struct, IPixel<TPixel>
4747
{
48-
Vector4 vector = default;
49-
5048
Convolve2DImpl(
5149
in matrixY,
5250
in matrixX,
@@ -57,7 +55,7 @@ public static void Convolve2D3<TPixel>(
5755
maxRow,
5856
minColumn,
5957
maxColumn,
60-
ref vector);
58+
out Vector4 vector);
6159

6260
ref Vector4 target = ref Unsafe.Add(ref targetRowRef, column);
6361
vector.W = target.W;
@@ -95,8 +93,6 @@ public static void Convolve2D4<TPixel>(
9593
int maxColumn)
9694
where TPixel : struct, IPixel<TPixel>
9795
{
98-
Vector4 vector = default;
99-
10096
Convolve2DImpl(
10197
in matrixY,
10298
in matrixX,
@@ -107,7 +103,7 @@ public static void Convolve2D4<TPixel>(
107103
maxRow,
108104
minColumn,
109105
maxColumn,
110-
ref vector);
106+
out Vector4 vector);
111107

112108
ref Vector4 target = ref Unsafe.Add(ref targetRowRef, column);
113109
Vector4Utils.UnPremultiply(ref vector);
@@ -125,7 +121,7 @@ public static void Convolve2DImpl<TPixel>(
125121
int maxRow,
126122
int minColumn,
127123
int maxColumn,
128-
ref Vector4 vector)
124+
out Vector4 vector)
129125
where TPixel : struct, IPixel<TPixel>
130126
{
131127
Vector4 vectorY = default;
@@ -281,4 +277,4 @@ private static void ConvolveImpl<TPixel>(
281277
}
282278
}
283279
}
284-
}
280+
}

src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the Apache License, Version 2.0.
33

44
using System;
5-
using System.Diagnostics;
65
using System.Numerics;
76
using System.Runtime.CompilerServices;
87
using System.Runtime.InteropServices;

src/ImageSharp/Common/Helpers/SimdUtils.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77
using System.Runtime.CompilerServices;
88
using System.Runtime.InteropServices;
99

10-
using SixLabors.ImageSharp.PixelFormats;
11-
using SixLabors.ImageSharp.Tuples;
12-
1310
namespace SixLabors.ImageSharp
1411
{
1512
/// <summary>

src/ImageSharp/Formats/Jpeg/Components/Decoder/IRawJpegData.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the Apache License, Version 2.0.
33

44
using System;
5-
using System.Collections.Generic;
65

76
using SixLabors.Primitives;
87

src/ImageSharp/Formats/Jpeg/Components/Encoder/YCbCrForwardConverter{TPixel}.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System;
55
using System.Runtime.CompilerServices;
66

7-
using SixLabors.ImageSharp.Advanced;
87
using SixLabors.ImageSharp.PixelFormats;
98

109
namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder

src/ImageSharp/Formats/Jpeg/Components/GenericBlock8x8.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
using SixLabors.ImageSharp.Advanced;
88
using SixLabors.ImageSharp.Memory;
99
using SixLabors.ImageSharp.PixelFormats;
10-
using SixLabors.Memory;
1110

1211
// ReSharper disable InconsistentNaming
1312
namespace SixLabors.ImageSharp.Formats.Jpeg.Components

src/ImageSharp/Memory/Buffer2DExtensions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the Apache License, Version 2.0.
33

44
using System;
5-
using System.Buffers;
65
using System.Diagnostics;
76
using System.Runtime.CompilerServices;
87
using System.Runtime.InteropServices;

src/ImageSharp/Memory/Buffer2D{T}.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,31 @@ public Buffer2D(MemorySource<T> memorySource, int width, int height)
6161
[MethodImpl(MethodImplOptions.AggressiveInlining)]
6262
get
6363
{
64-
ImageSharp.DebugGuard.MustBeLessThan(x, this.Width, nameof(x));
65-
ImageSharp.DebugGuard.MustBeLessThan(y, this.Height, nameof(y));
64+
DebugGuard.MustBeLessThan(x, this.Width, nameof(x));
65+
DebugGuard.MustBeLessThan(y, this.Height, nameof(y));
66+
6667
Span<T> span = this.Span;
6768
return ref span[(this.Width * y) + x];
6869
}
6970
}
7071

72+
/// <summary>
73+
/// Creates a new <see cref="Buffer2D{T}"/> instance that maps to a target rows interval from the current instance.
74+
/// </summary>
75+
/// <param name="y">The target vertical offset for the rows interval to retrieve.</param>
76+
/// <param name="h">The desired number of rows to extract.</param>
77+
/// <returns>The new <see cref="Buffer2D{T}"/> instance with the requested rows interval.</returns>
78+
public Buffer2D<T> Slice(int y, int h)
79+
{
80+
DebugGuard.MustBeGreaterThanOrEqualTo(y, 0, nameof(y));
81+
DebugGuard.MustBeGreaterThan(h, 0, nameof(h));
82+
DebugGuard.MustBeLessThanOrEqualTo(y + h, this.Height, nameof(h));
83+
84+
Memory<T> slice = this.Memory.Slice(y * this.Width, h * this.Width);
85+
var memory = new MemorySource<T>(slice);
86+
return new Buffer2D<T>(memory, this.Width, h);
87+
}
88+
7189
/// <summary>
7290
/// Disposes the <see cref="Buffer2D{T}"/> instance
7391
/// </summary>
@@ -98,4 +116,4 @@ private static void SwapDimensionData(Buffer2D<T> a, Buffer2D<T> b)
98116
a.Height = bSize.Height;
99117
}
100118
}
101-
}
119+
}

0 commit comments

Comments
 (0)