From 07e9e40b98620ab0bd1969853775026184f629b0 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 27 Aug 2017 20:01:41 +0200 Subject: [PATCH] GetSubArea() --- .../Formats/Jpeg/Common/IJpegComponent.cs | 11 +++++++++++ .../Components/Decoder/OrigComponent.cs | 10 +++++----- .../Components/PdfJsFrameComponent.cs | 10 ++++------ src/ImageSharp/Memory/Buffer2DExtensions.cs | 7 +++++++ src/ImageSharp/Memory/BufferArea.cs | 19 +++++++++++++++++++ .../Formats/Jpg/SpectralJpegTests.cs | 2 +- .../Jpg/Utils/LibJpegTools.ComponentData.cs | 12 ++++++------ .../Jpg/Utils/LibJpegTools.SpectralData.cs | 6 +++--- .../Formats/Jpg/Utils/LibJpegTools.cs | 4 ++-- .../Memory/BufferAreaTests.cs | 19 +++++++++++++++++++ 10 files changed, 77 insertions(+), 23 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Common/IJpegComponent.cs b/src/ImageSharp/Formats/Jpeg/Common/IJpegComponent.cs index 07dba0bdbb..55bd5fe304 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/IJpegComponent.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/IJpegComponent.cs @@ -1,5 +1,10 @@ +using SixLabors.ImageSharp.Memory; + namespace SixLabors.ImageSharp.Formats.Jpeg.Common { + /// + /// Common interface to represent raw Jpeg components. + /// internal interface IJpegComponent { /// @@ -26,5 +31,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common /// Gets the vertical sampling factor. /// int VerticalSamplingFactor { get; } + + /// + /// Gets the storing the "raw" frequency-domain decoded blocks. + /// We need to apply IDCT, dequantiazition and unzigging to transform them into color-space blocks. + /// + Buffer2D SpectralBlocks { get; } } } \ No newline at end of file diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponent.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponent.cs index 035a7ddd82..3917084419 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponent.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponent.cs @@ -7,8 +7,7 @@ using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder { - using SixLabors.Primitives; - + /// /// /// Represents a single color component /// @@ -39,11 +38,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder /// public byte Selector { get; private set; } + /// /// - /// Gets the storing the "raw" frequency-domain decoded blocks. + /// Gets the storing the "raw" frequency-domain decoded blocks. /// We need to apply IDCT, dequantiazition and unzigging to transform them into color-space blocks. - /// This is done by . - /// When us true, we are touching these blocks multiple times - each time we process a Scan. + /// This is done by . + /// When us true, we are touching these blocks multiple times - each time we process a Scan. /// public Buffer2D SpectralBlocks { get; private set; } diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs index 2363d9600b..cd1e6c7a99 100644 --- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs +++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs @@ -42,6 +42,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components /// public int VerticalSamplingFactor { get; } + Buffer2D IJpegComponent.SpectralBlocks => throw new NotImplementedException(); + /// /// Gets the identifier /// @@ -55,14 +57,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components /// public int Index { get; } - /// - /// Gets the number of blocks per line - /// + /// public int WidthInBlocks { get; private set; } - /// - /// Gets the number of blocks per column - /// + /// public int HeightInBlocks { get; private set; } /// diff --git a/src/ImageSharp/Memory/Buffer2DExtensions.cs b/src/ImageSharp/Memory/Buffer2DExtensions.cs index bfc0f715b0..401003eedd 100644 --- a/src/ImageSharp/Memory/Buffer2DExtensions.cs +++ b/src/ImageSharp/Memory/Buffer2DExtensions.cs @@ -75,6 +75,13 @@ namespace SixLabors.ImageSharp.Memory public static BufferArea GetArea(this IBuffer2D buffer, Rectangle rectangle) where T : struct => new BufferArea(buffer, rectangle); + public static BufferArea GetArea(this IBuffer2D buffer, int x, int y, int width, int height) + where T : struct + { + var rectangle = new Rectangle(x, y, width, height); + return new BufferArea(buffer, rectangle); + } + /// /// Return a to the whole area of 'buffer' /// diff --git a/src/ImageSharp/Memory/BufferArea.cs b/src/ImageSharp/Memory/BufferArea.cs index 4ef095b8b2..542420d0c7 100644 --- a/src/ImageSharp/Memory/BufferArea.cs +++ b/src/ImageSharp/Memory/BufferArea.cs @@ -46,6 +46,25 @@ namespace SixLabors.ImageSharp.Memory return this.DestinationBuffer.Span.Slice(yy + xx, width); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public BufferArea GetSubArea(int x, int y, int width, int height) + { + var rectangle = new Rectangle(x, y, width, height); + return this.GetSubArea(rectangle); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public BufferArea GetSubArea(Rectangle rectangle) + { + DebugGuard.MustBeLessThanOrEqualTo(rectangle.Width, this.Rectangle.Width, nameof(rectangle)); + DebugGuard.MustBeLessThanOrEqualTo(rectangle.Height, this.Rectangle.Height, nameof(rectangle)); + + int x = this.Rectangle.X + rectangle.X; + int y = this.Rectangle.Y + rectangle.Y; + rectangle = new Rectangle(x, y, rectangle.Width, rectangle.Height); + return new BufferArea(this.DestinationBuffer, rectangle); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private int GetIndexOf(int x, int y) { diff --git a/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs index c72a4977b6..351d57bd78 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs @@ -107,7 +107,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg this.Output.WriteLine($"Component{i}: {diff}"); averageDifference += diff.average; totalDifference += diff.total; - tolerance += libJpegComponent.Blocks.Length; + tolerance += libJpegComponent.SpectralBlocks.Length; } averageDifference /= componentCount; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs index ec544f97cc..360ffff211 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs @@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils this.HeightInBlocks = heightInBlocks; this.WidthInBlocks = widthInBlocks; this.Index = index; - this.Blocks = new Buffer2D(this.WidthInBlocks, this.HeightInBlocks); + this.SpectralBlocks = new Buffer2D(this.WidthInBlocks, this.HeightInBlocks); } public Size Size => new Size(this.WidthInBlocks, this.HeightInBlocks); @@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils public int VerticalSamplingFactor => throw new NotSupportedException(); - public Buffer2D Blocks { get; private set; } + public Buffer2D SpectralBlocks { get; private set; } public short MinVal { get; private set; } = short.MaxValue; @@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils { this.MinVal = Math.Min((short)this.MinVal, data.Min()); this.MaxVal = Math.Max((short)this.MaxVal, data.Max()); - this.Blocks[x, y] = new Block8x8(data); + this.SpectralBlocks[x, y] = new Block8x8(data); } public static ComponentData Load(PdfJsFrameComponent c, int index) @@ -103,7 +103,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils internal void WriteToImage(int bx, int by, Image image) { - Block8x8 block = this.Blocks[bx, by]; + Block8x8 block = this.SpectralBlocks[bx, by]; for (int y = 0; y < 8; y++) { @@ -145,8 +145,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils { for (int x = 0; x < this.WidthInBlocks; x++) { - Block8x8 a = this.Blocks[x, y]; - Block8x8 b = other.Blocks[x, y]; + Block8x8 a = this.SpectralBlocks[x, y]; + Block8x8 b = other.SpectralBlocks[x, y]; if (!a.Equals(b)) return false; } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.SpectralData.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.SpectralData.cs index 327d3f3387..e18a5a285f 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.SpectralData.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.SpectralData.cs @@ -71,9 +71,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils LibJpegTools.ComponentData c1 = this.Components[1]; LibJpegTools.ComponentData c2 = this.Components[2]; - Block8x8 block0 = c0.Blocks[bx, by]; - Block8x8 block1 = c1.Blocks[bx, by]; - Block8x8 block2 = c2.Blocks[bx, by]; + Block8x8 block0 = c0.SpectralBlocks[bx, by]; + Block8x8 block1 = c1.SpectralBlocks[bx, by]; + Block8x8 block2 = c2.SpectralBlocks[bx, by]; float d0 = (c0.MaxVal - c0.MinVal); float d1 = (c1.MaxVal - c1.MinVal); diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.cs index 3747528d0a..9c7fb879a5 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.cs @@ -29,8 +29,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils { for (int x = 0; x < w; x++) { - Block8x8 aa = expected.Blocks[x, y]; - Block8x8 bb = actual.Blocks[x, y]; + Block8x8 aa = expected.SpectralBlocks[x, y]; + Block8x8 bb = actual.SpectralBlocks[x, y]; long diff = Block8x8.TotalDifference(ref aa, ref bb); totalDiff += diff; diff --git a/tests/ImageSharp.Tests/Memory/BufferAreaTests.cs b/tests/ImageSharp.Tests/Memory/BufferAreaTests.cs index a370134123..961380033a 100644 --- a/tests/ImageSharp.Tests/Memory/BufferAreaTests.cs +++ b/tests/ImageSharp.Tests/Memory/BufferAreaTests.cs @@ -98,5 +98,24 @@ namespace SixLabors.ImageSharp.Tests.Memory } } } + + [Fact] + public void GetSubArea() + { + using (Buffer2D buffer = CreateTestBuffer(20, 30)) + { + BufferArea area0 = buffer.GetArea(6, 8, 10, 10); + + BufferArea area1 = area0.GetSubArea(4, 4, 5, 5); + + var expectedRect = new Rectangle(10, 12, 5, 5); + + Assert.Equal(buffer, area1.DestinationBuffer); + Assert.Equal(expectedRect, area1.Rectangle); + + int value00 = 12 * 100 + 10; + Assert.Equal(value00, area1[0, 0]); + } + } } } \ No newline at end of file