Coverage Report

Created: 2025-12-31 07:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libjxl/lib/jxl/quant_weights.cc
Line
Count
Source
1
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
2
//
3
// Use of this source code is governed by a BSD-style
4
// license that can be found in the LICENSE file.
5
#include "lib/jxl/quant_weights.h"
6
7
#include <jxl/memory_manager.h>
8
9
#include <cmath>
10
#include <cstdint>
11
#include <cstdio>
12
#include <cstdlib>
13
#include <vector>
14
15
#include "lib/jxl/ac_strategy.h"
16
#include "lib/jxl/base/compiler_specific.h"
17
#include "lib/jxl/base/status.h"
18
#include "lib/jxl/coeff_order_fwd.h"
19
#include "lib/jxl/dct_scales.h"
20
#include "lib/jxl/dec_bit_reader.h"
21
#include "lib/jxl/dec_modular.h"
22
#include "lib/jxl/fields.h"
23
#include "lib/jxl/frame_dimensions.h"
24
#include "lib/jxl/memory_manager_internal.h"
25
26
#undef HWY_TARGET_INCLUDE
27
#define HWY_TARGET_INCLUDE "lib/jxl/quant_weights.cc"
28
#include <hwy/foreach_target.h>
29
#include <hwy/highway.h>
30
31
#include "lib/jxl/base/fast_math-inl.h"
32
33
HWY_BEFORE_NAMESPACE();
34
namespace jxl {
35
namespace HWY_NAMESPACE {
36
37
// These templates are not found via ADL.
38
using hwy::HWY_NAMESPACE::Lt;
39
using hwy::HWY_NAMESPACE::MulAdd;
40
using hwy::HWY_NAMESPACE::Sqrt;
41
42
// kQuantWeights[N * N * c + N * y + x] is the relative weight of the (x, y)
43
// coefficient in component c. Higher weights correspond to finer quantization
44
// intervals and more bits spent in encoding.
45
46
static constexpr const float kAlmostZero = 1e-8f;
47
48
void GetQuantWeightsDCT2(const QuantEncoding::DCT2Weights& dct2weights,
49
5.38k
                         float* weights) {
50
21.5k
  for (size_t c = 0; c < 3; c++) {
51
16.1k
    size_t start = c * 64;
52
16.1k
    weights[start] = 0xBAD;
53
16.1k
    weights[start + 1] = weights[start + 8] = dct2weights[c][0];
54
16.1k
    weights[start + 9] = dct2weights[c][1];
55
48.4k
    for (size_t y = 0; y < 2; y++) {
56
96.9k
      for (size_t x = 0; x < 2; x++) {
57
64.6k
        weights[start + y * 8 + x + 2] = dct2weights[c][2];
58
64.6k
        weights[start + (y + 2) * 8 + x] = dct2weights[c][2];
59
64.6k
      }
60
32.3k
    }
61
48.4k
    for (size_t y = 0; y < 2; y++) {
62
96.9k
      for (size_t x = 0; x < 2; x++) {
63
64.6k
        weights[start + (y + 2) * 8 + x + 2] = dct2weights[c][3];
64
64.6k
      }
65
32.3k
    }
66
80.7k
    for (size_t y = 0; y < 4; y++) {
67
323k
      for (size_t x = 0; x < 4; x++) {
68
258k
        weights[start + y * 8 + x + 4] = dct2weights[c][4];
69
258k
        weights[start + (y + 4) * 8 + x] = dct2weights[c][4];
70
258k
      }
71
64.6k
    }
72
80.7k
    for (size_t y = 0; y < 4; y++) {
73
323k
      for (size_t x = 0; x < 4; x++) {
74
258k
        weights[start + (y + 4) * 8 + x + 4] = dct2weights[c][5];
75
258k
      }
76
64.6k
    }
77
16.1k
  }
78
5.38k
}
Unexecuted instantiation: jxl::N_SSE4::GetQuantWeightsDCT2(std::__1::array<std::__1::array<float, 6ul>, 3ul> const&, float*)
jxl::N_AVX2::GetQuantWeightsDCT2(std::__1::array<std::__1::array<float, 6ul>, 3ul> const&, float*)
Line
Count
Source
49
5.38k
                         float* weights) {
50
21.5k
  for (size_t c = 0; c < 3; c++) {
51
16.1k
    size_t start = c * 64;
52
16.1k
    weights[start] = 0xBAD;
53
16.1k
    weights[start + 1] = weights[start + 8] = dct2weights[c][0];
54
16.1k
    weights[start + 9] = dct2weights[c][1];
55
48.4k
    for (size_t y = 0; y < 2; y++) {
56
96.9k
      for (size_t x = 0; x < 2; x++) {
57
64.6k
        weights[start + y * 8 + x + 2] = dct2weights[c][2];
58
64.6k
        weights[start + (y + 2) * 8 + x] = dct2weights[c][2];
59
64.6k
      }
60
32.3k
    }
61
48.4k
    for (size_t y = 0; y < 2; y++) {
62
96.9k
      for (size_t x = 0; x < 2; x++) {
63
64.6k
        weights[start + (y + 2) * 8 + x + 2] = dct2weights[c][3];
64
64.6k
      }
65
32.3k
    }
66
80.7k
    for (size_t y = 0; y < 4; y++) {
67
323k
      for (size_t x = 0; x < 4; x++) {
68
258k
        weights[start + y * 8 + x + 4] = dct2weights[c][4];
69
258k
        weights[start + (y + 4) * 8 + x] = dct2weights[c][4];
70
258k
      }
71
64.6k
    }
72
80.7k
    for (size_t y = 0; y < 4; y++) {
73
323k
      for (size_t x = 0; x < 4; x++) {
74
258k
        weights[start + (y + 4) * 8 + x + 4] = dct2weights[c][5];
75
258k
      }
76
64.6k
    }
77
16.1k
  }
78
5.38k
}
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
5.22k
                             float* weights) {
82
20.8k
  for (size_t c = 0; c < 3; c++) {
83
1.01M
    for (int i = 0; i < 64; i++) {
84
1.00M
      weights[64 * c + i] = idweights[c][0];
85
1.00M
    }
86
15.6k
    weights[64 * c + 1] = idweights[c][1];
87
15.6k
    weights[64 * c + 8] = idweights[c][1];
88
15.6k
    weights[64 * c + 9] = idweights[c][2];
89
15.6k
  }
90
5.22k
}
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
5.22k
                             float* weights) {
82
20.8k
  for (size_t c = 0; c < 3; c++) {
83
1.01M
    for (int i = 0; i < 64; i++) {
84
1.00M
      weights[64 * c + i] = idweights[c][0];
85
1.00M
    }
86
15.6k
    weights[64 * c + 1] = idweights[c][1];
87
15.6k
    weights[64 * c + 8] = idweights[c][1];
88
15.6k
    weights[64 * c + 9] = idweights[c][2];
89
15.6k
  }
90
5.22k
}
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
187k
                            size_t len) {
94
187k
  float scaled_pos = pos * (len - 1) / max;
95
187k
  size_t idx = scaled_pos;
96
187k
  JXL_ENSURE(idx + 1 < len);
97
187k
  float a = array[idx];
98
187k
  float b = array[idx + 1];
99
187k
  return a * FastPowf(b / a, scaled_pos - idx);
100
187k
}
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
187k
                            size_t len) {
94
187k
  float scaled_pos = pos * (len - 1) / max;
95
187k
  size_t idx = scaled_pos;
96
187k
  JXL_ENSURE(idx + 1 < len);
97
187k
  float a = array[idx];
98
187k
  float b = array[idx + 1];
99
187k
  return a * FastPowf(b / a, scaled_pos - idx);
100
187k
}
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.03M
float Mult(float v) {
103
1.03M
  if (v > 0.0f) return 1.0f + v;
104
1.03M
  return 1.0f / (1.0f - v);
105
1.03M
}
Unexecuted instantiation: jxl::N_SSE4::Mult(float)
jxl::N_AVX2::Mult(float)
Line
Count
Source
102
1.03M
float Mult(float v) {
103
1.03M
  if (v > 0.0f) return 1.0f + v;
104
1.03M
  return 1.0f / (1.0f - v);
105
1.03M
}
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
30.8M
    hwy::HWY_NAMESPACE::Vec<DF4> scaled_pos, const float* array) {
111
30.8M
  HWY_CAPPED(int32_t, 4) di;
112
113
30.8M
  auto idx = ConvertTo(di, scaled_pos);
114
115
30.8M
  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
30.8M
  auto a = GatherIndex(DF4(), array, idx);
120
30.8M
  auto b = GatherIndex(DF4(), array + 1, idx);
121
122
30.8M
  return Mul(a, FastPowf(DF4(), Div(b, a), frac));
123
30.8M
}
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
30.8M
    hwy::HWY_NAMESPACE::Vec<DF4> scaled_pos, const float* array) {
111
30.8M
  HWY_CAPPED(int32_t, 4) di;
112
113
30.8M
  auto idx = ConvertTo(di, scaled_pos);
114
115
30.8M
  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
30.8M
  auto a = GatherIndex(DF4(), array, idx);
120
30.8M
  auto b = GatherIndex(DF4(), array + 1, idx);
121
122
30.8M
  return Mul(a, FastPowf(DF4(), Div(b, a), frac));
123
30.8M
}
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
62.2k
    size_t num_bands, float* out) {
133
249k
  for (size_t c = 0; c < 3; c++) {
134
186k
    float bands[DctQuantWeightParams::kMaxDistanceBands] = {
135
186k
        distance_bands[c][0]};
136
186k
    if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
137
1.17M
    for (size_t i = 1; i < num_bands; i++) {
138
988k
      bands[i] = bands[i - 1] * Mult(distance_bands[c][i]);
139
988k
      if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
140
988k
    }
141
186k
    float scale = (num_bands - 1) / (kSqrt2 + 1e-6f);
142
186k
    float rcpcol = scale / (COLS - 1);
143
186k
    float rcprow = scale / (ROWS - 1);
144
186k
    JXL_ENSURE(COLS >= Lanes(DF4()));
145
186k
    HWY_ALIGN float l0123[4] = {0, 1, 2, 3};
146
3.17M
    for (uint32_t y = 0; y < ROWS; y++) {
147
2.98M
      float dy = y * rcprow;
148
2.98M
      float dy2 = dy * dy;
149
33.8M
      for (uint32_t x = 0; x < COLS; x += Lanes(DF4())) {
150
30.8M
        auto dx =
151
30.8M
            Mul(Add(Set(DF4(), x), Load(DF4(), l0123)), Set(DF4(), rcpcol));
152
30.8M
        auto scaled_distance = Sqrt(MulAdd(dx, dx, Set(DF4(), dy2)));
153
30.8M
        auto weight = num_bands == 1 ? Set(DF4(), bands[0])
154
30.8M
                                     : InterpolateVec(scaled_distance, bands);
155
30.8M
        StoreU(weight, DF4(), out + c * COLS * ROWS + y * COLS + x);
156
30.8M
      }
157
2.98M
    }
158
186k
  }
159
62.2k
  return true;
160
62.2k
}
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
62.2k
    size_t num_bands, float* out) {
133
249k
  for (size_t c = 0; c < 3; c++) {
134
186k
    float bands[DctQuantWeightParams::kMaxDistanceBands] = {
135
186k
        distance_bands[c][0]};
136
186k
    if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
137
1.17M
    for (size_t i = 1; i < num_bands; i++) {
138
988k
      bands[i] = bands[i - 1] * Mult(distance_bands[c][i]);
139
988k
      if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
140
988k
    }
141
186k
    float scale = (num_bands - 1) / (kSqrt2 + 1e-6f);
142
186k
    float rcpcol = scale / (COLS - 1);
143
186k
    float rcprow = scale / (ROWS - 1);
144
186k
    JXL_ENSURE(COLS >= Lanes(DF4()));
145
186k
    HWY_ALIGN float l0123[4] = {0, 1, 2, 3};
146
3.17M
    for (uint32_t y = 0; y < ROWS; y++) {
147
2.98M
      float dy = y * rcprow;
148
2.98M
      float dy2 = dy * dy;
149
33.8M
      for (uint32_t x = 0; x < COLS; x += Lanes(DF4())) {
150
30.8M
        auto dx =
151
30.8M
            Mul(Add(Set(DF4(), x), Load(DF4(), l0123)), Set(DF4(), rcpcol));
152
30.8M
        auto scaled_distance = Sqrt(MulAdd(dx, dx, Set(DF4(), dy2)));
153
30.8M
        auto weight = num_bands == 1 ? Set(DF4(), bands[0])
154
30.8M
                                     : InterpolateVec(scaled_distance, bands);
155
30.8M
        StoreU(weight, DF4(), out + c * COLS * ROWS + y * COLS + x);
156
30.8M
      }
157
2.98M
    }
158
186k
  }
159
62.2k
  return true;
160
62.2k
}
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
67.6k
                         QuantTable kind, size_t* pos) {
167
67.6k
  constexpr size_t N = kBlockDim;
168
67.6k
  size_t quant_table_idx = static_cast<size_t>(kind);
169
67.6k
  size_t wrows = 8 * DequantMatrices::required_size_x[quant_table_idx];
170
67.6k
  size_t wcols = 8 * DequantMatrices::required_size_y[quant_table_idx];
171
67.6k
  size_t num = wrows * wcols;
172
173
67.6k
  std::vector<float> weights(3 * num);
174
175
67.6k
  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
5.22k
    case QuantEncoding::kQuantModeID: {
183
5.22k
      JXL_ENSURE(num == kDCTBlockSize);
184
5.22k
      GetQuantWeightsIdentity(encoding.idweights, weights.data());
185
5.22k
      break;
186
5.22k
    }
187
5.38k
    case QuantEncoding::kQuantModeDCT2: {
188
5.38k
      JXL_ENSURE(num == kDCTBlockSize);
189
5.38k
      GetQuantWeightsDCT2(encoding.dct2weights, weights.data());
190
5.38k
      break;
191
5.38k
    }
192
4.30k
    case QuantEncoding::kQuantModeDCT4: {
193
4.30k
      JXL_ENSURE(num == kDCTBlockSize);
194
4.30k
      float weights4x4[3 * 4 * 4];
195
      // Always use 4x4 GetQuantWeights for DCT4 quantization tables.
196
4.30k
      JXL_RETURN_IF_ERROR(
197
4.30k
          GetQuantWeights(4, 4, encoding.dct_params.distance_bands,
198
4.30k
                          encoding.dct_params.num_distance_bands, weights4x4));
199
17.2k
      for (size_t c = 0; c < 3; c++) {
200
116k
        for (size_t y = 0; y < kBlockDim; y++) {
201
929k
          for (size_t x = 0; x < kBlockDim; x++) {
202
826k
            weights[c * num + y * kBlockDim + x] =
203
826k
                weights4x4[c * 16 + (y / 2) * 4 + (x / 2)];
204
826k
          }
205
103k
        }
206
12.9k
        weights[c * num + 1] /= encoding.dct4multipliers[c][0];
207
12.9k
        weights[c * num + N] /= encoding.dct4multipliers[c][0];
208
12.9k
        weights[c * num + N + 1] /= encoding.dct4multipliers[c][1];
209
12.9k
      }
210
4.30k
      break;
211
4.30k
    }
212
5.43k
    case QuantEncoding::kQuantModeDCT4X8: {
213
5.43k
      JXL_ENSURE(num == kDCTBlockSize);
214
5.43k
      float weights4x8[3 * 4 * 8];
215
      // Always use 4x8 GetQuantWeights for DCT4X8 quantization tables.
216
5.43k
      JXL_RETURN_IF_ERROR(
217
5.43k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
218
5.43k
                          encoding.dct_params.num_distance_bands, weights4x8));
219
21.7k
      for (size_t c = 0; c < 3; c++) {
220
146k
        for (size_t y = 0; y < kBlockDim; y++) {
221
1.17M
          for (size_t x = 0; x < kBlockDim; x++) {
222
1.04M
            weights[c * num + y * kBlockDim + x] =
223
1.04M
                weights4x8[c * 32 + (y / 2) * 8 + x];
224
1.04M
          }
225
130k
        }
226
16.2k
        weights[c * num + N] /= encoding.dct4x8multipliers[c];
227
16.2k
      }
228
5.43k
      break;
229
5.43k
    }
