diff --git a/src/ImageSharp/Dithering/ErrorDiffusion/ErrorDiffuser.cs b/src/ImageSharp/Dithering/ErrorDiffusion/ErrorDiffuser.cs
index 8d05bfcb6..7a225e1d0 100644
--- a/src/ImageSharp/Dithering/ErrorDiffusion/ErrorDiffuser.cs
+++ b/src/ImageSharp/Dithering/ErrorDiffusion/ErrorDiffuser.cs
@@ -69,15 +69,15 @@ namespace SixLabors.ImageSharp.Dithering
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Dither(ImageBase pixels, TPixel source, TPixel transformed, int x, int y, int width, int height)
+ public void Dither(ImageBase pixels, TPixel source, TPixel transformed, int x, int y, int minX, int minY, int maxX, int maxY)
where TPixel : struct, IPixel
{
- this.Dither(pixels, source, transformed, x, y, width, height, true);
+ this.Dither(pixels, source, transformed, x, y, minX, minY, maxX, maxY, true);
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Dither(ImageBase image, TPixel source, TPixel transformed, int x, int y, int width, int height, bool replacePixel)
+ public void Dither(ImageBase image, TPixel source, TPixel transformed, int x, int y, int minX, int minY, int maxX, int maxY, bool replacePixel)
where TPixel : struct, IPixel
{
if (replacePixel)
@@ -93,7 +93,7 @@ namespace SixLabors.ImageSharp.Dithering
for (int row = 0; row < this.matrixHeight; row++)
{
int matrixY = y + row;
- if (matrixY > 0 && matrixY < height)
+ if (matrixY > minY && matrixY < maxY)
{
Span rowSpan = image.GetRowSpan(matrixY);
@@ -101,7 +101,7 @@ namespace SixLabors.ImageSharp.Dithering
{
int matrixX = x + (col - this.startingOffset);
- if (matrixX > 0 && matrixX < width)
+ if (matrixX > minX && matrixX < maxX)
{
float coefficient = this.matrix[row, col];
diff --git a/src/ImageSharp/Dithering/ErrorDiffusion/IErrorDiffuser.cs b/src/ImageSharp/Dithering/ErrorDiffusion/IErrorDiffuser.cs
index 57eea6b92..850c978fe 100644
--- a/src/ImageSharp/Dithering/ErrorDiffusion/IErrorDiffuser.cs
+++ b/src/ImageSharp/Dithering/ErrorDiffusion/IErrorDiffuser.cs
@@ -18,10 +18,12 @@ namespace SixLabors.ImageSharp.Dithering
/// The transformed pixel
/// The column index.
/// The row index.
- /// The image width.
- /// The image height.
+ /// The minimum column value.
+ /// The minimum row value.
+ /// The maximum column value.
+ /// The maximum row value.
/// The pixel format.
- void Dither(ImageBase image, TPixel source, TPixel transformed, int x, int y, int width, int height)
+ void Dither(ImageBase image, TPixel source, TPixel transformed, int x, int y, int minX, int minY, int maxX, int maxY)
where TPixel : struct, IPixel;
///
@@ -32,14 +34,16 @@ namespace SixLabors.ImageSharp.Dithering
/// The transformed pixel
/// The column index.
/// The row index.
- /// The image width.
- /// The image height.
+ /// The minimum column value.
+ /// The minimum row value.
+ /// The maximum column value.
+ /// The maximum row value.
///
/// Whether to replace the pixel at the given coordinates with the transformed value.
/// Generally this would be true for standard two-color dithering but when used in conjunction with color quantization this should be false.
///
/// The pixel format.
- void Dither(ImageBase image, TPixel source, TPixel transformed, int x, int y, int width, int height, bool replacePixel)
+ void Dither(ImageBase image, TPixel source, TPixel transformed, int x, int y, int minX, int minY, int maxX, int maxY, bool replacePixel)
where TPixel : struct, IPixel;
}
}
diff --git a/src/ImageSharp/Dithering/Ordered/IOrderedDither.cs b/src/ImageSharp/Dithering/Ordered/IOrderedDither.cs
index fbd51a253..e3c7c5cba 100644
--- a/src/ImageSharp/Dithering/Ordered/IOrderedDither.cs
+++ b/src/ImageSharp/Dithering/Ordered/IOrderedDither.cs
@@ -21,10 +21,8 @@ namespace SixLabors.ImageSharp.Dithering
/// The component index to test the threshold against. Must range from 0 to 3.
/// The column index.
/// The row index.
- /// The image width.
- /// The image height.
/// The pixel format.
- void Dither(ImageBase image, TPixel source, TPixel upper, TPixel lower, byte[] bytes, int index, int x, int y, int width, int height)
+ void Dither(ImageBase image, TPixel source, TPixel upper, TPixel lower, byte[] bytes, int index, int x, int y)
where TPixel : struct, IPixel;
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Dithering/Ordered/OrderedDither4x4.cs b/src/ImageSharp/Dithering/Ordered/OrderedDither4x4.cs
index 94292b7b5..6be103713 100644
--- a/src/ImageSharp/Dithering/Ordered/OrderedDither4x4.cs
+++ b/src/ImageSharp/Dithering/Ordered/OrderedDither4x4.cs
@@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.Dithering.Ordered
}
///
- public void Dither(ImageBase image, TPixel source, TPixel upper, TPixel lower, byte[] bytes, int index, int x, int y, int width, int height)
+ public void Dither(ImageBase image, TPixel source, TPixel upper, TPixel lower, byte[] bytes, int index, int x, int y)
where TPixel : struct, IPixel
{
// TODO: This doesn't really cut it for me.
diff --git a/src/ImageSharp/Processing/Processors/Binarization/ErrorDiffusionDitherProcessor.cs b/src/ImageSharp/Processing/Processors/Binarization/ErrorDiffusionDitherProcessor.cs
index 2590aa6a0..ec92993a3 100644
--- a/src/ImageSharp/Processing/Processors/Binarization/ErrorDiffusionDitherProcessor.cs
+++ b/src/ImageSharp/Processing/Processors/Binarization/ErrorDiffusionDitherProcessor.cs
@@ -61,39 +61,21 @@ namespace SixLabors.ImageSharp.Processing.Processors
///
protected override void OnApply(ImageBase source, Rectangle sourceRectangle)
{
- int startY = sourceRectangle.Y;
- int endY = sourceRectangle.Bottom;
- int startX = sourceRectangle.X;
- int endX = sourceRectangle.Right;
+ var interest = Rectangle.Intersect(sourceRectangle, source.Bounds());
+ int startY = interest.Y;
+ int endY = interest.Bottom;
+ int startX = interest.X;
+ int endX = interest.Right;
- // Align start/end positions.
- int minX = Math.Max(0, startX);
- int maxX = Math.Min(source.Width, endX);
- int minY = Math.Max(0, startY);
- int maxY = Math.Min(source.Height, endY);
-
- // Reset offset if necessary.
- if (minX > 0)
- {
- startX = 0;
- }
-
- if (minY > 0)
- {
- startY = 0;
- }
-
- for (int y = minY; y < maxY; y++)
+ for (int y = startY; y < endY; y++)
{
- int offsetY = y - startY;
- Span row = source.GetRowSpan(offsetY);
+ Span row = source.GetRowSpan(y);
- for (int x = minX; x < maxX; x++)
+ for (int x = startX; x < endX; x++)
{
- int offsetX = x - startX;
- TPixel sourceColor = row[offsetX];
+ TPixel sourceColor = row[x];
TPixel transformedColor = sourceColor.ToVector4().X >= this.Threshold ? this.UpperColor : this.LowerColor;
- this.Diffuser.Dither(source, sourceColor, transformedColor, offsetX, offsetY, maxX, maxY);
+ this.Diffuser.Dither(source, sourceColor, transformedColor, x, y, startX, startY, endX, endY);
}
}
}
diff --git a/src/ImageSharp/Processing/Processors/Binarization/OrderedDitherProcessor.cs b/src/ImageSharp/Processing/Processors/Binarization/OrderedDitherProcessor.cs
index b71ea97cf..27114be80 100644
--- a/src/ImageSharp/Processing/Processors/Binarization/OrderedDitherProcessor.cs
+++ b/src/ImageSharp/Processing/Processors/Binarization/OrderedDitherProcessor.cs
@@ -69,39 +69,21 @@ namespace SixLabors.ImageSharp.Processing.Processors
///
protected override void OnApply(ImageBase source, Rectangle sourceRectangle)
{
- int startY = sourceRectangle.Y;
- int endY = sourceRectangle.Bottom;
- int startX = sourceRectangle.X;
- int endX = sourceRectangle.Right;
-
- // Align start/end positions.
- int minX = Math.Max(0, startX);
- int maxX = Math.Min(source.Width, endX);
- int minY = Math.Max(0, startY);
- int maxY = Math.Min(source.Height, endY);
-
- // Reset offset if necessary.
- if (minX > 0)
- {
- startX = 0;
- }
-
- if (minY > 0)
- {
- startY = 0;
- }
+ var interest = Rectangle.Intersect(sourceRectangle, source.Bounds());
+ int startY = interest.Y;
+ int endY = interest.Bottom;
+ int startX = interest.X;
+ int endX = interest.Right;
byte[] bytes = new byte[4];
- for (int y = minY; y < maxY; y++)
+ for (int y = startY; y < endY; y++)
{
- int offsetY = y - startY;
- Span row = source.GetRowSpan(offsetY);
+ Span row = source.GetRowSpan(y);
- for (int x = minX; x < maxX; x++)
+ for (int x = startX; x < endX; x++)
{
- int offsetX = x - startX;
- TPixel sourceColor = row[offsetX];
- this.Dither.Dither(source, sourceColor, this.UpperColor, this.LowerColor, bytes, this.Index, offsetX, offsetY, maxX, maxY);
+ TPixel sourceColor = row[x];
+ this.Dither.Dither(source, sourceColor, this.UpperColor, this.LowerColor, bytes, this.Index, x, y);
}
}
}
diff --git a/src/ImageSharp/Quantizers/OctreeQuantizer{TPixel}.cs b/src/ImageSharp/Quantizers/OctreeQuantizer{TPixel}.cs
index f41bcd04d..1cd0020ba 100644
--- a/src/ImageSharp/Quantizers/OctreeQuantizer{TPixel}.cs
+++ b/src/ImageSharp/Quantizers/OctreeQuantizer{TPixel}.cs
@@ -103,7 +103,7 @@ namespace SixLabors.ImageSharp.Quantizers
if (this.Dither)
{
// Apply the dithering matrix. We have to reapply the value now as the original has changed.
- this.DitherType.Dither(source, sourcePixel, transformedPixel, x, y, width, height, false);
+ this.DitherType.Dither(source, sourcePixel, transformedPixel, x, y, 0, 0, width, height, false);
}
output[(y * source.Width) + x] = pixelValue;
diff --git a/src/ImageSharp/Quantizers/PaletteQuantizer{TPixel}.cs b/src/ImageSharp/Quantizers/PaletteQuantizer{TPixel}.cs
index 56ecf7c90..985994dce 100644
--- a/src/ImageSharp/Quantizers/PaletteQuantizer{TPixel}.cs
+++ b/src/ImageSharp/Quantizers/PaletteQuantizer{TPixel}.cs
@@ -99,7 +99,7 @@ namespace SixLabors.ImageSharp.Quantizers
if (this.Dither)
{
// Apply the dithering matrix. We have to reapply the value now as the original has changed.
- this.DitherType.Dither(source, sourcePixel, transformedPixel, x, y, width, height, false);
+ this.DitherType.Dither(source, sourcePixel, transformedPixel, x, y, 0, 0, width, height, false);
}
output[(y * source.Width) + x] = pixelValue;
diff --git a/src/ImageSharp/Quantizers/WuQuantizer{TPixel}.cs b/src/ImageSharp/Quantizers/WuQuantizer{TPixel}.cs
index 4bb902817..790097b7b 100644
--- a/src/ImageSharp/Quantizers/WuQuantizer{TPixel}.cs
+++ b/src/ImageSharp/Quantizers/WuQuantizer{TPixel}.cs
@@ -277,7 +277,7 @@ namespace SixLabors.ImageSharp.Quantizers
if (this.Dither)
{
// Apply the dithering matrix. We have to reapply the value now as the original has changed.
- this.DitherType.Dither(source, sourcePixel, transformedPixel, x, y, width, height, false);
+ this.DitherType.Dither(source, sourcePixel, transformedPixel, x, y, 0, 0, width, height, false);
}
output[(y * source.Width) + x] = pixelValue;
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Binarization/DitherTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Binarization/DitherTests.cs
index 75fd32fc8..7c858babc 100644
--- a/tests/ImageSharp.Tests/Processing/Processors/Binarization/DitherTests.cs
+++ b/tests/ImageSharp.Tests/Processing/Processors/Binarization/DitherTests.cs
@@ -111,8 +111,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Binarization
}
}
- // TODO: Does not work because of a bug! Fix it!
- [Theory(Skip = "TODO: Does not work because of a bug! Fix it!")]
+ [Theory]
[WithFile(TestImages.Png.CalliphoraPartial, DefaultPixelType)]
public void ApplyDiffusionFilterInBox(TestImageProvider provider)
where TPixel : struct, IPixel