Coverage Report

Created: 2026-05-24 07:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libjxl/lib/jxl/quant_weights.cc
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
#include "lib/jxl/quant_weights.h"
6
7
#include <jxl/memory_manager.h>
8
9
#include <cmath>
10
#include <cstdint>
11
#include <cstdio>
12
#include <cstdlib>
13
#include <vector>
14
15
#include "lib/jxl/ac_strategy.h"
16
#include "lib/jxl/base/compiler_specific.h"
17
#include "lib/jxl/base/status.h"
18
#include "lib/jxl/coeff_order_fwd.h"
19
#include "lib/jxl/dct_scales.h"
20
#include "lib/jxl/dec_bit_reader.h"
21
#include "lib/jxl/dec_modular.h"
22
#include "lib/jxl/fields.h"
23
#include "lib/jxl/frame_dimensions.h"
24
#include "lib/jxl/memory_manager_internal.h"
25
26
#undef HWY_TARGET_INCLUDE
27
#define HWY_TARGET_INCLUDE "lib/jxl/quant_weights.cc"
28
#include <hwy/foreach_target.h>
29
#include <hwy/highway.h>
30
31
#include "lib/jxl/base/fast_math-inl.h"
32
33
HWY_BEFORE_NAMESPACE();
34
namespace jxl {
35
namespace HWY_NAMESPACE {
36
37
// These templates are not found via ADL.
38
using hwy::HWY_NAMESPACE::Lt;
39
using hwy::HWY_NAMESPACE::MulAdd;
40
using hwy::HWY_NAMESPACE::Sqrt;
41
42
// kQuantWeights[N * N * c + N * y + x] is the relative weight of the (x, y)
43
// coefficient in component c. Higher weights correspond to finer quantization
44
// intervals and more bits spent in encoding.
45
46
static constexpr const float kAlmostZero = 1e-8f;
47
48
void GetQuantWeightsDCT2(const QuantEncoding::DCT2Weights& dct2weights,
49
5.52k
                         float* weights) {
50
22.0k
  for (size_t c = 0; c < 3; c++) {
51
16.5k
    size_t start = c * 64;
52
16.5k
    weights[start] = 0xBAD;
53
16.5k
    weights[start + 1] = weights[start + 8] = dct2weights[c][0];
54
16.5k
    weights[start + 9] = dct2weights[c][1];
55
49.6k
    for (size_t y = 0; y < 2; y++) {
56
99.3k
      for (size_t x = 0; x < 2; x++) {
57
66.2k
        weights[start + y * 8 + x + 2] = dct2weights[c][2];
58
66.2k
        weights[start + (y + 2) * 8 + x] = dct2weights[c][2];
59
66.2k
      }
60
33.1k
    }
61
49.6k
    for (size_t y = 0; y < 2; y++) {
62
99.3k
      for (size_t x = 0; x < 2; x++) {
63
66.2k
        weights[start + (y + 2) * 8 + x + 2] = dct2weights[c][3];
64
66.2k
      }
65
33.1k
    }
66
82.8k
    for (size_t y = 0; y < 4; y++) {
67
331k
      for (size_t x = 0; x < 4; x++) {
68
264k
        weights[start + y * 8 + x + 4] = dct2weights[c][4];
69
264k
        weights[start + (y + 4) * 8 + x] = dct2weights[c][4];
70
264k
      }
71
66.2k
    }
72
82.8k
    for (size_t y = 0; y < 4; y++) {
73
331k
      for (size_t x = 0; x < 4; x++) {
74
264k
        weights[start + (y + 4) * 8 + x + 4] = dct2weights[c][5];
75
264k
      }
76
66.2k
    }
77
16.5k
  }
78
5.52k
}
Unexecuted instantiation: jxl::N_SSE4::GetQuantWeightsDCT2(std::__1::array<std::__1::array<float, 6ul>, 3ul> const&, float*)
jxl::N_AVX2::GetQuantWeightsDCT2(std::__1::array<std::__1::array<float, 6ul>, 3ul> const&, float*)
Line
Count
Source
49
5.52k
                         float* weights) {
50
22.0k
  for (size_t c = 0; c < 3; c++) {
51
16.5k
    size_t start = c * 64;
52
16.5k
    weights[start] = 0xBAD;
53
16.5k
    weights[start + 1] = weights[start + 8] = dct2weights[c][0];
54
16.5k
    weights[start + 9] = dct2weights[c][1];
55
49.6k
    for (size_t y = 0; y < 2; y++) {
56
99.3k
      for (size_t x = 0; x < 2; x++) {
57
66.2k
        weights[start + y * 8 + x + 2] = dct2weights[c][2];
58
66.2k
        weights[start + (y + 2) * 8 + x] = dct2weights[c][2];
59
66.2k
      }
60
33.1k
    }
61
49.6k
    for (size_t y = 0; y < 2; y++) {
62
99.3k
      for (size_t x = 0; x < 2; x++) {
63
66.2k
        weights[start + (y + 2) * 8 + x + 2] = dct2weights[c][3];
64
66.2k
      }
65
33.1k
    }
66
82.8k
    for (size_t y = 0; y < 4; y++) {
67
331k
      for (size_t x = 0; x < 4; x++) {
68
264k
        weights[start + y * 8 + x + 4] = dct2weights[c][4];
69
264k
        weights[start + (y + 4) * 8 + x] = dct2weights[c][4];
70
264k
      }
71
66.2k
    }
72
82.8k
    for (size_t y = 0; y < 4; y++) {
73
331k
      for (size_t x = 0; x < 4; x++) {
74
264k
        weights[start + (y + 4) * 8 + x + 4] = dct2weights[c][5];
75
264k
      }
76
66.2k
    }
77
16.5k
  }
78
5.52k
}
Unexecuted instantiation: jxl::N_AVX3::GetQuantWeightsDCT2(std::__1::array<std::__1::array<float, 6ul>, 3ul> const&, float*)
Unexecuted instantiation: jxl::N_AVX3_ZEN4::GetQuantWeightsDCT2(std::__1::array<std::__1::array<float, 6ul>, 3ul> const&, float*)
Unexecuted instantiation: jxl::N_AVX3_SPR::GetQuantWeightsDCT2(std::__1::array<std::__1::array<float, 6ul>, 3ul> const&, float*)
Unexecuted instantiation: jxl::N_SSE2::GetQuantWeightsDCT2(std::__1::array<std::__1::array<float, 6ul>, 3ul> const&, float*)
79
80
void GetQuantWeightsIdentity(const QuantEncoding::IdWeights& idweights,
81
6.82k
                             float* weights) {
82
27.2k
  for (size_t c = 0; c < 3; c++) {
83
1.33M
    for (int i = 0; i < 64; i++) {
84
1.30M
      weights[64 * c + i] = idweights[c][0];
85
1.30M
    }
86
20.4k
    weights[64 * c + 1] = idweights[c][1];
87
20.4k
    weights[64 * c + 8] = idweights[c][1];
88
20.4k
    weights[64 * c + 9] = idweights[c][2];
89
20.4k
  }
90
6.82k
}
Unexecuted instantiation: jxl::N_SSE4::GetQuantWeightsIdentity(std::__1::array<std::__1::array<float, 3ul>, 3ul> const&, float*)
jxl::N_AVX2::GetQuantWeightsIdentity(std::__1::array<std::__1::array<float, 3ul>, 3ul> const&, float*)
Line
Count
Source
81
6.82k
                             float* weights) {
82
27.2k
  for (size_t c = 0; c < 3; c++) {
83
1.33M
    for (int i = 0; i < 64; i++) {
84
1.30M
      weights[64 * c + i] = idweights[c][0];
85
1.30M
    }
86
20.4k
    weights[64 * c + 1] = idweights[c][1];
87
20.4k
    weights[64 * c + 8] = idweights[c][1];
88
20.4k
    weights[64 * c + 9] = idweights[c][2];
89
20.4k
  }
90
6.82k
}
Unexecuted instantiation: jxl::N_AVX3::GetQuantWeightsIdentity(std::__1::array<std::__1::array<float, 3ul>, 3ul> const&, float*)
Unexecuted instantiation: jxl::N_AVX3_ZEN4::GetQuantWeightsIdentity(std::__1::array<std::__1::array<float, 3ul>, 3ul> const&, float*)
Unexecuted instantiation: jxl::N_AVX3_SPR::GetQuantWeightsIdentity(std::__1::array<std::__1::array<float, 3ul>, 3ul> const&, float*)
Unexecuted instantiation: jxl::N_SSE2::GetQuantWeightsIdentity(std::__1::array<std::__1::array<float, 3ul>, 3ul> const&, float*)
91
92
StatusOr<float> Interpolate(float pos, float max, const float* array,
93
263k
                            size_t len) {
94
263k
  float scaled_pos = pos * (len - 1) / max;
95
263k
  size_t idx = scaled_pos;
96
263k
  JXL_ENSURE(idx + 1 < len);
97
263k
  float a = array[idx];
98
263k
  float b = array[idx + 1];
99
263k
  return a * FastPowf(b / a, scaled_pos - idx);
100
263k
}
Unexecuted instantiation: jxl::N_SSE4::Interpolate(float, float, float const*, unsigned long)
jxl::N_AVX2::Interpolate(float, float, float const*, unsigned long)
Line
Count
Source
93
263k
                            size_t len) {
94
263k
  float scaled_pos = pos * (len - 1) / max;
95
263k
  size_t idx = scaled_pos;
96
263k
  JXL_ENSURE(idx + 1 < len);
97
263k
  float a = array[idx];
98
263k
  float b = array[idx + 1];
99
263k
  return a * FastPowf(b / a, scaled_pos - idx);
100
263k
}
Unexecuted instantiation: jxl::N_AVX3::Interpolate(float, float, float const*, unsigned long)
Unexecuted instantiation: jxl::N_AVX3_ZEN4::Interpolate(float, float, float const*, unsigned long)
Unexecuted instantiation: jxl::N_AVX3_SPR::Interpolate(float, float, float const*, unsigned long)
Unexecuted instantiation: jxl::N_SSE2::Interpolate(float, float, float const*, unsigned long)
101
102
1.33M
float Mult(float v) {
103
1.33M
  if (v > 0.0f) return 1.0f + v;
104
1.33M
  return 1.0f / (1.0f - v);
105
1.33M
}
Unexecuted instantiation: jxl::N_SSE4::Mult(float)
jxl::N_AVX2::Mult(float)
Line
Count
Source
102
1.33M
float Mult(float v) {
103
1.33M
  if (v > 0.0f) return 1.0f + v;
104
1.33M
  return 1.0f / (1.0f - v);
105
1.33M
}
Unexecuted instantiation: jxl::N_AVX3::Mult(float)
Unexecuted instantiation: jxl::N_AVX3_ZEN4::Mult(float)
Unexecuted instantiation: jxl::N_AVX3_SPR::Mult(float)
Unexecuted instantiation: jxl::N_SSE2::Mult(float)
106
107
using DF4 = HWY_CAPPED(float, 4);
108
109
hwy::HWY_NAMESPACE::Vec<DF4> InterpolateVec(
110
29.9M
    hwy::HWY_NAMESPACE::Vec<DF4> scaled_pos, const float* array) {
111
29.9M
  HWY_CAPPED(int32_t, 4) di;
112
113
29.9M
  auto idx = ConvertTo(di, scaled_pos);
114
115
29.9M
  auto frac = Sub(scaled_pos, ConvertTo(DF4(), idx));
116
117
  // TODO(veluca): in theory, this could be done with 8 TableLookupBytes, but
118
  // it's probably slower.
119
29.9M
  auto a = GatherIndex(DF4(), array, idx);
120
29.9M
  auto b = GatherIndex(DF4(), array + 1, idx);
121
122
29.9M
  return Mul(a, FastPowf(DF4(), Div(b, a), frac));
123
29.9M
}
Unexecuted instantiation: jxl::N_SSE4::InterpolateVec(hwy::N_SSE4::Vec128<float, 4ul>, float const*)
jxl::N_AVX2::InterpolateVec(hwy::N_AVX2::Vec128<float, 4ul>, float const*)
Line
Count
Source
110
29.9M
    hwy::HWY_NAMESPACE::Vec<DF4> scaled_pos, const float* array) {
111
29.9M
  HWY_CAPPED(int32_t, 4) di;
112
113
29.9M
  auto idx = ConvertTo(di, scaled_pos);
114
115
29.9M
  auto frac = Sub(scaled_pos, ConvertTo(DF4(), idx));
116
117
  // TODO(veluca): in theory, this could be done with 8 TableLookupBytes, but
118
  // it's probably slower.
119
29.9M
  auto a = GatherIndex(DF4(), array, idx);
120
29.9M
  auto b = GatherIndex(DF4(), array + 1, idx);
121
122
29.9M
  return Mul(a, FastPowf(DF4(), Div(b, a), frac));
123
29.9M
}
Unexecuted instantiation: jxl::N_AVX3::InterpolateVec(hwy::N_AVX3::Vec128<float, 4ul>, float const*)
Unexecuted instantiation: jxl::N_AVX3_ZEN4::InterpolateVec(hwy::N_AVX3_ZEN4::Vec128<float, 4ul>, float const*)
Unexecuted instantiation: jxl::N_AVX3_SPR::InterpolateVec(hwy::N_AVX3_SPR::Vec128<float, 4ul>, float const*)
Unexecuted instantiation: jxl::N_SSE2::InterpolateVec(hwy::N_SSE2::Vec128<float, 4ul>, float const*)
124
125
// Computes quant weights for a COLS*ROWS-sized transform, using num_bands
126
// eccentricity bands and num_ebands eccentricity bands. If print_mode is 1,
127
// prints the resulting matrix; if print_mode is 2, prints the matrix in a
128
// format suitable for a 3d plot with gnuplot.
129
Status GetQuantWeights(
130
    size_t ROWS, size_t COLS,
131
    const DctQuantWeightParams::DistanceBandsArray& distance_bands,
132
82.7k
    size_t num_bands, float* out) {
133
330k
  for (size_t c = 0; c < 3; c++) {
134
248k
    float bands[DctQuantWeightParams::kMaxDistanceBands] = {
135
248k
        distance_bands[c][0]};
136
248k
    if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
137
1.52M
    for (size_t i = 1; i < num_bands; i++) {
138
1.27M
      bands[i] = bands[i - 1] * Mult(distance_bands[c][i]);
139
1.27M
      if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
140
1.27M
    }
141
248k
    float scale = (num_bands - 1) / (kSqrt2 + 1e-6f);
142
248k
    float rcpcol = scale / (COLS - 1);
143
248k
    float rcprow = scale / (ROWS - 1);
144
248k
    JXL_ENSURE(COLS >= Lanes(DF4()));
145
248k
    HWY_ALIGN float l0123[4] = {0, 1, 2, 3};
146
3.54M
    for (uint32_t y = 0; y < ROWS; y++) {
147
3.29M
      float dy = y * rcprow;
148
3.29M
      float dy2 = dy * dy;
149
33.2M
      for (uint32_t x = 0; x < COLS; x += Lanes(DF4())) {
150
29.9M
        auto dx =
151
29.9M
            Mul(Add(Set(DF4(), x), Load(DF4(), l0123)), Set(DF4(), rcpcol));
152
29.9M
        auto scaled_distance = Sqrt(MulAdd(dx, dx, Set(DF4(), dy2)));
153
29.9M
        auto weight = num_bands == 1 ? Set(DF4(), bands[0])
154
29.9M
                                     : InterpolateVec(scaled_distance, bands);
155
29.9M
        StoreU(weight, DF4(), out + c * COLS * ROWS + y * COLS + x);
156
29.9M
      }
157
3.29M
    }
158
248k
  }
159
82.7k
  return true;
160
82.7k
}
Unexecuted instantiation: jxl::N_SSE4::GetQuantWeights(unsigned long, unsigned long, std::__1::array<std::__1::array<float, 17ul>, 3ul> const&, unsigned long, float*)
jxl::N_AVX2::GetQuantWeights(unsigned long, unsigned long, std::__1::array<std::__1::array<float, 17ul>, 3ul> const&, unsigned long, float*)
Line
Count
Source
132
82.7k
    size_t num_bands, float* out) {
133
330k
  for (size_t c = 0; c < 3; c++) {
134
248k
    float bands[DctQuantWeightParams::kMaxDistanceBands] = {
135
248k
        distance_bands[c][0]};
136
248k
    if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
137
1.52M
    for (size_t i = 1; i < num_bands; i++) {
138
1.27M
      bands[i] = bands[i - 1] * Mult(distance_bands[c][i]);
139
1.27M
      if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
140
1.27M
    }
141
248k
    float scale = (num_bands - 1) / (kSqrt2 + 1e-6f);
142
248k
    float rcpcol = scale / (COLS - 1);
143
248k
    float rcprow = scale / (ROWS - 1);
144
248k
    JXL_ENSURE(COLS >= Lanes(DF4()));
145
248k
    HWY_ALIGN float l0123[4] = {0, 1, 2, 3};
146
3.54M
    for (uint32_t y = 0; y < ROWS; y++) {
147
3.29M
      float dy = y * rcprow;
148
3.29M
      float dy2 = dy * dy;
149
33.2M
      for (uint32_t x = 0; x < COLS; x += Lanes(DF4())) {
150
29.9M
        auto dx =
151
29.9M
            Mul(Add(Set(DF4(), x), Load(DF4(), l0123)), Set(DF4(), rcpcol));
152
29.9M
        auto scaled_distance = Sqrt(MulAdd(dx, dx, Set(DF4(), dy2)));
153
29.9M
        auto weight = num_bands == 1 ? Set(DF4(), bands[0])
154
29.9M
                                     : InterpolateVec(scaled_distance, bands);
155
29.9M
        StoreU(weight, DF4(), out + c * COLS * ROWS + y * COLS + x);
156
29.9M
      }
157
3.29M
    }
158
248k
  }
159
82.7k
  return true;
160
82.7k
}
Unexecuted instantiation: jxl::N_AVX3::GetQuantWeights(unsigned long, unsigned long, std::__1::array<std::__1::array<float, 17ul>, 3ul> const&, unsigned long, float*)
Unexecuted instantiation: jxl::N_AVX3_ZEN4::GetQuantWeights(unsigned long, unsigned long, std::__1::array<std::__1::array<float, 17ul>, 3ul> const&, unsigned long, float*)
Unexecuted instantiation: jxl::N_AVX3_SPR::GetQuantWeights(unsigned long, unsigned long, std::__1::array<std::__1::array<float, 17ul>, 3ul> const&, unsigned long, float*)
Unexecuted instantiation: jxl::N_SSE2::GetQuantWeights(unsigned long, unsigned long, std::__1::array<std::__1::array<float, 17ul>, 3ul> const&, unsigned long, float*)
161
162
// TODO(veluca): SIMD-fy. With 256x256, this is actually slow.
163
Status ComputeQuantTable(const QuantEncoding& encoding,
164
                         float* JXL_RESTRICT table,
165
                         float* JXL_RESTRICT inv_table, size_t table_num,
166
87.7k
                         QuantTable kind, size_t* pos) {
167
87.7k
  constexpr size_t N = kBlockDim;
168
87.7k
  size_t quant_table_idx = static_cast<size_t>(kind);
169
87.7k
  size_t wrows = 8 * DequantMatrices::required_size_x[quant_table_idx];
170
87.7k
  size_t wcols = 8 * DequantMatrices::required_size_y[quant_table_idx];
171
87.7k
  size_t num = wrows * wcols;
172
173
87.7k
  std::vector<float> weights(3 * num);
174
175
87.7k
  switch (encoding.mode) {
176
0
    case QuantEncoding::kQuantModeLibrary: {
177
      // Library and copy quant encoding should get replaced by the actual
178
      // parameters by the caller.
179
0
      JXL_ENSURE(false);
180
0
      break;
181
0
    }
182
6.82k
    case QuantEncoding::kQuantModeID: {
183
6.82k
      JXL_ENSURE(num == kDCTBlockSize);
184
6.82k
      GetQuantWeightsIdentity(encoding.idweights, weights.data());
185
6.82k
      break;
186
6.82k
    }
187
5.52k
    case QuantEncoding::kQuantModeDCT2: {
188
5.52k
      JXL_ENSURE(num == kDCTBlockSize);
189
5.52k
      GetQuantWeightsDCT2(encoding.dct2weights, weights.data());
190
5.52k
      break;
191
5.52k
    }
192
4.10k
    case QuantEncoding::kQuantModeDCT4: {
193
4.10k
      JXL_ENSURE(num == kDCTBlockSize);
194
4.10k
      float weights4x4[3 * 4 * 4];
195
      // Always use 4x4 GetQuantWeights for DCT4 quantization tables.
196
4.10k
      JXL_RETURN_IF_ERROR(
197
4.10k
          GetQuantWeights(4, 4, encoding.dct_params.distance_bands,
198
4.10k
                          encoding.dct_params.num_distance_bands, weights4x4));
199
16.4k
      for (size_t c = 0; c < 3; c++) {
200
110k
        for (size_t y = 0; y < kBlockDim; y++) {
201
886k
          for (size_t x = 0; x < kBlockDim; x++) {
202
787k
            weights[c * num + y * kBlockDim + x] =
203
787k
                weights4x4[c * 16 + (y / 2) * 4 + (x / 2)];
204
787k
          }
205
98.4k
        }
206
12.3k
        weights[c * num + 1] /= encoding.dct4multipliers[c][0];
207
12.3k
        weights[c * num + N] /= encoding.dct4multipliers[c][0];
208
12.3k
        weights[c * num + N + 1] /= encoding.dct4multipliers[c][1];
209
12.3k
      }
210
4.10k
      break;
211
4.10k
    }
212
5.02k
    case QuantEncoding::kQuantModeDCT4X8: {
213
5.02k
      JXL_ENSURE(num == kDCTBlockSize);
214
5.02k
      float weights4x8[3 * 4 * 8];
215
      // Always use 4x8 GetQuantWeights for DCT4X8 quantization tables.
216
5.02k
      JXL_RETURN_IF_ERROR(
217
5.02k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
218
5.02k
                          encoding.dct_params.num_distance_bands, weights4x8));
219
20.0k
      for (size_t c = 0; c < 3; c++) {
220
135k
        for (size_t y = 0; y < kBlockDim; y++) {
221
1.08M
          for (size_t x = 0; x < kBlockDim; x++) {
222
964k
            weights[c * num + y * kBlockDim + x] =
223
964k
                weights4x8[c * 32 + (y / 2) * 8 + x];
224
964k
          }
225
120k
        }
226
15.0k
        weights[c * num + N] /= encoding.dct4x8multipliers[c];
227
15.0k
      }
228
5.02k
      break;
229
5.02k
    }
230
58.9k
    case QuantEncoding::kQuantModeDCT: {
231
58.9k
      JXL_RETURN_IF_ERROR(GetQuantWeights(
232
58.9k
          wrows, wcols, encoding.dct_params.distance_bands,
233
58.9k
          encoding.dct_params.num_distance_bands, weights.data()));
234
58.9k
      break;
235
58.9k
    }
236
58.9k
    case QuantEncoding::kQuantModeRAW: {
237
3
      if (!encoding.qraw.qtable || encoding.qraw.qtable->size() != 3 * num) {
238
0
        return JXL_FAILURE("Invalid table encoding");
239
0
      }
240
3
      int* qtable = encoding.qraw.qtable->data();
241
579
      for (size_t i = 0; i < 3 * num; i++) {
242
576
        weights[i] = 1.f / (encoding.qraw.qtable_den * qtable[i]);
243
576
      }
244
3
      break;
245
3
    }
246
7.32k
    case QuantEncoding::kQuantModeAFV: {
247
7.32k
      constexpr float kFreqs[] = {
248
7.32k
          0xBAD,
249
7.32k
          0xBAD,
250
7.32k
          0.8517778890324296,
251
7.32k
          5.37778436506804,
252
7.32k
          0xBAD,
253
7.32k
          0xBAD,
254
7.32k
          4.734747904497923,
255
7.32k
          5.449245381693219,
256
7.32k
          1.6598270267479331,
257
7.32k
          4,
258
7.32k
          7.275749096817861,
259
7.32k
          10.423227632456525,
260
7.32k
          2.662932286148962,
261
7.32k
          7.630657783650829,
262
7.32k
          8.962388608184032,
263
7.32k
          12.97166202570235,
264
7.32k
      };
265
266
7.32k
      float weights4x8[3 * 4 * 8];
267
7.32k
      JXL_RETURN_IF_ERROR((
268
7.32k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
269
7.32k
                          encoding.dct_params.num_distance_bands, weights4x8)));
270
7.32k
      float weights4x4[3 * 4 * 4];
271
7.32k
      JXL_RETURN_IF_ERROR((GetQuantWeights(
272
7.32k
          4, 4, encoding.dct_params_afv_4x4.distance_bands,
273
7.32k
          encoding.dct_params_afv_4x4.num_distance_bands, weights4x4)));
274
275
7.32k
      constexpr float lo = 0.8517778890324296;
276
7.32k
      constexpr float hi = 12.97166202570235f - lo + 1e-6f;
277
29.2k
      for (size_t c = 0; c < 3; c++) {
278
21.9k
        float bands[4];
279
21.9k
        bands[0] = encoding.afv_weights[c][5];
280
21.9k
        if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
281
87.7k
        for (size_t i = 1; i < 4; i++) {
282
65.8k
          bands[i] = bands[i - 1] * Mult(encoding.afv_weights[c][i + 5]);
283
65.8k
          if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
284
65.8k
        }
285
21.9k
        size_t start = c * 64;
286
373k
        auto set_weight = [&start, &weights](size_t x, size_t y, float val) {
287
373k
          weights[start + y * 8 + x] = val;
288
373k
        };
Unexecuted instantiation: quant_weights.cc:jxl::N_SSE4::ComputeQuantTable(jxl::QuantEncoding const&, float*, float*, unsigned long, jxl::QuantTable, unsigned long*)::$_0::operator()(unsigned long, unsigned long, float) const
quant_weights.cc:jxl::N_AVX2::ComputeQuantTable(jxl::QuantEncoding const&, float*, float*, unsigned long, jxl::QuantTable, unsigned long*)::$_0::operator()(unsigned long, unsigned long, float) const
Line
Count
Source
286
373k
        auto set_weight = [&start, &weights](size_t x, size_t y, float val) {
287
373k
          weights[start + y * 8 + x] = val;
288
373k
        };
Unexecuted instantiation: quant_weights.cc:jxl::N_AVX3::ComputeQuantTable(jxl::QuantEncoding const&, float*, float*, unsigned long, jxl::QuantTable, unsigned long*)::$_0::operator()(unsigned long, unsigned long, float) const
Unexecuted instantiation: quant_weights.cc:jxl::N_AVX3_ZEN4::ComputeQuantTable(jxl::QuantEncoding const&, float*, float*, unsigned long, jxl::QuantTable, unsigned long*)::$_0::operator()(unsigned long, unsigned long, float) const
Unexecuted instantiation: quant_weights.cc:jxl::N_AVX3_SPR::ComputeQuantTable(jxl::QuantEncoding const&, float*, float*, unsigned long, jxl::QuantTable, unsigned long*)::$_0::operator()(unsigned long, unsigned long, float) const
Unexecuted instantiation: quant_weights.cc:jxl::N_SSE2::ComputeQuantTable(jxl::QuantEncoding const&, float*, float*, unsigned long, jxl::QuantTable, unsigned long*)::$_0::operator()(unsigned long, unsigned long, float) const
289
21.9k
        weights[start] = 1;  // Not used, but causes MSAN error otherwise.
290
        // Weights for (0, 1) and (1, 0).
291
21.9k
        set_weight(0, 1, encoding.afv_weights[c][0]);
292
21.9k
        set_weight(1, 0, encoding.afv_weights[c][1]);
293
        // AFV special weights for 3-pixel corner.
294
21.9k
        set_weight(0, 2, encoding.afv_weights[c][2]);
295
21.9k
        set_weight(2, 0, encoding.afv_weights[c][3]);
296
21.9k
        set_weight(2, 2, encoding.afv_weights[c][4]);
297
298
        // All other AFV weights.
299
109k
        for (size_t y = 0; y < 4; y++) {
300
438k
          for (size_t x = 0; x < 4; x++) {
301
351k
            if (x < 2 && y < 2) continue;
302
526k
            JXL_ASSIGN_OR_RETURN(
303
526k
                float val, Interpolate(kFreqs[y * 4 + x] - lo, hi, bands, 4));
304
526k
            set_weight(2 * x, 2 * y, val);
305
526k
          }
306
87.7k
        }
307
308
        // Put 4x8 weights in odd rows, except (1, 0).
309
109k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
310
789k
          for (size_t x = 0; x < kBlockDim; x++) {
311
702k
            if (x == 0 && y == 0) continue;
312
680k
            weights[c * num + (2 * y + 1) * kBlockDim + x] =
313
680k
                weights4x8[c * 32 + y * 8 + x];
314
680k
          }
315
87.7k
        }
316
        // Put 4x4 weights in even rows / odd columns, except (0, 1).
317
109k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
318
438k
          for (size_t x = 0; x < kBlockDim / 2; x++) {
319
351k
            if (x == 0 && y == 0) continue;
320
329k
            weights[c * num + (2 * y) * kBlockDim + 2 * x + 1] =
321
329k
                weights4x4[c * 16 + y * 4 + x];
322
329k
          }
323
87.7k
        }
