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.h59
1 files changed, 43 insertions, 16 deletions
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h
index f730d53acec..9e173f73f63 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.h
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.h
@@ -114,6 +114,12 @@ class MemoryBuffer {
*/
bool owns_data_;
+ /** Stride to make any x coordinate within buffer positive (non-zero). */
+ int to_positive_x_stride_;
+
+ /** Stride to make any y coordinate within buffer positive (non-zero). */
+ int to_positive_y_stride_;
+
public:
/**
* \brief construct new temporarily MemoryBuffer for an area
@@ -166,9 +172,9 @@ class MemoryBuffer {
/**
* Get offset needed to jump from buffer start to given coordinates.
*/
- int get_coords_offset(int x, int y) const
+ intptr_t get_coords_offset(int x, int y) const
{
- return (y - m_rect.ymin) * row_stride + (x - m_rect.xmin) * elem_stride;
+ return ((intptr_t)y - m_rect.ymin) * row_stride + ((intptr_t)x - m_rect.xmin) * elem_stride;
}
/**
@@ -176,7 +182,7 @@ class MemoryBuffer {
*/
float *get_elem(int x, int y)
{
- BLI_assert(x >= m_rect.xmin && x < m_rect.xmax && y >= m_rect.ymin && y < m_rect.ymax);
+ BLI_assert(has_coords(x, y));
return m_buffer + get_coords_offset(x, y);
}
@@ -185,7 +191,7 @@ class MemoryBuffer {
*/
const float *get_elem(int x, int y) const
{
- BLI_assert(x >= m_rect.xmin && x < m_rect.xmax && y >= m_rect.ymin && y < m_rect.ymax);
+ BLI_assert(has_coords(x, y));
return m_buffer + get_coords_offset(x, y);
}
@@ -196,7 +202,7 @@ class MemoryBuffer {
void read_elem_checked(int x, int y, float *out) const
{
- if (x < m_rect.xmin || x >= m_rect.xmax || y < m_rect.ymin || y >= m_rect.ymax) {
+ if (!has_coords(x, y)) {
clear_elem(out);
}
else {
@@ -206,12 +212,7 @@ class MemoryBuffer {
void read_elem_checked(float x, float y, float *out) const
{
- if (x < m_rect.xmin || x >= m_rect.xmax || y < m_rect.ymin || y >= m_rect.ymax) {
- clear_elem(out);
- }
- else {
- read_elem(x, y, out);
- }
+ read_elem_checked(floor_x(x), floor_y(y), out);
}
void read_elem_bilinear(float x, float y, float *out) const
@@ -286,8 +287,7 @@ class MemoryBuffer {
*/
float &get_value(int x, int y, int channel)
{
- BLI_assert(x >= m_rect.xmin && x < m_rect.xmax && y >= m_rect.ymin && y < m_rect.ymax &&
- channel >= 0 && channel < m_num_channels);
+ BLI_assert(has_coords(x, y) && channel >= 0 && channel < m_num_channels);
return m_buffer[get_coords_offset(x, y) + channel];
}
@@ -296,8 +296,7 @@ class MemoryBuffer {
*/
const float &get_value(int x, int y, int channel) const
{
- BLI_assert(x >= m_rect.xmin && x < m_rect.xmax && y >= m_rect.ymin && y < m_rect.ymax &&
- channel >= 0 && channel < m_num_channels);
+ BLI_assert(has_coords(x, y) && channel >= 0 && channel < m_num_channels);
return m_buffer[get_coords_offset(x, y) + channel];
}
@@ -306,7 +305,7 @@ class MemoryBuffer {
*/
const float *get_row_end(int y) const
{
- BLI_assert(y >= 0 && y < getHeight());
+ BLI_assert(has_y(y));
return m_buffer + (is_a_single_elem() ? m_num_channels : get_coords_offset(getWidth(), y));
}
@@ -681,6 +680,34 @@ class MemoryBuffer {
return y - m_rect.ymin;
}
+ template<typename T> bool has_coords(T x, T y) const
+ {
+ return has_x(x) && has_y(y);
+ }
+
+ template<typename T> bool has_x(T x) const
+ {
+ return x >= m_rect.xmin && x < m_rect.xmax;
+ }
+
+ template<typename T> bool has_y(T y) const
+ {
+ return y >= m_rect.ymin && y < m_rect.ymax;
+ }
+
+ /* Fast `floor(..)` functions. The caller should check result is within buffer bounds.
+ * It `ceil(..)` in near cases and when given coordinate
+ * is negative and less than buffer rect `min - 1`. */
+ int floor_x(float x) const
+ {
+ return (int)(x + to_positive_x_stride_) - to_positive_x_stride_;
+ }
+
+ int floor_y(float y) const
+ {
+ return (int)(y + to_positive_y_stride_) - to_positive_y_stride_;
+ }
+
void copy_single_elem_from(const MemoryBuffer *src,
int channel_offset,
int elem_size,