Coverage Report

Created: 2026-06-16 07:20

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