From d22ba208499ef3b46f16ebb01375a339c75cff55 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Sun, 20 Aug 2017 19:21:29 +1000 Subject: [PATCH] Fix diffusion tests --- .../Dithering/ErrorDiffusion/ErrorDiffuser.cs | 10 ++--- .../ErrorDiffusion/IErrorDiffuser.cs | 16 +++++--- .../Dithering/Ordered/IOrderedDither.cs | 4 +- .../Dithering/Ordered/OrderedDither4x4.cs | 2 +- .../ErrorDiffusionDitherProcessor.cs | 38 +++++-------------- .../Binarization/OrderedDitherProcessor.cs | 38 +++++-------------- .../Quantizers/OctreeQuantizer{TPixel}.cs | 2 +- .../Quantizers/PaletteQuantizer{TPixel}.cs | 2 +- .../Quantizers/WuQuantizer{TPixel}.cs | 2 +- .../Processors/Binarization/DitherTests.cs | 3 +- 10 files changed, 41 insertions(+), 76 deletions(-) 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