Coverage Report

Created: 2026-01-20 07:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libjxl/lib/jxl/quant_weights.cc
Line
Count
Source
1
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
2
//
3
// Use of this source code is governed by a BSD-style
4
// license that can be found in the LICENSE file.
5
#include "lib/jxl/quant_weights.h"
6
7
#include <jxl/memory_manager.h>
8
9
#include <cmath>
10
#include <cstdint>
11
#include <cstdio>
12
#include <cstdlib>
13
#include <vector>
14
15
#include "lib/jxl/ac_strategy.h"
16
#include "lib/jxl/base/compiler_specific.h"
17
#include "lib/jxl/base/status.h"
18
#include "lib/jxl/coeff_order_fwd.h"
19
#include "lib/jxl/dct_scales.h"
20
#include "lib/jxl/dec_bit_reader.h"
21
#include "lib/jxl/dec_modular.h"
22
#include "lib/jxl/fields.h"
23
#include "lib/jxl/frame_dimensions.h"
24
#include "lib/jxl/memory_manager_internal.h"
25
26
#undef HWY_TARGET_INCLUDE
27
#define HWY_TARGET_INCLUDE "lib/jxl/quant_weights.cc"
28
#include <hwy/foreach_target.h>
29
#include <hwy/highway.h>
30
31
#include "lib/jxl/base/fast_math-inl.h"
32
33
HWY_BEFORE_NAMESPACE();
34
namespace jxl {
35
namespace HWY_NAMESPACE {
36
37
// These templates are not found via ADL.
38
using hwy::HWY_NAMESPACE::Lt;
39
using hwy::HWY_NAMESPACE::MulAdd;
40
using hwy::HWY_NAMESPACE::Sqrt;
41
42
// kQuantWeights[N * N * c + N * y + x] is the relative weight of the (x, y)
43
// coefficient in component c. Higher weights correspond to finer quantization
44
// intervals and more bits spent in encoding.
45
46
static constexpr const float kAlmostZero = 1e-8f;
47
48
void GetQuantWeightsDCT2(const QuantEncoding::DCT2Weights& dct2weights,
49
5.61k
                         float* weights) {
50
22.4k
  for (size_t c = 0; c < 3; c++) {
51
16.8k
    size_t start = c * 64;
52
16.8k
    weights[start] = 0xBAD;
53
16.8k
    weights[start + 1] = weights[start + 8] = dct2weights[c][0];
54
16.8k
    weights[start + 9] = dct2weights[c][1];
55
50.5k
    for (size_t y = 0; y < 2; y++) {
56
101k
      for (size_t x = 0; x < 2; x++) {
57
67.4k
        weights[start + y * 8 + x + 2] = dct2weights[c][2];
58
67.4k
        weights[start + (y + 2) * 8 + x] = dct2weights[c][2];
59
67.4k
      }
60
33.7k
    }
61
50.5k
    for (size_t y = 0; y < 2; y++) {
62
101k
      for (size_t x = 0; x < 2; x++) {
63
67.4k
        weights[start + (y + 2) * 8 + x + 2] = dct2weights[c][3];
64
67.4k
      }
65
33.7k
    }
66
84.2k
    for (size_t y = 0; y < 4; y++) {
67
337k
      for (size_t x = 0; x < 4; x++) {
68
269k
        weights[start + y * 8 + x + 4] = dct2weights[c][4];
69
269k
        weights[start + (y + 4) * 8 + x] = dct2weights[c][4];
70
269k
      }
71
67.4k
    }
72
84.2k
    for (size_t y = 0; y < 4; y++) {
73
337k
      for (size_t x = 0; x < 4; x++) {
74
269k
        weights[start + (y + 4) * 8 + x + 4] = dct2weights[c][5];
75
269k
      }
76
67.4k
    }
77
16.8k
  }
78
5.61k
}
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.61k
                         float* weights) {
50
22.4k
  for (size_t c = 0; c < 3; c++) {
51
16.8k
    size_t start = c * 64;
52
16.8k
    weights[start] = 0xBAD;
53
16.8k
    weights[start + 1] = weights[start + 8] = dct2weights[c][0];
54
16.8k
    weights[start + 9] = dct2weights[c][1];
55
50.5k
    for (size_t y = 0; y < 2; y++) {
56
101k
      for (size_t x = 0; x < 2; x++) {
57
67.4k
        weights[start + y * 8 + x + 2] = dct2weights[c][2];
58
67.4k
        weights[start + (y + 2) * 8 + x] = dct2weights[c][2];
59
67.4k
      }
60
33.7k
    }
61
50.5k
    for (size_t y = 0; y < 2; y++) {
62
101k
      for (size_t x = 0; x < 2; x++) {
63
67.4k
        weights[start + (y + 2) * 8 + x + 2] = dct2weights[c][3];
64
67.4k
      }
65
33.7k
    }
66
84.2k
    for (size_t y = 0; y < 4; y++) {
67
337k
      for (size_t x = 0; x < 4; x++) {
68
269k
        weights[start + y * 8 + x + 4] = dct2weights[c][4];
69
269k
        weights[start + (y + 4) * 8 + x] = dct2weights[c][4];
70
269k
      }
71
67.4k
    }
72
84.2k
    for (size_t y = 0; y < 4; y++) {
73
337k
      for (size_t x = 0; x < 4; x++) {
74
269k
        weights[start + (y + 4) * 8 + x + 4] = dct2weights[c][5];
75
269k
      }
76
67.4k
    }
77
16.8k
  }
78
5.61k
}
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.47k
                             float* weights) {
82
21.9k
  for (size_t c = 0; c < 3; c++) {
83
1.06M
    for (int i = 0; i < 64; i++) {
84
1.05M
      weights[64 * c + i] = idweights[c][0];
85
1.05M
    }
86
16.4k
    weights[64 * c + 1] = idweights[c][1];
87
16.4k
    weights[64 * c + 8] = idweights[c][1];
88
16.4k
    weights[64 * c + 9] = idweights[c][2];
89
16.4k
  }
90
5.47k
}
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.47k
                             float* weights) {
82
21.9k
  for (size_t c = 0; c < 3; c++) {
83
1.06M
    for (int i = 0; i < 64; i++) {
84
1.05M
      weights[64 * c + i] = idweights[c][0];
85
1.05M
    }
86
16.4k
    weights[64 * c + 1] = idweights[c][1];
87
16.4k
    weights[64 * c + 8] = idweights[c][1];
88
16.4k
    weights[64 * c + 9] = idweights[c][2];
89
16.4k
  }
90
5.47k
}
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
195k
                            size_t len) {
94
195k
  float scaled_pos = pos * (len - 1) / max;
95
195k
  size_t idx = scaled_pos;
96
195k
  JXL_ENSURE(idx + 1 < len);
97
195k
  float a = array[idx];
98
195k
  float b = array[idx + 1];
99
195k
  return a * FastPowf(b / a, scaled_pos - idx);
100
195k
}
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
195k
                            size_t len) {
94
195k
  float scaled_pos = pos * (len - 1) / max;
95
195k
  size_t idx = scaled_pos;
96
195k
  JXL_ENSURE(idx + 1 < len);
97
195k
  float a = array[idx];
98
195k
  float b = array[idx + 1];
99
195k
  return a * FastPowf(b / a, scaled_pos - idx);
100
195k
}
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.07M
float Mult(float v) {
103
1.07M
  if (v > 0.0f) return 1.0f + v;
104
1.07M
  return 1.0f / (1.0f - v);
105
1.07M
}
Unexecuted instantiation: jxl::N_SSE4::Mult(float)
jxl::N_AVX2::Mult(float)
Line
Count
Source
102
1.07M
float Mult(float v) {
103
1.07M
  if (v > 0.0f) return 1.0f + v;
104
1.07M
  return 1.0f / (1.0f - v);
105
1.07M
}
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
32.0M
    hwy::HWY_NAMESPACE::Vec<DF4> scaled_pos, const float* array) {
111
32.0M
  HWY_CAPPED(int32_t, 4) di;
112
113
32.0M
  auto idx = ConvertTo(di, scaled_pos);
114
115
32.0M
  auto frac = Sub(scaled_pos, ConvertTo(DF4(), idx));
116
117
  // TODO(veluca): in theory, this could be done with 8 TableLookupBytes, but
118
  // it's probably slower.
119
32.0M
  auto a = GatherIndex(DF4(), array, idx);
120
32.0M
  auto b = GatherIndex(DF4(), array + 1, idx);
121
122
32.0M
  return Mul(a, FastPowf(DF4(), Div(b, a), frac));
123
32.0M
}
Unexecuted instantiation: jxl::N_SSE4::InterpolateVec(hwy::N_SSE4::Vec128<float, 4ul>, float const*)
jxl::N_AVX2::InterpolateVec(hwy::N_AVX2::Vec128<float, 4ul>, float const*)
Line
Count
Source
110
32.0M
    hwy::HWY_NAMESPACE::Vec<DF4> scaled_pos, const float* array) {
111
32.0M
  HWY_CAPPED(int32_t, 4) di;
112
113
32.0M
  auto idx = ConvertTo(di, scaled_pos);
114
115
32.0M
  auto frac = Sub(scaled_pos, ConvertTo(DF4(), idx));
116
117
  // TODO(veluca): in theory, this could be done with 8 TableLookupBytes, but
118
  // it's probably slower.
119
32.0M
  auto a = GatherIndex(DF4(), array, idx);
120
32.0M
  auto b = GatherIndex(DF4(), array + 1, idx);
121
122
32.0M
  return Mul(a, FastPowf(DF4(), Div(b, a), frac));
123
32.0M
}
Unexecuted instantiation: jxl::N_AVX3::InterpolateVec(hwy::N_AVX3::Vec128<float, 4ul>, float const*)
Unexecuted instantiation: jxl::N_AVX3_ZEN4::InterpolateVec(hwy::N_AVX3_ZEN4::Vec128<float, 4ul>, float const*)
Unexecuted instantiation: jxl::N_AVX3_SPR::InterpolateVec(hwy::N_AVX3_SPR::Vec128<float, 4ul>, float const*)
Unexecuted instantiation: jxl::N_SSE2::InterpolateVec(hwy::N_SSE2::Vec128<float, 4ul>, float const*)
124
125
// Computes quant weights for a COLS*ROWS-sized transform, using num_bands
126
// eccentricity bands and num_ebands eccentricity bands. If print_mode is 1,
127
// prints the resulting matrix; if print_mode is 2, prints the matrix in a
128
// format suitable for a 3d plot with gnuplot.
129
Status GetQuantWeights(
130
    size_t ROWS, size_t COLS,
131
    const DctQuantWeightParams::DistanceBandsArray& distance_bands,
132
64.8k
    size_t num_bands, float* out) {
133
259k
  for (size_t c = 0; c < 3; c++) {
134
194k
    float bands[DctQuantWeightParams::kMaxDistanceBands] = {
135
194k
        distance_bands[c][0]};
136
194k
    if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
137
1.22M
    for (size_t i = 1; i < num_bands; i++) {
138
1.02M
      bands[i] = bands[i - 1] * Mult(distance_bands[c][i]);
139
1.02M
      if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
140
1.02M
    }
141
194k
    float scale = (num_bands - 1) / (kSqrt2 + 1e-6f);
142
194k
    float rcpcol = scale / (COLS - 1);
143
194k
    float rcprow = scale / (ROWS - 1);
144
194k
    JXL_ENSURE(COLS >= Lanes(DF4()));
145
194k
    HWY_ALIGN float l0123[4] = {0, 1, 2, 3};
146
3.30M
    for (uint32_t y = 0; y < ROWS; y++) {
147
3.10M
      float dy = y * rcprow;
148
3.10M
      float dy2 = dy * dy;
149
35.1M
      for (uint32_t x = 0; x < COLS; x += Lanes(DF4())) {
150
32.0M
        auto dx =
151
32.0M
            Mul(Add(Set(DF4(), x), Load(DF4(), l0123)), Set(DF4(), rcpcol));
152
32.0M
        auto scaled_distance = Sqrt(MulAdd(dx, dx, Set(DF4(), dy2)));
153
32.0M
        auto weight = num_bands == 1 ? Set(DF4(), bands[0])
154
32.0M
                                     : InterpolateVec(scaled_distance, bands);
155
32.0M
        StoreU(weight, DF4(), out + c * COLS * ROWS + y * COLS + x);
156
32.0M
      }
157
3.10M
    }
158
194k
  }
159
64.8k
  return true;
160
64.8k
}
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
64.8k
    size_t num_bands, float* out) {
133
259k
  for (size_t c = 0; c < 3; c++) {
134
194k
    float bands[DctQuantWeightParams::kMaxDistanceBands] = {
135
194k
        distance_bands[c][0]};
136
194k
    if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
137
1.22M
    for (size_t i = 1; i < num_bands; i++) {
138
1.02M
      bands[i] = bands[i - 1] * Mult(distance_bands[c][i]);
139
1.02M
      if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
140
1.02M
    }
141
194k
    float scale = (num_bands - 1) / (kSqrt2 + 1e-6f);
142
194k
    float rcpcol = scale / (COLS - 1);
143
194k
    float rcprow = scale / (ROWS - 1);
144
194k
    JXL_ENSURE(COLS >= Lanes(DF4()));
145
194k
    HWY_ALIGN float l0123[4] = {0, 1, 2, 3};
146
3.30M
    for (uint32_t y = 0; y < ROWS; y++) {
147
3.10M
      float dy = y * rcprow;
148
3.10M
      float dy2 = dy * dy;
149
35.1M
      for (uint32_t x = 0; x < COLS; x += Lanes(DF4())) {
150
32.0M
        auto dx =
151
32.0M
            Mul(Add(Set(DF4(), x), Load(DF4(), l0123)), Set(DF4(), rcpcol));
152
32.0M
        auto scaled_distance = Sqrt(MulAdd(dx, dx, Set(DF4(), dy2)));
153
32.0M
        auto weight = num_bands == 1 ? Set(DF4(), bands[0])
154
32.0M
                                     : InterpolateVec(scaled_distance, bands);
155
32.0M
        StoreU(weight, DF4(), out + c * COLS * ROWS + y * COLS + x);
156
32.0M
      }
157
3.10M
    }
158
194k
  }
159
64.8k
  return true;
160
64.8k
}
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
70.4k
                         QuantTable kind, size_t* pos) {
167
70.4k
  constexpr size_t N = kBlockDim;
168
70.4k
  size_t quant_table_idx = static_cast<size_t>(kind);
169
70.4k
  size_t wrows = 8 * DequantMatrices::required_size_x[quant_table_idx];
170
70.4k
  size_t wcols = 8 * DequantMatrices::required_size_y[quant_table_idx];
171
70.4k
  size_t num = wrows * wcols;
172
173
70.4k
  std::vector<float> weights(3 * num);
174
175
70.4k
  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.47k
    case QuantEncoding::kQuantModeID: {
183
5.47k
      JXL_ENSURE(num == kDCTBlockSize);
184
5.47k
      GetQuantWeightsIdentity(encoding.idweights, weights.data());
185
5.47k
      break;
186
5.47k
    }
187
5.61k
    case QuantEncoding::kQuantModeDCT2: {
188
5.61k
      JXL_ENSURE(num == kDCTBlockSize);
189
5.61k
      GetQuantWeightsDCT2(encoding.dct2weights, weights.data());
190
5.61k
      break;
191
5.61k
    }
192
4.46k
    case QuantEncoding::kQuantModeDCT4: {
193
4.46k
      JXL_ENSURE(num == kDCTBlockSize);
194
4.46k
      float weights4x4[3 * 4 * 4];
195
      // Always use 4x4 GetQuantWeights for DCT4 quantization tables.
196
4.46k
      JXL_RETURN_IF_ERROR(
197
4.46k
          GetQuantWeights(4, 4, encoding.dct_params.distance_bands,
198
4.46k
                          encoding.dct_params.num_distance_bands, weights4x4));
199
17.8k
      for (size_t c = 0; c < 3; c++) {
200
120k
        for (size_t y = 0; y < kBlockDim; y++) {
201
964k
          for (size_t x = 0; x < kBlockDim; x++) {
202
857k
            weights[c * num + y * kBlockDim + x] =
203
857k
                weights4x4[c * 16 + (y / 2) * 4 + (x / 2)];
204
857k
          }
205
107k
        }
206
13.3k
        weights[c * num + 1] /= encoding.dct4multipliers[c][0];
207
13.3k
        weights[c * num + N] /= encoding.dct4multipliers[c][0];
208
13.3k
        weights[c * num + N + 1] /= encoding.dct4multipliers[c][1];
209
13.3k
      }
210
4.46k
      break;
211
4.46k
    }
212
5.66k
    case QuantEncoding::kQuantModeDCT4X8: {
213
5.66k
      JXL_ENSURE(num == kDCTBlockSize);
214
5.66k
      float weights4x8[3 * 4 * 8];
215
      // Always use 4x8 GetQuantWeights for DCT4X8 quantization tables.
216
5.66k
      JXL_RETURN_IF_ERROR(
217
5.66k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
218
5.66k
                          encoding.dct_params.num_distance_bands, weights4x8));
219
22.6k
      for (size_t c = 0; c < 3; c++) {
220
152k
        for (size_t y = 0; y < kBlockDim; y++) {
221
1.22M
          for (size_t x = 0; x < kBlockDim; x++) {
222
1.08M
            weights[c * num + y * kBlockDim + x] =
223
1.08M
                weights4x8[c * 32 + (y / 2) * 8 + x];
224
1.08M
          }
225
135k
        }
226
16.9k
        weights[c * num + N] /= encoding.dct4x8multipliers[c];
227
16.9k
      }
228
5.66k
      break;
229
5.66k
    }
