Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/compositor/intern/COM_MemoryBuffer.h')
-rw-r--r--source/blender/compositor/intern/COM_MemoryBuffer.h254
1 files changed, 134 insertions, 120 deletions
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h
index 9e173f73f63..1765fb93035 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.h
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.h
@@ -21,12 +21,15 @@
#include "COM_BufferArea.h"
#include "COM_BufferRange.h"
#include "COM_BuffersIterator.h"
-#include "COM_ExecutionGroup.h"
-#include "COM_MemoryProxy.h"
+#include "COM_Enums.h"
-#include "BLI_math.h"
+#include "BLI_math_interp.h"
#include "BLI_rect.h"
+#include "IMB_colormanagement.h"
+
+struct ImBuf;
+
namespace blender::compositor {
/**
@@ -76,38 +79,38 @@ class MemoryBuffer {
/**
* \brief proxy of the memory (same for all chunks in the same buffer)
*/
- MemoryProxy *m_memoryProxy;
+ MemoryProxy *memory_proxy_;
/**
* \brief the type of buffer DataType::Value, DataType::Vector, DataType::Color
*/
- DataType m_datatype;
+ DataType datatype_;
/**
* \brief region of this buffer inside relative to the MemoryProxy
*/
- rcti m_rect;
+ rcti rect_;
/**
* \brief state of the buffer
*/
- MemoryBufferState m_state;
+ MemoryBufferState state_;
/**
* \brief the actual float buffer/data
*/
- float *m_buffer;
+ float *buffer_;
/**
* \brief the number of channels of a single value in the buffer.
* For value buffers this is 1, vector 3 and color 4
*/
- uint8_t m_num_channels;
+ uint8_t num_channels_;
/**
* Whether buffer is a single element in memory.
*/
- bool m_is_a_single_elem;
+ bool is_a_single_elem_;
/**
* Whether MemoryBuffer owns buffer data.
@@ -124,16 +127,24 @@ class MemoryBuffer {
/**
* \brief construct new temporarily MemoryBuffer for an area
*/
- MemoryBuffer(MemoryProxy *memoryProxy, const rcti &rect, MemoryBufferState state);
+ MemoryBuffer(MemoryProxy *memory_proxy, const rcti &rect, MemoryBufferState state);
/**
* \brief construct new temporarily MemoryBuffer for an area
*/
- MemoryBuffer(DataType datatype, const rcti &rect, bool is_a_single_elem = false);
+ MemoryBuffer(DataType data_type, const rcti &rect, bool is_a_single_elem = false);
+ /**
+ * Construct MemoryBuffer from a float buffer. MemoryBuffer is not responsible for
+ * freeing it.
+ */
MemoryBuffer(
float *buffer, int num_channels, int width, int height, bool is_a_single_elem = false);
+ /**
+ * Construct MemoryBuffer from a float buffer area. MemoryBuffer is not responsible for
+ * freeing given buffer.
+ */
MemoryBuffer(float *buffer, int num_channels, const rcti &rect, bool is_a_single_elem = false);
/**
@@ -152,21 +163,21 @@ class MemoryBuffer {
*/
bool is_a_single_elem() const
{
- return m_is_a_single_elem;
+ return is_a_single_elem_;
}
float &operator[](int index)
{
- BLI_assert(m_is_a_single_elem ? index < m_num_channels :
- index < get_coords_offset(getWidth(), getHeight()));
- return m_buffer[index];
+ BLI_assert(is_a_single_elem_ ? index < num_channels_ :
+ index < get_coords_offset(get_width(), get_height()));
+ return buffer_[index];
}
const float &operator[](int index) const
{
- BLI_assert(m_is_a_single_elem ? index < m_num_channels :
- index < get_coords_offset(getWidth(), getHeight()));
- return m_buffer[index];
+ BLI_assert(is_a_single_elem_ ? index < num_channels_ :
+ index < get_coords_offset(get_width(), get_height()));
+ return buffer_[index];
}
/**
@@ -174,7 +185,7 @@ class MemoryBuffer {
*/
intptr_t get_coords_offset(int x, int y) const
{
- return ((intptr_t)y - m_rect.ymin) * row_stride + ((intptr_t)x - m_rect.xmin) * elem_stride;
+ return ((intptr_t)y - rect_.ymin) * row_stride + ((intptr_t)x - rect_.xmin) * elem_stride;
}
/**
@@ -183,7 +194,7 @@ class MemoryBuffer {
float *get_elem(int x, int y)
{
BLI_assert(has_coords(x, y));
- return m_buffer + get_coords_offset(x, y);
+ return buffer_ + get_coords_offset(x, y);
}
/**
@@ -192,7 +203,7 @@ class MemoryBuffer {
const float *get_elem(int x, int y) const
{
BLI_assert(has_coords(x, y));
- return m_buffer + get_coords_offset(x, y);
+ return buffer_ + get_coords_offset(x, y);
}
void read_elem(int x, int y, float *out) const
@@ -218,21 +229,19 @@ class MemoryBuffer {
void read_elem_bilinear(float x, float y, float *out) const
{
/* Only clear past +/-1 borders to be able to smooth edges. */
- if (x <= m_rect.xmin - 1.0f || x >= m_rect.xmax || y <= m_rect.ymin - 1.0f ||
- y >= m_rect.ymax) {
+ if (x <= rect_.xmin - 1.0f || x >= rect_.xmax || y <= rect_.ymin - 1.0f || y >= rect_.ymax) {
clear_elem(out);
return;
}
- if (m_is_a_single_elem) {
- if (x >= m_rect.xmin && x < m_rect.xmax - 1.0f && y >= m_rect.ymin &&
- y < m_rect.ymax - 1.0f) {
- memcpy(out, m_buffer, get_elem_bytes_len());
+ if (is_a_single_elem_) {
+ if (x >= rect_.xmin && x < rect_.xmax - 1.0f && y >= rect_.ymin && y < rect_.ymax - 1.0f) {
+ memcpy(out, buffer_, get_elem_bytes_len());
return;
}
/* Do sampling at borders to smooth edges. */
- const float last_x = getWidth() - 1.0f;
+ const float last_x = get_width() - 1.0f;
const float rel_x = get_relative_x(x);
float single_x = 0.0f;
if (rel_x < 0.0f) {
@@ -242,7 +251,7 @@ class MemoryBuffer {
single_x = rel_x - last_x;
}
- const float last_y = getHeight() - 1.0f;
+ const float last_y = get_height() - 1.0f;
const float rel_y = get_relative_y(y);
float single_y = 0.0f;
if (rel_y < 0.0f) {
@@ -252,15 +261,15 @@ class MemoryBuffer {
single_y = rel_y - last_y;
}
- BLI_bilinear_interpolation_fl(m_buffer, out, 1, 1, m_num_channels, single_x, single_y);
+ BLI_bilinear_interpolation_fl(buffer_, out, 1, 1, num_channels_, single_x, single_y);
return;
}
- BLI_bilinear_interpolation_fl(m_buffer,
+ BLI_bilinear_interpolation_fl(buffer_,
out,
- getWidth(),
- getHeight(),
- m_num_channels,
+ get_width(),
+ get_height(),
+ num_channels_,
get_relative_x(x),
get_relative_y(y));
}
@@ -279,16 +288,15 @@ class MemoryBuffer {
}
}
- void read_elem_filtered(
- const float x, const float y, float dx[2], float dy[2], float *out) const;
+ void read_elem_filtered(float x, float y, float dx[2], float dy[2], float *out) const;
/**
* Get channel value at given coordinates.
*/
float &get_value(int x, int y, int channel)
{
- BLI_assert(has_coords(x, y) && channel >= 0 && channel < m_num_channels);
- return m_buffer[get_coords_offset(x, y) + channel];
+ BLI_assert(has_coords(x, y) && channel >= 0 && channel < num_channels_);
+ return buffer_[get_coords_offset(x, y) + channel];
}
/**
@@ -296,8 +304,8 @@ class MemoryBuffer {
*/
const float &get_value(int x, int y, int channel) const
{
- BLI_assert(has_coords(x, y) && channel >= 0 && channel < m_num_channels);
- return m_buffer[get_coords_offset(x, y) + channel];
+ BLI_assert(has_coords(x, y) && channel >= 0 && channel < num_channels_);
+ return buffer_[get_coords_offset(x, y) + channel];
}
/**
@@ -306,7 +314,7 @@ class MemoryBuffer {
const float *get_row_end(int y) const
{
BLI_assert(has_y(y));
- return m_buffer + (is_a_single_elem() ? m_num_channels : get_coords_offset(getWidth(), y));
+ return buffer_ + (is_a_single_elem() ? num_channels_ : get_coords_offset(get_width(), y));
}
/**
@@ -315,7 +323,7 @@ class MemoryBuffer {
*/
int get_memory_width() const
{
- return is_a_single_elem() ? 1 : getWidth();
+ return is_a_single_elem() ? 1 : get_width();
}
/**
@@ -324,17 +332,17 @@ class MemoryBuffer {
*/
int get_memory_height() const
{
- return is_a_single_elem() ? 1 : getHeight();
+ return is_a_single_elem() ? 1 : get_height();
}
uint8_t get_num_channels() const
{
- return this->m_num_channels;
+ return num_channels_;
}
uint8_t get_elem_bytes_len() const
{
- return this->m_num_channels * sizeof(float);
+ return num_channels_ * sizeof(float);
}
/**
@@ -342,22 +350,22 @@ class MemoryBuffer {
*/
BufferRange<float> as_range()
{
- return BufferRange<float>(m_buffer, 0, buffer_len(), elem_stride);
+ return BufferRange<float>(buffer_, 0, buffer_len(), elem_stride);
}
BufferRange<const float> as_range() const
{
- return BufferRange<const float>(m_buffer, 0, buffer_len(), elem_stride);
+ return BufferRange<const float>(buffer_, 0, buffer_len(), elem_stride);
}
BufferArea<float> get_buffer_area(const rcti &area)
{
- return BufferArea<float>(m_buffer, getWidth(), area, elem_stride);
+ return BufferArea<float>(buffer_, get_width(), area, elem_stride);
}
BufferArea<const float> get_buffer_area(const rcti &area) const
{
- return BufferArea<const float>(m_buffer, getWidth(), area, elem_stride);
+ return BufferArea<const float>(buffer_, get_width(), area, elem_stride);
}
BuffersIterator<float> iterate_with(Span<MemoryBuffer *> inputs);
@@ -367,25 +375,29 @@ class MemoryBuffer {
* \brief get the data of this MemoryBuffer
* \note buffer should already be available in memory
*/
- float *getBuffer()
+ float *get_buffer()
{
- return this->m_buffer;
+ return buffer_;
}
float *release_ownership_buffer()
{
owns_data_ = false;
- return this->m_buffer;
+ return buffer_;
}
+ /**
+ * Converts a single elem buffer to a full size buffer (allocates memory for all
+ * elements in resolution).
+ */
MemoryBuffer *inflate() const;
inline void wrap_pixel(int &x, int &y, MemoryBufferExtend extend_x, MemoryBufferExtend extend_y)
{
- const int w = getWidth();
- const int h = getHeight();
- x = x - m_rect.xmin;
- y = y - m_rect.ymin;
+ const int w = get_width();
+ const int h = get_height();
+ x = x - rect_.xmin;
+ y = y - rect_.ymin;
switch (extend_x) {
case MemoryBufferExtend::Clip:
@@ -425,8 +437,8 @@ class MemoryBuffer {
break;
}
- x = x + m_rect.xmin;
- y = y + m_rect.ymin;
+ x = x + rect_.xmin;
+ y = y + rect_.ymin;
}
inline void wrap_pixel(float &x,
@@ -434,10 +446,10 @@ class MemoryBuffer {
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y) const
{
- const float w = (float)getWidth();
- const float h = (float)getHeight();
- x = x - m_rect.xmin;
- y = y - m_rect.ymin;
+ const float w = (float)get_width();
+ const float h = (float)get_height();
+ x = x - rect_.xmin;
+ y = y - rect_.ymin;
switch (extend_x) {
case MemoryBufferExtend::Clip:
@@ -477,8 +489,8 @@ class MemoryBuffer {
break;
}
- x = x + m_rect.xmin;
- y = y + m_rect.ymin;
+ x = x + rect_.xmin;
+ y = y + rect_.ymin;
}
/* TODO(manzanilla): to be removed with tiled implementation. For applying #MemoryBufferExtend
@@ -489,28 +501,28 @@ class MemoryBuffer {
MemoryBufferExtend extend_x = MemoryBufferExtend::Clip,
MemoryBufferExtend extend_y = MemoryBufferExtend::Clip)
{
- bool clip_x = (extend_x == MemoryBufferExtend::Clip && (x < m_rect.xmin || x >= m_rect.xmax));
- bool clip_y = (extend_y == MemoryBufferExtend::Clip && (y < m_rect.ymin || y >= m_rect.ymax));
+ bool clip_x = (extend_x == MemoryBufferExtend::Clip && (x < rect_.xmin || x >= rect_.xmax));
+ bool clip_y = (extend_y == MemoryBufferExtend::Clip && (y < rect_.ymin || y >= rect_.ymax));
if (clip_x || clip_y) {
/* clip result outside rect is zero */
- memset(result, 0, this->m_num_channels * sizeof(float));
+ memset(result, 0, num_channels_ * sizeof(float));
}
else {
int u = x;
int v = y;
this->wrap_pixel(u, v, extend_x, extend_y);
const int offset = get_coords_offset(u, v);
- float *buffer = &this->m_buffer[offset];
- memcpy(result, buffer, sizeof(float) * this->m_num_channels);
+ float *buffer = &buffer_[offset];
+ memcpy(result, buffer, sizeof(float) * num_channels_);
}
}
/* TODO(manzanilla): to be removed with tiled implementation. */
- inline void readNoCheck(float *result,
- int x,
- int y,
- MemoryBufferExtend extend_x = MemoryBufferExtend::Clip,
- MemoryBufferExtend extend_y = MemoryBufferExtend::Clip)
+ inline void read_no_check(float *result,
+ int x,
+ int y,
+ MemoryBufferExtend extend_x = MemoryBufferExtend::Clip,
+ MemoryBufferExtend extend_y = MemoryBufferExtend::Clip)
{
int u = x;
int v = y;
@@ -519,38 +531,38 @@ class MemoryBuffer {
const int offset = get_coords_offset(u, v);
BLI_assert(offset >= 0);
- BLI_assert(offset < this->buffer_len() * this->m_num_channels);
- BLI_assert(!(extend_x == MemoryBufferExtend::Clip && (u < m_rect.xmin || u >= m_rect.xmax)) &&
- !(extend_y == MemoryBufferExtend::Clip && (v < m_rect.ymin || v >= m_rect.ymax)));
- float *buffer = &this->m_buffer[offset];
- memcpy(result, buffer, sizeof(float) * this->m_num_channels);
+ BLI_assert(offset < this->buffer_len() * num_channels_);
+ BLI_assert(!(extend_x == MemoryBufferExtend::Clip && (u < rect_.xmin || u >= rect_.xmax)) &&
+ !(extend_y == MemoryBufferExtend::Clip && (v < rect_.ymin || v >= rect_.ymax)));
+ float *buffer = &buffer_[offset];
+ memcpy(result, buffer, sizeof(float) * num_channels_);
}
- void writePixel(int x, int y, const float color[4]);
- void addPixel(int x, int y, const float color[4]);
- inline void readBilinear(float *result,
- float x,
- float y,
- MemoryBufferExtend extend_x = MemoryBufferExtend::Clip,
- MemoryBufferExtend extend_y = MemoryBufferExtend::Clip) const
+ void write_pixel(int x, int y, const float color[4]);
+ void add_pixel(int x, int y, const float color[4]);
+ inline void read_bilinear(float *result,
+ float x,
+ float y,
+ MemoryBufferExtend extend_x = MemoryBufferExtend::Clip,
+ MemoryBufferExtend extend_y = MemoryBufferExtend::Clip) const
{
float u = x;
float v = y;
this->wrap_pixel(u, v, extend_x, extend_y);
- if ((extend_x != MemoryBufferExtend::Repeat && (u < 0.0f || u >= getWidth())) ||
- (extend_y != MemoryBufferExtend::Repeat && (v < 0.0f || v >= getHeight()))) {
- copy_vn_fl(result, this->m_num_channels, 0.0f);
+ if ((extend_x != MemoryBufferExtend::Repeat && (u < 0.0f || u >= get_width())) ||
+ (extend_y != MemoryBufferExtend::Repeat && (v < 0.0f || v >= get_height()))) {
+ copy_vn_fl(result, num_channels_, 0.0f);
return;
}
- if (m_is_a_single_elem) {
- memcpy(result, m_buffer, sizeof(float) * this->m_num_channels);
+ if (is_a_single_elem_) {
+ memcpy(result, buffer_, sizeof(float) * num_channels_);
}
else {
- BLI_bilinear_interpolation_wrap_fl(this->m_buffer,
+ BLI_bilinear_interpolation_wrap_fl(buffer_,
result,
- getWidth(),
- getHeight(),
- this->m_num_channels,
+ get_width(),
+ get_height(),
+ num_channels_,
u,
v,
extend_x == MemoryBufferExtend::Repeat,
@@ -563,11 +575,16 @@ class MemoryBuffer {
/**
* \brief is this MemoryBuffer a temporarily buffer (based on an area, not on a chunk)
*/
- inline bool isTemporarily() const
+ inline bool is_temporarily() const
{
- return this->m_state == MemoryBufferState::Temporary;
+ return state_ == MemoryBufferState::Temporary;
}
+ /**
+ * \brief Apply a color processor on the given area.
+ */
+ void apply_processor(ColormanageProcessor &processor, const rcti area);
+
void copy_from(const MemoryBuffer *src, const rcti &area);
void copy_from(const MemoryBuffer *src, const rcti &area, int to_x, int to_y);
void copy_from(const MemoryBuffer *src,
@@ -618,8 +635,8 @@ class MemoryBuffer {
void fill(const rcti &area, const float *value);
void fill(const rcti &area, int channel_offset, const float *value, int value_size);
/**
- * \brief add the content from otherBuffer to this MemoryBuffer
- * \param otherBuffer: source buffer
+ * \brief add the content from other_buffer to this MemoryBuffer
+ * \param other_buffer: source buffer
*
* \note take care when running this on a new buffer since it won't fill in
* uninitialized values in areas where the buffers don't overlap.
@@ -631,23 +648,23 @@ class MemoryBuffer {
*/
const rcti &get_rect() const
{
- return this->m_rect;
+ return rect_;
}
/**
* \brief get the width of this MemoryBuffer
*/
- const int getWidth() const
+ const int get_width() const
{
- return BLI_rcti_size_x(&m_rect);
+ return BLI_rcti_size_x(&rect_);
}
/**
* \brief get the height of this MemoryBuffer
*/
- const int getHeight() const
+ const int get_height() const
{
- return BLI_rcti_size_y(&m_rect);
+ return BLI_rcti_size_y(&rect_);
}
/**
@@ -667,17 +684,17 @@ class MemoryBuffer {
void clear_elem(float *out) const
{
- memset(out, 0, this->m_num_channels * sizeof(float));
+ memset(out, 0, num_channels_ * sizeof(float));
}
template<typename T> T get_relative_x(T x) const
{
- return x - m_rect.xmin;
+ return x - rect_.xmin;
}
template<typename T> T get_relative_y(T y) const
{
- return y - m_rect.ymin;
+ return y - rect_.ymin;
}
template<typename T> bool has_coords(T x, T y) const
@@ -687,12 +704,12 @@ class MemoryBuffer {
template<typename T> bool has_x(T x) const
{
- return x >= m_rect.xmin && x < m_rect.xmax;
+ return x >= rect_.xmin && x < rect_.xmax;
}
template<typename T> bool has_y(T y) const
{
- return y >= m_rect.ymin && y < m_rect.ymax;
+ return y >= rect_.ymin && y < rect_.ymax;
}
/* Fast `floor(..)` functions. The caller should check result is within buffer bounds.
@@ -711,18 +728,15 @@ class MemoryBuffer {
void copy_single_elem_from(const MemoryBuffer *src,
int channel_offset,
int elem_size,
- const int to_channel_offset);
- void copy_rows_from(const MemoryBuffer *src,
- const rcti &src_area,
- const int to_x,
- const int to_y);
+ int to_channel_offset);
+ void copy_rows_from(const MemoryBuffer *src, const rcti &src_area, int to_x, int to_y);
void copy_elems_from(const MemoryBuffer *src,
const rcti &area,
- const int channel_offset,
- const int elem_size,
- const int to_x,
- const int to_y,
- const int to_channel_offset);
+ int channel_offset,
+ int elem_size,
+ int to_x,
+ int to_y,
+ int to_channel_offset);
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBuffer")