GCC Code Coverage Report


Directory: ./
File: tasks/dorogin_v_bin_img_conv_hull_TBB/tbb/src/ops_tbb.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 59 64 92.2%
Functions: 8 10 80.0%
Branches: 57 122 46.7%

Line Branch Exec Source
1 #include "dorogin_v_bin_img_conv_hull_TBB/tbb/include/ops_tbb.hpp"
2
3 #include <tbb/parallel_for.h>
4 #include <tbb/parallel_sort.h>
5
6 #include <algorithm>
7 #include <array>
8 #include <cstddef>
9 #include <cstdint>
10 #include <ranges>
11 #include <stack>
12 #include <utility>
13 #include <vector>
14
15 #include "dorogin_v_bin_img_conv_hull_TBB/common/include/common.hpp"
16
17 namespace dorogin_v_bin_img_conv_hull_tbb {
18 namespace {
19 constexpr std::array<std::pair<int, int>, 4> k4Connected = {{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}};
20 } // namespace
21
22
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 DoroginVImgConvHullTBB::DoroginVImgConvHullTBB(const InputType &input) {
23 SetTypeOfTask(GetStaticTypeOfTask());
24 GetInput() = input;
25 32 }
26
27 32 bool DoroginVImgConvHullTBB::ValidationImpl() {
28 const auto &input = GetInput();
29
2/4
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
32 if (input.rows <= 0 || input.cols <= 0) {
30 return false;
31 }
32 32 const size_t required_size = static_cast<size_t>(input.rows) * static_cast<size_t>(input.cols);
33 32 return input.pixels.size() == required_size;
34 }
35
36 32 bool DoroginVImgConvHullTBB::PreProcessingImpl() {
37 image_ = GetInput();
38 32 BinarizeImage();
39 GetOutput().clear();
40 32 return true;
41 }
42
43 32 bool DoroginVImgConvHullTBB::RunImpl() {
44 32 ExtractComponentsAndHulls();
45 32 return true;
46 }
47
48 32 bool DoroginVImgConvHullTBB::PostProcessingImpl() {
49 32 return true;
50 }
51
52 void DoroginVImgConvHullTBB::BinarizeImage(uint8_t threshold) {
53 auto &pixels = image_.pixels;
54 const size_t pixel_count = pixels.size();
55 tbb::parallel_for(size_t{0}, pixel_count,
56
3/4
✓ Branch 0 taken 5752 times.
✓ Branch 1 taken 296 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 32 times.
11832 [&](size_t i) { pixels[i] = pixels[i] > threshold ? uint8_t{255} : uint8_t{0}; });
57 }
58
59 44 void DoroginVImgConvHullTBB::FloodFillComponent(int row_start, int col_start, std::vector<bool> *visited,
60 std::vector<PixelPoint> *component) const {
61 std::stack<PixelPoint> stack;
62 stack.emplace(row_start, col_start);
63
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44 times.
44 (*visited)[PixelIndex(row_start, col_start, image_.cols)] = true;
64
65
2/2
✓ Branch 0 taken 296 times.
✓ Branch 1 taken 44 times.
340 while (!stack.empty()) {
66
1/2
✓ Branch 0 taken 296 times.
✗ Branch 1 not taken.
296 PixelPoint cur = stack.top();
67 stack.pop();
68 component->push_back(cur);
69
70
2/2
✓ Branch 0 taken 1184 times.
✓ Branch 1 taken 296 times.
1480 for (const auto &[dr, dc] : k4Connected) {
71 1184 const int nr = cur.row + dr;
72 1184 const int nc = cur.col + dc;
73
4/8
✓ Branch 0 taken 1184 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1184 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1184 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1184 times.
1184 if (nr < 0 || nr >= image_.rows || nc < 0 || nc >= image_.cols) {
74 continue;
75 }
76
77 const size_t idx = PixelIndex(nr, nc, image_.cols);
78
4/4
✓ Branch 0 taken 700 times.
✓ Branch 1 taken 484 times.
✓ Branch 2 taken 252 times.
✓ Branch 3 taken 448 times.
1184 if (!(*visited)[idx] && image_.pixels[idx] == 255) {
79 (*visited)[idx] = true;
80 stack.emplace(nr, nc);
81 }
82 }
83 }
84 44 }
85
86 int64_t DoroginVImgConvHullTBB::Cross(const PixelPoint &a, const PixelPoint &b, const PixelPoint &c) {
87 728 const int64_t abx = static_cast<int64_t>(b.col) - static_cast<int64_t>(a.col);
88 728 const int64_t aby = static_cast<int64_t>(b.row) - static_cast<int64_t>(a.row);
89 728 const int64_t acx = static_cast<int64_t>(c.col) - static_cast<int64_t>(a.col);
90 728 const int64_t acy = static_cast<int64_t>(c.row) - static_cast<int64_t>(a.row);
91 728 return (abx * acy) - (aby * acx);
92 }
93
94
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 32 times.
44 std::vector<PixelPoint> DoroginVImgConvHullTBB::ComputeConvexHull(const std::vector<PixelPoint> &points) {
95
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 32 times.
44 if (points.size() <= 2) {
96 12 return points;
97 }
98
99 32 std::vector<PixelPoint> ordered = points;
100
1/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
32 tbb::parallel_sort(ordered.begin(), ordered.end(), [](const PixelPoint &a, const PixelPoint &b) {
101
4/44
✗ 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 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 184 times.
✓ Branch 39 taken 68 times.
✓ Branch 40 taken 388 times.
✓ Branch 41 taken 248 times.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
888 if (a.row != b.row) {
102 572 return a.row < b.row;
103 }
104 316 return a.col < b.col;
105 });
106 const auto unique_end = std::ranges::unique(
107
3/8
✓ Branch 0 taken 184 times.
✓ Branch 1 taken 68 times.
✓ Branch 2 taken 184 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
252 ordered, [](const PixelPoint &a, const PixelPoint &b) { return a.row == b.row && a.col == b.col; });
108 ordered.erase(unique_end.begin(), unique_end.end());
109
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if (ordered.size() <= 2) {
110 return ordered;
111 }
112
113 32 std::vector<PixelPoint> lower;
114
2/2
✓ Branch 0 taken 284 times.
✓ Branch 1 taken 32 times.
316 for (const auto &p : ordered) {
115
4/4
✓ Branch 0 taken 364 times.
✓ Branch 1 taken 116 times.
✓ Branch 2 taken 196 times.
✓ Branch 3 taken 168 times.
480 while (lower.size() >= 2 && Cross(lower[lower.size() - 2], lower.back(), p) <= 0) {
116 lower.pop_back();
117 }
118 lower.push_back(p);
119 }
120
121 32 std::vector<PixelPoint> upper;
122
2/2
✓ Branch 0 taken 284 times.
✓ Branch 1 taken 32 times.
316 for (const auto &point : std::ranges::reverse_view(ordered)) {
123
4/4
✓ Branch 0 taken 364 times.
✓ Branch 1 taken 116 times.
✓ Branch 2 taken 168 times.
✓ Branch 3 taken 196 times.
480 while (upper.size() >= 2 && Cross(upper[upper.size() - 2], upper.back(), point) <= 0) {
124 upper.pop_back();
125 }
126 upper.push_back(point);
127 }
128
129 lower.pop_back();
130 upper.pop_back();
131
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 lower.insert(lower.end(), upper.begin(), upper.end());
132 return lower;
133 }
134
135 32 void DoroginVImgConvHullTBB::ExtractComponentsAndHulls() {
136 32 const size_t total = static_cast<size_t>(image_.rows) * static_cast<size_t>(image_.cols);
137 32 std::vector<bool> visited(total, false);
138 auto &hulls = GetOutput();
139
140
2/2
✓ Branch 0 taken 368 times.
✓ Branch 1 taken 32 times.
400 for (int row_idx = 0; row_idx < image_.rows; ++row_idx) {
141
2/2
✓ Branch 0 taken 6048 times.
✓ Branch 1 taken 368 times.
6416 for (int col_idx = 0; col_idx < image_.cols; ++col_idx) {
142 const size_t idx = PixelIndex(row_idx, col_idx, image_.cols);
143
4/4
✓ Branch 0 taken 296 times.
✓ Branch 1 taken 5752 times.
✓ Branch 2 taken 252 times.
✓ Branch 3 taken 44 times.
6048 if (image_.pixels[idx] != 255 || visited[idx]) {
144 6004 continue;
145 }
146
147 44 std::vector<PixelPoint> component;
148
1/2
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
44 FloodFillComponent(row_idx, col_idx, &visited, &component);
149
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 if (!component.empty()) {
150
1/4
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
88 hulls.push_back(ComputeConvexHull(component));
151 }
152 }
153 }
154 32 }
155
156 } // namespace dorogin_v_bin_img_conv_hull_tbb
157