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