Coverage Report

Created: 2026-09-14 07:37

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
7.00k
                         float* weights) {
50
28.0k
  for (size_t c = 0; c < 3; c++) {
51
21.0k
    size_t start = c * 64;
52
21.0k
    weights[start] = 0xBAD;
53
21.0k
    weights[start + 1] = weights[start + 8] = dct2weights[c][0];
54
21.0k
    weights[start + 9] = dct2weights[c][1];
55
63.0k
    for (size_t y = 0; y < 2; y++) {
56
126k
      for (size_t x = 0; x < 2; x++) {
57
84.0k
        weights[start + y * 8 + x + 2] = dct2weights[c][2];
58
84.0k
        weights[start + (y + 2) * 8 + x] = dct2weights[c][2];
59
84.0k
      }
60
42.0k
    }
61
63.0k
    for (size_t y = 0; y < 2; y++) {
62
126k
      for (size_t x = 0; x < 2; x++) {
63
84.0k
        weights[start + (y + 2) * 8 + x + 2] = dct2weights[c][3];
64
84.0k
      }
65
42.0k
    }
66
105k
    for (size_t y = 0; y < 4; y++) {
67
420k
      for (size_t x = 0; x < 4; x++) {
68
336k
        weights[start + y * 8 + x + 4] = dct2weights[c][4];
69
336k
        weights[start + (y + 4) * 8 + x] = dct2weights[c][4];
70
336k
      }
71
84.0k
    }
72
105k
    for (size_t y = 0; y < 4; y++) {
73
420k
      for (size_t x = 0; x < 4; x++) {
74
336k
        weights[start + (y + 4) * 8 + x + 4] = dct2weights[c][5];
75
336k
      }
76
84.0k
    }
77
21.0k
  }
78
7.00k
}
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
7.00k
                         float* weights) {
50
28.0k
  for (size_t c = 0; c < 3; c++) {
51
21.0k
    size_t start = c * 64;
52
21.0k
    weights[start] = 0xBAD;
53
21.0k
    weights[start + 1] = weights[start + 8] = dct2weights[c][0];
54
21.0k
    weights[start + 9] = dct2weights[c][1];
55
63.0k
    for (size_t y = 0; y < 2; y++) {
56
126k
      for (size_t x = 0; x < 2; x++) {
57
84.0k
        weights[start + y * 8 + x + 2] = dct2weights[c][2];
58
84.0k
        weights[start + (y + 2) * 8 + x] = dct2weights[c][2];
59
84.0k
      }
60
42.0k
    }
61
63.0k
    for (size_t y = 0; y < 2; y++) {
62
126k
      for (size_t x = 0; x < 2; x++) {
63
84.0k
        weights[start + (y + 2) * 8 + x + 2] = dct2weights[c][3];
64
84.0k
      }
65
42.0k
    }
66
105k
    for (size_t y = 0; y < 4; y++) {
67
420k
      for (size_t x = 0; x < 4; x++) {
68
336k
        weights[start + y * 8 + x + 4] = dct2weights[c][4];
69
336k
        weights[start + (y + 4) * 8 + x] = dct2weights[c][4];
70
336k
      }
71
84.0k
    }
72
105k
    for (size_t y = 0; y < 4; y++) {
73
420k
      for (size_t x = 0; x < 4; x++) {
74
336k
        weights[start + (y + 4) * 8 + x + 4] = dct2weights[c][5];
75
336k
      }
76
84.0k
    }
77
21.0k
  }
78
7.00k
}
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
10.2k
                             float* weights) {
82
41.0k
  for (size_t c = 0; c < 3; c++) {
83
2.00M
    for (int i = 0; i < 64; i++) {
84
1.97M
      weights[64 * c + i] = idweights[c][0];
85
1.97M
    }
86
30.8k
    weights[64 * c + 1] = idweights[c][1];
87
30.8k
    weights[64 * c + 8] = idweights[c][1];
88
30.8k
    weights[64 * c + 9] = idweights[c][2];
89
30.8k
  }
90
10.2k
}
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
10.2k
                             float* weights) {
82
41.0k
  for (size_t c = 0; c < 3; c++) {
83
2.00M
    for (int i = 0; i < 64; i++) {
84
1.97M
      weights[64 * c + i] = idweights[c][0];
85
1.97M
    }
86
30.8k
    weights[64 * c + 1] = idweights[c][1];
87
30.8k
    weights[64 * c + 8] = idweights[c][1];
88
30.8k
    weights[64 * c + 9] = idweights[c][2];
89
30.8k
  }
90
10.2k
}
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
327k
                            size_t len) {
94
327k
  float scaled_pos = pos * (len - 1) / max;
95
327k
  size_t idx = scaled_pos;
96
327k
  JXL_ENSURE(idx + 1 < len);
97
327k
  float a = array[idx];
98
327k
  float b = array[idx + 1];
99
327k
  return a * FastPowf(b / a, scaled_pos - idx);
100
327k
}
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
327k
                            size_t len) {
94
327k
  float scaled_pos = pos * (len - 1) / max;
95
327k
  size_t idx = scaled_pos;
96
327k
  JXL_ENSURE(idx + 1 < len);
97
327k
  float a = array[idx];
98
327k
  float b = array[idx + 1];
99
327k
  return a * FastPowf(b / a, scaled_pos - idx);
100
327k
}
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.64M
float Mult(float v) {
103
1.64M
  if (v > 0.0f) return 1.0f + v;
104
1.64M
  return 1.0f / (1.0f - v);
105
1.64M
}
Unexecuted instantiation: jxl::N_SSE4::Mult(float)
jxl::N_AVX2::Mult(float)
Line
Count
Source
102
1.64M
float Mult(float v) {
103
1.64M
  if (v > 0.0f) return 1.0f + v;
104
1.64M
  return 1.0f / (1.0f - v);
105
1.64M
}
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
38.0M
    hwy::HWY_NAMESPACE::Vec<DF4> scaled_pos, const float* array) {
111
38.0M
  HWY_CAPPED(int32_t, 4) di;
112
113
38.0M
  auto idx = ConvertTo(di, scaled_pos);
114
115
38.0M
  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
38.0M
  auto a = GatherIndex(DF4(), array, idx);
120
38.0M
  auto b = GatherIndex(DF4(), array + 1, idx);
121
122
38.0M
  return Mul(a, FastPowf(DF4(), Div(b, a), frac));
123
38.0M
}
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
38.0M
    hwy::HWY_NAMESPACE::Vec<DF4> scaled_pos, const float* array) {
111
38.0M
  HWY_CAPPED(int32_t, 4) di;
112
113
38.0M
  auto idx = ConvertTo(di, scaled_pos);
114
115
38.0M
  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
38.0M
  auto a = GatherIndex(DF4(), array, idx);
120
38.0M
  auto b = GatherIndex(DF4(), array + 1, idx);
121
122
38.0M
  return Mul(a, FastPowf(DF4(), Div(b, a), frac));
123
38.0M
}
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
101k
    size_t num_bands, float* out) {
133
404k
  for (size_t c = 0; c < 3; c++) {
134
303k
    float bands[DctQuantWeightParams::kMaxDistanceBands] = {
135
303k
        distance_bands[c][0]};
136
303k
    if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
137
1.86M
    for (size_t i = 1; i < num_bands; i++) {
138
1.55M
      bands[i] = bands[i - 1] * Mult(distance_bands[c][i]);
139
1.55M
      if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
140
1.55M
    }
141
303k
    float scale = (num_bands - 1) / (kSqrt2 + 1e-6f);
142
303k
    float rcpcol = scale / (COLS - 1);
143
303k
    float rcprow = scale / (ROWS - 1);
144
303k
    JXL_ENSURE(COLS >= Lanes(DF4()));
145
303k
    HWY_ALIGN float l0123[4] = {0, 1, 2, 3};
146
4.42M
    for (uint32_t y = 0; y < ROWS; y++) {
147
4.12M
      float dy = y * rcprow;
148
4.12M
      float dy2 = dy * dy;
149
42.1M
      for (uint32_t x = 0; x < COLS; x += Lanes(DF4())) {
150
38.0M
        auto dx =
151
38.0M
            Mul(Add(Set(DF4(), x), Load(DF4(), l0123)), Set(DF4(), rcpcol));
152
38.0M
        auto scaled_distance = Sqrt(MulAdd(dx, dx, Set(DF4(), dy2)));
153
38.0M
        auto weight = num_bands == 1 ? Set(DF4(), bands[0])
154
38.0M
                                     : InterpolateVec(scaled_distance, bands);
155
38.0M
        StoreU(weight, DF4(), out + c * COLS * ROWS + y * COLS + x);
156
38.0M
      }
157
4.12M
    }
158
303k
  }
159
101k
  return true;
160
101k
}
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
101k
    size_t num_bands, float* out) {
133
404k
  for (size_t c = 0; c < 3; c++) {
134
303k
    float bands[DctQuantWeightParams::kMaxDistanceBands] = {
135
303k
        distance_bands[c][0]};
136
303k
    if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
137
1.86M
    for (size_t i = 1; i < num_bands; i++) {
138
1.55M
      bands[i] = bands[i - 1] * Mult(distance_bands[c][i]);
139
1.55M
      if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
140
1.55M
    }
141
303k
    float scale = (num_bands - 1) / (kSqrt2 + 1e-6f);
142
303k
    float rcpcol = scale / (COLS - 1);
143
303k
    float rcprow = scale / (ROWS - 1);
144
303k
    JXL_ENSURE(COLS >= Lanes(DF4()));
145
303k
    HWY_ALIGN float l0123[4] = {0, 1, 2, 3};
146
4.42M
    for (uint32_t y = 0; y < ROWS; y++) {
147
4.12M
      float dy = y * rcprow;
148
4.12M
      float dy2 = dy * dy;
149
42.1M
      for (uint32_t x = 0; x < COLS; x += Lanes(DF4())) {
150
38.0M
        auto dx =
151
38.0M
            Mul(Add(Set(DF4(), x), Load(DF4(), l0123)), Set(DF4(), rcpcol));
152
38.0M
        auto scaled_distance = Sqrt(MulAdd(dx, dx, Set(DF4(), dy2)));
153
38.0M
        auto weight = num_bands == 1 ? Set(DF4(), bands[0])
154
38.0M
                                     : InterpolateVec(scaled_distance, bands);
155
38.0M
        StoreU(weight, DF4(), out + c * COLS * ROWS + y * COLS + x);
156
38.0M
      }
157
4.12M
    }
158
303k
  }
159
101k
  return true;
160
101k
}
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
109k
                         QuantTable kind, size_t* pos) {
167
109k
  constexpr size_t N = kBlockDim;
168
109k
  size_t quant_table_idx = static_cast<size_t>(kind);
169
109k
  size_t wrows = 8 * DequantMatrices::required_size_x[quant_table_idx];
170
109k
  size_t wcols = 8 * DequantMatrices::required_size_y[quant_table_idx];
171
109k
  size_t num = wrows * wcols;
172
173
109k
  std::vector<float> weights(3 * num);
174
175
109k
  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
10.2k
    case QuantEncoding::kQuantModeID: {
183
10.2k
      JXL_ENSURE(num == kDCTBlockSize);
184
10.2k
      GetQuantWeightsIdentity(encoding.idweights, weights.data());
185
10.2k
      break;
186
10.2k
    }
187
7.00k
    case QuantEncoding::kQuantModeDCT2: {
188
7.00k
      JXL_ENSURE(num == kDCTBlockSize);
189
7.00k
      GetQuantWeightsDCT2(encoding.dct2weights, weights.data());
190
7.00k
      break;
191
7.00k
    }
192
5.15k
    case QuantEncoding::kQuantModeDCT4: {
193
5.15k
      JXL_ENSURE(num == kDCTBlockSize);
194
5.15k
      float weights4x4[3 * 4 * 4];
195
      // Always use 4x4 GetQuantWeights for DCT4 quantization tables.
196
5.15k
      JXL_RETURN_IF_ERROR(
197
5.15k
          GetQuantWeights(4, 4, encoding.dct_params.distance_bands,
198
5.15k
                          encoding.dct_params.num_distance_bands, weights4x4));
199
20.6k
      for (size_t c = 0; c < 3; c++) {
200
139k
        for (size_t y = 0; y < kBlockDim; y++) {
201
1.11M
          for (size_t x = 0; x < kBlockDim; x++) {
202
989k
            weights[c * num + y * kBlockDim + x] =
203
989k
                weights4x4[c * 16 + (y / 2) * 4 + (x / 2)];
204
989k
          }
205
123k
        }
206
15.4k
        weights[c * num + 1] /= encoding.dct4multipliers[c][0];
207
15.4k
        weights[c * num + N] /= encoding.dct4multipliers[c][0];
208
15.4k
        weights[c * num + N + 1] /= encoding.dct4multipliers[c][1];
209
15.4k
      }
210
5.15k
      break;
211
5.15k
    }
212
6.54k
    case QuantEncoding::kQuantModeDCT4X8: {
213
6.54k
      JXL_ENSURE(num == kDCTBlockSize);
214
6.54k
      float weights4x8[3 * 4 * 8];
215
      // Always use 4x8 GetQuantWeights for DCT4X8 quantization tables.
216
6.54k
      JXL_RETURN_IF_ERROR(
217
6.54k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
218
6.54k
                          encoding.dct_params.num_distance_bands, weights4x8));
219
26.1k
      for (size_t c = 0; c < 3; c++) {
220
176k
        for (size_t y = 0; y < kBlockDim; y++) {
221
1.41M
          for (size_t x = 0; x < kBlockDim; x++) {
222
1.25M
            weights[c * num + y * kBlockDim + x] =
223
1.25M
                weights4x8[c * 32 + (y / 2) * 8 + x];
224
1.25M
          }
225
156k
        }
226
19.6k
        weights[c * num + N] /= encoding.dct4x8multipliers[c];
227
19.6k
      }
228
6.53k
      break;
229
6.54k
    }