230
43.8k
    case QuantEncoding::kQuantModeDCT: {
231
43.8k
      JXL_RETURN_IF_ERROR(GetQuantWeights(
232
43.8k
          wrows, wcols, encoding.dct_params.distance_bands,
233
43.8k
          encoding.dct_params.num_distance_bands, weights.data()));
234
43.8k
      break;
235
43.8k
    }
236
43.8k
    case QuantEncoding::kQuantModeRAW: {
237
3
      if (!encoding.qraw.qtable || encoding.qraw.qtable->size() != 3 * num) {
238
0
        return JXL_FAILURE("Invalid table encoding");
239
0
      }
240
3
      int* qtable = encoding.qraw.qtable->data();
241
579
      for (size_t i = 0; i < 3 * num; i++) {
242
576
        weights[i] = 1.f / (encoding.qraw.qtable_den * qtable[i]);
243
576
      }
244
3
      break;
245
3
    }
246
5.44k
    case QuantEncoding::kQuantModeAFV: {
247
5.44k
      constexpr float kFreqs[] = {
248
5.44k
          0xBAD,
249
5.44k
          0xBAD,
250
5.44k
          0.8517778890324296,
251
5.44k
          5.37778436506804,
252
5.44k
          0xBAD,
253
5.44k
          0xBAD,
254
5.44k
          4.734747904497923,
255
5.44k
          5.449245381693219,
256
5.44k
          1.6598270267479331,
257
5.44k
          4,
258
5.44k
          7.275749096817861,
259
5.44k
          10.423227632456525,
260
5.44k
          2.662932286148962,
261
5.44k
          7.630657783650829,
262
5.44k
          8.962388608184032,
263
5.44k
          12.97166202570235,
264
5.44k
      };
265
266
5.44k
      float weights4x8[3 * 4 * 8];
267
5.44k
      JXL_RETURN_IF_ERROR((
268
5.44k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
269
5.44k
                          encoding.dct_params.num_distance_bands, weights4x8)));