324
21.9k
      }
325
7.31k
      break;
326
7.32k
    }
327
87.7k
  }
328
87.7k
  size_t prev_pos = *pos;
329
87.7k
  HWY_CAPPED(float, 64) d;
330
15.5M
  for (size_t i = 0; i < num * 3; i += Lanes(d)) {
331
15.4M
    auto inv_val = LoadU(d, weights.data() + i);
332
15.4M
    if (JXL_UNLIKELY(!AllFalse(d, Ge(inv_val, Set(d, 1.0f / kAlmostZero))) ||
333
15.4M
                     !AllFalse(d, Lt(inv_val, Set(d, kAlmostZero))))) {
334
57
      return JXL_FAILURE("Invalid quantization table");
335
57
    }
336
15.4M
    auto val = Div(Set(d, 1.0f), inv_val);
337
15.4M
    StoreU(val, d, table + *pos + i);
338
15.4M
    StoreU(inv_val, d, inv_table + *pos + i);
339
15.4M
  }
340
87.6k
  (*pos) += 3 * num;
341
342
  // Ensure that the lowest frequencies have a 0 inverse table.
343
  // This does not affect en/decoding, but allows AC strategy selection to be
344
  // slightly simpler.
345
87.6k
  size_t xs = DequantMatrices::required_size_x[quant_table_idx];
