Browse Source

Scan component count refactor

pull/1702/head
Dmitry Pentin 5 years ago
parent
commit
b299e1a2f7
  1. 24
      src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanScanDecoder.cs
  2. 8
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

24
src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanScanDecoder.cs

@ -22,6 +22,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
private JpegFrame frame; private JpegFrame frame;
private JpegComponent[] components; private JpegComponent[] components;
// The number of interleaved components.
private int componentsCount;
/// <summary> /// <summary>
/// The reset interval determined by RST markers. /// The reset interval determined by RST markers.
/// </summary> /// </summary>
@ -86,9 +89,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
} }
} }
// The number of interleaved components.
public int ComponentsLength { get; set; }
// The spectral selection start. // The spectral selection start.
public int SpectralStart { get; set; } public int SpectralStart { get; set; }
@ -104,10 +104,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
/// <summary> /// <summary>
/// Decodes the entropy coded data. /// Decodes the entropy coded data.
/// </summary> /// </summary>
public void ParseEntropyCodedData() public void ParseEntropyCodedData(int componentCount)
{ {
this.cancellationToken.ThrowIfCancellationRequested(); this.cancellationToken.ThrowIfCancellationRequested();
this.componentsCount = componentCount;
this.scanBuffer = new HuffmanScanBuffer(this.stream); this.scanBuffer = new HuffmanScanBuffer(this.stream);
bool fullScan = this.frame.Progressive || this.frame.MultiScan; bool fullScan = this.frame.Progressive || this.frame.MultiScan;
@ -138,7 +140,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
private void ParseBaselineData() private void ParseBaselineData()
{ {
if (this.ComponentsLength == this.frame.ComponentCount) if (this.componentsCount == this.frame.ComponentCount)
{ {
this.ParseBaselineDataInterleaved(); this.ParseBaselineDataInterleaved();
} }
@ -157,7 +159,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
ref HuffmanScanBuffer buffer = ref this.scanBuffer; ref HuffmanScanBuffer buffer = ref this.scanBuffer;
// Pre-derive the huffman table to avoid in-loop checks. // Pre-derive the huffman table to avoid in-loop checks.
for (int i = 0; i < this.ComponentsLength; i++) for (int i = 0; i < this.componentsCount; i++)
{ {
int order = this.frame.ComponentOrder[i]; int order = this.frame.ComponentOrder[i];
JpegComponent component = this.components[order]; JpegComponent component = this.components[order];
@ -177,7 +179,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
{ {
// Scan an interleaved mcu... process components in order // Scan an interleaved mcu... process components in order
int mcuCol = mcu % mcusPerLine; int mcuCol = mcu % mcusPerLine;
for (int k = 0; k < this.ComponentsLength; k++) for (int k = 0; k < this.componentsCount; k++)
{ {
int order = this.frame.ComponentOrder[k]; int order = this.frame.ComponentOrder[k];
JpegComponent component = this.components[order]; JpegComponent component = this.components[order];
@ -286,7 +288,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
} }
// AC scans may have only one component. // AC scans may have only one component.
if (this.ComponentsLength != 1) if (this.componentsCount != 1)
{ {
invalid = true; invalid = true;
} }
@ -318,7 +320,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
{ {
this.CheckProgressiveData(); this.CheckProgressiveData();
if (this.ComponentsLength == 1) if (this.componentsCount == 1)
{ {
this.ParseProgressiveDataNonInterleaved(); this.ParseProgressiveDataNonInterleaved();
} }
@ -337,7 +339,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
ref HuffmanScanBuffer buffer = ref this.scanBuffer; ref HuffmanScanBuffer buffer = ref this.scanBuffer;
// Pre-derive the huffman table to avoid in-loop checks. // Pre-derive the huffman table to avoid in-loop checks.
for (int k = 0; k < this.ComponentsLength; k++) for (int k = 0; k < this.componentsCount; k++)
{ {
int order = this.frame.ComponentOrder[k]; int order = this.frame.ComponentOrder[k];
JpegComponent component = this.components[order]; JpegComponent component = this.components[order];
@ -352,7 +354,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
// Scan an interleaved mcu... process components in order // Scan an interleaved mcu... process components in order
int mcuRow = mcu / mcusPerLine; int mcuRow = mcu / mcusPerLine;
int mcuCol = mcu % mcusPerLine; int mcuCol = mcu % mcusPerLine;
for (int k = 0; k < this.ComponentsLength; k++) for (int k = 0; k < this.componentsCount; k++)
{ {
int order = this.frame.ComponentOrder[k]; int order = this.frame.ComponentOrder[k];
JpegComponent component = this.components[order]; JpegComponent component = this.components[order];

8
src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

@ -1044,19 +1044,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
int spectralEnd = this.temp[1]; int spectralEnd = this.temp[1];
int successiveApproximation = this.temp[2]; int successiveApproximation = this.temp[2];
// All the comments below are for separate refactoring PR
// Main reason it's not fixed here is to make this commit less intrusive
// This can be passed as ParseEntropyCodedData() parameter as it is used only there
this.scanDecoder.ComponentsLength = selectorsCount;
// This is okay to inject here, might be good to wrap it in a separate struct but not really necessary // This is okay to inject here, might be good to wrap it in a separate struct but not really necessary
this.scanDecoder.SpectralStart = spectralStart; this.scanDecoder.SpectralStart = spectralStart;
this.scanDecoder.SpectralEnd = spectralEnd; this.scanDecoder.SpectralEnd = spectralEnd;
this.scanDecoder.SuccessiveHigh = successiveApproximation >> 4; this.scanDecoder.SuccessiveHigh = successiveApproximation >> 4;
this.scanDecoder.SuccessiveLow = successiveApproximation & 15; this.scanDecoder.SuccessiveLow = successiveApproximation & 15;
this.scanDecoder.ParseEntropyCodedData(); this.scanDecoder.ParseEntropyCodedData(selectorsCount);
} }
/// <summary> /// <summary>

Loading…
Cancel
Save