270
5.44k
      float weights4x4[3 * 4 * 4];
271
5.44k
      JXL_RETURN_IF_ERROR((GetQuantWeights(
272
5.44k
          4, 4, encoding.dct_params_afv_4x4.distance_bands,
273
5.44k
          encoding.dct_params_afv_4x4.num_distance_bands, weights4x4)));
274
275
5.44k
      constexpr float lo = 0.8517778890324296;
276
5.44k
      constexpr float hi = 12.97166202570235f - lo + 1e-6f;
277
21.7k
      for (size_t c = 0; c < 3; c++) {
278
16.3k
        float bands[4];
279
16.3k
        bands[0] = encoding.afv_weights[c][5];
280
16.3k
        if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
281
65.2k
        for (size_t i = 1; i < 4; i++) {
282
48.9k
          bands[i] = bands[i - 1] * Mult(encoding.afv_weights[c][i + 5]);
283
48.9k
          if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
284
48.9k
        }
285
16.3k
        size_t start = c * 64;
286
277k
        auto set_weight = [&start, &weights](size_t x, size_t y, float val) {
287
277k
          weights[start + y * 8 + x] = val;
288
277k
        };
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
277k
        auto set_weight = [&start, &weights](size_t x, size_t y, float val) {
287
277k
          weights[start + y * 8 + x] = val;
288
277k
        };
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
16.3k
        weights[start] = 1;  // Not used, but causes MSAN error otherwise.
290
        // Weights for (0, 1) and (1, 0).
291
16.3k
        set_weight(0, 1, encoding.afv_weights[c][0]);
292
16.3k
        set_weight(1, 0, encoding.afv_weights[c][1]);
293
        // AFV special weights for 3-pixel corner.
294
16.3k
        set_weight(0, 2, encoding.afv_weights[c][2]);
295
16.3k
        set_weight(2, 0, encoding.afv_weights[c][3]);
296
16.3k
        set_weight(2, 2, encoding.afv_weights[c][4]);
297
298
        // All other AFV weights.
299
81.5k
        for (size_t y = 0; y < 4; y++) {
300
326k
          for (size_t x = 0; x < 4; x++) {
301
260k
            if (x < 2 && y < 2) continue;
302
391k
            JXL_ASSIGN_OR_RETURN(
303
391k
                float val, Interpolate(kFreqs[y * 4 + x] - lo, hi, bands, 4));
304
391k
            set_weight(2 * x, 2 * y, val);
305
391k
          }
306
65.2k
        }
307
308
        // Put 4x8 weights in odd rows, except (1, 0).
309
81.5k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
310
586k
          for (size_t x = 0; x < kBlockDim; x++) {
311
521k
            if (x == 0 && y == 0) continue;
312
505k
            weights[c * num + (2 * y + 1) * kBlockDim + x] =
313
505k
                weights4x8[c * 32 + y * 8 + x];
314
505k
          }
315
65.2k
        }
