Coverage Report

Created: 2025-12-03 07:28

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
4.67k
                         float* weights) {
50
18.7k
  for (size_t c = 0; c < 3; c++) {
51
14.0k
    size_t start = c * 64;
52
14.0k
    weights[start] = 0xBAD;
53
14.0k
    weights[start + 1] = weights[start + 8] = dct2weights[c][0];
54
14.0k
    weights[start + 9] = dct2weights[c][1];
55
42.0k
    for (size_t y = 0; y < 2; y++) {
56
84.1k
      for (size_t x = 0; x < 2; x++) {
57
56.1k
        weights[start + y * 8 + x + 2] = dct2weights[c][2];
58
56.1k
        weights[start + (y + 2) * 8 + x] = dct2weights[c][2];
59
56.1k
      }
60
28.0k
    }
61
42.0k
    for (size_t y = 0; y < 2; y++) {
62
84.1k
      for (size_t x = 0; x < 2; x++) {
63
56.1k
        weights[start + (y + 2) * 8 + x + 2] = dct2weights[c][3];
64
56.1k
      }
65
28.0k
    }
66
70.1k
    for (size_t y = 0; y < 4; y++) {
67
280k
      for (size_t x = 0; x < 4; x++) {
68
224k
        weights[start + y * 8 + x + 4] = dct2weights[c][4];
69
224k
        weights[start + (y + 4) * 8 + x] = dct2weights[c][4];
70
224k
      }
71
56.1k
    }
72
70.1k
    for (size_t y = 0; y < 4; y++) {
73
280k
      for (size_t x = 0; x < 4; x++) {
74
224k
        weights[start + (y + 4) * 8 + x + 4] = dct2weights[c][5];
75
224k
      }
76
56.1k
    }
77
14.0k
  }
78
4.67k
}
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
4.67k
                         float* weights) {
50
18.7k
  for (size_t c = 0; c < 3; c++) {
51
14.0k
    size_t start = c * 64;
52
14.0k
    weights[start] = 0xBAD;
53
14.0k
    weights[start + 1] = weights[start + 8] = dct2weights[c][0];
54
14.0k
    weights[start + 9] = dct2weights[c][1];
55
42.0k
    for (size_t y = 0; y < 2; y++) {
56
84.1k
      for (size_t x = 0; x < 2; x++) {
57
56.1k
        weights[start + y * 8 + x + 2] = dct2weights[c][2];
58
56.1k
        weights[start + (y + 2) * 8 + x] = dct2weights[c][2];
59
56.1k
      }
60
28.0k
    }
61
42.0k
    for (size_t y = 0; y < 2; y++) {
62
84.1k
      for (size_t x = 0; x < 2; x++) {
63
56.1k
        weights[start + (y + 2) * 8 + x + 2] = dct2weights[c][3];
64
56.1k
      }
65
28.0k
    }
66
70.1k
    for (size_t y = 0; y < 4; y++) {
67
280k
      for (size_t x = 0; x < 4; x++) {
68
224k
        weights[start + y * 8 + x + 4] = dct2weights[c][4];
69
224k
        weights[start + (y + 4) * 8 + x] = dct2weights[c][4];
70
224k
      }
71
56.1k
    }
72
70.1k
    for (size_t y = 0; y < 4; y++) {
73
280k
      for (size_t x = 0; x < 4; x++) {
74
224k
        weights[start + (y + 4) * 8 + x + 4] = dct2weights[c][5];
75
224k
      }
76
56.1k
    }
77
14.0k
  }
78
4.67k
}
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
4.53k
                             float* weights) {
82
18.1k
  for (size_t c = 0; c < 3; c++) {
83
883k
    for (int i = 0; i < 64; i++) {
84
869k
      weights[64 * c + i] = idweights[c][0];
85
869k
    }
86
13.5k
    weights[64 * c + 1] = idweights[c][1];
87
13.5k
    weights[64 * c + 8] = idweights[c][1];
88
13.5k
    weights[64 * c + 9] = idweights[c][2];
89
13.5k
  }
90
4.53k
}
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
4.53k
                             float* weights) {
82
18.1k
  for (size_t c = 0; c < 3; c++) {
83
883k
    for (int i = 0; i < 64; i++) {
84
869k
      weights[64 * c + i] = idweights[c][0];
85
869k
    }
86
13.5k
    weights[64 * c + 1] = idweights[c][1];
87
13.5k
    weights[64 * c + 8] = idweights[c][1];
88
13.5k
    weights[64 * c + 9] = idweights[c][2];
89
13.5k
  }
90
4.53k
}
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
162k
                            size_t len) {
94
162k
  float scaled_pos = pos * (len - 1) / max;
95
162k
  size_t idx = scaled_pos;
96
162k
  JXL_ENSURE(idx + 1 < len);
97
162k
  float a = array[idx];
98
162k
  float b = array[idx + 1];
99
162k
  return a * FastPowf(b / a, scaled_pos - idx);
100
162k
}
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
162k
                            size_t len) {
94
162k
  float scaled_pos = pos * (len - 1) / max;
95
162k
  size_t idx = scaled_pos;
96
162k
  JXL_ENSURE(idx + 1 < len);
97
162k
  float a = array[idx];
98
162k
  float b = array[idx + 1];
99
162k
  return a * FastPowf(b / a, scaled_pos - idx);
100
162k
}
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
898k
float Mult(float v) {
103
898k
  if (v > 0.0f) return 1.0f + v;
104
898k
  return 1.0f / (1.0f - v);
105
898k
}
Unexecuted instantiation: jxl::N_SSE4::Mult(float)
jxl::N_AVX2::Mult(float)
Line
Count
Source
102
898k
float Mult(float v) {
103
898k
  if (v > 0.0f) return 1.0f + v;
104
898k
  return 1.0f / (1.0f - v);
105
898k
}
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
26.7M
    hwy::HWY_NAMESPACE::Vec<DF4> scaled_pos, const float* array) {
111
26.7M
  HWY_CAPPED(int32_t, 4) di;
112
113
26.7M
  auto idx = ConvertTo(di, scaled_pos);
114
115
26.7M
  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
26.7M
  auto a = GatherIndex(DF4(), array, idx);
120
26.7M
  auto b = GatherIndex(DF4(), array + 1, idx);
121
122
26.7M
  return Mul(a, FastPowf(DF4(), Div(b, a), frac));
123
26.7M
}
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
26.7M
    hwy::HWY_NAMESPACE::Vec<DF4> scaled_pos, const float* array) {
111
26.7M
  HWY_CAPPED(int32_t, 4) di;
112
113
26.7M
  auto idx = ConvertTo(di, scaled_pos);
114
115
26.7M
  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
26.7M
  auto a = GatherIndex(DF4(), array, idx);
120
26.7M
  auto b = GatherIndex(DF4(), array + 1, idx);
121
122
26.7M
  return Mul(a, FastPowf(DF4(), Div(b, a), frac));
123
26.7M
}
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
54.1k
    size_t num_bands, float* out) {
133
216k
  for (size_t c = 0; c < 3; c++) {
134
162k
    float bands[DctQuantWeightParams::kMaxDistanceBands] = {
135
162k
        distance_bands[c][0]};
136
162k
    if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
137
1.02M
    for (size_t i = 1; i < num_bands; i++) {
138
858k
      bands[i] = bands[i - 1] * Mult(distance_bands[c][i]);
139
858k
      if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
140
858k
    }
141
162k
    float scale = (num_bands - 1) / (kSqrt2 + 1e-6f);
142
162k
    float rcpcol = scale / (COLS - 1);
143
162k
    float rcprow = scale / (ROWS - 1);
144
162k
    JXL_ENSURE(COLS >= Lanes(DF4()));
145
162k
    HWY_ALIGN float l0123[4] = {0, 1, 2, 3};
146
2.74M
    for (uint32_t y = 0; y < ROWS; y++) {
147
2.58M
      float dy = y * rcprow;
148
2.58M
      float dy2 = dy * dy;
149
29.3M
      for (uint32_t x = 0; x < COLS; x += Lanes(DF4())) {
150
26.7M
        auto dx =
151
26.7M
            Mul(Add(Set(DF4(), x), Load(DF4(), l0123)), Set(DF4(), rcpcol));
152
26.7M
        auto scaled_distance = Sqrt(MulAdd(dx, dx, Set(DF4(), dy2)));
153
26.7M
        auto weight = num_bands == 1 ? Set(DF4(), bands[0])
154
26.7M
                                     : InterpolateVec(scaled_distance, bands);
155
26.7M
        StoreU(weight, DF4(), out + c * COLS * ROWS + y * COLS + x);
156
26.7M
      }
157
2.58M
    }
158
162k
  }
159
54.0k
  return true;
160
54.1k
}
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
54.1k
    size_t num_bands, float* out) {
133
216k
  for (size_t c = 0; c < 3; c++) {
134
162k
    float bands[DctQuantWeightParams::kMaxDistanceBands] = {
135
162k
        distance_bands[c][0]};
136
162k
    if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
137
1.02M
    for (size_t i = 1; i < num_bands; i++) {
138
858k
      bands[i] = bands[i - 1] * Mult(distance_bands[c][i]);
139
858k
      if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid distance bands");
140
858k
    }
141
162k
    float scale = (num_bands - 1) / (kSqrt2 + 1e-6f);
142
162k
    float rcpcol = scale / (COLS - 1);
143
162k
    float rcprow = scale / (ROWS - 1);
144
162k
    JXL_ENSURE(COLS >= Lanes(DF4()));
145
162k
    HWY_ALIGN float l0123[4] = {0, 1, 2, 3};
146
2.74M
    for (uint32_t y = 0; y < ROWS; y++) {
147
2.58M
      float dy = y * rcprow;
148
2.58M
      float dy2 = dy * dy;
149
29.3M
      for (uint32_t x = 0; x < COLS; x += Lanes(DF4())) {
150
26.7M
        auto dx =
151
26.7M
            Mul(Add(Set(DF4(), x), Load(DF4(), l0123)), Set(DF4(), rcpcol));
152
26.7M
        auto scaled_distance = Sqrt(MulAdd(dx, dx, Set(DF4(), dy2)));
153
26.7M
        auto weight = num_bands == 1 ? Set(DF4(), bands[0])
154
26.7M
                                     : InterpolateVec(scaled_distance, bands);
155
26.7M
        StoreU(weight, DF4(), out + c * COLS * ROWS + y * COLS + x);
156
26.7M
      }
157
2.58M
    }
158
162k
  }
159
54.0k
  return true;
160
54.1k
}
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
58.8k
                         QuantTable kind, size_t* pos) {
167
58.8k
  constexpr size_t N = kBlockDim;
168
58.8k
  size_t quant_table_idx = static_cast<size_t>(kind);
169
58.8k
  size_t wrows = 8 * DequantMatrices::required_size_x[quant_table_idx];
170
58.8k
  size_t wcols = 8 * DequantMatrices::required_size_y[quant_table_idx];
171
58.8k
  size_t num = wrows * wcols;
172
173
58.8k
  std::vector<float> weights(3 * num);
174
175
58.8k
  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
4.53k
    case QuantEncoding::kQuantModeID: {
183
4.53k
      JXL_ENSURE(num == kDCTBlockSize);
184
4.53k
      GetQuantWeightsIdentity(encoding.idweights, weights.data());
185
4.53k
      break;
186
4.53k
    }
187
4.67k
    case QuantEncoding::kQuantModeDCT2: {
188
4.67k
      JXL_ENSURE(num == kDCTBlockSize);
189
4.67k
      GetQuantWeightsDCT2(encoding.dct2weights, weights.data());
190
4.67k
      break;
191
4.67k
    }
192
3.75k
    case QuantEncoding::kQuantModeDCT4: {
193
3.75k
      JXL_ENSURE(num == kDCTBlockSize);
194
3.75k
      float weights4x4[3 * 4 * 4];
195
      // Always use 4x4 GetQuantWeights for DCT4 quantization tables.
196
3.75k
      JXL_RETURN_IF_ERROR(
197
3.75k
          GetQuantWeights(4, 4, encoding.dct_params.distance_bands,
198
3.75k
                          encoding.dct_params.num_distance_bands, weights4x4));
199
15.0k
      for (size_t c = 0; c < 3; c++) {
200
101k
        for (size_t y = 0; y < kBlockDim; y++) {
201
811k
          for (size_t x = 0; x < kBlockDim; x++) {
202
721k
            weights[c * num + y * kBlockDim + x] =
203
721k
                weights4x4[c * 16 + (y / 2) * 4 + (x / 2)];
204
721k
          }
205
90.1k
        }
206
11.2k
        weights[c * num + 1] /= encoding.dct4multipliers[c][0];
207
11.2k
        weights[c * num + N] /= encoding.dct4multipliers[c][0];
208
11.2k
        weights[c * num + N + 1] /= encoding.dct4multipliers[c][1];
209
11.2k
      }
210
3.75k
      break;
211
3.75k
    }
212
4.72k
    case QuantEncoding::kQuantModeDCT4X8: {
213
4.72k
      JXL_ENSURE(num == kDCTBlockSize);
214
4.72k
      float weights4x8[3 * 4 * 8];
215
      // Always use 4x8 GetQuantWeights for DCT4X8 quantization tables.
216
4.72k
      JXL_RETURN_IF_ERROR(
217
4.72k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
218
4.72k
                          encoding.dct_params.num_distance_bands, weights4x8));
219
18.8k
      for (size_t c = 0; c < 3; c++) {
220
127k
        for (size_t y = 0; y < kBlockDim; y++) {
221
1.02M
          for (size_t x = 0; x < kBlockDim; x++) {
222
906k
            weights[c * num + y * kBlockDim + x] =
223
906k
                weights4x8[c * 32 + (y / 2) * 8 + x];
224
906k
          }
225
113k
        }
226
14.1k
        weights[c * num + N] /= encoding.dct4x8multipliers[c];
227
14.1k
      }
228
4.72k
      break;
229
4.72k
    }
