Gnash
0.8.10
|
00001 // ImageIterators.h: Specialized iterators for image data. 00002 // 00003 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 00004 // Free Software Foundation, Inc 00005 // 00006 // This program is free software; you can redistribute it and/or modify 00007 // it under the terms of the GNU General Public License as published by 00008 // the Free Software Foundation; either version 3 of the License, or 00009 // (at your option) any later version. 00010 // 00011 // This program is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 // 00016 // You should have received a copy of the GNU General Public License 00017 // along with this program; if not, write to the Free Software 00018 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00019 // 00020 00021 00022 #ifndef GNASH_IMAGE_ITERATORS_H 00023 #define GNASH_IMAGE_ITERATORS_H 00024 00025 #include <boost/iterator/iterator_facade.hpp> 00026 #include <iterator> 00027 #include <algorithm> 00028 00029 #include "GnashImage.h" 00030 00031 namespace gnash { 00032 namespace image { 00033 00035 class ARGB 00036 { 00037 public: 00038 00039 typedef GnashImage::iterator iterator; 00040 00042 ARGB(iterator& i, ImageType t) 00043 : 00044 _it(i), 00045 _t(t) 00046 {} 00047 00049 // 00051 ARGB& operator=(const ARGB& other) { 00052 switch (_t) { 00053 case TYPE_RGBA: 00054 // RGBA to RGBA 00055 if (other._t == TYPE_RGBA) { 00056 std::copy(other._it, other._it + 4, _it); 00057 break; 00058 } 00059 00060 // RGB to RGBA 00061 std::copy(other._it, other._it + 3, _it); 00062 *(_it + 3) = 0xff; 00063 break; 00064 00065 case TYPE_RGB: 00066 // It doesn't matter what the other image is. 00067 std::copy(other._it, other._it + 3, _it); 00068 00069 default: 00070 break; 00071 } 00072 return *this; 00073 } 00074 00076 // 00078 const ARGB& operator=(boost::uint32_t pixel) const { 00079 switch (_t) { 00080 case TYPE_RGBA: 00081 // alpha 00082 *(_it + 3) = (pixel & 0xff000000) >> 24; 00083 case TYPE_RGB: 00084 *_it = (pixel & 0x00ff0000) >> 16; 00085 *(_it + 1) = (pixel & 0x0000ff00) >> 8; 00086 *(_it + 2) = (pixel & 0x000000ff); 00087 default: 00088 break; 00089 } 00090 return *this; 00091 } 00092 00094 operator boost::uint32_t() const { 00095 boost::uint32_t ret = 0xff000000; 00096 switch (_t) { 00097 case TYPE_RGBA: 00098 // alpha 00099 ret = *(_it + 3) << 24; 00100 case TYPE_RGB: 00101 ret |= (*_it << 16 | *(_it + 1) << 8 | *(_it + 2)); 00102 default: 00103 break; 00104 } 00105 return ret; 00106 } 00107 00108 private: 00109 iterator& _it; 00110 const ImageType _t; 00111 }; 00112 00113 00115 // 00118 // 00121 template<typename Pixel> 00122 struct pixel_iterator : public boost::iterator_facade< 00123 pixel_iterator<Pixel>, 00124 const Pixel, 00125 std::random_access_iterator_tag> 00126 { 00127 00128 typedef std::ptrdiff_t difference_type; 00129 typedef typename Pixel::iterator iterator; 00130 00132 pixel_iterator(iterator it, ImageType t) 00133 : 00134 _it(it), 00135 _t(t), 00136 _p(_it, _t) 00137 {} 00138 00140 pixel_iterator(const pixel_iterator& other) 00141 : 00142 _it(other._it), 00143 _t(other._t), 00144 _p(_it, _t) 00145 {} 00146 00148 pixel_iterator& operator=(const pixel_iterator& other) 00149 { 00150 _it = other._it; 00151 _t = other._t; 00152 _p = Pixel(_it, _t); 00153 return *this; 00154 } 00155 00156 private: 00157 00158 friend class boost::iterator_core_access; 00159 00160 const Pixel& dereference() const { 00161 return _p; 00162 } 00163 00164 void increment() { 00165 _it += numChannels(_t); 00166 } 00167 00168 void decrement() { 00169 _it -= numChannels(_t); 00170 } 00171 00172 bool equal(const pixel_iterator& o) const { 00173 return o._it == _it; 00174 } 00175 00176 difference_type distance_to(const pixel_iterator& o) const { 00177 return (o._it - _it) / static_cast<int>(numChannels(_t)); 00178 } 00179 00180 void advance(difference_type n) { 00181 _it += n * numChannels(_t); 00182 } 00183 00184 iterator _it; 00185 ImageType _t; 00186 Pixel _p; 00187 }; 00188 00189 template<typename T> 00190 pixel_iterator<T> 00191 begin(GnashImage& im) 00192 { 00193 return pixel_iterator<T>(im.begin(), im.type()); 00194 } 00195 00196 template<typename T> 00197 pixel_iterator<T> 00198 end(GnashImage& im) 00199 { 00200 return pixel_iterator<T>(im.end(), im.type()); 00201 } 00202 00203 } // namespace image 00204 } // namespace gnash 00205 00206 #endif