Filter Library Camera Interface Physics

ScanFilterDZ.cpp

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

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