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 <cstdint>
11 #include <memory>
12 #include <vector>
13 #include <optional>
14 #include <ifm3d/common/json.hpp>
15 #include <limits.h>
16 #include <ifm3d/fg/frame_grabber_export.h>
17 #include <ifm3d/device/device.h>
18 
19 namespace ifm3d
20 {
98  class IFM3D_FRAME_GRABBER_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::pixel_format 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 
122  class BufferAllocator;
123  std::shared_ptr<BufferAllocator> buffer_allocator_;
124 
125  public:
132  Buffer();
133  /*@overload
134  @param cols Number of columns in a Buffer.
135  @param rows Number of rows in a Buffer.
136  @param nchannel Number of channels in Buffer
137  @param format value from ifm3d::pixel_format releates to data type
138  need to store one value.
139  @param metadata json formatted metadata of the chunk obtain from device
140 
141  @note This internally calls Create Method to allocates Memory
142  */
143  Buffer(const std::uint32_t cols,
144  const std::uint32_t rows,
145  const std::uint32_t nchannel,
146  ifm3d::pixel_format format,
147  std::optional<ifm3d::json> metadata = std::nullopt);
148 
149  virtual ~Buffer() = default;
150 
151  // move semantics
152  Buffer(Buffer&&) = default;
153  Buffer& operator=(Buffer&&) = default;
154 
155  // copy ctor/assignment operator
156  Buffer(const Buffer&) = default;
157  Buffer& operator=(const Buffer&) = default;
158 
159  /*@brief allocates the memory required for storing the image data
160  @param cols Number of columns in a Buffer.
161  @param rows Number of rows in a Buffer.
162  @param nchannel Number of channels in Buffer
163  @param format value from ifm3d::pixel_format releates to data type
164 
165  @Note On repeated calling it will deference the old Memory
166  */
167  void create(const std::uint32_t cols,
168  const std::uint32_t rows,
169  const std::uint32_t nchannel,
170  ifm3d::pixel_format format);
171 
174  Buffer clone() const;
175 
176  /* getters*/
177  std::uint32_t height() const;
178  std::uint32_t width() const;
179  std::uint32_t nchannels() const;
180  ifm3d::pixel_format dataFormat() const;
181  ifm3d::json metadata() const;
182 
186  size_t size() const;
190  template <typename T = std::uint8_t>
191  T* ptr(const std::uint32_t row);
192 
196  template <typename T = std::uint8_t>
197  T const* ptr(const std::uint32_t row) const;
198 
204  template <typename T = std::uint8_t>
205  T* ptr(const std::uint32_t row, const std::uint32_t col);
206 
212  template <typename T = std::uint8_t>
213  T const* ptr(const std::uint32_t row, const std::uint32_t col) const;
214 
215  /*@brief access to the pixel for read and write
216  @param Index of the pixel considering image as 1D array
217  @return refernce of the value at the index
218  */
219  template <typename T>
220  T& at(const std::size_t index);
221  /*@overload considering image as 2D
222  @param row 1st dimension index
223  @param col 2nd dimension index
224  */
225  template <typename T>
226  T& at(const std::uint32_t row, const std::uint32_t col);
227 
228  /*@brief access to the pixel for read and write
229  @param Index of the pixel considering image as 1D array
230  @return refernce of the value at the index
231  */
232  template <typename T>
233  T const& at(const std::size_t index) const;
234  /*@overload considering image as 2D
235  @param row 1st dimension index
236  @param col 2nd dimension index
237  */
238  template <typename T>
239  T const& at(const std::uint32_t row, const std::uint32_t col) const;
240 
241  /*@brief set the value where mask value is 1
242  @param val value to be set
243  @param mask Binary mask
244 
245  @Note mask size must be same as this
246  */
247  template <typename T>
248  void setTo(const T val, const ifm3d::Buffer& mask);
249 
250  /*===========================*/
251  /* Iterators */
252  /*===========================*/
253  template <typename T>
254  struct Iterator
255  {
256  using iterator_category = std::random_access_iterator_tag;
257  using difference_type = std::ptrdiff_t;
258  using value_type = T;
259  using pointer = T*;
260  using reference = T&;
261 
262  Iterator(uint8_t* ptr);
263  reference operator*() const;
264  pointer operator->();
265  Iterator& operator++();
266  Iterator operator++(std::int32_t);
267 
268  friend bool
269  operator==(const Iterator& a, const Iterator& b)
270  {
271  return a.m_ptr == b.m_ptr;
272  }
273 
274  friend bool
275  operator!=(const Iterator& a, const Iterator& b)
276  {
277  return a.m_ptr != b.m_ptr;
278  }
279 
280  bool
281  operator-(const Iterator& rhs) const noexcept
282  {
283  // logic here
284  return this->m_ptr - rhs.m_ptr; // for example
285  }
286 
287  private:
288  pointer m_ptr;
289  };
290 
291  /*@brief Return the Iterator pointing to start of data*/
292  template <typename T>
293  Iterator<T> begin();
294  /*@brief Return the Iterator pointing to end of data*/
295  template <typename T>
296  Iterator<T> end();
297 
298  }; // end Buffer
299 
300  /*@brief IteratorAdapter is adapter and can be used in range based loops
301 
302  @code
303  for (auto value : ifm3d::IteratorAdapter<unsigned short>(image))
304  {
305  // operation on value
306  @endcode
307  */
308  template <typename T>
310  {
311  private:
312  Buffer& it;
313 
314  public:
315  IteratorAdapter(Buffer& it);
316  auto begin();
317  auto end();
318  };
319 
321 
322  template <typename Tp>
323  class Buffer_ : public Buffer
324  {
325  public:
326  /*@brief fefault constructor*/
327  Buffer_();
328 
329  /* Similar to Buffer(cols,rows,ifm3d::formatType<Tp>::nchannel,
330  * ifm3d::formatType<Tp>::format ) */
331  Buffer_(const std::uint32_t cols,
332  const std::uint32_t rows,
333  std::optional<ifm3d::json> metadata = std::nullopt);
334 
335  ~Buffer_() = default;
336 
337  // move semantics
338  Buffer_(Buffer_<Tp>&&) = default;
339  Buffer_& operator=(Buffer_<Tp>&&) = default;
340 
341  // copy ctor/assignment operator
342  Buffer_(const Buffer_<Tp>&) = default;
343  Buffer_& operator=(const Buffer_<Tp>&) = default;
344 
345  Buffer_(const Buffer&);
346  Buffer_& operator=(const Buffer&);
347 
348  /* Similar to Buffer::create(cols,rows,ifm3d::formatType<Tp>::nchannel,
349  * ifm3d::formatType<Tp>::format ) */
350  void create(const std::uint32_t cols, const std::uint32_t rows);
351 
354  Buffer_ clone() const;
355 
356  /* getters*/
357  std::uint32_t height() const;
358  std::uint32_t width() const;
359  std::uint32_t nchannels() const;
360  ifm3d::pixel_format dataFormat() const;
361  ifm3d::json metadata() const;
362 
366  Tp* ptr(const std::uint32_t row);
367 
373  Tp* ptr(const std::uint32_t row, const std::uint32_t col);
374 
375  /*@brief access to the pixel for read and write
376  @param Index of the pixel considering image as 1D array
377  @return refernce of the value at the index
378  */
379  Tp& at(const std::size_t index);
380  /*@overload considering image as 2D
381  @param row 1st dimension index
382  @param col 2nd dimension index
383  */
384  Tp& at(const std::uint32_t row, const std::uint32_t col);
385  /*@brief set the value where mask value is 1
386  @param val value to be set
387  @param mask Binary mask
388 
389  @Note mask size must be same as this
390  */
391  void setTo(const Tp val, ifm3d::Buffer& mask);
392 
393  /*@brief Return the Iterator pointing to start of data*/
394  Iterator<Tp> begin();
395  /*@brief Return the Iterator pointing to end of data*/
396  Iterator<Tp> end();
397 
398  }; // end Buffer_<Tp>
399 
403  template <typename T, int n>
404  struct Point
405  {
406  T val[n];
407  using value_type = T;
408  };
409 
410  template <typename T>
411  using Point3D = struct Point<T, 3>;
412 
413  template <typename T>
414  using Point4D = struct Point<T, 4>;
415 
416  // user helper types
419  // checking for 32 bit float support
420  static_assert(CHAR_BIT * sizeof(float) == 32, "32 bit float required");
421  using Point3D_32F = Point3D<float>;
422 
425  using Point4D_32F = Point4D<float>;
426 
427 } // end: namespace ifm3d
428 
429 #include <ifm3d/fg/detail/buffer.hpp>
430 #endif // IFM3D_FG_Buffer_H
ifm3d::json
Definition: json.hpp:128
ifm3d::Buffer_::clone
Buffer_ clone() const
Creates a full copy of the array and the underlying data.
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::Iterator
Definition: buffer.h:254
ifm3d::IteratorAdapter
Definition: buffer.h:309
ifm3d::Point
Struct for 3D space point.
Definition: buffer.h:404
ifm3d::Buffer_::ptr
Tp * ptr(const std::uint32_t row)
returns a pointer to the specified Buffer row.
ifm3d::Buffer_
Definition: buffer.h:323