GCC Code Coverage Report


Directory: ./
File: tasks/batushin_i_incr_contrast_with_lhs/stl/src/ops_stl.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 69 86 80.2%
Functions: 10 11 90.9%
Branches: 31 66 47.0%

Line Branch Exec Source
1 #include "batushin_i_incr_contrast_with_lhs/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <thread>
7 #include <utility>
8 #include <vector>
9
10 #include "batushin_i_incr_contrast_with_lhs/common/include/common.hpp"
11
12 namespace batushin_i_incr_contrast_with_lhs {
13
14
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 BatushinIIncrContrastWithLhsSTL::BatushinIIncrContrastWithLhsSTL(const InType &in) {
15 SetTypeOfTask(GetStaticTypeOfTask());
16
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 GetInput() = in;
17
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 GetOutput().resize(in.size());
18 48 }
19
20 48 bool BatushinIIncrContrastWithLhsSTL::ValidationImpl() {
21 48 return !GetInput().empty();
22 }
23
24 48 bool BatushinIIncrContrastWithLhsSTL::PreProcessingImpl() {
25 48 return true;
26 }
27
28 namespace {
29
30 unsigned char NormalizePixel(unsigned char pixel, unsigned char min_val, double scale_factor) {
31 216 double normalized = static_cast<double>(pixel - min_val) * scale_factor;
32 216 normalized = std::floor(normalized + 0.5);
33 normalized = std::max(normalized, 0.0);
34 normalized = std::min(normalized, 255.0);
35 216 return static_cast<unsigned char>(normalized);
36 }
37
38 unsigned int GetNumThreads() {
39 96 unsigned int threads = std::thread::hardware_concurrency();
40 96 return (threads == 0) ? 1 : threads;
41 }
42
43 size_t ComputeChunkSize(size_t data_size, unsigned int num_threads) {
44
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
96 return std::max(static_cast<size_t>(1), data_size / num_threads);
45 }
46
47 size_t ComputeNumBlocks(size_t data_size, size_t chunk_size) {
48 96 return (data_size + chunk_size - 1) / chunk_size;
49 }
50
51 struct MinMaxResult {
52 unsigned char min_val;
53 unsigned char max_val;
54 };
55
56 MinMaxResult FindMinMaxInBlock(const std::vector<unsigned char> &data, size_t start, size_t end) {
57 unsigned char local_min = 255;
58 unsigned char local_max = 0;
59
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 216 times.
432 for (size_t idx = start; idx < end; ++idx) {
60 216 unsigned char val = data[idx];
61 local_min = std::min(local_min, val);
62 local_max = std::max(local_max, val);
63 }
64 // Используем designated initializers
65 return MinMaxResult{.min_val = local_min, .max_val = local_max};
66 }
67
68 48 MinMaxResult MergeMinMaxResults(const std::vector<MinMaxResult> &results) {
69 48 unsigned char global_min = 255;
70 48 unsigned char global_max = 0;
71
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 48 times.
264 for (const auto &result : results) {
72 216 global_min = std::min(global_min, result.min_val);
73 216 global_max = std::max(global_max, result.max_val);
74 }
75 // Используем designated initializers
76 48 return MinMaxResult{.min_val = global_min, .max_val = global_max};
77 }
78
79
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 std::pair<unsigned char, unsigned char> FindMinMaxParallel(const std::vector<unsigned char> &data) {
80
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (data.empty()) {
81 return {0, 0};
82 }
83
84 48 const size_t data_size = data.size();
85 const unsigned int num_threads = GetNumThreads();
86 const size_t chunk_size = ComputeChunkSize(data_size, num_threads);
87 const size_t num_blocks = ComputeNumBlocks(data_size, chunk_size);
88
89 48 std::vector<MinMaxResult> block_results(num_blocks, MinMaxResult{.min_val = 255, .max_val = 0});
90 48 std::vector<std::thread> threads;
91
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 threads.reserve(num_blocks);
92
93
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 48 times.
264 for (size_t block_idx = 0; block_idx < num_blocks; ++block_idx) {
94 216 size_t start = block_idx * chunk_size;
95
1/2
✓ Branch 1 taken 216 times.
✗ Branch 2 not taken.
216 size_t end = std::min(start + chunk_size, data_size);
96
97
1/2
✓ Branch 1 taken 216 times.
✗ Branch 2 not taken.
216 threads.emplace_back([&data, &block_results, block_idx, start, end] {
98 216 block_results[block_idx] = FindMinMaxInBlock(data, start, end);
99 });
100 }
101
102
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 48 times.
264 for (auto &thread : threads) {
103
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 if (thread.joinable()) {
104
1/2
✓ Branch 1 taken 216 times.
✗ Branch 2 not taken.
216 thread.join();
105 }
106 }
107
108 48 MinMaxResult final_result = MergeMinMaxResults(block_results);
109 48 return {final_result.min_val, final_result.max_val};
110 48 }
111
112 216 void NormalizeBlock(const std::vector<unsigned char> &source, std::vector<unsigned char> &destination, size_t start,
113 size_t end, unsigned char min_value, double scale_coefficient) {
114
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 216 times.
432 for (size_t idx = start; idx < end; ++idx) {
115 216 destination[idx] = NormalizePixel(source[idx], min_value, scale_coefficient);
116 }
117 216 }
118
119 48 void NormalizeImageParallel(const std::vector<unsigned char> &source, std::vector<unsigned char> &destination,
120 unsigned char min_value, double scale_coefficient) {
121 48 const size_t data_size = source.size();
122 const unsigned int num_threads = GetNumThreads();
123 const size_t chunk_size = ComputeChunkSize(data_size, num_threads);
124 const size_t num_blocks = ComputeNumBlocks(data_size, chunk_size);
125
126 48 std::vector<std::thread> threads;
127
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 threads.reserve(num_blocks);
128
129
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 48 times.
264 for (size_t block_idx = 0; block_idx < num_blocks; ++block_idx) {
130 216 size_t start = block_idx * chunk_size;
131
1/2
✓ Branch 1 taken 216 times.
✗ Branch 2 not taken.
216 size_t end = std::min(start + chunk_size, data_size);
132
133
1/2
✓ Branch 1 taken 216 times.
✗ Branch 2 not taken.
216 threads.emplace_back([&source, &destination, start, end, min_value, scale_coefficient] {
134 216 NormalizeBlock(source, destination, start, end, min_value, scale_coefficient);
135 216 });
136 }
137
138
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 48 times.
264 for (auto &thread : threads) {
139
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 if (thread.joinable()) {
140
1/2
✓ Branch 1 taken 216 times.
✗ Branch 2 not taken.
216 thread.join();
141 }
142 }
143 48 }
144
145 void FillUniformBlock(std::vector<unsigned char> &output, size_t start, size_t end) {
146 for (size_t idx = start; idx < end; ++idx) {
147 output[idx] = 128;
148 }
149 }
150
151 void FillUniformImageParallel(std::vector<unsigned char> &output, size_t size) {
152 const unsigned int num_threads = GetNumThreads();
153 const size_t chunk_size = ComputeChunkSize(size, num_threads);
154 const size_t num_blocks = ComputeNumBlocks(size, chunk_size);
155
156 std::vector<std::thread> threads;
157 threads.reserve(num_blocks);
158
159 for (size_t block_idx = 0; block_idx < num_blocks; ++block_idx) {
160 size_t start = block_idx * chunk_size;
161 size_t end = std::min(start + chunk_size, size);
162
163 threads.emplace_back([&output, start, end] { FillUniformBlock(output, start, end); });
164 }
165
166 for (auto &thread : threads) {
167 if (thread.joinable()) {
168 thread.join();
169 }
170 }
171 }
172
173 } // namespace
174
175 48 bool BatushinIIncrContrastWithLhsSTL::RunImpl() {
176 const std::vector<unsigned char> &source = GetInput();
177 std::vector<unsigned char> &destination = GetOutput();
178
179 48 auto min_max = FindMinMaxParallel(source);
180 48 unsigned char min_value = min_max.first;
181 48 unsigned char max_value = min_max.second;
182
183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (min_value == max_value) {
184 FillUniformImageParallel(destination, source.size());
185 return true;
186 }
187
188 48 const double scale_coefficient = 255.0 / static_cast<double>(max_value - min_value);
189 48 destination.resize(source.size());
190
191 48 NormalizeImageParallel(source, destination, min_value, scale_coefficient);
192
193 return true;
194 }
195
196 48 bool BatushinIIncrContrastWithLhsSTL::PostProcessingImpl() {
197 48 return true;
198 }
199
200 } // namespace batushin_i_incr_contrast_with_lhs
201