CVB++ 14.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
37
53 template<class T>
54 T ReadField(const FieldID& fieldId) const
55 {
56 T val;
57 GetField(fieldId, val);
58 return val;
59 }
60
61
63
78 template<class T>
79 void WriteField(FieldID fieldId, const T& value)
80 {
81 WriteFieldTyped(fieldId, value);
82 }
83
84
86
93 {
94 size_t sz = 0;
95 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetFieldnameAsStringTyped(handle_.Handle(),
96 static_cast<CExports::CVSField>(fieldId),
97 reinterpret_cast<Char*>(NULL), sz));
98 std::vector<Char> cvbVal(sz);
99 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetFieldnameAsStringTyped(handle_.Handle(),
100 static_cast<CExports::CVSField>(fieldId),
101 cvbVal.data(), sz));
102 return String(cvbVal.data());
103 }
104
106
113 {
114 auto fieldType = CFieldType(fieldId);
115 return static_cast<Spectral::FieldType>(fieldType);
116 }
117
119
124 int NumberOfFields() const
125 {
126 auto valOut = Internal::DoResCallValueOut<size_t>([&](size_t& val)
127 {
128 return CVB_CALL_CAPI(CVSMetaDataGetNumberOfFields(handle_.Handle(), val));
129 });
130 return static_cast<int>(valOut);
131 }
132
134
139 void ClearField(FieldID fieldId)
140 {
141 Internal::DoResCall([&]()
142 {
143 return CVB_CALL_CAPI(CVSMetaDataClearField(handle_.Handle(),
144 static_cast<CExports::CVSField>(fieldId)));
145 });
146 }
147
149
156 {
157 auto valOut = Internal::DoResCallValueOut<CExports::cvbbool_t>([&](CExports::cvbbool_t& isDefined)
158 {
159 return CVB_CALL_CAPI(CVSMetaDataIsFieldDefined(handle_.Handle(),
160 static_cast<CExports::CVSField>(fieldId),
161 isDefined));
162 });
163 return valOut ? true : false;
164 }
165
167
172 int Samples() const
173 {
174 return ReadField<int>(FieldID::Samples);
175 }
176
178
183 int Lines() const
184 {
185 return ReadField<int>(FieldID::Lines);
186 }
187
189
194 int Bands() const
195 {
196 return ReadField<int>(FieldID::Bands);
197 }
198
200
206 {
207 auto interleaveStr = ReadField<String>(FieldID::Interleave);
208 std::transform(interleaveStr.begin(), interleaveStr.end(), interleaveStr.begin(), [](String::value_type ch)
209 {
210 return static_cast<String::value_type>(std::toupper(ch));
211 });
212 if (interleaveStr == CVB_LIT("BIL"))
214 if (interleaveStr == CVB_LIT("BSQ"))
216 if (interleaveStr == CVB_LIT("BIP"))
218
219 throw Cvb::CvbException::FromCvbResult(CExports::CVC_E_NOTSUPPORTED, "Unknown interleaved type");
220 }
221
223
229 {
230 return ReadField<std::vector<double>>(FieldID::Wavelength);
231 }
232
233
235
241 {
242 return Internal::DoResCallObjectOut<MetaData>([&](void* & metaDataOut)
243 {
244 return CVB_CALL_CAPI(CVSCreateMetaData(metaDataOut));
245 });
246 }
247
249
253 void* Handle() const noexcept
254 {
255 return handle_.Handle();
256 }
257
259
267 static std::unique_ptr<MetaData> FromHandle(HandleGuard<MetaData>&& guard)
268 {
269 if (!guard.Handle())
270 throw std::runtime_error("handle must not be null");
271 return std::unique_ptr<MetaData>(new MetaData(std::move(guard)));
272 }
273
274
275 private:
276 MetaData(HandleGuard<MetaData>&& guard) noexcept
277 : handle_(std::move(guard))
278 {
279 }
280
281 MetaData(MetaData && other) noexcept
282 : handle_(std::move(other.handle_))
283 {
284 }
285
286 MetaData & operator=(MetaData && other) = default;
287
288
289 void GetField(FieldID fieldId, int& valueOut) const
290 {
291 CExports::cvbint64_t cvbVal = 0;
292 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsInteger(handle_.Handle(),
293 static_cast<CExports::CVSField>(fieldId), cvbVal));
294 valueOut = static_cast<int>(cvbVal);
295 }
296
297
298 void GetField(FieldID fieldId, double& valueOut) const
299 {
300 double cvbVal = 0;
301 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsFloat(handle_.Handle(),
302 static_cast<CExports::CVSField>(fieldId), cvbVal));
303 valueOut = std::move(cvbVal);
304 }
305
306
307 void GetField(FieldID fieldId, String& valueOut) const
308 {
309 size_t sz = 0;
310 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsStringTyped(handle_.Handle(),
311 static_cast<CExports::CVSField>(fieldId), reinterpret_cast<char*>(NULL), sz));
312 std::vector<char> cvbVal(sz);
313 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsStringTyped(handle_.Handle(),
314 static_cast<CExports::CVSField>(fieldId), cvbVal.data(), sz));
315 std::string str(cvbVal.data());
316 valueOut = String(str.begin(), str.end());
317 }
318
319
320 void GetField(FieldID fieldId, std::vector<int>& valueOut) const
321 {
322 size_t sz = 0;
323 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetArraySize(handle_.Handle(),
324 static_cast<CExports::CVSField>(fieldId), sz));
325 std::vector<int> cvbVal(sz);
326 for (CExports::cvbval_t i = 0; i < static_cast<CExports::cvbval_t>(sz); ++i)
327 {
328 CExports::cvbint64_t cvbElement = 0;
329 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsIntegerArray(handle_.Handle(),
330 static_cast<CExports::CVSField>(fieldId), i, cvbElement));
331 cvbVal.at(i) = static_cast<int>(cvbElement);
332 }
333 valueOut = std::move(cvbVal);
334 }
335
336
337 void GetField(FieldID fieldId, std::vector<double>& valueOut) const
338 {
339 size_t sz = 0;
340 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetArraySize(handle_.Handle(),
341 static_cast<CExports::CVSField>(fieldId), sz));
342 std::vector<double> cvbVal(sz);
343 for (CExports::cvbval_t i = 0; i < static_cast<CExports::cvbval_t>(sz); ++i)
344 {
345 double cvbElement = 0;
346 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsFloatArray(handle_.Handle(),
347 static_cast<CExports::CVSField>(fieldId), i, cvbElement));
348 cvbVal.at(i) = static_cast<double>(cvbElement);
349 }
350 valueOut = std::move(cvbVal);
351 }
352
353
354 void GetField(FieldID fieldId, std::vector<String>& valueOut) const
355 {
356 size_t sz = 0;
357 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetArraySize(handle_.Handle(),
358 static_cast<CExports::CVSField>(fieldId), sz));
359 std::vector<String> cvbVal(sz);
360
361 for (CExports::cvbval_t i = 0; i < static_cast<CExports::cvbval_t>(sz); ++i)
362 {
363 size_t szString = 0;
364 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsStringArrayTyped(handle_.Handle(),
365 static_cast<CExports::CVSField>(fieldId), i, reinterpret_cast<char*>(NULL), szString));
366 std::vector<char> cvbElement(szString);
367 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsStringArrayTyped(handle_.Handle(),
368 static_cast<CExports::CVSField>(fieldId), i, cvbElement.data(), szString));
369 std::string tmpStr(cvbElement.data());
370 cvbVal.at(i) = String(tmpStr.begin(), tmpStr.end());
371 }
372
373 valueOut = std::move(cvbVal);
374 }
375
376
377 void WriteFieldTyped(FieldID fieldId, const int& value)
378 {
379 CVB_CALL_CAPI_CHECKED(CVSMetaDataSetAsInteger(handle_.Handle(),
380 static_cast<CExports::CVSField>(fieldId),
381 static_cast<CExports::cvbint64_t>(value)));
382 }
383
384
385 void WriteFieldTyped(FieldID fieldId, const double& value)
386 {
387 CVB_CALL_CAPI_CHECKED(CVSMetaDataSetAsFloat(handle_.Handle(),
388 static_cast<CExports::CVSField>(fieldId),
389 value));
390 }
391
392
393 void WriteFieldTyped(FieldID fieldId, const String& value)
394 {
395 CVB_CALL_CAPI_CHECKED(CVSMetaDataSetAsStringTyped(handle_.Handle(),
396 static_cast<CExports::CVSField>(fieldId),
397 value.c_str()));
398 }
399
400
401 void WriteFieldTyped(FieldID fieldId, const std::vector<int>& value)
402 {
403 CVB_CALL_CAPI_CHECKED(CVSMetaDataClearField(handle_.Handle(),
404 static_cast<CExports::CVSField>(fieldId)));
405 for (auto e : value)
406 CVB_CALL_CAPI_CHECKED(CVSMetaDataAddToIntegerArray(handle_.Handle(),
407 static_cast<CExports::CVSField>(fieldId),
408 static_cast<CExports::cvbint64_t>(e)));
409 }
410
411
412 void WriteFieldTyped(FieldID fieldId, const std::vector<double>& value)
413 {
414 CVB_CALL_CAPI_CHECKED(CVSMetaDataClearField(handle_.Handle(),
415 static_cast<CExports::CVSField>(fieldId)));
416 for (auto e : value)
417 CVB_CALL_CAPI_CHECKED(CVSMetaDataAddToFloatArray(handle_.Handle(),
418 static_cast<CExports::CVSField>(fieldId),
419 static_cast<double>(e)));
420 }
421
422
423 void WriteFieldTyped(FieldID fieldId, const std::vector<String>& value)
424 {
425 CVB_CALL_CAPI_CHECKED(CVSMetaDataClearField(handle_.Handle(),
426 static_cast<CExports::CVSField>(fieldId)));
427 for (auto e : value)
428 CVB_CALL_CAPI_CHECKED(CVSMetaDataAddToStringArrayTyped(handle_.Handle(),
429 static_cast<CExports::CVSField>(fieldId),
430 e.c_str()));
431 }
432
433
435
440 CExports::CVSFieldType CFieldType(FieldID fieldId) const
441 {
442 return Internal::DoResCallValueOut<CExports::CVSFieldType>([&](CExports::CVSFieldType& val)
443 {
444 return CVB_CALL_CAPI(CVSMetaDataGetFieldType(handle_.Handle(),
445 static_cast<CExports::CVSField>(fieldId), val));
446 });
447 }
448
449 private:
450
451 HandleGuard<MetaData> handle_;
452
453
454 };
455 }
456
457using Spectral::MetaData;
458
459CVB_END_INLINE_NS
460
461}
462
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:139
static std::unique_ptr< MetaData > FromHandle(HandleGuard< MetaData > &&guard)
Creates metadata from a classic API handle.
Definition: meta_data.hpp:267
String FieldNameAsString(FieldID fieldId) const
Gets the field name as Cvb::String.
Definition: meta_data.hpp:92
T ReadField(const FieldID &fieldId) const
Template function to get the value of the field.
Definition: meta_data.hpp:54
bool IsFieldDefined(FieldID fieldId)
Checks if the given field is already defined.
Definition: meta_data.hpp:155
void WriteField(FieldID fieldId, const T &value)
Template function to set the value of a given field.
Definition: meta_data.hpp:79
CubeEncoding InterleavedType() const
Convenience function to access the value of field FieldID::Interleave.
Definition: meta_data.hpp:205
Spectral::FieldType FieldType(FieldID fieldId) const
Gets the type of the given field.
Definition: meta_data.hpp:112
int Bands() const
Convenience function to access the value of field FieldID::Bands.
Definition: meta_data.hpp:194
int Samples() const
Convenience function to access the value of field FieldID::Samples.
Definition: meta_data.hpp:172
std::vector< double > Wavelengths() const
Convenience function to access the value of field FieldID::Wavelength.
Definition: meta_data.hpp:228
void * Handle() const noexcept
Returns C-API style handle to the metadata.
Definition: meta_data.hpp:253
int NumberOfFields() const
Gets the total number of all fields.
Definition: meta_data.hpp:124
int Lines() const
Convenience function to access the value of field FieldID::Lines.
Definition: meta_data.hpp:183
static std::unique_ptr< MetaData > Create()
Creates an empty metadata object.
Definition: meta_data.hpp:240
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:24
char Char
Character type for wide characters or unicode characters.
Definition: string.hpp:59
std::string String
String for wide characters or unicode characters.
Definition: string.hpp:45