ImageView.h
1 /* Copyright (C) 2015 Marc Boris Duerner
2 
3  This library is free software; you can redistribute it and/or
4  modify it under the terms of the GNU Lesser General Public
5  License as published by the Free Software Foundation; either
6  version 2.1 of the License, or (at your option) any later version.
7 
8  As a special exception, you may use this file as part of a free
9  software library without restriction. Specifically, if other files
10  instantiate templates or use macros or inline functions from this
11  file, or you compile this file and link it with other files to
12  produce an executable, this file does not by itself cause the
13  resulting executable to be covered by the GNU General Public
14  License. This exception does not however invalidate any other
15  reasons why the executable file might be covered by the GNU Library
16  General Public License.
17 
18  This library is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  Lesser General Public License for more details.
22 
23  You should have received a copy of the GNU Lesser General Public
24  License along with this library; if not, write to the Free Software
25  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26  02110-1301 USA
27 */
28 
29 #ifndef PT_GFX_IMAGEVIEW_H
30 #define PT_GFX_IMAGEVIEW_H
31 
32 #include <Pt/Gfx/Api.h>
33 #include <Pt/Gfx/Size.h>
34 #include <Pt/Gfx/Color.h>
35 #include <Pt/Gfx/ImageFormat.h>
36 #include <Pt/Gfx/CompositionMode.h>
37 #include <Pt/Types.h>
38 
39 namespace Pt {
40 namespace Gfx {
41 
42 
43 class ImageView;
44 
45 
48 class Pixel
49 {
50  public:
51  Pixel(ImageView& view, Pt::ssize_t x, Pt::ssize_t y);
52 
53  Pixel(const Pixel& p)
54  : _view(p._view)
55  , _base(p._base)
56  , _x(p._x)
57  , _y(p._y)
58  { }
59 
60  Pixel& operator=(const Pixel& p)
61  {
62  assign(p, CompositionMode::SourceCopy);
63  return *this;
64  }
65 
66  Pixel& operator=(const ConstPixel& p)
67  {
68  assign(p, CompositionMode::SourceCopy);
69  return *this;
70  }
71 
72  Pixel& operator=(const Color& color)
73  {
74  assign(color, CompositionMode::SourceCopy);
75  return *this;
76  }
77 
78  void reset(ImageView& view, Pt::ssize_t x, Pt::ssize_t y);
79 
80  void reset(const Pixel& p)
81  {
82  _view = p._view;
83  _base = p._base;
84  _x = p._x;
85  _y = p._y;
86  }
87 
88  void advance();
89 
90  void advance( Pt::ssize_t n );
91 
92  void assign(const Color& color, CompositionMode mode);
93 
94  void assign(const Pixel& p, CompositionMode mode)
95  {
96  assign(p.toColor(), mode);
97  }
98 
99  void assign(const ConstPixel& p, CompositionMode mode);
100 
101  Color toColor() const;
102 
103  ImageView& view() const
104  { return *_view; }
105 
106  Pt::ssize_t x() const
107  { return _x; }
108 
109  Pt::ssize_t y() const
110  { return _y; }
111 
112  Pt::uint8_t* base()
113  { return _base; }
114 
115  const Pt::uint8_t* base() const
116  { return _base; }
117 
118  bool operator!=(const Pixel& p) const
119  { return _base != p._base; }
120 
121  bool operator==(const Pixel& p) const
122  { return _base == p._base; }
123 
124  std::size_t pixelStride() const;
125 
126  private:
127  ImageView* _view;
128  Pt::uint8_t* _base;
129  Pt::ssize_t _x;
130  Pt::ssize_t _y;
131 };
132 
136 {
137  public:
138  ConstPixel(const ImageView& view, Pt::ssize_t x, Pt::ssize_t y);
139 
140  ConstPixel(const ConstPixel& p)
141  : _view(p._view)
142  , _base(p._base)
143  , _x(p._x)
144  , _y(p._y)
145  { }
146 
147  void reset(const ImageView& view, Pt::ssize_t x, Pt::ssize_t y);
148 
149  void reset(const ConstPixel& p)
150  {
151  _view = p._view;
152  _base = p._base;
153  _x = p._x;
154  _y = p._y;
155  }
156 
157  void advance();
158 
159  void advance( Pt::ssize_t n );
160 
161  Color toColor() const;
162 
163  const ImageView& view() const
164  { return *_view; }
165 
166  Pt::ssize_t x() const
167  { return _x; }
168 
169  Pt::ssize_t y() const
170  { return _y; }
171 
172  const Pt::uint8_t* base() const
173  { return _base; }
174 
175  bool operator!=(const ConstPixel& p) const
176  { return _base != p._base; }
177 
178  bool operator==(const ConstPixel& p) const
179  { return _base == p._base; }
180 
181  std::size_t pixelStride() const;
182 
183  private:
184  const ImageView* _view;
185  const Pt::uint8_t* _base;
186  Pt::ssize_t _x;
187  Pt::ssize_t _y;
188 };
189 
193 {
194  public:
195  typedef Gfx::Pixel Pixel;
196  typedef Gfx::ConstPixel ConstPixel;
197 
198  class PixelIterator
199  {
200  public:
201  PixelIterator(ImageView& image, Pt::ssize_t x, Pt::ssize_t y)
202  : _pixel(image, x, y)
203  {}
204 
205  PixelIterator(const PixelIterator& it)
206  : _pixel(it._pixel)
207  {}
208 
209  PixelIterator& operator=(const PixelIterator& it)
210  {
211  _pixel.reset(it._pixel);
212  return *this;
213  }
214 
215  bool operator!=(const PixelIterator& it) const
216  { return _pixel != it._pixel; }
217 
218  bool operator==(const PixelIterator& it) const
219  { return _pixel == it._pixel; }
220 
221  Pixel& operator*()
222  { return _pixel; }
223 
224  Pixel* operator->()
225  { return &_pixel; }
226 
227  PixelIterator& operator++()
228  {
229  _pixel.advance();
230  return *this;
231  }
232 
233  PixelIterator& operator+=(Pt::ssize_t n)
234  {
235  _pixel.advance(n);
236  return *this;
237  }
238 
239  std::size_t pixelStride() const
240  { return _pixel.pixelStride(); }
241 
242  private:
243  Pixel _pixel;
244  };
245 
246  class ConstPixelIterator
247  {
248  public:
249  ConstPixelIterator(const ImageView& image, Pt::ssize_t x, Pt::ssize_t y)
250  : _pixel(image, x, y)
251  {}
252 
253  ConstPixelIterator(const ConstPixelIterator& it)
254  : _pixel(it._pixel)
255  {}
256 
257  ConstPixelIterator& operator=(const ConstPixelIterator& it)
258  {
259  _pixel.reset(it._pixel);
260  return *this;
261  }
262 
263  bool operator!=(const ConstPixelIterator& it) const
264  { return _pixel != it._pixel; }
265 
266  bool operator==(const ConstPixelIterator& it) const
267  { return _pixel == it._pixel; }
268 
269  const ConstPixel& operator*()
270  { return _pixel; }
271 
272  const ConstPixel* operator->() const
273  { return &_pixel; }
274 
275  ConstPixelIterator& operator++()
276  {
277  _pixel.advance();
278  return *this;
279  }
280 
281  ConstPixelIterator& operator+=(Pt::ssize_t n)
282  {
283  _pixel.advance(n);
284  return *this;
285  }
286 
287  std::size_t pixelStride() const
288  { return _pixel.pixelStride(); }
289 
290  private:
291  ConstPixel _pixel;
292  };
293 
294  public:
295  ImageView()
296  : _format( &ImageFormat::argb32() )
297  , _data(0)
298  , _size(0, 0)
299  , _padding(0)
300  , _stride(0)
301  { }
302 
303  explicit ImageView(const ImageFormat& format)
304  : _format(&format)
305  , _data(0)
306  , _size()
307  , _padding(0)
308  , _stride(0)
309  { }
310 
311  ImageView(const ImageFormat& format, Pt::uint8_t* data,
312  const Size& size, Pt::ssize_t padding)
313  : _format(&format)
314  , _data(data)
315  , _size(size)
316  , _padding(padding)
317  {
318  _stride = (_size.width() * _format->pixelStride()) + _padding;
319  }
320 
321  virtual ~ImageView()
322  {}
323 
324  void reset(const ImageFormat& format, Pt::uint8_t* data,
325  const Size& size, Pt::ssize_t padding)
326  {
327  _format = &format;
328  _data = data;
329  _size = size;
330  _padding = padding;
331  _stride = (_size.width() * _format->pixelStride()) + _padding;
332  }
333 
334  PixelIterator pixel(Pt::ssize_t x, Pt::ssize_t y)
335  { return PixelIterator(*this, x, y); }
336 
337  PixelIterator begin()
338  { return PixelIterator(*this, 0, 0); }
339 
340  PixelIterator end()
341  { return PixelIterator(*this, 0, height()); }
342 
343  ConstPixelIterator pixel(Pt::ssize_t x, Pt::ssize_t y) const
344  { return ConstPixelIterator(*this, x, y); }
345 
346  ConstPixelIterator begin() const
347  { return ConstPixelIterator(*this, 0, 0); }
348 
349  ConstPixelIterator end() const
350  { return ConstPixelIterator(*this, 0, height()); }
351 
352  const ImageFormat& format() const
353  { return *_format; }
354 
355  const Size& size() const
356  { return _size; }
357 
358  Pt::ssize_t width() const
359  { return _size.width(); }
360 
361  Pt::ssize_t height() const
362  { return _size.height(); }
363 
364  bool empty() const
365  { return _size.width() == 0 || _size.height() == 0; }
366 
367  Pt::uint8_t* data()
368  { return _data; }
369 
370  const Pt::uint8_t* data() const
371  { return _data; }
372 
373  std::size_t pixelStride() const
374  { return _format->pixelStride(); }
375 
376  Pt::ssize_t stride() const
377  { return _stride; }
378 
379  Pt::ssize_t padding() const
380  { return _padding; }
381 
382  private:
383  const ImageFormat* _format;
384 
385  Pt::uint8_t* _data;
386  Size _size;
387  Pt::ssize_t _padding;
388  Pt::ssize_t _stride;
389 };
390 
391 
393 // Pixel Implementation
395 
396 inline Pixel::Pixel(ImageView& view, Pt::ssize_t x, Pt::ssize_t y)
397 : _view(&view)
398 , _x(x)
399 , _y(y)
400 {
401  _base = view.data() + view.stride() * y + x * view.pixelStride();
402 }
403 
404 
405 inline void Pixel::reset(ImageView& view, Pt::ssize_t x, Pt::ssize_t y)
406 {
407  _view = &view;
408  _x = x;
409  _y = y;
410 
411  _base = view.data() + view.stride() * _y + _x * view.pixelStride();
412 }
413 
414 
415 inline void Pixel::advance()
416 {
417  if( ++_x >= _view->width() )
418  {
419  _x = 0;
420  ++_y;
421 
422  _base += _view->padding();
423  }
424 
425  _base += _view->pixelStride();
426 }
427 
428 
429 inline void Pixel::advance(Pt::ssize_t n)
430 {
431  Pt::ssize_t off = _x + n;
432  _y += off / _view->width();
433  _x = off % _view->width();
434 
435  _base = _view->data() + _view->stride() * _y + _x * _view->pixelStride();
436 }
437 
438 
439 inline void Pixel::assign(const Color& color, CompositionMode mode)
440 {
441  _view->format().setPixel(*this, color, mode);
442 }
443 
444 
445 inline void Pixel::assign(const ConstPixel& p, CompositionMode mode)
446 {
447  assign(p.toColor(), mode);
448 }
449 
450 
451 inline Color Pixel::toColor() const
452 {
453  return _view->format().getColor(*this);
454 }
455 
456 
457 inline std::size_t Pixel::pixelStride() const
458 {
459  return _view->pixelStride();
460 }
461 
462 
464 // ConstPixel Implementation
466 
467 inline ConstPixel::ConstPixel(const ImageView& view, Pt::ssize_t x, Pt::ssize_t y)
468 : _view(&view)
469 , _x(x)
470 , _y(y)
471 {
472  _base = view.data() + view.stride() * y + x * view.pixelStride();
473 }
474 
475 
476 inline void ConstPixel::reset(const ImageView& view, Pt::ssize_t x, Pt::ssize_t y)
477 {
478  _view = &view;
479  _x = x;
480  _y = y;
481 
482  _base = view.data() + view.stride() * _y + _x * view.pixelStride();
483 }
484 
485 
486 inline void ConstPixel::advance()
487 {
488  if( ++_x >= _view->width() )
489  {
490  _x = 0;
491  ++_y;
492 
493  _base += _view->padding();
494  }
495 
496  _base += _view->pixelStride();
497 }
498 
499 
500 inline void ConstPixel::advance(Pt::ssize_t n)
501 {
502  Pt::ssize_t off = _x + n;
503  _y += off / _view->width();
504  _x += off % _view->width();
505 
506  _base = _view->data() + _view->stride() * _y + _x * _view->pixelStride();
507 }
508 
509 
510 inline Color ConstPixel::toColor() const
511 {
512  return _view->format().getColor(*this);
513 }
514 
515 
516 inline std::size_t ConstPixel::pixelStride() const
517 {
518  return _view->pixelStride();
519 }
520 
521 
522 } // namespace
523 } // namespace
524 
525 #endif
T width() const
Returns the width.
Definition: Size.h:65
std::size_t pixelStride() const
Returns distance in bytes between two pixel base pointers.
Definition: ImageFormat.h:61
Color getColor(const Pixel &pixel) const
Gets the pixel color.
Definition: ImageFormat.h:139
View on image data.
Definition: ImageView.h:192
Pixel in an image.
Definition: ImageView.h:48
T height() const
Returns the height.
Definition: Size.h:69
Const pixel in an image.
Definition: ImageView.h:135
void setPixel(Pixel &to, const Pixel &from, CompositionMode mode) const
Sets the pixel color.
Definition: ImageFormat.h:85
Image format.
Definition: ImageFormat.h:49
uint_type uint8_t
Unsigned 8-bit integer type.
Definition: Types.h:18