hyperion.ng
Image.h
1 #pragma once
2 
3 // STL includes
4 #include <vector>
5 #include <cstdint>
6 #include <cstring>
7 #include <algorithm>
8 #include <cassert>
9 #include <utils/ColorRgb.h>
10 
11 
12 template <typename Pixel_T>
13 class Image
14 {
15 public:
16 
17  typedef Pixel_T pixel_type;
18 
22  Image() :
23  _width(1),
24  _height(1),
25  _pixels(new Pixel_T[2]),
26  _endOfPixels(_pixels + 1)
27  {
28  memset(_pixels, 0, 2*sizeof(Pixel_T));
29  }
30 
37  Image(const unsigned width, const unsigned height) :
38  _width(width),
39  _height(height),
40  _pixels(new Pixel_T[width * height + 1]),
41  _endOfPixels(_pixels + width * height)
42  {
43  memset(_pixels, 0, (_width*_height+1)*sizeof(Pixel_T));
44  }
45 
53  Image(const unsigned width, const unsigned height, const Pixel_T background) :
54  _width(width),
55  _height(height),
56  _pixels(new Pixel_T[width * height + 1]),
57  _endOfPixels(_pixels + width * height)
58  {
59  std::fill(_pixels, _endOfPixels, background);
60  }
61 
65  Image(const Image & other) :
66  _width(other._width),
67  _height(other._height),
68  _pixels(new Pixel_T[other._width * other._height + 1]),
69  _endOfPixels(_pixels + other._width * other._height)
70  {
71  memcpy(_pixels, other._pixels, (long) other._width * other._height * sizeof(Pixel_T));
72  }
73 
74  // Define assignment operator in terms of the copy constructor
75  // More to read: https://stackoverflow.com/questions/255612/dynamically-allocating-an-array-of-objects?answertab=active#tab-top
76  Image& operator=(Image rhs)
77  {
78  rhs.swap(*this);
79  return *this;
80  }
81 
82  void swap(Image& s) noexcept
83  {
84  using std::swap;
85  swap(this->_width, s._width);
86  swap(this->_height, s._height);
87  swap(this->_pixels, s._pixels);
88  swap(this->_endOfPixels, s._endOfPixels);
89  }
90 
91  // C++11
92  Image(Image&& src) noexcept
93  : _width(0)
94  , _height(0)
95  , _pixels(NULL)
96  , _endOfPixels(NULL)
97  {
98  src.swap(*this);
99  }
100  Image& operator=(Image&& src) noexcept
101  {
102  src.swap(*this);
103  return *this;
104  }
105 
110  {
111  delete[] _pixels;
112  }
113 
119  inline unsigned width() const
120  {
121  return _width;
122  }
123 
129  inline unsigned height() const
130  {
131  return _height;
132  }
133 
134  uint8_t red(const unsigned pixel) const
135  {
136  return (_pixels + pixel)->red;
137  }
138 
139  uint8_t green(const unsigned pixel) const
140  {
141  return (_pixels + pixel)->green;
142  }
143 
144  uint8_t blue(const unsigned pixel) const
145  {
146  return (_pixels + pixel)->blue;
147  }
148 
157  const Pixel_T& operator()(const unsigned x, const unsigned y) const
158  {
159  return _pixels[toIndex(x,y)];
160  }
161 
170  Pixel_T& operator()(const unsigned x, const unsigned y)
171  {
172  return _pixels[toIndex(x,y)];
173  }
174 
178  void resize(const unsigned width, const unsigned height)
179  {
180  if ((width*height) > unsigned((_endOfPixels-_pixels)))
181  {
182  delete[] _pixels;
183  _pixels = new Pixel_T[width*height + 1];
184  _endOfPixels = _pixels + width*height;
185  }
186 
187  _width = width;
188  _height = height;
189  }
190 
196  void copy(const Image<Pixel_T>& other)
197  {
198  assert(other._width == _width);
199  assert(other._height == _height);
200 
201  memcpy(_pixels, other._pixels, _width*_height*sizeof(Pixel_T));
202  }
203 
208  Pixel_T* memptr()
209  {
210  return _pixels;
211  }
212 
217  const Pixel_T* memptr() const
218  {
219  return _pixels;
220  }
221 
222 
228  void toRgb(Image<ColorRgb>& image)
229  {
230  image.resize(_width, _height);
231  const unsigned imageSize = _width * _height;
232 
233  for (unsigned idx=0; idx<imageSize; idx++)
234  {
235  const Pixel_T color = memptr()[idx];
236  image.memptr()[idx] = ColorRgb{color.red, color.green, color.blue};
237  }
238  }
239 
242  //
243  ssize_t size() const
244  {
245  return (ssize_t) _width * _height * sizeof(Pixel_T);
246  }
247 
248 private:
249 
258  inline unsigned toIndex(const unsigned x, const unsigned y) const
259  {
260  return y*_width + x;
261  }
262 
263 private:
265  unsigned _width;
267  unsigned _height;
268 
270  Pixel_T* _pixels;
271 
273  Pixel_T* _endOfPixels;
274 };
const Pixel_T & operator()(const unsigned x, const unsigned y) const
Returns a const reference to a specified pixel in the image.
Definition: Image.h:157
unsigned height() const
Returns the height of the image.
Definition: Image.h:129
Image(const unsigned width, const unsigned height, const Pixel_T background)
Constructor for an image with specified width and height.
Definition: Image.h:53
unsigned width() const
Returns the width of the image.
Definition: Image.h:119
ssize_t size() const
get size of buffer
Definition: Image.h:243
Pixel_T * memptr()
Returns a memory pointer to the first pixel in the image.
Definition: Image.h:208
Image()
Default constructor for an image.
Definition: Image.h:22
Image(const unsigned width, const unsigned height)
Constructor for an image with specified width and height.
Definition: Image.h:37
~Image()
Destructor.
Definition: Image.h:109
void resize(const unsigned width, const unsigned height)
Resize the image.
Definition: Image.h:178
void copy(const Image< Pixel_T > &other)
Copies another image into this image.
Definition: Image.h:196
Pixel_T & operator()(const unsigned x, const unsigned y)
Returns a reference to a specified pixel in the image.
Definition: Image.h:170
Image(const Image &other)
Copy constructor for an image.
Definition: Image.h:65
void toRgb(Image< ColorRgb > &image)
Convert image of any color order to a RGB image.
Definition: Image.h:228
Definition: Image.h:13
const Pixel_T * memptr() const
Returns a const memory pointer to the first pixel in the image.
Definition: Image.h:217
uint8_t red
The red color channel.
Definition: ColorRgb.h:16
Plain-Old-Data structure containing the red-green-blue color specification.
Definition: ColorRgb.h:13