Blender V4.3
COM_BufferArea.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
7#include "BLI_assert.h"
8#include "BLI_rect.h"
9#include <iterator>
10
11namespace blender::compositor {
12
13/* Forward declarations. */
14template<typename T> class BufferAreaIterator;
15
19template<typename T> class BufferArea : rcti {
20 public:
23
24 private:
25 T *buffer_;
26 /* Number of elements in a buffer row. */
27 int buffer_width_;
28 /* Buffer element stride. */
29 int elem_stride_;
30
31 public:
32 constexpr BufferArea() = default;
33
37 constexpr BufferArea(T *buffer, int buffer_width, const rcti &area, int elem_stride = 1)
38 : rcti(area), buffer_(buffer), buffer_width_(buffer_width), elem_stride_(elem_stride)
39 {
40 }
41
45 constexpr BufferArea(T *buffer, int buffer_width, int buffer_height, int elem_stride = 1)
46 : buffer_(buffer), buffer_width_(buffer_width), elem_stride_(elem_stride)
47 {
48 BLI_rcti_init(this, 0, buffer_width, 0, buffer_height);
49 }
50
51 constexpr friend bool operator==(const BufferArea &a, const BufferArea &b)
52 {
53 return a.buffer_ == b.buffer_ && BLI_rcti_compare(&a, &b) && a.elem_stride_ == b.elem_stride_;
54 }
55
56 constexpr const rcti &get_rect() const
57 {
58 return *this;
59 }
60
64 constexpr int width() const
65 {
66 return BLI_rcti_size_x(this);
67 }
68
72 constexpr int height() const
73 {
74 return BLI_rcti_size_y(this);
75 }
76
77 constexpr Iterator begin()
78 {
79 return begin_iterator<Iterator>();
80 }
81
82 constexpr Iterator end()
83 {
84 return end_iterator<Iterator>();
85 }
86
87 constexpr ConstIterator begin() const
88 {
89 return begin_iterator<ConstIterator>();
90 }
91
92 constexpr ConstIterator end() const
93 {
94 return end_iterator<ConstIterator>();
95 }
96
97 private:
98 template<typename TIterator> constexpr TIterator begin_iterator() const
99 {
100 T *end_ptr = get_end_ptr();
101 if (elem_stride_ == 0) {
102 /* Iterate a single element. */
103 return TIterator(buffer_, end_ptr, 1, 1, 1);
104 }
105
106 T *begin_ptr = buffer_ + (intptr_t)this->ymin * buffer_width_ * elem_stride_ +
107 (intptr_t)this->xmin * elem_stride_;
108 return TIterator(begin_ptr, end_ptr, buffer_width_, BLI_rcti_size_x(this), elem_stride_);
109 }
110
111 template<typename TIterator> constexpr TIterator end_iterator() const
112 {
113 T *end_ptr = get_end_ptr();
114 if (elem_stride_ == 0) {
115 /* Iterate a single element. */
116 return TIterator(end_ptr, end_ptr, 1, 1, 1);
117 }
118
119 return TIterator(end_ptr, end_ptr, buffer_width_, BLI_rcti_size_x(this), elem_stride_);
120 }
121
122 T *get_end_ptr() const
123 {
124 if (elem_stride_ == 0) {
125 return buffer_ + 1;
126 }
127 return buffer_ + (intptr_t)(this->ymax - 1) * buffer_width_ * elem_stride_ +
128 (intptr_t)this->xmax * elem_stride_;
129 }
130};
131
132template<typename T> class BufferAreaIterator {
133 public:
134 using iterator_category = std::input_iterator_tag;
135 using value_type = T *;
136 using pointer = T *const *;
137 using reference = T *const &;
138 using difference_type = std::ptrdiff_t;
139
140 private:
141 int elem_stride_;
142 int row_stride_;
143 /* Stride between a row end and the next row start. */
144 int rows_gap_;
145 T *current_;
146 const T *row_end_;
147 const T *end_;
148
149 public:
150 constexpr BufferAreaIterator() = default;
151
153 T *current, const T *end, int buffer_width, int area_width, int elem_stride = 1)
154 : elem_stride_(elem_stride),
155 row_stride_(buffer_width * elem_stride),
156 rows_gap_(row_stride_ - area_width * elem_stride),
157 current_(current),
158 row_end_(current + area_width * elem_stride),
159 end_(end)
160 {
161 }
162
164 {
165 current_ += elem_stride_;
166 BLI_assert(current_ <= row_end_);
167 if (current_ == row_end_) {
168 BLI_assert(current_ <= end_);
169 if (current_ == end_) {
170 return *this;
171 }
172 current_ += rows_gap_;
173 row_end_ += row_stride_;
174 }
175 return *this;
176 }
177
178 constexpr BufferAreaIterator operator++(int) const
179 {
180 BufferAreaIterator copied_iterator = *this;
181 ++copied_iterator;
182 return copied_iterator;
183 }
184
185 constexpr friend bool operator!=(const BufferAreaIterator &a, const BufferAreaIterator &b)
186 {
187 return a.current_ != b.current_;
188 }
189
190 constexpr friend bool operator==(const BufferAreaIterator &a, const BufferAreaIterator &b)
191 {
192 return a.current_ == b.current_;
193 }
194
195 constexpr T *operator*() const
196 {
197 return current_;
198 }
199};
200
201} // namespace blender::compositor
#define BLI_assert(a)
Definition BLI_assert.h:50
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:193
bool BLI_rcti_compare(const struct rcti *rect_a, const struct rcti *rect_b)
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
Definition rct.c:418
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:189
constexpr friend bool operator==(const BufferAreaIterator &a, const BufferAreaIterator &b)
constexpr BufferAreaIterator(T *current, const T *end, int buffer_width, int area_width, int elem_stride=1)
constexpr BufferAreaIterator & operator++()
constexpr BufferAreaIterator operator++(int) const
std::input_iterator_tag iterator_category
constexpr friend bool operator!=(const BufferAreaIterator &a, const BufferAreaIterator &b)
constexpr BufferArea(T *buffer, int buffer_width, const rcti &area, int elem_stride=1)
constexpr int height() const
constexpr BufferArea(T *buffer, int buffer_width, int buffer_height, int elem_stride=1)
constexpr ConstIterator begin() const
constexpr const rcti & get_rect() const
constexpr BufferArea()=default
constexpr friend bool operator==(const BufferArea &a, const BufferArea &b)
constexpr int width() const
constexpr ConstIterator end() const
local_group_size(16, 16) .push_constant(Type b
_W64 int intptr_t
Definition stdint.h:118
int ymin
int ymax
int xmin
int xmax