cmtkTypedArray.cxx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2010 Torsten Rohlfing
00004 //
00005 //  Copyright 2004-2010 SRI International
00006 //
00007 //  This file is part of the Computational Morphometry Toolkit.
00008 //
00009 //  http://www.nitrc.org/projects/cmtk/
00010 //
00011 //  The Computational Morphometry Toolkit is free software: you can
00012 //  redistribute it and/or modify it under the terms of the GNU General Public
00013 //  License as published by the Free Software Foundation, either version 3 of
00014 //  the License, or (at your option) any later version.
00015 //
00016 //  The Computational Morphometry Toolkit is distributed in the hope that it
00017 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00018 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //  GNU General Public License for more details.
00020 //
00021 //  You should have received a copy of the GNU General Public License along
00022 //  with the Computational Morphometry Toolkit.  If not, see
00023 //  <http://www.gnu.org/licenses/>.
00024 //
00025 //  $Revision: 2398 $
00026 //
00027 //  $LastChangedDate: 2010-10-05 14:54:37 -0700 (Tue, 05 Oct 2010) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
00030 //
00031 */
00032 
00033 #include <Base/cmtkTypedArray.h>
00034 #include <Base/cmtkTemplateArray.h>
00035 
00036 #include <math.h>
00037 
00038 namespace
00039 cmtk
00040 {
00041 
00044 
00045 void
00046 TypedArray
00047 ::RescaleToRange( const Types::DataItemRange& toRange )
00048 {
00049   const Types::DataItemRange fromRange = this->GetRange();
00050   
00051   const Types::DataItem scale = toRange.Width() / fromRange.Width();
00052   const Types::DataItem offset = toRange.m_LowerBound - (fromRange.m_LowerBound * scale);
00053 
00054   this->Rescale( scale, offset );
00055 }
00056 
00057 void
00058 TypedArray
00059 ::BlockSwap
00060 ( const size_t fromOffset, const size_t toOffset, const size_t blockLength )
00061 {
00062   char buffer[2048];
00063 
00064   size_t itemSize = this->GetItemSize();
00065   char *dataPtr = static_cast<char*>( this->GetDataPtr() );
00066 
00067   size_t bytesToGo = itemSize * blockLength;
00068   char *fromPtr = dataPtr + itemSize * fromOffset;
00069   char *toPtr = dataPtr + itemSize * toOffset;
00070 
00071   while ( bytesToGo > sizeof( buffer ) ) 
00072     {
00073     memcpy( buffer, toPtr, sizeof( buffer ) );
00074     memcpy( toPtr, fromPtr, sizeof( buffer ) );
00075     memcpy( fromPtr, buffer, sizeof( buffer ) );
00076     
00077     fromPtr += sizeof( buffer );
00078     toPtr += sizeof( buffer );
00079     bytesToGo -= sizeof( buffer );
00080     }
00081 
00082   if ( bytesToGo ) 
00083     {
00084     memcpy( buffer, toPtr, bytesToGo );
00085     memcpy( toPtr, fromPtr, bytesToGo );
00086     memcpy( fromPtr, buffer, bytesToGo );
00087     }
00088 }
00089 
00090 void
00091 TypedArray
00092 ::BlockReverse
00093 ( const size_t fromOffset, const size_t blockLength )
00094 {
00095   // we get into trouble here for item sizes > 128 bits.
00096   char buffer[16];
00097 
00098   size_t itemSize = this->GetItemSize();
00099   char *dataPtr = static_cast<char*>( this->GetDataPtr() );
00100 
00101   char *fromPtr = dataPtr + fromOffset * itemSize;
00102   char *toPtr = fromPtr + (blockLength-1) * itemSize;
00103 
00104   for ( size_t itemsToGo = blockLength / 2; itemsToGo; --itemsToGo ) 
00105     {
00106     memcpy( buffer, toPtr, itemSize );
00107     memcpy( toPtr, fromPtr, itemSize );
00108     memcpy( fromPtr, buffer, itemSize );
00109     
00110     fromPtr += itemSize;
00111     toPtr -= itemSize;
00112     }
00113 }
00114 
00115 TypedArray::SmartPtr
00116 TypedArray
00117 ::Create
00118 ( const ScalarDataType dtype, void *const data, const size_t size, const bool freeArray, const bool paddingFlag, const void* paddingData ) 
00119 {
00120   switch (dtype) 
00121     {
00122     case TYPE_BYTE: 
00123       return Self::SmartPtr( new ByteArray( data, size, freeArray, paddingFlag, paddingData ) );
00124       break;
00125     case TYPE_CHAR: 
00126       return Self::SmartPtr( new CharArray( data, size, freeArray, paddingFlag, paddingData ) );
00127       break;
00128     case TYPE_SHORT: 
00129       return Self::SmartPtr( new ShortArray( data, size, freeArray, paddingFlag, paddingData ) );
00130       break;
00131     case TYPE_USHORT: 
00132       return Self::SmartPtr( new UShortArray( data, size, freeArray, paddingFlag, paddingData ) );
00133       break;
00134     case TYPE_INT: 
00135       return Self::SmartPtr( new IntArray( data, size, freeArray, paddingFlag, paddingData ) );
00136       break;
00137     case TYPE_FLOAT: 
00138       return Self::SmartPtr( new FloatArray( data, size, freeArray, paddingFlag, paddingData ) );
00139       break;
00140     case TYPE_DOUBLE: 
00141       return Self::SmartPtr( new DoubleArray( data, size, freeArray, paddingFlag, paddingData ) );
00142       break;
00143     default:
00144       break;
00145     }
00146   
00147   fprintf(stderr,"TypedArray::Create - Data type %d unknown.",dtype);
00148   return Self::SmartPtr();
00149 }
00150 
00151 TypedArray::SmartPtr
00152 TypedArray
00153 ::Create( const ScalarDataType dtype, const size_t size )
00154 {
00155   switch ( dtype ) 
00156     {
00157     case TYPE_BYTE:   
00158       return Self::SmartPtr( new ByteArray( size ) );
00159       break;
00160     case TYPE_CHAR:   
00161       return Self::SmartPtr( new CharArray( size ) );
00162       break;
00163     case TYPE_SHORT:  
00164       return Self::SmartPtr( new ShortArray( size ) );
00165       break;
00166     case TYPE_USHORT:  
00167       return Self::SmartPtr( new UShortArray( size ) );
00168       break;
00169     case TYPE_INT:    
00170       return Self::SmartPtr( new IntArray( size ) );
00171       break;
00172     case TYPE_FLOAT:  
00173       return Self::SmartPtr( new FloatArray( size ) );
00174       break;
00175     case TYPE_DOUBLE:
00176       return Self::SmartPtr( new DoubleArray( size ) );
00177       break;
00178     default:
00179       break;
00180     }
00181 
00182   fprintf( stderr, "TypedArray::Create - Data type %d unknown.", dtype );
00183   return Self::SmartPtr();
00184 }
00185 
00186 void 
00187 TypedArray
00188 ::PruneHistogram
00189 ( const bool pruneHi, const bool pruneLo, const size_t numberOfBinsTarget, const size_t numberOfBinsInternal )
00190 {
00191   Histogram<unsigned int>::SmartPtr originalHistogram( this->GetHistogram( numberOfBinsInternal ) );
00192   
00193   const size_t oneBinFraction = this->GetDataSize() / numberOfBinsTarget;
00194   size_t accumulatedNumberOfSamples = 0;
00195 
00196   const Types::DataItemRange range = this->GetRange();
00197 
00198   Types::DataItem min = range.m_LowerBound;
00199   Types::DataItem max = range.m_UpperBound;
00200 
00201   const Types::DataItem originalMax = max;
00202 
00203   if ( pruneHi )
00204     {
00205     for ( size_t binIdx = numberOfBinsInternal-1; binIdx > 0; --binIdx )
00206       {
00207       accumulatedNumberOfSamples += (*originalHistogram)[binIdx];
00208       if ( accumulatedNumberOfSamples > oneBinFraction )
00209         {
00210         max = min + (max-min)/1024*binIdx;
00211         break;
00212         }
00213       }
00214     }
00215 
00216   if ( pruneLo )
00217     {
00218     for ( size_t binIdx = 0; binIdx < numberOfBinsInternal; ++binIdx )
00219       {
00220       accumulatedNumberOfSamples += (*originalHistogram)[binIdx];
00221       if ( accumulatedNumberOfSamples > oneBinFraction )
00222         {
00223         min = originalMax - (originalMax-min)/numberOfBinsInternal*binIdx;
00224         break;
00225         }
00226       }
00227     }
00228   
00229   this->Threshold( Types::DataItemRange( min, max ) );
00230 }
00231 
00232 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines