CVB++ 14.1
decl_array_access.hpp
1#pragma once
2
3#include <algorithm>
4#include <array>
5#include <cassert>
6
7#include "../data_type.hpp"
8#include "../size_2d.hpp"
9#include "../rect.hpp"
10
11#include "decl_access_base.hpp"
12
13namespace Cvb
14{
15
16 CVB_BEGIN_INLINE_NS
17
18 class ImagePlane;
19 class Vpat;
20 class LinearAccessData;
21
26 class ArrayAccess final : public ValueAccessBase<ArrayAccess>
27 {
28 /*
29 * \brief Creates a new array access object.
30 *
31 * \pre
32 * \a scan0 != \b nullptr, \a inc > 0 and \a width_ > 0
33 *
34 * \post
35 * Valid() == \b true
36 *
37 * \param [in] scan0 Non-\b nullptr address of first pixel in plane.
38 * \param [in] inc Increment to next pixel in bytes.
39 * \param [in] width The pixel width of the buffer that is accessed.
40 */
41 explicit ArrayAccess(std::uint8_t *basePtr, std::intptr_t inc, int width) noexcept
42 : basePtr_(basePtr)
43 , inc_(inc)
44 , width_(width)
45 {
46 assert(basePtr_ != nullptr && inc_ > 0 && width_ > 0); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
47 }
48
49 public:
55 ArrayAccess() noexcept;
56
57
58 ArrayAccess(const ArrayAccess &other) noexcept = default;
59 ArrayAccess &operator=(const ArrayAccess &other) noexcept = default;
60 ArrayAccess(ArrayAccess&& other) noexcept = default;
61 ArrayAccess& operator=(ArrayAccess && other) noexcept = default;
62 ~ArrayAccess() = default;
63
73 template <class PLANE_T>
74 static ArrayAccess FromPlane(const PLANE_T &plane) noexcept;
75
83 static ArrayAccess FromLinearAccess(const LinearAccessData &access, Size2D<int> size) noexcept;
84
94 static ArrayAccess FromVpat(const Vpat &access, Size2D<int> size, DataType dataType) noexcept;
95
105 LinearAccessData NewMoved(const Rect<int> newAoi) const noexcept;
106
116 ArrayAccess NewMoved(int idx) const noexcept
117 {
118 return ArrayAccess{basePtr_ + idx * inc_, inc_, width_};
119 }
120
126 CVB_FORCE_INLINE std::uint8_t *BasePtr() const noexcept
127 {
128 return this->basePtr_;
129 }
130
136 CVB_FORCE_INLINE std::intptr_t XInc() const noexcept
137 {
138 return this->inc_;
139 }
140
146 CVB_FORCE_INLINE std::intptr_t YInc() const noexcept
147 {
148 return this->inc_ * this->width_;
149 }
150
156 CVB_FORCE_INLINE int Width() const noexcept
157 {
158 return this->width_;
159 }
160
167 bool Valid() const noexcept
168 {
169 return this->basePtr_ != 0 && this->inc_ > 0 && this->width_ > 0;
170 }
171
173 explicit operator bool() const noexcept
174 {
175 return this->Valid();
176 }
177
188 CVB_FORCE_INLINE const void *operator()(int x, int y) const noexcept
189 {
190 return reinterpret_cast<const void *>(this->basePtr_ + y * this->inc_ * this->width_ + x * this->inc_);
191 }
192
203 CVB_FORCE_INLINE void *operator()(int x, int y) noexcept
204 {
205 return reinterpret_cast<void *>(this->basePtr_ + y * this->inc_ * this->width_ + x * this->inc_);
206 }
207
217 CVB_FORCE_INLINE const void *operator[](int idx) const noexcept
218 {
219 return reinterpret_cast<const void *>(this->basePtr_ + idx * this->inc_);
220 }
221
231 CVB_FORCE_INLINE void *operator[](int idx) noexcept
232 {
233 return reinterpret_cast<void *>(this->basePtr_ + idx * this->inc_);
234 }
235
240 class Row
241 {
242 friend class ArrayAccess;
243
244 std::uint8_t *line0_;
245 std::intptr_t xInc_;
246
247 /*
248 * \brief Ctor.
249 *
250 * \param [in] line0 Address of the first pixel of the row.
251 * \param [in] xInc Increment to next pixel in line.
252 */
253 Row(std::uint8_t *line0, std::intptr_t xInc) noexcept
254 : line0_(line0)
255 , xInc_(xInc)
256 {
257 }
258
259 public:
261 Row() noexcept
262 : line0_(0)
263 , xInc_(0)
264 {
265 }
266
267
268 Row(const Row &other) noexcept = default;
269 Row &operator=(const Row &other) noexcept = default;
270 Row(Row&& other) noexcept = default;
271 Row& operator=(Row&& other) noexcept = default;
272 ~Row() = default;
273
283 CVB_FORCE_INLINE void *operator[](int x) noexcept
284 {
285 return reinterpret_cast<void *>(line0_ + x * xInc_);
286 }
287
297 CVB_FORCE_INLINE const void *operator[](int x) const noexcept
298 {
299 return reinterpret_cast<const void *>(line0_ + x * xInc_);
300 }
301 };
302
307 class Column
308 {
309 friend class ArrayAccess;
310
311 std::uint8_t *column0_;
312 std::intptr_t yInc_;
313
314 /*
315 * \brief Ctor.
316 *
317 * \param [in] column0 Address of the first pixel of the column.
318 * \param [in] yInc Increment to next pixel in the column.
319 */
320 Column(std::uint8_t *column0, std::intptr_t yInc) noexcept
321 : column0_(column0)
322 , yInc_(yInc)
323 {
324 }
325
326 public:
328 Column() noexcept
329 : column0_(0)
330 , yInc_(0)
331 {
332 }
333
334
335 Column(const Column& other) noexcept = default;
336 Column& operator=(const Column& other) noexcept = default;
337 Column(Column&& other) noexcept = default;
338 Column& operator=(Column&& other) noexcept = default;
339 ~Column() = default;
340
350 CVB_FORCE_INLINE void *operator[](int y) noexcept
351 {
352 return reinterpret_cast<void *>(column0_ + y * yInc_);
353 }
354
364 CVB_FORCE_INLINE const void *operator[](int y) const noexcept
365 {
366 return reinterpret_cast<const void *>(column0_ + y * yInc_);
367 }
368 };
369
379 Row RowAt(int y) const noexcept
380 {
381 return {basePtr_ + y * inc_ * width_, inc_};
382 }
383
393 Column ColumnAt(int x) const noexcept
394 {
395 return {basePtr_ + x * inc_, inc_ * width_};
396 }
397
398 private:
399 std::uint8_t *basePtr_ = nullptr;
400 std::intptr_t inc_ = 0;
401 int width_ = 0;
402 };
403
404 inline ArrayAccess::ArrayAccess() noexcept = default;
405
414 inline bool operator!=(const ArrayAccess &lhs, const ArrayAccess &rhs) noexcept
415 {
416 return lhs.BasePtr() != rhs.BasePtr() || lhs.XInc() != rhs.XInc() || lhs.Width() != rhs.Width();
417 }
418
427 inline bool operator==(const ArrayAccess &lhs, const ArrayAccess &rhs) noexcept
428 {
429 return !(lhs != rhs);
430 }
431
436 inline bool IsInterleaved(size_t bytesPerPixel, const ArrayAccess &access0, const ArrayAccess &access1) noexcept
437 {
438 return access0.BasePtr() + bytesPerPixel == access1.BasePtr() && access0.XInc() == access1.XInc()
439 && access0.YInc() == access1.YInc();
440 }
441
442 namespace // NOLINT(cert-dcl59-cpp)
443 {
444 inline bool IsInterleaved(size_t, const ArrayAccess &) noexcept
445 {
446 return true;
447 }
448
449 struct ArrayAccessFindNonInterleaved
450 {
451 size_t bytesPerPixel;
452
453 inline bool operator()(const ArrayAccess *access0, const ArrayAccess *access1) const noexcept
454 {
455 return !IsInterleaved(bytesPerPixel, *access0, *access1);
456 }
457
458 inline bool operator()(const ArrayAccess &access0, const ArrayAccess &access1) const noexcept
459 {
460 return !IsInterleaved(bytesPerPixel, access0, access1);
461 }
462 };
463
464 } // namespace
465
466 template <size_t I>
467 bool IsInterleaved(std::size_t bytesPerPixel, const std::array<ArrayAccess, I> &accesses) noexcept
468 {
469 return std::adjacent_find(accesses.cbegin(), accesses.cend(), Cvb::ArrayAccessFindNonInterleaved{bytesPerPixel})
470 == accesses.cend();
471 }
472
488 template <class... ACCESSES>
489 bool IsInterleaved(size_t bytesPerPixel, const ArrayAccess &access0, const ArrayAccess &access1,
490 const ACCESSES &... accs) noexcept
491 {
492 const std::array<const ArrayAccess *, sizeof...(accs) + 2> arr{&access0, &access1, &accs...};
493 return IsInterleaved(bytesPerPixel, arr);
494 }
495
496 CVB_END_INLINE_NS
497
498} // namespace Cvb
A single column.
Definition: decl_array_access.hpp:308
CVB_FORCE_INLINE const void * operator[](int y) const noexcept
Value access.
Definition: decl_array_access.hpp:364
CVB_FORCE_INLINE void * operator[](int y) noexcept
Value access.
Definition: decl_array_access.hpp:350
Column() noexcept
Default ctor of invalid column.
Definition: decl_array_access.hpp:328
A single row.
Definition: decl_array_access.hpp:241
CVB_FORCE_INLINE void * operator[](int x) noexcept
Value access.
Definition: decl_array_access.hpp:283
Row() noexcept
Default ctor of invalid row.
Definition: decl_array_access.hpp:261
CVB_FORCE_INLINE const void * operator[](int x) const noexcept
Value access.
Definition: decl_array_access.hpp:297
Access trait for contiguous linear CVB image planes.
Definition: decl_array_access.hpp:27
CVB_FORCE_INLINE std::intptr_t XInc() const noexcept
Gets the offset to the next pixel on this line in this plane.
Definition: decl_array_access.hpp:136
CVB_FORCE_INLINE void * operator[](int idx) noexcept
Index pixel access operator.
Definition: decl_array_access.hpp:231
static ArrayAccess FromVpat(const Vpat &access, Size2D< int > size, DataType dataType) noexcept
Tries to get a valid ArrayAccess trait from the given VPAT access.
Definition: detail_plane_access.hpp:103
CVB_FORCE_INLINE std::uint8_t * BasePtr() const noexcept
Gets the address of the first pixel of the plane.
Definition: decl_array_access.hpp:126
bool IsInterleaved(size_t bytesPerPixel, const ArrayAccess &access0, const ArrayAccess &access1) noexcept
Definition: decl_array_access.hpp:436
bool Valid() const noexcept
Gets whether this linear access object is valid.
Definition: decl_array_access.hpp:167
bool operator==(const ArrayAccess &lhs, const ArrayAccess &rhs) noexcept
Equality operator.
Definition: decl_array_access.hpp:427
bool IsInterleaved(size_t bytesPerPixel, const ArrayAccess &access0, const ArrayAccess &access1, const ACCESSES &... accs) noexcept
Definition: decl_array_access.hpp:489
ArrayAccess() noexcept
CVB_FORCE_INLINE std::intptr_t YInc() const noexcept
Gets the offset to the next pixel on the next line in this plane.
Definition: decl_array_access.hpp:146
CVB_FORCE_INLINE int Width() const noexcept
Gets the width of the buffer, this access operates on.
Definition: decl_array_access.hpp:156
static ArrayAccess FromLinearAccess(const LinearAccessData &access, Size2D< int > size) noexcept
Tries to get a valid ArrayAccess trait from the given access.
Definition: detail_plane_access.hpp:93
CVB_FORCE_INLINE const void * operator()(int x, int y) const noexcept
Coordinate pixel access operator.
Definition: decl_array_access.hpp:188
LinearAccessData NewMoved(const Rect< int > newAoi) const noexcept
Creates a new, moved linear access object.
Definition: detail_plane_access.hpp:108
Row RowAt(int y) const noexcept
Gets the ArrayAccess::Row at y.
Definition: decl_array_access.hpp:379
CVB_FORCE_INLINE void * operator()(int x, int y) noexcept
Coordinate pixel access operator.
Definition: decl_array_access.hpp:203
static ArrayAccess FromPlane(const PLANE_T &plane) noexcept
Tries to get a valid ArrayAccess trait from the given plane.
Definition: detail_plane_access.hpp:86
Column ColumnAt(int x) const noexcept
Gets the ArrayAccess::Column at x.
Definition: decl_array_access.hpp:393
CVB_FORCE_INLINE const void * operator[](int idx) const noexcept
Index pixel access operator.
Definition: decl_array_access.hpp:217
Data type description for an image plane.
Definition: data_type.hpp:28
Linear access properties.
Definition: decl_linear_access.hpp:25
Rectangle object.
Definition: rect.hpp:26
Stores a pair of numbers that represents the width and the height of a subject, typically a rectangle...
Definition: size_2d.hpp:20
Common base class for access traits, providing typed Value access to planes.
Definition: decl_access_base.hpp:22
Virtual Pixel Access Table.
Definition: decl_vpat.hpp:24
Root namespace for the Image Manager interface.
Definition: c_barcode.h:24