Browse Source

Implement remaining distributions

pull/2633/head
Ynse Hoornenborg 2 years ago
parent
commit
1d83ac3e44
  1. 1618
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1DefaultDistributions.cs
  2. 48
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SymbolDecoder.cs
  3. 10
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs

1618
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1DefaultDistributions.cs

File diff suppressed because it is too large

48
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SymbolDecoder.cs

@ -23,12 +23,24 @@ internal ref struct Av1SymbolDecoder
private readonly Av1Distribution[] filterIntra = Av1DefaultDistributions.FilterIntra;
private readonly Av1Distribution[][] transformSize = Av1DefaultDistributions.TransformSize;
private readonly Av1Distribution[][][] endOfBlockFlag;
private readonly Av1Distribution[][][] coefficientsBase;
private readonly Av1Distribution[][][] baseEndOfBlock;
private readonly Av1Distribution[][] dcSign;
private readonly Av1Distribution[][][] coefficientsBaseRange;
private readonly Av1Distribution[][] transformBlockSkip;
private readonly Av1Distribution[][][] endOfBlockExtra;
private Av1SymbolReader reader;
public Av1SymbolDecoder(Span<byte> tileData, int qIndex)
{
this.reader = new Av1SymbolReader(tileData);
this.endOfBlockFlag = Av1DefaultDistributions.GetEndOfBlockFlag(qIndex);
this.coefficientsBase = Av1DefaultDistributions.GetCoefficientsBase(qIndex);
this.baseEndOfBlock = Av1DefaultDistributions.GetBaseEndOfBlock(qIndex);
this.dcSign = Av1DefaultDistributions.GetDcSign(qIndex);
this.coefficientsBaseRange = Av1DefaultDistributions.GetCoefficientsBaseRange(qIndex);
this.transformBlockSkip = Av1DefaultDistributions.GetTransformBlockSkip(qIndex);
this.endOfBlockExtra = Av1DefaultDistributions.GetEndOfBlockExtra(qIndex);
}
public int ReadLiteral(int bitCount)
@ -188,17 +200,41 @@ internal ref struct Av1SymbolDecoder
return r.ReadSymbol(this.endOfBlockFlag[endOfBlockMultiSize][(int)planeType][endOfBlockContext]) + 1;
}
public bool ReadTransformBlockSkip(Av1TransformSize transformSizeContext, int skipContext) => throw new NotImplementedException();
public bool ReadTransformBlockSkip(Av1TransformSize transformSizeContext, int skipContext)
{
ref Av1SymbolReader r = ref this.reader;
return r.ReadSymbol(this.transformBlockSkip[(int)transformSizeContext][skipContext]) > 0;
}
public bool ReadEndOfBlockExtra(Av1TransformSize transformSizeContext, Av1PlaneType planeType, int endOfBlockContext) => throw new NotImplementedException();
public bool ReadEndOfBlockExtra(Av1TransformSize transformSizeContext, Av1PlaneType planeType, int endOfBlockContext)
{
ref Av1SymbolReader r = ref this.reader;
return r.ReadSymbol(this.endOfBlockExtra[(int)transformSizeContext][(int)planeType][endOfBlockContext]) > 0;
}
public int ReadBaseRange(Av1TransformSize transformSizeContext, Av1PlaneType planeType, int baseRangeContext) => throw new NotImplementedException();
public int ReadCoefficientsBaseRange(Av1TransformSize transformSizeContext, Av1PlaneType planeType, int baseRangeContext)
{
ref Av1SymbolReader r = ref this.reader;
return r.ReadSymbol(this.coefficientsBaseRange[(int)transformSizeContext][(int)planeType][baseRangeContext]);
}
public int ReadDcSign(Av1PlaneType planeType, int dcSignContext) => throw new NotImplementedException();
public int ReadDcSign(Av1PlaneType planeType, int dcSignContext)
{
ref Av1SymbolReader r = ref this.reader;
return r.ReadSymbol(this.dcSign[(int)planeType][dcSignContext]);
}
public int ReadBaseEndOfBlock(Av1TransformSize transformSizeContext, Av1PlaneType planeType, int coefficientContext) => throw new NotImplementedException();
public int ReadBaseEndOfBlock(Av1TransformSize transformSizeContext, Av1PlaneType planeType, int coefficientContext)
{
ref Av1SymbolReader r = ref this.reader;
return r.ReadSymbol(this.baseEndOfBlock[(int)transformSizeContext][(int)planeType][coefficientContext]);
}
public int ReadBase(int coeff_ctx, Av1TransformSize transformSizeContext, Av1PlaneType planeType) => throw new NotImplementedException();
public int ReadCoefficientsBase(int coefficientContext, Av1TransformSize transformSizeContext, Av1PlaneType planeType)
{
ref Av1SymbolReader r = ref this.reader;
return r.ReadSymbol(this.coefficientsBase[coefficientContext][(int)transformSizeContext][(int)planeType]);
}
private static uint GetElementProbability(Av1Distribution probability, Av1PartitionType element)
=> probability[(int)element - 1] - probability[(int)element];

