Zivid C++ API 2.13.1+18e79e79-1
Array2D.h
Go to the documentation of this file.
1/*******************************************************************************
2 * This file is part of the Zivid API
3 *
4 * Copyright 2015-2024 (C) Zivid AS
5 * All rights reserved.
6 *
7 * Zivid Software License, v1.0
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of Zivid AS nor the names of its contributors may be used
20 * to endorse or promote products derived from this software without specific
21 * prior written permission.
22 *
23 * 4. This software, with or without modification, must not be used with any
24 * other 3D camera than from Zivid AS.
25 *
26 * 5. Any software provided in binary form under this license must not be
27 * reverse engineered, decompiled, modified and/or disassembled.
28 *
29 * THIS SOFTWARE IS PROVIDED BY ZIVID AS "AS IS" AND ANY EXPRESS OR IMPLIED
30 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
32 * DISCLAIMED. IN NO EVENT SHALL ZIVID AS OR CONTRIBUTORS BE LIABLE FOR ANY
33 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Contact: Zivid Customer Success Team <customersuccess@zivid.com>
41 * Info: http://www.zivid.com
42 ******************************************************************************/
43
44#pragma once
45
47#include "Zivid/Resolution.h"
48
49#include <cstddef>
50#include <cstring>
51#include <iterator>
52#include <memory>
53#include <sstream>
54#include <stdexcept>
55#include <string>
56#include <type_traits>
57
58namespace Zivid
59{
60 template<class PixelFormat>
61 class Image;
62
63#ifndef NO_DOC
65 namespace Detail
66 {
67 ZIVID_CORE_EXPORT std::string array2DToString(std::size_t width, std::size_t height);
68 } // namespace Detail
69#endif
70
81 template<typename DataFormat>
82 class Array2D
83 {
84 public:
86 using ValueType = DataFormat;
87
91 using ConstIterator = const DataFormat *;
92
95 : m_width{ 0 }
96 , m_height{ 0 }
97 {}
98
100 size_t width() const
101 {
102 return m_width;
103 }
104
106 size_t height() const
107 {
108 return m_height;
109 }
110
113 size_t size() const
114 {
115 return width() * height();
116 }
117
119 bool isEmpty() const
120 {
121 return size() == 0;
122 }
123
126 const DataFormat *data() const
127 {
128 return m_data.get();
129 }
130
138 const DataFormat &operator()(size_t idx) const
139 {
140#ifdef __clang__
141# if __has_warning("-Wunsafe-buffer-usage")
142# pragma clang diagnostic push
143# pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
144# endif
145#endif
146 return *(data() + idx);
147#ifdef __clang__
148# if __has_warning("-Wunsafe-buffer-usage")
149# pragma clang diagnostic pop
150# endif
151#endif
152 }
153
162 const DataFormat &operator()(size_t i, size_t j) const
163 {
164 return operator()(width() * i + j);
165 }
166
169 {
170 return data();
171 }
172
175 {
176#ifdef __clang__
177# if __has_warning("-Wunsafe-buffer-usage")
178# pragma clang diagnostic push
179# pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
180# endif
181#endif
182 return data() + size();
183#ifdef __clang__
184# if __has_warning("-Wunsafe-buffer-usage")
185# pragma clang diagnostic pop
186# endif
187#endif
188 }
189
192 {
193 return begin();
194 }
195
198 {
199 return end();
200 }
201
203 std::string toString() const
204 {
205 return Detail::array2DToString(width(), height());
206 }
207
208 private:
209 template<
210 typename Iterator,
211 typename T = DataFormat,
212 typename std::enable_if<
213 std::is_convertible<typename std::iterator_traits<Iterator>::value_type, T>::value,
214 std::nullptr_t>::type = nullptr>
215 Array2D(const Resolution &resolution, Iterator beginIt, Iterator endIt)
216 : m_width{ resolution.width() }
217 , m_height{ resolution.height() }
218 , m_data{ [&] {
219 const auto inputSize = std::distance(beginIt, endIt);
220 if(inputSize != static_cast<std::ptrdiff_t>(resolution.size()))
221 {
222 /* NOLINT */ throw std::out_of_range(
223 "Array2D constructor got input that does not match image size. Expected "
224 + std::to_string(resolution.size()) + " items, got " + std::to_string(inputSize)
225 + " items.");
226 }
227 std::unique_ptr<DataFormat[]> data{ new DataFormat[resolution.size()] };
228 std::copy(beginIt, endIt, data.get());
229 return data.release();
230 }(),
231 std::default_delete<DataFormat[]>() }
232 {}
233
234 template<
235 typename T = DataFormat,
236 typename std::enable_if<std::is_trivial<T>::value, std::nullptr_t>::type = nullptr>
237 Array2D(const Resolution &resolution, const unsigned char *begin, const unsigned char *end)
238 : m_width{ resolution.width() }
239 , m_height{ resolution.height() }
240 {
241 const auto byteCount = std::distance(begin, end);
242 {
243 const auto expectedByteCount = static_cast<std::ptrdiff_t>(resolution.size() * sizeof(DataFormat));
244 if(expectedByteCount != byteCount)
245 {
246 std::ostringstream errorMessage;
247 errorMessage
248 << "The provided input buffer size does not match the expected size. The provided input buffer size is "
249 << byteCount << " bytes. Expected " << expectedByteCount << " bytes (" << resolution.width()
250 << " x " << resolution.height() << " x " << sizeof(DataFormat) << " bytes).";
251 /* NOLINT */ throw std::logic_error(std::move(errorMessage).str());
252 }
253 }
254 std::shared_ptr<DataFormat> data(new DataFormat[resolution.size()], std::default_delete<DataFormat[]>{});
255
256 if(resolution.size() != 0) // To handle the case where resolution is zero and begin == end == nullptr.
257 {
258 std::memcpy(data.get(), begin, byteCount);
259 }
260
261 m_data = std::move(data);
262 }
263
264 friend class Array2DFactory;
265 friend class Image<DataFormat>;
266
267 Array2D(std::size_t width, std::size_t height, std::unique_ptr<DataFormat[]> data)
268 : m_width{ width }
269 , m_height{ height }
270 , m_data{ // Due to poor support for shared_ptr array types in C++11 the data
271 // ownership is transferred from the std::unique_ptr to a std::shared_ptr
272 // of non-array type with a specified array deleter.
273 data.release(),
274 std::default_delete<DataFormat[]>()
275 }
276 {}
277
278 std::size_t m_width;
279 std::size_t m_height;
280 std::shared_ptr<const DataFormat> m_data;
281 };
282
284 template<typename T>
285 std::ostream &operator<<(std::ostream &stream, const Array2D<T> &array)
286 {
287 return stream << array.toString();
288 }
289
291 template<typename T>
293 {
294 return array.cbegin();
295 }
296
298 template<typename T>
300 {
301 return array.begin();
302 }
303
305 template<typename T>
307 {
308 return array.cend();
309 }
310
312 template<typename T>
314 {
315 return array.end();
316 }
317} // namespace Zivid
#define ZIVID_CORE_EXPORT
Definition CoreExport.h:56
Two-dimensional container of data.
Definition Array2D.h:83
ConstIterator cbegin() const
Iterator to the beginning of the array.
Definition Array2D.h:191
const DataFormat * ConstIterator
The iterator type for immutable access. It iterates over individual Array2D elements in row major ord...
Definition Array2D.h:91
const DataFormat & operator()(size_t i, size_t j) const
Constant reference to an element given by row and column.
Definition Array2D.h:162
ConstIterator cend() const
Iterator to the end of the array.
Definition Array2D.h:197
const DataFormat & operator()(size_t idx) const
Constant reference to an element given by a 1D linear index.
Definition Array2D.h:138
size_t height() const
Get the height of the array (number of rows)
Definition Array2D.h:106
const DataFormat * data() const
Pointer to the first data element of the array.
Definition Array2D.h:126
bool isEmpty() const
Check if the array is empty.
Definition Array2D.h:119
std::string toString() const
Get array information as string.
Definition Array2D.h:203
ConstIterator end() const
Iterator to the end of the array.
Definition Array2D.h:174
DataFormat ValueType
The type of the elements stored in the Array2D.
Definition Array2D.h:86
size_t size() const
Get the number of elements in the array.
Definition Array2D.h:113
size_t width() const
Get the width of the array (number of columns)
Definition Array2D.h:100
ConstIterator begin() const
Iterator to the beginning of the array.
Definition Array2D.h:168
Array2D()
Create an empty Array2D.
Definition Array2D.h:94
A 2-dimensional image.
Definition Image.h:85
Class describing a resolution with a width and a height.
Definition Resolution.h:56
ZIVID_CORE_EXPORT size_t size() const
Get the size (area) that is the product of the width and height.
ZIVID_CORE_EXPORT size_t height() const
Get the height value of the resolution.
ZIVID_CORE_EXPORT size_t width() const
Get the width value of the resolution.
ZIVID_CORE_EXPORT Resolution resolution(const CameraInfo &cameraInfo, const Settings &settings)
The main Zivid namespace. All Zivid code is found here.
Definition Application.h:56
Array2D< T >::ConstIterator end(const Array2D< T > &array)
Iterator to the end of the array.
Definition Array2D.h:313
Array2D< T >::ConstIterator cbegin(const Array2D< T > &array)
Iterator to the beginning of the array.
Definition Array2D.h:292
std::ostream & operator<<(std::ostream &stream, const Array2D< T > &array)
Serialize array information to a stream.
Definition Array2D.h:285
Array2D< T >::ConstIterator cend(const Array2D< T > &array)
Iterator to the end of the array.
Definition Array2D.h:306
Array2D< T >::ConstIterator begin(const Array2D< T > &array)
Iterator to the beginning of the array.
Definition Array2D.h:299