Browse Source

ParallelHelper -> CropProcessor, additional FlipProcessor test

pull/710/head
Anton Firszov 8 years ago
parent
commit
2ee4a88d54
  1. 20
      src/ImageSharp/Common/ParallelUtils/ParallelExecutionSettings.cs
  2. 32
      src/ImageSharp/Processing/Processors/Transforms/CropProcessor.cs
  3. 3
      src/ImageSharp/Processing/Processors/Transforms/FlipProcessor.cs
  4. 19
      tests/ImageSharp.Tests/Processing/Processors/Transforms/FlipTests.cs
  5. 2
      tests/Images/External

20
src/ImageSharp/Common/ParallelUtils/ParallelExecutionSettings.cs

@ -12,7 +12,15 @@ namespace SixLabors.ImageSharp.ParallelUtils
/// </summary>
internal struct ParallelExecutionSettings
{
public ParallelExecutionSettings(int maxDegreeOfParallelism, int minimumPixelsProcessedPerTask, MemoryAllocator memoryAllocator)
/// <summary>
/// Default value for <see cref="MinimumPixelsProcessedPerTask"/>.
/// </summary>
public const int DefaultMinimumPixelsProcessedPerTask = 2048;
public ParallelExecutionSettings(
int maxDegreeOfParallelism,
int minimumPixelsProcessedPerTask,
MemoryAllocator memoryAllocator)
{
this.MaxDegreeOfParallelism = maxDegreeOfParallelism;
this.MinimumPixelsProcessedPerTask = minimumPixelsProcessedPerTask;
@ -20,7 +28,7 @@ namespace SixLabors.ImageSharp.ParallelUtils
}
public ParallelExecutionSettings(int maxDegreeOfParallelism, MemoryAllocator memoryAllocator)
: this(maxDegreeOfParallelism, 2048, memoryAllocator)
: this(maxDegreeOfParallelism, DefaultMinimumPixelsProcessedPerTask, memoryAllocator)
{
}
@ -37,5 +45,13 @@ namespace SixLabors.ImageSharp.ParallelUtils
/// Initialized with 2048 by default, the optimum value is operation specific.
/// </summary>
public int MinimumPixelsProcessedPerTask { get; }
public ParallelExecutionSettings MultiplyMinimumPixelsPerTask(int multiplier)
{
return new ParallelExecutionSettings(
this.MaxDegreeOfParallelism,
this.MinimumPixelsProcessedPerTask * multiplier,
this.MemoryAllocator);
}
}
}

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

@ -4,8 +4,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.ParallelUtils;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Primitives;
@ -53,21 +53,23 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
return;
}
int minY = Math.Max(this.CropRectangle.Y, sourceRectangle.Y);
int maxY = Math.Min(this.CropRectangle.Bottom, sourceRectangle.Bottom);
int minX = Math.Max(this.CropRectangle.X, sourceRectangle.X);
int maxX = Math.Min(this.CropRectangle.Right, sourceRectangle.Right);
var rect = Rectangle.Intersect(this.CropRectangle, sourceRectangle);
ParallelFor.WithConfiguration(
minY,
maxY,
configuration,
y =>
{
Span<TPixel> sourceRow = source.GetPixelRowSpan(y).Slice(minX);
Span<TPixel> targetRow = destination.GetPixelRowSpan(y - minY);
sourceRow.Slice(0, maxX - minX).CopyTo(targetRow);
});
// Copying is cheap, we should process more pixels per task:
ParallelExecutionSettings parallelSettings = configuration.GetParallelSettings().MultiplyMinimumPixelsPerTask(4);
ParallelHelper.IterateRows(
rect,
parallelSettings,
rows =>
{
for (int y = rows.Min; y < rows.Max; y++)
{
Span<TPixel> sourceRow = source.GetPixelRowSpan(y).Slice(rect.Left);
Span<TPixel> targetRow = destination.GetPixelRowSpan(y - rect.Top);
sourceRow.Slice(0, rect.Width).CopyTo(targetRow);
}
});
}
}
}

3
src/ImageSharp/Processing/Processors/Transforms/FlipProcessor.cs

@ -57,8 +57,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
int height = source.Height;
int halfHeight = (int)Math.Ceiling(source.Height * .5F);
using (Buffer2D<TPixel> targetPixels = configuration.MemoryAllocator.Allocate2D<TPixel>(source.Size()))
{
ParallelFor.WithConfiguration(
0,
halfHeight,

19
tests/ImageSharp.Tests/Processing/Processors/Transforms/FlipTests.cs

@ -5,23 +5,24 @@ using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Xunit;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
{
using SixLabors.ImageSharp.Processing;
[GroupOutput("Transforms")]
public class FlipTests
{
public static readonly TheoryData<FlipMode> FlipValues
= new TheoryData<FlipMode>
{
{ FlipMode.None },
{ FlipMode.Vertical },
{ FlipMode.Horizontal },
};
public static readonly TheoryData<FlipMode> FlipValues =
new TheoryData<FlipMode>
{
FlipMode.None,
FlipMode.Vertical,
FlipMode.Horizontal,
};
[Theory]
[WithTestPatternImages(nameof(FlipValues), 20, 37, PixelTypes.Rgba32)]
[WithTestPatternImages(nameof(FlipValues), 53, 37, PixelTypes.Rgba32)]
[WithTestPatternImages(nameof(FlipValues), 17, 32, PixelTypes.Rgba32)]
public void Flip<TPixel>(TestImageProvider<TPixel> provider, FlipMode flipMode)

2
tests/Images/External

@ -1 +1 @@
Subproject commit 2841a79efd68d47c6552ce857869eb0d80f8de75
Subproject commit c1e14c0e431066c57585f255d3feb8d3a1860d50
Loading…
Cancel
Save