TuttleOFX  1
ViewsMerging.hpp
Go to the documentation of this file.
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