8 #ifndef BOOST_GIL_LOCATOR_HPP     9 #define BOOST_GIL_LOCATOR_HPP    11 #include <boost/gil/dynamic_step.hpp>    12 #include <boost/gil/pixel_iterator.hpp>    13 #include <boost/gil/point.hpp>    15 #include <boost/assert.hpp>    19 namespace boost { 
namespace gil {
    24 template <
typename P> std::ptrdiff_t memunit_step(
const P*);
    25 template <
typename P> P* memunit_advanced(
const P* p, std::ptrdiff_t diff);
    26 template <
typename P> P& memunit_advanced_ref(P* p, std::ptrdiff_t diff);
    28 template <
typename T> 
class point;
    31     template <std::
size_t D, 
typename Loc>  
class locator_axis;
    35 template <
typename T> 
struct color_space_type;
    36 template <
typename T> 
struct channel_mapping_type;
    37 template <
typename T> 
struct is_planar;
    43 template <
typename LocatorOrView>
    46     using type = LocatorOrView;
   108 template <
typename Loc, 
typename XIterator, 
typename YIterator>    
   112     using x_iterator = XIterator;
   113     using y_iterator = YIterator;
   116     static const std::size_t num_dimensions=2;
   117     using value_type = 
typename std::iterator_traits<x_iterator>::value_type;
   118     using reference = 
typename std::iterator_traits<x_iterator>::reference;    
   119     using coord_t = 
typename std::iterator_traits<x_iterator>::difference_type;      
   122     template <std::
size_t D> 
struct axis
   124         using coord_t = 
typename detail::locator_axis<D,Loc>::coord_t;
   125         using iterator = 
typename detail::locator_axis<D,Loc>::iterator;
   129     using x_coord_t = 
typename point_t::template axis<0>::coord_t;
   130     using y_coord_t = 
typename point_t::template axis<1>::coord_t;
   132     bool              operator!=(
const Loc& p)
          const { 
return !(concrete()==p); }
   134     x_iterator        x_at(x_coord_t dx, y_coord_t dy)
  const { Loc tmp=concrete(); tmp+=
point_t(dx,dy); 
return tmp.x(); }
   135     x_iterator        x_at(
const difference_type& d)
    const { Loc tmp=concrete(); tmp+=d;              
return tmp.x(); }
   136     y_iterator        y_at(x_coord_t dx, y_coord_t dy)
  const { Loc tmp=concrete(); tmp+=
point_t(dx,dy); 
return tmp.y(); }
   137     y_iterator        y_at(
const difference_type& d)
    const { Loc tmp=concrete(); tmp+=d;              
return tmp.y(); }
   138     Loc               xy_at(x_coord_t dx, y_coord_t dy)
 const { Loc tmp=concrete(); tmp+=
point_t(dx,dy); 
return tmp; }
   139     Loc               xy_at(
const difference_type& d)
   const { Loc tmp=concrete(); tmp+=d;              
return tmp; }
   141     template <std::
size_t D> 
typename axis<D>::iterator&       axis_iterator()                       { 
return detail::locator_axis<D,Loc>()(concrete()); }
   142     template <std::
size_t D> 
typename axis<D>::iterator 
const& axis_iterator()
                 const { 
return detail::locator_axis<D,Loc>()(concrete()); }
   143     template <std::
size_t D> 
typename axis<D>::iterator        axis_iterator(
const point_t& p)
 const { 
return detail::locator_axis<D,Loc>()(concrete(),p); }
   145     reference         operator()(x_coord_t dx, y_coord_t dy)
 const { 
return *x_at(dx,dy); }
   146     reference         operator[](
const difference_type& d)
   const { 
return *x_at(d.x,d.y); }
   148     reference         operator*()
                            const { 
return *concrete().x(); }
   150     Loc&              operator+=(
const difference_type& d)         { concrete().x()+=d.x; concrete().y()+=d.y; 
return concrete(); }
   151     Loc&              operator-=(
const difference_type& d)         { concrete().x()-=d.x; concrete().y()-=d.y; 
return concrete(); }
   162     Loc&              concrete()       { 
return (Loc&)*
this; }
   163     const Loc&        concrete()
 const { 
return (
const Loc&)*
this; }
   165     template <
typename X> 
friend class pixel_2d_locator;
   170     template <
typename Loc>
   171     class locator_axis<0,Loc> {
   172         using point_t = 
typename Loc::point_t;
   174         using coord_t = 
typename point_t::template axis<0>::coord_t;
   175         using iterator = 
typename Loc::x_iterator;
   177         inline iterator&        operator()(      Loc& loc)
                   const { 
return loc.x(); }
   178         inline iterator  
const& operator()(
const Loc& loc)
                   const { 
return loc.x(); }
   179         inline iterator         operator()(      Loc& loc, 
const point_t& d)
 const { 
return loc.x_at(d); }
   180         inline iterator         operator()(
const Loc& loc, 
const point_t& d)
 const { 
return loc.x_at(d); }
   183     template <
typename Loc>
   184     class locator_axis<1,Loc> {
   185         using point_t = 
typename Loc::point_t;
   187         using coord_t = 
typename point_t::template axis<1>::coord_t;
   188         using iterator = 
typename Loc::y_iterator;
   190         inline iterator&        operator()(      Loc& loc)
               const { 
return loc.y(); }
   191         inline iterator 
const&  operator()(
const Loc& loc)
               const { 
return loc.y(); }
   192         inline iterator     operator()(      Loc& loc, 
const point_t& d)
 const { 
return loc.y_at(d); }
   193         inline iterator     operator()(
const Loc& loc, 
const point_t& d)
 const { 
return loc.y_at(d); }
   197 template <
typename Loc, 
typename XIt, 
typename YIt>
   198 struct channel_type<pixel_2d_locator_base<Loc,XIt,YIt> > : 
public channel_type<XIt> {};
   200 template <
typename Loc, 
typename XIt, 
typename YIt>
   201 struct color_space_type<pixel_2d_locator_base<Loc,XIt,YIt> > : 
public color_space_type<XIt> {};
   203 template <
typename Loc, 
typename XIt, 
typename YIt>
   204 struct channel_mapping_type<pixel_2d_locator_base<Loc,XIt,YIt> > : 
public channel_mapping_type<XIt> {};
   206 template <
typename Loc, 
typename XIt, 
typename YIt>
   207 struct is_planar<pixel_2d_locator_base<Loc,XIt,YIt> > : 
public is_planar<XIt> {};
   230 template <
typename StepIterator>
   231 class memory_based_2d_locator : 
public pixel_2d_locator_base<memory_based_2d_locator<StepIterator>, typename iterator_adaptor_get_base<StepIterator>::type, StepIterator> {
   232     using this_t = memory_based_2d_locator<StepIterator>;
   233     GIL_CLASS_REQUIRE(StepIterator, boost::gil, StepIteratorConcept)
   235     using parent_t = pixel_2d_locator_base<memory_based_2d_locator<StepIterator>, 
typename iterator_adaptor_get_base<StepIterator>::type, StepIterator>;
   236     using const_t = memory_based_2d_locator<typename const_iterator_type<StepIterator>::type>; 
   238     using coord_t = 
typename parent_t::coord_t;
   239     using x_coord_t = 
typename parent_t::x_coord_t;
   240     using y_coord_t = 
typename parent_t::y_coord_t;
   241     using x_iterator = 
typename parent_t::x_iterator;
   242     using y_iterator = 
typename parent_t::y_iterator;
   243     using difference_type = 
typename parent_t::difference_type;
   244     using reference = 
typename parent_t::reference;
   246     template <
typename Deref> 
struct add_deref
   248         using type = memory_based_2d_locator<typename iterator_add_deref<StepIterator,Deref>::type>;
   249         static type make(
const memory_based_2d_locator<StepIterator>& loc, 
const Deref& nderef) {
   250             return type(iterator_add_deref<StepIterator,Deref>::make(loc.y(),nderef));
   254     memory_based_2d_locator() {}
   255     memory_based_2d_locator(
const StepIterator& yit) : _p(yit) {}
   256     template <
typename SI> memory_based_2d_locator(
const memory_based_2d_locator<SI>& loc, coord_t y_step) : _p(loc.x(), loc.row_size()*y_step) {}
   257     template <
typename SI> memory_based_2d_locator(
const memory_based_2d_locator<SI>& loc, coord_t x_step, coord_t y_step, 
bool transpose=
false)
   258         : _p(make_step_iterator(loc.x(),(transpose ? loc.row_size() : loc.pixel_size())*x_step),
   259                                         (transpose ? loc.pixel_size() : loc.row_size())*y_step ) {}
   261     memory_based_2d_locator(x_iterator xit, std::ptrdiff_t row_bytes) : _p(xit,row_bytes) {}
   262     template <
typename X> memory_based_2d_locator(
const memory_based_2d_locator<X>& pl) : _p(pl._p) {}
   263     memory_based_2d_locator(
const memory_based_2d_locator& pl) : _p(pl._p) {}
   264     memory_based_2d_locator& operator=(memory_based_2d_locator 
const& other) = 
default;
   266     bool                  operator==(
const this_t& p)
  const { 
return _p==p._p; }
   268     x_iterator 
const&     x()
                          const { 
return _p.base(); }
   269     y_iterator 
const&     y()
                          const { 
return _p; }
   270     x_iterator&           x()                                { 
return _p.base(); }
   271     y_iterator&           y()                                { 
return _p; }
   274     x_iterator x_at      (x_coord_t dx, y_coord_t dy)
  const { 
return memunit_advanced(x(), offset(dx,dy)); }
   275     x_iterator x_at      (
const difference_type& d)
    const { 
return memunit_advanced(x(), offset(d.x,d.y)); }
   276     this_t     xy_at     (x_coord_t dx, y_coord_t dy)
  const { 
return this_t(x_at( dx , dy ), row_size()); }
   277     this_t     xy_at     (
const difference_type& d)
    const { 
return this_t(x_at( d.x, d.y), row_size()); }
   278     reference  operator()(x_coord_t dx, y_coord_t dy)
  const { 
return memunit_advanced_ref(x(),offset(dx,dy)); }
   279     reference  operator[](
const difference_type& d)
    const { 
return memunit_advanced_ref(x(),offset(d.x,d.y)); }
   280     this_t&    operator+=(
const difference_type& d)          { memunit_advance(x(),offset(d.x,d.y)); 
return *
this; }
   281     this_t&    operator-=(
const difference_type& d)          { memunit_advance(x(),offset(-d.x,-d.y)); 
return *
this; }
   284     using cached_location_t = std::ptrdiff_t; 
   285     cached_location_t cache_location(
const difference_type& d)
  const { 
return offset(d.x,d.y); }
   286     cached_location_t cache_location(x_coord_t dx, y_coord_t dy)
const { 
return offset(dx,dy); }
   287     reference         operator[](
const cached_location_t& loc)
  const { 
return memunit_advanced_ref(x(),loc); }
   290     std::ptrdiff_t         row_size()
                           const { 
return memunit_step(y()); }    
   291     std::ptrdiff_t         pixel_size()
                         const { 
return memunit_step(x()); }    
   293     bool                   is_1d_traversable(x_coord_t width)
   const { 
return row_size()-pixel_size()*width==0; }   
   296     std::ptrdiff_t y_distance_to(this_t 
const& p2, x_coord_t xDiff)
 const   298         std::ptrdiff_t rowDiff = memunit_distance(x(), p2.x()) - pixel_size() * xDiff;
   299         BOOST_ASSERT((rowDiff % row_size()) == 0);
   300         return rowDiff / row_size();
   304     template <
typename X> 
friend class memory_based_2d_locator;
   305     std::ptrdiff_t offset(x_coord_t x, y_coord_t y)
        const { 
return y*row_size() + x*pixel_size(); }
   313 template <
typename SI>
   314 struct color_space_type<memory_based_2d_locator<SI> > : 
public color_space_type<typename memory_based_2d_locator<SI>::parent_t> {
   317 template <
typename SI>
   318 struct channel_mapping_type<memory_based_2d_locator<SI> > : 
public channel_mapping_type<typename memory_based_2d_locator<SI>::parent_t> {
   321 template <
typename SI>
   322 struct is_planar<memory_based_2d_locator<SI> > : 
public is_planar<typename memory_based_2d_locator<SI>::parent_t> {
   325 template <
typename SI>
   326 struct channel_type<memory_based_2d_locator<SI> > : 
public channel_type<typename memory_based_2d_locator<SI>::parent_t> {
   334 template <
typename SI>
   335 struct dynamic_x_step_type<memory_based_2d_locator<SI> > {
   337     using base_iterator_t = 
typename iterator_adaptor_get_base<SI>::type;
   338     using base_iterator_step_t = 
typename dynamic_x_step_type<base_iterator_t>::type;
   339     using dynamic_step_base_t = 
typename iterator_adaptor_rebind<SI, base_iterator_step_t>::type;
   341     using type = memory_based_2d_locator<dynamic_step_base_t>;
   348 template <
typename SI>
   349 struct dynamic_y_step_type<memory_based_2d_locator<SI> > {
   350     using type = memory_based_2d_locator<SI>;
 base class for models of PixelLocatorConceptPixel locator is similar to a pixel iterator,...
Definition: locator.hpp:109
Returns the type (and creates an instance) of an iterator that invokes the given dereference adaptor ...
Definition: locator.hpp:27
Definition: image_view_factory.hpp:40
Definition: color_convert.hpp:31
Returns the number of channels of a pixel-based GIL construct.
Definition: locator.hpp:38
2D point both axes of which have the same dimension typeModels: Point2DConcept
Definition: locator.hpp:28