cube.hpp
1 #pragma once
2 
3 #include "meta_data.hpp"
4 #include "../data_type.hpp"
5 #include "cube_range.hpp"
6 #include "../_cexports/c_spectral.h"
7 #include "spectral.hpp"
8 #include "../image.hpp"
9 #include "linear_access_data.hpp"
10 
11 namespace Cvb
12 {
13  CVB_BEGIN_INLINE_NS
14 
15  template <>
16  inline HandleGuard<Spectral::Cube>::HandleGuard(void * handle) noexcept
17  : HandleGuard<Spectral::Cube>(handle, [](void* handle) { CVB_CALL_CAPI(ReleaseObject(handle)); })
18  {
19  }
20 
21  namespace Spectral
22  {
23 
49 
50  class Cube
51  {
52  public:
53  virtual ~Cube() {}; //virtual destructor to make this class polymorphic! --> dynamic_cast
54 
56 
66  static std::unique_ptr<Cube> Create(int numSamples, int numLines, int numBands,
68  {
69  return Internal::DoResCallObjectOut<Cube>([&](void* & cubeOut)
70  {
71  return CVB_CALL_CAPI(CVSCreateContinuousCube(numSamples, numLines, numBands,
72  dataType.NativeDescriptor(), static_cast<CExports::CVSCubeEncoding>(bufferLayout),
73  cubeOut));
74  });
75  }
76 
77 
79 
87  {
88  return Internal::DoResCallObjectOut<Cube>([&](void* & cubeOut)
89  {
90  return CVB_CALL_CAPI(CVSCreateDuplicatedContinuousCube(handle_.Handle(),
91  cubeOut));
92  });
93  }
94 
95 
97 
107  {
109  for (auto pImg : images)
110  imgArr.push_back(pImg->Handle());
111  return Internal::DoResCallObjectOut<Cube>([&](void* & cubeOut)
112  {
113  return CVB_CALL_CAPI(CVSCreateStackedCube(imgArr.data(),
114  imgArr.size(), static_cast<CExports::CVSCubeEncoding>(bufferLayout),
115  cubeOut));
116  });
117  }
118 
119 
121 
126  CubeType Type() const
127  {
128  CExports::CVSCubeType cType = Internal::DoResCallValueOut<CExports::CVSCubeType>([&](CExports::CVSCubeType& val)
129  {
130  return CVB_CALL_CAPI(CVSCubeGetType(handle_.Handle(), val));
131  });
132  return static_cast<CubeType>(cType);
133  }
134 
135 
137 
145  class DataType DataType() const
146  {
147  CExports::cvbdatatype_t cType =
148  Internal::DoResCallValueOut<CExports::cvbdatatype_t>([&](CExports::cvbdatatype_t& val)
149  {
150  return CVB_CALL_CAPI(CVSCubeGetDatatype(handle_.Handle(), val));
151  });
153  }
154 
155 
157 
173  {
174  bool mapTarget = !(this->Type() == CubeType::StackedCube);
175  return Internal::DoResCallObjectOut<Cube>([&](void* & obj)
176  {
177  return CVB_CALL_CAPI(CVSCreateTransposedCube(handle_.Handle(),
178  static_cast<CExports::CVSCubeEncoding>(targetView),
179  static_cast<CExports::cvbbool_t>(mapTarget),
180  obj));
181  });
182  }
183 
184 
186 
202  {
203  bool mapTarget = !(this->Type() == CubeType::StackedCube);
204  CExports::CVSCuboid cCuboid;
205  cCuboid.Samples = { static_cast<CExports::cvbdim_t>(spectralCubeoid.Samples().Min()), static_cast<CExports::cvbdim_t>(spectralCubeoid.Samples().Max()) };
206  cCuboid.Lines = { static_cast<CExports::cvbdim_t>(spectralCubeoid.Lines().Min()), static_cast<CExports::cvbdim_t>(spectralCubeoid.Lines().Max()) };
207  cCuboid.Bands = { static_cast<CExports::cvbdim_t>(spectralCubeoid.Bands().Min()), static_cast<CExports::cvbdim_t>(spectralCubeoid.Bands().Max()) };
208  return Internal::DoResCallObjectOut<Cube>([&](void* & obj)
209  {
210  return CVB_CALL_CAPI(CVSCreateCroppedCube(handle_.Handle(),
211  cCuboid,
212  static_cast<CExports::cvbbool_t>(mapTarget),
213  obj));
214  });
215  }
216 
217 
219 
231  {
232  return Internal::DoResCallObjectOut<Image>([&](void* & obj)
233  {
234  return CVB_CALL_CAPI(CVSCubeGetBufferView(handle_.Handle(),
235  obj));
236  });
237  }
238 
239 
241 
250  {
251  return Internal::DoResCallObjectOut<Spectral::MetaData>([&](void* & obj)
252  {
253  return CVB_CALL_CAPI(CVSCubeGetMetaData(handle_.Handle(),
254  obj));
255  });
256  }
257 
258 
260 
266  bool TryLinearAccess(LinearAccessData& linearAccessOut) const noexcept
267  {
268  void* pBase = nullptr;
269  intptr_t sampleInc = 0, lineInc = 0, bandInc = 0;
270  auto code = CExports::MakeErrorCode(CVB_CALL_CAPI(CVSCubeGetLinearAccess(handle_.Handle(), pBase, sampleInc, lineInc, bandInc)));
271  if (code < 0)
272  return false;
273  linearAccessOut = Spectral::LinearAccessData(reinterpret_cast<uintptr_t>(pBase), sampleInc, lineInc, bandInc);
274  return true;
275  }
276 
277 
279 
285  {
286  LinearAccessData linAcc_;
287  if (!TryLinearAccess(linAcc_))
288  Utilities::SystemInfo::ThrowLastError(static_cast<CExports::cvbres_t>(CExports::CVC_E_ERROR));
289  return linAcc_;
290  }
291 
292 
294 
301  template<typename T>
302  std::vector<T> SpectralDensity(int sampleIndex, int lineIndex) const
303  {
304  std::vector<T> tmpSpecDens;
305  SpectralDensity(sampleIndex, lineIndex, tmpSpecDens);
306  return tmpSpecDens;
307  }
308 
310 
317  static std::unique_ptr<Cube> Load(Cvb::String EnviHeader, Cvb::String EnviBinary)
318  {
319  return Internal::DoResCallObjectOut<Cube>([&](void* & cubeOut)
320  {
321  return CVB_CALL_CAPI(CVSLoadEnviFileTyped(
322  EnviHeader.c_str(), EnviBinary.c_str(),
323  cubeOut));
324  });
325  }
326 
328 
334  void Save(Cvb::String EnviHeader, Cvb::String EnviBinary) const
335  {
336  CVB_CALL_CAPI_CHECKED(CVSWriteEnviFileTyped(
337  handle_.Handle(),
338  EnviHeader.c_str(), EnviBinary.c_str()));
339  }
340 
342 
353  {
354  return Internal::DoResCallObjectOut<Cube>([&](void* & cubeOut)
355  {
356  return CVB_CALL_CAPI(CVSCubeSwapSamplesAndLines(handle_.Handle(), cubeOut));
357  });
358  }
359 
360 
361 
363 
366  void* Handle() const noexcept
367  {
368  return handle_.Handle();
369  }
370 
371 
373 
381  static std::unique_ptr<Cube> FromHandle(HandleGuard<Cube>&& guard)
382  {
383  if (!guard.Handle())
384  throw std::runtime_error("handle must not be null");
385  return std::unique_ptr<Cube>(new Cube(std::move(guard)));
386  }
387 
388 
389  protected:
390 
391 
392  Cube(HandleGuard<Cube>&& guard) noexcept
393  : handle_(std::move(guard))
394  {
395  }
396 
397  Cube(Cube && other) noexcept
398  : handle_(std::move(other.handle_))
399  {
400  }
401 
402  Cube & operator=(Cube && other) = default;
403 
404 
406 
415  bool TryBufferView(ImagePtr& bufferViewOut) const noexcept
416  {
417  CExports::IMG objH = nullptr;
418  if (CExports::MakeErrorCode(CVB_CALL_CAPI(CVSCubeGetBufferView(handle_.Handle(), objH))) < 0)
419  return false;
420  bufferViewOut = Image::FromHandle(HandleGuard<Image>(objH));
421  return true;
422  }
423 
424 
426 
431  bool TryMetaData(MetaDataPtr& metaDataOut) const noexcept
432  {
433  CExports::CVSMETADATA objH = nullptr;
434  if (CExports::MakeErrorCode(CVB_CALL_CAPI(CVSCubeGetMetaData(handle_.Handle(), objH))) < 0)
435  return false;
436  metaDataOut = MetaData::FromHandle(HandleGuard<Spectral::MetaData>(objH));
437  return true;
438  }
439 
440 
441  private:
442 
443 
444  void SpectralDensity(int sampleIndex, int lineIndex, std::vector<int>& specDens) const noexcept
445  {
446  size_t sz = 0;
447  CVB_CALL_CAPI_CHECKED(CVSCubeGetSpectrumAsInteger(handle_.Handle(), sampleIndex, lineIndex,
448  reinterpret_cast<CExports::cvbval_t*>(0), sz));
450  CVB_CALL_CAPI_CHECKED(CVSCubeGetSpectrumAsInteger(handle_.Handle(), sampleIndex, lineIndex,
451  tmpBuff.data(), sz));
452  // convert int64_t to int
453  std::vector<int> tmpSpecDens(sz);
454  for (auto e : tmpBuff)
455  tmpSpecDens.push_back(static_cast<int>(e));
456  specDens = tmpSpecDens;
457  }
458 
459  void SpectralDensity(int sampleIndex, int lineIndex, std::vector<double>& specDens) const noexcept
460  {
461  size_t sz = 0;
462  CVB_CALL_CAPI_CHECKED(CVSCubeGetSpectrumAsDouble(handle_.Handle(), sampleIndex, lineIndex,
463  reinterpret_cast<double*>(0), sz));
464  std::vector<double> tmpBuff(sz);
465  CVB_CALL_CAPI_CHECKED(CVSCubeGetSpectrumAsDouble(handle_.Handle(), sampleIndex, lineIndex,
466  tmpBuff.data(), sz));
467  specDens = tmpBuff;
468  }
469 
470  private:
471 
472  HandleGuard<Cube> handle_;
473  };
474 
475  }
476 
477  using Spectral::Cube;
478 
479  CVB_END_INLINE_NS
480 }
std::unique_ptr< Cube > Transpose(CubeEncoding targetView) const
Creates a transposed cube.
Definition: cube.hpp:172
CubeEncoding
View Perspective: Defines how the mapping between a typical x-y image and samples-lines-bands is done...
Definition: spectral.hpp:210
void * Handle() const noexcept
Returns C-API style handle to the Cube.
Definition: cube.hpp:366
Stacked Cube with potentially non-linear buffer.
ValueRange< int > Samples() const noexcept
Gets the range regarding the samples dimension.
Definition: cube_range.hpp:55
T Min() const noexcept
Gets the minimum value.
Definition: value_range.hpp:50
T Max() const noexcept
Gets the maximum value.
Definition: value_range.hpp:72
CubeType
Defines the type of the cube.
Definition: spectral.hpp:224
int NativeDescriptor() const noexcept
Native data type descriptor.
Definition: data_type.hpp:322
std::vector< T > SpectralDensity(int sampleIndex, int lineIndex) const
Retrieves spectral density at given pixel.
Definition: cube.hpp:302
static std::unique_ptr< Cube > FromHandle(HandleGuard< Cube > &&guard)
Creates cube from a classic API handle.
Definition: cube.hpp:381
static std::unique_ptr< Cube > FromImages(const std::vector< ImagePtr > &images, CubeEncoding bufferLayout)
Initializes a stacked cube using an array of images.
Definition: cube.hpp:106
Cvb::ImagePtr BufferView() const
Retrieves the buffer view of the cube.
Definition: cube.hpp:230
STL class.
Spectral Cube object.
Definition: cube.hpp:50
Root namespace for the Image Manager interface.
Definition: version.hpp:11
bool TryBufferView(ImagePtr &bufferViewOut) const noexcept
Retrieves the buffer view of the cube without throwing an exception.
Definition: cube.hpp:415
Linear access properties.
Definition: linear_access_data.hpp:20
static std::unique_ptr< MetaData > FromHandle(HandleGuard< MetaData > &&guard)
Creates metadata from a classic API handle.
Definition: meta_data.hpp:267
void Save(Cvb::String EnviHeader, Cvb::String EnviBinary) const
Writes this cube object to ENVI-format.
Definition: cube.hpp:334
static std::unique_ptr< Image > FromHandle(HandleGuard< Image > &&guard)
Creates an image from a classic API handle.
Definition: decl_image.hpp:153
bool TryLinearAccess(LinearAccessData &linearAccessOut) const noexcept
Retrieve linear access of cube data without throwing an exception.
Definition: cube.hpp:266
std::unique_ptr< Cube > SwapSamplesAndLines() const
Swaps the dimensions for samples and lines and returns a deep copy.
Definition: cube.hpp:352
STL class.
STL class.
static DataType FromNativeDescriptor(int dataTypeDescriptor) noexcept
Construct a data type descriptor from one of the native library's descriptor values.
Definition: data_type.hpp:37
Data type description for an image plane.
Definition: data_type.hpp:27
std::unique_ptr< Cube > Clone()
Copies the memory to a new instance of a cube.
Definition: cube.hpp:86
static std::unique_ptr< Cube > Load(Cvb::String EnviHeader, Cvb::String EnviBinary)
Static function Loads a cube from ENVI.
Definition: cube.hpp:317
3D rectangle in the samples, lines and bands domain.
Definition: cube_range.hpp:23
static std::unique_ptr< Cube > Create(int numSamples, int numLines, int numBands, DataType dataType, CubeEncoding bufferLayout=CubeEncoding::BandInterleavedByLine)
Creates a Continuous Cube object.
Definition: cube.hpp:66
std::unique_ptr< Cube > Map(CubeRange spectralCubeoid)
Creates a cropped cube.
Definition: cube.hpp:201
bool TryMetaData(MetaDataPtr &metaDataOut) const noexcept
Retrieves the meta data object of the cube without throwing an exception.
Definition: cube.hpp:431
MetaDataPtr MetaData() const
Retrieves the meta data object of the cube.
Definition: cube.hpp:249
ValueRange< int > Bands() const noexcept
Gets the range regarding bands dimension.
Definition: cube_range.hpp:101
CubeType Type() const
Retrieves the type of this cube object.
Definition: cube.hpp:126
ValueRange< int > Lines() const noexcept
Gets the range regarding lines dimension.
Definition: cube_range.hpp:78
LinearAccessData LinearAccess() const
Retrieve linear access of cube data.
Definition: cube.hpp:284