GCC Code Coverage Report


Directory: ./
File: tasks/moskaev_v_lin_filt_block_gauss_3/seq/src/ops_seq.cpp
Date: 2026-04-02 17:12:27
Exec Total Coverage
Lines: 66 66 100.0%
Functions: 8 8 100.0%
Branches: 30 36 83.3%

Line Branch Exec Source
1 #include "moskaev_v_lin_filt_block_gauss_3/seq/include/ops_seq.hpp"
2
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <cstdint>
7 #include <vector>
8
9 #include "moskaev_v_lin_filt_block_gauss_3/common/include/common.hpp"
10
11 namespace moskaev_v_lin_filt_block_gauss_3 {
12
13
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 MoskaevVLinFiltBlockGauss3SEQ::MoskaevVLinFiltBlockGauss3SEQ(const InType &in) {
14 SetTypeOfTask(GetStaticTypeOfTask());
15 GetInput() = in;
16 32 GetOutput() = OutType();
17 32 }
18
19 32 bool MoskaevVLinFiltBlockGauss3SEQ::ValidationImpl() {
20 const auto &input = GetInput();
21 32 return !std::get<4>(input).empty();
22 }
23
24 32 bool MoskaevVLinFiltBlockGauss3SEQ::PreProcessingImpl() {
25 32 return true;
26 }
27
28 32 void MoskaevVLinFiltBlockGauss3SEQ::ApplyGaussianFilterToBlock(const std::vector<uint8_t> &input_block,
29 std::vector<uint8_t> &output_block, int block_width,
30 int block_height, int channels) {
31 32 int inner_width = block_width - 2;
32 32 int inner_height = block_height - 2;
33
34
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 32 times.
96 for (int row = 0; row < inner_height; ++row) {
35
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 64 times.
208 for (int col = 0; col < inner_width; ++col) {
36
2/2
✓ Branch 0 taken 208 times.
✓ Branch 1 taken 144 times.
352 for (int channel = 0; channel < channels; ++channel) {
37 float sum = 0.0F;
38
39
2/2
✓ Branch 0 taken 624 times.
✓ Branch 1 taken 208 times.
832 for (int ky = -1; ky <= 1; ++ky) {
40
2/2
✓ Branch 0 taken 1872 times.
✓ Branch 1 taken 624 times.
2496 for (int kx = -1; kx <= 1; ++kx) {
41 1872 int ny = row + 1 + ky;
42 1872 int nx = col + 1 + kx;
43
44 1872 int idx = (((ny * block_width) + nx) * channels) + channel;
45 1872 sum += static_cast<float>(input_block[idx]) * kGaussianKernel[((ky + 1) * 3) + (kx + 1)];
46 }
47 }
48
49 208 int out_idx = (((row * inner_width) + col) * channels) + channel;
50 208 output_block[out_idx] = static_cast<uint8_t>(std::round(sum));
51 }
52 }
53 }
54 32 }
55
56 namespace {
57 32 void CopyBlockWithPadding(const std::vector<uint8_t> &source_image, std::vector<uint8_t> &padded_block, int width,
58 int height, int channels, int block_x, int block_y, int current_block_width,
59 int current_block_height, int block_with_padding_width) {
60
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 32 times.
160 for (int row = -1; row <= current_block_height; ++row) {
61
2/2
✓ Branch 0 taken 528 times.
✓ Branch 1 taken 128 times.
656 for (int col = -1; col <= current_block_width; ++col) {
62 528 int src_y = std::clamp(block_y + row, 0, height - 1);
63 528 int src_x = std::clamp(block_x + col, 0, width - 1);
64 528 int dst_y = row + 1;
65 528 int dst_x = col + 1;
66
67
2/2
✓ Branch 0 taken 784 times.
✓ Branch 1 taken 528 times.
1312 for (int channel = 0; channel < channels; ++channel) {
68 784 int src_idx = (((src_y * width) + src_x) * channels) + channel;
69 784 int dst_idx = (((dst_y * block_with_padding_width) + dst_x) * channels) + channel;
70 784 padded_block[dst_idx] = source_image[src_idx];
71 }
72 }
73 }
74 32 }
75
76 32 void CopyProcessedBlockToOutput(const std::vector<uint8_t> &processed_block, std::vector<uint8_t> &output_image,
77 int width, int channels, int block_x, int block_y, int current_block_width,
78 int current_block_height) {
79
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 32 times.
96 for (int row = 0; row < current_block_height; ++row) {
80
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 64 times.
208 for (int col = 0; col < current_block_width; ++col) {
81
2/2
✓ Branch 0 taken 208 times.
✓ Branch 1 taken 144 times.
352 for (int channel = 0; channel < channels; ++channel) {
82 208 int src_idx = (((row * current_block_width) + col) * channels) + channel;
83 208 int dst_idx = ((((block_y + row) * width) + (block_x + col)) * channels) + channel;
84 208 output_image[dst_idx] = processed_block[src_idx];
85 }
86 }
87 }
88 32 }
89 } // namespace
90
91 32 bool MoskaevVLinFiltBlockGauss3SEQ::RunImpl() {
92 const auto &input = GetInput();
93
94 32 int width = std::get<0>(input);
95 32 int height = std::get<1>(input);
96
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 int channels = std::get<2>(input);
97 const auto &image_data = std::get<4>(input);
98
99
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 if (image_data.empty()) {
100 return false;
101 }
102
103 32 block_size_ = 64;
104
105 32 GetOutput().resize(static_cast<size_t>(width) * static_cast<size_t>(height) * static_cast<size_t>(channels));
106
107
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 32 times.
64 for (int block_y = 0; block_y < height; block_y += block_size_) {
108
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 32 times.
64 for (int block_x = 0; block_x < width; block_x += block_size_) {
109 32 int current_block_width = std::min(block_size_, width - block_x);
110 32 int current_block_height = std::min(block_size_, height - block_y);
111
112 32 int block_with_padding_width = current_block_width + 2;
113 32 int block_with_padding_height = current_block_height + 2;
114
115 32 std::vector<uint8_t> input_block(static_cast<size_t>(block_with_padding_width) *
116 32 static_cast<size_t>(block_with_padding_height) *
117 static_cast<size_t>(channels),
118 32 0);
119
120 32 std::vector<uint8_t> output_block(static_cast<size_t>(current_block_width) *
121 32 static_cast<size_t>(current_block_height) * static_cast<size_t>(channels),
122
1/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
32 0);
123
124 // Копирование блок с отступами
125 32 CopyBlockWithPadding(image_data, input_block, width, height, channels, block_x, block_y, current_block_width,
126 current_block_height, block_with_padding_width);
127
128 // фильтр
129 32 ApplyGaussianFilterToBlock(input_block, output_block, block_with_padding_width, block_with_padding_height,
130 channels);
131
132 // Копирование обработанный блок обратно в выходное изображение
133 32 CopyProcessedBlockToOutput(output_block, GetOutput(), width, channels, block_x, block_y, current_block_width,
134 current_block_height);
135 }
136 }
137
138 return true;
139 }
140
141 32 bool MoskaevVLinFiltBlockGauss3SEQ::PostProcessingImpl() {
142 32 return !GetOutput().empty();
143 }
144
145 } // namespace moskaev_v_lin_filt_block_gauss_3
146