CVB++ 15.0
meta_data.hpp
1#pragma once
2
3#include <memory>
4
5#include "../global.hpp"
6#include "../_cexports/c_img.h"
7#include "../string.hpp"
8#include "../_cexports/c_spectral.h"
9#include "spectral.hpp"
10#include "../exception.hpp"
11#include <cctype>
12#include <algorithm>
13
14
15namespace Cvb
16{
17 CVB_BEGIN_INLINE_NS
18
19 template <>
20 inline HandleGuard<Spectral::MetaData>::HandleGuard(void * handle) noexcept
21 : HandleGuard<Spectral::MetaData>(handle, [](void* handle) { CVB_CALL_CAPI(ReleaseObject(handle)); })
22 {
23 }
24
25 namespace Spectral
26 {
27
28
30
32 class MetaData final
33 {
34 public:
35
36 MetaData(const MetaData& other) noexcept = delete;
37 MetaData& operator=(const MetaData & other) = delete;
38 MetaData(MetaData&& other) noexcept = default;
39 MetaData& operator=(MetaData&& other) = default;
40 ~MetaData() = default;
41
43
59 template<class T>
60 T ReadField(const FieldID& fieldId) const
61 {
62 T val;
63 GetField(fieldId, val);
64 return val;
65 }
66
67
69
84 template<class T>
85 void WriteField(FieldID fieldId, const T& value)
86 {
87 WriteFieldTyped(fieldId, value);
88 }
89
90
92
99 {
100 size_t sz = 0;
101 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetFieldnameAsStringTyped(handle_.Handle(),
102 static_cast<CExports::CVSField>(fieldId),
103 reinterpret_cast<Char*>(NULL), sz));
104 std::vector<Char> cvbVal(sz);
105 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetFieldnameAsStringTyped(handle_.Handle(),
106 static_cast<CExports::CVSField>(fieldId),
107 cvbVal.data(), sz));
108 return String(cvbVal.data());
109 }
110
112
119 {
120 auto fieldType = CFieldType(fieldId);
121 return static_cast<Spectral::FieldType>(fieldType);
122 }
123
125
130 int NumberOfFields() const
131 {
132 auto valOut = Internal::DoResCallValueOut<size_t>([&](size_t& val)
133 {
134 return CVB_CALL_CAPI(CVSMetaDataGetNumberOfFields(handle_.Handle(), val));
135 });
136 return static_cast<int>(valOut);
137 }
138
140
145 void ClearField(FieldID fieldId)
146 {
147 Internal::DoResCall([&]()
148 {
149 return CVB_CALL_CAPI(CVSMetaDataClearField(handle_.Handle(),
150 static_cast<CExports::CVSField>(fieldId)));
151 });
152 }
153
155
162 {
163 auto valOut = Internal::DoResCallValueOut<CExports::cvbbool_t>([&](CExports::cvbbool_t& isDefined)
164 {
165 return CVB_CALL_CAPI(CVSMetaDataIsFieldDefined(handle_.Handle(),
166 static_cast<CExports::CVSField>(fieldId),
167 isDefined));
168 });
169 return valOut ? true : false;
170 }
171
173
178 int Samples() const
179 {
180 return ReadField<int>(FieldID::Samples);
181 }
182
184
189 int Lines() const
190 {
191 return ReadField<int>(FieldID::Lines);
192 }
193
195
200 int Bands() const
201 {
202 return ReadField<int>(FieldID::Bands);
203 }
204
206
212 {
213 auto interleaveStr = ReadField<String>(FieldID::Interleave);
214 std::transform(interleaveStr.begin(), interleaveStr.end(), interleaveStr.begin(), [](String::value_type ch)
215 {
216 return static_cast<String::value_type>(std::toupper(ch));
217 });
218 if (interleaveStr == CVB_LIT("BIL"))
220 if (interleaveStr == CVB_LIT("BSQ"))
222 if (interleaveStr == CVB_LIT("BIP"))
224
225 throw std::runtime_error("Unknown interleaved type");
226 }
227
229
235 {
236 return ReadField<std::vector<double>>(FieldID::Wavelength);
237 }
238
239
241
247 {
248 return Internal::DoResCallObjectOut<MetaData>([&](void* & metaDataOut)
249 {
250 return CVB_CALL_CAPI(CVSCreateMetaData(metaDataOut));
251 });
252 }
253
255
259 void* Handle() const noexcept
260 {
261 return handle_.Handle();
262 }
263
265
273 static std::unique_ptr<MetaData> FromHandle(HandleGuard<MetaData>&& guard)
274 {
275 if (!guard.Handle())
276 throw std::runtime_error("handle must not be null");
277 return std::unique_ptr<MetaData>(new MetaData(std::move(guard)));
278 }
279
280
281 private:
282 explicit MetaData(HandleGuard<MetaData>&& guard) noexcept
283 : handle_(std::move(guard))
284 {
285 }
286
287
288
289
290 void GetField(FieldID fieldId, int& valueOut) const
291 {
292 CExports::cvbint64_t cvbVal = 0;
293 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsInteger(handle_.Handle(),
294 static_cast<CExports::CVSField>(fieldId), cvbVal));
295 valueOut = static_cast<int>(cvbVal);
296 }
297
298
299 void GetField(FieldID fieldId, double& valueOut) const
300 {
301 double cvbVal = 0;
302 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsFloat(handle_.Handle(),
303 static_cast<CExports::CVSField>(fieldId), cvbVal));
304 valueOut = std::move(cvbVal);
305 }
306
307
308 void GetField(FieldID fieldId, String& valueOut) const
309 {
310 size_t sz = 0;
311 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsStringTyped(handle_.Handle(),
312 static_cast<CExports::CVSField>(fieldId), reinterpret_cast<char*>(NULL), sz));
313 std::vector<char> cvbVal(sz);
314 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsStringTyped(handle_.Handle(),
315 static_cast<CExports::CVSField>(fieldId), cvbVal.data(), sz));
316 std::string str(cvbVal.data());
317 valueOut = String(str.begin(), str.end());
318 }
319
320
321 void GetField(FieldID fieldId, std::vector<int>& valueOut) const
322 {
323 size_t sz = 0;
324 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetArraySize(handle_.Handle(),
325 static_cast<CExports::CVSField>(fieldId), sz));
326 std::vector<int> cvbVal(sz);
327 for (CExports::cvbval_t i = 0; i < static_cast<CExports::cvbval_t>(sz); ++i)
328 {
329 CExports::cvbint64_t cvbElement = 0;
330 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsIntegerArray(handle_.Handle(),
331 static_cast<CExports::CVSField>(fieldId), i, cvbElement));
332 cvbVal.at(i) = static_cast<int>(cvbElement);
333 }
334 valueOut = std::move(cvbVal);
335 }
336
337
338 void GetField(FieldID fieldId, std::vector<double>& valueOut) const
339 {
340 size_t sz = 0;
341 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetArraySize(handle_.Handle(),
342 static_cast<CExports::CVSField>(fieldId), sz));
343 std::vector<double> cvbVal(sz);
344 for (CExports::cvbval_t i = 0; i < static_cast<CExports::cvbval_t>(sz); ++i)
345 {
346 double cvbElement = 0;
347 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsFloatArray(handle_.Handle(),
348 static_cast<CExports::CVSField>(fieldId), i, cvbElement));
349 cvbVal.at(i) = static_cast<double>(cvbElement);
350 }
351 valueOut = std::move(cvbVal);
352 }
353
354
355 void GetField(FieldID fieldId, std::vector<String>& valueOut) const
356 {
357 size_t sz = 0;
358 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetArraySize(handle_.Handle(),
359 static_cast<CExports::CVSField>(fieldId), sz));
360 std::vector<String> cvbVal(sz);
361
362 for (CExports::cvbval_t i = 0; i < static_cast<CExports::cvbval_t>(sz); ++i)
363 {
364 size_t szString = 0;
365 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsStringArrayTyped(handle_.Handle(),
366 static_cast<CExports::CVSField>(fieldId), i, reinterpret_cast<char*>(NULL), szString));
367 std::vector<char> cvbElement(szString);
368 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsStringArrayTyped(handle_.Handle(),
369 static_cast<CExports::CVSField>(fieldId), i, cvbElement.data(), szString));
370 std::string tmpStr(cvbElement.data());
371 cvbVal.at(i) = String(tmpStr.begin(), tmpStr.end());
372 }
373
374 valueOut = std::move(cvbVal);
375 }
376
377
378 void WriteFieldTyped(FieldID fieldId, const int& value)
379 {
380 CVB_CALL_CAPI_CHECKED(CVSMetaDataSetAsInteger(handle_.Handle(),
381 static_cast<CExports::CVSField>(fieldId),
382 static_cast<CExports::cvbint64_t>(value)));
383 }
384
385
386 void WriteFieldTyped(FieldID fieldId, const double& value)
387 {
388 CVB_CALL_CAPI_CHECKED(CVSMetaDataSetAsFloat(handle_.Handle(),
389 static_cast<CExports::CVSField>(fieldId),
390 value));
391 }
392
393
394 void WriteFieldTyped(FieldID fieldId, const String& value)
395 {
396 CVB_CALL_CAPI_CHECKED(CVSMetaDataSetAsStringTyped(handle_.Handle(),
397 static_cast<CExports::CVSField>(fieldId),
398 value.c_str()));
399 }
400
401
402 void WriteFieldTyped(FieldID fieldId, const std::vector<int>& value)
403 {
404 CVB_CALL_CAPI_CHECKED(CVSMetaDataClearField(handle_.Handle(),
405 static_cast<CExports::CVSField>(fieldId)));
406 for (auto e : value)
407 CVB_CALL_CAPI_CHECKED(CVSMetaDataAddToIntegerArray(handle_.Handle(),
408 static_cast<CExports::CVSField>(fieldId),
409 static_cast<CExports::cvbint64_t>(e)));
410 }
411
412
413 void WriteFieldTyped(FieldID fieldId, const std::vector<double>& value)
414 {
415 CVB_CALL_CAPI_CHECKED(CVSMetaDataClearField(handle_.Handle(),
416 static_cast<CExports::CVSField>(fieldId)));
417 for (auto e : value)
418 CVB_CALL_CAPI_CHECKED(CVSMetaDataAddToFloatArray(handle_.Handle(),
419 static_cast<CExports::CVSField>(fieldId),
420 static_cast<double>(e)));
421 }
422
423
424 void WriteFieldTyped(FieldID fieldId, const std::vector<String>& value)
425 {
426 CVB_CALL_CAPI_CHECKED(CVSMetaDataClearField(handle_.Handle(),
427 static_cast<CExports::CVSField>(fieldId)));
428 for (auto e : value)
429 CVB_CALL_CAPI_CHECKED(CVSMetaDataAddToStringArrayTyped(handle_.Handle(),
430 static_cast<CExports::CVSField>(fieldId),
431 e.c_str()));
432 }
433
434
436
441 CExports::CVSFieldType CFieldType(FieldID fieldId) const
442 {
443 return Internal::DoResCallValueOut<CExports::CVSFieldType>([&](CExports::CVSFieldType& val)
444 {
445 return CVB_CALL_CAPI(CVSMetaDataGetFieldType(handle_.Handle(),
446 static_cast<CExports::CVSField>(fieldId), val));
447 });
448 }
449
450 private:
451
452 HandleGuard<MetaData> handle_;
453
454
455 };
456 }
457
458using Spectral::MetaData;
459
460CVB_END_INLINE_NS
461
462}
463
Spectral MetaData object.
Definition: meta_data.hpp:33
void ClearField(FieldID fieldId)
Clears the given field and sets the FieldType to FieldType::Invalid.
Definition: meta_data.hpp:145
static std::unique_ptr< MetaData > FromHandle(HandleGuard< MetaData > &&guard)
Creates metadata from a classic API handle.
Definition: meta_data.hpp:273
String FieldNameAsString(FieldID fieldId) const
Gets the field name as Cvb::String.
Definition: meta_data.hpp:98
T ReadField(const FieldID &fieldId) const
Template function to get the value of the field.
Definition: meta_data.hpp:60
bool IsFieldDefined(FieldID fieldId)
Checks if the given field is already defined.
Definition: meta_data.hpp:161
void WriteField(FieldID fieldId, const T &value)
Template function to set the value of a given field.
Definition: meta_data.hpp:85
CubeEncoding InterleavedType() const
Convenience function to access the value of field FieldID::Interleave.
Definition: meta_data.hpp:211
Spectral::FieldType FieldType(FieldID fieldId) const
Gets the type of the given field.
Definition: meta_data.hpp:118
int Bands() const
Convenience function to access the value of field FieldID::Bands.
Definition: meta_data.hpp:200
int Samples() const
Convenience function to access the value of field FieldID::Samples.
Definition: meta_data.hpp:178
std::vector< double > Wavelengths() const
Convenience function to access the value of field FieldID::Wavelength.
Definition: meta_data.hpp:234
void * Handle() const noexcept
Returns C-API style handle to the metadata.
Definition: meta_data.hpp:259
int NumberOfFields() const
Gets the total number of all fields.
Definition: meta_data.hpp:130
int Lines() const
Convenience function to access the value of field FieldID::Lines.
Definition: meta_data.hpp:189
static std::unique_ptr< MetaData > Create()
Creates an empty metadata object.
Definition: meta_data.hpp:246
FieldID
FieldID enum class to access fields in the MetaData object.
Definition: spectral.hpp:121
@ Bands
The number of bands.
@ Lines
The number of lines.
@ Wavelength
Array of wavelengths with the unit given in FieldID::WavelengthUnit.
@ Interleave
Defines the way the spectral data of the buffer is ordered (CubeEncoding)
@ Samples
The number of samples.
FieldType
Data type of a field.
Definition: spectral.hpp:180
CubeEncoding
View Perspective: Defines how the mapping between a typical x-y image and samples-lines-bands is done...
Definition: spectral.hpp:211
Root namespace for the Image Manager interface.
Definition: c_barcode.h:15
char Char
Character type for wide characters or unicode characters.
Definition: string.hpp:70
std::string String
String for wide characters or unicode characters.
Definition: string.hpp:56