230
42.1k
    case QuantEncoding::kQuantModeDCT: {
231
42.1k
      JXL_RETURN_IF_ERROR(GetQuantWeights(
232
42.1k
          wrows, wcols, encoding.dct_params.distance_bands,
233
42.1k
          encoding.dct_params.num_distance_bands, weights.data()));
234
42.1k
      break;
235
42.1k
    }
236
42.1k
    case QuantEncoding::kQuantModeRAW: {
237
2
      if (!encoding.qraw.qtable || encoding.qraw.qtable->size() != 3 * num) {
238
0
        return JXL_FAILURE("Invalid table encoding");
239
0
      }
240
2
      int* qtable = encoding.qraw.qtable->data();
241
386
      for (size_t i = 0; i < 3 * num; i++) {
242
384
        weights[i] = 1.f / (encoding.qraw.qtable_den * qtable[i]);
243
384
      }
244
2
      break;
245
2
    }
246
5.21k
    case QuantEncoding::kQuantModeAFV: {
247
5.21k
      constexpr float kFreqs[] = {
248
5.21k
          0xBAD,
249
5.21k
          0xBAD,
250
5.21k
          0.8517778890324296,
251
5.21k
          5.37778436506804,
252
5.21k
          0xBAD,
253
5.21k
          0xBAD,
254
5.21k
          4.734747904497923,
255
5.21k
          5.449245381693219,
256
5.21k
          1.6598270267479331,
257
5.21k
          4,
258
5.21k
          7.275749096817861,
259
5.21k
          10.423227632456525,
260
5.21k
          2.662932286148962,
261
5.21k
          7.630657783650829,
262
5.21k
          8.962388608184032,
263
5.21k
          12.97166202570235,
264
5.21k
      };
265
266
5.21k
      float weights4x8[3 * 4 * 8];
267
5.21k
      JXL_RETURN_IF_ERROR((
268
5.21k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
269
5.21k
                          encoding.dct_params.num_distance_bands, weights4x8)));
