Blender  V3.3
COM_GaussianAlphaXBlurOperation.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2011 Blender Foundation. */
3 
5 
6 namespace blender::compositor {
7 
10 {
11 }
12 
14 {
15  lock_mutex();
16  if (!sizeavailable_) {
17  update_gauss();
18  }
19  void *buffer = get_input_operation(0)->initialize_tile_data(nullptr);
20  unlock_mutex();
21  return buffer;
22 }
23 
25 {
27 
28  init_mutex();
29 
31  float rad = max_ff(size_ * data_.sizex, 0.0f);
33 
36  }
37 }
38 
39 void GaussianAlphaXBlurOperation::update_gauss()
40 {
41  if (gausstab_ == nullptr) {
42  update_size();
43  float rad = max_ff(size_ * data_.sizex, 0.0f);
45 
47  }
48 
49  if (distbuf_inv_ == nullptr) {
50  update_size();
51  float rad = max_ff(size_ * data_.sizex, 0.0f);
52  rad = min_ff(rad, MAX_GAUSSTAB_RADIUS);
54 
56  }
57 }
58 
59 void GaussianAlphaXBlurOperation::execute_pixel(float output[4], int x, int y, void *data)
60 {
61  const bool do_invert = do_subtract_;
62  MemoryBuffer *input_buffer = (MemoryBuffer *)data;
63  float *buffer = input_buffer->get_buffer();
64  int bufferwidth = input_buffer->get_width();
65  const rcti &input_rect = input_buffer->get_rect();
66  int bufferstartx = input_rect.xmin;
67  int bufferstarty = input_rect.ymin;
68 
69  const rcti &rect = input_buffer->get_rect();
70  int xmin = max_ii(x - filtersize_, rect.xmin);
71  int xmax = min_ii(x + filtersize_ + 1, rect.xmax);
72  int ymin = max_ii(y, rect.ymin);
73 
74  /* *** this is the main part which is different to 'GaussianXBlurOperation' *** */
75  int step = get_step();
76  int bufferindex = ((xmin - bufferstartx)) + ((ymin - bufferstarty) * bufferwidth);
77 
78  /* gauss */
79  float alpha_accum = 0.0f;
80  float multiplier_accum = 0.0f;
81 
82  /* dilate */
83  float value_max = finv_test(
84  buffer[(x) + (y * bufferwidth)],
85  do_invert); /* init with the current color to avoid unneeded lookups */
86  float distfacinv_max = 1.0f; /* 0 to 1 */
87 
88  for (int nx = xmin; nx < xmax; nx += step) {
89  const int index = (nx - x) + filtersize_;
90  float value = finv_test(buffer[bufferindex], do_invert);
91  float multiplier;
92 
93  /* gauss */
94  {
95  multiplier = gausstab_[index];
96  alpha_accum += value * multiplier;
97  multiplier_accum += multiplier;
98  }
99 
100  /* dilate - find most extreme color */
101  if (value > value_max) {
102  multiplier = distbuf_inv_[index];
103  value *= multiplier;
104  if (value > value_max) {
105  value_max = value;
106  distfacinv_max = multiplier;
107  }
108  }
109  bufferindex += step;
110  }
111 
112  /* blend between the max value and gauss blue - gives nice feather */
113  const float value_blur = alpha_accum / multiplier_accum;
114  const float value_final = (value_max * distfacinv_max) + (value_blur * (1.0f - distfacinv_max));
115  output[0] = finv_test(value_final, do_invert);
116 }
117 
119 {
121 
122  if (gausstab_) {
124  gausstab_ = nullptr;
125  }
126 
127  if (distbuf_inv_) {
129  distbuf_inv_ = nullptr;
130  }
131 
132  deinit_mutex();
133 }
134 
136  rcti *input, ReadBufferOperation *read_operation, rcti *output)
137 {
138  rcti new_input;
139 #if 0 /* until we add size input */
140  rcti size_input;
141  size_input.xmin = 0;
142  size_input.ymin = 0;
143  size_input.xmax = 5;
144  size_input.ymax = 5;
145 
146  NodeOperation *operation = this->get_input_operation(1);
147  if (operation->determine_depending_area_of_interest(&size_input, read_operation, output)) {
148  return true;
149  }
150  else
151 #endif
152  {
153  if (sizeavailable_ && gausstab_ != nullptr) {
154  new_input.xmax = input->xmax + filtersize_ + 1;
155  new_input.xmin = input->xmin - filtersize_ - 1;
156  new_input.ymax = input->ymax;
157  new_input.ymin = input->ymin;
158  }
159  else {
160  new_input.xmax = this->get_width();
161  new_input.xmin = 0;
162  new_input.ymax = this->get_height();
163  new_input.ymin = 0;
164  }
165  return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output);
166  }
167 }
168 
169 } // namespace blender::compositor
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
#define MAX_GAUSSTAB_RADIUS
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
#define X
Definition: GeomUtils.cpp:199
float * make_gausstab(float rad, int size)
float * make_dist_fac_inverse(float rad, int size, int falloff)
BLI_INLINE float finv_test(const float f, const bool test)
bool determine_depending_area_of_interest(rcti *input, ReadBufferOperation *read_operation, rcti *output) override
void deinit_execution() override
Deinitialize the execution.
void execute_pixel(float output[4], int x, int y, void *data) override
The inner loop of this operation.
a MemoryBuffer contains access to the data of a chunk
const rcti & get_rect() const
get the rect of this MemoryBuffer
const int get_width() const
get the width of this MemoryBuffer
float * get_buffer()
get the data of this MemoryBuffer
NodeOperation contains calculation logic.
NodeOperation * get_input_operation(int index)
virtual bool determine_depending_area_of_interest(rcti *input, ReadBufferOperation *read_operation, rcti *output)
virtual void * initialize_tile_data(rcti *)
ccl_global float * buffer
ccl_global KernelShaderEvalInput ccl_global float * output
ccl_global KernelShaderEvalInput * input
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
ccl_device_inline float3 ceil(const float3 &a)
Definition: math_float3.h:363
int ymin
Definition: DNA_vec_types.h:64
int ymax
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
int xmax
Definition: DNA_vec_types.h:63