ML Reference
MeVis/Foundation/Sources/ML/include/mlScaleShiftData.h
Go to the documentation of this file.
00001 // **InsertLicense** code
00002 //-------------------------------------------------------------------------
00009 //-------------------------------------------------------------------------
00010 #ifndef __mlScaleShiftData_H
00011 #define __mlScaleShiftData_H
00012 
00013 // ML-includes
00014 #ifndef __mlInitSystemML_H
00015 #include "mlInitSystemML.h"
00016 #endif
00017 
00018 #include "mlDataTypes.h"
00019 
00020 ML_START_NAMESPACE
00021 
00022 //-------------------------------------------------------------------------
00045 //-------------------------------------------------------------------------
00046 template <typename DT>
00047 class TScaleShiftData
00048 {
00049   
00050 public:
00058   enum ReorderMode {
00059     NoReordering = 0,                   
00060     ReorderColorPlanesToInterleaved = 1 
00061   };
00062   
00063   //------------------------------------------------------
00065 
00066   //------------------------------------------------------
00067   
00069   inline TScaleShiftData() 
00070   : _scale(static_cast<DT>(1)),
00071     _shift(static_cast<DT>(0)),
00072     _reorderMode(NoReordering)
00073   {
00074     ML_TRACE_IN_TIME_CRITICAL( "ScaleShiftData( )" );
00075   }
00076   
00078   inline TScaleShiftData(const TScaleShiftData<DT> &ssd) 
00079   : _scale(ssd._scale), 
00080   _shift(ssd._shift),
00081   _reorderMode(ssd._reorderMode)
00082   {
00083     ML_TRACE_IN_TIME_CRITICAL( "ScaleShiftData( )" );
00084   }
00085   
00088   inline TScaleShiftData(DT scale, DT shift) : _scale(scale), _shift(shift) , _reorderMode(NoReordering)
00089   {
00090     ML_TRACE_IN_TIME_CRITICAL( "ScaleShiftData( )" );
00091   }
00092   
00103   inline TScaleShiftData(DT fromMin, DT fromMax, DT toMin, DT toMax)
00104     :_reorderMode(NoReordering)
00105   {
00106     ML_TRACE_IN_TIME_CRITICAL( "ScaleShiftData( )" );
00107     
00108     setFromMinMaxToMinMax(fromMin, fromMax, toMin, toMax); 
00109   }
00111   
00112   
00113   //------------------------------------------------------
00115 
00116   //------------------------------------------------------
00117   
00119   inline TScaleShiftData &operator=(const TScaleShiftData<DT> &ssd)
00120   {
00121     ML_TRACE_IN_TIME_CRITICAL( "ScaleShiftData::operator=" );
00122     
00123     _scale = ssd._scale;  
00124     _shift = ssd._shift; 
00125     _reorderMode = ssd._reorderMode; 
00126     
00127     return *this; 
00128   }
00130   
00131   
00132   //------------------------------------------------------
00134 
00135   //------------------------------------------------------
00136   
00138   inline bool operator==(const TScaleShiftData<DT> &ssd) const
00139   {
00140     ML_TRACE_IN_TIME_CRITICAL( "ScaleShiftData::operator==" );
00141     
00142     return MLValuesAreEqualWOM(_scale, ssd._scale) && 
00143     MLValuesAreEqualWOM(_shift, ssd._shift) && (_reorderMode == ssd._reorderMode); 
00144   }
00145   
00147   inline bool operator!=(const TScaleShiftData<DT> &ssd) const
00148   {
00149     ML_TRACE_IN_TIME_CRITICAL( "ScaleShiftData::operator!=" );
00150     
00151     return !(*this == ssd);
00152   }
00154   
00155   
00156   //------------------------------------------------------
00158 
00159   //------------------------------------------------------
00160   
00163   inline void setScaleOffset(DT scale, DT shift)
00164   {
00165     ML_TRACE_IN_TIME_CRITICAL( "ScaleShiftData::setScaleOffset( )" );
00166     
00167     _scale=scale; 
00168     _shift=shift; 
00169   }
00170   
00181   inline void setFromMinMaxToMinMax(DT fromMin, DT fromMax, DT toMin, DT toMax)
00182   {
00183     ML_TRACE_IN( "ScaleShiftData::setFromMinMaxToMinMax( )" );
00184     ML_TRY
00185     {
00186       if (toMin   > toMax)  { DT help; help = toMin;   toMin   = toMax;   toMax   = help; }
00187       if (fromMin > fromMax){ DT help; help = fromMin; fromMin = fromMax; fromMax = help; }
00188       DT srcWidth = fromMax-fromMin;
00189       if (srcWidth > 0){
00190         _scale = (toMax - toMin) / srcWidth;
00191         _shift = -fromMin * _scale + toMin;
00192       }
00193       else{
00194         // Our source interval has (nearly) identical left and right interval border.
00195         // Since this case often occurs if images have identical minimum and maximum
00196         // values we handle it so that the source interval is assumed as [fromMin, fromMin+1].
00197         // So the only value from that interval is projected to the minimum value of the
00198         // target interval.
00199         _scale = static_cast<DT>(1);
00200         _shift = toMin - fromMin;
00201       }
00202     }
00203     ML_CATCH_RETHROW;
00204   }
00205   
00241   inline void setFromMinMaxToMinMax(MLDataType fromType, DT fromMin, DT fromMax,
00242                                     MLDataType toType,   DT toMin, DT toMax)
00243   {
00244     ML_TRACE_IN( "ScaleShiftData::setFromMinMaxToMinMax( )" );
00245     ML_TRY
00246     {
00247       bool fromTypeIsInt = MLIsIntType(fromType)!=0;
00248       bool toTypeIsInt   = MLIsIntType(toType)!=0;
00249       if (toMin   > toMax)  { DT help; help = toMin;   toMin   = toMax;   toMax   = help; }
00250       if (fromMin > fromMax){ DT help; help = fromMin; fromMin = fromMax; fromMax = help; }
00251       DT srcWidth = fromMax-fromMin;
00252       if (srcWidth > 0){
00253         if (!fromTypeIsInt && toTypeIsInt) {
00254           // Float -> Int:
00255           // adding 0.99 to the integer range, since that is almost the case
00256           // like adding 1. and avoids having to clamp the result to the int max value.
00257           toMax += 0.99;
00258         } else if (fromTypeIsInt && toTypeIsInt) {
00259           // Int -> Int:
00260           // max+1 is be used for both ranges (which is the same as shifting for
00261           // power-of-two differences in range)
00262           fromMax += 1;
00263           toMax += 1;
00264           srcWidth += 1;
00265         } else {
00266           // Int -> Float:
00267           // use max int value, and not max+1, so that the max integer value will get the
00268           // max float value (like in OpenGL, where the max integer is mapped to 1.)
00269 
00270           // Float -> Float:
00271           // keep max as given
00272         }
00273         _scale = (toMax - toMin) / srcWidth;
00274         _shift = -fromMin * _scale + toMin;
00275       }
00276       else{
00277         // Our source interval has (nearly) identical left and right interval border.
00278         // Since this case often occurs if images have identical minimum and maximum
00279         // values we handle it so that the source interval is assumed as [fromMin, fromMin+1].
00280         // So the only value from that interval is projected to the minimum value of the
00281         // target interval.
00282         _scale = static_cast<DT>(1);
00283         _shift = toMin - fromMin;
00284       }
00285 
00286     }
00287     ML_CATCH_RETHROW;
00288   }
00289 
00291   inline void unset()
00292   {
00293     ML_TRACE_IN_TIME_CRITICAL( "ScaleShiftData::unset( )" );
00294     
00295     _scale = static_cast<DT>(1); 
00296     _shift = static_cast<DT>(0);
00297     _reorderMode = NoReordering;
00298   }
00300   
00301   
00302   //------------------------------------------------------
00304 
00305   //------------------------------------------------------
00306   
00308   inline DT getScale() const { return _scale; }
00309   
00311   inline DT getShift() const { return _shift; }
00313 
00315   inline ReorderMode getReorderMode() const { return _reorderMode; }
00316 
00318   inline void setReorderMode(ReorderMode mode) { _reorderMode = mode; }
00319 
00320 private:
00321   
00323 
00324 
00325   DT _scale;
00326   
00328   DT _shift;
00330 
00332   ReorderMode _reorderMode;
00333 
00334 };
00335 
00337 typedef TScaleShiftData<MLdouble> ScaleShiftData;
00338 
00339 
00340 ML_END_NAMESPACE
00341 
00342 //-----------------------------------------------------------------------------------
00343 //   Stream output for std::ostream
00344 //-----------------------------------------------------------------------------------
00345 namespace std {
00346   
00348   inline ostream& operator<<(ostream& s, const ML_NAMESPACE::ScaleShiftData &ssd)
00349   {
00350     return s << "Scale=" << ssd.getScale() << ",  Shift=" << ssd.getShift();
00351   }
00352   
00353 }
00354 
00355 
00356 #endif //of __mlScaleShiftData_H
00357 
00358 
00359