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