230
71.1k
    case QuantEncoding::kQuantModeDCT: {
231
71.1k
      JXL_RETURN_IF_ERROR(GetQuantWeights(
232
71.1k
          wrows, wcols, encoding.dct_params.distance_bands,
233
71.1k
          encoding.dct_params.num_distance_bands, weights.data()));
234
71.1k
      break;
235
71.1k
    }
236
71.1k
    case QuantEncoding::kQuantModeRAW: {
237
4
      if (!encoding.qraw.qtable || encoding.qraw.qtable->size() != 3 * num) {
238
0
        return JXL_FAILURE("Invalid table encoding");
239
0
      }
240
4
      int* qtable = encoding.qraw.qtable->data();
241
772
      for (size_t i = 0; i < 3 * num; i++) {
242
768
        weights[i] = 1.f / (encoding.qraw.qtable_den * qtable[i]);
243
768
      }
244
4
      break;
245
4
    }
246
9.10k
    case QuantEncoding::kQuantModeAFV: {
247
9.10k
      constexpr float kFreqs[] = {
248
9.10k
          0xBAD,
249
9.10k
          0xBAD,
250
9.10k
          0.8517778890324296,
251
9.10k
          5.37778436506804,
252
9.10k
          0xBAD,
253
9.10k
          0xBAD,
254
9.10k
          4.734747904497923,
255
9.10k
          5.449245381693219,
256
9.10k
          1.6598270267479331,
257
9.10k
          4,
258
9.10k
          7.275749096817861,
259
9.10k
          10.423227632456525,
260
9.10k
          2.662932286148962,
261
9.10k
          7.630657783650829,
262
9.10k
          8.962388608184032,
263
9.10k
          12.97166202570235,
264
9.10k
      };
265
266
9.10k
      float weights4x8[3 * 4 * 8];
267
9.10k
      JXL_RETURN_IF_ERROR((
268
9.10k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
269
9.10k
                          encoding.dct_params.num_distance_bands, weights4x8)));