230
36.6k
    case QuantEncoding::kQuantModeDCT: {
231
36.6k
      JXL_RETURN_IF_ERROR(GetQuantWeights(
232
36.6k
          wrows, wcols, encoding.dct_params.distance_bands,
233
36.6k
          encoding.dct_params.num_distance_bands, weights.data()));
234
36.6k
      break;
235
36.6k
    }
236
36.6k
    case QuantEncoding::kQuantModeRAW: {
237
2
      if (!encoding.qraw.qtable || encoding.qraw.qtable->size() != 3 * num) {
238
0
        return JXL_FAILURE("Invalid table encoding");
239
0
      }
240
2
      int* qtable = encoding.qraw.qtable->data();
241
386
      for (size_t i = 0; i < 3 * num; i++) {
242
384
        weights[i] = 1.f / (encoding.qraw.qtable_den * qtable[i]);
243
384
      }
244
2
      break;
245
2
    }
246
4.51k
    case QuantEncoding::kQuantModeAFV: {
247
4.51k
      constexpr float kFreqs[] = {
248
4.51k
          0xBAD,
249
4.51k
          0xBAD,
250
4.51k
          0.8517778890324296,
251
4.51k
          5.37778436506804,
252
4.51k
          0xBAD,
253
4.51k
          0xBAD,
254
4.51k
          4.734747904497923,
255
4.51k
          5.449245381693219,
256
4.51k
          1.6598270267479331,
257
4.51k
          4,
258
4.51k
          7.275749096817861,
259
4.51k
          10.423227632456525,
260
4.51k
          2.662932286148962,
261
4.51k
          7.630657783650829,
262
4.51k
          8.962388608184032,
263
4.51k
          12.97166202570235,
264
4.51k
      };
265
266
4.51k
      float weights4x8[3 * 4 * 8];
267
4.51k
      JXL_RETURN_IF_ERROR((
268
4.51k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
269
4.51k
                          encoding.dct_params.num_distance_bands, weights4x8)));