316
        // Put 4x4 weights in even rows / odd columns, except (0, 1).
317
81.5k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
318
326k
          for (size_t x = 0; x < kBlockDim / 2; x++) {
319
260k
            if (x == 0 && y == 0) continue;
320
244k
            weights[c * num + (2 * y) * kBlockDim + 2 * x + 1] =
321
244k
                weights4x4[c * 16 + y * 4 + x];
322
244k
          }
323
65.2k
        }
324
16.3k
      }
325
5.43k
      break;
326
5.44k
    }
327
70.4k
  }
328
70.4k
  size_t prev_pos = *pos;
329
70.4k
  HWY_CAPPED(float, 64) d;
330
16.5M
  for (size_t i = 0; i < num * 3; i += Lanes(d)) {
331
16.4M
    auto inv_val = LoadU(d, weights.data() + i);
332
16.4M
    if (JXL_UNLIKELY(!AllFalse(d, Ge(inv_val, Set(d, 1.0f / kAlmostZero))) ||
333
16.4M
                     !AllFalse(d, Lt(inv_val, Set(d, kAlmostZero))))) {
334
58
      return JXL_FAILURE("Invalid quantization table");
335
58
    }
336
16.4M
    auto val = Div(Set(d, 1.0f), inv_val);
337
16.4M
    StoreU(val, d, table + *pos + i);
338
16.4M
    StoreU(inv_val, d, inv_table + *pos + i);
339
16.4M
  }
340
70.3k
  (*pos) += 3 * num;
