Coverage Report

Created: 2025-08-12 07:37

/src/libjxl/lib/jxl/enc_ans_params.h
Line
Count
Source (jump to first uncovered line)
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_ENC_ANS_PARAMS_H_
7
#define LIB_JXL_ENC_ANS_PARAMS_H_
8
9
// Encoder-only parameter needed for ANS entropy encoding methods.
10
11
#include <cstdint>
12
#include <cstdlib>
13
#include <utility>
14
#include <vector>
15
16
#include "lib/jxl/ans_common.h"
17
#include "lib/jxl/base/common.h"
18
#include "lib/jxl/base/status.h"
19
#include "lib/jxl/common.h"
20
#include "lib/jxl/dec_ans.h"
21
22
namespace jxl {
23
24
// Forward declaration to break include cycle.
25
struct CompressParams;
26
27
// RebalanceHistogram requires a signed type.
28
using ANSHistBin = int32_t;
29
30
struct HistogramParams {
31
  enum class ClusteringType {
32
    kFastest,  // Only 4 clusters.
33
    kFast,
34
    kBest,
35
  };
36
37
  enum class HybridUintMethod {
38
    kNone,        // just use kHybridUint420Config.
39
    k000,         // force the fastest option.
40
    kFast,        // just try a couple of options.
41
    kContextMap,  // fast choice for ctx map.
42
    kBest,
43
  };
44
45
  enum class LZ77Method {
46
    kNone,     // do not try lz77.
47
    kRLE,      // only try doing RLE.
48
    kLZ77,     // try lz77 with backward references.
49
    kOptimal,  // optimal-matching LZ77 parsing.
50
  };
51
52
  enum class ANSHistogramStrategy {
53
    kFast,         // Only try some methods, early exit.
54
    kApproximate,  // Only try some methods.
55
    kPrecise,      // Try all methods.
56
  };
57
58
37.2k
  HistogramParams() = default;
59
60
162
  HistogramParams(SpeedTier tier, size_t num_ctx) {
61
162
    if (tier > SpeedTier::kFalcon) {
62
0
      clustering = ClusteringType::kFastest;
63
0
      lz77_method = LZ77Method::kNone;
64
162
    } else if (tier > SpeedTier::kTortoise) {
65
162
      clustering = ClusteringType::kFast;
66
162
    } else {
67
0
      clustering = ClusteringType::kBest;
68
0
    }
69
162
    if (tier > SpeedTier::kTortoise) {
70
162
      uint_method = HybridUintMethod::kNone;
71
162
    }
72
162
    if (tier >= SpeedTier::kSquirrel) {
73
162
      ans_histogram_strategy = ANSHistogramStrategy::kApproximate;
74
162
    }
75
162
  }
76
77
  static HistogramParams ForModular(
78
      const CompressParams& cparams,
79
      const std::vector<uint8_t>& extra_dc_precision, bool streaming_mode);
80
81
5.81k
  HybridUintConfig UintConfig() const {
82
5.81k
    if (uint_method == HistogramParams::HybridUintMethod::kContextMap) {
83
4.22k
      return HybridUintConfig(2, 0, 1);
84
4.22k
    }
85
1.58k
    if (uint_method == HistogramParams::HybridUintMethod::k000) {
86
0
      return HybridUintConfig(0, 0, 0);
87
0
    }
88
    // Default config for clustering.
89
1.58k
    return HybridUintConfig();
90
1.58k
  }
91
92
  ClusteringType clustering = ClusteringType::kBest;
93
  HybridUintMethod uint_method = HybridUintMethod::kBest;
94
  LZ77Method lz77_method = LZ77Method::kRLE;
95
  ANSHistogramStrategy ans_histogram_strategy = ANSHistogramStrategy::kPrecise;
96
  std::vector<size_t> image_widths;
97
  size_t max_histograms = ~0;
98
  bool force_huffman = false;
99
  bool initialize_global_state = true;
100
  bool streaming_mode = false;
101
  bool add_missing_symbols = false;
102
  bool add_fixed_histograms = false;
103
};
104
105
struct Histogram {
106
493k
  Histogram() = default;
107
108
0
  explicit Histogram(size_t length) { EnsureCapacity(length); }
109
110
  // Create flat histogram
111
0
  static Histogram Flat(int length, int total_count) {
112
0
    Histogram flat;
113
0
    flat.counts = CreateFlatHistogram(length, total_count);
114
0
    flat.total_count = static_cast<size_t>(total_count);
115
0
    return flat;
116
0
  }
117
187
  void Clear() {
118
187
    counts.clear();
119
187
    total_count = 0;
120
187
    entropy = 0.0;
121
187
  }
122
32.8M
  void Add(size_t symbol) {
123
32.8M
    if (counts.size() <= symbol) {
124
246k
      counts.resize(DivCeil(symbol + 1, kRounding) * kRounding);
125
246k
    }
126
32.8M
    ++counts[symbol];
127
32.8M
    ++total_count;
128
32.8M
  }
129
130
  // Use this before FastAdd sequence.
131
35.3k
  void EnsureCapacity(size_t length) {
132
35.3k
    counts.resize(DivCeil(length, kRounding) * kRounding);
133
35.3k
  }
134
  // Just increment symbol counter; caller must stretch Histogram beforehead.
135
47.0M
  void FastAdd(size_t symbol) { (*(counts.data() + symbol))++; }
136
  // Should be called after sequence of FastAdd to actualize total_count.
137
  void Condition();
138
139
145k
  void AddHistogram(const Histogram& other) {
140
145k
    if (other.counts.size() > counts.size()) {
141
7.29k
      counts.resize(other.counts.size());
142
7.29k
    }
143
3.23M
    for (size_t i = 0; i < other.counts.size(); ++i) {
144
3.08M
      counts[i] += other.counts[i];
145
3.08M
    }
146
145k
    total_count += other.total_count;
147
145k
  }
148
143k
  size_t alphabet_size() const {
149
676k
    for (int i = counts.size() - 1; i >= 0; --i) {
150
676k
      if (counts[i] > 0) {
151
143k
        return i + 1;
152
143k
      }
153
676k
    }
154
0
    return 0;
155
143k
  }
156
157
4.59k
  size_t MaxSymbol() const {
158
4.59k
    if (total_count == 0) return 0;
159
20.4k
    for (int i = counts.size() - 1; i > 0; --i) {
160
20.3k
      if (counts[i]) return i;
161
20.3k
    }
162
50
    return 0;
163
4.59k
  }
164
165
  // Returns an estimate of the number of bits required to encode the given
166
  // histogram (header bits plus data bits).
167
  StatusOr<float> ANSPopulationCost() const;
168
169
  float ShannonEntropy() const;
170
171
9.68k
  void swap(Histogram& other) {
172
9.68k
    counts.swap(other.counts);
173
9.68k
    std::swap(total_count, other.total_count);
174
9.68k
    std::swap(entropy, other.entropy);
175
9.68k
  }
176
177
  std::vector<ANSHistBin> counts;
178
  size_t total_count = 0;
179
  mutable float entropy = 0;  // WARNING: not kept up-to-date.
180
  static constexpr size_t kRounding = 8;
181
};
182
183
}  // namespace jxl
184
185
#endif  // LIB_JXL_ENC_ANS_PARAMS_H_