00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef GIL_PIXEL_ALGORITHM_H
00010 #define GIL_PIXEL_ALGORITHM_H
00011
00020
00021 #include "gil_config.hpp"
00022 #include <algorithm>
00023 #include "gil_concept.hpp"
00024
00025 ADOBE_GIL_NAMESPACE_BEGIN
00026
00027
00028
00029 template <typename T> T inline channel_min_value();
00030 template <typename T> T inline channel_max_value();
00031
00032 namespace detail {
00033
00036 template <int N> struct channel_recursion {
00037 template <typename P,typename F> static void multiplies_eq(P& p, F x) {
00038 channel_recursion<N-1>::multiplies_eq(p,x);
00039 p.template semantic_channel<N-1>()*=x;
00040 }
00041 template <typename P,typename F> static void divides_eq(P& p, F x) {
00042 channel_recursion<N-1>::divides_eq(p,x);
00043 p.template semantic_channel<N-1>()/=x;
00044 }
00045 template <typename P1,typename P2> static void copy_channels(P1& p1, const P2& p2) {
00046 channel_recursion<N-1>::copy_channels(p1,p2);
00047 p1.template semantic_channel<N-1>()=p2.template semantic_channel<N-1>();
00048 }
00049 template <typename P1,typename P2> static void plus_eq(P1& p1, const P2& p2) {
00050 channel_recursion<N-1>::plus_eq(p1,p2);
00051 p1.template semantic_channel<N-1>()+=p2.template semantic_channel<N-1>();
00052 }
00053 template <typename P1,typename P2> static void minus_eq(P1& p1, const P2& p2) {
00054 channel_recursion<N-1>::minus_eq(p1,p2);
00055 p1.template semantic_channel<N-1>()-=p2.template semantic_channel<N-1>();
00056 }
00057 template <typename P,typename T2> static void fill_channels(P& p, T2 v) {
00058 channel_recursion<N-1>::fill_channels(p,v);
00059 p.template semantic_channel<N-1>()=v;
00060 }
00061 template <typename P1,typename P2> static bool equal_to(const P1& p1, const P2& p2) {
00062 return channel_recursion<N-1>::equal_to(p1,p2) && p1.template semantic_channel<N-1>()==p2.template semantic_channel<N-1>();
00063 }
00064
00065 template <typename P1,typename OP>
00066 static OP for_each_channel(const P1& p1, OP op) {
00067 op=channel_recursion<N-1>::for_each_channel(p1,op);
00068 op(p1.template semantic_channel<N-1>());
00069 return op;
00070 }
00071 template <typename P1,typename P2,typename OP>
00072 static OP for_each_channel(const P1& p1, const P2& p2, OP op) {
00073 op=channel_recursion<N-1>::for_each_channel(p1,p2,op);
00074 op(p1.template semantic_channel<N-1>(), p2.template semantic_channel<N-1>());
00075 return op;
00076 }
00077 template <typename P1,typename P2,typename P3,typename OP>
00078 static OP for_each_channel(const P1& p1, const P2& p2, const P3& p3, OP op) {
00079 op=channel_recursion<N-1>::for_each_channel(p1,p2,p3,op);
00080 op(p1.template semantic_channel<N-1>(), p2.template semantic_channel<N-1>(), p3.template semantic_channel<N-1>());
00081 return op;
00082 }
00083
00084 template <typename DST,typename OP>
00085 static OP transform_channels(DST& dst, OP op) {
00086 op=channel_recursion<N-1>::transform_channels(dst,op);
00087 dst.template semantic_channel<N-1>()=op();
00088 return op;
00089 }
00090 template <typename P1,typename DST,typename OP>
00091 static OP transform_channels(const P1& src, DST& dst, OP op) {
00092 op=channel_recursion<N-1>::transform_channels(src,dst,op);
00093 dst.template semantic_channel<N-1>()=op(src.template semantic_channel<N-1>());
00094 return op;
00095 }
00096 template <typename P1,typename P2,typename DST,typename OP>
00097 static OP transform_channels(const P1& src1, const P2& src2, DST& dst, OP op) {
00098 op=channel_recursion<N-1>::transform_channels(src1,src2,dst,op);
00099 dst.template semantic_channel<N-1>()=op(src1.template semantic_channel<N-1>(), src2.template semantic_channel<N-1>());
00100 return op;
00101 }
00102 };
00103
00106 template<> struct channel_recursion<0> {
00107 template <typename P, typename F> static void multiplies_eq(P&, F) {}
00108 template <typename P, typename F> static void divides_eq(P&, F) {}
00109 template <typename P1,typename P2> static void copy_channels(P1&, const P2&) {}
00110 template <typename P1,typename P2> static void plus_eq(P1&, const P2&) {}
00111 template <typename P1,typename P2> static void minus_eq(P1&, const P2&) {}
00112 template <typename P, typename T2> static void fill_channels(P&, T2) {}
00113 template <typename P1,typename P2> static bool equal_to(const P1&, const P2&) { return true; }
00114
00115 template <typename P1,typename OP>
00116 static OP for_each_channel(const P1&,OP op){return op;}
00117 template <typename P1,typename P2,typename OP>
00118 static OP for_each_channel(const P1&,const P2&,OP op){return op;}
00119 template <typename P1,typename P2,typename P3,typename OP>
00120 static OP for_each_channel(const P1&,const P2&,const P3&,OP op){return op;}
00121
00122 template <typename DST,typename OP>
00123 static OP transform_channels(DST&,OP op){return op;}
00124 template <typename P1,typename DST,typename OP>
00125 static OP transform_channels(const P1&,DST&,OP op){return op;}
00126 template <typename P1,typename P2,typename DST,typename OP>
00127 static OP transform_channels(const P1&,const P2&,DST&,OP op){return op;}
00128 };
00129
00132 template <int N>
00133 struct min_max_recur {
00134 template <typename P> static typename P::channel_t max_(const P& p) {
00135 return std::max(min_max_recur<N-1>::max_(p),p.template semantic_channel<N-1>());
00136 }
00137 template <typename P> static typename P::channel_t min_(const P& p) {
00138 return std::min(min_max_recur<N-1>::min_(p),p.template semantic_channel<N-1>());
00139 }
00140 };
00143 template <>
00144 struct min_max_recur<1> {
00145 template <typename P> static typename P::channel_t max_(const P& p) { return p.template semantic_channel<0>(); }
00146 template <typename P> static typename P::channel_t min_(const P& p) { return p.template semantic_channel<0>(); }
00147 };
00148 }
00149
00150
00154
00155
00157 template <typename P> typename P::channel_t max_channel(const P& p) { return detail::min_max_recur<P::num_channels>::max_(p); }
00159 template <typename P> typename P::channel_t min_channel(const P& p) { return detail::min_max_recur<P::num_channels>::min_(p); }
00160
00163 template <typename P> typename P::channel_t alpha(const P& p) { return channel_max_value<typename P::channel_t>(); }
00164
00166 template <typename P,typename V>
00167 void fill_channels(P& p, const V& v) { detail::channel_recursion<P::num_channels>::fill_channels(p,v); }
00168
00169 template <typename P1,typename OP>
00170 OP transform_channels(P1& dst,OP op) { return detail::channel_recursion<P1::num_channels>::transform_channels(dst,op); }
00171 template <typename P1,typename P2,typename OP>
00172 OP transform_channels(const P2& p2,P1& dst,OP op) { return detail::channel_recursion<P1::num_channels>::transform_channels(p2,dst,op); }
00173 template <typename P1,typename P2,typename P3,typename OP>
00174 OP transform_channels(const P2& p2,const P3& p3,P1& dst,OP op) { return detail::channel_recursion<P1::num_channels>::transform_channels(p2,p3,dst,op); }
00175 template <typename P1,typename OP>
00176 OP for_each_channel(const P1& p1, OP op) { return detail::channel_recursion<P1::num_channels>::for_each_channel(p1,op); }
00177 template <typename P1,typename P2,typename OP>
00178 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); }
00179 template <typename P1,typename P2,typename P3,typename OP>
00180 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); }
00182
00183 ADOBE_GIL_NAMESPACE_END
00184
00185 #endif