TuttleOFX
1
|
00001 #ifndef _TERRY_VIEWS_MERGING_HPP_ 00002 #define _TERRY_VIEWS_MERGING_HPP_ 00003 00004 #include "MergeAbstractFunctor.hpp" 00005 00006 #include <boost/static_assert.hpp> 00007 #include <boost/gil/typedefs.hpp> 00008 #include <boost/gil/utilities.hpp> 00009 00010 namespace terry { 00011 00012 namespace detail { 00013 template<class OPERATES> 00014 struct merger {}; 00015 00016 template<> 00017 struct merger<merge_per_pixel> 00018 { 00019 template <class Pixel, class Functor> 00020 GIL_FORCEINLINE 00021 void operator()( const Pixel& A, const Pixel& B, Pixel& d, Functor& fun ) const 00022 { 00023 fun( A, B, d ); 00024 } 00025 }; 00026 00027 template<> 00028 struct merger<merge_per_channel_with_alpha> 00029 { 00030 template <class Pixel, class Functor> 00031 GIL_FORCEINLINE 00032 void operator()( const Pixel& A, const Pixel& B, Pixel& d, Functor& fun ) const 00033 { 00034 fun.a = alpha_or_max( A ); 00035 fun.b = alpha_or_max( B ); 00036 static_for_each( A, B, d, fun ); 00037 } 00038 00039 }; 00040 00041 template<> 00042 struct merger<merge_per_channel> 00043 { 00044 template <class Pixel, class Functor> 00045 GIL_FORCEINLINE 00046 void operator()( const Pixel& A, 00047 const Pixel& B, 00048 Pixel& d, 00049 Functor& fun ) const 00050 { 00051 static_for_each( A, B, d, fun ); 00052 } 00053 00054 }; 00055 } // end namespace detail 00056 00057 /** 00058 * @defgroup ViewsMerging 00059 * @brief Merge two views by means of a given functor. 00060 **/ 00061 template < class F, class View> 00062 void merge_views( const View& srcA, const View& srcB, View& dst, F fun ) 00063 { 00064 detail::merger<typename F::operating_mode_t> merge_op; 00065 // If merging functor needs alpha, check if destination contains alpha. 00066 typedef typename contains_color< typename View::value_type, alpha_t>::type has_alpha_t; 00067 // BOOST_STATIC_ASSERT(( boost::is_same<typename F::operating_mode_t, merge_per_channel_with_alpha>::value ? has_alpha_t::value : true )); 00068 00069 // Merge views. 00070 for( std::ptrdiff_t y = 0; y < dst.height(); ++y ) 00071 { 00072 typename View::x_iterator srcIt1 = srcA.row_begin( y ); 00073 typename View::x_iterator srcIt2 = srcB.row_begin( y ); 00074 typename View::x_iterator dstIt = dst.row_begin( y ); 00075 for( std::ptrdiff_t x = 0; x < dst.width(); ++x ) 00076 merge_op( srcIt1[x], srcIt2[x], dstIt[x], fun ); 00077 } 00078 } 00079 00080 } 00081 00082 #endif