10
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs

@ -642,7 +642,7 @@ internal class Av1TileDecoder : IAv1TileDecoder
int baseRangeContext = GetBaseRangeContextEndOfBlock(pos, bwl, transformClass);
for (int idx = 0; idx < Av1Constants.CoefficientBaseRange / Av1Constants.BaseRangeSizeMinus1; idx++)
{
int coefficinetBaseRange = reader.ReadBaseRange(transformSizeContext, planeType, baseRangeContext);
int coefficinetBaseRange = reader.ReadCoefficientsBaseRange(transformSizeContext, planeType, baseRangeContext);
level += coefficinetBaseRange;
if (coefficinetBaseRange < Av1Constants.BaseRangeSizeMinus1)
{
@ -715,13 +715,13 @@ internal class Av1TileDecoder : IAv1TileDecoder
{
int pos = scan[c];
int coeff_ctx = GetLowerLevelsContext2d(levels, pos, bwl, transformSize);
int level = reader.ReadBase(pos, transformSizeContext, planeType);
int level = reader.ReadCoefficientsBase(pos, transformSizeContext, planeType);
if (level > Av1Constants.BaseLevelsCount)
{
int baseRangeContext = GetBaseRangeContext2d(levels, pos, bwl);
for (int idx = 0; idx < Av1Constants.CoefficientBaseRange; idx += Av1Constants.BaseRangeSizeMinus1)
{
int k = reader.ReadBaseRange(transformSizeContext, planeType, baseRangeContext);
int k = reader.ReadCoefficientsBaseRange(transformSizeContext, planeType, baseRangeContext);
level += k;
if (k < Av1Constants.BaseRangeSizeMinus1)
{
@ -776,13 +776,13 @@ internal class Av1TileDecoder : IAv1TileDecoder
{
int pos = scan[c];
int coeff_ctx = GetLowerLevelsContext(levels, pos, bwl, transformSize, transformClass);
int level = reader.ReadBase(coeff_ctx, transformSizeContext, planeType);
int level = reader.ReadCoefficientsBase(coeff_ctx, transformSizeContext, planeType);
if (level > Av1Constants.BaseLevelsCount)
{
int baseRangeContext = GetBaseRangeContext(levels, pos, bwl, transformClass);
for (int idx = 0; idx < Av1Constants.CoefficientBaseRange; idx += Av1Constants.BaseRangeSizeMinus1)
{
int k = reader.ReadBaseRange(transformSizeContext, planeType, baseRangeContext);
int k = reader.ReadCoefficientsBaseRange(transformSizeContext, planeType, baseRangeContext);
level += k;
if (k < Av1Constants.BaseRangeSizeMinus1)
{

Loading…
Cancel
Save