Blender  V2.93
COM_BilateralBlurOperation.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2011, Blender Foundation.
17  */
18 
20 #include "BLI_math.h"
21 
22 #include "RE_pipeline.h"
23 
24 namespace blender::compositor {
25 
27 {
31  this->flags.complex = true;
32 
33  this->m_inputColorProgram = nullptr;
34  this->m_inputDeterminatorProgram = nullptr;
35 }
36 
38 {
39  this->m_inputColorProgram = getInputSocketReader(0);
40  this->m_inputDeterminatorProgram = getInputSocketReader(1);
41  this->m_space = this->m_data->sigma_space + this->m_data->iter;
43 }
44 
45 void BilateralBlurOperation::executePixel(float output[4], int x, int y, void *data)
46 {
47  // read the determinator color at x, y, this will be used as the reference color for the
48  // determinator
49  float determinatorReferenceColor[4];
50  float determinator[4];
51  float tempColor[4];
52  float blurColor[4];
53  float blurDivider;
54  float space = this->m_space;
55  float sigmacolor = this->m_data->sigma_color;
56  int minx = floor(x - space);
57  int maxx = ceil(x + space);
58  int miny = floor(y - space);
59  int maxy = ceil(y + space);
60  float deltaColor;
61  this->m_inputDeterminatorProgram->read(determinatorReferenceColor, x, y, data);
62 
63  zero_v4(blurColor);
64  blurDivider = 0.0f;
65  /* TODO(sergey): This isn't really good bilateral filter, it should be
66  * using gaussian bell for weights. Also sigma_color doesn't seem to be
67  * used correct at all.
68  */
69  for (int yi = miny; yi < maxy; yi += QualityStepHelper::getStep()) {
70  for (int xi = minx; xi < maxx; xi += QualityStepHelper::getStep()) {
71  // read determinator
72  this->m_inputDeterminatorProgram->read(determinator, xi, yi, data);
73  deltaColor = (fabsf(determinatorReferenceColor[0] - determinator[0]) +
74  fabsf(determinatorReferenceColor[1] - determinator[1]) +
75  fabsf(determinatorReferenceColor[2] -
76  determinator[2])); // do not take the alpha channel into account
77  if (deltaColor < sigmacolor) {
78  // add this to the blur
79  this->m_inputColorProgram->read(tempColor, xi, yi, data);
80  add_v4_v4(blurColor, tempColor);
81  blurDivider += 1.0f;
82  }
83  }
84  }
85 
86  if (blurDivider > 0.0f) {
87  mul_v4_v4fl(output, blurColor, 1.0f / blurDivider);
88  }
89  else {
90  output[0] = 0.0f;
91  output[1] = 0.0f;
92  output[2] = 0.0f;
93  output[3] = 1.0f;
94  }
95 }
96 
98 {
99  this->m_inputColorProgram = nullptr;
100  this->m_inputDeterminatorProgram = nullptr;
101 }
102 
104  ReadBufferOperation *readOperation,
105  rcti *output)
106 {
107  rcti newInput;
108  int add = ceil(this->m_space) + 1;
109 
110  newInput.xmax = input->xmax + (add);
111  newInput.xmin = input->xmin - (add);
112  newInput.ymax = input->ymax + (add);
113  newInput.ymin = input->ymin - (add);
114 
115  return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
116 }
117 
118 } // namespace blender::compositor
MINLINE void mul_v4_v4fl(float r[3], const float a[4], float f)
MINLINE void add_v4_v4(float r[4], const float a[4])
MINLINE void zero_v4(float r[4])
_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 output
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) override
void executePixel(float output[4], int x, int y, void *data) override
void addInputSocket(DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
void read(float result[4], int x, int y, void *chunkData)
void addOutputSocket(DataType datatype)
SocketReader * getInputSocketReader(unsigned int inputSocketindex)
virtual bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
#define fabsf(x)
static void add(GHash *messages, MemArena *memarena, const Message *msg)
Definition: msgfmt.c:268
int ymin
Definition: DNA_vec_types.h:80
int ymax
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
int xmax
Definition: DNA_vec_types.h:79
ccl_device_inline float2 floor(const float2 &a)
ccl_device_inline float3 ceil(const float3 &a)