@@ -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 {
0 commit comments