Browse Source

Fix HEIF XML summary formatting

pull/2633/head
James Jackson-South 2 months ago
parent
commit
4845399030
  1. 88
      src/ImageSharp/Formats/Heif/Av1/Av1BlockSize.cs
  2. 164
      src/ImageSharp/Formats/Heif/Hevc/HevcCabacContexts.cs
  3. 148
      src/ImageSharp/Formats/Heif/Hevc/HevcCabacSyntaxReader.cs
  4. 64
      src/ImageSharp/Formats/Heif/Hevc/HevcCodingTreeState.cs
  5. 84
      src/ImageSharp/Formats/Heif/Hevc/HevcIntraPredictionState.cs
  6. 72
      src/ImageSharp/Formats/Heif/Hevc/HevcPictureBuffer.cs
  7. 180
      src/ImageSharp/Formats/Heif/Hevc/HevcPictureParameterSet.cs
  8. 12
      src/ImageSharp/Formats/Heif/Hevc/HevcPlane.cs
  9. 196
      src/ImageSharp/Formats/Heif/Hevc/HevcSequenceParameterSet.cs
  10. 76
      src/ImageSharp/Formats/Heif/Hevc/HevcSliceSegmentHeader.cs

88
src/ImageSharp/Formats/Heif/Av1/Av1BlockSize.cs

@ -8,70 +8,114 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1;
/// </summary>
internal enum Av1BlockSize : byte
{
/// <summary>A block of samples, 4 samples wide and 4 samples high.</summary>
/// <summary>
/// A block of samples, 4 samples wide and 4 samples high.
/// </summary>
Block4x4 = 0,
/// <summary>A block of samples, 4 samples wide and 8 samples high.</summary>
/// <summary>
/// A block of samples, 4 samples wide and 8 samples high.
/// </summary>
Block4x8 = 1,
/// <summary>A block of samples, 8 samples wide and 4 samples high.</summary>
/// <summary>
/// A block of samples, 8 samples wide and 4 samples high.
/// </summary>
Block8x4 = 2,
/// <summary>A block of samples, 8 samples wide and 8 samples high.</summary>
/// <summary>
/// A block of samples, 8 samples wide and 8 samples high.
/// </summary>
Block8x8 = 3,
/// <summary>A block of samples, 8 samples wide and 16 samples high.</summary>
/// <summary>
/// A block of samples, 8 samples wide and 16 samples high.
/// </summary>
Block8x16 = 4,
/// <summary>A block of samples, 16 samples wide and 8 samples high.</summary>
/// <summary>
/// A block of samples, 16 samples wide and 8 samples high.
/// </summary>
Block16x8 = 5,
/// <summary>A block of samples, 16 samples wide and 16 samples high.</summary>
/// <summary>
/// A block of samples, 16 samples wide and 16 samples high.
/// </summary>
Block16x16 = 6,
/// <summary>A block of samples, 16 samples wide and 32 samples high.</summary>
/// <summary>
/// A block of samples, 16 samples wide and 32 samples high.
/// </summary>
Block16x32 = 7,
/// <summary>A block of samples, 32 samples wide and 16 samples high.</summary>
/// <summary>
/// A block of samples, 32 samples wide and 16 samples high.
/// </summary>
Block32x16 = 8,
/// <summary>A block of samples, 32 samples wide and 32 samples high.</summary>
/// <summary>
/// A block of samples, 32 samples wide and 32 samples high.
/// </summary>
Block32x32 = 9,
/// <summary>A block of samples, 32 samples wide and 64 samples high.</summary>
/// <summary>
/// A block of samples, 32 samples wide and 64 samples high.
/// </summary>
Block32x64 = 10,
/// <summary>A block of samples, 64 samples wide and 32 samples high.</summary>
/// <summary>
/// A block of samples, 64 samples wide and 32 samples high.
/// </summary>
Block64x32 = 11,
/// <summary>A block of samples, 64 samples wide and 64 samples high.</summary>
/// <summary>
/// A block of samples, 64 samples wide and 64 samples high.
/// </summary>
Block64x64 = 12,
/// <summary>A block of samples, 64 samples wide and 128 samples high.</summary>
/// <summary>
/// A block of samples, 64 samples wide and 128 samples high.
/// </summary>
Block64x128 = 13,
/// <summary>A block of samples, 128 samples wide and 64 samples high.</summary>
/// <summary>
/// A block of samples, 128 samples wide and 64 samples high.
/// </summary>
Block128x64 = 14,
/// <summary>A block of samples, 128 samples wide and 128 samples high.</summary>
/// <summary>
/// A block of samples, 128 samples wide and 128 samples high.
/// </summary>
Block128x128 = 15,
/// <summary>A block of samples, 4 samples wide and 16 samples high.</summary>
/// <summary>
/// A block of samples, 4 samples wide and 16 samples high.
/// </summary>
Block4x16 = 16,
/// <summary>A block of samples, 16 samples wide and 4 samples high.</summary>
/// <summary>
/// A block of samples, 16 samples wide and 4 samples high.
/// </summary>
Block16x4 = 17,
/// <summary>A block of samples, 8 samples wide and 32 samples high.</summary>
/// <summary>
/// A block of samples, 8 samples wide and 32 samples high.
/// </summary>
Block8x32 = 18,
/// <summary>A block of samples, 32 samples wide and 8 samples high.</summary>
/// <summary>
/// A block of samples, 32 samples wide and 8 samples high.
/// </summary>
Block32x8 = 19,
/// <summary>A block of samples, 16 samples wide and 64 samples high.</summary>
/// <summary>
/// A block of samples, 16 samples wide and 64 samples high.
/// </summary>
Block16x64 = 20,
/// <summary>A block of samples, 64 samples wide and 16 samples high.</summary>
/// <summary>
/// A block of samples, 64 samples wide and 16 samples high.
/// </summary>
Block64x16 = 21,
/// <summary>

164
src/ImageSharp/Formats/Heif/Hevc/HevcCabacContexts.cs

@ -8,67 +8,109 @@ namespace SixLabors.ImageSharp.Formats.Heif.Hevc;
/// </summary>
internal sealed class HevcCabacContexts
{
/// <summary>The first transquant-bypass context.</summary>
/// <summary>
/// The first transquant-bypass context.
/// </summary>
private const int TransquantBypassOffset = 0;
/// <summary>The first coding-unit split context.</summary>
/// <summary>
/// The first coding-unit split context.
/// </summary>
private const int SplitOffset = 1;
/// <summary>The intra partition-size context.</summary>
/// <summary>
/// The intra partition-size context.
/// </summary>
private const int PartitionSizeOffset = 4;
/// <summary>The luma intra-prediction context.</summary>
/// <summary>
/// The luma intra-prediction context.
/// </summary>
private const int IntraPredictionOffset = 5;
/// <summary>The first chroma intra-prediction context.</summary>
/// <summary>
/// The first chroma intra-prediction context.
/// </summary>
private const int ChromaPredictionOffset = 6;
/// <summary>The first luma quantization-delta context.</summary>
/// <summary>
/// The first luma quantization-delta context.
/// </summary>
private const int DeltaQuantizationOffset = 8;
/// <summary>The chroma quantization-adjustment flag context.</summary>
/// <summary>
/// The chroma quantization-adjustment flag context.
/// </summary>
private const int ChromaQuantizationAdjustmentFlagOffset = 11;
/// <summary>The chroma quantization-adjustment index context.</summary>
/// <summary>
/// The chroma quantization-adjustment index context.
/// </summary>
private const int ChromaQuantizationAdjustmentIndexOffset = 12;
/// <summary>The first transform-tree coded-block-flag context.</summary>
/// <summary>
/// The first transform-tree coded-block-flag context.
/// </summary>
private const int TransformCodedBlockFlagOffset = 13;
/// <summary>The first horizontal last-significant-coefficient context.</summary>
/// <summary>
/// The first horizontal last-significant-coefficient context.
/// </summary>
private const int LastSignificantXOffset = 23;
/// <summary>The first vertical last-significant-coefficient context.</summary>
/// <summary>
/// The first vertical last-significant-coefficient context.
/// </summary>
private const int LastSignificantYOffset = 53;
/// <summary>The first significant-coefficient-group context.</summary>
/// <summary>
/// The first significant-coefficient-group context.
/// </summary>
private const int SignificantCoefficientGroupOffset = 83;
/// <summary>The first significant-coefficient context.</summary>
/// <summary>
/// The first significant-coefficient context.
/// </summary>
private const int SignificantCoefficientOffset = 87;
/// <summary>The first greater-than-one coefficient-level context.</summary>
/// <summary>
/// The first greater-than-one coefficient-level context.
/// </summary>
private const int GreaterThanOneOffset = 131;
/// <summary>The first greater-than-two coefficient-level context.</summary>
/// <summary>
/// The first greater-than-two coefficient-level context.
/// </summary>
private const int GreaterThanTwoOffset = 155;
/// <summary>The sample-adaptive-offset merge context.</summary>
/// <summary>
/// The sample-adaptive-offset merge context.
/// </summary>
private const int SampleAdaptiveOffsetMergeOffset = 161;
/// <summary>The sample-adaptive-offset type context.</summary>
/// <summary>
/// The sample-adaptive-offset type context.
/// </summary>
private const int SampleAdaptiveOffsetTypeOffset = 162;
/// <summary>The first transform-tree subdivision context.</summary>
/// <summary>
/// The first transform-tree subdivision context.
/// </summary>
private const int TransformSubdivisionOffset = 163;
/// <summary>The first transform-skip context.</summary>
/// <summary>
/// The first transform-skip context.
/// </summary>
private const int TransformSkipOffset = 166;
/// <summary>The first cross-component prediction context.</summary>
/// <summary>
/// The first cross-component prediction context.
/// </summary>
private const int CrossComponentPredictionOffset = 168;
/// <summary>The number of contexts used by the independently coded intra-picture syntax.</summary>
/// <summary>
/// The number of contexts used by the independently coded intra-picture syntax.
/// </summary>
private const int ContextCount = 178;
/// <summary>
@ -154,72 +196,112 @@ internal sealed class HevcCabacContexts
}
}
/// <summary>Gets the coding-unit transquant-bypass context.</summary>
/// <summary>
/// Gets the coding-unit transquant-bypass context.
/// </summary>
public Span<HevcCabacContext> TransquantBypass => this.contexts.AsSpan(TransquantBypassOffset, 1);
/// <summary>Gets the coding-unit split contexts, ordered by neighboring split depth.</summary>
/// <summary>
/// Gets the coding-unit split contexts, ordered by neighboring split depth.
/// </summary>
public Span<HevcCabacContext> Split => this.contexts.AsSpan(SplitOffset, 3);
/// <summary>Gets the intra partition-size context.</summary>
/// <summary>
/// Gets the intra partition-size context.
/// </summary>
public Span<HevcCabacContext> PartitionSize => this.contexts.AsSpan(PartitionSizeOffset, 1);
/// <summary>Gets the luma intra-prediction context.</summary>
/// <summary>
/// Gets the luma intra-prediction context.
/// </summary>
public Span<HevcCabacContext> IntraPrediction => this.contexts.AsSpan(IntraPredictionOffset, 1);
/// <summary>Gets the chroma intra-prediction contexts.</summary>
/// <summary>
/// Gets the chroma intra-prediction contexts.
/// </summary>
public Span<HevcCabacContext> ChromaPrediction => this.contexts.AsSpan(ChromaPredictionOffset, 2);
/// <summary>Gets the luma quantization-delta contexts.</summary>
/// <summary>
/// Gets the luma quantization-delta contexts.
/// </summary>
public Span<HevcCabacContext> DeltaQuantization => this.contexts.AsSpan(DeltaQuantizationOffset, 3);
/// <summary>Gets the chroma quantization-adjustment flag context.</summary>
/// <summary>
/// Gets the chroma quantization-adjustment flag context.
/// </summary>
public Span<HevcCabacContext> ChromaQuantizationAdjustmentFlag =>
this.contexts.AsSpan(ChromaQuantizationAdjustmentFlagOffset, 1);
/// <summary>Gets the chroma quantization-adjustment index context.</summary>
/// <summary>
/// Gets the chroma quantization-adjustment index context.
/// </summary>
public Span<HevcCabacContext> ChromaQuantizationAdjustmentIndex =>
this.contexts.AsSpan(ChromaQuantizationAdjustmentIndexOffset, 1);
/// <summary>Gets the transform-tree coded-block-flag contexts, with luma preceding chroma.</summary>
/// <summary>
/// Gets the transform-tree coded-block-flag contexts, with luma preceding chroma.
/// </summary>
public Span<HevcCabacContext> TransformCodedBlockFlag =>
this.contexts.AsSpan(TransformCodedBlockFlagOffset, 10);
/// <summary>Gets the horizontal last-significant-coefficient contexts, with luma preceding chroma.</summary>
/// <summary>
/// Gets the horizontal last-significant-coefficient contexts, with luma preceding chroma.
/// </summary>
public Span<HevcCabacContext> LastSignificantX => this.contexts.AsSpan(LastSignificantXOffset, 30);
/// <summary>Gets the vertical last-significant-coefficient contexts, with luma preceding chroma.</summary>
/// <summary>
/// Gets the vertical last-significant-coefficient contexts, with luma preceding chroma.
/// </summary>
public Span<HevcCabacContext> LastSignificantY => this.contexts.AsSpan(LastSignificantYOffset, 30);
/// <summary>Gets the significant-coefficient-group contexts, with luma preceding chroma.</summary>
/// <summary>
/// Gets the significant-coefficient-group contexts, with luma preceding chroma.
/// </summary>
public Span<HevcCabacContext> SignificantCoefficientGroup =>
this.contexts.AsSpan(SignificantCoefficientGroupOffset, 4);
/// <summary>Gets the significant-coefficient contexts, with luma preceding chroma.</summary>
/// <summary>
/// Gets the significant-coefficient contexts, with luma preceding chroma.
/// </summary>
public Span<HevcCabacContext> SignificantCoefficient =>
this.contexts.AsSpan(SignificantCoefficientOffset, 44);
/// <summary>Gets the greater-than-one coefficient-level contexts, with luma preceding chroma.</summary>
/// <summary>
/// Gets the greater-than-one coefficient-level contexts, with luma preceding chroma.
/// </summary>
public Span<HevcCabacContext> GreaterThanOne => this.contexts.AsSpan(GreaterThanOneOffset, 24);
/// <summary>Gets the greater-than-two coefficient-level contexts, with luma preceding chroma.</summary>
/// <summary>
/// Gets the greater-than-two coefficient-level contexts, with luma preceding chroma.
/// </summary>
public Span<HevcCabacContext> GreaterThanTwo => this.contexts.AsSpan(GreaterThanTwoOffset, 6);
/// <summary>Gets the sample-adaptive-offset merge context.</summary>
/// <summary>
/// Gets the sample-adaptive-offset merge context.
/// </summary>
public Span<HevcCabacContext> SampleAdaptiveOffsetMerge =>
this.contexts.AsSpan(SampleAdaptiveOffsetMergeOffset, 1);
/// <summary>Gets the sample-adaptive-offset type context.</summary>
/// <summary>
/// Gets the sample-adaptive-offset type context.
/// </summary>
public Span<HevcCabacContext> SampleAdaptiveOffsetType =>
this.contexts.AsSpan(SampleAdaptiveOffsetTypeOffset, 1);
/// <summary>Gets the transform-tree subdivision contexts.</summary>
/// <summary>
/// Gets the transform-tree subdivision contexts.
/// </summary>
public Span<HevcCabacContext> TransformSubdivision =>
this.contexts.AsSpan(TransformSubdivisionOffset, 3);
/// <summary>Gets the transform-skip contexts, with luma preceding chroma.</summary>
/// <summary>
/// Gets the transform-skip contexts, with luma preceding chroma.
/// </summary>
public Span<HevcCabacContext> TransformSkip => this.contexts.AsSpan(TransformSkipOffset, 2);
/// <summary>Gets the cross-component prediction contexts, with Cb preceding Cr.</summary>
/// <summary>
/// Gets the cross-component prediction contexts, with Cb preceding Cr.
/// </summary>
public Span<HevcCabacContext> CrossComponentPrediction =>
this.contexts.AsSpan(CrossComponentPredictionOffset, 10);
}

