Coverage Report

Created: 2026-06-16 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libjxl/lib/jxl/lehmer_code.h
Line
Count
Source
1
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
2
//
3
// Use of this source code is governed by a BSD-style
4
// license that can be found in the LICENSE file.
5
6
#ifndef LIB_JXL_LEHMER_CODE_H_
7
#define LIB_JXL_LEHMER_CODE_H_
8
9
#include <stddef.h>
10
#include <stdint.h>
11
12
#include "lib/jxl/base/bits.h"
13
#include "lib/jxl/base/compiler_specific.h"
14
#include "lib/jxl/base/status.h"
15
16
namespace jxl {
17
18
// Permutation <=> factorial base representation (Lehmer code).
19
20
using LehmerT = uint32_t;
21
22
template <typename T>
23
73.9M
constexpr T ValueOfLowest1Bit(T t) {
24
73.9M
  return t & -t;
25
73.9M
}
unsigned int jxl::ValueOfLowest1Bit<unsigned int>(unsigned int)
Line
Count
Source
23
39.3M
constexpr T ValueOfLowest1Bit(T t) {
24
39.3M
  return t & -t;
25
39.3M
}
int jxl::ValueOfLowest1Bit<int>(int)
Line
Count
Source
23
5.69M
constexpr T ValueOfLowest1Bit(T t) {
24
5.69M
  return t & -t;
25
5.69M
}
unsigned long jxl::ValueOfLowest1Bit<unsigned long>(unsigned long)
Line
Count
Source
23
28.8M
constexpr T ValueOfLowest1Bit(T t) {
24
28.8M
  return t & -t;
25
28.8M
}
26
27
// Computes the Lehmer (factorial basis) code of permutation, an array of n
28
// unique indices in [0..n), and stores it in code[0..len). N*logN time.
29
// temp must have n + 1 elements but need not be initialized.
30
template <typename PermutationT>
31
Status ComputeLehmerCode(const PermutationT* JXL_RESTRICT permutation,
32
                         uint32_t* JXL_RESTRICT temp, const size_t n,
33
34.7k
                         LehmerT* JXL_RESTRICT code) {
34
7.43M
  for (size_t idx = 0; idx < n + 1; ++idx) temp[idx] = 0;
35
36
7.39M
  for (size_t idx = 0; idx < n; ++idx) {
37
7.36M
    const PermutationT s = permutation[idx];
38
39
    // Compute sum in Fenwick tree
40
7.36M
    uint32_t penalty = 0;
41
7.36M
    uint32_t i = s + 1;
42
39.4M
    while (i != 0) {
43
32.0M
      penalty += temp[i];
44
32.0M
      i &= i - 1;  // clear lowest bit
45
32.0M
    }
46
7.36M
    JXL_ENSURE(s >= penalty);
47
7.36M
    code[idx] = s - penalty;
48
7.36M
    i = s + 1;
49
    // Add operation in Fenwick tree
50
46.7M
    while (i < n + 1) {
51
39.3M
      temp[i] += 1;
52
39.3M
      i += ValueOfLowest1Bit(i);
53
39.3M
    }
54
7.36M
  }
55
34.7k
  return true;
56
34.7k
}
57
58
// Decodes the Lehmer code in code[0..n) into permutation[0..n).
59
// temp must have 1 << CeilLog2(n) elements but need not be initialized.
60
template <typename PermutationT>
61
Status DecodeLehmerCode(const LehmerT* JXL_RESTRICT code,
62
                        uint32_t* JXL_RESTRICT temp, size_t n,
63
118k
                        PermutationT* JXL_RESTRICT permutation) {
64
118k
  JXL_ENSURE(n != 0);
65
118k
  const size_t log2n = CeilLog2Nonzero(n);
66
118k
  const size_t padded_n = 1ull << log2n;
67
68
5.81M
  for (size_t i = 0; i < padded_n; i++) {
69
5.69M
    const int32_t i1 = static_cast<int32_t>(i + 1);
70
5.69M
    temp[i] = static_cast<uint32_t>(ValueOfLowest1Bit(i1));
71
5.69M
  }
72
73
5.80M
  for (size_t i = 0; i < n; i++) {
74
5.68M
    JXL_ENSURE(code[i] + i < n);
75
5.68M
    uint32_t rank = code[i] + 1;
76
77
    // Extract i-th unused element via implicit order-statistics tree.
78
5.68M
    size_t bit = padded_n;
79
5.68M
    size_t next = 0;
80
57.6M
    for (size_t b = 0; b <= log2n; b++) {
81
52.0M
      const size_t cand = next + bit;
82
52.0M
      JXL_ENSURE(cand >= 1);
83
52.0M
      bit >>= 1;
84
52.0M
      if (temp[cand - 1] < rank) {
85
23.1M
        next = cand;
86
23.1M
        rank -= temp[cand - 1];
87
23.1M
      }
88
52.0M
    }
89
90
5.68M
    permutation[i] = next;
91
92
    // Mark as used
93
5.68M
    next += 1;
94
34.5M
    while (next <= padded_n) {
95
28.8M
      temp[next - 1] -= 1;
96
28.8M
      next += ValueOfLowest1Bit(next);
97
28.8M
    }
98
5.68M
  }
99
118k
  return true;
100
118k
}
101
102
}  // namespace jxl
103
104
#endif  // LIB_JXL_LEHMER_CODE_H_