KleidiCV Coverage Report


Directory: ./
File: kleidicv/include/kleidicv/resize/resize_linear.h
Date: 2026-03-05 15:57:40
Exec Total Coverage
Lines: 43 44 97.7%
Functions: 4 4 100.0%
Branches: 53 56 94.6%

Line Branch Exec Source
1 // SPDX-FileCopyrightText: 2024 - 2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 #ifndef KLEIDICV_RESIZE_RESIZE_LINEAR_H
6 #define KLEIDICV_RESIZE_RESIZE_LINEAR_H
7
8 #include <algorithm>
9 #include <array>
10 #include <cstddef>
11
12 #include "kleidicv/kleidicv.h"
13
14 #define KLEIDICV_RESIZE_MAX_WIDTH_OR_HEIGHT ((1ULL << 24) - 1)
15
16 namespace kleidicv {
17
18 1780 inline bool resize_linear_u8_is_implemented(size_t src_width, size_t src_height,
19 size_t dst_width, size_t dst_height,
20 size_t channels) {
21
2/2
✓ Branch 0 taken 1765 times.
✓ Branch 1 taken 15 times.
1780 if (src_width > KLEIDICV_RESIZE_MAX_WIDTH_OR_HEIGHT ||
22
2/2
✓ Branch 0 taken 1750 times.
✓ Branch 1 taken 15 times.
1765 src_height > KLEIDICV_RESIZE_MAX_WIDTH_OR_HEIGHT ||
23
4/4
✓ Branch 0 taken 1735 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 1720 times.
1750 dst_width > KLEIDICV_RESIZE_MAX_WIDTH_OR_HEIGHT ||
24 1735 dst_height > KLEIDICV_RESIZE_MAX_WIDTH_OR_HEIGHT) {
25 60 return false;
26 }
27
28
4/4
✓ Branch 0 taken 1715 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 1710 times.
1720 if (src_width == 0 || src_height == 0) {
29 10 return true;
30 }
31
32
2/2
✓ Branch 0 taken 545 times.
✓ Branch 1 taken 1165 times.
1710 if (channels == 1) {
33
4/4
✓ Branch 0 taken 840 times.
✓ Branch 1 taken 325 times.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 780 times.
1270 if ((src_width / 2 == dst_width || (src_width + 1) / 2 == dst_width) &&
34
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 280 times.
385 (src_height / 2 == dst_height || (src_height + 1) / 2 == dst_height)) {
35 385 return true;
36 }
37
38 780 const std::array<size_t, 2> implemented_ratios = {2, 4};
39
4/4
✓ Branch 0 taken 510 times.
✓ Branch 1 taken 270 times.
✓ Branch 2 taken 510 times.
✓ Branch 3 taken 270 times.
1560 if (std::any_of(implemented_ratios.begin(), implemented_ratios.end(),
40 2035 [&](size_t ratio) {
41
2/2
✓ Branch 0 taken 725 times.
✓ Branch 1 taken 530 times.
1785 return src_width * ratio == dst_width &&
42 530 src_height * ratio == dst_height;
43 })) {
44 510 return true;
45 }
46 780 }
47
48 // Downsize between horizontal ratios of 1/3 and 1/1: a minimal width is
49 // needed to execute vector operations
50
7/8
✓ Branch 0 taken 805 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 805 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 680 times.
✓ Branch 5 taken 125 times.
✓ Branch 6 taken 45 times.
✓ Branch 7 taken 635 times.
815 if (channels <= 3 && dst_width * 3 >= src_width && dst_width < src_width &&
51 680 dst_height < src_height) {
52
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 620 times.
635 if (dst_width < 8) {
53 15 return false;
54 }
55
4/4
✓ Branch 0 taken 320 times.
✓ Branch 1 taken 300 times.
✓ Branch 2 taken 100 times.
✓ Branch 3 taken 220 times.
620 if ((dst_width * 2 >= src_width) && (channels != 3)) {
56 220 return src_width >= 16;
57 }
58 400 return src_width >= 32;
59 }
60
61 180 return false;
62 1780 }
63
64 815 inline bool resize_linear_f32_is_implemented(size_t src_width,
65 size_t src_height,
66 size_t dst_width,
67 size_t dst_height,
68 size_t channels) {
69
2/2
✓ Branch 0 taken 810 times.
✓ Branch 1 taken 5 times.
815 if (src_width > KLEIDICV_RESIZE_MAX_WIDTH_OR_HEIGHT ||
70
2/2
✓ Branch 0 taken 805 times.
✓ Branch 1 taken 5 times.
810 src_height > KLEIDICV_RESIZE_MAX_WIDTH_OR_HEIGHT ||
71
4/4
✓ Branch 0 taken 800 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 795 times.
805 dst_width > KLEIDICV_RESIZE_MAX_WIDTH_OR_HEIGHT ||
72 800 dst_height > KLEIDICV_RESIZE_MAX_WIDTH_OR_HEIGHT) {
73 20 return false;
74 }
75
76
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 785 times.
795 if (channels != 1) {
77 10 return false;
78 }
79
80
2/4
✓ Branch 0 taken 785 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 785 times.
785 if (src_width == 0 || src_height == 0) {
81 return true;
82 }
83 785 const std::array<size_t, 3> implemented_ratios = {2, 4, 8};
84 1570 return std::any_of(implemented_ratios.begin(), implemented_ratios.end(),
85 2325 [&](size_t ratio) {
86
2/2
✓ Branch 0 taken 790 times.
✓ Branch 1 taken 750 times.
2290 return src_width * ratio == dst_width &&
87 750 src_height * ratio == dst_height;
88 });
89 815 }
90
91 namespace neon {
92 kleidicv_error_t resize_to_quarter_u8(const uint8_t *src, size_t src_stride,
93 size_t src_width, size_t src_height,
94 uint8_t *dst, size_t dst_stride,
95 size_t dst_width, size_t dst_height);
96 kleidicv_error_t kleidicv_resize_2x2_stripe_u8(
97 const uint8_t *src, size_t src_stride, size_t src_width, size_t src_height,
98 size_t y_begin, size_t y_end, uint8_t *dst, size_t dst_stride);
99 kleidicv_error_t kleidicv_resize_4x4_stripe_u8(
100 const uint8_t *src, size_t src_stride, size_t src_width, size_t src_height,
101 size_t y_begin, size_t y_end, uint8_t *dst, size_t dst_stride);
102 template <ptrdiff_t kRatio, ptrdiff_t kChannels>
103 kleidicv_error_t kleidicv_resize_generic_stripe_u8(
104 const uint8_t *src, size_t src_stride, size_t src_width, size_t src_height,
105 size_t y_begin, size_t y_end, uint8_t *dst, size_t dst_stride,
106 size_t dst_width, size_t dst_height);
107 kleidicv_error_t kleidicv_resize_linear_stripe_f32(
108 const float *src, size_t src_stride, size_t src_width, size_t src_height,
109 size_t y_begin, size_t y_end, float *dst, size_t dst_stride,
110 size_t dst_width, size_t dst_height);
111 } // namespace neon
112
113 namespace sve2 {
114 kleidicv_error_t resize_to_quarter_u8(const uint8_t *src, size_t src_stride,
115 size_t src_width, size_t src_height,
116 uint8_t *dst, size_t dst_stride,
117 size_t dst_width, size_t dst_height);
118 kleidicv_error_t kleidicv_resize_2x2_stripe_u8(
119 const uint8_t *src, size_t src_stride, size_t src_width, size_t src_height,
120 size_t y_begin, size_t y_end, uint8_t *dst, size_t dst_stride);
121 kleidicv_error_t kleidicv_resize_4x4_stripe_u8(
122 const uint8_t *src, size_t src_stride, size_t src_width, size_t src_height,
123 size_t y_begin, size_t y_end, uint8_t *dst, size_t dst_stride);
124 template <ptrdiff_t kRatio, ptrdiff_t kChannels>
125 kleidicv_error_t kleidicv_resize_generic_stripe_u8(
126 const uint8_t *src, size_t src_stride, size_t src_width, size_t src_height,
127 size_t y_begin, size_t y_end, uint8_t *dst, size_t dst_stride,
128 size_t dst_width, size_t dst_height);
129 kleidicv_error_t kleidicv_resize_linear_stripe_f32(
130 const float *src, size_t src_stride, size_t src_width, size_t src_height,
131 size_t y_begin, size_t y_end, float *dst, size_t dst_stride,
132 size_t dst_width, size_t dst_height);
133 } // namespace sve2
134
135 namespace sme {
136 kleidicv_error_t resize_to_quarter_u8(const uint8_t *src, size_t src_stride,
137 size_t src_width, size_t src_height,
138 uint8_t *dst, size_t dst_stride,
139 size_t dst_width, size_t dst_height);
140 kleidicv_error_t kleidicv_resize_2x2_stripe_u8(
141 const uint8_t *src, size_t src_stride, size_t src_width, size_t src_height,
142 size_t y_begin, size_t y_end, uint8_t *dst, size_t dst_stride);
143 kleidicv_error_t kleidicv_resize_4x4_stripe_u8(
144 const uint8_t *src, size_t src_stride, size_t src_width, size_t src_height,
145 size_t y_begin, size_t y_end, uint8_t *dst, size_t dst_stride);
146 template <ptrdiff_t kRatio, ptrdiff_t kChannels>
147 kleidicv_error_t kleidicv_resize_generic_stripe_u8(
148 const uint8_t *src, size_t src_stride, size_t src_width, size_t src_height,
149 size_t y_begin, size_t y_end, uint8_t *dst, size_t dst_stride,
150 size_t dst_width, size_t dst_height);
151 kleidicv_error_t kleidicv_resize_linear_stripe_f32(
152 const float *src, size_t src_stride, size_t src_width, size_t src_height,
153 size_t y_begin, size_t y_end, float *dst, size_t dst_stride,
154 size_t dst_width, size_t dst_height);
155 } // namespace sme
156
157 namespace sme2 {
158 kleidicv_error_t resize_to_quarter_u8(const uint8_t *src, size_t src_stride,
159 size_t src_width, size_t src_height,
160 uint8_t *dst, size_t dst_stride,
161 size_t dst_width, size_t dst_height);
162 kleidicv_error_t kleidicv_resize_2x2_stripe_u8(
163 const uint8_t *src, size_t src_stride, size_t src_width, size_t src_height,
164 size_t y_begin, size_t y_end, uint8_t *dst, size_t dst_stride);
165 kleidicv_error_t kleidicv_resize_4x4_stripe_u8(
166 const uint8_t *src, size_t src_stride, size_t src_width, size_t src_height,
167 size_t y_begin, size_t y_end, uint8_t *dst, size_t dst_stride);
168 template <ptrdiff_t kRatio, ptrdiff_t kChannels>
169 kleidicv_error_t kleidicv_resize_generic_stripe_u8(
170 const uint8_t *src, size_t src_stride, size_t src_width, size_t src_height,
171 size_t y_begin, size_t y_end, uint8_t *dst, size_t dst_stride,
172 size_t dst_width, size_t dst_height);
173 kleidicv_error_t kleidicv_resize_linear_stripe_f32(
174 const float *src, size_t src_stride, size_t src_width, size_t src_height,
175 size_t y_begin, size_t y_end, float *dst, size_t dst_stride,
176 size_t dst_width, size_t dst_height);
177 } // namespace sme2
178
179 } // namespace kleidicv
180
181 #ifdef __cplusplus
182 extern "C" {
183 #endif // __cplusplus
184 /// Internal - not part of the public API and its direct use is not supported.
185 /// It is used by the multithreaded function.
186 extern kleidicv_error_t kleidicv_resize_linear_stripe_u8(
187 const uint8_t *src, size_t src_stride, size_t src_width, size_t src_height,
188 size_t y_begin, size_t y_end, uint8_t *dst, size_t dst_stride,
189 size_t dst_width, size_t dst_height, size_t channels);
190
191 /// Internal - not part of the public API and its direct use is not
192 /// supported. It is used by the multithreaded function.
193 extern kleidicv_error_t (*kleidicv_resize_linear_stripe_f32)(
194 const float *src, size_t src_stride, size_t src_width, size_t src_height,
195 size_t y_begin, size_t y_end, float *dst, size_t dst_stride,
196 size_t dst_width, size_t dst_height);
197
198 #ifdef __cplusplus
199 } // extern "C"
200 #endif // __cplusplus
201
202 #endif // KLEIDICV_RESIZE_RESIZE_H
203