148
src/ImageSharp/Formats/Heif/Hevc/HevcCabacSyntaxReader.cs

@ -8,16 +8,24 @@ namespace SixLabors.ImageSharp.Formats.Heif.Hevc;
/// </summary>
internal ref struct HevcCabacSyntaxReader
{
/// <summary>The truncated-unary cutoff for a coding-unit luma quantization delta.</summary>
/// <summary>
/// The truncated-unary cutoff for a coding-unit luma quantization delta.
/// </summary>
private const int DeltaQuantizationCutoff = 5;
/// <summary>The prefix length at which coefficient levels switch from Rice to exponential-Golomb coding.</summary>
/// <summary>
/// The prefix length at which coefficient levels switch from Rice to exponential-Golomb coding.
/// </summary>
private const int CoefficientRemainingReduction = 3;
/// <summary>The binary arithmetic decoder for the current entropy substream.</summary>
/// <summary>
/// The binary arithmetic decoder for the current entropy substream.
/// </summary>
private HevcCabacDecoder decoder;
/// <summary>The adaptive intra-picture probability contexts for the current entropy substream.</summary>
/// <summary>
/// The adaptive intra-picture probability contexts for the current entropy substream.
/// </summary>
private readonly HevcCabacContexts contexts;
/// <summary>
@ -32,10 +40,14 @@ internal ref struct HevcCabacSyntaxReader
this.contexts = new HevcCabacContexts(quantizationParameter);
}
/// <summary>Gets the number of entropy-substream bytes loaded by the arithmetic decoder.</summary>
/// <summary>
/// Gets the number of entropy-substream bytes loaded by the arithmetic decoder.
/// </summary>
public readonly int BytesConsumed => this.decoder.BytesConsumed;
/// <summary>Decodes the coding-unit transquant-bypass flag.</summary>
/// <summary>
/// Decodes the coding-unit transquant-bypass flag.
/// </summary>
/// <returns>The decoded flag value.</returns>
public bool ReadTransquantBypass()
{
@ -43,7 +55,9 @@ internal ref struct HevcCabacSyntaxReader
return this.decoder.ReadDecision(ref selectedContexts[0]);
}
/// <summary>Decodes a coding-unit split flag.</summary>
/// <summary>
/// Decodes a coding-unit split flag.
/// </summary>
/// <param name="contextIndex">The context derived from the available neighboring coding-unit depths.</param>
/// <returns>The decoded flag value.</returns>
public bool ReadSplit(int contextIndex)
@ -53,7 +67,9 @@ internal ref struct HevcCabacSyntaxReader
return this.decoder.ReadDecision(ref selectedContexts[contextIndex]);
}
/// <summary>Decodes whether a minimum-size intra coding unit uses four square prediction partitions.</summary>
/// <summary>
/// Decodes whether a minimum-size intra coding unit uses four square prediction partitions.
/// </summary>
/// <param name="isMinimumCodingBlockSize">
/// A value indicating whether the coding unit is at the minimum coding-block size.
/// </param>
@ -71,7 +87,9 @@ internal ref struct HevcCabacSyntaxReader
return !this.decoder.ReadDecision(ref selectedContexts[0]);
}
/// <summary>Decodes whether a luma intra mode is selected from the three most-probable modes.</summary>
/// <summary>
/// Decodes whether a luma intra mode is selected from the three most-probable modes.
/// </summary>
/// <returns>The decoded flag value.</returns>
public bool ReadPreviousIntraLumaPredictionFlag()
{
@ -79,7 +97,9 @@ internal ref struct HevcCabacSyntaxReader
return this.decoder.ReadDecision(ref selectedContexts[0]);
}
/// <summary>Decodes the zero-based selector for one of the three most-probable luma intra modes.</summary>
/// <summary>
/// Decodes the zero-based selector for one of the three most-probable luma intra modes.
/// </summary>
/// <returns>The selector in the inclusive range zero through two.</returns>
public int ReadMostProbableIntraLumaPredictionIndex()
{
@ -91,11 +111,15 @@ internal ref struct HevcCabacSyntaxReader
return this.decoder.ReadBypass() ? 2 : 1;
}
/// <summary>Decodes the five-bit selector for a luma intra mode outside the most-probable set.</summary>
/// <summary>
/// Decodes the five-bit selector for a luma intra mode outside the most-probable set.
/// </summary>
/// <returns>The decoded selector in the inclusive range zero through thirty-one.</returns>
public int ReadRemainingIntraLumaPredictionMode() => (int)this.decoder.ReadBypassBits(5);
/// <summary>Decodes the chroma intra prediction selector.</summary>
/// <summary>
/// Decodes the chroma intra prediction selector.
/// </summary>
/// <returns>
/// Negative one when chroma derives its mode from luma; otherwise, the decoded selector in the inclusive range
/// zero through three.
@ -111,7 +135,9 @@ internal ref struct HevcCabacSyntaxReader
return (int)this.decoder.ReadBypassBits(2);
}
/// <summary>Decodes a transform-tree subdivision flag.</summary>
/// <summary>
/// Decodes a transform-tree subdivision flag.
/// </summary>
/// <param name="log2TransformBlockSize">The base-two logarithm of the current transform-block size.</param>
/// <returns>The decoded flag value.</returns>
public bool ReadTransformSubdivision(int log2TransformBlockSize)
@ -121,7 +147,9 @@ internal ref struct HevcCabacSyntaxReader
return this.decoder.ReadDecision(ref selectedContexts[5 - log2TransformBlockSize]);
}
/// <summary>Decodes a transform-tree coded-block flag.</summary>
/// <summary>
/// Decodes a transform-tree coded-block flag.
/// </summary>
/// <param name="isChroma">A value indicating whether the flag describes a chroma transform block.</param>
/// <param name="contextIndex">The transform-depth-derived context index.</param>
/// <returns>The decoded flag value.</returns>
@ -133,7 +161,9 @@ internal ref struct HevcCabacSyntaxReader
return this.decoder.ReadDecision(ref selectedContexts[channelOffset + contextIndex]);
}
/// <summary>Decodes whether a transform block bypasses the inverse transform.</summary>
/// <summary>
/// Decodes whether a transform block bypasses the inverse transform.
/// </summary>
/// <param name="isChroma">A value indicating whether the transform block belongs to a chroma channel.</param>
/// <returns>The decoded flag value.</returns>
public bool ReadTransformSkip(bool isChroma)
@ -142,7 +172,9 @@ internal ref struct HevcCabacSyntaxReader
return this.decoder.ReadDecision(ref selectedContexts[isChroma ? 1 : 0]);
}
/// <summary>Decodes the signed coding-unit luma quantization-parameter delta.</summary>
/// <summary>
/// Decodes the signed coding-unit luma quantization-parameter delta.
/// </summary>
/// <returns>The signed delta value.</returns>
/// <exception cref="InvalidImageContentException">The coded magnitude exceeds a 32-bit signed value.</exception>
public int ReadDeltaQuantizationParameter()
@ -168,7 +200,9 @@ internal ref struct HevcCabacSyntaxReader
return this.decoder.ReadBypass() ? -signedMagnitude : signedMagnitude;
}
/// <summary>Decodes the coding-unit chroma quantization-adjustment selector.</summary>
/// <summary>
/// Decodes the coding-unit chroma quantization-adjustment selector.
/// </summary>
/// <param name="listLength">The number of chroma offset pairs declared by the picture parameters.</param>
/// <returns>Zero when no adjustment applies; otherwise, the one-based offset-list selector.</returns>
public int ReadChromaQuantizationAdjustment(int listLength)
@ -188,7 +222,9 @@ internal ref struct HevcCabacSyntaxReader
return (int)this.ReadTruncatedUnary(indexContexts, 0, 0, listLength - 1) + 1;
}
/// <summary>Decodes the cross-component residual-prediction scale for one chroma plane.</summary>
/// <summary>
/// Decodes the cross-component residual-prediction scale for one chroma plane.
/// </summary>
/// <param name="chromaPlaneIndex">Zero for Cb or one for Cr.</param>
/// <returns>Zero when prediction is disabled; otherwise, a signed power of two from one through eight.</returns>
public int ReadCrossComponentPredictionScale(int chromaPlaneIndex)
@ -212,7 +248,9 @@ internal ref struct HevcCabacSyntaxReader
return this.decoder.ReadDecision(ref selectedContexts[contextOffset + 4]) ? -magnitude : magnitude;
}
/// <summary>Decodes a sample-adaptive-offset merge flag.</summary>
/// <summary>
/// Decodes a sample-adaptive-offset merge flag.
/// </summary>
/// <returns>The decoded flag value.</returns>
public bool ReadSampleAdaptiveOffsetMerge()
{
@ -220,7 +258,9 @@ internal ref struct HevcCabacSyntaxReader
return this.decoder.ReadDecision(ref selectedContexts[0]);
}
/// <summary>Decodes the sample-adaptive-offset mode selector.</summary>
/// <summary>
/// Decodes the sample-adaptive-offset mode selector.
/// </summary>
/// <returns>Zero for off, one for band offset, or two for edge offset.</returns>
public int ReadSampleAdaptiveOffsetType()
{
@ -233,7 +273,9 @@ internal ref struct HevcCabacSyntaxReader
return this.decoder.ReadBypass() ? 2 : 1;
}
/// <summary>Decodes a truncated-unary absolute sample-adaptive-offset value.</summary>
/// <summary>
/// Decodes a truncated-unary absolute sample-adaptive-offset value.
/// </summary>
/// <param name="maximumValue">The inclusive maximum offset magnitude.</param>
/// <returns>The decoded offset magnitude.</returns>
public int ReadSampleAdaptiveOffsetAbsolute(int maximumValue)
@ -252,19 +294,27 @@ internal ref struct HevcCabacSyntaxReader
return value;
}
/// <summary>Decodes the five-bit sample-adaptive band-offset starting position.</summary>
/// <summary>
/// Decodes the five-bit sample-adaptive band-offset starting position.
/// </summary>
/// <returns>The decoded band position.</returns>
public int ReadSampleAdaptiveOffsetBandPosition() => (int)this.decoder.ReadBypassBits(5);
/// <summary>Decodes the two-bit sample-adaptive edge-offset class.</summary>
/// <summary>
/// Decodes the two-bit sample-adaptive edge-offset class.
/// </summary>
/// <returns>The decoded edge class.</returns>
public int ReadSampleAdaptiveOffsetEdgeClass() => (int)this.decoder.ReadBypassBits(2);
/// <summary>Decodes a sample-adaptive band-offset sign.</summary>
/// <summary>
/// Decodes a sample-adaptive band-offset sign.
/// </summary>
/// <returns><see langword="true"/> for a negative offset; otherwise, <see langword="false"/>.</returns>
public bool ReadSampleAdaptiveOffsetSign() => this.decoder.ReadBypass();
/// <summary>Decodes a horizontal last-significant-coefficient prefix flag.</summary>
/// <summary>
/// Decodes a horizontal last-significant-coefficient prefix flag.
/// </summary>
/// <param name="isChroma">A value indicating whether the coefficient belongs to a chroma channel.</param>
/// <param name="contextIndex">The block-size and prefix-derived context index within the channel.</param>
/// <returns>The decoded flag value.</returns>
@ -274,7 +324,9 @@ internal ref struct HevcCabacSyntaxReader
return this.decoder.ReadDecision(ref selectedContexts[(isChroma ? 15 : 0) + contextIndex]);
}
/// <summary>Decodes a vertical last-significant-coefficient prefix flag.</summary>
/// <summary>
/// Decodes a vertical last-significant-coefficient prefix flag.
/// </summary>
/// <param name="isChroma">A value indicating whether the coefficient belongs to a chroma channel.</param>
/// <param name="contextIndex">The block-size and prefix-derived context index within the channel.</param>
/// <returns>The decoded flag value.</returns>
@ -284,7 +336,9 @@ internal ref struct HevcCabacSyntaxReader
return this.decoder.ReadDecision(ref selectedContexts[(isChroma ? 15 : 0) + contextIndex]);
}
/// <summary>Decodes a significant-coefficient-group flag.</summary>
/// <summary>
/// Decodes a significant-coefficient-group flag.
/// </summary>
/// <param name="isChroma">A value indicating whether the coefficient group belongs to a chroma channel.</param>
/// <param name="contextIndex">The neighboring-group-derived context index.</param>
/// <returns>The decoded flag value.</returns>
@ -294,7 +348,9 @@ internal ref struct HevcCabacSyntaxReader
return this.decoder.ReadDecision(ref selectedContexts[(isChroma ? 2 : 0) + contextIndex]);
}
/// <summary>Decodes a significant-coefficient flag.</summary>
/// <summary>
/// Decodes a significant-coefficient flag.
/// </summary>
/// <param name="isChroma">A value indicating whether the coefficient belongs to a chroma channel.</param>
/// <param name="contextIndex">The scan-position-derived context index within the channel.</param>
/// <returns>The decoded flag value.</returns>
@ -304,7 +360,9 @@ internal ref struct HevcCabacSyntaxReader
return this.decoder.ReadDecision(ref selectedContexts[(isChroma ? 28 : 0) + contextIndex]);
}
/// <summary>Decodes whether a significant coefficient has an absolute level greater than one.</summary>
/// <summary>
/// Decodes whether a significant coefficient has an absolute level greater than one.
/// </summary>
/// <param name="isChroma">A value indicating whether the coefficient belongs to a chroma channel.</param>
/// <param name="contextIndex">The coefficient-group and preceding-level-derived context index.</param>
/// <returns>The decoded flag value.</returns>
@ -314,7 +372,9 @@ internal ref struct HevcCabacSyntaxReader
return this.decoder.ReadDecision(ref selectedContexts[(isChroma ? 16 : 0) + contextIndex]);
}
/// <summary>Decodes whether the first eligible coefficient has an absolute level greater than two.</summary>
/// <summary>
/// Decodes whether the first eligible coefficient has an absolute level greater than two.
/// </summary>
/// <param name="isChroma">A value indicating whether the coefficient belongs to a chroma channel.</param>
/// <param name="contextIndex">The coefficient-group-derived context index within the channel.</param>
/// <returns>The decoded flag value.</returns>
@ -324,7 +384,9 @@ internal ref struct HevcCabacSyntaxReader
return this.decoder.ReadDecision(ref selectedContexts[(isChroma ? 4 : 0) + contextIndex]);
}
/// <summary>Decodes an absolute coefficient-level remainder.</summary>
/// <summary>
/// Decodes an absolute coefficient-level remainder.
/// </summary>
/// <param name="riceParameter">The current Golomb-Rice parameter.</param>
/// <param name="useLimitedPrefixLength">
/// A value indicating whether extended-precision processing limits the prefix length.
@ -396,23 +458,33 @@ internal ref struct HevcCabacSyntaxReader
return (uint)result;
}
/// <summary>Decodes a most-significant-bit-first sequence of equal-probability flags.</summary>
/// <summary>
/// Decodes a most-significant-bit-first sequence of equal-probability flags.
/// </summary>
/// <param name="bitCount">The number of flags to decode.</param>
/// <returns>The decoded unsigned value.</returns>
public uint ReadBypassBits(int bitCount) => this.decoder.ReadBypassBits(bitCount);
/// <summary>Selects the byte-aligned range used by aligned bypass syntax.</summary>
/// <summary>
/// Selects the byte-aligned range used by aligned bypass syntax.
/// </summary>
public void AlignBypass() => this.decoder.AlignBypass();
/// <summary>Decodes the flag that terminates a coding-tree block or entropy substream.</summary>
/// <summary>
/// Decodes the flag that terminates a coding-tree block or entropy substream.
/// </summary>
/// <returns>The decoded termination flag.</returns>
public bool ReadTerminate() => this.decoder.ReadTerminate();
/// <summary>Validates the stop bit and zero padding after a terminating entropy-coded value.</summary>
/// <summary>
/// Validates the stop bit and zero padding after a terminating entropy-coded value.
/// </summary>
/// <exception cref="InvalidImageContentException">The entropy substream has invalid termination alignment.</exception>
public readonly void ValidateTerminationAlignment() => this.decoder.ValidateTerminationAlignment();
/// <summary>Decodes a context-adaptive truncated-unary value.</summary>
/// <summary>
/// Decodes a context-adaptive truncated-unary value.
/// </summary>
/// <param name="selectedContexts">The context set selected for the syntax element.</param>
/// <param name="firstContextIndex">The context used by the first binary decision.</param>
/// <param name="continuationContextIndex">The context used by each subsequent decision.</param>
@ -440,7 +512,9 @@ internal ref struct HevcCabacSyntaxReader
return value;
}
/// <summary>Decodes an equal-probability exponential-Golomb value.</summary>
/// <summary>
/// Decodes an equal-probability exponential-Golomb value.
/// </summary>
/// <param name="order">The initial suffix width.</param>
/// <returns>The decoded unsigned value.</returns>
/// <exception cref="InvalidImageContentException">The coded value exceeds a 32-bit unsigned value.</exception>

