farm-ng-core
mut_image.h
Go to the documentation of this file.
1 // Copyright (c) 2011, Hauke Strasdat
2 // Copyright (c) 2012, Steven Lovegrove
3 // Copyright (c) 2021, farm-ng, inc.
4 //
5 // Use of this source code is governed by an MIT-style
6 // license that can be found in the LICENSE file or at
7 // https://opensource.org/licenses/MIT.
8 
9 /// Image MutImage, owning images types.
10 ///
11 /// Note that it is a conscious API decision to follow "shallow-compare" type
12 /// semantic for ImageView, MutImageView, Image and MutImage. See image_view.h
13 /// for details.
14 #pragma once
15 
16 #include "sophus/common/enum.h"
18 
19 #include <optional>
20 
21 namespace sophus {
22 
23 // Types are largely inspired / derived from Pangolin.
24 
25 template <class TPixel, class TAllocator>
26 class Image;
27 
28 template <class TPredicate, class TAllocator>
29 class MutDynImage;
30 
31 template <class TAllocator>
33  UniqueDataAreaDeleter() = default;
34 
36  void operator()(uint8_t* p) const {
37  if (p != nullptr) {
38  TAllocator().deallocate(p, num_bytes);
39  }
40  }
41 
42  UniqueDataAreaDeleter(UniqueDataAreaDeleter const& other) = default;
43  auto operator=(UniqueDataAreaDeleter const&)
44  -> UniqueDataAreaDeleter& = default;
45 
46  size_t num_bytes = 0;
47 };
48 
49 static_assert(std::is_nothrow_move_constructible<
50  UniqueDataAreaDeleter<Eigen::aligned_allocator<uint8_t>>>());
51 
52 template <class TAllocator>
58 
60  MaybeLeakingUniqueDataAreaDeleter const& other) = default;
63 
64  void operator()(uint8_t* p) const {
65  if (image_deleter) {
66  (*image_deleter)(p);
67  }
68  }
69 
70  std::optional<UniqueDataAreaDeleter<TAllocator>> image_deleter;
71 };
72 
73 static_assert(
74  std::is_nothrow_move_constructible<MaybeLeakingUniqueDataAreaDeleter<
75  Eigen::aligned_allocator<uint8_t>>>());
76 
77 template <class TAllocator>
78 using UniqueDataArea =
79  std::unique_ptr<uint8_t, MaybeLeakingUniqueDataAreaDeleter<TAllocator>>;
80 
81 /// A image with write access to pixels and exclusive ownership. There is no
82 /// copy constr / copy assignment, but move constr / assignment.
83 ///
84 /// Content from a MutImage can be moved into an Image.
85 ///
86 /// Type is nullable. In that case `this->isEmpty()` is true.
87 ///
88 template <class TPixel, class TAllocator = Eigen::aligned_allocator<uint8_t>>
89 class MutImage : public MutImageView<TPixel> {
90  public:
91  template <class TT, class TAllocator2T>
92  friend class Image;
93 
94  template <class TPredicate, class TAllocator2T>
95  friend class MutDynImage;
96 
97  /// Constructs empty image.
98  MutImage() : unique_(nullptr) {}
99 
100  /// Creates new image with given layout.
101  ///
102  /// If layout is not empty, memory allocation will happen.
103  explicit MutImage(ImageLayout layout)
104  : MutImageView<TPixel>(layout, nullptr), unique_(nullptr) {
105  if (layout.sizeBytes() != 0u) {
106  SOPHUS_ASSERT_EQ(layout.sizeBytes() % sizeof(TPixel), 0);
108  TAllocator().allocate(layout.sizeBytes()),
111  }
112  this->ptr_ = reinterpret_cast<TPixel*>(this->unique_.get());
113  }
114 
115  /// Creates new contiguous image with given size.
116  ///
117  /// If layout is not empty, memory allocation will happen.
119  : MutImage(ImageLayout::makeFromSize<TPixel>(size)) {}
120 
121  /// Creates contiguous copy from view.
122  ///
123  /// If view is not empty, memory allocation will happen.
124  [[nodiscard]] static auto makeCopyFrom(ImageView<TPixel> const& view)
125  -> MutImage {
126  MutImage image(view.imageSize());
127  image.copyDataFrom(view);
128  return image;
129  }
130 
131  /// Creates new MutImage given view and unary transform function.
132  ///
133  /// mut_image(u, v) = unary_op(view(u, v));
134  template <class TOtherPixel, class TUnaryOperation>
135  static auto makeFromTransform(
136  ImageView<TOtherPixel> view, TUnaryOperation const& unary_op)
137  -> MutImage {
138  MutImage mut_image(view.imageSize());
139  mut_image.transformFrom(view, unary_op);
140  return mut_image;
141  }
142 
143  /// Creates new MutImage given two views and binary transform function.
144  ///
145  /// mut_image(u, v) = binary_op(lhs(u, v), rhs(u, v));
146  template <class TLhsPixel, class TRhsPixel, class TBinaryOperation>
147  static auto makeFromTransform(
150  TBinaryOperation const& binary_op) -> MutImage {
151  MutImage mut_image(lhs.imageSize());
152  mut_image.transformFrom(lhs, rhs, binary_op);
153  return mut_image;
154  }
155 
156  // Begin(Rule of 5):
157  // https://en.cppreference.com/w/cpp/language/rule_of_three
158 
159  /// Destructor
160  ~MutImage() { reset(); }
161 
162  /// Not copy constructable
163  MutImage(MutImage<TPixel> const& other) = delete;
164 
165  /// Not copy assignable
166  auto operator=(MutImage const&) -> MutImage& = delete;
167 
168  /// Nothrow move constructor.
169  MutImage(MutImage&& img) noexcept
170  : MutImageView<TPixel>(img.viewMut()), unique_(std::move(img.unique_)) {
171  this->ptr_ = reinterpret_cast<TPixel*>(unique_.get());
172  img.setViewToEmpty();
173  }
174 
175  /// Nothrow move assignment
176  auto operator=(MutImage&& img) noexcept -> MutImage& {
177  reset();
178  this->layout_ = img.layout_;
179  this->unique_ = std::move(img.unique_);
180  this->ptr_ = reinterpret_cast<TPixel*>(unique_.get());
181  img.setViewToEmpty();
182  return *this;
183  }
184  // End (Rule of 5)
185 
186  [[nodiscard]] auto viewMut() const -> MutImageView<TPixel> {
187  return MutImageView<TPixel>(this->layout(), this->ptrMut());
188  }
189 
190  /// Swaps img and this.
191  void swap(MutImage& img) {
192  std::swap(img.layout_, this->layout_);
193  std::swap(img.ptr_, this->ptr_);
194  std::swap(img.unique_, this->unique_);
195  }
196 
197  /// Clears image.
198  ///
199  /// If image was not empty, memory deallocations will happen.
200  void reset() {
201  unique_.reset();
202  this->setViewToEmpty();
203  }
204 
205  protected:
206  /// Leaks memory and returns deleter.
208  SOPHUS_ASSERT(!this->isEmpty());
210  *std::get_deleter<MaybeLeakingUniqueDataAreaDeleter<TAllocator>>(
211  unique_);
213  del.image_deleter.reset();
214  return del_copy;
215  }
216 
217  /// MutImage has unique ownership.
219 };
220 } // namespace sophus
sophus::MutImage::MutImage
MutImage(MutImage &&img) noexcept
Nothrow move constructor.
Definition: mut_image.h:169
sophus::MutDynImage
Definition: mut_dyn_image.h:23
sophus::MutImage::~MutImage
~MutImage()
Destructor.
Definition: mut_image.h:160
SOPHUS_ASSERT
#define SOPHUS_ASSERT(...)
Definition: common.h:40
sophus::UniqueDataAreaDeleter::num_bytes
size_t num_bytes
Definition: mut_image.h:46
sophus::Image
Image read-only access to pixels and shared ownership, hence cheap to copy. Type is nullable.
Definition: image.h:31
sophus::ImageLayout
Layout of the image: width, height and pitch in bytes.
Definition: layout.h:23
sophus
Image MutImage, owning images types.
Definition: num_diff.h:20
sophus::UniqueDataArea
std::unique_ptr< uint8_t, MaybeLeakingUniqueDataAreaDeleter< TAllocator > > UniqueDataArea
Definition: mut_image.h:79
sophus::ImageView
A view of an (immutable) image, which does not own the data.
Definition: image_view.h:55
sophus::MutImage::leakAndReturnDeleter
auto leakAndReturnDeleter() -> MaybeLeakingUniqueDataAreaDeleter< TAllocator >
Leaks memory and returns deleter.
Definition: mut_image.h:207
sophus::MutImage::swap
void swap(MutImage &img)
Swaps img and this.
Definition: mut_image.h:191
sophus::MutImage::makeFromTransform
static auto makeFromTransform(ImageView< TOtherPixel > view, TUnaryOperation const &unary_op) -> MutImage
Creates new MutImage given view and unary transform function.
Definition: mut_image.h:135
sophus::MaybeLeakingUniqueDataAreaDeleter
Definition: mut_image.h:53
sophus::MutImage::makeFromTransform
static auto makeFromTransform(ImageView< TLhsPixel > lhs, ImageView< TRhsPixel > rhs, TBinaryOperation const &binary_op) -> MutImage
Creates new MutImage given two views and binary transform function.
Definition: mut_image.h:147
sophus::MutImage::MutImage
MutImage(sophus::ImageSize size)
Creates new contiguous image with given size.
Definition: mut_image.h:118
sophus::MutImage::MutImage
MutImage()
Constructs empty image.
Definition: mut_image.h:98
sophus::MutImage::reset
void reset()
Clears image.
Definition: mut_image.h:200
sophus::MaybeLeakingUniqueDataAreaDeleter::image_deleter
std::optional< UniqueDataAreaDeleter< TAllocator > > image_deleter
Definition: mut_image.h:70
sophus::MutImage
A image with write access to pixels and exclusive ownership. There is no copy constr / copy assignmen...
Definition: image_view.h:32
sophus::UniqueDataAreaDeleter::UniqueDataAreaDeleter
UniqueDataAreaDeleter(size_t num_bytes)
Definition: mut_image.h:35
sophus::MutImage::unique_
UniqueDataArea< TAllocator > unique_
MutImage has unique ownership.
Definition: mut_image.h:218
sophus::MutImage::viewMut
auto viewMut() const -> MutImageView< TPixel >
Definition: mut_image.h:186
SOPHUS_ASSERT_EQ
#define SOPHUS_ASSERT_EQ(...)
Definition: common.h:41
sophus::UniqueDataAreaDeleter
Definition: mut_image.h:32
sophus::MaybeLeakingUniqueDataAreaDeleter::operator=
auto operator=(MaybeLeakingUniqueDataAreaDeleter const &) -> MaybeLeakingUniqueDataAreaDeleter &=default
sophus::MutImage::operator=
auto operator=(MutImage const &) -> MutImage &=delete
Not copy assignable.
sophus::MaybeLeakingUniqueDataAreaDeleter::MaybeLeakingUniqueDataAreaDeleter
MaybeLeakingUniqueDataAreaDeleter(UniqueDataAreaDeleter< TAllocator > image_deleter)
Definition: mut_image.h:55
sophus::MutImage::operator=
auto operator=(MutImage &&img) noexcept -> MutImage &
Nothrow move assignment.
Definition: mut_image.h:176
sophus::MutImage::makeCopyFrom
static auto makeCopyFrom(ImageView< TPixel > const &view) -> MutImage
Creates contiguous copy from view.
Definition: mut_image.h:124
sophus::UniqueDataAreaDeleter::operator=
auto operator=(UniqueDataAreaDeleter const &) -> UniqueDataAreaDeleter &=default
mut_image_view.h
sophus::UniqueDataAreaDeleter::operator()
void operator()(uint8_t *p) const
Definition: mut_image.h:36
sophus::MaybeLeakingUniqueDataAreaDeleter::operator()
void operator()(uint8_t *p) const
Definition: mut_image.h:64
sophus::MutImageView
View of a mutable image, which does not own the data.
Definition: mut_image_view.h:61
sophus::MaybeLeakingUniqueDataAreaDeleter::MaybeLeakingUniqueDataAreaDeleter
MaybeLeakingUniqueDataAreaDeleter()=default
enum.h
sophus::MutImage::MutImage
MutImage(ImageLayout layout)
Creates new image with given layout.
Definition: mut_image.h:103
sophus::ImageLayout::sizeBytes
auto sizeBytes() const -> size_t
Definition: layout.h:62
sophus::ImageSize
Image size, hence its width and height.
Definition: image_size.h:21
sophus::UniqueDataAreaDeleter::UniqueDataAreaDeleter
UniqueDataAreaDeleter()=default