Browse Source

ParallelHelper -> ResizeProcessor

pull/710/head
Anton Firszov 7 years ago
parent
commit
196c8a1a6d
  1. 148
      src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs

148
src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs

@ -11,6 +11,7 @@ using System.Runtime.InteropServices;
using System.Threading.Tasks;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.ParallelUtils;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Memory;
using SixLabors.Primitives;
@ -267,26 +268,31 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
if (this.Sampler is NearestNeighborResampler)
{
var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY);
// Scaling factors
float widthFactor = sourceRectangle.Width / (float)this.ResizeRectangle.Width;
float heightFactor = sourceRectangle.Height / (float)this.ResizeRectangle.Height;
ParallelFor.WithConfiguration(
minY,
maxY,
ParallelHelper.IterateRows(
workingRect,
configuration,
y =>
{
// Y coordinates of source points
Span<TPixel> sourceRow = source.GetPixelRowSpan((int)(((y - startY) * heightFactor) + sourceY));
Span<TPixel> targetRow = destination.GetPixelRowSpan(y);
for (int x = minX; x < maxX; x++)
rows =>
{
// X coordinates of source points
targetRow[x] = sourceRow[(int)(((x - startX) * widthFactor) + sourceX)];
}
});
for (int y = rows.Min; y < rows.Max; y++)
{
// Y coordinates of source points
Span<TPixel> sourceRow =
source.GetPixelRowSpan((int)(((y - startY) * heightFactor) + sourceY));
Span<TPixel> targetRow = destination.GetPixelRowSpan(y);
for (int x = minX; x < maxX; x++)
{
// X coordinates of source points
targetRow[x] = sourceRow[(int)(((x - startX) * widthFactor) + sourceX)];
}
}
});
return;
}
@ -300,72 +306,88 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{
firstPassPixels.MemorySource.Clear();
ParallelFor.WithTemporaryBuffer(
0,
sourceRectangle.Bottom,
var processColsRect = new Rectangle(0, 0, source.Width, sourceRectangle.Bottom);
ParallelHelper.IterateRowsWithTempBuffer<Vector4>(
processColsRect,
configuration,
source.Width,
(int y, IMemoryOwner<Vector4> tempRowBuffer) =>
(rows, tempRowBuffer) =>
{
ref Vector4 firstPassRow = ref MemoryMarshal.GetReference(firstPassPixels.GetRowSpan(y));
Span<TPixel> sourceRow = source.GetPixelRowSpan(y);
Span<Vector4> tempRowSpan = tempRowBuffer.GetSpan();
for (int y = rows.Min; y < rows.Max; y++)
{
ref Vector4 firstPassRow =
ref MemoryMarshal.GetReference(firstPassPixels.GetRowSpan(y));
Span<TPixel> sourceRow = source.GetPixelRowSpan(y);
Span<Vector4> tempRowSpan = tempRowBuffer.Span;
PixelOperations<TPixel>.Instance.ToVector4(sourceRow, tempRowSpan, sourceRow.Length);
PixelOperations<TPixel>.Instance.ToVector4(sourceRow, tempRowSpan, sourceRow.Length);
if (this.Compand)
{
for (int x = minX; x < maxX; x++)
if (this.Compand)
{
WeightsWindow window = this.horizontalWeights.Weights[x - startX];
Unsafe.Add(ref firstPassRow, x) = window.ComputeExpandedWeightedRowSum(tempRowSpan, sourceX);
for (int x = minX; x < maxX; x++)
{
WeightsWindow window = this.horizontalWeights.Weights[x - startX];
Unsafe.Add(ref firstPassRow, x) =
window.ComputeExpandedWeightedRowSum(tempRowSpan, sourceX);
}
}
}
else
{
for (int x = minX; x < maxX; x++)
else
{
WeightsWindow window = this.horizontalWeights.Weights[x - startX];
Unsafe.Add(ref firstPassRow, x) = window.ComputeWeightedRowSum(tempRowSpan, sourceX);
for (int x = minX; x < maxX; x++)
{
WeightsWindow window = this.horizontalWeights.Weights[x - startX];
Unsafe.Add(ref firstPassRow, x) =
window.ComputeWeightedRowSum(tempRowSpan, sourceX);
}
}
}
});
var processRowsRect = Rectangle.FromLTRB(0, minY, width, maxY);
// Now process the rows.
ParallelFor.WithConfiguration(
minY,
maxY,
ParallelHelper.IterateRows(
processRowsRect,
configuration,
y =>
{
// Ensure offsets are normalized for cropping and padding.
WeightsWindow window = this.verticalWeights.Weights[y - startY];
ref TPixel targetRow = ref MemoryMarshal.GetReference(destination.GetPixelRowSpan(y));
if (this.Compand)
{
for (int x = 0; x < width; x++)
{
// Destination color components
Vector4 destinationVector = window.ComputeWeightedColumnSum(firstPassPixels, x, sourceY);
destinationVector = destinationVector.Compress();
ref TPixel pixel = ref Unsafe.Add(ref targetRow, x);
pixel.PackFromVector4(destinationVector);
}
}
else
rows =>
{
for (int x = 0; x < width; x++)
for (int y = rows.Min; y < rows.Max; y++)
{
// Destination color components
Vector4 destinationVector = window.ComputeWeightedColumnSum(firstPassPixels, x, sourceY);
// Ensure offsets are normalized for cropping and padding.
WeightsWindow window = this.verticalWeights.Weights[y - startY];
ref TPixel targetRow = ref MemoryMarshal.GetReference(destination.GetPixelRowSpan(y));
ref TPixel pixel = ref Unsafe.Add(ref targetRow, x);
pixel.PackFromVector4(destinationVector);
if (this.Compand)
{
for (int x = 0; x < width; x++)
{
// Destination color components
Vector4 destinationVector = window.ComputeWeightedColumnSum(
firstPassPixels,
x,
sourceY);
destinationVector = destinationVector.Compress();
ref TPixel pixel = ref Unsafe.Add(ref targetRow, x);
pixel.PackFromVector4(destinationVector);
}
}
else
{
for (int x = 0; x < width; x++)
{
// Destination color components
Vector4 destinationVector = window.ComputeWeightedColumnSum(
firstPassPixels,
x,
sourceY);
ref TPixel pixel = ref Unsafe.Add(ref targetRow, x);
pixel.PackFromVector4(destinationVector);
}
}
}
}
});
});
}
}

Loading…
Cancel
Save