Filter Library Camera Interface Physics

ScanFilterNull.cpp

00001 /*
00002  * // FIXME-ADAPT: filename and text
00003  * ScanFilterNull.cpp - a null filter to
00004  * (1) document general ascpects of filters, (2) act as a filter template.
00005  *
00006  * This file is part of the Camera Filter Library.
00007  * Computer Aided Measurement Environment for Realtime Atomic imaging (Camera)
00008  *
00009  * Copyright (C) 2004, Leiden Probe Microscopy.
00010  * Copyright (C) 2004, Universiteit Leiden.
00011  *
00012  * Authors: Martin J. Moene (original)
00013  *
00014  * $Id: ScanFilterNull.cpp 236 2005-06-27 09:03:17Z moene $
00015  */
00016 
00017 /*
00018  * configuration defines:
00019  */
00020 
00021 //#define NO_PARAMETERS                 // if Get/SetParameters() is not supported
00022 //#define NO_FILTER_SETTINGS            // if Get/WriteFilterSettings() is not supported
00023 
00024 /*
00025  * end of configuration defines.
00026  */
00027 
00028 /**
00029  * \todo: can do partial data?
00030  */
00031 
00032 /**
00033  * \todo change "stdafx.h" to <cfl/stdafx.h> when all filters have been adapted.
00034  * "stdafx.h" is used to determine the contents of the precompiled headers;
00035  * see prj settings C/C++, precompiled headers, through header "stdafx.h")
00036  */
00037 
00038 #include "stdafx.h"                     // for common (pre-compiled) headers
00039 //#include <cfl/stdafx.h>                 // for common (pre-compiled) headers
00040 #include <cfl/resource.h>               // for messages and other resources
00041 
00042 #include <Camera/InterfaceDll.h>        // Camera--Filter Library interface
00043 
00044 #include <cfl/ScanFilterNull.h>         // this filter's header
00045 #include <cfl/FilterDlg_Null.h>         // this filter's dialog
00046 
00047 #include <algorithm>                    // for STL std::transform()
00048 #include <functional>                   // for STL std::unary_function
00049 
00050 #ifdef _DEBUG
00051 #undef THIS_FILE
00052 static char THIS_FILE[]=__FILE__;
00053 #define new DEBUG_NEW
00054 #endif
00055 
00056 // FIXME-ADAPT: this filter's name 3x
00057                                         ///< permanent storage schema version
00058 #define CFL_SCHEMAVERSION_FILTERLINREG 0
00059                                         // this filter's name
00060 LPCTSTR CScanFilterNull::m_lpcsFilterName = _T( "Null" );
00061                                         // this filter's short name
00062 LPCTSTR CScanFilterNull::m_lpcsShortFilterName = CScanFilterNull::m_lpcsFilterName;
00063                                         // serialization
00064 IMPLEMENT_SERIAL( CScanFilterNull, CScanFilter, CFL_SCHEMAVERSION_FILTERLINREG )
00065 
00066 /*
00067  * default values: [out] = 1 x [in] + 0.
00068  */
00069 
00070 const double CScanFilterNull::def_dFactor = 1.0;
00071 const double CScanFilterNull::def_dOffset = 0.0;
00072 
00073 /**
00074  * default constructor: setup filter to run without dialog;
00075  * see also CScanFilterNull::CScanFilterNull().
00076  *
00077  * The constructor initializes the class' datamembers and prepares the filter to
00078  * run without dialog by calling ReadFilterSettings().
00079  *
00080  * For example:
00081  * \code
00082  * CScanFilterNull::CScanFilterNull() : CScanFilter( ),
00083  *    m_dFactor( def_dFactor ), m_dOffset( def_dOffset )
00084  * {
00085  *    m_csFilterName = m_lpcsFilterName;
00086  *
00087  *    ReadFilterSettings();      // get filter settings to run without dialog
00088  * }
00089  * \endcode
00090  *
00091  */
00092 
00093 CScanFilterNull::CScanFilterNull() : CScanFilter( ),
00094    m_dFactor( def_dFactor ), m_dOffset( def_dOffset )
00095 {
00096    m_csFilterName = m_lpcsFilterName;
00097 
00098    ReadFilterSettings();                 // get filter settings to run without dialog
00099 }
00100 
00101 /**
00102  * destructor.
00103  *
00104  * The destructor may have to release resources (e.g. memory) that the constructor
00105  * has allocated. In this specific case, the destructor does nothing;
00106  * however note that the base-class destructor (CScanFilter::~CScanFilter())
00107  * does some more work: it destroys the dialog if present.
00108  *
00109  * For example:
00110  * \code
00111  * CScanFilterNull::~CScanFilterNull()
00112  * {
00113  *    ; // do nothing
00114  * }
00115  * \endcode
00116  */
00117 
00118 CScanFilterNull::~CScanFilterNull()
00119 {
00120    ; // do nothing
00121 }
00122 
00123 /**
00124  * store or retrieve the object's settings;
00125  * currently filter serialization is not used;
00126  * see also CScanFilterNull::Serialize().
00127  *
00128  * This method lets you store the filter's settings to and retrieve them from an
00129  * archive. This process is called serialization.
00130  *
00131  * \note Currently filter serialization is not used.
00132  *
00133  * \param ar the archiver
00134  * \return void
00135  *
00136  * This is an example of how you may implement Serialize().
00137  * \code
00138  * // store or retrieve the object's settings.
00139  *
00140  * void CScanFilterNull::Serialize( CArchive& ar )
00141  * {
00142  *    CScanFilter::Serialize( ar );
00143  *
00144  *    if ( ar.IsStoring() )
00145  *    {
00146  *       ar << m_dFactor << m_dOffset;
00147  *    }
00148  *    else
00149  *    {
00150  *       ar >> m_dFactor >> m_dOffset;
00151  *    }
00152  * }
00153  * \endcode
00154  */
00155 
00156 void CScanFilterNull::Serialize( CArchive& ar )
00157 {
00158 // Q_LOG( _T("CScanFilterNull::Serialize") );
00159 
00160    CScanFilter::Serialize( ar );
00161 
00162    if ( ar.IsStoring() )
00163    {
00164       ar << m_dFactor << m_dOffset;
00165    }
00166    else
00167    {
00168       ar >> m_dFactor >> m_dOffset;
00169    }
00170 }
00171 
00172 #if 0
00173 /**
00174  * true if filter can process a data-selection in the buffer.
00175  */
00176 
00177 BOOL CScanFilterNull::CanDoPartialData() const
00178 {
00179    return TRUE;
00180 }
00181 #endif
00182 
00183 #if 0
00184 /**
00185  * true if a dialog can be used.
00186  */
00187 
00188 BOOL CScanFilterNull::CanDoDialogEntry() const
00189 {
00190    return FALSE;
00191 }
00192 #endif
00193 
00194 /**
00195  * \brief configure filter with settings as provided by the application on the
00196  * filterlist window (e.g. via registry); see also CScanFilterNull::ReadFilterSettings().
00197  *
00198  * This method obtains the filter setting as supplied by the application on the
00199  * filterlist window, for example via the registry, and initializes the filter
00200  * with these settings.
00201  *
00202  * ReadFilterSettings() is called from the constructor of the filter.
00203  *
00204  * A no-op example:
00205  * \code
00206  * void CScanFilterNull::ReadFilterSettings( )
00207  * {
00208  *    // Only few filters provide this method.
00209  * }
00210  * \endcode
00211  *
00212  * An if-used example:
00213  * \code
00214  * void CScanFilterNull::ReadFilterSettings( )
00215  * {
00216  *    CWinApp* pApp = AfxGetApp();
00217  *
00218  *    if ( Q_INVALID( NULL == pApp ) )
00219  *       return ;
00220  *
00221  *    //
00222  *    // parameter string: x-size,y-size,parameter,factor
00223  *    //
00224  *    SetParameters( pApp->GetProfileString( gCflRegistrySubkey, m_lpcsFilterName, _T( "1,0" ) ) );
00225  * }
00226  * \endcode
00227  */
00228 
00229 void CScanFilterNull::ReadFilterSettings( )
00230 {
00231 // Q_LOG( _T("CScanFilterNull::ReadFilterSettings()") );
00232 
00233 #ifdef NO_FILTER_SETTINGS
00234    /*
00235     * Only few filters provide this method.
00236     */
00237 #else
00238    CWinApp* pApp = AfxGetApp();
00239 
00240    if ( Q_INVALID( NULL == pApp ) )
00241       return ;
00242 
00243    /*
00244     * parameter string: x-size,y-size,parameter,factor
00245     */
00246    SetParameters( pApp->GetProfileString( gCflRegistrySubkey, m_lpcsFilterName, _T( "1,0" ) ) );
00247 #endif
00248 }
00249 
00250 /**
00251  * \brief save filter settings e.g. for use with the filterlist window (e.g. via registry);
00252  * see also ReadFilterSettings().
00253  *
00254  * A no-op example:
00255  * \code
00256  * void CScanFilterNull::WriteFilterSettings( ) const
00257  * {
00258  *    // Only few filters provide this method.
00259  * }
00260  * \endcode
00261  *
00262  * An if-used example:
00263  * \code
00264  * void CScanFilterNull::WriteFilterSettings( ) const
00265  * {
00266  *    CWinApp* pApp = AfxGetApp();
00267  *
00268  *    if ( Q_INVALID( NULL == pApp ) )
00269  *       return ;
00270  *
00271  *    //
00272  *    // parameter string: x-size,y-size,parameter,factor
00273  *    //
00274  *    LPCTSTR pStr = GetParameters();
00275  *
00276  *    if ( pStr )
00277  *    {
00278  *       pApp->WriteProfileString( gCflRegistrySubkey, m_lpcsFilterName, pStr );
00279  *       delete const_cast<LPTSTR>( pStr );
00280  *    }
00281  * }
00282  * \endcode
00283  */
00284 
00285 void CScanFilterNull::WriteFilterSettings() const
00286 {
00287 #ifdef NO_FILTER_SETTINGS
00288    /*
00289     * Only few filters provide this method.
00290     */
00291 #else
00292    CWinApp* pApp = AfxGetApp();
00293 
00294    if ( Q_INVALID( NULL == pApp ) )
00295       return ;
00296 
00297    /*
00298     * parameter string: x-size,y-size,parameter,factor
00299     */
00300    LPCTSTR pStr = GetParameters();
00301 
00302    if ( pStr )
00303    {
00304       pApp->WriteProfileString( gCflRegistrySubkey, m_lpcsFilterName, pStr );
00305       delete const_cast<LPTSTR>( pStr );
00306    }
00307 #endif
00308 }
00309 
00310 /**
00311  * provide current filter parameter(s) for filter-scripting capture
00312  * in the main application;
00313  * see also CScanFilterNull::GetParameters().
00314  *
00315  * Analogous to GetInitParameters(), this method returns filter parameters, in
00316  * this case for the filter-scripting capture operation in the main application.
00317  *
00318  * \return C-string with parameter values, e.g. "1.23,4.56"
00319  * \see GetInitParameters().
00320  * \note caller is responsible for \c delete-ing returned string storage.
00321  *
00322  * A no-op example:
00323  * \code
00324  * LPCTSTR CScanFilterNull::GetParameters( ) const
00325  * {
00326  *    // returns "no parameter values":
00327  *
00328  *    return NULL;
00329  * }
00330  * \endcode
00331  *
00332  * An if-used example:
00333  * \code
00334  * LPCTSTR CScanFilterNull::GetParameters( ) const
00335  * {
00336  *    // format parameters and return a c-string on the heap:
00337  *
00338  *    CString csParameters;
00339  *
00340  *    csParameters.Format( _T( "%g,%g" ), m_dFactor, m_dOffset );
00341  *
00342  *    return strcpy( new TCHAR[ csParameters.GetLength() + 1 ], csParameters );
00343  * }
00344  * \endcode
00345  */
00346 
00347 LPCTSTR CScanFilterNull::GetParameters( ) const
00348 {
00349 // Q_LOG( _T("CScanFilterNull::GetParameters()") );
00350 
00351 #ifdef NO_PARAMETERS
00352    /*
00353     * no-op:
00354     */
00355    return NULL;
00356 #else
00357    /*
00358     * format parameters and return a c-string on the heap:
00359     */
00360    CString csParameters;
00361 
00362    csParameters.Format( _T( "%g,%g" ), m_dFactor, m_dOffset );
00363 
00364    return strcpy( new TCHAR[ csParameters.GetLength() + 1 ], csParameters );
00365 #endif
00366 }
00367 
00368 /**
00369  * set parameters for filter-script execution of filter;
00370  * see also CScanFilterNull::SetParameters().
00371  *
00372  * This method initializes the filter parameters for filter-script execution of
00373  * the filter toe the parameters specified.
00374  *
00375  * \param lpParameters a C-string specifying the filter parameter values, e.g. "1.23,4.56".
00376  * \return TRUE (Success), FALSE (Failure)
00377  *
00378  * A not-supported example:
00379  * \code
00380  * BOOL CScanFilterNull::SetParameters( LPCTSTR lpParameters )
00381  * {
00382  *    // we do not expect any parameters, so say so:
00383  *
00384  *    if ( Q_INVALID ( NULL != lpParameters && 0 < ::strlen( lpParameters ) &&
00385  *       "CScanFilterNull (SetParameters): no parameters expected." ) )
00386  *    {
00387  *       return FALSE;
00388  *    }
00389  *
00390  *    return FALSE;
00391  * }
00392  * \endcode
00393  *
00394  * An if-used example:
00395  * \code
00396  * BOOL CScanFilterNull::SetParameters( LPCTSTR lpParameters )
00397  * {
00398  *    if ( Q_INVALID( NULL == lpParameters && 
00399  *           "CScanFilterNull (SetParameters): parameters expected, none provided (NULL).") )
00400  *    {
00401  *       return FALSE;
00402  *    }
00403  *
00404  *    // set defaults, read parameter string with factor and optional offset:
00405  *
00406  *    m_dFactor = def_dFactor;
00407  *    m_dOffset = def_dOffset;
00408  *
00409  *    int nfields = _stscanf( lpParameters, _T( "%lg,%lg" ), &m_dFactor, &m_dOffset );
00410  *
00411  *    if ( Q_LOG( 1 > nfields && 
00412  *         "CScanFilterNull (SetParameters): factor and optional offset expected, got none." ) )
00413  *    {
00414  *       return FALSE;
00415  *    }
00416  *
00417  *    return TRUE;
00418  * }
00419  * \endcode
00420  */
00421 
00422 BOOL CScanFilterNull::SetParameters( LPCTSTR lpParameters )
00423 {
00424 // Q_LOG( _T("CScanFilterNull::SetParameters()") );
00425 
00426 #ifdef NO_PARAMETERS
00427    /*
00428     * we do not expect any parameters, so say so:
00429     */
00430    Q_LOG( NULL != lpParameters && 0 < ::strlen( lpParameters &&
00431            "CScanFilterNull (SetParameters): no parameters expected." ) )
00432 
00433    return FALSE;
00434 #else
00435    if ( Q_INVALID( NULL == lpParameters && 
00436            "CScanFilterNull (SetParameters): parameters expected, none provided (NULL).") )
00437    {
00438       return FALSE;
00439    }
00440 
00441    /*
00442     * set defaults, read parameter string with factor and optional offset:
00443     */
00444    m_dFactor = def_dFactor;
00445    m_dOffset = def_dOffset;
00446 
00447    int nfields = _stscanf( lpParameters, _T( "%lg,%lg" ), &m_dFactor, &m_dOffset );
00448 
00449    if ( Q_INVALID( 1 > nfields && "CScanFilterNull (SetParameters): factor and optional offset expected, got none." ) )
00450    {
00451       return FALSE;
00452    }
00453 
00454    return TRUE;
00455 #endif
00456 }
00457 
00458 /**
00459  * create filter dialog and pre Apply() filter to view result;
00460  * see also CScanFilterNull::RunModeless().
00461  *
00462  * This method creates the filter dialog and pre-applies the filter using
00463  * Apply() to show its result.
00464  *
00465  * \param pDoc the document to update on a filter action (parameter change, Ok, Cancel)
00466  * \param pParentWnd the parent window for the creation of the filter dialog box
00467  * \return TRUE (Success), FALSE (Failure)
00468  *
00469  * Here's an example of how you may implement RunModeless().
00470  * \code
00471  * BOOL CScanFilter::RunModeless( CWnd* pParentWnd, CDocument* pDoc )
00472  * {
00473  *    CFilterDlg_NullPtr pDlg = new CFilterDlg_Null();
00474  *
00475  *    if ( Q_INVALID( NULL == pDlg ) )
00476  *       return FALSE;
00477  *
00478  *    pDlg->SetParameters( this, pDoc );   // (void) method
00479  *
00480  * //   Q_RETURN( pDlg->Create( IDD_FILTERDLG_NULL, pParentWnd ) );   // FIXME-ADAPT: IDD_
00481  *    pDlg->Create( IDD_FILTERDLG_NULL, pParentWnd );   // FIXME-ADAPT: IDD_
00482  *
00483  *    m_pDlg = pDlg;
00484  *
00485  *    // pre-Apply the filter and show initial results;
00486  *    // on error, simulate failure to create dialog:
00487  *
00488  *    BOOL bRet = Apply();
00489  *
00490  *    if ( bRet )
00491  *    {
00492  *       pDlg->UpdateView();
00493  *    }
00494  *
00495  *    return bRet;
00496  * }
00497  * \endcode
00498  */
00499 
00500 BOOL CScanFilterNull::RunModeless( CWnd* pParentWnd, CDocument* pDoc )
00501 {
00502 // Q_LOG( _T("CScanFilterNull::RunModeless()") );               // FIXME-ADAPT: string
00503 
00504    CFilterDlg_NullPtr pDlg = new CFilterDlg_Null();             // FIXME-ADAPT: type
00505 
00506    if ( Q_INVALID( NULL == pDlg ) )
00507       return FALSE;
00508 
00509    pDlg->SetParameters( this, pDoc );   // (void) method
00510 
00511    /*
00512     * For the dialog panel, I had to replace several lines in resource.h with
00513     * lines from a previously created dialog to make the dialog visible.
00514     *
00515     * Create returns non-zero if dialog was created and initialized succesfully.
00516     * Note: no pDlg->DestroyWindow() must be done.
00517     */
00518 //   Q_RETURN( pDlg->Create( IDD_FILTERDLG_NULL, pParentWnd ) );   // FIXME-ADAPT: IDD_
00519    pDlg->Create( IDD_FILTERDLG_NULL, pParentWnd );   // FIXME-ADAPT: IDD_
00520 
00521    m_pDlg = pDlg;
00522 
00523    /*
00524     * pre-Apply the filter and show initial results;
00525     * on error, simulate failure to create dialog:
00526     */
00527    BOOL bRet = Apply();
00528 
00529    if ( bRet )
00530    {
00531       pDlg->UpdateView();
00532    }
00533 
00534    return bRet;
00535 }
00536 
00537 /**
00538  * let ApplyCore() perform the filter processing; catch MFC and std exceptions;
00539  * see also CScanFilterNull::Apply().
00540  *
00541  * Method Apply is an MFC and std exception handling wrapper around method ApplyCore.
00542  *
00543  * \return TRUE (Success), FALSE (Failure)
00544  *
00545  * Here is an example of how you may implement Apply().
00546  * \code
00547  * BOOL CScanFilterNull::Apply()
00548  * {
00549  *    BOOL bRet = FALSE;        // preset to Failure
00550  *
00551  *    try
00552  *    {
00553  *       bRet = ApplyCore();    // sets status, unless exception occurs
00554  *    }
00555  *    catch ( CException* e )
00556  *    {
00557  *       Q_MFC_EXCEPTION( e );  // macro uses pointer-to (without surrounding () )
00558  *       e->Delete();           // see MSDN: Exceptions: Catching and Deleting Exceptions
00559  *    }
00560  *    catch ( const std::exception& e )
00561  *    {
00562  *       Q_STD_EXCEPTION( e );
00563  *    }
00564  *
00565  *    return bRet;              // return status
00566  * }
00567  * \endcode
00568  */
00569 
00570 BOOL CScanFilterNull::Apply()
00571 {
00572 // Q_LOG( _T("CScanFilterNull::Apply()") );
00573 
00574    BOOL bRet = FALSE;                   // preset to Failure
00575 
00576    try
00577    {
00578       bRet = ApplyCore();               // sets status, unless exception occurs
00579    }
00580    catch ( CException* e )
00581    {
00582       Q_MFC_EXCEPTION( e );             // macro uses pointer-to (without surrounding () )
00583       e->Delete();                      // see MSDN: Exceptions: Catching and Deleting Exceptions
00584    }
00585    catch ( const std::exception& e )
00586    {
00587       Q_STD_EXCEPTION( e );
00588 #if 0
00589 //    if ( m_pDlg )
00590       if ( IsInteractive() )          // FIXME: when member of CScanFilter.
00591       {
00592          ::MessageBox(                  // FIXME-ADAPT: filter name.
00593             AfxGetMainWnd()->m_hWnd, e.what(), _T("NullFilter Failure"), MB_OK | MB_ICONWARNING );
00594       }
00595 #endif
00596    }
00597 
00598    return bRet;                         // return status
00599 }
00600 
00601 /**
00602  * check parameters, take care of a properly sized output buffer,
00603  * set its name and copy filter parameters and Process();
00604  * see also CScanFilterNull::ApplyCore().
00605  *
00606  * This method checks the presence of the filter's buffer(s), takes care of a
00607  * properly sized output buffer, set its name and copies the filter parameters
00608  * from the input buffer to the ouput buffer and calls Process() to do the filter
00609  * processing.
00610  *
00611  * \note Currently this filter does not support partial (line-by-line) filtering.
00612  * \note For an example of a filter that uses two input buffers, see filter
00613  * %ScanFilterDZ.h and %ScanFilterDZ.cpp (class CScanFilterDZ).
00614  *
00615  * Here is an example of how ApplyCore() may be implemented.
00616  * Note that method ApplyCore() is highly filter-specific.
00617  * \code
00618  * BOOL CScanFilterNull::ApplyCore()
00619  * {
00620  *    if ( Q_INVALID( NULL == m_lpsbIn ) )
00621  *       return FALSE;
00622  *
00623  *    if ( Q_INVALID( NULL == m_lpsbOut ) )
00624  *       return FALSE;
00625  *
00626  *    //
00627  *    // for first Apply, setup filter settings, filter name, dialog if present
00628  *    // and output buffer:
00629  *    //
00630 
00631  *    //
00632  *    // copy the filter settings (not the data):
00633  *    //
00634  *    Q_RETURN( m_lpsbOut->CreateOutputBufferFor( *m_lpsbIn ) );
00635  *
00636  *    // FIXME-ADAPT: filtername
00637  *    m_lpsbOut->m_csBufferName.Format( _T("%s - %s"), m_lpsbIn->m_csBufferName, m_lpcsShortFilterName );
00638  *
00639  *    //
00640  *    // if the dialog is present:
00641  *    //
00642  *    if ( IsInteractive() )
00643  *    {
00644  *       m_pDlg->SetDlgItemText( IDC_BUFFEROUTNAME, m_lpsbOut->m_csBufferName );
00645  *    }
00646  *
00647  *    //
00648  *    // process the L2R part and the R2L part (if present).
00649  *    //
00650  *    DWORD dwSize =  m_lpsbIn->FrameSize();
00651  *
00652  *    if (  m_lpsbIn->IsBidirectionalScan() && m_lpsbOut->IsBidirectionalScan() )
00653  *    {
00654  *       dwSize *= 2;
00655  *    }
00656  *
00657  *    Process( m_lpsbIn->Data(), m_lpsbOut->Data(), dwSize );
00658  *
00659  *    //
00660  *    // recalculate all temporary variables:
00661  *    //
00662  *    m_lpsbOut->m_dwParameterMask  = 0;
00663  *
00664  *    return TRUE;                         // return Ok
00665  * }
00666  * \endcode
00667  */
00668 
00669 BOOL CScanFilterNull::ApplyCore()       // FIXME-ADAPT: method ApplyCore is highly filter-specific
00670 {
00671    if ( Q_INVALID( NULL == m_lpsbIn ) )
00672       return FALSE;
00673 
00674    if ( Q_INVALID( NULL == m_lpsbOut ) )
00675       return FALSE;
00676 
00677    /*
00678     * for first Apply, setup filter settings, filter name, dialog if present
00679     * and output buffer:
00680     */
00681 
00682     /*
00683      * BUG: this is Not a Good thing for scripting. There one filter object is
00684      *      used for filter operations on more than one channel. Each channel
00685      *      requires its own processing (e.g. name).
00686      */
00687 
00688    /*
00689     * copy the filter settings (not the data):
00690     */
00691    Q_RETURN( m_lpsbOut->CreateOutputBufferFor( *m_lpsbIn ) );
00692 
00693    // FIXME-ADAPT: filtername
00694    m_lpsbOut->m_csBufferName.Format( _T("%s - %s"), m_lpsbIn->m_csBufferName, m_lpcsShortFilterName );
00695 
00696    /*
00697     * if the dialog is present:
00698     */
00699    if ( IsInteractive() )          // FIXME: when member of CScanFilter.
00700    {
00701       m_pDlg->SetDlgItemText( IDC_BUFFEROUTNAME, m_lpsbOut->m_csBufferName );
00702    }
00703 
00704    /*
00705     * process the L2R part and the R2L part (if present).
00706     */
00707    DWORD dwSize = m_lpsbIn->GetFrameSize();
00708 
00709    if ( m_lpsbIn->IsBidirectionalScan() && m_lpsbOut->IsBidirectionalScan() )
00710    {
00711       dwSize *= 2;
00712    }
00713 
00714    Process( m_lpsbIn->Data(), m_lpsbOut->Data(), dwSize );
00715 
00716    /*
00717     * recalculate all temporary variables:
00718     */
00719    // ClearParametersMask( m_lpsbOut ); // FIXME: maybe
00720    m_lpsbOut->m_dwParameterMask  = 0;
00721 
00722    return TRUE;                         // return Ok
00723 }
00724 
00725 /*
00726  * anonymous namespace to hide class NullOp from other modules:
00727  */
00728 
00729 namespace
00730 {
00731    // FIXME-ADAPT: required operation is highly filter-specific.
00732 
00733    /**
00734     * unary functor to perform calculation in std::transform.
00735     */
00736    template <typename T>
00737    class NullOp : public std::unary_function<T, T>
00738    {
00739    public:
00740       /**
00741        * default contructor; 0.5 is added to offset for rounding.
00742        */
00743       NullOp(double fac = 1.0, double off = 0.0) : m_factor(fac), m_offset(off + 0.5)
00744       {
00745       }
00746 
00747       /**
00748        * visit element; return factor x elem + offset.
00749        */
00750       inline T operator()( T x )
00751       {
00752          return static_cast<T>( m_factor * x + m_offset );
00753       }
00754 
00755    private:
00756       double m_factor;                  ///< the factor
00757       double m_offset;                  ///< the offset
00758    };
00759 }  // end anonymous namespace
00760 
00761 /**
00762  * filter specified data range to output.
00763  *
00764  * This filter simply copies its input buffer to its ouput buffer using STL std::
00765  * transform(), while applying the formula: \f$y_{ij} = factor \times x_{ij} + offset\f$.
00766  * \code
00767  * void CScanFilterNull::Process( ConstPointer pStartIn, Pointer pStartOut, DWORD dwSize )
00768  * {
00769  *    // FIXME-ADAPT: required operation is highly filter-specific.
00770  *
00771  *    std::transform(
00772  *       pStartIn,                         // in.begin()
00773  *       pStartIn + dwSize,                // in.end()
00774  *       pStartOut,                        // out.begin()
00775  *       NullOp<ValueType>( GetFactor(), GetOffset() )    // UnaryOp
00776  *    );
00777  * }
00778  * \endcode
00779  */
00780 
00781 void CScanFilterNull::Process( ConstPointer pStartIn, Pointer pStartOut, DWORD dwSize )
00782 {
00783    // FIXME-ADAPT: required operation is highly filter-specific.
00784 
00785    std::transform(
00786       pStartIn,                         // in.begin()
00787       pStartIn + dwSize,                // in.end()
00788       pStartOut,                        // out.begin()
00789       NullOp<ValueType>( GetFactor(), GetOffset() )    // UnaryOp
00790    );
00791 }
00792 
00793 /**
00794  * measure algorithm performance.
00795  *
00796  * We measure two aspects of the algorithm:
00797  * -# the time to prepare for the operation on the buffers
00798  * -# the time to process the data from the input buffer to the output buffer
00799  *
00800  * In the following example, there is no preparation phase, so all time is
00801  * attributed to the operation on the buffers.
00802  * \code
00803  *    SPerformanceTestResult result;
00804  *
00805  *    typedef long Count;
00806  *
00807  *    CPerfTimer Timer;
00808  *
00809  *    //
00810  *    // time Preparation:
00811  *    //
00812  *
00813  *    ; // nothing here
00814  *
00815  *    //
00816  *    // time Process:
00817  *    //
00818  *    Time  timeToProcess  = 0.4;          // time to measure in [s]
00819  *    Count countProcessed = 0;            // iteration count
00820  *
00821  *    Timer.Start( true );                 // restart start the timing
00822  *    while ( Timer.Elapsed() < timeToProcess )
00823  *    {
00824  *       Process( m_lpsbIn->Data(), m_lpsbOut->Data(), m_lpsbIn->FrameSize() );
00825  *
00826  *       ++countProcessed;                // update iteration count
00827  *    }
00828  *
00829  *    Timer.Stop();                        // stop the timing
00830  *    result.timeBuffer = Timer.Elapsed() / countProcessed;
00831  *
00832  *    if ( m_lpsbIn->IsBidirectionalScan() && m_lpsbOut->IsBidirectionalScan() )
00833  *    {
00834  *       result.timeBuffer *= 2;
00835  *    }
00836  *
00837  *    result.totalTime = result.timePrepare + result.timeBuffer;
00838  *
00839  *    return result;
00840  * }
00841  * \endcode
00842  */
00843 
00844 SPerformanceTestResult CScanFilterNull::GetPerformanceTestResult()
00845 {
00846    SPerformanceTestResult result;
00847 
00848    typedef long Count;
00849 
00850    CPerfTimer Timer;
00851 
00852    /*
00853     * time Preparation:
00854     */
00855 
00856    /*
00857     * time Process:
00858     */
00859    Time  timeToProcess  = 0.4;          // time to measure in [s]
00860    Count countProcessed = 0;            // iteration count
00861 
00862    Timer.Start( true );                 // restart start the timing
00863    while ( Timer.Elapsed() < timeToProcess )
00864    {
00865       Process( m_lpsbIn->Data(), m_lpsbOut->Data(), m_lpsbIn->GetFrameSize() );
00866 
00867       ++countProcessed;                // update iteration count
00868    }
00869 
00870    Timer.Stop();                        // stop the timing
00871    result.timeBuffer = Timer.Elapsed() / countProcessed;
00872 
00873    if ( m_lpsbIn->IsBidirectionalScan() && m_lpsbOut->IsBidirectionalScan() )
00874    {
00875       result.timeBuffer *= 2;
00876    }
00877 
00878    result.totalTime = result.timePrepare + result.timeBuffer;
00879 
00880    return result;
00881 }
00882 
00883 /*
00884  * end of file
00885  */
00886 

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