10#define ASSERT_BUFFER_CONTAINS_AREA(buf, area) \
11 BLI_assert(BLI_rcti_inside_rcti(&(buf)->get_rect(), &(area)))
13#define ASSERT_BUFFER_CONTAINS_AREA_AT_COORDS(buf, area, x, y) \
14 BLI_assert((buf)->get_rect().xmin <= (x)); \
15 BLI_assert((buf)->get_rect().ymin <= (y)); \
16 BLI_assert((buf)->get_rect().xmax >= (x) + BLI_rcti_size_x(&(area))); \
17 BLI_assert((buf)->get_rect().ymax >= (y) + BLI_rcti_size_y(&(area)))
19#define ASSERT_VALID_ELEM_SIZE(buf, channel_offset, elem_size) \
20 BLI_assert((buf)->get_num_channels() >= (channel_offset) + (elem_size))
34 is_a_single_elem_ =
false;
37 sizeof(
float) * buffer_len() * num_channels_, 16,
"COM_MemoryBuffer");
39 datatype_ = data_type;
50 sizeof(
float) * buffer_len() * num_channels_, 16,
"COM_MemoryBuffer");
52 datatype_ = data_type;
58 float *buffer,
int num_channels,
int width,
int height,
bool is_a_single_elem)
64 const int num_channels,
66 const bool is_a_single_elem)
70 num_channels_ = num_channels;
84void MemoryBuffer::set_strides()
86 if (is_a_single_elem_) {
94 to_positive_x_stride_ = rect_.
xmin < 0 ? -rect_.
xmin + 1 : (rect_.
xmin == 0 ? 1 : 0);
95 to_positive_y_stride_ = rect_.
ymin < 0 ? -rect_.
ymin + 1 : (rect_.
ymin == 0 ? 1 : 0);
100 memset(buffer_, 0, buffer_len() * num_channels_ *
sizeof(
float));
112 builder.
add_input(input->get_buffer(), input->get_rect(), input->elem_stride);
114 return builder.
build();
127 float result = buffer_[0];
128 const int64_t size = this->buffer_len();
131 const float *fp_src = buffer_;
133 for (i = 0; i <
size; i++, fp_src += num_channels_) {
134 float value = *fp_src;
135 if (value > result) {
162 if (buffer_ && owns_data_) {
170 copy_from(src, area, area.xmin, area.ymin);
184 const int channel_offset,
186 const int to_channel_offset)
188 copy_from(src, area, channel_offset, elem_size, area.xmin, area.ymin, to_channel_offset);
193 const int channel_offset,
197 const int to_channel_offset)
200 copy_single_elem_from(src, channel_offset, elem_size, to_channel_offset);
203 elem_size == this->get_num_channels())
207 copy_rows_from(src, area, to_x, to_y);
210 copy_elems_from(src, area, channel_offset, elem_size, to_x, to_y, to_channel_offset);
223 const int channel_offset,
225 const int elem_stride,
226 const int row_stride,
227 const int to_channel_offset)
242 const int channel_offset,
244 const int elem_stride,
245 const int row_stride,
248 const int to_channel_offset)
255 const uchar *
const src_start = src + area.ymin *
row_stride + channel_offset;
256 for (
int y = 0; y < height; y++) {
258 float *to_elem = &this->
get_value(to_x, to_y + y, to_channel_offset);
259 const float *row_end = to_elem + width * this->
elem_stride;
260 while (to_elem < row_end) {
261 for (
int i = 0; i < elem_size; i++) {
262 to_elem[i] =
float(from_elem[i]) * (1.0f / 255.0f);
274 float *out =
get_elem(area.xmin, area.ymin);
280 for (
int y = 0; y < height; y++) {
291 float *out = buf->
get_elem(area.xmin, area.ymin);
298 for (
int y = 0; y < height; y++) {
308 for (
int y = area.ymin; y < area.ymax; y++) {
309 for (
int x = area.xmin; x < area.xmax; x++) {
317 const bool ensure_premultiplied,
318 const bool ensure_linear_space)
325 const int channel_offset,
327 const int to_channel_offset,
328 const bool ensure_premultiplied,
329 const bool ensure_linear_space)
338 ensure_premultiplied,
339 ensure_linear_space);
344 const int channel_offset,
348 const int to_channel_offset,
349 const bool ensure_premultiplied,
350 const bool ensure_linear_space)
354 copy_from(&mem_buf, area, channel_offset, elem_size, to_x, to_y, to_channel_offset);
369 if (ensure_linear_space) {
372 if (ensure_premultiplied) {
378 const float *zero_elem =
new float[elem_size]{0};
379 fill(area, to_channel_offset, zero_elem, elem_size);
390 const int channel_offset,
392 const int value_size)
395 copy_from(&single_elem, area, 0, value_size, area.xmin, area.ymin, channel_offset);
412 memcpy(&buffer_[offset], color,
sizeof(
float) * num_channels_);
420 float *dst = &buffer_[offset];
421 const float *src = color;
422 for (
int i = 0; i < num_channels_; i++, dst++, src++) {
441 const float x,
const float y,
float dx[2],
float dy[2],
bool extend_boundary,
float *out)
const
445 const float deriv[2][2] = {{dx[0], dx[1]}, {dy[0], dy[1]}};
452 float uv_normal[2] = {get_relative_x(x) * inv_width, get_relative_y(y) * inv_height};
453 float du_normal[2] = {deriv[0][0] * inv_width, deriv[0][1] * inv_height};
454 float dv_normal[2] = {deriv[1][0] * inv_width, deriv[1][1] * inv_height};
468void MemoryBuffer::copy_single_elem_from(
const MemoryBuffer *src,
469 const int channel_offset,
471 const int to_channel_offset)
479 const float *from_elem = &src->
get_value(
481 const int elem_bytes = elem_size *
sizeof(
float);
482 memcpy(to_elem, from_elem, elem_bytes);
485void MemoryBuffer::copy_rows_from(
const MemoryBuffer *src,
499 for (
int y = 0; y < height; y++) {
500 float *to_row = this->
get_elem(to_x, to_y + y);
501 const float *from_row = src->get_elem(area.xmin, area.ymin + y);
502 memcpy(to_row, from_row, row_bytes);
506void MemoryBuffer::copy_elems_from(
const MemoryBuffer *src,
508 const int channel_offset,
512 const int to_channel_offset)
521 const int elem_bytes = elem_size *
sizeof(
float);
522 for (
int y = 0; y < height; y++) {
523 float *to_elem = &this->
get_value(to_x, to_y + y, to_channel_offset);
524 const float *from_elem = &src->get_value(area.xmin, area.ymin + y, channel_offset);
525 const float *row_end = to_elem + width * this->
elem_stride;
526 while (to_elem < row_end) {
527 memcpy(to_elem, from_elem, elem_bytes);
529 from_elem += src->elem_stride;
MINLINE void straight_to_premul_v4(float color[4])
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])
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
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)
bool BLI_rcti_is_empty(const struct rcti *rect)
#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)
void IMB_colormanagement_processor_apply(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, ColorSpace *colorspace, bool predivide)
Contains defines and structs used throughout the imbuf module.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
void add_input(const T *input, const rcti &buffer_area, int elem_stride=1)
BuffersIteratorBuilder::Iterator build()
a MemoryBuffer contains access to the data
const rcti & get_rect() const
get the rect of this MemoryBuffer
void read_elem_checked(int x, int y, float *out) const
float & get_value(int x, int y, int channel)
~MemoryBuffer()
destructor
float get_max_value() const
void copy_from(const MemoryBuffer *src, const rcti &area)
uint8_t get_num_channels() const
MemoryBuffer * inflate() const
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])
bool is_a_single_elem() const
float * get_elem(int x, int y)
void fill(const rcti &area, const float *value)
void fill_from(const MemoryBuffer &src)
add the content from other_buffer to this MemoryBuffer
MemoryBuffer(DataType data_type, int width, int height)
construct new temporarily MemoryBuffer for a width and height.
void read_elem_clamped(int x, int y, float *out) const
void read_elem_filtered(float x, float y, float dx[2], float dy[2], bool extend_boundary, float *out) const
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.
draw_view in_light_buf[] float
DataType
possible data types for sockets
void * MEM_mallocN_aligned(size_t len, size_t alignment, const char *str)
void MEM_freeN(void *vmemh)
static void premultiply_alpha(MemoryBuffer *buf, const rcti &area)
static rcti create_rect(const int width, const int height)
constexpr DataType COM_num_channels_data_type(const int num_channels)
constexpr int COM_data_type_num_channels(const DataType datatype)
static void read_ewa_elem_clamped(void *userdata, int x, int y, float result[4])
static void colorspace_to_scene_linear(MemoryBuffer *buf, const rcti &area, ColorSpace *colorspace)
static void read_ewa_elem_checked(void *userdata, int x, int y, float result[4])
typename BuffersIteratorBuilder< T >::Iterator BuffersIterator
static blender::bke::bNodeSocketTemplate inputs[]
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer