[Bf-blender-cvs] [f4ea8f5d403] compositor-full-frame: Compositor: Full frame Despeckle node

Manuel Castilla noreply at git.blender.org
Thu Aug 12 01:06:40 CEST 2021


Commit: f4ea8f5d403bb33889135843bd015e7ea5fbf996
Author: Manuel Castilla
Date:   Wed Aug 11 11:18:07 2021 +0200
Branches: compositor-full-frame
https://developer.blender.org/rBf4ea8f5d403bb33889135843bd015e7ea5fbf996

Compositor: Full frame Despeckle node

===================================================================

M	source/blender/compositor/operations/COM_DespeckleOperation.cc
M	source/blender/compositor/operations/COM_DespeckleOperation.h

===================================================================

diff --git a/source/blender/compositor/operations/COM_DespeckleOperation.cc b/source/blender/compositor/operations/COM_DespeckleOperation.cc
index fc8778c7d2e..19bd7b2af6f 100644
--- a/source/blender/compositor/operations/COM_DespeckleOperation.cc
+++ b/source/blender/compositor/operations/COM_DespeckleOperation.cc
@@ -127,6 +127,11 @@ void DespeckleOperation::executePixel(float output[4], int x, int y, void * /*da
   else {
     copy_v4_v4(output, color_org);
   }
+
+#undef TOT_DIV_ONE
+#undef TOT_DIV_CNR
+#undef WTOT
+#undef COLOR_ADD
 }
 
 bool DespeckleOperation::determineDependingAreaOfInterest(rcti *input,
@@ -144,4 +149,106 @@ bool DespeckleOperation::determineDependingAreaOfInterest(rcti *input,
   return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
 }
 
+void DespeckleOperation::get_area_of_interest(const int input_idx,
+                                              const rcti &output_area,
+                                              rcti &r_input_area)
+{
+  switch (input_idx) {
+    case IMAGE_INPUT_INDEX: {
+      const int add_x = 2;  //(this->m_filterWidth - 1) / 2 + 1;
+      const int add_y = 2;  //(this->m_filterHeight - 1) / 2 + 1;
+      r_input_area.xmin = output_area.xmin - add_x;
+      r_input_area.xmax = output_area.xmax + add_x;
+      r_input_area.ymin = output_area.ymin - add_y;
+      r_input_area.ymax = output_area.ymax + add_y;
+      break;
+    }
+    case FACTOR_INPUT_INDEX: {
+      r_input_area = output_area;
+      break;
+    }
+  }
+}
+
+void DespeckleOperation::update_memory_buffer_partial(MemoryBuffer *output,
+                                                      const rcti &area,
+                                                      Span<MemoryBuffer *> inputs)
+{
+  const MemoryBuffer *image = inputs[IMAGE_INPUT_INDEX];
+  const int last_x = getWidth() - 1;
+  const int last_y = getHeight() - 1;
+  for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
+    const int x1 = MAX2(it.x - 1, 0);
+    const int x2 = it.x;
+    const int x3 = MIN2(it.x + 1, last_x);
+    const int y1 = MAX2(it.y - 1, 0);
+    const int y2 = it.y;
+    const int y3 = MIN2(it.y + 1, last_y);
+
+    float w = 0.0f;
+    const float *color_org = it.in(IMAGE_INPUT_INDEX);
+    float color_mid[4];
+    float color_mid_ok[4];
+    const float *in1 = nullptr;
+
+#define TOT_DIV_ONE 1.0f
+#define TOT_DIV_CNR (float)M_SQRT1_2
+
+#define WTOT (TOT_DIV_ONE * 4 + TOT_DIV_CNR * 4)
+
+#define COLOR_ADD(fac) \
+  { \
+    madd_v4_v4fl(color_mid, in1, fac); \
+    if (color_diff(in1, color_org, m_threshold)) { \
+      w += fac; \
+      madd_v4_v4fl(color_mid_ok, in1, fac); \
+    } \
+  }
+
+    zero_v4(color_mid);
+    zero_v4(color_mid_ok);
+
+    in1 = image->get_elem(x1, y1);
+    COLOR_ADD(TOT_DIV_CNR)
+    in1 = image->get_elem(x2, y1);
+    COLOR_ADD(TOT_DIV_ONE)
+    in1 = image->get_elem(x3, y1);
+    COLOR_ADD(TOT_DIV_CNR)
+    in1 = image->get_elem(x1, y2);
+    COLOR_ADD(TOT_DIV_ONE)
+
+#if 0
+  const float* in2 = image->get_elem(x2, y2);
+  madd_v4_v4fl(color_mid, in2, this->m_filter[4]);
+#endif
+
+    in1 = image->get_elem(x3, y2);
+    COLOR_ADD(TOT_DIV_ONE)
+    in1 = image->get_elem(x1, y3);
+    COLOR_ADD(TOT_DIV_CNR)
+    in1 = image->get_elem(x2, y3);
+    COLOR_ADD(TOT_DIV_ONE)
+    in1 = image->get_elem(x3, y3);
+    COLOR_ADD(TOT_DIV_CNR)
+
+    mul_v4_fl(color_mid, 1.0f / (4.0f + (4.0f * (float)M_SQRT1_2)));
+    // mul_v4_fl(color_mid, 1.0f / w);
+
+    if ((w != 0.0f) && ((w / WTOT) > (m_threshold_neighbor)) &&
+        color_diff(color_mid, color_org, m_threshold)) {
+      const float factor = *it.in(FACTOR_INPUT_INDEX);
+      mul_v4_fl(color_mid_ok, 1.0f / w);
+      interp_v4_v4v4(it.out, color_org, color_mid_ok, factor);
+    }
+    else {
+      copy_v4_v4(it.out, color_org);
+    }
+
+#undef TOT_DIV_ONE
+#undef TOT_DIV_CNR
+#undef WTOT
+#undef COLOR_ADD
+  }
+}
+
 }  // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_DespeckleOperation.h b/source/blender/compositor/operations/COM_DespeckleOperation.h
index e8d3461d2ec..70d6c2227f4 100644
--- a/source/blender/compositor/operations/COM_DespeckleOperation.h
+++ b/source/blender/compositor/operations/COM_DespeckleOperation.h
@@ -18,12 +18,15 @@
 
 #pragma once
 
-#include "COM_NodeOperation.h"
+#include "COM_MultiThreadedOperation.h"
 
 namespace blender::compositor {
 
-class DespeckleOperation : public NodeOperation {
+class DespeckleOperation : public MultiThreadedOperation {
  private:
+  constexpr static int IMAGE_INPUT_INDEX = 0;
+  constexpr static int FACTOR_INPUT_INDEX = 1;
+
   float m_threshold;
   float m_threshold_neighbor;
 
@@ -52,6 +55,11 @@ class DespeckleOperation : public NodeOperation {
 
   void initExecution() override;
   void deinitExecution() override;
+
+  void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override;
+  void update_memory_buffer_partial(MemoryBuffer *output,
+                                    const rcti &area,
+                                    Span<MemoryBuffer *> inputs) override;
 };
 
 }  // namespace blender::compositor



More information about the Bf-blender-cvs mailing list