KleidiCV Coverage Report


Directory: ./
File: kleidicv/include/kleidicv/workspace/border_15x15.h
Date: 2025-09-25 14:13:34
Exec Total Coverage
Lines: 153 153 100.0%
Functions: 66 66 100.0%
Branches: 108 110 98.2%

Line Branch Exec Source
1 // SPDX-FileCopyrightText: 2024 - 2025 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_15X15_H
6 #define KLEIDICV_WORKSPACE_BORDER_15X15_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 15x15 filters.
18 template <typename T>
19 class FixedBorderInfo<T, 15UL> 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 21888 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, ptrdiff_t o9, ptrdiff_t o10, ptrdiff_t o11,
31 ptrdiff_t o12, ptrdiff_t o13, ptrdiff_t o14)
32 175104 : offsets_{o0, o1, o2, o3, o4, o5, o6, o7,
33 175104 o8, o9, o10, o11, o12, o13, o14} {}
34
35 40032 ptrdiff_t c0() const { return offsets_[0]; }
36 40032 ptrdiff_t c1() const { return offsets_[1]; }
37 40032 ptrdiff_t c2() const { return offsets_[2]; }
38 40032 ptrdiff_t c3() const { return offsets_[3]; }
39 40032 ptrdiff_t c4() const { return offsets_[4]; }
40 40032 ptrdiff_t c5() const { return offsets_[5]; }
41 40032 ptrdiff_t c6() const { return offsets_[6]; }
42 40032 ptrdiff_t c7() const { return offsets_[7]; }
43 40032 ptrdiff_t c8() const { return offsets_[8]; }
44 40032 ptrdiff_t c9() const { return offsets_[9]; }
45 40032 ptrdiff_t c10() const { return offsets_[10]; }
46 40032 ptrdiff_t c11() const { return offsets_[11]; }
47 40032 ptrdiff_t c12() const { return offsets_[12]; }
48 40032 ptrdiff_t c13() const { return offsets_[13]; }
49 40032 ptrdiff_t c14() const { return offsets_[14]; }
50
51 private:
52 ptrdiff_t offsets_[15];
53 };
54
55 192 FixedBorderInfo(size_t height, FixedBorderType border_type)
56 192 : height_(height), border_type_(border_type) {}
57
58 // Returns offsets without the influence of any border.
59 1392 Offsets offsets_without_border() const KLEIDICV_STREAMING {
60 1392 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
61 }
62
63 // NOLINTBEGIN(readability-function-cognitive-complexity)
64 // Returns offsets for columns affected by left border.
65 10248 Offsets offsets_with_left_border(size_t column_index) const
66 KLEIDICV_STREAMING {
67
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 2562 times.
✓ Branch 2 taken 2562 times.
✓ Branch 3 taken 2562 times.
✓ Branch 4 taken 2562 times.
10248 switch (border_type_) {
68 case FixedBorderType::REPLICATE:
69
2/2
✓ Branch 0 taken 2196 times.
✓ Branch 1 taken 366 times.
2562 if (column_index == 0) {
70 366 return get(0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7);
71
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1830 times.
2196 } else if (column_index == 1) {
72 366 return get(-1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7);
73
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1464 times.
1830 } else if (column_index == 2) {
74 366 return get(-2, -2, -2, -2, -2, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
75
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1098 times.
1464 } else if (column_index == 3) {
76 366 return get(-3, -3, -3, -3, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
77
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 732 times.
1098 } else if (column_index == 4) {
78 366 return get(-4, -4, -4, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
79
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 366 times.
732 } else if (column_index == 5) {
80 366 return get(-5, -5, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
81 } else {
82 366 return get(-6, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
83 }
84 break;
85
86 case FixedBorderType::REFLECT:
87
2/2
✓ Branch 0 taken 2196 times.
✓ Branch 1 taken 366 times.
2562 if (column_index == 0) {
88 366 return get(6, 5, 4, 3, 2, 1, 0, 0, 1, 2, 3, 4, 5, 6, 7);
89
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1830 times.
2196 } else if (column_index == 1) {
90 366 return get(4, 3, 2, 1, 0, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7);
91
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1464 times.
1830 } else if (column_index == 2) {
92 366 return get(2, 1, 0, -1, -2, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
93
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1098 times.
1464 } else if (column_index == 3) {
94 366 return get(0, -1, -2, -3, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
95
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 732 times.
1098 } else if (column_index == 4) {
96 366 return get(-2, -3, -4, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
97
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 366 times.
732 } else if (column_index == 5) {
98 366 return get(-4, -5, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
99 } else {
100 366 return get(-6, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
101 }
102 break;
103
104 case FixedBorderType::WRAP:
105
2/2
✓ Branch 0 taken 2196 times.
✓ Branch 1 taken 366 times.
2562 if (column_index == 0) {
106 732 return get(height_ - 7, height_ - 6, height_ - 5, height_ - 4,
107 366 height_ - 3, height_ - 2, height_ - 1, 0, 1, 2, 3, 4, 5, 6,
108 7);
109
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1830 times.
2196 } else if (column_index == 1) {
110 732 return get(height_ - 7, height_ - 6, height_ - 5, height_ - 4,
111 366 height_ - 3, height_ - 2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
112
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1464 times.
1830 } else if (column_index == 2) {
113 732 return get(height_ - 7, height_ - 6, height_ - 5, height_ - 4,
114 366 height_ - 3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
115
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1098 times.
1464 } else if (column_index == 3) {
116 366 return get(height_ - 7, height_ - 6, height_ - 5, height_ - 4, -3, -2,
117 -1, 0, 1, 2, 3, 4, 5, 6, 7);
118
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 732 times.
1098 } else if (column_index == 4) {
119 366 return get(height_ - 7, height_ - 6, height_ - 5, -4, -3, -2, -1, 0,
120 1, 2, 3, 4, 5, 6, 7);
121
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 366 times.
732 } else if (column_index == 5) {
122 366 return get(height_ - 7, height_ - 6, -5, -4, -3, -2, -1, 0, 1, 2, 3,
123 4, 5, 6, 7);
124 } else {
125 366 return get(height_ - 7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6,
126 7);
127 }
128 break;
129
130 case FixedBorderType::REVERSE:
131
2/2
✓ Branch 0 taken 2196 times.
✓ Branch 1 taken 366 times.
2562 if (column_index == 0) {
132 366 return get(7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7);
133
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1830 times.
2196 } else if (column_index == 1) {
134 366 return get(5, 4, 3, 2, 1, 0, -1, 0, 1, 2, 3, 4, 5, 6, 7);
135
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1464 times.
1830 } else if (column_index == 2) {
136 366 return get(3, 2, 1, 0, -1, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
137
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1098 times.
1464 } else if (column_index == 3) {
138 366 return get(1, 0, -1, -2, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
139
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 732 times.
1098 } else if (column_index == 4) {
140 366 return get(-1, -2, -3, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
141
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 366 times.
732 } else if (column_index == 5) {
142 366 return get(-3, -4, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
143 } else {
144 366 return get(-5, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7);
145 }
146 break;
147 }
148 // Unreachable. Compiler should emit a warning-as-error if any cases are
149 // uncovered above.
150 return Offsets{}; // GCOVR_EXCL_LINE
151 10248 }
152
153 // Returns offsets for columns affected by right border.
154 10248 Offsets offsets_with_right_border(size_t column_index) const
155 KLEIDICV_STREAMING {
156
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 2562 times.
✓ Branch 2 taken 2562 times.
✓ Branch 3 taken 2562 times.
✓ Branch 4 taken 2562 times.
10248 switch (border_type_) {
157 case FixedBorderType::REPLICATE:
158
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 2196 times.
2562 if (column_index == (height_ - 7)) {
159 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 6);
160
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1830 times.
2196 } else if (column_index == (height_ - 6)) {
161 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 5, 5);
162
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1464 times.
1830 } else if (column_index == (height_ - 5)) {
163 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 4, 4, 4);
164
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1098 times.
1464 } else if (column_index == (height_ - 4)) {
165 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 3, 3, 3, 3);
166
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 732 times.
1098 } else if (column_index == (height_ - 3)) {
167 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 2, 2, 2, 2, 2);
168
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 366 times.
732 } else if (column_index == (height_ - 2)) {
169 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 1, 1, 1, 1, 1, 1);
170 } else {
171 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 0, 0, 0, 0, 0, 0, 0);
172 }
173 break;
174
175 case FixedBorderType::REFLECT:
176
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 2196 times.
2562 if (column_index == (height_ - 7)) {
177 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 6);
178
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1830 times.
2196 } else if (column_index == (height_ - 6)) {
179 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 5, 4);
180
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1464 times.
1830 } else if (column_index == (height_ - 5)) {
181 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 4, 3, 2);
182
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1098 times.
1464 } else if (column_index == (height_ - 4)) {
183 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 3, 2, 1, 0);
184
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 732 times.
1098 } else if (column_index == (height_ - 3)) {
185 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 2, 1, 0, -1, -2);
186
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 366 times.
732 } else if (column_index == (height_ - 2)) {
187 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 1, 0, -1, -2, -3, -4);
188 } else {
189 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 0, -1, -2, -3, -4, -5, -6);
190 }
191 break;
192
193 case FixedBorderType::WRAP:
194
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 2196 times.
2562 if (column_index == (height_ - 7)) {
195 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6,
196 366 7 - height_);
197
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1830 times.
2196 } else if (column_index == (height_ - 6)) {
198 732 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6 - height_,
199 366 7 - height_);
200
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1464 times.
1830 } else if (column_index == (height_ - 5)) {
201 732 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 - height_,
202 366 6 - height_, 7 - height_);
203
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1098 times.
1464 } else if (column_index == (height_ - 4)) {
204 732 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4 - height_,
205 366 5 - height_, 6 - height_, 7 - height_);
206
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 732 times.
1098 } else if (column_index == (height_ - 3)) {
207 732 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3 - height_,
208 366 4 - height_, 5 - height_, 6 - height_, 7 - height_);
209
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 366 times.
732 } else if (column_index == (height_ - 2)) {
210 732 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2 - height_, 3 - height_,
211 366 4 - height_, 5 - height_, 6 - height_, 7 - height_);
212 } else {
213 732 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1 - height_, 2 - height_,
214 366 3 - height_, 4 - height_, 5 - height_, 6 - height_,
215 366 7 - height_);
216 }
217 break;
218
219 case FixedBorderType::REVERSE:
220
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 2196 times.
2562 if (column_index == (height_ - 7)) {
221 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 5);
222
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1830 times.
2196 } else if (column_index == (height_ - 6)) {
223 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 4, 3);
224
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1464 times.
1830 } else if (column_index == (height_ - 5)) {
225 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 3, 2, 1);
226
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1098 times.
1464 } else if (column_index == (height_ - 4)) {
227 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 2, 1, 0, -1);
228
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 732 times.
1098 } else if (column_index == (height_ - 3)) {
229 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 1, 0, -1, -2, -3);
230
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 366 times.
732 } else if (column_index == (height_ - 2)) {
231 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, 1, 0, -1, -2, -3, -4, -5);
232 } else {
233 366 return get(-7, -6, -5, -4, -3, -2, -1, 0, -1, -2, -3, -4, -5, -6, -7);
234 }
235 break;
236 }
237 // Unreachable. Compiler should emit a warning-as-error if any cases are
238 // uncovered above.
239 return Offsets{}; // GCOVR_EXCL_LINE
240 10248 }
241 // NOLINTEND(readability-function-cognitive-complexity)
242
243 // Returns offsets for rows or columns affected by any border.
244 1368 Offsets offsets_with_border(size_t row_or_column_index) const
245 KLEIDICV_STREAMING {
246
2/2
✓ Branch 0 taken 672 times.
✓ Branch 1 taken 696 times.
1368 if (row_or_column_index <= 6U) {
247 // Rows and columns have the same offsets.
248 672 return offsets_with_left_border(row_or_column_index);
249 }
250
2/2
✓ Branch 0 taken 672 times.
✓ Branch 1 taken 24 times.
696 if (row_or_column_index >= (height_ - 7U)) {
251 // Rows and columns have the same offsets.
252 672 return offsets_with_right_border(row_or_column_index);
253 }
254 24 return offsets_without_border();
255 1368 }
256
257 private:
258 // Takes care of static signed to unsigned casts.
259 21888 Offsets get(ptrdiff_t o0, ptrdiff_t o1, ptrdiff_t o2, ptrdiff_t o3,
260 ptrdiff_t o4, ptrdiff_t o5, ptrdiff_t o6, ptrdiff_t o7,
261 ptrdiff_t o8, ptrdiff_t o9, ptrdiff_t o10, ptrdiff_t o11,
262 ptrdiff_t o12, ptrdiff_t o13,
263 ptrdiff_t o14) const KLEIDICV_STREAMING {
264 43776 return Offsets{o0, o1, o2, o3, o4, o5, o6, o7,
265 21888 o8, o9, o10, o11, o12, o13, o14};
266 }
267
268 size_t height_;
269 FixedBorderType border_type_;
270 }; // end of class FixedBorderInfo<T, 15UL>
271
272 // Shorthand for 15x15 filter border type.
273 template <typename T>
274 using FixedBorderInfo15x15 = FixedBorderInfo<T, 15UL>;
275
276 } // namespace KLEIDICV_TARGET_NAMESPACE
277
278 #endif // KLEIDICV_WORKSPACE_BORDER_15X15_H
279