Browse Source

additional usages of Span

pull/298/head
Scott Williams 9 years ago
parent
commit
db2b712e02
  1. 49
      src/ImageSharp/Formats/Jpeg/Port/Components/IDCT.cs
  2. 8
      src/ImageSharp/Formats/Jpeg/Port/Components/JpegPixelArea.cs
  3. 18
      src/ImageSharp/Formats/Jpeg/Port/Components/ScanDecoder.cs

49
src/ImageSharp/Formats/Jpeg/Port/Components/IDCT.cs

@ -31,6 +31,7 @@
{
Span<short> qt = quantizationTables.Tables.GetRowSpan(component.QuantizationIdentifier);
Span<short> blockData = component.BlockData.Slice(blockBufferOffset);
Span<short> computationBufferSpan = computationBuffer;
int v0, v1, v2, v3, v4, v5, v6, v7;
int p0, p1, p2, p3, p4, p5, p6, p7;
int t;
@ -56,14 +57,14 @@
{
t = ((DctSqrt2 * p0) + 512) >> 10;
short st = (short)t;
computationBuffer[row] = st;
computationBuffer[row + 1] = st;
computationBuffer[row + 2] = st;
computationBuffer[row + 3] = st;
computationBuffer[row + 4] = st;
computationBuffer[row + 5] = st;
computationBuffer[row + 6] = st;
computationBuffer[row + 7] = st;
computationBufferSpan[row] = st;
computationBufferSpan[row + 1] = st;
computationBufferSpan[row + 2] = st;
computationBufferSpan[row + 3] = st;
computationBufferSpan[row + 4] = st;
computationBufferSpan[row + 5] = st;
computationBufferSpan[row + 6] = st;
computationBufferSpan[row + 7] = st;
continue;
}
@ -110,27 +111,27 @@
v6 = t;
// stage 1
computationBuffer[row] = (short)(v0 + v7);
computationBuffer[row + 7] = (short)(v0 - v7);
computationBuffer[row + 1] = (short)(v1 + v6);
computationBuffer[row + 6] = (short)(v1 - v6);
computationBuffer[row + 2] = (short)(v2 + v5);
computationBuffer[row + 5] = (short)(v2 - v5);
computationBuffer[row + 3] = (short)(v3 + v4);
computationBuffer[row + 4] = (short)(v3 - v4);
computationBufferSpan[row] = (short)(v0 + v7);
computationBufferSpan[row + 7] = (short)(v0 - v7);
computationBufferSpan[row + 1] = (short)(v1 + v6);
computationBufferSpan[row + 6] = (short)(v1 - v6);
computationBufferSpan[row + 2] = (short)(v2 + v5);
computationBufferSpan[row + 5] = (short)(v2 - v5);
computationBufferSpan[row + 3] = (short)(v3 + v4);
computationBufferSpan[row + 4] = (short)(v3 - v4);
}
// inverse DCT on columns
for (int col = 0; col < 8; ++col)
{
p0 = computationBuffer[col];
p1 = computationBuffer[col + 8];
p2 = computationBuffer[col + 16];
p3 = computationBuffer[col + 24];
p4 = computationBuffer[col + 32];
p5 = computationBuffer[col + 40];
p6 = computationBuffer[col + 48];
p7 = computationBuffer[col + 56];
p0 = computationBufferSpan[col];
p1 = computationBufferSpan[col + 8];
p2 = computationBufferSpan[col + 16];
p3 = computationBufferSpan[col + 24];
p4 = computationBufferSpan[col + 32];
p5 = computationBufferSpan[col + 40];
p6 = computationBufferSpan[col + 48];
p7 = computationBufferSpan[col + 56];
// check for all-zero AC coefficients
if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) == 0)

8
src/ImageSharp/Formats/Jpeg/Port/Components/JpegPixelArea.cs

