Browse Source

Added SOF data precision comments, decoupled precision value from decoder core

pull/1702/head
Dmitry Pentin 5 years ago
parent
commit
9067c64b30
  1. 7
      src/ImageSharp/Formats/Jpeg/Components/Decoder/IRawJpegData.cs
  2. 6
      src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockPostProcessor.cs
  3. 13
      src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentPostProcessor.cs
  4. 2
      src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs
  5. 18
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

7
src/ImageSharp/Formats/Jpeg/Components/Decoder/IRawJpegData.cs

@ -26,11 +26,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
/// </summary>
JpegColorSpace ColorSpace { get; }
/// <summary>
/// Gets the number of bits used for precision.
/// </summary>
int Precision { get; }
/// <summary>
/// Gets the components.
/// </summary>
@ -41,4 +36,4 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
/// </summary>
Block8x8F[] QuantizationTables { get; }
}
}
}

6
src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockPostProcessor.cs

@ -38,11 +38,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
/// </summary>
private Size subSamplingDivisors;
/// <summary>
/// Defines the maximum value derived from the bitdepth.
/// </summary>
private readonly int maximumValue;
/// <summary>
/// Initializes a new instance of the <see cref="JpegBlockPostProcessor"/> struct.
/// </summary>
@ -53,7 +48,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
int qtIndex = component.QuantizationTableIndex;
this.DequantiazationTable = ZigZag.CreateDequantizationTable(ref decoder.QuantizationTables[qtIndex]);
this.subSamplingDivisors = component.SubSamplingDivisors;
this.maximumValue = (int)MathF.Pow(2, decoder.Precision) - 1;
this.SourceBlock = default;
this.WorkspaceBlock1 = default;

13
src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentPostProcessor.cs

@ -21,11 +21,18 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
/// </summary>
private readonly Size blockAreaSize;
/// <summary>
/// Jpeg frame instance containing required decoding metadata.
/// </summary>
private readonly JpegFrame frame;
/// <summary>
/// Initializes a new instance of the <see cref="JpegComponentPostProcessor"/> class.
/// </summary>
public JpegComponentPostProcessor(MemoryAllocator memoryAllocator, IRawJpegData rawJpeg, Size postProcessorBufferSize, IJpegComponent component)
public JpegComponentPostProcessor(MemoryAllocator memoryAllocator, JpegFrame frame, IRawJpegData rawJpeg, Size postProcessorBufferSize, IJpegComponent component)
{
this.frame = frame;
this.Component = component;
this.RawJpeg = rawJpeg;
this.blockAreaSize = this.Component.SubSamplingDivisors * 8;
@ -70,7 +77,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
Buffer2D<Block8x8> spectralBuffer = this.Component.SpectralBlocks;
var blockPp = new JpegBlockPostProcessor(this.RawJpeg, this.Component);
float maximumValue = MathF.Pow(2, this.RawJpeg.Precision) - 1;
// TODO: this is a constant value for ALL components
float maximumValue = MathF.Pow(2, this.frame.Precision) - 1;
int destAreaStride = this.ColorBuffer.Width;

2
src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs

@ -78,7 +78,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
this.componentProcessors = new JpegComponentPostProcessor[frame.Components.Length];
for (int i = 0; i < this.componentProcessors.Length; i++)
{
this.componentProcessors[i] = new JpegComponentPostProcessor(allocator, jpegData, postProcessorBufferSize, frame.Components[i]);
this.componentProcessors[i] = new JpegComponentPostProcessor(allocator, frame, jpegData, postProcessorBufferSize, frame.Components[i]);
}
// single 'stride' rgba32 buffer for conversion between spectral and TPixel

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

@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// <summary>
/// The only supported precision
/// </summary>
private readonly int[] supportedPrecisions = { 8, 12 };
private readonly byte[] supportedPrecisions = { 8, 12 };
/// <summary>
/// The buffer used to temporarily store bytes read from the stream.
@ -148,9 +148,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// <inheritdoc/>
public JpegColorSpace ColorSpace { get; private set; }
/// <inheritdoc/>
public int Precision { get; private set; }
/// <summary>
/// Gets the components.
/// </summary>
@ -825,23 +822,24 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
JpegThrowHelper.ThrowInvalidImageContentException("Multiple SOF markers. Only single frame jpegs supported.");
}
// Read initial marker definitions.
// Read initial marker definitions
const int length = 6;
stream.Read(this.temp, 0, length);
// We only support 8-bit and 12-bit precision.
if (Array.IndexOf(this.supportedPrecisions, this.temp[0]) == -1)
// 1 byte: Bits/sample precision
byte precision = this.temp[0];
// Validity check: only 8-bit and 12-bit precisions are supported
if (Array.IndexOf(this.supportedPrecisions, precision) == -1)
{
JpegThrowHelper.ThrowInvalidImageContentException("Only 8-Bit and 12-Bit precision supported.");
}
this.Precision = this.temp[0];
this.Frame = new JpegFrame
{
Extended = frameMarker.Marker == JpegConstants.Markers.SOF1,
Progressive = frameMarker.Marker == JpegConstants.Markers.SOF2,
Precision = this.temp[0],
Precision = precision,
PixelHeight = (this.temp[1] << 8) | this.temp[2],
PixelWidth = (this.temp[3] << 8) | this.temp[4],
ComponentCount = this.temp[5]

Loading…
Cancel
Save