Filter Library | Camera | Interface Physics |
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