270
4.50k
      float weights4x4[3 * 4 * 4];
271
4.50k
      JXL_RETURN_IF_ERROR((GetQuantWeights(
272
4.50k
          4, 4, encoding.dct_params_afv_4x4.distance_bands,
273
4.50k
          encoding.dct_params_afv_4x4.num_distance_bands, weights4x4)));
274
275
4.50k
      constexpr float lo = 0.8517778890324296;
276
4.50k
      constexpr float hi = 12.97166202570235f - lo + 1e-6f;
277
18.0k
      for (size_t c = 0; c < 3; c++) {
278
13.5k
        float bands[4];
279
13.5k
        bands[0] = encoding.afv_weights[c][5];
280
13.5k
        if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
281
54.0k
        for (size_t i = 1; i < 4; i++) {
282
40.5k
          bands[i] = bands[i - 1] * Mult(encoding.afv_weights[c][i + 5]);
283
40.5k
          if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
284
40.5k
        }
285
13.5k
        size_t start = c * 64;
286
229k
        auto set_weight = [&start, &weights](size_t x, size_t y, float val) {
287
229k
          weights[start + y * 8 + x] = val;
288
229k
        };
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
229k
        auto set_weight = [&start, &weights](size_t x, size_t y, float val) {
287
229k
          weights[start + y * 8 + x] = val;
288
229k
        };
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
13.5k
        weights[start] = 1;  // Not used, but causes MSAN error otherwise.
290
        // Weights for (0, 1) and (1, 0).
291
13.5k
        set_weight(0, 1, encoding.afv_weights[c][0]);
292
13.5k
        set_weight(1, 0, encoding.afv_weights[c][1]);
293
        // AFV special weights for 3-pixel corner.
294
13.5k
        set_weight(0, 2, encoding.afv_weights[c][2]);
295
13.5k
        set_weight(2, 0, encoding.afv_weights[c][3]);
296
13.5k
        set_weight(2, 2, encoding.afv_weights[c][4]);
297
298
        // All other AFV weights.
299
67.5k
        for (size_t y = 0; y < 4; y++) {
300
270k
          for (size_t x = 0; x < 4; x++) {
301
216k
            if (x < 2 && y < 2) continue;
302
324k
            JXL_ASSIGN_OR_RETURN(
303
324k
                float val, Interpolate(kFreqs[y * 4 + x] - lo, hi, bands, 4));
304
324k
            set_weight(2 * x, 2 * y, val);
305
324k
          }
306
54.0k
        }
307
308
        // Put 4x8 weights in odd rows, except (1, 0).
309
67.5k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
310
486k
          for (size_t x = 0; x < kBlockDim; x++) {
311
432k
            if (x == 0 && y == 0) continue;
312
418k
            weights[c * num + (2 * y + 1) * kBlockDim + x] =
313
418k
                weights4x8[c * 32 + y * 8 + x];
314
418k
          }
315
54.0k
        }
