diff --git a/shared-infrastructure b/shared-infrastructure
index bc88dab174..06a7339834 160000
--- a/shared-infrastructure
+++ b/shared-infrastructure
@@ -1 +1 @@
-Subproject commit bc88dab1746d34048d938566a313848a7a911869
+Subproject commit 06a733983486638b9e38197c7c6eb197ecac43e6
diff --git a/src/ImageSharp/Processing/BinaryThresholdColorComponent.cs b/src/ImageSharp/Processing/BinaryThresholdMode.cs
similarity index 53%
rename from src/ImageSharp/Processing/BinaryThresholdColorComponent.cs
rename to src/ImageSharp/Processing/BinaryThresholdMode.cs
index e46070dcb6..0ca1f08d14 100644
--- a/src/ImageSharp/Processing/BinaryThresholdColorComponent.cs
+++ b/src/ImageSharp/Processing/BinaryThresholdMode.cs
@@ -4,22 +4,22 @@
namespace SixLabors.ImageSharp.Processing
{
///
- /// The color component to be compared to threshold.
+ /// Selects the value to be compared to threshold.
///
- public enum BinaryThresholdColorComponent : int
+ public enum BinaryThresholdMode
{
///
- /// Luminance color component according to ITU-R Recommendation BT.709.
+ /// Compare the color luminance (according to ITU-R Recommendation BT.709).
///
Luminance = 0,
///
- /// HSL saturation color component.
+ /// Compare the HSL saturation of the color.
///
Saturation = 1,
///
- /// Maximum of YCbCr chroma value, i.e. Cb and Cr distance from achromatic value.
+ /// Compare the maximum of YCbCr chroma value, i.e. Cb and Cr distance from achromatic value.
///
MaxChroma = 2,
}
diff --git a/src/ImageSharp/Processing/Extensions/Binarization/BinaryThresholdExtensions.cs b/src/ImageSharp/Processing/Extensions/Binarization/BinaryThresholdExtensions.cs
index 11c6433f22..5132fd731d 100644
--- a/src/ImageSharp/Processing/Extensions/Binarization/BinaryThresholdExtensions.cs
+++ b/src/ImageSharp/Processing/Extensions/Binarization/BinaryThresholdExtensions.cs
@@ -19,20 +19,20 @@ namespace SixLabors.ImageSharp.Processing
/// The threshold to apply binarization of the image. Must be between 0 and 1.
/// The to allow chaining of operations.
public static IImageProcessingContext BinaryThreshold(this IImageProcessingContext source, float threshold)
- => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, BinaryThresholdColorComponent.Luminance));
+ => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, BinaryThresholdMode.Luminance));
///
/// Applies binarization to the image splitting the pixels at the given threshold.
///
/// The image this method extends.
/// The threshold to apply binarization of the image. Must be between 0 and 1.
- /// The color component to be compared to threshold.
+ /// Selects the value to be compared to threshold.
/// The to allow chaining of operations.
public static IImageProcessingContext BinaryThreshold(
this IImageProcessingContext source,
float threshold,
- BinaryThresholdColorComponent colorComponent)
- => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, colorComponent));
+ BinaryThresholdMode mode)
+ => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, mode));
///
/// Applies binarization to the image splitting the pixels at the given threshold with
@@ -48,14 +48,14 @@ namespace SixLabors.ImageSharp.Processing
this IImageProcessingContext source,
float threshold,
Rectangle rectangle)
- => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, BinaryThresholdColorComponent.Luminance), rectangle);
+ => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, BinaryThresholdMode.Luminance), rectangle);
///
/// Applies binarization to the image splitting the pixels at the given threshold.
///
/// The image this method extends.
/// The threshold to apply binarization of the image. Must be between 0 and 1.
- /// The color component to be compared to threshold.
+ /// Selects the value to be compared to threshold.
///
/// The structure that specifies the portion of the image object to alter.
///
@@ -63,9 +63,9 @@ namespace SixLabors.ImageSharp.Processing
public static IImageProcessingContext BinaryThreshold(
this IImageProcessingContext source,
float threshold,
- BinaryThresholdColorComponent colorComponent,
+ BinaryThresholdMode mode,
Rectangle rectangle)
- => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, colorComponent), rectangle);
+ => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, mode), rectangle);
///
/// Applies binarization to the image splitting the pixels at the given threshold with
@@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.Processing
float threshold,
Color upperColor,
Color lowerColor)
- => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor, BinaryThresholdColorComponent.Luminance));
+ => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor, BinaryThresholdMode.Luminance));
///
/// Applies binarization to the image splitting the pixels at the given threshold.
@@ -90,15 +90,15 @@ namespace SixLabors.ImageSharp.Processing
/// The threshold to apply binarization of the image. Must be between 0 and 1.
/// The color to use for pixels that are above the threshold.
/// The color to use for pixels that are below the threshold
- /// The color component to be compared to threshold.
+ /// Selects the value to be compared to threshold.
/// The to allow chaining of operations.
public static IImageProcessingContext BinaryThreshold(
this IImageProcessingContext source,
float threshold,
Color upperColor,
Color lowerColor,
- BinaryThresholdColorComponent colorComponent)
- => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor, colorComponent));
+ BinaryThresholdMode mode)
+ => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor, mode));
///
/// Applies binarization to the image splitting the pixels at the given threshold with
@@ -118,7 +118,7 @@ namespace SixLabors.ImageSharp.Processing
Color upperColor,
Color lowerColor,
Rectangle rectangle)
- => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor, BinaryThresholdColorComponent.Luminance), rectangle);
+ => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor, BinaryThresholdMode.Luminance), rectangle);
///
/// Applies binarization to the image splitting the pixels at the given threshold.
@@ -127,7 +127,7 @@ namespace SixLabors.ImageSharp.Processing
/// The threshold to apply binarization of the image. Must be between 0 and 1.
/// The color to use for pixels that are above the threshold.
/// The color to use for pixels that are below the threshold
- /// The color component to be compared to threshold.
+ /// Selects the value to be compared to threshold.
///
/// The structure that specifies the portion of the image object to alter.
///
@@ -137,8 +137,8 @@ namespace SixLabors.ImageSharp.Processing
float threshold,
Color upperColor,
Color lowerColor,
- BinaryThresholdColorComponent colorComponent,
+ BinaryThresholdMode mode,
Rectangle rectangle) =>
- source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor, colorComponent), rectangle);
+ source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor, mode), rectangle);
}
}
diff --git a/src/ImageSharp/Processing/Extensions/ProcessingExtensions.IntegralImage.cs b/src/ImageSharp/Processing/Extensions/ProcessingExtensions.IntegralImage.cs
new file mode 100644
index 0000000000..af6d32b216
--- /dev/null
+++ b/src/ImageSharp/Processing/Extensions/ProcessingExtensions.IntegralImage.cs
@@ -0,0 +1,77 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using System.Buffers;
+using SixLabors.ImageSharp.Advanced;
+using SixLabors.ImageSharp.Memory;
+using SixLabors.ImageSharp.PixelFormats;
+
+namespace SixLabors.ImageSharp.Processing
+{
+ ///
+ /// Defines extensions that allow the computation of image integrals on an
+ ///
+ public static partial class ProcessingExtensions
+ {
+ ///
+ /// Apply an image integral.
+ ///
+ /// The image on which to apply the integral.
+ /// The type of the pixel.
+ /// The containing all the sums.
+ public static Buffer2D CalculateIntegralImage(this Image source)
+ where TPixel : unmanaged, IPixel
+ {
+ Configuration configuration = source.GetConfiguration();
+
+ int endY = source.Height;
+ int endX = source.Width;
+
+ Buffer2D intImage = configuration.MemoryAllocator.Allocate2D(source.Width, source.Height);
+ ulong sumX0 = 0;
+
+ using (IMemoryOwner tempRow = configuration.MemoryAllocator.Allocate(source.Width))
+ {
+ Span tempSpan = tempRow.GetSpan();
+ Span sourceRow = source.GetPixelRowSpan(0);
+ Span destRow = intImage.GetRowSpan(0);
+
+ PixelOperations.Instance.ToL8(configuration, sourceRow, tempSpan);
+
+ // First row
+ for (int x = 0; x < endX; x++)
+ {
+ sumX0 += tempSpan[x].PackedValue;
+ destRow[x] = sumX0;
+ }
+
+ Span previousDestRow = destRow;
+
+ // All other rows
+ for (int y = 1; y < endY; y++)
+ {
+ sourceRow = source.GetPixelRowSpan(y);
+ destRow = intImage.GetRowSpan(y);
+
+ PixelOperations.Instance.ToL8(configuration, sourceRow, tempSpan);
+
+ // Process first column
+ sumX0 = tempSpan[0].PackedValue;
+ destRow[0] = sumX0 + previousDestRow[0];
+
+ // Process all other colmns
+ for (int x = 1; x < endX; x++)
+ {
+ sumX0 += tempSpan[x].PackedValue;
+ destRow[x] = sumX0 + previousDestRow[x];
+ }
+
+ previousDestRow = destRow;
+ }
+ }
+
+ return intImage;
+ }
+ }
+}
diff --git a/src/ImageSharp/Processing/Extensions/ProcessingExtensions.cs b/src/ImageSharp/Processing/Extensions/ProcessingExtensions.cs
index 0bf83812d0..ac14d84231 100644
--- a/src/ImageSharp/Processing/Extensions/ProcessingExtensions.cs
+++ b/src/ImageSharp/Processing/Extensions/ProcessingExtensions.cs
@@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.Processing
///
/// Adds extensions that allow the processing of images to the type.
///
- public static class ProcessingExtensions
+ public static partial class ProcessingExtensions
{
///
/// Mutates the source image by applying the image operation to it.
diff --git a/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs b/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs
index 24a3e6c1da..77fc6938d9 100644
--- a/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs
+++ b/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs
@@ -14,9 +14,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
/// Initializes a new instance of the class.
///
/// The threshold to split the image. Must be between 0 and 1.
- /// The color component to be compared to threshold.
- public BinaryThresholdProcessor(float threshold, BinaryThresholdColorComponent colorComponent)
- : this(threshold, Color.White, Color.Black, colorComponent)
+ /// The color component to be compared to threshold.
+ public BinaryThresholdProcessor(float threshold, BinaryThresholdMode mode)
+ : this(threshold, Color.White, Color.Black, mode)
{
}
@@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
///
/// The threshold to split the image. Must be between 0 and 1.
public BinaryThresholdProcessor(float threshold)
- : this(threshold, Color.White, Color.Black, BinaryThresholdColorComponent.Luminance)
+ : this(threshold, Color.White, Color.Black, BinaryThresholdMode.Luminance)
{
}
@@ -36,14 +36,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
/// The threshold to split the image. Must be between 0 and 1.
/// The color to use for pixels that are above the threshold.
/// The color to use for pixels that are below the threshold.
- /// The color component to be compared to threshold.
- public BinaryThresholdProcessor(float threshold, Color upperColor, Color lowerColor, BinaryThresholdColorComponent colorComponent)
+ /// The color component to be compared to threshold.
+ public BinaryThresholdProcessor(float threshold, Color upperColor, Color lowerColor, BinaryThresholdMode mode)
{
Guard.MustBeBetweenOrEqualTo(threshold, 0, 1, nameof(threshold));
this.Threshold = threshold;
this.UpperColor = upperColor;
this.LowerColor = lowerColor;
- this.ColorComponent = colorComponent;
+ this.Mode = mode;
}
///
@@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
/// The color to use for pixels that are above the threshold.
/// The color to use for pixels that are below the threshold.
public BinaryThresholdProcessor(float threshold, Color upperColor, Color lowerColor)
- : this(threshold, upperColor, lowerColor, BinaryThresholdColorComponent.Luminance)
+ : this(threshold, upperColor, lowerColor, BinaryThresholdMode.Luminance)
{
}
@@ -73,10 +73,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
///
public Color LowerColor { get; }
- ///
- /// Gets a value indicating whether to use saturation value instead of luminance.
+ ///
+ /// Gets the defining the value to be compared to threshold.
///
- public BinaryThresholdColorComponent ColorComponent { get; }
+ public BinaryThresholdMode Mode { get; }
///
public IImageProcessor CreatePixelSpecificProcessor(Configuration configuration, Image source, Rectangle sourceRectangle)
diff --git a/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs
index aa03cc27d2..5942c71641 100644
--- a/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs
@@ -45,7 +45,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
upper,
lower,
threshold,
- this.definition.ColorComponent,
+ this.definition.Mode,
configuration);
ParallelRowIterator.IterateRows(
@@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
private readonly TPixel upper;
private readonly TPixel lower;
private readonly byte threshold;
- private readonly BinaryThresholdColorComponent colorComponent;
+ private readonly BinaryThresholdMode mode;
private readonly int startX;
private readonly Configuration configuration;
@@ -74,7 +74,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
TPixel upper,
TPixel lower,
byte threshold,
- BinaryThresholdColorComponent colorComponent,
+ BinaryThresholdMode mode,
Configuration configuration)
{
this.startX = startX;
@@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
this.upper = upper;
this.lower = lower;
this.threshold = threshold;
- this.colorComponent = colorComponent;
+ this.mode = mode;
this.configuration = configuration;
}
@@ -96,9 +96,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
Span rowSpan = this.source.GetPixelRowSpan(y).Slice(this.startX, span.Length);
PixelOperations.Instance.ToRgb24(this.configuration, rowSpan, span);
- switch (this.colorComponent)
+ switch (this.mode)
{
- case BinaryThresholdColorComponent.Luminance:
+ case BinaryThresholdMode.Luminance:
{
byte threshold = this.threshold;
for (int x = 0; x < rowSpan.Length; x++)
@@ -112,7 +112,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
break;
}
- case BinaryThresholdColorComponent.Saturation:
+ case BinaryThresholdMode.Saturation:
{
float threshold = this.threshold / 255F;
for (int x = 0; x < rowSpan.Length; x++)
@@ -125,7 +125,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
break;
}
- case BinaryThresholdColorComponent.MaxChroma:
+ case BinaryThresholdMode.MaxChroma:
{
float threshold = this.threshold / 2F;
for (int x = 0; x < rowSpan.Length; x++)
diff --git a/tests/ImageSharp.Tests/Processing/Binarization/BinaryThresholdTest.cs b/tests/ImageSharp.Tests/Processing/Binarization/BinaryThresholdTest.cs
index a02ca36eeb..a2fb9f9bad 100644
--- a/tests/ImageSharp.Tests/Processing/Binarization/BinaryThresholdTest.cs
+++ b/tests/ImageSharp.Tests/Processing/Binarization/BinaryThresholdTest.cs
@@ -16,7 +16,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Binarization
this.operations.BinaryThreshold(.23f);
BinaryThresholdProcessor p = this.Verify();
Assert.Equal(.23f, p.Threshold);
- Assert.Equal(BinaryThresholdColorComponent.Luminance, p.ColorComponent);
+ Assert.Equal(BinaryThresholdMode.Luminance, p.Mode);
Assert.Equal(Color.White, p.UpperColor);
Assert.Equal(Color.Black, p.LowerColor);
}
@@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Binarization
this.operations.BinaryThreshold(.93f, this.rect);
BinaryThresholdProcessor p = this.Verify(this.rect);
Assert.Equal(.93f, p.Threshold);
- Assert.Equal(BinaryThresholdColorComponent.Luminance, p.ColorComponent);
+ Assert.Equal(BinaryThresholdMode.Luminance, p.Mode);
Assert.Equal(Color.White, p.UpperColor);
Assert.Equal(Color.Black, p.LowerColor);
}
@@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Binarization
this.operations.BinaryThreshold(.23f, Color.HotPink, Color.Yellow);
BinaryThresholdProcessor p = this.Verify();
Assert.Equal(.23f, p.Threshold);
- Assert.Equal(BinaryThresholdColorComponent.Luminance, p.ColorComponent);
+ Assert.Equal(BinaryThresholdMode.Luminance, p.Mode);
Assert.Equal(Color.HotPink, p.UpperColor);
Assert.Equal(Color.Yellow, p.LowerColor);
}
@@ -48,7 +48,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Binarization
{
this.operations.BinaryThreshold(.93f, Color.HotPink, Color.Yellow, this.rect);
BinaryThresholdProcessor p = this.Verify(this.rect);
- Assert.Equal(BinaryThresholdColorComponent.Luminance, p.ColorComponent);
+ Assert.Equal(BinaryThresholdMode.Luminance, p.Mode);
Assert.Equal(.93f, p.Threshold);
Assert.Equal(Color.HotPink, p.UpperColor);
Assert.Equal(Color.Yellow, p.LowerColor);
@@ -57,10 +57,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Binarization
[Fact]
public void BinarySaturationThreshold_CorrectProcessor()
{
- this.operations.BinaryThreshold(.23f, BinaryThresholdColorComponent.Saturation);
+ this.operations.BinaryThreshold(.23f, BinaryThresholdMode.Saturation);
BinaryThresholdProcessor p = this.Verify();
Assert.Equal(.23f, p.Threshold);
- Assert.Equal(BinaryThresholdColorComponent.Saturation, p.ColorComponent);
+ Assert.Equal(BinaryThresholdMode.Saturation, p.Mode);
Assert.Equal(Color.White, p.UpperColor);
Assert.Equal(Color.Black, p.LowerColor);
}
@@ -68,10 +68,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Binarization
[Fact]
public void BinarySaturationThreshold_rect_CorrectProcessor()
{
- this.operations.BinaryThreshold(.93f, BinaryThresholdColorComponent.Saturation, this.rect);
+ this.operations.BinaryThreshold(.93f, BinaryThresholdMode.Saturation, this.rect);
BinaryThresholdProcessor p = this.Verify(this.rect);
Assert.Equal(.93f, p.Threshold);
- Assert.Equal(BinaryThresholdColorComponent.Saturation, p.ColorComponent);
+ Assert.Equal(BinaryThresholdMode.Saturation, p.Mode);
Assert.Equal(Color.White, p.UpperColor);
Assert.Equal(Color.Black, p.LowerColor);
}
@@ -79,10 +79,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Binarization
[Fact]
public void BinarySaturationThreshold_CorrectProcessorWithUpperLower()
{
- this.operations.BinaryThreshold(.23f, Color.HotPink, Color.Yellow, BinaryThresholdColorComponent.Saturation);
+ this.operations.BinaryThreshold(.23f, Color.HotPink, Color.Yellow, BinaryThresholdMode.Saturation);
BinaryThresholdProcessor p = this.Verify();
Assert.Equal(.23f, p.Threshold);
- Assert.Equal(BinaryThresholdColorComponent.Saturation, p.ColorComponent);
+ Assert.Equal(BinaryThresholdMode.Saturation, p.Mode);
Assert.Equal(Color.HotPink, p.UpperColor);
Assert.Equal(Color.Yellow, p.LowerColor);
}
@@ -90,10 +90,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Binarization
[Fact]
public void BinarySaturationThreshold_rect_CorrectProcessorWithUpperLower()
{
- this.operations.BinaryThreshold(.93f, Color.HotPink, Color.Yellow, BinaryThresholdColorComponent.Saturation, this.rect);
+ this.operations.BinaryThreshold(.93f, Color.HotPink, Color.Yellow, BinaryThresholdMode.Saturation, this.rect);
BinaryThresholdProcessor p = this.Verify(this.rect);
Assert.Equal(.93f, p.Threshold);
- Assert.Equal(BinaryThresholdColorComponent.Saturation, p.ColorComponent);
+ Assert.Equal(BinaryThresholdMode.Saturation, p.Mode);
Assert.Equal(Color.HotPink, p.UpperColor);
Assert.Equal(Color.Yellow, p.LowerColor);
}
@@ -101,10 +101,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Binarization
[Fact]
public void BinaryMaxChromaThreshold_CorrectProcessor()
{
- this.operations.BinaryThreshold(.23f, BinaryThresholdColorComponent.MaxChroma);
+ this.operations.BinaryThreshold(.23f, BinaryThresholdMode.MaxChroma);
BinaryThresholdProcessor p = this.Verify();
Assert.Equal(.23f, p.Threshold);
- Assert.Equal(BinaryThresholdColorComponent.MaxChroma, p.ColorComponent);
+ Assert.Equal(BinaryThresholdMode.MaxChroma, p.Mode);
Assert.Equal(Color.White, p.UpperColor);
Assert.Equal(Color.Black, p.LowerColor);
}
@@ -112,10 +112,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Binarization
[Fact]
public void BinaryMaxChromaThreshold_rect_CorrectProcessor()
{
- this.operations.BinaryThreshold(.93f, BinaryThresholdColorComponent.MaxChroma, this.rect);
+ this.operations.BinaryThreshold(.93f, BinaryThresholdMode.MaxChroma, this.rect);
BinaryThresholdProcessor p = this.Verify(this.rect);
Assert.Equal(.93f, p.Threshold);
- Assert.Equal(BinaryThresholdColorComponent.MaxChroma, p.ColorComponent);
+ Assert.Equal(BinaryThresholdMode.MaxChroma, p.Mode);
Assert.Equal(Color.White, p.UpperColor);
Assert.Equal(Color.Black, p.LowerColor);
}
@@ -123,10 +123,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Binarization
[Fact]
public void BinaryMaxChromaThreshold_CorrectProcessorWithUpperLower()
{
- this.operations.BinaryThreshold(.23f, Color.HotPink, Color.Yellow, BinaryThresholdColorComponent.MaxChroma);
+ this.operations.BinaryThreshold(.23f, Color.HotPink, Color.Yellow, BinaryThresholdMode.MaxChroma);
BinaryThresholdProcessor p = this.Verify();
Assert.Equal(.23f, p.Threshold);
- Assert.Equal(BinaryThresholdColorComponent.MaxChroma, p.ColorComponent);
+ Assert.Equal(BinaryThresholdMode.MaxChroma, p.Mode);
Assert.Equal(Color.HotPink, p.UpperColor);
Assert.Equal(Color.Yellow, p.LowerColor);
}
@@ -134,10 +134,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Binarization
[Fact]
public void BinaryMaxChromaThreshold_rect_CorrectProcessorWithUpperLower()
{
- this.operations.BinaryThreshold(.93f, Color.HotPink, Color.Yellow, BinaryThresholdColorComponent.MaxChroma, this.rect);
+ this.operations.BinaryThreshold(.93f, Color.HotPink, Color.Yellow, BinaryThresholdMode.MaxChroma, this.rect);
BinaryThresholdProcessor p = this.Verify(this.rect);
Assert.Equal(.93f, p.Threshold);
- Assert.Equal(BinaryThresholdColorComponent.MaxChroma, p.ColorComponent);
+ Assert.Equal(BinaryThresholdMode.MaxChroma, p.Mode);
Assert.Equal(Color.HotPink, p.UpperColor);
Assert.Equal(Color.Yellow, p.LowerColor);
}
diff --git a/tests/ImageSharp.Tests/Processing/IntegralImageTests.cs b/tests/ImageSharp.Tests/Processing/IntegralImageTests.cs
new file mode 100644
index 0000000000..481463f47e
--- /dev/null
+++ b/tests/ImageSharp.Tests/Processing/IntegralImageTests.cs
@@ -0,0 +1,110 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.Memory;
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Processing;
+using Xunit;
+
+namespace SixLabors.ImageSharp.Tests.Processing.Transforms
+{
+ public class IntegralImageTests : BaseImageOperationsExtensionTest
+ {
+ [Theory]
+ [WithFile(TestImages.Png.Bradley01, PixelTypes.Rgba32)]
+ [WithFile(TestImages.Png.Bradley02, PixelTypes.Rgba32)]
+ [WithFile(TestImages.Png.Ducky, PixelTypes.Rgba32)]
+ public void CalculateIntegralImage_Rgba32Works(TestImageProvider provider)
+ {
+ using Image image = provider.GetImage();
+
+ // Act:
+ Buffer2D integralBuffer = image.CalculateIntegralImage();
+
+ // Assert:
+ VerifySumValues(provider, integralBuffer, (Rgba32 pixel) =>
+ {
+ L8 outputPixel = default;
+
+ outputPixel.FromRgba32(pixel);
+
+ return outputPixel.PackedValue;
+ });
+ }
+
+ [Theory]
+ [WithFile(TestImages.Png.Bradley01, PixelTypes.L8)]
+ [WithFile(TestImages.Png.Bradley02, PixelTypes.L8)]
+ public void CalculateIntegralImage_L8Works(TestImageProvider provider)
+ {
+ using Image image = provider.GetImage();
+
+ // Act:
+ Buffer2D integralBuffer = image.CalculateIntegralImage();
+
+ // Assert:
+ VerifySumValues(provider, integralBuffer, (L8 pixel) => { return pixel.PackedValue; });
+ }
+
+ private static void VerifySumValues(
+ TestImageProvider provider,
+ Buffer2D integralBuffer,
+ System.Func getPixel)
+ where TPixel : unmanaged, IPixel
+ {
+ Image image = provider.GetImage();
+
+ // Check top-left corner
+ Assert.Equal(getPixel(image[0, 0]), integralBuffer[0, 0]);
+
+ ulong pixelValues = 0;
+
+ pixelValues += getPixel(image[0, 0]);
+ pixelValues += getPixel(image[1, 0]);
+ pixelValues += getPixel(image[0, 1]);
+ pixelValues += getPixel(image[1, 1]);
+
+ // Check top-left 2x2 pixels
+ Assert.Equal(pixelValues, integralBuffer[1, 1]);
+
+ pixelValues = 0;
+
+ pixelValues += getPixel(image[image.Width - 3, 0]);
+ pixelValues += getPixel(image[image.Width - 2, 0]);
+ pixelValues += getPixel(image[image.Width - 1, 0]);
+ pixelValues += getPixel(image[image.Width - 3, 1]);
+ pixelValues += getPixel(image[image.Width - 2, 1]);
+ pixelValues += getPixel(image[image.Width - 1, 1]);
+
+ // Check top-right 3x2 pixels
+ Assert.Equal(pixelValues, integralBuffer[image.Width - 1, 1] + 0 - 0 - integralBuffer[image.Width - 4, 1]);
+
+ pixelValues = 0;
+
+ pixelValues += getPixel(image[0, image.Height - 3]);
+ pixelValues += getPixel(image[0, image.Height - 2]);
+ pixelValues += getPixel(image[0, image.Height - 1]);
+ pixelValues += getPixel(image[1, image.Height - 3]);
+ pixelValues += getPixel(image[1, image.Height - 2]);
+ pixelValues += getPixel(image[1, image.Height - 1]);
+
+ // Check bottom-left 2x3 pixels
+ Assert.Equal(pixelValues, integralBuffer[1, image.Height - 1] + 0 - integralBuffer[1, image.Height - 4] - 0);
+
+ pixelValues = 0;
+
+ pixelValues += getPixel(image[image.Width - 3, image.Height - 3]);
+ pixelValues += getPixel(image[image.Width - 2, image.Height - 3]);
+ pixelValues += getPixel(image[image.Width - 1, image.Height - 3]);
+ pixelValues += getPixel(image[image.Width - 3, image.Height - 2]);
+ pixelValues += getPixel(image[image.Width - 2, image.Height - 2]);
+ pixelValues += getPixel(image[image.Width - 1, image.Height - 2]);
+ pixelValues += getPixel(image[image.Width - 3, image.Height - 1]);
+ pixelValues += getPixel(image[image.Width - 2, image.Height - 1]);
+ pixelValues += getPixel(image[image.Width - 1, image.Height - 1]);
+
+ // Check bottom-right 3x3 pixels
+ Assert.Equal(pixelValues, integralBuffer[image.Width - 1, image.Height - 1] + integralBuffer[image.Width - 4, image.Height - 4] - integralBuffer[image.Width - 1, image.Height - 4] - integralBuffer[image.Width - 4, image.Height - 1]);
+ }
+ }
+}
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Binarization/BinaryThresholdTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Binarization/BinaryThresholdTest.cs
index 79ed4c7cdb..fd08eb2dea 100644
--- a/tests/ImageSharp.Tests/Processing/Processors/Binarization/BinaryThresholdTest.cs
+++ b/tests/ImageSharp.Tests/Processing/Processors/Binarization/BinaryThresholdTest.cs
@@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Binarization
{
using (Image image = provider.GetImage())
{
- image.Mutate(x => x.BinaryThreshold(value, BinaryThresholdColorComponent.Saturation));
+ image.Mutate(x => x.BinaryThreshold(value, BinaryThresholdMode.Saturation));
image.DebugSave(provider, value);
image.CompareToReferenceOutput(ImageComparer.Exact, provider, value.ToString("0.00", NumberFormatInfo.InvariantInfo));
}
@@ -79,7 +79,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Binarization
{
var bounds = new Rectangle(image.Width / 8, image.Height / 8, 6 * image.Width / 8, 6 * image.Width / 8);
- image.Mutate(x => x.BinaryThreshold(value, BinaryThresholdColorComponent.Saturation, bounds));
+ image.Mutate(x => x.BinaryThreshold(value, BinaryThresholdMode.Saturation, bounds));
image.DebugSave(provider, value);
image.CompareToReferenceOutput(ImageComparer.Exact, provider, value.ToString("0.00", NumberFormatInfo.InvariantInfo));
}
@@ -92,7 +92,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Binarization
{
using (Image image = provider.GetImage())
{
- image.Mutate(x => x.BinaryThreshold(value, BinaryThresholdColorComponent.MaxChroma));
+ image.Mutate(x => x.BinaryThreshold(value, BinaryThresholdMode.MaxChroma));
image.DebugSave(provider, value);
if (!TestEnvironment.Is64BitProcess && TestEnvironment.IsFramework)
@@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Binarization
{
var bounds = new Rectangle(image.Width / 8, image.Height / 8, 6 * image.Width / 8, 6 * image.Width / 8);
- image.Mutate(x => x.BinaryThreshold(value, BinaryThresholdColorComponent.MaxChroma, bounds));
+ image.Mutate(x => x.BinaryThreshold(value, BinaryThresholdMode.MaxChroma, bounds));
image.DebugSave(provider, value);
if (!TestEnvironment.Is64BitProcess && TestEnvironment.IsFramework)