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 |