hyperion.ng/include/utils/Image.h
2020-08-08 13:09:15 +02:00

210 lines
3.6 KiB
C++

#pragma once
#include <QSharedDataPointer>
#include <utils/ImageData.h>
template <typename Pixel_T>
class Image
{
public:
typedef Pixel_T pixel_type;
Image() :
Image(1, 1, Pixel_T())
{
}
Image(unsigned width, unsigned height) :
Image(width, height, Pixel_T())
{
}
///
/// Constructor for an image with specified width and height
///
/// @param width The width of the image
/// @param height The height of the image
/// @param background The color of the image
///
Image(unsigned width, unsigned height, const Pixel_T background) :
_d_ptr(new ImageData<Pixel_T>(width, height, background))
{
}
///
/// Copy constructor for an image
/// @param other The image which will be copied
///
Image(const Image & other)
{
_d_ptr = other._d_ptr;
}
Image& operator=(Image rhs)
{
// Define assignment operator in terms of the copy constructor
// More to read: https://stackoverflow.com/questions/255612/dynamically-allocating-an-array-of-objects?answertab=active#tab-top
_d_ptr = rhs._d_ptr;
return *this;
}
void swap(Image& s)
{
std::swap(this->_d_ptr, s._d_ptr);
}
Image(Image&& src) noexcept
{
std::swap(this->_d_ptr, src._d_ptr);
}
Image& operator=(Image&& src) noexcept
{
src.swap(*this);
return *this;
}
///
/// Destructor
///
~Image()
{
}
///
/// Returns the width of the image
///
/// @return The width of the image
///
inline unsigned width() const
{
return _d_ptr->width();
}
///
/// Returns the height of the image
///
/// @return The height of the image
///
inline unsigned height() const
{
return _d_ptr->height();
}
uint8_t red(unsigned pixel) const
{
return _d_ptr->red(pixel);
}
uint8_t green(unsigned pixel) const
{
return _d_ptr->green(pixel);
}
///
/// Returns a const reference to a specified pixel in the image
///
/// @param x The x index
/// @param y The y index
///
/// @return const reference to specified pixel
///
uint8_t blue(unsigned pixel) const
{
return _d_ptr->blue(pixel);
}
///
/// Returns a reference to a specified pixel in the image
///
/// @param x The x index
/// @param y The y index
const Pixel_T& operator()(unsigned x, unsigned y) const
{
return _d_ptr->operator()(x, y);
}
///
/// @return reference to specified pixel
///
Pixel_T& operator()(unsigned x, unsigned y)
{
return _d_ptr->operator()(x, y);
}
/// Resize the image
/// @param width The width of the image
/// @param height The height of the image
void resize(unsigned width, unsigned height)
{
_d_ptr->resize(width, height);
}
///
/// Returns a memory pointer to the first pixel in the image
/// @return The memory pointer to the first pixel
///
Pixel_T* memptr()
{
return _d_ptr->memptr();
}
///
/// Returns a const memory pointer to the first pixel in the image
/// @return The const memory pointer to the first pixel
///
const Pixel_T* memptr() const
{
return _d_ptr->memptr();
}
///
/// Convert image of any color order to a RGB image.
///
/// @param[out] image The image that buffers the output
///
void toRgb(Image<ColorRgb>& image) const
{
_d_ptr->toRgb(*image._d_ptr);
}
///
/// Get size of buffer
///
ssize_t size() const
{
return _d_ptr->size();
}
///
/// Clear the image
///
void clear()
{
_d_ptr->clear();
}
private:
template<class T>
friend class Image;
///
/// Translate x and y coordinate to index of the underlying vector
///
/// @param x The x index
/// @param y The y index
///
/// @return The index into the underlying data-vector
///
inline unsigned toIndex(unsigned x, unsigned y) const
{
return _d_ptr->toIndex(x, y);
}
private:
QSharedDataPointer<ImageData<Pixel_T>> _d_ptr;
};