64
src/ImageSharp/Formats/Heif/Hevc/HevcCodingTreeState.cs

@ -10,19 +10,29 @@ namespace SixLabors.ImageSharp.Formats.Heif.Hevc;
/// </summary>
internal sealed class HevcCodingTreeState : IDisposable
{
/// <summary>The coding-unit flag indicating transform and quantization bypass.</summary>
/// <summary>
/// The coding-unit flag indicating transform and quantization bypass.
/// </summary>
private const byte TransquantBypassFlag = 1 << 0;
/// <summary>The coding-unit flag indicating pulse-code-modulated samples.</summary>
/// <summary>
/// The coding-unit flag indicating pulse-code-modulated samples.
/// </summary>
private const byte PcmFlag = 1 << 1;
/// <summary>The decoded coding-unit depth at minimum-coding-block resolution.</summary>
/// <summary>
/// The decoded coding-unit depth at minimum-coding-block resolution.
/// </summary>
private readonly Buffer2D<byte> depths;
/// <summary>The effective luma quantization parameter at minimum-coding-block resolution.</summary>
/// <summary>
/// The effective luma quantization parameter at minimum-coding-block resolution.
/// </summary>
private readonly Buffer2D<sbyte> quantizationParameters;
/// <summary>The packed bypass and PCM flags at minimum-coding-block resolution.</summary>
/// <summary>
/// The packed bypass and PCM flags at minimum-coding-block resolution.
/// </summary>
private readonly Buffer2D<byte> flags;
/// <summary>
@ -54,16 +64,24 @@ internal sealed class HevcCodingTreeState : IDisposable
this.HeightInMinCodingBlocks);
}
/// <summary>Gets the base-two logarithm of the state map's luma sample unit.</summary>
/// <summary>
/// Gets the base-two logarithm of the state map's luma sample unit.
/// </summary>
public int MinCodingBlockLog2 { get; }
/// <summary>Gets the state-map width in minimum coding blocks.</summary>
/// <summary>
/// Gets the state-map width in minimum coding blocks.
/// </summary>
public int WidthInMinCodingBlocks { get; }
/// <summary>Gets the state-map height in minimum coding blocks.</summary>
/// <summary>
/// Gets the state-map height in minimum coding blocks.
/// </summary>
public int HeightInMinCodingBlocks { get; }
/// <summary>Gets the split-flag context derived from available left and above coding units.</summary>
/// <summary>
/// Gets the split-flag context derived from available left and above coding units.
/// </summary>
/// <param name="x">The current coding-unit left coordinate in luma samples.</param>
/// <param name="y">The current coding-unit top coordinate in luma samples.</param>
/// <param name="depth">The current coding-tree depth.</param>
@ -88,7 +106,9 @@ internal sealed class HevcCodingTreeState : IDisposable
return context;
}
/// <summary>Records the state shared by every minimum coding block covered by one leaf coding unit.</summary>
/// <summary>
/// Records the state shared by every minimum coding block covered by one leaf coding unit.
/// </summary>
/// <param name="x">The coding-unit left coordinate in luma samples.</param>
/// <param name="y">The coding-unit top coordinate in luma samples.</param>
/// <param name="log2Size">The base-two logarithm of the square coding-unit size.</param>
@ -122,21 +142,27 @@ internal sealed class HevcCodingTreeState : IDisposable
}
}
/// <summary>Gets the recorded coding-tree depth at a luma sample coordinate.</summary>
/// <summary>
/// Gets the recorded coding-tree depth at a luma sample coordinate.
/// </summary>
/// <param name="x">The luma sample X coordinate.</param>
/// <param name="y">The luma sample Y coordinate.</param>
/// <returns>The leaf coding-unit depth.</returns>
public int GetDepth(int x, int y)
=> this.depths.DangerousGetRowSpan(y >> this.MinCodingBlockLog2)[x >> this.MinCodingBlockLog2];
/// <summary>Gets the effective luma quantization parameter at a luma sample coordinate.</summary>
/// <summary>
/// Gets the effective luma quantization parameter at a luma sample coordinate.
/// </summary>
/// <param name="x">The luma sample X coordinate.</param>
/// <param name="y">The luma sample Y coordinate.</param>
/// <returns>The effective luma quantization parameter.</returns>
public int GetQuantizationParameter(int x, int y)
=> this.quantizationParameters.DangerousGetRowSpan(y >> this.MinCodingBlockLog2)[x >> this.MinCodingBlockLog2];
/// <summary>Gets a value indicating whether the coding unit at a luma sample coordinate bypasses transform and quantization.</summary>
/// <summary>
/// Gets a value indicating whether the coding unit at a luma sample coordinate bypasses transform and quantization.
/// </summary>
/// <param name="x">The luma sample X coordinate.</param>
/// <param name="y">The luma sample Y coordinate.</param>
/// <returns><see langword="true"/> when bypass is enabled; otherwise, <see langword="false"/>.</returns>
@ -144,7 +170,9 @@ internal sealed class HevcCodingTreeState : IDisposable
=> (this.flags.DangerousGetRowSpan(y >> this.MinCodingBlockLog2)[x >> this.MinCodingBlockLog2]
& TransquantBypassFlag) != 0;
/// <summary>Gets a value indicating whether the coding unit at a luma sample coordinate contains PCM samples.</summary>
/// <summary>
/// Gets a value indicating whether the coding unit at a luma sample coordinate contains PCM samples.
/// </summary>
/// <param name="x">The luma sample X coordinate.</param>
/// <param name="y">The luma sample Y coordinate.</param>
/// <returns><see langword="true"/> for pulse-code-modulated samples; otherwise, <see langword="false"/>.</returns>
@ -152,7 +180,9 @@ internal sealed class HevcCodingTreeState : IDisposable
=> (this.flags.DangerousGetRowSpan(y >> this.MinCodingBlockLog2)[x >> this.MinCodingBlockLog2]
& PcmFlag) != 0;
/// <summary>Releases the owned coding-tree state maps.</summary>
/// <summary>
/// Releases the owned coding-tree state maps.
/// </summary>
public void Dispose()
{
this.depths.Dispose();
@ -160,7 +190,9 @@ internal sealed class HevcCodingTreeState : IDisposable
this.flags.Dispose();
}
/// <summary>Divides a nonnegative sample count by a power of two with upward rounding.</summary>
/// <summary>
/// Divides a nonnegative sample count by a power of two with upward rounding.
/// </summary>
/// <param name="value">The sample count.</param>
/// <param name="shift">The base-two divisor logarithm.</param>
/// <returns>The upward-rounded quotient.</returns>