270
5.21k
      float weights4x4[3 * 4 * 4];
271
5.21k
      JXL_RETURN_IF_ERROR((GetQuantWeights(
272
5.21k
          4, 4, encoding.dct_params_afv_4x4.distance_bands,
273
5.21k
          encoding.dct_params_afv_4x4.num_distance_bands, weights4x4)));
274
275
5.20k
      constexpr float lo = 0.8517778890324296;
276
5.20k
      constexpr float hi = 12.97166202570235f - lo + 1e-6f;
277
20.8k
      for (size_t c = 0; c < 3; c++) {
278
15.6k
        float bands[4];
279
15.6k
        bands[0] = encoding.afv_weights[c][5];
280
15.6k
        if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
281
62.4k
        for (size_t i = 1; i < 4; i++) {
282
46.8k
          bands[i] = bands[i - 1] * Mult(encoding.afv_weights[c][i + 5]);
283
46.8k
          if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
284
46.8k
        }
285
15.6k
        size_t start = c * 64;
286
265k
        auto set_weight = [&start, &weights](size_t x, size_t y, float val) {
287
265k
          weights[start + y * 8 + x] = val;
288
265k
        };
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
265k
        auto set_weight = [&start, &weights](size_t x, size_t y, float val) {
287
265k
          weights[start + y * 8 + x] = val;
288
265k
        };
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
15.6k
        weights[start] = 1;  // Not used, but causes MSAN error otherwise.
290
        // Weights for (0, 1) and (1, 0).
291
15.6k
        set_weight(0, 1, encoding.afv_weights[c][0]);
292
15.6k
        set_weight(1, 0, encoding.afv_weights[c][1]);
293
        // AFV special weights for 3-pixel corner.
294
15.6k
        set_weight(0, 2, encoding.afv_weights[c][2]);
295
15.6k
        set_weight(2, 0, encoding.afv_weights[c][3]);
296
15.6k
        set_weight(2, 2, encoding.afv_weights[c][4]);
297
298
        // All other AFV weights.
299
78.0k
        for (size_t y = 0; y < 4; y++) {
300
312k
          for (size_t x = 0; x < 4; x++) {
301
249k
            if (x < 2 && y < 2) continue;
302
374k
            JXL_ASSIGN_OR_RETURN(
303
374k
                float val, Interpolate(kFreqs[y * 4 + x] - lo, hi, bands, 4));
304
374k
            set_weight(2 * x, 2 * y, val);
305
374k
          }
306
62.4k
        }
307
308
        // Put 4x8 weights in odd rows, except (1, 0).
309
78.0k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
310
561k
          for (size_t x = 0; x < kBlockDim; x++) {
311
499k
            if (x == 0 && y == 0) continue;
312
483k
            weights[c * num + (2 * y + 1) * kBlockDim + x] =
313
483k
                weights4x8[c * 32 + y * 8 + x];
314
483k
          }
315
62.4k
        }
