TuttleOFX
1
|
00001 #ifndef _TERRY_NUMERIC_MINMAX_HPP_ 00002 #define _TERRY_NUMERIC_MINMAX_HPP_ 00003 00004 #include <boost/gil/gil_config.hpp> 00005 #include <boost/gil/channel.hpp> 00006 00007 #include <functional> 00008 00009 namespace terry { 00010 namespace numeric { 00011 00012 using namespace boost::gil; 00013 00014 /// \ingroup ChannelNumericOperations 00015 /// \brief ch2 = min( ch1, ch2 ) 00016 /// structure for adding one channel to another 00017 /// this is a generic implementation; user should specialize it for better performance 00018 template <typename ChannelSrc, typename ChannelDst> 00019 struct channel_assign_min_t : public std::binary_function<ChannelSrc, ChannelDst, ChannelDst> 00020 { 00021 GIL_FORCEINLINE 00022 typename channel_traits<ChannelDst>::reference operator()( typename channel_traits<ChannelSrc>::const_reference ch1, 00023 typename channel_traits<ChannelDst>::reference ch2 ) const 00024 { 00025 return ch2 = std::min( ChannelDst( ch1 ), ch2 ); 00026 } 00027 }; 00028 00029 00030 /// \ingroup PixelNumericOperations 00031 /// \brief p2 = min( p1, p2 ) 00032 template <typename PixelSrc, // models pixel concept 00033 typename PixelDst> 00034 // models pixel value concept 00035 struct pixel_assign_min_t 00036 { 00037 GIL_FORCEINLINE 00038 PixelDst& operator()( const PixelSrc& p1, 00039 PixelDst& p2 ) const 00040 { 00041 static_for_each( p1, p2, 00042 channel_assign_min_t<typename channel_type<PixelSrc>::type, 00043 typename channel_type<PixelDst>::type>() ); 00044 return p2; 00045 } 00046 }; 00047 00048 00049 /// \ingroup ChannelNumericOperations 00050 /// \brief ch2 = max( ch1, ch2 ) 00051 /// this is a generic implementation; user should specialize it for better performance 00052 template <typename ChannelSrc, typename ChannelDst> 00053 struct channel_assign_max_t : public std::binary_function<ChannelSrc, ChannelDst, ChannelDst> 00054 { 00055 GIL_FORCEINLINE 00056 typename channel_traits<ChannelDst>::reference operator()( typename channel_traits<ChannelSrc>::const_reference ch1, 00057 typename channel_traits<ChannelDst>::reference ch2 ) const 00058 { 00059 return ch2 = std::max( ChannelDst( ch1 ), ch2 ); 00060 } 00061 }; 00062 00063 00064 /// \ingroup PixelNumericOperations 00065 /// \brief p2 = max( p1, p2 ) 00066 template <typename PixelSrc, // models pixel concept 00067 typename PixelDst> 00068 // models pixel value concept 00069 struct pixel_assign_max_t 00070 { 00071 GIL_FORCEINLINE 00072 PixelDst& operator()( const PixelSrc& p1, 00073 PixelDst& p2 ) const 00074 { 00075 static_for_each( p1, p2, 00076 channel_assign_max_t<typename channel_type<PixelSrc>::type, 00077 typename channel_type<PixelDst>::type>() ); 00078 return p2; 00079 } 00080 00081 }; 00082 00083 00084 template<typename CPixel> 00085 struct pixel_minmax_by_channel_t 00086 { 00087 typedef typename channel_type<CPixel>::type Channel; 00088 00089 CPixel min; 00090 CPixel max; 00091 00092 pixel_minmax_by_channel_t( const CPixel& v ) 00093 : min( v ) 00094 , max( v ) 00095 { 00096 } 00097 00098 template<typename Pixel> 00099 GIL_FORCEINLINE 00100 void operator()( const Pixel& v ) 00101 { 00102 pixel_assign_min_t<Pixel,CPixel>()( v, min ); 00103 pixel_assign_max_t<Pixel,CPixel>()( v, max ); 00104 } 00105 }; 00106 00107 00108 } 00109 } 00110 00111 #endif