341
342
  // Ensure that the lowest frequencies have a 0 inverse table.
343
  // This does not affect en/decoding, but allows AC strategy selection to be
344
  // slightly simpler.
345
70.3k
  size_t xs = DequantMatrices::required_size_x[quant_table_idx];
346
70.3k
  size_t ys = DequantMatrices::required_size_y[quant_table_idx];
347
70.3k
  CoefficientLayout(&ys, &xs);
348
281k
  for (size_t c = 0; c < 3; c++) {
349
647k
    for (size_t y = 0; y < ys; y++) {
350
2.49M
      for (size_t x = 0; x < xs; x++) {
351
2.06M
        inv_table[prev_pos + c * ys * xs * kDCTBlockSize + y * kBlockDim * xs +
352
2.06M
                  x] = 0;
353
2.06M
      }
354
436k
    }
355
211k
  }
356
70.3k
  return true;
357
70.4k
}
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
70.4k
                         QuantTable kind, size_t* pos) {
167
70.4k
  constexpr size_t N = kBlockDim;
168
70.4k
  size_t quant_table_idx = static_cast<size_t>(kind);
169
70.4k
  size_t wrows = 8 * DequantMatrices::required_size_x[quant_table_idx];
170
70.4k
  size_t wcols = 8 * DequantMatrices::required_size_y[quant_table_idx];
171
70.4k
  size_t num = wrows * wcols;
172
173
70.4k
  std::vector<float> weights(3 * num);
174
175
70.4k
  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.47k
    case QuantEncoding::kQuantModeID: {
183
5.47k
      JXL_ENSURE(num == kDCTBlockSize);
184
5.47k
      GetQuantWeightsIdentity(encoding.idweights, weights.data());
185
5.47k
      break;
186
5.47k
    }
187
5.61k
    case QuantEncoding::kQuantModeDCT2: {
188
5.61k
      JXL_ENSURE(num == kDCTBlockSize);
189
5.61k
      GetQuantWeightsDCT2(encoding.dct2weights, weights.data());
190
5.61k
      break;
191
5.61k
    }
192
4.46k
    case QuantEncoding::kQuantModeDCT4: {
193
4.46k
      JXL_ENSURE(num == kDCTBlockSize);
194
4.46k
      float weights4x4[3 * 4 * 4];
195
      // Always use 4x4 GetQuantWeights for DCT4 quantization tables.
196
4.46k
      JXL_RETURN_IF_ERROR(
197
4.46k
          GetQuantWeights(4, 4, encoding.dct_params.distance_bands,
198
4.46k
                          encoding.dct_params.num_distance_bands, weights4x4));
199
17.8k
      for (size_t c = 0; c < 3; c++) {
200
120k
        for (size_t y = 0; y < kBlockDim; y++) {
201
964k
          for (size_t x = 0; x < kBlockDim; x++) {
202
857k
            weights[c * num + y * kBlockDim + x] =
203
857k
                weights4x4[c * 16 + (y / 2) * 4 + (x / 2)];
204
857k
          }
205
107k
        }
206
13.3k
        weights[c * num + 1] /= encoding.dct4multipliers[c][0];
207
13.3k
        weights[c * num + N] /= encoding.dct4multipliers[c][0];
208
13.3k
        weights[c * num + N + 1] /= encoding.dct4multipliers[c][1];
209
13.3k
      }
210
4.46k
      break;
211
4.46k
    }
212
5.66k
    case QuantEncoding::kQuantModeDCT4X8: {
213
5.66k
      JXL_ENSURE(num == kDCTBlockSize);
214
5.66k
      float weights4x8[3 * 4 * 8];
215
      // Always use 4x8 GetQuantWeights for DCT4X8 quantization tables.
216
5.66k
      JXL_RETURN_IF_ERROR(
217
5.66k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
218
5.66k
                          encoding.dct_params.num_distance_bands, weights4x8));
219
22.6k
      for (size_t c = 0; c < 3; c++) {
220
152k
        for (size_t y = 0; y < kBlockDim; y++) {
221
1.22M
          for (size_t x = 0; x < kBlockDim; x++) {
222
1.08M
            weights[c * num + y * kBlockDim + x] =
223
1.08M
                weights4x8[c * 32 + (y / 2) * 8 + x];
224
1.08M
          }
225
135k
        }
226
16.9k
        weights[c * num + N] /= encoding.dct4x8multipliers[c];
227
16.9k
      }
228
5.66k
      break;
229
5.66k
    }
230
43.8k
    case QuantEncoding::kQuantModeDCT: {
231
43.8k
      JXL_RETURN_IF_ERROR(GetQuantWeights(
232
43.8k
          wrows, wcols, encoding.dct_params.distance_bands,
233
43.8k
          encoding.dct_params.num_distance_bands, weights.data()));
234
43.8k
      break;
235
43.8k
    }
236
43.8k
    case QuantEncoding::kQuantModeRAW: {
237
3
      if (!encoding.qraw.qtable || encoding.qraw.qtable->size() != 3 * num) {
238
0
        return JXL_FAILURE("Invalid table encoding");
239
0
      }
240
3
      int* qtable = encoding.qraw.qtable->data();
241
579
      for (size_t i = 0; i < 3 * num; i++) {
242
576
        weights[i] = 1.f / (encoding.qraw.qtable_den * qtable[i]);
243
576
      }
244
3
      break;
245
3
    }
246
5.44k
    case QuantEncoding::kQuantModeAFV: {
247
5.44k
      constexpr float kFreqs[] = {
248
5.44k
          0xBAD,
249
5.44k
          0xBAD,
250
5.44k
          0.8517778890324296,
251
5.44k
          5.37778436506804,
252
5.44k
          0xBAD,
253
5.44k
          0xBAD,
254
5.44k
          4.734747904497923,
255
5.44k
          5.449245381693219,
256
5.44k
          1.6598270267479331,
257
5.44k
          4,
258
5.44k
          7.275749096817861,
259
5.44k
          10.423227632456525,
260
5.44k
          2.662932286148962,
261
5.44k
          7.630657783650829,
262
5.44k
          8.962388608184032,
263
5.44k
          12.97166202570235,
264
5.44k
      };
265
266
5.44k
      float weights4x8[3 * 4 * 8];
267
5.44k
      JXL_RETURN_IF_ERROR((
268
5.44k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
269
5.44k
                          encoding.dct_params.num_distance_bands, weights4x8)));