316
        // Put 4x4 weights in even rows / odd columns, except (0, 1).
317
67.5k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
318
270k
          for (size_t x = 0; x < kBlockDim / 2; x++) {
319
216k
            if (x == 0 && y == 0) continue;
320
202k
            weights[c * num + (2 * y) * kBlockDim + 2 * x + 1] =
321
202k
                weights4x4[c * 16 + y * 4 + x];
322
202k
          }
323
54.0k
        }
324
13.5k
      }
325
4.49k
      break;
326
4.50k
    }
327
58.8k
  }
328
58.7k
  size_t prev_pos = *pos;
329
58.7k
  HWY_CAPPED(float, 64) d;
330
13.8M
  for (size_t i = 0; i < num * 3; i += Lanes(d)) {
331
13.7M
    auto inv_val = LoadU(d, weights.data() + i);
332
13.7M
    if (JXL_UNLIKELY(!AllFalse(d, Ge(inv_val, Set(d, 1.0f / kAlmostZero))) ||
333
13.7M
                     !AllFalse(d, Lt(inv_val, Set(d, kAlmostZero))))) {
334
52
      return JXL_FAILURE("Invalid quantization table");
335
52
    }
336
13.7M
    auto val = Div(Set(d, 1.0f), inv_val);
337
13.7M
    StoreU(val, d, table + *pos + i);
338
13.7M
    StoreU(inv_val, d, inv_table + *pos + i);
339
13.7M
  }
