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
00026
00027
00028
00029
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
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 }