pixel_algorithm.hpp

Go to the documentation of this file.
00001 /*
00002   Copyright 2005-2006 Adobe Systems Incorporated
00003   Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
00004   or a copy at http://opensource.adobe.com/licenses.html)
00005 */
00006 
00007 /*************************************************************************************************/
00008 
00009 #ifndef GIL_PIXEL_ALGORITHM_HPP
00010 #define GIL_PIXEL_ALGORITHM_HPP
00011 
00020 
00021 #include <algorithm>
00022 #include "gil_config.hpp"
00023 #include "gil_concept.hpp"
00024 
00025 ADOBE_GIL_NAMESPACE_BEGIN
00026 
00027 namespace detail {
00028 
00031 template <int N>
00032 struct channel_recursion {
00033     template <typename P,typename F>
00034     static void multiplies_eq(P& p, F x) {
00035         channel_recursion<N-1>::multiplies_eq(p,x);
00036         p.template semantic_channel<N-1>()*=x;
00037     }
00038     template <typename P,typename F>
00039     static void divides_eq(P& p, F x) {
00040         channel_recursion<N-1>::divides_eq(p,x);
00041         p.template semantic_channel<N-1>()/=x;
00042     }
00043     template <typename P1,typename P2>
00044     static void plus_eq(P1& p1, const P2& p2) {
00045         channel_recursion<N-1>::plus_eq(p1,p2);
00046         p1.template semantic_channel<N-1>()+=p2.template semantic_channel<N-1>();
00047     }
00048     template <typename P1,typename P2>
00049     static void minus_eq(P1& p1, const P2& p2) {
00050         channel_recursion<N-1>::minus_eq(p1,p2);
00051         p1.template semantic_channel<N-1>()-=p2.template semantic_channel<N-1>();
00052     }
00054     template <typename P1,typename P2>
00055     static bool equal_channels(const P1& p1, const P2& p2) { 
00056         return channel_recursion<N-1>::equal_channels(p1,p2) &&
00057                p1.template semantic_channel<N-1>()==p2.template semantic_channel<N-1>(); 
00058     }
00059     //copy_channels
00060     template <typename P1,typename P2>
00061     static void copy_channels(const P1& p1, P2& p2) {
00062         channel_recursion<N-1>::copy_channels(p1,p2);
00063         p2.template semantic_channel<N-1>()=p1.template semantic_channel<N-1>();
00064     }
00065     template <typename P1,typename P2>
00066     static void copy_channels(const P1& p1, const P2& p2) {
00067         channel_recursion<N-1>::copy_channels(p1,p2);
00068         p2.template semantic_channel<N-1>()=p1.template semantic_channel<N-1>();
00069     }
00070     //fill_channels
00071     template <typename P,typename T2>
00072     static void fill_channels(P& p, T2 v) {
00073         channel_recursion<N-1>::fill_channels(p,v);
00074         p.template semantic_channel<N-1>()=v;
00075     }
00076     template <typename P,typename T2>
00077     static void fill_channels(const P& p, T2 v) {
00078         channel_recursion<N-1>::fill_channels(p,v);
00079         p.template semantic_channel<N-1>()=v;
00080     }
00081     //generate_channels
00082     template <typename Dst,typename Op> 
00083     static Op generate_channels(Dst& dst, Op op) {
00084         op=channel_recursion<N-1>::generate_channels(dst,op);
00085         dst.template semantic_channel<N-1>()=op();
00086         return op;
00087     }
00088     template <typename Dst,typename Op> 
00089     static Op generate_channels(const Dst& dst, Op op) {
00090         op=channel_recursion<N-1>::generate_channels(dst,op);
00091         dst.template semantic_channel<N-1>()=op();
00092         return op;
00093     }
00094     //for_each_channel with one source
00095     template <typename P1,typename Op> 
00096     static Op for_each_channel(P1& p1, Op op) {
00097         op=channel_recursion<N-1>::for_each_channel(p1,op);
00098         op(p1.template semantic_channel<N-1>());
00099         return op;
00100     }
00101     template <typename P1,typename Op> 
00102     static Op for_each_channel(const P1& p1, Op op) {
00103         op=channel_recursion<N-1>::for_each_channel(p1,op);
00104         op(p1.template semantic_channel<N-1>());
00105         return op;
00106     }
00107     //for_each_channel with two sources
00108     template <typename P1,typename P2,typename Op> 
00109     static Op for_each_channel(P1& p1, P2& p2, Op op) {
00110         op=channel_recursion<N-1>::for_each_channel(p1,p2,op);
00111         op(p1.template semantic_channel<N-1>(), p2.template semantic_channel<N-1>());
00112         return op;
00113     }
00114     template <typename P1,typename P2,typename Op> 
00115     static Op for_each_channel(P1& p1, const P2& p2, Op op) {
00116         op=channel_recursion<N-1>::for_each_channel(p1,p2,op);
00117         op(p1.template semantic_channel<N-1>(), p2.template semantic_channel<N-1>());
00118         return op;
00119     }
00120     template <typename P1,typename P2,typename Op> 
00121     static Op for_each_channel(const P1& p1, P2& p2, Op op) {
00122         op=channel_recursion<N-1>::for_each_channel(p1,p2,op);
00123         op(p1.template semantic_channel<N-1>(), p2.template semantic_channel<N-1>());
00124         return op;
00125     }
00126     template <typename P1,typename P2,typename Op> 
00127     static Op for_each_channel(const P1& p1, const P2& p2, Op op) {
00128         op=channel_recursion<N-1>::for_each_channel(p1,p2,op);
00129         op(p1.template semantic_channel<N-1>(), p2.template semantic_channel<N-1>());
00130         return op;
00131     }
00132     //for_each_channel with three sources
00133     template <typename P1,typename P2,typename P3,typename Op>
00134     static Op for_each_channel(P1& p1, P2& p2, P3& p3, Op op) {
00135         op=channel_recursion<N-1>::for_each_channel(p1,p2,p3,op);
00136         op(p1.template semantic_channel<N-1>(), p2.template semantic_channel<N-1>(), p3.template semantic_channel<N-1>());
00137         return op;
00138     }
00139     template <typename P1,typename P2,typename P3,typename Op>
00140     static Op for_each_channel(P1& p1, P2& p2, const P3& p3, Op op) {
00141         op=channel_recursion<N-1>::for_each_channel(p1,p2,p3,op);
00142         op(p1.template semantic_channel<N-1>(), p2.template semantic_channel<N-1>(), p3.template semantic_channel<N-1>());
00143         return op;
00144     }
00145     template <typename P1,typename P2,typename P3,typename Op>
00146     static Op for_each_channel(P1& p1, const P2& p2, P3& p3, Op op) {
00147         op=channel_recursion<N-1>::for_each_channel(p1,p2,p3,op);
00148         op(p1.template semantic_channel<N-1>(), p2.template semantic_channel<N-1>(), p3.template semantic_channel<N-1>());
00149         return op;
00150     }
00151     template <typename P1,typename P2,typename P3,typename Op>
00152     static Op for_each_channel(P1& p1, const P2& p2, const P3& p3, Op op) {
00153         op=channel_recursion<N-1>::for_each_channel(p1,p2,p3,op);
00154         op(p1.template semantic_channel<N-1>(), p2.template semantic_channel<N-1>(), p3.template semantic_channel<N-1>());
00155         return op;
00156     }
00157     template <typename P1,typename P2,typename P3,typename Op>
00158     static Op for_each_channel(const P1& p1, P2& p2, P3& p3, Op op) {
00159         op=channel_recursion<N-1>::for_each_channel(p1,p2,p3,op);
00160         op(p1.template semantic_channel<N-1>(), p2.template semantic_channel<N-1>(), p3.template semantic_channel<N-1>());
00161         return op;
00162     }
00163     template <typename P1,typename P2,typename P3,typename Op>
00164     static Op for_each_channel(const P1& p1, P2& p2, const P3& p3, Op op) {
00165         op=channel_recursion<N-1>::for_each_channel(p1,p2,p3,op);
00166         op(p1.template semantic_channel<N-1>(), p2.template semantic_channel<N-1>(), p3.template semantic_channel<N-1>());
00167         return op;
00168     }
00169     template <typename P1,typename P2,typename P3,typename Op>
00170     static Op for_each_channel(const P1& p1, const P2& p2, P3& p3, Op op) {
00171         op=channel_recursion<N-1>::for_each_channel(p1,p2,p3,op);
00172         op(p1.template semantic_channel<N-1>(), p2.template semantic_channel<N-1>(), p3.template semantic_channel<N-1>());
00173         return op;
00174     }
00175     template <typename P1,typename P2,typename P3,typename Op>
00176     static Op for_each_channel(const P1& p1, const P2& p2, const P3& p3, Op op) {
00177         op=channel_recursion<N-1>::for_each_channel(p1,p2,p3,op);
00178         op(p1.template semantic_channel<N-1>(), p2.template semantic_channel<N-1>(), p3.template semantic_channel<N-1>());
00179         return op;
00180     }
00181     //transform_channels with one source
00182     template <typename P1,typename Dst,typename Op> 
00183     static Op transform_channels(P1& src, Dst& dst, Op op) {
00184         op=channel_recursion<N-1>::transform_channels(src,dst,op);
00185         dst.template semantic_channel<N-1>()=op(src.template semantic_channel<N-1>());
00186         return op;
00187     }
00188     template <typename P1,typename Dst,typename Op> 
00189     static Op transform_channels(P1& src, const Dst& dst, Op op) {
00190         op=channel_recursion<N-1>::transform_channels(src,dst,op);
00191         dst.template semantic_channel<N-1>()=op(src.template semantic_channel<N-1>());
00192         return op;
00193     }
00194     template <typename P1,typename Dst,typename Op> 
00195     static Op transform_channels(const P1& src, Dst& dst, Op op) {
00196         op=channel_recursion<N-1>::transform_channels(src,dst,op);
00197         dst.template semantic_channel<N-1>()=op(src.template semantic_channel<N-1>());
00198         return op;
00199     }
00200     template <typename P1,typename Dst,typename Op> 
00201     static Op transform_channels(const P1& src, const Dst& dst, Op op) {
00202         op=channel_recursion<N-1>::transform_channels(src,dst,op);
00203         dst.template semantic_channel<N-1>()=op(src.template semantic_channel<N-1>());
00204         return op;
00205     }
00206     //transform_channels with two sources
00207     template <typename P1,typename P2,typename Dst,typename Op>
00208     static Op transform_channels(P1& src1, P2& src2, Dst& dst, Op op) {
00209         op=channel_recursion<N-1>::transform_channels(src1,src2,dst,op);
00210         dst.template semantic_channel<N-1>()=op(src1.template semantic_channel<N-1>(), src2.template semantic_channel<N-1>());
00211         return op;
00212     }
00213     template <typename P1,typename P2,typename Dst,typename Op>
00214     static Op transform_channels(P1& src1, P2& src2, const Dst& dst, Op op) {
00215         op=channel_recursion<N-1>::transform_channels(src1,src2,dst,op);
00216         dst.template semantic_channel<N-1>()=op(src1.template semantic_channel<N-1>(), src2.template semantic_channel<N-1>());
00217         return op;
00218     }
00219     template <typename P1,typename P2,typename Dst,typename Op>
00220     static Op transform_channels(P1& src1, const P2& src2, Dst& dst, Op op) {
00221         op=channel_recursion<N-1>::transform_channels(src1,src2,dst,op);
00222         dst.template semantic_channel<N-1>()=op(src1.template semantic_channel<N-1>(), src2.template semantic_channel<N-1>());
00223         return op;
00224     }
00225     template <typename P1,typename P2,typename Dst,typename Op>
00226     static Op transform_channels(P1& src1, const P2& src2, const Dst& dst, Op op) {
00227         op=channel_recursion<N-1>::transform_channels(src1,src2,dst,op);
00228         dst.template semantic_channel<N-1>()=op(src1.template semantic_channel<N-1>(), src2.template semantic_channel<N-1>());
00229         return op;
00230     }
00231     template <typename P1,typename P2,typename Dst,typename Op>
00232     static Op transform_channels(const P1& src1, P2& src2, Dst& dst, Op op) {
00233         op=channel_recursion<N-1>::transform_channels(src1,src2,dst,op);
00234         dst.template semantic_channel<N-1>()=op(src1.template semantic_channel<N-1>(), src2.template semantic_channel<N-1>());
00235         return op;
00236     }
00237     template <typename P1,typename P2,typename Dst,typename Op>
00238     static Op transform_channels(const P1& src1, P2& src2, const Dst& dst, Op op) {
00239         op=channel_recursion<N-1>::transform_channels(src1,src2,dst,op);
00240         dst.template semantic_channel<N-1>()=op(src1.template semantic_channel<N-1>(), src2.template semantic_channel<N-1>());
00241         return op;
00242     }
00243     template <typename P1,typename P2,typename Dst,typename Op>
00244     static Op transform_channels(const P1& src1, const P2& src2, Dst& dst, Op op) {
00245         op=channel_recursion<N-1>::transform_channels(src1,src2,dst,op);
00246         dst.template semantic_channel<N-1>()=op(src1.template semantic_channel<N-1>(), src2.template semantic_channel<N-1>());
00247         return op;
00248     }
00249     template <typename P1,typename P2,typename Dst,typename Op>
00250     static Op transform_channels(const P1& src1, const P2& src2, const Dst& dst, Op op) {
00251         op=channel_recursion<N-1>::transform_channels(src1,src2,dst,op);
00252         dst.template semantic_channel<N-1>()=op(src1.template semantic_channel<N-1>(), src2.template semantic_channel<N-1>());
00253         return op;
00254     }
00255 };
00256 
00259 template<> struct channel_recursion<0> {
00260     template <typename P, typename F>  static void multiplies_eq(P&, F) {}
00261     template <typename P, typename F>  static void divides_eq(P&, F) {}
00262     template <typename P1,typename P2> static void plus_eq(P1&, const P2&) {}
00263     template <typename P1,typename P2> static void minus_eq(P1&, const P2&) {}
00264     //equal_channels
00265     template <typename P1,typename P2>
00266     static bool equal_channels(const P1&, const P2&) { return true; }
00267     //copy_channels
00268     template <typename P1,typename P2>
00269     static void copy_channels(const P1&, const P2&) {}
00270     //fill_channels
00271     template <typename P, typename T2>
00272     static void fill_channels(const P&, T2) {}
00273     //generate_channels
00274     template <typename Dst,typename Op>
00275     static Op generate_channels(const Dst&,Op op){return op;}
00276     //for_each_channel with one source
00277     template <typename P1,typename Op>
00278     static Op for_each_channel(const P1&,Op op){return op;}
00279     //for_each_channel with two sources
00280     template <typename P1,typename P2,typename Op>
00281     static Op for_each_channel(const P1&,const P2&,Op op){return op;}
00282     //for_each_channel with three sources
00283     template <typename P1,typename P2,typename P3,typename Op>
00284     static Op for_each_channel(const P1&,const P2&,const P3&,Op op){return op;}
00285     //transform_channels with one source
00286     template <typename P1,typename Dst,typename Op>
00287     static Op transform_channels(const P1&,const Dst&,Op op){return op;}
00288     //transform_channels with two sources
00289     template <typename P1,typename P2,typename Dst,typename Op>
00290     static Op transform_channels(const P1&,const P2&,const Dst&,Op op){return op;}
00291 };
00292 
00295 template <int N>
00296 struct min_max_recur {
00297     template <typename P> static typename P::channel_t max_(const P& p) {
00298         return std::max(min_max_recur<N-1>::max_(p),p.template semantic_channel<N-1>());
00299     }    
00300     template <typename P> static typename P::channel_t min_(const P& p) {
00301         return std::min(min_max_recur<N-1>::min_(p),p.template semantic_channel<N-1>());
00302     }    
00303 };
00306 template <>
00307 struct min_max_recur<1> {
00308     template <typename P> static typename P::channel_t max_(const P& p) { return p.template semantic_channel<0>(); }
00309     template <typename P> static typename P::channel_t min_(const P& p) { return p.template semantic_channel<0>(); }
00310 };
00311 }  // namespace detail
00312 
00313 
00317 
00318 
00320 template <typename P>
00321 GIL_FORCEINLINE
00322 typename P::channel_t max_channel(const P& p) { return detail::min_max_recur<P::num_channels>::max_(p); }
00324 template <typename P>
00325 GIL_FORCEINLINE
00326 typename P::channel_t min_channel(const P& p) { return detail::min_max_recur<P::num_channels>::min_(p); }
00327 
00330 //forward declarations
00331 template <typename T> T inline channel_max_value();
00332 template <typename P>
00333 GIL_FORCEINLINE
00334 typename P::channel_t alpha(const P& p) { return channel_max_value<typename P::channel_t>(); }  // no alpha = 100% alpha
00335 
00337 template <typename P1,typename P2>
00338 GIL_FORCEINLINE
00339 bool equal_channels(const P1& p1, const P2& p2) { return detail::channel_recursion<P1::num_channels>::equal_channels(p1,p2); }
00340 
00342 template <typename Src,typename Dst>
00343 GIL_FORCEINLINE
00344 void copy_channels(const Src& src, Dst& dst) {  detail::channel_recursion<Dst::num_channels>::copy_channels(src,dst); }
00345 template <typename Src,typename Dst>
00346 GIL_FORCEINLINE
00347 void copy_channels(const Src& src, const Dst& dst) {  detail::channel_recursion<Dst::num_channels>::copy_channels(src,dst); }
00348 
00350 template <typename P,typename V>
00351 GIL_FORCEINLINE
00352 void fill_channels(P& p, const V& v) {  detail::channel_recursion<P::num_channels>::fill_channels(p,v); }
00353 template <typename P,typename V>
00354 GIL_FORCEINLINE
00355 void fill_channels(const P& p, const V& v) {  detail::channel_recursion<P::num_channels>::fill_channels(p,v); }
00356 
00357 template <typename P1,typename Op>
00358 GIL_FORCEINLINE
00359 Op generate_channels(P1& dst,Op op)                           { return detail::channel_recursion<P1::num_channels>::generate_channels(dst,op); }
00360 template <typename P1,typename Op>
00361 GIL_FORCEINLINE
00362 Op generate_channels(const P1& dst, Op op)                    { return detail::channel_recursion<P1::num_channels>::generate_channels(dst,op); }
00363 
00364 //transform_channels with one source
00365 template <typename Src,typename Dst,typename Op>
00366 GIL_FORCEINLINE
00367 Op transform_channels(Src& p2,Dst& dst,Op op)              { return detail::channel_recursion<Dst::num_channels>::transform_channels(p2,dst,op); }
00368 template <typename Src,typename Dst,typename Op>
00369 GIL_FORCEINLINE
00370 Op transform_channels(Src& p2,const Dst& dst,Op op)              { return detail::channel_recursion<Dst::num_channels>::transform_channels(p2,dst,op); }
00371 template <typename Src,typename Dst,typename Op>
00372 GIL_FORCEINLINE
00373 Op transform_channels(const Src& p2,Dst& dst,Op op)              { return detail::channel_recursion<Dst::num_channels>::transform_channels(p2,dst,op); }
00374 template <typename Src,typename Dst,typename Op>
00375 GIL_FORCEINLINE
00376 Op transform_channels(const Src& p2,const Dst& dst,Op op)              { return detail::channel_recursion<Dst::num_channels>::transform_channels(p2,dst,op); }
00377 //transform_channels with two sources
00378 template <typename P2,typename P3,typename Dst,typename Op>
00379 GIL_FORCEINLINE
00380 Op transform_channels(P2& p2,P3& p3,Dst& dst,Op op) { return detail::channel_recursion<Dst::num_channels>::transform_channels(p2,p3,dst,op); }
00381 template <typename P2,typename P3,typename Dst,typename Op>
00382 GIL_FORCEINLINE
00383 Op transform_channels(P2& p2,P3& p3,const Dst& dst,Op op) { return detail::channel_recursion<Dst::num_channels>::transform_channels(p2,p3,dst,op); }
00384 template <typename P2,typename P3,typename Dst,typename Op>
00385 GIL_FORCEINLINE
00386 Op transform_channels(P2& p2,const P3& p3,Dst& dst,Op op) { return detail::channel_recursion<Dst::num_channels>::transform_channels(p2,p3,dst,op); }
00387 template <typename P2,typename P3,typename Dst,typename Op>
00388 GIL_FORCEINLINE
00389 Op transform_channels(P2& p2,const P3& p3,const Dst& dst,Op op) { return detail::channel_recursion<Dst::num_channels>::transform_channels(p2,p3,dst,op); }
00390 template <typename P2,typename P3,typename Dst,typename Op>
00391 GIL_FORCEINLINE
00392 Op transform_channels(const P2& p2,P3& p3,Dst& dst,Op op) { return detail::channel_recursion<Dst::num_channels>::transform_channels(p2,p3,dst,op); }
00393 template <typename P2,typename P3,typename Dst,typename Op>
00394 GIL_FORCEINLINE
00395 Op transform_channels(const P2& p2,P3& p3,const Dst& dst,Op op) { return detail::channel_recursion<Dst::num_channels>::transform_channels(p2,p3,dst,op); }
00396 template <typename P2,typename P3,typename Dst,typename Op>
00397 GIL_FORCEINLINE
00398 Op transform_channels(const P2& p2,const P3& p3,Dst& dst,Op op) { return detail::channel_recursion<Dst::num_channels>::transform_channels(p2,p3,dst,op); }
00399 template <typename P2,typename P3,typename Dst,typename Op>
00400 GIL_FORCEINLINE
00401 Op transform_channels(const P2& p2,const P3& p3,const Dst& dst,Op op) { return detail::channel_recursion<Dst::num_channels>::transform_channels(p2,p3,dst,op); }
00402 
00403 //for_each_channel with one source
00404 template <typename P1,typename Op>
00405 GIL_FORCEINLINE
00406 Op for_each_channel(      P1& p1, Op op)                          { return detail::channel_recursion<P1::num_channels>::for_each_channel(p1,op); }
00407 template <typename P1,typename Op>
00408 GIL_FORCEINLINE
00409 Op for_each_channel(const P1& p1, Op op)                          { return detail::channel_recursion<P1::num_channels>::for_each_channel(p1,op); }
00410 //for_each_channel with two sources
00411 template <typename P1,typename P2,typename Op>
00412 GIL_FORCEINLINE
00413 Op for_each_channel(P1& p1,      P2& p2, Op op)             { return detail::channel_recursion<P1::num_channels>::for_each_channel(p1,p2,op); }
00414 template <typename P1,typename P2,typename Op>
00415 GIL_FORCEINLINE
00416 Op for_each_channel(P1& p1,const P2& p2, Op op)             { return detail::channel_recursion<P1::num_channels>::for_each_channel(p1,p2,op); }
00417 template <typename P1,typename P2,typename Op>
00418 GIL_FORCEINLINE
00419 Op for_each_channel(const P1& p1,      P2& p2, Op op)             { return detail::channel_recursion<P1::num_channels>::for_each_channel(p1,p2,op); }
00420 template <typename P1,typename P2,typename Op>
00421 GIL_FORCEINLINE
00422 Op for_each_channel(const P1& p1,const P2& p2, Op op)             { return detail::channel_recursion<P1::num_channels>::for_each_channel(p1,p2,op); }
00423 //for_each_channel with three sources
00424 template <typename P1,typename P2,typename P3,typename Op>
00425 GIL_FORCEINLINE
00426 Op for_each_channel(P1& p1,P2& p2,P3& p3,Op op) { return detail::channel_recursion<P1::num_channels>::for_each_channel(p1,p2,p3,op); }
00427 template <typename P1,typename P2,typename P3,typename Op>
00428 GIL_FORCEINLINE
00429 Op for_each_channel(P1& p1,P2& p2,const P3& p3,Op op) { return detail::channel_recursion<P1::num_channels>::for_each_channel(p1,p2,p3,op); }
00430 template <typename P1,typename P2,typename P3,typename Op>
00431 GIL_FORCEINLINE
00432 Op for_each_channel(P1& p1,const P2& p2,P3& p3,Op op) { return detail::channel_recursion<P1::num_channels>::for_each_channel(p1,p2,p3,op); }
00433 template <typename P1,typename P2,typename P3,typename Op>
00434 GIL_FORCEINLINE
00435 Op for_each_channel(P1& p1,const P2& p2,const P3& p3,Op op) { return detail::channel_recursion<P1::num_channels>::for_each_channel(p1,p2,p3,op); }
00436 template <typename P1,typename P2,typename P3,typename Op>
00437 GIL_FORCEINLINE
00438 Op for_each_channel(const P1& p1,P2& p2,P3& p3,Op op) { return detail::channel_recursion<P1::num_channels>::for_each_channel(p1,p2,p3,op); }
00439 template <typename P1,typename P2,typename P3,typename Op>
00440 GIL_FORCEINLINE
00441 Op for_each_channel(const P1& p1,P2& p2,const P3& p3,Op op) { return detail::channel_recursion<P1::num_channels>::for_each_channel(p1,p2,p3,op); }
00442 template <typename P1,typename P2,typename P3,typename Op>
00443 GIL_FORCEINLINE
00444 Op for_each_channel(const P1& p1,const P2& p2,P3& p3,Op op) { return detail::channel_recursion<P1::num_channels>::for_each_channel(p1,p2,p3,op); }
00445 template <typename P1,typename P2,typename P3,typename Op>
00446 GIL_FORCEINLINE
00447 Op for_each_channel(const P1& p1,const P2& p2,const P3& p3,Op op) { return detail::channel_recursion<P1::num_channels>::for_each_channel(p1,p2,p3,op); }
00449 
00450 ADOBE_GIL_NAMESPACE_END
00451 
00452 #endif

Copyright © 2006 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google