Skip to content

Commit 30669dd

Browse files
authored
Merge branch 'master' into af/externalize-RentReturnRelease_SubsequentRentReturnsDifferentHandles
2 parents bbbf687 + a9e718c commit 30669dd

22 files changed

+222
-74
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public Buffer2DRegion(Buffer2D<T> buffer)
8888
/// <param name="y">The row index</param>
8989
/// <returns>The span</returns>
9090
[MethodImpl(MethodImplOptions.AggressiveInlining)]
91-
public Span<T> GetRowSpan(int y)
91+
public Span<T> DangerousGetRowSpan(int y)
9292
{
9393
int yy = this.Rectangle.Y + y;
9494
int xx = this.Rectangle.X;
@@ -152,7 +152,7 @@ internal void Clear()
152152

153153
for (int y = 0; y < this.Rectangle.Height; y++)
154154
{
155-
Span<T> row = this.GetRowSpan(y);
155+
Span<T> row = this.DangerousGetRowSpan(y);
156156
row.Clear();
157157
}
158158
}

src/ImageSharp/Processing/Processors/CloningImageProcessor{TPixel}.cs

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -46,38 +46,25 @@ protected CloningImageProcessor(Configuration configuration, Image<TPixel> sourc
4646
/// <inheritdoc/>
4747
Image<TPixel> ICloningImageProcessor<TPixel>.CloneAndExecute()
4848
{
49-
try
50-
{
51-
Image<TPixel> clone = this.CreateTarget();
52-
this.CheckFrameCount(this.Source, clone);
49+
Image<TPixel> clone = this.CreateTarget();
50+
this.CheckFrameCount(this.Source, clone);
5351

54-
Configuration configuration = this.Configuration;
55-
this.BeforeImageApply(clone);
52+
Configuration configuration = this.Configuration;
53+
this.BeforeImageApply(clone);
5654

57-
for (int i = 0; i < this.Source.Frames.Count; i++)
58-
{
59-
ImageFrame<TPixel> sourceFrame = this.Source.Frames[i];
60-
ImageFrame<TPixel> clonedFrame = clone.Frames[i];
55+
for (int i = 0; i < this.Source.Frames.Count; i++)
56+
{
57+
ImageFrame<TPixel> sourceFrame = this.Source.Frames[i];
58+
ImageFrame<TPixel> clonedFrame = clone.Frames[i];
6159

62-
this.BeforeFrameApply(sourceFrame, clonedFrame);
63-
this.OnFrameApply(sourceFrame, clonedFrame);
64-
this.AfterFrameApply(sourceFrame, clonedFrame);
65-
}
60+
this.BeforeFrameApply(sourceFrame, clonedFrame);
61+
this.OnFrameApply(sourceFrame, clonedFrame);
62+
this.AfterFrameApply(sourceFrame, clonedFrame);
63+
}
6664

67-
this.AfterImageApply(clone);
65+
this.AfterImageApply(clone);
6866

69-
return clone;
70-
}
71-
#if DEBUG
72-
catch (Exception)
73-
{
74-
throw;
75-
#else
76-
catch (Exception ex)
77-
{
78-
throw new ImageProcessingException($"An error occurred when processing the image using {this.GetType().Name}. See the inner exception for more detail.", ex);
79-
#endif
80-
}
67+
return clone;
8168
}
8269

8370
/// <inheritdoc/>

src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ public AffineTransformProcessor(Matrix3x2 matrix, IResampler sampler, Size targe
2121
Guard.NotNull(sampler, nameof(sampler));
2222
Guard.MustBeValueType(sampler, nameof(sampler));
2323

24+
if (TransformUtils.IsDegenerate(matrix))
25+
{
26+
throw new DegenerateTransformException("Matrix is degenerate. Check input values.");
27+
}
28+
2429
this.Sampler = sampler;
2530
this.TransformMatrix = matrix;
2631
this.DestinationSize = targetDimensions;

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

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,18 @@ public void ApplyTransform<TResampler>(in TResampler sampler)
6161
Matrix3x2 matrix = this.transformMatrix;
6262

6363
// Handle transforms that result in output identical to the original.
64-
if (matrix.Equals(default) || matrix.Equals(Matrix3x2.Identity))
64+
// Degenerate matrices are already handled in the upstream definition.
65+
if (matrix.Equals(Matrix3x2.Identity))
6566
{
6667
// The clone will be blank here copy all the pixel data over
67-
source.GetPixelMemoryGroup().CopyTo(destination.GetPixelMemoryGroup());
68+
var interest = Rectangle.Intersect(this.SourceRectangle, destination.Bounds());
69+
Buffer2DRegion<TPixel> sourceBuffer = source.PixelBuffer.GetRegion(interest);
70+
Buffer2DRegion<TPixel> destbuffer = destination.PixelBuffer.GetRegion(interest);
71+
for (int y = 0; y < sourceBuffer.Height; y++)
72+
{
73+
sourceBuffer.DangerousGetRowSpan(y).CopyTo(destbuffer.DangerousGetRowSpan(y));
74+
}
75+
6876
return;
6977
}
7078

@@ -73,7 +81,12 @@ public void ApplyTransform<TResampler>(in TResampler sampler)
7381

7482
if (sampler is NearestNeighborResampler)
7583
{
76-
var nnOperation = new NNAffineOperation(source.PixelBuffer, destination.PixelBuffer, matrix);
84+
var nnOperation = new NNAffineOperation(
85+
source.PixelBuffer,
86+
Rectangle.Intersect(this.SourceRectangle, source.Bounds()),
87+
destination.PixelBuffer,
88+
matrix);
89+
7790
ParallelRowIterator.IterateRows(
7891
configuration,
7992
destination.Bounds(),
@@ -85,6 +98,7 @@ public void ApplyTransform<TResampler>(in TResampler sampler)
8598
var operation = new AffineOperation<TResampler>(
8699
configuration,
87100
source.PixelBuffer,
101+
Rectangle.Intersect(this.SourceRectangle, source.Bounds()),
88102
destination.PixelBuffer,
89103
in sampler,
90104
matrix);
@@ -105,12 +119,13 @@ public void ApplyTransform<TResampler>(in TResampler sampler)
105119
[MethodImpl(InliningOptions.ShortMethod)]
106120
public NNAffineOperation(
107121
Buffer2D<TPixel> source,
122+
Rectangle bounds,
108123
Buffer2D<TPixel> destination,
109124
Matrix3x2 matrix)
110125
{
111126
this.source = source;
127+
this.bounds = bounds;
112128
this.destination = destination;
113-
this.bounds = source.Bounds();
114129
this.matrix = matrix;
115130
}
116131

@@ -138,6 +153,7 @@ public void Invoke(int y)
138153
{
139154
private readonly Configuration configuration;
140155
private readonly Buffer2D<TPixel> source;
156+
private readonly Rectangle bounds;
141157
private readonly Buffer2D<TPixel> destination;
142158
private readonly TResampler sampler;
143159
private readonly Matrix3x2 matrix;
@@ -148,12 +164,14 @@ public void Invoke(int y)
148164
public AffineOperation(
149165
Configuration configuration,
150166
Buffer2D<TPixel> source,
167+
Rectangle bounds,
151168
Buffer2D<TPixel> destination,
152169
in TResampler sampler,
153170
Matrix3x2 matrix)
154171
{
155172
this.configuration = configuration;
156173
this.source = source;
174+
this.bounds = bounds;
157175
this.destination = destination;
158176
this.sampler = sampler;
159177
this.matrix = matrix;
@@ -182,8 +200,10 @@ public void Invoke(in RowInterval rows, Span<Vector4> span)
182200
TResampler sampler = this.sampler;
183201
float yRadius = this.yRadius;
184202
float xRadius = this.xRadius;
185-
int maxY = this.source.Height - 1;
186-
int maxX = this.source.Width - 1;
203+
int minY = this.bounds.Y;
204+
int maxY = this.bounds.Bottom - 1;
205+
int minX = this.bounds.X;
206+
int maxX = this.bounds.Right - 1;
187207

188208
for (int y = rows.Min; y < rows.Max; y++)
189209
{
@@ -200,10 +220,10 @@ public void Invoke(in RowInterval rows, Span<Vector4> span)
200220
float pY = point.Y;
201221
float pX = point.X;
202222

203-
int top = LinearTransformUtility.GetRangeStart(yRadius, pY, maxY);
204-
int bottom = LinearTransformUtility.GetRangeEnd(yRadius, pY, maxY);
205-
int left = LinearTransformUtility.GetRangeStart(xRadius, pX, maxX);
206-
int right = LinearTransformUtility.GetRangeEnd(xRadius, pX, maxX);
223+
int top = LinearTransformUtility.GetRangeStart(yRadius, pY, minY, maxY);
224+
int bottom = LinearTransformUtility.GetRangeEnd(yRadius, pY, minY, maxY);
225+
int left = LinearTransformUtility.GetRangeStart(xRadius, pX, minX, maxX);
226+
int right = LinearTransformUtility.GetRangeEnd(xRadius, pX, minX, maxX);
207227

208228
if (bottom == top || right == left)
209229
{
@@ -245,8 +265,10 @@ private void InvokeMacOSX(in RowInterval rows, Span<Vector4> span)
245265
TResampler sampler = this.sampler;
246266
float yRadius = this.yRadius;
247267
float xRadius = this.xRadius;
248-
int maxY = this.source.Height - 1;
249-
int maxX = this.source.Width - 1;
268+
int minY = this.bounds.Y;
269+
int maxY = this.bounds.Bottom - 1;
270+
int minX = this.bounds.X;
271+
int maxX = this.bounds.Right - 1;
250272

251273
for (int y = rows.Min; y < rows.Max; y++)
252274
{
@@ -263,10 +285,10 @@ private void InvokeMacOSX(in RowInterval rows, Span<Vector4> span)
263285
float pY = point.Y;
264286
float pX = point.X;
265287

266-
int top = LinearTransformUtility.GetRangeStart(yRadius, pY, maxY);
267-
int bottom = LinearTransformUtility.GetRangeEnd(yRadius, pY, maxY);
268-
int left = LinearTransformUtility.GetRangeStart(xRadius, pX, maxX);
269-
int right = LinearTransformUtility.GetRangeEnd(xRadius, pX, maxX);
288+
int top = LinearTransformUtility.GetRangeStart(yRadius, pY, minY, maxY);
289+
int bottom = LinearTransformUtility.GetRangeEnd(yRadius, pY, minY, maxY);
290+
int left = LinearTransformUtility.GetRangeStart(xRadius, pX, minX, maxX);
291+
int right = LinearTransformUtility.GetRangeEnd(xRadius, pX, minX, maxX);
270292

271293
if (bottom == top || right == left)
272294
{

src/ImageSharp/Processing/Processors/Transforms/Linear/LinearTransformUtility.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,24 @@ public static float GetSamplingRadius<TResampler>(in TResampler sampler, int sou
3939
/// </summary>
4040
/// <param name="radius">The radius.</param>
4141
/// <param name="center">The center position.</param>
42+
/// <param name="min">The min allowed amouunt.</param>
4243
/// <param name="max">The max allowed amouunt.</param>
4344
/// <returns>The <see cref="int"/>.</returns>
4445
[MethodImpl(InliningOptions.ShortMethod)]
45-
public static int GetRangeStart(float radius, float center, int max)
46-
=> Numerics.Clamp((int)MathF.Ceiling(center - radius), 0, max);
46+
public static int GetRangeStart(float radius, float center, int min, int max)
47+
=> Numerics.Clamp((int)MathF.Ceiling(center - radius), min, max);
4748

4849
/// <summary>
4950
/// Gets the end position (inclusive) for a sampling range given
5051
/// the radius, center position and max constraint.
5152
/// </summary>
5253
/// <param name="radius">The radius.</param>
5354
/// <param name="center">The center position.</param>
55+
/// <param name="min">The min allowed amouunt.</param>
5456
/// <param name="max">The max allowed amouunt.</param>
5557
/// <returns>The <see cref="int"/>.</returns>
5658
[MethodImpl(InliningOptions.ShortMethod)]
57-
public static int GetRangeEnd(float radius, float center, int max)
58-
=> Numerics.Clamp((int)MathF.Floor(center + radius), 0, max);
59+
public static int GetRangeEnd(float radius, float center, int min, int max)
60+
=> Numerics.Clamp((int)MathF.Floor(center + radius), min, max);
5961
}
6062
}

src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ public ProjectiveTransformProcessor(Matrix4x4 matrix, IResampler sampler, Size t
2121
Guard.NotNull(sampler, nameof(sampler));
2222
Guard.MustBeValueType(sampler, nameof(sampler));
2323

24+
if (TransformUtils.IsDegenerate(matrix))
25+
{
26+
throw new DegenerateTransformException("Matrix is degenerate. Check input values.");
27+
}
28+
2429
this.Sampler = sampler;
2530
this.TransformMatrix = matrix;
2631
this.DestinationSize = targetDimensions;

0 commit comments

Comments
 (0)