"L. Spiro Engine"

F:/My Projects/LSEngine/Modules/LSImageLib/Src/Resampler/LSIResampler.h

00001 
00017 #ifndef __LSI_RESAMPLER_H__
00018 #define __LSI_RESAMPLER_H__
00019 
00020 #include "../LSIImageLib.h"
00021 
00022 namespace lsi {
00023 
00031         class CResampler {
00032         public :
00033                 // == Various constructors.
00034                 LSE_CALLCTOR                                                            CResampler();
00035                 LSE_CALLCTOR                                                            ~CResampler();
00036 
00037 
00038                 // == Enumerations.
00042                 enum {
00043                         LSI_MAX_SCANLINE                                                = 16384
00044                 };
00045 
00046 
00047                 // == Types.
00051                 typedef struct LSI_CONTRIB {
00055                         LSFLOAT                                                                 fWeight;
00056 
00060                         LSUINT16                                                                ui16Value;
00061                 } * LPLSI_CONTRIB, * const LPCLSI_CONTRIB;
00062 
00066                 typedef struct LSI_CONTRIB_EX {
00070                         LSI_CONTRIB *                                                   pcValues;
00071 
00075                         LSUINT32                                                                ui32N;
00076                 } * LPLSI_CONTRIB_EX, * const LPCLSI_CONTRIB_EX;
00077 
00081                 typedef struct LSI_CONTRIB_LIST {
00085                         CVectorPoD<LSI_CONTRIB, LSUINT32>               vPool;
00086 
00090                         CVectorPoD<LSI_CONTRIB_EX, LSUINT32>    vList;
00091                 } * LPLSI_CONTRIB_LIST, * const LPCLSI_CONTRIB_LIST;
00092 
00096                 typedef struct LSI_SCANLINE {
00100                         LSFLOAT *                                                               pfScanBufL[LSI_MAX_SCANLINE];
00101 
00105                         LSINT32                                                                 i32ScanBufY[LSI_MAX_SCANLINE];
00106                 } * LPLSI_SCANLINE, * const LPCLSI_SCANLINE;
00107 
00114                 typedef LSFLOAT (LSE_CALL *                                     PfFilterFunc)( LSFLOAT _fT );
00115 
00119                 typedef struct LSI_FILTER {
00123                         const LSCHAR *                                                  pcName;
00124 
00128                         PfFilterFunc                                                    pfFunc;
00129 
00133                         LSFLOAT                                                                 pfSupport;
00134                 } * LPLSI_FILTER, * const LPCLSI_FILTER;
00135 
00136 
00137                 // == Functions.
00155                 LSSTD_ERRORS LSE_CALL                                           InitResampler( LSUINT32 _ui32SrcWidth, LSUINT32 _ui32SrcHeight,
00156                         LSUINT32 _ui32DstWidth, LSUINT32 _ui32DstHeight,
00157                         LSFLOAT _fSampleLow = 0.0f, LSFLOAT _fSampleHi = 1.0f,
00158                         const LSCHAR * _pcFilter = "lanczos4",
00159                         LSI_CONTRIB_LIST * _pclContX = NULL,
00160                         LSI_CONTRIB_LIST * _pclContY = NULL,
00161                         LSFLOAT _fFilterScaleX = 1.0f,
00162                         LSFLOAT _fFilterScaleY = 1.0f,
00163                         CVectorPoD<LSFLOAT, LSUINT32> * _pvDstBuffer = NULL );
00164 
00170                 LSI_CONTRIB_LIST * LSE_CALL                                     GetContribX();
00171 
00177                 LSI_CONTRIB_LIST * LSE_CALL                                     GetContribY();
00178 
00185                 LSBOOL LSE_CALL                                                         AddScanLine( const LSFLOAT * _pfScanline );
00186 
00192                 const CVectorPoD<LSFLOAT, LSUINT32> * LSE_CALL
00193                                                                                                         GetScanLine();
00194 
00195 
00196         protected :
00197                 // == Types.
00201                 typedef struct LSI_CONTRIB_BOUNDS {
00205                         LSFLOAT                                                                 fCenter;
00206 
00210                         LSINT32                                                                 i32Left;
00211 
00215                         LSINT32                                                                 i32Right;
00216                 } * LPLSI_CONTRIB_BOUNDS, * const LPCLSI_CONTRIB_BOUNDS;
00217                 
00218                 // == Members.
00222                 LSI_CONTRIB_LIST *                                                      m_pclContribsX;
00223 
00227                 LSI_CONTRIB_LIST *                                                      m_pclContribsY;
00228 
00232                 LSI_FILTER *                                                            m_pfFilter;
00233 
00237                 LSBOOL                                                                          m_bBorrowedX;
00238 
00242                 LSBOOL                                                                          m_bBorrowedY;
00243 
00247                 LSFLOAT                                                                         m_fLow;
00248 
00252                 LSFLOAT                                                                         m_fHi;
00253 
00257                 LSUINT32                                                                        m_ui32SrcWidth;
00258 
00262                 LSUINT32                                                                        m_ui32SrcHeight;
00263 
00267                 LSUINT32                                                                        m_ui32DstWidth;
00268 
00272                 LSUINT32                                                                        m_ui32DstHeight;
00273 
00277                 LSUINT32                                                                        m_ui32CurSrcY;
00278 
00282                 LSUINT32                                                                        m_ui32CurDstY;
00283 
00287                 LSUINT32                                                                        m_ui32IntermX;
00288 
00292                 LSBOOL                                                                          m_bDelayX;
00293 
00297                 mutable CVectorPoD<LSINT32, LSUINT32>           m_vSrcCountY;
00298 
00302                 mutable CVectorPoD<LSUINT8, LSUINT32>           m_vSrcFlagsY;
00303 
00307                 CVectorPoD<LSFLOAT, LSUINT32> *                         m_pvDstBuffer;
00308 
00312                 mutable CVectorPoD<LSFLOAT, LSUINT32>           m_vTempBuffer;
00313 
00317                 LSI_SCANLINE *                                                          m_psScanBuffer;
00318 
00322                 CVectorPoD<LSFLOAT, LSUINT32>                           m_vScanBufferChunk;
00323 
00327                 LSUINT32                                                                        m_ui32ScanChunkPos;
00328 
00332                 LSUINT32                                                                        m_ui32LastSearchPos;
00333 
00337                 static LSI_FILTER                                                       m_fFilters[];
00338 
00339 
00340                 // == Functions.
00347                 LSVOID LSE_CALL                                                         ResampleX( LSFLOAT * _pfDst, const LSFLOAT * _pfSrc ) const;
00348 
00354                 LSVOID LSE_CALL                                                         ResampleY( CVectorPoD<LSFLOAT, LSUINT32> &_vDst ) const;
00355 
00364                 static LSVOID LSE_CALL                                          ScaleY( CVectorPoD<LSFLOAT, LSUINT32> &_pfDst, const LSFLOAT * _pfSrc, LSFLOAT _fScale, LSUINT32 _ui32Total );
00365 
00374                 static LSVOID LSE_CALL                                          ScaleYAdd( CVectorPoD<LSFLOAT, LSUINT32> &_pfDst, const LSFLOAT * _pfSrc, LSFLOAT _fScale, LSUINT32 _ui32Total );
00375 
00384                 static LSVOID LSE_CALL                                          ClampSamples( LSFLOAT * _pfSamples, LSUINT32 _ui32Total, LSFLOAT _fLo, LSFLOAT _fHi );
00385 
00396                 static LSI_CONTRIB_LIST *                                       CreateContribList( LSUINT32 _ui32SrcSize, LSUINT32 _ui32DstSize,
00397                         PfFilterFunc _pfFilter, LSFLOAT _fFilterSupport, LSFLOAT _fFilterScale );
00398 
00406                 static LSINT32 LSE_CALL                                         ClampTexel( LSINT32 _i32TexelPos, LSUINT32 _ui32Size );
00407 
00414                 static LSUINT32 LSE_CALL                                        CountOps( const LSI_CONTRIB_LIST &_clList );
00415 
00422                 static LSE_INLINE LSFLOAT LSE_CALL                      Clean( LSDOUBLE _dVal );
00423 
00432                 static LSE_INLINE LSDOUBLE LSE_CALL                     KaiserHelper( LSDOUBLE _dAlpha, LSDOUBLE _dHalfWidth, LSDOUBLE _dX );
00433 
00442                 static LSE_INLINE LSFLOAT LSE_CALL                      MitchellFilterHelper( LSFLOAT _fT, LSFLOAT _fB, LSFLOAT _fC );
00443 
00450                 static LSE_INLINE LSDOUBLE LSE_CALL                     Bessel0( LSDOUBLE _dX );
00451 
00458                 static LSE_INLINE LSDOUBLE LSE_CALL                     SinC( LSDOUBLE _dX );
00459 
00466                 static LSFLOAT LSE_CALL                                         BoxFilterFunc( LSFLOAT _fT );
00467 
00474                 static LSFLOAT LSE_CALL                                         BilinearFilterFunc( LSFLOAT _fT );
00475 
00482                 static LSFLOAT LSE_CALL                                         KaiserFilterFunc( LSFLOAT _fT );
00483 
00490                 static LSFLOAT LSE_CALL                                         Lanczos3FilterFunc( LSFLOAT _fT );
00491 
00498                 static LSFLOAT LSE_CALL                                         Lanczos4FilterFunc( LSFLOAT _fT );
00499 
00506                 static LSFLOAT LSE_CALL                                         Lanczos6FilterFunc( LSFLOAT _fT );
00507 
00514                 static LSFLOAT LSE_CALL                                         Lanczos8FilterFunc( LSFLOAT _fT );
00515 
00522                 static LSFLOAT LSE_CALL                                         Lanczos12FilterFunc( LSFLOAT _fT );
00523 
00530                 static LSFLOAT LSE_CALL                                         Lanczos64FilterFunc( LSFLOAT _fT );
00531 
00538                 static LSFLOAT LSE_CALL                                         MitchellFilterFunc( LSFLOAT _fT );
00539 
00546                 static LSFLOAT LSE_CALL                                         CatmullRomFilterFunc( LSFLOAT _fT );
00547         };
00548 
00549 
00550         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00551         // DEFINITIONS
00552         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00553         // == Functions.
00560          LSE_INLINE LSFLOAT LSE_CALL CResampler::Clean( LSDOUBLE _dVal ) {
00561                  static const LSDOUBLE dEps = 0.0000125;
00562                  return ::fabs( _dVal ) >= dEps ? static_cast<LSFLOAT>(_dVal) : 0.0f;
00563          }
00564 
00573          LSE_INLINE LSDOUBLE LSE_CALL CResampler::KaiserHelper( LSDOUBLE _dAlpha, LSDOUBLE _dHalfWidth, LSDOUBLE _dX ) {
00574                 const LSDOUBLE dRatio = _dX / _dHalfWidth;
00575                 return Bessel0( _dAlpha * ::sqrt( 1.0 - dRatio * dRatio ) ) / Bessel0( _dAlpha );
00576          }
00577 
00586          LSE_INLINE LSFLOAT LSE_CALL CResampler::MitchellFilterHelper( LSFLOAT _fT, LSFLOAT _fB, LSFLOAT _fC ) {
00587 
00588                 LSFLOAT fTt = _fT * _fT;
00589                 _fT = ::fabsf( _fT );
00590                 if ( _fT < 1.0f ) {
00591                         _fT = (((12.0f - 9.0f * _fB - 6.0f * _fC) * (_fT * fTt))
00592                                 + ((-18.0f + 12.0f * _fB + 6.0f * _fC) * fTt)
00593                                 + (6.0f - 2.0f * _fB));
00594                         return _fT / 6.0f;
00595                 }
00596                 else if ( _fT < 2.0f ) {
00597                         _fT = (((-1.0f * _fB - 6.0f * _fC) * (_fT * fTt))
00598                                 + ((6.0f * _fB + 30.0f * _fC) * fTt)
00599                                 + ((-12.0f * _fB - 48.0f * _fC) * _fT)
00600                                 + (8.0f * _fB + 24.0f * _fC));
00601 
00602                         return (_fT / 6.0f);
00603                 }
00604 
00605                 return 0.0f;
00606          }
00607 
00614          LSE_INLINE LSDOUBLE LSE_CALL CResampler::Bessel0( LSDOUBLE _dX ) {
00615                  static const LSDOUBLE dEspiRatio = 1.0e-16;
00616                  LSDOUBLE dSum = 1.0, dPow = 1.0, dDs = 1.0, dXh = _dX * 0.5;
00617                  LSUINT32 ui32K = 0;
00618 
00619                  while ( dDs > dSum * dEspiRatio ) {
00620                         ++ui32K;
00621                         dPow *= (dXh / ui32K);
00622                         dDs = dPow * dPow;
00623                         dSum += dDs;
00624                  }
00625 
00626                  return dSum;
00627          }
00628 
00635          LSE_INLINE LSDOUBLE LSE_CALL CResampler::SinC( LSDOUBLE _dX ) {
00636                 _dX *= LSM_PI_DOUBLE;
00637                 if ( _dX < 0.01 && _dX > -0.01 ) {
00638                         return 1.0 + _dX * _dX * (-1.0 / 6.0 + _dX * _dX * 1.0 / 120.0);
00639                 }
00640 
00641                 return ::sin( _dX ) / _dX;
00642          }
00643 
00644 }       // namespace lsi
00645 
00646 #endif  // __LSI_RESAMPLER_H__
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator