| 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 |