LibraryLink Utilities  3.0.1
Modern C++ wrapper over LibraryLink and WSTP
Image.h
Go to the documentation of this file.
1 
9 #ifndef LLU_CONTAINERS_IMAGE_H_
10 #define LLU_CONTAINERS_IMAGE_H_
11 
12 #include <array>
13 
16 
17 namespace LLU {
18 
25  template<typename T>
26  class TypedImage : public MArray<T> {
27  public:
28  using MArray<T>::MArray;
29 
37  T get(mint row, mint col, mint channel) const {
38  std::array<mint, 2> pos {{row, col}};
39  return getValueAt(pos.data(), channel);
40  }
41 
50  T get(mint slice, mint row, mint col, mint channel) const {
51  std::array<mint, 3> pos {{slice, row, col}};
52  return getValueAt(pos.data(), channel);
53  }
54 
63  void set(mint row, mint col, mint channel, T newValue) {
64  std::array<mint, 2> pos {{row, col}};
65  setValueAt(pos.data(), channel, newValue);
66  }
67 
77  void set(mint slice, mint row, mint col, mint channel, T newValue) {
78  std::array<mint, 3> pos {{slice, row, col}};
79  setValueAt(pos.data(), channel, newValue);
80  }
81 
82  private:
88  T* getData() const noexcept override {
89  return static_cast<T*>(LibraryData::ImageAPI()->MImage_getRawData(this->getInternal()));
90  }
91 
93  virtual MImage getInternal() const = 0;
94 
96  [[noreturn]] void indexError() const {
98  }
99 
106  T getValueAt(mint* pos, mint channel) const;
107 
114  void setValueAt(mint* pos, mint channel, T newValue);
115  };
116 
126  template<typename T>
127  class Image : public TypedImage<T>, public GenericImage {
128  public:
137  Image(mint w, mint h, mint channels, colorspace_t cs, bool interleavingQ);
138 
149  Image(mint nFrames, mint w, mint h, mint channels, colorspace_t cs, bool interleavingQ);
150 
156  explicit Image(GenericImage im);
157 
165  Image(MImage mi, Ownership owner) : Image(GenericImage(mi, owner)) {};
166 
168  Image() = default;
169 
175  Image clone() const;
176 
183  template<typename U>
184  Image<U> convert(bool interleaved) const;
185 
191  template<typename U>
192  Image<U> convert() const;
193 
194  private:
195  using GenericBase = GenericImage;
196 
198  MImage getInternal() const noexcept override {
199  return this->getContainer();
200  }
201 
203  [[noreturn]] static void sizeError() {
205  }
206 
212  static MArrayDimensions dimensionsFromGenericImage(const GenericBase& im);
213  };
214 
215  template<typename T>
216  Image<T>::Image(mint w, mint h, mint channels, colorspace_t cs, bool interleavingQ) : Image(0, w, h, channels, cs, interleavingQ) {}
217 
218  template<typename T>
219  Image<T>::Image(GenericBase im) : TypedImage<T>(dimensionsFromGenericImage(im)), GenericBase(std::move(im)) {
220  if (ImageType<T> != GenericBase::type()) {
222  }
223  }
224 
225  template<typename T>
226  Image<T>::Image(mint nFrames, mint w, mint h, mint channels, colorspace_t cs, bool interleavingQ)
227  : Image(GenericBase {nFrames, w, h, channels, ImageType<T>, cs, interleavingQ}) {}
228 
229  template<typename T>
231  return Image {cloneContainer(), Ownership::Library};
232  }
233 
234  template<typename T>
235  template<typename U>
236  Image<U> Image<T>::convert(bool interleaved) const {
237  return Image<U> {GenericImage::convert(ImageType<U>, interleaved)};
238  }
239 
240  template<typename T>
241  template<typename U>
243  return convert<U>(interleavedQ());
244  }
245 
246  template<typename T>
248  std::vector<mint> dims;
249  if (!im.getContainer()) {
250  return MArrayDimensions {dims};
251  }
252  mint depth = im.getRank() + (im.channels() == 1 ? 0 : 1);
253  if (im.is3D()) {
254  dims = {im.slices(), im.rows(), im.columns()};
255  } else {
256  dims = {im.rows(), im.columns()};
257  }
258  if (im.channels() > 1) {
259  if (im.interleavedQ()) {
260  dims.push_back(im.channels());
261  } else {
262  dims.insert(dims.begin(), im.channels());
263  }
264  }
265  if (dims.size() != static_cast<std::make_unsigned_t<mint>>(depth)) {
266  sizeError();
267  }
268  return MArrayDimensions {dims};
269  }
270 } /* namespace LLU */
271 
272 #endif /* LLU_CONTAINERS_IMAGE_H_ */
LLU::TypedImage::set
void set(mint row, mint col, mint channel, T newValue)
Set channel value at specified position in 2D image.
Definition: Image.h:63
LLU::TypedImage::set
void set(mint slice, mint row, mint col, mint channel, T newValue)
Set channel value at specified position in 3D image.
Definition: Image.h:77
LLU::Image::Image
Image()=default
Default constructor - creates an empty wrapper.
LLU::GenericImage
MContainer< MArgumentType::Image > GenericImage
MContainer specialization for MImage is called GenericImage.
Definition: Generic/Image.hpp:17
LLU
Main namespace of LibraryLink Utilities.
Definition: Queue.h:13
LLU::Image
This is a class template, where template parameter T is the type of data elements....
Definition: Image.h:127
LLU::TypedImage::get
T get(mint slice, mint row, mint col, mint channel) const
Get channel value at specified position in 3D image.
Definition: Image.h:50
LLU::MContainer< MArgumentType::Image >::type
imagedata_t type() const override
Get the data type of the image.
Definition: Generic/Image.hpp:134
LLU::ErrorName::ImageTypeError
const std::string ImageTypeError
Image type mismatch.
LLU::MArrayDimensions
Helper class that carries meta-information about container's size and dimensions.
Definition: MArrayDimensions.h:23
LLU::ErrorName::ImageIndexError
const std::string ImageIndexError
trying to access non-existing element
LLU::MContainer< MArgumentType::Image >
MContainer specialization for MImage.
Definition: Generic/Image.hpp:23
LLU::Image::convert
Image< U > convert() const
Copy this image with type conversion and other properties (dimensions, interleaving,...
Definition: Image.h:242
LLU::MArray
This is a class template, where template parameter T is the type of data elements....
Definition: MArray.hpp:36
Image.hpp
GenericImage definition and implementation.
LLU::Ownership::Library
@ Library
The library (LLU) is responsible for managing the container's memory. Used for Manual passing and con...
LLU::TypedImage
Typed interface for Image.
Definition: Image.h:26
MArray.hpp
Template base class for C++ wrappers of LibraryLink containers.
LLU::LibraryData::ImageAPI
static const st_WolframImageLibrary_Functions * ImageAPI()
Get a pointer to structure with function pointers to MImage API.
Definition: LibraryData.cpp:41
LLU::MContainerBase< MArgumentType::Image >::getContainer
Container getContainer() const noexcept
Get internal container.
Definition: Base.hpp:97
LLU::TypedImage::get
T get(mint row, mint col, mint channel) const
Get channel value at specified position in 2D image.
Definition: Image.h:37
LLU::MContainer< MArgumentType::Image >::channels
mint channels() const override
Get number of channels.
Definition: Generic/Image.hpp:104
LLU::ErrorManager::throwException
static void throwException(const std::string &errorName, T &&... args)
Throw exception with given name.
Definition: ErrorManager.h:199
LLU::MContainer< MArgumentType::Image >::convert
GenericImage convert(imagedata_t t, mbool interleavingQ) const
Convert this object to a new GenericImage of given datatype, optionally changing interleaving.
Definition: Image.cpp:27
LLU::ErrorName::ImageSizeError
const std::string ImageSizeError
wrong assumption about Image size
LLU::Image::Image
Image(MImage mi, Ownership owner)
Constructs Image based on MImage.
Definition: Image.h:165
LLU::Image::clone
Image clone() const
Clone this Image, performing a deep copy of the underlying MImage.
Definition: Image.h:230
LLU::Ownership
Ownership
An enum listing possible owners of a LibraryLink container.
Definition: Base.hpp:22