Browse Source

Implement ac_context.h

pull/3153/head
winscripter 3 days ago
parent
commit
996e93dba2
  1. 53
      src/ImageSharp/Formats/Jxl/Ac/JxlAcContext.cs
  2. 72
      src/ImageSharp/Formats/Jxl/Ac/JxlBlockContextMap.cs
  3. 24
      src/ImageSharp/Formats/Jxl/Coefficients/JxlForwardCoefficientOrder.cs
  4. 2
      src/ImageSharp/Formats/Jxl/JxlFormat.cs

53
src/ImageSharp/Formats/Jxl/Ac/JxlAcContext.cs

@ -0,0 +1,53 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Diagnostics;
using System.Runtime.CompilerServices;
#pragma warning disable SA1405 // Debug.Assert should provide message text
namespace SixLabors.ImageSharp.Formats.Jxl.Ac;
/// <summary>
/// AC context
/// </summary>
internal static class JxlAcContext
{
public const int DctOrderContextStart = 0;
public const int NonZeroBuckets = 37;
public const int ZeroDensityContextCount = 458;
public const int ZeroDensityContextLimit = 474;
public static ReadOnlySpan<int> CoefficientFrequencyContext =>
[
0xBAD, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26,
27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30,
];
public static ReadOnlySpan<int> CoefficientNumNonzeroContext =>
[
0xBAD, 0, 31, 62, 62, 93, 93, 93, 93, 123, 123, 123, 123,
152, 152, 152, 152, 152, 152, 152, 152, 180, 180, 180, 180, 180,
180, 180, 180, 180, 180, 180, 180, 206, 206, 206, 206, 206, 206,
206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
];
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int ZeroDensityContext(int nonZeroesLeft, int k, int coveredBlocks, int log2CoveredBlocks, int prev)
{
Debug.Assert((1 << log2CoveredBlocks) == coveredBlocks);
nonZeroesLeft = (nonZeroesLeft + coveredBlocks - 1) >> log2CoveredBlocks;
k >>= log2CoveredBlocks;
Debug.Assert(k > 0);
Debug.Assert(k < 64);
Debug.Assert(nonZeroesLeft > 0);
Debug.Assert(nonZeroesLeft < 64);
return ((CoefficientNumNonzeroContext[nonZeroesLeft] + CoefficientFrequencyContext[k]) * 2) + prev;
}
}

72
src/ImageSharp/Formats/Jxl/Ac/JxlBlockContextMap.cs

@ -0,0 +1,72 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Formats.Jxl.Coefficients;
namespace SixLabors.ImageSharp.Formats.Jxl.Ac;
internal sealed class JxlBlockContextMap
{
public JxlBlockContextMap()
{
DefaultContextMap.CopyTo(this.ContextMap);
this.ContextCount = this.ContextMap.Max() + 1;
this.DcContextCount = 1;
}
private static ReadOnlySpan<byte> DefaultContextMap =>
[
0, 1, 2, 2, 3, 3, 4, 5, 6, 6, 6, 6, 6,
7, 8, 9, 9, 10, 11, 12, 13, 14, 14, 14, 14, 14,
7, 8, 9, 9, 10, 11, 12, 13, 14, 14, 14, 14, 14,
];
public List<int>[] DcThresholds { get; } = [[], [], []];
public List<uint> QfThresholds { get; } = [];
public byte[] ContextMap { get; } = new byte[DefaultContextMap.Length];
public int ContextCount { get; set; }
public int DcContextCount { get; set; }
public int AcContextCount => (this.ContextCount * JxlAcContext.NonZeroBuckets) + JxlAcContext.ZeroDensityContextCount;
public int Context(int dcIndex, uint qf, int ord, int c)
{
int qfIndex = 0;
for (int i = 0; i < this.QfThresholds.Count; i++)
{
uint t = this.QfThresholds[i];
if (qf > t)
{
qfIndex++;
}
}
int idx = c < 2 ? c ^ 1 : 2;
idx = (idx * JxlForwardCoefficientOrder.OrderCount) + ord;
idx = (idx * (this.QfThresholds.Count + 1)) + qfIndex;
idx = (idx * this.DcContextCount) + dcIndex;
return this.ContextMap[idx];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int ZeroDensityContextOffset(int blockContext) =>
(this.ContextCount * JxlAcContext.NonZeroBuckets) + JxlAcContext.ZeroDensityContextCount + blockContext;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int NonZeroContext(int nonZeroes, int blockContext)
{
if (nonZeroes >= 64)
{
nonZeroes = 64;
}
int ctx = nonZeroes < 8 ? nonZeroes : (4 + (nonZeroes / 2));
return (ctx * this.ContextCount) + blockContext;
}
}

24
src/ImageSharp/Formats/Jxl/Coefficients/JxlForwardCoefficientOrder.cs

@ -0,0 +1,24 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Runtime.CompilerServices;
namespace SixLabors.ImageSharp.Formats.Jxl.Coefficients;
internal static class JxlForwardCoefficientOrder
{
public const byte OrderCount = 13;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int CoefficientRows(int rows, int columns) => rows < columns ? rows : columns;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int CoefficientColumns(int rows, int columns) => rows < columns ? columns : rows;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CoefficientLayout(ref int rows, ref int columns)
{
rows = CoefficientRows(rows, columns);
columns = CoefficientColumns(rows, columns);
}
}

2
src/ImageSharp/Formats/Jxl/JxlFormat.cs

@ -1,8 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Collections.Generic;
namespace SixLabors.ImageSharp.Formats.Jxl;
internal class JxlFormat : IImageFormat

Loading…
Cancel
Save