316
        // Put 4x4 weights in even rows / odd columns, except (0, 1).
317
78.0k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
318
312k
          for (size_t x = 0; x < kBlockDim / 2; x++) {
319
249k
            if (x == 0 && y == 0) continue;
320
234k
            weights[c * num + (2 * y) * kBlockDim + 2 * x + 1] =
321
234k
                weights4x4[c * 16 + y * 4 + x];
322
234k
          }
323
62.4k
        }
324
15.6k
      }
325
5.19k
      break;
326
5.20k
    }
327
67.6k
  }
328
67.6k
  size_t prev_pos = *pos;
329
67.6k
  HWY_CAPPED(float, 64) d;
330
15.9M
  for (size_t i = 0; i < num * 3; i += Lanes(d)) {
331
15.8M
    auto inv_val = LoadU(d, weights.data() + i);
332
15.8M
    if (JXL_UNLIKELY(!AllFalse(d, Ge(inv_val, Set(d, 1.0f / kAlmostZero))) ||
333
15.8M
                     !AllFalse(d, Lt(inv_val, Set(d, kAlmostZero))))) {
334
56
      return JXL_FAILURE("Invalid quantization table");
335
56
    }
336
15.8M
    auto val = Div(Set(d, 1.0f), inv_val);
337
15.8M
    StoreU(val, d, table + *pos + i);
338
15.8M
    StoreU(inv_val, d, inv_table + *pos + i);
339
15.8M
  }
