TuttleOFX
1
|
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