Browse Source

Use using declarations to reduce nesting

pull/1068/head
Brian Popow 6 years ago
parent
commit
5e3a1903af
  1. 131
      src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor{TPixel}.cs

131
src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor{TPixel}.cs

@ -5,7 +5,6 @@ using System;
using System.Buffers; using System.Buffers;
using System.Numerics; using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Advanced.ParallelUtils; using SixLabors.ImageSharp.Advanced.ParallelUtils;
@ -58,88 +57,84 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects
Configuration configuration = this.Configuration; Configuration configuration = this.Configuration;
using (Buffer2D<TPixel> targetPixels = this.Configuration.MemoryAllocator.Allocate2D<TPixel>(source.Size())) using Buffer2D<TPixel> targetPixels = this.Configuration.MemoryAllocator.Allocate2D<TPixel>(source.Size());
{ source.CopyTo(targetPixels);
source.CopyTo(targetPixels);
var workingRect = Rectangle.FromLTRB(startX, startY, endX, endY);
var workingRect = Rectangle.FromLTRB(startX, startY, endX, endY); ParallelHelper.IterateRows(
ParallelHelper.IterateRows( workingRect,
workingRect, this.Configuration,
this.Configuration, (rows) =>
(rows) => {
// Rent the shared buffer only once per parallel item.
using IMemoryOwner<float> bins = configuration.MemoryAllocator.Allocate<float>(levels * 4);
ref float binsRef = ref bins.GetReference();
ref int intensityBinRef = ref Unsafe.As<float, int>(ref binsRef);
ref float redBinRef = ref Unsafe.Add(ref binsRef, levels);
ref float blueBinRef = ref Unsafe.Add(ref redBinRef, levels);
ref float greenBinRef = ref Unsafe.Add(ref blueBinRef, levels);
for (int y = rows.Min; y < rows.Max; y++)
{
Span<TPixel> sourceRow = source.GetPixelRowSpan(y);
Span<TPixel> targetRow = targetPixels.GetRowSpan(y);
for (int x = startX; x < endX; x++)
{ {
// Rent the shared buffer only once per parallel item. int maxIntensity = 0;
using (IMemoryOwner<float> bins = configuration.MemoryAllocator.Allocate<float>(levels * 4)) int maxIndex = 0;
{
ref float binsRef = ref bins.GetReference();
ref int intensityBinRef = ref Unsafe.As<float, int>(ref binsRef);
ref float redBinRef = ref Unsafe.Add(ref binsRef, levels);
ref float blueBinRef = ref Unsafe.Add(ref redBinRef, levels);
ref float greenBinRef = ref Unsafe.Add(ref blueBinRef, levels);
for (int y = rows.Min; y < rows.Max; y++)
{
Span<TPixel> sourceRow = source.GetPixelRowSpan(y);
Span<TPixel> targetRow = targetPixels.GetRowSpan(y);
for (int x = startX; x < endX; x++)
{
int maxIntensity = 0;
int maxIndex = 0;
// Clear the current shared buffer before processing each target pixel
bins.Memory.Span.Clear();
for (int fy = 0; fy <= radius; fy++) // Clear the current shared buffer before processing each target pixel
{ bins.Memory.Span.Clear();
int fyr = fy - radius;
int offsetY = y + fyr;
offsetY = offsetY.Clamp(0, maxY); for (int fy = 0; fy <= radius; fy++)
{
Span<TPixel> sourceOffsetRow = source.GetPixelRowSpan(offsetY); int fyr = fy - radius;
int offsetY = y + fyr;
for (int fx = 0; fx <= radius; fx++) offsetY = offsetY.Clamp(0, maxY);
{
int fxr = fx - radius;
int offsetX = x + fxr;
offsetX = offsetX.Clamp(0, maxX);
var vector = sourceOffsetRow[offsetX].ToVector4(); Span<TPixel> sourceOffsetRow = source.GetPixelRowSpan(offsetY);
float sourceRed = vector.X; for (int fx = 0; fx <= radius; fx++)
float sourceBlue = vector.Z; {
float sourceGreen = vector.Y; int fxr = fx - radius;
int offsetX = x + fxr;
offsetX = offsetX.Clamp(0, maxX);
int currentIntensity = (int)MathF.Round((sourceBlue + sourceGreen + sourceRed) / 3F * (levels - 1)); var vector = sourceOffsetRow[offsetX].ToVector4();
Unsafe.Add(ref intensityBinRef, currentIntensity)++; float sourceRed = vector.X;
Unsafe.Add(ref redBinRef, currentIntensity) += sourceRed; float sourceBlue = vector.Z;
Unsafe.Add(ref blueBinRef, currentIntensity) += sourceBlue; float sourceGreen = vector.Y;
Unsafe.Add(ref greenBinRef, currentIntensity) += sourceGreen;
if (Unsafe.Add(ref intensityBinRef, currentIntensity) > maxIntensity) int currentIntensity = (int)MathF.Round((sourceBlue + sourceGreen + sourceRed) / 3F * (levels - 1));
{
maxIntensity = Unsafe.Add(ref intensityBinRef, currentIntensity);
maxIndex = currentIntensity;
}
}
float red = MathF.Abs(Unsafe.Add(ref redBinRef, maxIndex) / maxIntensity); Unsafe.Add(ref intensityBinRef, currentIntensity)++;
float blue = MathF.Abs(Unsafe.Add(ref blueBinRef, maxIndex) / maxIntensity); Unsafe.Add(ref redBinRef, currentIntensity) += sourceRed;
float green = MathF.Abs(Unsafe.Add(ref greenBinRef, maxIndex) / maxIntensity); Unsafe.Add(ref blueBinRef, currentIntensity) += sourceBlue;
float alpha = sourceRow[x].ToVector4().W; Unsafe.Add(ref greenBinRef, currentIntensity) += sourceGreen;
ref TPixel pixel = ref targetRow[x]; if (Unsafe.Add(ref intensityBinRef, currentIntensity) > maxIntensity)
pixel.FromVector4(new Vector4(red, green, blue, sourceRow[x].ToVector4().W)); {
} maxIntensity = Unsafe.Add(ref intensityBinRef, currentIntensity);
maxIndex = currentIntensity;
} }
} }
float red = MathF.Abs(Unsafe.Add(ref redBinRef, maxIndex) / maxIntensity);
float blue = MathF.Abs(Unsafe.Add(ref blueBinRef, maxIndex) / maxIntensity);
float green = MathF.Abs(Unsafe.Add(ref greenBinRef, maxIndex) / maxIntensity);
float alpha = sourceRow[x].ToVector4().W;
ref TPixel pixel = ref targetRow[x];
pixel.FromVector4(new Vector4(red, green, blue, sourceRow[x].ToVector4().W));
} }
}); }
}
});
Buffer2D<TPixel>.SwapOrCopyContent(source.PixelBuffer, targetPixels); Buffer2D<TPixel>.SwapOrCopyContent(source.PixelBuffer, targetPixels);
}
} }
} }
} }

Loading…
Cancel
Save