270
9.10k
      float weights4x4[3 * 4 * 4];
271
9.10k
      JXL_RETURN_IF_ERROR((GetQuantWeights(
272
9.10k
          4, 4, encoding.dct_params_afv_4x4.distance_bands,
273
9.10k
          encoding.dct_params_afv_4x4.num_distance_bands, weights4x4)));
274
275
9.10k
      constexpr float lo = 0.8517778890324296;
276
9.10k
      constexpr float hi = 12.97166202570235f - lo + 1e-6f;
277
36.4k
      for (size_t c = 0; c < 3; c++) {
278
27.3k
        float bands[4];
279
27.3k
        bands[0] = encoding.afv_weights[c][5];
280
27.3k
        if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
281
109k
        for (size_t i = 1; i < 4; i++) {
282
81.8k
          bands[i] = bands[i - 1] * Mult(encoding.afv_weights[c][i + 5]);
283
81.8k
          if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
284
81.8k
        }
285
27.2k
        size_t start = c * 64;
286
463k
        auto set_weight = [&start, &weights](size_t x, size_t y, float val) {
287
463k
          weights[start + y * 8 + x] = val;
288
463k
        };
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
463k
        auto set_weight = [&start, &weights](size_t x, size_t y, float val) {
287
463k
          weights[start + y * 8 + x] = val;
288
463k
        };
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
27.2k
        weights[start] = 1;  // Not used, but causes MSAN error otherwise.
290
        // Weights for (0, 1) and (1, 0).
291
27.2k
        set_weight(0, 1, encoding.afv_weights[c][0]);
292
27.2k
        set_weight(1, 0, encoding.afv_weights[c][1]);
293
        // AFV special weights for 3-pixel corner.
294
27.2k
        set_weight(0, 2, encoding.afv_weights[c][2]);
295
27.2k
        set_weight(2, 0, encoding.afv_weights[c][3]);
296
27.2k
        set_weight(2, 2, encoding.afv_weights[c][4]);
297
298
        // All other AFV weights.
299
136k
        for (size_t y = 0; y < 4; y++) {
300
545k
          for (size_t x = 0; x < 4; x++) {
301
436k
            if (x < 2 && y < 2) continue;
302
655k
            JXL_ASSIGN_OR_RETURN(
303
655k
                float val, Interpolate(kFreqs[y * 4 + x] - lo, hi, bands, 4));
304
655k
            set_weight(2 * x, 2 * y, val);
305
655k
          }
306
109k
        }
307
308
        // Put 4x8 weights in odd rows, except (1, 0).
309
136k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
310
982k
          for (size_t x = 0; x < kBlockDim; x++) {
311
873k
            if (x == 0 && y == 0) continue;
312
846k
            weights[c * num + (2 * y + 1) * kBlockDim + x] =
313
846k
                weights4x8[c * 32 + y * 8 + x];
314
846k
          }
315
109k
        }
