mirror of https://github.com/SixLabors/ImageSharp
4 changed files with 149 additions and 2 deletions
@ -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; |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue