TuttleOFX  1
operations.hpp
Go to the documentation of this file.
00001 #ifndef _TERRY_NUMERIC_OPERATIONS_HPP_
00002 #define _TERRY_NUMERIC_OPERATIONS_HPP_
00003 
00004 #include <terry/globals.hpp>
00005 
00006 #include <boost/gil/channel.hpp>
00007 #include <boost/gil/pixel.hpp>
00008 
00009 #include <functional>
00010 
00011 namespace terry {
00012 using namespace boost::gil;
00013 
00014 namespace numeric {
00015 
00016 /// \ingroup ChannelNumericOperations
00017 /// structure for adding one channel to another
00018 /// this is a generic implementation; user should specialize it for better performance
00019 template <typename Channel1,typename Channel2,typename ChannelR>
00020 struct channel_plus_t : public std::binary_function<Channel1,Channel2,ChannelR> {
00021         GIL_FORCEINLINE
00022     ChannelR operator()(typename channel_traits<Channel1>::const_reference ch1,
00023                         typename channel_traits<Channel2>::const_reference ch2) const {
00024         return ChannelR(ch1)+ChannelR(ch2);
00025     }
00026 };
00027 
00028 /// \ingroup PixelNumericOperations
00029 /// \brief construct for adding two pixels
00030 template <typename PixelRef1, // models pixel concept
00031           typename PixelRef2, // models pixel concept
00032           typename PixelR>    // models pixel value concept
00033 struct pixel_plus_t {
00034         GIL_FORCEINLINE
00035     PixelR operator() (const PixelRef1& p1,
00036                        const PixelRef2& p2) const {
00037         PixelR result;
00038         static_transform(p1,p2,result,
00039                            channel_plus_t<typename channel_type<PixelRef1>::type,
00040                                           typename channel_type<PixelRef2>::type,
00041                                           typename channel_type<PixelR>::type>());
00042         return result;
00043     }
00044 };
00045 
00046 /// \ingroup ChannelNumericOperations
00047 /// structure for subtracting one channel from another
00048 /// this is a generic implementation; user should specialize it for better performance
00049 template <typename Channel1,typename Channel2,typename ChannelR>
00050 struct channel_minus_t : public std::binary_function<Channel1,Channel2,ChannelR> {
00051         GIL_FORCEINLINE
00052     ChannelR operator()(typename channel_traits<Channel1>::const_reference ch1,
00053                         typename channel_traits<Channel2>::const_reference ch2) const {
00054         return ChannelR(ch1)-ChannelR(ch2);
00055     }
00056 };
00057 
00058 
00059 /// \ingroup PixelNumericOperations
00060 /// \brief construct for subtracting two pixels
00061 template <typename PixelRef1, // models pixel concept
00062           typename PixelRef2, // models pixel concept
00063           typename PixelR>    // models pixel value concept
00064 struct pixel_minus_t {
00065         GIL_FORCEINLINE
00066     PixelR operator() (const PixelRef1& p1,
00067                        const PixelRef2& p2) const {
00068         PixelR result;
00069         static_transform(p1,p2,result,
00070                            channel_minus_t<typename channel_type<PixelRef1>::type,
00071                                            typename channel_type<PixelRef2>::type,
00072                                            typename channel_type<PixelR>::type>());
00073         return result;
00074     }
00075 };
00076 
00077 
00078 /// \ingroup ChannelNumericOperations
00079 /// structure for multiplying one channel to another
00080 /// this is a generic implementation; user should specialize it for better performance
00081 template <typename Channel1,typename Channel2,typename ChannelR>
00082 struct channel_multiplies_t : public std::binary_function<Channel1,Channel2,ChannelR> {
00083         GIL_FORCEINLINE
00084     ChannelR operator()(typename channel_traits<Channel1>::const_reference ch1,
00085                         typename channel_traits<Channel2>::const_reference ch2) const {
00086         return ChannelR(ch1)*ChannelR(ch2);
00087     }
00088 };
00089 
00090 
00091 /// \ingroup PixelNumericOperations
00092 /// \brief construct for adding two pixels
00093 template <typename PixelRef1, // models pixel concept
00094           typename PixelRef2, // models pixel concept
00095           typename PixelR>    // models pixel value concept
00096 struct pixel_multiplies_t {
00097         GIL_FORCEINLINE
00098     PixelR operator() (const PixelRef1& p1,
00099                        const PixelRef2& p2) const {
00100         PixelR result;
00101         static_transform(p1,p2,result,
00102                            channel_multiplies_t<typename channel_type<PixelRef1>::type,
00103                                           typename channel_type<PixelRef2>::type,
00104                                           typename channel_type<PixelR>::type>());
00105         return result;
00106     }
00107 };
00108 
00109 
00110 /// \ingroup ChannelNumericOperations
00111 /// structure for dividing channels
00112 /// this is a generic implementation; user should specialize it for better performance
00113 template <typename Channel1,typename Channel2,typename ChannelR>
00114 struct channel_divides_t : public std::binary_function<Channel1,Channel2,ChannelR> {
00115         GIL_FORCEINLINE
00116     ChannelR operator()(typename channel_traits<Channel1>::const_reference ch1,
00117                         typename channel_traits<Channel2>::const_reference ch2) const {
00118         if( ch2 == ChannelR(0) )
00119             return ChannelR(0);
00120         return ChannelR(ch1)/ChannelR(ch2);
00121     }
00122 };
00123 
00124 
00125 /// \ingroup PixelNumericOperations
00126 /// \brief construct for subtracting two pixels
00127 template <typename PixelRef1, // models pixel concept
00128           typename PixelRef2, // models pixel concept
00129           typename PixelR>    // models pixel value concept
00130 struct pixel_divides_t {
00131         GIL_FORCEINLINE
00132     PixelR operator() (const PixelRef1& p1,
00133                        const PixelRef2& p2) const {
00134         PixelR result;
00135         static_transform(p1,p2,result,
00136                            channel_divides_t<typename channel_type<PixelRef1>::type,
00137                                            typename channel_type<PixelRef2>::type,
00138                                            typename channel_type<PixelR>::type>());
00139         return result;
00140     }
00141 };
00142 
00143 /// \ingroup ChannelNumericOperations
00144 /// structure for adding a scalar to a channel
00145 /// this is a generic implementation; user should specialize it for better performance
00146 template <typename Channel,typename Scalar,typename ChannelR>
00147 struct channel_plus_scalar_t : public std::binary_function<Channel,Scalar,ChannelR> {
00148         GIL_FORCEINLINE
00149     ChannelR operator()(typename channel_traits<Channel>::const_reference ch,
00150                         const Scalar& s) const {
00151         return ChannelR(ch)+ChannelR(s);
00152     }
00153 };
00154 
00155 /// \ingroup ChannelNumericOperations
00156 /// structure for subtracting a scalar from a channel
00157 /// this is a generic implementation; user should specialize it for better performance
00158 template <typename Channel,typename Scalar,typename ChannelR>
00159 struct channel_minus_scalar_t : public std::binary_function<Channel,Scalar,ChannelR> {
00160         GIL_FORCEINLINE
00161     ChannelR operator()(typename channel_traits<Channel>::const_reference ch,
00162                         const Scalar& s) const {
00163         return ChannelR(ch-s);
00164     }
00165 };
00166 
00167 /// \ingroup ChannelNumericOperations
00168 /// structure for multiplying a scalar to one channel
00169 /// this is a generic implementation; user should specialize it for better performance
00170 template <typename Channel,typename Scalar,typename ChannelR>
00171 struct channel_multiplies_scalar_t : public std::binary_function<Channel,Scalar,ChannelR> {
00172         GIL_FORCEINLINE
00173     ChannelR operator()(typename channel_traits<Channel>::const_reference ch,
00174                         const Scalar& s) const {
00175         return ChannelR(ch)*ChannelR(s);
00176     }
00177 };
00178 
00179 
00180 /// \ingroup PixelNumericOperations
00181 /// \brief construct for multiplying scalar to a pixel
00182 template <typename PixelRef, // models pixel concept
00183           typename Scalar,   // models a scalar type
00184           typename PixelR=PixelRef>   // models pixel value concept
00185 struct pixel_multiplies_scalar_t {
00186         GIL_FORCEINLINE
00187     PixelR operator () (const PixelRef& p,
00188                         const Scalar& s) const {
00189         PixelR result;
00190         static_transform(p,result,
00191                            std::bind2nd(channel_multiplies_scalar_t<typename channel_type<PixelRef>::type,
00192                                                                     Scalar,
00193                                                                     typename channel_type<PixelR>::type>(),s));
00194         return result;
00195     }
00196 };
00197 
00198 
00199 /// \ingroup ChannelNumericOperations
00200 /// structure for dividing a channel by a scalar
00201 /// this is a generic implementation; user should specialize it for better performance
00202 template <typename Channel,typename Scalar,typename ChannelR>
00203 struct channel_divides_scalar_t : public std::binary_function<Channel,Scalar,ChannelR> {
00204         GIL_FORCEINLINE
00205     ChannelR operator()(typename channel_traits<Channel>::const_reference ch,
00206                         const Scalar& s) const {
00207         return ChannelR(ch)/ChannelR(s);
00208     }
00209 };
00210 
00211 /// \ingroup PixelNumericOperations
00212 /// \brief construct for dividing a pixel by a scalar
00213 template <typename PixelRef, // models pixel concept
00214           typename Scalar,   // models a scalar type
00215           typename PixelR=PixelRef>   // models pixel value concept
00216 struct pixel_divides_scalar_t {
00217         GIL_FORCEINLINE
00218     PixelR operator () (const PixelRef& p,
00219                         const Scalar& s) const {
00220         PixelR result;
00221         static_transform(p,result,
00222                            std::bind2nd(channel_divides_scalar_t<typename channel_type<PixelRef>::type,
00223                                                                  Scalar,
00224                                                                  typename channel_type<PixelR>::type>(),s));
00225         return result;
00226     }
00227 };
00228 
00229 
00230 /// \ingroup ChannelNumericOperations
00231 /// structure for halving a channel
00232 /// this is a generic implementation; user should specialize it for better performance
00233 template <typename Channel>
00234 struct channel_halves_t : public std::unary_function<Channel,Channel> {
00235         GIL_FORCEINLINE
00236     typename channel_traits<Channel>::reference
00237     operator()(typename channel_traits<Channel>::reference ch) const {
00238         return ch/=2.0;
00239     }
00240 };
00241 
00242 
00243 /// \ingroup PixelNumericOperations
00244 /// \brief construct for dividing a pixel by 2
00245 template <typename PixelRef> // models pixel concept
00246 struct pixel_halves_t {
00247         GIL_FORCEINLINE
00248     PixelRef& operator () (PixelRef& p) const {
00249         static_for_each(p,channel_halves_t<typename channel_type<PixelRef>::type>());
00250         return p;
00251     }
00252 };
00253 
00254 template <typename Pixel>
00255 GIL_FORCEINLINE
00256 void pixel_halves(Pixel& p)
00257 {
00258     pixel_halves_t<Pixel>()(p);
00259 }
00260 
00261 
00262 }
00263 }
00264 
00265 #endif