316
        // Put 4x4 weights in even rows / odd columns, except (0, 1).
317
136k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
318
545k
          for (size_t x = 0; x < kBlockDim / 2; x++) {
319
436k
            if (x == 0 && y == 0) continue;
320
409k
            weights[c * num + (2 * y) * kBlockDim + 2 * x + 1] =
321
409k
                weights4x4[c * 16 + y * 4 + x];
322
409k
          }
323
109k
        }
324
27.2k
      }
325
9.09k
      break;
326
9.10k
    }
327
109k
  }
328
109k
  size_t prev_pos = *pos;
329
109k
  HWY_CAPPED(float, 64) d;
330
19.7M
  for (size_t i = 0; i < num * 3; i += Lanes(d)) {
331
19.6M
    auto inv_val = LoadU(d, weights.data() + i);
332
19.6M
    if (JXL_UNLIKELY(!AllFalse(d, Ge(inv_val, Set(d, 1.0f / kAlmostZero))) ||
333
19.6M
                     !AllFalse(d, Lt(inv_val, Set(d, kAlmostZero))))) {
334
57
      return JXL_FAILURE("Invalid quantization table");
335
57
    }
336
19.6M
    auto val = Div(Set(d, 1.0f), inv_val);
337
19.6M
    StoreU(val, d, table + *pos + i);
338
19.6M
    StoreU(inv_val, d, inv_table + *pos + i);
339
19.6M
  }
