Browse Source

Remove code duplication in coefficient reading

pull/2633/head
Ynse Hoornenborg 1 year ago
parent
commit
38e649572e
  1. 32
      src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolDecoder.cs
  2. 23
      tests/ImageSharp.Tests/Formats/Heif/Av1/Av1CoefficientsEntropyTests.cs

32
src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolDecoder.cs

@ -410,15 +410,7 @@ internal ref struct Av1SymbolDecoder
if (level > Av1Constants.BaseLevelsCount)
{
int baseRangeContext = Av1SymbolContextHelper.GetBaseRangeContextEndOfBlock(position, transformClass);
for (int idx = 0; idx < Av1Constants.CoefficientBaseRange; idx += Av1Constants.BaseRangeSizeMinus1)
{
int coefficientBaseRange = this.ReadCoefficientsBaseRange(limitedTransformSizeContext, planeType, baseRangeContext);
level += coefficientBaseRange;
if (coefficientBaseRange < Av1Constants.BaseRangeSizeMinus1)
{
break;
}
}
this.ReadCoefficientsBaseRangeLoop(transformSizeContext, planeType, baseRangeContext, ref level);
}
levels.GetRow(position)[position.X] = (byte)level;
@ -435,15 +427,7 @@ internal ref struct Av1SymbolDecoder
if (level > Av1Constants.BaseLevelsCount)
{
int baseRangeContext = Av1SymbolContextHelper.GetBaseRangeContext2d(levels, position);
for (int idx = 0; idx < Av1Constants.CoefficientBaseRange; idx += Av1Constants.BaseRangeSizeMinus1)
{
int coefficientBaseRange = this.ReadCoefficientsBaseRange(limitedTransformSizeContext, planeType, baseRangeContext);
level += coefficientBaseRange;
if (coefficientBaseRange < Av1Constants.BaseRangeSizeMinus1)
{
break;
}
}
this.ReadCoefficientsBaseRangeLoop(transformSizeContext, planeType, baseRangeContext, ref level);
}
levels.GetRow(position)[position.X] = (byte)level;
@ -462,15 +446,7 @@ internal ref struct Av1SymbolDecoder
if (level > Av1Constants.BaseLevelsCount)
{
int baseRangeContext = Av1SymbolContextHelper.GetBaseRangeContext(levels, position, transformClass);
for (int idx = 0; idx < Av1Constants.CoefficientBaseRange; idx += Av1Constants.BaseRangeSizeMinus1)
{
int coefficientBaseRange = this.ReadCoefficientsBaseRange(limitedTransformSizeContext, planeType, baseRangeContext);
level += coefficientBaseRange;
if (coefficientBaseRange < Av1Constants.BaseRangeSizeMinus1)
{
break;
}
}
this.ReadCoefficientsBaseRangeLoop(transformSizeContext, planeType, baseRangeContext, ref level);
}
levels.GetRow(position)[position.X] = (byte)level;
@ -566,7 +542,7 @@ internal ref struct Av1SymbolDecoder
{
ref Av1SymbolReader r = ref this.reader;
Av1TransformSize limitedTransformSizeContext = (Av1TransformSize)Math.Min((int)transformSizeContext, (int)Av1TransformSize.Size32x32);
Av1Distribution distribution = this.coefficientsBaseRange[(int)transformSizeContext][(int)planeType][baseRangeContext];
Av1Distribution distribution = this.coefficientsBaseRange[(int)limitedTransformSizeContext][(int)planeType][baseRangeContext];
for (int idx = 0; idx < Av1Constants.CoefficientBaseRange; idx += Av1Constants.BaseRangeSizeMinus1)
{
int coefficientBaseRange = r.ReadSymbol(distribution);

23
tests/ImageSharp.Tests/Formats/Heif/Av1/Av1CoefficientsEntropyTests.cs

@ -112,6 +112,26 @@ public class Av1CoefficientsEntropyTests
Av1TransformType transformType = (Av1TransformType)txType;
Av1PredictionMode intraDirection = Av1PredictionMode.DC;
Av1FilterIntraMode filterIntraMode = Av1FilterIntraMode.DC;
RoundTripCoefficientsCore(endOfBlock, componentType, blockSize, transformSize, transformType, intraDirection, filterIntraMode);
}
[Theory]
[MemberData(nameof(GetBlockSize4x4Data))]
public void RoundTripFullCoefficientsUvSize4x4(int bSize, int txSize, int txType)
{
// Assign
const ushort endOfBlock = 16;
const Av1ComponentType componentType = Av1ComponentType.Chroma;
Av1BlockSize blockSize = (Av1BlockSize)bSize;
Av1TransformSize transformSize = (Av1TransformSize)txSize;
Av1TransformType transformType = (Av1TransformType)txType;
Av1PredictionMode intraDirection = Av1PredictionMode.DC;
Av1FilterIntraMode filterIntraMode = Av1FilterIntraMode.DC;
RoundTripCoefficientsCore(endOfBlock, componentType, blockSize, transformSize, transformType, intraDirection, filterIntraMode);
}
private static void RoundTripCoefficientsCore(ushort endOfBlock, Av1ComponentType componentType, Av1BlockSize blockSize, Av1TransformSize transformSize, Av1TransformType transformType, Av1PredictionMode intraDirection, Av1FilterIntraMode filterIntraMode)
{
Av1BlockModeInfo modeInfo = new(Av1Constants.MaxPlanes, blockSize, new Point(0, 0));
Av1TransformInfo transformInfo = new(transformSize, 0, 0);
int[] aboveContexts = new int[transformSize.Get4x4WideCount()];
@ -124,8 +144,7 @@ public class Av1CoefficientsEntropyTests
// Act
encoder.WriteCoefficients(transformSize, transformType, intraDirection, coefficientsBuffer, componentType, transformBlockContext, endOfBlock, true, filterIntraMode);
using IMemoryOwner<byte> encoded = encoder.Exit();
IMemoryOwner<byte> encoded = encoder.Exit();
Av1SymbolDecoder decoder = new(Configuration.Default, encoded.GetSpan(), BaseQIndex);
int plane = Math.Min((int)componentType, 1);

Loading…
Cancel
Save