00001
00002
00003
00004
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
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
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
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
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
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
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
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
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
00265 template <typename P1,typename P2>
00266 static bool equal_channels(const P1&, const P2&) { return true; }
00267
00268 template <typename P1,typename P2>
00269 static void copy_channels(const P1&, const P2&) {}
00270
00271 template <typename P, typename T2>
00272 static void fill_channels(const P&, T2) {}
00273
00274 template <typename Dst,typename Op>
00275 static Op generate_channels(const Dst&,Op op){return op;}
00276
00277 template <typename P1,typename Op>
00278 static Op for_each_channel(const P1&,Op op){return op;}
00279
00280 template <typename P1,typename P2,typename Op>
00281 static Op for_each_channel(const P1&,const P2&,Op op){return op;}
00282
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
00286 template <typename P1,typename Dst,typename Op>
00287 static Op transform_channels(const P1&,const Dst&,Op op){return op;}
00288
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 }
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
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>(); }
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
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
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
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
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
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