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
14namespace Cvb
15{
16 CVB_BEGIN_INLINE_NS
17
18 template <>
19 inline HandleGuard<Spectral::MetaData>::HandleGuard(void *handle) noexcept
20 : HandleGuard<Spectral::MetaData>(handle, [](void *handle) { CVB_CALL_CAPI(ReleaseObject(handle)); })
21 {
22 }
23
24 namespace Spectral
25 {
26
28
30 class MetaData final
31 {
32 public:
33 MetaData(const MetaData &other) noexcept = delete;
34 MetaData &operator=(const MetaData &other) = delete;
35 MetaData(MetaData &&other) noexcept = default;
36 MetaData &operator=(MetaData &&other) = default;
37 ~MetaData() = default;
38
40
56 template <class T>
57 T ReadField(const FieldID &fieldId) const
58 {
59 T val;
60 GetField(fieldId, val);
61 return val;
62 }
63
65
80 template <class T>
81 void WriteField(FieldID fieldId, const T &value)
82 {
83 WriteFieldTyped(fieldId, value);
84 }
85
87
94 {
95 size_t sz = 0;
96 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetFieldnameAsStringTyped(
97 handle_.Handle(), static_cast<CExports::CVSField>(fieldId), reinterpret_cast<Char *>(NULL), sz));
98 std::vector<Char> cvbVal(sz);
99 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetFieldnameAsStringTyped(
100 handle_.Handle(), static_cast<CExports::CVSField>(fieldId), cvbVal.data(), sz));
101 return String(cvbVal.data());
102 }
103
105
112 {
113 auto fieldType = CFieldType(fieldId);
114 return static_cast<Spectral::FieldType>(fieldType);
115 }
116
118
123 int NumberOfFields() const
124 {
125 auto valOut = Internal::DoResCallValueOut<size_t>(
126 [&](size_t &val) { return CVB_CALL_CAPI(CVSMetaDataGetNumberOfFields(handle_.Handle(), val)); });
127 return static_cast<int>(valOut);
128 }
129
131
136 void ClearField(FieldID fieldId)
137 {
138 Internal::DoResCall([&]() {
139 return CVB_CALL_CAPI(CVSMetaDataClearField(handle_.Handle(), static_cast<CExports::CVSField>(fieldId)));
140 });
141 }
142
144
151 {
152 auto valOut = Internal::DoResCallValueOut<CExports::cvbbool_t>([&](CExports::cvbbool_t &isDefined) {
153 return CVB_CALL_CAPI(
154 CVSMetaDataIsFieldDefined(handle_.Handle(), static_cast<CExports::CVSField>(fieldId), isDefined));
155 });
156 return valOut ? true : false;
157 }
158
160
165 int Samples() const
166 {
168 }
169
171
176 int Lines() const
177 {
179 }
180
182
187 int Bands() const
188 {
190 }
191
193
199 {
200 auto interleaveStr = ReadField<String>(FieldID::Interleave);
201 std::transform(interleaveStr.begin(), interleaveStr.end(), interleaveStr.begin(),
202 [](String::value_type ch) { return static_cast<String::value_type>(std::toupper(ch)); });
203 if (interleaveStr == CVB_LIT("BIL"))
205 if (interleaveStr == CVB_LIT("BSQ"))
207 if (interleaveStr == CVB_LIT("BIP"))
209
210 throw std::runtime_error("Unknown interleaved type");
211 }
212
214
223
225
231 {
232 return Internal::DoResCallObjectOut<MetaData>(
233 [&](void *&metaDataOut) { return CVB_CALL_CAPI(CVSCreateMetaData(metaDataOut)); });
234 }
235
237
241 void *Handle() const noexcept
242 {
243 return handle_.Handle();
244 }
245
247
255 static std::unique_ptr<MetaData> FromHandle(HandleGuard<MetaData> &&guard)
256 {
257 if (!guard.Handle())
258 throw std::runtime_error("handle must not be null");
259 return std::unique_ptr<MetaData>(new MetaData(std::move(guard)));
260 }
261
262 private:
263 explicit MetaData(HandleGuard<MetaData> &&guard) noexcept
264 : handle_(std::move(guard))
265 {
266 }
267
268 void GetField(FieldID fieldId, int &valueOut) const
269 {
270 CExports::cvbint64_t cvbVal = 0;
271 CVB_CALL_CAPI_CHECKED(
272 CVSMetaDataGetAsInteger(handle_.Handle(), static_cast<CExports::CVSField>(fieldId), cvbVal));
273 valueOut = static_cast<int>(cvbVal);
274 }
275
276 void GetField(FieldID fieldId, double &valueOut) const
277 {
278 double cvbVal = 0;
279 CVB_CALL_CAPI_CHECKED(
280 CVSMetaDataGetAsFloat(handle_.Handle(), static_cast<CExports::CVSField>(fieldId), cvbVal));
281 valueOut = std::move(cvbVal);
282 }
283
284 void GetField(FieldID fieldId, String &valueOut) const
285 {
286 size_t sz = 0;
287 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsStringTyped(handle_.Handle(), static_cast<CExports::CVSField>(fieldId),
288 reinterpret_cast<char *>(NULL), sz));
289 std::vector<char> cvbVal(sz);
290 CVB_CALL_CAPI_CHECKED(
291 CVSMetaDataGetAsStringTyped(handle_.Handle(), static_cast<CExports::CVSField>(fieldId), cvbVal.data(), sz));
292 std::string str(cvbVal.data());
293 valueOut = String(str.begin(), str.end());
294 }
295
296 void GetField(FieldID fieldId, std::vector<int> &valueOut) const
297 {
298 size_t sz = 0;
299 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetArraySize(handle_.Handle(), static_cast<CExports::CVSField>(fieldId), sz));
300 std::vector<int> cvbVal(sz);
301 for (CExports::cvbval_t i = 0; i < static_cast<CExports::cvbval_t>(sz); ++i)
302 {
303 CExports::cvbint64_t cvbElement = 0;
304 CVB_CALL_CAPI_CHECKED(
305 CVSMetaDataGetAsIntegerArray(handle_.Handle(), static_cast<CExports::CVSField>(fieldId), i, cvbElement));
306 cvbVal.at(i) = static_cast<int>(cvbElement);
307 }
308 valueOut = std::move(cvbVal);
309 }
310
311 void GetField(FieldID fieldId, std::vector<double> &valueOut) const
312 {
313 size_t sz = 0;
314 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetArraySize(handle_.Handle(), static_cast<CExports::CVSField>(fieldId), sz));
315 std::vector<double> cvbVal(sz);
316 for (CExports::cvbval_t i = 0; i < static_cast<CExports::cvbval_t>(sz); ++i)
317 {
318 double cvbElement = 0;
319 CVB_CALL_CAPI_CHECKED(
320 CVSMetaDataGetAsFloatArray(handle_.Handle(), static_cast<CExports::CVSField>(fieldId), i, cvbElement));
321 cvbVal.at(i) = static_cast<double>(cvbElement);
322 }
323 valueOut = std::move(cvbVal);
324 }
325
326 void GetField(FieldID fieldId, std::vector<String> &valueOut) const
327 {
328 size_t sz = 0;
329 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetArraySize(handle_.Handle(), static_cast<CExports::CVSField>(fieldId), sz));
330 std::vector<String> cvbVal(sz);
331
332 for (CExports::cvbval_t i = 0; i < static_cast<CExports::cvbval_t>(sz); ++i)
333 {
334 size_t szString = 0;
335 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsStringArrayTyped(
336 handle_.Handle(), static_cast<CExports::CVSField>(fieldId), i, reinterpret_cast<char *>(NULL), szString));
337 std::vector<char> cvbElement(szString);
338 CVB_CALL_CAPI_CHECKED(CVSMetaDataGetAsStringArrayTyped(
339 handle_.Handle(), static_cast<CExports::CVSField>(fieldId), i, cvbElement.data(), szString));
340 std::string tmpStr(cvbElement.data());
341 cvbVal.at(i) = String(tmpStr.begin(), tmpStr.end());
342 }
343
344 valueOut = std::move(cvbVal);
345 }
346
347 void WriteFieldTyped(FieldID fieldId, const int &value)
348 {
349 CVB_CALL_CAPI_CHECKED(CVSMetaDataSetAsInteger(handle_.Handle(), static_cast<CExports::CVSField>(fieldId),
350 static_cast<CExports::cvbint64_t>(value)));
351 }
352
353 void WriteFieldTyped(FieldID fieldId, const double &value)
354 {
355 CVB_CALL_CAPI_CHECKED(CVSMetaDataSetAsFloat(handle_.Handle(), static_cast<CExports::CVSField>(fieldId), value));
356 }
357
358 void WriteFieldTyped(FieldID fieldId, const String &value)
359 {
360 CVB_CALL_CAPI_CHECKED(
361 CVSMetaDataSetAsStringTyped(handle_.Handle(), static_cast<CExports::CVSField>(fieldId), value.c_str()));
362 }
363
364 void WriteFieldTyped(FieldID fieldId, const std::vector<int> &value)
365 {
366 CVB_CALL_CAPI_CHECKED(CVSMetaDataClearField(handle_.Handle(), static_cast<CExports::CVSField>(fieldId)));
367 for (auto e : value)
368 CVB_CALL_CAPI_CHECKED(CVSMetaDataAddToIntegerArray(handle_.Handle(), static_cast<CExports::CVSField>(fieldId),
369 static_cast<CExports::cvbint64_t>(e)));
370 }
371
372 void WriteFieldTyped(FieldID fieldId, const std::vector<double> &value)
373 {
374 CVB_CALL_CAPI_CHECKED(CVSMetaDataClearField(handle_.Handle(), static_cast<CExports::CVSField>(fieldId)));
375 for (auto e : value)
376 CVB_CALL_CAPI_CHECKED(CVSMetaDataAddToFloatArray(handle_.Handle(), static_cast<CExports::CVSField>(fieldId),
377 static_cast<double>(e)));
378 }
379
380 void WriteFieldTyped(FieldID fieldId, const std::vector<String> &value)
381 {
382 CVB_CALL_CAPI_CHECKED(CVSMetaDataClearField(handle_.Handle(), static_cast<CExports::CVSField>(fieldId)));
383 for (auto e : value)
384 CVB_CALL_CAPI_CHECKED(
385 CVSMetaDataAddToStringArrayTyped(handle_.Handle(), static_cast<CExports::CVSField>(fieldId), e.c_str()));
386 }
387
389
394 CExports::CVSFieldType CFieldType(FieldID fieldId) const
395 {
396 return Internal::DoResCallValueOut<CExports::CVSFieldType>([&](CExports::CVSFieldType &val) {
397 return CVB_CALL_CAPI(
398 CVSMetaDataGetFieldType(handle_.Handle(), static_cast<CExports::CVSField>(fieldId), val));
399 });
400 }
401
402 private:
403 HandleGuard<MetaData> handle_;
404 };
405 } // namespace Spectral
406
407 using Spectral::MetaData;
408
409 CVB_END_INLINE_NS
410
411} // namespace Cvb
Spectral MetaData object.
Definition meta_data.hpp:31
void ClearField(FieldID fieldId)
Clears the given field and sets the FieldType to FieldType::Invalid.
Definition meta_data.hpp:136
static std::unique_ptr< MetaData > FromHandle(HandleGuard< MetaData > &&guard)
Creates metadata from a classic API handle.
Definition meta_data.hpp:255
String FieldNameAsString(FieldID fieldId) const
Gets the field name as Cvb::String.
Definition meta_data.hpp:93
T ReadField(const FieldID &fieldId) const
Template function to get the value of the field.
Definition meta_data.hpp:57
bool IsFieldDefined(FieldID fieldId)
Checks if the given field is already defined.
Definition meta_data.hpp:150
void WriteField(FieldID fieldId, const T &value)
Template function to set the value of a given field.
Definition meta_data.hpp:81
CubeEncoding InterleavedType() const
Convenience function to access the value of field FieldID::Interleave.
Definition meta_data.hpp:198
Spectral::FieldType FieldType(FieldID fieldId) const
Gets the type of the given field.
Definition meta_data.hpp:111
int Bands() const
Convenience function to access the value of field FieldID::Bands.
Definition meta_data.hpp:187
int Samples() const
Convenience function to access the value of field FieldID::Samples.
Definition meta_data.hpp:165
std::vector< double > Wavelengths() const
Convenience function to access the value of field FieldID::Wavelength.
Definition meta_data.hpp:219
void * Handle() const noexcept
Returns C-API style handle to the metadata.
Definition meta_data.hpp:241
int NumberOfFields() const
Gets the total number of all fields.
Definition meta_data.hpp:123
int Lines() const
Convenience function to access the value of field FieldID::Lines.
Definition meta_data.hpp:176
static std::unique_ptr< MetaData > Create()
Creates an empty metadata object.
Definition meta_data.hpp:230
cvbbool_t ReleaseObject(OBJ &Object)
T move(T... args)
Namespace for the Spectral package.
Definition arithmetic.hpp:14
FieldID
FieldID enum class to access fields in the MetaData object.
Definition spectral.hpp:124
@ Bands
The number of bands.
Definition spectral.hpp:132
@ Lines
The number of lines.
Definition spectral.hpp:130
@ Wavelength
Array of wavelengths with the unit given in FieldID::WavelengthUnit.
Definition spectral.hpp:157
@ Interleave
Defines the way the spectral data of the buffer is ordered (CubeEncoding)
Definition spectral.hpp:126
@ Samples
The number of samples.
Definition spectral.hpp:128
FieldType
Data type of a field.
Definition spectral.hpp:183
@ String
Field contains string value.
Definition spectral.hpp:187
CubeEncoding
View Perspective: Defines how the mapping between a typical x-y image and samples-lines-bands is done...
Definition spectral.hpp:217
@ BandSequential
Definition spectral.hpp:223
@ BandInterleavedByPixel
Definition spectral.hpp:226
@ BandInterleavedByLine
Definition spectral.hpp:220
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17
char Char
Character type for wide characters or unicode characters.
Definition string.hpp:63
T transform(T... args)