Skip to content

Commit 3d86c58

Browse files
Refactor and fix for transform space
1 parent c51d84d commit 3d86c58

13 files changed

+184
-172
lines changed

src/ImageSharp/Common/Helpers/QuadDistortionHelper.cs

Lines changed: 0 additions & 79 deletions
This file was deleted.

src/ImageSharp/Processing/AffineTransformBuilder.cs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.Processing;
1111
/// </summary>
1212
public class AffineTransformBuilder
1313
{
14-
private readonly List<Func<Size, Matrix3x2>> transformMatrixFactories = new();
14+
private readonly List<Func<Size, Matrix3x2>> transformMatrixFactories = [];
1515

1616
/// <summary>
1717
/// Initializes a new instance of the <see cref="AffineTransformBuilder"/> class.
@@ -301,7 +301,8 @@ public AffineTransformBuilder AppendMatrix(Matrix3x2 matrix)
301301
/// </summary>
302302
/// <param name="sourceSize">The source image size.</param>
303303
/// <returns>The <see cref="Matrix3x2"/>.</returns>
304-
public Matrix3x2 BuildMatrix(Size sourceSize) => this.BuildMatrix(new Rectangle(Point.Empty, sourceSize));
304+
public Matrix3x2 BuildMatrix(Size sourceSize)
305+
=> this.BuildMatrix(new Rectangle(Point.Empty, sourceSize));
305306

306307
/// <summary>
307308
/// Returns the combined transform matrix for a given source rectangle.
@@ -345,18 +346,8 @@ public Matrix3x2 BuildMatrix(Rectangle sourceRectangle)
345346
/// <returns>The <see cref="Size"/>.</returns>
346347
public Size GetTransformedSize(Rectangle sourceRectangle)
347348
{
348-
Size size = sourceRectangle.Size;
349-
350-
// Translate the origin matrix to cater for source rectangle offsets.
351-
Matrix3x2 matrix = Matrix3x2.CreateTranslation(-sourceRectangle.Location);
352-
353-
foreach (Func<Size, Matrix3x2> factory in this.transformMatrixFactories)
354-
{
355-
matrix *= factory(size);
356-
CheckDegenerate(matrix);
357-
}
358-
359-
return TransformUtils.GetTransformedSize(matrix, size, this.TransformSpace);
349+
Matrix3x2 matrix = this.BuildMatrix(sourceRectangle);
350+
return TransformUtils.GetTransformedSize(matrix, sourceRectangle.Size, this.TransformSpace);
360351
}
361352

362353
private static void CheckDegenerate(Matrix3x2 matrix)

src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor{TPixel}.cs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,12 @@ public void ApplyTransform<TResampler>(in TResampler sampler)
6161
if (matrix.Equals(Matrix3x2.Identity))
6262
{
6363
// The clone will be blank here copy all the pixel data over
64-
var interest = Rectangle.Intersect(this.SourceRectangle, destination.Bounds());
64+
Rectangle interest = Rectangle.Intersect(this.SourceRectangle, destination.Bounds());
6565
Buffer2DRegion<TPixel> sourceBuffer = source.PixelBuffer.GetRegion(interest);
66-
Buffer2DRegion<TPixel> destbuffer = destination.PixelBuffer.GetRegion(interest);
66+
Buffer2DRegion<TPixel> destinationBuffer = destination.PixelBuffer.GetRegion(interest);
6767
for (int y = 0; y < sourceBuffer.Height; y++)
6868
{
69-
sourceBuffer.DangerousGetRowSpan(y).CopyTo(destbuffer.DangerousGetRowSpan(y));
69+
sourceBuffer.DangerousGetRowSpan(y).CopyTo(destinationBuffer.DangerousGetRowSpan(y));
7070
}
7171

7272
return;
@@ -77,7 +77,7 @@ public void ApplyTransform<TResampler>(in TResampler sampler)
7777

7878
if (sampler is NearestNeighborResampler)
7979
{
80-
var nnOperation = new NNAffineOperation(
80+
NNAffineOperation nnOperation = new(
8181
source.PixelBuffer,
8282
Rectangle.Intersect(this.SourceRectangle, source.Bounds()),
8383
destination.PixelBuffer,
@@ -91,7 +91,7 @@ public void ApplyTransform<TResampler>(in TResampler sampler)
9191
return;
9292
}
9393

94-
var operation = new AffineOperation<TResampler>(
94+
AffineOperation<TResampler> operation = new(
9595
configuration,
9696
source.PixelBuffer,
9797
Rectangle.Intersect(this.SourceRectangle, source.Bounds()),
@@ -128,17 +128,17 @@ public NNAffineOperation(
128128
[MethodImpl(InliningOptions.ShortMethod)]
129129
public void Invoke(int y)
130130
{
131-
Span<TPixel> destRow = this.destination.DangerousGetRowSpan(y);
131+
Span<TPixel> destinationRowSpan = this.destination.DangerousGetRowSpan(y);
132132

133-
for (int x = 0; x < destRow.Length; x++)
133+
for (int x = 0; x < destinationRowSpan.Length; x++)
134134
{
135-
var point = Vector2.Transform(new Vector2(x, y), this.matrix);
135+
Vector2 point = Vector2.Transform(new Vector2(x, y), this.matrix);
136136
int px = (int)MathF.Round(point.X);
137137
int py = (int)MathF.Round(point.Y);
138138

139139
if (this.bounds.Contains(px, py))
140140
{
141-
destRow[x] = this.source.GetElementUnsafe(px, py);
141+
destinationRowSpan[x] = this.source.GetElementUnsafe(px, py);
142142
}
143143
}
144144
}
@@ -195,16 +195,16 @@ public void Invoke(in RowInterval rows, Span<Vector4> span)
195195

196196
for (int y = rows.Min; y < rows.Max; y++)
197197
{
198-
Span<TPixel> rowSpan = this.destination.DangerousGetRowSpan(y);
198+
Span<TPixel> destinationRowSpan = this.destination.DangerousGetRowSpan(y);
199199
PixelOperations<TPixel>.Instance.ToVector4(
200200
this.configuration,
201-
rowSpan,
201+
destinationRowSpan,
202202
span,
203203
PixelConversionModifiers.Scale);
204204

205205
for (int x = 0; x < span.Length; x++)
206206
{
207-
var point = Vector2.Transform(new Vector2(x, y), matrix);
207+
Vector2 point = Vector2.Transform(new Vector2(x, y), matrix);
208208
float pY = point.Y;
209209
float pX = point.X;
210210

@@ -221,13 +221,14 @@ public void Invoke(in RowInterval rows, Span<Vector4> span)
221221
Vector4 sum = Vector4.Zero;
222222
for (int yK = top; yK <= bottom; yK++)
223223
{
224+
Span<TPixel> sourceRowSpan = this.source.DangerousGetRowSpan(yK);
224225
float yWeight = sampler.GetValue(yK - pY);
225226

226227
for (int xK = left; xK <= right; xK++)
227228
{
228229
float xWeight = sampler.GetValue(xK - pX);
229230

230-
Vector4 current = this.source.GetElementUnsafe(xK, yK).ToScaledVector4();
231+
Vector4 current = sourceRowSpan[xK].ToScaledVector4();
231232
Numerics.Premultiply(ref current);
232233
sum += current * xWeight * yWeight;
233234
}
@@ -240,7 +241,7 @@ public void Invoke(in RowInterval rows, Span<Vector4> span)
240241
PixelOperations<TPixel>.Instance.FromVector4Destructive(
241242
this.configuration,
242243
span,
243-
rowSpan,
244+
destinationRowSpan,
244245
PixelConversionModifiers.Scale);
245246
}
246247
}

src/ImageSharp/Common/Helpers/GaussianEliminationSolver.cs renamed to src/ImageSharp/Processing/Processors/Transforms/Linear/GaussianEliminationSolver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
33

4-
namespace SixLabors.ImageSharp.Common.Helpers;
4+
namespace SixLabors.ImageSharp.Processing.Processors.Transforms.Linear;
55

66
/// <summary>
77
/// Represents a solver for systems of linear equations using the Gaussian Elimination method.

src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor{TPixel}.cs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,12 @@ public void ApplyTransform<TResampler>(in TResampler sampler)
6161
if (matrix.Equals(Matrix4x4.Identity))
6262
{
6363
// The clone will be blank here copy all the pixel data over
64-
var interest = Rectangle.Intersect(this.SourceRectangle, destination.Bounds());
64+
Rectangle interest = Rectangle.Intersect(this.SourceRectangle, destination.Bounds());
6565
Buffer2DRegion<TPixel> sourceBuffer = source.PixelBuffer.GetRegion(interest);
66-
Buffer2DRegion<TPixel> destbuffer = destination.PixelBuffer.GetRegion(interest);
66+
Buffer2DRegion<TPixel> destinationBuffer = destination.PixelBuffer.GetRegion(interest);
6767
for (int y = 0; y < sourceBuffer.Height; y++)
6868
{
69-
sourceBuffer.DangerousGetRowSpan(y).CopyTo(destbuffer.DangerousGetRowSpan(y));
69+
sourceBuffer.DangerousGetRowSpan(y).CopyTo(destinationBuffer.DangerousGetRowSpan(y));
7070
}
7171

7272
return;
@@ -77,7 +77,7 @@ public void ApplyTransform<TResampler>(in TResampler sampler)
7777

7878
if (sampler is NearestNeighborResampler)
7979
{
80-
var nnOperation = new NNProjectiveOperation(
80+
NNProjectiveOperation nnOperation = new(
8181
source.PixelBuffer,
8282
Rectangle.Intersect(this.SourceRectangle, source.Bounds()),
8383
destination.PixelBuffer,
@@ -91,7 +91,7 @@ public void ApplyTransform<TResampler>(in TResampler sampler)
9191
return;
9292
}
9393

94-
var operation = new ProjectiveOperation<TResampler>(
94+
ProjectiveOperation<TResampler> operation = new(
9595
configuration,
9696
source.PixelBuffer,
9797
Rectangle.Intersect(this.SourceRectangle, source.Bounds()),
@@ -128,17 +128,17 @@ public NNProjectiveOperation(
128128
[MethodImpl(InliningOptions.ShortMethod)]
129129
public void Invoke(int y)
130130
{
131-
Span<TPixel> destRow = this.destination.DangerousGetRowSpan(y);
131+
Span<TPixel> destinationRowSpan = this.destination.DangerousGetRowSpan(y);
132132

133-
for (int x = 0; x < destRow.Length; x++)
133+
for (int x = 0; x < destinationRowSpan.Length; x++)
134134
{
135135
Vector2 point = TransformUtils.ProjectiveTransform2D(x, y, this.matrix);
136136
int px = (int)MathF.Round(point.X);
137137
int py = (int)MathF.Round(point.Y);
138138

139139
if (this.bounds.Contains(px, py))
140140
{
141-
destRow[x] = this.source.GetElementUnsafe(px, py);
141+
destinationRowSpan[x] = this.source.GetElementUnsafe(px, py);
142142
}
143143
}
144144
}
@@ -195,10 +195,10 @@ public void Invoke(in RowInterval rows, Span<Vector4> span)
195195

196196
for (int y = rows.Min; y < rows.Max; y++)
197197
{
198-
Span<TPixel> rowSpan = this.destination.DangerousGetRowSpan(y);
198+
Span<TPixel> destinationRowSpan = this.destination.DangerousGetRowSpan(y);
199199
PixelOperations<TPixel>.Instance.ToVector4(
200200
this.configuration,
201-
rowSpan,
201+
destinationRowSpan,
202202
span,
203203
PixelConversionModifiers.Scale);
204204

@@ -221,13 +221,14 @@ public void Invoke(in RowInterval rows, Span<Vector4> span)
221221
Vector4 sum = Vector4.Zero;
222222
for (int yK = top; yK <= bottom; yK++)
223223
{
224+
Span<TPixel> sourceRowSpan = this.source.DangerousGetRowSpan(yK);
224225
float yWeight = sampler.GetValue(yK - pY);
225226

226227
for (int xK = left; xK <= right; xK++)
227228
{
228229
float xWeight = sampler.GetValue(xK - pX);
229230

230-
Vector4 current = this.source.GetElementUnsafe(xK, yK).ToScaledVector4();
231+
Vector4 current = sourceRowSpan[xK].ToScaledVector4();
231232
Numerics.Premultiply(ref current);
232233
sum += current * xWeight * yWeight;
233234
}
@@ -240,7 +241,7 @@ public void Invoke(in RowInterval rows, Span<Vector4> span)
240241
PixelOperations<TPixel>.Instance.FromVector4Destructive(
241242
this.configuration,
242243
span,
243-
rowSpan,
244+
destinationRowSpan,
244245
PixelConversionModifiers.Scale);
245246
}
246247
}

0 commit comments

Comments
 (0)