340
109k
  (*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
109k
  size_t xs = DequantMatrices::required_size_x[quant_table_idx];
346
109k
  size_t ys = DequantMatrices::required_size_y[quant_table_idx];
347
109k
  CoefficientLayout(&ys, &xs);
348
436k
  for (size_t c = 0; c < 3; c++) {
349
912k
    for (size_t y = 0; y < ys; y++) {
350
3.04M
      for (size_t x = 0; x < xs; x++) {
351
2.45M
        inv_table[prev_pos + c * ys * xs * kDCTBlockSize + y * kBlockDim * xs +
352
2.45M
                  x] = 0;
353
2.45M
      }
354
584k
    }
355
327k
  }
356
109k
  return true;
357
109k
}
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
109k
                         QuantTable kind, size_t* pos) {
167
109k
  constexpr size_t N = kBlockDim;
168
109k
  size_t quant_table_idx = static_cast<size_t>(kind);
169
109k
  size_t wrows = 8 * DequantMatrices::required_size_x[quant_table_idx];
170
109k
  size_t wcols = 8 * DequantMatrices::required_size_y[quant_table_idx];
171
109k
  size_t num = wrows * wcols;
172
173
109k
  std::vector<float> weights(3 * num);
174
175
109k
  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
10.2k
    case QuantEncoding::kQuantModeID: {
183
10.2k
      JXL_ENSURE(num == kDCTBlockSize);
184
10.2k
      GetQuantWeightsIdentity(encoding.idweights, weights.data());
185
10.2k
      break;
186
10.2k
    }
187
7.00k
    case QuantEncoding::kQuantModeDCT2: {
188
7.00k
      JXL_ENSURE(num == kDCTBlockSize);
189
7.00k
      GetQuantWeightsDCT2(encoding.dct2weights, weights.data());
190
7.00k
      break;
191
7.00k
    }
192
5.15k
    case QuantEncoding::kQuantModeDCT4: {
193
5.15k
      JXL_ENSURE(num == kDCTBlockSize);
194
5.15k
      float weights4x4[3 * 4 * 4];
195
      // Always use 4x4 GetQuantWeights for DCT4 quantization tables.
196
5.15k
      JXL_RETURN_IF_ERROR(
197
5.15k
          GetQuantWeights(4, 4, encoding.dct_params.distance_bands,
198
5.15k
                          encoding.dct_params.num_distance_bands, weights4x4));
199
20.6k
      for (size_t c = 0; c < 3; c++) {
200
139k
        for (size_t y = 0; y < kBlockDim; y++) {
201
1.11M
          for (size_t x = 0; x < kBlockDim; x++) {
202
989k
            weights[c * num + y * kBlockDim + x] =
203
989k
                weights4x4[c * 16 + (y / 2) * 4 + (x / 2)];
204
989k
          }
205
123k
        }
206
15.4k
        weights[c * num + 1] /= encoding.dct4multipliers[c][0];
207
15.4k
        weights[c * num + N] /= encoding.dct4multipliers[c][0];
208
15.4k
        weights[c * num + N + 1] /= encoding.dct4multipliers[c][1];
209
15.4k
      }
210
5.15k
      break;
211
5.15k
    }
212
6.54k
    case QuantEncoding::kQuantModeDCT4X8: {
213
6.54k
      JXL_ENSURE(num == kDCTBlockSize);
214
6.54k
      float weights4x8[3 * 4 * 8];
215
      // Always use 4x8 GetQuantWeights for DCT4X8 quantization tables.
216
6.54k
      JXL_RETURN_IF_ERROR(
217
6.54k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
218
6.54k
                          encoding.dct_params.num_distance_bands, weights4x8));
219
26.1k
      for (size_t c = 0; c < 3; c++) {
220
176k
        for (size_t y = 0; y < kBlockDim; y++) {
221
1.41M
          for (size_t x = 0; x < kBlockDim; x++) {
222
1.25M
            weights[c * num + y * kBlockDim + x] =
223
1.25M
                weights4x8[c * 32 + (y / 2) * 8 + x];
224
1.25M
          }
225
156k
        }
226
19.6k
        weights[c * num + N] /= encoding.dct4x8multipliers[c];
227
19.6k
      }
228
6.53k
      break;
229
6.54k
    }
230
71.1k
    case QuantEncoding::kQuantModeDCT: {
231
71.1k
      JXL_RETURN_IF_ERROR(GetQuantWeights(
232
71.1k
          wrows, wcols, encoding.dct_params.distance_bands,
233
71.1k
          encoding.dct_params.num_distance_bands, weights.data()));
234
71.1k
      break;
235
71.1k
    }
236
71.1k
    case QuantEncoding::kQuantModeRAW: {
237
4
      if (!encoding.qraw.qtable || encoding.qraw.qtable->size() != 3 * num) {
238
0
        return JXL_FAILURE("Invalid table encoding");
239
0
      }
240
4
      int* qtable = encoding.qraw.qtable->data();
241
772
      for (size_t i = 0; i < 3 * num; i++) {
242
768
        weights[i] = 1.f / (encoding.qraw.qtable_den * qtable[i]);
243
768
      }
244
4
      break;
245
4
    }
246
9.10k
    case QuantEncoding::kQuantModeAFV: {
247
9.10k
      constexpr float kFreqs[] = {
248
9.10k
          0xBAD,
249
9.10k
          0xBAD,
250
9.10k
          0.8517778890324296,
251
9.10k
          5.37778436506804,
252
9.10k
          0xBAD,
253
9.10k
          0xBAD,
254
9.10k
          4.734747904497923,
255
9.10k
          5.449245381693219,
256
9.10k
          1.6598270267479331,
257
9.10k
          4,
258
9.10k
          7.275749096817861,
259
9.10k
          10.423227632456525,
260
9.10k
          2.662932286148962,
261
9.10k
          7.630657783650829,
262
9.10k
          8.962388608184032,
263
9.10k
          12.97166202570235,
264
9.10k
      };
265
266
9.10k
      float weights4x8[3 * 4 * 8];
267
9.10k
      JXL_RETURN_IF_ERROR((
268
9.10k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
269
9.10k
                          encoding.dct_params.num_distance_bands, weights4x8)));
270
9.10k
      float weights4x4[3 * 4 * 4];
271
9.10k
      JXL_RETURN_IF_ERROR((GetQuantWeights(
272
9.10k
          4, 4, encoding.dct_params_afv_4x4.distance_bands,
273
9.10k
          encoding.dct_params_afv_4x4.num_distance_bands, weights4x4)));
274
275
9.10k
      constexpr float lo = 0.8517778890324296;
276
9.10k
      constexpr float hi = 12.97166202570235f - lo + 1e-6f;
