Coverage Report

Created: 2025-07-23 08:18

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