340
58.7k
  (*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
58.7k
  size_t xs = DequantMatrices::required_size_x[quant_table_idx];
346
58.7k
  size_t ys = DequantMatrices::required_size_y[quant_table_idx];
347
58.7k
  CoefficientLayout(&ys, &xs);
348
234k
  for (size_t c = 0; c < 3; c++) {
349
539k
    for (size_t y = 0; y < ys; y++) {
350
2.08M
      for (size_t x = 0; x < xs; x++) {
351
1.71M
        inv_table[prev_pos + c * ys * xs * kDCTBlockSize + y * kBlockDim * xs +
352
1.71M
                  x] = 0;
353
1.71M
      }
354
363k
    }
355
176k
  }
356
58.7k
  return true;
357
58.7k
}
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
58.8k
                         QuantTable kind, size_t* pos) {
167
58.8k
  constexpr size_t N = kBlockDim;
168
58.8k
  size_t quant_table_idx = static_cast<size_t>(kind);
169
58.8k
  size_t wrows = 8 * DequantMatrices::required_size_x[quant_table_idx];
170
58.8k
  size_t wcols = 8 * DequantMatrices::required_size_y[quant_table_idx];
171
58.8k
  size_t num = wrows * wcols;
172
173
58.8k
  std::vector<float> weights(3 * num);
174
175
58.8k
  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
4.53k
    case QuantEncoding::kQuantModeID: {
183
4.53k
      JXL_ENSURE(num == kDCTBlockSize);
184
4.53k
      GetQuantWeightsIdentity(encoding.idweights, weights.data());
185
4.53k
      break;
186
4.53k
    }
187
4.67k
    case QuantEncoding::kQuantModeDCT2: {
188
4.67k
      JXL_ENSURE(num == kDCTBlockSize);
189
4.67k
      GetQuantWeightsDCT2(encoding.dct2weights, weights.data());
190
4.67k
      break;
191
4.67k
    }
192
3.75k
    case QuantEncoding::kQuantModeDCT4: {
193
3.75k
      JXL_ENSURE(num == kDCTBlockSize);
194
3.75k
      float weights4x4[3 * 4 * 4];
195
      // Always use 4x4 GetQuantWeights for DCT4 quantization tables.
196
3.75k
      JXL_RETURN_IF_ERROR(
197
3.75k
          GetQuantWeights(4, 4, encoding.dct_params.distance_bands,
198
3.75k
                          encoding.dct_params.num_distance_bands, weights4x4));
199
15.0k
      for (size_t c = 0; c < 3; c++) {
200
101k
        for (size_t y = 0; y < kBlockDim; y++) {
201
811k
          for (size_t x = 0; x < kBlockDim; x++) {
202
721k
            weights[c * num + y * kBlockDim + x] =
203
721k
                weights4x4[c * 16 + (y / 2) * 4 + (x / 2)];
204
721k
          }
205
90.1k
        }
206
11.2k
        weights[c * num + 1] /= encoding.dct4multipliers[c][0];
207
11.2k
        weights[c * num + N] /= encoding.dct4multipliers[c][0];
208
11.2k
        weights[c * num + N + 1] /= encoding.dct4multipliers[c][1];
209
11.2k
      }
210
3.75k
      break;
211
3.75k
    }
212
4.72k
    case QuantEncoding::kQuantModeDCT4X8: {
213
4.72k
      JXL_ENSURE(num == kDCTBlockSize);
214
4.72k
      float weights4x8[3 * 4 * 8];
215
      // Always use 4x8 GetQuantWeights for DCT4X8 quantization tables.
216
4.72k
      JXL_RETURN_IF_ERROR(
217
4.72k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
218
4.72k
                          encoding.dct_params.num_distance_bands, weights4x8));
219
18.8k
      for (size_t c = 0; c < 3; c++) {
220
127k
        for (size_t y = 0; y < kBlockDim; y++) {
221
1.02M
          for (size_t x = 0; x < kBlockDim; x++) {
222
906k
            weights[c * num + y * kBlockDim + x] =
223
906k
                weights4x8[c * 32 + (y / 2) * 8 + x];
224
906k
          }
225
113k
        }
226
14.1k
        weights[c * num + N] /= encoding.dct4x8multipliers[c];
227
14.1k
      }
228
4.72k
      break;
229
4.72k
    }
230
36.6k
    case QuantEncoding::kQuantModeDCT: {
231
36.6k
      JXL_RETURN_IF_ERROR(GetQuantWeights(
232
36.6k
          wrows, wcols, encoding.dct_params.distance_bands,
233
36.6k
          encoding.dct_params.num_distance_bands, weights.data()));
234
36.6k
      break;
235
36.6k
    }
236
36.6k
    case QuantEncoding::kQuantModeRAW: {
237
2
      if (!encoding.qraw.qtable || encoding.qraw.qtable->size() != 3 * num) {
238
0
        return JXL_FAILURE("Invalid table encoding");
239
0
      }
240
2
      int* qtable = encoding.qraw.qtable->data();
241
386
      for (size_t i = 0; i < 3 * num; i++) {
242
384
        weights[i] = 1.f / (encoding.qraw.qtable_den * qtable[i]);
243
384
      }
244
2
      break;
245
2
    }
246
4.51k
    case QuantEncoding::kQuantModeAFV: {
247
4.51k
      constexpr float kFreqs[] = {
248
4.51k
          0xBAD,
249
4.51k
          0xBAD,
250
4.51k
          0.8517778890324296,
251
4.51k
          5.37778436506804,
252
4.51k
          0xBAD,
253
4.51k
          0xBAD,
254
4.51k
          4.734747904497923,
255
4.51k
          5.449245381693219,
256
4.51k
          1.6598270267479331,
257
4.51k
          4,
258
4.51k
          7.275749096817861,
259
4.51k
          10.423227632456525,
260
4.51k
          2.662932286148962,
261
4.51k
          7.630657783650829,
262
4.51k
          8.962388608184032,
263
4.51k
          12.97166202570235,
264
4.51k
      };
265
266
4.51k
      float weights4x8[3 * 4 * 8];
267
4.51k
      JXL_RETURN_IF_ERROR((
268
4.51k
          GetQuantWeights(4, 8, encoding.dct_params.distance_bands,
269
4.51k
                          encoding.dct_params.num_distance_bands, weights4x8)));
270
4.50k
      float weights4x4[3 * 4 * 4];
271
4.50k
      JXL_RETURN_IF_ERROR((GetQuantWeights(
272
4.50k
          4, 4, encoding.dct_params_afv_4x4.distance_bands,
273
4.50k
          encoding.dct_params_afv_4x4.num_distance_bands, weights4x4)));
274
275
4.50k
      constexpr float lo = 0.8517778890324296;
276
4.50k
      constexpr float hi = 12.97166202570235f - lo + 1e-6f;
277
18.0k
      for (size_t c = 0; c < 3; c++) {
278
13.5k
        float bands[4];
279
13.5k
        bands[0] = encoding.afv_weights[c][5];
280
13.5k
        if (bands[0] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
281
54.0k
        for (size_t i = 1; i < 4; i++) {
282
40.5k
          bands[i] = bands[i - 1] * Mult(encoding.afv_weights[c][i + 5]);
283
40.5k
          if (bands[i] < kAlmostZero) return JXL_FAILURE("Invalid AFV bands");
284
40.5k
        }
285
13.5k
        size_t start = c * 64;
286
13.5k
        auto set_weight = [&start, &weights](size_t x, size_t y, float val) {
287
13.5k
          weights[start + y * 8 + x] = val;
288
13.5k
        };
289
13.5k
        weights[start] = 1;  // Not used, but causes MSAN error otherwise.
290
        // Weights for (0, 1) and (1, 0).
291
13.5k
        set_weight(0, 1, encoding.afv_weights[c][0]);
292
13.5k
        set_weight(1, 0, encoding.afv_weights[c][1]);
293
        // AFV special weights for 3-pixel corner.
294
13.5k
        set_weight(0, 2, encoding.afv_weights[c][2]);
295
13.5k
        set_weight(2, 0, encoding.afv_weights[c][3]);
296
13.5k
        set_weight(2, 2, encoding.afv_weights[c][4]);
297
298
        // All other AFV weights.
299
67.5k
        for (size_t y = 0; y < 4; y++) {
300
270k
          for (size_t x = 0; x < 4; x++) {
301
216k
            if (x < 2 && y < 2) continue;
302
324k
            JXL_ASSIGN_OR_RETURN(
303
324k
                float val, Interpolate(kFreqs[y * 4 + x] - lo, hi, bands, 4));
304
324k
            set_weight(2 * x, 2 * y, val);
305
324k
          }
306
54.0k
        }
307
308
        // Put 4x8 weights in odd rows, except (1, 0).
309
67.5k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
310
486k
          for (size_t x = 0; x < kBlockDim; x++) {
311
432k
            if (x == 0 && y == 0) continue;
312
418k
            weights[c * num + (2 * y + 1) * kBlockDim + x] =
313
418k
                weights4x8[c * 32 + y * 8 + x];
314
418k
          }
315
54.0k
        }
316
        // Put 4x4 weights in even rows / odd columns, except (0, 1).
317
67.5k
        for (size_t y = 0; y < kBlockDim / 2; y++) {
318
270k
          for (size_t x = 0; x < kBlockDim / 2; x++) {
319
216k
            if (x == 0 && y == 0) continue;
320
202k
            weights[c * num + (2 * y) * kBlockDim + 2 * x + 1] =
321
202k
                weights4x4[c * 16 + y * 4 + x];
322
202k
          }
323
54.0k
        }
324
13.5k
      }
325
4.49k
      break;
326
4.50k
    }
