Coverage Report

Created: 2025-08-11 08:01

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