KleidiCV Coverage Report


Directory: ./
File: kleidicv/include/kleidicv/filters/median_blur.h
Date: 2025-09-25 14:13:34
Exec Total Coverage
Lines: 24 24 100.0%
Functions: 21 21 100.0%
Branches: 238 238 100.0%

Line Branch Exec Source
1 // SPDX-FileCopyrightText: 2023 - 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 #ifndef KLEIDICV_FILTERS_MEDIAN_BLUR_H
6 #define KLEIDICV_FILTERS_MEDIAN_BLUR_H
7
8 #include <utility>
9
10 #include "kleidicv/config.h"
11 #include "kleidicv/kleidicv.h"
12 #include "kleidicv/types.h"
13 #include "kleidicv/workspace/border_types.h"
14
15 extern "C" {
16
17 // For internal use only. See instead kleidicv_median_blur_s8.
18 // Find a median across an image.
19 // The stripe is defined by the range (y_begin, y_end].
20 KLEIDICV_API_DECLARATION(kleidicv_median_blur_sorting_network_stripe_s8,
21 const int8_t *src, size_t src_stride, int8_t *dst,
22 size_t dst_stride, size_t width, size_t height,
23 size_t y_begin, size_t y_end, size_t channels,
24 size_t kernel_width, size_t kernel_height,
25 kleidicv::FixedBorderType border_type);
26
27 // For internal use only. See instead kleidicv_median_blur_u8.
28 // Find a median across an image.
29 // The stripe is defined by the range (y_begin, y_end].
30 KLEIDICV_API_DECLARATION(kleidicv_median_blur_sorting_network_stripe_u8,
31 const uint8_t *src, size_t src_stride, uint8_t *dst,
32 size_t dst_stride, size_t width, size_t height,
33 size_t y_begin, size_t y_end, size_t channels,
34 size_t kernel_width, size_t kernel_height,
35 kleidicv::FixedBorderType border_type);
36
37 // For internal use only. See instead kleidicv_median_blur_s16.
38 // Find a median across an image.
39 // The stripe is defined by the range (y_begin, y_end].
40 KLEIDICV_API_DECLARATION(kleidicv_median_blur_sorting_network_stripe_s16,
41 const int16_t *src, size_t src_stride, int16_t *dst,
42 size_t dst_stride, size_t width, size_t height,
43 size_t y_begin, size_t y_end, size_t channels,
44 size_t kernel_width, size_t kernel_height,
45 kleidicv::FixedBorderType border_type);
46
47 // For internal use only. See instead kleidicv_median_blur_u16.
48 // Find a median across an image.
49 // The stripe is defined by the range (y_begin, y_end].
50 KLEIDICV_API_DECLARATION(kleidicv_median_blur_sorting_network_stripe_u16,
51 const uint16_t *src, size_t src_stride, uint16_t *dst,
52 size_t dst_stride, size_t width, size_t height,
53 size_t y_begin, size_t y_end, size_t channels,
54 size_t kernel_width, size_t kernel_height,
55 kleidicv::FixedBorderType border_type);
56
57 // For internal use only. See instead kleidicv_median_blur_s32.
58 // Find a median across an image.
59 // The stripe is defined by the range (y_begin, y_end].
60 KLEIDICV_API_DECLARATION(kleidicv_median_blur_sorting_network_stripe_s32,
61 const int32_t *src, size_t src_stride, int32_t *dst,
62 size_t dst_stride, size_t width, size_t height,
63 size_t y_begin, size_t y_end, size_t channels,
64 size_t kernel_width, size_t kernel_height,
65 kleidicv::FixedBorderType border_type);
66
67 // For internal use only. See instead kleidicv_median_blur_u32.
68 // Find a median across an image.
69 // The stripe is defined by the range (y_begin, y_end].
70 KLEIDICV_API_DECLARATION(kleidicv_median_blur_sorting_network_stripe_u32,
71 const uint32_t *src, size_t src_stride, uint32_t *dst,
72 size_t dst_stride, size_t width, size_t height,
73 size_t y_begin, size_t y_end, size_t channels,
74 size_t kernel_width, size_t kernel_height,
75 kleidicv::FixedBorderType border_type);
76
77 // For internal use only. See instead kleidicv_median_blur_f32.
78 // Find a median across an image.
79 // The stripe is defined by the range (y_begin, y_end].
80 KLEIDICV_API_DECLARATION(kleidicv_median_blur_sorting_network_stripe_f32,
81 const float *src, size_t src_stride, float *dst,
82 size_t dst_stride, size_t width, size_t height,
83 size_t y_begin, size_t y_end, size_t channels,
84 size_t kernel_width, size_t kernel_height,
85 kleidicv::FixedBorderType border_type);
86
87 // For internal use only. See instead kleidicv_median_blur_u8.
88 // Find a median across an image.
89 // The stripe is defined by the range (y_begin, y_end].
90 KLEIDICV_API_DECLARATION(kleidicv_median_blur_small_hist_stripe_u8,
91 const uint8_t *src, size_t src_stride, uint8_t *dst,
92 size_t dst_stride, size_t width, size_t height,
93 size_t y_begin, size_t y_end, size_t channels,
94 size_t kernel_width, size_t kernel_height,
95 kleidicv::FixedBorderType border_type);
96
97 // For internal use only. See instead kleidicv_median_blur_u8.
98 // Find a median across an image.
99 // The stripe is defined by the range (y_begin, y_end].
100 KLEIDICV_API_DECLARATION(kleidicv_median_blur_large_hist_stripe_u8,
101 const uint8_t *src, size_t src_stride, uint8_t *dst,
102 size_t dst_stride, size_t width, size_t height,
103 size_t y_begin, size_t y_end, size_t channels,
104 size_t kernel_width, size_t kernel_height,
105 kleidicv::FixedBorderType border_type);
106 }
107
108 namespace kleidicv {
109
110 namespace neon {
111 template <typename T>
112 kleidicv_error_t median_blur_sorting_network_stripe(
113 const T *src, size_t src_stride, T *dst, size_t dst_stride, size_t width,
114 size_t height, size_t y_begin, size_t y_end, size_t channels,
115 size_t kernel_width, size_t kernel_height, FixedBorderType border_type);
116
117 kleidicv_error_t median_blur_small_hist_stripe_u8(
118 const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride,
119 size_t width, size_t height, size_t y_begin, size_t y_end, size_t channels,
120 size_t kernel_width, size_t kernel_height, FixedBorderType border_type);
121
122 kleidicv_error_t median_blur_large_hist_stripe_u8(
123 const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride,
124 size_t width, size_t height, size_t y_begin, size_t y_end, size_t channels,
125 size_t kernel_width, size_t kernel_height, FixedBorderType border_type);
126 } // namespace neon
127
128 namespace sve2 {
129
130 template <typename T>
131 kleidicv_error_t median_blur_sorting_network_stripe(
132 const T *src, size_t src_stride, T *dst, size_t dst_stride, size_t width,
133 size_t height, size_t y_begin, size_t y_end, size_t channels,
134 size_t kernel_width, size_t kernel_height, FixedBorderType border_type);
135
136 } // namespace sve2
137
138 namespace sme {
139
140 template <typename T>
141 kleidicv_error_t median_blur_sorting_network_stripe(
142 const T *src, size_t src_stride, T *dst, size_t dst_stride, size_t width,
143 size_t height, size_t y_begin, size_t y_end, size_t channels,
144 size_t kernel_width, size_t kernel_height, FixedBorderType border_type);
145
146 } // namespace sme
147
148 template <typename T>
149 7710 inline kleidicv_error_t check_ptrs_strides_imagesizes(const T *src,
150 size_t src_stride, T *dst,
151 size_t dst_stride,
152 size_t width,
153 size_t height) {
154
28/28
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1035 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1035 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1551 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 1551 times.
✓ Branch 8 taken 3 times.
✓ Branch 9 taken 1410 times.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 1410 times.
✓ Branch 12 taken 3 times.
✓ Branch 13 taken 1410 times.
✓ Branch 14 taken 3 times.
✓ Branch 15 taken 1410 times.
✓ Branch 16 taken 3 times.
✓ Branch 17 taken 636 times.
✓ Branch 18 taken 3 times.
✓ Branch 19 taken 636 times.
✓ Branch 20 taken 3 times.
✓ Branch 21 taken 636 times.
✓ Branch 22 taken 3 times.
✓ Branch 23 taken 636 times.
✓ Branch 24 taken 3 times.
✓ Branch 25 taken 1011 times.
✓ Branch 26 taken 3 times.
✓ Branch 27 taken 1011 times.
7710 CHECK_POINTER_AND_STRIDE(src, src_stride, height);
155
28/28
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1032 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1032 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1548 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 1548 times.
✓ Branch 8 taken 3 times.
✓ Branch 9 taken 1407 times.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 1407 times.
✓ Branch 12 taken 3 times.
✓ Branch 13 taken 1407 times.
✓ Branch 14 taken 3 times.
✓ Branch 15 taken 1407 times.
✓ Branch 16 taken 3 times.
✓ Branch 17 taken 633 times.
✓ Branch 18 taken 3 times.
✓ Branch 19 taken 633 times.
✓ Branch 20 taken 3 times.
✓ Branch 21 taken 633 times.
✓ Branch 22 taken 3 times.
✓ Branch 23 taken 633 times.
✓ Branch 24 taken 3 times.
✓ Branch 25 taken 1008 times.
✓ Branch 26 taken 3 times.
✓ Branch 27 taken 1008 times.
7689 CHECK_POINTER_AND_STRIDE(dst, dst_stride, height);
156
42/42
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1023 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1020 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 1020 times.
✓ Branch 6 taken 9 times.
✓ Branch 7 taken 1539 times.
✓ Branch 8 taken 3 times.
✓ Branch 9 taken 1536 times.
✓ Branch 10 taken 12 times.
✓ Branch 11 taken 1536 times.
✓ Branch 12 taken 9 times.
✓ Branch 13 taken 1398 times.
✓ Branch 14 taken 3 times.
✓ Branch 15 taken 1395 times.
✓ Branch 16 taken 12 times.
✓ Branch 17 taken 1395 times.
✓ Branch 18 taken 9 times.
✓ Branch 19 taken 1398 times.
✓ Branch 20 taken 3 times.
✓ Branch 21 taken 1395 times.
✓ Branch 22 taken 12 times.
✓ Branch 23 taken 1395 times.
✓ Branch 24 taken 9 times.
✓ Branch 25 taken 624 times.
✓ Branch 26 taken 3 times.
✓ Branch 27 taken 621 times.
✓ Branch 28 taken 12 times.
✓ Branch 29 taken 621 times.
✓ Branch 30 taken 9 times.
✓ Branch 31 taken 624 times.
✓ Branch 32 taken 3 times.
✓ Branch 33 taken 621 times.
✓ Branch 34 taken 12 times.
✓ Branch 35 taken 621 times.
✓ Branch 36 taken 9 times.
✓ Branch 37 taken 999 times.
✓ Branch 38 taken 3 times.
✓ Branch 39 taken 996 times.
✓ Branch 40 taken 12 times.
✓ Branch 41 taken 996 times.
7668 CHECK_IMAGE_SIZE(width, height);
157 7584 return KLEIDICV_OK;
158 7710 }
159
160 template <typename T>
161 5151 inline bool is_kernel_size_supported(size_t kernel_width,
162 size_t kernel_height) {
163 if constexpr (std::is_same_v<T, uint8_t>) {
164
4/4
✓ Branch 0 taken 930 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 921 times.
✓ Branch 3 taken 9 times.
1860 return (kernel_width == kernel_height) && (kernel_width >= 3) &&
165
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 918 times.
921 (kernel_width <= 255) && ((kernel_width % 2) != 0);
166 } else {
167
24/24
✓ Branch 0 taken 702 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 693 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 789 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 780 times.
✓ Branch 7 taken 9 times.
✓ Branch 8 taken 789 times.
✓ Branch 9 taken 9 times.
✓ Branch 10 taken 780 times.
✓ Branch 11 taken 9 times.
✓ Branch 12 taken 600 times.
✓ Branch 13 taken 6 times.
✓ Branch 14 taken 597 times.
✓ Branch 15 taken 3 times.
✓ Branch 16 taken 600 times.
✓ Branch 17 taken 6 times.
✓ Branch 18 taken 597 times.
✓ Branch 19 taken 3 times.
✓ Branch 20 taken 687 times.
✓ Branch 21 taken 6 times.
✓ Branch 22 taken 684 times.
✓ Branch 23 taken 3 times.
8343 return (kernel_width == kernel_height) && (kernel_width >= 3) &&
168
12/12
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 669 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 744 times.
✓ Branch 4 taken 36 times.
✓ Branch 5 taken 744 times.
✓ Branch 6 taken 9 times.
✓ Branch 7 taken 588 times.
✓ Branch 8 taken 9 times.
✓ Branch 9 taken 588 times.
✓ Branch 10 taken 21 times.
✓ Branch 11 taken 663 times.
4131 (kernel_width <= 7) && ((kernel_width % 2) != 0);
169 }
170 }
171
172 template <typename T>
173 7710 inline std::pair<kleidicv_error_t, FixedBorderType> median_blur_is_implemented(
174 const T *src, size_t src_stride, T *dst, size_t dst_stride, size_t width,
175 size_t height, size_t channels, size_t kernel_width, size_t kernel_height,
176 kleidicv_border_type_t border_type) {
177 15420 auto image_check = check_ptrs_strides_imagesizes(src, src_stride, dst,
178 7710 dst_stride, width, height);
179
14/14
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1020 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 1536 times.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 1395 times.
✓ Branch 6 taken 18 times.
✓ Branch 7 taken 1395 times.
✓ Branch 8 taken 18 times.
✓ Branch 9 taken 621 times.
✓ Branch 10 taken 18 times.
✓ Branch 11 taken 621 times.
✓ Branch 12 taken 18 times.
✓ Branch 13 taken 996 times.
7710 if (image_check != KLEIDICV_OK) {
180 126 return std::make_pair(image_check, FixedBorderType{});
181 }
182
183 7584 auto fixed_border_type = kleidicv::get_fixed_border_type(border_type);
184
185
28/28
✓ Branch 0 taken 1011 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 1005 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 1527 times.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 1521 times.
✓ Branch 7 taken 6 times.
✓ Branch 8 taken 1386 times.
✓ Branch 9 taken 9 times.
✓ Branch 10 taken 1380 times.
✓ Branch 11 taken 6 times.
✓ Branch 12 taken 1386 times.
✓ Branch 13 taken 9 times.
✓ Branch 14 taken 1380 times.
✓ Branch 15 taken 6 times.
✓ Branch 16 taken 615 times.
✓ Branch 17 taken 6 times.
✓ Branch 18 taken 612 times.
✓ Branch 19 taken 3 times.
✓ Branch 20 taken 615 times.
✓ Branch 21 taken 6 times.
✓ Branch 22 taken 612 times.
✓ Branch 23 taken 3 times.
✓ Branch 24 taken 990 times.
✓ Branch 25 taken 6 times.
✓ Branch 26 taken 987 times.
✓ Branch 27 taken 3 times.
7584 if ((src != dst) && (channels <= KLEIDICV_MAXIMUM_CHANNEL_COUNT) &&
186
28/28
✓ Branch 0 taken 882 times.
✓ Branch 1 taken 123 times.
✓ Branch 2 taken 711 times.
✓ Branch 3 taken 171 times.
✓ Branch 4 taken 1278 times.
✓ Branch 5 taken 243 times.
✓ Branch 6 taken 939 times.
✓ Branch 7 taken 339 times.
✓ Branch 8 taken 1137 times.
✓ Branch 9 taken 243 times.
✓ Branch 10 taken 798 times.
✓ Branch 11 taken 339 times.
✓ Branch 12 taken 1137 times.
✓ Branch 13 taken 243 times.
✓ Branch 14 taken 798 times.
✓ Branch 15 taken 339 times.
✓ Branch 16 taken 609 times.
✓ Branch 17 taken 3 times.
✓ Branch 18 taken 606 times.
✓ Branch 19 taken 3 times.
✓ Branch 20 taken 609 times.
✓ Branch 21 taken 3 times.
✓ Branch 22 taken 606 times.
✓ Branch 23 taken 3 times.
✓ Branch 24 taken 864 times.
✓ Branch 25 taken 123 times.
✓ Branch 26 taken 693 times.
✓ Branch 27 taken 171 times.
7497 (height >= kernel_height - 1) && (width >= kernel_width - 1) &&
187
28/28
✓ Branch 0 taken 675 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 669 times.
✓ Branch 4 taken 894 times.
✓ Branch 5 taken 45 times.
✓ Branch 6 taken 6 times.
✓ Branch 7 taken 888 times.
✓ Branch 8 taken 735 times.
✓ Branch 9 taken 63 times.
✓ Branch 10 taken 3 times.
✓ Branch 11 taken 732 times.
✓ Branch 12 taken 735 times.
✓ Branch 13 taken 63 times.
✓ Branch 14 taken 3 times.
✓ Branch 15 taken 732 times.
✓ Branch 16 taken 585 times.
✓ Branch 17 taken 21 times.
✓ Branch 18 taken 3 times.
✓ Branch 19 taken 582 times.
✓ Branch 20 taken 585 times.
✓ Branch 21 taken 21 times.
✓ Branch 22 taken 3 times.
✓ Branch 23 taken 582 times.
✓ Branch 24 taken 660 times.
✓ Branch 25 taken 33 times.
✓ Branch 26 taken 3 times.
✓ Branch 27 taken 657 times.
5151 is_kernel_size_supported<T>(kernel_width, kernel_height) &&
188 4869 fixed_border_type.has_value()) {
189 4842 return std::make_pair(KLEIDICV_OK, *fixed_border_type);
190 }
191
192 2742 return std::make_pair(KLEIDICV_ERROR_NOT_IMPLEMENTED, FixedBorderType{});
193 7710 }
194
195 } // namespace kleidicv
196
197 #endif // KLEIDICV_FILTERS_MEDIAN_BLUR_H
198