327
58.8k
  }
328
58.7k
  size_t prev_pos = *pos;
329
58.7k
  HWY_CAPPED(float, 64) d;
330
13.8M
  for (size_t i = 0; i < num * 3; i += Lanes(d)) {
331
13.7M
    auto inv_val = LoadU(d, weights.data() + i);
332
13.7M
    if (JXL_UNLIKELY(!AllFalse(d, Ge(inv_val, Set(d, 1.0f / kAlmostZero))) ||
333
13.7M
                     !AllFalse(d, Lt(inv_val, Set(d, kAlmostZero))))) {
334
52
      return JXL_FAILURE("Invalid quantization table");
335
52
    }
336
13.7M
    auto val = Div(Set(d, 1.0f), inv_val);
337
13.7M
    StoreU(val, d, table + *pos + i);
338
13.7M
    StoreU(inv_val, d, inv_table + *pos + i);
339
13.7M
  }
340
58.7k
  (*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
58.7k
  size_t xs = DequantMatrices::required_size_x[quant_table_idx];
346
58.7k
  size_t ys = DequantMatrices::required_size_y[quant_table_idx];
347
58.7k
  CoefficientLayout(&ys, &xs);
348
234k
  for (size_t c = 0; c < 3; c++) {
349
539k
    for (size_t y = 0; y < ys; y++) {
350
2.08M
      for (size_t x = 0; x < xs; x++) {
351
1.71M
        inv_table[prev_pos + c * ys * xs * kDCTBlockSize + y * kBlockDim * xs +
352
1.71M
                  x] = 0;
353
1.71M
      }
354
363k
    }
355
176k
  }
356
58.7k
  return true;
357
58.7k
}
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
341
Status DecodeDctParams(BitReader* br, DctQuantWeightParams* params) {
374
341
  params->num_distance_bands =
375
341
      br->ReadFixedBits<DctQuantWeightParams::kLog2MaxDistanceBands>() + 1;
376
1.07k
  for (size_t c = 0; c < 3; c++) {
377
4.08k
    for (size_t i = 0; i < params->num_distance_bands; i++) {
378
3.25k
      JXL_RETURN_IF_ERROR(F16Coder::Read(br, &params->distance_bands[c][i]));
379
3.25k
    }
380
829
    if (params->distance_bands[c][0] < kAlmostZero) {
381
95
      return JXL_FAILURE("Distance band seed is too small");
382
95
    }
383
734
    params->distance_bands[c][0] *= 64.0f;
384
734
  }
385
219
  return true;
386
341
}
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
8.96k
              ModularFrameDecoder* modular_frame_decoder) {
392
8.96k
  size_t required_size = required_size_x * required_size_y;
393
8.96k
  required_size_x *= kBlockDim;
394
8.96k
  required_size_y *= kBlockDim;
395
8.96k
  int mode = br->ReadFixedBits<kLog2NumQuantModes>();
396
8.96k
  switch (mode) {
397
7.79k
    case QuantEncoding::kQuantModeLibrary: {
398
7.79k
      encoding->predefined = br->ReadFixedBits<kCeilLog2NumPredefinedTables>();
399
7.79k
      if (encoding->predefined >= kNumPredefinedTables) {
400
0
        return JXL_FAILURE("Invalid predefined table");
401
0
      }
402
7.79k
      break;
403
7.79k
    }
404
7.79k
    case QuantEncoding::kQuantModeID: {
405
133
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
406
289
      for (size_t c = 0; c < 3; c++) {
407
847
        for (size_t i = 0; i < 3; i++) {
408
668
          JXL_RETURN_IF_ERROR(F16Coder::Read(br, &encoding->idweights[c][i]));
409
647
          if (std::abs(encoding->idweights[c][i]) < kAlmostZero) {
410
43
            return JXL_FAILURE("ID Quantizer is too small");
411
43
          }
412
604
          encoding->idweights[c][i] *= 64;
413
604
        }
414
243
      }
415
46
      break;
416
110
    }
417
135
    case QuantEncoding::kQuantModeDCT2: {
418
135
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
419
306
      for (size_t c = 0; c < 3; c++) {
420
1.52k
        for (size_t i = 0; i < 6; i++) {
421
1.34k
          JXL_RETURN_IF_ERROR(F16Coder::Read(br, &encoding->dct2weights[c][i]));
422
1.31k
          if (std::abs(encoding->dct2weights[c][i]) < kAlmostZero) {
423
50
            return JXL_FAILURE("Quantizer is too small");
424
50
          }
425
1.26k
          encoding->dct2weights[c][i] *= 64;
426
1.26k
        }
427
256
      }
428
50
      break;
429
122
    }
430
232
    case QuantEncoding::kQuantModeDCT4X8: {
431
232
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
432
606
      for (size_t c = 0; c < 3; c++) {
433
511
        JXL_RETURN_IF_ERROR(
434
511
            F16Coder::Read(br, &encoding->dct4x8multipliers[c]));
435
495
        if (std::abs(encoding->dct4x8multipliers[c]) < kAlmostZero) {
436
96
          return JXL_FAILURE("DCT4X8 multiplier is too small");
437
96
        }
438
495
      }
439
95
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
440
64
      break;
441
95
    }
442
111
    case QuantEncoding::kQuantModeDCT4: {
443
111
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
444
310
      for (size_t c = 0; c < 3; c++) {
445
694
        for (size_t i = 0; i < 2; i++) {
446
487
          JXL_RETURN_IF_ERROR(
447
487
              F16Coder::Read(br, &encoding->dct4multipliers[c][i]));
448
472
          if (std::abs(encoding->dct4multipliers[c][i]) < kAlmostZero) {
449
33
            return JXL_FAILURE("DCT4 multiplier is too small");
450
33
          }
451
472
        }
452
255
      }
453
55
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
454
42
      break;
455
55
    }
456
85
    case QuantEncoding::kQuantModeAFV: {
457
85
      if (required_size != 1) return JXL_FAILURE("Invalid mode");
458
203
      for (size_t c = 0; c < 3; c++) {
459
1.40k
        for (size_t i = 0; i < 9; i++) {
460
1.27k
          JXL_RETURN_IF_ERROR(F16Coder::Read(br, &encoding->afv_weights[c][i]));
461
1.27k
        }
462
875
        for (size_t i = 0; i < 6; i++) {
463
750
          encoding->afv_weights[c][i] *= 64;
464
750
        }
465
125
      }
466
37
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
467
21
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params_afv_4x4));
468
18
      break;
469
21
    }
