ML Reference
|
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