ifm3d
buffer.h
1 // -*- c++ -*-
2 /*
3  * Copyright 2021-present ifm electronic, gmbh
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef IFM3D_FG_Buffer_H
8 #define IFM3D_FG_Buffer_H
9 
10 #include <climits>
11 #include <cstdint>
12 #include <ifm3d/common/json.hpp>
13 #include <ifm3d/device/device.h>
14 #include <ifm3d/fg/buffer_id.h>
15 #include <ifm3d/fg/module_frame_grabber.h>
16 #include <memory>
17 #include <optional>
18 
19 namespace ifm3d
20 {
98  class IFM3D_EXPORT Buffer
99  {
100  private:
101  /* @ brief raw pointer to the data*/
102  uint8_t* _data{};
103  /*@brief number of columns in Buffer (width)*/
104  std::uint32_t _cols{};
105  /*@brief number of rows in Buffer (height)*/
106  std::uint32_t _rows{};
107  /*@brief number of channel in Buffer*/
108  std::uint32_t _nchannel{};
109  /* @brief data format or type*/
110  ifm3d::PixelFormat _data_format{};
111  /* @brief number of pixel to store one value of data*/
112  std::size_t _data_size_in_bytes{};
113  /* @brief size of the memory allocated*/
114  size_t _size{};
115  /* @brief bytes to store pixel */
116  size_t _bytes_per_pixel{};
117  /* @brief bytes per row */
118  size_t _bytes_per_row{};
119  /* @brief json formatted metadata of the chunk obtain from device*/
120  json _metadata;
121  /* @brief buffer id of Buffer */
122  ifm3d::buffer_id _buffer_id{};
123 
124  class BufferAllocator;
125  std::shared_ptr<BufferAllocator> _buffer_allocator;
126 
127  public:
134  Buffer();
135  /*@overload
136  @param cols Number of columns in a Buffer.
137  @param rows Number of rows in a Buffer.
138  @param nchannel Number of channels in Buffer
139  @param format value from ifm3d::pixel_format releates to data type
140  need to store one value.
141  @param metadata json formatted metadata of the chunk obtain from device
142 
143  @note This internally calls Create Method to allocates Memory
144  */
145  Buffer(std::uint32_t cols,
146  std::uint32_t rows,
147  std::uint32_t nchannel,
148  ifm3d::PixelFormat format,
149  const std::optional<ifm3d::json>& metadata = std::nullopt,
150  ifm3d::buffer_id buffer_id = static_cast<ifm3d::buffer_id>(0));
151 
152  virtual ~Buffer() = default;
153 
154  // move semantics
155  Buffer(Buffer&&) = default;
156  Buffer& operator=(Buffer&&) = default;
157 
158  // copy ctor/assignment operator
159  Buffer(const Buffer&) = default;
160  Buffer& operator=(const Buffer&) = default;
161 
162  /*@brief allocates the memory required for storing the image data
163  @param cols Number of columns in a Buffer.
164  @param rows Number of rows in a Buffer.
165  @param nchannel Number of channels in Buffer
166  @param format value from ifm3d::pixel_format releates to data type
167 
168  @Note On repeated calling it will deference the old Memory
169  */
170  void Create(std::uint32_t cols,
171  std::uint32_t rows,
172  std::uint32_t nchannel,
173  ifm3d::PixelFormat format,
175 
178  [[nodiscard]] Buffer Clone() const;
179 
180  /* getters*/
181  [[nodiscard]] std::uint32_t Height() const;
182  [[nodiscard]] std::uint32_t Width() const;
183  [[nodiscard]] std::uint32_t NumChannels() const;
184  [[nodiscard]] ifm3d::PixelFormat DataFormat() const;
185  [[nodiscard]] ifm3d::json Metadata() const;
186  [[nodiscard]] ifm3d::buffer_id BufferId() const;
187 
191  [[nodiscard]] size_t Size() const;
195  template <typename T = std::uint8_t>
196  T* Ptr(std::uint32_t row);
197 
201  template <typename T = std::uint8_t>
202  T const* Ptr(std::uint32_t row) const;
203 
209  template <typename T = std::uint8_t>
210  T* Ptr(std::uint32_t row, std::uint32_t col);
211 
217  template <typename T = std::uint8_t>
218  T const* Ptr(std::uint32_t row, std::uint32_t col) const;
219 
220  /*@brief access to the pixel for read and write
221  @param Index of the pixel considering image as 1D array
222  @return refernce of the value at the index
223  */
224  template <typename T>
225  T& At(std::size_t index);
226  /*@overload considering image as 2D
227  @param row 1st dimension index
228  @param col 2nd dimension index
229  */
230  template <typename T>
231  T& At(std::uint32_t row, std::uint32_t col);
232 
233  /*@brief access to the pixel for read and write
234  @param Index of the pixel considering image as 1D array
235  @return refernce of the value at the index
236  */
237  template <typename T>
238  T const& At(std::size_t index) const;
239  /*@overload considering image as 2D
240  @param row 1st dimension index
241  @param col 2nd dimension index
242  */
243  template <typename T>
244  T const& At(std::uint32_t row, std::uint32_t col) const;
245 
246  /*@brief set the value where mask value is 1
247  @param val value to be set
248  @param mask Binary mask
249 
250  @Note mask size must be same as this
251  */
252  template <typename T>
253  void SetTo(T val, const ifm3d::Buffer& mask);
254 
255  /*===========================*/
256  /* Iterators */
257  /*===========================*/
258  template <typename T>
259  struct Iterator
260  {
261  using iterator_category = std::random_access_iterator_tag;
262  using difference_type = std::ptrdiff_t;
263  using value_type = T;
264  using pointer = T*;
265  using reference = T&;
266 
267  Iterator(const std::uint8_t* ptr);
268  reference operator*() const;
269  pointer operator->();
270  Iterator& operator++();
271  Iterator operator++(std::int32_t);
272 
273  friend bool
274  operator==(const Iterator& a, const Iterator& b)
275  {
276  return a._ptr == b._ptr;
277  }
278 
279  friend bool
280  operator!=(const Iterator& a, const Iterator& b)
281  {
282  return a._ptr != b._ptr;
283  }
284 
285  bool
286  operator-(const Iterator& rhs) const noexcept
287  {
288  // logic here
289  return this->_ptr - rhs._ptr; // for example
290  }
291 
292  private:
293  pointer _ptr;
294  };
295 
296  // NOLINTBEGIN(readability-identifier-naming)
297  /*@brief Return the Iterator pointing to start of data*/
298  template <typename T>
299  Iterator<T> begin();
300  /*@brief Return the Iterator pointing to end of data*/
301  template <typename T>
302  Iterator<T> end();
303  // NOLINTEND(readability-identifier-naming)
304 
305  }; // end Buffer
306 
307  /*@brief IteratorAdapter is adapter and can be used in range based loops
308 
309  @code
310  for (auto value : ifm3d::IteratorAdapter<unsigned short>(image))
311  {
312  // operation on value
313  @endcode
314  */
315  template <typename T>
317  {
318  private:
319  Buffer& _it; // NOLINT(*-avoid-const-or-ref-data-members)
320 
321  public:
322  IteratorAdapter(Buffer& it);
323  auto begin(); // NOLINT(readability-identifier-naming)
324  auto end(); // NOLINT(readability-identifier-naming)
325  };
326 
328 
329  template <typename TP>
330  // NOLINTNEXTLINE(readability-identifier-naming)
331  class Buffer_ : public Buffer
332  {
333  public:
334  /*@brief fefault constructor*/
335  Buffer_();
336 
337  /* Similar to Buffer(cols,rows,ifm3d::formatType<Tp>::nchannel,
338  * ifm3d::formatType<Tp>::format ) */
339  Buffer_(std::uint32_t cols,
340  std::uint32_t rows,
341  std::optional<ifm3d::json> metadata = std::nullopt);
342 
343  ~Buffer_() override = default;
344 
345  // move semantics
346  Buffer_(Buffer_<TP>&&) = default;
347  Buffer_& operator=(Buffer_<TP>&&) = default;
348 
349  // copy ctor/assignment operator
350  Buffer_(const Buffer_<TP>&) = default;
351  Buffer_& operator=(const Buffer_<TP>&) = default;
352 
353  Buffer_(const Buffer&);
354  Buffer_& operator=(const Buffer&);
355 
356  /* Similar to Buffer::create(cols,rows,ifm3d::formatType<Tp>::nchannel,
357  * ifm3d::formatType<Tp>::format, ifm3d::buffer_id buffer_id ) */
358  void Create(std::uint32_t cols,
359  std::uint32_t rows,
361 
364  Buffer_ Clone() const;
365 
366  /* getters*/
367  [[nodiscard]] std::uint32_t Height() const;
368  [[nodiscard]] std::uint32_t Width() const;
369  [[nodiscard]] std::uint32_t Nchannels() const;
370  [[nodiscard]] ifm3d::PixelFormat DataFormat() const;
371  [[nodiscard]] ifm3d::json Metadata() const;
372 
376  TP* Ptr(std::uint32_t row);
377 
383  TP* Ptr(std::uint32_t row, std::uint32_t col);
384 
385  /*@brief access to the pixel for read and write
386  @param Index of the pixel considering image as 1D array
387  @return refernce of the value at the index
388  */
389  TP& At(std::size_t index);
390  /*@overload considering image as 2D
391  @param row 1st dimension index
392  @param col 2nd dimension index
393  */
394  TP& At(std::uint32_t row, std::uint32_t col);
395  /*@brief set the value where mask value is 1
396  @param val value to be set
397  @param mask Binary mask
398 
399  @Note mask size must be same as this
400  */
401  void SetTo(TP val, ifm3d::Buffer& mask);
402 
403  /*@brief Return the Iterator pointing to start of data*/
404  Iterator<TP> begin();
405  /*@brief Return the Iterator pointing to end of data*/
406  Iterator<TP> end();
407 
408  }; // end Buffer_<Tp>
409 
413  template <typename T, int N>
414  struct Point
415  {
416  std::array<T, N> val;
417  using ValueType = T;
418  };
419 
420  template <typename T>
421  using Point3D = struct Point<T, 3>;
422 
423  template <typename T>
424  using Point4D = struct Point<T, 4>;
425 
426  // user helper types
429  // checking for 32 bit float support
430  static_assert(CHAR_BIT * sizeof(float) == 32, "32 bit float required");
431  using Point3D_32F = Point3D<float>;
432 
435  using Point4D_32F = Point4D<float>;
436 
437 } // end: namespace ifm3d
438 
439 #include <ifm3d/fg/detail/buffer.hpp>
440 #endif // IFM3D_FG_Buffer_H
ifm3d::json
Definition: json.hpp:130
ifm3d::Buffer
The class Buffer represent a STL container to store data from the ifm devices in 2 dimension and supp...
Definition: buffer.h:98
ifm3d::buffer_id
buffer_id
Definition: buffer_id.h:18
ifm3d::Buffer::Iterator
Definition: buffer.h:259
ifm3d::Buffer_::Clone
Buffer_ Clone() const
Creates a full copy of the array and the underlying data.
ifm3d::IteratorAdapter
Definition: buffer.h:316
ifm3d::Point
Struct for 3D space point.
Definition: buffer.h:414
ifm3d::Buffer_
Definition: buffer.h:331
ifm3d::Buffer_::Ptr
TP * Ptr(std::uint32_t row)
returns a pointer to the specified Buffer row.