470
133
    case QuantEncoding::kQuantModeDCT: {
471
133
      JXL_RETURN_IF_ERROR(DecodeDctParams(br, &encoding->dct_params));
472
74
      break;
473
133
    }
474
342
    case QuantEncoding::kQuantModeRAW: {
475
      // Set mode early, to avoid mem-leak.
476
342
      encoding->mode = QuantEncoding::kQuantModeRAW;
477
342
      JXL_RETURN_IF_ERROR(ModularFrameDecoder::DecodeQuantTable(
478
342
          memory_manager, required_size_x, required_size_y, br, encoding, idx,
479
342
          modular_frame_decoder));
480
24
      break;
481
342
    }
482
24
    default:
483
0
      return JXL_FAILURE("Invalid quantization table encoding");
484
8.96k
  }
485
8.11k
  encoding->mode = static_cast<QuantEncoding::Mode>(mode);
486
8.11k
  return true;
487
8.96k
}
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
4.54k
                               ModularFrameDecoder* modular_frame_decoder) {
499
4.54k
  size_t all_default = br->ReadBits(1);
500
4.54k
  size_t num_tables = all_default ? 0 : static_cast<size_t>(kNumQuantTables);
501
4.54k
  encodings_.clear();
502
4.54k
  encodings_.resize(kNumQuantTables, QuantEncoding::Library<0>());
503
12.6k
  for (size_t i = 0; i < num_tables; i++) {
504
8.96k
    JXL_RETURN_IF_ERROR(jxl::Decode(memory_manager, br, &encodings_[i],
505
8.96k
                                    required_size_x[i % kNumQuantTables],
506
8.96k
                                    required_size_y[i % kNumQuantTables], i,
507
8.96k
                                    modular_frame_decoder));
508
8.96k
  }
509
3.69k
  computed_mask_ = 0;
510
3.69k
  return true;
511
4.54k
}
512
513
91.9k
Status DequantMatrices::DecodeDC(BitReader* br) {
514
91.9k
  bool all_default = static_cast<bool>(br->ReadBits(1));
515
91.9k
  if (!br->AllReadsWithinBounds()) return JXL_FAILURE("EOS during DecodeDC");
516
85.9k
  if (!all_default) {
517
78.7k
    for (size_t c = 0; c < 3; c++) {
518
59.8k
      JXL_RETURN_IF_ERROR(F16Coder::Read(br, &dc_quant_[c]));
519
58.9k
      dc_quant_[c] *= 1.0f / 128.0f;
520
      // Negative values and nearly zero are invalid values.
521
58.9k
      if (dc_quant_[c] < kAlmostZero) {
522
1.92k
        return JXL_FAILURE("Invalid dc_quant: coefficient is too small.");
523
1.92k
      }
524
57.0k
      inv_dc_quant_[c] = 1.0f / dc_quant_[c];
525
57.0k
    }
526
21.7k
  }
527
83.1k
  return true;
528
85.9k
}
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
7.39k
const QuantEncoding* DequantMatrices::Library() {
1179
7.39k
  static const DequantMatrices::DequantLibraryInternal kDequantLibrary =
1180
7.39k
      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
7.39k
  return reinterpret_cast<const QuantEncoding*>(kDequantLibrary.data());
1188
7.39k
}
1189
1190
365k
DequantMatrices::DequantMatrices() {
1191
365k
  encodings_.resize(kNumQuantTables, QuantEncoding::Library<0>());
1192
365k
  size_t pos = 0;
1193
365k
  size_t offsets[kNumQuantTables * 3];
1194
6.57M
  for (size_t i = 0; i < static_cast<size_t>(kNumQuantTables); i++) {
1195
6.20M
    size_t num_blocks =
1196
6.20M
        static_cast<size_t>(required_size_x[i]) * required_size_y[i];
1197
6.20M
    size_t num = num_blocks * kDCTBlockSize;
1198
24.8M
    for (size_t c = 0; c < 3; c++) {
1199
18.6M
      offsets[3 * i + c] = pos + c * num;
1200
18.6M
    }
1201
6.20M
    pos += 3 * num;
1202
6.20M
  }
1203
10.2M
  for (size_t i = 0; i < AcStrategy::kNumValidStrategies; i++) {
1204
39.4M
    for (size_t c = 0; c < 3; c++) {
1205
29.5M
      table_offsets_[i * 3 + c] =
1206
29.5M
          offsets[static_cast<size_t>(kAcStrategyToQuantTableMap[i]) * 3 + c];
1207
29.5M
    }
1208
9.85M
  }
1209
365k
}
1210
1211
Status DequantMatrices::EnsureComputed(JxlMemoryManager* memory_manager,
1212
7.39k
                                       uint32_t acs_mask) {
1213
7.39k
  const QuantEncoding* library = Library();
1214
1215
7.39k
  if (!table_storage_) {
1216
7.39k
    size_t table_storage_bytes = 2 * kTotalTableSize * sizeof(float);
1217
7.39k
    JXL_ASSIGN_OR_RETURN(
1218
7.39k
        table_storage_,
1219
7.39k
        AlignedMemory::Create(memory_manager, table_storage_bytes));
1220
7.39k
    table_ = table_storage_.address<float>();
1221
7.39k
    inv_table_ = table_ + kTotalTableSize;
1222
7.39k
  }
1223
1224
7.39k
  size_t offsets[kNumQuantTables * 3 + 1];
1225
7.39k
  size_t pos = 0;
1226
133k
  for (size_t i = 0; i < kNumQuantTables; i++) {
1227
125k
    size_t num_blocks =
1228
125k
        static_cast<size_t>(required_size_x[i]) * required_size_y[i];
1229
125k
    size_t num = num_blocks * kDCTBlockSize;
1230
502k
    for (size_t c = 0; c < 3; c++) {
1231
377k
      offsets[3 * i + c] = pos + c * num;
1232
377k
    }
1233
125k
    pos += 3 * num;
1234
125k
  }
1235
7.39k
  offsets[kNumQuantTables * 3] = pos;
1236
7.39k
  JXL_ENSURE(pos == kTotalTableSize);
1237
1238
7.39k
  uint32_t kind_mask = 0;
1239
207k
  for (size_t i = 0; i < AcStrategy::kNumValidStrategies; i++) {
1240
199k
    if (acs_mask & (1u << i)) {
1241
92.2k
      kind_mask |= 1u << static_cast<uint32_t>(kAcStrategyToQuantTableMap[i]);
1242
92.2k
    }
1243
199k
  }
1244
7.39k
  uint32_t computed_kind_mask = 0;
1245
207k
  for (size_t i = 0; i < AcStrategy::kNumValidStrategies; i++) {
1246
199k
    if (computed_mask_ & (1u << i)) {
1247
0
      computed_kind_mask |=
1248
0
          1u << static_cast<uint32_t>(kAcStrategyToQuantTableMap[i]);
1249
0
    }
1250
199k
  }
1251
131k
  for (size_t table = 0; table < kNumQuantTables; table++) {
1252
124k
    if ((1 << table) & computed_kind_mask) continue;
1253
124k
    if ((1 << table) & ~kind_mask) continue;
1254
58.8k
    size_t offset = offsets[table * 3];
1255
58.8k
    float* mutable_table = table_storage_.address<float>();
1256
58.8k
    if (encodings_[table].mode == QuantEncoding::kQuantModeLibrary) {
1257
58.7k
      JXL_RETURN_IF_ERROR(HWY_DYNAMIC_DISPATCH(ComputeQuantTable)(
1258
58.7k
          library[table], mutable_table, mutable_table + kTotalTableSize, table,
1259
58.7k
          QuantTable(table), &offset));
1260
58.7k
    } else {
1261
93
      JXL_RETURN_IF_ERROR(HWY_DYNAMIC_DISPATCH(ComputeQuantTable)(
1262
93
          encodings_[table], mutable_table, mutable_table + kTotalTableSize,
1263
93
          table, QuantTable(table), &offset));
1264
93
    }
1265
58.7k
    JXL_ENSURE(offset == offsets[table * 3 + 3]);
1266
58.7k
  }
1267
7.31k
  computed_mask_ |= acs_mask;
1268
1269
7.31k
  return true;
1270
7.39k
}
1271
1272
}  // namespace jxl
1273
#endif