PixelView.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,
26 MA 02110-1301 USA
27*/
28
29#ifndef PT_GFX_PIXEL_VIEW_H
30#define PT_GFX_PIXEL_VIEW_H
31
32#include <Pt/Gfx/Api.h>
33#include <Pt/Gfx/View.h>
34#include <Pt/Types.h>
35
36#include <iterator>
37#include <cstddef>
38
39namespace Pt {
40
41namespace Gfx {
42
43template <typename FormatT, typename TraitsT>
44class PixelIterator;
45
46template <typename FormatT, typename TraitsT>
47class ConstPixelIterator;
48
49
50template <typename FormatT, typename TraitsT>
51class PixelIterator
52{
53 template <typename F, typename T>
54 friend class ConstPixelIterator;
55
56 public:
57 typedef FormatT Format;
58 typedef TraitsT Traits;
59
60 typedef typename Traits::Pixel Pixel;
61 typedef typename Traits::ConstPixel ConstPixel;
62
63 typedef ConstPixelIterator<Format, Traits> ConstIterator;
64
65 public:
66 using iterator_category = std::forward_iterator_tag;
67 using value_type = Pixel;
68 using difference_type = std::ptrdiff_t;
69 using pointer = Pixel*;
70 using reference = Pixel&;
71
72 public:
73 template <typename T>
74 PixelIterator(T& view, Pt::ssize_t x, Pt::ssize_t y)
75 : _x(x)
76 , _y(y)
77 , _pixel(view, x, y)
78 { }
79
80 PixelIterator(const PixelIterator& it)
81 : _x(it._x)
82 , _y(it._y)
83 , _pixel(it._pixel)
84 { }
85
86 PixelIterator& operator=(const PixelIterator& it)
87 {
88 _pixel.reset(it._pixel);
89 _x = it._x;
90 _y = it._y;
91 return *this;
92 }
93
94 bool operator!=(const PixelIterator& it) const
95 { return ! _pixel.equals(it._pixel); }
96
97 bool operator!=(const ConstIterator& it) const
98 { return ! _pixel.equals(it._pixel); }
99
100 bool operator==(const PixelIterator& it) const
101 { return _pixel.equals(it._pixel); }
102
103 bool operator==(const ConstIterator& it) const
104 { return _pixel.equals(it._pixel); }
105
106 Pixel& operator*()
107 { return _pixel; }
108
109 Pixel* operator->()
110 { return &_pixel; }
111
112 PixelIterator& operator++()
113 {
114 _pixel.advance();
115
116 if( ++_x >= _pixel.view().width() )
117 {
118 _x = 0;
119 ++_y;
120
121 _pixel.skipPadding();
122 }
123
124 return *this;
125 }
126
127 PixelIterator& operator+=(Pt::ssize_t n)
128 {
129 Pt::ssize_t off = _x + n;
130 std::size_t dy = off / _pixel.view().width();
131 std::size_t dx = off % _pixel.view().width() - _x;
132
133 if(dy > 0)
134 {
135 _pixel.advanceLines(dy);
136 _y += dy;
137 }
138
139 _pixel.advance(dx);
140 _x += dx;
141
142 return *this;
143 }
144
145 private:
146 Pt::ssize_t _x;
147 Pt::ssize_t _y;
148 Pixel _pixel;
149};
150
151
152template <typename FormatT, typename TraitsT>
153class ConstPixelIterator
154{
155 template <typename F, typename T>
156 friend class PixelIterator;
157
158 public:
159 typedef FormatT Format;
160 typedef TraitsT Traits;
161
162 typedef typename Traits::Pixel Pixel;
163 typedef typename Traits::ConstPixel ConstPixel;
164
165 typedef PixelIterator<Format, Traits> Iterator;
166
167 public:
168 using iterator_category = std::forward_iterator_tag;
169 using value_type = ConstPixel;
170 using difference_type = std::ptrdiff_t;
171 using pointer = ConstPixel*;
172 using reference = ConstPixel&;
173
174 public:
175 template <typename T>
176 ConstPixelIterator(const T& view,
177 Pt::ssize_t x, Pt::ssize_t y)
178 : _x(x)
179 , _y(y)
180 , _pixel(view, x, y)
181 { }
182
183 template <typename T>
184 ConstPixelIterator(T& view,
185 Pt::ssize_t x, Pt::ssize_t y)
186 : _x(x)
187 , _y(y)
188 , _pixel(view, x, y)
189 { }
190
191 ConstPixelIterator(const ConstPixelIterator& it)
192 : _x(it._x)
193 , _y(it._y)
194 , _pixel(it._pixel)
195 { }
196
197 ConstPixelIterator& operator=(const ConstPixelIterator& it)
198 {
199 _pixel.reset(it._pixel);
200 _x = it._x;
201 _y = it._y;
202 return *this;
203 }
204
205 bool operator!=(const ConstPixelIterator& it) const
206 { return ! _pixel.equals(it._pixel); }
207
208 bool operator!=(const Iterator& it) const
209 { return ! _pixel.equals(it._pixel); }
210
211 bool operator==(const ConstPixelIterator& it) const
212 { return _pixel.equals(it._pixel); }
213
214 bool operator==(const Iterator& it) const
215 { return _pixel.equals(it._pixel); }
216
217 const ConstPixel& operator*() const
218 { return _pixel; }
219
220 const ConstPixel* operator->() const
221 { return &_pixel; }
222
223 ConstPixelIterator& operator++()
224 {
225 _pixel.advance();
226
227 if( ++_x >= _pixel.view().width() )
228 {
229 _x = 0;
230 ++_y;
231
232 _pixel.skipPadding();
233 }
234
235 return *this;
236 }
237
238 ConstPixelIterator& operator+=(Pt::ssize_t n)
239 {
240 Pt::ssize_t off = _x + n;
241 std::size_t dy = off / _pixel.view().width();
242 std::size_t dx = off % _pixel.view().width() - _x;
243
244 if(dy > 0)
245 {
246 _pixel.advanceLines(dy);
247 _y += dy;
248 }
249
250 _pixel.advance(dx);
251 _x += dx;
252
253 return *this;
254 }
255
256 private:
257 Pt::ssize_t _x;
258 Pt::ssize_t _y;
259 ConstPixel _pixel;
260};
261
262
263template <typename FormatT, typename TraitsT>
264class BasicPixelView
265{
266 public:
267 typedef FormatT Format;
268 typedef TraitsT Traits;
269
270 typedef typename Traits::Pixel Pixel;
271 typedef typename Traits::ConstPixel ConstPixel;
272
273 typedef PixelIterator<Format, Traits> Iterator;
274
275 public:
276 explicit BasicPixelView( const Format& format = FormatT::get() );
277
278 BasicPixelView(Pt::uint8_t* data, Pt::ssize_t width, Pt::ssize_t height,
279 Pt::ssize_t padding = 0, const Format& format = FormatT::get());
280
281 template <typename T>
282 explicit BasicPixelView(T& source);
283
284 template <typename T>
285 BasicPixelView(T& source, Int x, Int y, Int w, Int h);
286
287 BasicPixelView& operator=(const BasicPixelView&) = default;
288
289 Pt::uint8_t* data()
290 { return _view.data(); }
291
292 const Pt::uint8_t* data() const
293 { return _view.data(); }
294
295 Pt::ssize_t width() const
296 { return _view.width(); }
297
298 Pt::ssize_t height() const
299 { return _view.height(); }
300
301 Pt::ssize_t stride() const
302 { return _view.stride(); }
303
304 const Format& format() const
305 { return _view.format(); }
306
307 Pt::ssize_t pixelStride() const
308 { return _view.pixelStride(); }
309
310 Pt::ssize_t padding() const
311 { return _view.padding(); }
312
313 Iterator pixel(Pt::ssize_t x, Pt::ssize_t y)
314 { return Iterator(_view, x, y); }
315
316 Iterator begin()
317 { return Iterator(_view, 0, 0); }
318
319 Iterator end()
320 { return Iterator(_view, 0, _view.height()); }
321
322 private:
323 BasicView<Format, Traits> _view;
324};
325
326
327template <typename FormatT, typename TraitsT>
328class BasicConstPixelView
329{
330 public:
331 typedef FormatT Format;
332 typedef TraitsT Traits;
333
334 typedef typename Traits::Pixel Pixel;
335 typedef typename Traits::ConstPixel ConstPixel;
336
337 typedef ConstPixelIterator<Format, Traits> Iterator;
338
339 public:
340 explicit BasicConstPixelView( const Format& format = FormatT::get() );
341
342 BasicConstPixelView(const Pt::uint8_t* data, Pt::ssize_t width, Pt::ssize_t height,
343 Pt::ssize_t padding, const Format& format = FormatT::get());
344
345 template <typename T>
346 explicit BasicConstPixelView(const T& source);
347
348 template <typename T>
349 BasicConstPixelView(const T& source, Int x, Int y, Int w, Int h);
350
351 BasicConstPixelView& operator=(const BasicConstPixelView&) = default;
352
353 const Pt::uint8_t* data() const
354 { return _view.data(); }
355
356 Pt::ssize_t width() const
357 { return _view.width(); }
358
359 Pt::ssize_t height() const
360 { return _view.height(); }
361
362 Pt::ssize_t stride() const
363 { return _view.stride(); }
364
365 const Format& format() const
366 { return _view.format(); }
367
368 Pt::ssize_t pixelStride() const
369 { return _view.pixelStride(); }
370
371 Pt::ssize_t padding() const
372 { return _view.padding(); }
373
374 Iterator pixel(Pt::ssize_t x, Pt::ssize_t y) const
375 { return Iterator(_view, x, y); }
376
377 Iterator begin() const
378 { return Iterator(_view, 0, 0); }
379
380 Iterator end() const
381 { return Iterator(_view, 0, _view.height()); }
382
383 private:
384 BasicConstView<Format, Traits> _view;
385};
386
387
388template <typename T>
389BasicPixelView<typename T::Format,
390 typename T::Traits> pixelView(T& source)
391{
392 return BasicPixelView<typename T::Format, typename T::Traits>(source);
393}
394
395template <typename T>
396BasicConstPixelView<typename T::Format,
397 typename T::Traits> pixelView(const T& source)
398{
399 return BasicConstPixelView<typename T::Format, typename T::Traits>(source);
400}
401
402
403template <typename T>
404BasicPixelView<typename T::Format,
405 typename T::Traits> pixelView(T& source, Int x, Int y, Int w, Int h)
406{
407 return BasicPixelView<typename T::Format, typename T::Traits>(source, x, y, w, h);
408}
409
410
411template <typename T>
412BasicConstPixelView<typename T::Format,
413 typename T::Traits> pixelView(const T& source, Int x, Int y, Int w, Int h)
414{
415 return BasicConstPixelView<typename T::Format, typename T::Traits>(source, x, y, w, h);
416}
417
418
419template <typename FormatT, typename TraitsT = ImageTraits<FormatT> >
420BasicPixelView<FormatT,
421 TraitsT> pixelView(Pt::uint8_t* data, Pt::ssize_t width,
422 Pt::ssize_t height, Pt::ssize_t padding = 0)
423{
424 return BasicPixelView<FormatT, TraitsT>(data, width, height, padding, FormatT::get());
425}
426
427
428template <typename FormatT, typename TraitsT = ImageTraits<FormatT> >
429BasicConstPixelView<FormatT,
430 TraitsT> pixelView(const Pt::uint8_t* data, Pt::ssize_t width,
431 Pt::ssize_t height, Pt::ssize_t padding = 0)
432{
433 return BasicConstPixelView<FormatT, TraitsT>(data, width, height, padding, FormatT::get());
434}
435
436
437template <typename T>
438BasicPixelView<typename T::Format,
439 ImageTraitsF> pixelViewF(T& source)
440{
441 return BasicPixelView<typename T::Format, ImageTraitsF>(source);
442}
443
444
445template <typename T>
446BasicConstPixelView<typename T::Format,
447 ImageTraitsF> pixelViewF(const T& source)
448{
449 return BasicConstPixelView<typename T::Format, ImageTraitsF>(source);
450}
451
452
453template <typename T>
454BasicPixelView<typename T::Format,
455 ImageTraitsF> pixelViewF(T& source, Int x, Int y, Int w, Int h)
456{
457 return BasicPixelView<typename T::Format, ImageTraitsF>(source, x, y, w, h);
458}
459
460
461template <typename T>
462BasicConstPixelView<typename T::Format,
463 ImageTraitsF> pixelViewF(const T& source, Int x, Int y, Int w, Int h)
464{
465 return BasicConstPixelView<typename T::Format, ImageTraitsF>(source, x, y, w, h);
466}
467
468
469inline PixelViewF pixelViewF(Pt::uint8_t* data, Pt::ssize_t width,
470 Pt::ssize_t height, Pt::ssize_t padding,
471 const ImageFormat& format)
472{
473 return PixelViewF(data, width, height, padding, format);
474}
475
476
477inline ConstPixelViewF pixelViewF(const Pt::uint8_t* data, Pt::ssize_t width,
478 Pt::ssize_t height, Pt::ssize_t padding,
479 const ImageFormat& format)
480{
481 return ConstPixelViewF(data, width, height, padding, format);
482}
483
484} // namespace
485
486} // namespace
487
488#endif
489
490#include <Pt/Gfx/PixelView.hpp>
Runtime pixel format.
Definition ImageFormat.h:72
uint_type uint8_t
Unsigned 8-bit integer type.
Definition Api-Types.h:24
Graphics and imaging services.
Definition Api-Argb32Image.h:12
Core module.
Definition Allocator.h:33