diff --git a/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor.cs b/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor.cs
index b14de6679f..46e2e67c0d 100644
--- a/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor.cs
+++ b/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor.cs
@@ -1,6 +1,8 @@
using System;
using SixLabors.ImageSharp.Advanced;
+using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.Memory;
using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors
@@ -9,7 +11,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
/// Performs Bradley Adaptive Threshold filter against an image
///
/// The pixel format of the image
- internal class AdaptiveThresholdProcessor : IImageProcessor
+ internal class AdaptiveThresholdProcessor : ImageProcessor
where TPixel : struct, IPixel
{
///
@@ -41,72 +43,81 @@ namespace SixLabors.ImageSharp.Processing.Processors
///
public TPixel Lower { get; set; }
- public unsafe void Apply(Image source, Rectangle sourceRectangle)
+ ///
+ protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration)
{
- ushort xStart = (ushort)Math.Max(0, sourceRectangle.X);
- ushort yStart = (ushort)Math.Max(0, sourceRectangle.Y);
- ushort xEnd = (ushort)Math.Min(xStart + sourceRectangle.Width, source.Width);
- ushort yEnd = (ushort)Math.Min(yStart + sourceRectangle.Height, source.Height);
+ var interest = Rectangle.Intersect(sourceRectangle, source.Bounds());
+ ushort startY = (ushort)interest.Y;
+ ushort endY = (ushort)interest.Bottom;
+ ushort startX = (ushort)interest.X;
+ ushort endX = (ushort)interest.Right;
- // Algorithm variables
- uint sum, count;
- ushort s = (ushort)Math.Truncate((xEnd / 16f) - 1);
- uint[,] intImage = new uint[yEnd, xEnd];
+ ushort width = (ushort)(endX - startX);
+ ushort height = (ushort)(endY - startY);
- // Trying to figure out how to do this
- // Using (Buffer2D intImg = source.GetConfiguration().MemoryAllocator.Allocate2D)
- Rgb24 rgb = default;
+ // Algorithm variables //
+ ulong sum;
+ uint count;
- for (ushort i = yStart; i < yEnd; i++)
- {
- Span span = source.GetPixelRowSpan(i);
+ // Tweaked to support upto 4k wide pixels
+ ushort s = (ushort)Math.Truncate((width / 16f) - 1);
- sum = 0;
+ // Trying to figure out how to do this
+ using (Buffer2D intImage = configuration.MemoryAllocator.Allocate2D(width, height, AllocationOptions.Clean))
+ {
+ Rgb24 rgb = default;
- for (ushort j = xStart; j < xEnd; j++)
+ for (ushort i = startY; i < endY; i++)
{
- span[j].ToRgb24(ref rgb);
+ Span span = source.GetPixelRowSpan(i);
- sum += (uint)(rgb.R + rgb.G + rgb.B);
+ sum = 0;
- if (i != 0)
+ for (ushort j = startX; j < endX; j++)
{
- intImage[i, j] = intImage[i - 1, j] + sum;
- }
- else
- {
- intImage[i, j] = sum;
+ span[j].ToRgb24(ref rgb);
+
+ sum += (uint)(rgb.R + rgb.G + rgb.B);
+
+ if (i != 0)
+ {
+ intImage[i, j] = intImage[i - 1, j] + sum;
+ }
+ else
+ {
+ intImage[i, j] = sum;
+ }
}
}
- }
- // How can I parallelize this?
- ushort x1, x2, y1, y2;
+ // How can I parallelize this?
+ ushort x1, x2, y1, y2;
- for (ushort i = yStart; i < yEnd; i++)
- {
- Span span = source.GetPixelRowSpan(i);
-
- for (ushort j = xStart; j < xEnd; j++)
+ for (ushort i = startY; i < endY; i++)
{
- x1 = (ushort)Math.Max(i - s + 1, 0);
- x2 = (ushort)Math.Min(i + s + 1, yEnd - 1);
- y1 = (ushort)Math.Max(j - s + 1, 0);
- y2 = (ushort)Math.Min(j + s + 1, xEnd - 1);
+ Span span = source.GetPixelRowSpan(i);
- count = (ushort)((x2 - x1) * (y2 - y1));
+ for (ushort j = startX; j < endX; j++)
+ {
+ x1 = (ushort)Math.Max(i - s + 1, 0);
+ x2 = (ushort)Math.Min(i + s + 1, endY - 1);
+ y1 = (ushort)Math.Max(j - s + 1, 0);
+ y2 = (ushort)Math.Min(j + s + 1, endX - 1);
- sum = intImage[x2, y2] - intImage[x1, y2] - intImage[x2, y1] + intImage[x1, y1];
+ count = (uint)((x2 - x1) * (y2 - y1));
- span[j].ToRgb24(ref rgb);
+ sum = intImage[x2, y2] - intImage[x1, y2] - intImage[x2, y1] + intImage[x1, y1];
- if ((rgb.R + rgb.G + rgb.B) * count < sum * (1.0 - 0.15))
- {
- span[j] = this.Lower;
- }
- else
- {
- span[j] = this.Upper;
+ span[j].ToRgb24(ref rgb);
+
+ if ((rgb.R + rgb.G + rgb.B) * count < sum * (1.0 - 0.15))
+ {
+ span[j] = this.Lower;
+ }
+ else
+ {
+ span[j] = this.Upper;
+ }
}
}
}