10#ifndef MVE_IMAGE_HEADER
11#define MVE_IMAGE_HEADER
26template <
typename T>
class Image;
42 typedef std::shared_ptr<Image<T> >
Ptr;
43 typedef std::shared_ptr<Image<T>
const>
ConstPtr;
52 Image (int64_t width, int64_t height, int64_t channels);
58 static Ptr create (
void);
60 static Ptr create (int64_t width, int64_t height, int64_t channels);
65 Ptr duplicate (
void)
const;
68 void fill_color (T
const* color);
71 void add_channels (int64_t amount, T
const& value = T(0));
73 void swap_channels (int64_t c1, int64_t c2);
75 void copy_channel (int64_t src, int64_t dest);
77 void delete_channel (int64_t channel);
80 T
const& at (int64_t index)
const;
82 T
const& at (int64_t index, int64_t channel)
const;
84 T
const& at (int64_t x, int64_t y, int64_t channel)
const;
87 T& at (int64_t index);
89 T& at (int64_t index, int64_t channel);
91 T& at (int64_t x, int64_t y, int64_t channel);
94 T linear_at (
float x,
float y, int64_t channel)
const;
101 void linear_at (
float x,
float y, T* px)
const;
104 T& operator[] (int64_t index);
105 T
const& operator[] (int64_t index)
const;
107 T
const& operator() (int64_t index)
const;
108 T
const& operator() (int64_t index, int64_t channel)
const;
109 T
const& operator() (int64_t x, int64_t y, int64_t channel)
const;
110 T& operator() (int64_t index);
111 T& operator() (int64_t index, int64_t channel);
112 T& operator() (int64_t x, int64_t y, int64_t channel);
126create_for_type (
ImageType type, int64_t width, int64_t height, int64_t chans);
179 this->allocate(width, height, channels);
221 for (T* ptr = this->begin(); ptr != this->end(); ptr += this->c)
222 std::copy_n(color, this->c, ptr);
229 if (num_channels <= 0 || !this->valid())
232 std::vector<T> tmp(this->w * this->h * (this->c + num_channels));
233 typename std::vector<T>::iterator dest_ptr = tmp.end();
234 typename std::vector<T>::const_iterator src_ptr = this->data.end();
235 const int64_t pixels = this->get_pixel_amount();
236 for (int64_t p = 0; p < pixels; ++p)
238 for (int64_t i = 0; i < num_channels; ++i)
239 *(--dest_ptr) = value;
240 for (int64_t i = 0; i < this->c; ++i)
241 *(--dest_ptr) = *(--src_ptr);
244 this->c += num_channels;
252 if (!this->valid() || c1 == c2
253 || c1 >= this->channels() || c2 >= this->channels())
256 T* iter1 = &this->data[0] + c1;
257 T* iter2 = &this->data[0] + c2;
258 int64_t pixels = this->get_pixel_amount();
259 for (int64_t i = 0; i < pixels; ++i, iter1 += this->c, iter2 += this->c)
267 if (!this->valid() || src == dest)
272 dest = this->channels();
273 this->add_channels(1);
276 T
const* src_iter = &this->data[0] + src;
277 T* dst_iter = &this->data[0] + dest;
278 int64_t pixels = this->get_pixel_amount();
279 for (int64_t i = 0; i < pixels;
280 ++i, src_iter += this->c, dst_iter += this->c)
282 *dst_iter = *src_iter;
290 if (chan < 0 || chan >= this->channels())
293 typename std::vector<T>::iterator src_iter = this->data.begin();
294 typename std::vector<T>::iterator dst_iter = this->data.begin();
295 for (int64_t i = 0; src_iter != this->data.end(); ++i)
297 if (i % this->c == chan)
300 *(dst_iter++) = *(src_iter++);
302 this->resize(this->width(), this->height(), this->channels() - 1);
309 return this->data[index];
316 int64_t off = index * this->channels() + channel;
317 return this->data[off];
324 int64_t off = channel + this->channels() * (x + y * this->width());
325 return this->data[off];
332 return this->data[index];
339 int64_t off = index * this->channels() + channel;
340 return this->data[off];
347 int64_t off = channel + this->channels() * (x + y * this->width());
348 return this->data[off];
355 return this->data[index];
362 return this->data[index];
369 return this->at(index);
376 return this->at(index, channel);
383 return this->at(x, y, channel);
390 return this->at(index);
397 return this->at(index, channel);
404 return this->at(x, y, channel);
411 x = std::max(0.0f, std::min(
static_cast<float>(this->w - 1), x));
412 y = std::max(0.0f, std::min(
static_cast<float>(this->h - 1), y));
414 int64_t
const floor_x =
static_cast<int64_t
>(x);
415 int64_t
const floor_y =
static_cast<int64_t
>(y);
416 int64_t
const floor_xp1 = std::min(floor_x + 1, this->w - 1);
417 int64_t
const floor_yp1 = std::min(floor_y + 1, this->h - 1);
419 float const w1 = x -
static_cast<float>(floor_x);
420 float const w0 = 1.0f - w1;
421 float const w3 = y -
static_cast<float>(floor_y);
422 float const w2 = 1.0f - w3;
424 int64_t
const rowstride = this->w * this->c;
425 int64_t
const row1 = floor_y * rowstride;
426 int64_t
const row2 = floor_yp1 * rowstride;
427 int64_t
const col1 = floor_x * this->c;
428 int64_t
const col2 = floor_xp1 * this->c;
430 return math::interpolate<T>
431 (this->at(row1 + col1 + channel), this->at(row1 + col2 + channel),
432 this->at(row2 + col1 + channel), this->at(row2 + col2 + channel),
433 w0 * w2, w1 * w2, w0 * w3, w1 * w3);
440 x = std::max(0.0f, std::min(
static_cast<float>(this->w - 1), x));
441 y = std::max(0.0f, std::min(
static_cast<float>(this->h - 1), y));
443 int64_t
const floor_x =
static_cast<int64_t
>(x);
444 int64_t
const floor_y =
static_cast<int64_t
>(y);
445 int64_t
const floor_xp1 = std::min(floor_x + 1, this->w - 1);
446 int64_t
const floor_yp1 = std::min(floor_y + 1, this->h - 1);
448 float const w1 = x -
static_cast<float>(floor_x);
449 float const w0 = 1.0f - w1;
450 float const w3 = y -
static_cast<float>(floor_y);
451 float const w2 = 1.0f - w3;
453 int64_t
const rowstride = this->w * this->c;
454 int64_t
const row1 = floor_y * rowstride;
455 int64_t
const row2 = floor_yp1 * rowstride;
456 int64_t
const col1 = floor_x * this->c;
457 int64_t
const col2 = floor_xp1 * this->c;
460 for (int64_t cc = 0; cc < this->c; ++cc)
462 px[cc] = math::interpolate<T>
463 (this->at(row1 + col1 + cc), this->at(row1 + col2 + cc),
464 this->at(row2 + col1 + cc), this->at(row2 + col2 + cc),
465 w0 * w2, w1 * w2, w0 * w3, w1 * w3);
std::shared_ptr< ImageBase > Ptr
Multi-channel image class of arbitrary but homogenous data type.
std::shared_ptr< Image< T > > Ptr
std::shared_ptr< Image< T > const > ConstPtr
T const & at(int64_t index) const
Linear indexing of image data.
void swap_channels(int64_t c1, int64_t c2)
Swaps channels 'c1' and 'c2'.
T linear_at(float x, float y, int64_t channel) const
Linear interpolation (more expensive) for a single color channel.
void copy_channel(int64_t src, int64_t dest)
Copies channel from src to dest.
Ptr duplicate(void) const
Duplicates the image.
Image(void)=default
Default constructor creates an empty image.
std::vector< T > ImageData
void add_channels(int64_t amount, T const &value=T(0))
Adds 'amount' channels to the back with default value 'value'.
T & operator[](int64_t index)
static Ptr create(void)
Smart pointer image constructor.
T const & operator()(int64_t index) const
void fill_color(T const *color)
Fills every pixel of the image with the given color.
void delete_channel(int64_t channel)
Deletes a channel from the image.
Base class for images of arbitrary type.
void swap(TypedImageBase< T > &other)
Swaps the contents of the images.
#define MVE_IMAGE_NAMESPACE_END
#define MVE_NAMESPACE_BEGIN
#define MVE_IMAGE_NAMESPACE_BEGIN
#define STD_NAMESPACE_END
#define MVE_NAMESPACE_END
#define STD_NAMESPACE_BEGIN
ImageBase::Ptr create_for_type(ImageType type, int64_t width, int64_t height, int64_t chans)
Creates an image instance for a given type.
ImageType
Identifiers for image types.
void swap(mve::Image< T > &a, mve::Image< T > &b)
Specialization of std::swap for efficient image swapping.