Browse Source

Implemented new spectral buffers allocation

pull/1694/head
Dmitry Pentin 5 years ago
parent
commit
639ed629a8
  1. 4
      src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanScanDecoder.cs
  2. 12
      src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponent.cs
  3. 9
      src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegFrame.cs
  4. 3
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

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

@ -128,10 +128,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
{
if (this.componentsLength == 1)
{
this.frame.AllocateComponents(fullScan: true);
this.ParseBaselineDataNonInterleaved();
}
else
{
// interleaved baseline is the only place where we can optimize memory footprint via reusing single spectral stride
this.frame.AllocateComponents(fullScan: false);
this.ParseBaselineDataInterleaved();
}
}
@ -305,6 +308,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
{
this.CheckProgressiveData();
this.frame.AllocateComponents(fullScan: true);
if (this.componentsLength == 1)
{
this.ParseProgressiveDataNonInterleaved();

12
src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponent.cs

@ -125,6 +125,18 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
{
JpegThrowHelper.ThrowBadSampling();
}
}
public void AllocateSpectral(bool fullScan)
{
if (this.SpectralBlocks != null)
{
// this method will be called each scan marker so we need to allocate only once
return;
}
int blocksPerLineForMcu = this.Frame.McusPerLine * this.HorizontalSamplingFactor;
int blocksPerColumnForMcu = fullScan ? this.Frame.McusPerColumn * this.VerticalSamplingFactor : this.VerticalSamplingFactor;
int totalNumberOfBlocks = blocksPerColumnForMcu * (blocksPerLineForMcu + 1);
int width = this.WidthInBlocks + 1;

9
src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegFrame.cs

@ -104,5 +104,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
component.Init();
}
}
public void AllocateComponents(bool fullScan)
{
for (int i = 0; i < this.ComponentCount; i++)
{
JpegComponent component = this.Components[i];
component.AllocateSpectral(fullScan);
}
}
}
}

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

@ -921,9 +921,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
this.Frame.MaxVerticalFactor = maxV;
this.ColorSpace = this.DeduceJpegColorSpace();
this.Metadata.GetJpegMetadata().ColorType = this.ColorSpace == JpegColorSpace.Grayscale ? JpegColorType.Luminance : JpegColorType.YCbCr;
this.Frame.InitComponents();
this.ImageSizeInMCU = new Size(this.Frame.McusPerLine, this.Frame.McusPerColumn);
this.Frame.InitComponents();
// This can be injected in SOF marker callback
this.scanDecoder.InjectFrameData(this.Frame, this);
}

Loading…
Cancel
Save