Gnash  0.8.10
ImageIterators.h
Go to the documentation of this file.
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