Browse Source

CopyColorsTo() no longer uses MutableSpan

pull/322/head
Anton Firszov 9 years ago
parent
commit
f3b11146a6
  1. 24
      src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs
  2. 5
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/DecodedBlock.cs
  3. 2
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/JpegBlockProcessor.cs
  4. 6
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OldComponent.cs
  5. 4
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OldJpegPixelArea.cs
  6. 6
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OldJpegScanDecoder.cs
  7. 25
      src/ImageSharp/Formats/Jpeg/GolangPort/OldJpegDecoderCore.cs
  8. 4
      tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs

24
src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs

@ -305,26 +305,26 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common
/// <summary>
/// Level shift by +128, clip to [0, 255], and write to buffer.
/// </summary>
/// <param name="buffer">Color buffer</param>
/// <param name="destinationBuffer">Color buffer</param>
/// <param name="stride">Stride offset</param>
/// <param name="tempBlockPtr">Temp Block pointer</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe void CopyColorsTo(MutableSpan<byte> buffer, int stride, Block8x8F* tempBlockPtr)
public unsafe void CopyColorsTo(Span<byte> destinationBuffer, int stride, Block8x8F* tempBlockPtr)
{
this.TransformByteConvetibleColorValuesInto(ref *tempBlockPtr);
ref byte d = ref destinationBuffer.DangerousGetPinnableReference();
float* src = (float*)tempBlockPtr;
for (int i = 0; i < 8; i++)
{
buffer[0] = (byte)src[0];
buffer[1] = (byte)src[1];
buffer[2] = (byte)src[2];
buffer[3] = (byte)src[3];
buffer[4] = (byte)src[4];
buffer[5] = (byte)src[5];
buffer[6] = (byte)src[6];
buffer[7] = (byte)src[7];
buffer.AddOffset(stride);
ref byte dRow = ref Unsafe.Add(ref d, i * stride);
Unsafe.Add(ref dRow, 0) = (byte)src[0];
Unsafe.Add(ref dRow, 1) = (byte)src[1];
Unsafe.Add(ref dRow, 2) = (byte)src[2];
Unsafe.Add(ref dRow, 3) = (byte)src[3];
Unsafe.Add(ref dRow, 4) = (byte)src[4];
Unsafe.Add(ref dRow, 5) = (byte)src[5];
Unsafe.Add(ref dRow, 6) = (byte)src[6];
Unsafe.Add(ref dRow, 7) = (byte)src[7];
src += 8;
}
}

5
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/DecodedBlock.cs