340
67.5k
  (*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
67.5k
  size_t xs = DequantMatrices::required_size_x[quant_table_idx];
346
67.5k
  size_t ys = DequantMatrices::required_size_y[quant_table_idx];
347
67.5k
  CoefficientLayout(&ys, &xs);
348
270k
  for (size_t c = 0; c < 3; c++) {
349
622k
    for (size_t y = 0; y < ys; y++) {
350
2.40M
      for (size_t x = 0; x < xs; x++) {
351
1.98M
        inv_table[prev_pos + c * ys * xs * kDCTBlockSize + y * kBlockDim * xs +
352
1.98M
                  x] = 0;
353
1.98M
      }
354
419k
    }
355
202k
  }
356
67.5k
  return true;
357
67.6k
}
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
67.6k
                         QuantTable kind, size_t* pos) {
167
67.6k
  constexpr size_t N = kBlockDim;
168
67.6k
  size_t quant_table_idx = static_cast<size_t>(kind);
169
67.6k
  size_t wrows = 8 * DequantMatrices::required_size_x[quant_table_idx];
170
67.6k
  size_t wcols = 8 * DequantMatrices::required_size_y[quant_table_idx];
171
67.6k
  size_t num = wrows * wcols;
172
173
67.6k
  std::vector<float> weights(3 * num);
174
175
67.6k
  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
5.22k
    case QuantEncoding::kQuantModeID: {
183
5.22k
      JXL_ENSURE(num == kDCTBlockSize);
184
5.22k
      GetQuantWeightsIdentity(encoding.idweights, weights.data());
185
5.22k
      break;
186
5.22k
    }
187
5.38k
    case QuantEncoding::kQuantModeDCT2: {
188
5.38k
      JXL_ENSURE(num == kDCTBlockSize);
189
5.38k
      GetQuantWeightsDCT2(encoding.dct2weights, weights.data());
190
5.38k
      break;
191
5.38k
    }
192
4.30k
    case QuantEncoding::kQuantModeDCT4: {
193
4.30k
      JXL_ENSURE(num == kDCTBlockSize);
194
4.30k
      float weights4x4[3 * 4 * 4];
195
      // Always use 4x4 GetQuantWeights for DCT4 quantization tables.
196
4.30k
      JXL_RETURN_IF_ERROR(
197
4.30k
          GetQuantWeights(4, 4, encoding.dct_params.distance_bands,
198
4.30k
                          encoding.dct_params.num_distance_bands, weights4x4));
199
17.2k
      for (size_t c = 0; c < 3; c++) {
200
116k
        for (size_t y = 0; y < kBlockDim; y++) {
201
929k
          for (size_t x = 0; x < kBlockDim; x++) {
202
826k
            weights[c * num + y * kBlockDim + x] =
203
826k
                weights4x4[c * 16 + (y / 2) * 4 + (x / 2)];
204
826k
          }
205
103k
        }
206
12.9k
        weights[c * num + 1] /= encoding.dct4multipliers[c][0];
207
12.9k
        weights[c * num + N] /= encoding.dct4multipliers[c][0];
208
12.9k
        weights[c * num + N + 1] /= encoding.dct4multipliers[c][1];
209
12.9k
      }
210
4.30k
      break;
211
4.30k
    }
212
5.43k
    case QuantEncoding::kQuantModeDCT4X8: {
213
5.43k
      JXL_ENSURE(num == kDCTBlockSize);
214
5.43k
      float weights4x8[3 * 4 * 8];
215
      // Always use 4x8 GetQuantWeights for DCT4X8 quantization tables.
216
5.43k
      JXL_RETURN_IF_ERROR(
217
5.43k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
218
5.43k
                          encoding.dct_params.num_distance_bands, weights4x8));
219
21.7k
      for (size_t c = 0; c < 3; c++) {
220
146k
        for (size_t y = 0; y < kBlockDim; y++) {
221
1.17M
          for (size_t x = 0; x < kBlockDim; x++) {
222
1.04M
            weights[c * num + y * kBlockDim + x] =
223
1.04M
                weights4x8[c * 32 + (y / 2) * 8 + x];
224
1.04M
          }
225
130k
        }
226
16.2k
        weights[c * num + N] /= encoding.dct4x8multipliers[c];
227
16.2k
      }
228
5.43k
      break;
229
5.43k
    }
230
42.1k
    case QuantEncoding::kQuantModeDCT: {
231
42.1k
      JXL_RETURN_IF_ERROR(GetQuantWeights(
232
42.1k
          wrows, wcols, encoding.dct_params.distance_bands,
233
42.1k
          encoding.dct_params.num_distance_bands, weights.data()));
234
42.1k
      break;
235
42.1k
    }
236
42.1k
    case QuantEncoding::kQuantModeRAW: {
237
2
      if (!encoding.qraw.qtable || encoding.qraw.qtable->size() != 3 * num) {
238
0
        return JXL_FAILURE("Invalid table encoding");
239
0
      }
240
2
      int* qtable = encoding.qraw.qtable->data();
241
386
      for (size_t i = 0; i < 3 * num; i++) {
242
384
        weights[i] = 1.f / (encoding.qraw.qtable_den * qtable[i]);
243
384
      }
244
2
      break;
245
2
    }
246
5.21k
    case QuantEncoding::kQuantModeAFV: {
247
5.21k
      constexpr float kFreqs[] = {
248
5.21k
          0xBAD,
249
5.21k
          0xBAD,
250
5.21k
          0.8517778890324296,
251
5.21k
          5.37778436506804,
252
5.21k
          0xBAD,
253
5.21k
          0xBAD,
254
5.21k
          4.734747904497923,
255
5.21k
          5.449245381693219,
256
5.21k
          1.6598270267479331,
257
5.21k
          4,
258
5.21k
          7.275749096817861,
259
5.21k
          10.423227632456525,
260
5.21k
          2.662932286148962,
261
5.21k
          7.630657783650829,
262
5.21k
          8.962388608184032,
263
5.21k
          12.97166202570235,
264
5.21k
      };
265
266
5.21k
      float weights4x8[3 * 4 * 8];
267
5.21k
      JXL_RETURN_IF_ERROR((
268
5.21k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
269
5.21k
                          encoding.dct_params.num_distance_bands, weights4x8)));
270
5.21k
      float weights4x4[3 * 4 * 4];
271
5.21k
      JXL_RETURN_IF_ERROR((GetQuantWeights(
272
5.21k
          4, 4, encoding.dct_params_afv_4x4.distance_bands,
273
5.21k
          encoding.dct_params_afv_4x4.num_distance_bands, weights4x4)));
274
275
5.20k
      constexpr float lo = 0.8517778890324296;
276
5.20k
      constexpr float hi = 12.97166202570235f - lo + 1e-6f;
