Browse Source

ParallelHelper -> AffineTransformProcessor, RotateProcessor

af/merge-core
Anton Firszov 8 years ago
parent
commit
3e24c577f7
  1. 46
      src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs
  2. 32
      src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs

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

@ -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;
@ -78,11 +79,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);
@ -94,6 +96,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
destRow[x] = source[point.X, point.Y]; destRow[x] = source[point.X, point.Y];
} }
} }
}
}); });
return; return;
@ -116,11 +119,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));
@ -161,13 +165,32 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
} }
// It appears these have to be calculated on-the-fly. // It appears these have to be calculated on-the-fly.
// Precalulating transformed weights would require prior knowledge of every transformed pixel location // Precalculating transformed weights would require prior knowledge of every transformed pixel location
// since they can be at sub-pixel positions on both axis. // since they can be at sub-pixel positions on both axis.
// 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
{ {
@ -197,6 +220,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
// Reverse the premultiplication // Reverse the premultiplication
dest.PackFromVector4(sum.UnPremultiply()); dest.PackFromVector4(sum.UnPremultiply());
} }
}
}); });
} }
} }

32
src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs

@ -5,6 +5,7 @@ using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.MetaData.Profiles.Exif; using SixLabors.ImageSharp.MetaData.Profiles.Exif;
using SixLabors.ImageSharp.ParallelUtils;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors.Transforms; using SixLabors.ImageSharp.Processing.Processors.Transforms;
using SixLabors.Primitives; using SixLabors.Primitives;
@ -147,11 +148,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
int height = source.Height; int height = source.Height;
Rectangle destinationBounds = destination.Bounds(); Rectangle destinationBounds = destination.Bounds();
ParallelFor.WithConfiguration( ParallelHelper.IterateRows(
0, source.Bounds(),
height,
configuration, configuration,
y => rows =>
{
for (int y = rows.Min; y < rows.Max; y++)
{ {
Span<TPixel> sourceRow = source.GetPixelRowSpan(y); Span<TPixel> sourceRow = source.GetPixelRowSpan(y);
for (int x = 0; x < width; x++) for (int x = 0; x < width; x++)
@ -165,6 +167,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
destination[newX, newY] = sourceRow[x]; destination[newX, newY] = sourceRow[x];
} }
} }
}
}); });
} }
@ -179,11 +182,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
int width = source.Width; int width = source.Width;
int height = source.Height; int height = source.Height;
ParallelFor.WithConfiguration( ParallelHelper.IterateRows(
0, source.Bounds(),
height,
configuration, configuration,
y => rows =>
{
for (int y = rows.Min; y < rows.Max; y++)
{ {
Span<TPixel> sourceRow = source.GetPixelRowSpan(y); Span<TPixel> sourceRow = source.GetPixelRowSpan(y);
Span<TPixel> targetRow = destination.GetPixelRowSpan(height - y - 1); Span<TPixel> targetRow = destination.GetPixelRowSpan(height - y - 1);
@ -192,6 +196,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{ {
targetRow[width - x - 1] = sourceRow[x]; targetRow[width - x - 1] = sourceRow[x];
} }
}
}); });
} }
@ -207,21 +212,24 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
int height = source.Height; int height = source.Height;
Rectangle destinationBounds = destination.Bounds(); Rectangle destinationBounds = destination.Bounds();
ParallelFor.WithConfiguration( ParallelHelper.IterateRows(
0, source.Bounds(),
height,
configuration, configuration,
y => rows =>
{
for (int y = rows.Min; y < rows.Max; y++)
{ {
Span<TPixel> sourceRow = source.GetPixelRowSpan(y); Span<TPixel> sourceRow = source.GetPixelRowSpan(y);
int newX = height - y - 1; int newX = height - y - 1;
for (int x = 0; x < width; x++) for (int x = 0; x < width; x++)
{ {
// TODO: Optimize this:
if (destinationBounds.Contains(newX, x)) if (destinationBounds.Contains(newX, x))
{ {
destination[newX, x] = sourceRow[x]; destination[newX, x] = sourceRow[x];
} }
} }
}
}); });
} }
} }

Loading…
Cancel
Save