Coverage Report

Created: 2026-10-28 07:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libjxl/lib/jxl/compressed_dc.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
6
#include "lib/jxl/compressed_dc.h"
7
8
#include <jxl/memory_manager.h>
9
10
#include <algorithm>
11
#include <cstdint>
12
#include <cstdlib>
13
#include <cstring>
14
#include <vector>
15
16
#include "lib/jxl/ac_context.h"
17
#include "lib/jxl/frame_header.h"
18
#include "lib/jxl/modular/modular_image.h"
19
20
#undef HWY_TARGET_INCLUDE
21
#define HWY_TARGET_INCLUDE "lib/jxl/compressed_dc.cc"
22
#include <hwy/foreach_target.h>
23
#include <hwy/highway.h>
24
25
#include "lib/jxl/base/compiler_specific.h"
26
#include "lib/jxl/base/data_parallel.h"
27
#include "lib/jxl/base/rect.h"
28
#include "lib/jxl/base/status.h"
29
#include "lib/jxl/image.h"
30
HWY_BEFORE_NAMESPACE();
31
namespace jxl {
32
namespace HWY_NAMESPACE {
33
34
using D = HWY_FULL(float);
35
using DScalar = HWY_CAPPED(float, 1);
36
37
// These templates are not found via ADL.
38
using hwy::HWY_NAMESPACE::Abs;
39
using hwy::HWY_NAMESPACE::Add;
40
using hwy::HWY_NAMESPACE::Div;
41
using hwy::HWY_NAMESPACE::Max;
42
using hwy::HWY_NAMESPACE::Mul;
43
using hwy::HWY_NAMESPACE::MulAdd;
44
using hwy::HWY_NAMESPACE::Rebind;
45
using hwy::HWY_NAMESPACE::Sub;
46
using hwy::HWY_NAMESPACE::Vec;
47
using hwy::HWY_NAMESPACE::ZeroIfNegative;
48
49
// TODO(veluca): optimize constants.
50
const float w1 = 0.20345139757231578f;
51
const float w2 = 0.0334829185968739f;
52
const float w0 = 1.0f - 4.0f * (w1 + w2);
53
54
template <class V>
55
12.7M
V MaxWorkaround(V a, V b) {
56
#if (HWY_TARGET == HWY_AVX3) && HWY_COMPILER_CLANG <= 800
57
  // Prevents "Do not know how to split the result of this operator" error
58
  return IfThenElse(a > b, a, b);
59
#else
60
12.7M
  return Max(a, b);
61
12.7M
#endif
62
12.7M
}
Unexecuted instantiation: hwy::N_SSE4::Vec128<float, 1ul> jxl::N_SSE4::MaxWorkaround<hwy::N_SSE4::Vec128<float, 1ul> >(hwy::N_SSE4::Vec128<float, 1ul>, hwy::N_SSE4::Vec128<float, 1ul>)
Unexecuted instantiation: hwy::N_SSE4::Vec128<float, 4ul> jxl::N_SSE4::MaxWorkaround<hwy::N_SSE4::Vec128<float, 4ul> >(hwy::N_SSE4::Vec128<float, 4ul>, hwy::N_SSE4::Vec128<float, 4ul>)
hwy::N_AVX2::Vec128<float, 1ul> jxl::N_AVX2::MaxWorkaround<hwy::N_AVX2::Vec128<float, 1ul> >(hwy::N_AVX2::Vec128<float, 1ul>, hwy::N_AVX2::Vec128<float, 1ul>)
Line
Count
Source
55
10.1M
V MaxWorkaround(V a, V b) {
56
#if (HWY_TARGET == HWY_AVX3) && HWY_COMPILER_CLANG <= 800
57
  // Prevents "Do not know how to split the result of this operator" error
58
  return IfThenElse(a > b, a, b);
59
#else
60
10.1M
  return Max(a, b);
61
10.1M
#endif
62
10.1M
}
hwy::N_AVX2::Vec256<float> jxl::N_AVX2::MaxWorkaround<hwy::N_AVX2::Vec256<float> >(hwy::N_AVX2::Vec256<float>, hwy::N_AVX2::Vec256<float>)
Line
Count
Source
55
2.59M
V MaxWorkaround(V a, V b) {
56
#if (HWY_TARGET == HWY_AVX3) && HWY_COMPILER_CLANG <= 800
57
  // Prevents "Do not know how to split the result of this operator" error
58
  return IfThenElse(a > b, a, b);
59
#else
60
2.59M
  return Max(a, b);
61
2.59M
#endif
62
2.59M
}
Unexecuted instantiation: hwy::N_AVX3::Vec128<float, 1ul> jxl::N_AVX3::MaxWorkaround<hwy::N_AVX3::Vec128<float, 1ul> >(hwy::N_AVX3::Vec128<float, 1ul>, hwy::N_AVX3::Vec128<float, 1ul>)
Unexecuted instantiation: hwy::N_AVX3::Vec512<float> jxl::N_AVX3::MaxWorkaround<hwy::N_AVX3::Vec512<float> >(hwy::N_AVX3::Vec512<float>, hwy::N_AVX3::Vec512<float>)
Unexecuted instantiation: hwy::N_AVX3_ZEN4::Vec128<float, 1ul> jxl::N_AVX3_ZEN4::MaxWorkaround<hwy::N_AVX3_ZEN4::Vec128<float, 1ul> >(hwy::N_AVX3_ZEN4::Vec128<float, 1ul>, hwy::N_AVX3_ZEN4::Vec128<float, 1ul>)
Unexecuted instantiation: hwy::N_AVX3_ZEN4::Vec512<float> jxl::N_AVX3_ZEN4::MaxWorkaround<hwy::N_AVX3_ZEN4::Vec512<float> >(hwy::N_AVX3_ZEN4::Vec512<float>, hwy::N_AVX3_ZEN4::Vec512<float>)
Unexecuted instantiation: hwy::N_AVX3_SPR::Vec128<float, 1ul> jxl::N_AVX3_SPR::MaxWorkaround<hwy::N_AVX3_SPR::Vec128<float, 1ul> >(hwy::N_AVX3_SPR::Vec128<float, 1ul>, hwy::N_AVX3_SPR::Vec128<float, 1ul>)
Unexecuted instantiation: hwy::N_AVX3_SPR::Vec512<float> jxl::N_AVX3_SPR::MaxWorkaround<hwy::N_AVX3_SPR::Vec512<float> >(hwy::N_AVX3_SPR::Vec512<float>, hwy::N_AVX3_SPR::Vec512<float>)
Unexecuted instantiation: hwy::N_SSE2::Vec128<float, 1ul> jxl::N_SSE2::MaxWorkaround<hwy::N_SSE2::Vec128<float, 1ul> >(hwy::N_SSE2::Vec128<float, 1ul>, hwy::N_SSE2::Vec128<float, 1ul>)
Unexecuted instantiation: hwy::N_SSE2::Vec128<float, 4ul> jxl::N_SSE2::MaxWorkaround<hwy::N_SSE2::Vec128<float, 4ul> >(hwy::N_SSE2::Vec128<float, 4ul>, hwy::N_SSE2::Vec128<float, 4ul>)
63
64
template <typename D>
65
JXL_INLINE void ComputePixelChannel(const D d, const float dc_factor,
66
                                    const float* JXL_RESTRICT row_top,
67
                                    const float* JXL_RESTRICT row,
68
                                    const float* JXL_RESTRICT row_bottom,
69
                                    Vec<D>* JXL_RESTRICT mc,
70
                                    Vec<D>* JXL_RESTRICT sm,
71
12.7M
                                    Vec<D>* JXL_RESTRICT gap, size_t x) {
72
12.7M
  const auto tl = LoadU(d, row_top + x - 1);
73
12.7M
  const auto tc = Load(d, row_top + x);
74
12.7M
  const auto tr = LoadU(d, row_top + x + 1);
75
76
12.7M
  const auto ml = LoadU(d, row + x - 1);
77
12.7M
  *mc = Load(d, row + x);
78
12.7M
  const auto mr = LoadU(d, row + x + 1);
79
80
12.7M
  const auto bl = LoadU(d, row_bottom + x - 1);
81
12.7M
  const auto bc = Load(d, row_bottom + x);
82
12.7M
  const auto br = LoadU(d, row_bottom + x + 1);
83
84
12.7M
  const auto w_center = Set(d, w0);
85
12.7M
  const auto w_side = Set(d, w1);
86
12.7M
  const auto w_corner = Set(d, w2);
87
88
12.7M
  const auto corner = Add(Add(tl, tr), Add(bl, br));
89
12.7M
  const auto side = Add(Add(ml, mr), Add(tc, bc));
90
12.7M
  *sm = MulAdd(corner, w_corner, MulAdd(side, w_side, Mul(*mc, w_center)));
91
92
12.7M
  const auto dc_quant = Set(d, dc_factor);
93
12.7M
  *gap = MaxWorkaround(*gap, Abs(Div(Sub(*mc, *sm), dc_quant)));
94
12.7M
}
Unexecuted instantiation: void jxl::N_SSE4::ComputePixelChannel<hwy::N_SSE4::Simd<float, 1ul, 0> >(hwy::N_SSE4::Simd<float, 1ul, 0>, float, float const*, float const*, float const*, decltype (Zero((hwy::N_SSE4::Simd<float, 1ul, 0>)()))*, decltype (Zero((hwy::N_SSE4::Simd<float, 1ul, 0>)()))*, decltype (Zero((hwy::N_SSE4::Simd<float, 1ul, 0>)()))*, unsigned long)
Unexecuted instantiation: void jxl::N_SSE4::ComputePixelChannel<hwy::N_SSE4::Simd<float, 4ul, 0> >(hwy::N_SSE4::Simd<float, 4ul, 0>, float, float const*, float const*, float const*, decltype (Zero((hwy::N_SSE4::Simd<float, 4ul, 0>)()))*, decltype (Zero((hwy::N_SSE4::Simd<float, 4ul, 0>)()))*, decltype (Zero((hwy::N_SSE4::Simd<float, 4ul, 0>)()))*, unsigned long)
void jxl::N_AVX2::ComputePixelChannel<hwy::N_AVX2::Simd<float, 1ul, 0> >(hwy::N_AVX2::Simd<float, 1ul, 0>, float, float const*, float const*, float const*, decltype (Zero((hwy::N_AVX2::Simd<float, 1ul, 0>)()))*, decltype (Zero((hwy::N_AVX2::Simd<float, 1ul, 0>)()))*, decltype (Zero((hwy::N_AVX2::Simd<float, 1ul, 0>)()))*, unsigned long)
Line
Count
Source
71
10.1M
                                    Vec<D>* JXL_RESTRICT gap, size_t x) {
72
10.1M
  const auto tl = LoadU(d, row_top + x - 1);
73
10.1M
  const auto tc = Load(d, row_top + x);
74
10.1M
  const auto tr = LoadU(d, row_top + x + 1);
75
76
10.1M
  const auto ml = LoadU(d, row + x - 1);
77
10.1M
  *mc = Load(d, row + x);
78
10.1M
  const auto mr = LoadU(d, row + x + 1);
79
80
10.1M
  const auto bl = LoadU(d, row_bottom + x - 1);
81
10.1M
  const auto bc = Load(d, row_bottom + x);
82
10.1M
  const auto br = LoadU(d, row_bottom + x + 1);
83
84
10.1M
  const auto w_center = Set(d, w0);
85
10.1M
  const auto w_side = Set(d, w1);
86
10.1M
  const auto w_corner = Set(d, w2);
87
88
10.1M
  const auto corner = Add(Add(tl, tr), Add(bl, br));
89
10.1M
  const auto side = Add(Add(ml, mr), Add(tc, bc));
90
10.1M
  *sm = MulAdd(corner, w_corner, MulAdd(side, w_side, Mul(*mc, w_center)));
91
92
10.1M
  const auto dc_quant = Set(d, dc_factor);
93
10.1M
  *gap = MaxWorkaround(*gap, Abs(Div(Sub(*mc, *sm), dc_quant)));
94
10.1M
}
void jxl::N_AVX2::ComputePixelChannel<hwy::N_AVX2::Simd<float, 8ul, 0> >(hwy::N_AVX2::Simd<float, 8ul, 0>, float, float const*, float const*, float const*, decltype (Zero((hwy::N_AVX2::Simd<float, 8ul, 0>)()))*, decltype (Zero((hwy::N_AVX2::Simd<float, 8ul, 0>)()))*, decltype (Zero((hwy::N_AVX2::Simd<float, 8ul, 0>)()))*, unsigned long)
Line
Count
Source
71
2.59M
                                    Vec<D>* JXL_RESTRICT gap, size_t x) {
72
2.59M
  const auto tl = LoadU(d, row_top + x - 1);
73
2.59M
  const auto tc = Load(d, row_top + x);
74
2.59M
  const auto tr = LoadU(d, row_top + x + 1);
75
76
2.59M
  const auto ml = LoadU(d, row + x - 1);
77
2.59M
  *mc = Load(d, row + x);
78
2.59M
  const auto mr = LoadU(d, row + x + 1);
79
80
2.59M
  const auto bl = LoadU(d, row_bottom + x - 1);
81
2.59M
  const auto bc = Load(d, row_bottom + x);
82
2.59M
  const auto br = LoadU(d, row_bottom + x + 1);
83
84
2.59M
  const auto w_center = Set(d, w0);
85
2.59M
  const auto w_side = Set(d, w1);
86
2.59M
  const auto w_corner = Set(d, w2);
87
88
2.59M
  const auto corner = Add(Add(tl, tr), Add(bl, br));
89
2.59M
  const auto side = Add(Add(ml, mr), Add(tc, bc));
90
2.59M
  *sm = MulAdd(corner, w_corner, MulAdd(side, w_side, Mul(*mc, w_center)));
91
92
2.59M
  const auto dc_quant = Set(d, dc_factor);
93
2.59M
  *gap = MaxWorkaround(*gap, Abs(Div(Sub(*mc, *sm), dc_quant)));
94
2.59M
}
Unexecuted instantiation: void jxl::N_AVX3::ComputePixelChannel<hwy::N_AVX3::Simd<float, 1ul, 0> >(hwy::N_AVX3::Simd<float, 1ul, 0>, float, float const*, float const*, float const*, decltype (Zero((hwy::N_AVX3::Simd<float, 1ul, 0>)()))*, decltype (Zero((hwy::N_AVX3::Simd<float, 1ul, 0>)()))*, decltype (Zero((hwy::N_AVX3::Simd<float, 1ul, 0>)()))*, unsigned long)
Unexecuted instantiation: void jxl::N_AVX3::ComputePixelChannel<hwy::N_AVX3::Simd<float, 16ul, 0> >(hwy::N_AVX3::Simd<float, 16ul, 0>, float, float const*, float const*, float const*, decltype (Zero((hwy::N_AVX3::Simd<float, 16ul, 0>)()))*, decltype (Zero((hwy::N_AVX3::Simd<float, 16ul, 0>)()))*, decltype (Zero((hwy::N_AVX3::Simd<float, 16ul, 0>)()))*, unsigned long)
Unexecuted instantiation: void jxl::N_AVX3_ZEN4::ComputePixelChannel<hwy::N_AVX3_ZEN4::Simd<float, 1ul, 0> >(hwy::N_AVX3_ZEN4::Simd<float, 1ul, 0>, float, float const*, float const*, float const*, decltype (Zero((hwy::N_AVX3_ZEN4::Simd<float, 1ul, 0>)()))*, decltype (Zero((hwy::N_AVX3_ZEN4::Simd<float, 1ul, 0>)()))*, decltype (Zero((hwy::N_AVX3_ZEN4::Simd<float, 1ul, 0>)()))*, unsigned long)
Unexecuted instantiation: void jxl::N_AVX3_ZEN4::ComputePixelChannel<hwy::N_AVX3_ZEN4::Simd<float, 16ul, 0> >(hwy::N_AVX3_ZEN4::Simd<float, 16ul, 0>, float, float const*, float const*, float const*, decltype (Zero((hwy::N_AVX3_ZEN4::Simd<float, 16ul, 0>)()))*, decltype (Zero((hwy::N_AVX3_ZEN4::Simd<float, 16ul, 0>)()))*, decltype (Zero((hwy::N_AVX3_ZEN4::Simd<float, 16ul, 0>)()))*, unsigned long)
Unexecuted instantiation: void jxl::N_AVX3_SPR::ComputePixelChannel<hwy::N_AVX3_SPR::Simd<float, 1ul, 0> >(hwy::N_AVX3_SPR::Simd<float, 1ul, 0>, float, float const*, float const*, float const*, decltype (Zero((hwy::N_AVX3_SPR::Simd<float, 1ul, 0>)()))*, decltype (Zero((hwy::N_AVX3_SPR::Simd<float, 1ul, 0>)()))*, decltype (Zero((hwy::N_AVX3_SPR::Simd<float, 1ul, 0>)()))*, unsigned long)
Unexecuted instantiation: void jxl::N_AVX3_SPR::ComputePixelChannel<hwy::N_AVX3_SPR::Simd<float, 16ul, 0> >(hwy::N_AVX3_SPR::Simd<float, 16ul, 0>, float, float const*, float const*, float const*, decltype (Zero((hwy::N_AVX3_SPR::Simd<float, 16ul, 0>)()))*, decltype (Zero((hwy::N_AVX3_SPR::Simd<float, 16ul, 0>)()))*, decltype (Zero((hwy::N_AVX3_SPR::Simd<float, 16ul, 0>)()))*, unsigned long)
Unexecuted instantiation: void jxl::N_SSE2::ComputePixelChannel<hwy::N_SSE2::Simd<float, 1ul, 0> >(hwy::N_SSE2::Simd<float, 1ul, 0>, float, float const*, float const*, float const*, decltype (Zero((hwy::N_SSE2::Simd<float, 1ul, 0>)()))*, decltype (Zero((hwy::N_SSE2::Simd<float, 1ul, 0>)()))*, decltype (Zero((hwy::N_SSE2::Simd<float, 1ul, 0>)()))*, unsigned long)
Unexecuted instantiation: void jxl::N_SSE2::ComputePixelChannel<hwy::N_SSE2::Simd<float, 4ul, 0> >(hwy::N_SSE2::Simd<float, 4ul, 0>, float, float const*, float const*, float const*, decltype (Zero((hwy::N_SSE2::Simd<float, 4ul, 0>)()))*, decltype (Zero((hwy::N_SSE2::Simd<float, 4ul, 0>)()))*, decltype (Zero((hwy::N_SSE2::Simd<float, 4ul, 0>)()))*, unsigned long)
95
96
template <typename D>
97
JXL_INLINE void ComputePixel(
98
    const float* JXL_RESTRICT dc_factors,
99
    const float* JXL_RESTRICT* JXL_RESTRICT rows_top,
100
    const float* JXL_RESTRICT* JXL_RESTRICT rows,
101
    const float* JXL_RESTRICT* JXL_RESTRICT rows_bottom,
102
4.25M
    float* JXL_RESTRICT* JXL_RESTRICT out_rows, size_t x) {
103
4.25M
  const D d;
104
4.25M
  auto mc_x = Undefined(d);
105
4.25M
  auto mc_y = Undefined(d);
106
4.25M
  auto mc_b = Undefined(d);
107
4.25M
  auto sm_x = Undefined(d);
108
4.25M
  auto sm_y = Undefined(d);
109
4.25M
  auto sm_b = Undefined(d);
110
4.25M
  auto gap = Set(d, 0.5f);
111
4.25M
  ComputePixelChannel(d, dc_factors[0], rows_top[0], rows[0], rows_bottom[0],
112
4.25M
                      &mc_x, &sm_x, &gap, x);
113
4.25M
  ComputePixelChannel(d, dc_factors[1], rows_top[1], rows[1], rows_bottom[1],
114
4.25M
                      &mc_y, &sm_y, &gap, x);
115
4.25M
  ComputePixelChannel(d, dc_factors[2], rows_top[2], rows[2], rows_bottom[2],
116
4.25M
                      &mc_b, &sm_b, &gap, x);
117
4.25M
  auto factor = MulAdd(Set(d, -4.0f), gap, Set(d, 3.0f));
118
4.25M
  factor = ZeroIfNegative(factor);
119
120
4.25M
  auto out = MulAdd(Sub(sm_x, mc_x), factor, mc_x);
121
4.25M
  Store(out, d, out_rows[0] + x);
122
4.25M
  out = MulAdd(Sub(sm_y, mc_y), factor, mc_y);
123
4.25M
  Store(out, d, out_rows[1] + x);
124
4.25M
  out = MulAdd(Sub(sm_b, mc_b), factor, mc_b);
125
4.25M
  Store(out, d, out_rows[2] + x);
126
4.25M
}
Unexecuted instantiation: void jxl::N_SSE4::ComputePixel<hwy::N_SSE4::Simd<float, 1ul, 0> >(float const*, float const* restrict*, float const* restrict*, float const* restrict*, float* restrict*, unsigned long)
Unexecuted instantiation: void jxl::N_SSE4::ComputePixel<hwy::N_SSE4::Simd<float, 4ul, 0> >(float const*, float const* restrict*, float const* restrict*, float const* restrict*, float* restrict*, unsigned long)
void jxl::N_AVX2::ComputePixel<hwy::N_AVX2::Simd<float, 1ul, 0> >(float const*, float const* restrict*, float const* restrict*, float const* restrict*, float* restrict*, unsigned long)
Line
Count
Source
102
3.38M
    float* JXL_RESTRICT* JXL_RESTRICT out_rows, size_t x) {
103
3.38M
  const D d;
104
3.38M
  auto mc_x = Undefined(d);
105
3.38M
  auto mc_y = Undefined(d);
106
3.38M
  auto mc_b = Undefined(d);
107
3.38M
  auto sm_x = Undefined(d);
108
3.38M
  auto sm_y = Undefined(d);
109
3.38M
  auto sm_b = Undefined(d);
110
3.38M
  auto gap = Set(d, 0.5f);
111
3.38M
  ComputePixelChannel(d, dc_factors[0], rows_top[0], rows[0], rows_bottom[0],
112
3.38M
                      &mc_x, &sm_x, &gap, x);
113
3.38M
  ComputePixelChannel(d, dc_factors[1], rows_top[1], rows[1], rows_bottom[1],
114
3.38M
                      &mc_y, &sm_y, &gap, x);
115
3.38M
  ComputePixelChannel(d, dc_factors[2], rows_top[2], rows[2], rows_bottom[2],
116
3.38M
                      &mc_b, &sm_b, &gap, x);
117
3.38M
  auto factor = MulAdd(Set(d, -4.0f), gap, Set(d, 3.0f));
118
3.38M
  factor = ZeroIfNegative(factor);
119
120
3.38M
  auto out = MulAdd(Sub(sm_x, mc_x), factor, mc_x);
121
3.38M
  Store(out, d, out_rows[0] + x);
122
3.38M
  out = MulAdd(Sub(sm_y, mc_y), factor, mc_y);
123
3.38M
  Store(out, d, out_rows[1] + x);
124
3.38M
  out = MulAdd(Sub(sm_b, mc_b), factor, mc_b);
125
3.38M
  Store(out, d, out_rows[2] + x);
126
3.38M
}
void jxl::N_AVX2::ComputePixel<hwy::N_AVX2::Simd<float, 8ul, 0> >(float const*, float const* restrict*, float const* restrict*, float const* restrict*, float* restrict*, unsigned long)
Line
Count
Source
102
865k
    float* JXL_RESTRICT* JXL_RESTRICT out_rows, size_t x) {
103
865k
  const D d;
104
865k
  auto mc_x = Undefined(d);
105
865k
  auto mc_y = Undefined(d);
106
865k
  auto mc_b = Undefined(d);
107
865k
  auto sm_x = Undefined(d);
108
865k
  auto sm_y = Undefined(d);
109
865k
  auto sm_b = Undefined(d);
110
865k
  auto gap = Set(d, 0.5f);
111
865k
  ComputePixelChannel(d, dc_factors[0], rows_top[0], rows[0], rows_bottom[0],
112
865k
                      &mc_x, &sm_x, &gap, x);
113
865k
  ComputePixelChannel(d, dc_factors[1], rows_top[1], rows[1], rows_bottom[1],
114
865k
                      &mc_y, &sm_y, &gap, x);
115
865k
  ComputePixelChannel(d, dc_factors[2], rows_top[2], rows[2], rows_bottom[2],
116
865k
                      &mc_b, &sm_b, &gap, x);
117
865k
  auto factor = MulAdd(Set(d, -4.0f), gap, Set(d, 3.0f));
118
865k
  factor = ZeroIfNegative(factor);
119
120
865k
  auto out = MulAdd(Sub(sm_x, mc_x), factor, mc_x);
121
865k
  Store(out, d, out_rows[0] + x);
122
865k
  out = MulAdd(Sub(sm_y, mc_y), factor, mc_y);
123
865k
  Store(out, d, out_rows[1] + x);
124
865k
  out = MulAdd(Sub(sm_b, mc_b), factor, mc_b);
125
865k
  Store(out, d, out_rows[2] + x);
126
865k
}
Unexecuted instantiation: void jxl::N_AVX3::ComputePixel<hwy::N_AVX3::Simd<float, 1ul, 0> >(float const*, float const* restrict*, float const* restrict*, float const* restrict*, float* restrict*, unsigned long)
Unexecuted instantiation: void jxl::N_AVX3::ComputePixel<hwy::N_AVX3::Simd<float, 16ul, 0> >(float const*, float const* restrict*, float const* restrict*, float const* restrict*, float* restrict*, unsigned long)
Unexecuted instantiation: void jxl::N_AVX3_ZEN4::ComputePixel<hwy::N_AVX3_ZEN4::Simd<float, 1ul, 0> >(float const*, float const* restrict*, float const* restrict*, float const* restrict*, float* restrict*, unsigned long)
Unexecuted instantiation: void jxl::N_AVX3_ZEN4::ComputePixel<hwy::N_AVX3_ZEN4::Simd<float, 16ul, 0> >(float const*, float const* restrict*, float const* restrict*, float const* restrict*, float* restrict*, unsigned long)
Unexecuted instantiation: void jxl::N_AVX3_SPR::ComputePixel<hwy::N_AVX3_SPR::Simd<float, 1ul, 0> >(float const*, float const* restrict*, float const* restrict*, float const* restrict*, float* restrict*, unsigned long)
Unexecuted instantiation: void jxl::N_AVX3_SPR::ComputePixel<hwy::N_AVX3_SPR::Simd<float, 16ul, 0> >(float const*, float const* restrict*, float const* restrict*, float const* restrict*, float* restrict*, unsigned long)
Unexecuted instantiation: void jxl::N_SSE2::ComputePixel<hwy::N_SSE2::Simd<float, 1ul, 0> >(float const*, float const* restrict*, float const* restrict*, float const* restrict*, float* restrict*, unsigned long)
Unexecuted instantiation: void jxl::N_SSE2::ComputePixel<hwy::N_SSE2::Simd<float, 4ul, 0> >(float const*, float const* restrict*, float const* restrict*, float const* restrict*, float* restrict*, unsigned long)
127
128
template <typename D>
129
JXL_INLINE void ComputePixelSingleChannel(const float dc_factor,
130
                                          const float* JXL_RESTRICT row_top,
131
                                          const float* JXL_RESTRICT row,
132
                                          const float* JXL_RESTRICT row_bottom,
133
                                          float* JXL_RESTRICT out_row,
134
140
                                          size_t x) {
135
140
  const D d;
136
140
  auto mc = Undefined(d);
137
140
  auto sm = Undefined(d);
138
140
  auto gap = Set(d, 0.5f);
139
140
  ComputePixelChannel(d, dc_factor, row_top, row, row_bottom, &mc, &sm, &gap,
140
140
                      x);
141
140
  auto factor = MulAdd(Set(d, -4.0f), gap, Set(d, 3.0f));
142
140
  factor = ZeroIfNegative(factor);
143
144
140
  auto out = MulAdd(Sub(sm, mc), factor, mc);
145
140
  Store(out, d, out_row + x);
146
140
}
Unexecuted instantiation: void jxl::N_SSE4::ComputePixelSingleChannel<hwy::N_SSE4::Simd<float, 1ul, 0> >(float, float const*, float const*, float const*, float*, unsigned long)
Unexecuted instantiation: void jxl::N_SSE4::ComputePixelSingleChannel<hwy::N_SSE4::Simd<float, 4ul, 0> >(float, float const*, float const*, float const*, float*, unsigned long)
void jxl::N_AVX2::ComputePixelSingleChannel<hwy::N_AVX2::Simd<float, 1ul, 0> >(float, float const*, float const*, float const*, float*, unsigned long)
Line
Count
Source
134
140
                                          size_t x) {
135
140
  const D d;
136
140
  auto mc = Undefined(d);
137
140
  auto sm = Undefined(d);
138
140
  auto gap = Set(d, 0.5f);
139
140
  ComputePixelChannel(d, dc_factor, row_top, row, row_bottom, &mc, &sm, &gap,
140
140
                      x);
141
140
  auto factor = MulAdd(Set(d, -4.0f), gap, Set(d, 3.0f));
142
140
  factor = ZeroIfNegative(factor);
143
144
140
  auto out = MulAdd(Sub(sm, mc), factor, mc);
145
140
  Store(out, d, out_row + x);
146
140
}
Unexecuted instantiation: void jxl::N_AVX2::ComputePixelSingleChannel<hwy::N_AVX2::Simd<float, 8ul, 0> >(float, float const*, float const*, float const*, float*, unsigned long)
Unexecuted instantiation: void jxl::N_AVX3::ComputePixelSingleChannel<hwy::N_AVX3::Simd<float, 1ul, 0> >(float, float const*, float const*, float const*, float*, unsigned long)
Unexecuted instantiation: void jxl::N_AVX3::ComputePixelSingleChannel<hwy::N_AVX3::Simd<float, 16ul, 0> >(float, float const*, float const*, float const*, float*, unsigned long)
Unexecuted instantiation: void jxl::N_AVX3_ZEN4::ComputePixelSingleChannel<hwy::N_AVX3_ZEN4::Simd<float, 1ul, 0> >(float, float const*, float const*, float const*, float*, unsigned long)
Unexecuted instantiation: void jxl::N_AVX3_ZEN4::ComputePixelSingleChannel<hwy::N_AVX3_ZEN4::Simd<float, 16ul, 0> >(float, float const*, float const*, float const*, float*, unsigned long)
Unexecuted instantiation: void jxl::N_AVX3_SPR::ComputePixelSingleChannel<hwy::N_AVX3_SPR::Simd<float, 1ul, 0> >(float, float const*, float const*, float const*, float*, unsigned long)
Unexecuted instantiation: void jxl::N_AVX3_SPR::ComputePixelSingleChannel<hwy::N_AVX3_SPR::Simd<float, 16ul, 0> >(float, float const*, float const*, float const*, float*, unsigned long)
Unexecuted instantiation: void jxl::N_SSE2::ComputePixelSingleChannel<hwy::N_SSE2::Simd<float, 1ul, 0> >(float, float const*, float const*, float const*, float*, unsigned long)
Unexecuted instantiation: void jxl::N_SSE2::ComputePixelSingleChannel<hwy::N_SSE2::Simd<float, 4ul, 0> >(float, float const*, float const*, float const*, float*, unsigned long)
147
148
Status AdaptiveDCSmoothing(JxlMemoryManager* memory_manager,
149
                           const float* dc_factors, Image3F* dc,
150
                           const YCbCrChromaSubsampling& chroma_subsampling,
151
53.6k
                           ThreadPool* pool) {
152
53.6k
  const size_t xsize = dc->xsize();
153
53.6k
  const size_t ysize = dc->ysize();
154
53.6k
  if (ysize <= 2 || xsize <= 2) return true;
155
156
  // TODO(veluca): use tile-based processing?
157
  // TODO(veluca): decide if changes to the y channel should be propagated to
158
  // the x and b channels through color correlation.
159
7.78k
  JXL_ENSURE(w1 + w2 < 0.25f);
160
161
7.78k
  if (chroma_subsampling.Is444()) {
162
7.77k
    JXL_ASSIGN_OR_RETURN(Image3F smoothed,
163
7.77k
                         Image3F::Create(memory_manager, xsize, ysize));
164
    // Fill in borders that the loop below will not. First and last are unused.
165
31.1k
    for (size_t c = 0; c < 3; c++) {
166
46.6k
      for (size_t y : {static_cast<size_t>(0), ysize - 1}) {
167
46.6k
        memcpy(smoothed.PlaneRow(c, y), dc->PlaneRow(c, y),
168
46.6k
               xsize * sizeof(float));
169
46.6k
      }
170
23.3k
    }
171
320k
    auto process_row = [&](const uint32_t y, size_t /*thread*/) -> Status {
172
320k
      const float* JXL_RESTRICT rows_top[3]{
173
320k
          dc->ConstPlaneRow(0, y - 1),
174
320k
          dc->ConstPlaneRow(1, y - 1),
175
320k
          dc->ConstPlaneRow(2, y - 1),
176
320k
      };
177
320k
      const float* JXL_RESTRICT rows[3] = {
178
320k
          dc->ConstPlaneRow(0, y),
179
320k
          dc->ConstPlaneRow(1, y),
180
320k
          dc->ConstPlaneRow(2, y),
181
320k
      };
182
320k
      const float* JXL_RESTRICT rows_bottom[3] = {
183
320k
          dc->ConstPlaneRow(0, y + 1),
184
320k
          dc->ConstPlaneRow(1, y + 1),
185
320k
          dc->ConstPlaneRow(2, y + 1),
186
320k
      };
187
320k
      float* JXL_RESTRICT rows_out[3] = {
188
320k
          smoothed.PlaneRow(0, y),
189
320k
          smoothed.PlaneRow(1, y),
190
320k
          smoothed.PlaneRow(2, y),
191
320k
      };
192
641k
      for (size_t x : {static_cast<size_t>(0), xsize - 1}) {
193
2.56M
        for (size_t c = 0; c < 3; c++) {
194
1.92M
          rows_out[c][x] = rows[c][x];
195
1.92M
        }
196
641k
      }
197
198
320k
      size_t x = 1;
199
      // First pixels
200
320k
      const size_t N = Lanes(D());
201
2.53M
      for (; x < std::min(N, xsize - 1); x++) {
202
2.21M
        ComputePixel<DScalar>(dc_factors, rows_top, rows, rows_bottom, rows_out,
203
2.21M
                              x);
204
2.21M
      }
205
      // Full vectors.
206
1.18M
      for (; x + N <= xsize - 1; x += N) {
207
865k
        ComputePixel<D>(dc_factors, rows_top, rows, rows_bottom, rows_out, x);
208
865k
      }
209
      // Last pixels.
210
1.48M
      for (; x < xsize - 1; x++) {
211
1.16M
        ComputePixel<DScalar>(dc_factors, rows_top, rows, rows_bottom, rows_out,
212
1.16M
                              x);
213
1.16M
      }
214
320k
      return true;
215
320k
    };
Unexecuted instantiation: compressed_dc.cc:jxl::N_SSE4::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)::$_0::operator()(unsigned int, unsigned long) const
compressed_dc.cc:jxl::N_AVX2::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)::$_0::operator()(unsigned int, unsigned long) const
Line
Count
Source
171
320k
    auto process_row = [&](const uint32_t y, size_t /*thread*/) -> Status {
172
320k
      const float* JXL_RESTRICT rows_top[3]{
173
320k
          dc->ConstPlaneRow(0, y - 1),
174
320k
          dc->ConstPlaneRow(1, y - 1),
175
320k
          dc->ConstPlaneRow(2, y - 1),
176
320k
      };
177
320k
      const float* JXL_RESTRICT rows[3] = {
178
320k
          dc->ConstPlaneRow(0, y),
179
320k
          dc->ConstPlaneRow(1, y),
180
320k
          dc->ConstPlaneRow(2, y),
181
320k
      };
182
320k
      const float* JXL_RESTRICT rows_bottom[3] = {
183
320k
          dc->ConstPlaneRow(0, y + 1),
184
320k
          dc->ConstPlaneRow(1, y + 1),
185
320k
          dc->ConstPlaneRow(2, y + 1),
186
320k
      };
187
320k
      float* JXL_RESTRICT rows_out[3] = {
188
320k
          smoothed.PlaneRow(0, y),
189
320k
          smoothed.PlaneRow(1, y),
190
320k
          smoothed.PlaneRow(2, y),
191
320k
      };
192
641k
      for (size_t x : {static_cast<size_t>(0), xsize - 1}) {
193
2.56M
        for (size_t c = 0; c < 3; c++) {
194
1.92M
          rows_out[c][x] = rows[c][x];
195
1.92M
        }
196
641k
      }
197
198
320k
      size_t x = 1;
199
      // First pixels
200
320k
      const size_t N = Lanes(D());
201
2.53M
      for (; x < std::min(N, xsize - 1); x++) {
202
2.21M
        ComputePixel<DScalar>(dc_factors, rows_top, rows, rows_bottom, rows_out,
203
2.21M
                              x);
204
2.21M
      }
205
      // Full vectors.
206
1.18M
      for (; x + N <= xsize - 1; x += N) {
207
865k
        ComputePixel<D>(dc_factors, rows_top, rows, rows_bottom, rows_out, x);
208
865k
      }
209
      // Last pixels.
210
1.48M
      for (; x < xsize - 1; x++) {
211
1.16M
        ComputePixel<DScalar>(dc_factors, rows_top, rows, rows_bottom, rows_out,
212
1.16M
                              x);
213
1.16M
      }
214
320k
      return true;
215
320k
    };
