// // Copyright 2005-2007 Adobe Systems Incorporated // // Distributed under the Boost Software License, Version 1.0 // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt // #ifndef BOOST_GIL_EXTENSION_NUMERIC_ALGORITHM_HPP #define BOOST_GIL_EXTENSION_NUMERIC_ALGORITHM_HPP #include #include #include #include #include #include #include namespace boost { namespace gil { /// \brief Returns the reference proxy associated with a type that has a \p "reference" member type alias. /// /// The reference proxy is the reference type, but with stripped-out C++ reference. It models PixelConcept template struct pixel_proxy : public remove_reference {}; /// \brief std::for_each for a pair of iterators template BinaryFunction for_each(Iterator1 first1,Iterator1 last1,Iterator2 first2,BinaryFunction f) { while(first1!=last1) f(*first1++,*first2++); return f; } template inline DstIterator assign_pixels(SrcIterator src,SrcIterator src_end,DstIterator dst) { for_each(src,src_end,dst,pixel_assigns_t::value_type>::type, typename pixel_proxy::value_type>::type>()); return dst+(src_end-src); } namespace detail { template struct inner_product_k_t { template static _Tp apply(_InputIterator1 __first1, _InputIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) { __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); return inner_product_k_t::template apply(__first1+1,__first2+1,__init, __binary_op1, __binary_op2); } }; template <> struct inner_product_k_t<0> { template static _Tp apply(_InputIterator1 __first1, _InputIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) { return __init; } }; } // namespace detail /// static version of std::inner_product template BOOST_FORCEINLINE _Tp inner_product_k(_InputIterator1 __first1, _InputIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) { return detail::inner_product_k_t::template apply(__first1,__first2,__init, __binary_op1, __binary_op2); } /// \brief 1D un-guarded correlation with a variable-size kernel template inline DstIterator correlate_pixels_n(SrcIterator src_begin,SrcIterator src_end, KernelIterator ker_begin,Integer ker_size, DstIterator dst_begin) { using PIXEL_SRC_REF = typename pixel_proxy::value_type>::type; using PIXEL_DST_REF = typename pixel_proxy::value_type>::type; using kernel_type = typename std::iterator_traits::value_type; PixelAccum acc_zero; pixel_zeros_t()(acc_zero); while(src_begin!=src_end) { pixel_assigns_t()( std::inner_product(src_begin,src_begin+ker_size,ker_begin,acc_zero, pixel_plus_t(), pixel_multiplies_scalar_t()), *dst_begin); ++src_begin; ++dst_begin; } return dst_begin; } /// \brief 1D un-guarded correlation with a fixed-size kernel template inline DstIterator correlate_pixels_k(SrcIterator src_begin,SrcIterator src_end, KernelIterator ker_begin, DstIterator dst_begin) { using PIXEL_SRC_REF = typename pixel_proxy::value_type>::type; using PIXEL_DST_REF = typename pixel_proxy::value_type>::type; using kernel_type = typename std::iterator_traits::value_type; PixelAccum acc_zero; pixel_zeros_t()(acc_zero); while(src_begin!=src_end) { pixel_assigns_t()( inner_product_k(src_begin,ker_begin,acc_zero, pixel_plus_t(), pixel_multiplies_scalar_t()), *dst_begin); ++src_begin; ++dst_begin; } return dst_begin; } /// \brief destination is set to be product of the source and a scalar template inline void view_multiplies_scalar(const SrcView& src,const Scalar& scalar,const DstView& dst) { BOOST_ASSERT(src.dimensions() == dst.dimensions()); using PIXEL_SRC_REF = typename pixel_proxy::type; using PIXEL_DST_REF = typename pixel_proxy::type; int height=src.height(); for(int rr=0;rr()( pixel_multiplies_scalar_t()(*it_src,scalar), *it_dst); ++it_src; ++it_dst; } } } }} // namespace boost::gil #endif