GCC Code Coverage Report


Directory: ./
File: tasks/dorogin_v_bin_img_conv_hull_OMP/omp/src/ops_omp.cpp
Date: 2026-04-02 17:12:27
Exec Total Coverage
Lines: 77 78 98.7%
Functions: 8 8 100.0%
Branches: 69 120 57.5%

Line Branch Exec Source
1 #include "dorogin_v_bin_img_conv_hull_OMP/omp/include/ops_omp.hpp"
2
3 #include <algorithm>
4 #include <array>
5 #include <cstddef>
6 #include <cstdint>
7 #include <ranges>
8 #include <utility>
9 #include <vector>
10
11 #include "dorogin_v_bin_img_conv_hull_OMP/common/include/common.hpp"
12
13 namespace dorogin_v_bin_img_conv_hull_omp {
14
15 namespace {
16
17 std::size_t Index(int x, int y, int w) {
18
4/4
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 444 times.
✓ Branch 2 taken 344 times.
✓ Branch 3 taken 496 times.
1392 return (static_cast<std::size_t>(y) * static_cast<std::size_t>(w)) + static_cast<std::size_t>(x);
19 }
20
21 bool Inside(int x, int y, int w, int h) {
22 1716 return (x >= 0) && (y >= 0) && (x < w) && (y < h);
23 }
24
25 20 ComponentHull CollectOneComponent(const BinaryImage &img, std::vector<std::uint8_t> &visited, int w, int h, int start_x,
26 int start_y, const std::array<int, 8> &dx, const std::array<int, 8> &dy) {
27 20 ComponentHull pixels;
28
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 pixels.reserve(64);
29
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 std::vector<Point> stack;
30 const std::size_t start_id = Index(start_x, start_y, w);
31 20 visited[start_id] = 1U;
32
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 stack.push_back(Point{.x = start_x, .y = start_y});
33
34
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 20 times.
128 while (!stack.empty()) {
35
1/2
✓ Branch 0 taken 108 times.
✗ Branch 1 not taken.
108 const Point p = stack.back();
36 stack.pop_back();
37 pixels.push_back(p);
38
39
2/2
✓ Branch 0 taken 864 times.
✓ Branch 1 taken 108 times.
972 for (int dir = 0; dir < 8; ++dir) {
40 864 const int nx = p.x + dx.at(static_cast<std::size_t>(dir));
41
2/2
✓ Branch 0 taken 852 times.
✓ Branch 1 taken 12 times.
864 const int ny = p.y + dy.at(static_cast<std::size_t>(dir));
42
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 840 times.
852 if (!Inside(nx, ny, w, h)) {
43 24 continue;
44 }
45 const std::size_t nid = Index(nx, ny, w);
46
4/4
✓ Branch 0 taken 344 times.
✓ Branch 1 taken 496 times.
✓ Branch 2 taken 88 times.
✓ Branch 3 taken 256 times.
840 if (img.data[nid] == 0 || visited[nid] != 0U) {
47 752 continue;
48 }
49 88 visited[nid] = 1U;
50
1/4
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
88 stack.push_back(Point{.x = nx, .y = ny});
51 }
52 }
53
54 20 return pixels;
55 }
56
57 20 std::vector<ComponentHull> CollectComponents(const BinaryImage &img) {
58 20 const int w = img.width;
59 20 const int h = img.height;
60 20 const std::size_t n = static_cast<std::size_t>(w) * static_cast<std::size_t>(h);
61
62 20 std::vector<std::uint8_t> visited(n, 0U);
63 20 std::vector<ComponentHull> components;
64
65 20 const std::array<int, 8> dx = {1, 1, 0, -1, -1, -1, 0, 1};
66 20 const std::array<int, 8> dy = {0, 1, 1, 1, 0, -1, -1, -1};
67
68
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 20 times.
112 for (int yy = 0; yy < h; ++yy) {
69
2/2
✓ Branch 0 taken 552 times.
✓ Branch 1 taken 92 times.
644 for (int xx = 0; xx < w; ++xx) {
70 const std::size_t id = Index(xx, yy, w);
71
4/4
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 444 times.
✓ Branch 2 taken 88 times.
✓ Branch 3 taken 20 times.
552 if (img.data[id] == 0 || visited[id] != 0U) {
72 532 continue;
73 }
74
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 ComponentHull pixels = CollectOneComponent(img, visited, w, h, xx, yy, dx, dy);
75
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (!pixels.empty()) {
76 components.push_back(std::move(pixels));
77 }
78 }
79 }
80
81 20 return components;
82 }
83
84 std::int64_t Cross(const Point &o, const Point &a, const Point &b) {
85 184 const std::int64_t x1 = static_cast<std::int64_t>(a.x) - static_cast<std::int64_t>(o.x);
86 184 const std::int64_t y1 = static_cast<std::int64_t>(a.y) - static_cast<std::int64_t>(o.y);
87 184 const std::int64_t x2 = static_cast<std::int64_t>(b.x) - static_cast<std::int64_t>(o.x);
88 184 const std::int64_t y2 = static_cast<std::int64_t>(b.y) - static_cast<std::int64_t>(o.y);
89 184 return (x1 * y2) - (y1 * x2);
90 }
91
92
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 16 times.
20 ComponentHull BuildHull(ComponentHull pts) {
93
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 16 times.
20 if (pts.size() <= 1) {
94 return pts;
95 }
96
97 std::ranges::sort(pts, [](const Point &a, const Point &b) {
98
4/26
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 56 times.
✓ Branch 23 taken 32 times.
✓ Branch 24 taken 100 times.
✓ Branch 25 taken 76 times.
264 if (a.x != b.x) {
99 156 return a.x < b.x;
100 }
101 108 return a.y < b.y;
102 });
103 const auto uniq_result =
104
3/8
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 60 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
88 std::ranges::unique(pts, [](const Point &a, const Point &b) { return (a.x == b.x) && (a.y == b.y); });
105 pts.erase(uniq_result.end(), pts.end());
106
107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (pts.size() <= 1) {
108 return pts;
109 }
110
111
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 ComponentHull lower;
112
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 lower.reserve(pts.size());
113
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 16 times.
120 for (const auto &p : pts) {
114
4/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 76 times.
✓ Branch 2 taken 64 times.
✓ Branch 3 taken 28 times.
168 while (lower.size() >= 2 && Cross(lower[lower.size() - 2], lower[lower.size() - 1], p) <= 0) {
115 lower.pop_back();
116 }
117 lower.push_back(p);
118 }
119
120
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 ComponentHull upper;
121
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 upper.reserve(pts.size());
122
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 16 times.
120 for (std::size_t i = pts.size(); i-- > 0;) {
123 const Point &p = pts[i];
124
4/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 76 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 64 times.
168 while (upper.size() >= 2 && Cross(upper[upper.size() - 2], upper[upper.size() - 1], p) <= 0) {
125 upper.pop_back();
126 }
127 upper.push_back(p);
128 }
129
130
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (!lower.empty()) {
131 lower.pop_back();
132 }
133
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (!upper.empty()) {
134 upper.pop_back();
135 }
136
137
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 lower.insert(lower.end(), upper.begin(), upper.end());
138 return lower;
139 }
140
141 } // namespace
142
143
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 DoroginVBinImgConvHullOMP::DoroginVBinImgConvHullOMP(const InType &in) {
144 SetTypeOfTask(GetStaticTypeOfTask());
145 GetInput() = in;
146 GetOutput().clear();
147 20 }
148
149 40 bool DoroginVBinImgConvHullOMP::ValidationImpl() {
150 const auto &img = GetInput();
151
2/4
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
40 if (img.width <= 0 || img.height <= 0) {
152 return false;
153 }
154 40 const std::size_t required = static_cast<std::size_t>(img.width) * static_cast<std::size_t>(img.height);
155 40 return img.data.size() == required;
156 }
157
158
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 bool DoroginVBinImgConvHullOMP::PreProcessingImpl() {
159 GetOutput().clear();
160 20 return true;
161 }
162
163 20 bool DoroginVBinImgConvHullOMP::RunImpl() {
164
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 if (!ValidationImpl()) {
165 return false;
166 }
167
168 20 auto components = CollectComponents(GetInput());
169
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 OutType hulls;
170
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 hulls.resize(components.size());
171
172 20 const int count = static_cast<int>(components.size());
173
174 20 #pragma omp parallel for default(none) shared(components, hulls, count)
175 for (int i = 0; i < count; ++i) {
176 const auto idx = static_cast<std::size_t>(i);
177 hulls[idx] = BuildHull(std::move(components[idx]));
178 }
179
180 20 GetOutput() = std::move(hulls);
181 return true;
182 20 }
183
184 20 bool DoroginVBinImgConvHullOMP::PostProcessingImpl() {
185 20 return true;
186 }
187
188 } // namespace dorogin_v_bin_img_conv_hull_omp
189