BasicImage.h
1 /* Copyright (C) 2015 Marc Boris Duerner
2  Copyright (C) 2015 Laurentiu-Gheorghe Crisan
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  As a special exception, you may use this file as part of a free
10  software library without restriction. Specifically, if other files
11  instantiate templates or use macros or inline functions from this
12  file, or you compile this file and link it with other files to
13  produce an executable, this file does not by itself cause the
14  resulting executable to be covered by the GNU General Public
15  License. This exception does not however invalidate any other
16  reasons why the executable file might be covered by the GNU Library
17  General Public License.
18 
19  This library is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  Lesser General Public License for more details.
23 
24  You should have received a copy of the GNU Lesser General Public
25  License along with this library; if not, write to the Free Software
26  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
27  02110-1301 USA
28 */
29 
30 #ifndef PT_GFX_BASICIMAGE_H
31 #define PT_GFX_BASICIMAGE_H
32 
33 #include <Pt/Gfx/Api.h>
34 #include <Pt/Gfx/Size.h>
35 #include <Pt/Types.h>
36 #include <vector>
37 
38 namespace Pt {
39 
40 namespace Gfx {
41 
42 template <typename ModelT>
43 class BasicView
44 {
45  public:
46  typedef ModelT Model;
47  typedef typename ModelT::Pixel Pixel;
48  typedef typename ModelT::ConstPixel ConstPixel;
49 
50  class PixelIterator
51  {
52  public:
53  PixelIterator(BasicView& view, Pt::ssize_t x, Pt::ssize_t y)
54  : _pixel(view, x, y)
55  { }
56 
57  PixelIterator(const PixelIterator& it)
58  : _pixel(it._pixel)
59  {}
60 
61  PixelIterator& operator=(const PixelIterator& it)
62  {
63  _pixel.reset(it._pixel);
64  return *this;
65  }
66 
67  Pixel& operator*()
68  { return _pixel; }
69 
70  Pixel* operator->()
71  { return &_pixel; }
72 
73  PixelIterator& operator++()
74  {
75  _pixel.advance();
76  return *this;
77  }
78 
79  PixelIterator& operator+=(Pt::ssize_t n)
80  {
81  _pixel.advance(n);
82  return *this;
83  }
84 
85  bool operator!=(const PixelIterator& it) const
86  { return _pixel != it._pixel; }
87 
88  bool operator==(const PixelIterator& it) const
89  { return _pixel == it._pixel; }
90 
91  std::size_t pixelStride() const
92  { return Model::pixelStride(); }
93 
94  private:
95  Pixel _pixel;
96  };
97 
98  class ConstPixelIterator
99  {
100  public:
101  ConstPixelIterator(const BasicView& view, Pt::ssize_t x, Pt::ssize_t y)
102  : _pixel(view, x, y)
103  { }
104 
105  ConstPixelIterator(const ConstPixelIterator& it)
106  : _pixel(it._pixel)
107  {}
108 
109  ConstPixelIterator& operator=(const ConstPixelIterator& it)
110  {
111  _pixel.reset(it._pixel);
112  return *this;
113  }
114 
115  const ConstPixel& operator*() const
116  { return _pixel; }
117 
118  const ConstPixel* operator->() const
119  { return &_pixel; }
120 
121  ConstPixelIterator& operator++()
122  {
123  _pixel.advance();
124  return *this;
125  }
126 
127  ConstPixelIterator& operator+=(Pt::ssize_t n)
128  {
129  _pixel.advance(n);
130  return *this;
131  }
132 
133  bool operator!=(const ConstPixelIterator& it) const
134  { return _pixel != it._pixel; }
135 
136  bool operator==(const ConstPixelIterator& it) const
137  { return _pixel == it._pixel; }
138 
139  std::size_t pixelStride() const
140  { return Model::pixelStride(); }
141 
142  private:
143  ConstPixel _pixel;
144  };
145 
146  public:
147  BasicView(Pt::uint8_t* data, const Size& size, Pt::ssize_t padding = 0)
148  : _data(data)
149  , _size(size)
150  , _padding(padding)
151  , _stride(0)
152  {
153  _stride = (_size.width() * ModelT::pixelStride()) + _padding;
154  }
155 
158  PixelIterator pixel(Pt::ssize_t x, Pt::ssize_t y)
159  { return PixelIterator(*this, x, y); }
160 
163  PixelIterator begin()
164  { return PixelIterator(*this, 0, 0); }
165 
168  PixelIterator end()
169  { return PixelIterator(*this, 0, height()); }
170 
173  ConstPixelIterator pixel(Pt::ssize_t x, Pt::ssize_t y) const
174  { return ConstPixelIterator(*this, x, y); }
175 
178  ConstPixelIterator begin() const
179  { return PixelIterator(*this, 0, 0); }
180 
183  ConstPixelIterator end() const
184  { return PixelIterator(*this, 0, height()); }
185 
188  const Size& size() const
189  { return _size; }
190 
191  Pt::ssize_t width() const
192  { return _size.width(); }
193 
194  Pt::ssize_t height() const
195  { return _size.height(); }
196 
197  bool empty() const
198  { return _size.width() == 0 || _size.height() == 0; }
199 
200  Pt::uint8_t* data()
201  { return _data; }
202 
203  const Pt::uint8_t* data() const
204  { return _data; }
205 
206  Pt::ssize_t stride() const
207  { return _stride; }
208 
209  Pt::ssize_t padding() const
210  { return _padding; }
211 
212  std::size_t pixelStride() const
213  { return Model::pixelStride(); }
214 
215  private:
216  Pt::uint8_t* _data;
217  Size _size;
218  Pt::ssize_t _padding;
219  Pt::ssize_t _stride;
220 };
221 
222 
223 template <typename ModelT, typename ViewT = BasicView<ModelT> >
224 class BasicImage
225 {
226  public:
227  typedef ModelT Model;
228  typedef typename ModelT::Pixel Pixel;
229  typedef typename ModelT::ConstPixel ConstPixel;
230 
231  typedef ViewT View;
232  typedef typename View::PixelIterator PixelIterator;
233  typedef typename View::ConstPixelIterator ConstPixelIterator;
234 
235  public:
236  BasicImage(const Size& size, Pt::ssize_t padding = 0)
237  : _buffer( Model::imageSize(size, padding) )
238  , _view(_buffer.empty() ? 0 : &_buffer[0], size, padding)
239  { }
240 
241  BasicImage(Pt::uint8_t* data, const Size& size, Pt::ssize_t padding = 0)
242  : _view(data, size, padding)
243  { }
244 
245  virtual ~BasicImage()
246  {}
247 
250  PixelIterator pixel(Pt::ssize_t x, Pt::ssize_t y)
251  { return _view.pixel(x, y); }
252 
255  PixelIterator begin()
256  { return _view.begin(); }
257 
260  PixelIterator end()
261  { return _view.end(); }
262 
265  ConstPixelIterator pixel(Pt::ssize_t x, Pt::ssize_t y) const
266  { return _view.pixel(x, y); }
267 
270  ConstPixelIterator begin() const
271  { return _view.begin(); }
272 
275  ConstPixelIterator end() const
276  { return _view.end(); }
277 
280  const Size& size() const
281  { return _view.size(); }
282 
283  Pt::ssize_t width() const
284  { return _view.width(); }
285 
286  Pt::ssize_t height() const
287  { return _view.height(); }
288 
289  Pt::ssize_t padding() const
290  { return _view.padding(); }
291 
292  Pt::uint8_t* data()
293  { return _view.data(); }
294 
295  const Pt::uint8_t* data() const
296  { return _view.data(); }
297 
298  bool empty() const
299  { return _view.empty(); }
300 
301  const View& view() const
302  { return _view; }
303 
304  private:
305  std::vector<Pt::uint8_t> _buffer;
306  View _view;
307 };
308 
309 } // namespace
310 
311 } // namespace
312 
313 #endif
T width() const
Returns the width.
Definition: Size.h:65
uint_type uint8_t
Unsigned 8-bit integer type.
Definition: Types.h:18