TuttleOFX  1
bc.hpp
Go to the documentation of this file.
00001 #ifndef _TERRY_SAMPLER_BC_HPP_
00002 #define _TERRY_SAMPLER_BC_HPP_
00003 
00004 #include "details.hpp"
00005 
00006 namespace terry {
00007 using namespace boost::gil;
00008 namespace sampler {
00009 
00010 struct bc_sampler
00011 {
00012         const size_t               _windowSize;
00013         const RESAMPLING_CORE_TYPE _valB;
00014         const RESAMPLING_CORE_TYPE _valC;
00015 
00016         bc_sampler() :
00017                 _windowSize ( 4.0 ), // 4 pixels:    A B C D
00018                 _valB       ( 0.0 ),
00019                 _valC       ( 0.0 )
00020         {
00021         }
00022 
00023         bc_sampler( RESAMPLING_CORE_TYPE valB, RESAMPLING_CORE_TYPE valC ) :
00024                 _windowSize ( 4.0  ), // 4 pixels:    A B C D
00025                 _valB       ( valB ),
00026                 _valC       ( valC )
00027         {
00028         }
00029 
00030         /**
00031          * @brief Get weight for a specific distance, for all BC-cubic resampling (bicubic, catmul-rom, ...).
00032          *
00033          * For compute cubic BC resampler weights, we use these functions
00034          * [ Reconstruction Filters in Computer Graphics,
00035          *   Don P. Mitchell, Arun N. Netravali,
00036          *   Computer Graphics - volume 22 number 4 - August 1988
00037          *   <a href="http://www.cs.utexas.edu/users/fussell/courses/cs384g/lectures/mitchell/Mitchell.pdf">online paper</a>
00038          * ]:
00039          *
00040          * \f[ W(x) =
00041          * \begin{cases}
00042          * (a+2)|x|^3-(a+3)|x|^2+1 & \text{for } |x| \leq 1 \\
00043          * a|x|^3-5a|x|^2+8a|x|-4a & \text{for } 1 < |x| < 2 \\
00044          * 0                       & \text{otherwise}
00045          * \end{cases}
00046          * \f]
00047          * @param[in] B value of B in BC-cubic resampling function
00048          * @param[in] C value of C in BC-cubic resampling function
00049          * @param[in] distance between the pixels and the current pixel
00050          * @param[out] weight return value to weight the pixel in filtering
00051         **/
00052         template<typename Weight>
00053         void operator()( const RESAMPLING_CORE_TYPE& distance, Weight& weight )
00054         {
00055                 RESAMPLING_CORE_TYPE absDistance = std::abs( (RESAMPLING_CORE_TYPE) distance );
00056                 if( absDistance <= 1.0 )
00057                 {
00058                         RESAMPLING_CORE_TYPE P =  12.0 -  9.0 * _valB - 6.0 * _valC;
00059                         RESAMPLING_CORE_TYPE Q = -18.0 + 12.0 * _valB + 6.0 * _valC;
00060                         RESAMPLING_CORE_TYPE S =   6.0 -  2.0 * _valB;
00061                         // note: R is null
00062                         weight = ( ( P * absDistance + Q ) *  absDistance * absDistance + S ) / 6.0;
00063                 }
00064                 else
00065                 {
00066                         if( absDistance < 2.0 )
00067                         {
00068                                 RESAMPLING_CORE_TYPE T = -        _valB -  6.0 * _valC;
00069                                 RESAMPLING_CORE_TYPE U =    6.0 * _valB + 30.0 * _valC;
00070                                 RESAMPLING_CORE_TYPE V = - 12.0 * _valB - 48.0 * _valC;
00071                                 RESAMPLING_CORE_TYPE W =    8.0 * _valB + 24.0 * _valC;
00072                                 weight = ( ( ( T * absDistance + U ) *  absDistance + V ) * absDistance + W ) / 6.0;
00073                                 return;
00074                         }
00075                         weight = 0.0;
00076                 }
00077         }
00078 };
00079 
00080 //
00081 // valC is equal to -a in the equation
00082 //
00083 struct cubic_sampler : bc_sampler
00084 {
00085         cubic_sampler() :
00086                 bc_sampler( 0.0, 0.0 )
00087         {
00088         }
00089         cubic_sampler( RESAMPLING_CORE_TYPE a ) :
00090                 bc_sampler( 0.0, -a )
00091         {
00092         }
00093 };
00094 
00095 struct bicubic_sampler : cubic_sampler
00096 {
00097         bicubic_sampler() : cubic_sampler ( 0.0 ) {}
00098 };
00099 
00100 // catmul-rom resampling function
00101 struct catrom_sampler : cubic_sampler
00102 {
00103         catrom_sampler() : cubic_sampler ( -0.5 ) {}
00104 };
00105 
00106 // equal to catrom resampling function
00107 struct keys_sampler : cubic_sampler
00108 {
00109         keys_sampler() : cubic_sampler ( -0.5 ) {}
00110 };
00111 
00112 
00113 struct simon_sampler : cubic_sampler
00114 {
00115         simon_sampler() : cubic_sampler ( -0.75 ) {}
00116 };
00117 
00118 
00119 struct rifman_sampler : cubic_sampler
00120 {
00121         rifman_sampler() : cubic_sampler ( -1.0 ) {}
00122 };
00123 
00124 struct mitchell_sampler : bc_sampler
00125 {
00126         mitchell_sampler() :
00127                 bc_sampler( 1.0 / 3.0, 1.0 / 3.0 )
00128         {
00129         }
00130 };
00131 
00132 struct parzen_sampler : bc_sampler
00133 {
00134         parzen_sampler() :
00135                 bc_sampler( 1.0, 0.0 )
00136         {
00137         }
00138 };
00139 
00140 }
00141 }
00142 
00143 #endif