GCC Code Coverage Report


Directory: ./
File: tasks/otcheskov_s_contrast_lin_stretch/stl/src/ops_stl.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 58 72 80.6%
Functions: 9 10 90.0%
Branches: 29 50 58.0%

Line Branch Exec Source
1 #include "otcheskov_s_contrast_lin_stretch/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <cstddef>
5 #include <cstdint>
6 #include <thread>
7 #include <vector>
8
9 #include "otcheskov_s_contrast_lin_stretch/common/include/common.hpp"
10 #include "util/include/util.hpp"
11
12 namespace otcheskov_s_contrast_lin_stretch {
13
14
1/2
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
72 OtcheskovSContrastLinStretchSTL::OtcheskovSContrastLinStretchSTL(const InType &in) {
15 SetTypeOfTask(GetStaticTypeOfTask());
16
1/2
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
72 GetInput() = in;
17 GetOutput().clear();
18 72 }
19
20 72 bool OtcheskovSContrastLinStretchSTL::ValidationImpl() {
21 72 return !GetInput().empty();
22 }
23
24 72 bool OtcheskovSContrastLinStretchSTL::PreProcessingImpl() {
25 72 GetOutput().resize(GetInput().size());
26 72 return GetOutput().size() == GetInput().size();
27 }
28
29
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 8 times.
72 bool OtcheskovSContrastLinStretchSTL::RunImpl() {
30
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 8 times.
72 if (GetInput().empty()) {
31 return false;
32 }
33
34 const InType &input = GetInput();
35 OutType &output = GetOutput();
36 const size_t size = input.size();
37
38 64 MinMax result = ComputeMinMax(input);
39
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 40 times.
64 if (result.min == result.max) {
40 const size_t threshold_size = 1000000;
41
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if (size > threshold_size) {
42 CopyInput(input, output);
43 } else {
44
2/2
✓ Branch 0 taken 2008816 times.
✓ Branch 1 taken 24 times.
2008840 for (size_t i = 0; i < size; ++i) {
45 2008816 output[i] = input[i];
46 }
47 }
48 24 return true;
49 }
50 40 const int min_i = static_cast<int>(result.min);
51 40 const int range = static_cast<int>(result.max - min_i);
52 40 LinearStretch(input, output, min_i, range);
53 return true;
54 }
55
56 72 bool OtcheskovSContrastLinStretchSTL::PostProcessingImpl() {
57 72 return true;
58 }
59
60 64 OtcheskovSContrastLinStretchSTL::MinMax OtcheskovSContrastLinStretchSTL::ComputeMinMax(const InType &input) {
61 64 const size_t size = input.size();
62 64 const size_t num_threads = std::min<size_t>(static_cast<size_t>(ppc::util::GetNumThreads()), size);
63
64 64 const size_t block = size / num_threads;
65 64 std::vector<MinMax> local(num_threads, {255, 0});
66
67 {
68 64 std::vector<std::jthread> threads;
69
1/2
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
64 threads.reserve(num_threads);
70
2/2
✓ Branch 0 taken 148 times.
✓ Branch 1 taken 64 times.
212 for (size_t tid = 0; tid < num_threads; ++tid) {
71 148 size_t begin = tid * block;
72
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 64 times.
148 size_t end = (tid == num_threads - 1) ? size : begin + block;
73
74
1/2
✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
148 threads.emplace_back([&, tid, begin, end]() {
75 148 auto [min, max] = std::ranges::minmax_element(input.begin() + static_cast<std::ptrdiff_t>(begin),
76 148 input.begin() + static_cast<std::ptrdiff_t>(end));
77 148 local[tid] = {.min = *min, .max = *max};
78 148 });
79 }
80 64 }
81
82 64 MinMax result{.min = 255, .max = 0};
83
2/2
✓ Branch 0 taken 148 times.
✓ Branch 1 taken 64 times.
212 for (size_t tid = 0; tid < num_threads; ++tid) {
84 148 result.min = std::min(result.min, local[tid].min);
85 148 result.max = std::max(result.max, local[tid].max);
86 }
87
1/2
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
128 return result;
88 }
89
90 void OtcheskovSContrastLinStretchSTL::CopyInput(const InType &input, OutType &output) {
91 const size_t size = input.size();
92 const size_t num_threads = std::min<size_t>(static_cast<size_t>(ppc::util::GetNumThreads()), size);
93 const size_t block = size / num_threads;
94
95 std::vector<std::jthread> threads;
96 threads.reserve(num_threads);
97 for (size_t tid = 0; tid < num_threads; ++tid) {
98 size_t begin = tid * block;
99 size_t end = (tid == num_threads - 1) ? size : begin + block;
100
101 threads.emplace_back([&, begin, end]() {
102 for (size_t i = begin; i < end; ++i) {
103 output[i] = input[i];
104 }
105 });
106 }
107 }
108
109 40 void OtcheskovSContrastLinStretchSTL::LinearStretch(const InType &input, OutType &output, int min_i, int range) {
110 40 const size_t size = input.size();
111
1/2
✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
40 const size_t num_threads = std::min<size_t>(static_cast<size_t>(ppc::util::GetNumThreads()), size);
112 40 const size_t block = size / num_threads;
113
114 40 std::vector<std::jthread> threads;
115
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 threads.reserve(num_threads);
116
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 40 times.
140 for (size_t tid = 0; tid < num_threads; ++tid) {
117 100 size_t begin = tid * block;
118
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 40 times.
100 size_t end = (tid == num_threads - 1) ? size : begin + block;
119
120
1/2
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
100 threads.emplace_back([&, begin, end, min_i, range]() {
121
2/2
✓ Branch 0 taken 3280104 times.
✓ Branch 1 taken 100 times.
3280204 for (size_t i = begin; i < end; ++i) {
122 3280104 int pixel = static_cast<int>(input[i]);
123 3280104 int value = (pixel - min_i) * 255 / (range);
124 value = std::clamp(value, 0, 255);
125 3280104 output[i] = static_cast<uint8_t>(value);
126 }
127 100 });
128 }
129 40 }
130
131 } // namespace otcheskov_s_contrast_lin_stretch
132