00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "stdafx.h"
00026
00027 #include <cfl/resource.h>
00028
00029 #include <cfl/FilterDlg_Math.h>
00030 #include <cfl/ScanFilterMath.h>
00031
00032 #pragma warning( disable: 4018 4100 4116 4146 4244 4663)
00033 #include <cil/Math.h>
00034 #pragma warning( default: 4018 4100 4116 4146 4244 4663)
00035
00036 #include <algorithm>
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
00046 LPCTSTR CScanFilterMath::m_lpcsFilterName = _T("Math");
00047
00048 LPCTSTR CScanFilterMath::m_lpcsShortFilterName = CScanFilterMath::m_lpcsFilterName;
00049
00050 IMPLEMENT_SERIAL( CScanFilterMath, CScanFilter, CFL_SCHEMAVERSION_FILTERMATH )
00051
00052
00053
00054
00055 const CScanFilterMath::MathOperationType CScanFilterMath::def_MathOperation = MATH_SUBAB;
00056
00057
00058
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
00071
00072 CScanFilterMath::~CScanFilterMath()
00073 {
00074
00075
00076 ;
00077 }
00078
00079
00080
00081
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
00100
00101
00102 void CScanFilterMath::ReadFilterSettings()
00103 {
00104
00105
00106 CWinApp* pApp = AfxGetApp();
00107
00108 if ( Q_INVALID( NULL == pApp ) )
00109 return ;
00110
00111
00112
00113
00114 SetParameters( pApp->GetProfileString( gCflRegistrySubkey, m_lpcsFilterName, _T( "0" ) ) );
00115 }
00116
00117
00118
00119
00120
00121 void CScanFilterMath::WriteFilterSettings() const
00122 {
00123
00124
00125 CWinApp* pApp = AfxGetApp();
00126
00127 if ( Q_INVALID( NULL == pApp ) )
00128 return ;
00129
00130
00131
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
00144
00145
00146
00147 LPCTSTR CScanFilterMath::GetParameters() const
00148 {
00149
00150
00151
00152
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
00163
00164
00165 BOOL CScanFilterMath::SetParameters( LPCTSTR lpParameters )
00166 {
00167
00168
00169 if ( Q_INVALID( NULL == lpParameters && "CScanFilterMath (SetParameters): parameters expected, none provided (NULL).") )
00170 {
00171 return FALSE;
00172 }
00173
00174
00175
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
00191
00192 DWORD CScanFilterMath::GetNrOfInBuffers() const
00193 {
00194
00195
00196 return 2;
00197 }
00198
00199
00200
00201
00202 CScanBaseBuffer *CScanFilterMath::GetInputBuffer( UINT nNr )
00203 {
00204
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
00218
00219 void CScanFilterMath::SetInputBuffer( UINT nNr, CScanBaseBuffer *lpsbIn )
00220 {
00221
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
00238
00239
00240 BOOL CScanFilterMath::RunModeless( CWnd* pParentWnd, CDocument* pDoc )
00241 {
00242
00243
00244 CFilterDlg_MathPtr pDlg = new CFilterDlg_Math();
00245
00246 if ( Q_INVALID( NULL == pDlg ) )
00247 return FALSE;
00248
00249 pDlg->SetParameters( this, pDoc );
00250
00251
00252
00253
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
00271
00272
00273
00274 BOOL CScanFilterMath::Apply()
00275 {
00276
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
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
00305
00306 SizeElementType size = lpm::min( m_lpsbIn->GetFrameSize(), m_lpsbIn2->GetFrameSize(), m_lpsbOut->GetFrameSize() );
00307
00308
00309
00310
00311 Process(
00312 m_lpsbIn->Data(),
00313 m_lpsbIn->Data() + size,
00314 m_lpsbIn2->Data(),
00315 m_lpsbOut->Data()
00316 );
00317
00318
00319
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
00333
00334 m_lpsbOut->m_dwParameterMask = 0;
00335
00336 return TRUE;
00337 }
00338
00339
00340
00341
00342 namespace
00343 {
00344
00345
00346
00347 template <typename T>
00348 class AddOp : public std::binary_function<T, T, T>
00349 {
00350 public:
00351
00352
00353
00354 inline T operator()( const T a, const T b ) const { return static_cast<T>( a + b ); }
00355 };
00356
00357
00358
00359
00360 template <typename T>
00361 class SubOp : public std::binary_function<T, T, T>
00362 {
00363 public:
00364
00365
00366
00367 inline T operator()( const T a, const T b ) const { return static_cast<T>( a - b ); }
00368 };
00369
00370
00371
00372
00373 template <typename T>
00374 class InvSubOp : public std::binary_function<T, T, T>
00375 {
00376 public:
00377
00378
00379
00380 inline T operator()( const T a, const T b ) const { return static_cast<T>( b - a ); }
00381 };
00382
00383
00384
00385
00386 template <typename T>
00387 class MulOp : public std::binary_function<T, T, T>
00388 {
00389 public:
00390
00391
00392
00393 inline T operator()( const T a, const T b ) const { return static_cast<T>( a * b ); }
00394 };
00395
00396 }
00397
00398
00399
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
00426
00427