346
87.6k
  size_t ys = DequantMatrices::required_size_y[quant_table_idx];
347
87.6k
  CoefficientLayout(&ys, &xs);
348
350k
  for (size_t c = 0; c < 3; c++) {
349
725k
    for (size_t y = 0; y < ys; y++) {
350
2.39M
      for (size_t x = 0; x < xs; x++) {
351
1.93M
        inv_table[prev_pos + c * ys * xs * kDCTBlockSize + y * kBlockDim * xs +
352
1.93M
                  x] = 0;
353
1.93M
      }
354
462k
    }
355
263k
  }
356
87.6k
  return true;
357
87.7k
}
Unexecuted instantiation: jxl::N_SSE4::ComputeQuantTable(jxl::QuantEncoding const&, float*, float*, unsigned long, jxl::QuantTable, unsigned long*)
jxl::N_AVX2::ComputeQuantTable(jxl::QuantEncoding const&, float*, float*, unsigned long, jxl::QuantTable, unsigned long*)
Line
Count
Source
166
87.7k
                         QuantTable kind, size_t* pos) {
167
87.7k
  constexpr size_t N = kBlockDim;
168
87.7k
  size_t quant_table_idx = static_cast<size_t>(kind);
169
87.7k
  size_t wrows = 8 * DequantMatrices::required_size_x[quant_table_idx];
170
87.7k
  size_t wcols = 8 * DequantMatrices::required_size_y[quant_table_idx];
171
87.7k
  size_t num = wrows * wcols;
172
173
87.7k
  std::vector<float> weights(3 * num);
174
175
87.7k
  switch (encoding.mode) {
176
0
    case QuantEncoding::kQuantModeLibrary: {
177
      // Library and copy quant encoding should get replaced by the actual
178
      // parameters by the caller.
179
0
      JXL_ENSURE(false);
180
0
      break;
181
0
    }
182
6.82k
    case QuantEncoding::kQuantModeID: {
183
6.82k
      JXL_ENSURE(num == kDCTBlockSize);
184
6.82k
      GetQuantWeightsIdentity(encoding.idweights, weights.data());
185
6.82k
      break;
186
6.82k
    }
187
5.52k
    case QuantEncoding::kQuantModeDCT2: {
188
5.52k
      JXL_ENSURE(num == kDCTBlockSize);
189
5.52k
      GetQuantWeightsDCT2(encoding.dct2weights, weights.data());
190
5.52k
      break;
191
5.52k
    }
192
4.10k
    case QuantEncoding::kQuantModeDCT4: {
193
4.10k
      JXL_ENSURE(num == kDCTBlockSize);
194
4.10k
      float weights4x4[3 * 4 * 4];
195
      // Always use 4x4 GetQuantWeights for DCT4 quantization tables.
196
4.10k
      JXL_RETURN_IF_ERROR(
197
4.10k
          GetQuantWeights(4, 4, encoding.dct_params.distance_bands,
198
4.10k
                          encoding.dct_params.num_distance_bands, weights4x4));
199
16.4k
      for (size_t c = 0; c < 3; c++) {
200
110k
        for (size_t y = 0; y < kBlockDim; y++) {
201
886k
          for (size_t x = 0; x < kBlockDim; x++) {
202
787k
            weights[c * num + y * kBlockDim + x] =
203
787k
                weights4x4[c * 16 + (y / 2) * 4 + (x / 2)];
204
787k
          }
205
98.4k
        }
206
12.3k
        weights[c * num + 1] /= encoding.dct4multipliers[c][0];
207
12.3k
        weights[c * num + N] /= encoding.dct4multipliers[c][0];
208
12.3k
        weights[c * num + N + 1] /= encoding.dct4multipliers[c][1];
209
12.3k
      }
210
4.10k
      break;
211
4.10k
    }
212
5.02k
    case QuantEncoding::kQuantModeDCT4X8: {
213
5.02k
      JXL_ENSURE(num == kDCTBlockSize);
214
5.02k
      float weights4x8[3 * 4 * 8];
215
      // Always use 4x8 GetQuantWeights for DCT4X8 quantization tables.
216
5.02k
      JXL_RETURN_IF_ERROR(
217
5.02k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
218
5.02k
                          encoding.dct_params.num_distance_bands, weights4x8));
219
20.0k
      for (size_t c = 0; c < 3; c++) {
220
135k
        for (size_t y = 0; y < kBlockDim; y++) {
221
1.08M
          for (size_t x = 0; x < kBlockDim; x++) {
222
964k
            weights[c * num + y * kBlockDim + x] =
223
964k
                weights4x8[c * 32 + (y / 2) * 8 + x];
224
964k
          }
225
120k
        }
226
15.0k
        weights[c * num + N] /= encoding.dct4x8multipliers[c];
227
15.0k
      }
228
5.02k
      break;
229
5.02k
    }
230
58.9k
    case QuantEncoding::kQuantModeDCT: {
231
58.9k
      JXL_RETURN_IF_ERROR(GetQuantWeights(
232
58.9k
          wrows, wcols, encoding.dct_params.distance_bands,
233
58.9k
          encoding.dct_params.num_distance_bands, weights.data()));
234
58.9k
      break;
235
58.9k
    }
236
58.9k
    case QuantEncoding::kQuantModeRAW: {
237
3
      if (!encoding.qraw.qtable || encoding.qraw.qtable->size() != 3 * num) {
238
0
        return JXL_FAILURE("Invalid table encoding");
239
0
      }
240
3
      int* qtable = encoding.qraw.qtable->data();
241
579
      for (size_t i = 0; i < 3 * num; i++) {
242
576
        weights[i] = 1.f / (encoding.qraw.qtable_den * qtable[i]);
243
576
      }
244
3
      break;
245
3
    }
246
7.32k
    case QuantEncoding::kQuantModeAFV: {
247
7.32k
      constexpr float kFreqs[] = {
248
7.32k
          0xBAD,
249
7.32k
          0xBAD,
250
7.32k
          0.8517778890324296,
251
7.32k
          5.37778436506804,
252
7.32k
          0xBAD,
253
7.32k
          0xBAD,
254
7.32k
          4.734747904497923,
255
7.32k
          5.449245381693219,
256
7.32k
          1.6598270267479331,
257
7.32k
          4,
258
7.32k
          7.275749096817861,
259
7.32k
          10.423227632456525,
260
7.32k
          2.662932286148962,
261
7.32k
          7.630657783650829,
262
7.32k
          8.962388608184032,
263
7.32k
          12.97166202570235,
264
7.32k
      };
265
266
7.32k
      float weights4x8[3 * 4 * 8];
267
7.32k
      JXL_RETURN_IF_ERROR((
268
7.32k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
269
7.32k
                          encoding.dct_params.num_distance_bands, weights4x8)));
270
7.32k
      float weights4x4[3 * 4 * 4];
271
7.32k
      JXL_RETURN_IF_ERROR((GetQuantWeights(
272
7.32k
          4, 4, encoding.dct_params_afv_4x4.distance_bands,
273
7.32k
          encoding.dct_params_afv_4x4.num_distance_bands, weights4x4)));
274
275
7.32k
      constexpr float lo = 0.8517778890324296;
276
7.32k
      constexpr float hi = 12.97166202570235f - lo + 1e-6f;
277
29.2k
      for (size_t c = 0; c < 3; c++) {
278
21.9k
        float bands[4];
279
21.9k
        bands[0] = encoding.afv_weights[c][5];
280
21.9k
        if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
281
87.7k
        for (size_t i = 1; i < 4; i++) {
282
65.8k
          bands[i] = bands[i - 1] * Mult(encoding.afv_weights[c][i + 5]);
283
65.8k
          if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
284
65.8k
        }
285
21.9k
        size_t start = c * 64;
286
21.9k
        auto set_weight = [&start, &weights](size_t x, size_t y, float val) {
287
21.9k
          weights[start + y * 8 + x] = val;
288
21.9k
        };
289
21.9k
        weights[start] = 1;  // Not used, but causes MSAN error otherwise.
290
        // Weights for (0, 1) and (1, 0).
291
21.9k
        set_weight(0, 1, encoding.afv_weights[c][0]);
292
21.9k
        set_weight(1, 0, encoding.afv_weights[c][1]);
293
        // AFV special weights for 3-pixel corner.
294
21.9k
        set_weight(0, 2, encoding.afv_weights[c][2]);
295
21.9k
        set_weight(2, 0, encoding.afv_weights[c][3]);
296
21.9k
        set_weight(2, 2, encoding.afv_weights[c][4]);
297
298
        // All other AFV weights.
299
109k
        for (size_t y = 0; y < 4; y++) {
300
438k
          for (size_t x = 0; x < 4; x++) {
301
351k
            if (x < 2 && y < 2) continue;
302
526k
            JXL_ASSIGN_OR_RETURN(
303
526k
                float val, Interpolate(kFreqs[y * 4 + x] - lo, hi, bands, 4));
304
526k
            set_weight(2 * x, 2 * y, val);
305
526k
          }
306
87.7k
        }
307
308
        // Put 4x8 weights in odd rows, except (1, 0).
309
109k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
310
789k
          for (size_t x = 0; x < kBlockDim; x++) {
311
702k
            if (x == 0 && y == 0) continue;
312
680k
            weights[c * num + (2 * y + 1) * kBlockDim + x] =
313
680k
                weights4x8[c * 32 + y * 8 + x];
314
680k
          }
315
87.7k
        }
316
        // Put 4x4 weights in even rows / odd columns, except (0, 1).
317
109k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
318
438k
          for (size_t x = 0; x < kBlockDim / 2; x++) {
319
351k
            if (x == 0 && y == 0) continue;
320
329k
            weights[c * num + (2 * y) * kBlockDim + 2 * x + 1] =
321
329k
                weights4x4[c * 16 + y * 4 + x];
322
329k
          }
323
87.7k
        }
