GCC Code Coverage Report


Directory: ./
File: tasks/paramonov_v_bin_img_conv_hul_tbb/tbb/src/ops_tbb.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 68 72 94.4%
Functions: 10 12 83.3%
Branches: 57 78 73.1%

Line Branch Exec Source
1 #include "paramonov_v_bin_img_conv_hul_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 <iterator>
11 #include <stack>
12 #include <utility>
13 #include <vector>
14
15 #include "paramonov_v_bin_img_conv_hul_tbb/common/include/common.hpp"
16
17 namespace paramonov_v_bin_img_conv_hul_tbb {
18
19 namespace {
20 constexpr std::array<std::pair<int, int>, 4> kNeighbors = {{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}};
21
22 252 bool ComparePoints(const PixelPoint &a, const PixelPoint &b) {
23
2/2
✓ Branch 0 taken 184 times.
✓ Branch 1 taken 68 times.
252 if (a.row != b.row) {
24 184 return a.row < b.row;
25 }
26 68 return a.col < b.col;
27 }
28
29 } // namespace
30
31
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 ConvexHullTBB::ConvexHullTBB(const InputType &input) {
32 SetTypeOfTask(GetStaticTypeOfTask());
33 GetInput() = input;
34 32 }
35
36 32 bool ConvexHullTBB::ValidationImpl() {
37 const auto &img = GetInput();
38
2/4
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
32 if (img.rows <= 0 || img.cols <= 0) {
39 return false;
40 }
41
42 32 const size_t expected_size = static_cast<size_t>(img.rows) * static_cast<size_t>(img.cols);
43 32 return img.pixels.size() == expected_size;
44 }
45
46 32 bool ConvexHullTBB::PreProcessingImpl() {
47 working_image_ = GetInput();
48 BinarizeImage();
49 GetOutput().clear();
50 32 return true;
51 }
52
53 32 bool ConvexHullTBB::RunImpl() {
54 32 ExtractConnectedComponents();
55 32 return true;
56 }
57
58 32 bool ConvexHullTBB::PostProcessingImpl() {
59 32 return true;
60 }
61
62 void ConvexHullTBB::BinarizeImage(uint8_t threshold) {
63 const size_t size = working_image_.pixels.size();
64 auto &pixels = working_image_.pixels;
65
66 // Исправлено: используем static_cast вместо C-style cast
67 tbb::parallel_for(static_cast<size_t>(0), size,
68
5/6
✓ Branch 0 taken 761 times.
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 4991 times.
✓ Branch 3 taken 248 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 32 times.
11832 [&pixels, threshold](size_t i) { pixels[i] = pixels[i] > threshold ? uint8_t{255} : uint8_t{0}; });
69 }
70
71 44 void ConvexHullTBB::FloodFill(int start_row, int start_col, std::vector<bool> &visited,
72 std::vector<PixelPoint> &component) const {
73 std::stack<PixelPoint> pixel_stack;
74 pixel_stack.emplace(start_row, start_col);
75
76 44 const int rows = working_image_.rows;
77 44 const int cols = working_image_.cols;
78
79
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44 times.
44 visited[PixelIndex(start_row, start_col, cols)] = true;
80
81
2/2
✓ Branch 0 taken 296 times.
✓ Branch 1 taken 44 times.
340 while (!pixel_stack.empty()) {
82
1/2
✓ Branch 0 taken 296 times.
✗ Branch 1 not taken.
296 PixelPoint current = pixel_stack.top();
83 pixel_stack.pop();
84
85 component.push_back(current);
86
87
2/2
✓ Branch 0 taken 1184 times.
✓ Branch 1 taken 296 times.
1480 for (const auto &[dr, dc] : kNeighbors) {
88 1184 int next_row = current.row + dr;
89 1184 int next_col = current.col + dc;
90
91
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 taken 1184 times.
✗ Branch 7 not taken.
1184 if (next_row >= 0 && next_row < rows && next_col >= 0 && next_col < cols) {
92 size_t idx = PixelIndex(next_row, next_col, cols);
93
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] && working_image_.pixels[idx] == 255) {
94 visited[idx] = true;
95 pixel_stack.emplace(next_row, next_col);
96 }
97 }
98 }
99 }
100 44 }
101
102 32 void ConvexHullTBB::ExtractConnectedComponents() {
103 32 const int rows = working_image_.rows;
104 32 const int cols = working_image_.cols;
105 32 const size_t total_pixels = static_cast<size_t>(rows) * static_cast<size_t>(cols);
106
107 32 std::vector<bool> visited(total_pixels, false);
108 auto &output_hulls = GetOutput();
109
110
2/2
✓ Branch 0 taken 368 times.
✓ Branch 1 taken 32 times.
400 for (int row = 0; row < rows; ++row) {
111
2/2
✓ Branch 0 taken 6048 times.
✓ Branch 1 taken 368 times.
6416 for (int col = 0; col < cols; ++col) {
112 size_t idx = PixelIndex(row, col, cols);
113
114
4/4
✓ Branch 0 taken 296 times.
✓ Branch 1 taken 5752 times.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 252 times.
6048 if (working_image_.pixels[idx] == 255 && !visited[idx]) {
115 44 std::vector<PixelPoint> component;
116
1/2
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
44 FloodFill(row, col, visited, component);
117
118
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 if (!component.empty()) {
119
1/2
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
44 std::vector<PixelPoint> hull = ComputeConvexHull(component);
120 output_hulls.push_back(std::move(hull));
121 }
122 }
123 }
124 }
125 32 }
126
127 int64_t ConvexHullTBB::Orientation(const PixelPoint &p, const PixelPoint &q, const PixelPoint &r) {
128 972 return (static_cast<int64_t>(q.col - p.col) * (r.row - p.row)) -
129 972 (static_cast<int64_t>(q.row - p.row) * (r.col - p.col));
130 }
131
132
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 32 times.
44 std::vector<PixelPoint> ConvexHullTBB::ComputeConvexHull(const std::vector<PixelPoint> &points) {
133
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 32 times.
44 if (points.size() <= 2) {
134 12 return points;
135 }
136
137 32 auto lowest_point = *std::ranges::min_element(points, ComparePoints);
138
139
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 std::vector<PixelPoint> sorted_points;
140
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 sorted_points.reserve(points.size() - 1);
141 32 std::ranges::copy_if(points, std::back_inserter(sorted_points), [&lowest_point](const PixelPoint &p) {
142
4/4
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 184 times.
✓ Branch 2 taken 68 times.
✓ Branch 3 taken 32 times.
284 return (p.row != lowest_point.row) || (p.col != lowest_point.col);
143 });
144
145
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 tbb::parallel_sort(sorted_points.begin(), sorted_points.end(),
146
1/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
32 [&lowest_point](const PixelPoint &a, const PixelPoint &b) {
147 632 int64_t orient = Orientation(lowest_point, a, b);
148
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 464 times.
632 if (orient == 0) {
149 168 int64_t dist_a = ((a.row - lowest_point.row) * (a.row - lowest_point.row)) +
150 168 ((a.col - lowest_point.col) * (a.col - lowest_point.col));
151 168 int64_t dist_b = ((b.row - lowest_point.row) * (b.row - lowest_point.row)) +
152 168 ((b.col - lowest_point.col) * (b.col - lowest_point.col));
153 168 return dist_a < dist_b;
154 }
155 464 return orient > 0;
156 });
157
158
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 std::vector<PixelPoint> hull;
159
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 hull.reserve(points.size());
160 hull.push_back(lowest_point);
161
162
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 32 times.
284 for (const auto &p : sorted_points) {
163
2/2
✓ Branch 0 taken 340 times.
✓ Branch 1 taken 84 times.
424 while (hull.size() >= 2) {
164 const auto &a = hull[hull.size() - 2];
165 const auto &b = hull.back();
166
167
2/2
✓ Branch 0 taken 172 times.
✓ Branch 1 taken 168 times.
340 if (Orientation(a, b, p) <= 0) {
168 hull.pop_back();
169 } else {
170 break;
171 }
172 }
173 hull.push_back(p);
174 }
175
176 return hull;
177 }
178
179 } // namespace paramonov_v_bin_img_conv_hul_tbb
180