|
|
|
@ -148,11 +148,16 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder |
|
|
|
|
|
|
|
private void ParseBaselineData() |
|
|
|
{ |
|
|
|
if (this.componentsCount == this.frame.ComponentCount) |
|
|
|
if (this.componentsCount != 1) |
|
|
|
{ |
|
|
|
this.ParseBaselineDataInterleaved(); |
|
|
|
this.spectralConverter.CommitConversion(); |
|
|
|
} |
|
|
|
else if (this.frame.ComponentCount == 1) |
|
|
|
{ |
|
|
|
this.ParseBaselineDataSingleComponent(); |
|
|
|
this.spectralConverter.CommitConversion(); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
this.ParseBaselineDataNonInterleaved(); |
|
|
|
@ -161,7 +166,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder |
|
|
|
|
|
|
|
private void ParseBaselineDataInterleaved() |
|
|
|
{ |
|
|
|
// Interleaved
|
|
|
|
int mcu = 0; |
|
|
|
int mcusPerColumn = this.frame.McusPerColumn; |
|
|
|
int mcusPerLine = this.frame.McusPerLine; |
|
|
|
@ -198,7 +202,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder |
|
|
|
{ |
|
|
|
if (buffer.NoData) |
|
|
|
{ |
|
|
|
// It is very likely that some spectral data was decoded before we encountered EOI marker
|
|
|
|
// It is very likely that some spectral data was decoded before we've encountered 'end of scan'
|
|
|
|
// so we need to decode what's left and return (or maybe throw?)
|
|
|
|
this.spectralConverter.ConvertStrideBaseline(); |
|
|
|
return; |
|
|
|
@ -221,9 +225,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder |
|
|
|
this.HandleRestart(); |
|
|
|
} |
|
|
|
|
|
|
|
// convert from spectral to actual pixels via given converter
|
|
|
|
// Convert from spectral to actual pixels via given converter
|
|
|
|
this.spectralConverter.ConvertStrideBaseline(); |
|
|
|
} |
|
|
|
|
|
|
|
// Stride conversion must be sealed for stride conversion approach
|
|
|
|
this.spectralConverter.CommitConversion(); |
|
|
|
} |
|
|
|
|
|
|
|
private void ParseBaselineDataNonInterleaved() |
|
|
|
@ -261,6 +268,52 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void ParseBaselineDataSingleComponent() |
|
|
|
{ |
|
|
|
JpegComponent component = this.frame.Components[0]; |
|
|
|
int mcuLines = this.frame.McusPerColumn; |
|
|
|
int w = component.WidthInBlocks; |
|
|
|
int h = component.SamplingFactors.Height; |
|
|
|
ref HuffmanTable dcHuffmanTable = ref this.dcHuffmanTables[component.DCHuffmanTableId]; |
|
|
|
ref HuffmanTable acHuffmanTable = ref this.acHuffmanTables[component.ACHuffmanTableId]; |
|
|
|
|
|
|
|
ref HuffmanScanBuffer buffer = ref this.scanBuffer; |
|
|
|
|
|
|
|
for (int i = 0; i < mcuLines; i++) |
|
|
|
{ |
|
|
|
this.cancellationToken.ThrowIfCancellationRequested(); |
|
|
|
|
|
|
|
// decode from binary to spectral
|
|
|
|
for (int j = 0; j < h; j++) |
|
|
|
{ |
|
|
|
Span<Block8x8> blockSpan = component.SpectralBlocks.DangerousGetRowSpan(j); |
|
|
|
ref Block8x8 blockRef = ref MemoryMarshal.GetReference(blockSpan); |
|
|
|
|
|
|
|
for (int k = 0; k < w; k++) |
|
|
|
{ |
|
|
|
if (buffer.NoData) |
|
|
|
{ |
|
|
|
// It is very likely that some spectral data was decoded before we've encountered 'end of scan'
|
|
|
|
// so we need to decode what's left and return (or maybe throw?)
|
|
|
|
this.spectralConverter.ConvertStrideBaseline(); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
this.DecodeBlockBaseline( |
|
|
|
component, |
|
|
|
ref Unsafe.Add(ref blockRef, k), |
|
|
|
ref dcHuffmanTable, |
|
|
|
ref acHuffmanTable); |
|
|
|
|
|
|
|
this.HandleRestart(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Convert from spectral to actual pixels via given converter
|
|
|
|
this.spectralConverter.ConvertStrideBaseline(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void CheckProgressiveData() |
|
|
|
{ |
|
|
|
// Validate successive scan parameters.
|
|
|
|
|