277
36.4k
      for (size_t c = 0; c < 3; c++) {
278
27.3k
        float bands[4];
279
27.3k
        bands[0] = encoding.afv_weights[c][5];
280
27.3k
        if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
281
109k
        for (size_t i = 1; i < 4; i++) {
282
81.8k
          bands[i] = bands[i - 1] * Mult(encoding.afv_weights[c][i + 5]);
283
81.8k
          if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
284
81.8k
        }
285
27.2k
        size_t start = c * 64;
286
27.2k
        auto set_weight = [&start, &weights](size_t x, size_t y, float val) {
287
27.2k
          weights[start + y * 8 + x] = val;
288
27.2k
        };
289
27.2k
        weights[start] = 1;  // Not used, but causes MSAN error otherwise.
290
        // Weights for (0, 1) and (1, 0).
291
27.2k
        set_weight(0, 1, encoding.afv_weights[c][0]);
292
27.2k
        set_weight(1, 0, encoding.afv_weights[c][1]);
293
        // AFV special weights for 3-pixel corner.
294
27.2k
        set_weight(0, 2, encoding.afv_weights[c][2]);
295
27.2k
        set_weight(2, 0, encoding.afv_weights[c][3]);
296
27.2k
        set_weight(2, 2, encoding.afv_weights[c][4]);
297
298
        // All other AFV weights.
299
136k
        for (size_t y = 0; y < 4; y++) {
300
545k
          for (size_t x = 0; x < 4; x++) {
301
436k
            if (x < 2 && y < 2) continue;
302
655k
            JXL_ASSIGN_OR_RETURN(
303
655k
                float val, Interpolate(kFreqs[y * 4 + x] - lo, hi, bands, 4));
304
655k
            set_weight(2 * x, 2 * y, val);
305
655k
          }
306
109k
        }
307
308
        // Put 4x8 weights in odd rows, except (1, 0).
309
136k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
310
982k
          for (size_t x = 0; x < kBlockDim; x++) {
311
873k
            if (x == 0 && y == 0) continue;
312
846k
            weights[c * num + (2 * y + 1) * kBlockDim + x] =
313
846k
                weights4x8[c * 32 + y * 8 + x];
314
846k
          }
315
109k
        }
316
        // Put 4x4 weights in even rows / odd columns, except (0, 1).
317
136k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
318
545k
          for (size_t x = 0; x < kBlockDim / 2; x++) {
319
436k
            if (x == 0 && y == 0) continue;
320
409k
            weights[c * num + (2 * y) * kBlockDim + 2 * x + 1] =
321
409k
                weights4x4[c * 16 + y * 4 + x];
322
409k
          }
323
109k
        }
324
27.2k
      }
325
9.09k
      break;
326
9.10k
    }
327
109k
  }
328
109k
  size_t prev_pos = *pos;
329
109k
  HWY_CAPPED(float, 64) d;
330
19.7M
  for (size_t i = 0; i < num * 3; i += Lanes(d)) {
331
19.6M
    auto inv_val = LoadU(d, weights.data() + i);
332
19.6M
    if (JXL_UNLIKELY(!AllFalse(d, Ge(inv_val, Set(d, 1.0f / kAlmostZero))) ||
333
19.6M
                     !AllFalse(d, Lt(inv_val, Set(d, kAlmostZero))))) {
334
57
      return JXL_FAILURE("Invalid quantization table");
335
57
    }
336
19.6M
    auto val = Div(Set(d, 1.0f), inv_val);
337
19.6M
    StoreU(val, d, table + *pos + i);
338
19.6M
    StoreU(inv_val, d, inv_table + *pos + i);
339
19.6M
  }
