CVB++ 14.1
decl_linear_access.hpp
1#pragma once
2
3#include <algorithm>
4#include <array>
5#include <cassert>
6
7#include "../data_type.hpp"
8#include "../rect.hpp"
9#include "../size_2d.hpp"
10
11#include "decl_access_base.hpp"
12
13namespace Cvb
14{
15
16 CVB_BEGIN_INLINE_NS
17
18 class ImagePlane;
19 class ArrayAccess;
20 class Vpat;
21
23
24 class LinearAccessData final : public ValueAccessBase<LinearAccessData>
25 {
26 friend ImagePlane;
27 friend ArrayAccess;
28
29 public:
31
34 LinearAccessData() noexcept;
35
36 LinearAccessData(const LinearAccessData & other) noexcept = default;
37 LinearAccessData &operator=(const LinearAccessData &other) noexcept = default;
38 LinearAccessData(LinearAccessData&& other) noexcept = default;
39 LinearAccessData& operator=(LinearAccessData&& other) noexcept = default;
40 ~LinearAccessData() = default;
41
51 template <class PLANE_T>
52 static LinearAccessData FromPlane(const PLANE_T &plane) noexcept;
53
63 static LinearAccessData FromVpat(const Vpat &access, Cvb::Size2D<int> size, Cvb::DataType dataType) noexcept;
64
74 static LinearAccessData FromPtr(std::uint8_t *basePtr, std::intptr_t xInc, std::intptr_t yInc, int width) noexcept
75 {
76 return LinearAccessData{basePtr, xInc, yInc, width};
77 }
78
88 LinearAccessData NewMoved(const Cvb::Rect<int> newAoi) const noexcept
89 {
90 return LinearAccessData{basePtr_ + newAoi.Top() * yInc_ + newAoi.Left() * xInc_, xInc_, yInc_, newAoi.Width()};
91 }
92
94
102 std::uint8_t *BasePtr() const noexcept
103 {
104 return basePtr_;
105 }
106
108
112 std::intptr_t XInc() const noexcept
113 {
114 return xInc_;
115 }
116
118
122 std::intptr_t YInc() const noexcept
123 {
124 return yInc_;
125 }
126
132 CVB_FORCE_INLINE int Width() const noexcept
133 {
134 return this->width_;
135 }
136
143 bool Valid() const noexcept
144 {
145 return this->basePtr_ != nullptr && this->xInc_ != 0 && this->yInc_ != 0 && this->width_ > 0;
146 }
147
149 explicit operator bool() const noexcept
150 {
151 return this->Valid();
152 }
153
164 CVB_FORCE_INLINE const void *operator()(int x, int y) const noexcept
165 {
166 return reinterpret_cast<const void *>(this->basePtr_ + y * this->yInc_ + x * this->xInc_);
167 }
168
179 CVB_FORCE_INLINE void *operator()(int x, int y) noexcept
180 {
181 return reinterpret_cast<void *>(this->basePtr_ + y * this->yInc_ + x * this->xInc_);
182 }
183
193 CVB_FORCE_INLINE const void *operator[](int idx) const noexcept
194 {
195 const int y = idx / this->width_;
196 const int x = idx % this->width_; // calculating / and % is faster than idx - width_ * y as the compiler generate
197 // only a single idiv (or sdiv) for both lines
198 return reinterpret_cast<const void *>(this->basePtr_ + y * this->yInc_ + x * this->xInc_);
199 }
200
210 CVB_FORCE_INLINE void *operator[](int idx) noexcept
211 {
212 const int y = idx / this->width_;
213 const int x = idx % this->width_; // calculating / and % is faster than idx - width_ * y as the compiler generate
214 // only a single idiv (or sdiv) for both lines
215 return reinterpret_cast<void *>(this->basePtr_ + y * this->yInc_ + x * this->xInc_);
216 }
217
222 class Row
223 {
224 friend class LinearAccessData;
225
226 std::uint8_t *line0_;
227 std::intptr_t xInc_;
228
229 /*
230 * \brief Ctor.
231 *
232 * \param [in] line0 Address of the first pixel of the row.
233 * \param [in] xInc Increment to next pixel in line.
234 */
235 Row(std::uint8_t *line0, std::intptr_t xInc) noexcept
236 : line0_(line0)
237 , xInc_(xInc)
238 {
239 }
240
241 public:
243 Row() noexcept
244 : line0_(nullptr)
245 , xInc_(0)
246 {
247 }
248
249
250 Row(const Row& other) noexcept = default;
251 Row& operator=(const Row& other) noexcept = default;
252 Row(Row&& other) noexcept = default;
253 Row& operator=(Row&& other) noexcept = default;
254 ~Row() = default;
255
265 CVB_FORCE_INLINE void *operator[](int x) noexcept
266 {
267 return reinterpret_cast<void *>(line0_ + x * xInc_);
268 }
269
279 CVB_FORCE_INLINE const void *operator[](int x) const noexcept
280 {
281 return reinterpret_cast<const void *>(line0_ + x * xInc_);
282 }
283 };
284
289 class Column
290 {
291 friend class LinearAccessData;
292
293 std::uint8_t *column0_;
294 std::intptr_t yInc_;
295
296 /*
297 * \brief Ctor.
298 *
299 * \param [in] column0 Address of the first pixel of the column.
300 * \param [in] yInc Increment to next pixel in the column.
301 */
302 Column(std::uint8_t *column0, std::intptr_t yInc) noexcept
303 : column0_(column0)
304 , yInc_(yInc)
305 {
306 }
307
308 public:
310 Column() noexcept
311 : column0_(nullptr)
312 , yInc_(0)
313 {
314 }
315
316
317 Column(const Column &other) noexcept = default;
318 Column& operator=(const Column& other) noexcept = default;
319 Column(Column&& other) noexcept = default;
320 Column& operator=(Column&& other) noexcept = default;
321 ~Column() = default;
322
323
333 CVB_FORCE_INLINE void *operator[](int y) noexcept
334 {
335 return reinterpret_cast<void *>(column0_ + y * yInc_);
336 }
337
347 CVB_FORCE_INLINE const void *operator[](int y) const noexcept
348 {
349 return reinterpret_cast<const void *>(column0_ + y * yInc_);
350 }
351 };
352
362 Row RowAt(int y) const noexcept
363 {
364 return {basePtr_ + y * yInc_, xInc_};
365 }
366
376 Column ColumnAt(int x) const noexcept
377 {
378 return {basePtr_ + x * xInc_, yInc_};
379 }
380
381 private:
382 LinearAccessData(std::uint8_t *basePtr, std::intptr_t xInc, std::intptr_t yInc, int width) noexcept
383 : basePtr_(basePtr)
384 , xInc_(xInc)
385 , yInc_(yInc)
386 , width_(width)
387 {
388 }
389
390 template <class PLANE_T, std::enable_if_t<PlaneTraits<PLANE_T>::HasVpat, int> = 0>
391 static LinearAccessData FromPlaneImpl(const PLANE_T &plane) noexcept;
392 template <class PLANE_T, std::enable_if_t<!PlaneTraits<PLANE_T>::HasVpat, int> = 0>
393 static LinearAccessData FromPlaneImpl(const PLANE_T &plane) noexcept;
394
395 std::uint8_t *basePtr_ = nullptr;
396 std::intptr_t xInc_ = 0;
397 std::intptr_t yInc_ = 0;
398 int width_ = 0;
399 };
400
401 inline LinearAccessData::LinearAccessData() noexcept = default;
402
403 using LinearAccess = LinearAccessData;
404
413 inline bool operator!=(const LinearAccessData &lhs, const LinearAccessData &rhs) noexcept
414 {
415 return lhs.BasePtr() != rhs.BasePtr() || lhs.YInc() != rhs.YInc() || lhs.XInc() != rhs.XInc()
416 || lhs.Width() != rhs.Width();
417 }
418
427 inline bool operator==(const LinearAccessData &lhs, const LinearAccessData &rhs) noexcept
428 {
429 return !(lhs != rhs);
430 }
431
436 inline bool IsInterleaved(size_t bytesPerPixel, const LinearAccessData &access0,
437 const LinearAccessData &access1) noexcept
438 {
439 return access0.BasePtr() + bytesPerPixel == access1.BasePtr() && access0.XInc() == access1.XInc()
440 && access0.YInc() == access1.YInc();
441 }
442
443 namespace // NOLINT(cert-dcl59-cpp)
444 {
445 inline bool IsInterleaved(size_t, const LinearAccessData &) noexcept
446 {
447 return true;
448 }
449
450 struct LinearAccessFindNonInterleaved
451 {
452 size_t bytesPerPixel;
453
454 inline bool operator()(const LinearAccessData *access0, const LinearAccessData *access1) const noexcept
455 {
456 return !IsInterleaved(bytesPerPixel, *access0, *access1);
457 }
458
459 inline bool operator()(const LinearAccessData &access0, const LinearAccessData &access1) const noexcept
460 {
461 return !IsInterleaved(bytesPerPixel, access0, access1);
462 }
463 };
464 } // namespace
465
466 template <size_t I>
467 bool IsInterleaved(std::size_t bytesPerPixel, const std::array<LinearAccessData, I> &accesses) noexcept
468 {
469 return std::adjacent_find(accesses.cbegin(), accesses.cend(), Cvb::LinearAccessFindNonInterleaved{bytesPerPixel})
470 == accesses.cend();
471 }
472
488 template <class... ACCESSES>
489 bool IsInterleaved(size_t bytesPerPixel, const LinearAccessData &access0, const LinearAccessData &access1,
490 const ACCESSES &... accs) noexcept
491 {
492 const std::array<const LinearAccessData *, sizeof...(accs) + 2> arr{&access0, &access1, &accs...};
493 return std::adjacent_find(arr.cbegin(), arr.cend(), LinearAccessFindNonInterleaved{bytesPerPixel}) == arr.cend();
494 }
495
496 CVB_END_INLINE_NS
497} // namespace Cvb
Access trait for contiguous linear CVB image planes.
Definition: decl_array_access.hpp:27
Data type description for an image plane.
Definition: data_type.hpp:28
Image plane information container.
Definition: decl_image_plane.hpp:33
A single column.
Definition: decl_linear_access.hpp:290
CVB_FORCE_INLINE const void * operator[](int y) const noexcept
Value access.
Definition: decl_linear_access.hpp:347
CVB_FORCE_INLINE void * operator[](int y) noexcept
Value access.
Definition: decl_linear_access.hpp:333
Column() noexcept
Default ctor of invalid column.
Definition: decl_linear_access.hpp:310
A single row.
Definition: decl_linear_access.hpp:223
CVB_FORCE_INLINE void * operator[](int x) noexcept
Value access.
Definition: decl_linear_access.hpp:265
Row() noexcept
Default ctor of invalid row.
Definition: decl_linear_access.hpp:243
CVB_FORCE_INLINE const void * operator[](int x) const noexcept
Value access.
Definition: decl_linear_access.hpp:279
Linear access properties.
Definition: decl_linear_access.hpp:25
CVB_FORCE_INLINE void * operator[](int idx) noexcept
Index pixel access operator.
Definition: decl_linear_access.hpp:210
bool IsInterleaved(size_t bytesPerPixel, const LinearAccessData &access0, const LinearAccessData &access1, const ACCESSES &... accs) noexcept
Definition: decl_linear_access.hpp:489
std::intptr_t XInc() const noexcept
X-increment for linear access.
Definition: decl_linear_access.hpp:112
bool Valid() const noexcept
Gets whether this linear access object is valid.
Definition: decl_linear_access.hpp:143
bool IsInterleaved(size_t bytesPerPixel, const LinearAccessData &access0, const LinearAccessData &access1) noexcept
Definition: decl_linear_access.hpp:436
LinearAccessData() noexcept
Creates a default linear access data set.
bool operator==(const LinearAccessData &lhs, const LinearAccessData &rhs) noexcept
Equality operator.
Definition: decl_linear_access.hpp:427
static LinearAccessData FromPlane(const PLANE_T &plane) noexcept
Tries to get a valid LinearAccessData from the given plane.
Definition: detail_plane_access.hpp:40
CVB_FORCE_INLINE int Width() const noexcept
Gets the pixel width of the underlying plane.
Definition: decl_linear_access.hpp:132
LinearAccessData NewMoved(const Cvb::Rect< int > newAoi) const noexcept
Creates a new, moved linear access object.
Definition: decl_linear_access.hpp:88
static LinearAccessData FromPtr(std::uint8_t *basePtr, std::intptr_t xInc, std::intptr_t yInc, int width) noexcept
Creates LinearAccessData from the given pointer and increments.
Definition: decl_linear_access.hpp:74
std::intptr_t YInc() const noexcept
Y-increment for linear access.
Definition: decl_linear_access.hpp:122
std::uint8_t * BasePtr() const noexcept
Linear access base pointer.
Definition: decl_linear_access.hpp:102
CVB_FORCE_INLINE const void * operator()(int x, int y) const noexcept
Coordinate pixel access operator.
Definition: decl_linear_access.hpp:164
Row RowAt(int y) const noexcept
Gets the LinearAccessData::Row at y.
Definition: decl_linear_access.hpp:362
static LinearAccessData FromVpat(const Vpat &access, Cvb::Size2D< int > size, Cvb::DataType dataType) noexcept
Tries to get a valid LinearAccessData trait from the given vpat.
Definition: detail_plane_access.hpp:47
CVB_FORCE_INLINE void * operator()(int x, int y) noexcept
Coordinate pixel access operator.
Definition: decl_linear_access.hpp:179
Column ColumnAt(int x) const noexcept
Gets the LinearAccessData::Column at x.
Definition: decl_linear_access.hpp:376
CVB_FORCE_INLINE const void * operator[](int idx) const noexcept
Index pixel access operator.
Definition: decl_linear_access.hpp:193
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