Unexecuted instantiation: compressed_dc.cc:jxl::N_AVX3::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)::$_0::operator()(unsigned int, unsigned long) const
Unexecuted instantiation: compressed_dc.cc:jxl::N_AVX3_ZEN4::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)::$_0::operator()(unsigned int, unsigned long) const
Unexecuted instantiation: compressed_dc.cc:jxl::N_AVX3_SPR::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)::$_0::operator()(unsigned int, unsigned long) const
Unexecuted instantiation: compressed_dc.cc:jxl::N_SSE2::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)::$_0::operator()(unsigned int, unsigned long) const
216
7.77k
    JXL_RETURN_IF_ERROR(RunOnPool(pool, 1, ysize - 1, ThreadPool::NoInit,
217
7.77k
                                  process_row, "DCSmoothingRow"));
218
7.77k
    dc->Swap(smoothed);
219
7.77k
  } else {
220
9
    JXL_ASSIGN_OR_RETURN(ImageF smoothed,
221
9
                         ImageF::Create(memory_manager, xsize, ysize));
222
36
    for (size_t c = 0; c < 3; c++) {
223
27
      const size_t xsize_c = xsize >> chroma_subsampling.HShift(c);
224
27
      const size_t ysize_c = ysize >> chroma_subsampling.VShift(c);
225
27
      if (ysize_c <= 2 || xsize_c <= 2) continue;
226
54
      for (size_t y : {static_cast<size_t>(0), ysize_c - 1}) {
227
54
        memcpy(smoothed.Row(y), dc->PlaneRow(c, y), xsize_c * sizeof(float));
228
54
      }
229
118
      auto process_row = [&](const uint32_t y, size_t /*thread*/) -> Status {
230
118
        const float* JXL_RESTRICT row_top = dc->ConstPlaneRow(c, y - 1);
231
118
        const float* JXL_RESTRICT row = dc->ConstPlaneRow(c, y);
232
118
        const float* JXL_RESTRICT row_bottom = dc->ConstPlaneRow(c, y + 1);
233
118
        float* JXL_RESTRICT row_out = smoothed.Row(y);
234
236
        for (size_t x : {static_cast<size_t>(0), xsize_c - 1}) {
235
236
          row_out[x] = row[x];
236
236
        }
237
238
118
        size_t x = 1;
239
        // First pixels
240
118
        const size_t N = Lanes(D());
241
258
        for (; x < std::min(N, xsize_c - 1); x++) {
242
140
          ComputePixelSingleChannel<DScalar>(dc_factors[c], row_top, row,
243
140
                                             row_bottom, row_out, x);
244
140
        }
245
        // Full vectors.
246
118
        for (; x + N <= xsize_c - 1; x += N) {
247
0
          ComputePixelSingleChannel<D>(dc_factors[c], row_top, row, row_bottom,
248
0
                                       row_out, x);
249
0
        }
250
        // Last pixels.
251
118
        for (; x < xsize_c - 1; x++) {
252
0
          ComputePixelSingleChannel<DScalar>(dc_factors[c], row_top, row,
253
0
                                             row_bottom, row_out, x);
254
0
        }
255
118
        return true;
256
118
      };
Unexecuted instantiation: compressed_dc.cc:jxl::N_SSE4::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)::$_1::operator()(unsigned int, unsigned long) const
compressed_dc.cc:jxl::N_AVX2::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)::$_1::operator()(unsigned int, unsigned long) const
Line
Count
Source
229
118
      auto process_row = [&](const uint32_t y, size_t /*thread*/) -> Status {
230
118
        const float* JXL_RESTRICT row_top = dc->ConstPlaneRow(c, y - 1);
231
118
        const float* JXL_RESTRICT row = dc->ConstPlaneRow(c, y);
232
118
        const float* JXL_RESTRICT row_bottom = dc->ConstPlaneRow(c, y + 1);
233
118
        float* JXL_RESTRICT row_out = smoothed.Row(y);
234
236
        for (size_t x : {static_cast<size_t>(0), xsize_c - 1}) {
235
236
          row_out[x] = row[x];
236
236
        }
237
238
118
        size_t x = 1;
239
        // First pixels
240
118
        const size_t N = Lanes(D());
241
258
        for (; x < std::min(N, xsize_c - 1); x++) {
242
140
          ComputePixelSingleChannel<DScalar>(dc_factors[c], row_top, row,
243
140
                                             row_bottom, row_out, x);
244
140
        }
245
        // Full vectors.
246
118
        for (; x + N <= xsize_c - 1; x += N) {
247
0
          ComputePixelSingleChannel<D>(dc_factors[c], row_top, row, row_bottom,
248
0
                                       row_out, x);
249
0
        }
250
        // Last pixels.
251
118
        for (; x < xsize_c - 1; x++) {
252
0
          ComputePixelSingleChannel<DScalar>(dc_factors[c], row_top, row,
253
0
                                             row_bottom, row_out, x);
254
0
        }
255
118
        return true;
256
118
      };