277
20.8k
      for (size_t c = 0; c < 3; c++) {
278
15.6k
        float bands[4];
279
15.6k
        bands[0] = encoding.afv_weights[c][5];
280
15.6k
        if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
281
62.4k
        for (size_t i = 1; i < 4; i++) {
282
46.8k
          bands[i] = bands[i - 1] * Mult(encoding.afv_weights[c][i + 5]);
283
46.8k
          if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
284
46.8k
        }
285
15.6k
        size_t start = c * 64;
286
15.6k
        auto set_weight = [&start, &weights](size_t x, size_t y, float val) {
287
15.6k
          weights[start + y * 8 + x] = val;
288
15.6k
        };
289
15.6k
        weights[start] = 1;  // Not used, but causes MSAN error otherwise.
290
        // Weights for (0, 1) and (1, 0).
291
15.6k
        set_weight(0, 1, encoding.afv_weights[c][0]);
292
15.6k
        set_weight(1, 0, encoding.afv_weights[c][1]);
293
        // AFV special weights for 3-pixel corner.
294
15.6k
        set_weight(0, 2, encoding.afv_weights[c][2]);
295
15.6k
        set_weight(2, 0, encoding.afv_weights[c][3]);
296
15.6k
        set_weight(2, 2, encoding.afv_weights[c][4]);
297
298
        // All other AFV weights.
299
78.0k
        for (size_t y = 0; y < 4; y++) {
300
312k
          for (size_t x = 0; x < 4; x++) {
301
249k
            if (x < 2 && y < 2) continue;
302
374k
            JXL_ASSIGN_OR_RETURN(
303
374k
                float val, Interpolate(kFreqs[y * 4 + x] - lo, hi, bands, 4));
304
374k
            set_weight(2 * x, 2 * y, val);
305
374k
          }
306
62.4k
        }
307
308
        // Put 4x8 weights in odd rows, except (1, 0).
309
78.0k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
310
561k
          for (size_t x = 0; x < kBlockDim; x++) {
311
499k
            if (x == 0 && y == 0) continue;
312
483k
            weights[c * num + (2 * y + 1) * kBlockDim + x] =
313
483k
                weights4x8[c * 32 + y * 8 + x];
314
483k
          }
315
62.4k
        }
316
        // Put 4x4 weights in even rows / odd columns, except (0, 1).
317
78.0k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
318
312k
          for (size_t x = 0; x < kBlockDim / 2; x++) {
319
249k
            if (x == 0 && y == 0) continue;
320
234k
            weights[c * num + (2 * y) * kBlockDim + 2 * x + 1] =
321
234k
                weights4x4[c * 16 + y * 4 + x];
322
234k
          }
323
62.4k
        }
324
15.6k
      }
325
5.19k
      break;
326
5.20k
    }
327
67.6k
  }
328
67.6k
  size_t prev_pos = *pos;
329
67.6k
  HWY_CAPPED(float, 64) d;
330
15.9M
  for (size_t i = 0; i < num * 3; i += Lanes(d)) {
331
15.8M
    auto inv_val = LoadU(d, weights.data() + i);
332
15.8M
    if (JXL_UNLIKELY(!AllFalse(d, Ge(inv_val, Set(d, 1.0f / kAlmostZero))) ||
333
15.8M
                     !AllFalse(d, Lt(inv_val, Set(d, kAlmostZero))))) {
334
56
      return JXL_FAILURE("Invalid quantization table");
335
56
    }
336
15.8M
    auto val = Div(Set(d, 1.0f), inv_val);
337
15.8M
    StoreU(val, d, table + *pos + i);
338
15.8M
    StoreU(inv_val, d, inv_table + *pos + i);
339
15.8M
  }
