itom 1.1.0
|
00001 /* ******************************************************************** 00002 itom software 00003 URL: http://www.uni-stuttgart.de/ito 00004 Copyright (C) 2013, Institut für Technische Optik (ITO), 00005 Universität Stuttgart, Germany 00006 00007 This file is part of itom and its software development toolkit (SDK). 00008 00009 itom is free software; you can redistribute it and/or modify it 00010 under the terms of the GNU Library General Public Licence as published by 00011 the Free Software Foundation; either version 2 of the Licence, or (at 00012 your option) any later version. 00013 00014 In addition, as a special exception, the Institut für Technische 00015 Optik (ITO) gives you certain additional rights. 00016 These rights are described in the ITO LGPL Exception version 1.0, 00017 which can be found in the file LGPL_EXCEPTION.txt in this package. 00018 00019 itom is distributed in the hope that it will be useful, but 00020 WITHOUT ANY WARRANTY; without even the implied warranty of 00021 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library 00022 General Public Licence for more details. 00023 00024 You should have received a copy of the GNU Library General Public License 00025 along with itom. If not, see <http://www.gnu.org/licenses/>. 00026 *********************************************************************** */ 00027 00028 #ifndef __DATAOBJH 00029 #define __DATAOBJH 00030 00031 //#include <crtdbg.h> 00032 #include <cstdlib> 00033 #include <iostream> 00034 #include <complex> 00035 #include <limits> 00036 00037 #if !linux 00038 #pragma warning(disable:4996) 00039 #endif 00040 00041 #define NOMINMAX //see: http://social.msdn.microsoft.com/Forums/sv/vclanguage/thread/d986a370-d856-4f9e-9f14-53f3b18ab63e, this is only an issue with OpenCV 2.4.3, not 2.3.x 00042 00043 #include "opencv/cv.h" 00044 #include "opencv2/core/core.hpp" 00045 00046 #include "../common/sharedStructures.h" 00047 #include "../common/color.h" 00048 00049 #include "readWriteLock.h" 00050 00051 #include <vector> 00052 #include <map> 00053 #include <string> 00054 00055 namespace cv 00056 { 00057 template<> inline ito::float32 saturate_cast<ito::float32>( ito::float64 v) 00058 { 00059 //return (float32)v; 00060 if(cvIsInf(v)) return std::numeric_limits<ito::float32>::infinity(); 00061 if(cvIsNaN(v)) return std::numeric_limits<ito::float32>::signaling_NaN(); 00062 return static_cast<ito::float32>(std::max ( (ito::float64)(- std::numeric_limits<ito::float32>::max()) , std::min ( v , (ito::float64) std::numeric_limits<ito::float32>::max() ))); 00063 } 00064 00065 template<> inline ito::float64 saturate_cast<ito::float64>( ito::float32 v) 00066 { 00067 //return (float64)v; 00068 if(cvIsInf(v)) return std::numeric_limits<ito::float64>::infinity(); 00069 if(cvIsNaN(v)) return std::numeric_limits<ito::float64>::signaling_NaN(); 00070 return static_cast<ito::float64>(v); 00071 } 00072 00073 template<typename _Tp> static inline _Tp saturate_cast(ito::complex128 /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Not defined for input parameter type", "", __FILE__, __LINE__)); return 0; } 00074 template<typename _Tp> static inline _Tp saturate_cast(ito::complex64 /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Not defined for input parameter type", "", __FILE__, __LINE__)); return 0; } 00075 00076 template<typename _Tp> static inline _Tp saturate_cast(ito::Rgba32 /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Not defined for input parameter type", "", __FILE__, __LINE__)); return 0; } 00077 // template<typename _Tp> static inline ito::Rgba32 saturate_cast(_Tp /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Not defined for input parameter type", "", __FILE__, __LINE__)); return 0; } 00078 00079 template<> inline ito::complex64 saturate_cast(ito::uint8 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); } 00080 template<> inline ito::complex64 saturate_cast(ito::int8 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); } 00081 template<> inline ito::complex64 saturate_cast(ito::uint16 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); } 00082 template<> inline ito::complex64 saturate_cast(ito::int16 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); } 00083 template<> inline ito::complex64 saturate_cast(ito::uint32 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); } 00084 template<> inline ito::complex64 saturate_cast(ito::int32 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); } 00085 template<> inline ito::complex64 saturate_cast(ito::float32 v){ return ito::complex64(v,0.0); } 00086 template<> inline ito::complex64 saturate_cast(ito::float64 v){ return ito::complex64(saturate_cast<ito::float32>(v),0.0); } 00087 template<> inline ito::complex64 saturate_cast(ito::complex64 v){ return v; } 00088 template<> inline ito::complex64 saturate_cast(ito::complex128 v){ return std::complex<ito::float32>(saturate_cast<ito::float32>(v.real()),saturate_cast<ito::float32>(v.imag())); } 00089 00090 template<> inline ito::complex128 saturate_cast(ito::uint8 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); } 00091 template<> inline ito::complex128 saturate_cast(ito::int8 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); } 00092 template<> inline ito::complex128 saturate_cast(ito::uint16 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); } 00093 template<> inline ito::complex128 saturate_cast(ito::int16 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); } 00094 template<> inline ito::complex128 saturate_cast(ito::uint32 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); } 00095 template<> inline ito::complex128 saturate_cast(ito::int32 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); } 00096 template<> inline ito::complex128 saturate_cast(ito::float32 v){ return ito::complex128(saturate_cast<ito::float64>(v),0.0); } 00097 template<> inline ito::complex128 saturate_cast(ito::float64 v){ return ito::complex128(v,0.0); } 00098 template<> inline ito::complex128 saturate_cast(ito::complex64 v){ return ito::complex128(saturate_cast<ito::float64>(v.real()),saturate_cast<ito::float64>(v.imag())); } 00099 template<> inline ito::complex128 saturate_cast(ito::complex128 v){ return v; } 00100 00101 // template<> inline ito::Rgba32 saturate_cast(ito::int8 v) {return ito::Rgba32(saturate_cast<ito::uint8>(v));} 00102 template<> inline ito::Rgba32 saturate_cast(ito::uint8 v) {return ito::Rgba32(v);} 00103 template<> inline ito::Rgba32 saturate_cast(ito::uint16 v){return ito::Rgba32(saturate_cast<ito::uint8>(v));} 00104 // template<> inline ito::Rgba32 saturate_cast(ito::int16 v){return ito::Rgba32(saturate_cast<ito::uint8>(v));} 00105 template<> inline ito::Rgba32 saturate_cast(ito::uint32 v) 00106 { 00107 return ito::Rgba32::fromUnsignedLong(v); 00108 } 00109 template<> inline ito::Rgba32 saturate_cast(ito::int32 v) 00110 { 00111 ito::Rgba32 temp; 00112 temp.rgba = static_cast<ito::uint32>(v); 00113 return temp; 00114 } 00115 template<> inline ito::Rgba32 saturate_cast(ito::float32 v){return ito::Rgba32(saturate_cast<ito::uint8>(v));} 00116 template<> inline ito::Rgba32 saturate_cast(ito::float64 v){return ito::Rgba32(saturate_cast<ito::uint8>(v));} 00117 template<> inline ito::Rgba32 saturate_cast(ito::Rgba32 v){return v;} 00118 00119 template<> inline ito::Rgba32 saturate_cast(ito::int8 /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Not defined for output parameter type ito::Rgba32", "", __FILE__, __LINE__)); return ito::Rgba32(); } 00120 template<> inline ito::Rgba32 saturate_cast(ito::int16 /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Not defined for output parameter type ito::Rgba32", "", __FILE__, __LINE__)); return ito::Rgba32(); } 00121 template<> inline ito::Rgba32 saturate_cast(ito::complex128 /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Not defined for output parameter type ito::Rgba32", "", __FILE__, __LINE__)); return ito::Rgba32(); } 00122 template<> inline ito::Rgba32 saturate_cast(ito::complex64 /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Not defined for output parameter type ito::Rgba32", "", __FILE__, __LINE__)); return ito::Rgba32(); } 00123 00124 template<> inline ito::uint8 saturate_cast(ito::Rgba32 v){return saturate_cast<ito::uint8>(v.gray());}; 00125 //template<> inline ito::int16 saturate_cast(ito::Rgba32 v){return saturate_cast<ito::int16>(v.gray());}; 00126 template<> inline ito::uint16 saturate_cast(ito::Rgba32 v){return saturate_cast<ito::uint16>(v.gray());}; 00127 template<> inline ito::uint32 saturate_cast(ito::Rgba32 v){return v.argb();}; 00128 template<> inline ito::int32 saturate_cast(ito::Rgba32 v){return (ito::int32)(v.argb());}; 00129 template<> inline ito::float32 saturate_cast(ito::Rgba32 v){return v.gray();}; 00130 template<> inline ito::float64 saturate_cast(ito::Rgba32 v){return (ito::float64)v.gray();}; 00131 00132 00133 template<> class DataType<ito::Rgba32> 00134 { 00135 public: 00136 typedef ito::Rgba32 value_type; 00137 typedef ito::uint8 channel_type; 00138 typedef Vec<channel_type, 4> work_type; 00139 typedef value_type vec_type; 00140 enum 00141 { 00142 generic_type = 0, 00143 depth = cv::DataDepth<channel_type>::value, 00144 channels = 4, 00145 fmt = ((channels-1)<<8) + cv::DataDepth<channel_type>::fmt, 00146 type = CV_MAKETYPE(depth, channels) 00147 }; 00148 }; 00149 00150 template<> class DataType<ito::RedChannel> 00151 { 00152 public: 00153 typedef ito::RedChannel value_type; 00154 typedef ito::uint8 channel_type; 00155 typedef Vec<channel_type, 4> work_type; 00156 typedef value_type vec_type; 00157 enum 00158 { 00159 generic_type = 0, 00160 depth = cv::DataDepth<channel_type>::value, 00161 channels = 4, 00162 fmt = ((channels-1)<<8) + cv::DataDepth<channel_type>::fmt, 00163 type = CV_MAKETYPE(depth, channels) 00164 }; 00165 }; 00166 00167 template<> class DataType<ito::GreenChannel> 00168 { 00169 public: 00170 typedef ito::GreenChannel value_type; 00171 typedef ito::uint8 channel_type; 00172 typedef Vec<channel_type, 4> work_type; 00173 typedef value_type vec_type; 00174 enum 00175 { 00176 generic_type = 0, 00177 depth = cv::DataDepth<channel_type>::value, 00178 channels = 4, 00179 fmt = ((channels-1)<<8) + cv::DataDepth<channel_type>::fmt, 00180 type = CV_MAKETYPE(depth, channels) 00181 }; 00182 }; 00183 00184 template<> class DataType<ito::BlueChannel> 00185 { 00186 public: 00187 typedef ito::BlueChannel value_type; 00188 typedef ito::uint8 channel_type; 00189 typedef Vec<channel_type, 4> work_type; 00190 typedef value_type vec_type; 00191 enum 00192 { 00193 generic_type = 0, 00194 depth = cv::DataDepth<channel_type>::value, 00195 channels = 4, 00196 fmt = ((channels-1)<<8) + cv::DataDepth<channel_type>::fmt, 00197 type = CV_MAKETYPE(depth, channels) 00198 }; 00199 }; 00200 00201 template<> class DataType<ito::AlphaChannel> 00202 { 00203 public: 00204 typedef ito::AlphaChannel value_type; 00205 typedef ito::uint8 channel_type; 00206 typedef Vec<channel_type, 4> work_type; 00207 typedef value_type vec_type; 00208 enum 00209 { 00210 generic_type = 0, 00211 depth = cv::DataDepth<channel_type>::value, 00212 channels = 4, 00213 fmt = ((channels-1)<<8) + cv::DataDepth<channel_type>::fmt, 00214 type = CV_MAKETYPE(depth, channels) 00215 }; 00216 }; 00217 00218 00219 } // namespace cv 00220 00221 namespace ito { 00222 00223 #define __ITODEBUG 1 00224 00225 class DObjIterator; // Forward declaration 00226 class DataObject; 00227 class Range; 00228 struct Scalar; 00229 class DataObjectTags; 00230 class DataObjectTagType; 00231 00232 //---------------------------------------------------------------------------------------------------------------------------------- 00237 class Range 00238 { 00239 public: 00240 Range() : start(0), end(0) {} 00241 Range(int _start, int _end) { _start < _end ? (end = _end, start = _start) : (start = _end, end = _start); } 00242 inline unsigned int size() const { return end - start; } 00243 inline bool empty() const { return (start == end); } 00244 static Range all() { return Range(INT_MIN, INT_MAX); } 00246 int start; 00247 int end; 00248 }; 00249 00250 //---------------------------------------------------------------------------------------------------------------------------------- 00251 class DataObjectTagType 00252 { 00253 private: 00254 double m_dVal; 00255 std::string m_strValue; 00256 int m_type; 00257 00258 public: 00260 DataObjectTagType() : m_dVal(0), m_strValue(""), m_type(DataObjectTagType::typeInvalid){}; 00261 DataObjectTagType(double dVal) : m_dVal(dVal), m_strValue(""), m_type(DataObjectTagType::typeDouble){}; 00262 DataObjectTagType(std::string strVal) : m_dVal(std::numeric_limits<double>::signaling_NaN()), m_strValue(strVal), m_type(DataObjectTagType::typeString){}; 00263 DataObjectTagType(const char* cVal) : m_dVal(std::numeric_limits<double>::signaling_NaN()), m_type(DataObjectTagType::typeString){ cVal == NULL ? m_strValue = "" : m_strValue = cVal;}; 00265 DataObjectTagType(const DataObjectTagType& copyConstr) : m_dVal(copyConstr.m_dVal), m_strValue(copyConstr.m_strValue), m_type(copyConstr.m_type){}; 00266 00267 DataObjectTagType & operator = (const DataObjectTagType &rhs) 00268 { 00269 this->m_dVal = rhs.m_dVal; 00270 this->m_strValue = rhs.m_strValue; 00271 this->m_type = rhs.m_type; 00272 00273 return *this; 00274 } 00275 00276 enum tTagType 00277 { 00278 typeInvalid = 0x000000, 00279 typeDouble = 0x000008, 00280 typeString = 0x000020 00281 }; 00282 00283 inline int getType(void) const {return m_type;}; 00284 inline bool isValid(void) const { return (m_type == DataObjectTagType::typeInvalid) ? false: true;}; 00285 00291 inline double getVal_ToDouble(void) 00292 { 00293 if(m_type == DataObjectTagType::typeInvalid) 00294 { 00295 return std::numeric_limits<double>::signaling_NaN(); 00296 } 00297 else if(m_type == DataObjectTagType::typeDouble) 00298 { 00299 return m_dVal; 00300 } 00301 else 00302 { 00303 double dVal = std::numeric_limits<double>::signaling_NaN(); 00304 //dVal = atof(m_strValue.c_str()); //sometimes the result of that line has been arbitrary, therefore this conversion should fail. 00305 return dVal; 00306 } 00307 } 00308 00314 inline std::string getVal_ToString(void) 00315 { 00316 if(m_type == DataObjectTagType::typeInvalid) 00317 { 00318 return std::string(); 00319 } 00320 else if(m_type == DataObjectTagType::typeString) 00321 { 00322 return m_strValue; 00323 } 00324 else 00325 { 00326 if (cvIsNaN(m_dVal)) return std::string("NaN"); 00327 if (cvIsInf(m_dVal)) return std::string("Inf"); 00328 /*if(m_dVal == std::numeric_limits<double>::quiet_NaN()) return std::string("NaN"); 00329 if(m_dVal == std::numeric_limits<double>::signaling_NaN()) return std::string("NaN"); 00330 if(m_dVal == std::numeric_limits<double>::infinity()) return std::string("Inf");*/ 00331 00332 std::ostringstream strs; 00333 strs << m_dVal; 00334 00335 return strs.str(); 00336 } 00337 } 00338 }; 00339 00340 //---------------------------------------------------------------------------------------------------------------------------------- 00349 class DataObjectTags 00350 { 00351 private: 00352 std::map<std::string, DataObjectTagType> m_tags; 00353 std::vector<double> m_axisOffsets; 00354 std::vector<double> m_axisScales; 00355 std::vector<std::string> m_axisDescription; 00356 std::vector<std::string> m_axisUnit; 00357 double m_valueOffset; 00358 double m_valueScale; 00359 std::string m_valueDescription; 00360 std::string m_valueUnit; 00362 double m_rotMatrix[9]; 00364 friend class DataObject; 00365 00366 00367 public: 00369 DataObjectTags(unsigned int totalAxisNum) : m_valueOffset(0.0), m_valueScale(1.0), m_valueDescription(""), m_valueUnit("") 00370 { 00371 m_tags.clear(); 00372 m_axisOffsets.resize(totalAxisNum, 0.0); 00373 m_axisScales.resize(totalAxisNum, 1.0); 00374 m_axisDescription.resize(totalAxisNum, ""); 00375 m_axisUnit.resize(totalAxisNum, ""); 00376 m_valueUnit = std::string(); 00377 memset(m_rotMatrix, 0, sizeof(double)*9); 00378 m_rotMatrix[0] = 1; // r11 00379 m_rotMatrix[4] = 1; // r22 00380 m_rotMatrix[8] = 1; // r33 00381 } 00382 00384 ~DataObjectTags() 00385 { 00386 m_tags.clear(); 00387 m_axisOffsets.clear(); 00388 m_axisScales.clear(); 00389 m_axisDescription.clear(); 00390 m_axisUnit.clear(); 00391 } 00392 00394 DataObjectTags(const DataObjectTags& copyConstr) : m_tags(copyConstr.m_tags), m_axisOffsets(copyConstr.m_axisOffsets), 00395 m_axisScales(copyConstr.m_axisScales), m_axisDescription(copyConstr.m_axisDescription), 00396 m_axisUnit(copyConstr.m_axisUnit), m_valueOffset(copyConstr.m_valueOffset), m_valueScale(copyConstr.m_valueScale), 00397 m_valueDescription(copyConstr.m_valueDescription), m_valueUnit(copyConstr.m_valueUnit) 00398 { 00399 // m_tags = copyConstr.m_tags; 00400 // m_axisOffsets = copyConstr.m_axisOffsets; 00401 // m_axisScales = copyConstr.m_axisScales; 00402 // m_axisDescription = copyConstr.m_axisDescription; 00403 // m_axisUnit = copyConstr.m_axisUnit; 00404 // m_valueOffset = copyConstr.m_valueOffset; 00405 // m_valueScale = copyConstr.m_valueScale; 00406 // m_valueDescription = copyConstr.m_valueDescription; 00407 // m_valueUnit = copyConstr.m_valueUnit; 00408 memcpy(m_rotMatrix,copyConstr.m_rotMatrix, sizeof(double)*9); 00409 } 00410 00411 //friend class DataObjectTags; //I am my best friend (my own and only friend, and therefore my copy-constr has access to my friends members. nice.) 00412 }; 00413 00414 //---------------------------------------------------------------------------------------------------------------------------------- 00415 00416 class DObjConstIterator 00417 { 00418 public: 00419 00421 DObjConstIterator(); 00423 DObjConstIterator(const DataObject* _dObj, int pos = 0); 00425 DObjConstIterator(const DObjConstIterator& it); 00426 00428 DObjConstIterator& operator = (const DObjConstIterator& it); 00430 uchar* operator *() const; 00432 uchar* operator [](int i) const; 00433 00435 DObjConstIterator& operator += (int ofs); 00437 DObjConstIterator& operator -= (int ofs); 00439 DObjConstIterator& operator --(); 00441 DObjConstIterator operator --(int); 00443 DObjConstIterator& operator ++(); 00445 DObjConstIterator operator ++(int); 00446 00447 bool operator == (const DObjConstIterator& dObjIt); 00448 bool operator != (const DObjConstIterator& dObjIt); 00449 bool operator < (const DObjConstIterator& dObjIt); 00450 bool operator > (const DObjConstIterator& dObjIt); 00451 bool operator <= (const DObjConstIterator& dObjIt); 00452 bool operator >= (const DObjConstIterator& dObjIt); 00453 00454 protected: 00455 void seekAbs(int ofs); 00456 void seekRel(int ofs); 00457 00458 const DataObject* dObj; 00459 bool planeContinuous; 00460 int elemSize; 00461 uchar* ptr; 00462 uchar* sliceStart; 00463 uchar* sliceEnd; 00464 int plane; 00465 }; 00466 00467 //---------------------------------------------------------------------------------------------------------------------------------- 00468 class DObjIterator : public DObjConstIterator 00469 { 00470 public: 00471 00473 DObjIterator(); 00475 DObjIterator(DataObject* _dObj, int pos = 0); 00477 DObjIterator(const DObjIterator& it); 00478 00480 DObjIterator& operator = (const DObjIterator& it); 00482 uchar* operator *(); 00484 uchar* operator [](int i); 00485 00487 DObjIterator& operator += (int ofs); 00489 DObjIterator& operator -= (int ofs); 00491 DObjIterator& operator --(); 00493 DObjIterator operator --(int); 00495 DObjIterator& operator ++(); 00497 DObjIterator operator ++(int); 00498 }; 00499 00500 //---------------------------------------------------------------------------------------------------------------------------------- 00501 class DataObject 00502 { 00503 private: 00504 00506 00520 //length(sizes) == length(steps) 00521 void createHeader(const unsigned char dimensions, const int *sizes, const int *steps, const int elemSize) 00522 { 00523 if(dimensions == 1) 00524 { 00525 cv::error(cv::Exception(CV_StsAssert, "number of dimensions must be at least 2", "", __FILE__, __LINE__)); 00526 } 00527 00528 m_dims = dimensions; 00529 00530 if(dimensions > 0) 00531 { 00532 if (m_roi.m_p) 00533 { 00534 if (*(m_roi.m_p-1) != dimensions) 00535 { 00536 delete[] (m_roi.m_p - 1); 00537 00538 m_roi.m_p = new int [(dimensions + 1) + (dimensions + 1) + (dimensions + 1)]; 00539 m_osize.m_p = static_cast<int *>(m_roi.m_p + dimensions) + 1; 00540 m_osize.m_p[-1] = dimensions; 00541 m_size.m_p = static_cast<int *>(m_osize.m_p + dimensions) + 1; 00542 m_size.m_p[-1] = dimensions; 00543 m_roi.m_p = m_roi.m_p + 1; 00544 m_roi.m_p[-1] = dimensions; 00545 } 00546 } 00547 else 00548 { 00549 m_roi.m_p = new int [(dimensions + 1) + (dimensions + 1) + (dimensions + 1)]; 00550 m_osize.m_p = static_cast<int *>(m_roi.m_p + dimensions) + 1; 00551 m_osize.m_p[-1] = dimensions; 00552 m_size.m_p = static_cast<int *>(m_osize.m_p + dimensions) + 1; 00553 m_size.m_p[-1] = dimensions; 00554 m_roi.m_p = m_roi.m_p + 1; 00555 m_roi.m_p[-1] = dimensions; 00556 } 00557 00558 for (uchar n = 0 ; n < dimensions ; n++) 00559 { 00560 m_size.m_p[n] = sizes[n]; 00561 m_roi.m_p[n] = 0; 00562 00563 if(steps == NULL || n == 0) 00564 { 00565 m_osize.m_p[n] = sizes[n]; 00566 } 00567 else if(n == dimensions - 1) //last element 00568 { 00569 if (elemSize == 0) 00570 cv::Exception(CV_StsAssert, "elemSize is zero", "", __FILE__, __LINE__); 00571 m_osize.m_p[n] = steps[n-1] / elemSize; 00572 } 00573 else /*if(n < dimensions -1)*/ 00574 { 00575 if (steps[n] == 0) 00576 cv::Exception(CV_StsAssert, "step size is zero", "", __FILE__, __LINE__); 00577 m_osize.m_p[n] = steps[n - 1] / steps[n]; 00578 } 00579 } 00580 } 00581 } 00582 00584 00597 void createHeaderWithROI(const unsigned char dimensions, const int *sizes, const int *osizes = NULL, const int *roi = NULL) 00598 { 00599 if(dimensions == 1) 00600 { 00601 cv::error(cv::Exception(CV_StsAssert, "number of dimensions must be at least 2", "", __FILE__, __LINE__)); 00602 } 00603 00604 m_dims = dimensions; 00605 00606 if(dimensions > 0) 00607 { 00608 00609 if (m_roi.m_p) 00610 { 00611 if (*(m_roi.m_p-1) != dimensions) 00612 { 00613 delete[] (m_roi.m_p-1); 00614 00615 m_roi.m_p = new int [(dimensions + 1) + (dimensions + 1) + (dimensions + 1)]; 00616 m_osize.m_p = static_cast<int *>(m_roi.m_p + dimensions) + 1; 00617 m_osize.m_p[-1] = dimensions; 00618 m_size.m_p = static_cast<int *>(m_osize.m_p + dimensions) + 1; 00619 m_size.m_p[-1] = dimensions; 00620 m_roi.m_p = m_roi.m_p + 1; //move m_p pointer by one 00621 m_roi.m_p[-1] = dimensions; 00622 } 00623 } 00624 else 00625 { 00626 m_roi.m_p = new int [(dimensions + 1) + (dimensions + 1) + (dimensions + 1)]; 00627 m_osize.m_p = static_cast<int *>(m_roi.m_p + dimensions) + 1; 00628 m_osize.m_p[-1] = dimensions; 00629 m_size.m_p = static_cast<int *>(m_osize.m_p + dimensions) + 1; 00630 m_size.m_p[-1] = dimensions; 00631 m_roi.m_p = m_roi.m_p + 1; //move m_p pointer by one 00632 m_roi.m_p[-1] = dimensions; 00633 } 00634 00635 for (uchar n = 0; n < dimensions; n++) 00636 { 00637 m_size.m_p[n] = sizes[n]; 00638 00639 if (osizes) 00640 { 00641 m_osize.m_p[n] = osizes[n]; 00642 } 00643 else 00644 { 00645 m_osize.m_p[n] = sizes[n]; 00646 } 00647 00648 if (roi) 00649 { 00650 m_roi.m_p[n] = roi[n]; 00651 } 00652 else 00653 { 00654 m_roi.m_p[n] = 0; 00655 } 00656 } 00657 } 00658 } 00659 00660 void create(const unsigned char dimensions, const int *sizes, const int type, const unsigned char continuous, const uchar* continuousDataPtr = NULL, const int* steps = NULL); 00661 void create(const unsigned char dimensions, const int *sizes, const int type, const cv::Mat* planes, const unsigned int nrOfPlanes); 00662 00663 void freeData(void); 00664 void secureFreeData(void); 00667 //---------------------------------------------------------------------------------------------------------------------------------- 00668 ito::RetVal matNumToIdx(const int matNum, int *matIdx) const; 00669 00671 00679 inline ito::RetVal matIdxToNum(const unsigned int *matIdx, int *matNum) const 00680 { 00681 *matNum = 0; 00682 if (m_dims <= 2) 00683 { 00684 return 0; 00685 } 00686 00687 int planeSize = 1; 00688 00689 for (int n = m_dims - 3; n >= 0; n--) 00690 { 00691 #if __ITODEBUG 00692 if (((int)matIdx[n] + m_roi[n]) >= m_osize[n]) 00693 { 00694 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__, __LINE__)); 00695 } 00696 #endif 00697 (*matNum) += ((int)matIdx[n] + m_roi[n]) * planeSize; //CAST_TODO 00698 planeSize *= m_osize[n]; 00699 } 00700 00701 return 0; 00702 } 00703 00704 struct MSize 00705 { 00706 inline MSize() : m_p(NULL) {} 00707 inline int operator [] (const int dim) const 00708 { 00709 return m_p[dim]; //return the size value. this operator corresponds to the real data representation in memory 00710 }; 00711 inline operator const int * () const { return m_p; } 00712 bool operator == (const MSize& sz) const 00713 { 00714 if(m_p == NULL || sz.m_p == NULL) 00715 { 00716 return sz.m_p == m_p; 00717 } 00718 00719 int d = m_p[-1], dsz = sz.m_p[-1]; 00720 if( d != dsz ) 00721 return false; 00722 if( d == 2 ) 00723 { 00724 return m_p[0] == sz.m_p[0] && m_p[1] == sz.m_p[1]; 00725 } 00726 00727 for( int i = 0; i < d - 2; i++ ) 00728 { 00729 if( m_p[i] != sz.m_p[i] ) 00730 { 00731 return false; 00732 } 00733 } 00734 return (m_p[d - 2] == sz.m_p[d - 2]) && (m_p[d - 1] == sz.m_p[d - 1]); 00735 } 00736 00737 inline bool operator != (const MSize& sz) const { return !(*this == sz); } 00738 00739 int *m_p; 00740 }; 00741 00742 struct MROI 00743 { 00744 inline MROI() : m_p(NULL) {}; 00745 inline int operator [] (const int dim) const 00746 { 00747 return m_p[dim]; //return the size value. this operator corresponds to the real data representation in memory 00748 } 00749 00750 bool operator == (const MROI & rroi) const 00751 { 00752 if(m_p == NULL || rroi.m_p == NULL) 00753 { 00754 return rroi.m_p == m_p; 00755 } 00756 00757 if (m_p[-1] != rroi.m_p[-1]) 00758 { 00759 return false; 00760 } 00761 00762 int d = m_p[-1]; 00763 for (int n = 0; n < d - 2; n++) 00764 { 00765 if (m_p[n] != rroi.m_p[n]) 00766 { 00767 return false; 00768 } 00769 } 00770 00771 return m_p[d - 2] == rroi.m_p[d - 2] && m_p[d - 1] == rroi.m_p[d - 1]; 00772 00773 } 00774 00775 int *m_p; 00776 }; 00777 00778 DataObject(const DataObject& dObj, bool transposed); 00780 char m_continuous; 00781 char m_owndata; 00782 int m_type; 00783 int *m_pRefCount; 00784 int m_dims; 00785 MSize m_osize; 00786 MROI m_roi; 00787 MSize m_size; 00788 uchar **m_data; 00789 ReadWriteLock *m_objSharedDataLock; 00790 DataObjectTags *m_pDataObjectTags; 00791 ReadWriteLock m_objHeaderLock; 00792 const static int m_sizeofs; 00793 00794 inline int mdata_realloc(const int size) 00795 { 00796 if (m_data) 00797 { 00798 m_data = static_cast<uchar **>(realloc(m_data - m_sizeofs, (size + m_sizeofs) * sizeof(uchar *))); 00799 } 00800 else 00801 { 00802 int numBytes = (size + m_sizeofs) * sizeof(uchar *); 00803 m_data = static_cast<uchar **>(calloc(numBytes, 1)); 00804 memset( m_data, 0, numBytes ); 00805 } 00806 (*reinterpret_cast<int*>(m_data)) = size; 00807 m_data += m_sizeofs; 00808 return 0; 00809 } 00810 inline int mdata_size(void) const 00811 { 00812 if (!m_data) 00813 return 0; 00814 else 00815 return (*reinterpret_cast<int *>(m_data - m_sizeofs)); 00816 } 00817 inline int mdata_free() 00818 { 00819 if (m_data) 00820 { 00821 uchar **ptr = m_data - m_sizeofs; 00822 free(ptr); 00823 } 00824 m_data = NULL; 00825 return 0; 00826 } 00827 00828 //low-level, templated methods 00829 //most low-level methods are marked "friend" such that they can access private members of their data object parameters 00830 template<typename _Tp> friend RetVal CreateFunc(DataObject *dObj, const unsigned char dimensions, const int *sizes, const unsigned char continuous, const uchar* continuousDataPtr, const int* steps); 00831 template<typename _Tp> friend RetVal CreateFuncWithCVPlanes(DataObject *dObj, const unsigned char dimensions, const int *sizes, const cv::Mat* planes, const unsigned int nrOfPlanes); 00832 template<typename _Tp> friend RetVal FreeFunc(DataObject *dObj); 00833 template<typename _Tp> friend RetVal SecureFreeFunc(DataObject *dObj); 00834 template<typename _Tp> friend RetVal CopyToFunc(const DataObject &lhs, DataObject &rhs, unsigned char regionOnly); 00835 template<typename _Tp> friend RetVal ConvertToFunc(const DataObject &lhs, DataObject &rhs, const int type, const double alpha, const double beta); 00836 template<typename _Tp> friend RetVal AdjustROIFunc(DataObject *dObj, const int *lims); 00837 template<typename _Tp> friend RetVal MinMaxLocFunc(const DataObject &dObj, double *minVal, double *maxVal, int *minPos, int *maxPos); 00838 template<typename _Tp> friend RetVal AssignScalarFunc(const DataObject *src, const ito::tDataType type, const void *scalar); 00839 template<typename _Tp> friend RetVal MakeContinuousFunc(const DataObject &dObj, DataObject &resDObj); 00840 template<typename _Tp> friend RetVal EvaluateTransposeFlagFunc(DataObject *dObj); 00841 template<typename _Tp> friend RetVal CalcMinMaxValues(DataObject *lhs, double &result_min, double &result_max, const int cmplxSel = 0); 00842 template<typename _Tp> friend std::ostream& coutFunc(std::ostream& out, const DataObject& dObj); 00843 00844 // more friends due to change of std::vector to int ** for m_data ... 00845 template<typename _Tp> friend RetVal GetRangeFunc(DataObject *dObj, const int dtop, const int dbottom, const int dleft, const int dright); 00846 template<typename _Tp> friend RetVal AdjustROIFunc(DataObject *dObj, int dtop, int dbottom, int dleft, int dright); 00847 00848 public: 00849 int seekMat(const int matNum, const int numMats) const; 00850 int seekMat(const int matNum) const; 00851 int calcNumMats(void) const; 00852 00853 // TAGSPACEFUNCTIONS 00854 00856 inline double getValueOffset() const 00857 { 00858 if(!m_pDataObjectTags) return 0.0; // default 00859 return m_pDataObjectTags->m_valueOffset; 00860 } 00861 00863 inline double getValueScale() const 00864 { 00865 if(!m_pDataObjectTags) return 1.0; // default 00866 return m_pDataObjectTags->m_valueScale; 00867 } 00868 00870 inline const std::string getValueUnit() const 00871 { 00872 if(!m_pDataObjectTags) return std::string(); //default 00873 return m_pDataObjectTags->m_valueUnit; 00874 } 00875 00877 inline std::string getValueDescription() const 00878 { 00879 if(!m_pDataObjectTags) return std::string(); //default 00880 return m_pDataObjectTags->m_valueDescription; 00881 } 00882 00884 inline double getAxisOffset(const int axisNum) const 00885 { 00886 if(axisNum < 0 || axisNum >= m_dims) 00887 { 00888 cv::error(cv::Exception(CV_StsError, "Parameter axisNum out of range." ,"", __FILE__, __LINE__)); 00889 } 00890 if(!m_pDataObjectTags) return 0.0; // default 00891 00892 return m_pDataObjectTags->m_axisOffsets[axisNum] - m_roi[axisNum]; 00893 } 00894 00896 inline double getAxisScale(const int axisNum) const 00897 { 00898 if(axisNum < 0 || axisNum >= m_dims) 00899 { 00900 cv::error(cv::Exception(CV_StsError, "Parameter axisNum out of range." ,"", __FILE__, __LINE__)); 00901 } 00902 if(!m_pDataObjectTags) return 1.0; // default 00903 00904 return m_pDataObjectTags->m_axisScales[axisNum]; 00905 } 00906 00908 inline const std::string getAxisUnit(const int axisNum, bool &validOperation) const 00909 { 00910 if(axisNum < 0 || axisNum >= m_dims) 00911 { 00912 validOperation = false; 00913 cv::error(cv::Exception(CV_StsError, "Parameter axisNum out of range." ,"", __FILE__, __LINE__)); 00914 } 00915 if(!m_pDataObjectTags) 00916 { 00917 validOperation = false; 00918 return std::string(); //error 00919 } 00920 validOperation = true; 00921 return m_pDataObjectTags->m_axisUnit[axisNum]; 00922 } 00923 00925 const inline std::string getAxisDescription(const int axisNum, bool &validOperation) const 00926 { 00927 if(axisNum < 0 || axisNum >= m_dims) 00928 { 00929 validOperation = false; 00930 cv::error(cv::Exception(CV_StsError, "Parameter axisNum out of range." ,"", __FILE__, __LINE__)); 00931 } 00932 if(!m_pDataObjectTags) 00933 { 00934 validOperation = false; 00935 return std::string(); //error 00936 } 00937 00938 validOperation = true; 00939 return m_pDataObjectTags->m_axisDescription[axisNum]; 00940 } 00941 00942 inline DataObjectTagType getTag(const std::string &key, bool &validOperation) const 00943 { 00944 validOperation = false; 00945 if(!m_pDataObjectTags) 00946 { 00947 return DataObjectTagType(); //error 00948 } 00949 std::map<std::string, DataObjectTagType>::iterator it = m_pDataObjectTags->m_tags.find(key); 00950 if(it != m_pDataObjectTags->m_tags.end()) 00951 { 00952 validOperation = true; 00953 return it->second; 00954 } 00955 return DataObjectTagType(); 00956 } 00957 00958 inline bool getTagByIndex(const int tagNumber, std::string &key, DataObjectTagType &value) const 00959 { 00960 if(!m_pDataObjectTags) 00961 { 00962 key = std::string(); 00963 value = std::string(); 00964 return false; 00965 } 00966 00967 if((tagNumber < 0) || ((int)(tagNumber + 1) > (int)m_pDataObjectTags->m_tags.size())) 00968 { 00969 key = std::string(); 00970 value = std::string(); 00971 return false; 00972 } 00973 std::map<std::string, DataObjectTagType>::iterator it = m_pDataObjectTags->m_tags.begin(); 00974 for(int i = 0; i < tagNumber; i++) 00975 { 00976 ++it; 00977 } 00978 00979 key = (*it).first; 00980 value = (*it).second; 00981 return true; 00982 } 00983 00985 inline std::string getTagKey(const int tagNumber, bool &validOperation) const 00986 { 00987 if(!m_pDataObjectTags) 00988 { 00989 validOperation = false; 00990 return std::string(""); //error 00991 } 00992 if((tagNumber < 0) || ((int)(tagNumber + 1) > (int)m_pDataObjectTags->m_tags.size())) 00993 { 00994 validOperation = false; 00995 return std::string(""); //does not exist 00996 } 00997 std::map<std::string, DataObjectTagType>::iterator it = m_pDataObjectTags->m_tags.begin(); 00998 validOperation = true; 00999 for(int i = 0; i < tagNumber; i++) 01000 { 01001 ++it; 01002 } 01003 return (*it).first; 01004 } 01005 01007 inline int getTagListSize() const 01008 { 01009 if(!m_pDataObjectTags) return 0; //error 01010 return static_cast<int>(m_pDataObjectTags->m_tags.size()); 01011 } 01012 01013 // inline void setValueOffset(double offset) { m_valueOffset =offset; } 01014 // inline void setValueScale(double scale) { m_valueScale =scale; } 01015 01017 inline int setValueUnit(const std::string &unit) 01018 { 01019 if(!m_pDataObjectTags) return 1; //error 01020 m_pDataObjectTags->m_valueUnit = unit; 01021 return 0; 01022 } 01023 01025 inline int setValueDescription(const std::string &description) 01026 { 01027 if(!m_pDataObjectTags) return 1; //error 01028 m_pDataObjectTags->m_valueDescription = description; 01029 return 0; 01030 } 01031 01032 //inline lead to a linker error on MSVC when calling from several methods 01033 int setAxisOffset(const unsigned int axisNum, const double offset); 01034 int setAxisScale(const unsigned int axisNum, const double scale); 01035 int setAxisUnit(const unsigned int axisNum, const std::string &unit); 01036 int setAxisDescription(const unsigned int axisNum, const std::string &description); 01037 int setTag(const std::string &key, const DataObjectTagType &value); 01038 bool existTag(const std::string &key) const; 01039 bool deleteTag(const std::string &key); 01040 bool deleteAllTags(); 01041 int addToProtocol(const std::string &value); 01042 01043 01054 inline double getPhysToPix(const unsigned int dim, const double phys, bool &isInsideImage) const 01055 { 01056 double tPx = 0.0; 01057 if(static_cast<int>(dim) >= m_dims) 01058 { 01059 if(phys == 0.0) 01060 { 01061 isInsideImage = true; 01062 } 01063 else 01064 { 01065 isInsideImage = false; 01066 } 01067 return 0.0; 01068 } 01069 01070 if(m_pDataObjectTags) 01071 { 01072 tPx = (phys / getAxisScale(dim) + getAxisOffset(dim)); 01073 } 01074 else 01075 { 01076 tPx = phys; 01077 } 01078 01079 if(tPx > getSize(dim) - 1) 01080 { 01081 isInsideImage = false; 01082 tPx = static_cast<double>(getSize(dim)- 1); 01083 } 01084 else if( tPx < 0) 01085 { 01086 isInsideImage = false; 01087 tPx = 0; 01088 } 01089 else 01090 { 01091 isInsideImage = true; 01092 } 01093 01094 return tPx; 01095 } 01096 01100 inline int getPhysToPix2D(const double physY, double &tPxY, bool &isInsideImageY, const double physX, double &tPxX, bool &isInsideImageX) const 01101 { 01102 if(m_dims < 2) 01103 { 01104 tPxY = physY; 01105 if(physY != 0.0) 01106 { 01107 isInsideImageY = false; 01108 } 01109 01110 if(m_pDataObjectTags) 01111 { 01112 tPxX = physX / m_pDataObjectTags->m_axisScales[0] + m_pDataObjectTags->m_axisOffsets[0]; 01113 } 01114 else 01115 { 01116 tPxX = physX; 01117 } 01118 01119 if(tPxX > m_size[0] - 1) 01120 { 01121 isInsideImageX = false; 01122 tPxX = static_cast<double>(m_size[0] - 1); 01123 } 01124 } 01125 else 01126 { 01127 if(m_pDataObjectTags) 01128 { 01129 tPxX = physX / m_pDataObjectTags->m_axisScales[m_dims - 1] + m_pDataObjectTags->m_axisOffsets[m_dims - 1]; 01130 tPxY = physY / m_pDataObjectTags->m_axisScales[m_dims - 2] + m_pDataObjectTags->m_axisOffsets[m_dims - 2]; 01131 } 01132 else 01133 { 01134 tPxX = physX; 01135 tPxY = physY; 01136 } 01137 01138 if(tPxY > m_size[m_dims - 2] - 1) 01139 { 01140 isInsideImageY = false; 01141 tPxY = static_cast<double>(m_size[m_dims - 2] - 1); 01142 } 01143 if(tPxX > m_size[m_dims - 1] - 1) 01144 { 01145 isInsideImageX = false; 01146 tPxY = static_cast<double>(m_size[m_dims - 1] - 1); 01147 } 01148 } 01149 01150 if(tPxX < 0) 01151 { 01152 tPxX = 0; 01153 isInsideImageX = false; 01154 } 01155 if(tPxY < 0) 01156 { 01157 tPxY = 0; 01158 isInsideImageY = false; 01159 } 01160 return 0; 01161 } 01162 01172 inline double getPixToPhys(const unsigned int dim, const double pix, bool &isInsideImage) const 01173 { 01174 double tPhys = 0.0; 01175 if(static_cast<int>(dim) >= m_dims) 01176 { 01177 if(pix == 0) 01178 { 01179 isInsideImage = true; 01180 } 01181 else 01182 { 01183 isInsideImage = false; 01184 } 01185 return 0.0; 01186 } 01187 if(m_pDataObjectTags) 01188 { 01189 tPhys = (pix - getAxisOffset(dim)) * getAxisScale(dim); 01190 } 01191 else 01192 { 01193 tPhys = pix; 01194 } 01195 01196 if((pix > getSize(dim) - 1) || (pix < 0)) 01197 { 01198 isInsideImage = false; 01199 } 01200 else 01201 { 01202 isInsideImage = true; 01203 } 01204 01205 return tPhys; 01206 } 01207 01222 inline RetVal setXYRotationalMatrix(double r11, double r12, double r13, double r21, double r22, double r23, double r31, double r32, double r33) 01223 { 01224 if(!m_pDataObjectTags) return RetVal(retError, 0, "Tagspace not initialized"); // error 01225 m_pDataObjectTags->m_rotMatrix[0] = r11; 01226 m_pDataObjectTags->m_rotMatrix[1] = r12; 01227 m_pDataObjectTags->m_rotMatrix[2] = r13; 01228 m_pDataObjectTags->m_rotMatrix[3] = r21; 01229 m_pDataObjectTags->m_rotMatrix[4] = r22; 01230 m_pDataObjectTags->m_rotMatrix[5] = r23; 01231 m_pDataObjectTags->m_rotMatrix[6] = r31; 01232 m_pDataObjectTags->m_rotMatrix[7] = r32; 01233 m_pDataObjectTags->m_rotMatrix[8] = r33; 01234 return retOk; 01235 } 01236 01251 inline RetVal getXYRotationalMatrix(double &r11, double &r12, double &r13, double &r21, double &r22, double &r23, double &r31, double &r32, double &r33) const 01252 { 01253 if(!m_pDataObjectTags) return RetVal(retError, 0, "Tagspace not initialized"); // error 01254 r11 = m_pDataObjectTags->m_rotMatrix[0]; 01255 r12 = m_pDataObjectTags->m_rotMatrix[1]; 01256 r13 = m_pDataObjectTags->m_rotMatrix[2]; 01257 r21 = m_pDataObjectTags->m_rotMatrix[3]; 01258 r22 = m_pDataObjectTags->m_rotMatrix[4]; 01259 r23 = m_pDataObjectTags->m_rotMatrix[5]; 01260 r31 = m_pDataObjectTags->m_rotMatrix[6]; 01261 r32 = m_pDataObjectTags->m_rotMatrix[7]; 01262 r33 = m_pDataObjectTags->m_rotMatrix[8]; 01263 return retOk; 01264 } 01265 01266 RetVal copyTagMapTo(DataObject &rhs) const; 01267 RetVal copyAxisTagsTo(DataObject &rhs) const; 01269 // END TAGSPACE 01270 01272 inline int getDims(void) const { return m_dims; } 01273 01275 inline int getType(void) const { return m_type; } 01276 01278 inline char getContinuous(void) const { return m_continuous; } 01279 01281 inline char getOwnData(void) const { return m_owndata; } 01282 01284 01288 inline int getTotal() const 01289 { 01290 int dims = getDims(); 01291 int total = dims > 0 ? 1 : 0; 01292 for(int i = 0 ; i<dims ; i++) 01293 { 01294 total *= getSize(i); 01295 } 01296 return total; 01297 01298 } 01299 01301 01305 inline int getOriginalTotal() const 01306 { 01307 int dims = getDims(); 01308 int total = dims > 0 ? 1 : 0; 01309 for(int i = 0 ; i<dims ; i++) 01310 { 01311 total *= m_osize[i]; 01312 } 01313 return total; 01314 01315 } 01316 01318 01326 inline void lockRead() 01327 { 01328 m_objHeaderLock.lockRead(); 01329 if(m_objSharedDataLock) m_objSharedDataLock->lockRead(); 01330 } 01331 01333 01336 inline void lockWrite() 01337 { 01338 m_objHeaderLock.lockWrite(); 01339 if(m_objSharedDataLock) m_objSharedDataLock->lockWrite(); 01340 } 01341 01343 01346 inline void unlock() 01347 { 01348 if(m_objSharedDataLock) m_objSharedDataLock->unlock(); 01349 m_objHeaderLock.unlock(); 01350 } 01351 01352 RetVal copyTo(DataObject &rhs, unsigned char regionOnly = 0); 01353 RetVal convertTo(DataObject &rhs, const int type, const double alpha=1, const double beta=0 ) const; 01354 RetVal deepCopyPartial(DataObject &rhs); 01356 uchar ** get_mdata(void); 01357 uchar ** get_mdata(void) const; 01358 01360 01363 inline MSize getSize(void) { return m_size; } 01364 01366 01369 inline const MSize getSize(void) const { return m_size; } 01370 01372 01376 int getSize(int index) const 01377 { 01378 if(index < 0 || index >= m_dims) 01379 { 01380 return -1; 01381 } 01382 else 01383 { 01384 return m_size[index]; 01385 } 01386 } 01387 01389 01393 int getOriginalSize(int index) const 01394 { 01395 if(index < 0 || index >= m_dims) 01396 { 01397 return -1; 01398 } 01399 else 01400 { 01401 return m_osize[index]; 01402 } 01403 } 01404 01406 DObjIterator begin(); 01408 DObjIterator end(); 01409 01410 DObjConstIterator constBegin() const; 01411 DObjConstIterator constEnd() const; 01412 01414 01417 DataObject(void) : m_continuous(1), m_owndata(1), m_type(0), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0) {} 01418 01420 01428 DataObject(const int size, const int type): m_continuous(1), m_owndata(1), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0) 01429 { 01430 int sizes[2] = {1, size}; 01431 this->create(2, sizes, type, 1); 01432 } 01433 01435 01443 DataObject(const int sizeY, const int sizeX, const int type): m_continuous(1), m_owndata(1), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0) 01444 { 01445 int sizes[2] = {sizeY, sizeX}; 01446 this->create(2, sizes, type, 1); 01447 } 01448 01450 01460 DataObject(const int sizeZ, const int sizeY, const int sizeX, const int type, const unsigned char continuous = 0) : m_continuous(continuous), m_owndata(1), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0) 01461 { 01462 int sizes[3] = {sizeZ, sizeY, sizeX}; 01463 this->create(3, sizes, type, m_continuous); 01464 } 01465 01467 01481 DataObject(const int sizeZ, const int sizeY, const int sizeX, const int type, const uchar* continuousDataPtr, const int* steps = NULL) : m_continuous(1), m_owndata(1), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0) 01482 { 01483 int sizes[3] = {sizeZ, sizeY, sizeX}; 01484 this->create(3, sizes, type, m_continuous, continuousDataPtr, steps); 01485 } 01486 01488 01497 DataObject(const unsigned char dimensions, const int *sizes, const int type, const unsigned char continuous = 0) : m_continuous(continuous), m_owndata(1), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0) 01498 { 01499 this->create(dimensions, sizes, type, m_continuous); 01500 } 01501 01503 01516 DataObject(const unsigned char dimensions, const int *sizes, const int type, const uchar* continuousDataPtr, const int* steps = NULL) : m_continuous(1), m_owndata(1), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0) 01517 { 01518 this->create(dimensions, sizes, type, m_continuous, continuousDataPtr, steps); 01519 } 01520 01521 DataObject(const unsigned char dimensions, const int *sizes, const int type, const cv::Mat* planes, const unsigned int nrOfPlanes) : m_continuous(0), m_owndata(1), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0) 01522 { 01523 this->create(dimensions, sizes, type, planes, nrOfPlanes); 01524 } 01525 01526 DataObject(const DataObject& copyConstr); 01528 01529 01535 ~DataObject(void) 01536 { 01537 freeData(); 01538 } 01539 01541 DataObject & operator = (const cv::Mat &rhs); 01542 DataObject & operator = (const DataObject &rhs); 01543 DataObject & operator = (const int8 &value); 01544 DataObject & operator = (const uint8 &value); 01545 DataObject & operator = (const int16 &value); 01546 DataObject & operator = (const uint16 &value); 01547 DataObject & operator = (const int32 &value); 01548 DataObject & operator = (const uint32 &value); 01549 DataObject & operator = (const float32 &value); 01550 DataObject & operator = (const float64 &value); 01551 DataObject & operator = (const complex64 &value); 01552 DataObject & operator = (const complex128 &value); 01553 DataObject & operator = (const ito::Rgba32 &value); 01556 DataObject & operator += (const DataObject &rhs); 01557 DataObject & operator += (const float64 &value); 01558 01559 DataObject operator + (const DataObject &rhs); 01560 DataObject operator + (const float64 &value); 01561 01562 DataObject & operator -= (const DataObject &rhs); 01563 DataObject & operator -= (const float64 &value); 01564 01565 DataObject operator - (const DataObject &rhs); 01566 DataObject operator - (const float64 &value); 01567 01568 DataObject & operator *= (const DataObject &rhs); 01569 DataObject & operator *= (const float64 &factor); 01570 01571 DataObject operator * (const DataObject &rhs); 01572 DataObject operator * (const float64 &factor); 01573 01574 // Comparison Operators 01575 DataObject operator < (DataObject &rhs); 01576 DataObject operator > (DataObject &rhs); 01577 DataObject operator <= (DataObject &rhs); 01578 DataObject operator >= (DataObject &rhs); 01579 DataObject operator == (DataObject &rhs); 01580 DataObject operator != (DataObject &rhs); 01581 01582 01583 // bitshift operators 01584 DataObject operator << (const unsigned int shiftbit); 01585 DataObject & operator <<= (const unsigned int shiftbit); 01586 DataObject operator >> (const unsigned int shiftbit); 01587 DataObject & operator >>= (const unsigned int shiftbit); 01588 01589 // bitwise operators 01590 DataObject operator & (const DataObject & rhs); 01591 DataObject & operator &= (const DataObject & rhs); 01592 DataObject operator | (const DataObject & rhs); 01593 DataObject & operator |= (const DataObject & rhs); 01594 DataObject operator ^ (const DataObject & rhs); 01595 DataObject & operator ^= (const DataObject & rhs); 01596 01597 // allocates matrix with zero values 01598 RetVal zeros(const int type); 01599 RetVal zeros(const int size, const int type); 01600 RetVal zeros(const int sizeY, const int sizeX, const int type); 01601 RetVal zeros(const int sizeZ, const int sizeY, const int sizeX, const int type, const unsigned char continuous = 0); 01602 RetVal zeros(const unsigned char dimensions, const int *sizes, const int type, const unsigned char continuous = 0); 01603 01604 // allocates matrix with all values set to one 01605 RetVal ones(const int type); 01606 RetVal ones(const int size, const int type); 01607 RetVal ones(const int sizeY, const int sizeX, const int type); 01608 RetVal ones(const int sizeZ, const int sizeY, const int sizeX, const int type, const unsigned char continuous = 0); 01609 RetVal ones(const unsigned char dimensions, const int *sizes, const int type, const unsigned char continuous = 0); 01610 01611 // allocates matrix with uniform distributed noise 01612 RetVal rand(const int type, const bool randMode = false); 01613 RetVal rand(const int size, const int type, const bool randMode = false); 01614 RetVal rand(const int sizeY, const int sizeX, const int type, const bool randMode = false); 01615 RetVal rand(const int sizeZ, const int sizeY, const int sizeX, const int type, const bool randMode, const unsigned char continuous = 0); 01616 RetVal rand(const unsigned char dimensions, const int *sizes, const int type, const bool randMode, const unsigned char continuous = 0); 01617 01618 // allocates matrix with eye-matrix representation 01619 RetVal eye(const int type); 01620 RetVal eye(const int size, const int type); 01621 01622 RetVal conj(); 01623 DataObject adj() const; 01624 DataObject trans() const; 01625 01626 //RetVal makeContinuous(void); 01627 01628 DataObject mul(const DataObject &mat2, const double scale = 1.0); 01629 DataObject div(const DataObject &mat2, const double scale = 1.0); 01630 DataObject squeeze() const; 01631 int elemSize() const; 01632 01634 01639 template<typename _Tp> _Tp& at(const unsigned int y, const unsigned int x) const 01640 { 01641 #if __ITODEBUG 01642 if (m_dims != 2) 01643 { 01644 cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__)); 01645 } 01646 else if (((int)x >= m_size[1]) || ((int)y >= m_size[0]) ) 01647 { 01648 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__)); 01649 } 01650 #endif 01651 return (*(cv::Mat_<_Tp> *)(m_data[0]))(y, x); 01652 } 01653 01655 01660 template<typename _Tp> _Tp& at(const unsigned int y, const unsigned int x) 01661 { 01662 #if __ITODEBUG 01663 if (m_dims != 2) 01664 { 01665 cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__)); 01666 } 01667 else if (((int)x >= m_size[1]) || ((int)y >= m_size[0]) ) 01668 { 01669 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__)); 01670 } 01671 01672 #endif 01673 return (*(cv::Mat_<_Tp> *)(m_data[0]))(y, x); 01674 } 01675 01677 01683 template<typename _Tp> _Tp& at(const unsigned int z, const unsigned int y, const unsigned int x) const 01684 { 01685 #if __ITODEBUG 01686 if (m_dims != 3) 01687 { 01688 cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__)); 01689 } 01690 else if (((int)x >= m_size[2]) || ((int)y >= m_size[1]) || (((int)z + m_roi[0]) >= (m_roi[0] + m_size[0]))) 01691 { 01692 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__)); 01693 } 01694 #endif 01695 01696 return (*(cv::Mat_<_Tp> *)(m_data[z + m_roi[0]]))(y, x); 01697 } 01698 01700 01706 template<typename _Tp> _Tp& at(const unsigned int z, const unsigned int y, const unsigned int x) 01707 { 01708 #if __ITODEBUG 01709 if (m_dims != 3) 01710 { 01711 cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__)); 01712 } 01713 else if (((int)x >= m_size[2]) || ((int)y >= m_size[1]) || (((int)z + m_roi[0]) >= (m_roi[0] + m_size[0]))) 01714 { 01715 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__)); 01716 } 01717 #endif 01718 return (*(cv::Mat_<_Tp> *)(m_data[z + m_roi[0]]))(y, x); 01719 } 01720 01722 01727 template<typename _Tp> _Tp& at(const unsigned int *idx) const //idx is in virtual order 01728 { 01729 int matNum = 0; 01730 01731 matIdxToNum(idx, &matNum); 01732 01733 return (*(cv::Mat_<_Tp> *)(m_data[matNum]))(idx[m_dims - 2], idx[m_dims - 1]); 01734 } 01735 01737 01742 template<typename _Tp> _Tp& at(const unsigned int *idx) //idx is in virtual order 01743 { 01744 int matNum = 0; 01745 01746 matIdxToNum(idx, &matNum); 01747 01748 return (*(cv::Mat_<_Tp> *)(m_data[matNum]))(idx[m_dims - 2], idx[m_dims - 1]); 01749 } 01750 01751 DataObject at(const ito::Range &rowRange, const ito::Range &colRange); 01752 DataObject at(ito::Range *ranges); 01754 01755 01761 uchar* rowPtr(const int matNum, const int y) 01762 { 01763 int matIndex = seekMat(matNum); 01764 return ((cv::Mat*)m_data[matIndex])->ptr(y); 01765 } 01766 01768 01774 const uchar* rowPtr(const int matNum, const int y) const 01775 { 01776 int matIndex = seekMat(matNum); 01777 return ((cv::Mat*)m_data[matIndex])->ptr(y); 01778 } 01779 01780 DataObject row(const int selRow); 01781 DataObject col(const int selCol); 01782 //DataObject diag(void); 01783 01784 // ROI 01785 DataObject & adjustROI(const int dtop, const int dbottom, const int dleft, const int dright); 01786 DataObject & adjustROI(const unsigned char dims, const int *lims); 01787 RetVal locateROI(int *wholeSizes, int *offsets); 01788 RetVal locateROI(int *lims); 01789 template<typename _Tp> RetVal copyFromData2D(const _Tp* src, const int sizeX, const int sizeY); 01790 template<typename _Tp> RetVal copyFromData2D(const _Tp *src, const int sizeX, const int sizeY, const int x0, const int y0, const int width, const int height); 01791 template<typename _Tp> RetVal checkType(const _Tp *src); //compares type of elements in this data objects and type of given argument (doc in source) 01792 01793 // 01794 template<typename T2> operator T2 (); 01796 template<typename _Tp> RetVal linspace(const _Tp start, const _Tp end, const _Tp inc, const int transposed); 01797 }; 01798 01799 01800 //---------------------------------------------------------------------------------------------------------------------------------- 01801 // functions for DataObject in namespace ITO, which are NOT member functions 01802 //---------------------------------------------------------------------------------------------------------------------------------- 01803 DataObject abs(const DataObject &dObj); 01804 DataObject arg(const DataObject &dObj); 01805 DataObject real(const DataObject &dObj); 01806 DataObject imag(const DataObject &dObj); 01808 DataObject makeContinuous(const DataObject &dObj); 01810 template<typename _Tp, typename _T2> RetVal CastFunc(const DataObject *dObj, DataObject *resObj, double alpha = 1.0, double beta = 0.0); 01811 01812 //RetVal minMaxLoc(const DataObject &dObj, double *minVal, double *maxVal, int *minPos = NULL, int *maxPos = NULL); 01813 01815 01822 template<typename _Tp> _Tp numberConversion(ito::tDataType fromType, void *scalar) 01823 { 01824 //_Tp retValue = 0; 01825 _Tp retValue; 01826 01827 switch(fromType) 01828 { 01829 case ito::tUInt8: 01830 retValue = cv::saturate_cast<_Tp>(*(static_cast<uint8*>(scalar))); 01831 break; 01832 case ito::tInt8: 01833 retValue = cv::saturate_cast<_Tp>(*(static_cast<int8*>(scalar))); 01834 break; 01835 case ito::tUInt16: 01836 retValue = cv::saturate_cast<_Tp>(*(static_cast<uint16*>(scalar))); 01837 break; 01838 case ito::tInt16: 01839 retValue = cv::saturate_cast<_Tp>(*(static_cast<int16*>(scalar))); 01840 break; 01841 case ito::tUInt32: 01842 retValue = cv::saturate_cast<_Tp>(*(static_cast<uint32*>(scalar))); 01843 break; 01844 case ito::tInt32: 01845 retValue = cv::saturate_cast<_Tp>(*(static_cast<int32*>(scalar))); 01846 break; 01847 case ito::tFloat32: 01848 retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::float32*>(scalar))); 01849 break; 01850 case ito::tFloat64: 01851 retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::float64*>(scalar))); 01852 break; 01853 case ito::tComplex64: 01854 retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::complex64*>(scalar))); 01855 break; 01856 case ito::tComplex128: 01857 retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::complex128*>(scalar))); 01858 break; 01859 case ito::tRGBA32: 01860 retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::Rgba32*>(scalar))); 01861 break; 01862 default: 01863 cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__)); 01864 retValue = 0; 01865 } 01866 01867 return retValue; 01868 }; 01869 01870 //template<> ito::Rgba32 numberConversion<ito::Rgba32>(ito::tDataType fromType, void *scalar) 01871 //{ 01872 // _Tp retValue = 0; 01873 // 01874 // switch(fromType) 01875 // { 01876 // case ito::tUInt8: 01877 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<uint8*>(scalar))); 01878 // break; 01879 // case ito::tInt8: 01880 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<int8*>(scalar))); 01881 // break; 01882 // case ito::tUInt16: 01883 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<uint16*>(scalar))); 01884 // break; 01885 // case ito::tInt16: 01886 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<int16*>(scalar))); 01887 // break; 01888 // case ito::tUInt32: 01889 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<uint32*>(scalar))); 01890 // break; 01891 // case ito::tInt32: 01892 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<int32*>(scalar))); 01893 // break; 01894 // case ito::tFloat32: 01895 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::float32*>(scalar))); 01896 // break; 01897 // case ito::tFloat64: 01898 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::float64*>(scalar))); 01899 // break; 01900 // case ito::tComplex64: 01901 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::complex64*>(scalar))); 01902 // break; 01903 // case ito::tComplex128: 01904 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::complex128*>(scalar))); 01905 // break; 01906 // case ito::tRGBA32: 01907 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::Rgba32*>(scalar))); 01908 // break; 01909 // default: 01910 // cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__)); 01911 // retValue = 0; 01912 // } 01913 // 01914 // return retValue; 01915 //} 01916 01917 //---------------------------------------------------------------------------------------------------------------------------------- 01918 // cout 01919 //---------------------------------------------------------------------------------------------------------------------------------- 01920 template<typename _Tp> static std::ostream& coutFunc(std::ostream& out, const DataObject& dObj) 01921 { 01922 //cv::Mat_<_Tp> *cvMat = NULL; 01923 int numMats = dObj.calcNumMats(); 01924 int tMat = 0; 01925 01926 if (dObj.getDims() == 0) 01927 { 01928 std::cout << "DataObject()\n" << std::endl; 01929 } 01930 else 01931 { 01932 std::cout << "DataObject(size=[" << dObj.getSize(0); 01933 for (int dim = 1; dim < dObj.getDims(); ++dim) 01934 { 01935 std::cout << "x" << dObj.getSize(dim); 01936 } 01937 std::cout << "]\n" << std::endl; 01938 01939 int *idx = new int[dObj.getDims()]; 01940 01941 01942 for (int nMat = 0; nMat < numMats; nMat++) 01943 { 01944 tMat = dObj.seekMat(nMat, numMats); 01945 //std::cout << tMat + 1 << "->("; 01946 01947 dObj.matNumToIdx(tMat, idx); 01948 std::cout << "["; 01949 for (int i = 0; i < dObj.getDims() - 2; ++i) 01950 { 01951 std::cout << idx[i] << ","; 01952 } 01953 std::cout << ":,:]->("; 01954 01955 std::cout << cv::format( (*((cv::Mat_<_Tp> *)((dObj.get_mdata())[tMat]))) , "numpy" ) << std::endl << std::endl; 01956 01957 std::cout << ")" << "\n" << std::endl; 01958 } 01959 01960 delete[] idx; 01961 01962 std::cout << ")" << "\n" << std::endl; 01963 } 01964 return out; 01965 01966 } 01967 01968 typedef std::ostream& (*tCoutFunc)(std::ostream& out, const DataObject& dObj); 01969 01970 static tCoutFunc fListCout[] = 01971 { 01972 coutFunc<int8>, 01973 coutFunc<uint8>, 01974 coutFunc<int16>, 01975 coutFunc<uint16>, 01976 coutFunc<int32>, 01977 coutFunc<uint32>, 01978 coutFunc<ito::float32>, 01979 coutFunc<ito::float64>, 01980 coutFunc<ito::complex64>, 01981 coutFunc<ito::complex128>, 01982 coutFunc<ito::Rgba32> 01983 }; 01984 01985 static inline std::ostream& operator << (std::ostream& out, const DataObject& dObj) 01986 { 01987 return fListCout[dObj.getType()](out, dObj); 01988 } 01989 01991 01998 static ito::tDataType convertCmplxTypeToRealType(ito::tDataType cmplxType) 01999 { 02000 switch(cmplxType) 02001 { 02002 case ito::tInt8: 02003 case ito::tUInt8: 02004 case ito::tInt16: 02005 case ito::tUInt16: 02006 case ito::tInt32: 02007 case ito::tUInt32: 02008 case ito::tFloat32: 02009 case ito::tFloat64: 02010 case ito::tRGBA32: 02011 return cmplxType; 02012 case ito::tComplex64: 02013 return ito::tFloat32; 02014 case ito::tComplex128: 02015 return ito::tFloat64; 02016 } 02017 02018 cv::error(cv::Exception(CV_StsAssert, "Input data type unknown", "", __FILE__, __LINE__)); 02019 return ito::tInt8; 02020 } 02021 02023 02031 template<typename _Tp> static inline ito::tDataType getDataType(const _Tp* /*src*/) 02032 { 02033 cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__)); 02034 return ito::tInt8; 02035 } 02036 02037 template<> inline ito::tDataType getDataType(const uint8* /*src*/) { return ito::tUInt8; } 02038 template<> inline ito::tDataType getDataType(const int8* /*src*/) { return ito::tInt8; } 02039 template<> inline ito::tDataType getDataType(const uint16* /*src*/) { return ito::tUInt16; } 02040 template<> inline ito::tDataType getDataType(const int16* /*src*/) { return ito::tInt16; } 02041 template<> inline ito::tDataType getDataType(const uint32* /*src*/) { return ito::tUInt32; } 02042 template<> inline ito::tDataType getDataType(const int32* /*src*/) { return ito::tInt32; } 02043 template<> inline ito::tDataType getDataType(const float32* /*src*/) { return ito::tFloat32; } 02044 template<> inline ito::tDataType getDataType(const float64* /*src*/) { return ito::tFloat64; } 02045 template<> inline ito::tDataType getDataType(const complex64* /*src*/) { return ito::tComplex64; } 02046 template<> inline ito::tDataType getDataType(const complex128* /*src*/) { return ito::tComplex128; } 02047 template<> inline ito::tDataType getDataType(const Rgba32* /*src*/) { return ito::tRGBA32; } 02048 02049 02051 02060 template<typename _Tp> static inline ito::tDataType getDataType2() 02061 { 02062 cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__)); 02063 return ito::tInt8; 02064 } 02065 02066 template<> inline ito::tDataType getDataType2<uint8*>() { return ito::tUInt8; } 02067 template<> inline ito::tDataType getDataType2<int8*>() { return ito::tInt8; } 02068 template<> inline ito::tDataType getDataType2<uint16*>() { return ito::tUInt16; } 02069 template<> inline ito::tDataType getDataType2<int16*>() { return ito::tInt16; } 02070 template<> inline ito::tDataType getDataType2<uint32*>() { return ito::tUInt32; } 02071 template<> inline ito::tDataType getDataType2<int32*>() { return ito::tInt32; } 02072 template<> inline ito::tDataType getDataType2<float32*>() { return ito::tFloat32; } 02073 template<> inline ito::tDataType getDataType2<float64*>() { return ito::tFloat64; } 02074 template<> inline ito::tDataType getDataType2<complex64*>() { return ito::tComplex64; } 02075 template<> inline ito::tDataType getDataType2<complex128*>() { return ito::tComplex128; } 02076 template<> inline ito::tDataType getDataType2<Rgba32*>() { return ito::tRGBA32; } 02077 02079 02089 template<typename _Tp> static inline bool isZeroValue(_Tp v, _Tp /*epsilon*/) 02090 { 02091 return v == 0; 02092 } 02093 template<> inline bool isZeroValue(Rgba32 v, Rgba32 /*epsilon*/) 02094 { 02095 return v == Rgba32::zeros(); 02096 } 02097 template<> inline bool isZeroValue(float32 v, float32 epsilon) 02098 { 02099 return v >= epsilon ? false : (v <= -epsilon ? false : true); 02100 } 02101 template<> inline bool isZeroValue(float64 v, float64 epsilon) 02102 { 02103 return v >= epsilon ? false : (v <= -epsilon ? false : true); 02104 } 02105 template<> inline bool isZeroValue(std::complex<ito::float32> v, std::complex<ito::float32> epsilon) 02106 { 02107 return isZeroValue<ito::float32>(v.real(),epsilon.real()) && isZeroValue<ito::float32>(v.imag(),epsilon.real()); 02108 } 02109 template<> inline bool isZeroValue(std::complex<ito::float64> v, std::complex<ito::float64> epsilon) 02110 { 02111 return isZeroValue<ito::float64>(v.real(),epsilon.real()) && isZeroValue<ito::float64>(v.imag(),epsilon.real()); 02112 } 02113 02114 02115 //---------------------------------------------------------------------------------------------------------------------------------- 02116 // friend functions to access private members of DataObject 02117 //---------------------------------------------------------------------------------------------------------------------------------- 02118 } //namespace ito 02119 02120 #endif //__DATAOBJH 02121 02122