@ -72,17 +72,19 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
float scaleX = this.imageWidth / (float)width;
float scaleY = this.imageHeight / (float)height;
this.componentData = new Buffer<byte>(width * height * numberOfComponents);
Span<byte> componentDataSpan = this.componentData;
const uint Mask3Lsb = 0xFFFFFFF8; // Used to clear the 3 LSBs
using (var xScaleBlockOffset = new Buffer<int>(width))
{
Span<int> xScaleBlockOffsetSpan = xScaleBlockOffset;
for (int i = 0; i < numberOfComponents; i++)
{
ref Component component = ref components.Components[i];
float componentScaleX = component.ScaleX * scaleX;
float componentScaleY = component.ScaleY * scaleY;
int offset = i;
Buffer<short> output = component.Output;
Span<short> output = component.Output;
int blocksPerScanline = (component.BlocksPerLine + 1) << 3;
// Precalculate the xScaleBlockOffset
@ -90,7 +92,7 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
for (int x = 0; x < width; x++)
{
j = 0 | (int)(x * componentScaleX);
xScaleBlockOffset[x] = (int)((j & Mask3Lsb) << 3) | (j & 7);
xScaleBlockOffsetSpan[x] = (int)((j & Mask3Lsb) << 3) | (j & 7);
}
// Linearize the blocks of the component
@ -100,7 +102,7 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
int index = blocksPerScanline * (int)(j & Mask3Lsb) | ((j & 7) << 3);
for (int x = 0; x < width; x++)
{
this.componentData[offset] = (byte)output[index + xScaleBlockOffset[x]];
componentDataSpan[offset] = (byte)output[index + xScaleBlockOffsetSpan[x]];
offset += numberOfComponents;
}
}

18
src/ImageSharp/Formats/Jpeg/Port/Components/ScanDecoder.cs

@ -723,6 +723,7 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
return;
}
var componentBlockDataSpan = component.BlockData.Span;
int k = this.specStart;
int e = this.specEnd;
while (k <= e)
@ -750,7 +751,7 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
k += r;
byte z = QuantizationTables.DctZigZag[k];
component.BlockData[offset + z] = (short)(this.ReceiveAndExtend(s, stream) * (1 << this.successiveState));
componentBlockDataSpan[offset + z] = (short)(this.ReceiveAndExtend(s, stream) * (1 << this.successiveState));
k++;
}
}
@ -761,6 +762,7 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
int k = this.specStart;
int e = this.specEnd;
int r = 0;
var componentBlockDataSpan = component.BlockData.Span;
while (k <= e)
{
byte z = QuantizationTables.DctZigZag[k];
@ -802,7 +804,7 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
continue;
case 1: // Skipping r zero items
case 2:
if (component.BlockData[offset + z] != 0)
if (componentBlockDataSpan[offset + z] != 0)
{
int bit = this.ReadBit(stream);
if (this.endOfStreamReached || this.unexpectedMarkerReached)
@ -810,7 +812,7 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
return;
}
component.BlockData[offset + z] += (short)(bit << this.successiveState);
componentBlockDataSpan[offset + z] += (short)(bit << this.successiveState);
}
else
{
@ -823,7 +825,7 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
break;
case 3: // Set value for a zero item
if (component.BlockData[offset + z] != 0)
if (componentBlockDataSpan[offset + z] != 0)
{
int bit = this.ReadBit(stream);
if (this.endOfStreamReached || this.unexpectedMarkerReached)
@ -831,17 +833,17 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
return;
}
component.BlockData[offset + z] += (short)(bit << this.successiveState);
componentBlockDataSpan[offset + z] += (short)(bit << this.successiveState);
}
else
{
component.BlockData[offset + z] = (short)(this.successiveACNextValue << this.successiveState);
componentBlockDataSpan[offset + z] = (short)(this.successiveACNextValue << this.successiveState);
this.successiveACState = 0;
}
break;
case 4: // Eob
if (component.BlockData[offset + z] != 0)
if (componentBlockDataSpan[offset + z] != 0)
{
int bit = this.ReadBit(stream);
if (this.endOfStreamReached || this.unexpectedMarkerReached)
@ -849,7 +851,7 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
return;
}
component.BlockData[offset + z] += (short)(bit << this.successiveState);
componentBlockDataSpan[offset + z] += (short)(bit << this.successiveState);
}
break;

Loading…
Cancel
Save