340
67.5k
  (*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
67.5k
  size_t xs = DequantMatrices::required_size_x[quant_table_idx];
346
67.5k
  size_t ys = DequantMatrices::required_size_y[quant_table_idx];
347
67.5k
  CoefficientLayout(&ys, &xs);
348
270k
  for (size_t c = 0; c < 3; c++) {
349
622k
    for (size_t y = 0; y < ys; y++) {
350
2.40M
      for (size_t x = 0; x < xs; x++) {
351
1.98M
        inv_table[prev_pos + c * ys * xs * kDCTBlockSize + y * kBlockDim * xs +
352
1.98M
                  x] = 0;
353
1.98M
      }
354
419k
    }
355
202k
  }
356
67.5k
  return true;
357
67.6k
}
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
360
Status DecodeDctParams(BitReader* br, DctQuantWeightParams* params) {
374
360
  params->num_distance_bands =
375
360
      br->ReadFixedBits<DctQuantWeightParams::kLog2MaxDistanceBands>() + 1;
376
1.14k
  for (size_t c = 0; c < 3; c++) {
377
4.21k
    for (size_t i = 0; i < params->num_distance_bands; i++) {
378
3.32k
      JXL_RETURN_IF_ERROR(F16Coder::Read(br, &params->distance_bands[c][i]));
379
3.32k
    }
380
884
    if (params->distance_bands[c][0] < kAlmostZero) {
381
98
      return JXL_FAILURE("Distance band seed is too small");
382
98
    }
383
786
    params->distance_bands[c][0] *= 64.0f;
384
786
  }
385
235
  return true;
386
360
}
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
9.50k
              ModularFrameDecoder* modular_frame_decoder) {
392
9.50k
  size_t required_size = required_size_x * required_size_y;
393
9.50k
  required_size_x *= kBlockDim;
394
9.50k
  required_size_y *= kBlockDim;
395
9.50k
  int mode = br->ReadFixedBits<kLog2NumQuantModes>();
396
9.50k
  switch (mode) {
397
8.19k
    case QuantEncoding::kQuantModeLibrary: {
398
8.19k
      encoding->predefined = br->ReadFixedBits<kCeilLog2NumPredefinedTables>();
399
8.19k
      if (encoding->predefined >= kNumPredefinedTables) {
400
0
        return JXL_FAILURE("Invalid predefined table");
401
0
      }
402
8.19k
      break;
403
8.19k
    }
404
8.19k
    case QuantEncoding::kQuantModeID: {
405
146
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
406
323
      for (size_t c = 0; c < 3; c++) {
407
947
        for (size_t i = 0; i < 3; i++) {
408
747
          JXL_RETURN_IF_ERROR(F16Coder::Read(br, &encoding->idweights[c][i]));
409
723
          if (std::abs(encoding->idweights[c][i]) < kAlmostZero) {
410
50
            return JXL_FAILURE("ID Quantizer is too small");
411
50
          }
412
673
          encoding->idweights[c][i] *= 64;
413
673
        }
414
274
      }
415
49
      break;
416
123
    }
417
149
    case QuantEncoding::kQuantModeDCT2: {
418
149
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
419
324
      for (size_t c = 0; c < 3; c++) {
420
1.58k
        for (size_t i = 0; i < 6; i++) {
421
1.39k
          JXL_RETURN_IF_ERROR(F16Coder::Read(br, &encoding->dct2weights[c][i]));
422
1.37k
          if (std::abs(encoding->dct2weights[c][i]) < kAlmostZero) {
423
64
            return JXL_FAILURE("Quantizer is too small");
424
64
          }
425
1.31k
          encoding->dct2weights[c][i] *= 64;
426
1.31k
        }
427
273
      }
428
51
      break;
429
136
    }
430
318
    case QuantEncoding::kQuantModeDCT4X8: {
431
318
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
432
792
      for (size_t c = 0; c < 3; c++) {
433
693
        JXL_RETURN_IF_ERROR(
434
693
            F16Coder::Read(br, &encoding->dct4x8multipliers[c]));
435
674
        if (std::abs(encoding->dct4x8multipliers[c]) < kAlmostZero) {
436
174
          return JXL_FAILURE("DCT4X8 multiplier is too small");
437
174
        }
438
674
      }
439
99
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
440
67
      break;
441
99
    }
442
117
    case QuantEncoding::kQuantModeDCT4: {
443
117
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
444
327
      for (size_t c = 0; c < 3; c++) {
445
734
        for (size_t i = 0; i < 2; i++) {
446
516
          JXL_RETURN_IF_ERROR(
447
516
              F16Coder::Read(br, &encoding->dct4multipliers[c][i]));
448
499
          if (std::abs(encoding->dct4multipliers[c][i]) < kAlmostZero) {
449
34
            return JXL_FAILURE("DCT4 multiplier is too small");
450
34
          }
451
499
        }
452
269
      }
453
58
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
454
45
      break;
455
58
    }
456
93
    case QuantEncoding::kQuantModeAFV: {
457
93
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
458
226
      for (size_t c = 0; c < 3; c++) {
459
1.57k
        for (size_t i = 0; i < 9; i++) {
460
1.43k
          JXL_RETURN_IF_ERROR(F16Coder::Read(br, &encoding->afv_weights[c][i]));
461
1.43k
        }
462
980
        for (size_t i = 0; i < 6; i++) {
463
840
          encoding->afv_weights[c][i] *= 64;
464
840
        }
465
140
      }
466
41
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
467
23
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params_afv_4x4));
468
20
      break;
469
23
    }
470
139
    case QuantEncoding::kQuantModeDCT: {
471
139
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
472
80
      break;
473
139
    }
474
346
    case QuantEncoding::kQuantModeRAW: {
475
      // Set mode early, to avoid mem-leak.
476
346
      encoding->mode = QuantEncoding::kQuantModeRAW;
477
346
      JXL_RETURN_IF_ERROR(ModularFrameDecoder::DecodeQuantTable(
478
346
          memory_manager, required_size_x, required_size_y, br, encoding, idx,
479
346
          modular_frame_decoder));
480
24
      break;
481
346
    }
482
24
    default:
483
0
      return JXL_FAILURE("Invalid quantization table encoding");
484
9.50k
  }
485
8.52k
  encoding->mode = static_cast<QuantEncoding::Mode>(mode);
486
8.52k
  return true;
