TuttleOFX
1
|
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