KleidiCV Coverage Report


Directory: ./
File: kleidicv/include/kleidicv/workspace/blur_and_downsample_ws.h
Date: 2025-09-25 14:13:34
Exec Total Coverage
Lines: 41 41 100.0%
Functions: 6 6 100.0%
Branches: 6 6 100.0%

Line Branch Exec Source
1 // SPDX-FileCopyrightText: 2024 - 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 #ifndef KLEIDICV_WORKSPACE_BLUR_AND_DOWNSAMPLE_WS_H
6 #define KLEIDICV_WORKSPACE_BLUR_AND_DOWNSAMPLE_WS_H
7
8 #include "separable.h"
9
10 namespace KLEIDICV_TARGET_NAMESPACE {
11
12 // Alter SeparableFilterWorkspace's behavior to only process elements in even
13 // rows and columns
14 class BlurAndDownsampleFilterWorkspace final : public SeparableFilterWorkspace {
15 public:
16 template <typename FilterType>
17 129 void process(Rectangle rect, size_t y_begin, size_t y_end,
18 Rows<const typename FilterType::SourceType> src_rows,
19 Rows<typename FilterType::DestinationType> dst_rows,
20 size_t channels, typename FilterType::BorderType border_type,
21 FilterType filter) KLEIDICV_STREAMING {
22 // Border helper which calculates border offsets.
23 258 typename FilterType::BorderInfoType vertical_border{rect.height(),
24 129 border_type};
25 258 typename FilterType::BorderInfoType horizontal_border{rect.width(),
26 129 border_type};
27
28 // Buffer rows which hold intermediate widened data.
29 258 auto buffer_rows = Rows{reinterpret_cast<typename FilterType::BufferType *>(
30 129 &data_[buffer_rows_offset_]),
31 129 buffer_rows_stride_, channels};
32
33 // Vertical processing loop.
34
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 1281 times.
1410 for (size_t vertical_index = y_begin; vertical_index < y_end;
35 1281 vertical_index += 2) {
36 // Recalculate vertical border offsets.
37 1281 auto offsets = vertical_border.offsets_with_border(vertical_index);
38 // Process in the vertical direction first.
39 2562 filter.process_vertical(rect.width(), src_rows.at(vertical_index),
40 1281 buffer_rows, offsets);
41 // Process in the horizontal direction last.
42 2562 process_horizontal(rect.width(), buffer_rows,
43 1281 dst_rows.at(vertical_index / 2), filter,
44 1281 horizontal_border);
45 1281 }
46 129 }
47
48 private:
49 template <typename FilterType>
50 1281 void process_horizontal(size_t width,
51 Rows<typename FilterType::BufferType> buffer_rows,
52 Rows<typename FilterType::DestinationType> dst_rows,
53 FilterType filter,
54 typename FilterType::BorderInfoType horizontal_border)
55 KLEIDICV_STREAMING {
56 // Margin associated with the filter.
57 1281 constexpr size_t margin = filter.margin;
58
59 // Process data affected by left border.
60 KLEIDICV_FORCE_LOOP_UNROLL
61
2/2
✓ Branch 0 taken 1281 times.
✓ Branch 1 taken 1281 times.
2562 for (size_t horizontal_index = 0; horizontal_index < margin;
62 1281 horizontal_index += 2) {
63 1281 auto offsets =
64 1281 horizontal_border.offsets_with_left_border(horizontal_index);
65 2562 filter.process_horizontal_borders(buffer_rows.at(0, horizontal_index),
66 1281 dst_rows.at(0, horizontal_index / 2),
67 1281 offsets);
68 1281 }
69
70 // Process data which is not affected by any borders in bulk.
71 {
72 1281 size_t width_without_borders = width - (2 * margin);
73 1281 auto offsets = horizontal_border.offsets_without_border();
74 1281 size_t start = align_up(margin, 2);
75 2562 filter.process_horizontal(width_without_borders, buffer_rows.at(0, start),
76 1281 dst_rows.at(0, start / 2), offsets);
77 1281 }
78
79 // Process data affected by right border.
80
2/2
✓ Branch 0 taken 1281 times.
✓ Branch 1 taken 1281 times.
2562 for (size_t index = align_up(width - margin, 2); index < width;
81 1281 index += 2) {
82 1281 auto offsets = horizontal_border.offsets_with_right_border(index);
83 2562 filter.process_horizontal_borders(buffer_rows.at(0, index),
84 1281 dst_rows.at(0, index / 2), offsets);
85 1281 }
86 1281 }
87 }; // end of class BlurAndDownsampleFilterWorkspace
88
89 // BlurAndDownsampleFilterWorkspace and SeparableFilterWorkspace must have the
90 // same size because through the API of this library only
91 // SeparableFilterWorkspace can be created. So, child classes of
92 // SeparableFilterWorkspace can only add functionality but cannot add member
93 // variables.
94 static_assert(sizeof(BlurAndDownsampleFilterWorkspace) ==
95 sizeof(SeparableFilterWorkspace));
96
97 } // namespace KLEIDICV_TARGET_NAMESPACE
98
99 #endif // KLEIDICV_WORKSPACE_BLUR_AND_DOWNSAMPLE_WS_H
100