KleidiCV Coverage Report


Directory: ./
File: kleidicv/include/kleidicv/workspace/border_9x9.h
Date: 2026-03-05 15:57:40
Exec Total Coverage
Lines: 88 88 100.0%
Functions: 48 48 100.0%
Branches: 60 62 96.8%

Line Branch Exec Source
1 // SPDX-FileCopyrightText: 2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 #ifndef KLEIDICV_WORKSPACE_BORDER_9X9_H
6 #define KLEIDICV_WORKSPACE_BORDER_9X9_H
7
8 #include "border_types.h"
9 #include "kleidicv/kleidicv.h"
10
11 namespace KLEIDICV_TARGET_NAMESPACE {
12
13 // Border offsets for fixed-size filters.
14 template <typename T, const size_t S>
15 class FixedBorderInfo;
16
17 // Border offsets for 9x9 filters.
18 template <typename T>
19 class FixedBorderInfo<T, 9UL> final {
20 public:
21 // Simple object holding read-only constant offsets.
22 class Offsets final {
23 public:
24 // NOLINTBEGIN(hicpp-member-init)
25 Offsets() = default;
26 // NOLINTEND(hicpp-member-init)
27
28 24480 Offsets(ptrdiff_t o0, ptrdiff_t o1, ptrdiff_t o2, ptrdiff_t o3,
29 ptrdiff_t o4, ptrdiff_t o5, ptrdiff_t o6, ptrdiff_t o7,
30 ptrdiff_t o8)
31 24480 : offsets_{o0, o1, o2, o3, o4, o5, o6, o7, o8} {}
32
33 35032 ptrdiff_t c0() const { return offsets_[0]; }
34 35032 ptrdiff_t c1() const { return offsets_[1]; }
35 35032 ptrdiff_t c2() const { return offsets_[2]; }
36 35032 ptrdiff_t c3() const { return offsets_[3]; }
37 35032 ptrdiff_t c4() const { return offsets_[4]; }
38 35032 ptrdiff_t c5() const { return offsets_[5]; }
39 35032 ptrdiff_t c6() const { return offsets_[6]; }
40 35032 ptrdiff_t c7() const { return offsets_[7]; }
41 35032 ptrdiff_t c8() const { return offsets_[8]; }
42
43 private:
44 ptrdiff_t offsets_[9];
45 };
46
47 544 FixedBorderInfo(size_t height, FixedBorderType border_type)
48 544 : height_(height), border_type_(border_type) {}
49
50 // Returns offsets without the influence of any border.
51 3104 Offsets offsets_without_border() const KLEIDICV_STREAMING {
52 3104 return get(-4, -3, -2, -1, 0, 1, 2, 3, 4);
53 }
54
55 // Returns offsets for columns affected by left border.
56 10688 Offsets offsets_with_left_border(size_t column_index) const
57 KLEIDICV_STREAMING {
58
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5120 times.
✓ Branch 2 taken 1760 times.
✓ Branch 3 taken 1760 times.
✓ Branch 4 taken 2048 times.
10688 switch (border_type_) {
59 case FixedBorderType::REPLICATE:
60
2/2
✓ Branch 0 taken 3840 times.
✓ Branch 1 taken 1280 times.
5120 if (column_index == 0) {
61 1280 return get(0, 0, 0, 0, 0, 1, 2, 3, 4);
62
2/2
✓ Branch 0 taken 1280 times.
✓ Branch 1 taken 2560 times.
3840 } else if (column_index == 1) {
63 1280 return get(-1, -1, -1, -1, 0, 1, 2, 3, 4);
64
2/2
✓ Branch 0 taken 1280 times.
✓ Branch 1 taken 1280 times.
2560 } else if (column_index == 2) {
65 1280 return get(-2, -2, -2, -1, 0, 1, 2, 3, 4);
66 } else {
67 1280 return get(-3, -3, -2, -1, 0, 1, 2, 3, 4);
68 }
69 break;
70
71 case FixedBorderType::REFLECT:
72
2/2
✓ Branch 0 taken 1320 times.
✓ Branch 1 taken 440 times.
1760 if (column_index == 0) {
73 440 return get(3, 2, 1, 0, 0, 1, 2, 3, 4);
74
2/2
✓ Branch 0 taken 440 times.
✓ Branch 1 taken 880 times.
1320 } else if (column_index == 1) {
75 440 return get(1, 0, -1, -1, 0, 1, 2, 3, 4);
76
2/2
✓ Branch 0 taken 440 times.
✓ Branch 1 taken 440 times.
880 } else if (column_index == 2) {
77 440 return get(-1, -2, -2, -1, 0, 1, 2, 3, 4);
78 } else {
79 440 return get(-3, -3, -2, -1, 0, 1, 2, 3, 4);
80 }
81 break;
82
83 case FixedBorderType::WRAP:
84
2/2
✓ Branch 0 taken 1320 times.
✓ Branch 1 taken 440 times.
1760 if (column_index == 0) {
85 440 return get(height_ - 4, height_ - 3, height_ - 2, height_ - 1, 0, 1,
86 2, 3, 4);
87
2/2
✓ Branch 0 taken 440 times.
✓ Branch 1 taken 880 times.
1320 } else if (column_index == 1) {
88 440 return get(height_ - 4, height_ - 3, height_ - 2, -1, 0, 1, 2, 3, 4);
89
2/2
✓ Branch 0 taken 440 times.
✓ Branch 1 taken 440 times.
880 } else if (column_index == 2) {
90 440 return get(height_ - 4, height_ - 3, -2, -1, 0, 1, 2, 3, 4);
91 } else {
92 440 return get(height_ - 4, -3, -2, -1, 0, 1, 2, 3, 4);
93 }
94 break;
95
96 case FixedBorderType::REVERSE:
97
2/2
✓ Branch 0 taken 1536 times.
✓ Branch 1 taken 512 times.
2048 if (column_index == 0) {
98 512 return get(4, 3, 2, 1, 0, 1, 2, 3, 4);
99
2/2
✓ Branch 0 taken 512 times.
✓ Branch 1 taken 1024 times.
1536 } else if (column_index == 1) {
100 512 return get(2, 1, 0, -1, 0, 1, 2, 3, 4);
101
2/2
✓ Branch 0 taken 512 times.
✓ Branch 1 taken 512 times.
1024 } else if (column_index == 2) {
102 512 return get(0, -1, -2, -1, 0, 1, 2, 3, 4);
103 } else {
104 512 return get(-2, -3, -2, -1, 0, 1, 2, 3, 4);
105 }
106 break;
107 }
108 // Unreachable. Compiler should emit a warning-as-error if any cases are
109 // uncovered above.
110 return Offsets{}; // GCOVR_EXCL_LINE
111 10688 }
112
113 // Returns offsets for columns affected by right border.
114 10688 Offsets offsets_with_right_border(size_t column_index) const
115 KLEIDICV_STREAMING {
116
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5120 times.
✓ Branch 2 taken 1760 times.
✓ Branch 3 taken 1760 times.
✓ Branch 4 taken 2048 times.
10688 switch (border_type_) {
117 case FixedBorderType::REPLICATE:
118
2/2
✓ Branch 0 taken 1280 times.
✓ Branch 1 taken 3840 times.
5120 if (column_index == (height_ - 4)) {
119 1280 return get(-4, -3, -2, -1, 0, 1, 2, 3, 3);
120
2/2
✓ Branch 0 taken 1280 times.
✓ Branch 1 taken 2560 times.
3840 } else if (column_index == (height_ - 3)) {
121 1280 return get(-4, -3, -2, -1, 0, 1, 2, 2, 2);
122
2/2
✓ Branch 0 taken 1280 times.
✓ Branch 1 taken 1280 times.
2560 } else if (column_index == (height_ - 2)) {
123 1280 return get(-4, -3, -2, -1, 0, 1, 1, 1, 1);
124 } else {
125 1280 return get(-4, -3, -2, -1, 0, 0, 0, 0, 0);
126 }
127 break;
128
129 case FixedBorderType::REFLECT:
130
2/2
✓ Branch 0 taken 440 times.
✓ Branch 1 taken 1320 times.
1760 if (column_index == (height_ - 4)) {
131 440 return get(-4, -3, -2, -1, 0, 1, 2, 3, 3);
132
2/2
✓ Branch 0 taken 440 times.
✓ Branch 1 taken 880 times.
1320 } else if (column_index == (height_ - 3)) {
133 440 return get(-4, -3, -2, -1, 0, 1, 2, 2, 1);
134
2/2
✓ Branch 0 taken 440 times.
✓ Branch 1 taken 440 times.
880 } else if (column_index == (height_ - 2)) {
135 440 return get(-4, -3, -2, -1, 0, 1, 1, 0, -1);
136 } else {
137 440 return get(-4, -3, -2, -1, 0, 0, -1, -2, -3);
138 }
139 break;
140
141 case FixedBorderType::WRAP:
142
2/2
✓ Branch 0 taken 440 times.
✓ Branch 1 taken 1320 times.
1760 if (column_index == (height_ - 4)) {
143 440 return get(-4, -3, -2, -1, 0, 1, 2, 3, 4 - height_);
144
2/2
✓ Branch 0 taken 440 times.
✓ Branch 1 taken 880 times.
1320 } else if (column_index == (height_ - 3)) {
145 440 return get(-4, -3, -2, -1, 0, 1, 2, 3 - height_, 4 - height_);
146
2/2
✓ Branch 0 taken 440 times.
✓ Branch 1 taken 440 times.
880 } else if (column_index == (height_ - 2)) {
147 880 return get(-4, -3, -2, -1, 0, 1, 2 - height_, 3 - height_,
148 440 4 - height_);
149 } else {
150 880 return get(-4, -3, -2, -1, 0, 1 - height_, 2 - height_, 3 - height_,
151 440 4 - height_);
152 }
153 break;
154
155 case FixedBorderType::REVERSE:
156
2/2
✓ Branch 0 taken 512 times.
✓ Branch 1 taken 1536 times.
2048 if (column_index == (height_ - 4)) {
157 512 return get(-4, -3, -2, -1, 0, 1, 2, 3, 2);
158
2/2
✓ Branch 0 taken 512 times.
✓ Branch 1 taken 1024 times.
1536 } else if (column_index == (height_ - 3)) {
159 512 return get(-4, -3, -2, -1, 0, 1, 2, 1, 0);
160
2/2
✓ Branch 0 taken 512 times.
✓ Branch 1 taken 512 times.
1024 } else if (column_index == (height_ - 2)) {
161 512 return get(-4, -3, -2, -1, 0, 1, 0, -1, -2);
162 } else {
163 512 return get(-4, -3, -2, -1, 0, -1, -2, -3, -4);
164 }
165 break;
166 }
167 // Unreachable. Compiler should emit a warning-as-error if any cases are
168 // uncovered above.
169 return Offsets{}; // GCOVR_EXCL_LINE
170 10688 }
171
172 // Returns offsets for rows or columns affected by any border.
173 2448 Offsets offsets_with_border(size_t row_or_column_index) const
174 KLEIDICV_STREAMING {
175
2/2
✓ Branch 0 taken 896 times.
✓ Branch 1 taken 1552 times.
2448 if (row_or_column_index <= 3U) {
176 // Rows and columns have the same offsets.
177 896 return offsets_with_left_border(row_or_column_index);
178 }
179
2/2
✓ Branch 0 taken 896 times.
✓ Branch 1 taken 656 times.
1552 if (row_or_column_index >= (height_ - 4U)) {
180 // Rows and columns have the same offsets.
181 896 return offsets_with_right_border(row_or_column_index);
182 }
183 656 return offsets_without_border();
184 2448 }
185
186 private:
187 // Takes care of static signed to unsigned casts.
188 24480 Offsets get(ptrdiff_t o0, ptrdiff_t o1, ptrdiff_t o2, ptrdiff_t o3,
189 ptrdiff_t o4, ptrdiff_t o5, ptrdiff_t o6, ptrdiff_t o7,
190 ptrdiff_t o8) const KLEIDICV_STREAMING {
191 24480 return Offsets{o0, o1, o2, o3, o4, o5, o6, o7, o8};
192 }
193
194 size_t height_;
195 FixedBorderType border_type_;
196 }; // end of class FixedBorderInfo<T, 9UL>
197
198 // Shorthand for 9x9 filter border type.
199 template <typename T>
200 using FixedBorderInfo9x9 = FixedBorderInfo<T, 9UL>;
201
202 } // namespace KLEIDICV_TARGET_NAMESPACE
203
204 #endif // KLEIDICV_WORKSPACE_BORDER_9X9_H
205