|
|
@ -10,6 +10,7 @@ using System.Runtime.InteropServices; |
|
|
using System.Threading.Tasks; |
|
|
using System.Threading.Tasks; |
|
|
using SixLabors.ImageSharp.Advanced; |
|
|
using SixLabors.ImageSharp.Advanced; |
|
|
using SixLabors.ImageSharp.Memory; |
|
|
using SixLabors.ImageSharp.Memory; |
|
|
|
|
|
using SixLabors.ImageSharp.ParallelUtils; |
|
|
using SixLabors.ImageSharp.PixelFormats; |
|
|
using SixLabors.ImageSharp.PixelFormats; |
|
|
using SixLabors.Memory; |
|
|
using SixLabors.Memory; |
|
|
using SixLabors.Primitives; |
|
|
using SixLabors.Primitives; |
|
|
@ -75,11 +76,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms |
|
|
|
|
|
|
|
|
if (this.Sampler is NearestNeighborResampler) |
|
|
if (this.Sampler is NearestNeighborResampler) |
|
|
{ |
|
|
{ |
|
|
ParallelFor.WithConfiguration( |
|
|
ParallelHelper.IterateRows( |
|
|
0, |
|
|
targetBounds, |
|
|
height, |
|
|
|
|
|
configuration, |
|
|
configuration, |
|
|
y => |
|
|
rows => |
|
|
|
|
|
{ |
|
|
|
|
|
for (int y = rows.Min; y < rows.Max; y++) |
|
|
{ |
|
|
{ |
|
|
Span<TPixel> destRow = destination.GetPixelRowSpan(y); |
|
|
Span<TPixel> destRow = destination.GetPixelRowSpan(y); |
|
|
|
|
|
|
|
|
@ -96,6 +98,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms |
|
|
destRow[x] = source[px, py]; |
|
|
destRow[x] = source[px, py]; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
return; |
|
|
return; |
|
|
@ -121,11 +124,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms |
|
|
using (Buffer2D<float> yBuffer = memoryAllocator.Allocate2D<float>(yLength, height)) |
|
|
using (Buffer2D<float> yBuffer = memoryAllocator.Allocate2D<float>(yLength, height)) |
|
|
using (Buffer2D<float> xBuffer = memoryAllocator.Allocate2D<float>(xLength, height)) |
|
|
using (Buffer2D<float> xBuffer = memoryAllocator.Allocate2D<float>(xLength, height)) |
|
|
{ |
|
|
{ |
|
|
ParallelFor.WithConfiguration( |
|
|
ParallelHelper.IterateRows( |
|
|
0, |
|
|
targetBounds, |
|
|
height, |
|
|
|
|
|
configuration, |
|
|
configuration, |
|
|
y => |
|
|
rows => |
|
|
|
|
|
{ |
|
|
|
|
|
for (int y = rows.Min; y < rows.Max; y++) |
|
|
{ |
|
|
{ |
|
|
ref TPixel destRowRef = ref MemoryMarshal.GetReference(destination.GetPixelRowSpan(y)); |
|
|
ref TPixel destRowRef = ref MemoryMarshal.GetReference(destination.GetPixelRowSpan(y)); |
|
|
ref float ySpanRef = ref MemoryMarshal.GetReference(yBuffer.GetRowSpan(y)); |
|
|
ref float ySpanRef = ref MemoryMarshal.GetReference(yBuffer.GetRowSpan(y)); |
|
|
@ -175,8 +179,27 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms |
|
|
// I've optimized where I can but am always open to suggestions.
|
|
|
// I've optimized where I can but am always open to suggestions.
|
|
|
if (yScale > 1 && xScale > 1) |
|
|
if (yScale > 1 && xScale > 1) |
|
|
{ |
|
|
{ |
|
|
CalculateWeightsDown(top, bottom, minY, maxY, point.Y, sampler, yScale, ref ySpanRef, yLength); |
|
|
CalculateWeightsDown( |
|
|
CalculateWeightsDown(left, right, minX, maxX, point.X, sampler, xScale, ref xSpanRef, xLength); |
|
|
top, |
|
|
|
|
|
bottom, |
|
|
|
|
|
minY, |
|
|
|
|
|
maxY, |
|
|
|
|
|
point.Y, |
|
|
|
|
|
sampler, |
|
|
|
|
|
yScale, |
|
|
|
|
|
ref ySpanRef, |
|
|
|
|
|
yLength); |
|
|
|
|
|
|
|
|
|
|
|
CalculateWeightsDown( |
|
|
|
|
|
left, |
|
|
|
|
|
right, |
|
|
|
|
|
minX, |
|
|
|
|
|
maxX, |
|
|
|
|
|
point.X, |
|
|
|
|
|
sampler, |
|
|
|
|
|
xScale, |
|
|
|
|
|
ref xSpanRef, |
|
|
|
|
|
xLength); |
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
@ -206,6 +229,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms |
|
|
// Reverse the premultiplication
|
|
|
// Reverse the premultiplication
|
|
|
dest.PackFromVector4(sum.UnPremultiply()); |
|
|
dest.PackFromVector4(sum.UnPremultiply()); |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|