mirror of https://github.com/SixLabors/ImageSharp
2 changed files with 227 additions and 1 deletions
@ -0,0 +1,225 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Heif.Hevc; |
|||
|
|||
/// <summary>
|
|||
/// Owns the adaptive CABAC probability contexts used to decode one intra-coded HEVC entropy substream.
|
|||
/// </summary>
|
|||
internal sealed class HevcCabacContexts |
|||
{ |
|||
/// <summary>The first transquant-bypass context.</summary>
|
|||
private const int TransquantBypassOffset = 0; |
|||
|
|||
/// <summary>The first coding-unit split context.</summary>
|
|||
private const int SplitOffset = 1; |
|||
|
|||
/// <summary>The intra partition-size context.</summary>
|
|||
private const int PartitionSizeOffset = 4; |
|||
|
|||
/// <summary>The luma intra-prediction context.</summary>
|
|||
private const int IntraPredictionOffset = 5; |
|||
|
|||
/// <summary>The first chroma intra-prediction context.</summary>
|
|||
private const int ChromaPredictionOffset = 6; |
|||
|
|||
/// <summary>The first luma quantization-delta context.</summary>
|
|||
private const int DeltaQuantizationOffset = 8; |
|||
|
|||
/// <summary>The chroma quantization-adjustment flag context.</summary>
|
|||
private const int ChromaQuantizationAdjustmentFlagOffset = 11; |
|||
|
|||
/// <summary>The chroma quantization-adjustment index context.</summary>
|
|||
private const int ChromaQuantizationAdjustmentIndexOffset = 12; |
|||
|
|||
/// <summary>The first transform-tree coded-block-flag context.</summary>
|
|||
private const int TransformCodedBlockFlagOffset = 13; |
|||
|
|||
/// <summary>The first horizontal last-significant-coefficient context.</summary>
|
|||
private const int LastSignificantXOffset = 23; |
|||
|
|||
/// <summary>The first vertical last-significant-coefficient context.</summary>
|
|||
private const int LastSignificantYOffset = 53; |
|||
|
|||
/// <summary>The first significant-coefficient-group context.</summary>
|
|||
private const int SignificantCoefficientGroupOffset = 83; |
|||
|
|||
/// <summary>The first significant-coefficient context.</summary>
|
|||
private const int SignificantCoefficientOffset = 87; |
|||
|
|||
/// <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>
|
|||
private const int GreaterThanTwoOffset = 155; |
|||
|
|||
/// <summary>The sample-adaptive-offset merge context.</summary>
|
|||
private const int SampleAdaptiveOffsetMergeOffset = 161; |
|||
|
|||
/// <summary>The sample-adaptive-offset type context.</summary>
|
|||
private const int SampleAdaptiveOffsetTypeOffset = 162; |
|||
|
|||
/// <summary>The first transform-tree subdivision context.</summary>
|
|||
private const int TransformSubdivisionOffset = 163; |
|||
|
|||
/// <summary>The first transform-skip context.</summary>
|
|||
private const int TransformSkipOffset = 166; |
|||
|
|||
/// <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>
|
|||
private const int ContextCount = 178; |
|||
|
|||
/// <summary>
|
|||
/// The HEVC intra-slice initialization values in the same order as the owned context ranges.
|
|||
/// </summary>
|
|||
private static readonly byte[] IntraInitializationValues = |
|||
[ |
|||
|
|||
// cu_transquant_bypass_flag
|
|||
154, |
|||
|
|||
// split_cu_flag
|
|||
139, 141, 157, |
|||
|
|||
// part_mode and prev_intra_luma_pred_flag
|
|||
184, |
|||
184, |
|||
|
|||
// intra_chroma_pred_mode
|
|||
63, 139, |
|||
|
|||
// cu_qp_delta_abs, cu_chroma_qp_offset_flag, and cu_chroma_qp_offset_idx
|
|||
154, 154, 154, |
|||
154, |
|||
154, |
|||
|
|||
// cbf_luma followed by the chroma coded-block flags
|
|||
111, 141, 154, 154, 154, |
|||
94, 138, 182, 154, 154, |
|||
|
|||
// last_sig_coeff_x_prefix: luma followed by chroma
|
|||
110, 110, 124, 125, 140, 153, 125, 127, 140, 109, 111, 143, 127, 111, 79, |
|||
108, 123, 63, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, |
|||
|
|||
// last_sig_coeff_y_prefix: luma followed by chroma
|
|||
110, 110, 124, 125, 140, 153, 125, 127, 140, 109, 111, 143, 127, 111, 79, |
|||
108, 123, 63, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, |
|||
|
|||
// coded_sub_block_flag: luma followed by chroma
|
|||
91, 171, 134, 141, |
|||
|
|||
// sig_coeff_flag: luma followed by chroma
|
|||
111, 111, 125, 110, 110, 94, 124, 108, 124, 107, 125, 141, 179, 153, |
|||
125, 107, 125, 141, 179, 153, 125, 107, 125, 141, 179, 153, 125, 141, |
|||
140, 139, 182, 182, 152, 136, 152, 136, 153, 136, 139, 111, 136, 139, 111, 111, |
|||
|
|||
// coeff_abs_level_greater1_flag: luma followed by chroma
|
|||
140, 92, 137, 138, 140, 152, 138, 139, 153, 74, 149, 92, 139, 107, 122, 152, |
|||
140, 179, 166, 182, 140, 227, 122, 197, |
|||
|
|||
// coeff_abs_level_greater2_flag: luma followed by chroma
|
|||
138, 153, 136, 167, 152, 152, |
|||
|
|||
// sao_merge_flag and sao_type_idx
|
|||
153, |
|||
200, |
|||
|
|||
// split_transform_flag
|
|||
153, 138, 138, |
|||
|
|||
// transform_skip_flag: luma followed by chroma
|
|||
139, 139, |
|||
|
|||
// cross_comp_pred: five sign/magnitude contexts for Cb followed by five for Cr
|
|||
154, 154, 154, 154, 154, 154, 154, 154, 154, 154 |
|||
]; |
|||
|
|||
/// <summary>
|
|||
/// The contiguous adaptive context storage owned by the entropy substream.
|
|||
/// </summary>
|
|||
private readonly HevcCabacContext[] contexts; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="HevcCabacContexts"/> class for an intra-coded slice.
|
|||
/// </summary>
|
|||
/// <param name="quantizationParameter">The slice luma quantization parameter.</param>
|
|||
public HevcCabacContexts(int quantizationParameter) |
|||
{ |
|||
this.contexts = new HevcCabacContext[ContextCount]; |
|||
for (int index = 0; index < this.contexts.Length; index++) |
|||
{ |
|||
this.contexts[index] = new HevcCabacContext(quantizationParameter, IntraInitializationValues[index]); |
|||
} |
|||
} |
|||
|
|||
/// <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>
|
|||
public Span<HevcCabacContext> Split => this.contexts.AsSpan(SplitOffset, 3); |
|||
|
|||
/// <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>
|
|||
public Span<HevcCabacContext> IntraPrediction => this.contexts.AsSpan(IntraPredictionOffset, 1); |
|||
|
|||
/// <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>
|
|||
public Span<HevcCabacContext> DeltaQuantization => this.contexts.AsSpan(DeltaQuantizationOffset, 3); |
|||
|
|||
/// <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>
|
|||
public Span<HevcCabacContext> ChromaQuantizationAdjustmentIndex => |
|||
this.contexts.AsSpan(ChromaQuantizationAdjustmentIndexOffset, 1); |
|||
|
|||
/// <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>
|
|||
public Span<HevcCabacContext> LastSignificantX => this.contexts.AsSpan(LastSignificantXOffset, 30); |
|||
|
|||
/// <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>
|
|||
public Span<HevcCabacContext> SignificantCoefficientGroup => |
|||
this.contexts.AsSpan(SignificantCoefficientGroupOffset, 4); |
|||
|
|||
/// <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>
|
|||
public Span<HevcCabacContext> GreaterThanOne => this.contexts.AsSpan(GreaterThanOneOffset, 24); |
|||
|
|||
/// <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>
|
|||
public Span<HevcCabacContext> SampleAdaptiveOffsetMerge => |
|||
this.contexts.AsSpan(SampleAdaptiveOffsetMergeOffset, 1); |
|||
|
|||
/// <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>
|
|||
public Span<HevcCabacContext> TransformSubdivision => |
|||
this.contexts.AsSpan(TransformSubdivisionOffset, 3); |
|||
|
|||
/// <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>
|
|||
public Span<HevcCabacContext> CrossComponentPrediction => |
|||
this.contexts.AsSpan(CrossComponentPredictionOffset, 10); |
|||
} |
|||
Loading…
Reference in new issue