340
109k
  (*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
109k
  size_t xs = DequantMatrices::required_size_x[quant_table_idx];
346
109k
  size_t ys = DequantMatrices::required_size_y[quant_table_idx];
347
109k
  CoefficientLayout(&ys, &xs);
348
436k
  for (size_t c = 0; c < 3; c++) {
349
912k
    for (size_t y = 0; y < ys; y++) {
350
3.04M
      for (size_t x = 0; x < xs; x++) {
351
2.45M
        inv_table[prev_pos + c * ys * xs * kDCTBlockSize + y * kBlockDim * xs +
352
2.45M
                  x] = 0;
353
2.45M
      }
354
584k
    }
355
327k
  }
356
109k
  return true;
357
109k
}
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
556
Status DecodeDctParams(BitReader* br, DctQuantWeightParams* params) {
374
556
  params->num_distance_bands =
375
556
      br->ReadFixedBits<DctQuantWeightParams::kLog2MaxDistanceBands>() + 1;
376
1.59k
  for (size_t c = 0; c < 3; c++) {
377
5.12k
    for (size_t i = 0; i < params->num_distance_bands; i++) {
378
3.85k
      JXL_RETURN_IF_ERROR(F16Coder::Read(br, &params->distance_bands[c][i]));
379
3.85k
    }
380
1.26k
    if (params->distance_bands[c][0] < kAlmostZero) {
381
225
      return JXL_FAILURE("Distance band seed is too small");
382
225
    }
383
1.04k
    params->distance_bands[c][0] *= 64.0f;
384
1.04k
  }
385
305
  return true;
386
556
}
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
93.5k
              ModularFrameDecoder* modular_frame_decoder) {
392
93.5k
  size_t required_size = required_size_x * required_size_y;
393
93.5k
  required_size_x *= kBlockDim;
394
93.5k
  required_size_y *= kBlockDim;
395
93.5k
  int mode = br->ReadFixedBits<kLog2NumQuantModes>();
396
93.5k
  switch (mode) {
397
78.6k
    case QuantEncoding::kQuantModeLibrary: {
398
78.6k
      encoding->predefined = br->ReadFixedBits<kCeilLog2NumPredefinedTables>();
399
78.6k
      if (encoding->predefined >= kNumPredefinedTables) {
400
0
        return JXL_FAILURE("Invalid predefined table");
401
0
      }
402
78.6k
      break;
403
78.6k
    }
404
78.6k
    case QuantEncoding::kQuantModeID: {
405
2.01k
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
406
2.15k
      for (size_t c = 0; c < 3; c++) {
407
4.60k
        for (size_t i = 0; i < 3; i++) {
408
4.40k
          JXL_RETURN_IF_ERROR(F16Coder::Read(br, &encoding->idweights[c][i]));
409
4.35k
          if (std::abs(encoding->idweights[c][i]) < kAlmostZero) {
410
1.86k
            return JXL_FAILURE("ID Quantizer is too small");
411
1.86k
          }
412
2.49k
          encoding->idweights[c][i] *= 64;
413
2.49k
        }
414
2.10k
      }
415
50
      break;
416
1.95k
    }
417
806
    case QuantEncoding::kQuantModeDCT2: {
418
806
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
419
662
      for (size_t c = 0; c < 3; c++) {
420
2.80k
        for (size_t i = 0; i < 6; i++) {
421
2.55k
          JXL_RETURN_IF_ERROR(F16Coder::Read(br, &encoding->dct2weights[c][i]));
422
2.52k
          if (std::abs(encoding->dct2weights[c][i]) < kAlmostZero) {
423
305
            return JXL_FAILURE("Quantizer is too small");
424
305
          }
425
2.21k
          encoding->dct2weights[c][i] *= 64;
426
2.21k
        }
427
593
      }
428
69
      break;
429
408
    }
430
11.1k
    case QuantEncoding::kQuantModeDCT4X8: {
431
11.1k
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
432
22.4k
      for (size_t c = 0; c < 3; c++) {
433
22.3k
        JXL_RETURN_IF_ERROR(
434
22.3k
            F16Coder::Read(br, &encoding->dct4x8multipliers[c]));
435
22.3k
        if (std::abs(encoding->dct4x8multipliers[c]) < kAlmostZero) {
436
10.9k
          return JXL_FAILURE("DCT4X8 multiplier is too small");
437
10.9k
        }
438
22.3k
      }
439
136
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
440
70
      break;
441
136
    }
442
165
    case QuantEncoding::kQuantModeDCT4: {
443
165
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
444
400
      for (size_t c = 0; c < 3; c++) {
445
894
        for (size_t i = 0; i < 2; i++) {
446
632
          JXL_RETURN_IF_ERROR(
447
632
              F16Coder::Read(br, &encoding->dct4multipliers[c][i]));
448
618
          if (std::abs(encoding->dct4multipliers[c][i]) < kAlmostZero) {
449
57
            return JXL_FAILURE("DCT4 multiplier is too small");
450
57
          }
451
618
        }
452
333
      }
453
67
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
454
47
      break;
455
67
    }
456
129
    case QuantEncoding::kQuantModeAFV: {
457
129
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
458
361
      for (size_t c = 0; c < 3; c++) {
459
2.61k
        for (size_t i = 0; i < 9; i++) {
460
2.36k
          JXL_RETURN_IF_ERROR(F16Coder::Read(br, &encoding->afv_weights[c][i]));
461
2.36k
        }
462
1.71k
        for (size_t i = 0; i < 6; i++) {
463
1.47k
          encoding->afv_weights[c][i] *= 64;
464
1.47k
        }
465
245
      }
466
76
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
467
27
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params_afv_4x4));
468
23
      break;
469
27
    }
470
250
    case QuantEncoding::kQuantModeDCT: {
471
250
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
472
138
      break;
473
250
    }
474
387
    case QuantEncoding::kQuantModeRAW: {
475
      // Set mode early, to avoid mem-leak.
476
387
      encoding->mode = QuantEncoding::kQuantModeRAW;
477
387
      JXL_RETURN_IF_ERROR(ModularFrameDecoder::DecodeQuantTable(
478
387
          memory_manager, required_size_x, required_size_y, br, encoding, idx,
479
387
          modular_frame_decoder));
480
41
      break;
481
387
    }
482
41
    default:
483
0
      return JXL_FAILURE("Invalid quantization table encoding");
484
93.5k
  }
485
79.0k
  encoding->mode = static_cast<QuantEncoding::Mode>(mode);
486
79.0k
  return true;