324
21.9k
      }
325
7.31k
      break;
326
7.32k
    }
327
87.7k
  }
328
87.7k
  size_t prev_pos = *pos;
329
87.7k
  HWY_CAPPED(float, 64) d;
330
15.5M
  for (size_t i = 0; i < num * 3; i += Lanes(d)) {
331
15.4M
    auto inv_val = LoadU(d, weights.data() + i);
332
15.4M
    if (JXL_UNLIKELY(!AllFalse(d, Ge(inv_val, Set(d, 1.0f / kAlmostZero))) ||
333
15.4M
                     !AllFalse(d, Lt(inv_val, Set(d, kAlmostZero))))) {
334
57
      return JXL_FAILURE("Invalid quantization table");
335
57
    }
336
15.4M
    auto val = Div(Set(d, 1.0f), inv_val);
337
15.4M
    StoreU(val, d, table + *pos + i);
338
15.4M
    StoreU(inv_val, d, inv_table + *pos + i);
339
15.4M
  }
340
87.6k
  (*pos) += 3 * num;
341
342
  // Ensure that the lowest frequencies have a 0 inverse table.
343
  // This does not affect en/decoding, but allows AC strategy selection to be
344
  // slightly simpler.
345
87.6k
  size_t xs = DequantMatrices::required_size_x[quant_table_idx];
346
87.6k
  size_t ys = DequantMatrices::required_size_y[quant_table_idx];
347
87.6k
  CoefficientLayout(&ys, &xs);
