53 double q, q2, sc, cf[4], tsM[9], tsu[3], tsv[3];
67 if ((
xy < 1) || (
xy > 3)) {
86 if (sigma >= 3.556f) {
87 q = 0.9804f * (sigma - 3.556f) + 2.5091f;
90 q = (0.0561f * sigma + 0.5784f) * sigma - 0.2568f;
93 sc = (1.1668 + q) * (3.203729649 + (2.21566 + q) * q);
96 cf[1] = q * (5.788961737 + (6.76492 + 3.0 * q) * q) / sc;
97 cf[2] = -q2 * (3.38246 + 3.0 * q) / sc;
100 cf[0] = 1.0 - cf[1] - cf[2] - cf[3];
109 sc = cf[0] / ((1.0 + cf[1] - cf[2] + cf[3]) * (1.0 - cf[1] - cf[2] - cf[3]) *
110 (1.0 + cf[2] + (cf[1] - cf[3]) * cf[3]));
111 tsM[0] = sc * (-cf[3] * cf[1] + 1.0 - cf[3] * cf[3] - cf[2]);
112 tsM[1] = sc * ((cf[3] + cf[1]) * (cf[2] + cf[3] * cf[1]));
113 tsM[2] = sc * (cf[3] * (cf[1] + cf[3] * cf[2]));
114 tsM[3] = sc * (cf[1] + cf[3] * cf[2]);
115 tsM[4] = sc * (-(cf[2] - 1.0) * (cf[2] + cf[3] * cf[1]));
116 tsM[5] = sc * (-(cf[3] * cf[1] + cf[3] * cf[3] + cf[2] - 1.0) * cf[3]);
117 tsM[6] = sc * (cf[3] * cf[1] + cf[2] + cf[1] * cf[1] - cf[2] * cf[2]);
118 tsM[7] = sc * (cf[1] * cf[2] + cf[3] * cf[2] * cf[2] - cf[1] * cf[3] * cf[3] -
119 cf[3] * cf[3] * cf[3] - cf[3] * cf[2] + cf[3]);
120 tsM[8] = sc * (cf[3] * (cf[1] + cf[3] * cf[2]));
124 W[0] = cf[0] * X[0] + cf[1] * X[0] + cf[2] * X[0] + cf[3] * X[0]; \
125 W[1] = cf[0] * X[1] + cf[1] * W[0] + cf[2] * X[0] + cf[3] * X[0]; \
126 W[2] = cf[0] * X[2] + cf[1] * W[1] + cf[2] * W[0] + cf[3] * X[0]; \
127 for (i = 3; i < L; i++) { \
128 W[i] = cf[0] * X[i] + cf[1] * W[i - 1] + cf[2] * W[i - 2] + cf[3] * W[i - 3]; \
130 tsu[0] = W[L - 1] - X[L - 1]; \
131 tsu[1] = W[L - 2] - X[L - 1]; \
132 tsu[2] = W[L - 3] - X[L - 1]; \
133 tsv[0] = tsM[0] * tsu[0] + tsM[1] * tsu[1] + tsM[2] * tsu[2] + X[L - 1]; \
134 tsv[1] = tsM[3] * tsu[0] + tsM[4] * tsu[1] + tsM[5] * tsu[2] + X[L - 1]; \
135 tsv[2] = tsM[6] * tsu[0] + tsM[7] * tsu[1] + tsM[8] * tsu[2] + X[L - 1]; \
136 Y[L - 1] = cf[0] * W[L - 1] + cf[1] * tsv[0] + cf[2] * tsv[1] + cf[3] * tsv[2]; \
137 Y[L - 2] = cf[0] * W[L - 2] + cf[1] * Y[L - 1] + cf[2] * tsv[0] + cf[3] * tsv[1]; \
138 Y[L - 3] = cf[0] * W[L - 3] + cf[1] * Y[L - 2] + cf[2] * Y[L - 1] + cf[3] * tsv[0]; \
140 for (i = L - 4; i != UINT_MAX; i--) { \
141 Y[i] = cf[0] * W[i] + cf[1] * Y[i + 1] + cf[2] * Y[i + 2] + cf[3] * Y[i + 3]; \
147 src_dim_max = std::max(src_width, src_height);
148 X = (
double *)
MEM_callocN(src_dim_max *
sizeof(
double),
"IIR_gauss X buf");
149 Y = (
double *)
MEM_callocN(src_dim_max *
sizeof(
double),
"IIR_gauss Y buf");
150 W = (
double *)
MEM_callocN(src_dim_max *
sizeof(
double),
"IIR_gauss W buf");
153 for (
y = 0;
y < src_height;
y++) {
154 const int yx =
y * src_width;
155 offset = yx * num_channels + chan;
156 for (
x = 0;
x < src_width;
x++) {
157 X[
x] = buffer[offset];
158 offset += num_channels;
161 offset = yx * num_channels + chan;
162 for (
x = 0;
x < src_width;
x++) {
163 buffer[offset] =
Y[
x];
164 offset += num_channels;
170 const int add = src_width * num_channels;
172 for (
x = 0;
x < src_width;
x++) {
173 offset =
x * num_channels + chan;
174 for (
y = 0;
y < src_height;
y++) {
175 X[
y] = buffer[offset];
179 offset =
x * num_channels + chan;
180 for (
y = 0;
y < src_height;
y++) {
181 buffer[offset] =
Y[
y];
194 const rcti &output_area,
216 if (is_full_output) {
222 image->copy_from(input, area);
224 if ((sigma_x_ == sigma_y_) && (sigma_x_ > 0.0f)) {
230 if (sigma_x_ > 0.0f) {
235 if (sigma_y_ > 0.0f) {
242 if (!is_full_output) {
bool BLI_rcti_compare(const struct rcti *rect_a, const struct rcti *rect_b)
virtual void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override
Get input operation area being read by this operation on rendering given output area.
virtual void init_data() override
BlurBaseOperation(DataType data_type8)
static constexpr int IMAGE_INPUT_INDEX
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override
Get input operation area being read by this operation on rendering given output area.
void deinit_execution() override
void set_size(int size_x, int size_y)
void init_execution() override
FastGaussianBlurOperation()
static void IIR_gauss(MemoryBuffer *src, float sigma, unsigned int channel, unsigned int xy)
void init_data() override
void update_memory_buffer_started(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
a MemoryBuffer contains access to the data
uint8_t get_num_channels() const
const int get_width() const
get the width of this MemoryBuffer
const int get_height() const
get the height of this MemoryBuffer
float * get_buffer()
get the data of this MemoryBuffer
bool is_a_single_elem() const
virtual void init_execution()
NodeOperationOutput * get_output_socket(unsigned int index=0)
const rcti & get_canvas() const
input_tx image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "preview_img") .compute_source("compositor_compute_preview.glsl") .do_static_compilation(true)
DataType
possible data types for sockets
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
static void add(blender::Map< std::string, std::string > &messages, Message &msg)
constexpr int COM_DATA_TYPE_COLOR_CHANNELS
static blender::bke::bNodeSocketTemplate inputs[]