Blender V4.3
COM_ConvolutionFilterOperation.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6
7namespace blender::compositor {
8
17
19 float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9)
20{
21 filter_[0] = f1;
22 filter_[1] = f2;
23 filter_[2] = f3;
24 filter_[3] = f4;
25 filter_[4] = f5;
26 filter_[5] = f6;
27 filter_[6] = f7;
28 filter_[7] = f8;
29 filter_[8] = f9;
30 filter_height_ = 3;
31 filter_width_ = 3;
32}
33
35 const rcti &output_area,
36 rcti &r_input_area)
37{
38 switch (input_idx) {
39 case IMAGE_INPUT_INDEX: {
40 const int add_x = (filter_width_ - 1) / 2 + 1;
41 const int add_y = (filter_height_ - 1) / 2 + 1;
42 r_input_area.xmin = output_area.xmin - add_x;
43 r_input_area.xmax = output_area.xmax + add_x;
44 r_input_area.ymin = output_area.ymin - add_y;
45 r_input_area.ymax = output_area.ymax + add_y;
46 break;
47 }
48 case FACTOR_INPUT_INDEX: {
49 r_input_area = output_area;
50 break;
51 }
52 }
53}
54
56 const rcti &area,
58{
59 const MemoryBuffer *image = inputs[IMAGE_INPUT_INDEX];
60 const int last_x = get_width() - 1;
61 const int last_y = get_height() - 1;
62 for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
63 const int left_offset = (it.x == 0) ? 0 : -image->elem_stride;
64 const int right_offset = (it.x == last_x) ? 0 : image->elem_stride;
65 const int down_offset = (it.y == 0) ? 0 : -image->row_stride;
66 const int up_offset = (it.y == last_y) ? 0 : image->row_stride;
67
68 const float *center_color = it.in(IMAGE_INPUT_INDEX);
69 zero_v4(it.out);
70 madd_v4_v4fl(it.out, center_color + down_offset + left_offset, filter_[0]);
71 madd_v4_v4fl(it.out, center_color + down_offset, filter_[1]);
72 madd_v4_v4fl(it.out, center_color + down_offset + right_offset, filter_[2]);
73 madd_v4_v4fl(it.out, center_color + left_offset, filter_[3]);
74 madd_v4_v4fl(it.out, center_color, filter_[4]);
75 madd_v4_v4fl(it.out, center_color + right_offset, filter_[5]);
76 madd_v4_v4fl(it.out, center_color + up_offset + left_offset, filter_[6]);
77 madd_v4_v4fl(it.out, center_color + up_offset, filter_[7]);
78 madd_v4_v4fl(it.out, center_color + up_offset + right_offset, filter_[8]);
79
80 const float factor = *it.in(FACTOR_INPUT_INDEX);
81 const float factor_ = 1.0f - factor;
82 it.out[0] = it.out[0] * factor + center_color[0] * factor_;
83 it.out[1] = it.out[1] * factor + center_color[1] * factor_;
84 it.out[2] = it.out[2] * factor + center_color[2] * factor_;
85 it.out[3] = it.out[3] * factor + center_color[3] * factor_;
86
87 /* Make sure we don't return negative color. */
88 CLAMP4_MIN(it.out, 0.0f);
89 }
90}
91
92} // namespace blender::compositor
MINLINE void zero_v4(float r[4])
MINLINE void madd_v4_v4fl(float r[4], const float a[4], float f)
#define CLAMP4_MIN(vec, b)
virtual void update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) final
Get input operation area being read by this operation on rendering given output area.
void set3x3Filter(float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9)
a MemoryBuffer contains access to the data
void add_output_socket(DataType datatype)
void add_input_socket(DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
void set_canvas_input_index(unsigned int index)
set the index of the input socket that will determine the canvas of this operation
typename BuffersIteratorBuilder< T >::Iterator BuffersIterator
int ymin
int ymax
int xmin
int xmax