84
src/ImageSharp/Formats/Heif/Hevc/HevcIntraPredictionState.cs

@ -10,31 +10,49 @@ namespace SixLabors.ImageSharp.Formats.Heif.Hevc;
/// </summary>
internal sealed class HevcIntraPredictionState : IDisposable
{
/// <summary>The base-two logarithm of the minimum luma prediction-block size.</summary>
/// <summary>
/// The base-two logarithm of the minimum luma prediction-block size.
/// </summary>
private const int MinPredictionBlockLog2 = 2;
/// <summary>The planar intra prediction mode.</summary>
/// <summary>
/// The planar intra prediction mode.
/// </summary>
private const byte PlanarMode = 0;
/// <summary>The DC intra prediction mode.</summary>
/// <summary>
/// The DC intra prediction mode.
/// </summary>
private const byte DcMode = 1;
/// <summary>The horizontal intra prediction mode.</summary>
/// <summary>
/// The horizontal intra prediction mode.
/// </summary>
private const byte HorizontalMode = 10;
/// <summary>The vertical intra prediction mode.</summary>
/// <summary>
/// The vertical intra prediction mode.
/// </summary>
private const byte VerticalMode = 26;
/// <summary>The replacement chroma mode used when an explicit chroma candidate equals the luma mode.</summary>
/// <summary>
/// The replacement chroma mode used when an explicit chroma candidate equals the luma mode.
/// </summary>
private const byte ChromaReplacementMode = 34;
/// <summary>The chroma mode that derives its direction from the colocated luma prediction block.</summary>
/// <summary>
/// The chroma mode that derives its direction from the colocated luma prediction block.
/// </summary>
private const byte DerivedChromaMode = 36;
/// <summary>The luma intra mode at minimum-prediction-block resolution.</summary>
/// <summary>
/// The luma intra mode at minimum-prediction-block resolution.
/// </summary>
private readonly Buffer2D<byte> lumaModes;
/// <summary>The coded chroma intra mode at minimum-prediction-block resolution in luma coordinates.</summary>
/// <summary>
/// The coded chroma intra mode at minimum-prediction-block resolution in luma coordinates.
/// </summary>
private readonly Buffer2D<byte> chromaModes;
/// <summary>
@ -61,13 +79,19 @@ internal sealed class HevcIntraPredictionState : IDisposable
this.HeightInMinPredictionBlocks);
}
/// <summary>Gets the map width in minimum luma prediction blocks.</summary>
/// <summary>
/// Gets the map width in minimum luma prediction blocks.
/// </summary>
public int WidthInMinPredictionBlocks { get; }
/// <summary>Gets the map height in minimum luma prediction blocks.</summary>
/// <summary>
/// Gets the map height in minimum luma prediction blocks.
/// </summary>
public int HeightInMinPredictionBlocks { get; }
/// <summary>Decodes and records the luma intra modes of one leaf coding unit.</summary>
/// <summary>
/// Decodes and records the luma intra modes of one leaf coding unit.
/// </summary>
/// <param name="reader">The current entropy-substream syntax reader.</param>
/// <param name="x">The coding-unit left coordinate in luma samples.</param>
/// <param name="y">The coding-unit top coordinate in luma samples.</param>
@ -134,7 +158,9 @@ internal sealed class HevcIntraPredictionState : IDisposable
}
}
/// <summary>Decodes and records the chroma intra mode of one leaf coding unit.</summary>
/// <summary>
/// Decodes and records the chroma intra mode of one leaf coding unit.
/// </summary>
/// <param name="reader">The current entropy-substream syntax reader.</param>
/// <param name="x">The coding-unit left coordinate in luma samples.</param>
/// <param name="y">The coding-unit top coordinate in luma samples.</param>
@ -160,21 +186,27 @@ internal sealed class HevcIntraPredictionState : IDisposable
this.SetMode(this.chromaModes, x, y, log2Size, mode);
}
/// <summary>Gets the luma intra mode at a luma sample coordinate.</summary>
/// <summary>
/// Gets the luma intra mode at a luma sample coordinate.
/// </summary>
/// <param name="x">The luma sample X coordinate.</param>
/// <param name="y">The luma sample Y coordinate.</param>
/// <returns>The luma intra mode in the inclusive range zero through thirty-four.</returns>
public byte GetLumaMode(int x, int y)
=> this.lumaModes.DangerousGetRowSpan(y >> MinPredictionBlockLog2)[x >> MinPredictionBlockLog2];
/// <summary>Gets the coded chroma intra mode at a luma sample coordinate.</summary>
/// <summary>
/// Gets the coded chroma intra mode at a luma sample coordinate.
/// </summary>
/// <param name="x">The luma sample X coordinate.</param>
/// <param name="y">The luma sample Y coordinate.</param>
/// <returns>An explicit chroma direction or the derived-mode value.</returns>
public byte GetChromaMode(int x, int y)
=> this.chromaModes.DangerousGetRowSpan(y >> MinPredictionBlockLog2)[x >> MinPredictionBlockLog2];
/// <summary>Gets the effective chroma intra mode at a luma sample coordinate.</summary>
/// <summary>
/// Gets the effective chroma intra mode at a luma sample coordinate.
/// </summary>
/// <param name="x">The luma sample X coordinate.</param>
/// <param name="y">The luma sample Y coordinate.</param>
/// <returns>The explicit chroma mode, or the colocated luma mode when chroma uses derived mode.</returns>
@ -184,14 +216,18 @@ internal sealed class HevcIntraPredictionState : IDisposable
return mode == DerivedChromaMode ? this.GetLumaMode(x, y) : mode;
}
/// <summary>Releases the owned intra-mode maps.</summary>
/// <summary>
/// Releases the owned intra-mode maps.
/// </summary>
public void Dispose()
{
this.lumaModes.Dispose();
this.chromaModes.Dispose();
}
/// <summary>Derives the three most-probable luma intra modes from available spatial neighbors.</summary>
/// <summary>
/// Derives the three most-probable luma intra modes from available spatial neighbors.
/// </summary>
/// <param name="x">The prediction-block left coordinate in luma samples.</param>
/// <param name="y">The prediction-block top coordinate in luma samples.</param>
/// <param name="leftAvailable">A value indicating whether the left prediction block is available.</param>
@ -236,7 +272,9 @@ internal sealed class HevcIntraPredictionState : IDisposable
}
}
/// <summary>Records one prediction mode over a square luma-coordinate region.</summary>
/// <summary>
/// Records one prediction mode over a square luma-coordinate region.
/// </summary>
/// <param name="map">The luma or chroma mode map.</param>
/// <param name="x">The region left coordinate in luma samples.</param>
/// <param name="y">The region top coordinate in luma samples.</param>
@ -255,7 +293,9 @@ internal sealed class HevcIntraPredictionState : IDisposable
}
}
/// <summary>Sorts three intra-mode values into ascending order.</summary>
/// <summary>
/// Sorts three intra-mode values into ascending order.
/// </summary>
/// <param name="values">The three-element mode span.</param>
private static void SortThree(Span<byte> values)
{
@ -275,7 +315,9 @@ internal sealed class HevcIntraPredictionState : IDisposable
}
}
/// <summary>Divides a nonnegative sample count by a power of two with upward rounding.</summary>
/// <summary>
/// Divides a nonnegative sample count by a power of two with upward rounding.
/// </summary>
/// <param name="value">The sample count.</param>
/// <param name="shift">The base-two divisor logarithm.</param>
/// <returns>The upward-rounded quotient.</returns>

