Browse Source

GetSubArea()

pull/322/head
Anton Firszov 9 years ago
parent
commit
7f73f3135f
  1. 11
      src/ImageSharp/Formats/Jpeg/Common/IJpegComponent.cs
  2. 10
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponent.cs
  3. 10
      src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs
  4. 7
      src/ImageSharp/Memory/Buffer2DExtensions.cs
  5. 19
      src/ImageSharp/Memory/BufferArea.cs
  6. 2
      tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs
  7. 12
      tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs
  8. 6
      tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.SpectralData.cs
  9. 4
      tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.cs
  10. 19
      tests/ImageSharp.Tests/Memory/BufferAreaTests.cs

11
src/ImageSharp/Formats/Jpeg/Common/IJpegComponent.cs

@ -1,5 +1,10 @@
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Jpeg.Common
{
/// <summary>
/// Common interface to represent raw Jpeg components.
/// </summary>
internal interface IJpegComponent
{
/// <summary>
@ -26,5 +31,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common
/// Gets the vertical sampling factor.
/// </summary>
int VerticalSamplingFactor { get; }
/// <summary>
/// Gets the <see cref="Buffer2D{Block8x8}"/> storing the "raw" frequency-domain decoded blocks.
/// We need to apply IDCT, dequantiazition and unzigging to transform them into color-space blocks.
/// </summary>
Buffer2D<Block8x8> SpectralBlocks { get; }
}
}

10
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;
/// <inheritdoc cref="IJpegComponent" />
/// <summary>
/// Represents a single color component
/// </summary>
@ -39,11 +38,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// </summary>
public byte Selector { get; private set; }
/// <inheritdoc />
/// <summary>
/// Gets the <see cref="Buffer{T}"/> storing the "raw" frequency-domain decoded blocks.
/// Gets the <see cref="T:SixLabors.ImageSharp.Memory.Buffer`1" /> 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 <see cref="OrigJpegDecoderCore.ProcessBlocksIntoJpegImageChannels"/>.
/// When <see cref="OrigJpegDecoderCore.IsProgressive"/> us true, we are touching these blocks multiple times - each time we process a Scan.
/// This is done by <see cref="M:SixLabors.ImageSharp.Formats.Jpeg.GolangPort.OrigJpegDecoderCore.ProcessBlocksIntoJpegImageChannels" />.
/// When <see cref="P:SixLabors.ImageSharp.Formats.Jpeg.GolangPort.OrigJpegDecoderCore.IsProgressive" /> us true, we are touching these blocks multiple times - each time we process a Scan.
/// </summary>
public Buffer2D<Block8x8> SpectralBlocks { get; private set; }

10
src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs

@ -42,6 +42,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
/// <inheritdoc />
public int VerticalSamplingFactor { get; }
Buffer2D<Block8x8> IJpegComponent.SpectralBlocks => throw new NotImplementedException();
/// <summary>
/// Gets the identifier
/// </summary>
@ -55,14 +57,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
/// <inheritdoc />
public int Index { get; }
/// <summary>
/// Gets the number of blocks per line
/// </summary>
/// <inheritdoc />
public int WidthInBlocks { get; private set; }
/// <summary>
/// Gets the number of blocks per column
/// </summary>
/// <inheritdoc />
public int HeightInBlocks { get; private set; }
/// <summary>

7
src/ImageSharp/Memory/Buffer2DExtensions.cs

@ -75,6 +75,13 @@ namespace SixLabors.ImageSharp.Memory
public static BufferArea<T> GetArea<T>(this IBuffer2D<T> buffer, Rectangle rectangle)
where T : struct => new BufferArea<T>(buffer, rectangle);
public static BufferArea<T> GetArea<T>(this IBuffer2D<T> buffer, int x, int y, int width, int height)
where T : struct
{
var rectangle = new Rectangle(x, y, width, height);
return new BufferArea<T>(buffer, rectangle);
}
/// <summary>
/// Return a <see cref="BufferArea{T}"/> to the whole area of 'buffer'
/// </summary>

19
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<T> 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<T> 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<T>(this.DestinationBuffer, rectangle);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int GetIndexOf(int x, int y)
{

2
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;

12
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<Block8x8>(this.WidthInBlocks, this.HeightInBlocks);
this.SpectralBlocks = new Buffer2D<Block8x8>(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<Block8x8> Blocks { get; private set; }
public Buffer2D<Block8x8> 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<Rgba32> 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;
}
}

6
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);

4
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;

19
tests/ImageSharp.Tests/Memory/BufferAreaTests.cs

@ -98,5 +98,24 @@ namespace SixLabors.ImageSharp.Tests.Memory
}
}
}
[Fact]
public void GetSubArea()
{
using (Buffer2D<int> buffer = CreateTestBuffer(20, 30))
{
BufferArea<int> area0 = buffer.GetArea(6, 8, 10, 10);
BufferArea<int> 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]);
}
}
}
}
Loading…
Cancel
Save