Unexecuted instantiation: compressed_dc.cc:jxl::N_AVX3::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)::$_1::operator()(unsigned int, unsigned long) const
Unexecuted instantiation: compressed_dc.cc:jxl::N_AVX3_ZEN4::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)::$_1::operator()(unsigned int, unsigned long) const
Unexecuted instantiation: compressed_dc.cc:jxl::N_AVX3_SPR::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)::$_1::operator()(unsigned int, unsigned long) const
Unexecuted instantiation: compressed_dc.cc:jxl::N_SSE2::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)::$_1::operator()(unsigned int, unsigned long) const
257
27
      JXL_RETURN_IF_ERROR(RunOnPool(pool, 1, ysize_c - 1, ThreadPool::NoInit,
258
27
                                    process_row, "DCSmoothingRow"));
259
27
      dc->Plane(c).Swap(smoothed);
260
27
    }
261
9
  }
262
7.78k
  return true;
263
7.78k
}
Unexecuted instantiation: jxl::N_SSE4::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)
jxl::N_AVX2::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)
Line
Count
Source
151
53.6k
                           ThreadPool* pool) {
152
53.6k
  const size_t xsize = dc->xsize();
153
53.6k
  const size_t ysize = dc->ysize();
154
53.6k
  if (ysize <= 2 || xsize <= 2) return true;
155
156
  // TODO(veluca): use tile-based processing?
157
  // TODO(veluca): decide if changes to the y channel should be propagated to
158
  // the x and b channels through color correlation.
159
7.78k
  JXL_ENSURE(w1 + w2 < 0.25f);
160
161
7.78k
  if (chroma_subsampling.Is444()) {
162
7.77k
    JXL_ASSIGN_OR_RETURN(Image3F smoothed,
163
7.77k
                         Image3F::Create(memory_manager, xsize, ysize));
164
    // Fill in borders that the loop below will not. First and last are unused.
165
31.1k
    for (size_t c = 0; c < 3; c++) {
166
46.6k
      for (size_t y : {static_cast<size_t>(0), ysize - 1}) {
167
46.6k
        memcpy(smoothed.PlaneRow(c, y), dc->PlaneRow(c, y),
168
46.6k
               xsize * sizeof(float));
169
46.6k
      }
170
23.3k
    }
171
7.77k
    auto process_row = [&](const uint32_t y, size_t /*thread*/) -> Status {
172
7.77k
      const float* JXL_RESTRICT rows_top[3]{
173
7.77k
          dc->ConstPlaneRow(0, y - 1),
174
7.77k
          dc->ConstPlaneRow(1, y - 1),
175
7.77k
          dc->ConstPlaneRow(2, y - 1),
176
7.77k
      };
177
7.77k
      const float* JXL_RESTRICT rows[3] = {
178
7.77k
          dc->ConstPlaneRow(0, y),
179
7.77k
          dc->ConstPlaneRow(1, y),
180
7.77k
          dc->ConstPlaneRow(2, y),
181
7.77k
      };
182
7.77k
      const float* JXL_RESTRICT rows_bottom[3] = {
183
7.77k
          dc->ConstPlaneRow(0, y + 1),
184
7.77k
          dc->ConstPlaneRow(1, y + 1),
185
7.77k
          dc->ConstPlaneRow(2, y + 1),
186
7.77k
      };
187
7.77k
      float* JXL_RESTRICT rows_out[3] = {
188
7.77k
          smoothed.PlaneRow(0, y),
189
7.77k
          smoothed.PlaneRow(1, y),
190
7.77k
          smoothed.PlaneRow(2, y),
191
7.77k
      };
192
7.77k
      for (size_t x : {static_cast<size_t>(0), xsize - 1}) {
193
7.77k
        for (size_t c = 0; c < 3; c++) {
194
7.77k
          rows_out[c][x] = rows[c][x];
195
7.77k
        }
196
7.77k
      }
197
198
7.77k
      size_t x = 1;
199
      // First pixels
200
7.77k
      const size_t N = Lanes(D());
201
7.77k
      for (; x < std::min(N, xsize - 1); x++) {
202
7.77k
        ComputePixel<DScalar>(dc_factors, rows_top, rows, rows_bottom, rows_out,
203
7.77k
                              x);
204
7.77k
      }
205
      // Full vectors.
206
7.77k
      for (; x + N <= xsize - 1; x += N) {
207
7.77k
        ComputePixel<D>(dc_factors, rows_top, rows, rows_bottom, rows_out, x);
208
7.77k
      }
209
      // Last pixels.
210
7.77k
      for (; x < xsize - 1; x++) {
211
7.77k
        ComputePixel<DScalar>(dc_factors, rows_top, rows, rows_bottom, rows_out,
212
7.77k
                              x);
213
7.77k
      }
214
7.77k
      return true;
215
7.77k
    };
216
7.77k
    JXL_RETURN_IF_ERROR(RunOnPool(pool, 1, ysize - 1, ThreadPool::NoInit,
217
7.77k
                                  process_row, "DCSmoothingRow"));
218
7.77k
    dc->Swap(smoothed);
219
7.77k
  } else {
220
9
    JXL_ASSIGN_OR_RETURN(ImageF smoothed,
221
9
                         ImageF::Create(memory_manager, xsize, ysize));
222
36
    for (size_t c = 0; c < 3; c++) {
223
27
      const size_t xsize_c = xsize >> chroma_subsampling.HShift(c);
224
27
      const size_t ysize_c = ysize >> chroma_subsampling.VShift(c);
225
27
      if (ysize_c <= 2 || xsize_c <= 2) continue;
226
54
      for (size_t y : {static_cast<size_t>(0), ysize_c - 1}) {
227
54
        memcpy(smoothed.Row(y), dc->PlaneRow(c, y), xsize_c * sizeof(float));
228
54
      }
229
27
      auto process_row = [&](const uint32_t y, size_t /*thread*/) -> Status {
230
27
        const float* JXL_RESTRICT row_top = dc->ConstPlaneRow(c, y - 1);
231
27
        const float* JXL_RESTRICT row = dc->ConstPlaneRow(c, y);
232
27
        const float* JXL_RESTRICT row_bottom = dc->ConstPlaneRow(c, y + 1);
233
27
        float* JXL_RESTRICT row_out = smoothed.Row(y);
234
27
        for (size_t x : {static_cast<size_t>(0), xsize_c - 1}) {
235
27
          row_out[x] = row[x];
236
27
        }
237
238
27
        size_t x = 1;
239
        // First pixels
240
27
        const size_t N = Lanes(D());
241
27
        for (; x < std::min(N, xsize_c - 1); x++) {
242
27
          ComputePixelSingleChannel<DScalar>(dc_factors[c], row_top, row,
243
27
                                             row_bottom, row_out, x);
244
27
        }
245
        // Full vectors.
246
27
        for (; x + N <= xsize_c - 1; x += N) {
247
27
          ComputePixelSingleChannel<D>(dc_factors[c], row_top, row, row_bottom,
248
27
                                       row_out, x);
249
27
        }
250
        // Last pixels.
251
27
        for (; x < xsize_c - 1; x++) {
252
27
          ComputePixelSingleChannel<DScalar>(dc_factors[c], row_top, row,
253
27
                                             row_bottom, row_out, x);
254
27
        }
255
27
        return true;
256
27
      };
257
27
      JXL_RETURN_IF_ERROR(RunOnPool(pool, 1, ysize_c - 1, ThreadPool::NoInit,
258
27
                                    process_row, "DCSmoothingRow"));
259
27
      dc->Plane(c).Swap(smoothed);
260
27
    }
261
9
  }
262
7.78k
  return true;
263
7.78k
}
Unexecuted instantiation: jxl::N_AVX3::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)
Unexecuted instantiation: jxl::N_AVX3_ZEN4::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)
Unexecuted instantiation: jxl::N_AVX3_SPR::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)
Unexecuted instantiation: jxl::N_SSE2::AdaptiveDCSmoothing(JxlMemoryManagerStruct*, float const*, jxl::Image3<float>*, jxl::YCbCrChromaSubsampling const&, jxl::ThreadPool*)
264
265
// DC dequantization.
266
void DequantDC(const Rect& r, Image3F* dc, ImageB* quant_dc, const Image& in,
267
               const float* dc_factors, float mul, const float* cfl_factors,
268
               const YCbCrChromaSubsampling& chroma_subsampling,
269
80.9k
               const BlockCtxMap& bctx) {
270
80.9k
  const HWY_FULL(float) df;
271
80.9k
  const Rebind<pixel_type, HWY_FULL(float)> di;  // assumes pixel_type <= float
272
80.9k
  if (chroma_subsampling.Is444()) {
273
76.0k
    const auto fac_x = Set(df, dc_factors[0] * mul);
274
76.0k
    const auto fac_y = Set(df, dc_factors[1] * mul);
275
76.0k
    const auto fac_b = Set(df, dc_factors[2] * mul);
276
76.0k
    const auto cfl_fac_x = Set(df, cfl_factors[0]);
277
76.0k
    const auto cfl_fac_b = Set(df, cfl_factors[2]);
278
645k
    for (size_t y = 0; y < r.ysize(); y++) {
279
568k
      float* dec_row_x = r.PlaneRow(dc, 0, y);
280
568k
      float* dec_row_y = r.PlaneRow(dc, 1, y);
281
568k
      float* dec_row_b = r.PlaneRow(dc, 2, y);
282
568k
      const int32_t* quant_row_x = in.channel[1].plane.Row(y);
283
568k
      const int32_t* quant_row_y = in.channel[0].plane.Row(y);
284
568k
      const int32_t* quant_row_b = in.channel[2].plane.Row(y);
285
2.45M
      for (size_t x = 0; x < r.xsize(); x += Lanes(di)) {
286
1.88M
        const auto in_q_x = Load(di, quant_row_x + x);
287
1.88M
        const auto in_q_y = Load(di, quant_row_y + x);
288
1.88M
        const auto in_q_b = Load(di, quant_row_b + x);
289
1.88M
        const auto in_x = Mul(ConvertTo(df, in_q_x), fac_x);
290
1.88M
        const auto in_y = Mul(ConvertTo(df, in_q_y), fac_y);
291
1.88M
        const auto in_b = Mul(ConvertTo(df, in_q_b), fac_b);
292
1.88M
        Store(in_y, df, dec_row_y + x);
293
1.88M
        Store(MulAdd(in_y, cfl_fac_x, in_x), df, dec_row_x + x);
294
1.88M
        Store(MulAdd(in_y, cfl_fac_b, in_b), df, dec_row_b + x);
295
1.88M
      }
296
568k
    }
297
76.0k
  } else {
298
14.6k
    for (size_t c : {1, 0, 2}) {
299
14.6k
      Rect rect(r.x0() >> chroma_subsampling.HShift(c),
300
14.6k
                r.y0() >> chroma_subsampling.VShift(c),
301
14.6k
                r.xsize() >> chroma_subsampling.HShift(c),
302
14.6k
                r.ysize() >> chroma_subsampling.VShift(c));
303
14.6k
      const auto fac = Set(df, dc_factors[c] * mul);
304
14.6k
      const Channel& ch = in.channel[c < 2 ? c ^ 1 : c];
305
485k
      for (size_t y = 0; y < rect.ysize(); y++) {
306
470k
        const int32_t* quant_row = ch.plane.Row(y);
307
470k
        float* row = rect.PlaneRow(dc, c, y);
308
1.06M
        for (size_t x = 0; x < rect.xsize(); x += Lanes(di)) {
309
597k
          const auto in_q = Load(di, quant_row + x);
310
597k
          const auto out = Mul(ConvertTo(df, in_q), fac);
311
597k
          Store(out, df, row + x);
312
597k
        }
313
470k
      }
314
14.6k
    }
315
4.87k
  }
316
80.9k
  if (bctx.num_dc_ctxs <= 1) {
317
670k
    for (size_t y = 0; y < r.ysize(); y++) {
318
594k
      uint8_t* qdc_row = r.Row(quant_dc, y);
319
594k
      memset(qdc_row, 0, sizeof(*qdc_row) * r.xsize());
320
594k
    }
321
75.4k
  } else {
322
5.54k
    JXL_DASSERT(r.ysize() == 0 ||
323
5.54k
                (r.ysize() - 1) >> chroma_subsampling.VShift(0) <
324
5.54k
                    in.channel[1].plane.ysize());
325
5.54k
    JXL_DASSERT(r.ysize() == 0 ||
326
5.54k
                (r.ysize() - 1) >> chroma_subsampling.VShift(1) <
327
5.54k
                    in.channel[0].plane.ysize());
328
5.54k
    JXL_DASSERT(r.ysize() == 0 ||
329
5.54k
                (r.ysize() - 1) >> chroma_subsampling.VShift(2) <
330
5.54k
                    in.channel[2].plane.ysize());
331
137k
    for (size_t y = 0; y < r.ysize(); y++) {
332
132k
      uint8_t* qdc_row_val = r.Row(quant_dc, y);
333
132k
      const int32_t* quant_row_x =
334
132k
          in.channel[1].plane.Row(y >> chroma_subsampling.VShift(0));
335
132k
      const int32_t* quant_row_y =
336
132k
          in.channel[0].plane.Row(y >> chroma_subsampling.VShift(1));
337
132k
      const int32_t* quant_row_b =
338
132k
          in.channel[2].plane.Row(y >> chroma_subsampling.VShift(2));
339
1.38M
      for (size_t x = 0; x < r.xsize(); x++) {
340
1.25M
        int bucket_x = 0;
341
1.25M
        int bucket_y = 0;
342
1.25M
        int bucket_b = 0;
343
6.71M
        for (int t : bctx.dc_thresholds[0]) {
344
6.71M
          if (quant_row_x[x >> chroma_subsampling.HShift(0)] > t) bucket_x++;
345
6.71M
        }
346
1.25M
        for (int t : bctx.dc_thresholds[1]) {
347
237k
          if (quant_row_y[x >> chroma_subsampling.HShift(1)] > t) bucket_y++;
348
237k
        }
349
1.25M
        for (int t : bctx.dc_thresholds[2]) {
350
231k
          if (quant_row_b[x >> chroma_subsampling.HShift(2)] > t) bucket_b++;
351
231k
        }
352
1.25M
        int bucket = bucket_x;
353
1.25M
        bucket *= bctx.dc_thresholds[2].size() + 1;
354
1.25M
        bucket += bucket_b;
355
1.25M
        bucket *= bctx.dc_thresholds[1].size() + 1;
356
1.25M
        bucket += bucket_y;
357
1.25M
        qdc_row_val[x] = bucket;
358
1.25M
      }
359
132k
    }
360
5.54k
  }
361
80.9k
}
Unexecuted instantiation: jxl::N_SSE4::DequantDC(jxl::RectT<unsigned long> const&, jxl::Image3<float>*, jxl::Plane<unsigned char>*, jxl::Image const&, float const*, float, float const*, jxl::YCbCrChromaSubsampling const&, jxl::BlockCtxMap const&)
jxl::N_AVX2::DequantDC(jxl::RectT<unsigned long> const&, jxl::Image3<float>*, jxl::Plane<unsigned char>*, jxl::Image const&, float const*, float, float const*, jxl::YCbCrChromaSubsampling const&, jxl::BlockCtxMap const&)
Line
Count
Source
269
80.9k
               const BlockCtxMap& bctx) {
270
80.9k
  const HWY_FULL(float) df;
271
80.9k
  const Rebind<pixel_type, HWY_FULL(float)> di;  // assumes pixel_type <= float
272
80.9k
  if (chroma_subsampling.Is444()) {
273
76.0k
    const auto fac_x = Set(df, dc_factors[0] * mul);
274
76.0k
    const auto fac_y = Set(df, dc_factors[1] * mul);
275
76.0k
    const auto fac_b = Set(df, dc_factors[2] * mul);
276
76.0k
    const auto cfl_fac_x = Set(df, cfl_factors[0]);
277
76.0k
    const auto cfl_fac_b = Set(df, cfl_factors[2]);
278
645k
    for (size_t y = 0; y < r.ysize(); y++) {
279
568k
      float* dec_row_x = r.PlaneRow(dc, 0, y);
280
568k
      float* dec_row_y = r.PlaneRow(dc, 1, y);
281
568k
      float* dec_row_b = r.PlaneRow(dc, 2, y);
282
568k
      const int32_t* quant_row_x = in.channel[1].plane.Row(y);
283
568k
      const int32_t* quant_row_y = in.channel[0].plane.Row(y);
284
568k
      const int32_t* quant_row_b = in.channel[2].plane.Row(y);
285
2.45M
      for (size_t x = 0; x < r.xsize(); x += Lanes(di)) {
286
1.88M
        const auto in_q_x = Load(di, quant_row_x + x);
287
1.88M
        const auto in_q_y = Load(di, quant_row_y + x);
288
1.88M
        const auto in_q_b = Load(di, quant_row_b + x);
289
1.88M
        const auto in_x = Mul(ConvertTo(df, in_q_x), fac_x);
290
1.88M
        const auto in_y = Mul(ConvertTo(df, in_q_y), fac_y);
291
1.88M
        const auto in_b = Mul(ConvertTo(df, in_q_b), fac_b);
292
1.88M
        Store(in_y, df, dec_row_y + x);
293
1.88M
        Store(MulAdd(in_y, cfl_fac_x, in_x), df, dec_row_x + x);
294
1.88M
        Store(MulAdd(in_y, cfl_fac_b, in_b), df, dec_row_b + x);
295
1.88M
      }
296
568k
    }
297
76.0k
  } else {
298
14.6k
    for (size_t c : {1, 0, 2}) {
299
14.6k
      Rect rect(r.x0() >> chroma_subsampling.HShift(c),
300
14.6k
                r.y0() >> chroma_subsampling.VShift(c),
301
14.6k
                r.xsize() >> chroma_subsampling.HShift(c),
302
14.6k
                r.ysize() >> chroma_subsampling.VShift(c));
303
14.6k
      const auto fac = Set(df, dc_factors[c] * mul);
304
14.6k
      const Channel& ch = in.channel[c < 2 ? c ^ 1 : c];
305
485k
      for (size_t y = 0; y < rect.ysize(); y++) {
306
470k
        const int32_t* quant_row = ch.plane.Row(y);
307
470k
        float* row = rect.PlaneRow(dc, c, y);
308
1.06M
        for (size_t x = 0; x < rect.xsize(); x += Lanes(di)) {
309
597k
          const auto in_q = Load(di, quant_row + x);
310
597k
          const auto out = Mul(ConvertTo(df, in_q), fac);
311
597k
          Store(out, df, row + x);
312
597k
        }
313
470k
      }
314
14.6k
    }
315
4.87k
  }
316
80.9k
  if (bctx.num_dc_ctxs <= 1) {
317
670k
    for (size_t y = 0; y < r.ysize(); y++) {
318
594k
      uint8_t* qdc_row = r.Row(quant_dc, y);
319
594k
      memset(qdc_row, 0, sizeof(*qdc_row) * r.xsize());
320
594k
    }
321
75.4k
  } else {
322
5.54k
    JXL_DASSERT(r.ysize() == 0 ||
323
5.54k
                (r.ysize() - 1) >> chroma_subsampling.VShift(0) <
324
5.54k
                    in.channel[1].plane.ysize());
325
5.54k
    JXL_DASSERT(r.ysize() == 0 ||
326
5.54k
                (r.ysize() - 1) >> chroma_subsampling.VShift(1) <
327
5.54k
                    in.channel[0].plane.ysize());
328
5.54k
    JXL_DASSERT(r.ysize() == 0 ||
329
5.54k
                (r.ysize() - 1) >> chroma_subsampling.VShift(2) <
330
5.54k
                    in.channel[2].plane.ysize());
331
137k
    for (size_t y = 0; y < r.ysize(); y++) {
332
132k
      uint8_t* qdc_row_val = r.Row(quant_dc, y);
333
132k
      const int32_t* quant_row_x =
334
132k
          in.channel[1].plane.Row(y >> chroma_subsampling.VShift(0));
335
132k
      const int32_t* quant_row_y =
336
132k
          in.channel[0].plane.Row(y >> chroma_subsampling.VShift(1));
337
132k
      const int32_t* quant_row_b =
338
132k
          in.channel[2].plane.Row(y >> chroma_subsampling.VShift(2));
339
1.38M
      for (size_t x = 0; x < r.xsize(); x++) {
340
1.25M
        int bucket_x = 0;
341
1.25M
        int bucket_y = 0;
342
1.25M
        int bucket_b = 0;
343
6.71M
        for (int t : bctx.dc_thresholds[0]) {
344
6.71M
          if (quant_row_x[x >> chroma_subsampling.HShift(0)] > t) bucket_x++;
345
6.71M
        }
346
1.25M
        for (int t : bctx.dc_thresholds[1]) {
347
237k
          if (quant_row_y[x >> chroma_subsampling.HShift(1)] > t) bucket_y++;
348
237k
        }
349
1.25M
        for (int t : bctx.dc_thresholds[2]) {
350
231k
          if (quant_row_b[x >> chroma_subsampling.HShift(2)] > t) bucket_b++;
351
231k
        }
352
1.25M
        int bucket = bucket_x;
353
1.25M
        bucket *= bctx.dc_thresholds[2].size() + 1;
354
1.25M
        bucket += bucket_b;
355
1.25M
        bucket *= bctx.dc_thresholds[1].size() + 1;
356
1.25M
        bucket += bucket_y;
357
1.25M
        qdc_row_val[x] = bucket;
358
1.25M
      }
359
132k
    }
360
5.54k
  }
361
80.9k
}
Unexecuted instantiation: jxl::N_AVX3::DequantDC(jxl::RectT<unsigned long> const&, jxl::Image3<float>*, jxl::Plane<unsigned char>*, jxl::Image const&, float const*, float, float const*, jxl::YCbCrChromaSubsampling const&, jxl::BlockCtxMap const&)
Unexecuted instantiation: jxl::N_AVX3_ZEN4::DequantDC(jxl::RectT<unsigned long> const&, jxl::Image3<float>*, jxl::Plane<unsigned char>*, jxl::Image const&, float const*, float, float const*, jxl::YCbCrChromaSubsampling const&, jxl::BlockCtxMap const&)
Unexecuted instantiation: jxl::N_AVX3_SPR::DequantDC(jxl::RectT<unsigned long> const&, jxl::Image3<float>*, jxl::Plane<unsigned char>*, jxl::Image const&, float const*, float, float const*, jxl::YCbCrChromaSubsampling const&, jxl::BlockCtxMap const&)
Unexecuted instantiation: jxl::N_SSE2::DequantDC(jxl::RectT<unsigned long> const&, jxl::Image3<float>*, jxl::Plane<unsigned char>*, jxl::Image const&, float const*, float, float const*, jxl::YCbCrChromaSubsampling const&, jxl::BlockCtxMap const&)
362
363
// NOLINTNEXTLINE(google-readability-namespace-comments)
364
}  // namespace HWY_NAMESPACE
365
}  // namespace jxl
366
HWY_AFTER_NAMESPACE();
367
368
#if HWY_ONCE
369
namespace jxl {
370
371
HWY_EXPORT(DequantDC);
372
HWY_EXPORT(AdaptiveDCSmoothing);
373
Status AdaptiveDCSmoothing(JxlMemoryManager* memory_manager,
374
                           const float* dc_factors, Image3F* dc,
375
                           const YCbCrChromaSubsampling& chroma_subsampling,
376
53.6k
                           ThreadPool* pool) {
377
53.6k
  return HWY_DYNAMIC_DISPATCH(AdaptiveDCSmoothing)(
378
53.6k
      memory_manager, dc_factors, dc, chroma_subsampling, pool);
379
53.6k
}
380
381
void DequantDC(const Rect& r, Image3F* dc, ImageB* quant_dc, const Image& in,
382
               const float* dc_factors, float mul, const float* cfl_factors,
383
               const YCbCrChromaSubsampling& chroma_subsampling,
384
80.9k
               const BlockCtxMap& bctx) {
385
80.9k
  HWY_DYNAMIC_DISPATCH(DequantDC)
386
80.9k
  (r, dc, quant_dc, in, dc_factors, mul, cfl_factors, chroma_subsampling, bctx);
387
80.9k
}
388
389
}  // namespace jxl
390
#endif  // HWY_ONCE