487
93.5k
}
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
39.7k
                               ModularFrameDecoder* modular_frame_decoder) {
499
39.7k
  size_t all_default = br->ReadBits(1);
500
39.7k
  size_t num_tables = all_default ? 0 : static_cast<size_t>(kNumQuantTables);
501
39.7k
  encodings_.clear();
502
39.7k
  encodings_.resize(kNumQuantTables, QuantEncoding::Library<0>());
503
118k
  for (size_t i = 0; i < num_tables; i++) {
504
93.5k
    JXL_RETURN_IF_ERROR(jxl::Decode(memory_manager, br, &encodings_[i],
505
93.5k
                                    required_size_x[i % kNumQuantTables],
506
93.5k
                                    required_size_y[i % kNumQuantTables], i,
507
93.5k
                                    modular_frame_decoder));
508
93.5k
  }
509
25.2k
  computed_mask_ = 0;
510
25.2k
  return true;
511
39.7k
}
512
513
216k
Status DequantMatrices::DecodeDC(BitReader* br) {
514
216k
  bool all_default = static_cast<bool>(br->ReadBits(1));
515
216k
  if (!br->AllReadsWithinBounds()) return JXL_FAILURE("EOS during DecodeDC");
516
206k
  if (!all_default) {
517
160k
    for (size_t c = 0; c < 3; c++) {
518
122k
      JXL_RETURN_IF_ERROR(F16Coder::Read(br, &dc_quant_[c]));
519
121k
      dc_quant_[c] *= 1.0f / 128.0f;
520
      // Negative values and nearly zero are invalid values.
521
121k
      if (dc_quant_[c] < kAlmostZero) {
522
6.83k
        return JXL_FAILURE("Invalid dc_quant: coefficient is too small.");
523
6.83k
      }
524
114k
      inv_dc_quant_[c] = 1.0f / dc_quant_[c];
525
114k
    }
526
45.4k
  }
527
198k
  return true;
528
206k
}
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
30.2k
const QuantEncoding* DequantMatrices::Library() {
1179
30.2k
  static const DequantMatrices::DequantLibraryInternal kDequantLibrary =
1180
30.2k
      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
30.2k
  return reinterpret_cast<const QuantEncoding*>(kDequantLibrary.data());
1188
30.2k
}
1189
1190
697k
DequantMatrices::DequantMatrices() {
1191
697k
  encodings_.resize(kNumQuantTables, QuantEncoding::Library<0>());
1192
697k
  size_t pos = 0;
1193
697k
  size_t offsets[kNumQuantTables * 3];
1194
12.5M
  for (size_t i = 0; i < static_cast<size_t>(kNumQuantTables); i++) {
1195
11.8M
    size_t num_blocks =
1196
11.8M
        static_cast<size_t>(required_size_x[i]) * required_size_y[i];
1197
11.8M
    size_t num = num_blocks * kDCTBlockSize;
1198
47.4M
    for (size_t c = 0; c < 3; c++) {
1199
35.5M
      offsets[3 * i + c] = pos + c * num;
1200
35.5M
    }
1201
11.8M
    pos += 3 * num;
1202
11.8M
  }
1203
19.5M
  for (size_t i = 0; i < AcStrategy::kNumValidStrategies; i++) {
1204
75.3M
    for (size_t c = 0; c < 3; c++) {
1205
56.5M
      table_offsets_[i * 3 + c] =
1206
56.5M
          offsets[static_cast<size_t>(kAcStrategyToQuantTableMap[i]) * 3 + c];
1207
56.5M
    }
1208
18.8M
  }
1209
697k
}
1210
1211
Status DequantMatrices::EnsureComputed(JxlMemoryManager* memory_manager,
1212
30.2k
                                       uint32_t acs_mask) {
1213
30.2k
  const QuantEncoding* library = Library();
1214
1215
30.2k
  if (!table_storage_) {
1216
30.2k
    size_t table_storage_bytes = 2 * kTotalTableSize * sizeof(float);
1217
30.2k
    JXL_ASSIGN_OR_RETURN(
1218
30.2k
        table_storage_,
1219
30.2k
        AlignedMemory::Create(memory_manager, table_storage_bytes));
1220
30.2k
    table_ = table_storage_.address<float>();
1221
30.2k
    inv_table_ = table_ + kTotalTableSize;
1222
30.2k
  }
1223
1224
30.2k
  size_t offsets[kNumQuantTables * 3 + 1];
1225
30.2k
  size_t pos = 0;
1226
544k
  for (size_t i = 0; i < kNumQuantTables; i++) {
1227
514k
    size_t num_blocks =
1228
514k
        static_cast<size_t>(required_size_x[i]) * required_size_y[i];
1229
514k
    size_t num = num_blocks * kDCTBlockSize;
1230
2.05M
    for (size_t c = 0; c < 3; c++) {
1231
1.54M
      offsets[3 * i + c] = pos + c * num;
1232
1.54M
    }
1233
514k
    pos += 3 * num;
1234
514k
  }
1235
30.2k
  offsets[kNumQuantTables * 3] = pos;
1236
30.2k
  JXL_ENSURE(pos == kTotalTableSize);
1237
1238
30.2k
  uint32_t kind_mask = 0;
1239
846k
  for (size_t i = 0; i < AcStrategy::kNumValidStrategies; i++) {
1240
816k
    if (acs_mask & (1u << i)) {
1241
156k
      kind_mask |= 1u << static_cast<uint32_t>(kAcStrategyToQuantTableMap[i]);
1242
156k
    }
1243
816k
  }
1244
30.2k
  uint32_t computed_kind_mask = 0;
1245
846k
  for (size_t i = 0; i < AcStrategy::kNumValidStrategies; i++) {
1246
816k
    if (computed_mask_ & (1u << i)) {
1247
0
      computed_kind_mask |=
1248
0
          1u << static_cast<uint32_t>(kAcStrategyToQuantTableMap[i]);
1249
0
    }
1250
816k
  }
1251
542k
  for (size_t table = 0; table < kNumQuantTables; table++) {
1252
512k
    if ((1 << table) & computed_kind_mask) continue;
1253
512k
    if ((1 << table) & ~kind_mask) continue;
1254
109k
    size_t offset = offsets[table * 3];
1255
109k
    float* mutable_table = table_storage_.address<float>();
1256
109k
    if (encodings_[table].mode == QuantEncoding::kQuantModeLibrary) {
1257
109k
      JXL_RETURN_IF_ERROR(HWY_DYNAMIC_DISPATCH(ComputeQuantTable)(
1258
109k
          library[table], mutable_table, mutable_table + kTotalTableSize, table,
1259
109k
          QuantTable(table), &offset));
1260
109k
    } else {
1261
137
      JXL_RETURN_IF_ERROR(HWY_DYNAMIC_DISPATCH(ComputeQuantTable)(
1262
137
          encodings_[table], mutable_table, mutable_table + kTotalTableSize,
1263
137
          table, QuantTable(table), &offset));
1264
137
    }
1265
109k
    JXL_ENSURE(offset == offsets[table * 3 + 3]);
1266
109k
  }
1267
30.1k
  computed_mask_ |= acs_mask;
1268
1269
30.1k
  return true;
1270
30.2k
}
1271
1272
}  // namespace jxl
1273
#endif