KleidiCV Coverage Report


Directory: ./
File: kleidicv/src/morphology/morphology_api.cpp
Date: 2025-11-25 17:23:32
Exec Total Coverage
Lines: 30 30 100.0%
Functions: 4 4 100.0%
Branches: 40 40 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 #include "kleidicv/dispatch.h"
6 #include "kleidicv/kleidicv.h"
7 #include "kleidicv/morphology/workspace.h"
8
9 namespace kleidicv {
10
11 namespace neon {
12
13 template <typename T>
14 kleidicv_error_t dilate(const T *src, size_t src_stride, T *dst,
15 size_t dst_stride, size_t width, size_t height,
16 kleidicv_morphology_context_t *context);
17
18 template <typename T>
19 kleidicv_error_t erode(const T *src, size_t src_stride, T *dst,
20 size_t dst_stride, size_t width, size_t height,
21 kleidicv_morphology_context_t *context);
22
23 } // namespace neon
24
25 namespace sve2 {
26
27 template <typename T>
28 kleidicv_error_t dilate(const T *src, size_t src_stride, T *dst,
29 size_t dst_stride, size_t width, size_t height,
30 kleidicv_morphology_context_t *context);
31
32 template <typename T>
33 kleidicv_error_t erode(const T *src, size_t src_stride, T *dst,
34 size_t dst_stride, size_t width, size_t height,
35 kleidicv_morphology_context_t *context);
36
37 } // namespace sve2
38
39 namespace sme {
40
41 template <typename T>
42 kleidicv_error_t dilate(const T *src, size_t src_stride, T *dst,
43 size_t dst_stride, size_t width, size_t height,
44 kleidicv_morphology_context_t *context);
45
46 template <typename T>
47 kleidicv_error_t erode(const T *src, size_t src_stride, T *dst,
48 size_t dst_stride, size_t width, size_t height,
49 kleidicv_morphology_context_t *context);
50
51 } // namespace sme
52
53 namespace sme2 {
54
55 template <typename T>
56 kleidicv_error_t dilate(const T *src, size_t src_stride, T *dst,
57 size_t dst_stride, size_t width, size_t height,
58 kleidicv_morphology_context_t *context);
59
60 template <typename T>
61 kleidicv_error_t erode(const T *src, size_t src_stride, T *dst,
62 size_t dst_stride, size_t width, size_t height,
63 kleidicv_morphology_context_t *context);
64
65 } // namespace sme2
66
67 } // namespace kleidicv
68
69 extern "C" {
70
71 using KLEIDICV_TARGET_NAMESPACE::MorphologyWorkspace;
72
73 1384 kleidicv_error_t kleidicv_morphology_create(
74 kleidicv_morphology_context_t **context, kleidicv_rectangle_t kernel,
75 kleidicv_point_t anchor, kleidicv_border_type_t border_type,
76 const uint8_t *border_value, size_t channels, size_t iterations,
77 size_t type_size, kleidicv_rectangle_t image) {
78
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1380 times.
1384 CHECK_POINTERS(context);
79 1380 *context = nullptr;
80
6/6
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1376 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 1372 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 1372 times.
1380 CHECK_RECTANGLE_SIZE(kernel);
81
6/6
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1368 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 1364 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 1364 times.
1372 CHECK_RECTANGLE_SIZE(image);
82
83
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1360 times.
1364 if (type_size > KLEIDICV_MAXIMUM_TYPE_SIZE) {
84 4 return KLEIDICV_ERROR_RANGE;
85 }
86
87
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1352 times.
1360 if (channels > KLEIDICV_MAXIMUM_CHANNEL_COUNT) {
88 8 return KLEIDICV_ERROR_NOT_IMPLEMENTED;
89 }
90
91 1352 auto morphology_border_type =
92 1352 MorphologyWorkspace::get_border_type(border_type);
93
94
2/2
✓ Branch 0 taken 1332 times.
✓ Branch 1 taken 20 times.
1352 if (!morphology_border_type) {
95 20 return KLEIDICV_ERROR_NOT_IMPLEMENTED;
96 }
97
98 1332 MorphologyWorkspace::Pointer workspace;
99
6/6
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 1308 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 1308 times.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 1308 times.
2688 if (kleidicv_error_t error = MorphologyWorkspace::create(
100 1332 workspace, kernel, anchor, *morphology_border_type, border_value,
101 1332 channels, iterations, type_size, image)) {
102 24 return error;
103 }
104
105 1308 *context =
106 1308 reinterpret_cast<kleidicv_morphology_context_t *>(workspace.release());
107 1308 return KLEIDICV_OK;
108 1384 }
109
110 1312 kleidicv_error_t kleidicv_morphology_release(
111 kleidicv_morphology_context_t *context) {
112
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1308 times.
1312 CHECK_POINTERS(context);
113
114 // Deliberately create and immediately destroy a unique_ptr to delete the
115 // workspace.
116 // NOLINTBEGIN(bugprone-unused-raii)
117 1308 MorphologyWorkspace::Pointer{
118 1308 reinterpret_cast<MorphologyWorkspace *>(context)};
119 // NOLINTEND(bugprone-unused-raii)
120 1308 return KLEIDICV_OK;
121 1312 }
122
123 } // extern "C"
124
125 #define KLEIDICV_DEFINE_C_API(name, tname, type) \
126 KLEIDICV_MULTIVERSION_C_API( \
127 name, &kleidicv::neon::tname<type>, \
128 KLEIDICV_SVE2_IMPL_IF(&kleidicv::sve2::tname<type>), \
129 KLEIDICV_SME_IMPL_IF(&kleidicv::sme::tname<type>), \
130 KLEIDICV_SME2_IMPL_IF(&kleidicv::sme2::tname<type>))
131
132
6/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 1 times.
10 KLEIDICV_DEFINE_C_API(kleidicv_dilate_u8, dilate, uint8_t);
133
6/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 1 times.
10 KLEIDICV_DEFINE_C_API(kleidicv_erode_u8, erode, uint8_t);
134