GCC Code Coverage Report


Directory: ./
File: tasks/buzulukski_d_gaus_gorizontal/stl/src/ops_stl.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 0 52 0.0%
Functions: 0 7 0.0%
Branches: 0 32 0.0%

Line Branch Exec Source
1 #include "buzulukski_d_gaus_gorizontal/stl/include/ops_stl.hpp"
2
3 #include <algorithm>
4 #include <array>
5 #include <cstddef>
6 #include <cstdint>
7 #include <thread>
8 #include <vector>
9
10 #include "buzulukski_d_gaus_gorizontal/common/include/common.hpp"
11
12 namespace buzulukski_d_gaus_gorizontal {
13
14 namespace {
15 constexpr int kChannels = 3;
16 constexpr int kKernelSize = 3;
17 constexpr int kKernelSum = 16;
18
19 using KernelRow = std::array<int, kKernelSize>;
20 constexpr std::array<KernelRow, kKernelSize> kKernel = {{{1, 2, 1}, {2, 4, 2}, {1, 2, 1}}};
21
22 uint8_t CalculatePixelSTL(const uint8_t *in, int py, int px, int w, int h, int ch) {
23 int sum = 0;
24 for (int ky = -1; ky <= 1; ++ky) {
25 for (int kx = -1; kx <= 1; ++kx) {
26 int ny = std::clamp(py + ky, 0, h - 1);
27 int nx = std::clamp(px + kx, 0, w - 1);
28
29 size_t idx = ((static_cast<size_t>(ny) * w + nx) * kChannels) + ch;
30 sum += static_cast<int>(in[idx]) * kKernel.at(ky + 1).at(kx + 1);
31 }
32 }
33 return static_cast<uint8_t>(sum / kKernelSum);
34 }
35
36 void ProcessRows(int start_row, int end_row, int w, int h, const uint8_t *in, uint8_t *out) {
37 for (int py = start_row; py < end_row; ++py) {
38 for (int px = 0; px < w; ++px) {
39 for (int ch = 0; ch < kChannels; ++ch) {
40 size_t out_idx = ((static_cast<size_t>(py) * w + px) * kChannels) + ch;
41 out[out_idx] = CalculatePixelSTL(in, py, px, w, h, ch);
42 }
43 }
44 }
45 }
46 } // namespace
47
48 BuzulukskiDGausGorizontalSTL::BuzulukskiDGausGorizontalSTL(const InType &in) : BaseTask() {
49 SetTypeOfTask(GetStaticTypeOfTask());
50 GetInput() = in;
51 GetOutput() = 0;
52 }
53
54 bool BuzulukskiDGausGorizontalSTL::ValidationImpl() {
55 return GetInput() >= kKernelSize;
56 }
57
58 bool BuzulukskiDGausGorizontalSTL::PreProcessingImpl() {
59 width_ = GetInput();
60 height_ = GetInput();
61 const auto total_size = static_cast<std::size_t>(width_) * height_ * kChannels;
62 input_image_.assign(total_size, 100);
63 output_image_.assign(total_size, 0);
64 return true;
65 }
66
67 bool BuzulukskiDGausGorizontalSTL::RunImpl() {
68 const int h = height_;
69 const int w = width_;
70 const uint8_t *in_ptr = input_image_.data();
71 uint8_t *out_ptr = output_image_.data();
72
73 unsigned int raw_threads = std::thread::hardware_concurrency();
74 int n_threads = (raw_threads == 0) ? 2 : static_cast<int>(raw_threads);
75
76 std::vector<std::thread> threads;
77 threads.reserve(n_threads);
78
79 int rows_per_thread = h / n_threads;
80
81 for (int i = 0; i < n_threads; ++i) {
82 int start = i * rows_per_thread;
83 int end = (i == n_threads - 1) ? h : (i + 1) * rows_per_thread;
84
85 threads.emplace_back(ProcessRows, start, end, w, h, in_ptr, out_ptr);
86 }
87
88 for (auto &t : threads) {
89 if (t.joinable()) {
90 t.join();
91 }
92 }
93
94 return true;
95 }
96
97 bool BuzulukskiDGausGorizontalSTL::PostProcessingImpl() {
98 if (output_image_.empty()) {
99 return false;
100 }
101 int64_t total_sum = 0;
102 for (const auto &val : output_image_) {
103 total_sum += static_cast<int64_t>(val);
104 }
105 GetOutput() = static_cast<int>(total_sum / static_cast<int64_t>(output_image_.size()));
106 return true;
107 }
108
109 } // namespace buzulukski_d_gaus_gorizontal
110