Modules | Alphabetical List | Class List | Directories | File List | File Members | GIL Home Page # iterator_from_2d.hpp Go to the documentation of this file.
    00001 /*
    00002     Copyright 2005-2007 Adobe Systems Incorporated
    00003
    00004     Use, modification and distribution are subject to the Boost Software License,
    00005     Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    00006     http://www.boost.org/LICENSE_1_0.txt).
    00007
    00008     See http://opensource.adobe.com/gil for most recent version including documentation.
    00009 */
    00010 /*************************************************************************************************/
    00011
    00012 #ifndef GIL_ITERATOR_FROM_2D_H
    00013 #define GIL_ITERATOR_FROM_2D_H
    00014
    00023
    00024 #include <cassert>
    00025 #include <boost/iterator/iterator_facade.hpp>
    00026 #include "gil_concept.hpp"
    00027 #include "gil_config.hpp"
    00028 #include "pixel_iterator.hpp"
    00029 #include "locator.hpp"
    00030
    00031 namespace boost { namespace gil {
    00032
    00038
    00039
    00043
    00044
    00050
    00051 template <typename Loc2>    // Models PixelLocatorConcept
    00052 class iterator_from_2d : public iterator_facade<iterator_from_2d<Loc2>,
    00053                                                 typename Loc2::value_type,
    00054                                                 random_access_traversal_tag,
    00055                                                 typename Loc2::reference,
    00056                                                 typename Loc2::coord_t> {
    00057     GIL_CLASS_REQUIRE(Loc2, boost::gil, PixelLocatorConcept)
    00058 public:
    00059     typedef iterator_facade<iterator_from_2d<Loc2>,
    00060                             typename Loc2::value_type,
    00061                             random_access_traversal_tag,
    00062                             typename Loc2::reference,
    00063                             typename Loc2::coord_t> parent_t;
    00064     typedef typename parent_t::reference       reference;
    00065     typedef typename parent_t::difference_type difference_type;
    00066     typedef typename Loc2::x_iterator          x_iterator;
    00067     typedef typename Loc2::point_t             point_t;
    00068
    00069     int width()         const { return _width; }            // number of pixels per image row
    00070     int x_pos()         const { return _coords.x; }         // current x position
    00071     int y_pos()         const { return _coords.y; }         // current y position
    00072
    00075     reference operator[](difference_type d) const { return *(*this+d); }
    00076
    00077     bool            is_1d_traversable() const { return _p.is_1d_traversable(width()); }   // is there no gap at the end of each row?
    00078     x_iterator&     x()                   { return _p.x(); }
    00079
    00080     iterator_from_2d(){}
    00081     iterator_from_2d(const Loc2& p, int width, int x=0, int y=0) : _coords(x,y), _width(width), _p(p) {}
    00082     iterator_from_2d(const iterator_from_2d& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
    00083     template <typename Loc> iterator_from_2d(const iterator_from_2d<Loc>& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
    00084
    00085 private:
    00086     template <typename Loc> friend class iterator_from_2d;
    00087     friend class boost::iterator_core_access;
    00088     reference dereference() const { return *_p; }
    00089     void increment() {
    00090         ++_coords.x;
    00091         ++_p.x();
    00092         if (_coords.x>=_width) {
    00093             _coords.x=0;
    00094             ++_coords.y;
    00095             _p+=point_t(-_width,1);
    00096         }
    00097     }
    00098     void decrement() {
    00099         --_coords.x;
    00100         --_p.x();
    00101         if (_coords.x<0) {
    00102             _coords.x=_width-1;
    00103             --_coords.y;
    00104             _p+=point_t(_width,-1);
    00105         }
    00106     }
    00107
    00108     GIL_FORCEINLINE void advance(difference_type d) {
    00109         if (_width==0) return;  // unfortunately we need to check for that. Default-constructed images have width of 0 and the code below will throw if executed.
    00110         point_t delta;
    00111         if (_coords.x+d>=0) {  // not going back to a previous row?
    00112             delta.x=(_coords.x+(int)d)%_width - _coords.x;
    00113             delta.y=(_coords.x+(int)d)/_width;
    00114         } else {
    00115             delta.x=(_coords.x+(int)d*(1-_width))%_width -_coords.x;
    00116             delta.y=-(_width-_coords.x-(int)d-1)/_width;
    00117         }
    00118         _p+=delta;
    00119         _coords.x+=delta.x;
    00120         _coords.y+=delta.y;
    00121     }
    00122
    00123     difference_type distance_to(const iterator_from_2d& it) const {
    00124         if (_width==0) return 0;
    00125         return (it.y_pos()-_coords.y)*_width + (it.x_pos()-_coords.x);
    00126     }
    00127
    00128     bool equal(const iterator_from_2d& it) const {
    00129         assert(_width==it.width());     // they must belong to the same image
    00130         return _coords==it._coords && _p==it._p;
    00131     }
    00132
    00133     point2<int> _coords;
    00134     int _width;
    00135     Loc2 _p;
    00136 };
    00137
    00138 template <typename Loc> // Models PixelLocatorConcept
    00139 struct const_iterator_type<iterator_from_2d<Loc> > {
    00140     typedef iterator_from_2d<typename Loc::const_t> type;
    00141 };
    00142
    00143 template <typename Loc> // Models PixelLocatorConcept
    00144 struct iterator_is_mutable<iterator_from_2d<Loc> > : public iterator_is_mutable<typename Loc::x_iterator> {};
    00145
    00146
    00148 //  HasDynamicXStepTypeConcept
    00150
    00151 template <typename Loc>
    00152 struct dynamic_x_step_type<iterator_from_2d<Loc> > {
    00153     typedef iterator_from_2d<typename dynamic_x_step_type<Loc>::type>  type;
    00154 };
    00155
    00156
    00158 //  PixelBasedConcept
    00160
    00161 template <typename Loc> // Models PixelLocatorConcept
    00162 struct color_space_type<iterator_from_2d<Loc> > : public color_space_type<Loc> {};
    00163
    00164 template <typename Loc> // Models PixelLocatorConcept
    00165 struct channel_mapping_type<iterator_from_2d<Loc> > : public channel_mapping_type<Loc> {};
    00166
    00167 template <typename Loc> // Models PixelLocatorConcept
    00168 struct is_planar<iterator_from_2d<Loc> > : public is_planar<Loc> {};
    00169
    00170 template <typename Loc> // Models PixelLocatorConcept
    00171 struct channel_type<iterator_from_2d<Loc> > : public channel_type<Loc> {};
    00172
    00173 } }  // namespace boost::gil
    00174
    00175 #endif