Generic Image Library: algorithm.hpp Source File Boost , ,
algorithm.hpp Go to the documentation of this file. 00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef GIL_ALGORITHM_HPP
00015 #define GIL_ALGORITHM_HPP
00016
00017 #include <cassert>
00018 #include <cstddef>
00019 #include <cstring>
00020 #include <algorithm>
00021 #include <iterator>
00022 #include <memory>
00023 #include <typeinfo>
00024 #include "gil_config.hpp "
00025 #include "gil_concept.hpp "
00026 #include "color_base_algorithm.hpp "
00027 #include "image_view.hpp "
00028 #include "image_view_factory.hpp "
00029 #include "bit_aligned_pixel_iterator.hpp "
00030
00039
00040
00041
00042
00043
00044
00045 namespace boost { namespace gil {
00046
00047
00048 template <typename ChannelPtr, typename ColorSpace>
00049 struct planar_pixel_iterator;
00050 template <typename Iterator>
00051 class memory_based_step_iterator;
00052 template <typename StepIterator>
00053 class memory_based_2d_locator;
00054
00055
00056 struct error_t {};
00057
00082
00083
00087
00096 template <typename Derived, typename Result=void >
00097 struct binary_operation_obj {
00098 typedef Result result_type;
00099
00100 template <typename V1, typename V2> GIL_FORCEINLINE
00101 result_type operator()(const std::pair<const V1*,const V2*>& p) const {
00102 return apply(*p.first, *p.second, typename views_are_compatible<V1,V2>::type ());
00103 }
00104
00105 template <typename V1, typename V2> GIL_FORCEINLINE
00106 result_type operator()(const V1& v1, const V2& v2) const {
00107 return apply(v1, v2, typename views_are_compatible<V1,V2>::type ());
00108 }
00109
00110 result_type operator()(const error_t&) const { throw std::bad_cast(); }
00111 private :
00112
00113
00114 template <typename V1, typename V2>
00115 GIL_FORCEINLINE result_type apply(const V1& v1, const V2& v2, mpl::false_) const {
00116 return ((const Derived*)this )->apply_incompatible(v1,v2);
00117 }
00118
00119
00120 template <typename V1, typename V2>
00121 GIL_FORCEINLINE result_type apply(const V1& v1, const V2& v2, mpl::true_) const {
00122 return ((const Derived*)this )->apply_compatible(v1,v2);
00123 }
00124
00125
00126 template <typename V1, typename V2>
00127 GIL_FORCEINLINE result_type apply_incompatible(const V1& v1, const V2& v2) const {
00128 throw std::bad_cast();
00129 }
00130 };
00131 } }
00132
00138
00142
00143 namespace std {
00144
00147 template <typename T, typename Cs>
00148 GIL_FORCEINLINE boost::gil::pixel<T,Cs> *
00149 copy (boost::gil::pixel<T,Cs> * first, boost::gil::pixel<T,Cs> * last,
00150 boost::gil::pixel<T,Cs> * dst) {
00151 return (boost::gil::pixel<T,Cs> *)std::copy ((unsigned char *)first,(unsigned char *)last, (unsigned char *)dst);
00152 }
00153
00156 template <typename T, typename Cs>
00157 GIL_FORCEINLINE boost::gil::pixel<T,Cs> *
00158 copy (const boost::gil::pixel<T,Cs> * first, const boost::gil::pixel<T,Cs> * last,
00159 boost::gil::pixel<T,Cs> * dst) {
00160 return (boost::gil::pixel<T,Cs> *)std::copy ((unsigned char *)first,(unsigned char *)last, (unsigned char *)dst);
00161 }
00162 }
00163
00164 namespace boost { namespace gil {
00165 namespace detail {
00166 template <typename I, typename O> struct copy_fn {
00167 GIL_FORCEINLINE I operator()(I first, I last, O dst) const { return std::copy (first,last,dst); }
00168 };
00169 }
00170 } }
00171
00172 namespace std {
00175 template <typename Cs, typename IC1, typename IC2> GIL_FORCEINLINE
00176 boost::gil::planar_pixel_iterator<IC2,Cs> copy (boost::gil::planar_pixel_iterator<IC1,Cs> first, boost::gil::planar_pixel_iterator<IC1,Cs> last, boost::gil::planar_pixel_iterator<IC2,Cs> dst) {
00177 boost::gil::gil_function_requires<boost::gil::ChannelsCompatibleConcept<typename std::iterator_traits<IC1>::value_type,typename std::iterator_traits<IC2>::value_type> >();
00178 static_for_each(first,last,dst,boost::gil::detail::copy_fn<IC1,IC2>());
00179 return dst+(last-first);
00180 }
00181 }
00182
00183 namespace boost { namespace gil {
00184 namespace detail {
00187 template <typename I, typename O>
00188 struct copier_n {
00189 GIL_FORCEINLINE void operator()(I src, typename std::iterator_traits<I>::difference_type n, O dst) const { std::copy (src,src+n, dst); }
00190 };
00191
00193 template <typename IL, typename O>
00194 struct copier_n <iterator_from_2d <IL>,O> {
00195 typedef typename std::iterator_traits<iterator_from_2d<IL> >::difference_type diff_t;
00196 GIL_FORCEINLINE void operator()(iterator_from_2d<IL> src, diff_t n, O dst) const {
00197 gil_function_requires<PixelLocatorConcept<IL> >();
00198 gil_function_requires<MutablePixelIteratorConcept<O> >();
00199 while (n>0) {
00200 typedef typename iterator_from_2d<IL>::difference_type diff_t;
00201 diff_t l=src.width ()-src.x_pos ();
00202 diff_t numToCopy=(n<l ? n:l);
00203 detail::copy_n(src.x (), numToCopy, dst);
00204 dst+=numToCopy;
00205 src+=numToCopy;
00206 n-=numToCopy;
00207 }
00208 }
00209 };
00210
00212 template <typename I, typename OL>
00213 struct copier_n <I,iterator_from_2d <OL> > {
00214 typedef typename std::iterator_traits<I>::difference_type diff_t;
00215 GIL_FORCEINLINE void operator()(I src, diff_t n, iterator_from_2d<OL> dst) const {
00216 gil_function_requires<PixelIteratorConcept<I> >();
00217 gil_function_requires<MutablePixelLocatorConcept<OL> >();
00218 while (n>0) {
00219 diff_t l=dst.width ()-dst.x_pos ();
00220 diff_t numToCopy=(n<l ? n:l);
00221 detail::copy_n(src, numToCopy, dst.x ());
00222 dst+=numToCopy;
00223 src+=numToCopy;
00224 n-=numToCopy;
00225 }
00226 }
00227 };
00228
00230 template <typename IL, typename OL>
00231 struct copier_n <iterator_from_2d <IL>,iterator_from_2d <OL> > {
00232 typedef typename iterator_from_2d<IL>::difference_type diff_t;
00233 GIL_FORCEINLINE void operator()(iterator_from_2d<IL> src, diff_t n, iterator_from_2d<OL> dst) const {
00234 gil_function_requires<PixelLocatorConcept<IL> >();
00235 gil_function_requires<MutablePixelLocatorConcept<OL> >();
00236 if (src.x_pos ()!=dst.x_pos () || src.width ()!=dst.width ()) {
00237 while (n-->0) {
00238 *dst++=*src++;
00239 }
00240 }
00241 while (n>0) {
00242 diff_t l=dst.width ()-dst.x_pos ();
00243 diff_t numToCopy=(n<l ? n : l);
00244 detail::copy_n(src.x (), numToCopy, dst.x ());
00245 dst+=numToCopy;
00246 src+=numToCopy;
00247 n-=numToCopy;
00248 }
00249 }
00250 };
00251
00252 template <typename SrcIterator, typename DstIterator>
00253 GIL_FORCEINLINE DstIterator copy_with_2d_iterators(SrcIterator first, SrcIterator last, DstIterator dst) {
00254 typedef typename SrcIterator::x_iterator src_x_iterator;
00255 typedef typename DstIterator::x_iterator dst_x_iterator;
00256
00257 typename SrcIterator::difference_type n = last - first;
00258
00259 if (first.is_1d_traversable()) {
00260 if (dst.is_1d_traversable())
00261 copier_n<src_x_iterator,dst_x_iterator> ()(first.x(),n, dst.x());
00262 else
00263 copier_n<src_x_iterator,DstIterator > ()(first.x(),n, dst);
00264 } else {
00265 if (dst.is_1d_traversable())
00266 copier_n<SrcIterator,dst_x_iterator>()(first,n, dst.x());
00267 else
00268 copier_n<SrcIterator,DstIterator>()(first,n,dst);
00269 }
00270 return dst+n;
00271 }
00272
00273 }
00274 } }
00275
00276 namespace std {
00279 template <typename IL, typename OL>
00280 GIL_FORCEINLINE boost::gil::iterator_from_2d<OL> copy1 (boost::gil::iterator_from_2d<IL> first, boost::gil::iterator_from_2d<IL> last, boost::gil::iterator_from_2d<OL> dst) {
00281 return boost::gil::detail::copy_with_2d_iterators(first,last,dst);
00282 }
00283
00284 }
00285
00286 namespace boost { namespace gil {
00287
00288
00291 template <typename View1, typename View2> GIL_FORCEINLINE
00292 void copy_pixels (const View1& src, const View2& dst) {
00293 assert(src.dimensions()==dst.dimensions());
00294 detail::copy_with_2d_iterators(src.begin(),src.end(),dst.begin());
00295 }
00296
00302
00308
00309 namespace detail {
00310 template <typename CC>
00311 class copy_and_convert_pixels_fn : public binary_operation_obj<copy_and_convert_pixels_fn<CC> > {
00312 private :
00313 CC _cc;
00314 public :
00315 typedef typename binary_operation_obj<copy_and_convert_pixels_fn<CC> >::result_type result_type;
00316 copy_and_convert_pixels_fn() {}
00317 copy_and_convert_pixels_fn(CC cc_in) : _cc(cc_in) {}
00318
00319 template <typename V1, typename V2> GIL_FORCEINLINE
00320 result_type apply_incompatible(const V1& src, const V2& dst) const {
00321 copy_pixels (color_converted_view<typename V2::value_type>(src,_cc),dst);
00322 }
00323
00324
00325 template <typename V1, typename V2> GIL_FORCEINLINE
00326 result_type apply_compatible(const V1& src, const V2& dst) const {
00327 copy_pixels (src,dst);
00328 }
00329 };
00330 }
00331
00333 template <typename V1, typename V2,typename CC>
00334 GIL_FORCEINLINE
00335 void copy_and_convert_pixels(const V1& src, const V2& dst,CC cc) {
00336 detail::copy_and_convert_pixels_fn<CC> ccp(cc);
00337 ccp(src,dst);
00338 }
00339
00340 struct default_color_converter;
00341
00343 template <typename View1, typename View2>
00344 GIL_FORCEINLINE
00345 void copy_and_convert_pixels(const View1& src, const View2& dst) {
00346 detail::copy_and_convert_pixels_fn<default_color_converter> ccp;
00347 ccp(src,dst);
00348 }
00349
00350 } }
00351
00353
00354
00355
00357
00361
00362
00363 namespace std {
00372 template <typename IL, typename V>
00373 void fill (boost::gil::iterator_from_2d<IL> first, boost::gil::iterator_from_2d<IL> last, const V& val) {
00374 boost::gil::gil_function_requires<boost::gil::MutablePixelLocatorConcept<IL> >();
00375 if (first.is_1d_traversable ()) {
00376 std::fill (first.x (), last.x (), val);
00377 } else {
00378
00379 std::ptrdiff_t n=last-first;
00380 while (n>0) {
00381 std::ptrdiff_t numToDo=std::min<const std::ptrdiff_t>(n,(std::ptrdiff_t)(first.width()-first.x_pos()));
00382 fill_n(first.x(), numToDo, val);
00383 first+=numToDo;
00384 n-=numToDo;
00385 }
00386 }
00387 }
00388 }
00389
00390 namespace boost { namespace gil {
00391
00392 namespace detail {
00394 struct std_fill_t {
00395 template <typename It, typename P>
00396 void operator()(It first, It last, const P& p_in) {
00397 std::fill (first,last,p_in);
00398 }
00399 };
00401 template <typename It, typename P>
00402 GIL_FORCEINLINE
00403 void fill_aux(It first, It last, const P& p, mpl::true_) {
00404 static_for_each(first,last,p,std_fill_t ());
00405 }
00407 template <typename It, typename P>
00408 GIL_FORCEINLINE
00409 void fill_aux(It first, It last, const P& p,mpl::false_) {
00410 std::fill (first,last,p);
00411 }
00412 }
00413
00416 template <typename View, typename Value> GIL_FORCEINLINE
00417 void fill_pixels (const View& img_view, const Value& val) {
00418 if (img_view.is_1d_traversable())
00419 detail::fill_aux(img_view.begin().x(), img_view.end().x(),
00420 val,is_planar<View>());
00421 else
00422 for (std::ptrdiff_t y=0; y<img_view.height(); ++y)
00423 detail::fill_aux(img_view.row_begin(y),img_view.row_end(y),
00424 val,is_planar<View>());
00425 }
00426
00432
00436
00437
00438 namespace detail {
00439
00440 template <typename It> GIL_FORCEINLINE
00441 void destruct_range_impl(It first, It last, mpl::true_) {
00442 typedef typename std::iterator_traits<It>::value_type value_t;
00443 if (boost::has_trivial_destructor<value_t>::value)
00444 return ;
00445 while (first!=last) {
00446 first->~value_t();
00447 ++first;
00448 }
00449 }
00450 template <typename It> GIL_FORCEINLINE
00451 void destruct_range_impl(It first, It last, mpl::false_) {}
00452
00453 template <typename It> GIL_FORCEINLINE
00454 void destruct_range(It first, It last) {
00455 destruct_range_impl(first,last,typename is_pointer<It>::type());
00456 }
00457
00458 struct std_destruct_t {
00459 template <typename It> void operator()(It first, It last) const { destruct_range(first,last); }
00460 };
00461
00463 template <typename It>
00464 GIL_FORCEINLINE
00465 void destruct_aux(It first, It last, mpl::true_) {
00466 static_for_each(first,last,std_destruct_t());
00467 }
00469 template <typename It>
00470 GIL_FORCEINLINE
00471 void destruct_aux(It first, It last, mpl::false_) {
00472 destruct_range(first,last);
00473 }
00474
00475 }
00476
00479 template <typename View> GIL_FORCEINLINE
00480 void destruct_pixels (const View& img_view) {
00481 if (img_view.is_1d_traversable())
00482 detail::destruct_aux(img_view.begin().x(), img_view.end().x(),
00483 is_planar<View>());
00484 else
00485 for (std::ptrdiff_t y=0; y<img_view.height(); ++y)
00486 detail::destruct_aux(img_view.row_begin(y),img_view.row_end(y),
00487 is_planar<View>());
00488 }
00489
00495
00499
00500
00501 namespace detail {
00502
00505 template <typename It, typename P>
00506 GIL_FORCEINLINE
00507 void uninitialized_fill_aux(It first, It last,
00508 const P& p, mpl::true_) {
00509 int channel=0;
00510 try {
00511 typedef typename std::iterator_traits<It>::value_type pixel_t;
00512 while (channel < num_channels<pixel_t>::value) {
00513 std::uninitialized_fill(dynamic_at_c(first,channel), dynamic_at_c(last,channel),
00514 dynamic_at_c(p,channel));
00515 ++channel;
00516 }
00517 } catch (...) {
00518 for (int c=0; c<channel; ++c)
00519 destruct_range(dynamic_at_c(first,c), dynamic_at_c(last,c));
00520 throw ;
00521 }
00522 }
00523
00526 template <typename It, typename P>
00527 GIL_FORCEINLINE
00528 void uninitialized_fill_aux(It first, It last,
00529 const P& p,mpl::false_) {
00530 std::uninitialized_fill(first,last,p);
00531 }
00532
00533 }
00534
00539 template <typename View, typename Value>
00540 void uninitialized_fill_pixels (const View& img_view, const Value& val) {
00541 if (img_view.is_1d_traversable())
00542 detail::uninitialized_fill_aux(img_view.begin().x(), img_view.end().x(),
00543 val,is_planar<View>());
00544 else {
00545 typename View::y_coord_t y;
00546 try {
00547 for (y=0; y<img_view.height(); ++y)
00548 detail::uninitialized_fill_aux(img_view.row_begin(y),img_view.row_end(y),
00549 val,is_planar<View>());
00550 } catch (...) {
00551 for (typename View::y_coord_t y0=0; y0<y; ++y0)
00552 detail::destruct_aux(img_view.row_begin(y0),img_view.row_end(y0), is_planar<View>());
00553 throw ;
00554 }
00555 }
00556 }
00557
00563
00567
00568 namespace detail {
00569
00570 template <typename It> GIL_FORCEINLINE
00571 void default_construct_range_impl(It first, It last, mpl::true_) {
00572 typedef typename std::iterator_traits<It>::value_type value_t;
00573 It first1=first;
00574 try {
00575 while (first!=last) {
00576 new (first) value_t();
00577 ++first;
00578 }
00579 } catch (...) {
00580 destruct_range(first1,first);
00581 throw ;
00582 }
00583 }
00584
00585 template <typename It> GIL_FORCEINLINE
00586 void default_construct_range_impl(It first, It last, mpl::false_) {}
00587
00588 template <typename It> GIL_FORCEINLINE
00589 void default_construct_range(It first, It last) { default_construct_range_impl(first, last, typename is_pointer<It>::type()); }
00590
00592 template <typename It>
00593 GIL_FORCEINLINE
00594 void default_construct_aux(It first, It last, mpl::true_) {
00595 int channel=0;
00596 try {
00597 typedef typename std::iterator_traits<It>::value_type pixel_t;
00598 while (channel < num_channels<pixel_t>::value) {
00599 default_construct_range(dynamic_at_c(first,channel), dynamic_at_c(last,channel));
00600 ++channel;
00601 }
00602 } catch (...) {
00603 for (int c=0; c<channel; ++c)
00604 destruct_range(dynamic_at_c(first,c), dynamic_at_c(last,c));
00605 throw ;
00606 }
00607 }
00608
00610 template <typename It>
00611 GIL_FORCEINLINE
00612 void default_construct_aux(It first, It last, mpl::false_) {
00613 default_construct_range(first,last);
00614 }
00615
00616 template <typename View, bool IsPlanar>
00617 struct has_trivial_pixel_constructor : public boost::has_trivial_constructor<typename View::value_type> {};
00618 template <typename View>
00619 struct has_trivial_pixel_constructor<View, true> : public boost::has_trivial_constructor<typename channel_type<View>::type> {};
00620
00621 }
00622
00627 template <typename View>
00628 void default_construct_pixels (const View& img_view) {
00629 if (detail::has_trivial_pixel_constructor<View, is_planar<View>::value>::value)
00630 return ;
00631
00632 if (img_view.is_1d_traversable())
00633 detail::default_construct_aux(img_view.begin().x(), img_view.end().x(), is_planar<View>());
00634 else {
00635 typename View::y_coord_t y;
00636 try {
00637 for (y=0; y<img_view.height(); ++y)
00638 detail::default_construct_aux(img_view.row_begin(y),img_view.row_end(y), is_planar<View>());
00639 } catch (...) {
00640 for (typename View::y_coord_t y0=0; y0<y; ++y0)
00641 detail::destruct_aux(img_view.row_begin(y0),img_view.row_end(y0), is_planar<View>());
00642 throw ;
00643 }
00644 }
00645 }
00646
00647
00653
00657
00658 namespace detail {
00659
00661 template <typename It1, typename It2>
00662 GIL_FORCEINLINE
00663 void uninitialized_copy_aux(It1 first1, It1 last1,
00664 It2 first2, mpl::true_) {
00665 int channel=0;
00666 try {
00667 typedef typename std::iterator_traits<It1>::value_type pixel_t;
00668 while (channel < num_channels<pixel_t>::value) {
00669 std::uninitialized_copy(dynamic_at_c(first1,channel), dynamic_at_c(last1,channel), dynamic_at_c(first2,channel));
00670 ++channel;
00671 }
00672 } catch (...) {
00673 It2 last2=first2;
00674 std::advance(last2, std::distance(first1,last1));
00675 for (int c=0; c<channel; ++c)
00676 destruct_range(dynamic_at_c(first2,c), dynamic_at_c(last2,c));
00677 throw ;
00678 }
00679 }
00681 template <typename It1, typename It2>
00682 GIL_FORCEINLINE
00683 void uninitialized_copy_aux(It1 first1, It1 last1,
00684 It2 first2,mpl::false_) {
00685 std::uninitialized_copy(first1,last1,first2);
00686 }
00687 }
00688
00693 template <typename View1, typename View2>
00694 void uninitialized_copy_pixels (const View1& view1, const View2& view2) {
00695 typedef mpl::bool_<is_planar<View1>::value && is_planar<View2>::value> is_planar;
00696 assert(view1.dimensions()==view2.dimensions());
00697 if (view1.is_1d_traversable() && view2.is_1d_traversable())
00698 detail::uninitialized_copy_aux(view1.begin().x(), view1.end().x(),
00699 view2.begin().x(),
00700 is_planar());
00701 else {
00702 typename View1::y_coord_t y;
00703 try {
00704 for (y=0; y<view1.height(); ++y)
00705 detail::uninitialized_copy_aux(view1.row_begin(y), view1.row_end(y),
00706 view2.row_begin(y),
00707 is_planar());
00708 } catch (...) {
00709 for (typename View1::y_coord_t y0=0; y0<y; ++y0)
00710 detail::destruct_aux(view2.row_begin(y0),view2.row_end(y0), is_planar());
00711 throw ;
00712 }
00713 }
00714 }
00715
00721
00730
00732 template <typename V, typename F>
00733 F for_each_pixel(const V& img, F fun) {
00734 if (img.is_1d_traversable()) {
00735 return std::for_each(img.begin().x(), img.end().x(), fun);
00736 } else {
00737 for (std::ptrdiff_t y=0; y<img.height(); ++y)
00738 fun = std::for_each(img.row_begin(y),img.row_end(y),fun);
00739 return fun;
00740 }
00741 }
00742
00746
00748 template <typename View, typename F>
00749 F for_each_pixel_position(const View& img, F fun) {
00750 typename View::xy_locator loc=img.xy_at(0,0);
00751 for (std::ptrdiff_t y=0; y<img.height(); ++y) {
00752 for (std::ptrdiff_t x=0; x<img.width(); ++x, ++loc.x())
00753 fun(loc);
00754 loc.x()-=img.width(); ++loc.y();
00755 }
00756 return fun;
00757 }
00758
00759
00765
00769
00772 template <typename View, typename F>
00773 void generate_pixels (const View& v, F fun) {
00774 if (v.is_1d_traversable()) {
00775 std::generate(v.begin().x(), v.end().x(), fun);
00776 } else {
00777 for (std::ptrdiff_t y=0; y<v.height(); ++y)
00778 std::generate(v.row_begin(y),v.row_end(y),fun);
00779 }
00780 }
00781
00787
00791
00792 template <typename I1, typename I2> GIL_FORCEINLINE bool equal_n(I1 i1, std::ptrdiff_t n, I2 i2);
00793
00794 namespace detail {
00795
00796 template <typename I1, typename I2>
00797 struct equal_n_fn {
00798 GIL_FORCEINLINE bool operator()(I1 i1, std::ptrdiff_t n, I2 i2) const { return std::equal (i1,i1+n, i2); }
00799 };
00800
00803 template <typename T, typename Cs>
00804 struct equal_n_fn<const pixel <T,Cs>*, const pixel<T,Cs> *> {
00805 GIL_FORCEINLINE bool operator()(const pixel<T,Cs> * i1, std::ptrdiff_t n, const pixel<T,Cs> * i2) const {
00806 return memcmp(i1, i2, n*sizeof (pixel<T,Cs> ))==0;
00807 }
00808 };
00809 template <typename T, typename Cs>
00810 struct equal_n_fn<pixel <T,Cs>*, pixel<T,Cs> *> : equal_n_fn<const pixel<T,Cs>*, const pixel<T,Cs> *> {};
00811
00815 template <typename IC, typename Cs>
00816 struct equal_n_fn<planar_pixel_iterator <IC,Cs>, planar_pixel_iterator <IC,Cs> > {
00817 GIL_FORCEINLINE bool operator()(const planar_pixel_iterator<IC,Cs> i1, std::ptrdiff_t n, const planar_pixel_iterator<IC,Cs> i2) const {
00818 ptrdiff_t numBytes=n*sizeof (typename std::iterator_traits<IC>::value_type);
00819
00820 for (std::ptrdiff_t i=0; i<mpl::size<Cs>::value; ++i)
00821 if (memcmp(dynamic_at_c(i1,i), dynamic_at_c(i2,i), numBytes)!=0)
00822 return false ;
00823 return true ;
00824 }
00825 };
00826
00827
00829 template <typename Loc, typename I2>
00830 struct equal_n_fn<boost::gil::iterator_from_2d <Loc>,I2> {
00831 GIL_FORCEINLINE bool operator()(boost::gil::iterator_from_2d<Loc> i1, std::ptrdiff_t n, I2 i2) const {
00832 gil_function_requires<boost::gil::PixelLocatorConcept<Loc> >();
00833 gil_function_requires<boost::gil::PixelIteratorConcept<I2> >();
00834 while (n>0) {
00835 std::ptrdiff_t num=std::min<const std::ptrdiff_t>(n, i1.width ()-i1.x_pos ());
00836 if (!equal_n(i1.x (), num, i2))
00837 return false ;
00838 i1+=num;
00839 i2+=num;
00840 n-=num;
00841 }
00842 return true ;
00843 }
00844 };
00845
00847 template <typename I1, typename Loc>
00848 struct equal_n_fn<I1,boost::gil::iterator_from_2d <Loc> > {
00849 GIL_FORCEINLINE bool operator()(I1 i1, std::ptrdiff_t n, boost::gil::iterator_from_2d<Loc> i2) const {
00850 gil_function_requires<boost::gil::PixelIteratorConcept<I1> >();
00851 gil_function_requires<boost::gil::PixelLocatorConcept<Loc> >();
00852 while (n>0) {
00853 std::ptrdiff_t num=std::min<const std::ptrdiff_t>(n,i2.width ()-i2.x_pos ());
00854 if (!equal_n(i1, num, i2.x ()))
00855 return false ;
00856 i1+=num;
00857 i2+=num;
00858 n-=num;
00859 }
00860 return true ;
00861 }
00862 };
00863
00865 template <typename Loc1, typename Loc2>
00866 struct equal_n_fn<boost::gil::iterator_from_2d <Loc1>,boost::gil::iterator_from_2d <Loc2> > {
00867 GIL_FORCEINLINE bool operator()(boost::gil::iterator_from_2d<Loc1> i1, std::ptrdiff_t n, boost::gil::iterator_from_2d<Loc2> i2) const {
00868 gil_function_requires<boost::gil::PixelLocatorConcept<Loc1> >();
00869 gil_function_requires<boost::gil::PixelLocatorConcept<Loc2> >();
00870 if (i1.x_pos ()!=i2.x_pos () || i1.width ()!=i2.width ()) {
00871 while (n-->0) {
00872 if (*i1++!=*i2++) return false ;
00873 }
00874 }
00875 while (n>0) {
00876 std::ptrdiff_t num=std::min<const std::ptrdiff_t>(n,i2.width ()-i2.x_pos ());
00877 if (!equal_n(i1.x (), num, i2.x ()))
00878 return false ;
00879 i1+=num;
00880 i2+=num;
00881 n-=num;
00882 }
00883 return true ;
00884 }
00885 };
00886 }
00887
00888 template <typename I1, typename I2> GIL_FORCEINLINE
00889 bool equal_n(I1 i1, std::ptrdiff_t n, I2 i2) {
00890 return detail::equal_n_fn<I1,I2>()(i1,n,i2);
00891 }
00892 } }
00893
00894 namespace std {
00906 template <typename Loc1, typename Loc2> GIL_FORCEINLINE
00907 bool equal (boost::gil::iterator_from_2d<Loc1> first, boost::gil::iterator_from_2d<Loc1> last, boost::gil::iterator_from_2d<Loc2> first2) {
00908 boost::gil::gil_function_requires<boost::gil::PixelLocatorConcept<Loc1> >();
00909 boost::gil::gil_function_requires<boost::gil::PixelLocatorConcept<Loc2> >();
00910 std::ptrdiff_t n=last-first;
00911 if (first.is_1d_traversable()) {
00912 if (first2.is_1d_traversable ())
00913 return boost::gil::detail::equal_n_fn<typename Loc1::x_iterator,typename Loc2::x_iterator>()(first.x(),n, first2.x ());
00914 else
00915 return boost::gil::detail::equal_n_fn<typename Loc1::x_iterator,boost::gil::iterator_from_2d<Loc2> >()(first.x(),n, first2);
00916 } else {
00917 if (first2.is_1d_traversable ())
00918 return boost::gil::detail::equal_n_fn<boost::gil::iterator_from_2d<Loc1> ,typename Loc2::x_iterator>()(first,n, first2.x ());
00919 else
00920 return boost::gil::detail::equal_n_fn<boost::gil::iterator_from_2d<Loc1>,boost::gil::iterator_from_2d<Loc2> >()(first,n,first2);
00921 }
00922 }
00923 }
00924
00925 namespace boost { namespace gil {
00926
00929 template <typename View1, typename View2> GIL_FORCEINLINE
00930 bool equal_pixels (const View1& v1, const View2& v2) {
00931 assert(v1.dimensions()==v2.dimensions());
00932 return std::equal (v1.begin(),v1.end(),v2.begin());
00933 }
00934
00940
00944
00947 template <typename View1, typename View2, typename F> GIL_FORCEINLINE
00948 F transform_pixels (const View1& src,const View2& dst, F fun) {
00949 assert(src.dimensions()==dst.dimensions());
00950 for (std::ptrdiff_t y=0; y<src.height(); ++y) {
00951 typename View1::x_iterator srcIt=src.row_begin(y);
00952 typename View2::x_iterator dstIt=dst.row_begin(y);
00953 for (std::ptrdiff_t x=0; x<src.width(); ++x)
00954 dstIt[x]=fun(srcIt[x]);
00955 }
00956 return fun;
00957 }
00958
00961 template <typename View1, typename View2, typename View3, typename F> GIL_FORCEINLINE
00962 F transform_pixels (const View1& src1, const View2& src2,const View3& dst, F fun) {
00963 for (std::ptrdiff_t y=0; y<dst.height(); ++y) {
00964 typename View1::x_iterator srcIt1=src1.row_begin(y);
00965 typename View2::x_iterator srcIt2=src2.row_begin(y);
00966 typename View3::x_iterator dstIt=dst.row_begin(y);
00967 for (std::ptrdiff_t x=0; x<dst.width(); ++x)
00968 dstIt[x]=fun(srcIt1[x],srcIt2[x]);
00969 }
00970 return fun;
00971 }
00972
00976
00979 template <typename View1, typename View2, typename F> GIL_FORCEINLINE
00980 F transform_pixel_positions (const View1& src,const View2& dst, F fun) {
00981 assert(src.dimensions()==dst.dimensions());
00982 typename View1::xy_locator loc=src.xy_at(0,0);
00983 for (std::ptrdiff_t y=0; y<src.height(); ++y) {
00984 typename View2::x_iterator dstIt=dst.row_begin(y);
00985 for (std::ptrdiff_t x=0; x<src.width(); ++x, ++loc.x())
00986 dstIt[x]=fun(loc);
00987 loc.x()-=src.width(); ++loc.y();
00988 }
00989 return fun;
00990 }
00991
00994 template <typename View1, typename View2, typename View3, typename F> GIL_FORCEINLINE
00995 F transform_pixel_positions (const View1& src1,const View2& src2,const View3& dst, F fun) {
00996 assert(src1.dimensions()==dst.dimensions());
00997 assert(src2.dimensions()==dst.dimensions());
00998 typename View1::xy_locator loc1=src1.xy_at(0,0);
00999 typename View2::xy_locator loc2=src2.xy_at(0,0);
01000 for (std::ptrdiff_t y=0; y<src1.height(); ++y) {
01001 typename View3::x_iterator dstIt=dst.row_begin(y);
01002 for (std::ptrdiff_t x=0; x<src1.width(); ++x, ++loc1.x(), ++loc2.x())
01003 dstIt[x]=fun(loc1,loc2);
01004 loc1.x()-=src1.width(); ++loc1.y();
01005 loc2.x()-=src2.width(); ++loc2.y();
01006 }
01007 return fun;
01008 }
01009
01010 } }
01011
01012
01013
01014
01015
01016 #endif
Generated on Sat May 2 13:50:13 2009 for Generic Image Library by
1.5.6
Статья Generic Image Library: algorithm.hpp Source File раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: ::