487
9.50k
}
488
489
}  // namespace
490
491
#if JXL_CXX_LANG < JXL_CXX_17
492
constexpr const std::array<int, 17> DequantMatrices::required_size_x;
493
constexpr const std::array<int, 17> DequantMatrices::required_size_y;
494
constexpr const size_t DequantMatrices::kSumRequiredXy;
495
#endif
496
497
Status DequantMatrices::Decode(JxlMemoryManager* memory_manager, BitReader* br,
498
5.04k
                               ModularFrameDecoder* modular_frame_decoder) {
499
5.04k
  size_t all_default = br->ReadBits(1);
500
5.04k
  size_t num_tables = all_default ? 0 : static_cast<size_t>(kNumQuantTables);
501
5.04k
  encodings_.clear();
502
5.04k
  encodings_.resize(kNumQuantTables, QuantEncoding::Library<0>());
503
13.5k
  for (size_t i = 0; i < num_tables; i++) {
504
9.50k
    JXL_RETURN_IF_ERROR(jxl::Decode(memory_manager, br, &encodings_[i],
505
9.50k
                                    required_size_x[i % kNumQuantTables],
506
9.50k
                                    required_size_y[i % kNumQuantTables], i,
507
9.50k
                                    modular_frame_decoder));
508
9.50k
  }
509
4.07k
  computed_mask_ = 0;
510
4.07k
  return true;
511
5.04k
}
512
513
98.2k
Status DequantMatrices::DecodeDC(BitReader* br) {
514
98.2k
  bool all_default = static_cast<bool>(br->ReadBits(1));
515
98.2k
  if (!br->AllReadsWithinBounds()) return JXL_FAILURE("EOS during DecodeDC");
516
92.2k
  if (!all_default) {
517
85.1k
    for (size_t c = 0; c < 3; c++) {
518
64.6k
      JXL_RETURN_IF_ERROR(F16Coder::Read(br, &dc_quant_[c]));
519
63.7k
      dc_quant_[c] *= 1.0f / 128.0f;
520
      // Negative values and nearly zero are invalid values.
521
63.7k
      if (dc_quant_[c] < kAlmostZero) {
522
1.97k
        return JXL_FAILURE("Invalid dc_quant: coefficient is too small.");
523
1.97k
      }
524
61.8k
      inv_dc_quant_[c] = 1.0f / dc_quant_[c];
525
61.8k
    }
526
23.3k
  }
527
89.4k
  return true;
528
92.2k
}
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
8.30k
const QuantEncoding* DequantMatrices::Library() {
1179
8.30k
  static const DequantMatrices::DequantLibraryInternal kDequantLibrary =
1180
8.30k
      DequantMatrices::LibraryInit();
1181
  // Downcast the result to a const QuantEncoding* from QuantEncodingInternal*
1182
  // since the subclass (QuantEncoding) doesn't add any new members and users
1183
  // will need to upcast to QuantEncodingInternal to access the members of that
1184
  // class. This allows to have kDequantLibrary as a constexpr value while still
1185
  // allowing to create QuantEncoding::RAW() instances that use std::vector in
1186
  // C++11.
1187
8.30k
  return reinterpret_cast<const QuantEncoding*>(kDequantLibrary.data());
1188
8.30k
}
1189
1190
389k
DequantMatrices::DequantMatrices() {
1191
389k
  encodings_.resize(kNumQuantTables, QuantEncoding::Library<0>());
1192
389k
  size_t pos = 0;
1193
389k
  size_t offsets[kNumQuantTables * 3];
1194
7.01M
  for (size_t i = 0; i < static_cast<size_t>(kNumQuantTables); i++) {
1195
6.62M
    size_t num_blocks =
1196
6.62M
        static_cast<size_t>(required_size_x[i]) * required_size_y[i];
1197
6.62M
    size_t num = num_blocks * kDCTBlockSize;
1198
26.4M
    for (size_t c = 0; c < 3; c++) {
1199
19.8M
      offsets[3 * i + c] = pos + c * num;
1200
19.8M
    }
1201
6.62M
    pos += 3 * num;
1202
6.62M
  }
1203
10.9M
  for (size_t i = 0; i < AcStrategy::kNumValidStrategies; i++) {
1204
42.0M
    for (size_t c = 0; c < 3; c++) {
1205
31.5M
      table_offsets_[i * 3 + c] =
1206
31.5M
          offsets[static_cast<size_t>(kAcStrategyToQuantTableMap[i]) * 3 + c];
1207
31.5M
    }
1208
10.5M
  }
1209
389k
}
1210
1211
Status DequantMatrices::EnsureComputed(JxlMemoryManager* memory_manager,
1212
8.30k
                                       uint32_t acs_mask) {
1213
8.30k
  const QuantEncoding* library = Library();
1214
1215
8.30k
  if (!table_storage_) {
1216
8.30k
    size_t table_storage_bytes = 2 * kTotalTableSize * sizeof(float);
1217
8.30k
    JXL_ASSIGN_OR_RETURN(
1218
8.30k
        table_storage_,
1219
8.30k
        AlignedMemory::Create(memory_manager, table_storage_bytes));
1220
8.30k
    table_ = table_storage_.address<float>();
1221
8.30k
    inv_table_ = table_ + kTotalTableSize;
1222
8.30k
  }
1223
1224
8.30k
  size_t offsets[kNumQuantTables * 3 + 1];
1225
8.30k
  size_t pos = 0;
1226
149k
  for (size_t i = 0; i < kNumQuantTables; i++) {
1227
141k
    size_t num_blocks =
1228
141k
        static_cast<size_t>(required_size_x[i]) * required_size_y[i];
1229
141k
    size_t num = num_blocks * kDCTBlockSize;
1230
564k
    for (size_t c = 0; c < 3; c++) {
1231
423k
      offsets[3 * i + c] = pos + c * num;
1232
423k
    }
1233
141k
    pos += 3 * num;
1234
141k
  }
1235
8.30k
  offsets[kNumQuantTables * 3] = pos;
1236
8.30k
  JXL_ENSURE(pos == kTotalTableSize);
1237
1238
8.30k
  uint32_t kind_mask = 0;
1239
232k
  for (size_t i = 0; i < AcStrategy::kNumValidStrategies; i++) {
1240
224k
    if (acs_mask & (1u << i)) {
1241
106k
      kind_mask |= 1u << static_cast<uint32_t>(kAcStrategyToQuantTableMap[i]);
1242
106k
    }
1243
224k
  }
1244
8.30k
  uint32_t computed_kind_mask = 0;
1245
232k
  for (size_t i = 0; i < AcStrategy::kNumValidStrategies; i++) {
1246
224k
    if (computed_mask_ & (1u << i)) {
1247
0
      computed_kind_mask |=
1248
0
          1u << static_cast<uint32_t>(kAcStrategyToQuantTableMap[i]);
1249
0
    }
1250
224k
  }
1251
148k
  for (size_t table = 0; table < kNumQuantTables; table++) {
1252
139k
    if ((1 << table) & computed_kind_mask) continue;
1253
139k
    if ((1 << table) & ~kind_mask) continue;
1254
67.6k
    size_t offset = offsets[table * 3];
1255
67.6k
    float* mutable_table = table_storage_.address<float>();
1256
67.6k
    if (encodings_[table].mode == QuantEncoding::kQuantModeLibrary) {
1257
67.5k
      JXL_RETURN_IF_ERROR(HWY_DYNAMIC_DISPATCH(ComputeQuantTable)(
1258
67.5k
          library[table], mutable_table, mutable_table + kTotalTableSize, table,
1259
67.5k
          QuantTable(table), &offset));
1260
67.5k
    } else {
1261
102
      JXL_RETURN_IF_ERROR(HWY_DYNAMIC_DISPATCH(ComputeQuantTable)(
1262
102
          encodings_[table], mutable_table, mutable_table + kTotalTableSize,
1263
102
          table, QuantTable(table), &offset));
1264
102
    }
1265
67.5k
    JXL_ENSURE(offset == offsets[table * 3 + 3]);
1266
67.5k
  }
1267
8.22k
  computed_mask_ |= acs_mask;
1268
1269
8.22k
  return true;
1270
8.30k
}
1271
1272
}  // namespace jxl
1273
#endif