GCC Code Coverage Report


Directory: ./
File: tasks/marin_l_mark_components/seq/src/ops_seq.cpp
Date: 2026-04-02 17:12:27
Exec Total Coverage
Lines: 86 88 97.7%
Functions: 9 10 90.0%
Branches: 76 98 77.6%

Line Branch Exec Source
1 #include "marin_l_mark_components/seq/include/ops_seq.hpp"
2
3 #include <algorithm>
4 #include <cstddef>
5 #include <cstdint>
6 #include <vector>
7
8 #include "marin_l_mark_components/common/include/common.hpp"
9
10 namespace marin_l_mark_components {
11
12 namespace {
13
14 constexpr std::uint64_t kMaxPixels = 100000000ULL;
15
16 std::vector<int> &GetParentStorage() {
17
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
56 thread_local std::vector<int> parent_storage;
18 return parent_storage;
19 }
20
21 int FindRoot(std::vector<int> &parent, int x) {
22
7/8
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1213 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 762 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 7 times.
2003 while (parent[x] != x) {
23 21 parent[x] = parent[parent[x]];
24 x = parent[x];
25 }
26 return x;
27 }
28
29 7 void UnionLabels(std::vector<int> &parent, int a, int b) {
30 const int root_a = FindRoot(parent, a);
31 const int root_b = FindRoot(parent, b);
32
33
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if (root_a == root_b) {
34 return;
35 }
36
37
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 if (root_a < root_b) {
38 1 parent[root_b] = root_a;
39 } else {
40 6 parent[root_a] = root_b;
41 }
42 }
43
44 3776 void ProcessPixel(const Image &binary, Labels &labels, std::vector<int> &parent, int row, int col, int &next_label) {
45
2/2
✓ Branch 0 taken 1213 times.
✓ Branch 1 taken 2563 times.
3776 if (binary[row][col] == 0) {
46 3576 return;
47 }
48
49 1213 int left_label = 0;
50 1213 int top_label = 0;
51
52
2/2
✓ Branch 0 taken 1100 times.
✓ Branch 1 taken 113 times.
1213 if (col > 0) {
53 1100 left_label = labels[row][col - 1];
54 }
55
56
2/2
✓ Branch 0 taken 1092 times.
✓ Branch 1 taken 121 times.
1213 if (row > 0) {
57 1092 top_label = labels[row - 1][col];
58 }
59
60
4/4
✓ Branch 0 taken 890 times.
✓ Branch 1 taken 323 times.
✓ Branch 2 taken 762 times.
✓ Branch 3 taken 128 times.
1213 if (left_label == 0 && top_label == 0) {
61 762 labels[row][col] = next_label++;
62 762 return;
63 }
64
65
4/4
✓ Branch 0 taken 323 times.
✓ Branch 1 taken 128 times.
✓ Branch 2 taken 123 times.
✓ Branch 3 taken 200 times.
451 if (left_label != 0 && top_label == 0) {
66 123 labels[row][col] = left_label;
67 123 return;
68 }
69
70
3/4
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 200 times.
✓ Branch 2 taken 128 times.
✗ Branch 3 not taken.
328 if (left_label == 0 && top_label != 0) {
71 128 labels[row][col] = top_label;
72 128 return;
73 }
74
75 const int min_label = std::min(left_label, top_label);
76 200 labels[row][col] = min_label;
77
78
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 193 times.
200 if (left_label != top_label) {
79 7 UnionLabels(parent, left_label, top_label);
80 }
81 }
82
83 } // namespace
84
85
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 MarinLMarkComponentsSEQ::MarinLMarkComponentsSEQ(const InType &in) {
86 SetTypeOfTask(GetStaticTypeOfTask());
87 GetInput() = in;
88 48 }
89
90 bool MarinLMarkComponentsSEQ::IsBinary(const Image &img) {
91
2/4
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
448 for (const auto &row : img) {
92
2/4
✓ Branch 0 taken 3776 times.
✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4176 for (const int pixel : row) {
93
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3776 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3776 if (pixel != 0 && pixel != 1) {
94 return false;
95 }
96 }
97 }
98 return true;
99 }
100
101
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 bool MarinLMarkComponentsSEQ::ValidationImpl() {
102 const auto &img = GetInput().binary;
103
104
2/4
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
48 if (img.empty() || img.front().empty()) {
105 return false;
106 }
107
108 const std::size_t width = img.front().size();
109
110
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 48 times.
448 for (const auto &row : img) {
111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 400 times.
400 if (row.size() != width) {
112 return false;
113 }
114 }
115
116 return IsBinary(img);
117 }
118
119 48 bool MarinLMarkComponentsSEQ::PreProcessingImpl() {
120 48 binary_ = GetInput().binary;
121
122 48 const int height = static_cast<int>(binary_.size());
123 48 const int width = static_cast<int>(binary_.front().size());
124
125
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if (height <= 0 || width <= 0) {
126 return false;
127 }
128
129 48 const std::uint64_t pixels = static_cast<std::uint64_t>(height) * static_cast<std::uint64_t>(width);
130
131
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if (pixels > kMaxPixels) {
132 return false;
133 }
134
135 48 labels_.assign(static_cast<std::size_t>(height), std::vector<int>(static_cast<std::size_t>(width), 0));
136
137 48 return true;
138 }
139
140 48 bool MarinLMarkComponentsSEQ::RunImpl() {
141 48 FirstPass();
142 48 SecondPass();
143 48 return true;
144 }
145
146
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 40 times.
48 void MarinLMarkComponentsSEQ::FirstPass() {
147 48 const int height = static_cast<int>(binary_.size());
148 48 const int width = static_cast<int>(binary_.front().size());
149
150
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 40 times.
48 const int max_labels = height * width;
151
152 auto &parent = GetParentStorage();
153 48 parent.assign(static_cast<std::size_t>(max_labels) + 1ULL, 0);
154
155
2/2
✓ Branch 0 taken 3824 times.
✓ Branch 1 taken 48 times.
3872 for (int i = 0; i <= max_labels; ++i) {
156 3824 parent[i] = i;
157 }
158
159 48 int next_label = 1;
160
161
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 48 times.
448 for (int row = 0; row < height; ++row) {
162
2/2
✓ Branch 0 taken 3776 times.
✓ Branch 1 taken 400 times.
4176 for (int col = 0; col < width; ++col) {
163 3776 ProcessPixel(binary_, labels_, parent, row, col, next_label);
164 }
165 }
166
167
2/2
✓ Branch 0 taken 762 times.
✓ Branch 1 taken 48 times.
810 for (int label = 1; label < next_label; ++label) {
168 762 parent[label] = FindRoot(parent, label);
169 }
170 48 }
171
172
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 void MarinLMarkComponentsSEQ::SecondPass() {
173 48 const int height = static_cast<int>(labels_.size());
174
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 const int width = height > 0 ? static_cast<int>(labels_.front().size()) : 0;
175
176 auto &parent = GetParentStorage();
177
178 48 int max_label = 0;
179
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 48 times.
448 for (int i = 0; i < height; ++i) {
180
2/2
✓ Branch 0 taken 3776 times.
✓ Branch 1 taken 400 times.
4176 for (int j = 0; j < width; ++j) {
181
2/2
✓ Branch 0 taken 762 times.
✓ Branch 1 taken 3014 times.
4538 max_label = std::max(max_label, labels_[i][j]);
182 }
183 }
184
185
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (max_label == 0) {
186 return;
187 }
188
189 48 std::vector<int> root_to_compact(static_cast<std::size_t>(max_label + 1), 0);
190 int next_id = 1;
191
192
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 48 times.
448 for (int i = 0; i < height; ++i) {
193
2/2
✓ Branch 0 taken 3776 times.
✓ Branch 1 taken 400 times.
4176 for (int j = 0; j < width; ++j) {
194
2/2
✓ Branch 0 taken 2563 times.
✓ Branch 1 taken 1213 times.
3776 int label = labels_[i][j];
195
2/2
✓ Branch 0 taken 2563 times.
✓ Branch 1 taken 1213 times.
3776 if (label == 0) {
196 2563 continue;
197 }
198
199 const int root = FindRoot(parent, label);
200
201
2/2
✓ Branch 0 taken 755 times.
✓ Branch 1 taken 458 times.
1213 if (root_to_compact[root] == 0) {
202 755 root_to_compact[root] = next_id++;
203 }
204
205 1213 labels_[i][j] = root_to_compact[root];
206 }
207 }
208 }
209
210 48 bool MarinLMarkComponentsSEQ::PostProcessingImpl() {
211 48 OutType out;
212
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 out.labels = labels_;
213 GetOutput() = out;
214 48 return true;
215 }
216
217 } // namespace marin_l_mark_components
218