72
src/ImageSharp/Formats/Heif/Hevc/HevcPictureBuffer.cs

@ -10,10 +10,14 @@ namespace SixLabors.ImageSharp.Formats.Heif.Hevc;
/// </summary>
internal sealed class HevcPictureBuffer : IDisposable
{
/// <summary>The horizontal chroma subsampling shift.</summary>
/// <summary>
/// The horizontal chroma subsampling shift.
/// </summary>
private readonly int chromaSubsamplingX;
/// <summary>The vertical chroma subsampling shift.</summary>
/// <summary>
/// The vertical chroma subsampling shift.
/// </summary>
private readonly int chromaSubsamplingY;
/// <summary>
@ -44,54 +48,82 @@ internal sealed class HevcPictureBuffer : IDisposable
}
}
/// <summary>Gets the coded luma width in samples.</summary>
/// <summary>
/// Gets the coded luma width in samples.
/// </summary>
public int Width { get; }
/// <summary>Gets the coded luma height in samples.</summary>
/// <summary>
/// Gets the coded luma height in samples.
/// </summary>
public int Height { get; }
/// <summary>Gets the luma sample precision in bits.</summary>
/// <summary>
/// Gets the luma sample precision in bits.
/// </summary>
public int BitDepthLuma { get; }
/// <summary>Gets the chroma sample precision in bits.</summary>
/// <summary>
/// Gets the chroma sample precision in bits.
/// </summary>
public int BitDepthChroma { get; }
/// <summary>Gets the HEVC chroma-format identifier.</summary>
/// <summary>
/// Gets the HEVC chroma-format identifier.
/// </summary>
public byte ChromaFormat { get; }
/// <summary>Gets a value indicating whether the three planes are coded as independent full-resolution color planes.</summary>
/// <summary>
/// Gets a value indicating whether the three planes are coded as independent full-resolution color planes.
/// </summary>
public bool SeparateColorPlane { get; }
/// <summary>Gets the luma or first separate-color-plane allocation.</summary>
/// <summary>
/// Gets the luma or first separate-color-plane allocation.
/// </summary>
public Buffer2D<ushort> Luma { get; }
/// <summary>Gets the blue-difference chroma or second separate-color-plane allocation.</summary>
/// <summary>
/// Gets the blue-difference chroma or second separate-color-plane allocation.
/// </summary>
public Buffer2D<ushort>? ChromaBlue { get; }
/// <summary>Gets the red-difference chroma or third separate-color-plane allocation.</summary>
/// <summary>
/// Gets the red-difference chroma or third separate-color-plane allocation.
/// </summary>
public Buffer2D<ushort>? ChromaRed { get; }
/// <summary>Gets the horizontal chroma subsampling shift for the selected plane.</summary>
/// <summary>
/// Gets the horizontal chroma subsampling shift for the selected plane.
/// </summary>
/// <param name="plane">The reconstruction plane.</param>
/// <returns>Zero for luma and full-resolution planes; otherwise, the chroma shift.</returns>
public int GetSubsamplingX(HevcPlane plane) => plane == HevcPlane.Y ? 0 : this.chromaSubsamplingX;
/// <summary>Gets the vertical chroma subsampling shift for the selected plane.</summary>
/// <summary>
/// Gets the vertical chroma subsampling shift for the selected plane.
/// </summary>
/// <param name="plane">The reconstruction plane.</param>
/// <returns>Zero for luma and full-resolution planes; otherwise, the chroma shift.</returns>
public int GetSubsamplingY(HevcPlane plane) => plane == HevcPlane.Y ? 0 : this.chromaSubsamplingY;
/// <summary>Gets the selected plane width in samples.</summary>
/// <summary>
/// Gets the selected plane width in samples.
/// </summary>
/// <param name="plane">The reconstruction plane.</param>
/// <returns>The coded plane width.</returns>
public int GetWidth(HevcPlane plane) => DivideCeilingByPowerOfTwo(this.Width, this.GetSubsamplingX(plane));
/// <summary>Gets the selected plane height in samples.</summary>
/// <summary>
/// Gets the selected plane height in samples.
/// </summary>
/// <param name="plane">The reconstruction plane.</param>
/// <returns>The coded plane height.</returns>
public int GetHeight(HevcPlane plane) => DivideCeilingByPowerOfTwo(this.Height, this.GetSubsamplingY(plane));
/// <summary>Gets one coded row from the selected reconstruction plane.</summary>
/// <summary>
/// Gets one coded row from the selected reconstruction plane.
/// </summary>
/// <param name="plane">The reconstruction plane.</param>
/// <param name="row">The zero-based row index in plane samples.</param>
/// <returns>The complete coded plane row.</returns>
@ -103,7 +135,9 @@ internal sealed class HevcPictureBuffer : IDisposable
_ => this.ChromaRed!.DangerousGetRowSpan(row),
};
/// <summary>Releases the owned luma and chroma plane allocations.</summary>
/// <summary>
/// Releases the owned luma and chroma plane allocations.
/// </summary>
public void Dispose()
{
this.Luma.Dispose();
@ -111,7 +145,9 @@ internal sealed class HevcPictureBuffer : IDisposable
this.ChromaRed?.Dispose();
}
/// <summary>Divides a nonnegative sample count by a power of two with upward rounding.</summary>
/// <summary>
/// Divides a nonnegative sample count by a power of two with upward rounding.
/// </summary>
/// <param name="value">The sample count.</param>
/// <param name="shift">The base-two divisor logarithm.</param>
/// <returns>The upward-rounded quotient.</returns>

