TuttleOFX
1
|
00001 #ifndef _TERRY_SAMPLER_LANCZOS_HPP_ 00002 #define _TERRY_SAMPLER_LANCZOS_HPP_ 00003 00004 #include "details.hpp" 00005 00006 #include <boost/math/constants/constants.hpp> 00007 00008 #include <cmath> 00009 #include <limits> 00010 00011 #define TUTTLE_PI boost::math::constants::pi<RESAMPLING_CORE_TYPE>() 00012 00013 namespace terry { 00014 using namespace boost::gil; 00015 namespace sampler { 00016 00017 // source: http://src.chromium.org/svn/trunk/src/skia/ext/image_operations.cc 00018 00019 // Evaluates the Lanczos filter of the given filter size window for the given 00020 // position. 00021 // 00022 // |filter_size| is the width of the filter (the "window"), outside of which 00023 // the value of the function is 0. Inside of the window, the value is the 00024 // normalized sinc function: 00025 // lanczos(x) = sinc(x) * sinc(x / filter_size); 00026 // where 00027 // sinc(x) = sin(pi*x) / (pi*x); 00028 00029 //float EvalLanczos(int filter_size, float x) { 00030 // if (x <= -filter_size || x >= filter_size) 00031 // return 0.0f; // Outside of the window. 00032 // if (x > -std::numeric_limits<float>::epsilon() && 00033 // x < std::numeric_limits<float>::epsilon()) 00034 // return 1.0f; // Special case the discontinuity at the origin. 00035 // float xpi = x * static_cast<float>( boost::math::constants::pi<float>() ); 00036 // return (sin(xpi) / xpi) * // sinc(x) 00037 // sin(xpi / filter_size) / (xpi / filter_size); // sinc(x/filter_size) 00038 //} 00039 00040 struct lanczos_sampler{ 00041 const size_t _windowSize; 00042 const RESAMPLING_CORE_TYPE _sharpen; 00043 00044 lanczos_sampler( std::size_t filterSize, RESAMPLING_CORE_TYPE sharpen ) : 00045 _windowSize ( filterSize * 2 ), 00046 _sharpen ( sharpen ) 00047 { 00048 } 00049 00050 RESAMPLING_CORE_TYPE sinc( RESAMPLING_CORE_TYPE x ) 00051 { 00052 if ( x > -std::numeric_limits<RESAMPLING_CORE_TYPE>::epsilon() && 00053 x < std::numeric_limits<RESAMPLING_CORE_TYPE>::epsilon() ) 00054 { 00055 // Special case the discontinuity at the origin. 00056 return 1.f; 00057 } 00058 RESAMPLING_CORE_TYPE xpi = x * TUTTLE_PI; 00059 return sinf( xpi ) / ( xpi ); 00060 } 00061 00062 template<typename Weight> 00063 void operator()( const RESAMPLING_CORE_TYPE& distance, Weight& weight ) 00064 { 00065 weight = sinc( distance ) * sinc( _sharpen * distance / _windowSize ); 00066 } 00067 }; 00068 00069 struct lanczos3_sampler : public lanczos_sampler 00070 { 00071 lanczos3_sampler() : 00072 lanczos_sampler( 3.0, 1.0 ) 00073 { 00074 } 00075 }; 00076 00077 struct lanczos4_sampler : public lanczos_sampler 00078 { 00079 lanczos4_sampler() : 00080 lanczos_sampler( 4.0, 1.0 ) 00081 { 00082 } 00083 }; 00084 00085 struct lanczos6_sampler : public lanczos_sampler 00086 { 00087 lanczos6_sampler() : 00088 lanczos_sampler( 6.0, 1.0 ) 00089 { 00090 } 00091 }; 00092 00093 struct lanczos12_sampler : public lanczos_sampler 00094 { 00095 lanczos12_sampler() : 00096 lanczos_sampler( 12.0, 1.0 ) 00097 { 00098 } 00099 }; 00100 00101 } 00102 } 00103 00104 #endif 00105