@ -12,11 +12,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// </summary>
internal struct DecodedBlock
{
/// <summary>
/// A value indicating whether the <see cref="DecodedBlock"/> instance is initialized.
/// </summary>
public bool Initialized;
/// <summary>
/// X coordinate of the current block, in units of 8x8. (The third block in the first row has (bx, by) = (2, 0))
/// </summary>

2
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/JpegBlockProcessor.cs

@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// <param name="decoder">The <see cref="OldJpegDecoderCore"/> instance</param>
public void ProcessAllBlocks(OldJpegDecoderCore decoder)
{
Buffer<DecodedBlock> blockArray = decoder.DecodedBlocks[this.componentIndex];
Buffer<DecodedBlock> blockArray = decoder.Components[this.componentIndex].DecodedBlocks;
for (int i = 0; i < blockArray.Length; i++)
{
this.ProcessBlockColors(decoder, ref blockArray[i]);

6
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OldComponent.cs

@ -43,6 +43,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// </summary>
public byte Selector { get; private set; }
/// <summary>
/// Gets the <see cref="Buffer{T}"/> 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="OldJpegDecoderCore.ProcessBlocksIntoJpegImageChannels{TPixel}"/>.
/// When <see cref="OldJpegDecoderCore.IsProgressive"/>==true, we are touching these blocks multiple times - each time we process a Scan.
/// </summary>
public Buffer<DecodedBlock> DecodedBlocks { get; private set; }
/// <summary>

4
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OldJpegPixelArea.cs

@ -8,6 +8,8 @@ using Block8x8F = SixLabors.ImageSharp.Formats.Jpeg.Common.Block8x8F;
namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
{
using System;
/// <summary>
/// Represents an area of a Jpeg subimage (channel)
/// </summary>
@ -109,7 +111,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
public unsafe void LoadColorsFrom(Block8x8F* block, Block8x8F* temp)
{
// Level shift by +128, clip to [0, 255], and write to dst.
block->CopyColorsTo(new MutableSpan<byte>(this.Pixels.Array, this.Offset), this.Stride, temp);
block->CopyColorsTo(new Span<byte>(this.Pixels.Array, this.Offset), this.Stride, temp);
}
}
}

6
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OldJpegScanDecoder.cs

@ -171,7 +171,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
// Take an existing block (required when progressive):
int blockIndex = this.GetBlockIndex(decoder);
this.data.Block = decoder.DecodedBlocks[this.ComponentIndex][blockIndex].Block;
Buffer<DecodedBlock> blocks = decoder.Components[this.ComponentIndex].DecodedBlocks;
this.data.Block = blocks[blockIndex].Block;
if (!decoder.InputProcessor.UnexpectedEndOfStreamReached)
{
@ -179,7 +182,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
}
// Store the decoded block
Buffer<DecodedBlock> blocks = decoder.DecodedBlocks[this.ComponentIndex];
blocks[blockIndex].SaveBlock(this.bx, this.by, ref this.data.Block);
}

25
src/ImageSharp/Formats/Jpeg/GolangPort/OldJpegDecoderCore.cs

@ -15,6 +15,8 @@ using Block8x8F = SixLabors.ImageSharp.Formats.Jpeg.Common.Block8x8F;
namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
{
using System.Linq;
/// <summary>
/// Performs the jpeg decoding operation.
/// </summary>
@ -107,7 +109,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
this.HuffmanTrees = OldHuffmanTree.CreateHuffmanTrees();
this.QuantizationTables = new Block8x8F[MaxTq + 1];
this.Temp = new byte[2 * Block8x8F.ScalarCount];
this.DecodedBlocks = new Buffer<DecodedBlock>[MaxComponents];
}
/// <summary>
@ -119,15 +120,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
/// Gets the huffman trees
/// </summary>
public OldHuffmanTree[] HuffmanTrees { get; }
/// <summary>
/// Gets the array of <see cref="Buffer{T}"/>-s 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="ProcessBlocksIntoJpegImageChannels{TPixel}"/>.
/// When <see cref="IsProgressive"/>==true, we are touching these blocks multiple times - each time we process a Scan.
/// </summary>
public Buffer<DecodedBlock>[] DecodedBlocks { get; }
/// <summary>
/// Gets the quantization tables, in zigzag order.
/// </summary>
@ -217,10 +210,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
this.HuffmanTrees[i].Dispose();
}
foreach (Buffer<DecodedBlock> blockArray in this.DecodedBlocks)
if (this.Components != null)
{
blockArray?.Dispose();
foreach (Buffer<DecodedBlock> blockArray in this.Components.Select(c => c.DecodedBlocks))
{
blockArray?.Dispose();
}
}
this.ycbcrImage?.Dispose();
this.InputProcessor.Dispose();
@ -1225,9 +1222,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
// As a preparation for parallelizing Scan decoder, we also allocate DecodedBlocks in the non-progressive case!
for (int i = 0; i < this.ComponentCount; i++)
{
int count = this.TotalMCUCount * this.Components[i].HorizontalFactor
* this.Components[i].VerticalFactor;
this.DecodedBlocks[i] = Buffer<DecodedBlock>.CreateClean(count);
this.Components[i].InitializeBlocks(this);
}
}
}

4
tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs

@ -18,6 +18,8 @@ using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests
{
using System;
public class Block8x8FTests : JpegUtilityTestFixture
{
#if BENCHMARKING
@ -321,7 +323,7 @@ namespace SixLabors.ImageSharp.Tests
ReferenceImplementations.CopyColorsTo(ref block, new MutableSpan<byte>(colorsExpected, offset), stride);
block.CopyColorsTo(new MutableSpan<byte>(colorsActual, offset), stride, &temp);
block.CopyColorsTo(new Span<byte>(colorsActual, offset), stride, &temp);
// Output.WriteLine("******* EXPECTED: *********");
// PrintLinearData(colorsExpected);

Loading…
Cancel
Save