180
src/ImageSharp/Formats/Heif/Hevc/HevcPictureParameterSet.cs

@ -220,139 +220,229 @@ internal sealed class HevcPictureParameterSet
reader.ReadRbspTrailingBits();
}
/// <summary>Gets the picture-parameter-set identifier.</summary>
/// <summary>
/// Gets the picture-parameter-set identifier.
/// </summary>
public byte Id { get; }
/// <summary>Gets the referenced sequence-parameter-set identifier.</summary>
/// <summary>
/// Gets the referenced sequence-parameter-set identifier.
/// </summary>
public byte SequenceParameterSetId { get; }
/// <summary>Gets the sequence parameters governing this picture parameter set.</summary>
/// <summary>
/// Gets the sequence parameters governing this picture parameter set.
/// </summary>
public HevcSequenceParameterSet SequenceParameterSet { get; }
/// <summary>Gets a value indicating whether dependent slice segments can occur.</summary>
/// <summary>
/// Gets a value indicating whether dependent slice segments can occur.
/// </summary>
public bool DependentSliceSegmentsEnabled { get; }
/// <summary>Gets a value indicating whether slice headers contain the picture-output flag.</summary>
/// <summary>
/// Gets a value indicating whether slice headers contain the picture-output flag.
/// </summary>
public bool OutputFlagPresent { get; }
/// <summary>Gets the number of reserved extra bits at the start of each independent slice header.</summary>
/// <summary>
/// Gets the number of reserved extra bits at the start of each independent slice header.
/// </summary>
public int ExtraSliceHeaderBitCount { get; }
/// <summary>Gets a value indicating whether transform-coefficient sign hiding is enabled.</summary>
/// <summary>
/// Gets a value indicating whether transform-coefficient sign hiding is enabled.
/// </summary>
public bool SignDataHidingEnabled { get; }
/// <summary>Gets a value indicating whether slices can select an alternate CABAC initialization table.</summary>
/// <summary>
/// Gets a value indicating whether slices can select an alternate CABAC initialization table.
/// </summary>
public bool CabacInitializationPresent { get; }
/// <summary>Gets the default active reference-index count for reference list zero.</summary>
/// <summary>
/// Gets the default active reference-index count for reference list zero.
/// </summary>
public int DefaultReferenceIndexCountList0 { get; }
/// <summary>Gets the default active reference-index count for reference list one.</summary>
/// <summary>
/// Gets the default active reference-index count for reference list one.
/// </summary>
public int DefaultReferenceIndexCountList1 { get; }
/// <summary>Gets the picture quantization-parameter initializer relative to 26.</summary>
/// <summary>
/// Gets the picture quantization-parameter initializer relative to 26.
/// </summary>
public int InitialQuantizationParameterMinus26 { get; }
/// <summary>Gets a value indicating whether inter-coded neighbors are excluded from intra prediction.</summary>
/// <summary>
/// Gets a value indicating whether inter-coded neighbors are excluded from intra prediction.
/// </summary>
public bool ConstrainedIntraPredictionEnabled { get; }
/// <summary>Gets a value indicating whether residual transform skipping can be selected.</summary>
/// <summary>
/// Gets a value indicating whether residual transform skipping can be selected.
/// </summary>
public bool TransformSkipEnabled { get; }
/// <summary>Gets a value indicating whether coding units can change the quantization parameter.</summary>
/// <summary>
/// Gets a value indicating whether coding units can change the quantization parameter.
/// </summary>
public bool CodingUnitQuantizationParameterDeltaEnabled { get; }
/// <summary>Gets the coding-tree depth at which quantization-parameter deltas are signaled.</summary>
/// <summary>
/// Gets the coding-tree depth at which quantization-parameter deltas are signaled.
/// </summary>
public int QuantizationParameterDeltaDepth { get; }
/// <summary>Gets the picture-level Cb quantization-parameter offset.</summary>
/// <summary>
/// Gets the picture-level Cb quantization-parameter offset.
/// </summary>
public int ChromaCbQuantizationParameterOffset { get; }
/// <summary>Gets the picture-level Cr quantization-parameter offset.</summary>
/// <summary>
/// Gets the picture-level Cr quantization-parameter offset.
/// </summary>
public int ChromaCrQuantizationParameterOffset { get; }
/// <summary>Gets a value indicating whether slices can add Cb and Cr quantization-parameter offsets.</summary>
/// <summary>
/// Gets a value indicating whether slices can add Cb and Cr quantization-parameter offsets.
/// </summary>
public bool SliceChromaQuantizationParameterOffsetsPresent { get; }
/// <summary>Gets a value indicating whether weighted prediction can be used by predictive slices.</summary>
/// <summary>
/// Gets a value indicating whether weighted prediction can be used by predictive slices.
/// </summary>
public bool WeightedPredictionEnabled { get; }
/// <summary>Gets a value indicating whether weighted prediction can be used by bidirectional slices.</summary>
/// <summary>
/// Gets a value indicating whether weighted prediction can be used by bidirectional slices.
/// </summary>
public bool WeightedBiPredictionEnabled { get; }
/// <summary>Gets a value indicating whether coding units can bypass transform and quantization.</summary>
/// <summary>
/// Gets a value indicating whether coding units can bypass transform and quantization.
/// </summary>
public bool TransquantizationBypassEnabled { get; }
/// <summary>Gets a value indicating whether the coded picture is partitioned into tiles.</summary>
/// <summary>
/// Gets a value indicating whether the coded picture is partitioned into tiles.
/// </summary>
public bool TilesEnabled { get; }
/// <summary>Gets a value indicating whether wavefront entropy-coding synchronization is enabled.</summary>
/// <summary>
/// Gets a value indicating whether wavefront entropy-coding synchronization is enabled.
/// </summary>
public bool EntropyCodingSynchronizationEnabled { get; }
/// <summary>Gets a value indicating whether the tile grid uses uniform proportional spacing.</summary>
/// <summary>
/// Gets a value indicating whether the tile grid uses uniform proportional spacing.
/// </summary>
public bool UniformTileSpacing { get; }
/// <summary>Gets the tile-column widths in coding-tree blocks.</summary>
/// <summary>
/// Gets the tile-column widths in coding-tree blocks.
/// </summary>
public IReadOnlyList<int> TileColumnWidths { get; }
/// <summary>Gets the tile-row heights in coding-tree blocks.</summary>
/// <summary>
/// Gets the tile-row heights in coding-tree blocks.
/// </summary>
public IReadOnlyList<int> TileRowHeights { get; }
/// <summary>Gets a value indicating whether in-loop filtering crosses tile boundaries.</summary>
/// <summary>
/// Gets a value indicating whether in-loop filtering crosses tile boundaries.
/// </summary>
public bool LoopFilterAcrossTilesEnabled { get; }
/// <summary>Gets a value indicating whether in-loop filtering crosses slice boundaries.</summary>
/// <summary>
/// Gets a value indicating whether in-loop filtering crosses slice boundaries.
/// </summary>
public bool LoopFilterAcrossSlicesEnabled { get; }
/// <summary>Gets a value indicating whether picture or slice syntax controls deblocking.</summary>
/// <summary>
/// Gets a value indicating whether picture or slice syntax controls deblocking.
/// </summary>
public bool DeblockingFilterControlPresent { get; }
/// <summary>Gets a value indicating whether slice headers can override picture-level deblocking.</summary>
/// <summary>
/// Gets a value indicating whether slice headers can override picture-level deblocking.
/// </summary>
public bool DeblockingFilterOverrideEnabled { get; }
/// <summary>Gets a value indicating whether deblocking is disabled by default for the picture.</summary>
/// <summary>
/// Gets a value indicating whether deblocking is disabled by default for the picture.
/// </summary>
public bool DeblockingFilterDisabled { get; }
/// <summary>Gets half the picture-level deblocking beta-threshold offset.</summary>
/// <summary>
/// Gets half the picture-level deblocking beta-threshold offset.
/// </summary>
public int DeblockingFilterBetaOffsetDiv2 { get; }
/// <summary>Gets half the picture-level deblocking clipping-threshold offset.</summary>
/// <summary>
/// Gets half the picture-level deblocking clipping-threshold offset.
/// </summary>
public int DeblockingFilterTcOffsetDiv2 { get; }
/// <summary>Gets a value indicating whether this picture parameter set supplies scaling-list data.</summary>
/// <summary>
/// Gets a value indicating whether this picture parameter set supplies scaling-list data.
/// </summary>
public bool ScalingListDataPresent { get; }
/// <summary>Gets the effective quantization scaling matrices for slices using this picture parameter set.</summary>
/// <summary>
/// Gets the effective quantization scaling matrices for slices using this picture parameter set.
/// </summary>
public HevcScalingList ScalingList { get; }
/// <summary>Gets a value indicating whether slice headers can modify the initial reference-picture lists.</summary>
/// <summary>
/// Gets a value indicating whether slice headers can modify the initial reference-picture lists.
/// </summary>
public bool ReferenceListModificationPresent { get; }
/// <summary>Gets the base-two logarithm of the parallel merge-estimation region width and height.</summary>
/// <summary>
/// Gets the base-two logarithm of the parallel merge-estimation region width and height.
/// </summary>
public int ParallelMergeLevelLog2 { get; }
/// <summary>Gets a value indicating whether slice-segment headers carry extension bytes.</summary>
/// <summary>
/// Gets a value indicating whether slice-segment headers carry extension bytes.
/// </summary>
public bool SliceSegmentHeaderExtensionPresent { get; }
/// <summary>Gets the base-two logarithm of the maximum transform-skip block width and height.</summary>
/// <summary>
/// Gets the base-two logarithm of the maximum transform-skip block width and height.
/// </summary>
public int MaxTransformSkipBlockLog2 { get; private set; }
/// <summary>Gets a value indicating whether cross-component residual prediction is enabled.</summary>
/// <summary>
/// Gets a value indicating whether cross-component residual prediction is enabled.
/// </summary>
public bool CrossComponentPredictionEnabled { get; private set; }
/// <summary>Gets the coding-tree depth at which chroma quantization-offset indices are signaled.</summary>
/// <summary>
/// Gets the coding-tree depth at which chroma quantization-offset indices are signaled.
/// </summary>
public int ChromaQuantizationParameterOffsetDepth { get; private set; }
/// <summary>Gets the Cb offsets in the selectable chroma quantization-parameter offset list.</summary>
/// <summary>
/// Gets the Cb offsets in the selectable chroma quantization-parameter offset list.
/// </summary>
public IReadOnlyList<int> ChromaQuantizationParameterOffsetsCb { get; private set; } = Array.Empty<int>();
/// <summary>Gets the Cr offsets in the selectable chroma quantization-parameter offset list.</summary>
/// <summary>
/// Gets the Cr offsets in the selectable chroma quantization-parameter offset list.
/// </summary>
public IReadOnlyList<int> ChromaQuantizationParameterOffsetsCr { get; private set; } = Array.Empty<int>();
/// <summary>Gets the base-two logarithm of the luma sample-adaptive-offset value scale.</summary>
/// <summary>
/// Gets the base-two logarithm of the luma sample-adaptive-offset value scale.
/// </summary>
public int SampleAdaptiveOffsetScaleLumaLog2 { get; private set; }
/// <summary>Gets the base-two logarithm of the chroma sample-adaptive-offset value scale.</summary>
/// <summary>
/// Gets the base-two logarithm of the chroma sample-adaptive-offset value scale.
/// </summary>
public int SampleAdaptiveOffsetScaleChromaLog2 { get; private set; }
/// <summary>

