GCC Code Coverage Report


Directory: ./
File: tasks/badanov_a_select_edge_sobel/tbb/src/ops_tbb.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 65 65 100.0%
Functions: 10 10 100.0%
Branches: 27 32 84.4%

Line Branch Exec Source
1 #include "badanov_a_select_edge_sobel/tbb/include/ops_tbb.hpp"
2
3 #include <tbb/blocked_range.h>
4 #include <tbb/parallel_for.h>
5 #include <tbb/parallel_reduce.h>
6
7 #include <algorithm>
8 #include <cmath>
9 #include <cstddef>
10 #include <cstdint>
11 #include <vector>
12
13 #include "badanov_a_select_edge_sobel/common/include/common.hpp"
14
15 namespace badanov_a_select_edge_sobel {
16
17
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 BadanovASelectEdgeSobelTBB::BadanovASelectEdgeSobelTBB(const InType &in) {
18 SetTypeOfTask(GetStaticTypeOfTask());
19
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 GetInput() = in;
20 40 GetOutput() = std::vector<uint8_t>();
21 40 }
22
23 40 bool BadanovASelectEdgeSobelTBB::ValidationImpl() {
24 const auto &input = GetInput();
25 40 return !input.empty();
26 }
27
28
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 28 times.
40 bool BadanovASelectEdgeSobelTBB::PreProcessingImpl() {
29 const auto &input = GetInput();
30
31 40 width_ = static_cast<int>(std::sqrt(input.size()));
32 40 height_ = width_;
33
34
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 28 times.
40 if (width_ * height_ != static_cast<int>(input.size())) {
35 12 width_ = static_cast<int>(input.size());
36 12 height_ = 1;
37 }
38
39 40 GetOutput() = std::vector<uint8_t>(input.size(), 0);
40
41 40 return true;
42 }
43
44 20 void BadanovASelectEdgeSobelTBB::ApplySobelOperator(const std::vector<uint8_t> &input, std::vector<float> &magnitude,
45 float &max_magnitude) {
46 20 const int height = height_;
47 20 const int width = width_;
48
49 using Range = tbb::blocked_range<int>;
50
51 20 max_magnitude = tbb::parallel_reduce(Range(1, height - 1), 0.0F, [&](const Range &r, float init) -> float {
52 168 float local_max = init;
53
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 168 times.
336 for (int row = r.begin(); row < r.end(); ++row) {
54
2/2
✓ Branch 0 taken 1872 times.
✓ Branch 1 taken 168 times.
2040 for (int col = 1; col < width - 1; ++col) {
55 1872 float gradient_x = 0.0F;
56 1872 float gradient_y = 0.0F;
57
58 1872 ComputeGradientAtPixel(input, row, col, gradient_x, gradient_y);
59
60 1872 const float magnitude_value = std::sqrt((gradient_x * gradient_x) + (gradient_y * gradient_y));
61 1872 const size_t idx = (static_cast<size_t>(row) * static_cast<size_t>(width)) + static_cast<size_t>(col);
62 1872 magnitude[idx] = magnitude_value;
63
64 1872 local_max = std::max(magnitude_value, local_max);
65 }
66 }
67 168 return local_max;
68 20 }, [](float a, float b) -> float { return std::max(a, b); });
69 20 }
70
71 1872 void BadanovASelectEdgeSobelTBB::ComputeGradientAtPixel(const std::vector<uint8_t> &input, int row, int col,
72 float &gradient_x, float &gradient_y) const {
73 1872 gradient_x = 0.0F;
74 1872 gradient_y = 0.0F;
75
76
2/2
✓ Branch 0 taken 5616 times.
✓ Branch 1 taken 1872 times.
7488 for (int kernel_row = -1; kernel_row <= 1; ++kernel_row) {
77
2/2
✓ Branch 0 taken 16848 times.
✓ Branch 1 taken 5616 times.
22464 for (int kernel_col = -1; kernel_col <= 1; ++kernel_col) {
78 16848 const size_t pixel_index =
79 16848 (static_cast<size_t>(row + kernel_row) * static_cast<size_t>(width_)) + static_cast<size_t>(col + kernel_col);
80 16848 const uint8_t pixel = input[pixel_index];
81
82 16848 const int kx_idx = kernel_row + 1;
83 16848 const int ky_idx = kernel_col + 1;
84 16848 const int kernel_x_value = kKernelX.at(static_cast<size_t>(kx_idx)).at(static_cast<size_t>(ky_idx));
85 16848 const int kernel_y_value = kKernelY.at(static_cast<size_t>(kx_idx)).at(static_cast<size_t>(ky_idx));
86
87 16848 gradient_x += static_cast<float>(pixel) * static_cast<float>(kernel_x_value);
88 16848 gradient_y += static_cast<float>(pixel) * static_cast<float>(kernel_y_value);
89 }
90 }
91 1872 }
92
93 20 void BadanovASelectEdgeSobelTBB::ApplyThreshold(const std::vector<float> &magnitude, float max_magnitude,
94 std::vector<uint8_t> &output) const {
95
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 4 times.
20 if (max_magnitude > 0.0F) {
96 16 const float scale = 255.0F / max_magnitude;
97 const size_t size = magnitude.size();
98 16 const int threshold = threshold_;
99
100 2384 tbb::parallel_for(tbb::blocked_range<size_t>(0, size), [&](const tbb::blocked_range<size_t> &r) {
101
2/2
✓ Branch 0 taken 2368 times.
✓ Branch 1 taken 2368 times.
4736 for (size_t i = r.begin(); i < r.end(); ++i) {
102
2/2
✓ Branch 0 taken 1644 times.
✓ Branch 1 taken 724 times.
4012 output[i] = (magnitude[i] * scale > static_cast<float>(threshold)) ? 255 : 0;
103 }
104 2368 });
105 } else {
106 std::ranges::fill(output, 0);
107 }
108 20 }
109
110
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 20 times.
40 bool BadanovASelectEdgeSobelTBB::RunImpl() {
111 const auto &input = GetInput();
112 auto &output = GetOutput();
113
114
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
40 if (height_ < 3 || width_ < 3) {
115 20 output = input;
116 20 return true;
117 }
118
119 20 std::vector<float> magnitude(input.size(), 0.0F);
120 20 float max_magnitude = 0.0F;
121
122
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 ApplySobelOperator(input, magnitude, max_magnitude);
123
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 ApplyThreshold(magnitude, max_magnitude, output);
124
125 return true;
126 }
127
128 40 bool BadanovASelectEdgeSobelTBB::PostProcessingImpl() {
129 40 return true;
130 }
131
132 } // namespace badanov_a_select_edge_sobel
133