Filter Library Camera Interface Physics

ScanFilterMath.cpp

00001 /*
00002  * ScanFilterMath.h - math filter.
00003  *
00004  * This file is part of the Camera Filter Library.
00005  * Computer Aided Measurement Environment for Realtime Atomic imaging (Camera)
00006  *
00007  * Copyright (C) 2004-2005, Leiden Probe Microscopy.
00008  * Copyright (C) 2004-2005, Universiteit Leiden.
00009  *
00010  * Authors: M. Seynen (original), Martin J. Moene
00011  *
00012  * $Id: ScanFilterMath.cpp 400 2006-09-28 13:34:02Z moene $
00013  */
00014 
00015 /*
00016  * configuration defines:
00017  */
00018 
00019 // currently nothing
00020 
00021 /*
00022  * end of configuration defines.
00023  */
00024 
00025 #include "stdafx.h"                     // for common (pre-compiled) headers
00026 //#include <cfl/stdafx.h>                 // for common (pre-compiled) headers
00027 #include <cfl/resource.h>               // for dialog resources
00028 
00029 #include <cfl/FilterDlg_Math.h>         // for class CFilterDlg_Math
00030 #include <cfl/ScanFilterMath.h>         // for class CScanFilterMath
00031 
00032 #pragma warning( disable: 4018 4100 4116 4146 4244 4663)
00033 #include <cil/Math.h>                   // for lpm::min()
00034 #pragma warning( default: 4018 4100 4116 4146 4244 4663)
00035 
00036 #include <algorithm>                    // for std::transform()
00037 
00038 #ifdef _DEBUG
00039 #undef THIS_FILE
00040 static char THIS_FILE[]=__FILE__;
00041 #define new DEBUG_NEW
00042 #endif
00043 
00044 #define CFL_SCHEMAVERSION_FILTERMATH 0          // permanent storage schema version
00045                                                 // this filter's name
00046 LPCTSTR CScanFilterMath::m_lpcsFilterName = _T("Math");
00047                                         // this filter's short name
00048 LPCTSTR CScanFilterMath::m_lpcsShortFilterName = CScanFilterMath::m_lpcsFilterName;
00049                                                 // serialization
00050 IMPLEMENT_SERIAL( CScanFilterMath, CScanFilter, CFL_SCHEMAVERSION_FILTERMATH )
00051 
00052 /*
00053  * default math operation: a - b.
00054  */
00055 const CScanFilterMath::MathOperationType CScanFilterMath::def_MathOperation = MATH_SUBAB;
00056 
00057 /*
00058  * constructor.
00059  */
00060 CScanFilterMath::CScanFilterMath() :
00061    m_lpsbIn2( NULL ),
00062    m_MathOperation( def_MathOperation )
00063 {
00064    m_csFilterName = m_lpcsFilterName;
00065 
00066    ReadFilterSettings();
00067 }
00068 
00069 /*
00070  * destructor.
00071  */
00072 CScanFilterMath::~CScanFilterMath()
00073 {
00074 //   Q_LOG( _T("CScanFilterMath::~CScanFilterMath()") );
00075 
00076    ; // do nothing
00077 }
00078 
00079 /*
00080  * store or retrieve the object's settings;
00081  * see also CScanFilterNull::Serialize().
00082  */
00083 void CScanFilterMath::Serialize(CArchive& ar)
00084 {
00085    CScanFilter::Serialize( ar );
00086 
00087    if ( ar.IsStoring() )
00088    {
00089       ar << static_cast< int >( m_MathOperation );
00090    }
00091    else
00092    {
00093       int op;
00094       ar >> op; m_MathOperation = static_cast< MathOperationType >( op );
00095    }
00096 };
00097 
00098 /*
00099  * \brief configure filter with settings as provided by the application on the
00100  * filterlist window (e.g. via registry); see also CScanFilterNull::ReadFilterSettings().
00101  */
00102 void CScanFilterMath::ReadFilterSettings()
00103 {
00104 //   Q_LOG( _T("CScanFilterMath::ReadFilterSettings()") );
00105 
00106    CWinApp* pApp = AfxGetApp();
00107 
00108    if ( Q_INVALID( NULL == pApp ) )
00109       return ;
00110 
00111    /*
00112     * parameter string:
00113     */
00114    SetParameters( pApp->GetProfileString( gCflRegistrySubkey, m_lpcsFilterName, _T( "0" ) ) );
00115 }
00116 
00117 /*
00118  * \brief save filter settings e.g. for use with the filterlist window (e.g. via registry);
00119  * see also ReadFilterSettings().
00120  */
00121 void CScanFilterMath::WriteFilterSettings() const
00122 {
00123 //   Q_LOG( _T("CScanFilterMath::WriteFilterSettings()") );
00124 
00125    CWinApp* pApp = AfxGetApp();
00126 
00127    if ( Q_INVALID( NULL == pApp ) )
00128       return ;
00129 
00130    /*
00131     * parameter string:
00132     */
00133    LPCTSTR pStr = GetParameters();
00134 
00135    if ( pStr )
00136    {
00137       pApp->WriteProfileString( gCflRegistrySubkey, m_lpcsFilterName, pStr );
00138       delete const_cast<LPTSTR>( pStr );
00139    }
00140 }
00141 
00142 /*
00143  * provide current filter parameter(s) for filter-scripting capture
00144  * in the main application;
00145  * see also CScanFilterNull::GetParameters().
00146  */
00147 LPCTSTR CScanFilterMath::GetParameters() const
00148 {
00149 //   Q_LOG( _T("CScanFilterMath::GetParameters()") );
00150 
00151    /*
00152     * format parameters and return a c-string on the heap:
00153     */
00154    CString csParameters;
00155 
00156    csParameters.Format( _T( "%d" ), m_MathOperation );
00157 
00158    return strcpy( new TCHAR[ csParameters.GetLength() + 1 ], csParameters );
00159 }
00160 
00161 /*
00162  * set parameters for filter-script execution of filter;
00163  * see also CScanFilterNull::SetParameters().
00164  */
00165 BOOL CScanFilterMath::SetParameters( LPCTSTR lpParameters )
00166 {
00167 //   Q_LOG( _T("CScanFilterMath::SetParameters()") );
00168 
00169    if ( Q_INVALID( NULL == lpParameters && "CScanFilterMath (SetParameters): parameters expected, none provided (NULL).") )
00170    {
00171       return FALSE;
00172    }
00173 
00174    /*
00175     * set defaults, read parameter string with factor and optional offset:
00176     */
00177    m_MathOperation = def_MathOperation;
00178 
00179    int nfields = _stscanf( lpParameters, _T( "%d" ), &m_MathOperation );
00180 
00181    if ( Q_INVALID( 1 > nfields && "CScanFilterMath (SetParameters): math operation expected, got none." ) )
00182    {
00183       return FALSE;
00184    }
00185 
00186    return TRUE;
00187 }
00188 
00189 /**
00190  * the number of input buffers.
00191  */
00192 DWORD CScanFilterMath::GetNrOfInBuffers() const
00193 {
00194 //   Q_LOG( _T("CScanFilterMath::SetParameters()") );
00195 
00196    return 2;
00197 }
00198 
00199 /**
00200  * return the requested input buffer.
00201  */
00202 CScanBaseBuffer *CScanFilterMath::GetInputBuffer( UINT nNr )
00203 {
00204 //   Q_LOG( _T("CScanFilterMath::GetInputBuffer()") );
00205 
00206    Q_ASSERT( 0 <= nNr && nNr < GetNrOfInBuffers() && "ensure valid input buffer nr" );
00207 
00208    if ( 1 == nNr )
00209    {
00210       return m_lpsbIn2;
00211    }
00212 
00213    return m_lpsbIn;
00214 }
00215 
00216 /**
00217  * set the given input buffer.
00218  */
00219 void CScanFilterMath::SetInputBuffer( UINT nNr, CScanBaseBuffer *lpsbIn )
00220 {
00221 //   Q_LOG( _T("CScanFilterMath::SetInputBuffer()") );
00222 
00223    Q_ASSERT( 0 <= nNr && nNr < GetNrOfInBuffers() && "ensure valid input buffer nr" );
00224    Q_ASSERT( NULL != lpsbIn && "ensure valid input buffer" );
00225 
00226    if ( 0 == nNr )
00227    {
00228       m_lpsbIn = lpsbIn;
00229    }
00230    else if ( 1 == nNr )
00231    {
00232       m_lpsbIn2 = lpsbIn;
00233    }
00234 }
00235 
00236 /*
00237  * create filter dialog and pre Apply() filter to view result;
00238  * see also CScanFilterNull::RunModeless().
00239  */
00240 BOOL CScanFilterMath::RunModeless( CWnd* pParentWnd, CDocument* pDoc )
00241 {
00242 //   Q_LOG( _T("CScanFilterMath::RunModeless()") );
00243 
00244    CFilterDlg_MathPtr pDlg = new CFilterDlg_Math();
00245 
00246    if ( Q_INVALID( NULL == pDlg ) )
00247       return FALSE;
00248 
00249    pDlg->SetParameters( this, pDoc );   // (void) method
00250 
00251    /*
00252     * Create returns non-zero if dialog was created and initialized succesfully.
00253     * Note: no pDlg->DestroyWindow() must be done.
00254     */
00255    pDlg->Create( IDD_FILTERDLG_MATH, pParentWnd );
00256 
00257    m_pDlg = pDlg;
00258 
00259    BOOL bRet = Apply();
00260 
00261    if ( bRet )
00262    {
00263       pDlg->UpdateView();
00264    }
00265 
00266    return bRet;
00267 }
00268 
00269 /*
00270  * check parameters, take care of a properly sized output buffer,
00271  * set its name and copy filter parameters and process;
00272  * see also CScanFilterNull::ApplyCore().
00273  */
00274 BOOL CScanFilterMath::Apply()
00275 {
00276 //   Q_LOG( _T("CScanFilterMath::Apply()") );
00277 
00278    if ( Q_INVALID( NULL == m_lpsbIn && "ensure first input buffer") )
00279       return FALSE;
00280 
00281    if ( Q_INVALID( NULL == m_lpsbIn2 && "ensure second input buffer" ) )
00282       return FALSE;
00283 
00284    if ( Q_INVALID( NULL == m_lpsbOut && "ensure output buffer" ) )
00285       return FALSE;
00286 
00287    if ( Q_INVALID( !m_lpsbIn->IsCompleteFrame() && "ensure complete frame" ) )
00288       return FALSE;
00289 
00290    /*
00291     * copy the filter settings (not the data):
00292     */
00293    Q_RETURN( m_lpsbOut->CreateOutputBufferFor( *m_lpsbIn ) );
00294 
00295    m_lpsbOut->m_csBufferName.Format( _T("%s - %s"), m_lpsbIn->m_csBufferName, m_lpcsShortFilterName );
00296 
00297    if ( IsInteractive() )
00298    {
00299       m_pDlg->SetDlgItemText( IDC_BUFFERINNAME2, m_lpsbIn2->m_csBufferName );
00300       m_pDlg->SetDlgItemText( IDC_BUFFEROUTNAME, m_lpsbOut->m_csBufferName );
00301    }
00302 
00303    /*
00304     * limit buffer access to the smallest one: this also handles backtrace removal:
00305     */
00306    SizeElementType size = lpm::min( m_lpsbIn->GetFrameSize(), m_lpsbIn2->GetFrameSize(), m_lpsbOut->GetFrameSize() );
00307 
00308    /*
00309     * process first part (L2R):
00310     */
00311    Process(
00312       m_lpsbIn->Data(),
00313       m_lpsbIn->Data() + size,
00314       m_lpsbIn2->Data(),
00315       m_lpsbOut->Data()
00316    );
00317 
00318    /*
00319     * if we have a double buffer, L2R and R2L, process that part too.
00320     */
00321    if ( m_lpsbIn->IsBidirectionalScan() && m_lpsbIn2->IsBidirectionalScan() && m_lpsbOut->IsBidirectionalScan() )
00322    {
00323       Process(
00324          m_lpsbIn->Data()  + m_lpsbIn->GetFrameSize(),
00325          m_lpsbIn->Data()  + m_lpsbIn->GetFrameSize() + size,
00326          m_lpsbIn2->Data() + m_lpsbIn2->GetFrameSize(),
00327          m_lpsbOut->Data() + m_lpsbOut->GetFrameSize()
00328       );
00329    }
00330 
00331    /*
00332     * recalculate all temporary information:
00333     */
00334    m_lpsbOut->m_dwParameterMask = 0;
00335 
00336    return TRUE;
00337 }
00338 
00339 /**
00340  * anonymous namespace to hide class AddOp, SubOp, InvSubOp from other modules:
00341  */
00342 namespace
00343 {
00344    /**
00345     * binary functor to perform calculation on a + b in std::transform.
00346     */
00347    template <typename T>
00348    class AddOp : public std::binary_function<T, T, T>
00349    {
00350    public:
00351       /**
00352        * visit elements; return a + b.
00353        */
00354       inline T operator()( const T a, const T b ) const { return static_cast<T>( a + b ); }
00355    };
00356 
00357    /**
00358     * unary functor to perform calculation a - b in std::transform.
00359     */
00360    template <typename T>
00361    class SubOp : public std::binary_function<T, T, T>
00362    {
00363    public:
00364       /**
00365        * visit elements; return a - b.
00366        */
00367       inline T operator()( const T a, const T b ) const { return static_cast<T>( a - b ); }
00368    };
00369 
00370    /**
00371     * unary functor to perform calculation b - a in std::transform.
00372     */
00373    template <typename T>
00374    class InvSubOp : public std::binary_function<T, T, T>
00375    {
00376    public:
00377       /**
00378        * visit elements; return b - a.
00379        */
00380       inline T operator()( const T a, const T b ) const { return static_cast<T>( b - a ); }
00381    };
00382 
00383    /**
00384     * binary functor to perform calculation on a * b in std::transform.
00385     */
00386    template <typename T>
00387    class MulOp : public std::binary_function<T, T, T>
00388    {
00389    public:
00390       /**
00391        * visit elements; return a + b.
00392        */
00393       inline T operator()( const T a, const T b ) const { return static_cast<T>( a * b ); }
00394    };
00395 
00396 }  // end anonymous namespace
00397 
00398 /*
00399  * apply the operation to the buffers.
00400  */
00401 void CScanFilterMath::Process( ConstPointer in1, ConstPointer end1, ConstPointer in2, Pointer out )
00402 {
00403    switch( m_MathOperation )
00404    {
00405       case MATH_ADD:
00406          std::transform( in1, end1, in2, out, AddOp< ValueType >() );
00407          break;
00408 
00409       case MATH_SUBAB:
00410          std::transform( in1, end1, in2, out, SubOp< ValueType >() );
00411          break;
00412 
00413       case MATH_SUBBA:
00414          std::transform( in1, end1, in2, out, InvSubOp< ValueType >() );
00415          break;
00416 
00417       case MATH_MUL:
00418          std::transform( in1, end1, in2, out, MulOp< ValueType >() );
00419          break;
00420 
00421    };
00422 }
00423 
00424 /*
00425  * end of file
00426  */
00427 

Camera Filter Library documentation © 2004-2007 by Leiden Probe Microscopy