GCC Code Coverage Report


Directory: ./
File: tasks/balchunayte_z_sobel/stl/src/ops_stl.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 61 61 100.0%
Functions: 6 6 100.0%
Branches: 20 32 62.5%

Line Branch Exec Source
1 #include "balchunayte_z_sobel/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <cstddef>
5 #include <cstdlib>
6 #include <functional>
7 #include <thread>
8 #include <vector>
9
10 #include "balchunayte_z_sobel/common/include/common.hpp"
11
12 namespace balchunayte_z_sobel {
13
14 namespace {
15
16 int ConvertPixelToGray(const Pixel &pixel_value) {
17 96 return (77 * static_cast<int>(pixel_value.r) + 150 * static_cast<int>(pixel_value.g) +
18 96 29 * static_cast<int>(pixel_value.b)) >>
19 96 8;
20 }
21
22 48 void ProcessRows(const Image &input_image, std::vector<int> &output_data, int row_begin, int row_end) {
23 48 const int image_width = input_image.width;
24 48 const auto image_width_size = static_cast<size_t>(image_width);
25
26
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 48 times.
96 for (int row_index = row_begin; row_index < row_end; ++row_index) {
27
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 48 times.
144 for (int col_index = 1; col_index < image_width - 1; ++col_index) {
28 96 const size_t index_top_left =
29 96 (static_cast<size_t>(row_index - 1) * image_width_size) + static_cast<size_t>(col_index - 1);
30 96 const size_t index_top_middle =
31 96 (static_cast<size_t>(row_index - 1) * image_width_size) + static_cast<size_t>(col_index);
32 96 const size_t index_top_right =
33 96 (static_cast<size_t>(row_index - 1) * image_width_size) + static_cast<size_t>(col_index + 1);
34
35 96 const size_t index_middle_left =
36 96 (static_cast<size_t>(row_index) * image_width_size) + static_cast<size_t>(col_index - 1);
37 96 const size_t index_middle_right =
38 (static_cast<size_t>(row_index) * image_width_size) + static_cast<size_t>(col_index + 1);
39
40 96 const size_t index_bottom_left =
41 96 (static_cast<size_t>(row_index + 1) * image_width_size) + static_cast<size_t>(col_index - 1);
42 96 const size_t index_bottom_middle =
43 (static_cast<size_t>(row_index + 1) * image_width_size) + static_cast<size_t>(col_index);
44 96 const size_t index_bottom_right =
45 (static_cast<size_t>(row_index + 1) * image_width_size) + static_cast<size_t>(col_index + 1);
46
47 const int gray_top_left = ConvertPixelToGray(input_image.data[index_top_left]);
48 const int gray_top_middle = ConvertPixelToGray(input_image.data[index_top_middle]);
49 const int gray_top_right = ConvertPixelToGray(input_image.data[index_top_right]);
50
51 const int gray_middle_left = ConvertPixelToGray(input_image.data[index_middle_left]);
52 const int gray_middle_right = ConvertPixelToGray(input_image.data[index_middle_right]);
53
54 const int gray_bottom_left = ConvertPixelToGray(input_image.data[index_bottom_left]);
55 const int gray_bottom_middle = ConvertPixelToGray(input_image.data[index_bottom_middle]);
56 const int gray_bottom_right = ConvertPixelToGray(input_image.data[index_bottom_right]);
57
58 96 const int gradient_x = (-gray_top_left + gray_top_right) + (-2 * gray_middle_left + (2 * gray_middle_right)) +
59 96 (-gray_bottom_left + gray_bottom_right);
60
61 96 const int gradient_y = (gray_top_left + (2 * gray_top_middle) + gray_top_right) +
62 96 (-gray_bottom_left - (2 * gray_bottom_middle) - gray_bottom_right);
63
64 96 const int magnitude = std::abs(gradient_x) + std::abs(gradient_y);
65
66 96 const size_t output_index = (static_cast<size_t>(row_index) * image_width_size) + static_cast<size_t>(col_index);
67 96 output_data[output_index] = magnitude;
68 }
69 }
70 48 }
71
72 } // namespace
73
74
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 BalchunayteZSobelOpSTL::BalchunayteZSobelOpSTL(const InType &input_image) {
75 SetTypeOfTask(GetStaticTypeOfTask());
76 GetInput() = input_image;
77 GetOutput().clear();
78 24 }
79
80 24 bool BalchunayteZSobelOpSTL::ValidationImpl() {
81 const auto &input_image = GetInput();
82
83
2/4
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
24 if (input_image.width <= 0 || input_image.height <= 0) {
84 return false;
85 }
86
87
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 const auto expected_size = static_cast<size_t>(input_image.width) * static_cast<size_t>(input_image.height);
88
89
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (input_image.data.size() != expected_size) {
90 return false;
91 }
92
93 24 return GetOutput().empty();
94 }
95
96 24 bool BalchunayteZSobelOpSTL::PreProcessingImpl() {
97 const auto &input_image = GetInput();
98 24 GetOutput().assign(static_cast<size_t>(input_image.width) * static_cast<size_t>(input_image.height), 0);
99 24 return true;
100 }
101
102
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 bool BalchunayteZSobelOpSTL::RunImpl() {
103 const auto &input_image = GetInput();
104 auto &output_data = GetOutput();
105
106 24 const int image_height = input_image.height;
107
108
2/4
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
24 if (input_image.width < 3 || image_height < 3) {
109 return true;
110 }
111
112 24 const int inner_row_count = image_height - 2;
113
114 24 unsigned int hardware_thread_count = std::thread::hardware_concurrency();
115 24 if (hardware_thread_count == 0) {
116 hardware_thread_count = 1;
117 }
118
119
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 const int actual_thread_count = std::min(static_cast<int>(hardware_thread_count), inner_row_count);
120
121 24 std::vector<std::thread> worker_threads;
122
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 worker_threads.reserve(static_cast<size_t>(actual_thread_count));
123
124 24 const int rows_per_thread = inner_row_count / actual_thread_count;
125 24 const int remaining_rows = inner_row_count % actual_thread_count;
126
127 24 int start_row_index = 1;
128
129
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 24 times.
72 for (int thread_index = 0; thread_index < actual_thread_count; ++thread_index) {
130 48 const int extra_row_count = static_cast<int>(thread_index < remaining_rows);
131 48 const int end_row_index = start_row_index + rows_per_thread + extra_row_count;
132
133
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 worker_threads.emplace_back(ProcessRows, std::cref(input_image), std::ref(output_data), start_row_index,
134 end_row_index);
135
136 48 start_row_index = end_row_index;
137 }
138
139
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 24 times.
72 for (auto &worker_thread : worker_threads) {
140
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 worker_thread.join();
141 }
142
143 return true;
144 24 }
145
146 24 bool BalchunayteZSobelOpSTL::PostProcessingImpl() {
147 24 return true;
148 }
149
150 } // namespace balchunayte_z_sobel
151