Blender  V3.3
COM_MemoryBuffer.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2011 Blender Foundation. */
3 
4 #include "COM_MemoryBuffer.h"
5 
6 #include "COM_MemoryProxy.h"
7 
8 #include "IMB_colormanagement.h"
9 #include "IMB_imbuf_types.h"
10 
11 #define ASSERT_BUFFER_CONTAINS_AREA(buf, area) \
12  BLI_assert(BLI_rcti_inside_rcti(&(buf)->get_rect(), &(area)))
13 
14 #define ASSERT_BUFFER_CONTAINS_AREA_AT_COORDS(buf, area, x, y) \
15  BLI_assert((buf)->get_rect().xmin <= (x)); \
16  BLI_assert((buf)->get_rect().ymin <= (y)); \
17  BLI_assert((buf)->get_rect().xmax >= (x) + BLI_rcti_size_x(&(area))); \
18  BLI_assert((buf)->get_rect().ymax >= (y) + BLI_rcti_size_y(&(area)))
19 
20 #define ASSERT_VALID_ELEM_SIZE(buf, channel_offset, elem_size) \
21  BLI_assert((buf)->get_num_channels() >= (channel_offset) + (elem_size))
22 
23 namespace blender::compositor {
24 
25 static rcti create_rect(const int width, const int height)
26 {
27  rcti rect;
28  BLI_rcti_init(&rect, 0, width, 0, height);
29  return rect;
30 }
31 
33 {
34  rect_ = rect;
35  is_a_single_elem_ = false;
36  memory_proxy_ = memory_proxy;
37  num_channels_ = COM_data_type_num_channels(memory_proxy->get_data_type());
38  buffer_ = (float *)MEM_mallocN_aligned(
39  sizeof(float) * buffer_len() * num_channels_, 16, "COM_MemoryBuffer");
40  owns_data_ = true;
41  state_ = state;
42  datatype_ = memory_proxy->get_data_type();
43 
44  set_strides();
45 }
46 
47 MemoryBuffer::MemoryBuffer(DataType data_type, const rcti &rect, bool is_a_single_elem)
48 {
49  rect_ = rect;
50  is_a_single_elem_ = is_a_single_elem;
51  memory_proxy_ = nullptr;
52  num_channels_ = COM_data_type_num_channels(data_type);
53  buffer_ = (float *)MEM_mallocN_aligned(
54  sizeof(float) * buffer_len() * num_channels_, 16, "COM_MemoryBuffer");
55  owns_data_ = true;
57  datatype_ = data_type;
58 
59  set_strides();
60 }
61 
63  float *buffer, int num_channels, int width, int height, bool is_a_single_elem)
64  : MemoryBuffer(buffer, num_channels, create_rect(width, height), is_a_single_elem)
65 {
66 }
67 
69  const int num_channels,
70  const rcti &rect,
71  const bool is_a_single_elem)
72 {
73  rect_ = rect;
74  is_a_single_elem_ = is_a_single_elem;
75  memory_proxy_ = nullptr;
76  num_channels_ = num_channels;
77  datatype_ = COM_num_channels_data_type(num_channels);
78  buffer_ = buffer;
79  owns_data_ = false;
81 
82  set_strides();
83 }
84 
85 MemoryBuffer::MemoryBuffer(const MemoryBuffer &src) : MemoryBuffer(src.datatype_, src.rect_, false)
86 {
87  memory_proxy_ = src.memory_proxy_;
88  /* src may be single elem buffer */
89  fill_from(src);
90 }
91 
92 void MemoryBuffer::set_strides()
93 {
94  if (is_a_single_elem_) {
95  this->elem_stride = 0;
96  this->row_stride = 0;
97  }
98  else {
99  this->elem_stride = num_channels_;
100  this->row_stride = get_width() * num_channels_;
101  }
102  to_positive_x_stride_ = rect_.xmin < 0 ? -rect_.xmin + 1 : (rect_.xmin == 0 ? 1 : 0);
103  to_positive_y_stride_ = rect_.ymin < 0 ? -rect_.ymin + 1 : (rect_.ymin == 0 ? 1 : 0);
104 }
105 
107 {
108  memset(buffer_, 0, buffer_len() * num_channels_ * sizeof(float));
109 }
110 
112 {
113  return iterate_with(inputs, rect_);
114 }
115 
117 {
118  BuffersIteratorBuilder<float> builder(buffer_, rect_, area, elem_stride);
119  for (MemoryBuffer *input : inputs) {
120  builder.add_input(input->get_buffer(), input->get_rect(), input->elem_stride);
121  }
122  return builder.build();
123 }
124 
126 {
128  MemoryBuffer *inflated = new MemoryBuffer(datatype_, rect_, false);
129  inflated->copy_from(this, rect_);
130  return inflated;
131 }
132 
134 {
135  float result = buffer_[0];
136  const unsigned int size = this->buffer_len();
137  unsigned int i;
138 
139  const float *fp_src = buffer_;
140 
141  for (i = 0; i < size; i++, fp_src += num_channels_) {
142  float value = *fp_src;
143  if (value > result) {
144  result = value;
145  }
146  }
147 
148  return result;
149 }
150 
151 float MemoryBuffer::get_max_value(const rcti &rect) const
152 {
153  rcti rect_clamp;
154 
155  /* first clamp the rect by the bounds or we get un-initialized values */
156  BLI_rcti_isect(&rect, &rect_, &rect_clamp);
157 
158  if (!BLI_rcti_is_empty(&rect_clamp)) {
159  MemoryBuffer temp_buffer(datatype_, rect_clamp);
160  temp_buffer.fill_from(*this);
161  return temp_buffer.get_max_value();
162  }
163 
164  BLI_assert(0);
165  return 0.0f;
166 }
167 
169 {
170  if (buffer_ && owns_data_) {
171  MEM_freeN(buffer_);
172  buffer_ = nullptr;
173  }
174 }
175 
177 {
178  copy_from(src, area, area.xmin, area.ymin);
179 }
180 
182  const rcti &area,
183  const int to_x,
184  const int to_y)
185 {
186  BLI_assert(this->get_num_channels() == src->get_num_channels());
187  copy_from(src, area, 0, src->get_num_channels(), to_x, to_y, 0);
188 }
189 
191  const rcti &area,
192  const int channel_offset,
193  const int elem_size,
194  const int to_channel_offset)
195 {
196  copy_from(src, area, channel_offset, elem_size, area.xmin, area.ymin, to_channel_offset);
197 }
198 
200  const rcti &area,
201  const int channel_offset,
202  const int elem_size,
203  const int to_x,
204  const int to_y,
205  const int to_channel_offset)
206 {
207  if (this->is_a_single_elem()) {
208  copy_single_elem_from(src, channel_offset, elem_size, to_channel_offset);
209  }
210  else if (!src->is_a_single_elem() && elem_size == src->get_num_channels() &&
211  elem_size == this->get_num_channels()) {
212  BLI_assert(to_channel_offset == 0);
213  BLI_assert(channel_offset == 0);
214  copy_rows_from(src, area, to_x, to_y);
215  }
216  else {
217  copy_elems_from(src, area, channel_offset, elem_size, to_x, to_y, to_channel_offset);
218  }
219 }
220 
222 {
223  const int elem_stride = this->get_num_channels();
224  const int row_stride = elem_stride * get_width();
225  copy_from(src, area, 0, this->get_num_channels(), elem_stride, row_stride, 0);
226 }
227 
229  const rcti &area,
230  const int channel_offset,
231  const int elem_size,
232  const int elem_stride,
233  const int row_stride,
234  const int to_channel_offset)
235 {
236  copy_from(src,
237  area,
238  channel_offset,
239  elem_size,
240  elem_stride,
241  row_stride,
242  area.xmin,
243  area.ymin,
244  to_channel_offset);
245 }
246 
248  const rcti &area,
249  const int channel_offset,
250  const int elem_size,
251  const int elem_stride,
252  const int row_stride,
253  const int to_x,
254  const int to_y,
255  const int to_channel_offset)
256 {
257  ASSERT_BUFFER_CONTAINS_AREA_AT_COORDS(this, area, to_x, to_y);
258  ASSERT_VALID_ELEM_SIZE(this, to_channel_offset, elem_size);
259 
260  const int width = BLI_rcti_size_x(&area);
261  const int height = BLI_rcti_size_y(&area);
262  const uchar *const src_start = src + area.ymin * row_stride + channel_offset;
263  for (int y = 0; y < height; y++) {
264  const uchar *from_elem = src_start + y * row_stride + area.xmin * elem_stride;
265  float *to_elem = &this->get_value(to_x, to_y + y, to_channel_offset);
266  const float *row_end = to_elem + width * this->elem_stride;
267  while (to_elem < row_end) {
268  for (int i = 0; i < elem_size; i++) {
269  to_elem[i] = ((float)from_elem[i]) * (1.0f / 255.0f);
270  }
271  to_elem += this->elem_stride;
272  from_elem += elem_stride;
273  }
274  }
275 }
276 
278 {
279  const int width = BLI_rcti_size_x(&area);
280  const int height = BLI_rcti_size_y(&area);
281  float *out = get_elem(area.xmin, area.ymin);
282  /* If area allows continuous memory do conversion in one step. Otherwise per row. */
283  if (get_width() == width) {
285  }
286  else {
287  for (int y = 0; y < height; y++) {
289  out += row_stride;
290  }
291  }
292 }
293 
294 static void colorspace_to_scene_linear(MemoryBuffer *buf, const rcti &area, ColorSpace *colorspace)
295 {
296  const int width = BLI_rcti_size_x(&area);
297  const int height = BLI_rcti_size_y(&area);
298  float *out = buf->get_elem(area.xmin, area.ymin);
299  /* If area allows continuous memory do conversion in one step. Otherwise per row. */
300  if (buf->get_width() == width) {
302  out, width, height, buf->get_num_channels(), colorspace, false);
303  }
304  else {
305  for (int y = 0; y < height; y++) {
307  out, width, 1, buf->get_num_channels(), colorspace, false);
308  out += buf->row_stride;
309  }
310  }
311 }
312 
313 void MemoryBuffer::copy_from(const ImBuf *src, const rcti &area, const bool ensure_linear_space)
314 {
315  copy_from(src, area, 0, this->get_num_channels(), 0, ensure_linear_space);
316 }
317 
318 void MemoryBuffer::copy_from(const ImBuf *src,
319  const rcti &area,
320  const int channel_offset,
321  const int elem_size,
322  const int to_channel_offset,
323  const bool ensure_linear_space)
324 {
325  copy_from(src,
326  area,
327  channel_offset,
328  elem_size,
329  area.xmin,
330  area.ymin,
331  to_channel_offset,
332  ensure_linear_space);
333 }
334 
335 void MemoryBuffer::copy_from(const ImBuf *src,
336  const rcti &area,
337  const int channel_offset,
338  const int elem_size,
339  const int to_x,
340  const int to_y,
341  const int to_channel_offset,
342  const bool ensure_linear_space)
343 {
344  if (src->rect_float) {
345  const MemoryBuffer mem_buf(src->rect_float, src->channels, src->x, src->y, false);
346  copy_from(&mem_buf, area, channel_offset, elem_size, to_x, to_y, to_channel_offset);
347  }
348  else if (src->rect) {
349  const uchar *uc_buf = (uchar *)src->rect;
350  const int elem_stride = src->channels;
351  const int row_stride = elem_stride * src->x;
352  copy_from(uc_buf,
353  area,
354  channel_offset,
355  elem_size,
356  elem_stride,
357  row_stride,
358  to_x,
359  to_y,
360  to_channel_offset);
361  if (ensure_linear_space) {
362  colorspace_to_scene_linear(this, area, src->rect_colorspace);
363  }
364  }
365  else {
366  /* Empty ImBuf source. Fill destination with empty values. */
367  const float *zero_elem = new float[elem_size]{0};
368  fill(area, to_channel_offset, zero_elem, elem_size);
369  delete[] zero_elem;
370  }
371 }
372 
373 void MemoryBuffer::fill(const rcti &area, const float *value)
374 {
375  fill(area, 0, value, this->get_num_channels());
376 }
377 
379  const int channel_offset,
380  const float *value,
381  const int value_size)
382 {
383  const MemoryBuffer single_elem(const_cast<float *>(value), value_size, this->get_rect(), true);
384  copy_from(&single_elem, area, 0, value_size, area.xmin, area.ymin, channel_offset);
385 }
386 
388 {
389  rcti overlap;
390  overlap.xmin = MAX2(rect_.xmin, src.rect_.xmin);
391  overlap.xmax = MIN2(rect_.xmax, src.rect_.xmax);
392  overlap.ymin = MAX2(rect_.ymin, src.rect_.ymin);
393  overlap.ymax = MIN2(rect_.ymax, src.rect_.ymax);
394  copy_from(&src, overlap);
395 }
396 
397 void MemoryBuffer::write_pixel(int x, int y, const float color[4])
398 {
399  if (x >= rect_.xmin && x < rect_.xmax && y >= rect_.ymin && y < rect_.ymax) {
400  const int offset = get_coords_offset(x, y);
401  memcpy(&buffer_[offset], color, sizeof(float) * num_channels_);
402  }
403 }
404 
405 void MemoryBuffer::add_pixel(int x, int y, const float color[4])
406 {
407  if (x >= rect_.xmin && x < rect_.xmax && y >= rect_.ymin && y < rect_.ymax) {
408  const int offset = get_coords_offset(x, y);
409  float *dst = &buffer_[offset];
410  const float *src = color;
411  for (int i = 0; i < num_channels_; i++, dst++, src++) {
412  *dst += *src;
413  }
414  }
415 }
416 
417 static void read_ewa_elem(void *userdata, int x, int y, float result[4])
418 {
419  const MemoryBuffer *buffer = static_cast<const MemoryBuffer *>(userdata);
420  buffer->read_elem_checked(x, y, result);
421 }
422 
424  const float x, const float y, float dx[2], float dy[2], float *out) const
425 {
426  BLI_assert(datatype_ == DataType::Color);
427 
428  const float deriv[2][2] = {{dx[0], dx[1]}, {dy[0], dy[1]}};
429 
430  float inv_width = 1.0f / (float)this->get_width(), inv_height = 1.0f / (float)this->get_height();
431  /* TODO(sergey): Render pipeline uses normalized coordinates and derivatives,
432  * but compositor uses pixel space. For now let's just divide the values and
433  * switch compositor to normalized space for EWA later.
434  */
435  float uv_normal[2] = {get_relative_x(x) * inv_width, get_relative_y(y) * inv_height};
436  float du_normal[2] = {deriv[0][0] * inv_width, deriv[0][1] * inv_height};
437  float dv_normal[2] = {deriv[1][0] * inv_width, deriv[1][1] * inv_height};
438 
439  BLI_ewa_filter(this->get_width(),
440  this->get_height(),
441  false,
442  true,
443  uv_normal,
444  du_normal,
445  dv_normal,
447  const_cast<MemoryBuffer *>(this),
448  out);
449 }
450 
451 /* TODO(manzanilla): to be removed with tiled implementation. */
452 static void read_ewa_pixel_sampled(void *userdata, int x, int y, float result[4])
453 {
454  MemoryBuffer *buffer = (MemoryBuffer *)userdata;
455  buffer->read(result, x, y);
456 }
457 
458 /* TODO(manzanilla): to be removed with tiled implementation. */
459 void MemoryBuffer::readEWA(float *result, const float uv[2], const float derivatives[2][2])
460 {
461  if (is_a_single_elem_) {
462  memcpy(result, buffer_, sizeof(float) * num_channels_);
463  }
464  else {
465  BLI_assert(datatype_ == DataType::Color);
466  float inv_width = 1.0f / (float)this->get_width(),
467  inv_height = 1.0f / (float)this->get_height();
468  /* TODO(sergey): Render pipeline uses normalized coordinates and derivatives,
469  * but compositor uses pixel space. For now let's just divide the values and
470  * switch compositor to normalized space for EWA later.
471  */
472  float uv_normal[2] = {uv[0] * inv_width, uv[1] * inv_height};
473  float du_normal[2] = {derivatives[0][0] * inv_width, derivatives[0][1] * inv_height};
474  float dv_normal[2] = {derivatives[1][0] * inv_width, derivatives[1][1] * inv_height};
475 
476  BLI_ewa_filter(this->get_width(),
477  this->get_height(),
478  false,
479  true,
480  uv_normal,
481  du_normal,
482  dv_normal,
484  this,
485  result);
486  }
487 }
488 
489 void MemoryBuffer::copy_single_elem_from(const MemoryBuffer *src,
490  const int channel_offset,
491  const int elem_size,
492  const int to_channel_offset)
493 {
494  ASSERT_VALID_ELEM_SIZE(this, to_channel_offset, elem_size);
495  ASSERT_VALID_ELEM_SIZE(src, channel_offset, elem_size);
496  BLI_assert(this->is_a_single_elem());
497 
498  float *to_elem = &this->get_value(
499  this->get_rect().xmin, this->get_rect().ymin, to_channel_offset);
500  const float *from_elem = &src->get_value(
501  src->get_rect().xmin, src->get_rect().ymin, channel_offset);
502  const int elem_bytes = elem_size * sizeof(float);
503  memcpy(to_elem, from_elem, elem_bytes);
504 }
505 
506 void MemoryBuffer::copy_rows_from(const MemoryBuffer *src,
507  const rcti &area,
508  const int to_x,
509  const int to_y)
510 {
512  ASSERT_BUFFER_CONTAINS_AREA_AT_COORDS(this, area, to_x, to_y);
513  BLI_assert(this->get_num_channels() == src->get_num_channels());
514  BLI_assert(!this->is_a_single_elem());
515  BLI_assert(!src->is_a_single_elem());
516 
517  const int width = BLI_rcti_size_x(&area);
518  const int height = BLI_rcti_size_y(&area);
519  const int row_bytes = this->get_num_channels() * width * sizeof(float);
520  for (int y = 0; y < height; y++) {
521  float *to_row = this->get_elem(to_x, to_y + y);
522  const float *from_row = src->get_elem(area.xmin, area.ymin + y);
523  memcpy(to_row, from_row, row_bytes);
524  }
525 }
526 
527 void MemoryBuffer::copy_elems_from(const MemoryBuffer *src,
528  const rcti &area,
529  const int channel_offset,
530  const int elem_size,
531  const int to_x,
532  const int to_y,
533  const int to_channel_offset)
534 {
536  ASSERT_BUFFER_CONTAINS_AREA_AT_COORDS(this, area, to_x, to_y);
537  ASSERT_VALID_ELEM_SIZE(this, to_channel_offset, elem_size);
538  ASSERT_VALID_ELEM_SIZE(src, channel_offset, elem_size);
539 
540  const int width = BLI_rcti_size_x(&area);
541  const int height = BLI_rcti_size_y(&area);
542  const int elem_bytes = elem_size * sizeof(float);
543  for (int y = 0; y < height; y++) {
544  float *to_elem = &this->get_value(to_x, to_y + y, to_channel_offset);
545  const float *from_elem = &src->get_value(area.xmin, area.ymin + y, channel_offset);
546  const float *row_end = to_elem + width * this->elem_stride;
547  while (to_elem < row_end) {
548  memcpy(to_elem, from_elem, elem_bytes);
549  to_elem += this->elem_stride;
550  from_elem += src->elem_stride;
551  }
552  }
553 }
554 
555 } // namespace blender::compositor
typedef float(TangentPoint)[2]
#define BLI_assert(a)
Definition: BLI_assert.h:46
void BLI_ewa_filter(int width, int height, bool intpol, bool use_alpha, const float uv[2], const float du[2], const float dv[2], ewa_filter_read_pixel_cb read_pixel_cb, void *userdata, float result[4])
Definition: math_interp.c:584
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:190
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
Definition: rct.c:417
bool BLI_rcti_isect(const struct rcti *src1, const struct rcti *src2, struct rcti *dest)
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:186
bool BLI_rcti_is_empty(const struct rcti *rect)
unsigned char uchar
Definition: BLI_sys_types.h:70
#define MAX2(a, b)
#define MIN2(a, b)
#define ASSERT_VALID_ELEM_SIZE(buf, channel_offset, elem_size)
#define ASSERT_BUFFER_CONTAINS_AREA_AT_COORDS(buf, area, x, y)
#define ASSERT_BUFFER_CONTAINS_AREA(buf, area)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_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
_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 GLsizei width
void IMB_colormanagement_processor_apply(struct ColormanageProcessor *cm_processor, float *buffer, int width, int height, int channels, bool predivide)
void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, int width, int height, int channels, struct ColorSpace *colorspace, bool predivide)
Contains defines and structs used throughout the imbuf module.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
void add_input(const T *input, const rcti &buffer_area, int elem_stride=1)
BuffersIteratorBuilder::Iterator build()
a MemoryBuffer contains access to the data of a chunk
MemoryBuffer(MemoryProxy *memory_proxy, const rcti &rect, MemoryBufferState state)
construct new temporarily MemoryBuffer for an area
void copy_from(const MemoryBuffer *src, const rcti &area)
const rcti & get_rect() const
get the rect of this MemoryBuffer
const int get_width() const
get the width of this MemoryBuffer
intptr_t get_coords_offset(int x, int y) const
const int get_height() const
get the height of this MemoryBuffer
void write_pixel(int x, int y, const float color[4])
void fill(const rcti &area, const float *value)
void fill_from(const MemoryBuffer &src)
add the content from other_buffer to this MemoryBuffer
void readEWA(float *result, const float uv[2], const float derivatives[2][2])
float & get_value(int x, int y, int channel)
void apply_processor(ColormanageProcessor &processor, const rcti area)
Apply a color processor on the given area.
void add_pixel(int x, int y, const float color[4])
BuffersIterator< float > iterate_with(Span< MemoryBuffer * > inputs)
void clear()
clear the buffer. Make all pixels black transparent.
void read_elem_filtered(float x, float y, float dx[2], float dy[2], float *out) const
A MemoryProxy is a unique identifier for a memory buffer. A single MemoryProxy is used among all chun...
SyclQueue void void * src
MemoryBufferState
state of a memory buffer
@ Temporary
chunk is consolidated from other chunks. special state.
DataType
possible data types for sockets
Definition: COM_defines.h:30
ccl_global float * buffer
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ccl_global KernelShaderEvalInput * input
const int state
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_mallocN_aligned)(size_t len, size_t alignment, const char *str)
Definition: mallocn.c:35
static void read_ewa_elem(void *userdata, int x, int y, float result[4])
static void area(int d1, int d2, int e1, int e2, float weights[2])
static rcti create_rect(const int width, const int height)
constexpr DataType COM_num_channels_data_type(const int num_channels)
Definition: COM_defines.h:73
typename BuffersIteratorBuilder< T >::Iterator BuffersIterator
static void read_ewa_pixel_sampled(void *userdata, int x, int y, float result[4])
constexpr int COM_data_type_num_channels(const DataType datatype)
Definition: COM_defines.h:42
static void colorspace_to_scene_linear(MemoryBuffer *buf, const rcti &area, ColorSpace *colorspace)
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
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