12
src/ImageSharp/Formats/Heif/Hevc/HevcPlane.cs

@ -8,12 +8,18 @@ namespace SixLabors.ImageSharp.Formats.Heif.Hevc;
/// </summary>
internal enum HevcPlane
{
/// <summary>The luma or first separate-color plane.</summary>
/// <summary>
/// The luma or first separate-color plane.
/// </summary>
Y = 0,
/// <summary>The blue-difference chroma or second separate-color plane.</summary>
/// <summary>
/// The blue-difference chroma or second separate-color plane.
/// </summary>
Cb = 1,
/// <summary>The red-difference chroma or third separate-color plane.</summary>
/// <summary>
/// The red-difference chroma or third separate-color plane.
/// </summary>
Cr = 2,
}

196
src/ImageSharp/Formats/Heif/Hevc/HevcSequenceParameterSet.cs

@ -280,151 +280,249 @@ internal sealed class HevcSequenceParameterSet
reader.ReadRbspTrailingBits();
}
/// <summary>Gets the referenced video-parameter-set identifier.</summary>
/// <summary>
/// Gets the referenced video-parameter-set identifier.
/// </summary>
public byte VideoParameterSetId { get; }
/// <summary>Gets the sequence-parameter-set identifier.</summary>
/// <summary>
/// Gets the sequence-parameter-set identifier.
/// </summary>
public byte Id { get; }
/// <summary>Gets the declared number of temporal sublayers.</summary>
/// <summary>
/// Gets the declared number of temporal sublayers.
/// </summary>
public int MaxSubLayers { get; }
/// <summary>Gets a value indicating whether temporal identifiers are nested.</summary>
/// <summary>
/// Gets a value indicating whether temporal identifiers are nested.
/// </summary>
public bool TemporalIdNestingFlag { get; }
/// <summary>Gets the general profile, tier, constraint, and level description.</summary>
/// <summary>
/// Gets the general profile, tier, constraint, and level description.
/// </summary>
public HevcProfileTierLevel ProfileTierLevel { get; }
/// <summary>Gets the coded chroma format, from monochrome through YUV 4:4:4.</summary>
/// <summary>
/// Gets the coded chroma format, from monochrome through YUV 4:4:4.
/// </summary>
public byte ChromaFormat { get; }
/// <summary>Gets a value indicating whether 4:4:4 components are coded as separate color planes.</summary>
/// <summary>
/// Gets a value indicating whether 4:4:4 components are coded as separate color planes.
/// </summary>
public bool SeparateColorPlaneFlag { get; }
/// <summary>Gets the coded luma width before conformance cropping.</summary>
/// <summary>
/// Gets the coded luma width before conformance cropping.
/// </summary>
public int Width { get; }
/// <summary>Gets the coded luma height before conformance cropping.</summary>
/// <summary>
/// Gets the coded luma height before conformance cropping.
/// </summary>
public int Height { get; }
/// <summary>Gets the displayed width after conformance cropping.</summary>
/// <summary>
/// Gets the displayed width after conformance cropping.
/// </summary>
public int DisplayWidth { get; }
/// <summary>Gets the displayed height after conformance cropping.</summary>
/// <summary>
/// Gets the displayed height after conformance cropping.
/// </summary>
public int DisplayHeight { get; }
/// <summary>Gets the conformance-window left offset in luma samples.</summary>
/// <summary>
/// Gets the conformance-window left offset in luma samples.
/// </summary>
public int ConformanceWindowLeftOffset { get; }
/// <summary>Gets the conformance-window right offset in luma samples.</summary>
/// <summary>
/// Gets the conformance-window right offset in luma samples.
/// </summary>
public int ConformanceWindowRightOffset { get; }
/// <summary>Gets the conformance-window top offset in luma samples.</summary>
/// <summary>
/// Gets the conformance-window top offset in luma samples.
/// </summary>
public int ConformanceWindowTopOffset { get; }
/// <summary>Gets the conformance-window bottom offset in luma samples.</summary>
/// <summary>
/// Gets the conformance-window bottom offset in luma samples.
/// </summary>
public int ConformanceWindowBottomOffset { get; }
/// <summary>Gets the luma sample precision in bits.</summary>
/// <summary>
/// Gets the luma sample precision in bits.
/// </summary>
public int BitDepthLuma { get; }
/// <summary>Gets the chroma sample precision in bits.</summary>
/// <summary>
/// Gets the chroma sample precision in bits.
/// </summary>
public int BitDepthChroma { get; }
/// <summary>Gets the coded picture-order-count least-significant-bit width.</summary>
/// <summary>
/// Gets the coded picture-order-count least-significant-bit width.
/// </summary>
public int PictureOrderCountLsbBits { get; }
/// <summary>Gets the base-two logarithm of the minimum luma coding-block size.</summary>
/// <summary>
/// Gets the base-two logarithm of the minimum luma coding-block size.
/// </summary>
public int MinCodingBlockLog2 { get; }
/// <summary>Gets the base-two logarithm of the coding-tree-block size.</summary>
/// <summary>
/// Gets the base-two logarithm of the coding-tree-block size.
/// </summary>
public int CodingTreeBlockLog2 { get; }
/// <summary>Gets the base-two logarithm of the minimum luma transform-block size.</summary>
/// <summary>
/// Gets the base-two logarithm of the minimum luma transform-block size.
/// </summary>
public int MinTransformBlockLog2 { get; }
/// <summary>Gets the base-two logarithm of the maximum luma transform-block size.</summary>
/// <summary>
/// Gets the base-two logarithm of the maximum luma transform-block size.
/// </summary>
public int MaxTransformBlockLog2 { get; }
/// <summary>Gets the maximum inter-predicted transform hierarchy depth.</summary>
/// <summary>
/// Gets the maximum inter-predicted transform hierarchy depth.
/// </summary>
public int MaxTransformHierarchyDepthInter { get; }
/// <summary>Gets the maximum intra-predicted transform hierarchy depth.</summary>
/// <summary>
/// Gets the maximum intra-predicted transform hierarchy depth.
/// </summary>
public int MaxTransformHierarchyDepthIntra { get; }
/// <summary>Gets a value indicating whether scaling lists affect inverse quantization.</summary>
/// <summary>
/// Gets a value indicating whether scaling lists affect inverse quantization.
/// </summary>
public bool ScalingListEnabled { get; }
/// <summary>Gets the effective quantization scaling matrices.</summary>
/// <summary>
/// Gets the effective quantization scaling matrices.
/// </summary>
public HevcScalingList ScalingList { get; }
/// <summary>Gets a value indicating whether asymmetric motion partitions are enabled.</summary>
/// <summary>
/// Gets a value indicating whether asymmetric motion partitions are enabled.
/// </summary>
public bool AsymmetricMotionPartitionsEnabled { get; }
/// <summary>Gets a value indicating whether sample-adaptive offset filtering is enabled.</summary>
/// <summary>
/// Gets a value indicating whether sample-adaptive offset filtering is enabled.
/// </summary>
public bool SampleAdaptiveOffsetEnabled { get; }
/// <summary>Gets a value indicating whether pulse-code-modulated coding blocks are enabled.</summary>
/// <summary>
/// Gets a value indicating whether pulse-code-modulated coding blocks are enabled.
/// </summary>
public bool PcmEnabled { get; }
/// <summary>Gets the PCM luma sample precision in bits.</summary>
/// <summary>
/// Gets the PCM luma sample precision in bits.
/// </summary>
public int PcmBitDepthLuma { get; }
/// <summary>Gets the PCM chroma sample precision in bits.</summary>
/// <summary>
/// Gets the PCM chroma sample precision in bits.
/// </summary>
public int PcmBitDepthChroma { get; }
/// <summary>Gets the base-two logarithm of the minimum PCM coding-block size.</summary>
/// <summary>
/// Gets the base-two logarithm of the minimum PCM coding-block size.
/// </summary>
public int MinPcmCodingBlockLog2 { get; }
/// <summary>Gets the base-two logarithm of the maximum PCM coding-block size.</summary>
/// <summary>
/// Gets the base-two logarithm of the maximum PCM coding-block size.
/// </summary>
public int MaxPcmCodingBlockLog2 { get; }
/// <summary>Gets a value indicating whether in-loop filtering is disabled for PCM blocks.</summary>
/// <summary>
/// Gets a value indicating whether in-loop filtering is disabled for PCM blocks.
/// </summary>
public bool PcmLoopFilterDisabled { get; }
/// <summary>Gets the SPS short-term reference-picture sets.</summary>
/// <summary>
/// Gets the SPS short-term reference-picture sets.
/// </summary>
public IReadOnlyList<HevcShortTermReferencePictureSet> ShortTermReferencePictureSets { get; }
/// <summary>Gets the long-term reference picture-order-count values.</summary>
/// <summary>
/// Gets the long-term reference picture-order-count values.
/// </summary>
public IReadOnlyList<uint> LongTermReferencePictureOrderCounts { get; }
/// <summary>Gets the long-term reference-picture current-usage flags.</summary>
/// <summary>
/// Gets the long-term reference-picture current-usage flags.
/// </summary>
public IReadOnlyList<bool> LongTermReferencePicturesUsedByCurrent { get; }
/// <summary>Gets a value indicating whether temporal motion-vector prediction is enabled.</summary>
/// <summary>
/// Gets a value indicating whether temporal motion-vector prediction is enabled.
/// </summary>
public bool TemporalMotionVectorPredictionEnabled { get; }
/// <summary>Gets a value indicating whether strong intra smoothing is enabled.</summary>
/// <summary>
/// Gets a value indicating whether strong intra smoothing is enabled.
/// </summary>
public bool StrongIntraSmoothingEnabled { get; }
/// <summary>Gets the optional still-image VUI presentation description.</summary>
/// <summary>
/// Gets the optional still-image VUI presentation description.
/// </summary>
public HevcVideoUsabilityInformation? VideoUsabilityInformation { get; }
/// <summary>Gets a value indicating whether transform-skip coefficient rotation is enabled.</summary>
/// <summary>
/// Gets a value indicating whether transform-skip coefficient rotation is enabled.
/// </summary>
public bool TransformSkipRotationEnabled { get; }
/// <summary>Gets a value indicating whether transform-skip-specific entropy contexts are enabled.</summary>
/// <summary>
/// Gets a value indicating whether transform-skip-specific entropy contexts are enabled.
/// </summary>
public bool TransformSkipContextEnabled { get; }
/// <summary>Gets a value indicating whether implicit residual DPCM is enabled.</summary>
/// <summary>
/// Gets a value indicating whether implicit residual DPCM is enabled.
/// </summary>
public bool ImplicitResidualDpcmEnabled { get; }
/// <summary>Gets a value indicating whether explicit residual DPCM is enabled.</summary>
/// <summary>
/// Gets a value indicating whether explicit residual DPCM is enabled.
/// </summary>
public bool ExplicitResidualDpcmEnabled { get; }
/// <summary>Gets a value indicating whether extended-precision processing is enabled.</summary>
/// <summary>
/// Gets a value indicating whether extended-precision processing is enabled.
/// </summary>
public bool ExtendedPrecisionProcessingEnabled { get; }
/// <summary>Gets a value indicating whether intra smoothing is disabled.</summary>
/// <summary>
/// Gets a value indicating whether intra smoothing is disabled.
/// </summary>
public bool IntraSmoothingDisabled { get; }
/// <summary>Gets a value indicating whether high-precision prediction offsets are enabled.</summary>
/// <summary>
/// Gets a value indicating whether high-precision prediction offsets are enabled.
/// </summary>
public bool HighPrecisionOffsetsEnabled { get; }
/// <summary>Gets a value indicating whether persistent Rice adaptation is enabled.</summary>
/// <summary>
/// Gets a value indicating whether persistent Rice adaptation is enabled.
/// </summary>
public bool PersistentRiceAdaptationEnabled { get; }
/// <summary>Gets a value indicating whether CABAC bypass alignment is enabled.</summary>
/// <summary>
/// Gets a value indicating whether CABAC bypass alignment is enabled.
/// </summary>
public bool CabacBypassAlignmentEnabled { get; }
/// <summary>

