iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GenericImageOperatorsImpl.H
Go to the documentation of this file.
1 /*! @file
2  @author Laurent Itti
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 
35 
36 #ifndef INCLUDE_NRT_CORE_IMAGE_DETAILS_GENERICIMAGEOPERATORSIMPL_H
37 #define INCLUDE_NRT_CORE_IMAGE_DETAILS_GENERICIMAGEOPERATORSIMPL_H
38 
39 // ######################################################################
40 #define NRT_MACRO_GENIMA_TOPVIS(OPNAME, OPFUNC) \
41 namespace nrt { namespace detail { namespace genericimage { \
42  \
43  /* Visitor for GenericImage <OP> T, where OP is +, -, etc */ \
44  template <class PixType2> \
45  struct OPNAME##_gt_visitor : public boost::static_visitor<nrt::GenericImage> \
46  { \
47  /* Constructor */ \
48  inline OPNAME##_gt_visitor(PixType2 const & rhs_) : rhs(rhs_) { } \
49  \
50  /* Case when we have Pixel arithmetic defined between lhs and rhs pixel types */ \
51  template <class PixType1> inline \
52  typename std::enable_if<nrt::nrt_traits<PixType1, PixType2>::has_arithmetic, nrt::GenericImage>::type \
53  operator()(nrt::Image<PixType1> const & lhs) const \
54  { \
55  return nrt::GenericImage(OPFUNC(lhs, rhs)); \
56  } \
57  \
58  /* Heterogeneous pixels, no arith, PixType1 has more channels than PixType2 */ \
59  template <class PixType1> inline \
60  typename std::enable_if< (!nrt::nrt_traits<PixType1, PixType2>::has_arithmetic) && \
61  (nrt::pixel_traits<PixType1>::num_channels >= \
62  nrt::pixel_traits<PixType2>::num_channels), nrt::GenericImage>::type \
63  operator()(nrt::Image<PixType1 > const & lhs) const \
64  { \
65  typedef typename PixType1::PODType T1; \
66  typedef typename PixType2::PODType T2; \
67  typedef typename PixType1::template rebind<typename nrt::promote<T1,T2>::type>::type promo; \
68  return nrt::GenericImage(OPFUNC(lhs, promo(rhs))); \
69  } \
70  \
71  /* Heterogeneous pixels, no arith, PixType1 has fewer channels than PixType2 */ \
72  template <class PixType1> inline \
73  typename std::enable_if< (!nrt::nrt_traits<PixType1, PixType2>::has_arithmetic) && \
74  (nrt::pixel_traits<PixType1>::num_channels < \
75  nrt::pixel_traits<PixType2>::num_channels), nrt::GenericImage>::type \
76  operator()(nrt::Image<PixType1> const & lhs) const \
77  { \
78  typedef typename PixType1::PODType T1; \
79  typedef typename PixType2::PODType T2; \
80  typedef typename PixType2::template rebind<typename nrt::promote<T1,T2>::type>::type promo; \
81  return nrt::GenericImage(OPFUNC(nrt::Image<promo>(lhs) + rhs)); \
82  } \
83  \
84  private: \
85  PixType2 const & rhs; \
86  }; \
87  \
88  /* Visitor for T <OP> GenericImage, where OP is +, -, etc */ \
89  template <class PixType1> \
90  struct OPNAME##_tg_visitor : public boost::static_visitor<nrt::GenericImage> \
91  { \
92  /* Constructor */ \
93  inline OPNAME##_tg_visitor(PixType1 const & lhs_) : lhs(lhs_) { } \
94  \
95  /* Case when we have Pixel arithmetic defined between lhs and rhs pixel types */ \
96  template <class PixType2> inline \
97  typename std::enable_if<nrt::nrt_traits<PixType1, PixType2>::has_arithmetic, nrt::GenericImage>::type \
98  operator()(nrt::Image<PixType2> const & rhs) const \
99  { \
100  return nrt::GenericImage(OPFUNC(lhs, rhs)); \
101  } \
102  \
103  /* Heterogeneous pixels, no arith, PixType1 has more channels than PixType2 */ \
104  template <class PixType2> inline \
105  typename std::enable_if< (!nrt::nrt_traits<PixType1, PixType2>::has_arithmetic) && \
106  (nrt::pixel_traits<PixType1>::num_channels >= \
107  nrt::pixel_traits<PixType2>::num_channels), nrt::GenericImage>::type \
108  operator()(nrt::Image<PixType2> const & rhs) const \
109  { \
110  typedef typename PixType1::PODType T1; \
111  typedef typename PixType2::PODType T2; \
112  typedef typename PixType1::template rebind<typename nrt::promote<T1,T2>::type>::type promo; \
113  return nrt::GenericImage(OPFUNC(lhs, nrt::Image<promo>(rhs))); \
114  } \
115  \
116  /* Heterogeneous pixels, no arith, PixType1 has fewer channels than PixType2 */ \
117  template <class PixType2> inline \
118  typename std::enable_if< (!nrt::nrt_traits<PixType1, PixType2>::has_arithmetic) && \
119  (nrt::pixel_traits<PixType1>::num_channels < \
120  nrt::pixel_traits<PixType2>::num_channels), nrt::GenericImage>::type \
121  operator()(nrt::Image<PixType2> const & rhs) const \
122  { \
123  typedef typename PixType1::PODType T1; \
124  typedef typename PixType2::PODType T2; \
125  typedef typename PixType2::template rebind<typename nrt::promote<T1,T2>::type>::type promo; \
126  return nrt::GenericImage(OPFUNC(promo(lhs), rhs)); \
127  } \
128  \
129  private: \
130  PixType1 const & lhs; \
131  }; \
132 } } } \
133  \
134 template <class PixType2, typename> inline \
135 nrt::GenericImage OPFUNC(nrt::GenericImage const & lhs, PixType2 const& rhs) \
136 { return lhs.apply_visitor(nrt::detail::genericimage::OPNAME##_gt_visitor<PixType2>(rhs)); } \
137  \
138 template <class PixType1, typename> inline \
139 nrt::GenericImage OPFUNC(PixType1 const& lhs, nrt::GenericImage const & rhs) \
140 { return rhs.apply_visitor(nrt::detail::genericimage::OPNAME##_tg_visitor<PixType1>(lhs)); }
141 
142 // ######################################################################
143 NRT_MACRO_GENIMA_TOPVIS(plus, nrt::operator+);
144 NRT_MACRO_GENIMA_TOPVIS(minus, nrt::operator-);
145 NRT_MACRO_GENIMA_TOPVIS(times, nrt::operator*);
146 NRT_MACRO_GENIMA_TOPVIS(divid, nrt::operator/);
147 
148 #undef NRT_MACRO_GENIMA_TOPVIS
149 
150 
151 
152 
153 #endif // INCLUDE_NRT_CORE_IMAGE_DETAILS_GENERICIMAGEOPERATORSIMPL_H