KleidiCV Coverage Report


Directory: ./
File: kleidicv/include/kleidicv/filters/median_blur.h
Date: 2025-11-25 17:23:32
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 10280 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 4 times.
✓ Branch 1 taken 1380 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 1380 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 2068 times.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 2068 times.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 1880 times.
✓ Branch 10 taken 4 times.
✓ Branch 11 taken 1880 times.
✓ Branch 12 taken 4 times.
✓ Branch 13 taken 1880 times.
✓ Branch 14 taken 4 times.
✓ Branch 15 taken 1880 times.
✓ Branch 16 taken 4 times.
✓ Branch 17 taken 848 times.
✓ Branch 18 taken 4 times.
✓ Branch 19 taken 848 times.
✓ Branch 20 taken 4 times.
✓ Branch 21 taken 848 times.
✓ Branch 22 taken 4 times.
✓ Branch 23 taken 848 times.
✓ Branch 24 taken 4 times.
✓ Branch 25 taken 1348 times.
✓ Branch 26 taken 4 times.
✓ Branch 27 taken 1348 times.
10280 CHECK_POINTER_AND_STRIDE(src, src_stride, height);
155
28/28
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1376 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 1376 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 2064 times.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 2064 times.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 1876 times.
✓ Branch 10 taken 4 times.
✓ Branch 11 taken 1876 times.
✓ Branch 12 taken 4 times.
✓ Branch 13 taken 1876 times.
✓ Branch 14 taken 4 times.
✓ Branch 15 taken 1876 times.
✓ Branch 16 taken 4 times.
✓ Branch 17 taken 844 times.
✓ Branch 18 taken 4 times.
✓ Branch 19 taken 844 times.
✓ Branch 20 taken 4 times.
✓ Branch 21 taken 844 times.
✓ Branch 22 taken 4 times.
✓ Branch 23 taken 844 times.
✓ Branch 24 taken 4 times.
✓ Branch 25 taken 1344 times.
✓ Branch 26 taken 4 times.
✓ Branch 27 taken 1344 times.
10252 CHECK_POINTER_AND_STRIDE(dst, dst_stride, height);
156
42/42
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1364 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 1360 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 1360 times.
✓ Branch 6 taken 12 times.
✓ Branch 7 taken 2052 times.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 2048 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 2048 times.
✓ Branch 12 taken 12 times.
✓ Branch 13 taken 1864 times.
✓ Branch 14 taken 4 times.
✓ Branch 15 taken 1860 times.
✓ Branch 16 taken 16 times.
✓ Branch 17 taken 1860 times.
✓ Branch 18 taken 12 times.
✓ Branch 19 taken 1864 times.
✓ Branch 20 taken 4 times.
✓ Branch 21 taken 1860 times.
✓ Branch 22 taken 16 times.
✓ Branch 23 taken 1860 times.
✓ Branch 24 taken 12 times.
✓ Branch 25 taken 832 times.
✓ Branch 26 taken 4 times.
✓ Branch 27 taken 828 times.
✓ Branch 28 taken 16 times.
✓ Branch 29 taken 828 times.
✓ Branch 30 taken 12 times.
✓ Branch 31 taken 832 times.
✓ Branch 32 taken 4 times.
✓ Branch 33 taken 828 times.
✓ Branch 34 taken 16 times.
✓ Branch 35 taken 828 times.
✓ Branch 36 taken 12 times.
✓ Branch 37 taken 1332 times.
✓ Branch 38 taken 4 times.
✓ Branch 39 taken 1328 times.
✓ Branch 40 taken 16 times.
✓ Branch 41 taken 1328 times.
10224 CHECK_IMAGE_SIZE(width, height);
157 10112 return KLEIDICV_OK;
158 10280 }
159
160 template <typename T>
161 6868 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 1240 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 1228 times.
✓ Branch 3 taken 12 times.
2480 return (kernel_width == kernel_height) && (kernel_width >= 3) &&
165
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1224 times.
1228 (kernel_width <= 255) && ((kernel_width % 2) != 0);
166 } else {
167
24/24
✓ Branch 0 taken 936 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 924 times.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 1052 times.
✓ Branch 5 taken 12 times.
✓ Branch 6 taken 1040 times.
✓ Branch 7 taken 12 times.
✓ Branch 8 taken 1052 times.
✓ Branch 9 taken 12 times.
✓ Branch 10 taken 1040 times.
✓ Branch 11 taken 12 times.
✓ Branch 12 taken 800 times.
✓ Branch 13 taken 8 times.
✓ Branch 14 taken 796 times.
✓ Branch 15 taken 4 times.
✓ Branch 16 taken 800 times.
✓ Branch 17 taken 8 times.
✓ Branch 18 taken 796 times.
✓ Branch 19 taken 4 times.
✓ Branch 20 taken 916 times.
✓ Branch 21 taken 8 times.
✓ Branch 22 taken 912 times.
✓ Branch 23 taken 4 times.
11124 return (kernel_width == kernel_height) && (kernel_width >= 3) &&
168
12/12
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 892 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 992 times.
✓ Branch 4 taken 48 times.
✓ Branch 5 taken 992 times.
✓ Branch 6 taken 12 times.
✓ Branch 7 taken 784 times.
✓ Branch 8 taken 12 times.
✓ Branch 9 taken 784 times.
✓ Branch 10 taken 28 times.
✓ Branch 11 taken 884 times.
5508 (kernel_width <= 7) && ((kernel_width % 2) != 0);
169 }
170 }
171
172 template <typename T>
173 10280 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 20560 auto image_check = check_ptrs_strides_imagesizes(src, src_stride, dst,
178 10280 dst_stride, width, height);
179
14/14
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 1360 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 2048 times.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 1860 times.
✓ Branch 6 taken 24 times.
✓ Branch 7 taken 1860 times.
✓ Branch 8 taken 24 times.
✓ Branch 9 taken 828 times.
✓ Branch 10 taken 24 times.
✓ Branch 11 taken 828 times.
✓ Branch 12 taken 24 times.
✓ Branch 13 taken 1328 times.
10280 if (image_check != KLEIDICV_OK) {
180 168 return std::make_pair(image_check, FixedBorderType{});
181 }
182
183 10112 auto fixed_border_type = kleidicv::get_fixed_border_type(border_type);
184
185
28/28
✓ Branch 0 taken 1348 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 1340 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 2036 times.
✓ Branch 5 taken 12 times.
✓ Branch 6 taken 2028 times.
✓ Branch 7 taken 8 times.
✓ Branch 8 taken 1848 times.
✓ Branch 9 taken 12 times.
✓ Branch 10 taken 1840 times.
✓ Branch 11 taken 8 times.
✓ Branch 12 taken 1848 times.
✓ Branch 13 taken 12 times.
✓ Branch 14 taken 1840 times.
✓ Branch 15 taken 8 times.
✓ Branch 16 taken 820 times.
✓ Branch 17 taken 8 times.
✓ Branch 18 taken 816 times.
✓ Branch 19 taken 4 times.
✓ Branch 20 taken 820 times.
✓ Branch 21 taken 8 times.
✓ Branch 22 taken 816 times.
✓ Branch 23 taken 4 times.
✓ Branch 24 taken 1320 times.
✓ Branch 25 taken 8 times.
✓ Branch 26 taken 1316 times.
✓ Branch 27 taken 4 times.
10112 if ((src != dst) && (channels <= KLEIDICV_MAXIMUM_CHANNEL_COUNT) &&
186
28/28
✓ Branch 0 taken 1176 times.
✓ Branch 1 taken 164 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 228 times.
✓ Branch 4 taken 1704 times.
✓ Branch 5 taken 324 times.
✓ Branch 6 taken 1252 times.
✓ Branch 7 taken 452 times.
✓ Branch 8 taken 1516 times.
✓ Branch 9 taken 324 times.
✓ Branch 10 taken 1064 times.
✓ Branch 11 taken 452 times.
✓ Branch 12 taken 1516 times.
✓ Branch 13 taken 324 times.
✓ Branch 14 taken 1064 times.
✓ Branch 15 taken 452 times.
✓ Branch 16 taken 812 times.
✓ Branch 17 taken 4 times.
✓ Branch 18 taken 808 times.
✓ Branch 19 taken 4 times.
✓ Branch 20 taken 812 times.
✓ Branch 21 taken 4 times.
✓ Branch 22 taken 808 times.
✓ Branch 23 taken 4 times.
✓ Branch 24 taken 1152 times.
✓ Branch 25 taken 164 times.
✓ Branch 26 taken 924 times.
✓ Branch 27 taken 228 times.
9996 (height >= kernel_height - 1) && (width >= kernel_width - 1) &&
187
28/28
✓ Branch 0 taken 900 times.
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 892 times.
✓ Branch 4 taken 1192 times.
✓ Branch 5 taken 60 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 1184 times.
✓ Branch 8 taken 980 times.
✓ Branch 9 taken 84 times.
✓ Branch 10 taken 4 times.
✓ Branch 11 taken 976 times.
✓ Branch 12 taken 980 times.
✓ Branch 13 taken 84 times.
✓ Branch 14 taken 4 times.
✓ Branch 15 taken 976 times.
✓ Branch 16 taken 780 times.
✓ Branch 17 taken 28 times.
✓ Branch 18 taken 4 times.
✓ Branch 19 taken 776 times.
✓ Branch 20 taken 780 times.
✓ Branch 21 taken 28 times.
✓ Branch 22 taken 4 times.
✓ Branch 23 taken 776 times.
✓ Branch 24 taken 880 times.
✓ Branch 25 taken 44 times.
✓ Branch 26 taken 4 times.
✓ Branch 27 taken 876 times.
6868 is_kernel_size_supported<T>(kernel_width, kernel_height) &&
188 6492 fixed_border_type.has_value()) {
189 6456 return std::make_pair(KLEIDICV_OK, *fixed_border_type);
190 }
191
192 3656 return std::make_pair(KLEIDICV_ERROR_NOT_IMPLEMENTED, FixedBorderType{});
193 10280 }
194
195 } // namespace kleidicv
196
197 #endif // KLEIDICV_FILTERS_MEDIAN_BLUR_H
198