/src/libjxl/lib/jxl/inverse_mtf-inl.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) the JPEG XL Project Authors. All rights reserved. |
2 | | // |
3 | | // Use of this source code is governed by a BSD-style |
4 | | // license that can be found in the LICENSE file. |
5 | | |
6 | | // SIMDified inverse-move-to-front transform. |
7 | | |
8 | | #if defined(LIB_JXL_INVERSE_MTF_INL_H_) == defined(HWY_TARGET_TOGGLE) |
9 | | #ifdef LIB_JXL_INVERSE_MTF_INL_H_ |
10 | | #undef LIB_JXL_INVERSE_MTF_INL_H_ |
11 | | #else |
12 | | #define LIB_JXL_INVERSE_MTF_INL_H_ |
13 | | #endif |
14 | | |
15 | | #include <hwy/highway.h> |
16 | | |
17 | | #include "lib/jxl/base/sanitizers.h" |
18 | | |
19 | | HWY_BEFORE_NAMESPACE(); |
20 | | namespace jxl { |
21 | | namespace HWY_NAMESPACE { |
22 | | |
23 | | // These templates are not found via ADL. |
24 | | using hwy::HWY_NAMESPACE::FirstN; |
25 | | using hwy::HWY_NAMESPACE::IfThenElse; |
26 | | using hwy::HWY_NAMESPACE::Load; |
27 | | using hwy::HWY_NAMESPACE::LoadU; |
28 | | using hwy::HWY_NAMESPACE::StoreU; |
29 | | |
30 | 105k | inline void MoveToFront(uint8_t* v, uint8_t index) { |
31 | 105k | uint8_t value = v[index]; |
32 | 105k | uint8_t i = index; |
33 | 105k | if (i < 4) { |
34 | 95.5k | for (; i; --i) v[i] = v[i - 1]; |
35 | 59.3k | } else { |
36 | 59.3k | const HWY_CAPPED(uint8_t, 64) d; |
37 | 59.3k | int tail = i & (Lanes(d) - 1); |
38 | 59.3k | if (tail) { |
39 | 0 | i -= tail; |
40 | 0 | const auto vec = Load(d, v + i); |
41 | 0 | const auto prev = LoadU(d, v + i + 1); |
42 | 0 | StoreU(IfThenElse(FirstN(d, tail), vec, prev), d, v + i + 1); |
43 | 0 | } |
44 | 3.89M | while (i) { |
45 | 3.83M | i -= Lanes(d); |
46 | 3.83M | const auto vec = Load(d, v + i); |
47 | 3.83M | StoreU(vec, d, v + i + 1); |
48 | 3.83M | } |
49 | 59.3k | } |
50 | 105k | v[0] = value; |
51 | 105k | } |
52 | | |
53 | 5.08k | inline void InverseMoveToFrontTransform(uint8_t* v, int v_len) { |
54 | 5.08k | HWY_ALIGN uint8_t mtf[256 + 64]; |
55 | 5.08k | int i; |
56 | 1.30M | for (i = 0; i < 256; ++i) { |
57 | 1.30M | mtf[i] = static_cast<uint8_t>(i); |
58 | 1.30M | } |
59 | | #if JXL_MEMORY_SANITIZER |
60 | | const HWY_CAPPED(uint8_t, 64) d; |
61 | | for (size_t j = 0; j < Lanes(d); ++j) { |
62 | | mtf[256 + j] = 0; |
63 | | } |
64 | | #endif // JXL_MEMORY_SANITIZER |
65 | 5.10M | for (i = 0; i < v_len; ++i) { |
66 | 5.09M | uint8_t index = v[i]; |
67 | 5.09M | v[i] = mtf[index]; |
68 | 5.09M | if (index) MoveToFront(mtf, index); |
69 | 5.09M | } |
70 | 5.08k | } |
71 | | |
72 | | // NOLINTNEXTLINE(google-readability-namespace-comments) |
73 | | } // namespace HWY_NAMESPACE |
74 | | } // namespace jxl |
75 | | HWY_AFTER_NAMESPACE(); |
76 | | |
77 | | #endif // LIB_JXL_INVERSE_MTF_INL_H_ |
78 | | |
79 | | #if HWY_ONCE |
80 | | #ifndef INVERSE_MTF_ONCE |
81 | | #define INVERSE_MTF_ONCE |
82 | | |
83 | | namespace jxl { |
84 | 5.08k | inline void InverseMoveToFrontTransform(uint8_t* v, int v_len) { |
85 | 5.08k | HWY_STATIC_DISPATCH(InverseMoveToFrontTransform)(v, v_len); |
86 | 5.08k | } |
87 | | } // namespace jxl |
88 | | |
89 | | #endif // INVERSE_MTF_ONCE |
90 | | #endif // HWY_ONCE |