Filter Library Camera Interface Physics

ScanFilterShift.cpp

00001 /*
00002  * ScanFilterShift.cpp - shift 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: ScanFilterShift.cpp 358 2006-03-06 14:49: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/ScanFilterShift.h>        // this filter's header
00033 #include <cfl/FilterDlg_Shift.h>        // this filter's dialog
00034 
00035 #ifdef _DEBUG
00036 #undef THIS_FILE
00037 static char THIS_FILE[]=__FILE__;
00038 #define new DEBUG_NEW
00039 #endif
00040 
00041 #define CFL_SCHEMAVERSION_FILTERSHIFT 0  // permanent storage schema version
00042                                         // this filter's name
00043 LPCTSTR CScanFilterShift::m_lpcsFilterName = _T("Shift");
00044                                         // this filter's short name
00045 LPCTSTR CScanFilterShift::m_lpcsShortFilterName = CScanFilterShift::m_lpcsFilterName;
00046                                         // serialization
00047 IMPLEMENT_SERIAL( CScanFilterShift, CScanFilter, CFL_SCHEMAVERSION_FILTERSHIFT )
00048 
00049 /*
00050  * the default new X-size.
00051  */
00052 const CScanFilterShift::DiffElementType CScanFilterShift::def_nShiftX = 10;
00053 
00054 /*
00055  * the default new Y-size.
00056  */
00057 const CScanFilterShift::DiffElementType CScanFilterShift::def_nShiftY = 10;
00058 
00059 /*
00060  * constructor.
00061  */
00062 CScanFilterShift::CScanFilterShift() :
00063    m_cpShift( DiffType( def_nShiftX, def_nShiftY ) )
00064 {
00065    m_csFilterName = m_lpcsFilterName;
00066    
00067    ReadFilterSettings();
00068 }
00069 
00070 /*
00071  * destructor.
00072  */
00073 CScanFilterShift::~CScanFilterShift()
00074 {
00075    ; // do nothing
00076 }
00077 
00078 /*
00079  * store or retrieve the object's settings;
00080  * see also CScanFilterNull::Serialize().
00081  */
00082 void CScanFilterShift::Serialize( CArchive& ar )
00083 {
00084 //   Q_LOG( _T("CScanFilterShift::Serialize()") );
00085 
00086    CScanFilter::Serialize( ar );
00087 
00088    if ( ar.IsStoring() )
00089    {
00090       ar << m_cpShift.x << m_cpShift.y;
00091    }
00092    else
00093    {
00094       ar >> m_cpShift.x >> m_cpShift.y;
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 CScanFilterShift::ReadFilterSettings()
00103 {
00104 //   Q_LOG( _T("CScanFilterShift::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( "10,10" ) ) );
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 CScanFilterShift::WriteFilterSettings() const
00122 {
00123 //   Q_LOG( _T("CScanFilterShift::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 CScanFilterShift::GetParameters() const
00148 {
00149 //   Q_LOG( _T("CScanFilterShift::GetParameters()") );
00150 
00151    /*
00152     * format parameters and return a c-string on the heap:
00153     */
00154    CString csParameters;
00155 
00156    csParameters.Format( _T( "%d,%d" ), m_cpShift.x, m_cpShift.y );
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 CScanFilterShift::SetParameters( LPCTSTR lpParameters )
00166 {
00167 //   Q_LOG( _T("CScanFilterShift::SetParameters()") );
00168 
00169    if ( Q_INVALID( NULL == lpParameters && "CScanFilterShift (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_cpShift = DiffType( def_nShiftX, def_nShiftY );
00178 
00179    int nfields = _stscanf( lpParameters, _T( "%d,%d" ), &m_cpShift.x, &m_cpShift.y );
00180 
00181    if ( Q_INVALID( 2 > nfields && "CScanFilterShift (SetParameters): x- and y-size expected, got none." ) )
00182    {
00183       return FALSE;
00184    }
00185 
00186    return TRUE;
00187 }
00188 
00189 /*
00190  * create filter dialog and pre Apply() filter to view result;
00191  * see also CScanFilterNull::RunModeless().
00192  */
00193 BOOL CScanFilterShift::RunModeless( CWnd* pParentWnd, CDocument* pDoc )
00194 {
00195 //   Q_LOG( _T("CScanFilterShift::RunModeless()") );
00196 
00197    CFilterDlg_ShiftPtr pDlg = new CFilterDlg_Shift();
00198 
00199    if ( Q_INVALID( NULL == pDlg ) )
00200       return FALSE;
00201 
00202    pDlg->SetParameters( this, pDoc );   // (void) method
00203 
00204    /*
00205     * Create returns non-zero if dialog was created and initialized succesfully.
00206     * Note: no pDlg->DestroyWindow() must be done.
00207     */
00208    pDlg->Create( IDD_FILTERDLG_SHIFT, pParentWnd );
00209 
00210    m_pDlg = pDlg;
00211 
00212    BOOL bRet = Apply();
00213 
00214    if ( bRet )
00215    {
00216       pDlg->UpdateView();
00217    }
00218 
00219    return bRet;
00220 }
00221 
00222 #pragma warning( push )
00223 #pragma warning( disable : 4100 )       // unreferenced formal parameter
00224 
00225 /*
00226  * the supported dragmethod(s).
00227  */
00228 DragSupportType CScanFilterShift::SupportDragInput() const
00229 {
00230    return SFDS_POINT;
00231 }
00232 
00233 /*
00234  * apply the filter to the selected area.
00235  */
00236 void CScanFilterShift::SetDragInput( BOOL bL2R, CRect rcIn )
00237 {
00238 //   Q_LOG( _T("CScanFilterShift::SetDragInput()") );
00239 
00240    SetShiftX( rcIn.right  - rcIn.left );
00241    SetShiftY( rcIn.bottom - rcIn.top  );
00242 
00243    if ( IsInteractive() )
00244    {
00245       m_pDlg->SetDlgItemInt( IDC_SHIFT_SHIFTX, m_cpShift.x );
00246       m_pDlg->SetDlgItemInt( IDC_SHIFT_SHIFTY, m_cpShift.y );
00247    }
00248 
00249   if ( Q_FAILED( Apply() ) )
00250    {
00251       return ;
00252    }
00253 
00254    CFilterDlg_ShiftPtr pDlg = dynamic_cast<CFilterDlg_ShiftPtr>( m_pDlg );
00255 
00256    if ( Q_ASSERT( NULL != pDlg ) )
00257    {
00258       pDlg->UpdateView();
00259    }
00260 }
00261 
00262 #pragma warning( pop )
00263 
00264 /*
00265  * check parameters, take care of a properly sized output buffer,
00266  * set its name and copy filter parameters and process;
00267  * see also CScanFilterNull::ApplyCore().
00268  */
00269 BOOL CScanFilterShift::Apply()
00270 {
00271 //   Q_LOG( _T("CScanFilterShift::Apply()") );
00272 
00273    if ( Q_INVALID( NULL == m_lpsbIn && "ensure input buffer") )
00274       return FALSE;
00275 
00276    if ( Q_INVALID( NULL == m_lpsbOut && "ensure output buffer" ) )
00277       return FALSE;
00278 
00279    if ( Q_INVALID( !m_lpsbIn->IsCompleteFrame() && "ensure complete frame" ) )
00280       return FALSE;
00281 
00282    /*
00283     *  optionally adjust shift:
00284     */
00285    BOOL bAdjustX = FALSE;
00286    BOOL bAdjustY = FALSE;
00287 
00288    if ( GetShiftX() >= ( DiffElementType ) m_lpsbIn->Columns() )
00289    {
00290       bAdjustX = TRUE;
00291       SetShiftX( m_lpsbIn->Columns() - 1 );
00292    }
00293    else if ( GetShiftX() <= - ( DiffElementType ) m_lpsbIn->Columns() )
00294    {
00295       bAdjustX = TRUE;
00296       SetShiftX( 1 - ( DiffElementType ) m_lpsbIn->Columns() );
00297    }
00298 
00299    if ( GetShiftY() >= ( DiffElementType ) m_lpsbIn->Rows() )
00300    {
00301       bAdjustY = TRUE;
00302       SetShiftY( m_lpsbIn->Rows() - 1 );
00303    }
00304    else if ( GetShiftY() <= -( DiffElementType ) m_lpsbIn->Rows() )
00305    {
00306       bAdjustY = TRUE;
00307       SetShiftY( 1 - ( DiffElementType ) m_lpsbIn->Rows() );
00308    }
00309 
00310    /*
00311     * create output buffer:
00312     */
00313    Q_RETURN( m_lpsbOut->CreateOutputBufferFor( *m_lpsbIn ) );
00314 
00315    m_lpsbOut->m_csBufferName.Format( _T("%s - %s %d,%d"), m_lpsbIn->m_csBufferName, m_lpcsShortFilterName, GetShiftX(), GetShiftY() );
00316 
00317    if ( IsInteractive() )
00318    {
00319       m_pDlg->SetDlgItemText( IDC_BUFFEROUTNAME, m_lpsbOut->m_csBufferName );
00320 
00321       if ( bAdjustX )
00322       {
00323          m_pDlg->SetDlgItemInt( IDC_SHIFT_SHIFTX, GetShiftX() );
00324       }
00325 
00326       if ( bAdjustY )
00327       {
00328          m_pDlg->SetDlgItemInt(IDC_SHIFT_SHIFTY, GetShiftY() );
00329       }
00330    }
00331 
00332    /*
00333     * process first part (L2R):
00334     */
00335    Shift( FALSE );
00336 
00337    /*
00338     * if we have a double buffer, L2R and R2L, process that part too.
00339     */
00340    if ( m_lpsbIn->IsBidirectionalScan() && m_lpsbOut->IsBidirectionalScan() )
00341    {
00342       Shift( TRUE );
00343    }
00344 
00345    return TRUE;
00346 }
00347 
00348 /*
00349  * process the frame part at the given offset (L2R, R2L frame part).
00350  */
00351 void CScanFilterShift::Shift( BOOL bDoR2L )
00352 {
00353    CScanBaseBuffer::ConstPointer  pInpData = m_lpsbIn->Data()  + ( bDoR2L ? m_lpsbIn->GetFrameSize() : 0 );
00354    CScanBaseBuffer::Pointer       pOutData = m_lpsbOut->Data() + ( bDoR2L ? m_lpsbOut->GetFrameSize() : 0 );
00355 
00356    const CScanBaseBuffer::SizeType& width  =  m_lpsbOut->Columns();
00357    const CScanBaseBuffer::SizeType& height =  m_lpsbOut->Rows();
00358 
00359    DiffElementType blackLines = abs( GetShiftY() );
00360    DiffElementType dataLines  = height - blackLines;
00361 
00362    DiffElementType dataStartLine;
00363    DiffElementType dataStopLine ;
00364 
00365    /*
00366     * fill black part:
00367     */
00368    if ( GetShiftY() > 0 )
00369    {
00370       dataStartLine = blackLines;
00371       dataStopLine  = m_lpsbIn->Rows();
00372 
00373       memset( pOutData, 0, blackLines * width * sizeof( ValueType ) );
00374    }
00375    else
00376    {
00377       dataStartLine = 0;
00378       dataStopLine  = dataLines;
00379 
00380       memset( pOutData + dataLines * width, 0, blackLines * width * sizeof( ValueType ) );
00381    }
00382 
00383    pOutData += dataStartLine * width;
00384 
00385    DiffElementType blackCols = abs( GetShiftX() );
00386    DiffElementType dataCols  = width - blackCols;
00387 
00388    /*
00389     * copy the image data into the new area, clear the unused block at the left or right:
00390     */
00391    for ( DiffElementType y = dataStartLine; y < dataStopLine; ++y, pOutData += width )
00392    {
00393       const int currentLine = (y - GetShiftY() ) * width;
00394 
00395       if ( GetShiftX() > 0 )
00396       {
00397          /*
00398           * first the black part, then the data:
00399           */
00400          memset( pOutData, 0, blackCols * sizeof( ValueType ) );
00401 
00402          memcpy( pOutData + blackCols, pInpData + currentLine, dataCols * sizeof( ValueType ) );
00403       }
00404       else
00405       {
00406          /*
00407           * first the data, then the black part:
00408           */
00409          memcpy( pOutData, pInpData + currentLine + blackCols, dataCols * sizeof( ValueType ) );
00410 
00411          memset( pOutData + dataCols, 0, blackCols * sizeof( ValueType ) );
00412       }
00413    }
00414 }
00415 
00416 /*
00417  * end of file
00418  */
00419 

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