mirror of https://github.com/SixLabors/ImageSharp
1 changed files with 106 additions and 0 deletions
@ -0,0 +1,106 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Six Labors Split License.
|
||||
|
|
||||
|
using System.Runtime.CompilerServices; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Formats.Jxl.Processing; |
||||
|
|
||||
|
internal static class JxlLehmerCode |
||||
|
{ |
||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
|
private static int ValueOfLowest1Bit(int n) => n & -n; |
||||
|
|
||||
|
public static bool ComputeLehmerCode(ReadOnlySpan<int> permutation, Span<uint> temp, int n, Span<uint> code) |
||||
|
{ |
||||
|
temp[(n + 1)..].Clear(); |
||||
|
|
||||
|
for (int idx = 0; idx < n; idx++) |
||||
|
{ |
||||
|
int s = permutation[idx]; |
||||
|
|
||||
|
uint penalty = 0u; |
||||
|
uint i = (uint)s + 1u; |
||||
|
|
||||
|
while (i != 0u) |
||||
|
{ |
||||
|
penalty += temp[(int)i]; |
||||
|
i &= i - 1u; // Clear lowest bit
|
||||
|
} |
||||
|
|
||||
|
if (s < penalty) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
code[idx] = (uint)s - penalty; |
||||
|
i = (uint)s + 1u; |
||||
|
|
||||
|
while (i < n + 1u) |
||||
|
{ |
||||
|
temp[(int)i]++; |
||||
|
i += (uint)ValueOfLowest1Bit((int)i); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
public static bool DecodeLehmerCode(ReadOnlySpan<uint> code, Span<uint> temp, int n, Span<int> permutation) |
||||
|
{ |
||||
|
if (n == 0) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
int log2n = CeilLog2Nonzero(n); |
||||
|
int paddedN = 1 << log2n; |
||||
|
|
||||
|
for (int i = 0; i < paddedN; i++) |
||||
|
{ |
||||
|
int i1 = i + 1; |
||||
|
temp[i] = (uint)ValueOfLowest1Bit(i1); |
||||
|
} |
||||
|
|
||||
|
for (int i = 0; i < n; i++) |
||||
|
{ |
||||
|
if (code[i] + i >= n) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
uint rank = code[i] + 1; |
||||
|
|
||||
|
int bit = paddedN; |
||||
|
int next = 0; |
||||
|
|
||||
|
for (int b = 0; b <= log2n; b++) |
||||
|
{ |
||||
|
int cand = next + bit; |
||||
|
|
||||
|
if (cand < 1) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
bit >>= 1; |
||||
|
|
||||
|
if (temp[cand - 1] < rank) |
||||
|
{ |
||||
|
next = cand; |
||||
|
rank -= temp[cand - 1]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
permutation[i] = next; |
||||
|
|
||||
|
next++; |
||||
|
while (next <= paddedN) |
||||
|
{ |
||||
|
temp[next - 1]--; |
||||
|
next += ValueOfLowest1Bit(next); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue