/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 |