Do not expect exact load timing. Hopefull makes buildbot results more stable (see...
[gnash.git] / libbase / ImageIterators.h
blob15290c526d504031d8caaea5ec7f65c61530e4a1
1 // ImageIterators.h: Specialized iterators for image data.
2 //
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
4 // Foundation, Inc
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #ifndef GNASH_IMAGE_ITERATORS_H
23 #define GNASH_IMAGE_ITERATORS_H
25 #include <boost/iterator/iterator_facade.hpp>
26 #include <iterator>
27 #include <algorithm>
29 #include "GnashImage.h"
31 namespace gnash {
32 namespace image {
34 /// Adapt a pixel_iterator to use 32-bit values in ARGB byte order.
35 class ARGB
37 public:
39 typedef GnashImage::iterator iterator;
41 /// Construct an ARGB pixel helper
42 ARGB(iterator& i, ImageType t)
44 _it(i),
45 _t(t)
48 /// Standard assignment just copies bytes.
50 /// Underlying bytes are really in RGBA order, so we use that.
51 const ARGB& operator=(const ARGB& other) const {
52 switch (_t) {
53 case TYPE_RGBA:
54 // RGBA to RGBA
55 if (other._t == TYPE_RGBA) {
56 std::copy(other._it, other._it + 4, _it);
57 break;
60 // RGB to RGBA
61 std::copy(other._it, other._it + 3, _it);
62 *(_it + 3) = 0xff;
63 break;
65 case TYPE_RGB:
66 // It doesn't matter what the other image is.
67 std::copy(other._it, other._it + 3, _it);
69 default:
70 break;
72 return *this;
75 /// Writes a 32-bit unsigned value in ARGB byte order to the image
77 /// Take note of the different byte order!
78 const ARGB& operator=(boost::uint32_t pixel) const {
79 switch (_t) {
80 case TYPE_RGBA:
81 // alpha
82 *(_it + 3) = (pixel & 0xff000000) >> 24;
83 case TYPE_RGB:
84 *_it = (pixel & 0x00ff0000) >> 16;
85 *(_it + 1) = (pixel & 0x0000ff00) >> 8;
86 *(_it + 2) = (pixel & 0x000000ff);
87 default:
88 break;
90 return *this;
93 /// Convert to uint32_t in ARGB order
94 operator boost::uint32_t() const {
95 boost::uint32_t ret = 0xff000000;
96 switch (_t) {
97 case TYPE_RGBA:
98 // alpha
99 ret = *(_it + 3) << 24;
100 case TYPE_RGB:
101 ret |= (*_it << 16 | *(_it + 1) << 8 | *(_it + 2));
102 default:
103 break;
105 return ret;
108 private:
109 iterator& _it;
110 const ImageType _t;
114 /// The pixel_iterator class is a pixel-level adaptor for a GnashImage
116 /// Instead of iterating byte-by-byte, this iterator provides access at a
117 /// whole-pixel level. This makes it possible to assign custom colour values.
119 /// @tparam Pixel A class that determines the byte order of the colour
120 /// value.
121 template<typename Pixel>
122 struct pixel_iterator : public boost::iterator_facade<
123 pixel_iterator<Pixel>,
124 const Pixel,
125 std::random_access_iterator_tag>
128 typedef std::ptrdiff_t difference_type;
129 typedef typename Pixel::iterator iterator;
131 /// Construct a pixel_iterator
132 pixel_iterator(iterator it, ImageType t)
134 _it(it),
135 _t(t),
136 _p(_it, _t)
139 /// Copy a pixel_iterator
140 pixel_iterator(const pixel_iterator& other)
142 _it(other._it),
143 _t(other._t),
144 _p(_it, _t)
147 /// Assign to a pixel_iterator
148 pixel_iterator& operator=(const pixel_iterator& other)
150 _it = other._it;
151 _t = other._t;
152 _p = Pixel(_it, _t);
153 return *this;
156 private:
158 friend class boost::iterator_core_access;
160 const Pixel& dereference() const {
161 return _p;
164 void increment() {
165 _it += numChannels(_t);
168 void decrement() {
169 _it -= numChannels(_t);
172 bool equal(const pixel_iterator& o) const {
173 return o._it == _it;
176 difference_type distance_to(const pixel_iterator& o) const {
177 return (o._it - _it) / static_cast<int>(numChannels(_t));
180 void advance(difference_type n) {
181 _it += n * numChannels(_t);
184 iterator _it;
185 ImageType _t;
186 Pixel _p;
189 template<typename T>
190 pixel_iterator<T>
191 begin(GnashImage& im)
193 return pixel_iterator<T>(im.begin(), im.type());
196 template<typename T>
197 pixel_iterator<T>
198 end(GnashImage& im)
200 return pixel_iterator<T>(im.end(), im.type());
203 } // namespace image
204 } // namespace gnash
206 #endif