core/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_ALGORITHM_HPP
00010 #define GIL_ALGORITHM_HPP
00011 
00012 #include <cassert>
00013 #include <cstddef>
00014 #include <algorithm>
00015 #include "gil_config.hpp"
00016 #include "gil_concept.hpp"
00017 #include "pixel_algorithm.hpp"
00018 #include "image_view.hpp"
00019 #include "image_view_factory.hpp"
00020 
00029 
00030 ADOBE_GIL_NAMESPACE_BEGIN
00031 
00032 // a tag denoting incompatible arguments
00033 struct error_t {};
00034 
00035 
00044 template <typename Derived, typename Result=void>
00045 struct binary_operation_obj {
00046     typedef Result result_type;
00047 
00048     template <typename V1, typename V2> GIL_FORCEINLINE
00049     result_type operator()(const std::pair<const V1*,const V2*>& p) const {
00050         return apply(*p.first, *p.second, typename views_are_compatible<V1,V2>::type());
00051     }
00052 
00053     template <typename V1, typename V2> GIL_FORCEINLINE
00054     result_type operator()(const V1& v1, const V2& v2) const {
00055         return apply(v1, v2, typename views_are_compatible<V1,V2>::type());
00056     }
00057 
00058     result_type operator()(const error_t&) const { throw std::bad_cast(); }
00059 private:
00060 
00061     // dispatch from apply overload to a function with distinct name
00062     template <typename V1, typename V2>
00063     GIL_FORCEINLINE result_type apply(const V1& v1, const V2& v2, boost::mpl::false_) const {
00064         return ((const Derived*)this)->apply_incompatible(v1,v2);
00065     }
00066 
00067     // dispatch from apply overload to a function with distinct name
00068     template <typename V1, typename V2>
00069     GIL_FORCEINLINE result_type apply(const V1& v1, const V2& v2, boost::mpl::true_) const {
00070         return ((const Derived*)this)->apply_compatible(v1,v2);
00071     }
00072 
00073     // function with distinct name - it can be overloaded by subclasses
00074     template <typename V1, typename V2>
00075     GIL_FORCEINLINE result_type apply_incompatible(const V1& v1, const V2& v2) const {
00076         throw std::bad_cast();
00077     }
00078 };
00079 ADOBE_GIL_NAMESPACE_END
00080 
00086 
00090 
00091 namespace std {
00095 
00098     template<typename T, typename Cs> 
00099     GIL_FORCEINLINE GIL::pixel<T,Cs>* copy(GIL::pixel<T,Cs>* first, GIL::pixel<T,Cs>* last, GIL::pixel<T,Cs>* dst) { 
00100         return (GIL::pixel<T,Cs>*)std::copy((unsigned char*)first,(unsigned char*)last, (unsigned char*)dst);
00101     }
00102 
00105     template<typename T, typename Cs> 
00106     GIL_FORCEINLINE GIL::pixel<T,Cs>* copy(const GIL::pixel<T,Cs>* first, const GIL::pixel<T,Cs>* last, GIL::pixel<T,Cs>* dst) { 
00107         return (GIL::pixel<T,Cs>*)std::copy((unsigned char*)first,(unsigned char*)last, (unsigned char*)dst);
00108     }
00109 }
00110 
00111 ADOBE_GIL_NAMESPACE_BEGIN
00112 namespace detail {
00113     template <typename I, typename O> struct copy_fn { 
00114         GIL_FORCEINLINE I operator()(I first, I last, O dst) const { return std::copy(first,last,dst); } 
00115     };
00116 }
00117 ADOBE_GIL_NAMESPACE_END
00118 
00119 namespace std {
00122     template<typename IC1, typename Cs1, typename IC2, typename Cs2> GIL_FORCEINLINE
00123     GIL::planar_ptr<IC2,Cs2> copy(GIL::planar_ptr<IC1,Cs1> first, GIL::planar_ptr<IC1,Cs1> last, GIL::planar_ptr<IC2,Cs2> dst) { 
00124         GIL::gil_function_requires<GIL::ChannelsCompatibleConcept<typename std::iterator_traits<IC1>::value_type,typename std::iterator_traits<IC2>::value_type> >();
00125         GIL::gil_function_requires<GIL::ColorSpacesCompatibleConcept<Cs1,Cs2> >();
00126         for_each_channel(first,last,dst,GIL::detail::copy_fn<IC1,IC2>());
00127         return dst+(last-first);
00128     }
00129 }
00130 
00131 ADOBE_GIL_NAMESPACE_BEGIN
00132 namespace detail {
00135     template <typename I, typename O>
00136     struct copier_n {
00137         GIL_FORCEINLINE void operator()(I src, typename std::iterator_traits<I>::difference_type n, O dst) const { std::copy(src,src+n, dst); }
00138     };
00139 
00142     template <typename IL, typename O>  // IL Models ConstPixelLocatorConcept, O Models PixelIteratorConcept
00143     struct copier_n<GIL::pixel_image_iterator<IL>,O> {
00144         typedef typename std::iterator_traits<GIL::pixel_image_iterator<IL> >::difference_type diff_t;
00145         GIL_FORCEINLINE void operator()(GIL::pixel_image_iterator<IL> src, diff_t n, O dst) const {
00146             GIL::gil_function_requires<GIL::PixelLocatorConcept<IL> >();
00147             GIL::gil_function_requires<GIL::MutablePixelIteratorConcept<O> >();
00148             while (n>0) {
00149                 typedef typename GIL::pixel_image_iterator<IL>::difference_type diff_t;
00150                 diff_t l=src.width()-src.x_pos();
00151                 diff_t numToCopy=(n<l ? n:l);
00152                 adobe::copy_n(src.x(), numToCopy, dst);
00153                 dst+=numToCopy;
00154                 src+=numToCopy;
00155                 n-=numToCopy;
00156             }
00157         }
00158     };
00159 
00162     template <typename I, typename OL> // I Models ConstPixelIteratorConcept, OL Models PixelLocatorConcept
00163     struct copier_n<I,GIL::pixel_image_iterator<OL> > {
00164         typedef typename std::iterator_traits<I>::difference_type diff_t;
00165         GIL_FORCEINLINE void operator()(I src, diff_t n, GIL::pixel_image_iterator<OL> dst) const {
00166             GIL::gil_function_requires<GIL::PixelIteratorConcept<I> >();
00167             GIL::gil_function_requires<GIL::MutablePixelLocatorConcept<OL> >();
00168             while (n>0) {
00169                 diff_t l=dst.width()-dst.x_pos();
00170                 diff_t numToCopy=(n<l ? n:l);
00171                 adobe::copy_n(src, numToCopy, dst.x());
00172                 dst+=numToCopy;
00173                 src+=numToCopy;
00174                 n-=numToCopy;
00175             }
00176         }
00177     };
00178 
00181     template <typename IL, typename OL>
00182     struct copier_n<GIL::pixel_image_iterator<IL>,GIL::pixel_image_iterator<OL> > {
00183        typedef typename GIL::pixel_image_iterator<IL>::difference_type diff_t;
00184        GIL_FORCEINLINE void operator()(GIL::pixel_image_iterator<IL> src, diff_t n, GIL::pixel_image_iterator<OL> dst) const {
00185             GIL::gil_function_requires<GIL::PixelLocatorConcept<IL> >();
00186             GIL::gil_function_requires<GIL::MutablePixelLocatorConcept<OL> >();
00187             if (src.x_pos()!=dst.x_pos() || src.width()!=dst.width()) {
00188                 while(n-->0) {
00189                     *dst++=*src++;
00190                 }
00191             }
00192             while (n>0) {
00193                 diff_t l=dst.width()-dst.x_pos();
00194                 diff_t numToCopy=(n<l ? n : l);
00195                 adobe::copy_n(src.x(), numToCopy, dst.x());
00196                 dst+=numToCopy;
00197                 src+=numToCopy;
00198                 n-=numToCopy;
00199             }
00200         }
00201     };
00202 }
00203 ADOBE_GIL_NAMESPACE_END
00204 
00205 namespace std {
00217     template <typename IL, typename OL>
00218     GIL_FORCEINLINE GIL::pixel_image_iterator<OL> copy(GIL::pixel_image_iterator<IL> first, GIL::pixel_image_iterator<IL> last, GIL::pixel_image_iterator<OL> dst) {
00219         GIL::gil_function_requires<GIL::PixelLocatorConcept<IL> >();
00220         GIL::gil_function_requires<GIL::MutablePixelLocatorConcept<OL> >();
00221         typedef typename GIL::pixel_image_iterator<IL>::difference_type diff_t;
00222         diff_t n=diff_t(last-first);
00223         if (first.is_contiguous()) {
00224             if (dst.is_contiguous())
00225                 GIL::detail::copier_n<typename IL::x_iterator,typename OL::x_iterator>()(first.x(),n, dst.x());
00226             else
00227                 GIL::detail::copier_n<typename IL::x_iterator,GIL::pixel_image_iterator<OL> >()(first.x(),n, dst);
00228         } else {
00229             if (dst.is_contiguous())
00230                 GIL::detail::copier_n<GIL::pixel_image_iterator<IL>,typename OL::x_iterator>()(first,n, dst.x());
00231             else
00232                 GIL::detail::copier_n<GIL::pixel_image_iterator<IL>,GIL::pixel_image_iterator<OL> >()(first,n,dst);
00233         }
00234         return dst+n;
00235     }
00236 }
00237 
00238 ADOBE_GIL_NAMESPACE_BEGIN
00239 
00240 
00243 template <typename V1, typename V2> GIL_FORCEINLINE
00244 void copy_pixels(const V1& src, const V2& dst) { 
00245     assert(src.dimensions()==dst.dimensions());
00246     std::copy(src.begin(),src.end(),dst.begin());   // std::copy will choose the optimal method (see stl_override.h)
00247 }
00248 
00254 
00258 
00259 namespace detail {
00260 template <typename CC>
00261 class copy_and_convert_pixels_fn : public binary_operation_obj<copy_and_convert_pixels_fn<CC> > {
00262 private:
00263     CC _cc;
00264 public:
00265     typedef typename binary_operation_obj<copy_and_convert_pixels_fn<CC> >::result_type result_type;
00266     copy_and_convert_pixels_fn() {}
00267     copy_and_convert_pixels_fn(CC cc_in) : _cc(cc_in) {}
00268    // when the two color spaces are incompatible, a color conversion is performed
00269     template <typename V1, typename V2> GIL_FORCEINLINE 
00270     result_type apply_incompatible(const V1& src, const V2& dst) const {
00271         copy_pixels(color_converted_view<typename V2::value_type>(src,_cc),dst);
00272     }
00273 
00274     // If the two color spaces are compatible, copy_and_convert is just copy
00275     template <typename V1, typename V2> GIL_FORCEINLINE 
00276     result_type apply_compatible(const V1& src, const V2& dst) const {
00277          copy_pixels(src,dst);
00278     }
00279 };
00280 }
00281 
00284 template <typename V1, typename V2,typename CC> 
00285 GIL_FORCEINLINE 
00286 void copy_and_convert_pixels(const V1& src, const V2& dst,CC cc) { 
00287     detail::copy_and_convert_pixels_fn<CC> ccp(cc);
00288     ccp(src,dst);
00289 }
00290 
00291 //forward declaration for default_color_converter (see full definition in color_convert.hpp)
00292 struct default_color_converter;
00293 template <typename V1, typename V2> 
00294 GIL_FORCEINLINE 
00295 void copy_and_convert_pixels(const V1& src, const V2& dst) { 
00296     detail::copy_and_convert_pixels_fn<default_color_converter> ccp;
00297     ccp(src,dst);
00298 }
00299 
00300 ADOBE_GIL_NAMESPACE_END
00301 
00303 //
00304 // std::fill and gil::fill_pixels
00305 //
00307 
00311 
00312 namespace std {
00321     template <typename IL, typename V>
00322     void fill(GIL::pixel_image_iterator<IL> first, GIL::pixel_image_iterator<IL> last, const V& val) {
00323         GIL::gil_function_requires<GIL::MutablePixelLocatorConcept<IL> >();
00324         if (first.is_contiguous()) {
00325             std::fill(first.x(), last.x(), val);
00326         } else {
00327             // fill row by row
00328             std::ptrdiff_t n=last-first;
00329             while (n>0) {
00330                 std::ptrdiff_t numToDo=std::min<const std::ptrdiff_t>(n,(std::ptrdiff_t)(first.width()-first.x_pos()));
00331                 fill_n(first.x(), numToDo, val);
00332                 first+=numToDo;
00333                 n-=numToDo;
00334             }
00335         }
00336     } 
00337 }
00338 
00339 ADOBE_GIL_NAMESPACE_BEGIN
00340 
00343 template <typename V, typename Value> GIL_FORCEINLINE 
00344 void fill_pixels(const V& img_view, const Value& val) {
00345     if (img_view.begin().is_contiguous()) {
00346         std::fill(img_view.begin().x(), img_view.end().x(), val);
00347     } else {
00348         for (int y=0; y<img_view.height(); ++y)
00349             std::fill(img_view.row_begin(y),img_view.row_end(y),val);
00350     }   
00351 }
00352 ADOBE_GIL_NAMESPACE_END
00353 
00354 
00355 
00361 
00370 
00371 ADOBE_GIL_NAMESPACE_BEGIN
00372 
00373 
00376 template <typename V, typename F>
00377 F for_each_pixel(const V& img, F fun) {
00378     if (img.begin().is_contiguous()) {
00379         return std::for_each(img.begin().x(), img.end().x(), fun);
00380     } else {
00381         for (int y=0; y<img.height(); ++y)
00382             fun = std::for_each(img.row_begin(y),img.row_end(y),fun);
00383         return fun;
00384     }
00385 }
00386 
00389 template <typename View, typename F>
00390 F for_each_pixel_position(const View& img, F fun) {
00391     typename View::xy_locator loc=img.xy_at(0,0);
00392     for (int y=0; y<img.height(); ++y) {
00393         for (int x=0; x<img.width(); ++x, ++loc.x())
00394             fun(loc);
00395         loc.x()-=img.width(); ++loc.y();
00396     }
00397     return fun;
00398 }
00400 
00401 ADOBE_GIL_NAMESPACE_END
00402 
00408 
00409 ADOBE_GIL_NAMESPACE_BEGIN
00410 
00413 template <typename V, typename F>
00414 F generate_pixels(const V& img, F fun) {
00415     if (img.begin().is_contiguous())
00416         return std::generate(img.begin().x(), img.end().x(), fun);
00417     else {
00418         for (int y=0; y<img.height(); ++y)
00419             fun = std::generate(img.row_begin(y),img.row_end(y),fun);
00420         return fun;
00421     }
00422 }
00423 
00424 ADOBE_GIL_NAMESPACE_END
00425 
00431 
00435 
00436 ADOBE_GIL_NAMESPACE_BEGIN
00437 
00438 template <typename I1, typename I2> GIL_FORCEINLINE bool equal_n(I1 i1, std::ptrdiff_t n, I2 i2);
00439 
00440 
00441 namespace detail {
00444     template <typename I1, typename I2>
00445     struct equal_n_fn {
00446         GIL_FORCEINLINE bool operator()(I1 i1, std::ptrdiff_t n, I2 i2) const { return std::equal(i1,i1+n, i2); }
00447     };
00448 
00452     template<typename T, typename Cs>
00453     struct equal_n_fn<const pixel<T,Cs>*, const pixel<T,Cs>*> {
00454         GIL_FORCEINLINE bool operator()(const pixel<T,Cs>* i1, std::ptrdiff_t n, const pixel<T,Cs>* i2) const { 
00455             return memcmp(i1, i2, n*sizeof(pixel<T,Cs>))==0;
00456         }
00457     };
00458     template<typename T, typename Cs>
00459     struct equal_n_fn<pixel<T,Cs>*, pixel<T,Cs>*> : equal_n_fn<const pixel<T,Cs>*, const pixel<T,Cs>*> {};
00460 
00464     template<typename IC, typename Cs>
00465     struct equal_n_fn<planar_ptr<IC,Cs>, planar_ptr<IC,Cs> > {
00466         GIL_FORCEINLINE bool operator()(const planar_ptr<IC,Cs> i1, std::ptrdiff_t n, const planar_ptr<IC,Cs> i2) const { 
00467             ptrdiff_t numBytes=n*sizeof(typename std::iterator_traits<IC>::value_type);
00468 
00469             for (int i=0; i<Cs::num_channels; ++i)
00470                 if (memcmp(i1.channel_ptr(i), i2.channel_ptr(i), numBytes)!=0)
00471                     return false;
00472             return true;
00473         }
00474     };
00475 
00476 
00477 
00480     template <typename Loc, typename I2>  // IL Models ConstPixelLocatorConcept, O Models PixelIteratorConcept
00481     struct equal_n_fn<GIL::pixel_image_iterator<Loc>,I2> {
00482         GIL_FORCEINLINE bool operator()(GIL::pixel_image_iterator<Loc> i1, std::ptrdiff_t n, I2 i2) const {
00483             GIL::gil_function_requires<GIL::PixelLocatorConcept<Loc> >();
00484             GIL::gil_function_requires<GIL::PixelIteratorConcept<I2> >();
00485             while (n>0) {
00486                 std::ptrdiff_t num=std::min<const std::ptrdiff_t>(n, i1.width()-i1.x_pos());
00487                 if (!equal_n(i1.x(), num, i2))
00488                     return false;
00489                 i1+=num;
00490                 i2+=num;
00491                 n-=num;
00492             }
00493             return true;
00494         }
00495     };
00496 
00499     template <typename I1, typename Loc> // I Models PixelIteratorConcept, OL Models PixelLocatorConcept
00500     struct equal_n_fn<I1,GIL::pixel_image_iterator<Loc> > {
00501         GIL_FORCEINLINE bool operator()(I1 i1, std::ptrdiff_t n, GIL::pixel_image_iterator<Loc> i2) const {
00502             GIL::gil_function_requires<GIL::PixelIteratorConcept<I1> >();
00503             GIL::gil_function_requires<GIL::PixelLocatorConcept<Loc> >();
00504             while (n>0) {
00505                 std::ptrdiff_t num=std::min<const std::ptrdiff_t>(n,i2.width()-i2.x_pos());
00506                 if (!equal_n(i1, num, i2.x()))
00507                     return false;
00508                 i1+=num;
00509                 i2+=num;
00510                 n-=num;
00511             }
00512             return true;
00513         }
00514     };
00515 
00518     template <typename Loc1, typename Loc2>
00519     struct equal_n_fn<GIL::pixel_image_iterator<Loc1>,GIL::pixel_image_iterator<Loc2> > {
00520        GIL_FORCEINLINE bool operator()(GIL::pixel_image_iterator<Loc1> i1, std::ptrdiff_t n, GIL::pixel_image_iterator<Loc2> i2) const {
00521             GIL::gil_function_requires<GIL::PixelLocatorConcept<Loc1> >();
00522             GIL::gil_function_requires<GIL::PixelLocatorConcept<Loc2> >();
00523             if (i1.x_pos()!=i2.x_pos() || i1.width()!=i2.width()) {
00524                 while(n-->0) {
00525                     if (*i1++!=*i2++) return false;
00526                 }
00527             }
00528             while (n>0) {
00529                 std::ptrdiff_t num=std::min<const std::ptrdiff_t>(n,i2.width()-i2.x_pos());
00530                 if (!equal_n(i1.x(), num, i2.x()))
00531                     return false;
00532                 i1+=num;
00533                 i2+=num;
00534                 n-=num;
00535             }
00536             return true;
00537         }
00538     };
00539 }
00540 
00542 template <typename I1, typename I2> GIL_FORCEINLINE
00543 bool equal_n(I1 i1, std::ptrdiff_t n, I2 i2) {
00544     return detail::equal_n_fn<I1,I2>()(i1,n,i2);
00545 }
00546 ADOBE_GIL_NAMESPACE_END
00547 
00548 namespace std {
00560     template <typename Loc1, typename Loc2> GIL_FORCEINLINE 
00561     bool equal(GIL::pixel_image_iterator<Loc1> first, GIL::pixel_image_iterator<Loc1> last, GIL::pixel_image_iterator<Loc2> first2) {
00562         GIL::gil_function_requires<GIL::PixelLocatorConcept<Loc1> >();
00563         GIL::gil_function_requires<GIL::PixelLocatorConcept<Loc2> >();
00564         std::ptrdiff_t n=last-first;
00565         if (first.is_contiguous()) {
00566             if (first2.is_contiguous())
00567                 return GIL::detail::equal_n_fn<typename Loc1::x_iterator,typename Loc2::x_iterator>()(first.x(),n, first2.x());
00568             else
00569                 return GIL::detail::equal_n_fn<typename Loc1::x_iterator,GIL::pixel_image_iterator<Loc2> >()(first.x(),n, first2);
00570         } else {
00571             if (first2.is_contiguous())
00572                 return GIL::detail::equal_n_fn<GIL::pixel_image_iterator<Loc1>,typename Loc2::x_iterator>()(first,n, first2.x());
00573             else
00574                 return GIL::detail::equal_n_fn<GIL::pixel_image_iterator<Loc1>,GIL::pixel_image_iterator<Loc2> >()(first,n,first2);
00575         }
00576     }
00577 }
00578 
00579 ADOBE_GIL_NAMESPACE_BEGIN
00580 
00581 
00582 namespace detail {
00583     struct equal_pixels_fn : public binary_operation_obj<equal_pixels_fn,bool> {
00584         template <typename V1, typename V2>
00585         GIL_FORCEINLINE bool operator()(const V1& v1, const V2& v2) const {
00586             assert(v1.dimensions()==v2.dimensions());
00587             return std::equal(v1.begin(),v1.end(),v2.begin()); // std::equal has overloads with GIL iterators for optimal performance
00588         }
00589     };
00590 }
00591 
00594 template <typename V1, typename V2> GIL_FORCEINLINE 
00595 bool equal_pixels(const V1& v1, const V2& v2) {
00596     return detail::equal_pixels_fn()(v1,v2);
00597 }
00598 ADOBE_GIL_NAMESPACE_END
00599 
00600 
00606 
00610 
00611 ADOBE_GIL_NAMESPACE_BEGIN
00612 
00615 template <typename V1, typename V2, typename F> GIL_FORCEINLINE 
00616 F transform_pixels(const V1& src,const V2& dst, F fun) {
00617     assert(src.dimensions()==dst.dimensions());
00618     for (int y=0; y<src.height(); ++y) {
00619         typename V1::x_iterator srcIt=src.row_begin(y);
00620         typename V2::x_iterator dstIt=dst.row_begin(y);
00621         for (int x=0; x<src.width(); ++x)
00622             dstIt[x]=fun(srcIt[x]);
00623     }
00624     return fun;
00625 }
00626 
00629 template <typename V1, typename V2, typename V3, typename F> GIL_FORCEINLINE 
00630 F transform_pixels(const V1& src1, const V2& src2,const V3& dst, F fun) {
00631     for (int y=0; y<dst.height(); ++y) {
00632         typename V1::x_iterator srcIt1=src1.row_begin(y);
00633         typename V2::x_iterator srcIt2=src2.row_begin(y);
00634         typename V3::x_iterator dstIt=dst.row_begin(y);
00635         for (int x=0; x<dst.width(); ++x)
00636             dstIt[x]=fun(srcIt1[x],srcIt2[x]);
00637     }
00638     return fun;
00639 }
00640 
00643 template <typename V1, typename V2, typename F> GIL_FORCEINLINE 
00644 F transform_pixel_positions(const V1& src,const V2& dst, F fun) {
00645     assert(src.dimensions()==dst.dimensions());
00646     typename V1::xy_locator loc=src.xy_at(0,0);
00647     for (int y=0; y<src.height(); ++y) {
00648         typename V2::x_iterator dstIt=dst.row_begin(y);
00649         for (int x=0; x<src.width(); ++x, ++loc.x())
00650             dstIt[x]=fun(loc);
00651         loc.x()-=src.width(); ++loc.y();
00652     }
00653     return fun;
00654 }
00655 
00658 template <typename V1, typename V2, typename V3, typename F> GIL_FORCEINLINE 
00659 F transform_pixel_positions(const V1& src1,const V2& src2,const V3& dst, F fun) {
00660     assert(src1.dimensions()==dst.dimensions());
00661     assert(src2.dimensions()==dst.dimensions());
00662     typename V1::xy_locator loc1=src1.xy_at(0,0);
00663     typename V2::xy_locator loc2=src2.xy_at(0,0);
00664     for (int y=0; y<src1.height(); ++y) {
00665         typename V3::x_iterator dstIt=dst.row_begin(y);
00666         for (int x=0; x<src1.width(); ++x, ++loc1.x(), ++loc2.x())
00667             dstIt[x]=fun(loc1,loc2);
00668         loc1.x()-=src1.width(); ++loc1.y();
00669         loc2.x()-=src2.width(); ++loc2.y();
00670     }
00671     return fun;
00672 }
00674 
00675 
00676 
00677 ADOBE_GIL_NAMESPACE_END
00678 
00679 #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