Filter Library Camera Interface Physics

ScanBaseBuffer.cpp

00001 /*
00002  * ScanBaseBuffer.cpp - scanbuffer base class.
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: ScanBaseBuffer.cpp 235 2005-06-27 08:59:48Z moene $
00013  */
00014 
00015 /*
00016  * configuration defines:
00017  */
00018 
00019 /**
00020  * if USE_OLD_FFTBUFFER_ALLOCATION is defined,
00021  * - allocate a column with row pointers
00022  * - allocate buffer for each row
00023  *
00024  * if USE_OLD_FFTBUFFER_ALLOCATION is NOT defined,
00025  * - allocate a column with row pointers
00026  * - allocate buffer as one block
00027  */
00028 // #define USE_OLD_FFTBUFFER_ALLOCATION
00029 
00030 /*
00031  * end of configuration defines.
00032  */
00033 
00034 #include "stdafx.h"                     // for common (pre-compiled) headers
00035 //#include <cfl/stdafx.h>                 // for common (pre-compiled) headers
00036 #include <cfl/resource.h>               // for messages and other resources
00037 
00038 #include <Camera/InterfaceDll.h>        // Camera--Filter Library interface
00039 #include <cfl/ScanBaseBuffer.h>         // header
00040 
00041 #ifdef _DEBUG
00042 #undef THIS_FILE
00043 static char THIS_FILE[]=__FILE__;
00044 #define new DEBUG_NEW
00045 #endif
00046 
00047 IMPLEMENT_DYNCREATE( CScanBaseBuffer, CObject )
00048 
00049 #if defined( USE_OLD_FFTBUFFER_ALLOCATION )
00050 
00051 /**
00052  * allocate 2D buffer.
00053  */
00054 template< class ElementType >
00055 ElementType** Allocate2D( const int& rows, const int& cols )
00056 {
00057    typedef ElementType* ElementTypePtr;
00058 
00059    ElementTypePtr *ii = (ElementTypePtr*) calloc( rows, sizeof(ElementTypePtr) );
00060 
00061    for ( int i = 0; i < rows; i++ )
00062    {
00063       /*
00064        * every line, has x data (Re,Im):
00065        */
00066       ii[i] = (double *) calloc( cols, sizeof(ElementType) );
00067    }
00068 
00069    return ii;
00070 }
00071 
00072 /**
00073  * delete 2D buffer.
00074  */
00075 template < class ElementType >
00076 void Delete2D( ElementType**& ii, const int& rows )
00077 {
00078    /*
00079     * free 2D buffer, if any:
00080     */
00081    if ( 0 != ii )
00082    {
00083       for ( int y = 0; y < rows; ++y )
00084       {
00085          free( ii[ y ] );
00086       }
00087 
00088       free( ii ); ii = 0;
00089    }
00090 }
00091 
00092 #else
00093 
00094 /**
00095  * allocate 2D buffer.
00096  */
00097 template< class ElementType >
00098 ElementType** Allocate2D( const int& rows, const int& cols )
00099 {
00100    typedef ElementType* ElementTypePtr;
00101 
00102    ElementTypePtr *ii, i;
00103 
00104    if ( 0 == ( ii = new ElementTypePtr[ rows ] ) )
00105    {
00106       return 0;
00107    }
00108 
00109    if ( 0 == ( i = new ElementType[ rows * cols ] ) )
00110    {
00111       return 0;
00112    }
00113 
00114    ii[0] = i;
00115 
00116    for ( int j = 1; j < rows; ++j )
00117    {
00118       ii[j] = &i[ cols * j ];
00119    }
00120 
00121    return ii;
00122 }
00123 
00124 
00125 /**
00126  * delete 2D buffer.
00127  */
00128 template < class ElementType >
00129 void Delete2D( ElementType**& ii )
00130 {
00131    if ( 0 != ii )
00132    {
00133       delete[] ii[0];
00134       delete[] ii;
00135       
00136       ii = 0;
00137    }
00138 }
00139 
00140 #endif
00141 
00142 /*
00143  * destructor.
00144  */
00145 CScanBaseBuffer::~CScanBaseBuffer()
00146 {
00147 //   Q_LOG( "CScanBaseBuffer::~CScanBaseBuffer()" );
00148 
00149    ReleaseAllBuffers();
00150 }
00151 
00152 /**
00153  * constructor; \todo m_eStatus set to SB_NOTLOADED, so, when will it be SB_NEW ??
00154  */
00155 CScanBaseBuffer::CScanBaseBuffer()
00156 {
00157 //   Q_LOG( "CScanBaseBuffer::CScanBaseBuffer()" );
00158 
00159    /*
00160     * public members:
00161     */
00162    m_dwFlags               = 0;         // FlagType
00163    m_dwSizeX               = 0;         // SizeType
00164    m_dwSizeY               = 0;         // SizeType
00165    m_dwPixels              = 0;         // SizeType
00166    m_pwData                = NULL;      // Pointer
00167    m_pdFourierL2R          = NULL;      // double**
00168    m_pdFourierR2L          = NULL;      // double**
00169    m_csBufferName          = "";        // CString
00170    m_csDataName            = "";        // CString
00171    m_csDataUnit            = "";        // CString
00172    m_dDataScaleFactor      = 0;         // double
00173    m_nDataOffset           = 0;         // int
00174    m_dwParameterMask       = 0;         // MaskType
00175    m_dSlopeX               = 0;         // double
00176    m_dSlopeY               = 0;         // double
00177    m_dAvg                  = 0;         // double
00178    m_nMinZ                 = 0;         // int
00179    m_nMaxZ                 = 0;         // int
00180    m_dSecMom               = 0;         // double
00181    m_dwPixelOffset         = 0;         // SizeType
00182    m_dwPixelCount          = 0;         // SizeType
00183    m_dXStepSize            = 0;         // double
00184    m_dYStepSize            = 0;         // double
00185    m_dwOrgScanXSize        = 0;         // SizeType
00186    m_dwOrgScanYSize        = 0;         // SizeType
00187    m_dScanAngle            = 0;         // double
00188 
00189    /*
00190     * protected members:
00191     */
00192    m_eStatus               = SB_NOTLOADED; // StatusType        // FIXME: what should it be?
00193    m_dwMemoryAllocated     = 0;         // SizeType
00194    m_liRAWIndex.QuadPart   = 0;         // LARGE_INTEGER
00195    m_liEditIndex.QuadPart  = 0;         // LARGE_INTEGER
00196 }
00197 
00198 /**
00199  * shallow copy-assignment constructor; do not copy data and fourier buffers.
00200  */
00201 CScanBaseBuffer::CScanBaseBuffer( const Self& rhs )
00202 {
00203 //   Q_LOG( "CScanBaseBuffer::CScanBaseBuffer(const Self& rhs)" );
00204 
00205    ReleaseAllBuffers();
00206    Copy( rhs );
00207 }
00208 
00209 /**
00210  * shallo copy-assignment; do not copy data and fourier buffers.
00211  */
00212 CScanBaseBuffer::Self& CScanBaseBuffer::operator= ( const Self& rhs )
00213 {
00214 //   Q_LOG( "CScanBaseBuffer::operator=(const Self& rhs)" );
00215 
00216    if ( this != &rhs )
00217    {
00218       ReleaseAllBuffers();
00219       Copy( rhs );
00220    }
00221 
00222    return *this;
00223 }
00224 
00225 /**
00226  * shallow copy; set data and fourier buffer pointers to 0; 
00227  * \todo set mdwFlags to 0?.
00228  */
00229 void CScanBaseBuffer::Copy( const Self& rhs )
00230 {
00231 //   Q_LOG( "CScanBaseBuffer::Copy(const Self& rhs)" );
00232 
00233    /*
00234     * public members:
00235     */
00236    m_dwFlags               = rhs.m_dwFlags;             // FlagType
00237    m_dwSizeX               = rhs.m_dwSizeX;             // SizeType
00238    m_dwSizeY               = rhs.m_dwSizeY;             // SizeType
00239    m_dwPixels              = rhs.m_dwPixels;            // SizeType
00240    m_pwData                = NULL;                      // Pointer
00241    m_pdFourierL2R          = NULL;                      // double**
00242    m_pdFourierR2L          = NULL;                      // double**
00243    m_csBufferName          = rhs.m_csBufferName;        // CString
00244    m_csDataName            = rhs.m_csDataName;          // CString
00245    m_csDataUnit            = rhs.m_csDataUnit;          // CString
00246    m_dDataScaleFactor      = rhs.m_dDataScaleFactor;    // double
00247    m_nDataOffset           = rhs.m_nDataOffset;         // int
00248    m_dwParameterMask       = 0;                         // MaskType: recalculate
00249 //   m_dwParameterMask       = rhs.m_dwParameterMask;     // MaskType
00250    m_dSlopeX               = rhs.m_dSlopeX;             // double
00251    m_dSlopeY               = rhs.m_dSlopeY;             // double
00252    m_dAvg                  = rhs.m_dAvg;                // double
00253    m_nMinZ                 = rhs.m_nMinZ;               // int
00254    m_nMaxZ                 = rhs.m_nMaxZ;               // int
00255    m_dSecMom               = rhs.m_dSecMom;             // double
00256    m_dwPixelOffset         = rhs.m_dwPixelOffset;       // SizeType
00257    m_dwPixelCount          = rhs.m_dwPixelCount;        // SizeType
00258    m_dXStepSize            = rhs.m_dXStepSize;          // double
00259    m_dYStepSize            = rhs.m_dYStepSize;          // double
00260    m_dwOrgScanXSize        = rhs.m_dwOrgScanXSize;      // SizeType
00261    m_dwOrgScanYSize        = rhs.m_dwOrgScanYSize;      // SizeType
00262    m_dScanAngle            = rhs.m_dScanAngle;          // double
00263 
00264    /*
00265     * protected members:
00266     *
00267     * Note: the application sets the status of the output buffer to SB_NEW,
00268     * so it knows it has to write the data to disk yet: we leave it alone here.
00269     */
00270    // DO NOT ASSIGN TO m_eStatus = rhs.m_eStatus;       // StatusType
00271 
00272    m_dwMemoryAllocated     = 0;                         // SizeType
00273    m_liRAWIndex.QuadPart   = 0;                         // LARGE_INTEGER
00274    m_liEditIndex.QuadPart  = 0;                         // LARGE_INTEGER
00275 }
00276 
00277 /*
00278  * clear data buffer.
00279  */
00280 void CScanBaseBuffer::ClearDataBuffer()
00281 {
00282 //   Q_LOG( "CScanBaseBuffer::ClearDataBuffer()" );
00283 
00284    Q_ASSERT( NULL != m_pwData && "ensure buffer set" );
00285 
00286    /*
00287     * only clear used part (m_dwPixels), not whole buffer(m_dwMemoryAllocated):
00288     */
00289    ZeroMemory( m_pwData, m_dwPixels * sizeof( ValueType ) );
00290 }
00291 
00292 /*
00293  * clear fourier buffer.
00294  */
00295 void CScanBaseBuffer::ClearFourierBuffer()
00296 {
00297 //   Q_LOG( "CScanBaseBuffer::ClearFourierBuffer()" );
00298 
00299 #if defined( USE_OLD_FFTBUFFER_ALLOCATION )
00300    /*
00301     * in this case only the line buffer are contiguous:
00302     */
00303    if ( 0 != m_pdFourierL2R )   // if it exists
00304    {
00305       for ( int row = 0; row < GetRowsForFFT(); ++row )
00306       {
00307          ZeroMemory( m_pdFourierL2R[row], 2 * GetColumnsForFFT() * sizeof( RealType ) );
00308       }
00309    }
00310 
00311    if ( 0 != m_pdFourierR2L )   // if it exists
00312    {
00313       for ( int row = 0; row < GetRowsForFFT(); ++row )
00314       {
00315          ZeroMemory( m_pdFourierR2L[row], 2 * GetColumnsForFFT() * sizeof( RealType ) );
00316       }
00317    }
00318 #else
00319    /*
00320     * in this case both buffers are contiguous:
00321     */
00322    if ( 0 != m_pdFourierL2R )   // if it exists
00323    {
00324       ZeroMemory( m_pdFourierL2R[0], GetRowsForFFT() * 2 * GetColumnsForFFT() * sizeof( FourierElementType ) );
00325    }
00326 
00327    if ( 0 != m_pdFourierR2L )   // if it exists
00328    {
00329       ZeroMemory( m_pdFourierR2L[0], GetRowsForFFT() * 2 * GetColumnsForFFT() * sizeof( FourierElementType ) );
00330    }
00331 #endif
00332 }
00333 
00334 /*
00335  * allocate data buffer, but not fourier buffers.
00336  */
00337 void CScanBaseBuffer::AllocateDataBuffer( SizeType extra /* = 0 */ )
00338 {
00339 //   Q_LOG( "CScanBaseBuffer::AllocateDataBuffer()" );
00340 
00341    Q_ASSERT( NULL == m_pwData && "ensure buffer not set" );
00342 
00343    SizeType newSize = m_dwPixels + extra;
00344 
00345    if ( 0 == newSize )
00346    {
00347       m_pwData = NULL;
00348    }
00349    else
00350    {
00351       try
00352       {
00353          m_pwData = new ValueType[ newSize ];
00354       }
00355       catch ( std::bad_alloc )     // or std::exception
00356       {
00357 //            Q_LOG( "CScanBaseBuffer::Allocate(): memory allocation failed" );
00358          return ;
00359       }
00360 
00361       ZeroMemory( m_pwData, newSize * sizeof( ValueType ) );
00362    }
00363 
00364    m_dwMemoryAllocated = newSize;
00365 }
00366 
00367 /**
00368  * create the fourier buffer(s) based on the current databuffer size.
00369  */
00370 BOOL CScanBaseBuffer::CreateFourierBuffer()
00371 {
00372    AllocateFourierBuffer();
00373 
00374    return 0 != m_pdFourierL2R ; // and ...
00375 }
00376 
00377 /**
00378  * delete the fourier buffer(s).
00379  */
00380 BOOL CScanBaseBuffer::DeleteFourierBuffer()
00381 {
00382    ReleaseFourierBuffer();
00383    
00384    return 0 == m_pdFourierL2R && 0 == m_pdFourierR2L;
00385 }
00386 
00387 /**
00388  * allocate fourier buffer.
00389  */
00390 void CScanBaseBuffer::AllocateFourierBuffer()
00391 {
00392 //   Q_LOG( "CScanBaseBuffer::AllocateFourierBuffer()" );
00393 
00394    if ( HasLeftToRightScan() && 0 == m_pdFourierL2R )
00395    {
00396       m_pdFourierL2R = Allocate2D< FourierElementType >( GetRowsForFFT(), 2 * GetColumnsForFFT() );
00397    }
00398 
00399    if ( HasRightToLeftScan() && 0 == m_pdFourierR2L )
00400    {
00401       m_pdFourierR2L = Allocate2D< FourierElementType >( GetRowsForFFT(), 2 * GetColumnsForFFT() );
00402    }
00403    
00404    ClearFourierBuffer();
00405 }
00406 
00407 /*
00408  * release all buffers.
00409  */
00410 void CScanBaseBuffer::ReleaseAllBuffers()
00411 {
00412 //   Q_LOG( "CScanBaseBuffer::ReleaseAllBuffers()" );
00413 
00414    ReleaseDataBuffer();
00415    ReleaseFourierBuffer();
00416 }
00417 
00418 /*
00419  * release data buffer.
00420  */
00421 void CScanBaseBuffer::ReleaseDataBuffer()
00422 {
00423 //   Q_LOG( "CScanBaseBuffer::ReleaseDataBuffer()" );
00424 
00425    /*
00426     * delete data buffer:
00427     */
00428    if ( /* m_dwMemoryAllocated && */ m_pwData )
00429    {
00430       delete[] m_pwData; m_pwData = NULL;
00431       m_dwMemoryAllocated = 0;
00432    }
00433 }
00434 
00435 /*
00436  * release fourier buffer.
00437  */
00438 void CScanBaseBuffer::ReleaseFourierBuffer()
00439 {
00440 //   Q_LOG( "CScanBaseBuffer::ReleaseFourierBuffer()" );
00441 
00442 #if defined( USE_OLD_FFTBUFFER_ALLOCATION )
00443    Delete2D< FourierElementType >( m_pdFourierL2R, Rows() );
00444    Delete2D< FourierElementType >( m_pdFourierR2L, Rows() );
00445 #else
00446    Delete2D< FourierElementType >( m_pdFourierL2R );
00447    Delete2D< FourierElementType >( m_pdFourierR2L );
00448 #endif
00449 }
00450 
00451 /**
00452  * create this buffer for output based on the given input buffer;
00453  * \note remember to add new member variables.
00454  */
00455 BOOL CScanBaseBuffer::CreateOutputBufferFor( const Self& input, SizeType extra /* = 0 */ )
00456 {
00457 //   Q_LOG( "CScanBaseBuffer::CreateOutputBufferFor()" );
00458 
00459    /*
00460     * skip rest if buffers are already correctly setup:
00461     */
00462    if ( IsUsableOutputBufferFor( input ) )
00463    {
00464       return TRUE;
00465    }
00466 
00467    /*
00468     * release my buffers, shallow copy from input buffer:
00469     */
00470    ReleaseAllBuffers();
00471    Copy( input );
00472 
00473    /*
00474     * allocate new data buffer:
00475     */
00476    AllocateDataBuffer( extra );
00477 
00478    /*
00479     * true if valid buffer present:
00480     */
00481    return 0 != m_pwData;
00482 }
00483 
00484 /**
00485  * resize this data buffer to the given size, on reallocation add extra elements.
00486  */
00487 BOOL CScanBaseBuffer::ResizeDataBuffer( const CSize& size, SizeType extra /* = 0 */ )
00488 {
00489 //   Q_LOG( "CScanBaseBuffer::ResizeDataBuffer()" );
00490 
00491    /*
00492     * return if uchanged:
00493     */
00494    if ( m_dwSizeX == static_cast<SizeType>( size.cx ) && m_dwSizeY == static_cast<SizeType>( size.cy ) )
00495    {
00496       return TRUE;
00497    }
00498 
00499    /*
00500     * store new x- and y-size and number of pixels:
00501     */
00502    m_dwSizeX       = size.cx;
00503    m_dwSizeY       = size.cy;
00504    m_dwPixelOffset = 0;
00505    m_dwPixelCount  = m_dwSizeX * m_dwSizeY;
00506    m_dwPixels      = IsBidirectionalScan() ? 2 * m_dwPixelCount : m_dwPixelCount;
00507 
00508    /*
00509     * return if buffer is large enough:
00510     */
00511    if ( m_dwPixels <= m_dwMemoryAllocated )
00512    {
00513       return TRUE;
00514    }
00515 
00516    /*
00517     * release fourier buffer and data buffer, allocate new buffer:
00518     */
00519 //   Q_LOG( "CScanBaseBuffer::ResizeDataBuffer(): release databuffer and allocate new buffer" );
00520 
00521    ReleaseFourierBuffer(     );
00522    ReleaseDataBuffer (       );
00523    AllocateDataBuffer( extra );
00524 
00525    /*
00526     * true if valid buffer present:
00527     */
00528    return 0 != m_pwData;
00529 }
00530 
00531 #pragma warning( push, 3 )              // disable unreferenced parameter warning
00532 
00533 /**
00534  * true if buffer has the right size and settings to use as output buffer
00535  * for the given input buffer.
00536  */
00537 BOOL CScanBaseBuffer::IsUsableOutputBufferFor( const Self& input )
00538 {
00539 //   Q_LOG( "CScanBaseBuffer::IsUsableOutputBufferFor()" );
00540 
00541    return FALSE;
00542 }
00543 
00544 #pragma warning( pop )
00545 
00546 /**
00547  * allocate fourier buffer based on the current databuffer size and
00548  * copy contents from other buffer.
00549  */
00550 BOOL CScanBaseBuffer::CopyFourierBufferFrom( const Self& other )
00551 {
00552    if ( FALSE == CreateFourierBuffer() )
00553    {
00554       return FALSE;
00555    }
00556 
00557 #if defined( USE_OLD_FFTBUFFER_ALLOCATION )
00558    /*
00559     * in this case only the line buffer are contiguous:
00560     */
00561    if ( 0 != m_pdFourierL2R )   // if it exists
00562    {
00563       for ( int row = 0; row < GetRowsForFFT(); ++row )
00564       {
00565          CopyMemory(
00566             this->m_pdFourierL2R[row],                  // destination
00567             other.m_pdFourierL2R[row],                  // source
00568             2 * GetColumnsForFFT() * sizeof( FourierElementType ) // bytes
00569       }
00570    }
00571 
00572    if ( 0 != m_pdFourierR2L )   // if it exists
00573    {
00574       for ( int row = 0; row < GetRowsForFFT(); ++row )
00575       {
00576          CopyMemory(
00577             this->m_pdFourierR2L[row],                  // destination
00578             other.m_pdFourierR2L[row],                  // source
00579             2 * GetColumnsForFFT() * sizeof( FourierElementType ) // bytes
00580       }
00581    }
00582 #else
00583    /*
00584     * in this case both buffers are contiguous:
00585     */
00586    if ( 0 != m_pdFourierL2R && 0 != other.m_pdFourierL2R )
00587    {
00588       CopyMemory(
00589          this->m_pdFourierL2R[0],                                // destination
00590          other.m_pdFourierL2R[0],                                // source
00591          GetRowsForFFT() * 2 * GetColumnsForFFT() * sizeof( FourierElementType ) // bytes
00592       );
00593    }
00594 
00595    if ( 0 != m_pdFourierR2L && 0 != other.m_pdFourierR2L )
00596    {
00597       CopyMemory(
00598          this->m_pdFourierR2L[0],                                // destination
00599          other.m_pdFourierR2L[0],                                // source
00600          GetRowsForFFT() * 2 * GetColumnsForFFT() * sizeof( FourierElementType ) // bytes
00601       );
00602    }
00603 #endif
00604 
00605    return TRUE;
00606 }
00607 
00608 // -----------------------------------------------------------------------
00609 
00610 /*
00611  * make sure a buffer of appropriate size is available; return true on success.
00612  */
00613 BOOL CScanBaseBuffer::CheckAndSetBufferSize()
00614 {
00615    /*
00616     * allocate new buffer if size does not match:
00617     */
00618    if ( m_dwPixels && ( m_dwMemoryAllocated != m_dwPixels ) )
00619    {
00620       // delete previous buffer, if any:
00621 
00622       if ( m_pwData )
00623       {
00624          delete m_pwData;
00625       }
00626 
00627       // allocate new byffer and initialize it to zero and set check:
00628 
00629       m_pwData = new ValueType[ m_dwPixels ];
00630 
00631       ZeroMemory( m_pwData, m_dwPixels * sizeof( ValueType ) );
00632 
00633       m_dwMemoryAllocated = m_dwPixels;
00634    }
00635 
00636    /*
00637     * true if valid buffer present:
00638     */
00639    return ( m_pwData != NULL );
00640 }
00641 
00642 /*
00643  * end of file
00644  */
00645 

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