76
src/ImageSharp/Formats/Heif/Hevc/HevcSliceSegmentHeader.cs

@ -130,55 +130,89 @@ internal sealed class HevcSliceSegmentHeader
}
}
/// <summary>Gets the complete decoded NAL unit containing this slice segment.</summary>
/// <summary>
/// Gets the complete decoded NAL unit containing this slice segment.
/// </summary>
public HevcNalUnit NalUnit { get; }
/// <summary>Gets a value indicating whether this is the first slice segment of the coded picture.</summary>
/// <summary>
/// Gets a value indicating whether this is the first slice segment of the coded picture.
/// </summary>
public bool FirstSliceSegmentInPicture { get; }
/// <summary>Gets a value indicating whether this segment inherits syntax from an earlier independent slice.</summary>
/// <summary>
/// Gets a value indicating whether this segment inherits syntax from an earlier independent slice.
/// </summary>
public bool DependentSliceSegment { get; }
/// <summary>Gets the picture parameters selected by this slice segment.</summary>
/// <summary>
/// Gets the picture parameters selected by this slice segment.
/// </summary>
public HevcPictureParameterSet PictureParameterSet { get; }
/// <summary>Gets the raster-scan address of the first coding-tree block in this slice segment.</summary>
/// <summary>
/// Gets the raster-scan address of the first coding-tree block in this slice segment.
/// </summary>
public int SliceSegmentAddress { get; }
/// <summary>Gets the independent slice prediction type, or <see langword="null"/> for a dependent segment.</summary>
/// <summary>
/// Gets the independent slice prediction type, or <see langword="null"/> for a dependent segment.
/// </summary>
public HevcSliceType? SliceType { get; private set; }
/// <summary>Gets the selected color-plane identifier for separate-plane 4:4:4 coding.</summary>
/// <summary>
/// Gets the selected color-plane identifier for separate-plane 4:4:4 coding.
/// </summary>
public byte ColorPlaneId { get; private set; }
/// <summary>Gets a value indicating whether luma sample-adaptive offset filtering is enabled.</summary>
/// <summary>
/// Gets a value indicating whether luma sample-adaptive offset filtering is enabled.
/// </summary>
public bool? SampleAdaptiveOffsetLumaEnabled { get; private set; }
/// <summary>Gets a value indicating whether chroma sample-adaptive offset filtering is enabled.</summary>
/// <summary>
/// Gets a value indicating whether chroma sample-adaptive offset filtering is enabled.
/// </summary>
public bool? SampleAdaptiveOffsetChromaEnabled { get; private set; }
/// <summary>Gets the effective luma quantization parameter, or <see langword="null"/> for a dependent segment.</summary>
/// <summary>
/// Gets the effective luma quantization parameter, or <see langword="null"/> for a dependent segment.
/// </summary>
public int? QuantizationParameter { get; private set; }
/// <summary>Gets the slice-level Cb quantization-parameter offset.</summary>
/// <summary>
/// Gets the slice-level Cb quantization-parameter offset.
/// </summary>
public int ChromaCbQuantizationParameterOffset { get; private set; }
/// <summary>Gets the slice-level Cr quantization-parameter offset.</summary>
/// <summary>
/// Gets the slice-level Cr quantization-parameter offset.
/// </summary>
public int ChromaCrQuantizationParameterOffset { get; private set; }
/// <summary>Gets a value indicating whether coding units can select the PPS chroma-offset list.</summary>
/// <summary>
/// Gets a value indicating whether coding units can select the PPS chroma-offset list.
/// </summary>
public bool? ChromaQuantizationParameterOffsetListEnabled { get; private set; }
/// <summary>Gets a value indicating whether deblocking is disabled for this independent slice.</summary>
/// <summary>
/// Gets a value indicating whether deblocking is disabled for this independent slice.
/// </summary>
public bool? DeblockingFilterDisabled { get; private set; }
/// <summary>Gets half the effective deblocking beta-threshold offset.</summary>
/// <summary>
/// Gets half the effective deblocking beta-threshold offset.
/// </summary>
public int DeblockingFilterBetaOffsetDiv2 { get; private set; }
/// <summary>Gets half the effective deblocking clipping-threshold offset.</summary>
/// <summary>
/// Gets half the effective deblocking clipping-threshold offset.
/// </summary>
public int DeblockingFilterTcOffsetDiv2 { get; private set; }
/// <summary>Gets a value indicating whether in-loop filtering crosses slice boundaries.</summary>
/// <summary>
/// Gets a value indicating whether in-loop filtering crosses slice boundaries.
/// </summary>
public bool? LoopFilterAcrossSlicesEnabled { get; private set; }
/// <summary>
@ -186,10 +220,14 @@ internal sealed class HevcSliceSegmentHeader
/// </summary>
public IReadOnlyList<int> EntryPointOffsets { get; private set; } = Array.Empty<int>();
/// <summary>Gets the slice-header length in decoded raw-byte-sequence payload bytes.</summary>
/// <summary>
/// Gets the slice-header length in decoded raw-byte-sequence payload bytes.
/// </summary>
public int HeaderLength { get; }
/// <summary>Gets the entropy-coded slice data following byte alignment.</summary>
/// <summary>
/// Gets the entropy-coded slice data following byte alignment.
/// </summary>
public ReadOnlyMemory<byte> SliceData { get; }
/// <summary>

Loading…
Cancel
Save