TuttleOFX
1
|
00001 #ifndef _TERRY_ALGORITHM_STATIC_CHANNEL_RECURSION_HPP_ 00002 #define _TERRY_ALGORITHM_STATIC_CHANNEL_RECURSION_HPP_ 00003 00004 #include <boost/type_traits.hpp> 00005 #include <boost/utility/enable_if.hpp> 00006 #include <boost/mpl/contains.hpp> 00007 #include <boost/mpl/at.hpp> 00008 00009 #include <boost/gil/gil_config.hpp> 00010 #include <boost/gil/gil_concept.hpp> 00011 #include <boost/gil/utilities.hpp> 00012 00013 #include <algorithm> 00014 00015 namespace terry { 00016 using namespace boost::gil; 00017 namespace algorithm { 00018 00019 namespace ext_detail { 00020 00021 // compile-time recursion for per-element operations on color bases 00022 template <int N> 00023 struct element_recursion 00024 { 00025 //static_for_each with four sources 00026 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00027 static Op static_for_each(P1& p1, P2& p2, P3& p3, const P4& p4, Op op) { 00028 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op)); 00029 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4)); 00030 return op2; 00031 } 00032 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00033 static Op static_for_each(P1& p1, P2& p2, const P3& p3, const P4& p4, Op op) { 00034 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op)); 00035 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4)); 00036 return op2; 00037 } 00038 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00039 static Op static_for_each(P1& p1, const P2& p2, P3& p3, const P4& p4, Op op) { 00040 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op)); 00041 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4)); 00042 return op2; 00043 } 00044 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00045 static Op static_for_each(P1& p1, const P2& p2, const P3& p3, const P4& p4, Op op) { 00046 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op)); 00047 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4)); 00048 return op2; 00049 } 00050 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00051 static Op static_for_each(const P1& p1, P2& p2, P3& p3, const P4& p4, Op op) { 00052 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op)); 00053 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4)); 00054 return op2; 00055 } 00056 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00057 static Op static_for_each(const P1& p1, P2& p2, const P3& p3, const P4& p4, Op op) { 00058 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op)); 00059 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4)); 00060 return op2; 00061 } 00062 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00063 static Op static_for_each(const P1& p1, const P2& p2, P3& p3, const P4& p4, Op op) { 00064 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op)); 00065 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4)); 00066 return op2; 00067 } 00068 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00069 static Op static_for_each(const P1& p1, const P2& p2, const P3& p3, const P4& p4, Op op) { 00070 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op)); 00071 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4)); 00072 return op2; 00073 } 00074 00075 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00076 static Op static_for_each(P1& p1, P2& p2, P3& p3, P4& p4, Op op) { 00077 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op)); 00078 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4)); 00079 return op2; 00080 } 00081 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00082 static Op static_for_each(P1& p1, P2& p2, const P3& p3, P4& p4, Op op) { 00083 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op)); 00084 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4)); 00085 return op2; 00086 } 00087 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00088 static Op static_for_each(P1& p1, const P2& p2, P3& p3, P4& p4, Op op) { 00089 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op)); 00090 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4)); 00091 return op2; 00092 } 00093 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00094 static Op static_for_each(P1& p1, const P2& p2, const P3& p3, P4& p4, Op op) { 00095 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op)); 00096 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4)); 00097 return op2; 00098 } 00099 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00100 static Op static_for_each(const P1& p1, P2& p2, P3& p3, P4& p4, Op op) { 00101 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op)); 00102 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4)); 00103 return op2; 00104 } 00105 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00106 static Op static_for_each(const P1& p1, P2& p2, const P3& p3, P4& p4, Op op) { 00107 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op)); 00108 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4)); 00109 return op2; 00110 } 00111 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00112 static Op static_for_each(const P1& p1, const P2& p2, P3& p3, P4& p4, Op op) { 00113 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op)); 00114 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4)); 00115 return op2; 00116 } 00117 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00118 static Op static_for_each(const P1& p1, const P2& p2, const P3& p3, P4& p4, Op op) { 00119 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,p4,op)); 00120 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3), semantic_at_c<N-1>(p4)); 00121 return op2; 00122 } 00123 00124 // //static_transform with two sources 00125 // template <typename P1,typename P2,typename Dst,typename Op> 00126 // static Op static_transform(P1& src1, P2& src2, Dst& dst, Op op) { 00127 // Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op)); 00128 // semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2)); 00129 // return op2; 00130 // } 00131 // template <typename P1,typename P2,typename Dst,typename Op> 00132 // static Op static_transform(P1& src1, const P2& src2, Dst& dst, Op op) { 00133 // Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op)); 00134 // semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2)); 00135 // return op2; 00136 // } 00137 // template <typename P1,typename P2,typename Dst,typename Op> 00138 // static Op static_transform(const P1& src1, P2& src2, Dst& dst, Op op) { 00139 // Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op)); 00140 // semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2)); 00141 // return op2; 00142 // } 00143 // template <typename P1,typename P2,typename Dst,typename Op> 00144 // static Op static_transform(const P1& src1, const P2& src2, Dst& dst, Op op) { 00145 // Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op)); 00146 // semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2)); 00147 // return op2; 00148 // } 00149 }; 00150 00151 // Termination condition of the compile-time recursion for element operations on a color base 00152 template<> struct element_recursion<0> 00153 { 00154 //static_for_each with four sources 00155 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00156 static Op static_for_each(const P1&,const P2&,const P3&,const P4&,Op op){return op;} 00157 00158 //static_transform with three sources 00159 template <typename P1,typename P2,typename P3,typename Dst,typename Op> 00160 static Op static_transform(const P1&,const P2&,const P3&,const Dst&,Op op){return op;} 00161 }; 00162 00163 } 00164 00165 00166 /** 00167 \defgroup ColorBaseAlgorithmTransform static_transform 00168 \ingroup ColorBaseAlgorithm 00169 \brief Equivalent to std::transform. Pairs the elements semantically 00170 */ 00171 00172 /// \{ 00173 ////static_transform with three sources 00174 //template <typename P2,typename P3,typename Dst,typename Op> 00175 //GIL_FORCEINLINE 00176 //Op static_transform(P2& p2,P3& p3,Dst& dst,Op op) { return ext_detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); } 00177 //template <typename P2,typename P3,typename Dst,typename Op> 00178 //GIL_FORCEINLINE 00179 //Op static_transform(P2& p2,const P3& p3,Dst& dst,Op op) { return ext_detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); } 00180 //template <typename P2,typename P3,typename Dst,typename Op> 00181 //GIL_FORCEINLINE 00182 //Op static_transform(const P2& p2,P3& p3,Dst& dst,Op op) { return ext_detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); } 00183 //template <typename P2,typename P3,typename Dst,typename Op> 00184 //GIL_FORCEINLINE 00185 //Op static_transform(const P2& p2,const P3& p3,Dst& dst,Op op) { return ext_detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); } 00186 /// \} 00187 00188 /** 00189 \defgroup ColorBaseAlgorithmForEach static_for_each 00190 \ingroup ColorBaseAlgorithm 00191 \brief Equivalent to std::for_each. Pairs the elements semantically 00192 */ 00193 00194 ///\{ 00195 //static_for_each with four sources 00196 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00197 GIL_FORCEINLINE 00198 Op static_for_each(P1& p1,P2& p2,P3& p3,const P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); } 00199 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00200 GIL_FORCEINLINE 00201 Op static_for_each(P1& p1,P2& p2,const P3& p3,const P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); } 00202 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00203 GIL_FORCEINLINE 00204 Op static_for_each(P1& p1,const P2& p2,P3& p3,const P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); } 00205 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00206 GIL_FORCEINLINE 00207 Op static_for_each(P1& p1,const P2& p2,const P3& p3,const P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); } 00208 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00209 GIL_FORCEINLINE 00210 Op static_for_each(const P1& p1,P2& p2,P3& p3,const P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); } 00211 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00212 GIL_FORCEINLINE 00213 Op static_for_each(const P1& p1,P2& p2,const P3& p3,const P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); } 00214 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00215 GIL_FORCEINLINE 00216 Op static_for_each(const P1& p1,const P2& p2,P3& p3,const P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); } 00217 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00218 GIL_FORCEINLINE 00219 Op static_for_each(const P1& p1,const P2& p2,const P3& p3,const P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); } 00220 00221 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00222 GIL_FORCEINLINE 00223 Op static_for_each(P1& p1,P2& p2,P3& p3,P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); } 00224 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00225 GIL_FORCEINLINE 00226 Op static_for_each(P1& p1,P2& p2,const P3& p3,P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); } 00227 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00228 GIL_FORCEINLINE 00229 Op static_for_each(P1& p1,const P2& p2,P3& p3,P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); } 00230 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00231 GIL_FORCEINLINE 00232 Op static_for_each(P1& p1,const P2& p2,const P3& p3,P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); } 00233 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00234 GIL_FORCEINLINE 00235 Op static_for_each(const P1& p1,P2& p2,P3& p3,P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); } 00236 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00237 GIL_FORCEINLINE 00238 Op static_for_each(const P1& p1,P2& p2,const P3& p3,P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); } 00239 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00240 GIL_FORCEINLINE 00241 Op static_for_each(const P1& p1,const P2& p2,P3& p3,P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); } 00242 template <typename P1,typename P2,typename P3,typename P4,typename Op> 00243 GIL_FORCEINLINE 00244 Op static_for_each(const P1& p1,const P2& p2,const P3& p3,P4& p4,Op op) { return ext_detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,p4,op); } 00245 ///\} 00246 00247 } 00248 } 00249 00250 00251 #endif