Blender  V3.3
COM_CalculateMeanOperation.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 #include "COM_ExecutionSystem.h"
7 
8 #include "IMB_colormanagement.h"
9 
10 namespace blender::compositor {
11 
13 {
16  image_reader_ = nullptr;
17  iscalculated_ = false;
18  setting_ = 1;
19  flags_.complex = true;
20 }
22 {
24  iscalculated_ = false;
26 }
27 
28 void CalculateMeanOperation::execute_pixel(float output[4], int /*x*/, int /*y*/, void * /*data*/)
29 {
30  output[0] = result_;
31 }
32 
34 {
35  image_reader_ = nullptr;
37 }
38 
40  rcti * /*input*/, ReadBufferOperation *read_operation, rcti *output)
41 {
42  rcti image_input;
43  if (iscalculated_) {
44  return false;
45  }
46  NodeOperation *operation = get_input_operation(0);
47  image_input.xmax = operation->get_width();
48  image_input.xmin = 0;
49  image_input.ymax = operation->get_height();
50  image_input.ymin = 0;
51  if (operation->determine_depending_area_of_interest(&image_input, read_operation, output)) {
52  return true;
53  }
54  return false;
55 }
56 
58 {
59  lock_mutex();
60  if (!iscalculated_) {
63  iscalculated_ = true;
64  }
65  unlock_mutex();
66  return nullptr;
67 }
68 
70 {
71  result_ = 0.0f;
72  float *buffer = tile->get_buffer();
73  int size = tile->get_width() * tile->get_height();
74  int pixels = 0;
75  float sum = 0.0f;
76  for (int i = 0, offset = 0; i < size; i++, offset += 4) {
77  if (buffer[offset + 3] > 0) {
78  pixels++;
79 
80  switch (setting_) {
81  case 1: {
83  break;
84  }
85  case 2: {
86  sum += buffer[offset];
87  break;
88  }
89  case 3: {
90  sum += buffer[offset + 1];
91  break;
92  }
93  case 4: {
94  sum += buffer[offset + 2];
95  break;
96  }
97  case 5: {
98  float yuv[3];
100  buffer[offset + 1],
101  buffer[offset + 2],
102  &yuv[0],
103  &yuv[1],
104  &yuv[2],
106  sum += yuv[0];
107  break;
108  }
109  }
110  }
111  }
112  result_ = sum / pixels;
113 }
114 
116 {
117  setting_ = setting;
118  switch (setting) {
119  case 1: {
121  break;
122  }
123  case 2: {
124  setting_func_ = [](const float *elem) { return elem[0]; };
125  break;
126  }
127  case 3: {
128  setting_func_ = [](const float *elem) { return elem[1]; };
129  break;
130  }
131  case 4: {
132  setting_func_ = [](const float *elem) { return elem[2]; };
133  break;
134  }
135  case 5: {
136  setting_func_ = [](const float *elem) {
137  float yuv[3];
138  rgb_to_yuv(elem[0], elem[1], elem[2], &yuv[0], &yuv[1], &yuv[2], BLI_YUV_ITU_BT709);
139  return yuv[0];
140  };
141  break;
142  }
143  }
144 }
145 
147  const rcti &UNUSED(output_area),
148  rcti &r_input_area)
149 {
150  BLI_assert(input_idx == 0);
151  r_input_area = get_input_operation(input_idx)->get_canvas();
152 }
153 
155  const rcti &UNUSED(area),
157 {
158  if (!iscalculated_) {
159  MemoryBuffer *input = inputs[0];
161  iscalculated_ = true;
162  }
163 }
164 
166  const rcti &area,
168 {
169  output->fill(area, &result_);
170 }
171 
173 {
174  PixelsSum total = {0};
176  input->get_rect(),
177  [=](const rcti &split) { return calc_area_sum(input, split); },
178  total,
179  [](PixelsSum &join, const PixelsSum &chunk) {
180  join.sum += chunk.sum;
181  join.num_pixels += chunk.num_pixels;
182  });
183  return total.num_pixels == 0 ? 0.0f : total.sum / total.num_pixels;
184 }
185 
187 PixelsSum CalculateMeanOperation::calc_area_sum(const MemoryBuffer *input, const rcti &area)
188 {
189  PixelsSum result = {0};
190  for (const float *elem : input->get_buffer_area(area)) {
191  if (elem[3] <= 0.0f) {
192  continue;
193  }
194  result.sum += setting_func_(elem);
195  result.num_pixels++;
196  }
197  return result;
198 }
199 
200 } // namespace blender::compositor
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_YUV_ITU_BT709
void rgb_to_yuv(float r, float g, float b, float *r_y, float *r_u, float *r_v, int colorspace)
Definition: math_color.c:59
#define UNUSED(x)
BLI_INLINE float IMB_colormanagement_get_luminance(const float rgb[3])
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
static T sum(const btAlignedObjectArray< T > &items)
std::function< float(const float *elem)> setting_func_
virtual void update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
void execute_pixel(float output[4], int x, int y, void *data) override
SocketReader * image_reader_
Cached reference to the reader.
bool determine_depending_area_of_interest(rcti *input, ReadBufferOperation *read_operation, rcti *output) override
virtual void update_memory_buffer_started(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) override
Get input operation area being read by this operation on rendering given output area.
void execute_work(const rcti &work_rect, std::function< void(const rcti &split_rect)> work_func)
a MemoryBuffer contains access to the data of a chunk
NodeOperation contains calculation logic.
void add_output_socket(DataType datatype)
SocketReader * get_input_socket_reader(unsigned int index)
NodeOperation * get_input_operation(int index)
virtual bool determine_depending_area_of_interest(rcti *input, ReadBufferOperation *read_operation, rcti *output)
void add_input_socket(DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
virtual void * initialize_tile_data(rcti *)
ccl_global float * buffer
ccl_global KernelShaderEvalInput ccl_global float * output
ccl_global const KernelWorkTile * tile
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ccl_global KernelShaderEvalInput * input
static void area(int d1, int d2, int e1, int e2, float weights[2])
CalculateMeanOperation::PixelsSum PixelsSum
void split(const std::string &s, const char delim, std::vector< std::string > &tokens)
Definition: abc_util.cc:92
static bNodeSocketTemplate inputs[]
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