270
5.44k
      float weights4x4[3 * 4 * 4];
271
5.44k
      JXL_RETURN_IF_ERROR((GetQuantWeights(
272
5.44k
          4, 4, encoding.dct_params_afv_4x4.distance_bands,
273
5.44k
          encoding.dct_params_afv_4x4.num_distance_bands, weights4x4)));
274
275
5.44k
      constexpr float lo = 0.8517778890324296;
276
5.44k
      constexpr float hi = 12.97166202570235f - lo + 1e-6f;
277
21.7k
      for (size_t c = 0; c < 3; c++) {
278
16.3k
        float bands[4];
279
16.3k
        bands[0] = encoding.afv_weights[c][5];
280
16.3k
        if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
281
65.2k
        for (size_t i = 1; i < 4; i++) {
282
48.9k
          bands[i] = bands[i - 1] * Mult(encoding.afv_weights[c][i + 5]);
283
48.9k
          if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
284
48.9k
        }
285
16.3k
        size_t start = c * 64;
286
16.3k
        auto set_weight = [&start, &weights](size_t x, size_t y, float val) {
287
16.3k
          weights[start + y * 8 + x] = val;
288
16.3k
        };
289
16.3k
        weights[start] = 1;  // Not used, but causes MSAN error otherwise.
290
        // Weights for (0, 1) and (1, 0).
291
16.3k
        set_weight(0, 1, encoding.afv_weights[c][0]);
292
16.3k
        set_weight(1, 0, encoding.afv_weights[c][1]);
293
        // AFV special weights for 3-pixel corner.
294
16.3k
        set_weight(0, 2, encoding.afv_weights[c][2]);
295
16.3k
        set_weight(2, 0, encoding.afv_weights[c][3]);
296
16.3k
        set_weight(2, 2, encoding.afv_weights[c][4]);
297
298
        // All other AFV weights.
299
81.5k
        for (size_t y = 0; y < 4; y++) {
300
326k
          for (size_t x = 0; x < 4; x++) {
301
260k
            if (x < 2 && y < 2) continue;
302
391k
            JXL_ASSIGN_OR_RETURN(
303
391k
                float val, Interpolate(kFreqs[y * 4 + x] - lo, hi, bands, 4));
304
391k
            set_weight(2 * x, 2 * y, val);
305
391k
          }
306
65.2k
        }
307
308
        // Put 4x8 weights in odd rows, except (1, 0).
309
81.5k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
310
586k
          for (size_t x = 0; x < kBlockDim; x++) {
311
521k
            if (x == 0 && y == 0) continue;
312
505k
            weights[c * num + (2 * y + 1) * kBlockDim + x] =
313
505k
                weights4x8[c * 32 + y * 8 + x];
314
505k
          }
315
65.2k
        }
316
        // Put 4x4 weights in even rows / odd columns, except (0, 1).
317
81.5k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
318
326k
          for (size_t x = 0; x < kBlockDim / 2; x++) {
319
260k
            if (x == 0 && y == 0) continue;
320
244k
            weights[c * num + (2 * y) * kBlockDim + 2 * x + 1] =
321
244k
                weights4x4[c * 16 + y * 4 + x];
322
244k
          }
323
65.2k
        }
324
16.3k
      }
325
5.43k
      break;
326
5.44k
    }
327
70.4k
  }
328
70.4k
  size_t prev_pos = *pos;
329
70.4k
  HWY_CAPPED(float, 64) d;
330
16.5M
  for (size_t i = 0; i < num * 3; i += Lanes(d)) {
331
16.4M
    auto inv_val = LoadU(d, weights.data() + i);
332
16.4M
    if (JXL_UNLIKELY(!AllFalse(d, Ge(inv_val, Set(d, 1.0f / kAlmostZero))) ||
333
16.4M
                     !AllFalse(d, Lt(inv_val, Set(d, kAlmostZero))))) {
334
58
      return JXL_FAILURE("Invalid quantization table");
335
58
    }
336
16.4M
    auto val = Div(Set(d, 1.0f), inv_val);
337
16.4M
    StoreU(val, d, table + *pos + i);
338
16.4M
    StoreU(inv_val, d, inv_table + *pos + i);
339
16.4M
  }
340
70.3k
  (*pos) += 3 * num;
341
342
  // Ensure that the lowest frequencies have a 0 inverse table.
343
  // This does not affect en/decoding, but allows AC strategy selection to be
344
  // slightly simpler.
345
70.3k
  size_t xs = DequantMatrices::required_size_x[quant_table_idx];
346
70.3k
  size_t ys = DequantMatrices::required_size_y[quant_table_idx];
347
70.3k
  CoefficientLayout(&ys, &xs);
348
281k
  for (size_t c = 0; c < 3; c++) {
349
647k
    for (size_t y = 0; y < ys; y++) {
350
2.49M
      for (size_t x = 0; x < xs; x++) {
351
2.06M
        inv_table[prev_pos + c * ys * xs * kDCTBlockSize + y * kBlockDim * xs +
352
2.06M
                  x] = 0;
353
2.06M
      }
354
436k
    }
355
211k
  }
356
70.3k
  return true;
