Browse Source

Improve readability in scan decoder (less params, no discernable perf hit)

pull/549/head
James Jackson-South 8 years ago
parent
commit
2e96ff60ea
  1. 126
      src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsScanDecoder.cs

126
src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsScanDecoder.cs

@ -20,6 +20,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
private byte[] markerBuffer;
private int mcuToRead;
private int mcusPerLine;
private int mcu;
private int bitsData;
private int bitsCount;
@ -81,9 +87,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
this.unexpectedMarkerReached = false;
bool progressive = frame.Progressive;
int mcusPerLine = frame.McusPerLine;
this.mcusPerLine = frame.McusPerLine;
int mcu = 0;
this.mcu = 0;
int mcuExpected;
if (componentsLength == 1)
{
@ -91,13 +97,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
}
else
{
mcuExpected = mcusPerLine * frame.McusPerColumn;
mcuExpected = this.mcusPerLine * frame.McusPerColumn;
}
while (mcu < mcuExpected)
while (this.mcu < mcuExpected)
{
// Reset interval stuff
int mcuToRead = resetInterval != 0 ? Math.Min(mcuExpected - mcu, resetInterval) : mcuExpected;
this.mcuToRead = resetInterval != 0 ? Math.Min(mcuExpected - this.mcu, resetInterval) : mcuExpected;
for (int i = 0; i < components.Length; i++)
{
PdfJsFrameComponent c = components[i];
@ -108,17 +114,18 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
if (!progressive)
{
this.DecodeScanBaseline(dcHuffmanTables, acHuffmanTables, components, componentsLength, mcusPerLine, mcuToRead, ref mcu, stream);
this.DecodeScanBaseline(dcHuffmanTables, acHuffmanTables, components, componentsLength, stream);
}
else
{
bool isAc = this.specStart != 0;
bool isFirst = successivePrev == 0;
PdfJsHuffmanTables huffmanTables = isAc ? acHuffmanTables : dcHuffmanTables;
this.DecodeScanProgressive(huffmanTables, isAc, isFirst, components, componentsLength, mcusPerLine, mcuToRead, ref mcu, stream);
this.DecodeScanProgressive(huffmanTables, isAc, isFirst, components, componentsLength, stream);
}
// Reset
// TODO: I do not understand why these values are reset? We should surely be tracking the bits across mcu's?
this.bitsCount = 0;
this.bitsData = 0;
this.unexpectedMarkerReached = false;
@ -153,9 +160,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
PdfJsHuffmanTables acHuffmanTables,
PdfJsFrameComponent[] components,
int componentsLength,
int mcusPerLine,
int mcuToRead,
ref int mcu,
DoubleBufferedStreamReader stream)
{
if (componentsLength == 1)
@ -165,20 +169,20 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
ref PdfJsHuffmanTable dcHuffmanTable = ref dcHuffmanTables[component.DCHuffmanTableId];
ref PdfJsHuffmanTable acHuffmanTable = ref acHuffmanTables[component.ACHuffmanTableId];
for (int n = 0; n < mcuToRead; n++)
for (int n = 0; n < this.mcuToRead; n++)
{
if (this.endOfStreamReached || this.unexpectedMarkerReached)
{
continue;
}
this.DecodeBlockBaseline(ref dcHuffmanTable, ref acHuffmanTable, component, ref blockDataRef, mcu, stream);
mcu++;
this.DecodeBlockBaseline(ref dcHuffmanTable, ref acHuffmanTable, component, ref blockDataRef, stream);
this.mcu++;
}
}
else
{
for (int n = 0; n < mcuToRead; n++)
for (int n = 0; n < this.mcuToRead; n++)
{
for (int i = 0; i < componentsLength; i++)
{
@ -198,12 +202,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
continue;
}
this.DecodeMcuBaseline(ref dcHuffmanTable, ref acHuffmanTable, component, ref blockDataRef, mcusPerLine, mcu, j, k, stream);
this.DecodeMcuBaseline(ref dcHuffmanTable, ref acHuffmanTable, component, ref blockDataRef, j, k, stream);
}
}
}
mcu++;
this.mcu++;
}
}
}
@ -214,9 +218,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
bool isFirst,
PdfJsFrameComponent[] components,
int componentsLength,
int mcusPerLine,
int mcuToRead,
ref int mcu,
DoubleBufferedStreamReader stream)
{
if (componentsLength == 1)
@ -225,7 +226,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
ref short blockDataRef = ref MemoryMarshal.GetReference(MemoryMarshal.Cast<Block8x8, short>(component.SpectralBlocks.Span));
ref PdfJsHuffmanTable huffmanTable = ref huffmanTables[isAC ? component.ACHuffmanTableId : component.DCHuffmanTableId];
for (int n = 0; n < mcuToRead; n++)
for (int n = 0; n < this.mcuToRead; n++)
{
if (this.endOfStreamReached || this.unexpectedMarkerReached)
{
@ -236,31 +237,31 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
{
if (isFirst)
{
this.DecodeBlockACFirst(ref huffmanTable, component, ref blockDataRef, mcu, stream);
this.DecodeBlockACFirst(ref huffmanTable, component, ref blockDataRef, stream);
}
else
{
this.DecodeBlockACSuccessive(ref huffmanTable, component, ref blockDataRef, mcu, stream);
this.DecodeBlockACSuccessive(ref huffmanTable, component, ref blockDataRef, stream);
}
}
else
{
if (isFirst)
{
this.DecodeBlockDCFirst(ref huffmanTable, component, ref blockDataRef, mcu, stream);
this.DecodeBlockDCFirst(ref huffmanTable, component, ref blockDataRef, stream);
}
else
{
this.DecodeBlockDCSuccessive(component, ref blockDataRef, mcu, stream);
this.DecodeBlockDCSuccessive(component, ref blockDataRef, stream);
}
}
mcu++;
this.mcu++;
}
}
else
{
for (int n = 0; n < mcuToRead; n++)
for (int n = 0; n < this.mcuToRead; n++)
{
for (int i = 0; i < componentsLength; i++)
{
@ -284,47 +285,47 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
{
if (isFirst)
{
this.DecodeMcuACFirst(ref huffmanTable, component, ref blockDataRef, mcusPerLine, mcu, j, k, stream);
this.DecodeMcuACFirst(ref huffmanTable, component, ref blockDataRef, j, k, stream);
}
else
{
this.DecodeMcuACSuccessive(ref huffmanTable, component, ref blockDataRef, mcusPerLine, mcu, j, k, stream);
this.DecodeMcuACSuccessive(ref huffmanTable, component, ref blockDataRef, j, k, stream);
}
}
else
{
if (isFirst)
{
this.DecodeMcuDCFirst(ref huffmanTable, component, ref blockDataRef, mcusPerLine, mcu, j, k, stream);
this.DecodeMcuDCFirst(ref huffmanTable, component, ref blockDataRef, j, k, stream);
}
else
{
this.DecodeMcuDCSuccessive(component, ref blockDataRef, mcusPerLine, mcu, j, k, stream);
this.DecodeMcuDCSuccessive(component, ref blockDataRef, j, k, stream);
}
}
}
}
}
mcu++;
this.mcu++;
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DecodeBlockBaseline(ref PdfJsHuffmanTable dcHuffmanTable, ref PdfJsHuffmanTable acHuffmanTable, PdfJsFrameComponent component, ref short blockDataRef, int mcu, DoubleBufferedStreamReader stream)
private void DecodeBlockBaseline(ref PdfJsHuffmanTable dcHuffmanTable, ref PdfJsHuffmanTable acHuffmanTable, PdfJsFrameComponent component, ref short blockDataRef, DoubleBufferedStreamReader stream)
{
int blockRow = mcu / component.WidthInBlocks;
int blockCol = mcu % component.WidthInBlocks;
int blockRow = this.mcu / component.WidthInBlocks;
int blockCol = this.mcu % component.WidthInBlocks;
int offset = component.GetBlockBufferOffset(blockRow, blockCol);
this.DecodeBaseline(component, ref blockDataRef, offset, ref dcHuffmanTable, ref acHuffmanTable, stream);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DecodeMcuBaseline(ref PdfJsHuffmanTable dcHuffmanTable, ref PdfJsHuffmanTable acHuffmanTable, PdfJsFrameComponent component, ref short blockDataRef, int mcusPerLine, int mcu, int row, int col, DoubleBufferedStreamReader stream)
private void DecodeMcuBaseline(ref PdfJsHuffmanTable dcHuffmanTable, ref PdfJsHuffmanTable acHuffmanTable, PdfJsFrameComponent component, ref short blockDataRef, int row, int col, DoubleBufferedStreamReader stream)
{
int mcuRow = mcu / mcusPerLine;
int mcuCol = mcu % mcusPerLine;
int mcuRow = this.mcu / this.mcusPerLine;
int mcuCol = this.mcu % this.mcusPerLine;
int blockRow = (mcuRow * component.VerticalSamplingFactor) + row;
int blockCol = (mcuCol * component.HorizontalSamplingFactor) + col;
int offset = component.GetBlockBufferOffset(blockRow, blockCol);
@ -332,19 +333,19 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DecodeBlockDCFirst(ref PdfJsHuffmanTable dcHuffmanTable, PdfJsFrameComponent component, ref short blockDataRef, int mcu, DoubleBufferedStreamReader stream)
private void DecodeBlockDCFirst(ref PdfJsHuffmanTable dcHuffmanTable, PdfJsFrameComponent component, ref short blockDataRef, DoubleBufferedStreamReader stream)
{
int blockRow = mcu / component.WidthInBlocks;
int blockCol = mcu % component.WidthInBlocks;
int blockRow = this.mcu / component.WidthInBlocks;
int blockCol = this.mcu % component.WidthInBlocks;
int offset = component.GetBlockBufferOffset(blockRow, blockCol);
this.DecodeDCFirst(component, ref blockDataRef, offset, ref dcHuffmanTable, stream);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DecodeMcuDCFirst(ref PdfJsHuffmanTable dcHuffmanTable, PdfJsFrameComponent component, ref short blockDataRef, int mcusPerLine, int mcu, int row, int col, DoubleBufferedStreamReader stream)
private void DecodeMcuDCFirst(ref PdfJsHuffmanTable dcHuffmanTable, PdfJsFrameComponent component, ref short blockDataRef, int row, int col, DoubleBufferedStreamReader stream)
{
int mcuRow = mcu / mcusPerLine;
int mcuCol = mcu % mcusPerLine;
int mcuRow = this.mcu / this.mcusPerLine;
int mcuCol = this.mcu % this.mcusPerLine;
int blockRow = (mcuRow * component.VerticalSamplingFactor) + row;
int blockCol = (mcuCol * component.HorizontalSamplingFactor) + col;
int offset = component.GetBlockBufferOffset(blockRow, blockCol);
@ -352,19 +353,19 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DecodeBlockDCSuccessive(PdfJsFrameComponent component, ref short blockDataRef, int mcu, DoubleBufferedStreamReader stream)
private void DecodeBlockDCSuccessive(PdfJsFrameComponent component, ref short blockDataRef, DoubleBufferedStreamReader stream)
{
int blockRow = mcu / component.WidthInBlocks;
int blockCol = mcu % component.WidthInBlocks;
int blockRow = this.mcu / component.WidthInBlocks;
int blockCol = this.mcu % component.WidthInBlocks;
int offset = component.GetBlockBufferOffset(blockRow, blockCol);
this.DecodeDCSuccessive(component, ref blockDataRef, offset, stream);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DecodeMcuDCSuccessive(PdfJsFrameComponent component, ref short blockDataRef, int mcusPerLine, int mcu, int row, int col, DoubleBufferedStreamReader stream)
private void DecodeMcuDCSuccessive(PdfJsFrameComponent component, ref short blockDataRef, int row, int col, DoubleBufferedStreamReader stream)
{
int mcuRow = mcu / mcusPerLine;
int mcuCol = mcu % mcusPerLine;
int mcuRow = this.mcu / this.mcusPerLine;
int mcuCol = this.mcu % this.mcusPerLine;
int blockRow = (mcuRow * component.VerticalSamplingFactor) + row;
int blockCol = (mcuCol * component.HorizontalSamplingFactor) + col;
int offset = component.GetBlockBufferOffset(blockRow, blockCol);
@ -372,19 +373,19 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DecodeBlockACFirst(ref PdfJsHuffmanTable acHuffmanTable, PdfJsFrameComponent component, ref short blockDataRef, int mcu, DoubleBufferedStreamReader stream)
private void DecodeBlockACFirst(ref PdfJsHuffmanTable acHuffmanTable, PdfJsFrameComponent component, ref short blockDataRef, DoubleBufferedStreamReader stream)
{
int blockRow = mcu / component.WidthInBlocks;
int blockCol = mcu % component.WidthInBlocks;
int blockRow = this.mcu / component.WidthInBlocks;
int blockCol = this.mcu % component.WidthInBlocks;
int offset = component.GetBlockBufferOffset(blockRow, blockCol);
this.DecodeACFirst(ref blockDataRef, offset, ref acHuffmanTable, stream);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DecodeMcuACFirst(ref PdfJsHuffmanTable acHuffmanTable, PdfJsFrameComponent component, ref short blockDataRef, int mcusPerLine, int mcu, int row, int col, DoubleBufferedStreamReader stream)
private void DecodeMcuACFirst(ref PdfJsHuffmanTable acHuffmanTable, PdfJsFrameComponent component, ref short blockDataRef, int row, int col, DoubleBufferedStreamReader stream)
{
int mcuRow = mcu / mcusPerLine;
int mcuCol = mcu % mcusPerLine;
int mcuRow = this.mcu / this.mcusPerLine;
int mcuCol = this.mcu % this.mcusPerLine;
int blockRow = (mcuRow * component.VerticalSamplingFactor) + row;
int blockCol = (mcuCol * component.HorizontalSamplingFactor) + col;
int offset = component.GetBlockBufferOffset(blockRow, blockCol);
@ -392,19 +393,19 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DecodeBlockACSuccessive(ref PdfJsHuffmanTable acHuffmanTable, PdfJsFrameComponent component, ref short blockDataRef, int mcu, DoubleBufferedStreamReader stream)
private void DecodeBlockACSuccessive(ref PdfJsHuffmanTable acHuffmanTable, PdfJsFrameComponent component, ref short blockDataRef, DoubleBufferedStreamReader stream)
{
int blockRow = mcu / component.WidthInBlocks;
int blockCol = mcu % component.WidthInBlocks;
int blockRow = this.mcu / component.WidthInBlocks;
int blockCol = this.mcu % component.WidthInBlocks;
int offset = component.GetBlockBufferOffset(blockRow, blockCol);
this.DecodeACSuccessive(ref blockDataRef, offset, ref acHuffmanTable, stream);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DecodeMcuACSuccessive(ref PdfJsHuffmanTable acHuffmanTable, PdfJsFrameComponent component, ref short blockDataRef, int mcusPerLine, int mcu, int row, int col, DoubleBufferedStreamReader stream)
private void DecodeMcuACSuccessive(ref PdfJsHuffmanTable acHuffmanTable, PdfJsFrameComponent component, ref short blockDataRef, int row, int col, DoubleBufferedStreamReader stream)
{
int mcuRow = mcu / mcusPerLine;
int mcuCol = mcu % mcusPerLine;
int mcuRow = this.mcu / this.mcusPerLine;
int mcuCol = this.mcu % this.mcusPerLine;
int blockRow = (mcuRow * component.VerticalSamplingFactor) + row;
int blockCol = (mcuCol * component.HorizontalSamplingFactor) + col;
int offset = component.GetBlockBufferOffset(blockRow, blockCol);
@ -433,8 +434,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
{
// TODO: Read more then 1 byte at a time.
// In LibJpegTurbo this is be 25 bits (32-7) but I cannot get this to work
// for some images, I'm assuming because I am crossing MCU boundaries and not managing
// to detect it.
// for some images, I'm assuming because I am crossing MCU boundaries and not maintining the correct buffer state.
const int MinGetBits = 7;
if (!this.unexpectedMarkerReached)

Loading…
Cancel
Save