Coverage Report

Created: 2025-11-14 07:32

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