348
350k
  for (size_t c = 0; c < 3; c++) {
349
725k
    for (size_t y = 0; y < ys; y++) {
350
2.39M
      for (size_t x = 0; x < xs; x++) {
351
1.93M
        inv_table[prev_pos + c * ys * xs * kDCTBlockSize + y * kBlockDim * xs +
352
1.93M
                  x] = 0;
353
1.93M
      }
354
462k
    }
355
263k
  }
356
87.6k
  return true;
357
87.7k
}
Unexecuted instantiation: jxl::N_AVX3::ComputeQuantTable(jxl::QuantEncoding const&, float*, float*, unsigned long, jxl::QuantTable, unsigned long*)
Unexecuted instantiation: jxl::N_AVX3_ZEN4::ComputeQuantTable(jxl::QuantEncoding const&, float*, float*, unsigned long, jxl::QuantTable, unsigned long*)
Unexecuted instantiation: jxl::N_AVX3_SPR::ComputeQuantTable(jxl::QuantEncoding const&, float*, float*, unsigned long, jxl::QuantTable, unsigned long*)
Unexecuted instantiation: jxl::N_SSE2::ComputeQuantTable(jxl::QuantEncoding const&, float*, float*, unsigned long, jxl::QuantTable, unsigned long*)
358
359
// NOLINTNEXTLINE(google-readability-namespace-comments)
360
}  // namespace HWY_NAMESPACE
361
}  // namespace jxl
362
HWY_AFTER_NAMESPACE();
363
364
#if HWY_ONCE
365
366
namespace jxl {
367
namespace {
368
369
HWY_EXPORT(ComputeQuantTable);
370
371
constexpr const float kAlmostZero = 1e-8f;
372
373
476
Status DecodeDctParams(BitReader* br, DctQuantWeightParams* params) {
374
476
  params->num_distance_bands =
375
476
      br->ReadFixedBits<DctQuantWeightParams::kLog2MaxDistanceBands>() + 1;
376
1.44k
  for (size_t c = 0; c < 3; c++) {
377
4.65k
    for (size_t i = 0; i < params->num_distance_bands; i++) {
378
3.53k
      JXL_RETURN_IF_ERROR(F16Coder::Read(br, &params->distance_bands[c][i]));
379
3.53k
    }
380
1.12k
    if (params->distance_bands[c][0] < kAlmostZero) {
381
156
      return JXL_FAILURE("Distance band seed is too small");
382
156
    }
383
972
    params->distance_bands[c][0] *= 64.0f;
384
972
  }
385
294
  return true;
386
476
}
387
388
Status Decode(JxlMemoryManager* memory_manager, BitReader* br,
389
              QuantEncoding* encoding, size_t required_size_x,
390
              size_t required_size_y, size_t idx,
391
81.0k
              ModularFrameDecoder* modular_frame_decoder) {
392
81.0k
  size_t required_size = required_size_x * required_size_y;
393
81.0k
  required_size_x *= kBlockDim;
394
81.0k
  required_size_y *= kBlockDim;
395
81.0k
  int mode = br->ReadFixedBits<kLog2NumQuantModes>();
396
81.0k
  switch (mode) {
397
65.4k
    case QuantEncoding::kQuantModeLibrary: {
398
65.4k
      encoding->predefined = br->ReadFixedBits<kCeilLog2NumPredefinedTables>();
399
65.4k
      if (encoding->predefined >= kNumPredefinedTables) {
400
0
        return JXL_FAILURE("Invalid predefined table");
401
0
      }
402
65.4k
      break;
403
65.4k
    }
404
65.4k
    case QuantEncoding::kQuantModeID: {
405
255
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
406
399
      for (size_t c = 0; c < 3; c++) {
407
1.07k
        for (size_t i = 0; i < 3; i++) {
408
883
          JXL_RETURN_IF_ERROR(F16Coder::Read(br, &encoding->idweights[c][i]));
409
859
          if (std::abs(encoding->idweights[c][i]) < kAlmostZero) {
410
140
            return JXL_FAILURE("ID Quantizer is too small");
411
140
          }
412
719
          encoding->idweights[c][i] *= 64;
413
719
        }
414
352
      }
415
47
      break;
416
211
    }
417
766
    case QuantEncoding::kQuantModeDCT2: {
418
766
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
419
601
      for (size_t c = 0; c < 3; c++) {
420
2.40k
        for (size_t i = 0; i < 6; i++) {
421
2.22k
          JXL_RETURN_IF_ERROR(F16Coder::Read(br, &encoding->dct2weights[c][i]));
422
2.20k
          if (std::abs(encoding->dct2weights[c][i]) < kAlmostZero) {
423
353
            return JXL_FAILURE("Quantizer is too small");
424
353
          }
425
1.84k
          encoding->dct2weights[c][i] *= 64;
426
1.84k
        }
427
553
      }
428
48
      break;
429
423
    }
430
13.8k
    case QuantEncoding::kQuantModeDCT4X8: {
431
13.8k
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
432
27.7k
      for (size_t c = 0; c < 3; c++) {
433
27.6k
        JXL_RETURN_IF_ERROR(
434
27.6k
            F16Coder::Read(br, &encoding->dct4x8multipliers[c]));
435
27.6k
        if (std::abs(encoding->dct4x8multipliers[c]) < kAlmostZero) {
436
13.6k
          return JXL_FAILURE("DCT4X8 multiplier is too small");
437
13.6k
        }
438
27.6k
      }
439
118
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
440
68
      break;
441
118
    }
442
160
    case QuantEncoding::kQuantModeDCT4: {
443
160
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
444
371
      for (size_t c = 0; c < 3; c++) {
445
824
        for (size_t i = 0; i < 2; i++) {
446
584
          JXL_RETURN_IF_ERROR(
447
584
              F16Coder::Read(br, &encoding->dct4multipliers[c][i]));
448
571
          if (std::abs(encoding->dct4multipliers[c][i]) < kAlmostZero) {
449
57
            return JXL_FAILURE("DCT4 multiplier is too small");
450
57
          }
451
571
        }
452
310
      }
453
61
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
454
46
      break;
455
61
    }
456
104
    case QuantEncoding::kQuantModeAFV: {
457
104
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
458
279
      for (size_t c = 0; c < 3; c++) {
459
1.99k
        for (size_t i = 0; i < 9; i++) {
460
1.80k
          JXL_RETURN_IF_ERROR(F16Coder::Read(br, &encoding->afv_weights[c][i]));
461
1.80k
        }
462
1.28k
        for (size_t i = 0; i < 6; i++) {
463
1.09k
          encoding->afv_weights[c][i] *= 64;
464
1.09k
        }
465
183
      }
466
55
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
467
25
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params_afv_4x4));
468
22
      break;
469
25
    }
470
217
    case QuantEncoding::kQuantModeDCT: {
471
217
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
472
133
      break;
473
217
    }
474
377
    case QuantEncoding::kQuantModeRAW: {
475
      // Set mode early, to avoid mem-leak.
476
377
      encoding->mode = QuantEncoding::kQuantModeRAW;
477
377
      JXL_RETURN_IF_ERROR(ModularFrameDecoder::DecodeQuantTable(
478
377
          memory_manager, required_size_x, required_size_y, br, encoding, idx,
479
377
          modular_frame_decoder));
480
40
      break;
481
377
    }
482
40
    default:
483
0
      return JXL_FAILURE("Invalid quantization table encoding");
484
81.0k
  }
485
65.8k
  encoding->mode = static_cast<QuantEncoding::Mode>(mode);
486
65.8k
  return true;
487
81.0k
}
488
489
}  // namespace
490
491
#if JXL_CXX_LANG < JXL_CXX_17
492
constexpr const std::array<int, 17> DequantMatrices::required_size_x;
493
constexpr const std::array<int, 17> DequantMatrices::required_size_y;
494
constexpr const size_t DequantMatrices::kSumRequiredXy;
495
#endif
496
497
Status DequantMatrices::Decode(JxlMemoryManager* memory_manager, BitReader* br,
498
37.0k
                               ModularFrameDecoder* modular_frame_decoder) {
499
37.0k
  size_t all_default = br->ReadBits(1);
500
37.0k
  size_t num_tables = all_default ? 0 : static_cast<size_t>(kNumQuantTables);
501
37.0k
  encodings_.clear();
502
37.0k
  encodings_.resize(kNumQuantTables, QuantEncoding::Library<0>());
503
102k
  for (size_t i = 0; i < num_tables; i++) {
504
81.0k
    JXL_RETURN_IF_ERROR(jxl::Decode(memory_manager, br, &encodings_[i],
505
81.0k
                                    required_size_x[i % kNumQuantTables],
506
81.0k
                                    required_size_y[i % kNumQuantTables], i,
507
81.0k
                                    modular_frame_decoder));
508
81.0k
  }
509
21.7k
  computed_mask_ = 0;
510
21.7k
  return true;
511
37.0k
}
512
513
169k
Status DequantMatrices::DecodeDC(BitReader* br) {
514
169k
  bool all_default = static_cast<bool>(br->ReadBits(1));
515
169k
  if (!br->AllReadsWithinBounds()) return JXL_FAILURE("EOS during DecodeDC");
516
162k
  if (!all_default) {
517
92.1k
    for (size_t c = 0; c < 3; c++) {
518
70.3k
      JXL_RETURN_IF_ERROR(F16Coder::Read(br, &dc_quant_[c]));
519
69.5k
      dc_quant_[c] *= 1.0f / 128.0f;
520
      // Negative values and nearly zero are invalid values.
521
69.5k
      if (dc_quant_[c] < kAlmostZero) {
522
3.67k
        return JXL_FAILURE("Invalid dc_quant: coefficient is too small.");
523
3.67k
      }
524
65.9k
      inv_dc_quant_[c] = 1.0f / dc_quant_[c];
525
65.9k
    }
526
26.2k
  }
527
158k
  return true;
528
162k
}
529
530
0
constexpr float V(float v) { return static_cast<float>(v); }
531
532
namespace {
533
struct DequantMatricesLibraryDef {
534
  // DCT8
535
6
  static constexpr QuantEncodingInternal DCT() {
536
6
    return QuantEncodingInternal::DCT(DctQuantWeightParams({{{{
537
6
                                                                 V(3150.0),
538
6
                                                                 V(0.0),
539
6
                                                                 V(-0.4),
540
6
                                                                 V(-0.4),
541
6
                                                                 V(-0.4),
542
6
                                                                 V(-2.0),
543
6
                                                             }},
544
6
                                                             {{
545
6
                                                                 V(560.0),
546
6
                                                                 V(0.0),
547
6
                                                                 V(-0.3),
548
6
                                                                 V(-0.3),
549
6
                                                                 V(-0.3),
550
6
                                                                 V(-0.3),
551
6
                                                             }},
552
6
                                                             {{
553
6
                                                                 V(512.0),
554
6
                                                                 V(-2.0),
555
6
                                                                 V(-1.0),
556
6
                                                                 V(0.0),
557
6
                                                                 V(-1.0),
558
6
                                                                 V(-2.0),
559
6
                                                             }}}},
560
6
                                                           6));
561
6
  }
562
563
  // Identity
564
6
  static constexpr QuantEncodingInternal IDENTITY() {
565
6
    return QuantEncodingInternal::Identity({{{{
566
6
                                                 V(280.0),
567
6
                                                 V(3160.0),
568
6
                                                 V(3160.0),
569
6
                                             }},
570
6
                                             {{
571
6
                                                 V(60.0),
572
6
                                                 V(864.0),
573
6
                                                 V(864.0),
574
6
                                             }},
575
6
                                             {{
576
6
                                                 V(18.0),
577
6
                                                 V(200.0),
578
6
                                                 V(200.0),
579
6
                                             }}}});
580
6
  }
581
582
  // DCT2
583
6
  static constexpr QuantEncodingInternal DCT2X2() {
584
6
    return QuantEncodingInternal::DCT2({{{{
585
6
                                             V(3840.0),
586
6
                                             V(2560.0),
587
6
                                             V(1280.0),
588
6
                                             V(640.0),
589
6
                                             V(480.0),
590
6
                                             V(300.0),
591
6
                                         }},
592
6
                                         {{
593
6
                                             V(960.0),
594
6
                                             V(640.0),
595
6
                                             V(320.0),
596
6
                                             V(180.0),
597
6
                                             V(140.0),
598
6
                                             V(120.0),
599
6
                                         }},
600
6
                                         {{
601
6
                                             V(640.0),
602
6
                                             V(320.0),
603
6
                                             V(128.0),
604
6
                                             V(64.0),
605
6
                                             V(32.0),
606
6
                                             V(16.0),
607
6
                                         }}}});
608
6
  }
609
610
  // DCT4 (quant_kind 3)
611
12
  static constexpr QuantEncodingInternal DCT4X4() {
612
12
    return QuantEncodingInternal::DCT4(DctQuantWeightParams({{{{
613
12
                                                                  V(2200.0),
614
12
                                                                  V(0.0),
615
12
                                                                  V(0.0),
616
12
                                                                  V(0.0),
617
12
                                                              }},
618
12
                                                              {{
619
12
                                                                  V(392.0),
620
12
                                                                  V(0.0),
621
12
                                                                  V(0.0),
622
12
                                                                  V(0.0),
623
12
                                                              }},
624
12
                                                              {{
625
12
                                                                  V(112.0),
626
12
                                                                  V(-0.25),
627
12
                                                                  V(-0.25),
628
12
                                                                  V(-0.5),
629
12
                                                              }}}},
630
12
                                                            4),
631
                                       /* kMul */
632
12
                                       {{{{
633
12
                                             V(1.0),
634
12
                                             V(1.0),
635
12
                                         }},
636
12
                                         {{
637
12
                                             V(1.0),
638
12
                                             V(1.0),
639
12
                                         }},
640
12
                                         {{
641
12
                                             V(1.0),
642
12
                                             V(1.0),
643
12
                                         }}}});
644
12
  }
645
646
  // DCT16
647
6
  static constexpr QuantEncodingInternal DCT16X16() {
648
6
    return QuantEncodingInternal::DCT(
649
6
        DctQuantWeightParams({{{{
650
6
                                   V(8996.8725711814115328),
651
6
                                   V(-1.3000777393353804),
652
6
                                   V(-0.49424529824571225),
653
6
                                   V(-0.439093774457103443),
654
6
                                   V(-0.6350101832695744),
655
6
                                   V(-0.90177264050827612),
656
6
                                   V(-1.6162099239887414),
657
6
                               }},
658
6
                               {{
659
6
                                   V(3191.48366296844234752),
660
6
                                   V(-0.67424582104194355),
661
6
                                   V(-0.80745813428471001),
662
6
                                   V(-0.44925837484843441),
663
6
                                   V(-0.35865440981033403),
664
6
                                   V(-0.31322389111877305),
665
6
                                   V(-0.37615025315725483),
666
6
                               }},
667
6
                               {{
668
6
                                   V(1157.50408145487200256),
669
6
                                   V(-2.0531423165804414),
670
6
                                   V(-1.4),
671
6
                                   V(-0.50687130033378396),
672
6
                                   V(-0.42708730624733904),
673
6
                                   V(-1.4856834539296244),
674
6
                                   V(-4.9209142884401604),
675
6
                               }}}},
676
6
                             7));
677
6
  }
678
679
  // DCT32
680
6
  static constexpr QuantEncodingInternal DCT32X32() {
681
6
    return QuantEncodingInternal::DCT(
682
6
        DctQuantWeightParams({{{{
683
6
                                   V(15718.40830982518931456),
684
6
                                   V(-1.025),
685
6
                                   V(-0.98),
686
6
                                   V(-0.9012),
687
6
                                   V(-0.4),
688
6
                                   V(-0.48819395464),
689
6
                                   V(-0.421064),
690
6
                                   V(-0.27),
691
6
                               }},
692
6
                               {{
693
6
                                   V(7305.7636810695983104),
694
6
                                   V(-0.8041958212306401),
695
6
                                   V(-0.7633036457487539),
696
6
                                   V(-0.55660379990111464),
697
6
                                   V(-0.49785304658857626),
698
6
                                   V(-0.43699592683512467),
699
6
                                   V(-0.40180866526242109),
700
6
                                   V(-0.27321683125358037),
701
6
                               }},
702
6
                               {{
703
6
                                   V(3803.53173721215041536),
704
6
                                   V(-3.060733579805728),
705
6
                                   V(-2.0413270132490346),
706
6
                                   V(-2.0235650159727417),
707
6
                                   V(-0.5495389509954993),
708
6
                                   V(-0.4),
709
6
                                   V(-0.4),
710
6
                                   V(-0.3),
711
6
                               }}}},
712
6
                             8));
713
6
  }
714
715
  // DCT16X8
716
6
  static constexpr QuantEncodingInternal DCT8X16() {
717
6
    return QuantEncodingInternal::DCT(
718
6
        DctQuantWeightParams({{{{
719
6
                                   V(7240.7734393502),
720
6
                                   V(-0.7),
721
6
                                   V(-0.7),
722
6
                                   V(-0.2),
723
6
                                   V(-0.2),
724
6
                                   V(-0.2),
725
6
                                   V(-0.5),
726
6
                               }},
727
6
                               {{
728
6
                                   V(1448.15468787004),
729
6
                                   V(-0.5),
730
6
                                   V(-0.5),
731
6
                                   V(-0.5),
732
6
                                   V(-0.2),
733
6
                                   V(-0.2),
734
6
                                   V(-0.2),
735
6
                               }},
736
6
                               {{
737
6
                                   V(506.854140754517),
738
6
                                   V(-1.4),
739
6
                                   V(-0.2),
740
6
                                   V(-0.5),
741
6
                                   V(-0.5),
742
6
                                   V(-1.5),
743
6
                                   V(-3.6),
744
6
                               }}}},
745
6
                             7));
746
6
  }
747
748
  // DCT32X8
749
6
  static constexpr QuantEncodingInternal DCT8X32() {
750
6
    return QuantEncodingInternal::DCT(
751
6
        DctQuantWeightParams({{{{
752
6
                                   V(16283.2494710648897),
753
6
                                   V(-1.7812845336559429),
754
6
                                   V(-1.6309059012653515),
755
6
                                   V(-1.0382179034313539),
756
6
                                   V(-0.85),
757
6
                                   V(-0.7),
758
6
                                   V(-0.9),
759
6
                                   V(-1.2360638576849587),
760
6
                               }},
761
6
                               {{
762
6
                                   V(5089.15750884921511936),
763
6
                                   V(-0.320049391452786891),
764
6
                                   V(-0.35362849922161446),
765
6
                                   V(-0.30340000000000003),
766
6
                                   V(-0.61),
767
6
                                   V(-0.5),
768
6
                                   V(-0.5),
769
6
                                   V(-0.6),
770
6
                               }},
771
6
                               {{
772
6
                                   V(3397.77603275308720128),
773
6
                                   V(-0.321327362693153371),
774
6
                                   V(-0.34507619223117997),
775
6
                                   V(-0.70340000000000003),
776
6
                                   V(-0.9),
777
6
                                   V(-1.0),
778
6
                                   V(-1.0),
779
6
                                   V(-1.1754605576265209),
780
6
                               }}}},
781
6
                             8));
782
6
  }
783
784
  // DCT32X16
785
6
  static constexpr QuantEncodingInternal DCT16X32() {
786
6
    return QuantEncodingInternal::DCT(
787
6
        DctQuantWeightParams({{{{
788
6
                                   V(13844.97076442300573),
789
6
                                   V(-0.97113799999999995),
790
6
                                   V(-0.658),
791
6
                                   V(-0.42026),
792
6
                                   V(-0.22712),
793
6
                                   V(-0.2206),
794
6
                                   V(-0.226),
795
6
                                   V(-0.6),
796
6
                               }},
797
6
                               {{
798
6
                                   V(4798.964084220744293),
799
6
                                   V(-0.61125308982767057),
800
6
                                   V(-0.83770786552491361),
801
6
                                   V(-0.79014862079498627),
802
6
                                   V(-0.2692727459704829),
803
6
                                   V(-0.38272769465388551),
804
6
                                   V(-0.22924222653091453),
805
6
                                   V(-0.20719098826199578),
806
6
                               }},
807
6
                               {{
808
6
                                   V(1807.236946760964614),
809
6
                                   V(-1.2),
810
6
                                   V(-1.2),
811
6
                                   V(-0.7),
812
6
                                   V(-0.7),
813
6
                                   V(-0.7),
814
6
                                   V(-0.4),
815
6
                                   V(-0.5),
816
6
                               }}}},
817
6
                             8));
818
6
  }
819
820
  // DCT4X8 and 8x4
821
12
  static constexpr QuantEncodingInternal DCT4X8() {
822
12
    return QuantEncodingInternal::DCT4X8(
823
12
        DctQuantWeightParams({{
824
12
                                 {{
825
12
                                     V(2198.050556016380522),
826
12
                                     V(-0.96269623020744692),
827
12
                                     V(-0.76194253026666783),
828
12
                                     V(-0.6551140670773547),
829
12
                                 }},
830
12
                                 {{
831
12
                                     V(764.3655248643528689),
832
12
                                     V(-0.92630200888366945),
833
12
                                     V(-0.9675229603596517),
834
12
                                     V(-0.27845290869168118),
835
12
                                 }},
836
12
                                 {{
837
12
                                     V(527.107573587542228),
838
12
                                     V(-1.4594385811273854),
839
12
                                     V(-1.450082094097871593),
840
12
                                     V(-1.5843722511996204),
841
12
                                 }},
842
12
                             }},
843
12
                             4),
844
        /* kMuls */
845
12
        {{
846
12
            V(1.0),
847
12
            V(1.0),
848
12
            V(1.0),
849
12
        }});
850
12
  }
851
  // AFV
852
6
  static QuantEncodingInternal AFV0() {
853
6
    return QuantEncodingInternal::AFV(DCT4X8().dct_params, DCT4X4().dct_params,
854
6
                                      {{{{
855
                                            // 4x4/4x8 DC tendency.
856
6
                                            V(3072.0),
857
6
                                            V(3072.0),
858
                                            // AFV corner.
859
6
                                            V(256.0),
860
6
                                            V(256.0),
861
6
                                            V(256.0),
862
                                            // AFV high freqs.
863
6
                                            V(414.0),
864
6
                                            V(0.0),
865
6
                                            V(0.0),
866
6
                                            V(0.0),
867
6
                                        }},
868
6
                                        {{
869
                                            // 4x4/4x8 DC tendency.
870
6
                                            V(1024.0),
871
6
                                            V(1024.0),
872
                                            // AFV corner.
873
6
                                            V(50),
874
6
                                            V(50),
875
6
                                            V(50),
876
                                            // AFV high freqs.
877
6
                                            V(58.0),
878
6
                                            V(0.0),
879
6
                                            V(0.0),
880
6
                                            V(0.0),
881
6
                                        }},
882
6
                                        {{
883
                                            // 4x4/4x8 DC tendency.
884
6
                                            V(384.0),
885
6
                                            V(384.0),
886
                                            // AFV corner.
887
6
                                            V(12.0),
888
6
                                            V(12.0),
889
6
                                            V(12.0),
890
                                            // AFV high freqs.
891
6
                                            V(22.0),
892
6
                                            V(-0.25),
893
6
                                            V(-0.25),
894
6
                                            V(-0.25),
895
6
                                        }}}});
896
6
  }
897
898
  // DCT64
899
6
  static QuantEncodingInternal DCT64X64() {
900
6
    return QuantEncodingInternal::DCT(
901
6
        DctQuantWeightParams({{{{
902
6
                                   V(0.9 * 26629.073922049845),
903
6
                                   V(-1.025),
904
6
                                   V(-0.78),
905
6
                                   V(-0.65012),
906
6
                                   V(-0.19041574084286472),
907
6
                                   V(-0.20819395464),
908
6
                                   V(-0.421064),
909
6
                                   V(-0.32733845535848671),
910
6
                               }},
911
6
                               {{
912
6
                                   V(0.9 * 9311.3238710010046),
913
6
                                   V(-0.3041958212306401),
914
6
                                   V(-0.3633036457487539),
915
6
                                   V(-0.35660379990111464),
916
6
                                   V(-0.3443074455424403),
917
6
                                   V(-0.33699592683512467),
918
6
                                   V(-0.30180866526242109),
919
6
                                   V(-0.27321683125358037),
920
6
                               }},
921
6
                               {{
922
6
                                   V(0.9 * 4992.2486445538634),
923
6
                                   V(-1.2),
924
6
                                   V(-1.2),
925
6
                                   V(-0.8),
926
6
                                   V(-0.7),
927
6
                                   V(-0.7),
928
6
                                   V(-0.4),
929
6
                                   V(-0.5),
930
6
                               }}}},
931
6
                             8));
932
6
  }
933
934
  // DCT64X32
935
6
  static QuantEncodingInternal DCT32X64() {
936
6
    return QuantEncodingInternal::DCT(
937
6
        DctQuantWeightParams({{{{
938
6
                                   V(0.65 * 23629.073922049845),
939
6
                                   V(-1.025),
940
6
                                   V(-0.78),
941
6
                                   V(-0.65012),
942
6
                                   V(-0.19041574084286472),
943
6
                                   V(-0.20819395464),
944
6
                                   V(-0.421064),
945
6
                                   V(-0.32733845535848671),
946
6
                               }},
947
6
                               {{
948
6
                                   V(0.65 * 8611.3238710010046),
949
6
                                   V(-0.3041958212306401),
950
6
                                   V(-0.3633036457487539),
951
6
                                   V(-0.35660379990111464),
952
6
                                   V(-0.3443074455424403),
953
6
                                   V(-0.33699592683512467),
954
6
                                   V(-0.30180866526242109),
955
6
                                   V(-0.27321683125358037),
956
6
                               }},
957
6
                               {{
958
6
                                   V(0.65 * 4492.2486445538634),
959
6
                                   V(-1.2),
960
6
                                   V(-1.2),
961
6
                                   V(-0.8),
962
6
                                   V(-0.7),
963
6
                                   V(-0.7),
964
6
                                   V(-0.4),
965
6
                                   V(-0.5),
966
6
                               }}}},
967
6
                             8));
968
6
  }
969
  // DCT128X128
970
6
  static QuantEncodingInternal DCT128X128() {
971
6
    return QuantEncodingInternal::DCT(
972
6
        DctQuantWeightParams({{{{
973
6
                                   V(1.8 * 26629.073922049845),
974
6
                                   V(-1.025),
975
6
                                   V(-0.78),
976
6
                                   V(-0.65012),
977
6
                                   V(-0.19041574084286472),
978
6
                                   V(-0.20819395464),
979
6
                                   V(-0.421064),
980
6
                                   V(-0.32733845535848671),
981
6
                               }},
982
6
                               {{
983
6
                                   V(1.8 * 9311.3238710010046),
984
6
                                   V(-0.3041958212306401),
985
6
                                   V(-0.3633036457487539),
986
6
                                   V(-0.35660379990111464),
987
6
                                   V(-0.3443074455424403),
988
6
                                   V(-0.33699592683512467),
989
6
                                   V(-0.30180866526242109),
990
6
                                   V(-0.27321683125358037),
991
6
                               }},
992
6
                               {{
993
6
                                   V(1.8 * 4992.2486445538634),
994
6
                                   V(-1.2),
995
6
                                   V(-1.2),
996
6
                                   V(-0.8),
997
6
                                   V(-0.7),
998
6
                                   V(-0.7),
999
6
                                   V(-0.4),
1000
6
                                   V(-0.5),
1001
6
                               }}}},
1002
6
                             8));
1003
6
  }
1004
1005
  // DCT128X64
1006
6
  static QuantEncodingInternal DCT64X128() {
1007
6
    return QuantEncodingInternal::DCT(
1008
6
        DctQuantWeightParams({{{{
1009
6
                                   V(1.3 * 23629.073922049845),
1010
6
                                   V(-1.025),
1011
6
                                   V(-0.78),
1012
6
                                   V(-0.65012),
1013
6
                                   V(-0.19041574084286472),
1014
6
                                   V(-0.20819395464),
1015
6
                                   V(-0.421064),
1016
6
                                   V(-0.32733845535848671),
1017
6
                               }},
1018
6
                               {{
1019
6
                                   V(1.3 * 8611.3238710010046),
1020
6
                                   V(-0.3041958212306401),
1021
6
                                   V(-0.3633036457487539),
1022
6
                                   V(-0.35660379990111464),
1023
6
                                   V(-0.3443074455424403),
1024
6
                                   V(-0.33699592683512467),
1025
6
                                   V(-0.30180866526242109),
1026
6
                                   V(-0.27321683125358037),
1027
6
                               }},
1028
6
                               {{
1029
6
                                   V(1.3 * 4492.2486445538634),
1030
6
                                   V(-1.2),
1031
6
                                   V(-1.2),
1032
6
                                   V(-0.8),
1033
6
                                   V(-0.7),
1034
6
                                   V(-0.7),
1035
6
                                   V(-0.4),
1036
6
                                   V(-0.5),
1037
6
                               }}}},
1038
6
                             8));
1039
6
  }
1040
  // DCT256X256
1041
6
  static QuantEncodingInternal DCT256X256() {
1042
6
    return QuantEncodingInternal::DCT(
1043
6
        DctQuantWeightParams({{{{
1044
6
                                   V(3.6 * 26629.073922049845),
1045
6
                                   V(-1.025),
1046
6
                                   V(-0.78),
1047
6
                                   V(-0.65012),
1048
6
                                   V(-0.19041574084286472),
1049
6
                                   V(-0.20819395464),
1050
6
                                   V(-0.421064),
1051
6
                                   V(-0.32733845535848671),
1052
6
                               }},
1053
6
                               {{
1054
6
                                   V(3.6 * 9311.3238710010046),
1055
6
                                   V(-0.3041958212306401),
1056
6
                                   V(-0.3633036457487539),
1057
6
                                   V(-0.35660379990111464),
1058
6
                                   V(-0.3443074455424403),
1059
6
                                   V(-0.33699592683512467),
1060
6
                                   V(-0.30180866526242109),
1061
6
                                   V(-0.27321683125358037),
1062
6
                               }},
1063
6
                               {{
1064
6
                                   V(3.6 * 4992.2486445538634),
1065
6
                                   V(-1.2),
1066
6
                                   V(-1.2),
1067
6
                                   V(-0.8),
1068
6
                                   V(-0.7),
1069
6
                                   V(-0.7),
1070
6
                                   V(-0.4),
1071
6
                                   V(-0.5),
1072
6
                               }}}},
1073
6
                             8));
1074
6
  }
1075
1076
  // DCT256X128
1077
6
  static QuantEncodingInternal DCT128X256() {
1078
6
    return QuantEncodingInternal::DCT(
1079
6
        DctQuantWeightParams({{{{
1080
6
                                   V(2.6 * 23629.073922049845),
1081
6
                                   V(-1.025),
1082
6
                                   V(-0.78),
1083
6
                                   V(-0.65012),
1084
6
                                   V(-0.19041574084286472),
1085
6
                                   V(-0.20819395464),
1086
6
                                   V(-0.421064),
1087
6
                                   V(-0.32733845535848671),
1088
6
                               }},
1089
6
                               {{
1090
6
                                   V(2.6 * 8611.3238710010046),
1091
6
                                   V(-0.3041958212306401),
1092
6
                                   V(-0.3633036457487539),
1093
6
                                   V(-0.35660379990111464),
1094
6
                                   V(-0.3443074455424403),
1095
6
                                   V(-0.33699592683512467),
1096
6
                                   V(-0.30180866526242109),
1097
6
                                   V(-0.27321683125358037),
1098
6
                               }},
1099
6
                               {{
1100
6
                                   V(2.6 * 4492.2486445538634),
1101
6
                                   V(-1.2),
1102
6
                                   V(-1.2),
1103
6
                                   V(-0.8),
1104
6
                                   V(-0.7),
1105
6
                                   V(-0.7),
1106
6
                                   V(-0.4),
1107
6
                                   V(-0.5),
1108
6
                               }}}},
1109
6
                             8));
1110
6
  }
1111
};
1112
}  // namespace
1113
1114
6
DequantMatrices::DequantLibraryInternal DequantMatrices::LibraryInit() {
1115
6
  static_assert(kNumQuantTables == 17,
1116
6
                "Update this function when adding new quantization kinds.");
1117
6
  static_assert(kNumPredefinedTables == 1,
1118
6
                "Update this function when adding new quantization matrices to "
1119
6
                "the library.");
1120
1121
  // The library and the indices need to be kept in sync manually.
1122
6
  static_assert(0 == static_cast<uint8_t>(QuantTable::DCT),
1123
6
                "Update the DequantLibrary array below.");
1124
6
  static_assert(1 == static_cast<uint8_t>(QuantTable::IDENTITY),
1125
6
                "Update the DequantLibrary array below.");
1126
6
  static_assert(2 == static_cast<uint8_t>(QuantTable::DCT2X2),
1127
6
                "Update the DequantLibrary array below.");
1128
6
  static_assert(3 == static_cast<uint8_t>(QuantTable::DCT4X4),
1129
6
                "Update the DequantLibrary array below.");
1130
6
  static_assert(4 == static_cast<uint8_t>(QuantTable::DCT16X16),
1131
6
                "Update the DequantLibrary array below.");
1132
6
  static_assert(5 == static_cast<uint8_t>(QuantTable::DCT32X32),
1133
6
                "Update the DequantLibrary array below.");
1134
6
  static_assert(6 == static_cast<uint8_t>(QuantTable::DCT8X16),
1135
6
                "Update the DequantLibrary array below.");
1136
6
  static_assert(7 == static_cast<uint8_t>(QuantTable::DCT8X32),
1137
6
                "Update the DequantLibrary array below.");
1138
6
  static_assert(8 == static_cast<uint8_t>(QuantTable::DCT16X32),
1139
6
                "Update the DequantLibrary array below.");
1140
6
  static_assert(9 == static_cast<uint8_t>(QuantTable::DCT4X8),
1141
6
                "Update the DequantLibrary array below.");
1142
6
  static_assert(10 == static_cast<uint8_t>(QuantTable::AFV0),
1143
6
                "Update the DequantLibrary array below.");
1144
6
  static_assert(11 == static_cast<uint8_t>(QuantTable::DCT64X64),
1145
6
                "Update the DequantLibrary array below.");
1146
6
  static_assert(12 == static_cast<uint8_t>(QuantTable::DCT32X64),
1147
6
                "Update the DequantLibrary array below.");
1148
6
  static_assert(13 == static_cast<uint8_t>(QuantTable::DCT128X128),
1149
6
                "Update the DequantLibrary array below.");
1150
6
  static_assert(14 == static_cast<uint8_t>(QuantTable::DCT64X128),
1151
6
                "Update the DequantLibrary array below.");
1152
6
  static_assert(15 == static_cast<uint8_t>(QuantTable::DCT256X256),
1153
6
                "Update the DequantLibrary array below.");
1154
6
  static_assert(16 == static_cast<uint8_t>(QuantTable::DCT128X256),
1155
6
                "Update the DequantLibrary array below.");
1156
6
  return DequantMatrices::DequantLibraryInternal{{
1157
6
      DequantMatricesLibraryDef::DCT(),
1158
6
      DequantMatricesLibraryDef::IDENTITY(),
1159
6
      DequantMatricesLibraryDef::DCT2X2(),
1160
6
      DequantMatricesLibraryDef::DCT4X4(),
1161
6
      DequantMatricesLibraryDef::DCT16X16(),
1162
6
      DequantMatricesLibraryDef::DCT32X32(),
1163
6
      DequantMatricesLibraryDef::DCT8X16(),
1164
6
      DequantMatricesLibraryDef::DCT8X32(),
1165
6
      DequantMatricesLibraryDef::DCT16X32(),
1166
6
      DequantMatricesLibraryDef::DCT4X8(),
1167
6
      DequantMatricesLibraryDef::AFV0(),
1168
6
      DequantMatricesLibraryDef::DCT64X64(),
1169
6
      DequantMatricesLibraryDef::DCT32X64(),
1170
      // Same default for large transforms (128+) as for 64x* transforms.
1171
6
      DequantMatricesLibraryDef::DCT128X128(),
1172
6
      DequantMatricesLibraryDef::DCT64X128(),
1173
6
      DequantMatricesLibraryDef::DCT256X256(),
1174
6
      DequantMatricesLibraryDef::DCT128X256(),
1175
6
  }};
1176
6
}
1177
1178
25.6k
const QuantEncoding* DequantMatrices::Library() {
1179
25.6k
  static const DequantMatrices::DequantLibraryInternal kDequantLibrary =
1180
25.6k
      DequantMatrices::LibraryInit();
1181
  // Downcast the result to a const QuantEncoding* from QuantEncodingInternal*
1182
  // since the subclass (QuantEncoding) doesn't add any new members and users
1183
  // will need to upcast to QuantEncodingInternal to access the members of that
1184
  // class. This allows to have kDequantLibrary as a constexpr value while still
1185
  // allowing to create QuantEncoding::RAW() instances that use std::vector in
1186
  // C++11.
1187
25.6k
  return reinterpret_cast<const QuantEncoding*>(kDequantLibrary.data());
1188
25.6k
}
1189
1190
542k
DequantMatrices::DequantMatrices() {
1191
542k
  encodings_.resize(kNumQuantTables, QuantEncoding::Library<0>());
1192
542k
  size_t pos = 0;
1193
542k
  size_t offsets[kNumQuantTables * 3];
1194
9.77M
  for (size_t i = 0; i < static_cast<size_t>(kNumQuantTables); i++) {
1195
9.22M
    size_t num_blocks =
1196
9.22M
        static_cast<size_t>(required_size_x[i]) * required_size_y[i];
1197
9.22M
    size_t num = num_blocks * kDCTBlockSize;
1198
36.9M
    for (size_t c = 0; c < 3; c++) {
1199
27.6M
      offsets[3 * i + c] = pos + c * num;
1200
27.6M
    }
1201
9.22M
    pos += 3 * num;
1202
9.22M
  }
1203
15.2M
  for (size_t i = 0; i < AcStrategy::kNumValidStrategies; i++) {
1204
58.6M
    for (size_t c = 0; c < 3; c++) {
1205
43.9M
      table_offsets_[i * 3 + c] =
1206
43.9M
          offsets[static_cast<size_t>(kAcStrategyToQuantTableMap[i]) * 3 + c];
1207
43.9M
    }
1208
14.6M
  }
1209
542k
}
1210
1211
Status DequantMatrices::EnsureComputed(JxlMemoryManager* memory_manager,
1212
25.6k
                                       uint32_t acs_mask) {
1213
25.6k
  const QuantEncoding* library = Library();
1214
1215
25.6k
  if (!table_storage_) {
1216
25.6k
    size_t table_storage_bytes = 2 * kTotalTableSize * sizeof(float);
1217
25.6k
    JXL_ASSIGN_OR_RETURN(
1218
25.6k
        table_storage_,
1219
25.6k
        AlignedMemory::Create(memory_manager, table_storage_bytes));
1220
25.6k
    table_ = table_storage_.address<float>();
1221
25.6k
    inv_table_ = table_ + kTotalTableSize;
1222
25.6k
  }
1223
1224
25.6k
  size_t offsets[kNumQuantTables * 3 + 1];
1225
25.6k
  size_t pos = 0;
1226
462k
  for (size_t i = 0; i < kNumQuantTables; i++) {
1227
436k
    size_t num_blocks =
1228
436k
        static_cast<size_t>(required_size_x[i]) * required_size_y[i];
1229
436k
    size_t num = num_blocks * kDCTBlockSize;
1230
1.74M
    for (size_t c = 0; c < 3; c++) {
1231
1.30M
      offsets[3 * i + c] = pos + c * num;
1232
1.30M
    }
1233
436k
    pos += 3 * num;
1234
436k
  }
1235
25.6k
  offsets[kNumQuantTables * 3] = pos;
1236
25.6k
  JXL_ENSURE(pos == kTotalTableSize);
1237
1238
25.6k
  uint32_t kind_mask = 0;
1239
719k
  for (size_t i = 0; i < AcStrategy::kNumValidStrategies; i++) {
1240
693k
    if (acs_mask & (1u << i)) {
1241
123k
      kind_mask |= 1u << static_cast<uint32_t>(kAcStrategyToQuantTableMap[i]);
1242
123k
    }
1243
693k
  }
1244
25.6k
  uint32_t computed_kind_mask = 0;
1245
719k
  for (size_t i = 0; i < AcStrategy::kNumValidStrategies; i++) {
1246
693k
    if (computed_mask_ & (1u << i)) {
1247
0
      computed_kind_mask |=
1248
0
          1u << static_cast<uint32_t>(kAcStrategyToQuantTableMap[i]);
1249
0
    }
1250
693k
  }
1251
460k
  for (size_t table = 0; table < kNumQuantTables; table++) {
1252
435k
    if ((1 << table) & computed_kind_mask) continue;
1253
435k
    if ((1 << table) & ~kind_mask) continue;
1254
87.7k
    size_t offset = offsets[table * 3];
1255
87.7k
    float* mutable_table = table_storage_.address<float>();
1256
87.7k
    if (encodings_[table].mode == QuantEncoding::kQuantModeLibrary) {
1257
87.6k
      JXL_RETURN_IF_ERROR(HWY_DYNAMIC_DISPATCH(ComputeQuantTable)(
1258
87.6k
          library[table], mutable_table, mutable_table + kTotalTableSize, table,
1259
87.6k
          QuantTable(table), &offset));
1260
87.6k
    } else {
1261
152
      JXL_RETURN_IF_ERROR(HWY_DYNAMIC_DISPATCH(ComputeQuantTable)(
1262
152
          encodings_[table], mutable_table, mutable_table + kTotalTableSize,
1263
152
          table, QuantTable(table), &offset));
1264
152
    }
1265
87.6k
    JXL_ENSURE(offset == offsets[table * 3 + 3]);
1266
87.6k
  }
1267
25.6k
  computed_mask_ |= acs_mask;
1268
1269
25.6k
  return true;
1270
25.6k
}
1271
1272
}  // namespace jxl
1273
#endif