357
70.4k
}
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
365
Status DecodeDctParams(BitReader* br, DctQuantWeightParams* params) {
374
365
  params->num_distance_bands =
375
365
      br->ReadFixedBits<DctQuantWeightParams::kLog2MaxDistanceBands>() + 1;
376
1.17k
  for (size_t c = 0; c < 3; c++) {
377
4.24k
    for (size_t i = 0; i < params->num_distance_bands; i++) {
378
3.34k
      JXL_RETURN_IF_ERROR(F16Coder::Read(br, &params->distance_bands[c][i]));
379
3.34k
    }
380
901
    if (params->distance_bands[c][0] < kAlmostZero) {
381
96
      return JXL_FAILURE("Distance band seed is too small");
382
96
    }
383
805
    params->distance_bands[c][0] *= 64.0f;
384
805
  }
385
243
  return true;
386
365
}
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
10.1k
              ModularFrameDecoder* modular_frame_decoder) {
392
10.1k
  size_t required_size = required_size_x * required_size_y;
393
10.1k
  required_size_x *= kBlockDim;
394
10.1k
  required_size_y *= kBlockDim;
395
10.1k
  int mode = br->ReadFixedBits<kLog2NumQuantModes>();
396
10.1k
  switch (mode) {
397
8.75k
    case QuantEncoding::kQuantModeLibrary: {
398
8.75k
      encoding->predefined = br->ReadFixedBits<kCeilLog2NumPredefinedTables>();
399
8.75k
      if (encoding->predefined >= kNumPredefinedTables) {
400
0
        return JXL_FAILURE("Invalid predefined table");
401
0
      }
402
8.75k
      break;
403
8.75k
    }
404
8.75k
    case QuantEncoding::kQuantModeID: {
405
155
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
406
331
      for (size_t c = 0; c < 3; c++) {
407
957
        for (size_t i = 0; i < 3; i++) {
408
755
          JXL_RETURN_IF_ERROR(F16Coder::Read(br, &encoding->idweights[c][i]));
409
730
          if (std::abs(encoding->idweights[c][i]) < kAlmostZero) {
410
54
            return JXL_FAILURE("ID Quantizer is too small");
411
54
          }
412
676
          encoding->idweights[c][i] *= 64;
413
676
        }
414
281
      }
415
50
      break;
416
129
    }
417
153
    case QuantEncoding::kQuantModeDCT2: {
418
153
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
419
330
      for (size_t c = 0; c < 3; c++) {
420
1.61k
        for (size_t i = 0; i < 6; i++) {
421
1.42k
          JXL_RETURN_IF_ERROR(F16Coder::Read(br, &encoding->dct2weights[c][i]));
422
1.39k
          if (std::abs(encoding->dct2weights[c][i]) < kAlmostZero) {
423
63
            return JXL_FAILURE("Quantizer is too small");
424
63
          }
425
1.33k
          encoding->dct2weights[c][i] *= 64;
426
1.33k
        }
427
279
      }
428
51
      break;
429
140
    }
430
343
    case QuantEncoding::kQuantModeDCT4X8: {
431
343
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
432
841
      for (size_t c = 0; c < 3; c++) {
433
744
        JXL_RETURN_IF_ERROR(
434
744
            F16Coder::Read(br, &encoding->dct4x8multipliers[c]));
435
725
        if (std::abs(encoding->dct4x8multipliers[c]) < kAlmostZero) {
436
203
          return JXL_FAILURE("DCT4X8 multiplier is too small");
437
203
        }
438
725
      }
439
97
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
440
67
      break;
441
97
    }
442
124
    case QuantEncoding::kQuantModeDCT4: {
443
124
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
444
337
      for (size_t c = 0; c < 3; c++) {
445
755
        for (size_t i = 0; i < 2; i++) {
446
531
          JXL_RETURN_IF_ERROR(
447
531
              F16Coder::Read(br, &encoding->dct4multipliers[c][i]));
448
512
          if (std::abs(encoding->dct4multipliers[c][i]) < kAlmostZero) {
449
35
            return JXL_FAILURE("DCT4 multiplier is too small");
450
35
          }
451
512
        }
452
278
      }
453
59
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
454
47
      break;
455
59
    }
456
95
    case QuantEncoding::kQuantModeAFV: {
457
95
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
458
236
      for (size_t c = 0; c < 3; c++) {
459
1.65k
        for (size_t i = 0; i < 9; i++) {
460
1.50k
          JXL_RETURN_IF_ERROR(F16Coder::Read(br, &encoding->afv_weights[c][i]));
461
1.50k
        }
462
1.03k
        for (size_t i = 0; i < 6; i++) {
463
888
          encoding->afv_weights[c][i] *= 64;
464
888
        }
465
148
      }
466
43
      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
143
    case QuantEncoding::kQuantModeDCT: {
471
143
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
472
86
      break;
473
143
    }
474
371
    case QuantEncoding::kQuantModeRAW: {
475
      // Set mode early, to avoid mem-leak.
476
371
      encoding->mode = QuantEncoding::kQuantModeRAW;
477
371
      JXL_RETURN_IF_ERROR(ModularFrameDecoder::DecodeQuantTable(
478
371
          memory_manager, required_size_x, required_size_y, br, encoding, idx,
479
371
          modular_frame_decoder));
480
27
      break;
481
371
    }
482
27
    default:
483
0
      return JXL_FAILURE("Invalid quantization table encoding");
484
10.1k
  }
485
9.10k
  encoding->mode = static_cast<QuantEncoding::Mode>(mode);
486
9.10k
  return true;
487
10.1k
}
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.29k
                               ModularFrameDecoder* modular_frame_decoder) {
499
5.29k
  size_t all_default = br->ReadBits(1);
500
5.29k
  size_t num_tables = all_default ? 0 : static_cast<size_t>(kNumQuantTables);
501
5.29k
  encodings_.clear();
502
5.29k
  encodings_.resize(kNumQuantTables, QuantEncoding::Library<0>());
503
14.3k
  for (size_t i = 0; i < num_tables; i++) {
504
10.1k
    JXL_RETURN_IF_ERROR(jxl::Decode(memory_manager, br, &encodings_[i],
505
10.1k
                                    required_size_x[i % kNumQuantTables],
506
10.1k
                                    required_size_y[i % kNumQuantTables], i,
507
10.1k
                                    modular_frame_decoder));
508
10.1k
  }
509
4.25k
  computed_mask_ = 0;
510
4.25k
  return true;
511
5.29k
}
512
513
106k
Status DequantMatrices::DecodeDC(BitReader* br) {
514
106k
  bool all_default = static_cast<bool>(br->ReadBits(1));
515
106k
  if (!br->AllReadsWithinBounds()) return JXL_FAILURE("EOS during DecodeDC");
516
100k
  if (!all_default) {
517
87.8k
    for (size_t c = 0; c < 3; c++) {
518
66.6k
      JXL_RETURN_IF_ERROR(F16Coder::Read(br, &dc_quant_[c]));
519
65.8k
      dc_quant_[c] *= 1.0f / 128.0f;
520
      // Negative values and nearly zero are invalid values.
521
65.8k
      if (dc_quant_[c] < kAlmostZero) {
522
2.14k
        return JXL_FAILURE("Invalid dc_quant: coefficient is too small.");
523
2.14k
      }
524
63.6k
      inv_dc_quant_[c] = 1.0f / dc_quant_[c];
525
63.6k
    }
526
24.1k
  }
527
97.2k
  return true;
528
100k
}
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.64k
const QuantEncoding* DequantMatrices::Library() {
1179
8.64k
  static const DequantMatrices::DequantLibraryInternal kDequantLibrary =
1180
8.64k
      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.64k
  return reinterpret_cast<const QuantEncoding*>(kDequantLibrary.data());
1188
8.64k
}
1189
1190
419k
DequantMatrices::DequantMatrices() {
1191
419k
  encodings_.resize(kNumQuantTables, QuantEncoding::Library<0>());
1192
419k
  size_t pos = 0;
1193
419k
  size_t offsets[kNumQuantTables * 3];
1194
7.55M
  for (size_t i = 0; i < static_cast<size_t>(kNumQuantTables); i++) {
1195
7.13M
    size_t num_blocks =
1196
7.13M
        static_cast<size_t>(required_size_x[i]) * required_size_y[i];
1197
7.13M
    size_t num = num_blocks * kDCTBlockSize;
1198
28.5M
    for (size_t c = 0; c < 3; c++) {
1199
21.4M
      offsets[3 * i + c] = pos + c * num;
1200
21.4M
    }
1201
7.13M
    pos += 3 * num;
1202
7.13M
  }
1203
11.7M
  for (size_t i = 0; i < AcStrategy::kNumValidStrategies; i++) {
1204
45.3M
    for (size_t c = 0; c < 3; c++) {
1205
34.0M
      table_offsets_[i * 3 + c] =
1206
34.0M
          offsets[static_cast<size_t>(kAcStrategyToQuantTableMap[i]) * 3 + c];
1207
34.0M
    }
1208
11.3M
  }
1209
419k
}
1210
1211
Status DequantMatrices::EnsureComputed(JxlMemoryManager* memory_manager,
1212
8.64k
                                       uint32_t acs_mask) {
1213
8.64k
  const QuantEncoding* library = Library();
1214
1215
8.64k
  if (!table_storage_) {
1216
8.64k
    size_t table_storage_bytes = 2 * kTotalTableSize * sizeof(float);
1217
8.64k
    JXL_ASSIGN_OR_RETURN(
1218
8.64k
        table_storage_,
1219
8.64k
        AlignedMemory::Create(memory_manager, table_storage_bytes));
1220
8.64k
    table_ = table_storage_.address<float>();
1221
8.64k
    inv_table_ = table_ + kTotalTableSize;
1222
8.64k
  }
1223
1224
8.64k
  size_t offsets[kNumQuantTables * 3 + 1];
1225
8.64k
  size_t pos = 0;
1226
155k
  for (size_t i = 0; i < kNumQuantTables; i++) {
1227
146k
    size_t num_blocks =
1228
146k
        static_cast<size_t>(required_size_x[i]) * required_size_y[i];
1229
146k
    size_t num = num_blocks * kDCTBlockSize;
1230
587k
    for (size_t c = 0; c < 3; c++) {
1231
440k
      offsets[3 * i + c] = pos + c * num;
1232
440k
    }
1233
146k
    pos += 3 * num;
1234
146k
  }
1235
8.64k
  offsets[kNumQuantTables * 3] = pos;
1236
8.64k
  JXL_ENSURE(pos == kTotalTableSize);
1237
1238
8.64k
  uint32_t kind_mask = 0;
1239
241k
  for (size_t i = 0; i < AcStrategy::kNumValidStrategies; i++) {
1240
233k
    if (acs_mask & (1u << i)) {
1241
110k
      kind_mask |= 1u << static_cast<uint32_t>(kAcStrategyToQuantTableMap[i]);
1242
110k
    }
1243
233k
  }
1244
8.64k
  uint32_t computed_kind_mask = 0;
1245
241k
  for (size_t i = 0; i < AcStrategy::kNumValidStrategies; i++) {
1246
233k
    if (computed_mask_ & (1u << i)) {
1247
0
      computed_kind_mask |=
1248
0
          1u << static_cast<uint32_t>(kAcStrategyToQuantTableMap[i]);
1249
0
    }
1250
233k
  }
1251
154k
  for (size_t table = 0; table < kNumQuantTables; table++) {
1252
145k
    if ((1 << table) & computed_kind_mask) continue;
1253
145k
    if ((1 << table) & ~kind_mask) continue;
1254
70.4k
    size_t offset = offsets[table * 3];
1255
70.4k
    float* mutable_table = table_storage_.address<float>();
1256
70.4k
    if (encodings_[table].mode == QuantEncoding::kQuantModeLibrary) {
1257
70.3k
      JXL_RETURN_IF_ERROR(HWY_DYNAMIC_DISPATCH(ComputeQuantTable)(
1258
70.3k
          library[table], mutable_table, mutable_table + kTotalTableSize, table,
1259
70.3k
          QuantTable(table), &offset));
1260
70.3k
    } else {
1261
111
      JXL_RETURN_IF_ERROR(HWY_DYNAMIC_DISPATCH(ComputeQuantTable)(
1262
111
          encodings_[table], mutable_table, mutable_table + kTotalTableSize,
1263
111
          table, QuantTable(table), &offset));
1264
111
    }
1265
70.3k
    JXL_ENSURE(offset == offsets[table * 3 + 3]);
1266
70.3k
  }
1267
8.55k
  computed_mask_ |= acs_mask;
1268
1269
8.55k
  return true;
1270
8.64k
}
1271
1272
}  // namespace jxl
1273
#endif