Browse Source

update ResizeProcessor

pull/869/head
Anton Firszov 7 years ago
parent
commit
acb1dbc319
  1. 102
      src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs
  2. 2
      tests/Images/External

102
src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs

@ -9,7 +9,6 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.ColorSpaces.Companding;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.ParallelUtils;
using SixLabors.ImageSharp.PixelFormats;
@ -216,27 +215,33 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
workingRect,
configuration,
rows =>
{
for (int y = rows.Min; y < rows.Max; y++)
{
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++)
{
// 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)];
}
// X coordinates of source points
targetRow[x] = sourceRow[(int)(((x - startX) * widthFactor) + sourceX)];
}
});
}
});
return;
}
int sourceHeight = source.Height;
PixelConversionModifiers conversionModifiers = PixelConversionModifiers.Premultiply;
if (this.Compand)
{
conversionModifiers |= PixelConversionModifiers.Scale | PixelConversionModifiers.SRgbCompand;
}
// Interpolate the image using the calculated weights.
// A 2-pass 1D algorithm appears to be faster than splitting a 1-pass 2D algorithm
// First process the columns. Since we are not using multiple threads startY and endY
@ -251,30 +256,23 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
processColsRect,
configuration,
(rows, tempRowBuffer) =>
{
for (int y = rows.Min; y < rows.Max; y++)
{
for (int y = rows.Min; y < rows.Max; y++)
{
Span<TPixel> sourceRow = source.GetPixelRowSpan(y).Slice(sourceX);
Span<Vector4> tempRowSpan = tempRowBuffer.Span.Slice(sourceX);
PixelOperations<TPixel>.Instance.ToVector4(configuration, sourceRow, tempRowSpan);
Vector4Utils.Premultiply(tempRowSpan);
Span<TPixel> sourceRow = source.GetPixelRowSpan(y).Slice(sourceX);
Span<Vector4> tempRowSpan = tempRowBuffer.Span.Slice(sourceX);
ref Vector4 firstPassBaseRef = ref firstPassPixelsTransposed.Span[y];
PixelOperations<TPixel>.Instance.ToVector4(configuration, sourceRow, tempRowSpan, conversionModifiers);
if (this.Compand)
{
SRgbCompanding.Expand(tempRowSpan);
}
ref Vector4 firstPassBaseRef = ref firstPassPixelsTransposed.Span[y];
for (int x = minX; x < maxX; x++)
{
ResizeKernel kernel = this.horizontalKernelMap.GetKernel(x - startX);
Unsafe.Add(ref firstPassBaseRef, x * sourceHeight) =
kernel.Convolve(tempRowSpan);
}
for (int x = minX; x < maxX; x++)
{
ResizeKernel kernel = this.horizontalKernelMap.GetKernel(x - startX);
Unsafe.Add(ref firstPassBaseRef, x * sourceHeight) = kernel.Convolve(tempRowSpan);
}
});
}
});
var processRowsRect = Rectangle.FromLTRB(0, minY, width, maxY);
@ -283,35 +281,29 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
processRowsRect,
configuration,
(rows, tempRowBuffer) =>
{
Span<Vector4> tempRowSpan = tempRowBuffer.Span;
for (int y = rows.Min; y < rows.Max; y++)
{
// Ensure offsets are normalized for cropping and padding.
ResizeKernel kernel = this.verticalKernelMap.GetKernel(y - startY);
{
Span<Vector4> tempRowSpan = tempRowBuffer.Span;
ref Vector4 tempRowBase = ref MemoryMarshal.GetReference(tempRowSpan);
for (int y = rows.Min; y < rows.Max; y++)
{
// Ensure offsets are normalized for cropping and padding.
ResizeKernel kernel = this.verticalKernelMap.GetKernel(y - startY);
for (int x = 0; x < width; x++)
{
Span<Vector4> firstPassColumn = firstPassPixelsTransposed.GetRowSpan(x).Slice(sourceY);
ref Vector4 tempRowBase = ref MemoryMarshal.GetReference(tempRowSpan);
// Destination color components
Unsafe.Add(ref tempRowBase, x) = kernel.Convolve(firstPassColumn);
}
for (int x = 0; x < width; x++)
{
Span<Vector4> firstPassColumn = firstPassPixelsTransposed.GetRowSpan(x).Slice(sourceY);
Vector4Utils.UnPremultiply(tempRowSpan);
// Destination color components
Unsafe.Add(ref tempRowBase, x) = kernel.Convolve(firstPassColumn);
}
if (this.Compand)
{
SRgbCompanding.Compress(tempRowSpan);
}
Span<TPixel> targetRowSpan = destination.GetPixelRowSpan(y);
Span<TPixel> targetRowSpan = destination.GetPixelRowSpan(y);
PixelOperations<TPixel>.Instance.FromVector4(configuration, tempRowSpan, targetRowSpan);
}
});
PixelOperations<TPixel>.Instance.FromVector4(configuration, tempRowSpan, targetRowSpan, conversionModifiers);
}
});
}
}

2
tests/Images/External

@ -1 +1 @@
Subproject commit c4098e463ab0e7128ae196b7f963369271df8fd3
Subproject commit 4387e56e8590ee00607efe29a9babfda041621cb
Loading…
Cancel
Save